@deepseek-ai/dsh-cordis-client-runner 0.1.2-alpha.5 → 0.1.3-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/extensions/cordis-client-runner/README.md
5
- README.md: 3b5762786e0f5b00fc80533ca4fa97a3d4cd0a4b
6
- README.zh.md: d68dc218f75e65c9a1787a5e43f018c9cdfa3383
5
+ README.md: 260d4703bda2560a4254962d7b868221d0328ec8
6
+ README.zh.md: a74128508c5b6a81d0600452b6ec5301bf7c8dcb
package/README.md CHANGED
@@ -83,7 +83,6 @@ Read these pages when the package-level contract is not enough. They move from t
83
83
  - [Tool package](../tool-cordis/README.md) — the model-facing tools whose run requests reach this page.
84
84
  - [UI package](../ui-cordis/README.md) — the panel and cards that operate this face.
85
85
  - [Extensions subsystem](../../../docs/subsystems/extensions.md) — the generated `ctx.dynamicCordisRunner` API and `cordis/*` events.
86
- - [Dynamic client render and attachment ownership Agent Note](../../../.agents/notes/implemented/architecture/2026-08-17-dynamic-client-render-and-attachment-ownership.md) — how browser plugins own their rendering and CSS.
87
86
  - [Client shells and dynamic packages Agent Note](../../../.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.md) — package placement and build faces for the client halves.
88
87
 
89
88
  -----
package/README.zh.md CHANGED
@@ -83,7 +83,6 @@ kind: "package-reference"
83
83
  - [工具包](../tool-cordis/README.zh.md)——运行请求到达本页的模型侧工具。
84
84
  - [UI 包](../ui-cordis/README.zh.md)——操作这个面的面板与卡片。
85
85
  - [extensions 子系统](../../../docs/subsystems/extensions.zh.md)——生成的 `ctx.dynamicCordisRunner` API 与 `cordis/*` 事件。
86
- - [动态客户端渲染与附件归属 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-17-dynamic-client-render-and-attachment-ownership.zh.md)——浏览器插件如何拥有自己的渲染与 CSS。
87
86
  - [客户端外壳与动态包 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-15-client-shells-and-dynamic-packages.zh.md)——浏览器半的包归属与构建面。
88
87
 
89
88
  -----
package/lib/client.js CHANGED
@@ -1602,13 +1602,17 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1602
1602
  name: "AgentContext",
1603
1603
  declaration: "export type AgentContext = Omit<Context, 'remote'> & {\n readonly remote: ClientRemote & TypertRemoteScopeApi<'agent'>;\n};"
1604
1604
  },
1605
+ {
1606
+ name: "AssistantLiveChunkEvent",
1607
+ declaration: "export interface AssistantLiveChunkEvent {\n readonly type: 'assistant/live-chunk';\n readonly seq: number;\n readonly time: number;\n readonly data: {\n readonly attemptId: LlmAttemptId;\n readonly turn: number;\n readonly step: number;\n readonly chunk: StreamChunk;\n };\n}"
1608
+ },
1605
1609
  {
1606
1610
  name: "BakedActions",
1607
1611
  declaration: "export type BakedActions<T, A extends ActionsDecl<T>> = {\n [K in keyof A]: A[K] extends (draft: T, ...params: infer P) => void ? (...params: P) => void : never;\n};"
1608
1612
  },
1609
1613
  {
1610
1614
  name: "BeginSubmissionInput",
1611
- declaration: "export interface BeginSubmissionInput {\n readonly mode: 'queue' | 'steer';\n readonly text: string;\n readonly images: readonly PendingSubmissionImage[];\n readonly onRetire?: (retirement: PendingSubmissionRetirement) => void;\n}"
1615
+ declaration: "export interface BeginSubmissionInput {\n readonly mode: 'queue' | 'steer';\n readonly text: string;\n readonly attachments: readonly PendingSubmissionAttachment[];\n readonly onRetire?: (retirement: PendingSubmissionRetirement) => void;\n}"
1612
1616
  },
1613
1617
  {
1614
1618
  name: "BoundActions",
@@ -1630,10 +1634,6 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1630
1634
  name: "ChildrenDecl",
1631
1635
  declaration: "export type ChildrenDecl = {\n [P in keyof SlotMap & string]?: SlotSpec<SlotMap[P]>;\n};"
1632
1636
  },
1633
- {
1634
- name: "ChunkRowEvent",
1635
- declaration: "export type ChunkRowEvent = {\n [Kind in ChunkRow['type']]: {\n readonly type: `chunkrow/${Kind}`;\n readonly seq: number;\n readonly time: number;\n readonly data: Extract<ChunkRow, {\n readonly type: Kind;\n }>['data'];\n };\n}[ChunkRow['type']];"
1636
- },
1637
1637
  {
1638
1638
  name: "ClientConnectionRpc",
1639
1639
  declaration: "export interface ClientConnectionRpc {\n call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<ConnectionRpcResult<unknown>>;\n readonly open?: (channel: string, endpoint: string, payload: unknown, signal: AbortSignal) => AsyncIterable<unknown>;\n}"
@@ -1650,10 +1650,6 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1650
1650
  name: "ComposedProps",
1651
1651
  declaration: "export type ComposedProps<K extends keyof SlotMap & string, EntryKey extends EntryKeyOf<K>, S extends keyof SlotMap & string, H, I extends object, M = never, N = undefined> = PropsRuntime<K, EntryKey> & PropsRenderSlots<S> & PropsStore<H> & InjectFace<I> & MatchedShare<SlotMap[K], M> & PropsLocale<N>;"
1652
1652
  },
