|
@@ -3,13 +3,13 @@
|
|
|
// hole like the bash sample (a product registration, not a sample). The row
|
|
// hole like the bash sample (a product registration, not a sample). The row
|
|
|
// summarizes the written list (counts + active item) from the call args; the
|
|
// summarizes the written list (counts + active item) from the call args; the
|
|
|
// durable list itself renders in the TodoPanel above the composer, so the
|
|
// durable list itself renders in the TodoPanel above the composer, so the
|
|
|
-// row stays one line.
|
|
|
|
|
|
|
+// row stays one line. Chrome matches ToolRow (figma 780:53675).
|
|
|
|
|
|
|
|
import type { KeyboardEvent } from 'react'
|
|
import type { KeyboardEvent } from 'react'
|
|
|
import type { Context } from 'cordis'
|
|
import type { Context } from 'cordis'
|
|
|
-import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
|
|
|
|
|
+import { IconChecklistOutline16, StateDot } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
|
import type { ToolRowProps } from '../contract/slots.ts'
|
|
import type { ToolRowProps } from '../contract/slots.ts'
|
|
|
-import { toolRowModel } from '../contract/tool-call-model.ts'
|
|
|
|
|
|
|
+import { toolRowModel, type ToolRowState } from '../contract/tool-call-model.ts'
|
|
|
import css from './todo-row.module.css'
|
|
import css from './todo-row.module.css'
|
|
|
|
|
|
|
|
/** One parsed args item, shape-checked (model JSON: any field may be missing or mistyped). */
|
|
/** One parsed args item, shape-checked (model JSON: any field may be missing or mistyped). */
|
|
@@ -40,6 +40,17 @@ function summarize(argsRaw: string): string | null {
|
|
|
: head
|
|
: head
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/** Leading-slot state substitution matches ToolRow / bash: icon yields to the
|
|
|
|
|
+ * state semantic while running or failed; ok keeps the checklist glyph. */
|
|
|
|
|
+function leadingFor(state: ToolRowState) {
|
|
|
|
|
+ switch (state) {
|
|
|
|
|
+ case 'running': return <StateDot state="ongoing" />
|
|
|
|
|
+ case 'error': return <StateDot state="error" />
|
|
|
|
|
+ case 'stopped': return <StateDot state="warning" />
|
|
|
|
|
+ default: return <IconChecklistOutline16 />
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/** One-line plan update row (click opens the raw args in details). Non-ok
|
|
/** One-line plan update row (click opens the raw args in details). Non-ok
|
|
|
* execution states keep the generic row's dot semantics — a cancelled call
|
|
* execution states keep the generic row's dot semantics — a cancelled call
|
|
|
* wrote no todo/write, so it must not read as a completed update. */
|
|
* wrote no todo/write, so it must not read as a completed update. */
|
|
@@ -64,10 +75,9 @@ export function TodoRow({ toolName, block, openDetails }: ToolRowProps) {
|
|
|
onClick={openDetails}
|
|
onClick={openDetails}
|
|
|
onKeyDown={openFromKeyboard}
|
|
onKeyDown={openFromKeyboard}
|
|
|
>
|
|
>
|
|
|
- {model.state === 'ok'
|
|
|
|
|
- ? <span className={css.badge} aria-hidden>☰</span>
|
|
|
|
|
- : <StateDot state={model.state === 'running' ? 'ongoing' : model.state === 'stopped' ? 'warning' : 'error'} />}
|
|
|
|
|
|
|
+ <span className={css.leading} aria-hidden>{leadingFor(model.state)}</span>
|
|
|
<span className={css.title}>更新任务清单</span>
|
|
<span className={css.title}>更新任务清单</span>
|
|
|
|
|
+ <span className={css.sep} aria-hidden />
|
|
|
<span className={css.summary}>{summary}</span>
|
|
<span className={css.summary}>{summary}</span>
|
|
|
{model.state === 'error' && <span className={css.err}>failed</span>}
|
|
{model.state === 'error' && <span className={css.err}>failed</span>}
|
|
|
{model.state === 'stopped' && <span className={css.err}>已中断</span>}
|
|
{model.state === 'stopped' && <span className={css.err}>已中断</span>}
|