Deliver a conversation-first progressive workbench with safe live state

Why: make material, background work, confirmations and files accessible to nontechnical users across desktop and mobile.

Evidence: Dev SELF receipts for Frontend tsc, 190 tests, knip baseline, build, nine fixture browser cases and two real HTTP/browser smoke cases using MockRunner.

Impact: existing API and permissions remain authoritative; stale events/queries and duplicate effects are guarded, while one file preview and reading state are preserved.

Refs: work-companion-ui design r0.2 and plan r1 U2-U5; UI01-UI13.
This commit is contained in:
2026-10-12 16:05:13 +00:00
parent 4965de269a
commit 411a79d9e2
22 changed files with 1847 additions and 276 deletions
+11
View File
@@ -7,6 +7,17 @@ function p(partial: Partial<Part> & { type: Part['type'] }): Part {
}
describe('splitTimeline', () => {
it('keeps errors and file references outside a technical record even before a later tool', () => {
const parts: Part[] = [
p({ type: 'error', process: true, error: { code: 'read.failed', message: '评审意见无法读取' } }),
p({ type: 'artifact_ref', artifact: { artifactId: 'a1', name: '已整理的材料.docx' } }),
p({ type: 'tool_call', process: true, toolCall: { id: 'c1', name: 'search' } }),
p({ type: 'text', text: '已整理另外两份材料' }),
]
const split = splitTimeline(parts)
expect(split.timeline.map(x => x.type)).toEqual(['tool_call'])
expect(split.final.map(x => x.type)).toEqual(['error', 'artifact_ref', 'text'])
})
it('keeps everything up to the last process part in the timeline', () => {
const parts: Part[] = [
p({ type: 'text', text: '先找资料', process: true }),