1653
- {
1654
- name: "ConnectionConfig",
1655
- declaration: "export interface ConnectionConfig {\n backoffBaseMs?: number;\n backoffFactor?: number;\n backoffMaxMs?: number;\n generationReadyTimeoutMs?: number;\n}"
1656
- },
1657
1653
  {
1658
1654
  name: "ConnectionGeneration",
1659
1655
  declaration: "export interface ConnectionGeneration {\n readonly id: number;\n readonly host: ConnectionHostInfo;\n}"
@@ -1668,7 +1664,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1668
1664
  },
1669
1665
  {
1670
1666
  name: "ConnectionHandle",
1671
- declaration: "export interface ConnectionHandle {\n readonly isLoopback: boolean;\n readonly generation: ConnectionGenerationState;\n readonly state: ConnectionStateSource;\n readonly rpc: ClientConnectionRpc;\n reconnect(): void;\n registerGenerationSource(source: ConnectionGenerationSource): () => void;\n start(sinks: ConnectionSinks, config?: ConnectionConfig): ConnectionLoop;\n}"
1667
+ declaration: "export interface ConnectionHandle {\n readonly isLoopback: boolean;\n readonly generation: ConnectionGenerationState;\n readonly state: ConnectionStateSource;\n readonly rpc: ClientConnectionRpc;\n reconnect(): void;\n registerGenerationSource(source: ConnectionGenerationSource): () => void;\n start(sinks: ConnectionSinks, config?: ConnectionRecoveryConfig): ConnectionLoop;\n}"
1672
1668
  },
1673
1669
  {
1674
1670
  name: "ConnectionHostInfo",
@@ -1678,6 +1674,10 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1678
1674
  name: "ConnectionLoop",
1679
1675
  declaration: "export interface ConnectionLoop {\n stop(): void;\n}"
1680
1676
  },
1677
+ {
1678
+ name: "ConnectionRecoveryConfig",
1679
+ declaration: "export interface ConnectionRecoveryConfig {\n backoffBaseMs?: number;\n backoffFactor?: number;\n backoffMaxMs?: number;\n generationReadyWarnMs?: number;\n generationReadyTimeoutMs?: number;\n}"
1680
+ },
1681
1681
  {
1682
1682
  name: "ConnectionRpcFailure",
1683
1683
  declaration: "export interface ConnectionRpcFailure {\n readonly code: string;\n readonly message: string;\n readonly details: object;\n}"
@@ -1796,19 +1796,31 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1796
1796
  },
1797
1797
  {
1798
1798
  name: "PendingSubmission",
1799
- declaration: "export interface PendingSubmission {\n readonly requestId: SessionRequestId;\n readonly placement: PendingSubmissionPlacement;\n readonly time: number;\n readonly text: string;\n readonly images: readonly PendingSubmissionImage[];\n}"
1799
+ declaration: "export interface PendingSubmission {\n readonly requestId: SessionRequestId;\n readonly placement: PendingSubmissionPlacement;\n readonly time: number;\n readonly text: string;\n readonly attachments: readonly PendingSubmissionAttachment[];\n}"
1800
+ },
1801
+ {
1802
+ name: "PendingSubmissionAttachment",
1803
+ declaration: "export type PendingSubmissionAttachment = PendingSubmissionImageAttachment | PendingSubmissionFileAttachment;"
1804
+ },
1805
+ {
1806
+ name: "PendingSubmissionFileAttachment",
1807
+ declaration: "export interface PendingSubmissionFileAttachment {\n readonly type: 'file';\n readonly value: FileAttachmentRef;\n}"
1800
1808
  },
1801
1809
  {
1802
1810
  name: "PendingSubmissionImage",
1803
1811
  declaration: "export interface PendingSubmissionImage {\n readonly previewUrl: string;\n readonly name?: string;\n readonly width?: number;\n readonly height?: number;\n}"
1804
1812
  },
1813
+ {
1814
+ name: "PendingSubmissionImageAttachment",
1815
+ declaration: "export interface PendingSubmissionImageAttachment {\n readonly type: 'image';\n readonly value: PendingSubmissionImage;\n}"
1816
+ },
1805
1817
  {
1806
1818
  name: "PendingSubmissionPlacement",
1807
1819
  declaration: "export type PendingSubmissionPlacement = 'transcript' | 'queued' | 'steering';"
1808
1820
  },
1809
1821
  {
1810
1822
  name: "PendingSubmissionRetirement",
1811
- declaration: "export type PendingSubmissionRetirement = {\n readonly reason: 'observed';\n readonly attachments: readonly ImageAttachmentRef[];\n} | {\n readonly reason: 'failed';\n};"
1823
+ declaration: "export type PendingSubmissionRetirement = {\n readonly reason: 'observed';\n readonly attachments: readonly (ImageAttachmentRef | FileAttachmentRef)[];\n} | {\n readonly reason: 'failed';\n};"
1812
1824
  },
