From e30f642e37a8901c6f9575f97dfd03c721c4acc7 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 27 Jul 2026 17:23:36 +0800 Subject: [PATCH 1/6] refactor(todos): update TodoRow styling and logic, add IconChecklistOutline16, and enhance AssistantMarkdown rendering --- apps/web/tests/todo-display.snapshot.ts | 2 +- .../src/client/chat/AssistantMarkdown.tsx | 8 ++++- .../src/client/toolviews/todo-row.module.css | 35 ++++++++++++++----- .../src/client/toolviews/todo-row.tsx | 22 ++++++++---- .../tests/coverage-tails.spec.tsx | 14 ++++++++ .../client/ui-primitives/src/icons/index.tsx | 10 ++++++ .../client/ui-primitives/tests/icons.spec.tsx | 4 +-- 7 files changed, 77 insertions(+), 18 deletions(-) diff --git a/apps/web/tests/todo-display.snapshot.ts b/apps/web/tests/todo-display.snapshot.ts index 3116bf4242..86603b676c 100644 --- a/apps/web/tests/todo-display.snapshot.ts +++ b/apps/web/tests/todo-display.snapshot.ts @@ -158,7 +158,7 @@ it('renders the todo_write turn: dedicated tool row + the dock plan strip', asyn "text": "○浏览器验收", }, ], - "row": "☰更新任务清单1/3 已完成 · 实现 fixture 样本", + "row": "更新任务清单1/3 已完成 · 实现 fixture 样本", "rowState": "ok", } `) diff --git a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx index 0e91afcc07..2e2f8a6678 100644 --- a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx +++ b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx @@ -40,13 +40,19 @@ function ThinkRow({ text, running }: { text: string; running: boolean }) { export const AssistantMarkdown = memo(function AssistantMarkdown({ blocks, streaming, interrupted }: AssistantMarkdownProps) { const last = blocks.length - 1 + // Tool-call heads render as tool rows in the chat view's grouping pass, so + // a node that is only those heads (or empty) would paint an empty root + // between tool groups — skip the shell unless something visible remains. + const hasVisible = streaming === true + || interrupted === true + || blocks.some((block) => block.kind !== 'tool-call') + if (!hasVisible) return null return (
{blocks.map((block, i) => { switch (block.kind) { case 'text': return case 'reasoning': return - // Tool-call heads render as tool rows in the chat view's grouping pass. case 'tool-call': return null default: return } diff --git a/packages/client/ui-conversation/src/client/toolviews/todo-row.module.css b/packages/client/ui-conversation/src/client/toolviews/todo-row.module.css index ff4068d49c..dd32d56b01 100644 --- a/packages/client/ui-conversation/src/client/toolviews/todo-row.module.css +++ b/packages/client/ui-conversation/src/client/toolviews/todo-row.module.css @@ -1,29 +1,44 @@ -/* todo_write plan-update row: title + progress summary on one line. */ +/* todo_write plan-update row: ToolRow chrome (figma 780:53675) — + [16 checklist] gap6 [title 14/24] gap8 [2x2 dot] gap8 [summary FILL truncate]. */ .row { display: flex; align-items: center; - gap: 8px; height: 24px; min-width: 0; cursor: pointer; border-radius: 6px; - font-size: 13px; } .row:hover { background: var(--dsw-alias-interactive-bg-hover); } -.badge { +.leading { flex: none; - color: var(--dsw-alias-state-business-primary); + width: 16px; + height: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + margin-right: 6px; + color: var(--dsw-alias-label-tertiary); } .title { flex: none; - font-weight: 510; - color: var(--dsw-alias-label-primary); + font-size: 14px; + line-height: 24px; + color: var(--dsw-alias-label-primary-dimmed); +} + +.sep { + flex: none; + width: 2px; + height: 2px; + border-radius: 1px; + margin: 0 8px; + background: var(--dsw-alias-label-caption); } .summary { @@ -32,11 +47,15 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - color: var(--dsw-alias-label-secondary); + font-size: 14px; + line-height: 24px; + color: var(--dsw-alias-label-tertiary); } .err { flex: none; + margin-left: 8px; color: var(--dsw-alias-state-error-primary); font-size: 11px; + line-height: 16px; } diff --git a/packages/client/ui-conversation/src/client/toolviews/todo-row.tsx b/packages/client/ui-conversation/src/client/toolviews/todo-row.tsx index 353e7a5441..a47322b614 100644 --- a/packages/client/ui-conversation/src/client/toolviews/todo-row.tsx +++ b/packages/client/ui-conversation/src/client/toolviews/todo-row.tsx @@ -3,13 +3,13 @@ // 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 // 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 { 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 { toolRowModel } from '../contract/tool-call-model.ts' +import { toolRowModel, type ToolRowState } from '../contract/tool-call-model.ts' import css from './todo-row.module.css' /** 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 } +/** 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 + case 'error': return + case 'stopped': return + default: return + } +} + /** 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 * 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} onKeyDown={openFromKeyboard} > - {model.state === 'ok' - ? - : } + {leadingFor(model.state)} 更新任务清单 + {summary} {model.state === 'error' && failed} {model.state === 'stopped' && 已中断} diff --git a/packages/client/ui-conversation/tests/coverage-tails.spec.tsx b/packages/client/ui-conversation/tests/coverage-tails.spec.tsx index 18ac9a2891..d5cbf9ec42 100644 --- a/packages/client/ui-conversation/tests/coverage-tails.spec.tsx +++ b/packages/client/ui-conversation/tests/coverage-tails.spec.tsx @@ -60,6 +60,20 @@ describe('tails', () => { expect(stopped.getByText('已停止')).toBeTruthy() }) + it('AssistantMarkdown skips the root shell when only tool-call heads remain', () => { + // Tool heads are drawn by ChatView's tool groups; an empty root between + // groups is layout noise (no text, no pulse, no interrupted marker). + const empty = render( + , + ) + expect(empty.container.firstChild).toBeNull() + const blank = render() + expect(blank.container.firstChild).toBeNull() + }) + it('a settled others-variant row renders the sparkle icon in the leading slot', () => { const settled: ToolResultNode = { kind: 'tool-result', seq: 2, time: 2_000, callId: 'c5', diff --git a/packages/client/ui-primitives/src/icons/index.tsx b/packages/client/ui-primitives/src/icons/index.tsx index 4c2083bae1..5af9567b0d 100644 --- a/packages/client/ui-primitives/src/icons/index.tsx +++ b/packages/client/ui-primitives/src/icons/index.tsx @@ -653,6 +653,16 @@ export const IconDataOutline16 = ({ size = 16, className }: IconProps) => ( ) +/** ic_checklist_outline_16 (figma extract): two rings + two list bars. */ +export const IconChecklistOutline16 = ({ size = 16, className }: IconProps) => ( + + + + + + +) + /** ic_ds_List_Pen_outline_16 */ export const IconListPenOutline16 = ({ size = 16, className }: IconProps) => ( diff --git a/packages/client/ui-primitives/tests/icons.spec.tsx b/packages/client/ui-primitives/tests/icons.spec.tsx index 281124b8d5..c6303bc28e 100644 --- a/packages/client/ui-primitives/tests/icons.spec.tsx +++ b/packages/client/ui-primitives/tests/icons.spec.tsx @@ -14,8 +14,8 @@ const icons = Object.fromEntries( const iconNames = Object.keys(icons) describe('ic_ds_ icon set', () => { - it('exports the full P-I set (43 deepsuite + 12 figma extracts)', () => { - expect(iconNames.length).toBe(55) + it('exports the full P-I set (43 deepsuite + 13 figma extracts)', () => { + expect(iconNames.length).toBe(56) }) it.each(iconNames)('%s renders an svg with currentColor fills and no hardcoded palette', name => { From bede841ec71863378770f741f28359499d0c149e Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 27 Jul 2026 17:42:54 +0800 Subject: [PATCH 2/6] fix: cr --- .../client/ui-conversation/src/client/chat/AssistantMarkdown.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx index 2e2f8a6678..52fdc14217 100644 --- a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx +++ b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx @@ -53,6 +53,7 @@ export const AssistantMarkdown = memo(function AssistantMarkdown({ blocks, strea switch (block.kind) { case 'text': return case 'reasoning': return + // Grouped into tool rows by ChatView; hasVisible above skips an empty shell. case 'tool-call': return null default: return } From b21acea0ce26b1a53c8c503a055a0a8f9c55484d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:36:37 +0000 Subject: [PATCH 3/6] chore(deps): bump actions/configure-pages from 5 to 6 Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-pages.yml b/.github/workflows/docs-pages.yml index 281e931c50..036dcb268a 100644 --- a/.github/workflows/docs-pages.yml +++ b/.github/workflows/docs-pages.yml @@ -45,7 +45,7 @@ jobs: - name: Configure Pages id: pages - uses: actions/configure-pages@v5 + uses: actions/configure-pages@v6 - name: Verify and build documentation env: From 79b5d570e7cc98d3273c1dd7c7ccb977c8ca6eeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:37:12 +0000 Subject: [PATCH 4/6] chore(deps-dev): bump typescript in /native/landlock-run Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.9.3 to 6.0.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.3) --- updated-dependencies: - dependency-name: typescript dependency-version: 6.0.3 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- native/landlock-run/package.json | 2 +- native/landlock-run/pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/native/landlock-run/package.json b/native/landlock-run/package.json index f516588f17..307ce07227 100644 --- a/native/landlock-run/package.json +++ b/native/landlock-run/package.json @@ -25,6 +25,6 @@ "node-addon-landlock-run": "workspace:*", "@types/node": "^24.10.0", "tsx": "^4.20.6", - "typescript": "^5.9.3" + "typescript": "^6.0.3" } } diff --git a/native/landlock-run/pnpm-lock.yaml b/native/landlock-run/pnpm-lock.yaml index 88b1b3df00..6072f39940 100644 --- a/native/landlock-run/pnpm-lock.yaml +++ b/native/landlock-run/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^4.20.6 version: 4.23.0 typescript: - specifier: ^5.9.3 - version: 5.9.3 + specifier: ^6.0.3 + version: 6.0.3 packages/entry: optionalDependencies: @@ -210,8 +210,8 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true @@ -340,6 +340,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - typescript@5.9.3: {} + typescript@6.0.3: {} undici-types@7.18.2: {} From b2b063b6675d1ea9e27490086d25328bb4e64e88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 18:43:26 +0000 Subject: [PATCH 5/6] chore(deps): bump actions/deploy-pages from 4 to 5 Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-pages.yml b/.github/workflows/docs-pages.yml index 34a29c1293..59e5264512 100644 --- a/.github/workflows/docs-pages.yml +++ b/.github/workflows/docs-pages.yml @@ -69,4 +69,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 From 99d631d41abeaa1480335f367547da8b9f6ad445 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 28 Jul 2026 11:11:42 +0800 Subject: [PATCH 6/6] fix: ci --- .../ui-conversation/src/client/chat/AssistantMarkdown.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx index 52fdc14217..6daf78719e 100644 --- a/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx +++ b/packages/client/ui-conversation/src/client/chat/AssistantMarkdown.tsx @@ -43,9 +43,9 @@ export const AssistantMarkdown = memo(function AssistantMarkdown({ blocks, strea // Tool-call heads render as tool rows in the chat view's grouping pass, so // a node that is only those heads (or empty) would paint an empty root // between tool groups — skip the shell unless something visible remains. - const hasVisible = streaming === true + const hasVisible = streaming || interrupted === true - || blocks.some((block) => block.kind !== 'tool-call') + || blocks.some(block => block.kind !== 'tool-call') if (!hasVisible) return null return (