Parcourir la source

Showed end time for agent loop and changed message time to show date if not current day (#4503)

Co-authored-by: GitHub Action <[email protected]>
Valerio Di Maggio il y a 3 mois
Parent
commit
59742fbfee

+ 1 - 1
nix/hashes.json

@@ -1,3 +1,3 @@
 {
-  "nodeModules": "sha256-krj85tYW0P/YOnsXnO1cD5XkLtfWZzdXzj7CTNvsPPk="
+  "nodeModules": "sha256-N33FQyKF6IgGIRZ8NFd9o1/sjHMwbQ6KQcnMFyN0WmI="
 }

+ 31 - 2
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -79,6 +79,7 @@ const context = createContext<{
   width: number
   conceal: () => boolean
   showThinking: () => boolean
+  showTimestamps: () => boolean
 }>()
 
 function use() {
@@ -109,6 +110,7 @@ export function Session() {
   const [sidebar, setSidebar] = createSignal<"show" | "hide" | "auto">(kv.get("sidebar", "auto"))
   const [conceal, setConceal] = createSignal(true)
   const [showThinking, setShowThinking] = createSignal(true)
+  const [showTimestamps, setShowTimestamps] = createSignal(kv.get("timestamps", "hide") === "show")
 
   const wide = createMemo(() => dimensions().width > 120)
   const sidebarVisible = createMemo(() => sidebar() === "show" || (sidebar() === "auto" && wide()))
@@ -403,6 +405,19 @@ export function Session() {
         dialog.clear()
       },
     },
+    {
+      title: "Toggle timestamps",
+      value: "session.toggle.timestamps",
+      category: "Session",
+      onSelect: (dialog) => {
+        setShowTimestamps((prev) => {
+          const next = !prev
+          kv.set("timestamps", next ? "show" : "hide")
+          return next
+        })
+        dialog.clear()
+      },
+    },
     {
       title: "Toggle thinking blocks",
       value: "session.toggle.thinking",
@@ -712,6 +727,7 @@ export function Session() {
         },
         conceal,
         showThinking,
+        showTimestamps,
       }}
     >
       <box flexDirection="row" paddingBottom={1} paddingTop={1} paddingLeft={2} paddingRight={2} gap={2}>
@@ -891,6 +907,7 @@ function UserMessage(props: {
   index: number
   pending?: string
 }) {
+  const ctx = use()
   const text = createMemo(() => props.parts.flatMap((x) => (x.type === "text" && !x.synthetic ? [x] : []))[0])
   const files = createMemo(() => props.parts.flatMap((x) => (x.type === "file" ? [x] : [])))
   const sync = useSync()
@@ -949,7 +966,13 @@ function UserMessage(props: {
               {sync.data.config.username ?? "You"}{" "}
               <Show
                 when={queued()}
-                fallback={<span style={{ fg: theme.textMuted }}>{Locale.time(props.message.time.created)}</span>}
+                fallback={
+                  <span style={{ fg: theme.textMuted }}>
+                    {ctx.showTimestamps()
+                      ? `· ${Locale.todayTimeOrDateTime(props.message.time.created)}`
+                      : `· ${Locale.time(props.message.time.created)}`}
+                  </span>
+                }
               >
                 <span style={{ bg: theme.accent, fg: theme.backgroundPanel, bold: true }}> QUEUED </span>
               </Show>
@@ -973,6 +996,7 @@ function UserMessage(props: {
 function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; last: boolean }) {
   const local = useLocal()
   const { theme } = useTheme()
+  const ctx = use()
   return (
     <>
       <For each={props.parts}>
@@ -1015,7 +1039,12 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
           <box paddingLeft={3}>
             <text marginTop={1}>
               <span style={{ fg: local.agent.color(props.message.mode) }}>{Locale.titlecase(props.message.mode)}</span>{" "}
-              <span style={{ fg: theme.textMuted }}>{props.message.modelID}</span>
+              <span style={{ fg: theme.textMuted }}>
+                {props.message.modelID}
+                {ctx.showTimestamps() &&
+                  props.message.time.completed &&
+                  ` · ${Locale.todayTimeOrDateTime(props.message.time.completed)}`}
+              </span>
             </text>
           </box>
         </Match>

+ 22 - 2
packages/opencode/src/util/locale.ts

@@ -3,9 +3,29 @@ export namespace Locale {
     return str.replace(/\b\w/g, (c) => c.toUpperCase())
   }
 
-  export function time(input: number) {
+  export function time(input: number): string {
     const date = new Date(input)
-    return date.toLocaleTimeString()
+    return date.toLocaleTimeString(undefined, { timeStyle: "short" })
+  }
+
+  export function datetime(input: number): string {
+    const date = new Date(input)
+    const localTime = time(input)
+    const localDate = date.toLocaleDateString()
+    return `${localTime} · ${localDate}`
+  }
+
+  export function todayTimeOrDateTime(input: number): string {
+    const date = new Date(input)
+    const now = new Date()
+    const isToday =
+      date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate()
+
+    if (isToday) {
+      return time(input)
+    } else {
+      return datetime(input)
+    }
   }
 
   export function number(num: number): string {