1813
1825
  {
1814
1826
  name: "ProjectionsFace",
@@ -1816,7 +1828,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1816
1828
  },
1817
1829
  {
1818
1830
  name: "PromptContentPart",
1819
- declaration: "export type PromptContentPart = {\n readonly type: 'text';\n readonly text: string;\n} | {\n readonly type: 'image';\n readonly mediaType: ImageMediaType;\n readonly data: string;\n readonly name?: string;\n};"
1831
+ declaration: "export type PromptContentPart = {\n readonly type: 'text';\n readonly text: string;\n} | {\n readonly type: 'image';\n readonly mediaType: ImageMediaType;\n readonly data: string;\n readonly name?: string;\n} | {\n readonly type: 'file';\n readonly receiptId: Branded<'file-upload-receipt-id'>;\n};"
1820
1832
  },
1821
1833
  {
1822
1834
  name: "PromptError",
@@ -1878,17 +1890,21 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1878
1890
  name: "SessionAreaProps",
1879
1891
  declaration: "export interface SessionAreaProps {\n empty?: (() => ReactNode) | undefined;\n children: ReactNode;\n}"
1880
1892
  },
1893
+ {
1894
+ name: "SessionAssistantSettlementEntry",
1895
+ declaration: "export interface SessionAssistantSettlementEntry {\n readonly type: 'event';\n readonly event: SessionEvent<'assistant/message'> | SessionEvent<'assistant/attempt'>;\n}"
1896
+ },
1881
1897
  {
1882
1898
  name: "SessionBinding",
1883
1899
  declaration: "export interface SessionBinding {\n readonly sessionId: SessionId;\n readonly session: SessionFace;\n readonly eventSource: SessionEventSource;\n readonly ctx: AgentContext;\n}"
1884
1900
  },
1885
1901
  {
1886
1902
  name: "SessionEventChange",
1887
- declaration: "export type SessionEventChange = {\n readonly kind: 'replace';\n readonly entries: readonly SessionEventLikeEntry[];\n} | {\n readonly kind: 'prepend';\n readonly entries: readonly SessionEventLikeEntry[];\n} | {\n readonly kind: 'append';\n readonly entries: readonly SessionLiveEventEntry[];\n};"
1903
+ declaration: "export type SessionEventChange = {\n readonly kind: 'replace';\n readonly entries: readonly SessionEventLikeEntry[];\n} | {\n readonly kind: 'prepend';\n readonly entries: readonly SessionEventLikeEntry[];\n} | {\n readonly kind: 'append';\n readonly entries: readonly SessionEventLikeEntry[];\n} | {\n readonly kind: 'settle-assistant';\n readonly attemptId: LlmAttemptId;\n readonly entry?: SessionAssistantSettlementEntry;\n};"
1888
1904
  },
1889
1905
  {
1890
1906
  name: "SessionEventLikeEntry",
1891
- declaration: "export type SessionEventLikeEntry = {\n readonly type: 'event';\n readonly event: SessionEvent;\n} | {\n readonly type: 'chunks';\n readonly event: ChunkRowEvent;\n};"
1907
+ declaration: "export type SessionEventLikeEntry = {\n readonly type: 'event';\n readonly event: SessionEvent;\n} | {\n readonly type: 'transient';\n readonly event: AssistantLiveChunkEvent;\n};"
1892
1908
  },
1893
1909
  {
1894
1910
  name: "SessionEventSource",
@@ -1906,10 +1922,6 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
1906
1922
  name: "SessionIdOf",
1907
1923
  declaration: "export type SessionIdOf = SessionStandardProps extends {\n sessionId: infer S;\n} ? S : string;"
1908
1924
  },
1909
- {
1910
- name: "SessionLiveEventEntry",
1911
- declaration: "export type SessionLiveEventEntry = Extract<SessionEventLikeEntry, {\n readonly type: 'event';\n}>;"
1912
- },
1913
1925
  {
1914
1926
  name: "SessionMaybeStandardProps",
1915
1927
  declaration: "export interface SessionMaybeStandardProps {\n}"
@@ -2244,7 +2256,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2244
2256
  occupants: ["client-ui-message-feedback MessageFeedbackActions id 'feedback'"],
2245
2257
  replaceRisk: "none",
2246
2258
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.chat.assistant-actions', () => ctx.slots.register(\n { name: 'conversation.chat.assistant-actions', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2247
- source: "packages/client/ui-chat/src/client/contract/slots.ts:221"
2259
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:227"
2248
2260
  },
2249
2261
  {
2250
2262
  key: "conversation.chat.commandview",
@@ -2285,7 +2297,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2285
2297
  occupants: [],
2286
2298
  replaceRisk: "none",
2287
2299
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.chat.commandview', () => ctx.slots.register(\n { name: 'conversation.chat.commandview', key: '<one key the owner dispatches>' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2288
- source: "packages/client/ui-chat/src/client/contract/slots.ts:209"
2300
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:215"
2289
2301
  },
2290
2302
  {
2291
2303
  key: "conversation.chat.node",
@@ -2299,9 +2311,10 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2299
2311
  type: "string",
2300
2312
  doc: "Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant."
2301
2313
  }],
