mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
fix(client): align domain split with repository gates
This commit is contained in:
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-07-19-gui-web-client-architecture.md
|
||||
2026-07-19-gui-web-client-architecture.md: 8b4f940299cbba78d403c34b1e5fc9740e44f2c2
|
||||
2026-07-19-gui-web-client-architecture.zh.md: 705b1337dd97ac37bd01bdcc5aa22484b7971908
|
||||
2026-07-19-gui-web-client-architecture.md: 4448fd5c6871d67b30b71cfe4377682639704235
|
||||
2026-07-19-gui-web-client-architecture.zh.md: e8a8121a1a495db7f5392e288f3bcada92c70495
|
||||
|
||||
@@ -48,7 +48,7 @@ There is no component registration model besides slots — the former view and t
|
||||
|
||||
**Scope addressing** mirrors the host's agent-scope idiom: services are root singletons whose methods take no sessionId — they read the caller's scope mark (`scopeOf(ctx)`). Inside a session scope, `ctx.conversation.send('hi', 'queue')` targets that session; cross-session calls re-target by switching ctx (`ctx.sessions.scope(id)!.conversation.send(...)`); calling a scoped method from root ctx throws. Client session scopes are minted like host agent scopes (a no-op plugin fiber + a scope-key extend), built lazily on first viewing and torn down only when the session is removed and unwatched — host-session death alone does not tear a scope (it freezes into a read-only viewport).
|
||||
|
||||
## The data object layer (`packages/client/runtime/src/client/sessions/`)
|
||||
## The data object layer (`packages/api/session-controller/src/client/`)
|
||||
|
||||
Frames enter, snapshots exit, the Conversation assembler sits between — React-free (zero React imports, grep-assertable):
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ slot 之外不存在第二种组件注册模型——原视图环与工具环都
|
||||
|
||||
**scope 寻址**与 host 侧 agent(智能体)scope 惯例同构:服务是 root 单例,方法不收 sessionId——它们读调用方 ctx 上的 scope 标(`scopeOf(ctx)`)。在会话 scope 内,`ctx.conversation.send('hi', 'queue')` 自动打到该会话;跨会话调用换 ctx 定向(`ctx.sessions.scope(id)!.conversation.send(...)`);从 root ctx 直接调 scoped 方法即 throw。client 会话 scope 的铸造方式与 host agent scope 相同(no-op 插件 fiber + scope 键 extend),首次观看时惰性建,只有会话被移除且无人观看才拆——仅 host 会话死亡不拆 scope(冻结为只读视窗)。
|
||||
|
||||
## 数据对象层(`packages/client/runtime/src/client/sessions/`)
|
||||
## 数据对象层(`packages/api/session-controller/src/client/`)
|
||||
|
||||
帧从这里进、快照从这里出、Conversation assembler 坐在中间——React-free(零 React import,grep 可断言):
|
||||
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-08-client-tool-presentation-ownership.md
|
||||
2026-08-08-client-tool-presentation-ownership.md: 3feefc3cfbe538024b8610394b9f170c423556e8
|
||||
2026-08-08-client-tool-presentation-ownership.zh.md: 181c57a0da61795292d70b3d37ebd1485832795b
|
||||
2026-08-08-client-tool-presentation-ownership.md: 1daad1559a6c8ef15fadb8e7c8dfeb2874ae3f9a
|
||||
2026-08-08-client-tool-presentation-ownership.zh.md: f980db28e1174aa95b29defb8b0a36fc0ba4cf2e
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Tool is a first-class Client UI presentation concept. `@deepseek-ai/dsh-client-u
|
||||
|
||||
Conversation data assembly follows the later [Conversation business-node decision](2026-08-09-client-conversation-node-assembly.md). The `ui-conversation` Tool Definition pairs root call/result Session Events, folds Code Dispatch edges into recursive `ToolCallBlock.subCalls`, and emits one stable `tool-call` Chat Node. This data responsibility handles only official Tool identity and topology; it does not interpret presentation for concrete Tool names.
|
||||
|
||||
[`ChatView`](../../../../packages/client/ui-conversation/src/client/chat/ChatView.tsx) only places generic [`ChatNodeSeat`](../../../../packages/client/ui-conversation/src/client/chat/ChatNodeSeat.tsx) entries in Chat snapshot `order`. A Seat dispatches `'conversation.chat.node'` by `node.kind`; [`ui-tool`](../../../../packages/client/ui-tool/src/client/apply.ts) registers the `tool-call` entry, and [`ToolCallTree`](../../../../packages/client/ui-tool/src/client/tool/ToolCallTree.tsx) recursively traverses the root block. Every root or child level dispatches through the same keyed/session `'tool.call.toolview'` child slot with `entryKey: toolName`, falling back to `GenericToolCard` when no registration exists.
|
||||
[`ChatView`](../../../../packages/client/ui-chat/src/client/chat/ChatView.tsx) only places generic [`ChatNodeSeat`](../../../../packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx) entries in Chat snapshot `order`. A Seat dispatches `'conversation.chat.node'` by `node.kind`; [`ui-tool`](../../../../packages/client/ui-tool/src/client/apply.ts) registers the `tool-call` entry, and [`ToolCallTree`](../../../../packages/client/ui-tool/src/client/tool/ToolCallTree.tsx) recursively traverses the root block. Every root or child level dispatches through the same keyed/session `'tool.call.toolview'` child slot with `entryKey: toolName`, falling back to `GenericToolCard` when no registration exists.
|
||||
|
||||
A business Tool plugin receives one standard `ToolCallBlock`, identity, workspace cwd, and host actions; it does not read Session, Context, or the Conversation assembler. Skill remains an ordinary Tool and uses the same keyed-slot registration path as other business Tools.
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ Client 运行时已经按 `callId` 配对工具调用/结果事件,并能从 C
|
||||
|
||||
Conversation 数据组装遵循后续的 [Conversation 业务节点决策](2026-08-09-client-conversation-node-assembly.zh.md)。`ui-conversation` 的工具 Definition 从会话事件配对 root call/result,把 Code Dispatch edge fold 成递归 `ToolCallBlock.subCalls`,并生成一个稳定的 `tool-call` Chat Node;这里的数据职责只处理官方工具 identity 和拓扑,不解释具体工具名称的展示。
|
||||
|
||||
[`ChatView`](../../../../packages/client/ui-conversation/src/client/chat/ChatView.tsx) 只按 Chat 快照的 `order` 放置通用 [`ChatNodeSeat`](../../../../packages/client/ui-conversation/src/client/chat/ChatNodeSeat.tsx)。Seat 以 `node.kind` 分发 `'conversation.chat.node'`;[`ui-tool`](../../../../packages/client/ui-tool/src/client/apply.ts) 注册 `tool-call` entry,并由 [`ToolCallTree`](../../../../packages/client/ui-tool/src/client/tool/ToolCallTree.tsx) 递归遍历 root block。每一层 root 或 child 都通过同一个 keyed/session `'tool.call.toolview'` 子 slot 以 `entryKey: toolName` 分发,缺少注册时渲染 `GenericToolCard`。
|
||||
[`ChatView`](../../../../packages/client/ui-chat/src/client/chat/ChatView.tsx) 只按 Chat 快照的 `order` 放置通用 [`ChatNodeSeat`](../../../../packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx)。Seat 以 `node.kind` 分发 `'conversation.chat.node'`;[`ui-tool`](../../../../packages/client/ui-tool/src/client/apply.ts) 注册 `tool-call` entry,并由 [`ToolCallTree`](../../../../packages/client/ui-tool/src/client/tool/ToolCallTree.tsx) 递归遍历 root block。每一层 root 或 child 都通过同一个 keyed/session `'tool.call.toolview'` 子 slot 以 `entryKey: toolName` 分发,缺少注册时渲染 `GenericToolCard`。
|
||||
|
||||
业务工具插件接收一个标准 `ToolCallBlock`、identity、workspace cwd 和宿主动作,不读取会话、上下文或 Conversation assembler。skill(技能)仍是普通工具;它和其他业务工具使用同一 keyed slot 注册路径。
|
||||
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-09-client-conversation-node-assembly.md
|
||||
2026-08-09-client-conversation-node-assembly.md: 69f92b906e46ae881b7aa6b5e46e998047fca8c2
|
||||
2026-08-09-client-conversation-node-assembly.zh.md: d075e009d9a04f20dbc8dda518e90b368b54286f
|
||||
2026-08-09-client-conversation-node-assembly.md: e6c0e790a361265870a04ee63301b9f11940c648
|
||||
2026-08-09-client-conversation-node-assembly.zh.md: 702ddba0019e125d3976727f841db775276b3b77
|
||||
|
||||
+6
-6
@@ -33,7 +33,7 @@ Registry contributions are Cordis effects. Removing a Definition causes a low-fr
|
||||
|
||||
### Overall `ConversationNodeDefinition` contract
|
||||
|
||||
Each [`ConversationNodeDefinition`](../../../../packages/client/runtime/src/client/contract/conversation.ts) independently owns one business object's conversion from Events to State and final view Nodes. A Definition's `kind` is its unique Registry name and the namespace for its business IDs.
|
||||
Each [`ConversationNodeDefinition`](../../../../packages/client/ui-conversation/src/client/contract/conversation.ts) independently owns one business object's conversion from Events to State and final view Nodes. A Definition's `kind` is its unique Registry name and the namespace for its business IDs.
|
||||
|
||||
One Event may be claimed by several ordinary Definitions. For example, an Assistant Event updates both the Assistant Node and Turn Tail, while a Retry Event updates Retry, Assistant, and Turn Tail. The Assembler asks the fallback only when every ordinary Definition returns `null`.
|
||||
|
||||
@@ -160,7 +160,7 @@ IDs are never reused. Completed Contexts remain in the current window, providing
|
||||
|
||||
### Location is a first-class engine fact
|
||||
|
||||
[`ConversationLocationIndex`](../../../../packages/client/runtime/src/client/sessions/conversation-location-index.ts) maps Events to Locations from `turn/start`, `step/start`, explicit turn and step payloads, `step/end`, and `turn/end`.
|
||||
[`ConversationLocationIndex`](../../../../packages/client/ui-conversation/src/client/conversation/location-index.ts) maps Events to Locations from `turn/start`, `step/start`, explicit turn and step payloads, `step/end`, and `turn/end`.
|
||||
|
||||
Location has four shapes: `session`, `turn`, `step`, and `unresolved`. Turns and Steps each carry `open`, `closed`, or `unknown` status plus any loaded start and end Events.
|
||||
|
||||
@@ -302,19 +302,19 @@ Unknown fallback demonstrates Registry ownership: it handles only append-surface
|
||||
|
||||
## View Builder and React identity
|
||||
|
||||
[`ConversationViewRegistry`](../../../../packages/client/runtime/src/client/conversation/view-registry.ts) creates an independent per-Session builder for each target. The Registry stores factories and shares no Session's ordering or caches.
|
||||
[`ConversationViewRegistry`](../../../../packages/client/ui-conversation/src/client/conversation/view-registry.ts) creates an independent per-Session builder for each target. The Registry stores factories and shares no Session's ordering or caches.
|
||||
|
||||
The Assembler calls `replace({ nodes, timeline })` on low-frequency complete replacements and `apply({ upserts, timeline })` for ordinary prepend/append flushes. Builders receive only final target Nodes already constructed by Definitions.
|
||||
|
||||
[`ChatSnapshotBuilder`](../../../../packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts) maintains `order`, a keyed `nodes` store, the turn/step `locations` index, `timeline`, and the `legacy` slice used by StatsLine and mirrored into top-level public compatibility fields.
|
||||
[`ChatSnapshotBuilder`](../../../../packages/client/ui-chat/src/client/conversation-nodes/chat-snapshot-builder.ts) maintains `order`, a keyed `nodes` store, the turn/step `locations` index, `timeline`, and the `legacy` slice used by StatsLine and mirrored into top-level public compatibility fields.
|
||||
|
||||
Only a new key or a change to `anchorSeq`, visibility, or Location identity makes a Chat update structural. An ordinary content change does not rebuild `order`; the keyed Node store replaces only that key's value.
|
||||
|
||||
For a structural change, the Builder computes visible order from current store values and reuses unchanged index arrays by reference. Prepend may add earlier history keys, append may add a key at the tail or its business anchor, and ordering never renames existing keys.
|
||||
|
||||
[`ChatView`](../../../../packages/client/ui-conversation/src/client/chat/ChatView.tsx) only traverses `order`. Each [`ChatNodeSeat`](../../../../packages/client/ui-conversation/src/client/chat/ChatNodeSeat.tsx) remains in the same parent list under its Context key and dispatches the `'conversation.chat.node'` keyed slot by `node.kind`.
|
||||
[`ChatView`](../../../../packages/client/ui-chat/src/client/chat/ChatView.tsx) only traverses `order`. Each [`ChatNodeSeat`](../../../../packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx) remains in the same parent list under its Context key and dispatches the `'conversation.chat.node'` keyed slot by `node.kind`.
|
||||
|
||||
[`ChatNodeDataMap`](../../../../packages/client/ui-conversation/src/client/contract/chat-nodes.ts) is a declaration-merged renderer payload registry. Each business module registers its own Definition and keyed renderer; `registerConversationNodes()` and `registerChatNodeRenderers()` only assemble those independent contributions and do not interpret business through a closed union or central switch. Built-ins still live in `ui-conversation`, but this type and registration boundary allows a business to move into an independent package without changing the Chat dispatcher.
|
||||
[`ChatNodeDataMap`](../../../../packages/client/ui-chat/src/client/contract/chat-nodes.ts) is a declaration-merged renderer payload registry. Each business module registers its own Definition and keyed renderer; `registerConversationNodes()` and `registerChatNodeRenderers()` only assemble those independent contributions and do not interpret business through a closed union or central switch. Built-ins live in `ui-chat`, and this type and registration boundary allows a business to move into an independent package without changing the Chat dispatcher.
|
||||
|
||||
The Chat entry in `conversation.view` registers `ChatNodeTurnDataInjected` once when it declares the `conversation.chat.node` child slot. `ChatNodeSeat` passes only the stable Node key as `hookContext`; the Slot renderer combines that key with `useSession` from the official standard props to construct `useTurnData(businessKey)`. Every keyed Chat renderer therefore reads strongly typed, read-only data from its own Node's Turn, and the Assistant renderer has no special injection authority.
|
||||
|
||||
|
||||
+6
-6
@@ -33,7 +33,7 @@ Registry 注册是 Cordis effect,Definition 卸载会触发现有 Session 的
|
||||
|
||||
### `ConversationNodeDefinition` 总体契约
|
||||
|
||||
每个 [`ConversationNodeDefinition`](../../../../packages/client/runtime/src/client/contract/conversation.ts) 独立拥有一种业务对象从 Event 到 State 和最终 view Node 的转换。Definition 的 `kind` 是 Registry 内唯一名称,也是业务 ID 的命名空间。
|
||||
每个 [`ConversationNodeDefinition`](../../../../packages/client/ui-conversation/src/client/contract/conversation.ts) 独立拥有一种业务对象从 Event 到 State 和最终 view Node 的转换。Definition 的 `kind` 是 Registry 内唯一名称,也是业务 ID 的命名空间。
|
||||
|
||||
同一个 Event 可以被多个普通 Definition 认领。例如一条 Assistant Event 同时更新 Assistant Node 和 Turn Tail;一条 Retry Event 同时更新 Retry、Assistant 和 Turn Tail。Assembler 只有在全部普通 Definition 都返回 `null` 时才询问 fallback。
|
||||
|
||||
@@ -160,7 +160,7 @@ ID 不复用,完成的 Context 继续存在于当前窗口,既提供稳定
|
||||
|
||||
### Location 是一级引擎事实
|
||||
|
||||
[`ConversationLocationIndex`](../../../../packages/client/runtime/src/client/sessions/conversation-location-index.ts) 根据 `turn/start`、`step/start`、显式 turn/step payload、`step/end` 和 `turn/end` 建立 Event 到 Location 的映射。
|
||||
[`ConversationLocationIndex`](../../../../packages/client/ui-conversation/src/client/conversation/location-index.ts) 根据 `turn/start`、`step/start`、显式 turn/step payload、`step/end` 和 `turn/end` 建立 Event 到 Location 的映射。
|
||||
|
||||
Location 有 `session`、`turn`、`step` 和 `unresolved` 四种形状。Turn/Step 各自带 `open`、`closed` 或 `unknown` 状态,以及已加载的 start/end Event。
|
||||
|
||||
@@ -302,19 +302,19 @@ Unknown fallback 展示了 Registry ownership:fallback 只处理没有任何
|
||||
|
||||
## View Builder 与 React identity
|
||||
|
||||
[`ConversationViewRegistry`](../../../../packages/client/runtime/src/client/conversation/view-registry.ts) 为每个 target 创建独立的 per-Session builder。Registry 保存 factory,不共享某个 Session 的排序或缓存。
|
||||
[`ConversationViewRegistry`](../../../../packages/client/ui-conversation/src/client/conversation/view-registry.ts) 为每个 target 创建独立的 per-Session builder。Registry 保存 factory,不共享某个 Session 的排序或缓存。
|
||||
|
||||
Assembler 低频完整替换时调用 `replace({ nodes, timeline })`;普通 prepend/append flush 调用 `apply({ upserts, timeline })`。Builder 只接收 Definition 已构造完成的 target Nodes。
|
||||
|
||||
[`ChatSnapshotBuilder`](../../../../packages/client/ui-conversation/src/client/conversation-nodes/chat-snapshot-builder.ts) 维护 `order`、keyed `nodes` store、turn/step `locations` index、`timeline`,以及由 StatsLine 使用并镜像到顶层公共兼容字段的 `legacy` slice。
|
||||
[`ChatSnapshotBuilder`](../../../../packages/client/ui-chat/src/client/conversation-nodes/chat-snapshot-builder.ts) 维护 `order`、keyed `nodes` store、turn/step `locations` index、`timeline`,以及由 StatsLine 使用并镜像到顶层公共兼容字段的 `legacy` slice。
|
||||
|
||||
Chat 结构变化只由新 key、`anchorSeq`、visibility 或 Location identity 变化触发。普通内容变化不重建 `order`;keyed Node store 只替换该 key 的 value。
|
||||
|
||||
Builder 遇到结构变化时从 store 的当前 values 计算 visible order,并按未变化引用复用索引数组。Prepend 可以增加前部历史 key,append 可以增加尾部或按业务 anchor 落位,既有 key 不因排序变化而重命名。
|
||||
|
||||
[`ChatView`](../../../../packages/client/ui-conversation/src/client/chat/ChatView.tsx) 只遍历 `order`。每个 [`ChatNodeSeat`](../../../../packages/client/ui-conversation/src/client/chat/ChatNodeSeat.tsx) 以 Context key 固定在同一个父列表中,并按 `node.kind` 分发 `'conversation.chat.node'` keyed slot。
|
||||
[`ChatView`](../../../../packages/client/ui-chat/src/client/chat/ChatView.tsx) 只遍历 `order`。每个 [`ChatNodeSeat`](../../../../packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx) 以 Context key 固定在同一个父列表中,并按 `node.kind` 分发 `'conversation.chat.node'` keyed slot。
|
||||
|
||||
[`ChatNodeDataMap`](../../../../packages/client/ui-conversation/src/client/contract/chat-nodes.ts) 是 declaration-merged 的 renderer payload registry。每个业务模块分别注册自己的 Definition 和 keyed renderer;`registerConversationNodes()` 与 `registerChatNodeRenderers()` 只负责装配这些独立贡献,不通过 closed union 或中心 switch 解释业务。内建实现仍位于 `ui-conversation`,但该类型和注册边界允许业务迁入独立 package 而不修改 Chat dispatcher。
|
||||
[`ChatNodeDataMap`](../../../../packages/client/ui-chat/src/client/contract/chat-nodes.ts) 是 declaration-merged 的 renderer payload registry。每个业务模块分别注册自己的 Definition 和 keyed renderer;`registerConversationNodes()` 与 `registerChatNodeRenderers()` 只负责装配这些独立贡献,不通过 closed union 或中心 switch 解释业务。内建实现位于 `ui-chat`,且该类型和注册边界允许业务迁入独立 package 而不修改 Chat dispatcher。
|
||||
|
||||
`conversation.view` 的 Chat entry 在声明 `conversation.chat.node` child slot 时统一注册 `ChatNodeTurnDataInjected`。`ChatNodeSeat` 只把稳定 Node key 作为 `hookContext` 传给 slot;Slot renderer 用官方 standard props 中的 `useSession` 和该 key 构造 `useTurnData(businessKey)`,因此每个 keyed Chat renderer 都能读取自己 Node 所属 Turn 的强类型只读 data,Assistant renderer 不拥有特殊注入权限。
|
||||
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-10-cancelled-stream-prefix-finalize.md
|
||||
2026-08-10-cancelled-stream-prefix-finalize.md: 0cae25b786922fba8204d68ca9c0a669e43d76a0
|
||||
2026-08-10-cancelled-stream-prefix-finalize.zh.md: e961ea6a51f74dcc244e4ad8970eae4cbe4c9a6c
|
||||
2026-08-10-cancelled-stream-prefix-finalize.md: fd397a02663908f5984b4e1798d1b1759b140c79
|
||||
2026-08-10-cancelled-stream-prefix-finalize.zh.md: 44adb2ff4163cd1904a9a93895c99519bae2f234
|
||||
|
||||
+1
-1
@@ -36,4 +36,4 @@ Terminal provider errors still discard their streamed prefix. That asymmetry rem
|
||||
|
||||
## Testing
|
||||
|
||||
`packages/core/agent-loop/tests/cancel.spec.ts` covers content, cited seqs, event order, next-request parity, reasoning-only output, tool-call omission, recovery cancellation, and the empty-prefix case. `packages/llm/llm/tests/assembler.spec.ts` covers `interruptedBlocks()`. `packages/client/ui-conversation/tests/conversation-node-definitions.client.spec.ts` and `packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts` cover both client projections. The keyless `cancel` ACP snapshot and `goal-round-driver` goal snapshot cover assembled applications.
|
||||
`packages/core/agent-loop/tests/cancel.spec.ts` covers content, cited seqs, event order, next-request parity, reasoning-only output, tool-call omission, recovery cancellation, and the empty-prefix case. `packages/llm/llm/tests/assembler.spec.ts` covers `interruptedBlocks()`. `packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts` and `packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts` cover both client projections. The keyless `cancel` ACP snapshot and `goal-round-driver` goal snapshot cover assembled applications.
|
||||
|
||||
+1
-1
@@ -36,4 +36,4 @@ Chat 和 Trajectory Conversation Definition 从持久消息读取 `interrupted`
|
||||
|
||||
## Testing
|
||||
|
||||
`packages/core/agent-loop/tests/cancel.spec.ts` 覆盖内容、引用的 seq、事件顺序、下一请求的一致性、仅 reasoning 的输出、工具调用省略、恢复期间的取消和空前缀情形。`packages/llm/llm/tests/assembler.spec.ts` 覆盖 `interruptedBlocks()`。`packages/client/ui-conversation/tests/conversation-node-definitions.client.spec.ts` 和 `packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts` 覆盖两种客户端投影。keyless 的 `cancel` ACP 快照和 `goal-round-driver` goal 快照覆盖完整应用。
|
||||
`packages/core/agent-loop/tests/cancel.spec.ts` 覆盖内容、引用的 seq、事件顺序、下一请求的一致性、仅 reasoning 的输出、工具调用省略、恢复期间的取消和空前缀情形。`packages/llm/llm/tests/assembler.spec.ts` 覆盖 `interruptedBlocks()`。`packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts` 和 `packages/client/ui-trajectory/tests/conversation-definitions.client.spec.ts` 覆盖两种客户端投影。keyless 的 `cancel` ACP 快照和 `goal-round-driver` goal 快照覆盖完整应用。
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.md
|
||||
2026-08-20-client-session-conversation-ownership.md: e7ab737c13721c41d9244c7830c74cf56ea33f54
|
||||
2026-08-20-client-session-conversation-ownership.zh.md: deeca51740cf07e15192744c027e7bc09369bdfa
|
||||
+461
@@ -0,0 +1,461 @@
|
||||
# Agent Note: Client Session, Conversation, and UI ownership layers
|
||||
|
||||
Status: implemented
|
||||
|
||||
English | [中文](2026-08-20-client-session-conversation-ownership.zh.md)
|
||||
|
||||
## Problem
|
||||
|
||||
The Web Client once placed Session and Workspace objects, event windows, Conversation assembly, React hooks, the Slot registry, and the Store engine in one general Runtime. Protocol state, business projections, React bindings, and page presentation shared one dependency hub, so a change in any layer could spread across the entire frontend.
|
||||
|
||||
Session snapshots could also accumulate data they did not own, including event arrays, Conversation Views, Chat Nodes, and pending interactions. Ordinary consumers then had to understand event replay and concrete views, while adding a Conversation target could require changes to Session, Runtime, and the renderer.
|
||||
|
||||
Without an explicit interface between React and Session lifetimes, binding release, Hook source replacement, and Slot store cleanup became dedicated callback protocols. Approval and Question both affect sidebar state and composer takeover; independently maintained state could make those surfaces select different pending requests.
|
||||
|
||||
The Client needs one-way dependencies between data owners, React adapters, generic rendering machinery, and concrete views while preserving application behavior.
|
||||
|
||||
## Decision
|
||||
|
||||
The Client uses the layering “Controller and domain object → UI adapter → renderer → Slot component.” Controllers and domain objects publish React-free observable sources; their `ui-*` packages declare standard props and register sources; `ui-renderer` creates selector hooks at Slot binding points; components read data and actions only from Slot props.
|
||||
|
||||
```text
|
||||
[Remote / Controller / domain object]
|
||||
|
|
||||
| bare observable source
|
||||
v
|
||||
[ui-* adapter]
|
||||
|
|
||||
| standard source registration
|
||||
v
|
||||
[ui-renderer]
|
||||
|
|
||||
| selector hook binding
|
||||
v
|
||||
[Slot component]
|
||||
```
|
||||
|
||||
Client Session and Workspace objects belong to `api/session-controller/client` and `api/workspace-controller/client`, respectively. Target-neutral Conversation data structures and assembly belong to `client/ui-conversation`; Chat and Trajectory belong to `client/ui-chat` and `client/ui-trajectory`, respectively.
|
||||
|
||||
The React adapters for Session and Workspace belong to `client/ui-session` and `client/ui-workspace`. The Store engine belongs to `client/store`; the Slot registry, scope materialization, and observable-to-hook binding belong to `client/ui-renderer`.
|
||||
|
||||
The system has no aggregate `client/runtime` package and no replacement central facade. [Session history and event transport](2026-08-18-session-history-and-event-transport.md) defines Session history, Remote streams, pagination cursors, and reconnect continuity; this note starts from the Client objects and sources published by Controllers.
|
||||
|
||||
## Layering principles
|
||||
|
||||
### Controllers are React-free logic owners
|
||||
|
||||
A Controller may be installed as a Cordis service, but it does not own React Contexts, React hooks, Slot props, or components. A Controller snapshot contains only facts that it owns, and its commands change only Host or domain-object state.
|
||||
|
||||
The UI layer may read multiple Controllers for one navigation decision, but it does not write the combined result back into any Controller snapshot. A UI adapter does not duplicate a Controller command's business implementation.
|
||||
|
||||
### UI adapters own React integration
|
||||
|
||||
Each standard hook belongs to the `ui-*` package closest to its data semantics.
|
||||
|
||||
| Hook | Owner | Source |
|
||||
| --- | --- | --- |
|
||||
| `useSessions` | `client/ui-session` | Session Controller global list |
|
||||
| `useSession` | `client/ui-session` | Current Session snapshot |
|
||||
| `useProjection` | `client/ui-session` | Current Session keyed projection |
|
||||
| `useSessionPendingInteraction` | `client/ui-session` | Aggregated pending domains |
|
||||
| `useWorkspaces` | `client/ui-workspace` | Workspace Controller list |
|
||||
| `useConversation` | `client/ui-conversation` | Conversation binding snapshot |
|
||||
| `useChat` | `client/ui-chat` | `chat` target source |
|
||||
| `useTrajectory` | `client/ui-trajectory` | `trajectory` target source |
|
||||
|
||||
`ui-renderer` implements only generic binding. It does not import Session, Workspace, Conversation, Chat, or Trajectory business types or values.
|
||||
|
||||
### Slot scopes and standard props are separate
|
||||
|
||||
`ui-slots` declares root, session, and session-maybe scopes plus declaration-merge-extensible standard prop types. It does not decide which hooks each scope installs.
|
||||
|
||||
`ui-renderer` implements generic scope adapters and source materialization. `ui-session` installs the Session scope and supplies its built-in sources; other domain packages register only their own sources and the Slot entries that consume them.
|
||||
|
||||
Adding a target does not add a branch to the renderer or Session Controller. The data owner handles state identity, updates, errors, and release; the UI adapter owns the hook; the presentation owner owns target-specific projections and interaction state.
|
||||
|
||||
## Package ownership
|
||||
|
||||
| Package | Owns | Explicitly does not own |
|
||||
| --- | --- | --- |
|
||||
| `api/session-controller/client` | Session objects, list, selection, commands, projections, queue, event windows, and Agent Contexts | Conversation targets, React, Slots, Workspace |
|
||||
| `api/workspace-controller/client` | Workspace objects, ordering, archive state, commands, and snapshots | React, Session navigation policy, directory UI |
|
||||
| `client/ui-session` | Session scope, standard sources, `SessionProvider`, and pending-interaction aggregation | Session transport, Conversation assembly, Approval/Question results |
|
||||
| `client/ui-workspace` | Workspace hook, browser UI, and cross-Controller navigation policy | Workspace transport, copies of Session data |
|
||||
| `client/ui-conversation` | Conversation core, registries, bindings, shell, input, composer, queue, and View navigation | Session transport, Chat/Trajectory snapshots |
|
||||
| `client/ui-chat` | Chat target, Node definitions, renderers, selection, details, locale, and historical images | Session lifecycle, generic View navigation, Trajectory |
|
||||
| `client/ui-trajectory` | Trajectory target, event-record projection, and inspection view | Session snapshots, Chat snapshots |
|
||||
| `client/ui-approval` | Pending Approval, Remote listener, composer, and approval UI | Session control, generic composer election |
|
||||
| `client/ui-user-questions` | Pending Question, Remote listener, composer, and question UI | Session control, generic composer election |
|
||||
| `client/store` | React-free Store contract and implementation | Domain objects, React hooks, Slot lifetimes |
|
||||
| `client/ui-renderer` | SlotRegistry, scope binding, selector hooks, outlets, and React root | Session, Workspace, and Conversation business logic |
|
||||
|
||||
## Overall data flow
|
||||
|
||||
Session data reaches the UI through this path:
|
||||
|
||||
```text
|
||||
[ctx.remote.session]
|
||||
|
|
||||
v
|
||||
[api/session-controller/client]
|
||||
|-- SessionListState --------------------------> [ui-session] -> useSessions
|
||||
|-- SessionSnapshot ----------------------------> [ui-session] -> useSession
|
||||
|-- ProjectionValueSource ----------------------> [ui-session] -> useProjection
|
||||
`-- per-Session SessionEventSource
|
||||
|
|
||||
v
|
||||
[client/ui-conversation]
|
||||
|
|
||||
| assemble
|
||||
v
|
||||
ConversationSnapshot ----------------> useConversation
|
||||
|
|
||||
|---------+----------|
|
||||
v v
|
||||
[ui-chat] [ui-trajectory]
|
||||
| |
|
||||
useChat useTrajectory
|
||||
```
|
||||
|
||||
Workspace data enters the Workspace Controller from `ctx.remote.workspace`, then `ui-workspace` exposes it as `useWorkspaces`. For cross-domain navigation, `ui-workspace` temporarily reads the Session Controller and issues a selection or command.
|
||||
|
||||
Approval and Question arrive from the Host waterfall through `ctx.remote.$on` at their respective UI owners. Each owner publishes a Pending object; `ui-session.pendingInteractions` then supplies that same object to Session navigation state and Conversation composer selection.
|
||||
|
||||
## Session Controller Client
|
||||
|
||||
### Scope of SessionSnapshot
|
||||
|
||||
`SessionSnapshot` represents control and lifecycle facts belonging to a Session. It may contain identity, running, removed, blank, subagent address, open phase, history phase, prompt error, agent error, and queue state.
|
||||
|
||||
It does not contain:
|
||||
|
||||
- a raw event array;
|
||||
- Conversation Views;
|
||||
- Chat Nodes;
|
||||
- Trajectory rows;
|
||||
- pending Approval or Question objects;
|
||||
- presentation state that requires callers to traverse events.
|
||||
|
||||
Whether a field derives from an event, control frame, or local command does not automatically determine its owner; consumption semantics determine ownership. `composerPhase` depends on both Session lifecycle and Conversation target activity, so `ui-conversation` composes it instead of placing it in `SessionSnapshot`.
|
||||
|
||||
### Three read faces
|
||||
|
||||
The Session Controller exposes three distinct read faces:
|
||||
|
||||
1. The global Session list and current-selection source, used by navigation and `useSessions`.
|
||||
2. A logical binding for each Session containing `sessionId`, a `SessionSnapshot` source, commands, and projection sources.
|
||||
3. A Conversation-facing `SessionEventSource` used only by the Conversation assembly core.
|
||||
|
||||
Ordinary UI components do not read `SessionEventSource` directly. `ui-session` does not read private event windows, and the `ui-conversation` core receives neither React bindings nor Slot APIs.
|
||||
|
||||
### SessionEventSource
|
||||
|
||||
`SessionEventSource` exposes a materialized event window, not a transport.
|
||||
|
||||
The window carries ordered `entries`, `hasMore`, a monotonic `revision`, and a `replace | prepend | append` change description.
|
||||
|
||||
Initial open, reconnect, gap repair, and updates whose continuity cannot be proven publish `replace`; history pagination publishes `prepend`; a continuous live event publishes `append`. The Conversation core selects incremental update or complete rebuild from the revision and change.
|
||||
|
||||
`MutableSessionEventSource` is the Session Controller's internal write face. Consumers depend only on the read-only `SessionEventSource`.
|
||||
|
||||
### Session binding lifecycle
|
||||
|
||||
Each Session binding owns a Cordis Context and Fiber. The Session Controller creates and releases the binding.
|
||||
|
||||
Objects that depend on a Session register cleanup through `binding.ctx.effect()`. Releasing a binding cleans up Conversation bindings, UI materializations, and scoped Slot stores without a dedicated `onBindingRelease` or `onRelease` callback protocol.
|
||||
|
||||
This cleanup does not require the Session Controller to know the roster of upper-layer consumers.
|
||||
|
||||
## UI Session
|
||||
|
||||
### Service responsibilities
|
||||
|
||||
`client/ui-session` is the sole Session adapter between the Session Controller and the React/Slot system. It provides `ctx.uiSession` and:
|
||||
|
||||
- observes the Session list, current selection, and per-Session bindings;
|
||||
- installs the session and session-maybe scope adapters;
|
||||
- supplies `SessionProvider` rendering semantics;
|
||||
- supplies built-in Session snapshot, projection, and sessionId sources;
|
||||
- accepts Session-scoped source contributions from other domain packages;
|
||||
- aggregates pending interactions registered by business packages.
|
||||
|
||||
It does not own Session transport, event folding, Conversation targets, or concrete business results.
|
||||
|
||||
### Standard source registration
|
||||
|
||||
A domain package calls `ctx.uiSession.provide()` to register a bare source. The descriptor statically declares its hook, keyed-hook, and prop rosters; `resolve(binding)` returns exactly those values for one Session binding. For example, `ui-conversation` registers each binding's snapshot as the `conversation` hook source.
|
||||
|
||||
The renderer converts an ordinary source into `use<Name>`. Open key spaces such as projections use a keyed-hook resolver, while stable values use props.
|
||||
|
||||
The runtime rejects undeclared, missing, or duplicate standard props. `ui-session` materializes its own built-ins through the same mechanism, so the renderer has no Session-specific name branches.
|
||||
|
||||
### Scope binding
|
||||
|
||||
session and session-maybe use the same adapter with different binding semantics:
|
||||
|
||||
- a strict session scope refuses to render without a current binding;
|
||||
- session-maybe uses a stable absent binding to preserve hook call order;
|
||||
- changing the current Session rebuilds the strict Session subtree under the `sessionId` key;
|
||||
- root and session-maybe entries may remain mounted across Session changes.
|
||||
|
||||
Each real materialized binding retains the Controller binding's Context. `ui-session` removes the cache entry and withdraws the current binding through `binding.ctx.effect()`.
|
||||
|
||||
Changing the contribution roster rematerializes existing bindings and publishes a new source set. Source identity remains stable within one binding lifetime, as required by `useSyncExternalStore` caching.
|
||||
|
||||
### SessionProvider
|
||||
|
||||
`SessionProvider` is a standard seat derived by `PropsRenderSlots` from a session-scoped child declaration, not a React Context imported directly by business components.
|
||||
|
||||
It accepts ordinary `ReactNode` children rather than a `(sessionId) => ReactNode` render function; callers wrap `renderSlot('details', {})` directly.
|
||||
|
||||
Session identity comes from the scope binding and standard `sessionId` prop. The Provider handles only the absent branch and subtree isolation by Session identity; components do not obtain Session data through a Provider callback.
|
||||
|
||||
### Pending interactions
|
||||
|
||||
Business packages extend `SessionPendingInteractionMap` through declaration merging. Every pending object carries at least a stable `key`, domain `kind`, and `sessionId`; `ui-session` does not import concrete Approval or Question types.
|
||||
|
||||
A business plugin calls `registerPendingInteraction(precedence)` in `apply()` to create a stable registration for its pending domain. The returned per-request publication function publishes one exact object and returns an idempotent disposer for that object.
|
||||
|
||||
Concurrent objects with the same key are rejected; replacement requests use a new key. One Session may hold multiple domains or requests at once.
|
||||
|
||||
`ui-session` selects each Session's effective object using domain precedence. Higher precedence wins; at equal precedence, the later valid object in traversal order wins.
|
||||
|
||||
The aggregate is published as `pendingInteractions: ObservableSnapshot<ReadonlyMap<SessionId, SessionPendingInteraction>>`; `useSessionPendingInteraction` is its React read face.
|
||||
|
||||
Session navigation state and composer takeover read the same effective object. They do not maintain separate status maps or takeover rosters.
|
||||
|
||||
## Workspace Controller and UI Workspace
|
||||
|
||||
### Scope of WorkspaceSnapshot
|
||||
|
||||
`WorkspaceSnapshot` contains only Host-authoritative data owned by the Workspace Controller, including Workspace rows, order, archive set, follow phase, and errors. A Workspace row's `sessionIds` is an association field, not a copy of Session objects in the Workspace snapshot.
|
||||
|
||||
These combined facts do not enter `WorkspaceSnapshot`:
|
||||
|
||||
- whether the Workspace and Session baselines are both ready;
|
||||
- the most recent Workspace derived from Session update times;
|
||||
- whether the current Session is cleared because it was archived;
|
||||
- which blank Session New Session should reuse;
|
||||
- which Session initial startup should select.
|
||||
|
||||
### UI Workspace composition responsibilities
|
||||
|
||||
`client/ui-workspace` registers the Workspace list source as the root standard source `workspaces`, from which the renderer provides `useWorkspaces`.
|
||||
|
||||
Initial selection, blank-Session reuse, new-session navigation, concurrent-create coalescing, and navigation after archival are UI navigation policy. That policy may read both `ctx.workspaces` and `ctx.sessions` at decision time, but it issues only Controller commands and selection actions and does not publish a combined snapshot.
|
||||
|
||||
Directory pickers, directory browsing, and `openPath` are separate directory capabilities and do not enter the Workspace Controller.
|
||||
|
||||
## UI Conversation
|
||||
|
||||
### Assembly core
|
||||
|
||||
`client/ui-conversation` contains both the React-free Conversation assembly core and the React adapter for the same domain.
|
||||
|
||||
The core owns `ConversationSnapshot`, the Definition registry, the View registry, the event assembler, the location index, per-Session bindings, target sources, and target activity.
|
||||
|
||||
The core obtains `SessionEventSource` from a Session binding. Append and prepend changes with continuous revisions use incremental assembly; replace changes or revision gaps rebuild from the complete window.
|
||||
|
||||
Definition or View roster changes rebuild only the Conversation binding; they do not rebuild a Session or reopen a Remote stream. The core does not import React and can test event folding, incremental updates, and registry lifetimes independently.
|
||||
|
||||
`ConversationSnapshot` does not copy `SessionSnapshot` or expose raw events. It publishes only the target-neutral View roster, target activity, and target-source lookup.
|
||||
|
||||
`useSession` and `useConversation` come from separate sources and are not guaranteed to publish atomically in one React commit. Components that read both compute purely from their current snapshots and do not treat notification order as business causality.
|
||||
|
||||
### Definition and View registries
|
||||
|
||||
`UiConversation.events` is the sole registry for event Definitions, and `UiConversation.views` is the sole registry for target snapshot builders.
|
||||
|
||||
The registries reject duplicate keys, preserve registration order, and return idempotent disposers. Existing Conversation bindings rebuild from their current event windows when a roster changes.
|
||||
|
||||
A target package extends snapshot and location-data maps through declaration merging, then registers its Definitions, builder, and View. Registrations follow Cordis effect disposal.
|
||||
|
||||
`ui-conversation` does not import concrete target packages.
|
||||
|
||||
### Conversation React adapter
|
||||
|
||||
The React adapter registers each Conversation binding snapshot as the Session standard source `conversation`, from which the renderer provides `useConversation`.
|
||||
|
||||
The package also owns the shell, input, composer chain, queue UI, drafts, View navigation, and phase composition. The core reads no React Context, Slot props, or component state.
|
||||
|
||||
View selection order is a valid persisted selection, registered `chat`, then no View. An invalid selection does not overwrite the persisted value, and the system does not fall back to the first registered View.
|
||||
|
||||
Without `ui-chat`, the shell can still activate and mount but does not implicitly select Trajectory or another target.
|
||||
|
||||
The shell phase is a pure composition of Session lifecycle and Conversation target activity. An active Session or any target reporting visible content produces active; a failed first prompt remains engaging.
|
||||
|
||||
### Input and composer
|
||||
|
||||
The composer chain belongs to `ui-conversation`; a concrete takeover belongs to its business package. `ConversationRoot` reads the current Session's effective object through `useSessionPendingInteraction` and supplies it to chain selectors as `ComposerChainProps.pendingInteraction`.
|
||||
|
||||
A selector is a pure function of owner currency. Its non-null result reaches the selected component as `matched`. A stable composer entry and the default composer remain mounted together, while the chain selects one effective presentation.
|
||||
|
||||
Draft and input state belong to Conversation UI and do not enter the Session snapshot. Queue commands use a Session-scoped service for addressing and do not write queue UI into the Conversation core.
|
||||
|
||||
## Chat and Trajectory targets
|
||||
|
||||
### Chat owner
|
||||
|
||||
`client/ui-chat` registers target id `chat` and owns the Chat snapshot builder, Conversation Node definitions, keyed node renderers, selection, details, statistics, locale, Tool-inspection collaboration, and historical-image cache.
|
||||
|
||||
It registers the `chat` target source through `ctx.uiSession.provide()`. `ChatNodeSeat` and internal Chat consumers use `useChat` instead of passing `useConversation(snapshot => snapshot.views.get('chat'))`.
|
||||
|
||||
Only visible non-command Chat Nodes activate Chat. Ordinary command-only history keeps the Hero visible; the `/goal` `command-input` Node activates a fresh Conversation.
|
||||
|
||||
The historical-image cache's Session key, pending promise, generation guard, blob URL, and disposer all belong to `ui-chat`; draft images remain part of Conversation input.
|
||||
|
||||
### Trajectory owner
|
||||
|
||||
`client/ui-trajectory` registers `trajectory` through the same target protocol. It owns event-record projection, timelines, virtual rows, selection, and the inspection view, and exposes `useTrajectory` through a standard source.
|
||||
|
||||
Session lifecycle reads `useSession`, while Trajectory data reads `useTrajectory`. Trajectory does not obtain its own data through a Session or Chat snapshot.
|
||||
|
||||
Other targets use the same registration flow without modifying the renderer, Session Controller, or ui-session.
|
||||
|
||||
## Approval and Question
|
||||
|
||||
### Stable registration
|
||||
|
||||
Approval and Question plugin installation separates stable registrations from per-request handling. `apply()` registers locale data, calls `registerPendingInteraction()` once for its pending domain, and registers one stable entry in `conversation.composer`.
|
||||
|
||||
The stable Approval entry also declares its detail child Slot. Concurrent requests and Session count do not add composer entries or redeclare Slots, and every registration follows plugin-fiber disposal.
|
||||
|
||||
### One waterfall request
|
||||
|
||||
A Remote Event listener resolves the Session from its own Agent Context. Without a Session scope it calls `next()` to continue the waterfall; with a Session scope it creates a `PendingApproval` or `PendingQuestion`.
|
||||
|
||||
The listener publishes the object through the registered domain publication function, waits for user completion, cancellation, or request-signal abortion, and removes the exact object in `finally`.
|
||||
|
||||
One request does not register a Slot, create another lifecycle effect, or mutate the Session snapshot.
|
||||
|
||||
Approval exposes allow and reject; Question exposes answer and cancel. User cancellation of a Question returns `ASK_CANCELLED`; interruption of a pending request by `AbortSignal` returns `UserQuestionError(ASK_ABORTED)` rather than leaking the carrier's `AbortError` or an ordinary `Error`.
|
||||
|
||||
The Gateway requires only that Remote Event arguments and results are valid JSON transport values. It does not duplicate domain validation of Question options.
|
||||
|
||||
### One pending projection
|
||||
|
||||
The Sidebar and composer consume the same `pendingInteractions` snapshot. Navigation displays approval, plan-review, or question state from the effective object's `kind`; each composer entry selects its own panel by object identity.
|
||||
|
||||
The same request identity drives both UI surfaces. A request that replaces another request of the same type uses a new key, so selectors and subscribers observe the identity change.
|
||||
|
||||
`ui-session` implements only cross-domain precedence and does not interpret Approval or Question fields.
|
||||
|
||||
## UI Renderer and Store
|
||||
|
||||
### UI Renderer
|
||||
|
||||
`client/ui-renderer` owns the `SlotRegistry` service and React renderer. It is responsible for:
|
||||
|
||||
- `ctx.slots.register()`, `inject()`, `renderSlot()`, and declaration lifetimes;
|
||||
- root, session, and session-maybe scope adapters;
|
||||
- binding standard observable sources to selector hooks;
|
||||
- Slot outlets, error isolation, root mount, and hydration;
|
||||
- managing Slot store instance lifetimes by scope key.
|
||||
|
||||
The renderer may know generic scope names and binding protocols but does not read domain services. Rendering Session scope without an installed adapter is an assembly error that fails immediately.
|
||||
|
||||
### Store
|
||||
|
||||
`client/store` is a plain React-free library owning `ObservableSnapshot`, `SnapshotStore`, `defineStore`, `createSnapshotStore`, and `shallowEqual`.
|
||||
|
||||
`ui-slots` references the Store contract; `ui-renderer` manages Store instances and supplies `useStore`.
|
||||
|
||||
Stores hold viewing and interaction state such as drafts, View selection, Chat selection, inspection requests, and panel size. Session, Workspace, Conversation, Remote streams, and connection generations do not enter Stores.
|
||||
|
||||
### Registration and release order
|
||||
|
||||
When one plugin provides both a source and a Slot entry, it registers the source first and the entry second. Reverse Cordis disposal then removes the entry before the source, so a mounted entry never briefly loses a required hook.
|
||||
|
||||
Releasing a Session binding cleans up UI materialization and scoped Stores through `binding.ctx.effect()`. Releasing a plugin fiber cleans up sources, listeners, and Slot entries through registration disposers.
|
||||
|
||||
Every disposer is idempotent and depends on no implicit callback outside the Cordis lifecycle.
|
||||
|
||||
## Composition and dependency direction
|
||||
|
||||
The application bundle explicitly installs the required Controller, adapter, target, and renderer plugins. Each owner's `apply()` installs only its own service, listener, and contributions.
|
||||
|
||||
Runtime consumption flows as `session-controller → ui-session → ui-conversation → target UI`, `workspace-controller → ui-workspace`, and `store → ui-slots → ui-renderer`; Approval and Question depend only on the pending-registration point exposed by `ui-session`.
|
||||
|
||||
Arrows in this description represent runtime consumption and do not include type-only declaration-merge edges. Controllers do not depend back on UI adapters, the renderer does not depend back on domain packages, and the Conversation core does not depend on a concrete target.
|
||||
|
||||
UI components do not receive `ctx`. Cross-package collaboration uses Cordis services, standard sources, or Slot registrations without introducing an aggregate facade.
|
||||
|
||||
## Developer guidance
|
||||
|
||||
### Choose the data owner first
|
||||
|
||||
Before adding state, choose its sole owner from its consumption semantics: Host communication, commands, and entity lifecycle belong to an API Controller; data assembled from Session events but independent of a target belongs to the Conversation core; projections serving only one View belong to that target package; drafts, selections, and panel state belong to the UI package that owns the interaction.
|
||||
|
||||
The same fact must not be retained simultaneously in a Controller snapshot, Conversation snapshot, and Store. A cross-domain decision reads multiple sources and immediately issues a command; it does not create a joined snapshot or cache another domain's object.
|
||||
|
||||
These are signs of incorrect ownership: a Controller imports React; the renderer branches on business types; a component traverses Session events; a Store holds Session or Workspace entities; changing one target requires changing the Session Controller.
|
||||
|
||||
### Add Session-scoped data
|
||||
|
||||
1. Provide a React-free observable source in the domain owner.
|
||||
2. Declaration-merge the standard prop type in the owning UI adapter.
|
||||
3. Declare a fixed roster through `ctx.uiSession.provide()` and resolve its source from a Session binding.
|
||||
4. Let the Slot component receive the generated hook through `PropsRuntime`; do not pass `ctx` to a component.
|
||||
5. Attach each binding resource's cleanup to `binding.ctx.effect()` and leave registration cleanup to the plugin fiber.
|
||||
6. Test missing values, duplicate names, roster replacement, Session changes, and binding disposal.
|
||||
|
||||
Only open key spaces use keyed hooks. Finite stable sources use ordinary hooks, and immutable identifiers use props. Do not hard-code business names in the renderer to save one registration.
|
||||
|
||||
### Add a Conversation target
|
||||
|
||||
1. Extend the Conversation snapshot or location-data map in the target package.
|
||||
2. Register the required event Definitions with `UiConversation.events`.
|
||||
3. Register the snapshot builder, target id, View, and activity rule with `UiConversation.views`.
|
||||
4. Expose the target's standard selector hook through `ctx.uiSession.provide()`.
|
||||
5. Register the renderer, locale, and target-specific Slot entries in the same package.
|
||||
6. Verify that unloading the target rebuilds only the Conversation binding without changing the Session, other targets, or Remote stream.
|
||||
|
||||
A target must not use another target's snapshot as its data source. Optional collaboration uses a narrow port or Slot; when a target is absent, the shell remains bootable and does not guess a fallback.
|
||||
|
||||
### Add a pending-interaction domain
|
||||
|
||||
1. Define the Pending object and its completion, cancellation, and interruption semantics in the business package.
|
||||
2. Add the object to `SessionPendingInteractionMap` through declaration merging.
|
||||
3. Call `registerPendingInteraction()` once in `apply()` and register one stable composer entry.
|
||||
4. Resolve the Session from the Agent Context in the Remote waterfall listener; call `next()` when the listener cannot handle the request.
|
||||
5. When it can handle the request, create the Pending object, publish it through the publication function, await its result, and remove it in `finally`.
|
||||
6. Test concurrent keys, precedence, user cancellation, transport abort, plugin disposal, and delegation without a Session.
|
||||
|
||||
A request does not register Slots, declare child Slots, mutate the Session snapshot, or create a separate state index. Sidebar and composer both read one effective object from `useSessionPendingInteraction`.
|
||||
|
||||
### Review checks
|
||||
|
||||
- Every new source, registry contribution, listener, and cache has an explicit Cordis-fiber or Session-binding owner.
|
||||
- Every public hook traces to one React-free source; no selector is forwarded through layers only to pass arguments.
|
||||
- Every component obtains data and actions from standard props or the owning Slot's inject face.
|
||||
- Every target has defined behavior when absent, dynamically registered, and unloaded.
|
||||
- Every cross-layer import advances in the one-way Controller, adapter, renderer, component direction.
|
||||
- Each error is classified by the earliest owner that can explain its semantics; carrier errors do not leak directly as business errors.
|
||||
|
||||
## Verification
|
||||
|
||||
Tests owned by each layer pin Controller bindings and event sources, UI scopes and pending precedence, incremental Conversation assembly and View fallback, target projections, waterfall results, and renderer scope/Store lifetimes. Application-composition tests cover both the complete roster and startup without a concrete target; component tests do not replace object-layer, replay, and lifecycle tests.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- **Keep a Runtime facade.** One entry point would retain the dependency hub and let new code bypass domain owners, so the system provides neither the facade nor a compatibility export.
|
||||
- **Put all Client state in API Controllers.** Protocol objects would then own React, Views, and presentation policy, so Controllers retain only React-free domain state.
|
||||
- **Let Controllers provide React hooks directly.** Non-React consumers could not reuse the same objects, and transport and renderer lifetimes would become interdependent.
|
||||
- **Put Conversation in SessionSnapshot.** This would expand the Session API and force ordinary Session consumers to understand event folding and target rosters.
|
||||
- **Let Chat and Trajectory replay Session events independently.** Ordering, locations, and registry rebuild would be duplicated, so the shared assembly core stays in `ui-conversation`.
|
||||
- **Extract the Conversation core into another non-UI package.** The core and adapter currently evolve together and have no other non-UI package consumer; directory separation within one package keeps the core React-free.
|
||||
- **Combine Workspace and Session into one snapshot.** This would create another cross-domain owner, so cross-domain logic remains an immediate decision in `ui-workspace`.
|
||||
- **Build every standard hook into the renderer.** Generic infrastructure would need to know every domain, so standard-source registration keeps the renderer independent from business types.
|
||||
- **Dynamically register a composer entry for every pending request.** This would redeclare child Slots and make concurrent requests compete through registration order, so stable entries are separate from request publication.
|
||||
- **Write pending interactions into a Session projection.** An unanswered waterfall is not a committed durable Session fact; Remote Event replay restores it after refresh, so it remains in a business UI source.
|
||||
- **Add a dedicated release callback to bindings.** This would duplicate the Cordis lifecycle; `binding.ctx.effect()` already attaches consumer cleanup to the same owner.
|
||||
- **Pass the Session id from SessionProvider through a render function.** This would create another data-injection path; ordinary children and the standard `sessionId` prop retain one entry for scoped data.
|
||||
- **Keep Store in the renderer.** The Store contract does not depend on React and is reused by objects and test infrastructure, so `client/store` keeps the engine separate from rendering lifetimes.
|
||||
|
||||
## Consequences
|
||||
|
||||
Session, Workspace, Conversation, and each concrete target own one authoritative state. Non-React consumers can reuse Controllers and the assembly core directly. A new Conversation target registers its Definition, builder, View, standard source, and Slot entries; a new pending-interaction domain declares its type, registers its domain, and provides one stable composer entry.
|
||||
|
||||
The renderer and Session Controller gain no branch for a new business domain, while Session bindings and plugin fibers provide two explicit, composable release paths. The UI can observe independent Session and Conversation source publications, and consumers cannot depend on their notification order.
|
||||
|
||||
Composition packages must explicitly load the required adapter and target plugins. The shell remains operational without a concrete target but neither creates nor guesses that target's View. More packages and explicit registrations add assembly work, while dependency direction, test scope, and failure ownership become locally identifiable.
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-07-30-web-transcript-log-ordered-projection.md
|
||||
2026-07-30-web-transcript-log-ordered-projection.md: e4c9fdd6fcdec0b14ed2724dd58365e1d98af8b4
|
||||
2026-07-30-web-transcript-log-ordered-projection.zh.md: 625bd993a0b20bbbed318edf71d79866fa80bff0
|
||||
2026-07-30-web-transcript-log-ordered-projection.md: ed6fa4df3ac25bf6fe2947e6fb7bb7cbde6ac00a
|
||||
2026-07-30-web-transcript-log-ordered-projection.zh.md: cf8dc35099f416356310081f758d0b89fe8282b9
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@ import type { CompactionCheckpointSource } from '@deepseek-ai/dsh-compaction/che
|
||||
const COMPACT_PLUGIN: CompactionCheckpointSource['plugin'] = 'compact'
|
||||
```
|
||||
|
||||
Renaming the Service Definition's plugin id is now a compile error in the client: `TS2322: Type '"compact"' is not assignable to type '"compaction"'`. The import must stay **type-only** — a value import of any `@deepseek-ai` package that is neither a platform module nor an inline-safe wire layer is rejected by the client purity gate (`packages/client/tsdown.client.ts`), whose own message records that type-only imports are erased and never reach it. A type-only leaf import needs both a `tsconfig.base.json` `paths` entry and `{"path": "../../compaction/compaction"}` in `packages/client/runtime/tsconfig.json` `references`: composite `rootDir` rules apply to erased imports as well, and without the reference the diagnostic is `TS6059`/`TS6307`.
|
||||
Renaming the Service Definition's plugin id is now a compile error in the client: `TS2322: Type '"compact"' is not assignable to type '"compaction"'`. The import must stay **type-only** — a value import of any `@deepseek-ai` package that is neither a platform module nor an inline-safe wire layer is rejected by the client purity gate (`packages/client/tsdown.client.ts`), whose own message records that type-only imports are erased and never reach it. A type-only leaf import needs both a `tsconfig.base.json` `paths` entry and `{"path": "../../compaction/compaction"}` in `packages/client/ui-chat/tsconfig.json` `references`: composite `rootDir` rules apply to erased imports as well, and without the reference the diagnostic is `TS6059`/`TS6307`.
|
||||
|
||||
`packages/client/ui-conversation/tests/conversation-node-definitions.client.spec.ts` is the behavioral half, driving the compaction Definition with checkpoint and provenance records and proving that an older page can fill missing summary data. The Definition's type-only leaf import keeps the client isolated from the compact package root and the host-side `Context` merges reachable through it.
|
||||
`packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts` is the behavioral half, driving the compaction Definition with checkpoint and provenance records and proving that an older page can fill missing summary data. The Definition's type-only leaf import keeps the client isolated from the compact package root and the host-side `Context` merges reachable through it.
|
||||
|
||||
The divergence from the terminal is therefore narrow: both frontends recognize a checkpoint from the same declaration — the terminal value-imports `isCompactCheckpointSource` host-side, where no gate applies, and the client pins the type.
|
||||
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@ import type { CompactionCheckpointSource } from '@deepseek-ai/dsh-compaction/che
|
||||
const COMPACT_PLUGIN: CompactionCheckpointSource['plugin'] = 'compact'
|
||||
```
|
||||
|
||||
重命名 Service Definition 的插件 id 现在会在客户端产生编译错误:`TS2322: Type '"compact"' is not assignable to type '"compaction"'`。该导入必须保持**仅类型**——任何既非平台模块又非 inline-safe wire 层的 `@deepseek-ai` 包值导入都会被客户端纯度门禁(`packages/client/tsdown.client.ts`)拒绝,而它自己的报错信息就记录着仅类型导入会被擦除、永不抵达该门禁。仅类型的叶子导入同时需要 `tsconfig.base.json` 的一条 `paths` 条目和 `packages/client/runtime/tsconfig.json` `references` 中的 `{"path": "../../compaction/compaction"}`:composite 的 `rootDir` 规则同样适用于被擦除的导入,缺少该引用时的诊断是 `TS6059`/`TS6307`。
|
||||
重命名 Service Definition 的插件 id 现在会在客户端产生编译错误:`TS2322: Type '"compact"' is not assignable to type '"compaction"'`。该导入必须保持**仅类型**——任何既非平台模块又非 inline-safe wire 层的 `@deepseek-ai` 包值导入都会被客户端纯度门禁(`packages/client/tsdown.client.ts`)拒绝,而它自己的报错信息就记录着仅类型导入会被擦除、永不抵达该门禁。仅类型的叶子导入同时需要 `tsconfig.base.json` 的一条 `paths` 条目和 `packages/client/ui-chat/tsconfig.json` `references` 中的 `{"path": "../../compaction/compaction"}`:composite 的 `rootDir` 规则同样适用于被擦除的导入,缺少该引用时的诊断是 `TS6059`/`TS6307`。
|
||||
|
||||
`packages/client/ui-conversation/tests/conversation-node-definitions.client.spec.ts` 是行为侧的另一半,用检查点与溯源记录驱动压缩 Definition,并证明后续加载的旧分页可以补齐缺失的摘要数据。Definition 仅类型导入该叶子路径,使客户端继续与 compact 包根及经由它可达的宿主侧 `Context` 合并隔离。
|
||||
`packages/client/ui-chat/tests/conversation-node-definitions.client.spec.ts` 是行为侧的另一半,用检查点与溯源记录驱动压缩 Definition,并证明后续加载的旧分页可以补齐缺失的摘要数据。Definition 仅类型导入该叶子路径,使客户端继续与 compact 包根及经由它可达的宿主侧 `Context` 合并隔离。
|
||||
|
||||
因此与终端的分歧很窄:两个前端都从同一份声明识别检查点——终端在宿主侧值导入 `isCompactCheckpointSource`(那里不适用任何门禁),客户端钉住类型。
|
||||
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-05-workspace-blank-session-reuse-membership.md
|
||||
2026-08-05-workspace-blank-session-reuse-membership.md: 0d46a0ccf6924c508db2e6c0f3591468e2956722
|
||||
2026-08-05-workspace-blank-session-reuse-membership.zh.md: 6350c6773265edebb381d5ca10fd5126a5722a5a
|
||||
2026-08-05-workspace-blank-session-reuse-membership.md: df8cc898f5a80937b8aac69ebd51a6a93882971b
|
||||
2026-08-05-workspace-blank-session-reuse-membership.zh.md: 73ccdbbb002920eea8f7b01bc0fa8a18859bd3ee
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@ Stray blank sessions remain visible in Ungrouped (the user can still open them)
|
||||
|
||||
## Testing
|
||||
|
||||
`packages/client/runtime/tests/workspaces-service.client.spec.ts` covers the four outcomes: a member blank session is reused (no create RPC); a stray blank with matching cwd is **not** reused and a fresh accounted session is created (regression case); an archived blank is not reused; a rejected first prompt keeps a member blank eligible. The full client suite (`pnpm run test:gui`) stays green.
|
||||
`packages/client/ui-workspace/tests/workspaces-service.client.spec.ts` covers the four outcomes: a member blank session is reused (no create RPC); a stray blank with matching cwd is **not** reused and a fresh accounted session is created (regression case); an archived blank is not reused; a rejected first prompt keeps a member blank eligible. The full client suite (`pnpm run test:gui`) stays green.
|
||||
|
||||
+1
-1
@@ -26,4 +26,4 @@ Status: implemented
|
||||
|
||||
## 测试
|
||||
|
||||
`packages/client/runtime/tests/workspaces-service.client.spec.ts` 覆盖四种结果:成员空白会话被复用(无 create RPC);cwd 匹配但非成员的游离空白会话**不被**复用、改为创建全新入账会话(回归用例);已归档空白会话不被复用;首次提示词被拒后成员空白会话仍可复用。完整客户端套件(`pnpm run test:gui`)保持绿色。
|
||||
`packages/client/ui-workspace/tests/workspaces-service.client.spec.ts` 覆盖四种结果:成员空白会话被复用(无 create RPC);cwd 匹配但非成员的游离空白会话**不被**复用、改为创建全新入账会话(回归用例);已归档空白会话不被复用;首次提示词被拒后成员空白会话仍可复用。完整客户端套件(`pnpm run test:gui`)保持绿色。
|
||||
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-06-reader-scroll-attribution-observed-top-ledger.md
|
||||
2026-08-06-reader-scroll-attribution-observed-top-ledger.md: 66a1ca361cf28bf0beab95fa81da9cac3527474c
|
||||
2026-08-06-reader-scroll-attribution-observed-top-ledger.zh.md: 6aa1866e802b00d0a3431dfd5bef9efd57121294
|
||||
2026-08-06-reader-scroll-attribution-observed-top-ledger.md: b55bbc39f6e1f24bb7751b7743da23736abbd06b
|
||||
2026-08-06-reader-scroll-attribution-observed-top-ledger.zh.md: e38ead6c9b80e41b37556172bd6c1f411858b6ed
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ A shrink clamp whose layout regrows within the same rendering update before the
|
||||
|
||||
## Testing
|
||||
|
||||
Unit specs in `packages/client/ui-conversation/tests/chat-view.client.spec.tsx` pin the ledger contract directly: a `readerScroll` helper delivers a position the component never wrote, programmatic deliveries land on the ledger, and the stream-finalization shrink clamp keeps following. Two scenarios in `apps/web/tests/chat-scroll-contract.e2e.ts` extend the [browser e2e lane](../testing/2026-07-24-web-gui-browser-e2e-lane.md): keyboard paging over a settled transcript and a touch-style momentum fling against paced streaming, both red under the wheel-only implementation and green under the ledger.
|
||||
Unit specs in `packages/client/ui-chat/tests/chat-view.client.spec.tsx` pin the ledger contract directly: a `readerScroll` helper delivers a position the component never wrote, programmatic deliveries land on the ledger, and the stream-finalization shrink clamp keeps following. Two scenarios in `apps/web/tests/chat-scroll-contract.e2e.ts` extend the [browser e2e lane](../testing/2026-07-24-web-gui-browser-e2e-lane.md): keyboard paging over a settled transcript and a touch-style momentum fling against paced streaming, both red under the wheel-only implementation and green under the ledger.
|
||||
|
||||
The lane's Chromium cannot synthesize any non-wheel device scrolling, which bounds what the e2e can drive for real: `Input.synthesizeScrollGesture` with a touch source and hand-rolled `Input.dispatchTouchEvent` sequences deliver DOM events but never move a scroller (headless and headed-under-Xvfb alike); the `default` gesture source synthesizes wheel events; and compositor scrollbars ignore synthetic mouse input entirely, with a gutter visible only when `--hide-scrollbars` is removed. Keyboard is the one working non-wheel primitive, so it carries the real-input-pipeline proof, and the fling scenario replays touch's signature — per-frame decaying displacements the component never authored — through the scrollport directly.
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ ChatView 的贴底跟随此前只把滚轮/触控板手势识别为读者输
|
||||
|
||||
## 测试
|
||||
|
||||
`packages/client/ui-conversation/tests/chat-view.client.spec.tsx` 中的单元测试直接钉住 ledger 约定:`readerScroll` 辅助函数交付一个组件从未写入过的位置,程序化交付落在 ledger 上,流收尾阶段的收缩钳制保持跟随。`apps/web/tests/chat-scroll-contract.e2e.ts` 中的两个场景扩展了[浏览器 e2e 车道](../testing/2026-07-24-web-gui-browser-e2e-lane.zh.md):在已停稳的 transcript 上做键盘翻页,以及对着按节奏推进的流式输出做一次触控式惯性快滑(momentum fling);两者在仅认滚轮的实现下均为红、在 ledger 下均为绿。
|
||||
`packages/client/ui-chat/tests/chat-view.client.spec.tsx` 中的单元测试直接钉住 ledger 约定:`readerScroll` 辅助函数交付一个组件从未写入过的位置,程序化交付落在 ledger 上,流收尾阶段的收缩钳制保持跟随。`apps/web/tests/chat-scroll-contract.e2e.ts` 中的两个场景扩展了[浏览器 e2e 车道](../testing/2026-07-24-web-gui-browser-e2e-lane.zh.md):在已停稳的 transcript 上做键盘翻页,以及对着按节奏推进的流式输出做一次触控式惯性快滑(momentum fling);两者在仅认滚轮的实现下均为红、在 ledger 下均为绿。
|
||||
|
||||
该车道的 Chromium 无法合成任何非滚轮的设备滚动,这限定了 e2e 能真实驱动的范围:触控来源的 `Input.synthesizeScrollGesture` 与手工构造的 `Input.dispatchTouchEvent` 序列都能交付 DOM 事件,却从不移动滚动容器(无头模式与 Xvfb 下的有头模式皆然);`default` 手势来源合成的是滚轮事件;合成器滚动条则完全无视合成的鼠标输入,且只有移除 `--hide-scrollbars` 后才能看到滚动条槽。键盘是唯一可用的非滚轮原语,因此由它承担真实输入流水线的证明;快滑场景则把触控的特征(组件从未写入过的逐帧衰减位移)直接回放进滚动容器。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-02-web-thinking-tail-scroll.md
|
||||
2026-08-02-web-thinking-tail-scroll.md: b9aa47a01b4d8e22baddac1b03f52b3524250941
|
||||
2026-08-02-web-thinking-tail-scroll.zh.md: 41fe29f06202aef3307d756201eb4745fecca537
|
||||
2026-08-02-web-thinking-tail-scroll.md: 38c27274b2c85974044c2bb467c1519e19bfd148
|
||||
2026-08-02-web-thinking-tail-scroll.zh.md: bf637228b3a793f318fa5a5d7b0968ecd8e081d5
|
||||
|
||||
@@ -28,4 +28,4 @@ The collapsed row now communicates provider cadence through content motion as we
|
||||
|
||||
## Testing
|
||||
|
||||
`packages/client/ui-conversation/tests/reasoning-row.client.spec.tsx` pins the latest-line selection, the calculated right-edge scroll position, and the settlement reset to the first line and `scrollLeft = 0`. The keyless assembled Chromium scenario in `apps/web/tests/lifecycle-chrome.e2e.ts` replays real recorded reasoning chunks at observable pacing, narrows the viewport until the summary overflows, and asserts that the live collapsed Think row reaches its actual browser scroll extent. Its settled replay golden remains unchanged, proving the historical summary contract stays stable.
|
||||
`packages/client/ui-chat/tests/reasoning-row.client.spec.tsx` pins the latest-line selection, the calculated right-edge scroll position, and the settlement reset to the first line and `scrollLeft = 0`. The keyless assembled Chromium scenario in `apps/web/tests/lifecycle-chrome.e2e.ts` replays real recorded reasoning chunks at observable pacing, narrows the viewport until the summary overflows, and asserts that the live collapsed Think row reaches its actual browser scroll extent. Its settled replay golden remains unchanged, proving the historical summary contract stays stable.
|
||||
|
||||
@@ -28,4 +28,4 @@ Web Think 行在结算与流式 block 中都把 reasoning 首行渲染成折叠
|
||||
|
||||
## 测试
|
||||
|
||||
`packages/client/ui-conversation/tests/reasoning-row.client.spec.tsx` 固定最新行选择、算出的右端滚动位置,以及结算后恢复首行和 `scrollLeft = 0`。`apps/web/tests/lifecycle-chrome.e2e.ts` 中的无密钥组装态 Chromium 场景以可观察节奏回放真实录制的 reasoning chunks,把视口收窄到摘要溢出,并断言实时折叠 Think 行到达真实浏览器的滚动边界。其结算态 replay golden 保持不变,证明历史摘要约定仍然稳定。
|
||||
`packages/client/ui-chat/tests/reasoning-row.client.spec.tsx` 固定最新行选择、算出的右端滚动位置,以及结算后恢复首行和 `scrollLeft = 0`。`apps/web/tests/lifecycle-chrome.e2e.ts` 中的无密钥组装态 Chromium 场景以可观察节奏回放真实录制的 reasoning chunks,把视口收窄到摘要溢出,并断言实时折叠 Think 行到达真实浏览器的滚动边界。其结算态 replay golden 保持不变,证明历史摘要约定仍然稳定。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-08-web-background-job-display.md
|
||||
2026-08-08-web-background-job-display.md: 962d29e35ffe436c5ab91307d0cdfa557bbd539f
|
||||
2026-08-08-web-background-job-display.zh.md: 8b391c272b8ff38028cc6819f2fbec49505d85aa
|
||||
2026-08-08-web-background-job-display.md: 8da6c2fd914bf07cfa7d3545cff1e42552c69d27
|
||||
2026-08-08-web-background-job-display.zh.md: 0e05ef9d2fcd8193c661f471b5f7b9a84891f98a
|
||||
|
||||
@@ -101,7 +101,7 @@ A running one-shot background subagent therefore appears both there and in the s
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Signal frame plus RPC pull, the subagent-catalog shape.** Push a payload-free `jobs-changed` signal, debounce, then re-read authoritative state over a unary RPC. This is what the subagent catalog does, and the cost is visible in [`SessionManager`](../../../../packages/client/runtime/src/client/sessions/manager.ts): `catalogInflight` for single-flight, `catalogStale` for a trailing re-pull when a membership frame lands mid-request, `updateCatalogActivity` patching loaded rows in place *and* writing into the in-flight request so a response older than the frame gets overwritten, `parentAvailableOverride` replaying a stale `false`, and a reconnect path re-pulling every open catalog. That apparatus exists because the catalog's authority is split — durable lineage from a projection, liveness sampled at response time — and tasks have no durable half to justify inheriting it. It also fails specifically at the moment the output phase cares about: a task settles, its output stream closes immediately, but status only arrives after debounce plus round-trip, so the UI shows a running task with a dead stream for that window.
|
||||
**Signal frame plus RPC pull, the subagent-catalog shape.** Push a payload-free `jobs-changed` signal, debounce, then re-read authoritative state over a unary RPC. This is what the subagent catalog does, and the cost is visible in [`SessionManager`](../../../../packages/api/session-controller/src/client/sessions/manager.ts): `catalogInflight` for single-flight, `catalogStale` for a trailing re-pull when a membership frame lands mid-request, `updateCatalogActivity` patching loaded rows in place *and* writing into the in-flight request so a response older than the frame gets overwritten, `parentAvailableOverride` replaying a stale `false`, and a reconnect path re-pulling every open catalog. That apparatus exists because the catalog's authority is split — durable lineage from a projection, liveness sampled at response time — and tasks have no durable half to justify inheriting it. It also fails specifically at the moment the output phase cares about: a task settles, its output stream closes immediately, but status only arrives after debounce plus round-trip, so the UI shows a running task with a dead stream for that window.
|
||||
|
||||
**Popover-scoped polling with no seam change.** Cheapest to build and the only option that avoids touching `JobRegistry`. It cannot support a resident count on the trigger without a resident poll, and both later phases need a real change feed anyway, so it buys a week and spends it back.
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ abstract onJobsChanged(listener: JobsChangedListener): () => void
|
||||
|
||||
## 备选方案
|
||||
|
||||
**信号帧加 RPC 拉取,即 subagent 目录的形状。** 推一个无 payload 的 `jobs-changed` 信号,防抖后用一元 RPC 重读权威状态。subagent 目录就是这么做的,代价在 [`SessionManager`](../../../../packages/client/runtime/src/client/sessions/manager.ts) 里一览无余:`catalogInflight` 做单飞行、`catalogStale` 在成员帧落于请求中途时补一次尾拉、`updateCatalogActivity` 既就地打补丁又往在途请求里写一份好让比帧更旧的响应被覆盖、`parentAvailableOverride` 重放一个过期的 `false`,还有重连时逐一重拉每个打开的目录。这套装置之所以存在,是因为目录的权威被劈成两半——持久血缘来自投影,活跃度是响应时刻的采样——而任务没有持久的那一半,不该继承这份复杂度。它还恰好在输出那一期最在意的时刻失效:任务结算,输出流立即关闭,状态却要等防抖加一次往返才到,那段窗口里 UI 显示一个流已死的运行中任务。
|
||||
**信号帧加 RPC 拉取,即 subagent 目录的形状。** 推一个无 payload 的 `jobs-changed` 信号,防抖后用一元 RPC 重读权威状态。subagent 目录就是这么做的,代价在 [`SessionManager`](../../../../packages/api/session-controller/src/client/sessions/manager.ts) 里一览无余:`catalogInflight` 做单飞行、`catalogStale` 在成员帧落于请求中途时补一次尾拉、`updateCatalogActivity` 既就地打补丁又往在途请求里写一份好让比帧更旧的响应被覆盖、`parentAvailableOverride` 重放一个过期的 `false`,还有重连时逐一重拉每个打开的目录。这套装置之所以存在,是因为目录的权威被劈成两半——持久血缘来自投影,活跃度是响应时刻的采样——而任务没有持久的那一半,不该继承这份复杂度。它还恰好在输出那一期最在意的时刻失效:任务结算,输出流立即关闭,状态却要等防抖加一次往返才到,那段窗口里 UI 显示一个流已死的运行中任务。
|
||||
|
||||
**只在弹层打开时轮询,不改 seam。** 最省事,也是唯一不碰 `JobRegistry` 的选项。它无法在不常驻轮询的前提下支持触发器上的常驻计数,而后面两期反正都需要一条真正的变更订阅,所以它省下一周又还回去。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write apps/web/tests/README.md
|
||||
README.md: acb0c300bafe221f6a92f0168908bebf965377b9
|
||||
README.zh.md: 029f3190bb89bede5506d3d58f5e6df229218493
|
||||
README.md: 2104d9422cfbbcbc7ffc4b12e491c0a62daa3b9d
|
||||
README.zh.md: 4dfa5b2f61c757e481d9b8e012b37a5e71d75093
|
||||
|
||||
@@ -33,14 +33,11 @@ then surfaces as a missed selector or a stale mirrored value — a loud failure,
|
||||
never a silent pass. `scaffold.ts` follows this rule for the welcome-notice
|
||||
namespace, acknowledgement field, version, and asserted Chinese copy.
|
||||
|
||||
Two kinds of Client import stand. `assembled-boot.ts` drives the shell itself, so
|
||||
One kind of Client import stands. `assembled-boot.ts` drives the shell itself, so
|
||||
it imports `AppWebEntry` from `@deepseek-ai/dsh-client-web` and the boot-manifest
|
||||
type from `@deepseek-ai/dsh-client-modules/client`: booting the real shell is what
|
||||
that harness is for, and both packages are already in the Host graph. Separately,
|
||||
the chat scenarios import `conversationContextKey` from
|
||||
`@deepseek-ai/dsh-client-runtime/client` because `client/runtime` is reachable
|
||||
through the unsplit `directory-picker` packages and pulls nothing further in.
|
||||
That reachability is incidental, not a guarantee — if it ever leaves the graph,
|
||||
mirror the helper like the rest.
|
||||
that harness is for, and both packages are already in the Host graph. The chat
|
||||
scenarios mirror `conversationContextKey` in `support.ts` instead of importing
|
||||
its Client owner.
|
||||
|
||||
Nothing mechanically enforces this rule; keep it in review.
|
||||
|
||||
@@ -26,12 +26,10 @@ Client face,而该 face 必须等 Host tsdown 生成 `@deepseek-ai/dsh-goal/re
|
||||
import 点明源模块。这样漂移会表现为选择器未命中或镜像值过期——是响亮的失败,绝不会是静默
|
||||
通过。`scaffold.ts` 按此规则镜像欢迎声明的 namespace、确认字段、版本和被断言的中文文案。
|
||||
|
||||
有两类 Client import 是长期成立的。`assembled-boot.ts` 驱动 shell 本身,因此它从
|
||||
有一类 Client import 是长期成立的。`assembled-boot.ts` 驱动 shell 本身,因此它从
|
||||
`@deepseek-ai/dsh-client-web` import `AppWebEntry`、从
|
||||
`@deepseek-ai/dsh-client-modules/client` import boot manifest 类型:启动真实 shell 正是该
|
||||
harness 的用途,且这两个包本来就在 Host 图中。另外,chat 场景从
|
||||
`@deepseek-ai/dsh-client-runtime/client` import `conversationContextKey`,因为
|
||||
`client/runtime` 经未拆分的 `directory-picker` 包可达,且不会再牵入别的东西。这种可达性是
|
||||
偶然而非保证——一旦它离开该图,就像其余情形那样镜像该 helper。
|
||||
harness 的用途,且这两个包本来就在 Host 图中。chat 场景则在 `support.ts` 中镜像
|
||||
`conversationContextKey`,而不 import 其 Client owner。
|
||||
|
||||
没有任何机制强制这条规则;靠 review 守住它。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/api-gateway.md
|
||||
api-gateway.md: cd3103a172d75a4ab325a2368e37af354f09051b
|
||||
api-gateway.zh.md: fd7494917f209af4a16f88b87afbc47d75c6afd3
|
||||
api-gateway.md: 60b9893675ad965c3f88677eac32352acfffeb31
|
||||
api-gateway.zh.md: fc217ce3a976fd8cf045848aa331c2115c3a4d65
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ The Client uses concrete functions on ordinary objects, not a JavaScript Proxy.
|
||||
|
||||
```ts ignore-check
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { AgentContext } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { AgentContext } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-api-remotes/client'
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ Client 使用普通对象上的具体函数,不使用 JavaScript Proxy。直
|
||||
|
||||
```ts ignore-check
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { AgentContext } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { AgentContext } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-api-remotes/client'
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/config-catalog.md
|
||||
config-catalog.md: e83d794302e7fbcf84cb5c1672821e59842e2b28
|
||||
config-catalog.zh.md: 406dbb3c77527317332b48cf513909c56a9b8a3b
|
||||
config-catalog.md: 7636b1e3c7933f6d70a8e40d761b3617e746c13d
|
||||
config-catalog.zh.md: 4567f09059a05d3d87f336caa55fa7db831145af
|
||||
|
||||
@@ -3244,10 +3244,11 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
|
||||
- `@deepseek-ai/dsh-authorization` — requires `credentials` ([`packages/credentials/authorization/src/index.ts`](../packages/credentials/authorization/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-locale` ([`packages/client/locale/src/index.ts`](../packages/client/locale/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-modules` — requires `webServer` · `loader` ([`packages/client/modules/src/index.ts`](../packages/client/modules/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-runtime` ([`packages/client/runtime/src/index.ts`](../packages/client/runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-agent-preset` ([`packages/client/ui-agent-preset/src/index.ts`](../packages/client/ui-agent-preset/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-approval` ([`packages/client/ui-approval/src/index.ts`](../packages/client/ui-approval/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-attachment` ([`packages/client/ui-attachment/src/index.ts`](../packages/client/ui-attachment/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-brand-official` ([`packages/client/ui-brand-official/src/index.ts`](../packages/client/ui-brand-official/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-chat` ([`packages/client/ui-chat/src/index.ts`](../packages/client/ui-chat/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-commands` ([`packages/client/ui-commands/src/index.ts`](../packages/client/ui-commands/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-conversation` ([`packages/client/ui-conversation/src/index.ts`](../packages/client/ui-conversation/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-cordis` ([`packages/extensions/ui-cordis/src/index.ts`](../packages/extensions/ui-cordis/src/index.ts))
|
||||
@@ -3264,6 +3265,7 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
|
||||
- `@deepseek-ai/dsh-client-ui-plan` ([`packages/client/ui-plan/src/index.ts`](../packages/client/ui-plan/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-reference` ([`packages/client/ui-reference/src/index.ts`](../packages/client/ui-reference/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-renderer` ([`packages/client/ui-renderer/src/index.ts`](../packages/client/ui-renderer/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-session` ([`packages/client/ui-session/src/index.ts`](../packages/client/ui-session/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings` ([`packages/client/ui-settings/src/index.ts`](../packages/client/ui-settings/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings-general` ([`packages/client/ui-settings-general/src/index.ts`](../packages/client/ui-settings-general/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings-models` ([`packages/client/ui-settings-models/src/index.ts`](../packages/client/ui-settings-models/src/index.ts))
|
||||
@@ -3344,6 +3346,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them.
|
||||
- `@deepseek-ai/dsh-atomic-write` ([`packages/util/atomic-write/src/index.ts`](../packages/util/atomic-write/src/index.ts))
|
||||
- `@deepseek-ai/dsh-base` ([`packages/bundle/base/src/index.ts`](../packages/bundle/base/src/index.ts))
|
||||
- `@deepseek-ai/dsh-brand` ([`packages/util/brand/src/index.ts`](../packages/util/brand/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-store` ([`packages/client/store/src/index.ts`](../packages/client/store/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-test-runtime` ([`packages/test-support/client-runtime/src/index.ts`](../packages/test-support/client-runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-primitives` ([`packages/client/ui-primitives/src/index.ts`](../packages/client/ui-primitives/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-slots` ([`packages/client/ui-slots/src/index.ts`](../packages/client/ui-slots/src/index.ts))
|
||||
|
||||
@@ -3246,10 +3246,11 @@ export interface Config {
|
||||
- `@deepseek-ai/dsh-authorization` — 需要 `credentials`([`packages/credentials/authorization/src/index.ts`](../packages/credentials/authorization/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-locale`([`packages/client/locale/src/index.ts`](../packages/client/locale/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-modules` — 需要 `webServer` · `loader`([`packages/client/modules/src/index.ts`](../packages/client/modules/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-runtime`([`packages/client/runtime/src/index.ts`](../packages/client/runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-agent-preset`([`packages/client/ui-agent-preset/src/index.ts`](../packages/client/ui-agent-preset/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-approval`([`packages/client/ui-approval/src/index.ts`](../packages/client/ui-approval/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-attachment`([`packages/client/ui-attachment/src/index.ts`](../packages/client/ui-attachment/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-brand-official`([`packages/client/ui-brand-official/src/index.ts`](../packages/client/ui-brand-official/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-chat`([`packages/client/ui-chat/src/index.ts`](../packages/client/ui-chat/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-commands`([`packages/client/ui-commands/src/index.ts`](../packages/client/ui-commands/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-conversation`([`packages/client/ui-conversation/src/index.ts`](../packages/client/ui-conversation/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-cordis`([`packages/extensions/ui-cordis/src/index.ts`](../packages/extensions/ui-cordis/src/index.ts))
|
||||
@@ -3266,6 +3267,7 @@ export interface Config {
|
||||
- `@deepseek-ai/dsh-client-ui-plan`([`packages/client/ui-plan/src/index.ts`](../packages/client/ui-plan/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-reference`([`packages/client/ui-reference/src/index.ts`](../packages/client/ui-reference/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-renderer`([`packages/client/ui-renderer/src/index.ts`](../packages/client/ui-renderer/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-session`([`packages/client/ui-session/src/index.ts`](../packages/client/ui-session/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings`([`packages/client/ui-settings/src/index.ts`](../packages/client/ui-settings/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings-general`([`packages/client/ui-settings-general/src/index.ts`](../packages/client/ui-settings-general/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-settings-models`([`packages/client/ui-settings-models/src/index.ts`](../packages/client/ui-settings-models/src/index.ts))
|
||||
@@ -3345,6 +3347,7 @@ export interface Config {
|
||||
- `@deepseek-ai/dsh-atomic-write`([`packages/util/atomic-write/src/index.ts`](../packages/util/atomic-write/src/index.ts))
|
||||
- `@deepseek-ai/dsh-base`([`packages/bundle/base/src/index.ts`](../packages/bundle/base/src/index.ts))
|
||||
- `@deepseek-ai/dsh-brand`([`packages/util/brand/src/index.ts`](../packages/util/brand/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-store`([`packages/client/store/src/index.ts`](../packages/client/store/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-test-runtime`([`packages/test-support/client-runtime/src/index.ts`](../packages/test-support/client-runtime/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-primitives`([`packages/client/ui-primitives/src/index.ts`](../packages/client/ui-primitives/src/index.ts))
|
||||
- `@deepseek-ai/dsh-client-ui-slots`([`packages/client/ui-slots/src/index.ts`](../packages/client/ui-slots/src/index.ts))
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/cookbook/adding-a-conversation-node.md
|
||||
adding-a-conversation-node.md: c1965dc8a3081eebb8c1026ac53d2f7b8964edb7
|
||||
adding-a-conversation-node.zh.md: 2986f695b351cd17637d7ff99112c38042950692
|
||||
adding-a-conversation-node.md: daa86f90473cb7023a21e1cfa25339fcd79aa558
|
||||
adding-a-conversation-node.zh.md: 8c6360a99acb49aebadf9a28f440853b18514b9a
|
||||
|
||||
@@ -28,12 +28,13 @@ The example keeps the producer declarations and client contribution in one block
|
||||
|
||||
```ts ignore-check
|
||||
import { createElement } from 'react'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
import type {
|
||||
ClientContext, ConversationLocation, ConversationNodeContext,
|
||||
ConversationLocation, ConversationNodeContext,
|
||||
ConversationNodeDefinition,
|
||||
} from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
} from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-chat/client'
|
||||
|
||||
type ReviewId = Branded<'ReviewId'>
|
||||
|
||||
@@ -94,7 +95,7 @@ declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
||||
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
||||
interface ConversationStepDataMap {
|
||||
'review-job': ReviewChatData
|
||||
}
|
||||
@@ -182,10 +183,10 @@ function ReviewNodeView({ node }: ChatNodeViewProps<'review-job'>) {
|
||||
return createElement('p', null, text)
|
||||
}
|
||||
|
||||
export const inject = ['conversationEvents', 'slots']
|
||||
export const inject = ['uiConversation', 'slots']
|
||||
|
||||
export function apply(ctx: ClientContext): void {
|
||||
ctx.conversationEvents.register(reviewDefinition)
|
||||
ctx.uiConversation.events.register(reviewDefinition)
|
||||
ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({
|
||||
name: 'conversation.chat.node',
|
||||
key: 'review-job',
|
||||
@@ -230,4 +231,4 @@ Add focused tests that establish these outcomes:
|
||||
5. Repeated visible deltas preserve `context.key` and publish at most once per animation frame when requested.
|
||||
6. The keyed renderer consumes `node.data` and constrained Location hooks only; it does not scan the Session event window, Contexts, or Chat Nodes.
|
||||
|
||||
Use [`packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts) for streaming and interruption, [`inbox.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts) plus [`message.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/message.ts) for predecessor queries, and [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables) for a Definition that publishes Turn data without creating its own Node.
|
||||
Use [`packages/client/ui-chat/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/assistant.ts) for streaming and interruption, [`inbox.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/inbox.ts) plus [`message.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/message.ts) for predecessor queries, and [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables) for a Definition that publishes Turn data without creating its own Node.
|
||||
|
||||
@@ -28,12 +28,13 @@
|
||||
|
||||
```ts ignore-check
|
||||
import { createElement } from 'react'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
import type {
|
||||
ClientContext, ConversationLocation, ConversationNodeContext,
|
||||
ConversationLocation, ConversationNodeContext,
|
||||
ConversationNodeDefinition,
|
||||
} from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
} from '@deepseek-ai/dsh-client-ui-conversation/client'
|
||||
import type { ChatNodeViewProps } from '@deepseek-ai/dsh-client-ui-chat/client'
|
||||
|
||||
type ReviewId = Branded<'ReviewId'>
|
||||
|
||||
@@ -94,7 +95,7 @@ declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
||||
declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
|
||||
interface ConversationStepDataMap {
|
||||
'review-job': ReviewChatData
|
||||
}
|
||||
@@ -182,10 +183,10 @@ function ReviewNodeView({ node }: ChatNodeViewProps<'review-job'>) {
|
||||
return createElement('p', null, text)
|
||||
}
|
||||
|
||||
export const inject = ['conversationEvents', 'slots']
|
||||
export const inject = ['uiConversation', 'slots']
|
||||
|
||||
export function apply(ctx: ClientContext): void {
|
||||
ctx.conversationEvents.register(reviewDefinition)
|
||||
ctx.uiConversation.events.register(reviewDefinition)
|
||||
ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({
|
||||
name: 'conversation.chat.node',
|
||||
key: 'review-job',
|
||||
@@ -230,4 +231,4 @@ Assembler 会记录这项依赖。如果后续 older prepend 带来了更近的
|
||||
5. 重复的可见 delta 保持 `context.key`,并在请求 `animation-frame` 时每帧最多发布一次。
|
||||
6. keyed renderer 只消费 `node.data` 与受限 Location hook,不扫描 Session 事件窗口、Context 或 Chat Node。
|
||||
|
||||
流式与中断处理可参考 [`packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/assistant.ts),前序查询可参考 [`inbox.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/inbox.ts) 与 [`message.ts`](../../packages/client/ui-conversation/src/client/conversation-nodes/message.ts),只发布 Turn data 而不创建自有 Node 的例子见 [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables)。
|
||||
流式与中断处理可参考 [`packages/client/ui-chat/src/client/conversation-nodes/assistant.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/assistant.ts),前序查询可参考 [`inbox.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/inbox.ts) 与 [`message.ts`](../../packages/client/ui-chat/src/client/conversation-nodes/message.ts),只发布 Turn data 而不创建自有 Node 的例子见 [`packages/client/ui-deliverables`](../../packages/client/ui-deliverables)。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/cookbook/adding-a-settings-card.md
|
||||
adding-a-settings-card.md: 8fc0f63dfaa932adba25caf1504cfd8cf28c7460
|
||||
adding-a-settings-card.zh.md: 956af879b1c1fcbb018b9420f31b2ae11244b415
|
||||
adding-a-settings-card.md: 6035cc3c586cd319c89fad95c12610d35742708c
|
||||
adding-a-settings-card.zh.md: 79a4372c24f53e3d31b165d9300af591987da1f6
|
||||
|
||||
@@ -48,7 +48,7 @@ export function apply(ctx: Context, config: Config) {
|
||||
The card registers into `settings.plugin.item` under its namespace and owns everything inside it — chrome, controls, and copy. It reads and writes through `ctx.settingsScope`, which fences each write with the revision it read:
|
||||
|
||||
```ts ignore-check
|
||||
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
// Type-only: the keyed slot's declaration. Cross-plugin collaboration goes
|
||||
// through cordis services; a value import fails the client bundle-purity gate.
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'
|
||||
|
||||
@@ -48,7 +48,7 @@ export function apply(ctx: Context, config: Config) {
|
||||
卡片以自己的命名空间为键注册进 `settings.plugin.item`,并拥有其中的一切——外观、控件与文案。它通过 `ctx.settingsScope` 读写,后者用读取时的 revision 为每次写入设栅:
|
||||
|
||||
```ts ignore-check
|
||||
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
||||
// Type-only: the keyed slot's declaration. Cross-plugin collaboration goes
|
||||
// through cordis services; a value import fails the client bundle-purity gate.
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/module-graph.md
|
||||
module-graph.md: ab49462eac55dec981c4a5951a7eb0bfb28b08f0
|
||||
module-graph.zh.md: cf0f12f71fd59370059c5a875dfcaa6c7ae4b4ba
|
||||
module-graph.md: 9bbbb81dc1e5b4aa65619702d380eeb126cfdea3
|
||||
module-graph.zh.md: 86298ce1ed68aa550f5b0b489ee6dccd49771638
|
||||
|
||||
+346
-256
@@ -129,10 +129,12 @@ flowchart TD
|
||||
pkg_client_hmr["client-hmr"]
|
||||
pkg_client_locale["client-locale"]
|
||||
pkg_client_modules["client-modules"]
|
||||
pkg_client_runtime["client-runtime"]
|
||||
pkg_client_store["client-store"]
|
||||
pkg_client_ui_agent_preset["client-ui-agent-preset"]
|
||||
pkg_client_ui_approval["client-ui-approval"]
|
||||
pkg_client_ui_attachment["client-ui-attachment"]
|
||||
pkg_client_ui_brand_official["client-ui-brand-official"]
|
||||
pkg_client_ui_chat["client-ui-chat"]
|
||||
pkg_client_ui_commands["client-ui-commands"]
|
||||
pkg_client_ui_conversation["client-ui-conversation"]
|
||||
pkg_client_ui_deliverables["client-ui-deliverables"]
|
||||
@@ -149,6 +151,7 @@ flowchart TD
|
||||
pkg_client_ui_primitives["client-ui-primitives"]
|
||||
pkg_client_ui_reference["client-ui-reference"]
|
||||
pkg_client_ui_renderer["client-ui-renderer"]
|
||||
pkg_client_ui_session["client-ui-session"]
|
||||
pkg_client_ui_settings["client-ui-settings"]
|
||||
pkg_client_ui_settings_general["client-ui-settings-general"]
|
||||
pkg_client_ui_settings_models["client-ui-settings-models"]
|
||||
@@ -362,7 +365,9 @@ flowchart TD
|
||||
pkg_acp_app --> pkg_invariants
|
||||
pkg_base --> pkg_invariants
|
||||
pkg_sdk_app --> pkg_invariants
|
||||
pkg_client_store --> pkg_invariants
|
||||
pkg_client_ui_primitives --> pkg_invariants
|
||||
pkg_client_ui_renderer --> pkg_invariants
|
||||
pkg_client_ui_slots --> pkg_invariants
|
||||
pkg_client_web --> pkg_invariants
|
||||
pkg_code_runtime --> pkg_invariants
|
||||
@@ -1236,6 +1241,7 @@ flowchart TD
|
||||
pkg_api_session_controller --> pkg_api_gateway
|
||||
pkg_api_session_controller --> pkg_attachment
|
||||
pkg_api_session_controller --> pkg_brand
|
||||
pkg_api_session_controller --> pkg_client_connection
|
||||
pkg_api_session_controller --> pkg_invariants
|
||||
pkg_api_session_controller --> pkg_jobs
|
||||
pkg_api_session_controller --> pkg_llm
|
||||
@@ -1252,6 +1258,7 @@ flowchart TD
|
||||
pkg_api_session_controller --> pkg_typert_registry
|
||||
pkg_api_session_controller --> pkg_workspace
|
||||
pkg_api_workspace_controller --> pkg_api_gateway
|
||||
pkg_api_workspace_controller --> pkg_client_connection
|
||||
pkg_api_workspace_controller --> pkg_invariants
|
||||
pkg_api_workspace_controller --> pkg_session
|
||||
pkg_api_workspace_controller --> pkg_storage_domain
|
||||
@@ -1275,272 +1282,352 @@ flowchart TD
|
||||
pkg_api_remotes --> pkg_settings
|
||||
pkg_api_remotes --> pkg_user_approval
|
||||
pkg_api_remotes --> pkg_user_questions
|
||||
pkg_client_runtime --> pkg_agent
|
||||
pkg_client_runtime --> pkg_api_gateway
|
||||
pkg_client_runtime --> pkg_api_remotes
|
||||
pkg_client_runtime --> pkg_api_session_controller
|
||||
pkg_client_runtime --> pkg_api_workspace_controller
|
||||
pkg_client_runtime --> pkg_attachment
|
||||
pkg_client_runtime --> pkg_client_connection
|
||||
pkg_client_runtime --> pkg_commands
|
||||
pkg_client_runtime --> pkg_host_apiproxy
|
||||
pkg_client_runtime --> pkg_invariants
|
||||
pkg_client_runtime --> pkg_llm
|
||||
pkg_client_runtime --> pkg_llm_retry
|
||||
pkg_client_runtime --> pkg_session
|
||||
pkg_client_runtime --> pkg_session_projection
|
||||
pkg_client_runtime --> pkg_session_title
|
||||
pkg_client_runtime --> pkg_tool_todo
|
||||
pkg_client_runtime --> pkg_tools
|
||||
pkg_client_runtime --> pkg_typert_protocol
|
||||
pkg_client_runtime --> pkg_typert_registry
|
||||
pkg_client_runtime --> pkg_util_crypto
|
||||
pkg_client_ui_renderer --> pkg_client_runtime
|
||||
pkg_client_ui_renderer --> pkg_invariants
|
||||
pkg_client_ui_session --> pkg_api_session_controller
|
||||
pkg_client_ui_session --> pkg_client_ui_renderer
|
||||
pkg_client_ui_session --> pkg_invariants
|
||||
pkg_client_ui_session --> pkg_session
|
||||
pkg_client_ui_settings --> pkg_api_remotes
|
||||
pkg_client_ui_settings --> pkg_client_connection
|
||||
pkg_client_ui_settings --> pkg_client_runtime
|
||||
pkg_client_ui_settings --> pkg_invariants
|
||||
pkg_client_ui_settings --> pkg_settings
|
||||
pkg_client_locale --> pkg_api_remotes
|
||||
pkg_client_locale --> pkg_client_connection
|
||||
pkg_client_locale --> pkg_client_runtime
|
||||
pkg_client_locale --> pkg_client_ui_renderer
|
||||
pkg_client_locale --> pkg_client_ui_settings
|
||||
pkg_client_locale --> pkg_invariants
|
||||
pkg_client_locale --> pkg_settings
|
||||
pkg_client_test_runtime --> pkg_client_runtime
|
||||
pkg_client_test_runtime --> pkg_client_ui_renderer
|
||||
pkg_client_test_runtime --> pkg_client_ui_slots
|
||||
pkg_client_test_runtime --> pkg_host_apiproxy
|
||||
pkg_client_test_runtime --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_client_locale
|
||||
pkg_client_ui_input_trigger --> pkg_client_runtime
|
||||
pkg_client_ui_input_trigger --> pkg_file_reference
|
||||
pkg_client_ui_input_trigger --> pkg_invariants
|
||||
pkg_client_ui_settings_models --> pkg_api_remotes
|
||||
pkg_client_ui_settings_models --> pkg_client_connection
|
||||
pkg_client_ui_settings_models --> pkg_client_locale
|
||||
pkg_client_ui_settings_models --> pkg_client_runtime
|
||||
pkg_client_ui_settings_models --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_models --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_models --> pkg_invariants
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_api_remotes
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_locale
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_runtime
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_invariants
|
||||
pkg_client_ui_settings_plugins --> pkg_api_remotes
|
||||
pkg_client_ui_settings_plugins --> pkg_client_connection
|
||||
pkg_client_ui_settings_plugins --> pkg_client_locale
|
||||
pkg_client_ui_settings_plugins --> pkg_client_runtime
|
||||
pkg_client_ui_settings_plugins --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_plugins --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_plugins --> pkg_invariants
|
||||
pkg_client_ui_theme --> pkg_api_remotes
|
||||
pkg_client_ui_theme --> pkg_client_connection
|
||||
pkg_client_ui_theme --> pkg_client_locale
|
||||
pkg_client_ui_theme --> pkg_client_runtime
|
||||
pkg_client_ui_theme --> pkg_client_ui_renderer
|
||||
pkg_client_ui_theme --> pkg_client_ui_settings
|
||||
pkg_client_ui_theme --> pkg_host_webserver
|
||||
pkg_client_ui_theme --> pkg_invariants
|
||||
pkg_client_ui_theme --> pkg_settings
|
||||
pkg_client_ui_layout --> pkg_client_runtime
|
||||
pkg_client_ui_layout --> pkg_client_ui_renderer
|
||||
pkg_client_ui_layout --> pkg_client_ui_session
|
||||
pkg_client_ui_layout --> pkg_client_ui_theme
|
||||
pkg_client_ui_layout --> pkg_invariants
|
||||
pkg_cordis_client_runner --> pkg_api_remotes
|
||||
pkg_cordis_client_runner --> pkg_client_connection
|
||||
pkg_cordis_client_runner --> pkg_client_modules
|
||||
pkg_cordis_client_runner --> pkg_client_ui_renderer
|
||||
pkg_cordis_client_runner --> pkg_client_ui_theme
|
||||
pkg_cordis_client_runner --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_api_remotes
|
||||
pkg_client_ui_conversation --> pkg_api_session_controller
|
||||
pkg_client_ui_conversation --> pkg_api_workspace_controller
|
||||
pkg_client_ui_conversation --> pkg_attachment
|
||||
pkg_client_ui_conversation --> pkg_brand
|
||||
pkg_client_ui_conversation --> pkg_client_locale
|
||||
pkg_client_ui_conversation --> pkg_client_ui_layout
|
||||
pkg_client_ui_conversation --> pkg_client_ui_renderer
|
||||
pkg_client_ui_conversation --> pkg_client_ui_session
|
||||
pkg_client_ui_conversation --> pkg_client_ui_settings
|
||||
pkg_client_ui_conversation --> pkg_client_ui_workspace
|
||||
pkg_client_ui_conversation --> pkg_commands
|
||||
pkg_client_ui_conversation --> pkg_goal
|
||||
pkg_client_ui_conversation --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_llm
|
||||
pkg_client_ui_conversation --> pkg_llm_retry
|
||||
pkg_client_ui_conversation --> pkg_permission_presets
|
||||
pkg_client_ui_conversation --> pkg_plan_mode
|
||||
pkg_client_ui_conversation --> pkg_session
|
||||
pkg_client_ui_conversation --> pkg_settings
|
||||
pkg_client_ui_conversation --> pkg_token_meter
|
||||
pkg_client_ui_conversation --> pkg_tool_todo
|
||||
pkg_client_ui_conversation --> pkg_util_crypto
|
||||
pkg_client_ui_conversation --> pkg_workspace
|
||||
pkg_client_ui_sidebar --> pkg_api_workspace_controller
|
||||
pkg_client_ui_sidebar --> pkg_client_locale
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_layout
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_renderer
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_session
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_workspace
|
||||
pkg_client_ui_sidebar --> pkg_invariants
|
||||
pkg_client_ui_workspace --> pkg_api_session_controller
|
||||
pkg_client_ui_workspace --> pkg_api_workspace_controller
|
||||
pkg_client_ui_workspace --> pkg_client_connection
|
||||
pkg_client_ui_workspace --> pkg_client_locale
|
||||
pkg_client_ui_workspace --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workspace --> pkg_client_ui_renderer
|
||||
pkg_client_ui_workspace --> pkg_client_ui_session
|
||||
pkg_client_ui_workspace --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_workspace --> pkg_invariants
|
||||
pkg_client_ui_workspace --> pkg_session
|
||||
pkg_client_ui_agent_preset --> pkg_api_remotes
|
||||
pkg_client_ui_agent_preset --> pkg_api_session_controller
|
||||
pkg_client_ui_agent_preset --> pkg_client_connection
|
||||
pkg_client_ui_agent_preset --> pkg_client_locale
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_conversation
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_renderer
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_session
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_settings
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_workspace
|
||||
pkg_client_ui_agent_preset --> pkg_invariants
|
||||
pkg_client_ui_agent_preset --> pkg_session
|
||||
pkg_client_ui_approval --> pkg_api_remotes
|
||||
pkg_client_ui_approval --> pkg_api_session_controller
|
||||
pkg_client_ui_approval --> pkg_client_locale
|
||||
pkg_client_ui_approval --> pkg_client_ui_conversation
|
||||
pkg_client_ui_approval --> pkg_client_ui_renderer
|
||||
pkg_client_ui_approval --> pkg_client_ui_session
|
||||
pkg_client_ui_approval --> pkg_invariants
|
||||
pkg_client_ui_approval --> pkg_llm
|
||||
pkg_client_ui_approval --> pkg_session
|
||||
pkg_client_ui_approval --> pkg_typert_protocol
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_conversation
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_renderer
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_brand_official --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_connection
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_locale
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_renderer
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_browse --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_renderer
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_native --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_api_session_controller
|
||||
pkg_client_ui_input_trigger --> pkg_client_locale
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_conversation
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_renderer
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_session
|
||||
pkg_client_ui_input_trigger --> pkg_file_reference
|
||||
pkg_client_ui_input_trigger --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_session
|
||||
pkg_client_ui_jobs --> pkg_api_session_controller
|
||||
pkg_client_ui_jobs --> pkg_client_locale
|
||||
pkg_client_ui_jobs --> pkg_client_ui_conversation
|
||||
pkg_client_ui_jobs --> pkg_client_ui_renderer
|
||||
pkg_client_ui_jobs --> pkg_client_ui_session
|
||||
pkg_client_ui_jobs --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_api_remotes
|
||||
pkg_client_ui_plan --> pkg_client_locale
|
||||
pkg_client_ui_plan --> pkg_client_ui_conversation
|
||||
pkg_client_ui_plan --> pkg_client_ui_renderer
|
||||
pkg_client_ui_plan --> pkg_client_ui_session
|
||||
pkg_client_ui_plan --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_plan_mode
|
||||
pkg_client_ui_plan --> pkg_session
|
||||
pkg_client_ui_settings_general --> pkg_api_remotes
|
||||
pkg_client_ui_settings_general --> pkg_client_connection
|
||||
pkg_client_ui_settings_general --> pkg_client_locale
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_session
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_settings_general --> pkg_invariants
|
||||
pkg_client_ui_settings_general --> pkg_settings
|
||||
pkg_client_ui_trajectory --> pkg_agent
|
||||
pkg_client_ui_trajectory --> pkg_api_session_controller
|
||||
pkg_client_ui_trajectory --> pkg_client_locale
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_conversation
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_renderer
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_session
|
||||
pkg_client_ui_trajectory --> pkg_compaction
|
||||
pkg_client_ui_trajectory --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_session
|
||||
pkg_client_ui_trajectory --> pkg_tools
|
||||
pkg_client_ui_user_questions --> pkg_api_remotes
|
||||
pkg_client_ui_user_questions --> pkg_api_session_controller
|
||||
pkg_client_ui_user_questions --> pkg_client_locale
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_conversation
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_renderer
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_session
|
||||
pkg_client_ui_user_questions --> pkg_invariants
|
||||
pkg_client_ui_user_questions --> pkg_session
|
||||
pkg_client_ui_user_questions --> pkg_typert_protocol
|
||||
pkg_client_ui_user_questions --> pkg_user_questions
|
||||
pkg_client_ui_chat --> pkg_agent
|
||||
pkg_client_ui_chat --> pkg_api_remotes
|
||||
pkg_client_ui_chat --> pkg_api_session_controller
|
||||
pkg_client_ui_chat --> pkg_api_workspace_controller
|
||||
pkg_client_ui_chat --> pkg_attachment
|
||||
pkg_client_ui_chat --> pkg_client_locale
|
||||
pkg_client_ui_chat --> pkg_client_ui_approval
|
||||
pkg_client_ui_chat --> pkg_client_ui_conversation
|
||||
pkg_client_ui_chat --> pkg_client_ui_layout
|
||||
pkg_client_ui_chat --> pkg_client_ui_renderer
|
||||
pkg_client_ui_chat --> pkg_client_ui_session
|
||||
pkg_client_ui_chat --> pkg_client_ui_workspace
|
||||
pkg_client_ui_chat --> pkg_commands
|
||||
pkg_client_ui_chat --> pkg_compaction
|
||||
pkg_client_ui_chat --> pkg_invariants
|
||||
pkg_client_ui_chat --> pkg_llm
|
||||
pkg_client_ui_chat --> pkg_llm_retry
|
||||
pkg_client_ui_chat --> pkg_session
|
||||
pkg_client_ui_chat --> pkg_session_stats
|
||||
pkg_client_ui_chat --> pkg_token_meter
|
||||
pkg_client_ui_chat --> pkg_tools
|
||||
pkg_client_ui_commands --> pkg_api_remotes
|
||||
pkg_client_ui_commands --> pkg_api_session_controller
|
||||
pkg_client_ui_commands --> pkg_client_locale
|
||||
pkg_client_ui_commands --> pkg_client_ui_conversation
|
||||
pkg_client_ui_commands --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_commands --> pkg_client_ui_renderer
|
||||
pkg_client_ui_commands --> pkg_client_ui_session
|
||||
pkg_client_ui_commands --> pkg_commands
|
||||
pkg_client_ui_commands --> pkg_invariants
|
||||
pkg_client_ui_commands --> pkg_session
|
||||
pkg_client_ui_reference --> pkg_api_remotes
|
||||
pkg_client_ui_reference --> pkg_client_locale
|
||||
pkg_client_ui_reference --> pkg_client_runtime
|
||||
pkg_client_ui_reference --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_reference --> pkg_file_reference
|
||||
pkg_client_ui_reference --> pkg_invariants
|
||||
pkg_client_ui_reference --> pkg_session_reference
|
||||
pkg_client_ui_reference --> pkg_typert_protocol
|
||||
pkg_cordis_client_runner --> pkg_api_remotes
|
||||
pkg_cordis_client_runner --> pkg_client_connection
|
||||
pkg_cordis_client_runner --> pkg_client_modules
|
||||
pkg_cordis_client_runner --> pkg_client_runtime
|
||||
pkg_cordis_client_runner --> pkg_client_ui_theme
|
||||
pkg_cordis_client_runner --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_agent
|
||||
pkg_client_ui_conversation --> pkg_api_remotes
|
||||
pkg_client_ui_conversation --> pkg_attachment
|
||||
pkg_client_ui_conversation --> pkg_brand
|
||||
pkg_client_ui_conversation --> pkg_client_connection
|
||||
pkg_client_ui_conversation --> pkg_client_locale
|
||||
pkg_client_ui_conversation --> pkg_client_runtime
|
||||
pkg_client_ui_conversation --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_conversation --> pkg_client_ui_layout
|
||||
pkg_client_ui_conversation --> pkg_client_ui_settings
|
||||
pkg_client_ui_conversation --> pkg_commands
|
||||
pkg_client_ui_conversation --> pkg_compaction
|
||||
pkg_client_ui_conversation --> pkg_goal
|
||||
pkg_client_ui_conversation --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_llm_retry
|
||||
pkg_client_ui_conversation --> pkg_permission_presets
|
||||
pkg_client_ui_conversation --> pkg_plan_mode
|
||||
pkg_client_ui_conversation --> pkg_session_stats
|
||||
pkg_client_ui_conversation --> pkg_settings
|
||||
pkg_client_ui_conversation --> pkg_token_meter
|
||||
pkg_client_ui_conversation --> pkg_tool_todo
|
||||
pkg_client_ui_conversation --> pkg_tools
|
||||
pkg_client_ui_conversation --> pkg_util_crypto
|
||||
pkg_client_ui_sidebar --> pkg_client_locale
|
||||
pkg_client_ui_sidebar --> pkg_client_runtime
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_layout
|
||||
pkg_client_ui_sidebar --> pkg_invariants
|
||||
pkg_client_ui_agent_preset --> pkg_api_remotes
|
||||
pkg_client_ui_agent_preset --> pkg_client_connection
|
||||
pkg_client_ui_agent_preset --> pkg_client_locale
|
||||
pkg_client_ui_agent_preset --> pkg_client_runtime
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_conversation
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_settings
|
||||
pkg_client_ui_agent_preset --> pkg_invariants
|
||||
pkg_client_ui_attachment --> pkg_attachment
|
||||
pkg_client_ui_attachment --> pkg_client_runtime
|
||||
pkg_client_ui_attachment --> pkg_client_ui_conversation
|
||||
pkg_client_ui_attachment --> pkg_invariants
|
||||
pkg_client_ui_brand_official --> pkg_client_runtime
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_conversation
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_brand_official --> pkg_invariants
|
||||
pkg_client_ui_commands --> pkg_api_remotes
|
||||
pkg_client_ui_commands --> pkg_client_locale
|
||||
pkg_client_ui_commands --> pkg_client_runtime
|
||||
pkg_client_ui_commands --> pkg_client_ui_conversation
|
||||
pkg_client_ui_commands --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_commands --> pkg_commands
|
||||
pkg_client_ui_commands --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_client_connection
|
||||
pkg_client_ui_deliverables --> pkg_client_locale
|
||||
pkg_client_ui_deliverables --> pkg_client_runtime
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_conversation
|
||||
pkg_client_ui_deliverables --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_system_prompt
|
||||
pkg_client_ui_goal --> pkg_api_remotes
|
||||
pkg_client_ui_goal --> pkg_client_locale
|
||||
pkg_client_ui_goal --> pkg_client_runtime
|
||||
pkg_client_ui_goal --> pkg_client_ui_conversation
|
||||
pkg_client_ui_goal --> pkg_commands
|
||||
pkg_client_ui_goal --> pkg_goal
|
||||
pkg_client_ui_goal --> pkg_invariants
|
||||
pkg_client_ui_goal --> pkg_session
|
||||
pkg_client_ui_goal --> pkg_typert_protocol
|
||||
pkg_client_ui_jobs --> pkg_client_locale
|
||||
pkg_client_ui_jobs --> pkg_client_runtime
|
||||
pkg_client_ui_jobs --> pkg_client_ui_conversation
|
||||
pkg_client_ui_jobs --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_api_remotes
|
||||
pkg_client_ui_message_feedback --> pkg_client_connection
|
||||
pkg_client_ui_message_feedback --> pkg_client_locale
|
||||
pkg_client_ui_message_feedback --> pkg_client_runtime
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_conversation
|
||||
pkg_client_ui_message_feedback --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_message_feedback
|
||||
pkg_client_ui_message_feedback --> pkg_typert_protocol
|
||||
pkg_client_ui_plan --> pkg_api_remotes
|
||||
pkg_client_ui_plan --> pkg_client_locale
|
||||
pkg_client_ui_plan --> pkg_client_runtime
|
||||
pkg_client_ui_plan --> pkg_client_ui_conversation
|
||||
pkg_client_ui_plan --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_plan_mode
|
||||
pkg_client_ui_settings_general --> pkg_api_remotes
|
||||
pkg_client_ui_settings_general --> pkg_client_connection
|
||||
pkg_client_ui_settings_general --> pkg_client_locale
|
||||
pkg_client_ui_settings_general --> pkg_client_runtime
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_settings_general --> pkg_invariants
|
||||
pkg_client_ui_settings_general --> pkg_settings
|
||||
pkg_client_ui_subagent --> pkg_api_session_controller
|
||||
pkg_client_ui_subagent --> pkg_client_connection
|
||||
pkg_client_ui_subagent --> pkg_client_locale
|
||||
pkg_client_ui_subagent --> pkg_client_runtime
|
||||
pkg_client_ui_subagent --> pkg_client_ui_conversation
|
||||
pkg_client_ui_subagent --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_subagent --> pkg_client_ui_renderer
|
||||
pkg_client_ui_subagent --> pkg_client_ui_session
|
||||
pkg_client_ui_subagent --> pkg_invariants
|
||||
pkg_client_ui_subagent --> pkg_session
|
||||
pkg_client_ui_subagent --> pkg_subagent
|
||||
pkg_client_ui_subagent --> pkg_token_meter
|
||||
pkg_client_ui_tool --> pkg_api_remotes
|
||||
pkg_client_ui_tool --> pkg_client_connection
|
||||
pkg_client_ui_tool --> pkg_client_locale
|
||||
pkg_client_ui_tool --> pkg_client_runtime
|
||||
pkg_client_ui_tool --> pkg_client_ui_conversation
|
||||
pkg_client_ui_tool --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_agent
|
||||
pkg_client_ui_trajectory --> pkg_client_locale
|
||||
pkg_client_ui_trajectory --> pkg_client_runtime
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_conversation
|
||||
pkg_client_ui_trajectory --> pkg_compaction
|
||||
pkg_client_ui_trajectory --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_tools
|
||||
pkg_client_ui_user_questions --> pkg_api_remotes
|
||||
pkg_client_ui_user_questions --> pkg_client_locale
|
||||
pkg_client_ui_user_questions --> pkg_client_runtime
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_conversation
|
||||
pkg_client_ui_user_questions --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_client_locale
|
||||
pkg_client_ui_workflow_run --> pkg_client_runtime
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workflow_run --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_session
|
||||
pkg_client_ui_workflow_run --> pkg_tool_workflow
|
||||
pkg_client_ui_workflow_run --> pkg_workflow
|
||||
pkg_client_ui_workspace --> pkg_client_connection
|
||||
pkg_client_ui_workspace --> pkg_client_locale
|
||||
pkg_client_ui_workspace --> pkg_client_runtime
|
||||
pkg_client_ui_workspace --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workspace --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_workspace --> pkg_invariants
|
||||
pkg_session_log_export --> pkg_client_locale
|
||||
pkg_session_log_export --> pkg_client_runtime
|
||||
pkg_session_log_export --> pkg_client_ui_commands
|
||||
pkg_session_log_export --> pkg_client_ui_conversation
|
||||
pkg_session_log_export --> pkg_commands
|
||||
pkg_session_log_export --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_locale
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_runtime
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_browse --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_runtime
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_native --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_api_remotes
|
||||
pkg_client_ui_model_selection --> pkg_api_session_controller
|
||||
pkg_client_ui_model_selection --> pkg_client_connection
|
||||
pkg_client_ui_model_selection --> pkg_client_locale
|
||||
pkg_client_ui_model_selection --> pkg_client_runtime
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_commands
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_conversation
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_model_selection --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_typert_protocol
|
||||
pkg_client_ui_permission_presets --> pkg_api_remotes
|
||||
pkg_client_ui_permission_presets --> pkg_client_connection
|
||||
pkg_client_ui_permission_presets --> pkg_client_locale
|
||||
pkg_client_ui_permission_presets --> pkg_client_runtime
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_commands
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_settings
|
||||
pkg_client_ui_permission_presets --> pkg_invariants
|
||||
pkg_client_ui_permission_presets --> pkg_permission_presets
|
||||
pkg_client_ui_skill --> pkg_api_remotes
|
||||
pkg_client_ui_skill --> pkg_client_connection
|
||||
pkg_client_ui_skill --> pkg_client_locale
|
||||
pkg_client_ui_skill --> pkg_client_runtime
|
||||
pkg_client_ui_skill --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_skill --> pkg_client_ui_tool
|
||||
pkg_client_ui_skill --> pkg_invariants
|
||||
pkg_client_ui_cordis --> pkg_api_remotes
|
||||
pkg_client_ui_cordis --> pkg_client_connection
|
||||
pkg_client_ui_cordis --> pkg_client_locale
|
||||
pkg_client_ui_cordis --> pkg_client_runtime
|
||||
pkg_client_ui_cordis --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_cordis --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_cordis --> pkg_client_ui_tool
|
||||
pkg_client_ui_cordis --> pkg_cordis_client_runner
|
||||
pkg_client_ui_cordis --> pkg_invariants
|
||||
pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_browse
|
||||
pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_native
|
||||
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
|
||||
pkg_host_directory_picker_auto --> pkg_host_directory_picker_native
|
||||
pkg_host_directory_picker_auto --> pkg_host_webserver
|
||||
pkg_host_directory_picker_auto --> pkg_invariants
|
||||
pkg_session_log_export --> pkg_client_locale
|
||||
pkg_session_log_export --> pkg_client_ui_commands
|
||||
pkg_session_log_export --> pkg_client_ui_conversation
|
||||
pkg_session_log_export --> pkg_client_ui_renderer
|
||||
pkg_session_log_export --> pkg_client_ui_session
|
||||
pkg_session_log_export --> pkg_commands
|
||||
pkg_session_log_export --> pkg_invariants
|
||||
pkg_client_ui_attachment --> pkg_attachment
|
||||
pkg_client_ui_attachment --> pkg_client_ui_chat
|
||||
pkg_client_ui_attachment --> pkg_client_ui_conversation
|
||||
pkg_client_ui_attachment --> pkg_client_ui_renderer
|
||||
pkg_client_ui_attachment --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_client_connection
|
||||
pkg_client_ui_deliverables --> pkg_client_locale
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_chat
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_conversation
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_renderer
|
||||
pkg_client_ui_deliverables --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_session
|
||||
pkg_client_ui_deliverables --> pkg_system_prompt
|
||||
pkg_client_ui_goal --> pkg_api_remotes
|
||||
pkg_client_ui_goal --> pkg_api_session_controller
|
||||
pkg_client_ui_goal --> pkg_client_locale
|
||||
pkg_client_ui_goal --> pkg_client_ui_chat
|
||||
pkg_client_ui_goal --> pkg_client_ui_conversation
|
||||
pkg_client_ui_goal --> pkg_client_ui_renderer
|
||||
pkg_client_ui_goal --> pkg_client_ui_session
|
||||
pkg_client_ui_goal --> pkg_commands
|
||||
pkg_client_ui_goal --> pkg_goal
|
||||
pkg_client_ui_goal --> pkg_invariants
|
||||
pkg_client_ui_goal --> pkg_session
|
||||
pkg_client_ui_goal --> pkg_typert_protocol
|
||||
pkg_client_ui_message_feedback --> pkg_api_remotes
|
||||
pkg_client_ui_message_feedback --> pkg_client_connection
|
||||
pkg_client_ui_message_feedback --> pkg_client_locale
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_chat
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_conversation
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_renderer
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_session
|
||||
pkg_client_ui_message_feedback --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_message_feedback
|
||||
pkg_client_ui_message_feedback --> pkg_session
|
||||
pkg_client_ui_message_feedback --> pkg_typert_protocol
|
||||
pkg_client_ui_model_selection --> pkg_api_remotes
|
||||
pkg_client_ui_model_selection --> pkg_api_session_controller
|
||||
pkg_client_ui_model_selection --> pkg_client_connection
|
||||
pkg_client_ui_model_selection --> pkg_client_locale
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_commands
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_conversation
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_renderer
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_session
|
||||
pkg_client_ui_model_selection --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_session
|
||||
pkg_client_ui_model_selection --> pkg_typert_protocol
|
||||
pkg_client_ui_permission_presets --> pkg_api_remotes
|
||||
pkg_client_ui_permission_presets --> pkg_api_session_controller
|
||||
pkg_client_ui_permission_presets --> pkg_client_connection
|
||||
pkg_client_ui_permission_presets --> pkg_client_locale
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_commands
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_renderer
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_session
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_settings
|
||||
pkg_client_ui_permission_presets --> pkg_invariants
|
||||
pkg_client_ui_permission_presets --> pkg_permission_presets
|
||||
pkg_client_ui_tool --> pkg_api_remotes
|
||||
pkg_client_ui_tool --> pkg_api_workspace_controller
|
||||
pkg_client_ui_tool --> pkg_client_connection
|
||||
pkg_client_ui_tool --> pkg_client_locale
|
||||
pkg_client_ui_tool --> pkg_client_ui_chat
|
||||
pkg_client_ui_tool --> pkg_client_ui_conversation
|
||||
pkg_client_ui_tool --> pkg_client_ui_renderer
|
||||
pkg_client_ui_tool --> pkg_client_ui_session
|
||||
pkg_client_ui_tool --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_api_session_controller
|
||||
pkg_client_ui_workflow_run --> pkg_client_locale
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_chat
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_renderer
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_session
|
||||
pkg_client_ui_workflow_run --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_session
|
||||
pkg_client_ui_workflow_run --> pkg_tool_workflow
|
||||
pkg_client_ui_workflow_run --> pkg_workflow
|
||||
pkg_client_test_runtime --> pkg_api_session_controller
|
||||
pkg_client_test_runtime --> pkg_api_workspace_controller
|
||||
pkg_client_test_runtime --> pkg_attachment
|
||||
pkg_client_test_runtime --> pkg_client_connection
|
||||
pkg_client_test_runtime --> pkg_client_store
|
||||
pkg_client_test_runtime --> pkg_client_ui_chat
|
||||
pkg_client_test_runtime --> pkg_client_ui_conversation
|
||||
pkg_client_test_runtime --> pkg_client_ui_renderer
|
||||
pkg_client_test_runtime --> pkg_client_ui_session
|
||||
pkg_client_test_runtime --> pkg_client_ui_settings
|
||||
pkg_client_test_runtime --> pkg_client_ui_slots
|
||||
pkg_client_test_runtime --> pkg_invariants
|
||||
pkg_client_test_runtime --> pkg_session
|
||||
pkg_client_ui_skill --> pkg_api_remotes
|
||||
pkg_client_ui_skill --> pkg_api_session_controller
|
||||
pkg_client_ui_skill --> pkg_client_connection
|
||||
pkg_client_ui_skill --> pkg_client_locale
|
||||
pkg_client_ui_skill --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_skill --> pkg_client_ui_renderer
|
||||
pkg_client_ui_skill --> pkg_client_ui_tool
|
||||
pkg_client_ui_skill --> pkg_invariants
|
||||
pkg_client_ui_skill --> pkg_session
|
||||
pkg_client_ui_cordis --> pkg_api_remotes
|
||||
pkg_client_ui_cordis --> pkg_client_connection
|
||||
pkg_client_ui_cordis --> pkg_client_locale
|
||||
pkg_client_ui_cordis --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_cordis --> pkg_client_ui_renderer
|
||||
pkg_client_ui_cordis --> pkg_client_ui_session
|
||||
pkg_client_ui_cordis --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_cordis --> pkg_client_ui_tool
|
||||
pkg_client_ui_cordis --> pkg_cordis_client_runner
|
||||
pkg_client_ui_cordis --> pkg_invariants
|
||||
```
|
||||
|
||||
| Package | Group | Depends on |
|
||||
@@ -1560,7 +1647,9 @@ flowchart TD
|
||||
| [`acp-app`](../packages/bundle/acp-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`base`](../packages/bundle/base) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`sdk-app`](../packages/bundle/sdk-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-store`](../packages/client/store) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-primitives`](../packages/client/ui-primitives) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-renderer`](../packages/client/ui-renderer) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-slots`](../packages/client/ui-slots) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-web`](../packages/client/web) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`code-runtime`](../packages/code-runtime/code-runtime) | `code-runtime` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
@@ -1742,45 +1831,46 @@ flowchart TD
|
||||
| [`sdk-client`](../packages/sdk/client) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session) |
|
||||
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
|
||||
| [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |
|
||||
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-workspace-controller`](../packages/api/workspace-controller) | `api` | [`api-gateway`](../packages/api/gateway), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`storage-domain`](../packages/storage/storage-domain), [`typert-protocol`](../packages/typert/protocol), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-workspace-controller`](../packages/api/workspace-controller) | `api` | [`api-gateway`](../packages/api/gateway), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`storage-domain`](../packages/storage/storage-domain), [`typert-protocol`](../packages/typert/protocol), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-remotes`](../packages/api/remotes) | `api` | [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`commands`](../packages/interaction/commands), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`goal`](../packages/goal/goal), [`host-plugin-inventory`](../packages/host/plugin-inventory), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`message-feedback`](../packages/feedback/message-feedback), [`session`](../packages/core/session), [`session-reference`](../packages/context/session-reference), [`settings`](../packages/settings/settings), [`user-approval`](../packages/interaction/user-approval), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`client-runtime`](../packages/client/runtime) | `client` | [`agent`](../packages/core/agent), [`api-gateway`](../packages/api/gateway), [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`commands`](../packages/interaction/commands), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`session-title`](../packages/session/session-title), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-crypto`](../packages/util/crypto) |
|
||||
| [`client-ui-renderer`](../packages/client/ui-renderer) | `client` | [`client-runtime`](../packages/client/runtime), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-locale`](../packages/client/locale) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`client-runtime`](../packages/client/runtime), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-slots`](../packages/client/ui-slots), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-input-trigger`](../packages/client/ui-input-trigger) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-models`](../packages/client/ui-settings-models) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugin-inventory`](../packages/client/ui-settings-plugin-inventory) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugins`](../packages/client/ui-settings-plugins) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-theme`](../packages/client/ui-theme) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-layout`](../packages/client/ui-layout) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-reference`](../packages/client/ui-reference) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session-reference`](../packages/context/session-reference), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`cordis-client-runner`](../packages/extensions/cordis-client-runner) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-modules`](../packages/client/modules), [`client-runtime`](../packages/client/runtime), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`agent`](../packages/core/agent), [`api-remotes`](../packages/api/remotes), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-settings`](../packages/client/ui-settings), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`session-stats`](../packages/session/session-stats), [`settings`](../packages/settings/settings), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`util-crypto`](../packages/util/crypto) |
|
||||
| [`client-ui-sidebar`](../packages/client/ui-sidebar) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-layout`](../packages/client/ui-layout), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-attachment`](../packages/client/ui-attachment) | `client` | [`attachment`](../packages/attachment/attachment), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-brand-official`](../packages/client/ui-brand-official) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-commands`](../packages/client/ui-commands) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-jobs`](../packages/client/ui-jobs) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-message-feedback`](../packages/client/ui-message-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`plan-mode`](../packages/plan/plan-mode) |
|
||||
| [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`invariants`](../packages/runtime-diagnostics/invariants), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
|
||||
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-user-questions`](../packages/client/ui-user-questions) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workflow-run`](../packages/client/ui-workflow-run) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`client-ui-workspace`](../packages/client/ui-workspace) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`session-log-export`](../packages/session-query/session-log-export) | `session-query` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-model-selection`](../packages/client/ui-model-selection) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`invariants`](../packages/runtime-diagnostics/invariants), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-permission-presets`](../packages/client/ui-permission-presets) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`permission-presets`](../packages/interaction/permission-presets) |
|
||||
| [`client-ui-skill`](../packages/client/ui-skill) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-tool`](../packages/client/ui-tool), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-tool`](../packages/client/ui-tool), [`cordis-client-runner`](../packages/extensions/cordis-client-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-session`](../packages/client/ui-session) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-locale`](../packages/client/locale) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-settings-models`](../packages/client/ui-settings-models) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugin-inventory`](../packages/client/ui-settings-plugin-inventory) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugins`](../packages/client/ui-settings-plugins) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-theme`](../packages/client/ui-theme) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-layout`](../packages/client/ui-layout) | `client` | [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`cordis-client-runner`](../packages/extensions/cordis-client-runner) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-modules`](../packages/client/modules), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-locale`](../packages/client/locale), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-workspace`](../packages/client/ui-workspace), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`session`](../packages/core/session), [`settings`](../packages/settings/settings), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`util-crypto`](../packages/util/crypto), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`client-ui-sidebar`](../packages/client/ui-sidebar) | `client` | [`api-workspace-controller`](../packages/api/workspace-controller), [`client-locale`](../packages/client/locale), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workspace`](../packages/client/ui-workspace) | `client` | [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-approval`](../packages/client/ui-approval) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-brand-official`](../packages/client/ui-brand-official) | `client` | [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native) | `client` | [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-input-trigger`](../packages/client/ui-input-trigger) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-jobs`](../packages/client/ui-jobs) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`plan-mode`](../packages/plan/plan-mode), [`session`](../packages/core/session) |
|
||||
| [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-user-questions`](../packages/client/ui-user-questions) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`client-ui-chat`](../packages/client/ui-chat) | `client` | [`agent`](../packages/core/agent), [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-locale`](../packages/client/locale), [`client-ui-approval`](../packages/client/ui-approval), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-workspace`](../packages/client/ui-workspace), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-stats`](../packages/session/session-stats), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-commands`](../packages/client/ui-commands) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-reference`](../packages/client/ui-reference) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session-reference`](../packages/context/session-reference), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
|
||||
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse), [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native), [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`session-log-export`](../packages/session-query/session-log-export) | `session-query` | [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-attachment`](../packages/client/ui-attachment) | `client` | [`attachment`](../packages/attachment/attachment), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-message-feedback`](../packages/client/ui-message-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-model-selection`](../packages/client/ui-model-selection) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-permission-presets`](../packages/client/ui-permission-presets) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`permission-presets`](../packages/interaction/permission-presets) |
|
||||
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`api-remotes`](../packages/api/remotes), [`api-workspace-controller`](../packages/api/workspace-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workflow-run`](../packages/client/ui-workflow-run) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-store`](../packages/client/store), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-skill`](../packages/client/ui-skill) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-tool`](../packages/client/ui-tool), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-tool`](../packages/client/ui-tool), [`cordis-client-runner`](../packages/extensions/cordis-client-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
|
||||
+346
-256
@@ -131,10 +131,12 @@ flowchart TD
|
||||
pkg_client_hmr["client-hmr"]
|
||||
pkg_client_locale["client-locale"]
|
||||
pkg_client_modules["client-modules"]
|
||||
pkg_client_runtime["client-runtime"]
|
||||
pkg_client_store["client-store"]
|
||||
pkg_client_ui_agent_preset["client-ui-agent-preset"]
|
||||
pkg_client_ui_approval["client-ui-approval"]
|
||||
pkg_client_ui_attachment["client-ui-attachment"]
|
||||
pkg_client_ui_brand_official["client-ui-brand-official"]
|
||||
pkg_client_ui_chat["client-ui-chat"]
|
||||
pkg_client_ui_commands["client-ui-commands"]
|
||||
pkg_client_ui_conversation["client-ui-conversation"]
|
||||
pkg_client_ui_deliverables["client-ui-deliverables"]
|
||||
@@ -151,6 +153,7 @@ flowchart TD
|
||||
pkg_client_ui_primitives["client-ui-primitives"]
|
||||
pkg_client_ui_reference["client-ui-reference"]
|
||||
pkg_client_ui_renderer["client-ui-renderer"]
|
||||
pkg_client_ui_session["client-ui-session"]
|
||||
pkg_client_ui_settings["client-ui-settings"]
|
||||
pkg_client_ui_settings_general["client-ui-settings-general"]
|
||||
pkg_client_ui_settings_models["client-ui-settings-models"]
|
||||
@@ -364,7 +367,9 @@ flowchart TD
|
||||
pkg_acp_app --> pkg_invariants
|
||||
pkg_base --> pkg_invariants
|
||||
pkg_sdk_app --> pkg_invariants
|
||||
pkg_client_store --> pkg_invariants
|
||||
pkg_client_ui_primitives --> pkg_invariants
|
||||
pkg_client_ui_renderer --> pkg_invariants
|
||||
pkg_client_ui_slots --> pkg_invariants
|
||||
pkg_client_web --> pkg_invariants
|
||||
pkg_code_runtime --> pkg_invariants
|
||||
@@ -1238,6 +1243,7 @@ flowchart TD
|
||||
pkg_api_session_controller --> pkg_api_gateway
|
||||
pkg_api_session_controller --> pkg_attachment
|
||||
pkg_api_session_controller --> pkg_brand
|
||||
pkg_api_session_controller --> pkg_client_connection
|
||||
pkg_api_session_controller --> pkg_invariants
|
||||
pkg_api_session_controller --> pkg_jobs
|
||||
pkg_api_session_controller --> pkg_llm
|
||||
@@ -1254,6 +1260,7 @@ flowchart TD
|
||||
pkg_api_session_controller --> pkg_typert_registry
|
||||
pkg_api_session_controller --> pkg_workspace
|
||||
pkg_api_workspace_controller --> pkg_api_gateway
|
||||
pkg_api_workspace_controller --> pkg_client_connection
|
||||
pkg_api_workspace_controller --> pkg_invariants
|
||||
pkg_api_workspace_controller --> pkg_session
|
||||
pkg_api_workspace_controller --> pkg_storage_domain
|
||||
@@ -1277,272 +1284,352 @@ flowchart TD
|
||||
pkg_api_remotes --> pkg_settings
|
||||
pkg_api_remotes --> pkg_user_approval
|
||||
pkg_api_remotes --> pkg_user_questions
|
||||
pkg_client_runtime --> pkg_agent
|
||||
pkg_client_runtime --> pkg_api_gateway
|
||||
pkg_client_runtime --> pkg_api_remotes
|
||||
pkg_client_runtime --> pkg_api_session_controller
|
||||
pkg_client_runtime --> pkg_api_workspace_controller
|
||||
pkg_client_runtime --> pkg_attachment
|
||||
pkg_client_runtime --> pkg_client_connection
|
||||
pkg_client_runtime --> pkg_commands
|
||||
pkg_client_runtime --> pkg_host_apiproxy
|
||||
pkg_client_runtime --> pkg_invariants
|
||||
pkg_client_runtime --> pkg_llm
|
||||
pkg_client_runtime --> pkg_llm_retry
|
||||
pkg_client_runtime --> pkg_session
|
||||
pkg_client_runtime --> pkg_session_projection
|
||||
pkg_client_runtime --> pkg_session_title
|
||||
pkg_client_runtime --> pkg_tool_todo
|
||||
pkg_client_runtime --> pkg_tools
|
||||
pkg_client_runtime --> pkg_typert_protocol
|
||||
pkg_client_runtime --> pkg_typert_registry
|
||||
pkg_client_runtime --> pkg_util_crypto
|
||||
pkg_client_ui_renderer --> pkg_client_runtime
|
||||
pkg_client_ui_renderer --> pkg_invariants
|
||||
pkg_client_ui_session --> pkg_api_session_controller
|
||||
pkg_client_ui_session --> pkg_client_ui_renderer
|
||||
pkg_client_ui_session --> pkg_invariants
|
||||
pkg_client_ui_session --> pkg_session
|
||||
pkg_client_ui_settings --> pkg_api_remotes
|
||||
pkg_client_ui_settings --> pkg_client_connection
|
||||
pkg_client_ui_settings --> pkg_client_runtime
|
||||
pkg_client_ui_settings --> pkg_invariants
|
||||
pkg_client_ui_settings --> pkg_settings
|
||||
pkg_client_locale --> pkg_api_remotes
|
||||
pkg_client_locale --> pkg_client_connection
|
||||
pkg_client_locale --> pkg_client_runtime
|
||||
pkg_client_locale --> pkg_client_ui_renderer
|
||||
pkg_client_locale --> pkg_client_ui_settings
|
||||
pkg_client_locale --> pkg_invariants
|
||||
pkg_client_locale --> pkg_settings
|
||||
pkg_client_test_runtime --> pkg_client_runtime
|
||||
pkg_client_test_runtime --> pkg_client_ui_renderer
|
||||
pkg_client_test_runtime --> pkg_client_ui_slots
|
||||
pkg_client_test_runtime --> pkg_host_apiproxy
|
||||
pkg_client_test_runtime --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_client_locale
|
||||
pkg_client_ui_input_trigger --> pkg_client_runtime
|
||||
pkg_client_ui_input_trigger --> pkg_file_reference
|
||||
pkg_client_ui_input_trigger --> pkg_invariants
|
||||
pkg_client_ui_settings_models --> pkg_api_remotes
|
||||
pkg_client_ui_settings_models --> pkg_client_connection
|
||||
pkg_client_ui_settings_models --> pkg_client_locale
|
||||
pkg_client_ui_settings_models --> pkg_client_runtime
|
||||
pkg_client_ui_settings_models --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_models --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_models --> pkg_invariants
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_api_remotes
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_locale
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_runtime
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_plugin_inventory --> pkg_invariants
|
||||
pkg_client_ui_settings_plugins --> pkg_api_remotes
|
||||
pkg_client_ui_settings_plugins --> pkg_client_connection
|
||||
pkg_client_ui_settings_plugins --> pkg_client_locale
|
||||
pkg_client_ui_settings_plugins --> pkg_client_runtime
|
||||
pkg_client_ui_settings_plugins --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_plugins --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_plugins --> pkg_invariants
|
||||
pkg_client_ui_theme --> pkg_api_remotes
|
||||
pkg_client_ui_theme --> pkg_client_connection
|
||||
pkg_client_ui_theme --> pkg_client_locale
|
||||
pkg_client_ui_theme --> pkg_client_runtime
|
||||
pkg_client_ui_theme --> pkg_client_ui_renderer
|
||||
pkg_client_ui_theme --> pkg_client_ui_settings
|
||||
pkg_client_ui_theme --> pkg_host_webserver
|
||||
pkg_client_ui_theme --> pkg_invariants
|
||||
pkg_client_ui_theme --> pkg_settings
|
||||
pkg_client_ui_layout --> pkg_client_runtime
|
||||
pkg_client_ui_layout --> pkg_client_ui_renderer
|
||||
pkg_client_ui_layout --> pkg_client_ui_session
|
||||
pkg_client_ui_layout --> pkg_client_ui_theme
|
||||
pkg_client_ui_layout --> pkg_invariants
|
||||
pkg_cordis_client_runner --> pkg_api_remotes
|
||||
pkg_cordis_client_runner --> pkg_client_connection
|
||||
pkg_cordis_client_runner --> pkg_client_modules
|
||||
pkg_cordis_client_runner --> pkg_client_ui_renderer
|
||||
pkg_cordis_client_runner --> pkg_client_ui_theme
|
||||
pkg_cordis_client_runner --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_api_remotes
|
||||
pkg_client_ui_conversation --> pkg_api_session_controller
|
||||
pkg_client_ui_conversation --> pkg_api_workspace_controller
|
||||
pkg_client_ui_conversation --> pkg_attachment
|
||||
pkg_client_ui_conversation --> pkg_brand
|
||||
pkg_client_ui_conversation --> pkg_client_locale
|
||||
pkg_client_ui_conversation --> pkg_client_ui_layout
|
||||
pkg_client_ui_conversation --> pkg_client_ui_renderer
|
||||
pkg_client_ui_conversation --> pkg_client_ui_session
|
||||
pkg_client_ui_conversation --> pkg_client_ui_settings
|
||||
pkg_client_ui_conversation --> pkg_client_ui_workspace
|
||||
pkg_client_ui_conversation --> pkg_commands
|
||||
pkg_client_ui_conversation --> pkg_goal
|
||||
pkg_client_ui_conversation --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_llm
|
||||
pkg_client_ui_conversation --> pkg_llm_retry
|
||||
pkg_client_ui_conversation --> pkg_permission_presets
|
||||
pkg_client_ui_conversation --> pkg_plan_mode
|
||||
pkg_client_ui_conversation --> pkg_session
|
||||
pkg_client_ui_conversation --> pkg_settings
|
||||
pkg_client_ui_conversation --> pkg_token_meter
|
||||
pkg_client_ui_conversation --> pkg_tool_todo
|
||||
pkg_client_ui_conversation --> pkg_util_crypto
|
||||
pkg_client_ui_conversation --> pkg_workspace
|
||||
pkg_client_ui_sidebar --> pkg_api_workspace_controller
|
||||
pkg_client_ui_sidebar --> pkg_client_locale
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_layout
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_renderer
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_session
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_workspace
|
||||
pkg_client_ui_sidebar --> pkg_invariants
|
||||
pkg_client_ui_workspace --> pkg_api_session_controller
|
||||
pkg_client_ui_workspace --> pkg_api_workspace_controller
|
||||
pkg_client_ui_workspace --> pkg_client_connection
|
||||
pkg_client_ui_workspace --> pkg_client_locale
|
||||
pkg_client_ui_workspace --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workspace --> pkg_client_ui_renderer
|
||||
pkg_client_ui_workspace --> pkg_client_ui_session
|
||||
pkg_client_ui_workspace --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_workspace --> pkg_invariants
|
||||
pkg_client_ui_workspace --> pkg_session
|
||||
pkg_client_ui_agent_preset --> pkg_api_remotes
|
||||
pkg_client_ui_agent_preset --> pkg_api_session_controller
|
||||
pkg_client_ui_agent_preset --> pkg_client_connection
|
||||
pkg_client_ui_agent_preset --> pkg_client_locale
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_conversation
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_renderer
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_session
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_settings
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_workspace
|
||||
pkg_client_ui_agent_preset --> pkg_invariants
|
||||
pkg_client_ui_agent_preset --> pkg_session
|
||||
pkg_client_ui_approval --> pkg_api_remotes
|
||||
pkg_client_ui_approval --> pkg_api_session_controller
|
||||
pkg_client_ui_approval --> pkg_client_locale
|
||||
pkg_client_ui_approval --> pkg_client_ui_conversation
|
||||
pkg_client_ui_approval --> pkg_client_ui_renderer
|
||||
pkg_client_ui_approval --> pkg_client_ui_session
|
||||
pkg_client_ui_approval --> pkg_invariants
|
||||
pkg_client_ui_approval --> pkg_llm
|
||||
pkg_client_ui_approval --> pkg_session
|
||||
pkg_client_ui_approval --> pkg_typert_protocol
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_conversation
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_renderer
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_brand_official --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_connection
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_locale
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_renderer
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_browse --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_renderer
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_native --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_api_session_controller
|
||||
pkg_client_ui_input_trigger --> pkg_client_locale
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_conversation
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_renderer
|
||||
pkg_client_ui_input_trigger --> pkg_client_ui_session
|
||||
pkg_client_ui_input_trigger --> pkg_file_reference
|
||||
pkg_client_ui_input_trigger --> pkg_invariants
|
||||
pkg_client_ui_input_trigger --> pkg_session
|
||||
pkg_client_ui_jobs --> pkg_api_session_controller
|
||||
pkg_client_ui_jobs --> pkg_client_locale
|
||||
pkg_client_ui_jobs --> pkg_client_ui_conversation
|
||||
pkg_client_ui_jobs --> pkg_client_ui_renderer
|
||||
pkg_client_ui_jobs --> pkg_client_ui_session
|
||||
pkg_client_ui_jobs --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_api_remotes
|
||||
pkg_client_ui_plan --> pkg_client_locale
|
||||
pkg_client_ui_plan --> pkg_client_ui_conversation
|
||||
pkg_client_ui_plan --> pkg_client_ui_renderer
|
||||
pkg_client_ui_plan --> pkg_client_ui_session
|
||||
pkg_client_ui_plan --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_plan_mode
|
||||
pkg_client_ui_plan --> pkg_session
|
||||
pkg_client_ui_settings_general --> pkg_api_remotes
|
||||
pkg_client_ui_settings_general --> pkg_client_connection
|
||||
pkg_client_ui_settings_general --> pkg_client_locale
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_renderer
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_session
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_settings_general --> pkg_invariants
|
||||
pkg_client_ui_settings_general --> pkg_settings
|
||||
pkg_client_ui_trajectory --> pkg_agent
|
||||
pkg_client_ui_trajectory --> pkg_api_session_controller
|
||||
pkg_client_ui_trajectory --> pkg_client_locale
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_conversation
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_renderer
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_session
|
||||
pkg_client_ui_trajectory --> pkg_compaction
|
||||
pkg_client_ui_trajectory --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_session
|
||||
pkg_client_ui_trajectory --> pkg_tools
|
||||
pkg_client_ui_user_questions --> pkg_api_remotes
|
||||
pkg_client_ui_user_questions --> pkg_api_session_controller
|
||||
pkg_client_ui_user_questions --> pkg_client_locale
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_conversation
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_renderer
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_session
|
||||
pkg_client_ui_user_questions --> pkg_invariants
|
||||
pkg_client_ui_user_questions --> pkg_session
|
||||
pkg_client_ui_user_questions --> pkg_typert_protocol
|
||||
pkg_client_ui_user_questions --> pkg_user_questions
|
||||
pkg_client_ui_chat --> pkg_agent
|
||||
pkg_client_ui_chat --> pkg_api_remotes
|
||||
pkg_client_ui_chat --> pkg_api_session_controller
|
||||
pkg_client_ui_chat --> pkg_api_workspace_controller
|
||||
pkg_client_ui_chat --> pkg_attachment
|
||||
pkg_client_ui_chat --> pkg_client_locale
|
||||
pkg_client_ui_chat --> pkg_client_ui_approval
|
||||
pkg_client_ui_chat --> pkg_client_ui_conversation
|
||||
pkg_client_ui_chat --> pkg_client_ui_layout
|
||||
pkg_client_ui_chat --> pkg_client_ui_renderer
|
||||
pkg_client_ui_chat --> pkg_client_ui_session
|
||||
pkg_client_ui_chat --> pkg_client_ui_workspace
|
||||
pkg_client_ui_chat --> pkg_commands
|
||||
pkg_client_ui_chat --> pkg_compaction
|
||||
pkg_client_ui_chat --> pkg_invariants
|
||||
pkg_client_ui_chat --> pkg_llm
|
||||
pkg_client_ui_chat --> pkg_llm_retry
|
||||
pkg_client_ui_chat --> pkg_session
|
||||
pkg_client_ui_chat --> pkg_session_stats
|
||||
pkg_client_ui_chat --> pkg_token_meter
|
||||
pkg_client_ui_chat --> pkg_tools
|
||||
pkg_client_ui_commands --> pkg_api_remotes
|
||||
pkg_client_ui_commands --> pkg_api_session_controller
|
||||
pkg_client_ui_commands --> pkg_client_locale
|
||||
pkg_client_ui_commands --> pkg_client_ui_conversation
|
||||
pkg_client_ui_commands --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_commands --> pkg_client_ui_renderer
|
||||
pkg_client_ui_commands --> pkg_client_ui_session
|
||||
pkg_client_ui_commands --> pkg_commands
|
||||
pkg_client_ui_commands --> pkg_invariants
|
||||
pkg_client_ui_commands --> pkg_session
|
||||
pkg_client_ui_reference --> pkg_api_remotes
|
||||
pkg_client_ui_reference --> pkg_client_locale
|
||||
pkg_client_ui_reference --> pkg_client_runtime
|
||||
pkg_client_ui_reference --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_reference --> pkg_file_reference
|
||||
pkg_client_ui_reference --> pkg_invariants
|
||||
pkg_client_ui_reference --> pkg_session_reference
|
||||
pkg_client_ui_reference --> pkg_typert_protocol
|
||||
pkg_cordis_client_runner --> pkg_api_remotes
|
||||
pkg_cordis_client_runner --> pkg_client_connection
|
||||
pkg_cordis_client_runner --> pkg_client_modules
|
||||
pkg_cordis_client_runner --> pkg_client_runtime
|
||||
pkg_cordis_client_runner --> pkg_client_ui_theme
|
||||
pkg_cordis_client_runner --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_agent
|
||||
pkg_client_ui_conversation --> pkg_api_remotes
|
||||
pkg_client_ui_conversation --> pkg_attachment
|
||||
pkg_client_ui_conversation --> pkg_brand
|
||||
pkg_client_ui_conversation --> pkg_client_connection
|
||||
pkg_client_ui_conversation --> pkg_client_locale
|
||||
pkg_client_ui_conversation --> pkg_client_runtime
|
||||
pkg_client_ui_conversation --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_conversation --> pkg_client_ui_layout
|
||||
pkg_client_ui_conversation --> pkg_client_ui_settings
|
||||
pkg_client_ui_conversation --> pkg_commands
|
||||
pkg_client_ui_conversation --> pkg_compaction
|
||||
pkg_client_ui_conversation --> pkg_goal
|
||||
pkg_client_ui_conversation --> pkg_invariants
|
||||
pkg_client_ui_conversation --> pkg_llm_retry
|
||||
pkg_client_ui_conversation --> pkg_permission_presets
|
||||
pkg_client_ui_conversation --> pkg_plan_mode
|
||||
pkg_client_ui_conversation --> pkg_session_stats
|
||||
pkg_client_ui_conversation --> pkg_settings
|
||||
pkg_client_ui_conversation --> pkg_token_meter
|
||||
pkg_client_ui_conversation --> pkg_tool_todo
|
||||
pkg_client_ui_conversation --> pkg_tools
|
||||
pkg_client_ui_conversation --> pkg_util_crypto
|
||||
pkg_client_ui_sidebar --> pkg_client_locale
|
||||
pkg_client_ui_sidebar --> pkg_client_runtime
|
||||
pkg_client_ui_sidebar --> pkg_client_ui_layout
|
||||
pkg_client_ui_sidebar --> pkg_invariants
|
||||
pkg_client_ui_agent_preset --> pkg_api_remotes
|
||||
pkg_client_ui_agent_preset --> pkg_client_connection
|
||||
pkg_client_ui_agent_preset --> pkg_client_locale
|
||||
pkg_client_ui_agent_preset --> pkg_client_runtime
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_conversation
|
||||
pkg_client_ui_agent_preset --> pkg_client_ui_settings
|
||||
pkg_client_ui_agent_preset --> pkg_invariants
|
||||
pkg_client_ui_attachment --> pkg_attachment
|
||||
pkg_client_ui_attachment --> pkg_client_runtime
|
||||
pkg_client_ui_attachment --> pkg_client_ui_conversation
|
||||
pkg_client_ui_attachment --> pkg_invariants
|
||||
pkg_client_ui_brand_official --> pkg_client_runtime
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_conversation
|
||||
pkg_client_ui_brand_official --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_brand_official --> pkg_invariants
|
||||
pkg_client_ui_commands --> pkg_api_remotes
|
||||
pkg_client_ui_commands --> pkg_client_locale
|
||||
pkg_client_ui_commands --> pkg_client_runtime
|
||||
pkg_client_ui_commands --> pkg_client_ui_conversation
|
||||
pkg_client_ui_commands --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_commands --> pkg_commands
|
||||
pkg_client_ui_commands --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_client_connection
|
||||
pkg_client_ui_deliverables --> pkg_client_locale
|
||||
pkg_client_ui_deliverables --> pkg_client_runtime
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_conversation
|
||||
pkg_client_ui_deliverables --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_system_prompt
|
||||
pkg_client_ui_goal --> pkg_api_remotes
|
||||
pkg_client_ui_goal --> pkg_client_locale
|
||||
pkg_client_ui_goal --> pkg_client_runtime
|
||||
pkg_client_ui_goal --> pkg_client_ui_conversation
|
||||
pkg_client_ui_goal --> pkg_commands
|
||||
pkg_client_ui_goal --> pkg_goal
|
||||
pkg_client_ui_goal --> pkg_invariants
|
||||
pkg_client_ui_goal --> pkg_session
|
||||
pkg_client_ui_goal --> pkg_typert_protocol
|
||||
pkg_client_ui_jobs --> pkg_client_locale
|
||||
pkg_client_ui_jobs --> pkg_client_runtime
|
||||
pkg_client_ui_jobs --> pkg_client_ui_conversation
|
||||
pkg_client_ui_jobs --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_api_remotes
|
||||
pkg_client_ui_message_feedback --> pkg_client_connection
|
||||
pkg_client_ui_message_feedback --> pkg_client_locale
|
||||
pkg_client_ui_message_feedback --> pkg_client_runtime
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_conversation
|
||||
pkg_client_ui_message_feedback --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_message_feedback
|
||||
pkg_client_ui_message_feedback --> pkg_typert_protocol
|
||||
pkg_client_ui_plan --> pkg_api_remotes
|
||||
pkg_client_ui_plan --> pkg_client_locale
|
||||
pkg_client_ui_plan --> pkg_client_runtime
|
||||
pkg_client_ui_plan --> pkg_client_ui_conversation
|
||||
pkg_client_ui_plan --> pkg_invariants
|
||||
pkg_client_ui_plan --> pkg_plan_mode
|
||||
pkg_client_ui_settings_general --> pkg_api_remotes
|
||||
pkg_client_ui_settings_general --> pkg_client_connection
|
||||
pkg_client_ui_settings_general --> pkg_client_locale
|
||||
pkg_client_ui_settings_general --> pkg_client_runtime
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_settings
|
||||
pkg_client_ui_settings_general --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_settings_general --> pkg_invariants
|
||||
pkg_client_ui_settings_general --> pkg_settings
|
||||
pkg_client_ui_subagent --> pkg_api_session_controller
|
||||
pkg_client_ui_subagent --> pkg_client_connection
|
||||
pkg_client_ui_subagent --> pkg_client_locale
|
||||
pkg_client_ui_subagent --> pkg_client_runtime
|
||||
pkg_client_ui_subagent --> pkg_client_ui_conversation
|
||||
pkg_client_ui_subagent --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_subagent --> pkg_client_ui_renderer
|
||||
pkg_client_ui_subagent --> pkg_client_ui_session
|
||||
pkg_client_ui_subagent --> pkg_invariants
|
||||
pkg_client_ui_subagent --> pkg_session
|
||||
pkg_client_ui_subagent --> pkg_subagent
|
||||
pkg_client_ui_subagent --> pkg_token_meter
|
||||
pkg_client_ui_tool --> pkg_api_remotes
|
||||
pkg_client_ui_tool --> pkg_client_connection
|
||||
pkg_client_ui_tool --> pkg_client_locale
|
||||
pkg_client_ui_tool --> pkg_client_runtime
|
||||
pkg_client_ui_tool --> pkg_client_ui_conversation
|
||||
pkg_client_ui_tool --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_agent
|
||||
pkg_client_ui_trajectory --> pkg_client_locale
|
||||
pkg_client_ui_trajectory --> pkg_client_runtime
|
||||
pkg_client_ui_trajectory --> pkg_client_ui_conversation
|
||||
pkg_client_ui_trajectory --> pkg_compaction
|
||||
pkg_client_ui_trajectory --> pkg_invariants
|
||||
pkg_client_ui_trajectory --> pkg_tools
|
||||
pkg_client_ui_user_questions --> pkg_api_remotes
|
||||
pkg_client_ui_user_questions --> pkg_client_locale
|
||||
pkg_client_ui_user_questions --> pkg_client_runtime
|
||||
pkg_client_ui_user_questions --> pkg_client_ui_conversation
|
||||
pkg_client_ui_user_questions --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_client_locale
|
||||
pkg_client_ui_workflow_run --> pkg_client_runtime
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workflow_run --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_session
|
||||
pkg_client_ui_workflow_run --> pkg_tool_workflow
|
||||
pkg_client_ui_workflow_run --> pkg_workflow
|
||||
pkg_client_ui_workspace --> pkg_client_connection
|
||||
pkg_client_ui_workspace --> pkg_client_locale
|
||||
pkg_client_ui_workspace --> pkg_client_runtime
|
||||
pkg_client_ui_workspace --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workspace --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_workspace --> pkg_invariants
|
||||
pkg_session_log_export --> pkg_client_locale
|
||||
pkg_session_log_export --> pkg_client_runtime
|
||||
pkg_session_log_export --> pkg_client_ui_commands
|
||||
pkg_session_log_export --> pkg_client_ui_conversation
|
||||
pkg_session_log_export --> pkg_commands
|
||||
pkg_session_log_export --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_locale
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_runtime
|
||||
pkg_client_ui_directory_picker_browse --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_browse --> pkg_invariants
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_runtime
|
||||
pkg_client_ui_directory_picker_native --> pkg_client_ui_workspace
|
||||
pkg_client_ui_directory_picker_native --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_api_remotes
|
||||
pkg_client_ui_model_selection --> pkg_api_session_controller
|
||||
pkg_client_ui_model_selection --> pkg_client_connection
|
||||
pkg_client_ui_model_selection --> pkg_client_locale
|
||||
pkg_client_ui_model_selection --> pkg_client_runtime
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_commands
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_conversation
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_model_selection --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_typert_protocol
|
||||
pkg_client_ui_permission_presets --> pkg_api_remotes
|
||||
pkg_client_ui_permission_presets --> pkg_client_connection
|
||||
pkg_client_ui_permission_presets --> pkg_client_locale
|
||||
pkg_client_ui_permission_presets --> pkg_client_runtime
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_commands
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_settings
|
||||
pkg_client_ui_permission_presets --> pkg_invariants
|
||||
pkg_client_ui_permission_presets --> pkg_permission_presets
|
||||
pkg_client_ui_skill --> pkg_api_remotes
|
||||
pkg_client_ui_skill --> pkg_client_connection
|
||||
pkg_client_ui_skill --> pkg_client_locale
|
||||
pkg_client_ui_skill --> pkg_client_runtime
|
||||
pkg_client_ui_skill --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_skill --> pkg_client_ui_tool
|
||||
pkg_client_ui_skill --> pkg_invariants
|
||||
pkg_client_ui_cordis --> pkg_api_remotes
|
||||
pkg_client_ui_cordis --> pkg_client_connection
|
||||
pkg_client_ui_cordis --> pkg_client_locale
|
||||
pkg_client_ui_cordis --> pkg_client_runtime
|
||||
pkg_client_ui_cordis --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_cordis --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_cordis --> pkg_client_ui_tool
|
||||
pkg_client_ui_cordis --> pkg_cordis_client_runner
|
||||
pkg_client_ui_cordis --> pkg_invariants
|
||||
pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_browse
|
||||
pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_native
|
||||
pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse
|
||||
pkg_host_directory_picker_auto --> pkg_host_directory_picker_native
|
||||
pkg_host_directory_picker_auto --> pkg_host_webserver
|
||||
pkg_host_directory_picker_auto --> pkg_invariants
|
||||
pkg_session_log_export --> pkg_client_locale
|
||||
pkg_session_log_export --> pkg_client_ui_commands
|
||||
pkg_session_log_export --> pkg_client_ui_conversation
|
||||
pkg_session_log_export --> pkg_client_ui_renderer
|
||||
pkg_session_log_export --> pkg_client_ui_session
|
||||
pkg_session_log_export --> pkg_commands
|
||||
pkg_session_log_export --> pkg_invariants
|
||||
pkg_client_ui_attachment --> pkg_attachment
|
||||
pkg_client_ui_attachment --> pkg_client_ui_chat
|
||||
pkg_client_ui_attachment --> pkg_client_ui_conversation
|
||||
pkg_client_ui_attachment --> pkg_client_ui_renderer
|
||||
pkg_client_ui_attachment --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_client_connection
|
||||
pkg_client_ui_deliverables --> pkg_client_locale
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_chat
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_conversation
|
||||
pkg_client_ui_deliverables --> pkg_client_ui_renderer
|
||||
pkg_client_ui_deliverables --> pkg_invariants
|
||||
pkg_client_ui_deliverables --> pkg_session
|
||||
pkg_client_ui_deliverables --> pkg_system_prompt
|
||||
pkg_client_ui_goal --> pkg_api_remotes
|
||||
pkg_client_ui_goal --> pkg_api_session_controller
|
||||
pkg_client_ui_goal --> pkg_client_locale
|
||||
pkg_client_ui_goal --> pkg_client_ui_chat
|
||||
pkg_client_ui_goal --> pkg_client_ui_conversation
|
||||
pkg_client_ui_goal --> pkg_client_ui_renderer
|
||||
pkg_client_ui_goal --> pkg_client_ui_session
|
||||
pkg_client_ui_goal --> pkg_commands
|
||||
pkg_client_ui_goal --> pkg_goal
|
||||
pkg_client_ui_goal --> pkg_invariants
|
||||
pkg_client_ui_goal --> pkg_session
|
||||
pkg_client_ui_goal --> pkg_typert_protocol
|
||||
pkg_client_ui_message_feedback --> pkg_api_remotes
|
||||
pkg_client_ui_message_feedback --> pkg_client_connection
|
||||
pkg_client_ui_message_feedback --> pkg_client_locale
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_chat
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_conversation
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_renderer
|
||||
pkg_client_ui_message_feedback --> pkg_client_ui_session
|
||||
pkg_client_ui_message_feedback --> pkg_invariants
|
||||
pkg_client_ui_message_feedback --> pkg_message_feedback
|
||||
pkg_client_ui_message_feedback --> pkg_session
|
||||
pkg_client_ui_message_feedback --> pkg_typert_protocol
|
||||
pkg_client_ui_model_selection --> pkg_api_remotes
|
||||
pkg_client_ui_model_selection --> pkg_api_session_controller
|
||||
pkg_client_ui_model_selection --> pkg_client_connection
|
||||
pkg_client_ui_model_selection --> pkg_client_locale
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_commands
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_conversation
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_renderer
|
||||
pkg_client_ui_model_selection --> pkg_client_ui_session
|
||||
pkg_client_ui_model_selection --> pkg_invariants
|
||||
pkg_client_ui_model_selection --> pkg_session
|
||||
pkg_client_ui_model_selection --> pkg_typert_protocol
|
||||
pkg_client_ui_permission_presets --> pkg_api_remotes
|
||||
pkg_client_ui_permission_presets --> pkg_api_session_controller
|
||||
pkg_client_ui_permission_presets --> pkg_client_connection
|
||||
pkg_client_ui_permission_presets --> pkg_client_locale
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_commands
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_renderer
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_session
|
||||
pkg_client_ui_permission_presets --> pkg_client_ui_settings
|
||||
pkg_client_ui_permission_presets --> pkg_invariants
|
||||
pkg_client_ui_permission_presets --> pkg_permission_presets
|
||||
pkg_client_ui_tool --> pkg_api_remotes
|
||||
pkg_client_ui_tool --> pkg_api_workspace_controller
|
||||
pkg_client_ui_tool --> pkg_client_connection
|
||||
pkg_client_ui_tool --> pkg_client_locale
|
||||
pkg_client_ui_tool --> pkg_client_ui_chat
|
||||
pkg_client_ui_tool --> pkg_client_ui_conversation
|
||||
pkg_client_ui_tool --> pkg_client_ui_renderer
|
||||
pkg_client_ui_tool --> pkg_client_ui_session
|
||||
pkg_client_ui_tool --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_api_session_controller
|
||||
pkg_client_ui_workflow_run --> pkg_client_locale
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_chat
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_conversation
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_renderer
|
||||
pkg_client_ui_workflow_run --> pkg_client_ui_session
|
||||
pkg_client_ui_workflow_run --> pkg_invariants
|
||||
pkg_client_ui_workflow_run --> pkg_session
|
||||
pkg_client_ui_workflow_run --> pkg_tool_workflow
|
||||
pkg_client_ui_workflow_run --> pkg_workflow
|
||||
pkg_client_test_runtime --> pkg_api_session_controller
|
||||
pkg_client_test_runtime --> pkg_api_workspace_controller
|
||||
pkg_client_test_runtime --> pkg_attachment
|
||||
pkg_client_test_runtime --> pkg_client_connection
|
||||
pkg_client_test_runtime --> pkg_client_store
|
||||
pkg_client_test_runtime --> pkg_client_ui_chat
|
||||
pkg_client_test_runtime --> pkg_client_ui_conversation
|
||||
pkg_client_test_runtime --> pkg_client_ui_renderer
|
||||
pkg_client_test_runtime --> pkg_client_ui_session
|
||||
pkg_client_test_runtime --> pkg_client_ui_settings
|
||||
pkg_client_test_runtime --> pkg_client_ui_slots
|
||||
pkg_client_test_runtime --> pkg_invariants
|
||||
pkg_client_test_runtime --> pkg_session
|
||||
pkg_client_ui_skill --> pkg_api_remotes
|
||||
pkg_client_ui_skill --> pkg_api_session_controller
|
||||
pkg_client_ui_skill --> pkg_client_connection
|
||||
pkg_client_ui_skill --> pkg_client_locale
|
||||
pkg_client_ui_skill --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_skill --> pkg_client_ui_renderer
|
||||
pkg_client_ui_skill --> pkg_client_ui_tool
|
||||
pkg_client_ui_skill --> pkg_invariants
|
||||
pkg_client_ui_skill --> pkg_session
|
||||
pkg_client_ui_cordis --> pkg_api_remotes
|
||||
pkg_client_ui_cordis --> pkg_client_connection
|
||||
pkg_client_ui_cordis --> pkg_client_locale
|
||||
pkg_client_ui_cordis --> pkg_client_ui_input_trigger
|
||||
pkg_client_ui_cordis --> pkg_client_ui_renderer
|
||||
pkg_client_ui_cordis --> pkg_client_ui_session
|
||||
pkg_client_ui_cordis --> pkg_client_ui_sidebar
|
||||
pkg_client_ui_cordis --> pkg_client_ui_tool
|
||||
pkg_client_ui_cordis --> pkg_cordis_client_runner
|
||||
pkg_client_ui_cordis --> pkg_invariants
|
||||
```
|
||||
|
||||
| Package | Group | Depends on |
|
||||
@@ -1562,7 +1649,9 @@ flowchart TD
|
||||
| [`acp-app`](../packages/bundle/acp-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`base`](../packages/bundle/base) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`sdk-app`](../packages/bundle/sdk-app) | `bundle` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-store`](../packages/client/store) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-primitives`](../packages/client/ui-primitives) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-renderer`](../packages/client/ui-renderer) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-slots`](../packages/client/ui-slots) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-web`](../packages/client/web) | `client` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`code-runtime`](../packages/code-runtime/code-runtime) | `code-runtime` | [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
@@ -1744,45 +1833,46 @@ flowchart TD
|
||||
| [`sdk-client`](../packages/sdk/client) | `sdk` | [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session) |
|
||||
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent) |
|
||||
| [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |
|
||||
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-workspace-controller`](../packages/api/workspace-controller) | `api` | [`api-gateway`](../packages/api/gateway), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`storage-domain`](../packages/storage/storage-domain), [`typert-protocol`](../packages/typert/protocol), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`jobs`](../packages/jobs/jobs), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-workspace-controller`](../packages/api/workspace-controller) | `api` | [`api-gateway`](../packages/api/gateway), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`storage-domain`](../packages/storage/storage-domain), [`typert-protocol`](../packages/typert/protocol), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`api-remotes`](../packages/api/remotes) | `api` | [`agent-presets`](../packages/preset/agent-presets), [`api-gateway`](../packages/api/gateway), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`commands`](../packages/interaction/commands), [`cordis-host-runner`](../packages/extensions/cordis-host-runner), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`goal`](../packages/goal/goal), [`host-plugin-inventory`](../packages/host/plugin-inventory), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`message-feedback`](../packages/feedback/message-feedback), [`session`](../packages/core/session), [`session-reference`](../packages/context/session-reference), [`settings`](../packages/settings/settings), [`user-approval`](../packages/interaction/user-approval), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`client-runtime`](../packages/client/runtime) | `client` | [`agent`](../packages/core/agent), [`api-gateway`](../packages/api/gateway), [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`commands`](../packages/interaction/commands), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`session-title`](../packages/session/session-title), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-crypto`](../packages/util/crypto) |
|
||||
| [`client-ui-renderer`](../packages/client/ui-renderer) | `client` | [`client-runtime`](../packages/client/runtime), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-locale`](../packages/client/locale) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`client-runtime`](../packages/client/runtime), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-slots`](../packages/client/ui-slots), [`host-apiproxy`](../packages/host/apiproxy), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-input-trigger`](../packages/client/ui-input-trigger) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-models`](../packages/client/ui-settings-models) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugin-inventory`](../packages/client/ui-settings-plugin-inventory) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugins`](../packages/client/ui-settings-plugins) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-theme`](../packages/client/ui-theme) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-layout`](../packages/client/ui-layout) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-reference`](../packages/client/ui-reference) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session-reference`](../packages/context/session-reference), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`cordis-client-runner`](../packages/extensions/cordis-client-runner) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-modules`](../packages/client/modules), [`client-runtime`](../packages/client/runtime), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`agent`](../packages/core/agent), [`api-remotes`](../packages/api/remotes), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-settings`](../packages/client/ui-settings), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`session-stats`](../packages/session/session-stats), [`settings`](../packages/settings/settings), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`tools`](../packages/core/tools), [`util-crypto`](../packages/util/crypto) |
|
||||
| [`client-ui-sidebar`](../packages/client/ui-sidebar) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-layout`](../packages/client/ui-layout), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-attachment`](../packages/client/ui-attachment) | `client` | [`attachment`](../packages/attachment/attachment), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-brand-official`](../packages/client/ui-brand-official) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-commands`](../packages/client/ui-commands) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-jobs`](../packages/client/ui-jobs) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-message-feedback`](../packages/client/ui-message-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`plan-mode`](../packages/plan/plan-mode) |
|
||||
| [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`invariants`](../packages/runtime-diagnostics/invariants), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
|
||||
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-user-questions`](../packages/client/ui-user-questions) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workflow-run`](../packages/client/ui-workflow-run) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`client-ui-workspace`](../packages/client/ui-workspace) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`session-log-export`](../packages/session-query/session-log-export) | `session-query` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse) | `client` | [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native) | `client` | [`client-runtime`](../packages/client/runtime), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-model-selection`](../packages/client/ui-model-selection) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`invariants`](../packages/runtime-diagnostics/invariants), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-permission-presets`](../packages/client/ui-permission-presets) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`permission-presets`](../packages/interaction/permission-presets) |
|
||||
| [`client-ui-skill`](../packages/client/ui-skill) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-tool`](../packages/client/ui-tool), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-runtime`](../packages/client/runtime), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-tool`](../packages/client/ui-tool), [`cordis-client-runner`](../packages/extensions/cordis-client-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-session`](../packages/client/ui-session) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-settings`](../packages/client/ui-settings) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-locale`](../packages/client/locale) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-settings-models`](../packages/client/ui-settings-models) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugin-inventory`](../packages/client/ui-settings-plugin-inventory) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-settings-plugins`](../packages/client/ui-settings-plugins) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-theme`](../packages/client/ui-theme) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-settings`](../packages/client/ui-settings), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-layout`](../packages/client/ui-layout) | `client` | [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`cordis-client-runner`](../packages/extensions/cordis-client-runner) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-modules`](../packages/client/modules), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-theme`](../packages/client/ui-theme), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-conversation`](../packages/client/ui-conversation) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`brand`](../packages/util/brand), [`client-locale`](../packages/client/locale), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-workspace`](../packages/client/ui-workspace), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`permission-presets`](../packages/interaction/permission-presets), [`plan-mode`](../packages/plan/plan-mode), [`session`](../packages/core/session), [`settings`](../packages/settings/settings), [`token-meter`](../packages/llm/token-meter), [`tool-todo`](../packages/todo/tool-todo), [`util-crypto`](../packages/util/crypto), [`workspace`](../packages/workspace/workspace) |
|
||||
| [`client-ui-sidebar`](../packages/client/ui-sidebar) | `client` | [`api-workspace-controller`](../packages/api/workspace-controller), [`client-locale`](../packages/client/locale), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workspace`](../packages/client/ui-workspace) | `client` | [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-agent-preset`](../packages/client/ui-agent-preset) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-approval`](../packages/client/ui-approval) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-brand-official`](../packages/client/ui-brand-official) | `client` | [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native) | `client` | [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-workspace`](../packages/client/ui-workspace), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-input-trigger`](../packages/client/ui-input-trigger) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-jobs`](../packages/client/ui-jobs) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-plan`](../packages/client/ui-plan) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`plan-mode`](../packages/plan/plan-mode), [`session`](../packages/core/session) |
|
||||
| [`client-ui-settings-general`](../packages/client/ui-settings-general) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`invariants`](../packages/runtime-diagnostics/invariants), [`settings`](../packages/settings/settings) |
|
||||
| [`client-ui-trajectory`](../packages/client/ui-trajectory) | `client` | [`agent`](../packages/core/agent), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-user-questions`](../packages/client/ui-user-questions) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`client-ui-chat`](../packages/client/ui-chat) | `client` | [`agent`](../packages/core/agent), [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-locale`](../packages/client/locale), [`client-ui-approval`](../packages/client/ui-approval), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-layout`](../packages/client/ui-layout), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-workspace`](../packages/client/ui-workspace), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`invariants`](../packages/runtime-diagnostics/invariants), [`llm`](../packages/llm/llm), [`llm-retry`](../packages/llm/llm-retry), [`session`](../packages/core/session), [`session-stats`](../packages/session/session-stats), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) |
|
||||
| [`client-ui-commands`](../packages/client/ui-commands) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-reference`](../packages/client/ui-reference) | `client` | [`api-remotes`](../packages/api/remotes), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`file-reference`](../packages/context/file-reference), [`invariants`](../packages/runtime-diagnostics/invariants), [`session-reference`](../packages/context/session-reference), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-subagent`](../packages/client/ui-subagent) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`token-meter`](../packages/llm/token-meter) |
|
||||
| [`host-directory-picker-auto`](../packages/host/directory-picker-auto) | `host` | [`client-ui-directory-picker-browse`](../packages/client/ui-directory-picker-browse), [`client-ui-directory-picker-native`](../packages/client/ui-directory-picker-native), [`host-directory-picker-browse`](../packages/host/directory-picker-browse), [`host-directory-picker-native`](../packages/host/directory-picker-native), [`host-webserver`](../packages/host/webserver), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`session-log-export`](../packages/session-query/session-log-export) | `session-query` | [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-attachment`](../packages/client/ui-attachment) | `client` | [`attachment`](../packages/attachment/attachment), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-deliverables`](../packages/client/ui-deliverables) | `client` | [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| [`client-ui-goal`](../packages/client/ui-goal) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`commands`](../packages/interaction/commands), [`goal`](../packages/goal/goal), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-message-feedback`](../packages/client/ui-message-feedback) | `client` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`message-feedback`](../packages/feedback/message-feedback), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-model-selection`](../packages/client/ui-model-selection) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`typert-protocol`](../packages/typert/protocol) |
|
||||
| [`client-ui-permission-presets`](../packages/client/ui-permission-presets) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-commands`](../packages/client/ui-commands), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`invariants`](../packages/runtime-diagnostics/invariants), [`permission-presets`](../packages/interaction/permission-presets) |
|
||||
| [`client-ui-tool`](../packages/client/ui-tool) | `client` | [`api-remotes`](../packages/api/remotes), [`api-workspace-controller`](../packages/api/workspace-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
| [`client-ui-workflow-run`](../packages/client/ui-workflow-run) | `client` | [`api-session-controller`](../packages/api/session-controller), [`client-locale`](../packages/client/locale), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session), [`tool-workflow`](../packages/workflow/tool-workflow), [`workflow`](../packages/workflow/workflow) |
|
||||
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-store`](../packages/client/store), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-skill`](../packages/client/ui-skill) | `client` | [`api-remotes`](../packages/api/remotes), [`api-session-controller`](../packages/api/session-controller), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-tool`](../packages/client/ui-tool), [`invariants`](../packages/runtime-diagnostics/invariants), [`session`](../packages/core/session) |
|
||||
| [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | [`api-remotes`](../packages/api/remotes), [`client-connection`](../packages/client/connection), [`client-locale`](../packages/client/locale), [`client-ui-input-trigger`](../packages/client/ui-input-trigger), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-sidebar`](../packages/client/ui-sidebar), [`client-ui-tool`](../packages/client/ui-tool), [`cordis-client-runner`](../packages/extensions/cordis-client-runner), [`invariants`](../packages/runtime-diagnostics/invariants) |
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/user-questions.md
|
||||
user-questions.md: 93b1bc52580da16fe8ad0de4bc16ec309aaacc1f
|
||||
user-questions.zh.md: 50098f6e0f6b1b38a1035566b04e24e0b7a80ff7
|
||||
user-questions.md: fbbfb1435586c7191e47a6eaa5b1783c9f172d48
|
||||
user-questions.zh.md: 054ca06cd3c8a85cb35d99658c325848ea780cb5
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](user-questions.zh.md)
|
||||
|
||||
The user-questions seam of [dsh-user-questions](../../packages/interaction/user-questions). It is the provider-neutral vocabulary a tool or permission plugin uses when it needs the human to answer before the agent can continue. UI surfaces provide the active `UserQuestionProvider`; the host runtime relays requests to its connected client.
|
||||
The user-questions seam of [dsh-user-questions](../../packages/interaction/user-questions). It is the provider-neutral vocabulary a tool or permission plugin uses when it needs the human to answer before the agent can continue. Agent-scoped waterfall listeners compose the available UI surfaces, including listeners relayed to a connected client.
|
||||
|
||||
Source: [`packages/interaction/user-questions/src/index.ts`](../../packages/interaction/user-questions/src/index.ts)
|
||||
|
||||
@@ -74,14 +74,7 @@ interface AskUserQuestionItem {
|
||||
|
||||
```ts type-equiv
|
||||
/** Request for a human answer. */
|
||||
interface AskUserQuestionRequest {
|
||||
/** Questions to display. */
|
||||
questions: AskUserQuestionItem[]
|
||||
/** Exact live calling agent, when the request came from an agent tool call. */
|
||||
agent?: Agent
|
||||
/** Abort signal for the owning tool/step. */
|
||||
signal?: AbortSignal
|
||||
}
|
||||
interface AskUserQuestionRequest extends AskUserQuestionRequestEvent {}
|
||||
```
|
||||
|
||||
## Answer
|
||||
@@ -108,17 +101,6 @@ interface AskUserQuestionAnswer {
|
||||
}
|
||||
```
|
||||
|
||||
## Provider
|
||||
|
||||
Only one provider may be active in a context. Provider registration is effect-bound so HMR/disposal removes the active UI.
|
||||
|
||||
```ts type-equiv
|
||||
/** UI-side provider for user questions. */
|
||||
interface UserQuestionProvider {
|
||||
ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
`UserQuestionError` extends `HarnessError`, so `ctx.tools.execute()` preserves `{ name, code }` for model-facing tool failures such as `EMPTY_QUESTIONS`, `NO_PROVIDER`, `ASK_ABORTED`, or UI-side cancellation.
|
||||
@@ -145,19 +127,11 @@ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnp
|
||||
|
||||
### `ctx.userQuestions` — `UserQuestionService`
|
||||
|
||||
`ctx.userQuestions`: one active UI provider plus an `ask()` API.
|
||||
`ctx.userQuestions`: validation plus the scoped answerer waterfall.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Register the UI provider. Only one provider may be active in a context.
|
||||
*
|
||||
* @param provider UI-side implementation that collects answers.
|
||||
* @returns Disposer that unregisters this provider.
|
||||
*/
|
||||
registerProvider(provider: UserQuestionProvider): () => void
|
||||
|
||||
/**
|
||||
* Ask the active UI provider and wait for the user's answer.
|
||||
* Ask the scoped answerer waterfall and wait for the user's answer.
|
||||
*
|
||||
* When a caller supplies an agent, human interaction is valid only for the
|
||||
* exact live runtime root. Runtime ownership, not durable session lineage,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](user-questions.md) | 中文
|
||||
|
||||
[dsh-user-questions](../../packages/interaction/user-questions) 的用户交互 seam。它是工具或权限插件需要人类回答后 agent(智能体)才能继续时所使用的、提供方无关的词汇。UI 界面提供活跃的 `UserQuestionProvider`;host 运行时把请求转发给其连接的客户端。
|
||||
[dsh-user-questions](../../packages/interaction/user-questions) 的用户交互 seam。它是工具或权限插件需要人类回答后 agent(智能体)才能继续时所使用的、提供方无关的词汇。Agent-scoped waterfall listener 组合可用的 UI 界面,其中包括转发到已连接 client 的 listener。
|
||||
|
||||
源码:[`packages/interaction/user-questions/src/index.ts`](../../packages/interaction/user-questions/src/index.ts)
|
||||
|
||||
@@ -74,14 +74,7 @@ interface AskUserQuestionItem {
|
||||
|
||||
```ts type-equiv
|
||||
/** Request for a human answer. */
|
||||
interface AskUserQuestionRequest {
|
||||
/** Questions to display. */
|
||||
questions: AskUserQuestionItem[]
|
||||
/** Exact live calling agent, when the request came from an agent tool call. */
|
||||
agent?: Agent
|
||||
/** Abort signal for the owning tool/step. */
|
||||
signal?: AbortSignal
|
||||
}
|
||||
interface AskUserQuestionRequest extends AskUserQuestionRequestEvent {}
|
||||
```
|
||||
|
||||
## 回答
|
||||
@@ -108,17 +101,6 @@ interface AskUserQuestionAnswer {
|
||||
}
|
||||
```
|
||||
|
||||
## 提供方
|
||||
|
||||
同一上下文中只能有一个活跃的提供方。提供方注册绑定到 effect,因此 HMR(热模块替换)或 dispose(资源释放)会移除当前活跃的 UI。
|
||||
|
||||
```ts type-equiv
|
||||
/** UI-side provider for user questions. */
|
||||
interface UserQuestionProvider {
|
||||
ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>
|
||||
}
|
||||
```
|
||||
|
||||
## 错误
|
||||
|
||||
`UserQuestionError` 继承 `HarnessError`,因此 `ctx.tools.execute()` 会保留 `{ name, code }`,用于面向模型的工具失败,如 `EMPTY_QUESTIONS`、`NO_PROVIDER`、`ASK_ABORTED` 或 UI 侧取消。
|
||||
@@ -145,19 +127,11 @@ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnp
|
||||
|
||||
### `ctx.userQuestions` — `UserQuestionService`
|
||||
|
||||
`ctx.userQuestions`: one active UI provider plus an `ask()` API.
|
||||
`ctx.userQuestions`: validation plus the scoped answerer waterfall.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Register the UI provider. Only one provider may be active in a context.
|
||||
*
|
||||
* @param provider UI-side implementation that collects answers.
|
||||
* @returns Disposer that unregisters this provider.
|
||||
*/
|
||||
registerProvider(provider: UserQuestionProvider): () => void
|
||||
|
||||
/**
|
||||
* Ask the active UI provider and wait for the user's answer.
|
||||
* Ask the scoped answerer waterfall and wait for the user's answer.
|
||||
*
|
||||
* When a caller supplies an agent, human interaction is valid only for the
|
||||
* exact live runtime root. Runtime ownership, not durable session lineage,
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/api/gateway/README.md
|
||||
README.md: fe4834b4ca36590bc289be9b6863ffb082e8ee71
|
||||
README.zh.md: dff5a58599f0d3bf97996ceb36b134bf62da8ca0
|
||||
README.md: 2546b0c4e54ea106c9203ce419027fe8253c7ca5
|
||||
README.zh.md: 9281519cda422137c6fd08ff6680ba0d57902913
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/api/remotes/README.md
|
||||
README.md: 0c4f0fcab4a741f457f1ffbdd9a4ba7688b9d32c
|
||||
README.zh.md: b381751cec5285c34bb310b330fc55d34033cbf2
|
||||
README.zh.md: f83e31e63b57f09b16403df911154c9d93b07958
|
||||
|
||||
@@ -51,7 +51,7 @@ Non-negotiables across the layers:
|
||||
|
||||
- **Business data lives in the object layer, never a store.** Entry-declared stores carry shared viewing/interaction state (selection, drafts, panel widths); sessions, frames, and connections stay in the object layer.
|
||||
- **rpcId is strictly bidirectional**: the initiator mints, the responder echoes; business signatures see only `RpcRequest<P>`, minting stays in the carrier layer ([layering and RPC protocol note](../../.agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md)).
|
||||
- **Notifier publication discipline**: `notifyNow` is only the direct echo of a user gesture; structural updates use microtask-batched `markDirty`, while visible streaming chunks use cumulative `markFrameDirty`. See `runtime/src/client/sessions/notifier.ts`.
|
||||
- **Notifier publication discipline**: `notifyNow` is only the direct echo of a user gesture; structural updates use microtask-batched `markDirty`, while visible streaming chunks use cumulative `markFrameDirty`. See `../api/session-controller/src/client/sessions/notifier.ts`.
|
||||
- **The web layer is pure presentation.** Nothing that is "how to draw" (tool-card views, queue states) enters the session log; the host computes such data per frame or pushes it live, and replay recomputes it — falling back to the generic form when it can't. A new *model-visible* input still requires a session event (repo-wide rule).
|
||||
|
||||
## Dependency declaration
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/README.md
|
||||
README.md: b18aad486cd7d3fafe8261fee61fa9e26a7feaa6
|
||||
README.zh.md: 58c9aeb5c91f13d9306ba8de16de5af760fd43a2
|
||||
README.md: eaf01b282ead3c4638435e3d02d6a803ad1faa15
|
||||
README.zh.md: 2ff4b1529f07e0f31b3d06a9577d3c480dd34916
|
||||
|
||||
@@ -10,11 +10,12 @@ The browser side of the dsh web GUI: shell boot, browser-host communication, sha
|
||||
| [`ui-renderer/`](ui-renderer/README.md) | Binds slot data to React and mounts the assembled application after client boot settles. |
|
||||
| [`modules/`](modules/README.md) | Loads browser-side client modules. |
|
||||
| [`connection/`](connection/README.md) | Maintains browser-host RPC communication and event delivery. |
|
||||
| [`runtime/`](runtime/README.md) | Provides shared client services for sessions, workspaces, and UI composition. |
|
||||
| [`hmr/`](hmr/README.md) | Refreshes client plugins during development. |
|
||||
| [`locale/`](locale/README.md) | Provides localization preferences and message dictionaries. |
|
||||
| [`store/`](store/README.md) | Provides React-free observable and snapshot-store primitives. |
|
||||
| [`test-runtime/`](../test-support/client-runtime/README.md) | Provides shared repository test support for client feature packages. |
|
||||
| [`ui-slots/`](ui-slots/README.md) | Defines how UI features register and compose extension slots. |
|
||||
| [`ui-session/`](ui-session/README.md) | Adapts Session Controller state into standard Slot sources and hooks. |
|
||||
| [`ui-theme/`](ui-theme/README.md) | Applies the selected color theme. |
|
||||
| [`ui-primitives/`](ui-primitives/README.md) | Provides shared React controls, icons, and content renderers. |
|
||||
| [`ui-attachment/`](ui-attachment/README.md) | Registers composer and message-image attachment presentation. |
|
||||
@@ -23,6 +24,8 @@ The browser side of the dsh web GUI: shell boot, browser-host communication, sha
|
||||
| [`ui-brand-official/`](ui-brand-official/README.md) | Fills the generic browser-brand slots with the official name and marks. |
|
||||
| [`ui-workspace/`](ui-workspace/README.md) | Provides workspace selection and creation surfaces. |
|
||||
| [`ui-conversation/`](ui-conversation/README.md) | Presents the active conversation and its input surface. |
|
||||
| [`ui-chat/`](ui-chat/README.md) | Projects and renders the Chat conversation target. |
|
||||
| [`ui-approval/`](ui-approval/README.md) | Presents approval requests and returns user decisions. |
|
||||
| [`ui-tool/`](ui-tool/README.md) | Composes Tool call trees and keyed per-Tool views. |
|
||||
| [`ui-workflow-run/`](ui-workflow-run/README.md) | Replays durable workflow runs as nested Chat disclosures with live-only child navigation. |
|
||||
| [`ui-goal/`](ui-goal/README.md) | Presents and manages the current goal. |
|
||||
|
||||
@@ -10,11 +10,12 @@ dsh web GUI 的浏览器侧:shell 启动、浏览器与宿主通信、共享 U
|
||||
| [`ui-renderer/`](ui-renderer/README.zh.md) | 将 slot 数据绑定到 React,并在客户端启动稳定后挂载组装完成的应用。 |
|
||||
| [`modules/`](modules/README.zh.md) | 加载浏览器侧客户端模块。 |
|
||||
| [`connection/`](connection/README.zh.md) | 维护浏览器与宿主之间的 RPC 通信和事件传递。 |
|
||||
| [`runtime/`](runtime/README.zh.md) | 为会话、工作区和 UI 组合提供共享客户端服务。 |
|
||||
| [`hmr/`](hmr/README.zh.md) | 在开发期间刷新客户端插件。 |
|
||||
| [`locale/`](locale/README.zh.md) | 提供本地化偏好与消息词典。 |
|
||||
| [`store/`](store/README.zh.md) | 提供不依赖 React 的 observable 与 snapshot-store 基础设施。 |
|
||||
| [`test-runtime/`](../test-support/client-runtime/README.zh.md) | 为客户端功能包提供共享的仓库测试支持。 |
|
||||
| [`ui-slots/`](ui-slots/README.zh.md) | 定义 UI 功能注册和组合扩展 slot 的方式。 |
|
||||
| [`ui-session/`](ui-session/README.zh.md) | 把 Session Controller 状态适配为标准 Slot source 与 hook。 |
|
||||
| [`ui-theme/`](ui-theme/README.zh.md) | 应用所选颜色主题。 |
|
||||
| [`ui-primitives/`](ui-primitives/README.zh.md) | 提供共享 React 控件、图标和内容渲染器。 |
|
||||
| [`ui-attachment/`](ui-attachment/README.zh.md) | 注册输入框与消息图片的附件呈现。 |
|
||||
@@ -23,6 +24,8 @@ dsh web GUI 的浏览器侧:shell 启动、浏览器与宿主通信、共享 U
|
||||
| [`ui-brand-official/`](ui-brand-official/README.zh.md) | 使用官方名称和标记填充通用浏览器品牌 slot。 |
|
||||
| [`ui-workspace/`](ui-workspace/README.zh.md) | 提供工作区选择与创建界面。 |
|
||||
| [`ui-conversation/`](ui-conversation/README.zh.md) | 展示当前对话及其输入界面。 |
|
||||
| [`ui-chat/`](ui-chat/README.zh.md) | 投影并渲染 Chat conversation target。 |
|
||||
| [`ui-approval/`](ui-approval/README.zh.md) | 展示审批请求并返回用户决定。 |
|
||||
| [`ui-tool/`](ui-tool/README.zh.md) | 编排工具调用树和按工具键控的视图。 |
|
||||
| [`ui-workflow-run/`](ui-workflow-run/README.zh.md) | 把持久工作流运行回放为 Chat 嵌套折叠项,并只为实时子 Session 提供导航。 |
|
||||
| [`ui-goal/`](ui-goal/README.zh.md) | 展示和管理当前目标。 |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/store/README.md
|
||||
README.md: 51299c9730157eaf1cd7226d64a54e08b497b76e
|
||||
README.zh.md: 1f2883db9a0b591a12438eba96f2fb36d96fbda0
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-store
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
React-free observable and snapshot-store primitives shared by Client controllers and renderer adapters. The package owns synchronous and animation-frame publication, Immer-backed updates, shallow equality, and optional browser persistence; React hook construction remains in `@deepseek-ai/dsh-client-ui-renderer`.
|
||||
|
||||
## Model Experience
|
||||
|
||||
None, as this package provides browser-side state primitives and registers nothing model-facing.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
None; the stores neither assemble nor send model requests.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Persistence is browser-local** — persisted stores use JSON in `localStorage`; non-browser runtimes disable persistence, and the package provides no cross-device synchronization.
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-store
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
供 Client controller 与 renderer adapter 共用的不依赖 React 的 observable 和 snapshot-store 基础设施。本包负责同步与 animation-frame 发布、基于 Immer 的更新、浅比较和可选的浏览器持久化;React hook 的构造仍属于 `@deepseek-ai/dsh-client-ui-renderer`。
|
||||
|
||||
## 模型体验
|
||||
|
||||
无,因为本包提供浏览器侧状态基础设施,不注册任何面向模型的内容。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
无;这些 store 既不组装也不发送模型请求。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **持久化仅限浏览器本地**——持久化 store 使用 `localStorage` 中的 JSON;非浏览器运行时会禁用持久化,本包也不提供跨设备同步。
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-approval/README.md
|
||||
README.md: efc3a81ad88d94b2835b32a7663f72c2e95c1614
|
||||
README.zh.md: 8eaa561b9cbdffd0998b568109497c0e9587f043
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-approval
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Browser approval presentation over the Agent-scoped Remote Event waterfall. The plugin publishes each pending request through `ctx.uiSession`, takes over the Conversation composer, optionally renders correlated Tool detail, and returns the user's decision to the waiting Host request.
|
||||
|
||||
## Model Experience
|
||||
|
||||
None, as this package presents approval requests in the browser and registers nothing model-facing.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
None; approval request and response rendering does not alter a model request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The panel exposes transient decisions only** — it supports allow-once and reject; persistent permission policy remains owned by Host-side approval packages.
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-approval
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
基于 Agent-scoped Remote Event waterfall 的浏览器审批界面。插件通过 `ctx.uiSession` 发布每个待处理请求、接管 Conversation composer、按需渲染关联的 Tool 详情,并将用户决定返回给等待中的 Host 请求。
|
||||
|
||||
## 模型体验
|
||||
|
||||
无,因为本包只在浏览器中呈现审批请求,不注册任何面向模型的内容。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
无;审批请求和响应的呈现不会改变模型请求。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **面板只提供临时决定**——它支持仅本次允许和拒绝;持久权限策略仍由 Host 侧审批 package 拥有。
|
||||
@@ -56,6 +56,7 @@ function setupPlugin(): PluginBench {
|
||||
const registerPendingInteraction = vi.fn((_precedence: (value: PendingApproval) => number) => (
|
||||
value: PendingApproval,
|
||||
) => {
|
||||
_precedence(value)
|
||||
pending = [...pending, value]
|
||||
return () => { pending = pending.filter(candidate => candidate !== value) }
|
||||
})
|
||||
@@ -257,6 +258,22 @@ describe('approval Remote Event consumer', () => {
|
||||
await scope.fiber.dispose()
|
||||
})
|
||||
|
||||
it('publishes a scoped request without optional request metadata', async () => {
|
||||
const bench = setupPlugin()
|
||||
const scope = createScope(bench.ctx, id('s1'))
|
||||
await scope.fiber.await()
|
||||
const result = bench.listener.call(scope.ctx, { toolName: 'read' }, () => Promise.resolve('unavailable'))
|
||||
const pending = bench.pending.getSnapshot()[0]!
|
||||
|
||||
await pending.answer('rejected')
|
||||
|
||||
await expect(result).resolves.toBe('rejected')
|
||||
expect(pending).toMatchObject({ toolName: 'read' })
|
||||
expect(pending.callId).toBeUndefined()
|
||||
expect(pending.reason).toBeUndefined()
|
||||
await scope.fiber.dispose()
|
||||
})
|
||||
|
||||
it('removes stable registrations with the plugin lifetime', async () => {
|
||||
const bench = setupPlugin()
|
||||
await bench.ctx.fiber.dispose()
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-chat/README.md
|
||||
README.md: 56bb20ab7b4d9b5c0c95142b311a07ad9b8a1fd3
|
||||
README.zh.md: 40ee1ee710e2f86e802ffaac4dc0bb10852f128f
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-chat
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The browser Chat target for Conversation assembly. It registers Chat event definitions and snapshot construction, supplies `useChat`, renders transcript nodes and details, and owns Chat-specific stores, actions, localization, historical images, and scroll restoration.
|
||||
|
||||
## Model Experience
|
||||
|
||||
None, as this package renders logged conversation state in the browser and registers nothing model-facing.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
None; Chat presentation does not assemble or mutate provider requests.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **The view reflects the loaded Session window** — older transcript nodes become available only after Session Controller loads the preceding event page.
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-chat
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
Conversation 组装的浏览器 Chat target。本包注册 Chat event definition 与 snapshot 构造、提供 `useChat`、渲染 transcript node 和详情,并拥有 Chat 专属 store、action、本地化、历史图片与滚动位置恢复。
|
||||
|
||||
## 模型体验
|
||||
|
||||
无,因为本包在浏览器中渲染已记录的对话状态,不注册任何面向模型的内容。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
无;Chat 呈现不会组装或修改提供方请求。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **视图只反映已加载的 Session 窗口**——只有 Session Controller 加载前一页 event 后,更早的 transcript node 才会出现。
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-conversation/README.md
|
||||
README.md: b70bb96cc877279cc29662773eddf6fd7d6453ca
|
||||
README.zh.md: 604beeb336054376971277446e1690137132c29e
|
||||
README.md: 6f47cd87af46cc270d3160482ad047b249aa5053
|
||||
README.zh.md: 38e3c626073e9e90a16eebdb91af1e89d4da7c22
|
||||
|
||||
@@ -24,10 +24,15 @@ The resident composer survives no-Session and Session transitions. The no-Sessio
|
||||
|
||||
`conversation.composer` is a generic chain. Its complete owner currency is:
|
||||
|
||||
```ts
|
||||
export interface ComposerChainProps {
|
||||
```ts type-equiv
|
||||
/** Owner values used to elect a composer takeover. */
|
||||
interface ComposerChainProps {
|
||||
/** Current Session identity used by temporary business-owned entries. */
|
||||
sessionId: SessionId | undefined
|
||||
/** Current Session lifecycle state, absent without a selected Session. */
|
||||
session: SessionSnapshot | undefined
|
||||
/** Effective business-owned interaction awaiting the user in this Session. */
|
||||
pendingInteraction: SessionPendingInteraction | undefined
|
||||
}
|
||||
```
|
||||
|
||||
@@ -62,6 +67,14 @@ try {
|
||||
|
||||
The selector must be a pure function of the owner currency. Its non-null return is delivered to the component as `matched`; `PropsRuntime<'conversation.composer'>` supplies the standard Session and global props. Chain order remains ascending `priority`, then registration order, and the first non-null selector wins. The shell keeps the default composer mounted beneath a takeover. Request state, listeners, response encoding, and any request-specific child slots belong to the business package; they are not carried by `SessionSnapshot` or declared by this core package.
|
||||
|
||||
## Model experience
|
||||
## Model Experience
|
||||
|
||||
None. The package renders browser state and sends user-admitted inputs through Session Controller APIs; it does not construct model requests.
|
||||
None, as this package renders browser state and sends user-admitted inputs through Session Controller APIs without constructing model requests.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
None; Conversation assembly and browser input state do not alter provider-side prompt caching.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Only registered targets can render** — the shell deliberately has no implicit fallback target beyond the registered `chat` preference.
|
||||
|
||||
@@ -24,10 +24,15 @@ View 选择规则固定:有效且已注册的持久化选择优先,其次是
|
||||
|
||||
`conversation.composer` 是通用 chain,其完整 owner currency 为:
|
||||
|
||||
```ts
|
||||
export interface ComposerChainProps {
|
||||
```ts type-equiv
|
||||
/** Owner values used to elect a composer takeover. */
|
||||
interface ComposerChainProps {
|
||||
/** Current Session identity used by temporary business-owned entries. */
|
||||
sessionId: SessionId | undefined
|
||||
/** Current Session lifecycle state, absent without a selected Session. */
|
||||
session: SessionSnapshot | undefined
|
||||
/** Effective business-owned interaction awaiting the user in this Session. */
|
||||
pendingInteraction: SessionPendingInteraction | undefined
|
||||
}
|
||||
```
|
||||
|
||||
@@ -64,4 +69,12 @@ selector 必须是 owner currency 的纯函数。非 null 返回值作为 `match
|
||||
|
||||
## 模型体验
|
||||
|
||||
无。本包渲染浏览器状态,并通过 Session Controller API 发送用户确认提交的输入;它不构造模型请求。
|
||||
无,因为本包渲染浏览器状态,并通过 Session Controller API 发送用户确认提交的输入,而不构造模型请求。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
无;Conversation 组装和浏览器输入状态不会改变提供方侧的 prompt cache。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **只有已注册 target 可以渲染**——除已注册的 `chat` 偏好外,shell 刻意不提供隐式 fallback target。
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {} from '@deepseek-ai/dsh-client-locale/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-session/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-workspace/client'
|
||||
import { UiConversation } from './conversation/assembly.ts'
|
||||
import type { ViewTab } from './contract/views.ts'
|
||||
import type {
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-jobs/README.md
|
||||
README.md: e8c1852aca0b7fb375b3c58748a9f37385e8ebee
|
||||
README.zh.md: b9f980283a7cbddce3c8a4de07079e5fc3b61212
|
||||
README.md: 0523aa10ebfbaa6cde0bef391017bc0307d8bdd5
|
||||
README.zh.md: bb713f446855a9e8b23c5543827b9897f1177a48
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Web background-job feature owner: contributes one entry to `conversation.session.header.actions` listing the `ctx.jobs` records this session can see. The data arrives entirely through the `jobsBySession` list mirror that [`dsh-client-runtime`](../runtime/README.md) folds from `session/jobs` frames, so this package issues no RPC and holds no state beyond popover visibility.
|
||||
Web background-job feature owner: contributes one entry to `conversation.session.header.actions` listing the `ctx.jobs` records this session can see. The data arrives entirely through the `jobsBySession` list mirror that the [Session Controller](../../api/session-controller/README.md) folds from `session/jobs` frames, so this package issues no RPC and holds no state beyond popover visibility.
|
||||
|
||||
The trigger renders only when the session has at least one job, so an ordinary conversation never grows a control for a capability it is not using. Its badge counts `running` plus `stopping` and is omitted at zero, leaving a session that holds only finished jobs a quiet entry point into its history rather than one advertising a count of nothing. The popover is a flat list: live rows first by `startedAt` ascending, then settled rows by `finishedAt` descending, with a same-millisecond tie broken on start order so the host's map iteration never decides it. A row shows the producer kind, the label, a status marker, the producer's `detail` in place of the generic status word once it has one, and an elapsed duration. That duration advances once per second while the row is live and freezes at `finishedAt`; the clock runs only while an open list holds something that moves. A settled row missing `finishedAt` reads as zero rather than as a negative figure, and a duration past an hour stays in hours rather than growing a day vocabulary no producer currently reaches.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
Web 后台任务特性的归属方:向 `conversation.session.header.actions` 贡献一个条目,列出当前会话可见的 `ctx.jobs` 记录。数据完全来自 [`dsh-client-runtime`](../runtime/README.zh.md) 从 `session/jobs` 帧折叠出的 `jobsBySession` 列表镜像,因此本包不发任何 RPC,除弹层开合外不持有任何状态。
|
||||
Web 后台任务特性的归属方:向 `conversation.session.header.actions` 贡献一个条目,列出当前会话可见的 `ctx.jobs` 记录。数据完全来自 [Session Controller](../../api/session-controller/README.zh.md) 从 `session/jobs` 帧折叠出的 `jobsBySession` 列表镜像,因此本包不发任何 RPC,除弹层开合外不持有任何状态。
|
||||
|
||||
只有当会话至少有一个任务时才渲染触发器,普通对话不会因为一项未被使用的能力而长出控件。角标计数为 `running` 加 `stopping`,为零时省略,这样只剩已完成任务的会话保留一个安静的历史入口,而不是宣告一个「零」。弹层是一个扁平列表:活跃行在前按 `startedAt` 升序,随后终态行按 `finishedAt` 降序;毫秒相同的并列按启动顺序打破,宿主的 map 迭代顺序永远不参与决定。一行显示生产者 kind、label、状态标记、生产者一旦给出 `detail` 就取代通用状态词的那段文字,以及已耗时。该耗时在活跃时每秒推进,并在 `finishedAt` 冻结;只有当打开的列表里确实有会动的东西时时钟才运行。缺少 `finishedAt` 的终态行读作零而不是负数,超过一小时的耗时停留在小时单位,不会长出任何生产者目前都到不了的「天」词汇。
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-session/README.md
|
||||
README.md: d18dec6232ff43112af761e27104cc50db84b169
|
||||
README.zh.md: 4c72c767a3a2cddef7dc9793b88425b3d20a4d90
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-session
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
React and Slot adapter for Session Controller state. It contributes Session list and pending-interaction hooks at root scope, materializes per-Session hooks and props, and owns the standard `SessionProvider` rendering behavior without taking ownership of Session transport or lifecycle state.
|
||||
|
||||
## Model Experience
|
||||
|
||||
None, as this package adapts browser-side Session state and registers nothing model-facing.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
None; Session selectors and Slot scopes do not assemble model requests.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Pending interactions are process-local projections** — the owning Remote waterfall must replay an outstanding request after a browser reconnect.
|
||||
@@ -0,0 +1,17 @@
|
||||
# @deepseek-ai/dsh-client-ui-session
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
面向 Session Controller 状态的 React 与 Slot adapter。本包在 root scope 提供 Session list 和 pending-interaction hook,物化逐 Session hook 与 prop,并拥有标准 `SessionProvider` 渲染行为,但不接管 Session transport 或 lifecycle 状态。
|
||||
|
||||
## 模型体验
|
||||
|
||||
无,因为本包适配浏览器侧 Session 状态,不注册任何面向模型的内容。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
无;Session selector 与 Slot scope 不会组装模型请求。
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **Pending interaction 是进程本地投影**——浏览器重连后,所属 Remote waterfall 必须重放仍未完成的请求。
|
||||
@@ -77,7 +77,6 @@ class PendingInteractionDomain<T extends SessionPendingInteractionBase> {
|
||||
return () => {
|
||||
if (!active) return
|
||||
active = false
|
||||
if (this.values.get(interaction.key) !== interaction) return
|
||||
this.values.delete(interaction.key)
|
||||
this.changed()
|
||||
}
|
||||
@@ -206,7 +205,7 @@ export class UiSession extends Service {
|
||||
private readonly pendingListeners = new Set<() => void>()
|
||||
/** Root source of pending UI interactions, independent from Controller snapshots. */
|
||||
readonly pendingInteractions: HostObservable<SessionPendingInteractionSnapshot> = {
|
||||
getSnapshot: () => this.pendingSnapshot as SessionPendingInteractionSnapshot,
|
||||
getSnapshot: () => this.pendingSnapshot,
|
||||
subscribe: (listener) => {
|
||||
this.pendingListeners.add(listener)
|
||||
return () => { this.pendingListeners.delete(listener) }
|
||||
@@ -294,7 +293,7 @@ export class UiSession extends Service {
|
||||
this.publishPendingInteractions()
|
||||
return () => {
|
||||
const index = this.pendingDomains.indexOf(runtimeDomain)
|
||||
if (index !== -1) this.pendingDomains.splice(index, 1)
|
||||
this.pendingDomains.splice(index, 1)
|
||||
this.publishPendingInteractions()
|
||||
}
|
||||
}, 'uiSession.registerPendingInteraction()')
|
||||
@@ -366,19 +365,18 @@ export class UiSession extends Service {
|
||||
|
||||
private createMaterializedBinding(owner: SessionBinding): MaterializedBinding {
|
||||
const value = this.materialize(owner)
|
||||
let releaseEffect: () => void | Promise<void> = () => {}
|
||||
const record: MaterializedBinding = {
|
||||
owner,
|
||||
value,
|
||||
release: () => { void releaseEffect() },
|
||||
}
|
||||
releaseEffect = owner.ctx.effect(() => () => {
|
||||
const releaseEffect = owner.ctx.effect(() => () => {
|
||||
if (this.bindings.get(owner.sessionId) !== record) return
|
||||
this.bindings.delete(owner.sessionId)
|
||||
if (this.currentBinding !== value) return
|
||||
this.currentBinding = this.absent
|
||||
notifySubscribers(this.currentListeners, '[ui-session] current binding')
|
||||
}, `ui-session: binding ${owner.sessionId}`)
|
||||
const record: MaterializedBinding = {
|
||||
owner,
|
||||
value,
|
||||
release: () => { void releaseEffect() },
|
||||
}
|
||||
return record
|
||||
}
|
||||
|
||||
|
||||
@@ -260,6 +260,19 @@ describe('UiSession bindings', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('releases cached bindings when the owning Client context stops', async () => {
|
||||
const ctx = new Context()
|
||||
const bench = createSessionsBench(ctx)
|
||||
const service = createUiSession(ctx, bench)
|
||||
const id = sessionId('s1')
|
||||
bench.binding(id)
|
||||
bench.select(id)
|
||||
service.adapter.current.getSnapshot()
|
||||
|
||||
await expect(ctx.fiber.dispose()).resolves.toBeUndefined()
|
||||
await bench.release(id)
|
||||
})
|
||||
|
||||
it('rebuilds live bindings and removes only the disposed source contribution', () => {
|
||||
const ctx = new Context()
|
||||
const bench = createSessionsBench(ctx)
|
||||
@@ -370,10 +383,30 @@ describe('UiSession bindings', () => {
|
||||
})).toThrow("uiSession.provide: duplicate prop 'useFeature' at prop 'useFeature'")
|
||||
expect(service.adapter.current.getSnapshot()).toBe(before)
|
||||
})
|
||||
|
||||
it('releases partially rebuilt bindings when a later Session contribution fails', () => {
|
||||
const ctx = new Context()
|
||||
const bench = createSessionsBench(ctx)
|
||||
const service = createUiSession(ctx, bench)
|
||||
service.adapter.resolve(bench.binding(sessionId('s1')).sessionId)
|
||||
service.adapter.resolve(bench.binding(sessionId('s2')).sessionId)
|
||||
let calls = 0
|
||||
|
||||
expect(() => service.provide({
|
||||
props: ['partial'],
|
||||
resolve: () => {
|
||||
calls += 1
|
||||
if (calls === 2) throw new Error('second binding failed')
|
||||
return { props: { partial: true } }
|
||||
},
|
||||
})).toThrow('second binding failed')
|
||||
expect(calls).toBe(2)
|
||||
expect(service.adapter.resolve(sessionId('s1'))?.props).not.toHaveProperty('partial')
|
||||
})
|
||||
})
|
||||
|
||||
describe('UiSession pending interactions', () => {
|
||||
it('publishes the highest-precedence exact object and removes each source independently', () => {
|
||||
it('publishes the highest-precedence exact object and removes each source independently', async () => {
|
||||
const ctx = new Context()
|
||||
const bench = createSessionsBench(ctx)
|
||||
const service = createUiSession(ctx, bench)
|
||||
@@ -386,12 +419,16 @@ describe('UiSession pending interactions', () => {
|
||||
const registerQuestion = service.registerPendingInteraction<SessionPendingInteractionBase>(
|
||||
interaction => interaction.kind === 'plan-review' ? 2 : 1,
|
||||
)
|
||||
const registerBackground = service.registerPendingInteraction<SessionPendingInteractionBase>(
|
||||
() => -1,
|
||||
)
|
||||
listener.mockClear()
|
||||
|
||||
const approval = { key: 'approval:1', kind: 'approval', sessionId: id }
|
||||
const duplicate = { key: 'approval:2', kind: 'approval', sessionId: id }
|
||||
const question = { key: 'question:1', kind: 'question', sessionId: id }
|
||||
const plan = { key: 'question:2', kind: 'plan-review', sessionId: id }
|
||||
const background = { key: 'background:1', kind: 'background', sessionId: id }
|
||||
const removeApproval = registerApproval(approval)
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(approval)
|
||||
const removeDuplicate = registerApproval(duplicate)
|
||||
@@ -400,7 +437,10 @@ describe('UiSession pending interactions', () => {
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(question)
|
||||
const removePlan = registerQuestion(plan)
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(plan)
|
||||
const removeBackground = registerBackground(background)
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(plan)
|
||||
|
||||
removeBackground()
|
||||
removeQuestion()
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(plan)
|
||||
removePlan()
|
||||
@@ -408,8 +448,10 @@ describe('UiSession pending interactions', () => {
|
||||
removeDuplicate()
|
||||
expect(service.pendingInteractions.getSnapshot().get(id)).toBe(approval)
|
||||
removeApproval()
|
||||
removeApproval()
|
||||
expect(service.pendingInteractions.getSnapshot().has(id)).toBe(false)
|
||||
off()
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('rejects duplicate keys and contains a failing aggregate subscriber', () => {
|
||||
|
||||
@@ -6,6 +6,8 @@ import type {} from '@deepseek-ai/dsh-client-locale/client'
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
||||
// Type-only: pulls the Session root standard-props merge.
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-session/client'
|
||||
// Type-only: records the Workspace UI service dependency used below.
|
||||
import type {} from '@deepseek-ai/dsh-client-ui-workspace/client'
|
||||
import type { SidebarRootInjected } from './contract/slots.ts'
|
||||
import { SidebarRoot } from './SidebarRoot.tsx'
|
||||
import { en, zh, type SidebarKey } from './locales.ts'
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-slots/README.md
|
||||
README.md: 332bd092e8a4dec5a424acccce57c3dd0d8c27d8
|
||||
README.zh.md: 369776ea72c6f21184c0accd183aa9b409ee867a
|
||||
README.md: 7d5bffae32f4f1056f54d02f4a949bc7ed34058d
|
||||
README.zh.md: 8c242b94c88aa7414a6e32641269fb1e4ce4308c
|
||||
|
||||
@@ -19,7 +19,7 @@ The standard-kit interfaces (`SessionStandardProps`, `GlobalStandardProps`) are
|
||||
|
||||
The store family (`defineStore` spec in / `StoreHandle<T, A>` out) types the store seat: `init` infers the state schema, `actions` is the complete draft-transform write set, `BakedActions` strips the draft parameter into the callbacks components and inject factories receive. The `defineStore` value implementation lives in the runtime package (the engine's home) and satisfies the `DefineStore` contract exported here. Engine products and the renderer host contract carry bare snapshot sources (`getSnapshot`/`subscribe`), never React hooks — hook binding belongs to the render machinery; only the props-contract hook type (`SnapshotSelectorHook`) lives here.
|
||||
|
||||
`SlotCore` seeds the a-priori `'root'` slot at construction and enforces load-time validation (undeclared-slot registration, duplicate child declaration, one shared handle under two scopes, a chain registration without `select` — all throw at register). An entry's disposer collapses its declared child slots recursively: ledger rows, contributions, and store mounts die on one lifecycle axis. Each key also carries a declaration epoch that advances only on declaration and collapse; the runtime uses it for [`ctx.slots.inject`](../runtime/README.md#slot-declaration-injection), independently from ordinary entry versions. `renderer.ts` carries the installation contract (`SlotRenderer`, `SlotRendererHost`) plus `StaleAuthorizationError`/`SlotOwnershipError`; ui-renderer owns both the implementation and its plugin-lifecycle installation.
|
||||
`SlotCore` seeds the a-priori `'root'` slot at construction and enforces load-time validation (undeclared-slot registration, duplicate child declaration, one shared handle under two scopes, a chain registration without `select` — all throw at register). An entry's disposer collapses its declared child slots recursively: ledger rows, contributions, and store mounts die on one lifecycle axis. Each key also carries a declaration epoch that advances only on declaration and collapse; `ui-renderer` uses it for [`ctx.slots.inject`](../../../.agents/notes/implemented/architecture/2026-08-05-slot-declaration-injection.md), independently from ordinary entry versions. `renderer.ts` carries the installation contract (`SlotRenderer`, `SlotRendererHost`) plus `StaleAuthorizationError`/`SlotOwnershipError`; ui-renderer owns both the implementation and its plugin-lifecycle installation.
|
||||
|
||||
## Model Experience
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ chain-kind slot 会反转键控路由:条目自行提名,而不是由分发
|
||||
|
||||
store 家族(输入 `defineStore` 规范/输出 `StoreHandle<T, A>`)为 store seat 建模:`init` 推断状态 schema;`actions` 是完整的 draft-transform 写入集合;`BakedActions` 移除 draft 参数,成为组件和 inject factory 收到的回调。`defineStore` 值实现位于运行时包(引擎所属位置),并满足这里导出的 `DefineStore` 约定。引擎产物与 renderer host 约定携带裸快照 source(`getSnapshot`/`subscribe`),绝不携带 React 钩子;钩子绑定属于渲染机制,只有 props 约定钩子类型(`SnapshotSelectorHook`)位于这里。
|
||||
|
||||
`SlotCore` 在构造时预置 `'root'` slot,并强制执行加载时验证(注册未声明 slot、重复声明子项、在两个 scope 下使用同一个共享 handle、chain 注册缺少 `select`,这些情况都在 register 时抛出)。条目的 disposer 会递归移除其声明的子 slot:账本行、贡献和 store 挂载都会随同一生命周期结束而移除。每个 key 还携带一个 declaration epoch(声明代次),它只在声明与移除时递增;运行时将其用于 [`ctx.slots.inject`](../runtime/README.zh.md#slot-declaration-injection),且与普通条目版本相互独立。`renderer.ts` 携带安装约定(`SlotRenderer`、`SlotRendererHost`)以及 `StaleAuthorizationError`/`SlotOwnershipError`;ui-renderer 同时持有实现及其插件生命周期安装。
|
||||
`SlotCore` 在构造时预置 `'root'` slot,并强制执行加载时验证(注册未声明 slot、重复声明子项、在两个 scope 下使用同一个共享 handle、chain 注册缺少 `select`,这些情况都在 register 时抛出)。条目的 disposer 会递归移除其声明的子 slot:账本行、贡献和 store 挂载都会随同一生命周期结束而移除。每个 key 还携带一个 declaration epoch(声明代次),它只在声明与移除时递增;`ui-renderer` 将其用于 [`ctx.slots.inject`](../../../.agents/notes/implemented/architecture/2026-08-05-slot-declaration-injection.zh.md),且与普通条目版本相互独立。`renderer.ts` 携带安装约定(`SlotRenderer`、`SlotRendererHost`)以及 `StaleAuthorizationError`/`SlotOwnershipError`;ui-renderer 同时持有实现及其插件生命周期安装。
|
||||
|
||||
## 模型体验
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ async function bench(declare = true) {
|
||||
const registerPendingInteraction = vi.fn((_precedence: (value: PendingQuestion) => number) => (
|
||||
value: PendingQuestion,
|
||||
) => {
|
||||
_precedence(value)
|
||||
pending = [...pending, value]
|
||||
return () => { pending = pending.filter(candidate => candidate !== value) }
|
||||
})
|
||||
|
||||
@@ -876,7 +876,7 @@ describe('plugin lifecycle', () => {
|
||||
ctx.provide('remote', { $on: () => () => {} } as never)
|
||||
ctx.provide('settingsScope', { bind: () => stubSettingsScope().scope } as never)
|
||||
await ctx.plugin(TestSessions).await()
|
||||
const conversationEvents = new UiConversation(ctx, ctx.sessions as never).events
|
||||
const conversationEvents = new UiConversation(ctx, ctx.sessions).events
|
||||
ctx.slots.register({
|
||||
name: 'root',
|
||||
children: { 'conversation.chat.node': { kind: 'keyed', scope: 'session' } },
|
||||
|
||||
@@ -57,6 +57,19 @@ describe('deriveGroups', () => {
|
||||
.toMatchObject({ pendingInteraction: 'plan-review', running: true })
|
||||
})
|
||||
|
||||
it.each(['approval', 'question'] as const)(
|
||||
'projects the %s pending-interaction kind',
|
||||
(kind) => {
|
||||
const awaiting = summary(kind, 10)
|
||||
const attention: ReadonlyMap<SessionId, SessionPendingInteractionBase> = new Map([[
|
||||
awaiting.id,
|
||||
{ key: `${kind}:1`, kind, sessionId: awaiting.id },
|
||||
]])
|
||||
|
||||
expect(deriveFlat(list(awaiting), noArchive, attention)[0]?.pendingInteraction).toBe(kind)
|
||||
},
|
||||
)
|
||||
|
||||
it('puts only real unaccounted Sessions in the trailing Ungrouped group', () => {
|
||||
const sessions = list(summary('owned', 1, '/projects/first'), summary('loose', 9, '/other'))
|
||||
const groups = deriveGroups(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2339,18 +2339,12 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
},
|
||||
{
|
||||
key: 'userQuestions',
|
||||
summary: '`ctx.userQuestions`: one active UI provider plus an `ask()` API.',
|
||||
description: '`ctx.userQuestions`: one active UI provider plus an `ask()` API.',
|
||||
summary: '`ctx.userQuestions`: validation plus the scoped answerer waterfall.',
|
||||
description: '`ctx.userQuestions`: validation plus the scoped answerer waterfall.',
|
||||
methods: [
|
||||
{
|
||||
signature: 'registerProvider(provider: UserQuestionProvider): () => void',
|
||||
description: 'Register the UI provider. Only one provider may be active in a context.',
|
||||
parameters: [{ name: 'provider', description: 'UI-side implementation that collects answers.' }],
|
||||
returns: 'Disposer that unregisters this provider.',
|
||||
},
|
||||
{
|
||||
signature: 'async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>',
|
||||
description: 'Ask the active UI provider and wait for the user\'s answer.\n\nWhen a caller supplies an agent, human interaction is valid only for the exact live runtime root. Runtime ownership, not durable session lineage, decides this boundary: an owned child has no human answerer and would block forever, while a lineage-bearing session resumed as a new runtime root may ask normally.',
|
||||
description: 'Ask the scoped answerer waterfall and wait for the user\'s answer.\n\nWhen a caller supplies an agent, human interaction is valid only for the exact live runtime root. Runtime ownership, not durable session lineage, decides this boundary: an owned child has no human answerer and would block forever, while a lineage-bearing session resumed as a new runtime root may ask normally.',
|
||||
parameters: [{ name: 'request', description: 'Questions, owner agent, and abort signal.' }],
|
||||
returns: 'The answer chosen or typed by the human.',
|
||||
throws: ['{UserQuestionError} code `ASK_ABORTED` when the supplied signal is already or becomes aborted, `CALLER_NOT_LIVE` when a supplied agent is not the registry\'s exact live instance, or `DELEGATED_CALLER` when that live agent is owned by another agent.'],
|
||||
@@ -3185,11 +3179,11 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'AskUserQuestionRequest',
|
||||
declaration: 'export interface AskUserQuestionRequest {\n questions: AskUserQuestionItem[];\n agent?: Agent;\n signal?: AbortSignal;\n}',
|
||||
declaration: 'export interface AskUserQuestionRequest extends AskUserQuestionRequestEvent {\n}',
|
||||
},
|
||||
{
|
||||
name: 'AskUserQuestionRequestEvent',
|
||||
declaration: 'export interface AskUserQuestionRequestEvent {\n questions: AskUserQuestionItem[];\n agent: Agent;\n signal?: AbortSignal;\n}',
|
||||
declaration: 'export interface AskUserQuestionRequestEvent {\n questions: AskUserQuestionItem[];\n agent?: Agent;\n signal?: AbortSignal;\n}',
|
||||
},
|
||||
{
|
||||
name: 'AssembleContext',
|
||||
@@ -4363,6 +4357,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'ServerResponse',
|
||||
declaration: 'export interface ServerResponse {\n type: \'server-response\';\n rpcId: RpcId;\n result: RpcResult<unknown>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'Session',
|
||||
declaration: 'export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n get id(): SessionId;\n readonly firstLiveSeq: number;\n static create(id: SessionId, seed?: readonly SessionEvent[], header?: SessionHeader): Session;\n static fromRestore(id: SessionId, seed: readonly SessionEvent[], header: SessionHeader): Session;\n get events(): readonly SessionEvent[];\n get seq(): number;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [\n opts: SurfaceIntent\n ] : [\n ]): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionAddress',
|
||||
declaration: 'export type SessionAddress = {\n readonly kind: \'session\';\n readonly sessionId: SessionId;\n} | {\n readonly kind: \'subagent\';\n readonly parentSessionId: SessionId;\n readonly childSessionId: SessionId;\n readonly mode: \'one-shot\' | \'continuable\';\n};',
|
||||
@@ -4683,6 +4681,14 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SessionStartSource',
|
||||
declaration: 'export type SessionStartSource = \'startup\' | \'resume\' | \'clear\' | \'compact\';',
|
||||
},
|
||||
{
|
||||
name: 'SessionSummary',
|
||||
declaration: 'export interface SessionSummary {\n readonly sessionId: SessionId;\n readonly updatedAt: number;\n readonly running: boolean;\n readonly blank: boolean;\n readonly parentSessionId?: SessionId;\n readonly origin?: \'subagent\';\n readonly cwd?: string;\n readonly agentPreset?: string;\n readonly projections?: SessionProjectionsBlock;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionSurface',
|
||||
declaration: 'export interface SessionSurface {\n readonly nodes: readonly number[];\n readonly replaceGeneration: number;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SessionSurfaceSnapshot',
|
||||
declaration: 'export interface SessionSurfaceSnapshot {\n session: SessionHeader;\n capturedThroughSeq: number | null;\n events: SurfaceEvent[];\n}',
|
||||
@@ -5047,6 +5053,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'SurfaceEventType',
|
||||
declaration: 'export type SurfaceEventType = \'user/message\' | \'assistant/message\' | \'tool/result\';',
|
||||
},
|
||||
{
|
||||
name: 'SurfaceIntent',
|
||||
declaration: 'export interface SurfaceIntent {\n surfaceOp: SurfaceOp;\n sourceEventSeqs?: number[];\n}',
|
||||
},
|
||||
{
|
||||
name: 'SurfaceOp',
|
||||
declaration: 'export type SurfaceOp = \'append\' | {\n op: \'replace\';\n start: number;\n end: number;\n};',
|
||||
@@ -5411,10 +5421,6 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'UserMessage',
|
||||
declaration: 'export interface UserMessage extends Message {\n readonly role: \'user\';\n}',
|
||||
},
|
||||
{
|
||||
name: 'UserQuestionProvider',
|
||||
declaration: 'export interface UserQuestionProvider {\n ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'VerifiedWebhookDelivery',
|
||||
declaration: 'export interface VerifiedWebhookDelivery<K extends string = string> {\n readonly kind: K;\n readonly source: WebhookSourceId;\n readonly deliveryId: WebhookDeliveryId;\n readonly event: WebhookEventOf<K>;\n readonly receivedAt: number;\n}',
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
import { Context, Service } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-agent'
|
||||
import { HarnessError } from '@deepseek-ai/dsh-llm'
|
||||
import { scopeTarget } from '@deepseek-ai/dsh-scope'
|
||||
|
||||
|
||||
@@ -256,9 +256,11 @@ describe('stores', () => {
|
||||
it('storeOf guards: before renderRoot, and for storeless entries', async () => {
|
||||
const runtime = await runtimeWithFrame()
|
||||
runtime.slots.register({ name: 'trt.panel' }, () => null)
|
||||
runtime.slots.register({ name: 'trt.chat', store: createSuiteStore() }, () => null)
|
||||
expect(() => runtime.storeOf('trt.panel')).toThrow(/before renderRoot/)
|
||||
runtime.renderRoot()
|
||||
expect(() => runtime.storeOf('trt.panel')).toThrow(/declares no store/)
|
||||
expect(() => runtime.storeOf('trt.chat', 'missing')).toThrow(/no live Session binding/)
|
||||
await runtime.dispose()
|
||||
})
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/typert/protocol/README.md
|
||||
README.md: 84f9f1b31cca35cffce5dc5fc84db1017adaad08
|
||||
README.zh.md: 97e4734a7292f0a305ff8ed00ff1d72d1a53b5e9
|
||||
README.md: 3d8df3808a378cae115edb938160f73766f68747
|
||||
README.zh.md: 15247f37b0c08c1e0e9de38d159e5e7aea945109
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/typert/registry/README.md
|
||||
README.md: fa227b1c8faf1abd5a6492d4b8fe7d0c51ceeef1
|
||||
README.zh.md: 62c5a2141de9ccdd564654658a464d721b77f97d
|
||||
README.md: 2f3056735f5352c06b1e115a18c7ad1968ff90ae
|
||||
README.zh.md: 770d3111fc65b08ee5d30ead6c3e6899630dd3e0
|
||||
|
||||
@@ -148,7 +148,9 @@ export const SERVICE_WALK_EXEMPTIONS: Record<string, string> = {
|
||||
launchEnvironment: 'not a service: launcher-provided root accessor value (LaunchEnvironmentSnapshot | undefined) — packages/util/launch-environment/README.md owns this launcher contract',
|
||||
connection: 'interface-typed (HostConnectionHandle); implementing class HostConnectionService is declared in rpc-host.ts — packages/client/connection/README.md owns the API',
|
||||
uiRenderer: 'client-side interface-typed browser service — packages/client/ui-renderer/README.md owns the API',
|
||||
uiSession: 'client-side Session source adapter — packages/client/ui-session/README.md owns the API',
|
||||
uiConversation: 'client-side Conversation registries and assembler — packages/client/ui-conversation/README.md owns the API',
|
||||
uiWorkspace: 'client-side Workspace navigation adapter — packages/client/ui-workspace/README.md owns the API',
|
||||
settingsSchema: 'client-side schema introspection service — packages/client/ui-settings/README.md owns the API',
|
||||
settingsScope: 'client-side settings-namespace transport service — packages/client/ui-settings/README.md owns the API',
|
||||
chatFileMentions: 'client-side slot-contract accessor (ChatFileMentions) — packages/client/ui-chat/README.md owns the API',
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { collectPackageGraph } from './package-graph.ts'
|
||||
|
||||
const roots: string[] = []
|
||||
|
||||
afterEach(() => {
|
||||
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
|
||||
})
|
||||
|
||||
function fixture(packages: Readonly<Record<string, readonly string[]>>): string {
|
||||
const root = mkdtempSync(join(tmpdir(), 'dsh-package-graph-'))
|
||||
roots.push(root)
|
||||
for (const [name, dependencies] of Object.entries(packages)) {
|
||||
const directory = join(root, 'packages', 'client', name)
|
||||
mkdirSync(directory, { recursive: true })
|
||||
writeFileSync(join(directory, 'package.json'), `${JSON.stringify({
|
||||
name: `@deepseek-ai/dsh-${name}`,
|
||||
peerDependencies: Object.fromEntries(dependencies.map(dependency => [
|
||||
`@deepseek-ai/dsh-${dependency}`,
|
||||
'workspace:^',
|
||||
])),
|
||||
}, null, 2)}\n`)
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
describe('collectPackageGraph', () => {
|
||||
it('orders packages after their dependencies', () => {
|
||||
const root = fixture({ application: ['feature'], feature: ['foundation'], foundation: [] })
|
||||
|
||||
expect(collectPackageGraph(root, ['client'], 'fixture').map(pkg => pkg.short))
|
||||
.toEqual(['foundation', 'feature', 'application'])
|
||||
})
|
||||
|
||||
it('keeps a dependency cycle together and before its consumers', () => {
|
||||
const root = fixture({ consumer: ['left'], left: ['right'], right: ['left'], foundation: [] })
|
||||
|
||||
expect(collectPackageGraph(root, ['client'], 'fixture').map(pkg => pkg.short))
|
||||
.toEqual(['foundation', 'left', 'right', 'consumer'])
|
||||
})
|
||||
|
||||
it('rejects a missing in-repo peer', () => {
|
||||
const root = fixture({ consumer: ['missing'] })
|
||||
|
||||
expect(() => collectPackageGraph(root, ['client'], 'fixture'))
|
||||
.toThrow('fixture: @deepseek-ai/dsh-consumer references missing in-repo peer @deepseek-ai/dsh-missing')
|
||||
})
|
||||
})
|
||||
@@ -25,11 +25,12 @@ export interface PackageGraphNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read every harness package manifest and return dependency-safe graph nodes.
|
||||
* Read every harness package manifest and return dependency-first graph nodes.
|
||||
* @param root - absolute repository root.
|
||||
* @param groupOrder - caller-specific tiebreak order for packages in the same dependency layer.
|
||||
* @param gate - command name used in structural error messages.
|
||||
* @returns package nodes ordered after all of their in-repo dependencies.
|
||||
* @returns package nodes ordered after their in-repo dependencies, except for
|
||||
* stable back edges inside a dependency cycle.
|
||||
*/
|
||||
export function collectPackageGraph(root: string, groupOrder: readonly string[], gate: string): PackageGraphNode[] {
|
||||
const packages: PackageGraphNode[] = []
|
||||
@@ -57,14 +58,28 @@ export function collectPackageGraph(root: string, groupOrder: readonly string[],
|
||||
}
|
||||
|
||||
function topoSort(packages: PackageGraphNode[], groupOrder: readonly string[], gate: string): PackageGraphNode[] {
|
||||
const remaining = new Map(packages.map(pkg => [pkg.short, pkg]))
|
||||
const byName = new Map(packages.map(pkg => [pkg.short, pkg]))
|
||||
for (const pkg of packages) {
|
||||
for (const dependency of pkg.deps) {
|
||||
if (!byName.has(dependency)) {
|
||||
throw new Error(`${gate}: ${pkg.name} references missing in-repo peer ${SCOPE}${dependency}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
const remaining = new Map(byName)
|
||||
const placed = new Set<string>()
|
||||
const out: PackageGraphNode[] = []
|
||||
while (remaining.size > 0) {
|
||||
const ready = [...remaining.values()]
|
||||
let ready = [...remaining.values()]
|
||||
.filter(pkg => pkg.deps.every(dep => placed.has(dep)))
|
||||
.sort((a, b) => comparePackages(a, b, groupOrder))
|
||||
if (ready.length === 0) throw new Error(`${gate}: dependency cycle among ${[...remaining.keys()].join(', ')}`)
|
||||
if (ready.length === 0) {
|
||||
const cycle = sinkCycles(remaining)
|
||||
.map(component => component.sort((a, b) => comparePackages(a, b, groupOrder)))
|
||||
.sort((a, b) => comparePackages(a[0], b[0], groupOrder))[0]
|
||||
if (cycle === undefined) throw new Error(`${gate}: could not order package dependency graph`)
|
||||
ready = cycle
|
||||
}
|
||||
for (const pkg of ready) {
|
||||
out.push(pkg)
|
||||
placed.add(pkg.short)
|
||||
@@ -74,6 +89,66 @@ function topoSort(packages: PackageGraphNode[], groupOrder: readonly string[], g
|
||||
return out
|
||||
}
|
||||
|
||||
type PackageGraphComponent = [PackageGraphNode, ...PackageGraphNode[]]
|
||||
|
||||
function sinkCycles(remaining: ReadonlyMap<string, PackageGraphNode>): PackageGraphComponent[] {
|
||||
let nextIndex = 0
|
||||
const indices = new Map<string, number>()
|
||||
const lowLinks = new Map<string, number>()
|
||||
const stack: PackageGraphNode[] = []
|
||||
const stacked = new Set<string>()
|
||||
const components: PackageGraphComponent[] = []
|
||||
|
||||
const visit = (pkg: PackageGraphNode): void => {
|
||||
const index = nextIndex
|
||||
nextIndex += 1
|
||||
indices.set(pkg.short, index)
|
||||
lowLinks.set(pkg.short, index)
|
||||
stack.push(pkg)
|
||||
stacked.add(pkg.short)
|
||||
for (const dependency of pkg.deps) {
|
||||
const target = remaining.get(dependency)
|
||||
if (target === undefined) continue
|
||||
if (!indices.has(target.short)) {
|
||||
visit(target)
|
||||
lowLinks.set(pkg.short, Math.min(requiredValue(lowLinks, pkg.short), requiredValue(lowLinks, target.short)))
|
||||
} else if (stacked.has(target.short)) {
|
||||
lowLinks.set(pkg.short, Math.min(requiredValue(lowLinks, pkg.short), requiredValue(indices, target.short)))
|
||||
}
|
||||
}
|
||||
if (lowLinks.get(pkg.short) !== indices.get(pkg.short)) return
|
||||
const first = stack.pop()
|
||||
if (first === undefined) throw new Error('package graph traversal lost its active component')
|
||||
stacked.delete(first.short)
|
||||
const component: PackageGraphComponent = [first]
|
||||
let member = first
|
||||
while (member !== pkg) {
|
||||
const next = stack.pop()
|
||||
if (next === undefined) throw new Error('package graph traversal lost its active component')
|
||||
stacked.delete(next.short)
|
||||
component.push(next)
|
||||
member = next
|
||||
}
|
||||
components.push(component)
|
||||
}
|
||||
|
||||
for (const pkg of remaining.values()) {
|
||||
if (!indices.has(pkg.short)) visit(pkg)
|
||||
}
|
||||
return components.filter((component) => {
|
||||
const names = new Set(component.map(pkg => pkg.short))
|
||||
const first = component[0]
|
||||
const cyclic = component.length > 1 || first.deps.includes(first.short)
|
||||
return cyclic && component.every(pkg => pkg.deps.every(dep => !remaining.has(dep) || names.has(dep)))
|
||||
})
|
||||
}
|
||||
|
||||
function requiredValue<K, V>(values: ReadonlyMap<K, V>, key: K): V {
|
||||
const value = values.get(key)
|
||||
if (value === undefined) throw new Error('package graph traversal lost an indexed node')
|
||||
return value
|
||||
}
|
||||
|
||||
function comparePackages(a: PackageGraphNode, b: PackageGraphNode, groupOrder: readonly string[]): number {
|
||||
const groupA = groupOrder.indexOf(a.group)
|
||||
const groupB = groupOrder.indexOf(b.group)
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('Oxlint invocation', () => {
|
||||
|
||||
it('uses location-preserving diagnostics in CI', () => {
|
||||
expect(resolveOxlintInvocation(['.'], { CI: 'true', DSH_OXLINT_THREADS: '4' })).toEqual({
|
||||
args: ['.', '--format=unix', '--threads=4'],
|
||||
args: ['.', '--format=default', '--threads=4'],
|
||||
env: { CI: 'true', DSH_OXLINT_THREADS: '4', GOMAXPROCS: '4' },
|
||||
})
|
||||
})
|
||||
|
||||
@@ -32,7 +32,7 @@ export interface OxlintInvocation {
|
||||
*/
|
||||
export function resolveOxlintInvocation(args: readonly string[], env: NodeJS.ProcessEnv): OxlintInvocation {
|
||||
const resolvedArgs = [...args]
|
||||
if (env.CI === 'true' && !hasOutputFormat(args)) resolvedArgs.push('--format=unix')
|
||||
if (env.CI === 'true' && !hasOutputFormat(args)) resolvedArgs.push('--format=default')
|
||||
const raw = env.DSH_OXLINT_THREADS
|
||||
if (raw === undefined || raw === '') return { args: resolvedArgs, env: { ...env } }
|
||||
const parsed = Number.parseInt(raw, 10)
|
||||
|
||||
@@ -876,11 +876,6 @@
|
||||
"symbol": "AskUserQuestionAnswer",
|
||||
"source": "packages/interaction/user-questions/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/user-questions.md",
|
||||
"symbol": "UserQuestionProvider",
|
||||
"source": "packages/interaction/user-questions/src/index.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/user-questions.md",
|
||||
"symbol": "UserQuestionError",
|
||||
@@ -1980,6 +1975,11 @@
|
||||
"doc": "docs/subsystems/feedback.md",
|
||||
"symbol": "MessageFeedbackDeleteResult",
|
||||
"source": "packages/feedback/message-feedback/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "packages/client/ui-conversation/README.md",
|
||||
"symbol": "ComposerChainProps",
|
||||
"source": "packages/client/ui-conversation/src/client/contract/slots.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user