2302
- ownerProps: ["/** Stable owner currency delivered to a keyed Chat renderer. */\nexport interface ChatNodeOwnerProps {\n selectedCallId?: ToolCallId | undefined\n cwd?: string | undefined\n openFile: (path: string) => void\n inspectCall: (callId: ToolCallId) => void\n forkAt: (seq: number) => void\n renderMessageImages: RenderMessageImages\n fileMentions: (owner: TurnTailOwnerProps) => MarkdownFileMentions | undefined\n /** Turn-process state when this Node belongs to a projected Turn. */\n turnProcess?: TurnProcessOwnerProps | undefined\n}"],
2314
+ ownerProps: ["/** Stable owner currency delivered to a keyed Chat renderer. */\nexport interface ChatNodeOwnerProps {\n selectedCallId?: ToolCallId | undefined\n cwd?: string | undefined\n openFile: (path: string) => void\n inspectCall: (callId: ToolCallId) => void\n forkAt: (seq: number) => void\n /**\n * Session-authorized image loader, down-threaded from the Chat view so a\n * chat-node renderer can render the attachment presentation slot directly\n * with only the durable references plus this loader, instead of receiving a\n * rendering closure.\n */\n loadImage: MessageImageLoader\n renderMessageImages: RenderMessageImages\n fileMentions: (owner: TurnTailOwnerProps) => MarkdownFileMentions | undefined\n /** Turn-process state when this Node belongs to a projected Turn. */\n turnProcess?: TurnProcessOwnerProps | undefined\n}"],
2303
2315
  ownerPropsReferences: [
2304
2316
  "MarkdownFileMentions",
2317
+ "MessageImageLoader",
2305
2318
  "RenderMessageImages",
2306
2319
  "TurnProcessOwnerProps",
2307
2320
  "TurnTailOwnerProps"
@@ -2345,7 +2358,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2345
2358
  ],
2346
2359
  replaceRisk: "shadows-shipped-ui",
2347
2360
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.chat.node', () => ctx.slots.register(\n { name: 'conversation.chat.node', key: '<one key the owner dispatches>' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2348
- source: "packages/client/ui-chat/src/client/contract/slots.ts:190"
2361
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:196"
2349
2362
  },
2350
2363
  {
2351
2364
  key: "conversation.chat.turnTail",
@@ -2382,7 +2395,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2382
2395
  occupants: ["client-ui-deliverables ProducedFiles"],
2383
2396
  replaceRisk: "none",
2384
2397
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.chat.turnTail', () => ctx.slots.register(\n { name: 'conversation.chat.turnTail', select: owner => null },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2385
- source: "packages/client/ui-chat/src/client/contract/slots.ts:215"
2398
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:221"
2386
2399
  },
2387
2400
  {
2388
2401
  key: "conversation.composer",
@@ -2427,7 +2440,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2427
2440
  ],
2428
2441
  replaceRisk: "none",
2429
2442
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.composer', () => ctx.slots.register(\n { name: 'conversation.composer', select: owner => null },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2430
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:119"
2443
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:145"
2431
2444
  },
2432
2445
  {
2433
2446
  key: "conversation.composer.bar",
@@ -2457,7 +2470,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2457
2470
  occupants: ["client-ui-conversation InputBar"],
2458
2471
  replaceRisk: "shadows-shipped-ui",
2459
2472
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.composer.bar', () => ctx.slots.register(\n { name: 'conversation.composer.bar' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2460
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:137"
2473
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:163"
2461
2474
  },
2462
2475
  {
2463
2476
  key: "conversation.composer.dock",
@@ -2508,7 +2521,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2508
2521
  occupants: ["client-ui-chat StatsLine id 'stats'"],
2509
2522
  replaceRisk: "none",
2510
2523
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.composer.dock', () => ctx.slots.register(\n { name: 'conversation.composer.dock', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2511
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:131"
2524
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:157"
2512
2525
  },
2513
2526
  {
2514
2527
  key: "conversation.details.tool",
@@ -2540,7 +2553,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2540
2553
  occupants: ["client-ui-tool ToolDetails"],
2541
2554
  replaceRisk: "shadows-shipped-ui",
2542
2555
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.details.tool', () => ctx.slots.register(\n { name: 'conversation.details.tool' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2543
- source: "packages/client/ui-chat/src/client/contract/slots.ts:227"
2556
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:233"
2544
2557
  },
2545
2558
  {
2546
2559
  key: "conversation.hero.agentPreset",
@@ -2564,7 +2577,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2564
2577
  occupants: ["client-ui-agent-preset AgentPresetSeat"],
2565
2578
  replaceRisk: "shadows-shipped-ui",
2566
2579
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.hero.agentPreset', () => ctx.slots.register(\n { name: 'conversation.hero.agentPreset' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2567
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:125"
2580
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:151"
2568
2581
  },
2569
2582
  {
2570
2583
  key: "conversation.hero.brand.mark",
@@ -2588,7 +2601,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2588
2601
  occupants: [],
2589
2602
  replaceRisk: "none",
2590
2603
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.hero.brand.mark', () => ctx.slots.register(\n { name: 'conversation.hero.brand.mark' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2591
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:123"
2604
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:149"
2592
2605
  },
2593
2606
  {
2594
2607
  key: "conversation.hero.workspace",
@@ -2612,7 +2625,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2612
2625
  occupants: ["client-ui-workspace WorkspacePicker"],
2613
2626
  replaceRisk: "shadows-shipped-ui",
2614
2627
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.hero.workspace', () => ctx.slots.register(\n { name: 'conversation.hero.workspace' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2615
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:121"
2628
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:147"
2616
2629
  },
2617
2630
  {
2618
2631
  key: "conversation.hero.workspace.directoryFlow",
@@ -2642,11 +2655,15 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2642
2655
  key: "conversation.input.attachments",
2643
2656
  kind: "single",
2644
2657
  scope: "session-maybe",
2645
- summary: "Optional draft-image rail and drop target.",
2646
- doc: "Optional draft-image rail and drop target.",
2658
+ summary: "Optional draft-attachment rail and drop target.",
2659
+ doc: "Optional draft-attachment rail and drop target.",
2647
2660
  registerOptions: [],
2648
- ownerProps: ["/** Input state handed to the optional attachment presentation plugin. */\nexport interface ComposerAttachmentsOwnerProps {\n /** Browser-owned draft images in input order. */\n attachments: readonly ComposerAttachment[]\n /** Whether a document-level file drop may add images now. */\n canAcceptDrop: boolean\n /** Add one dropped batch through the composer's validation path. */\n onAddImages: (files: readonly File[]) => void\n /** Remove one draft image through the Conversation service. */\n onRemoveImage: (id: DraftAttachmentId) => void\n /** Display-ready limits for the drop invitation. */\n dropLimits?: { readonly count: number; readonly size: string } | undefined\n}"],
2649
- ownerPropsReferences: ["ComposerAttachment", "DraftAttachmentId"],
2661
+ ownerProps: ["/** Input state handed to the optional attachment presentation plugin. */\nexport interface ComposerAttachmentsOwnerProps {\n /** Browser-owned draft attachments in input order. */\n attachments: readonly ComposerAttachment[]\n /** Whether a document-level file drop may add attachments now. */\n canAcceptDrop: boolean\n /** Add one dropped batch through the composer's validation path. */\n onAddFiles: (files: readonly File[]) => void\n /** Remove one draft attachment through the Conversation service. */\n onRemoveAttachment: (id: DraftAttachmentId) => void\n /** Current per-draft upload states for file-kind attachments. */\n uploads: DraftFileUploads\n /** Restart one failed file upload. */\n onRetryFile: (id: DraftAttachmentId) => void\n /** Display-ready limits for the drop invitation. */\n dropLimits?: { readonly count: number; readonly size: string } | undefined\n}"],
2662
+ ownerPropsReferences: [
2663
+ "ComposerAttachment",
2664
+ "DraftAttachmentId",
2665
+ "DraftFileUploads"
2666
+ ],
2650
2667
  standardProps: [
2651
2668
  "useWorkspaces: SnapshotSelectorHook<WorkspaceSnapshot>",
2652
2669
  "useSessions: UseSessions",
@@ -2666,7 +2683,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2666
2683
  occupants: ["client-ui-attachment ComposerAttachments"],
2667
2684
  replaceRisk: "shadows-shipped-ui",
2668
2685
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.attachments', () => ctx.slots.register(\n { name: 'conversation.input.attachments' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2669
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:139"
2686
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:165"
2670
2687
  },
2671
2688
  {
2672
2689
  key: "conversation.input.dock",
@@ -2721,7 +2738,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2721
2738
  ],
2722
2739
  replaceRisk: "none",
2723
2740
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register(\n { name: 'conversation.input.dock', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2724
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:127"
2741
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:153"
2725
2742
  },
2726
2743
  {
2727
2744
  key: "conversation.input.left",
@@ -2772,7 +2789,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2772
2789
  occupants: [],
2773
2790
  replaceRisk: "none",
2774
2791
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.left', () => ctx.slots.register(\n { name: 'conversation.input.left', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2775
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:133"
2792
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:159"
2776
2793
  },
2777
2794
  {
2778
2795
  key: "conversation.input.model",
@@ -2804,7 +2821,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2804
2821
  occupants: ["client-ui-model-selection ModelSelect"],
2805
2822
  replaceRisk: "shadows-shipped-ui",
2806
2823
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.model', () => ctx.slots.register(\n { name: 'conversation.input.model' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2807
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:147"
2824
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:173"
2808
2825
  },
2809
2826
  {
2810
2827
  key: "conversation.input.overlay",
@@ -2855,7 +2872,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2855
2872
  occupants: ["client-ui-commands PopupSelectView id 'command-popup'", "client-ui-input-trigger MenuView id 'slash-menu'"],
2856
2873
  replaceRisk: "none",
2857
2874
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.overlay', () => ctx.slots.register(\n { name: 'conversation.input.overlay', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2858
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:129"
2875
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:155"
2859
2876
  },
2860
2877
  {
2861
2878
  key: "conversation.input.plan",
@@ -2887,7 +2904,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2887
2904
  occupants: ["client-ui-plan PlanChip"],
2888
2905
  replaceRisk: "shadows-shipped-ui",
2889
2906
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.plan', () => ctx.slots.register(\n { name: 'conversation.input.plan' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2890
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:145"
2907
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:171"
2891
2908
  },
2892
2909
  {
2893
2910
  key: "conversation.input.right",
@@ -2938,7 +2955,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2938
2955
  occupants: [],
2939
2956
  replaceRisk: "none",
2940
2957
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register(\n { name: 'conversation.input.right', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2941
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:135"
2958
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:161"
2942
2959
  },
2943
2960
  {
2944
2961
  key: "conversation.message.images",
@@ -2947,7 +2964,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2947
2964
  summary: "Renderer for one consecutive group of durable message images.",
2948
2965
  doc: "Renderer for one consecutive group of durable message images. The owner\nsupplies image references, an authorized loader, and alignment. A\nregistration replaces the shipped gallery; without one, images are omitted.",
2949
2966
  registerOptions: [],
2950
- ownerProps: ["/** Message image group handed to the optional attachment presentation plugin. */\nexport interface MessageImagesOwnerProps {\n /** Durable references or submission-echo previews in source order. */\n images: readonly MessageImageSource[]\n /** Session-authorized image URL loader for the durable arm. */\n loadImage: MessageImageLoader\n /** Horizontal placement inside the owning record. */\n align: 'start' | 'end'\n}"],
2967
+ ownerProps: ["/** Message image group handed to the optional attachment presentation plugin. */\nexport interface MessageImagesOwnerProps {\n /** Durable references or submission-echo previews in source order. */\n images: readonly MessageImageSource[]\n /** Session-authorized image URL loader for the durable arm. */\n loadImage: MessageImageLoader\n /** Horizontal placement inside the owning record. */\n align: 'start' | 'end'\n /** Force every image into the compact message-attachment tile size. */\n compact?: boolean\n}"],
2951
2968
  ownerPropsReferences: [
2952
2969
  "Message",
2953
2970
  "MessageImageLoader",
@@ -2974,7 +2991,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
2974
2991
  occupants: ["client-ui-attachment MessageImages"],
2975
2992
  replaceRisk: "shadows-shipped-ui",
2976
2993
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.message.images', () => ctx.slots.register(\n { name: 'conversation.message.images' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
2977
- source: "packages/client/ui-chat/src/client/contract/slots.ts:203"
2994
+ source: "packages/client/ui-chat/src/client/contract/slots.ts:209"
2978
2995
  },
2979
2996
  {
2980
2997
  key: "conversation.session",
@@ -3006,7 +3023,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3006
3023
  occupants: ["client-ui-conversation ConversationSession"],
3007
3024
  replaceRisk: "shadows-shipped-ui",
3008
3025
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.session', () => ctx.slots.register(\n { name: 'conversation.session' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3009
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:95"
3026
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:121"
3010
3027
  },
3011
3028
  {
3012
3029
  key: "conversation.session.header",
@@ -3038,7 +3055,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3038
3055
  occupants: ["client-ui-conversation ConversationSessionHeader"],
3039
3056
  replaceRisk: "shadows-shipped-ui",
3040
3057
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.session.header', () => ctx.slots.register(\n { name: 'conversation.session.header' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3041
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:97"
3058
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:123"
3042
3059
  },
3043
3060
  {
3044
3061
  key: "conversation.session.header.actions",
@@ -3094,7 +3111,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3094
3111
  ],
3095
3112
  replaceRisk: "none",
3096
3113
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.session.header.actions', () => ctx.slots.register(\n { name: 'conversation.session.header.actions', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3097
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:105"
3114
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:131"
3098
3115
  },
3099
3116
  {
3100
3117
  key: "conversation.session.header.lineage",
@@ -3126,7 +3143,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3126
3143
  occupants: ["client-ui-subagent SubagentHeaderLineage"],
3127
3144
  replaceRisk: "shadows-shipped-ui",
3128
3145
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.session.header.lineage', () => ctx.slots.register(\n { name: 'conversation.session.header.lineage' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3129
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:99"
3146
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:125"
3130
3147
  },
3131
3148
  {
3132
3149
  key: "conversation.session.header.utilities",
@@ -3174,10 +3191,10 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3174
3191
  hookContext: "",
3175
3192
  slotInject: "",
3176
3193
  declaredBy: "an entry in 'conversation.session.header' (client-ui-conversation), so it exists while that entry is mounted",
3177
- occupants: ["session-log-export SessionLogDownloadHeaderAction id 'session-log-download'"],
3194
+ occupants: ["client-ui-open-in-app OpenInAppAction id 'open-in-app'", "session-log-export SessionLogDownloadHeaderAction id 'session-log-download'"],
3178
3195
  replaceRisk: "none",
3179
3196
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.session.header.utilities', () => ctx.slots.register(\n { name: 'conversation.session.header.utilities', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3180
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:111"
3197
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:137"
3181
3198
  },
3182
3199
  {
3183
3200
  key: "conversation.trajectory.images",
@@ -3186,7 +3203,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3186
3203
  summary: "Renderer for one group of durable record images in the Trajectory ledger.",
3187
3204
  doc: "Renderer for one group of durable record images in the Trajectory\nledger. The owner supplies image references, an authorized loader, and\nalignment. A registration replaces the shipped gallery; without one,\nimages are omitted.",
3188
3205
  registerOptions: [],
3189
- ownerProps: ["/** Message image group handed to the optional attachment presentation plugin. */\nexport interface MessageImagesOwnerProps {\n /** Durable references or submission-echo previews in source order. */\n images: readonly MessageImageSource[]\n /** Session-authorized image URL loader for the durable arm. */\n loadImage: MessageImageLoader\n /** Horizontal placement inside the owning record. */\n align: 'start' | 'end'\n}"],
3206
+ ownerProps: ["/** Message image group handed to the optional attachment presentation plugin. */\nexport interface MessageImagesOwnerProps {\n /** Durable references or submission-echo previews in source order. */\n images: readonly MessageImageSource[]\n /** Session-authorized image URL loader for the durable arm. */\n loadImage: MessageImageLoader\n /** Horizontal placement inside the owning record. */\n align: 'start' | 'end'\n /** Force every image into the compact message-attachment tile size. */\n compact?: boolean\n}"],
3190
3207
  ownerPropsReferences: [
3191
3208
  "Message",
3192
3209
  "MessageImageLoader",
@@ -3264,7 +3281,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3264
3281
  occupants: ["client-ui-chat ChatView id 'chat'", "client-ui-trajectory TrajectoryView id 'trajectory'"],
3265
3282
  replaceRisk: "none",
3266
3283
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('conversation.view', () => ctx.slots.register(\n { name: 'conversation.view', id: 'my-entry', order: 100, label: 'My entry' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3267
- source: "packages/client/ui-conversation/src/client/contract/slots.ts:117"
3284
+ source: "packages/client/ui-conversation/src/client/contract/slots.ts:143"
3268
3285
  },
3269
3286
  {
3270
3287
  key: "details",
@@ -3957,6 +3974,38 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3957
3974
  example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('sidebar.workspaces.directoryFlow', () => ctx.slots.register(\n { name: 'sidebar.workspaces.directoryFlow' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
3958
3975
  source: "packages/client/ui-workspace/src/client/contract/slots.ts:59"
3959
3976
  },
3977
+ {
3978
+ key: "tool.call.images",
3979
+ kind: "single",
3980
+ scope: "session",
3981
+ summary: "Durable images of a settled image-bearing Tool call, rendered through the attachment presentation plugin.",
3982
+ doc: "Durable images of a settled image-bearing Tool call, rendered through\nthe attachment presentation plugin. The Tool layer never imports an\nattachment implementation: a toolview declares this slot as a child and\nrenders it with the image card's references plus the session-authorized\nloader it received in its owner, and the attachment plugin fills the\ngallery. Composing no attachment presentation plugin renders nothing,\nwhich is why the image card keeps its own envelope text beside the\ngallery. A child slot is declared by exactly one entry: registering a\nsecond toolview that declares the same child throws at load, so a\nfuture image-bearing tool must reuse this entry or own a distinct\nslot.",
3983
+ registerOptions: [],
3984
+ ownerProps: ["/** Owner currency of the Tool image gallery slot: references plus the loader. */\nexport interface ToolImagesOwnerProps {\n /** Durable references or submission-echo previews in result order. */\n images: readonly MessageImageSource[]\n /** Session-authorized image URL loader for the durable arm. */\n loadImage: MessageImageLoader\n /** Horizontal placement inside the owning record. */\n align: 'start' | 'end'\n}"],
3985
+ ownerPropsReferences: ["MessageImageLoader", "MessageImageSource"],
3986
+ standardProps: [
3987
+ "useWorkspaces: SnapshotSelectorHook<WorkspaceSnapshot>",
3988
+ "useSessions: UseSessions",
3989
+ "useSessionPendingInteraction: UseSessionPendingInteraction",
3990
+ "useWorkspaces: SnapshotSelectorHook<WorkspaceSnapshot>",
3991
+ "useChat: UseChat",
3992
+ "useConversation: UseConversation",
3993
+ "useInput: SnapshotSelectorHook<InputState>",
3994
+ "inputActions: InputActions",
3995
+ "useSession: SessionSnapshotSelector",
3996
+ "sessionId: SessionId",
3997
+ "useProjection: UseProjection",
3998
+ "useTrajectory: UseTrajectory"
3999
+ ],
4000
+ keyDomain: "",
4001
+ hookContext: "",
4002
+ slotInject: "",
4003
+ declaredBy: "an entry in 'tool.call.toolview' (client-ui-tool), so it exists while that entry is mounted",
4004
+ occupants: ["client-ui-attachment MessageImages"],
4005
+ replaceRisk: "shadows-shipped-ui",
4006
+ example: "return {\n inject: ['slots'],\n apply(ctx) {\n ctx.slots.inject('tool.call.images', () => ctx.slots.register(\n { name: 'tool.call.images' },\n () => React.createElement('div', null, 'hello'),\n ))\n },\n}",
4007
+ source: "packages/client/ui-tool/src/client/contract/slots.ts:40"
4008
+ },
3960
4009
  {
3961
4010
  key: "tool.call.toolview",
3962
4011
  kind: "keyed",
@@ -3969,8 +4018,8 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3969
4018
  type: "string",
3970
4019
  doc: "Your cell key: the entry renders where the owner dispatches this exact key. Registering an already-occupied key replaces that occupant."
3971
4020
  }],
3972
- ownerProps: ["/** Standard owner currency supplied to every atomic Tool view. */\nexport interface ToolCallOwnerProps {\n /** Tool call identity, stable across running and settled forms. */\n callId: string\n /** Wire Tool name and keyed dispatch value. */\n toolName: string\n /** Frozen running call or settled result node. */\n block: ToolCallBlock\n /** Session workspace root for relative summaries. */\n cwd?: string | undefined\n /** Host account home; POSIX home-rooted summaries display as `~`. */\n home?: string | undefined\n /** Open a Tool argument path through the Host. */\n openFile: (path: string) => void\n /** Inspect this call in the trajectory view when available. */\n inspect?: (() => void) | undefined\n}"],
3973
- ownerPropsReferences: [],
4021
+ ownerProps: ["/** Standard owner currency supplied to every atomic Tool view. */\nexport interface ToolCallOwnerProps {\n /** Tool call identity, stable across running and settled forms. */\n callId: string\n /** Wire Tool name and keyed dispatch value. */\n toolName: string\n /** Frozen running call or settled result node. */\n block: ToolCallBlock\n /** Session workspace root for relative summaries. */\n cwd?: string | undefined\n /** Host account home; POSIX home-rooted summaries display as `~`. */\n home?: string | undefined\n /** Open a Tool argument path through the Host. */\n openFile: (path: string) => void\n /**\n * Session-authorized image loader for the `tool.call.images` slot, supplied\n * by the chat node that owns this call. A composed chat node always\n * supplies it (`ChatNodeOwnerProps.loadImage` is required), so the tool\n * layer never imports an attachment implementation nor handles URL\n * authorization.\n */\n loadImage: MessageImageLoader\n /** Inspect this call in the trajectory view when available. */\n inspect?: (() => void) | undefined\n}"],
4022
+ ownerPropsReferences: ["ChatNodeOwnerProps", "MessageImageLoader"],
3974
4023
  standardProps: [
3975
4024
  "useWorkspaces: SnapshotSelectorHook<WorkspaceSnapshot>",
3976
4025
  "useSessions: UseSessions",
@@ -3985,7 +4034,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3985
4034
  "useProjection: UseProjection",
3986
4035
  "useTrajectory: UseTrajectory"
3987
4036
  ],
3988
- keyDomain: "open: any string the owner dispatches (no compile-time key set), already taken: ask_user_question, bash, cordis_define, cordis_run, cordis_stop, cordis_undefine, edit, glob, grep, read, skill, todo_write, web_fetch, web_search, write",
4037
+ keyDomain: "open: any string the owner dispatches (no compile-time key set), already taken: ask_user_question, bash, cordis_define, cordis_run, cordis_stop, cordis_undefine, edit, glob, grep, read, read_image, skill, todo_write, web_fetch, web_search, write",
3989
4038
  hookContext: "",
3990
4039
  slotInject: "",
3991
4040
  declaredBy: "an entry in 'conversation.chat.node' (client-ui-tool), so it exists while that entry is mounted",
@@ -3995,6 +4044,7 @@ call: (method, args = null) => env.invoke(method, args) }, harnessTrap(), ...Obj
3995
4044
  "client-ui-tool BashRow key 'bash'",
3996
4045
  "client-ui-tool FileMutationRow key 'edit'",
3997
4046
  "client-ui-tool FileMutationRow key 'write'",
4047
+ "client-ui-tool ReadImageRow key 'read_image'",
3998
4048
  "client-ui-tool ReadRow key 'read'",
3999
4049
  "client-ui-tool SearchRow key 'grep'",
4000
4050
  "client-ui-tool SearchRow key 'glob'",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-cordis-client-runner",
3
3
  "description": "Browser half of dynamic dual-half plugin packages: event subscription, closure evaluation, guard facade, and loader entries",
4
- "version": "0.1.2-alpha.5",
4
+ "version": "0.1.3-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -43,13 +43,13 @@
43
43
  "devDependencies": {
44
44
  "@types/react": "~18.3.1",
45
45
  "react": "^18.2.0",
46
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
47
- "@deepseek-ai/dsh-client-modules": "^0.1.2-alpha.5",
48
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-alpha.5",
49
- "@deepseek-ai/dsh-client-ui-theme": "^0.1.2-alpha.5",
50
- "@deepseek-ai/dsh-util-values": "^0.1.2-alpha.5",
51
- "@deepseek-ai/dsh-api-remotes": "^0.1.2-alpha.5",
52
- "@deepseek-ai/cordis": "^4.0.2"
46
+ "@deepseek-ai/dsh-client-modules": "^0.1.3-alpha.2",
47
+ "@deepseek-ai/dsh-api-remotes": "^0.1.3-alpha.2",
48
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.3-alpha.2",
49
+ "@deepseek-ai/dsh-client-ui-theme": "^0.1.3-alpha.2",
50
+ "@deepseek-ai/cordis": "^4.0.2",
51
+ "@deepseek-ai/dsh-util-values": "^0.1.3-alpha.2",
52
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.3"
53
53
  },
54
54
  "files": [
55
55
  "lib/index.js",