@kodax-ai/kodax 0.7.96 → 0.7.97-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +85 -62
  3. package/README_CN.md +57 -67
  4. package/config-templates/config.example.jsonc +0 -14
  5. package/dist/chunks/{agent-7N427EVB.js → agent-J7SHFM5N.js} +1 -1
  6. package/dist/chunks/argument-completer-ZJQOWTIS.js +2 -0
  7. package/dist/chunks/{chunk-ABZDFK2X.js → chunk-2GV6MQ4T.js} +14 -14
  8. package/dist/chunks/{chunk-6QI3GOYG.js → chunk-3PS3YEDS.js} +1 -1
  9. package/dist/chunks/chunk-4VJMQDTH.js +417 -0
  10. package/dist/chunks/{chunk-NI7PBPUR.js → chunk-5DSUVP46.js} +1 -1
  11. package/dist/chunks/chunk-5P7RTSZT.js +21 -0
  12. package/dist/chunks/{chunk-XXNR6S4Q.js → chunk-6ZAQKFIM.js} +1 -1
  13. package/dist/chunks/chunk-7V2QBZ73.js +137 -0
  14. package/dist/chunks/{chunk-C7U542KM.js → chunk-F7DHZH6T.js} +1 -1
  15. package/dist/chunks/{chunk-7IMWOR34.js → chunk-HSRYDDPF.js} +1 -1
  16. package/dist/chunks/chunk-K3DQGSQU.js +372 -0
  17. package/dist/chunks/chunk-NO23K2CB.js +2 -0
  18. package/dist/chunks/{chunk-NKT3B3DR.js → chunk-OT5WHAX4.js} +1 -1
  19. package/dist/chunks/{chunk-YEAUDI6U.js → chunk-QGWHJIO4.js} +1 -1
  20. package/dist/chunks/chunk-QOFFAY5C.js +261 -0
  21. package/dist/chunks/{chunk-4PFZ7BEE.js → chunk-QVDTORL3.js} +11 -11
  22. package/dist/chunks/chunk-QZ4B4AWG.js +473 -0
  23. package/dist/chunks/chunk-RXDS6CNA.js +355 -0
  24. package/dist/chunks/{chunk-WV3DJVW4.js → chunk-VDGPJQL7.js} +135 -135
  25. package/dist/chunks/chunk-VEZ4WHPN.js +641 -0
  26. package/dist/chunks/chunk-ZPPAT25E.js +5 -0
  27. package/dist/chunks/chunk-ZQYWDI4O.js +1 -0
  28. package/dist/chunks/chunk-ZS2GUADU.js +498 -0
  29. package/dist/chunks/{chunk-GN2IY5YE.js → chunk-ZTYZYXGV.js} +1 -1
  30. package/dist/chunks/{chunk-EM4XJBTK.js → chunk-ZZQ4GDVU.js} +1 -1
  31. package/dist/chunks/{client-6WZZTTSV.js → client-MXOJ5XUN.js} +1 -1
  32. package/dist/chunks/{compaction-config-ZMEJU4U7.js → compaction-config-5VZSGKBQ.js} +1 -1
  33. package/dist/chunks/{construction-bootstrap-RX4DMHI7.js → construction-bootstrap-U2ZU2WAT.js} +1 -1
  34. package/dist/chunks/dist-CSLNWLOE.js +2 -0
  35. package/dist/chunks/dist-XXMJMJDU.js +2 -0
  36. package/dist/chunks/host-RUXYZFYN.js +2 -0
  37. package/dist/chunks/readline-helpers-JCVULR4C.js +2 -0
  38. package/dist/chunks/run-manager-DRIM5VNE.js +2 -0
  39. package/dist/chunks/utils-MQEBGKIX.js +2 -0
  40. package/dist/index.d.ts +63 -30
  41. package/dist/index.js +10 -6
  42. package/dist/kodax_bootstrap.js +1 -1
  43. package/dist/kodax_cli.js +1745 -1734
  44. package/dist/kodax_resume.js +32 -35
  45. package/dist/native/win32-x64/kodax-windows-sandbox.exe +0 -0
  46. package/dist/native/win32-x64/kodax-windows-text-transaction.node +0 -0
  47. package/dist/native/win32-x64/manifest.json +2 -2
  48. package/dist/sandbox-network-broker.js +77 -77
  49. package/dist/sdk-a2a.d.ts +33 -18
  50. package/dist/sdk-a2a.js +8 -9
  51. package/dist/sdk-agent.d.ts +33 -26
  52. package/dist/sdk-agent.js +1 -1
  53. package/dist/sdk-client.d.ts +40 -0
  54. package/dist/sdk-client.js +2 -0
  55. package/dist/sdk-coding.d.ts +87 -499
  56. package/dist/sdk-coding.js +1 -1
  57. package/dist/sdk-experimental-memory.d.ts +3 -4
  58. package/dist/sdk-experimental-memory.js +1 -1
  59. package/dist/sdk-llm.d.ts +11 -9
  60. package/dist/sdk-llm.js +1 -1
  61. package/dist/sdk-mcp.d.ts +3 -3
  62. package/dist/sdk-mcp.js +1 -1
  63. package/dist/sdk-media.d.ts +3 -1
  64. package/dist/sdk-media.js +1 -1
  65. package/dist/sdk-repl.d.ts +317 -70
  66. package/dist/sdk-repl.js +2 -2
  67. package/dist/sdk-runtime.d.ts +580 -452
  68. package/dist/sdk-runtime.js +1 -1
  69. package/dist/sdk-sandbox.js +1 -1
  70. package/dist/sdk-session.d.ts +13 -9
  71. package/dist/sdk-session.js +1 -1
  72. package/dist/sdk-skills.js +1 -1
  73. package/dist/semantic-worker.js +57 -57
  74. package/dist/types-chunks/{base.d-Bt9lhwSV.d.ts → base.d-ZBOdjDUT.d.ts} +2 -1
  75. package/dist/types-chunks/{bash-prefix-extractor.d-DWFIMg0v.d.ts → bash-prefix-extractor.d-DvswAXKS.d.ts} +136 -66
  76. package/dist/types-chunks/{capability-learning.d-gRtO03f6.d.ts → capability-learning.d-B4pxKwP4.d.ts} +1 -1
  77. package/dist/types-chunks/{capability.d-Ch5Vos33.d.ts → capability.d-DOF3r0fJ.d.ts} +1 -1
  78. package/dist/types-chunks/{capsule.d-Dj1n6s0Y.d.ts → capsule.d-B4atvlxE.d.ts} +7 -19
  79. package/dist/types-chunks/client-contract-A1jdk6xz.d.ts +1993 -0
  80. package/dist/types-chunks/{controller.d-C0IM1Tud.d.ts → controller.d-BkUJ_3sl.d.ts} +1 -1
  81. package/dist/types-chunks/{controller.d-J2t1q8Ly.d.ts → controller.d-yyKajPTi.d.ts} +140 -1380
  82. package/dist/types-chunks/{cost-tracker.d-BWI4lFWn.d.ts → cost-tracker.d-BeaenODW.d.ts} +2 -47
  83. package/dist/types-chunks/{history-retrieval.d-CPN5PMBV.d.ts → history-retrieval.d-JdFfkeF3.d.ts} +2 -2
  84. package/dist/types-chunks/{manager.d-rtmywU9M.d.ts → manager.d-C_20XqCV.d.ts} +8 -1
  85. package/dist/types-chunks/manifest.d-Bw2i-zQi.d.ts +18 -0
  86. package/dist/types-chunks/provider-credential-context.d-BH2OaB1b.d.ts +47 -0
  87. package/dist/types-chunks/provider-request-observation.d-jL8T6wVO.d.ts +34 -0
  88. package/dist/types-chunks/{public-api.d-amBop8Nk.d.ts → public-api.d-Cq8ILMte.d.ts} +52 -13
  89. package/dist/types-chunks/{resolver.d-BrwLoWNr.d.ts → resolver.d-DLY01RHx.d.ts} +4 -2
  90. package/dist/types-chunks/{types.d-CSv0_cZC.d.ts → review-inbox.d-BeaLRNHx.d.ts} +251 -3
  91. package/dist/types-chunks/{shell-command-sets.d-oejwpP_7.d.ts → review-packet.d-D4bbTbq3.d.ts} +46 -3
  92. package/dist/types-chunks/{exec-policy.d-BPESl90L.d.ts → run-manager.d-C7Q71rin.d.ts} +385 -62
  93. package/dist/types-chunks/runtime-client-info-CxnlZlW5.d.ts +175 -0
  94. package/dist/types-chunks/{sdk-session-B6XjHNU1.d.ts → sdk-session-BDFjCpDn.d.ts} +12 -4
  95. package/dist/types-chunks/{side-query.d-DHWG1JZg.d.ts → side-query.d-DTrhVd_r.d.ts} +4 -3
  96. package/dist/types-chunks/trusted-repl-entry-vbUM8R6P.d.ts +445 -0
  97. package/dist/types-chunks/{types.d-CtO8mR1s.d.ts → types.d-BJTN-RZr.d.ts} +5 -5
  98. package/dist/types-chunks/{types.d-BrQMB-hy.d.ts → types.d-BjOq57-z.d.ts} +6 -0
  99. package/dist/types-chunks/types.d-o7t9dds4.d.ts +1484 -0
  100. package/dist/types-chunks/{utils.d-DcznBeQ3.d.ts → utils.d-CWiMhFfu.d.ts} +202 -36
  101. package/docs/CLIENT_CONTRACT.md +441 -0
  102. package/docs/SDK_MIGRATION.md +123 -0
  103. package/docs/SPACE_SDK_SEAMS.md +139 -0
  104. package/package.json +10 -5
  105. package/public_docs/README.md +12 -133
  106. package/public_docs/configuration/config-files.md +8 -14
  107. package/public_docs/sdk/embedder-guide.md +494 -420
  108. package/dist/chunks/argument-completer-FAIHW7HZ.js +0 -2
  109. package/dist/chunks/chunk-66XN5AFU.js +0 -417
  110. package/dist/chunks/chunk-7O2AIFNE.js +0 -373
  111. package/dist/chunks/chunk-DSXUXUZG.js +0 -5
  112. package/dist/chunks/chunk-GYO73UYQ.js +0 -275
  113. package/dist/chunks/chunk-HPCS3LZ5.js +0 -324
  114. package/dist/chunks/chunk-HZYRLIOC.js +0 -137
  115. package/dist/chunks/chunk-SC2ELSUS.js +0 -675
  116. package/dist/chunks/chunk-TEUD5VPJ.js +0 -471
  117. package/dist/chunks/chunk-TYZ2ZAYL.js +0 -487
  118. package/dist/chunks/dist-3UCCMCYR.js +0 -2
  119. package/dist/chunks/dist-F5IWZSAY.js +0 -2
  120. package/dist/chunks/host-W2JJ3V3Q.js +0 -2
  121. package/dist/chunks/run-manager-RBWU3EVE.js +0 -2
  122. package/dist/chunks/utils-DJ4ZFJGL.js +0 -2
  123. package/dist/runtime-worker.js +0 -5381
  124. package/dist/types-chunks/review-inbox.d-CTeUIKda.d.ts +0 -225
  125. package/dist/types-chunks/run-manager.d-hm1XgEou.d.ts +0 -94
  126. package/dist/types-chunks/trusted-repl-entry-D0w5M0UZ.d.ts +0 -323
  127. package/dist/types-chunks/types.d-B1l9pWyX.d.ts +0 -146
@@ -0,0 +1,123 @@
1
+ # SDK 统一 Client 契约迁移指南
2
+
3
+ 适用范围:当前工作树的 FEATURE_298/299 实现;包基线为 `0.7.97-alpha.1`。本文包含基线之后的接缝补齐,不表示 npm 已发布这些变更。接入前应核对所安装包的导出和 Host 能力。
4
+
5
+ Space 的可信授权绑定、canonical Fork/Retry/Rewind、宿主配置、附件/统计与退出恢复范围见 [SDK/Host 接缝](SPACE_SDK_SEAMS.md)。
6
+
7
+ ## 1. 替换范围与文档权威
8
+
9
+ TUI、桌面 UI、IDE、自动化应用接入共享 KodaX 时,以 `KodaXProductClient` 为业务契约。入口是 `@kodax-ai/kodax/client`;[完整行为契约](CLIENT_CONTRACT.md)与[类型定义](../packages/coding/src/client-contract.ts)共同说明方法、数据和错误语义。[英文接入指南](../public_docs/sdk/embedder-guide.md#product-client-integration)提供最小生命周期示例。
10
+
11
+ 这不是对旧 Runtime 对象的重命名:提交输入、执行结算、交互、显示和持久历史现在各有明确边界。不要对旧对象做类型断言来假装它实现了 `KodaXProductClient`。
12
+
13
+ | 接入目的 | 当前入口 | 迁移要求 |
14
+ | --- | --- | --- |
15
+ | 产品 UI / 共享 Session / 自动化应用 | `/client` 的 `ensureKodaXClient`、`connectKodaXClient` | 默认采用统一契约;执行、配置与存储归 Host |
16
+ | 浏览器侧类型、自己的 UI 适配器 | `@kodax-ai/coding/client-contract` 的 `import type`,或 `/client` 的类型导出 | 纯类型可用;Node 连接器不能直接在浏览器运行 |
17
+ | 受信任 Host 的启动、凭据桥、Host Tools、诊断或嵌入 | `/runtime` | 仍是独立的底层接缝;不属于产品 Client 的全部承诺 |
18
+ | 独立 Agent/LLM/coding 库 | `/agent`、`/llm`、`/coding` 等 | 保留独立使用;旧 `KodaXClient`/`Client` 是另一种执行对象,不等于 `KodaXProductClient` |
19
+
20
+ 根入口和上述底层导出尚未全部删除,也没有因为本次迁移就全部成为 TypeScript `@deprecated`。产品接入应迁走它们承担的业务职责;确需底层能力的受信任宿主仍可明确使用。客户端不能在连接失败时创建私有 Runtime,形成第二个 Session 写入者。
21
+
22
+ ## 2. 旧调用如何迁移
23
+
24
+ 下表按调用目的映射,参数和返回值不保证一对一兼容。
25
+
26
+ | 原有用法 | 统一契约用法 | 必须调整的行为 |
27
+ | --- | --- | --- |
28
+ | `createKodaXRuntime({mode:'daemon'})` 作为 UI 入口 | `ensureKodaXClient(options)` | 启动/升级交给统一启动器;返回产品 Client |
29
+ | `connectKodaXRuntime(...)` | `connectKodaXClient(...)` | 被动连接;`daemonToken` 对应产品选项 `token`,`endpoint` 只接受本地 pipe/socket |
30
+ | `runKodaX`、旧 `KodaXClient`、`runtime.runs.start` 提交用户请求 | `sessions.create/read` → `inputs.submit` → `runs.await` | 每个意图有 `inputId`;接收回执不是完成结果 |
31
+ | 调用时传 provider/model/effort 等执行选择 | `sessions.updateSettings` 或 versioned CAS | 设置是共享 Session 事实,影响下一次物理请求;不是任意 Run 私有 options |
32
+ | 客户端 pending 队列、`submitInput` 的旧 delivery | `inputs.submit/read/withdraw` | 使用 `immediate/after_turn/steer/redirect`;不要直接照搬旧 `interrupt` 字面量 |
33
+ | `onTextDelta/onTool*/onComplete`、`runtime.events.subscribe` 拼 UI 状态 | `sessions.observe` | 每次回调是完整当前 view 的替换;不用 delta 拼第二套运行权威 |
34
+ | `handle.result`、`onComplete` 或 spinner 停止判定结束 | `runs.await(runId)` / `runs.read(runId)` | 保留 `phase` 和 `error`;`unknown` 不是成功 |
35
+ | 仅调用 `runs.abort` 实现整个 Session 的 Stop | `sessions.cancel({sessionId, expectedRunId, requestId})` | 按 Host 的 Session 顺序边界停止;单 Run 停止用 `runs.stop` |
36
+ | permission/AskUser 回调或客户端创建权限请求 | `view.interactions` / `interactions.list` → `interactions.respond` | 只回答 Host 已创建的精确 requestId;授权 suggestionId 原样回传 |
37
+ | `SessionStorage`、`/session` 文件读写、`uiHistory` 拼接 | `sessions.*`、`readHistory/readHistoryEntry/searchHistory` | 客户端不直接访问活动 Host 的文件;历史与显示引用不混用 |
38
+ | 复制屏幕预览或对显示数组不断追加 | `readItem` 补读显示项;`readHistoryEntry` 补读历史/搜索项 | 正文分页校验 ID、偏移、长度与版本;显示窗口不是完整历史 |
39
+ | 本地追加 `/model` 等命令提示 | `sessions.appendNotice` | 通知由 Host 保存,属于 client-only 内容;失败要显示,不能重跑原命令 |
40
+ | 读写本地 config/MCP JSON;UI 创建 `McpManager` | `config.*`、`mcp.*`、`catalog.*` | Host 负责文件和连接;模型能力 probe 是显式、可能计费的动作 |
41
+ | 客户端展开 Skill、执行 command hooks、准备 review | `inputs.submit` 原始 Skill 输入;`commands.execute`、`review.start`、`agents.reviewLean` | 可信准备和执行归 Host;`commands.readPrompt` 仅返回可编辑文本 |
42
+ | UI 持有 workflow 模块或独立 memory/learning owner | `workflows.*`、`memory.forProject`、`learning.*` | 提交声明式意图;订阅故障和 Run 终态分开处理 |
43
+ | 客户端维护 Agent 注册或 mailbox 状态 | `registrations.*`、`agents.*` | 使用领域 ID、revision 和实际事件,不按 UI 缓存推断完成 |
44
+ | `runtime.close()` 或旧 Client dispose | `observation.close()`、`client.disconnect()` | 释放观察/连接;完整退出使用 lifecycle.requestExit,断连后 readKodaXClientExits 核验回执 |
45
+
46
+ 没有产品等价项的底层能力不能自动提升为产品承诺。例如凭据 lease、Host Tool bridge、原始 Runtime events 和特定诊断继续由受信任宿主明确接入 `/runtime`。产品 `mcp` 也不承诺旧 `McpManager` 的所有 start/stop/catalog 方法;先核对实际类型,不在 UI 中创建第二套执行连接来补齐。
47
+
48
+ ## 3. 输入、队列与结果恢复
49
+
50
+ 调用者保存 `sessionId`、`inputId`、原始正文和附件,再提交。输入 ID 应使用稳定生成的唯一值;一次响应丢失不能通过生成新 ID 自动重发。
51
+
52
+ - `submitted`:已进入会话上下文,不证明 Provider 已接收;用返回的 `runId` 跟随执行。
53
+ - `queued`:尚待交付。通过 `inputs.read(sessionId, inputId)` 逐项确认;多条输入可能合批为同一 Run。
54
+ - `withdrawn`:已撤回;只有 `withdraw` 的完整返回内容适合重新放回编辑器。
55
+ - `dropped`:目标 Run 已结束且未交付;明确再次提交时使用新 ID。
56
+
57
+ `after_turn` 可在当前 Run 的下一次模型请求前交付,并非必定等整个任务结束。`steer/redirect` 需要 `targetRunId`;steer 的等待不等于可撤回队列。Stop/失败也不表示 Host 自动清空所有待发送输入。
58
+
59
+ 同一个 Host 上丢失提交响应时查询原 `inputId`;已知 `runId` 时查询/等待原 Run。新 Host 不承诺继承旧 Host 的输入接收身份;查不到记录不能证明副作用未发生。命令、review、compact、memory 修改等丢失响应,也不能透明重放。
60
+
61
+ ## 4. 观察、历史与完整正文
62
+
63
+ `sessions.observe` 先给完整当前 view,后续仍是替换。`view.items` 有界,`view.runs` 也不是全量 Run 日志。显示层保持 Host 顺序,按项 ID 更新;不能用相同正文去重不同输入,不能把 `outputId` 当作唯一块 ID。
64
+
65
+ | 要读取的内容 | 入口与身份 |
66
+ | --- | --- |
67
+ | 当前屏幕 | `observe` 返回的 `ClientSessionView` |
68
+ | 显示项全文/工具参数 | `readItem(sessionId, viewItem.id, {part, offset})` |
69
+ | 较早的规范对话 | `readHistory(sessionId, {cursor})`,首次为最新页 |
70
+ | 历史页或搜索结果全文 | `readHistoryEntry(sessionId, historyItemId, {part, offset})` |
71
+ | 全 Session 搜索 | `searchHistory`,使用命中 itemId 读取正文 |
72
+
73
+ 页内从旧到新,页间 `nextCursor` 指向更旧页。一次组合读取必须保持同一 revision;修订失效就重新读取,不能拼接不同版本。正文偏移单位为 UTF-16 字符单元;沿 `nextOffset` 读取,`null`、无进展、版本变化和不连续都应报告失败。
74
+
75
+ 当前 view 最多 150 项且有正文预览预算。完整历史和离窗 canonical 项回源不裁剪单消息内部的内容块。冻结浏览应保存项身份、所见长度和版本;不能据此承诺任意并发替换时可恢复过去所有内容。
76
+
77
+ 普通 Ink 浏览的 15 秒等待上限是该 UI 的恢复策略,不是所有 SDK 请求的通用超时。其他消费者需要设计自己的等待/退出体验;不能误以为取消客户端等待就取消了已提交 Run 或 Host RPC。
78
+
79
+ ## 5. 交互与 Stop
80
+
81
+ 交互 UI 展示 Host 请求并提交匹配 kind 的回答。权限扩展只使用该请求给出的 `grantSuggestions`;Plan 审批显示完整 `options.plan`,不用参数预览冒充计划。人工取消问题使用 `{kind:'cancel'}`,不等同于停止 Run。重复、过期或已解决请求的 `accepted:false` 应按结果处理。
82
+
83
+ ```ts
84
+ import type { KodaXProductClient, ClientInteraction } from '@kodax-ai/kodax/client';
85
+
86
+ // Call only after the user chooses to reject this displayed permission request.
87
+ export async function rejectPermission(client: KodaXProductClient, request: ClientInteraction) {
88
+ if (request.kind !== 'permission') throw new Error('Expected a permission request');
89
+ return client.interactions.respond(request.requestId, {
90
+ kind: 'permission', decision: { type: 'reject', reason: 'Rejected by the user' },
91
+ });
92
+ }
93
+ ```
94
+
95
+ Session Stop 的 `expectedRunId` 来自用户点击时观察的 Run,`requestId` 在发出请求前生成并保留。过期 Run 冲突应刷新 UI,不把旧点击自动改投新 Run。Stop 回执的接收状态不代表已结束;继续观察并通过 `runs.await` 确认各 Run 的真实结果。
96
+
97
+ ## 6. 设置、能力与订阅
98
+
99
+ `getSettings` 是原始 Session 覆盖,`view.settings` 是 Host 解析的有效设置;`config.read` 是已保存默认值,`config.readEffective` 是有效执行配置。patch 的缺省字段保持不变,支持的 `null` 清除覆盖。并发编辑使用 `getSettingsVersioned/updateSettingsVersioned` 的 revision;临时覆盖结束后不能无条件恢复旧值覆盖其他客户端的新设置。
100
+
101
+ `ensureKodaXClient` 可启动/正常更新本地空闲 Host;`connectKodaXClient` 不启动或替换它。两者要求 `productClient` v1,具体新增领域能力仍可能要求额外握手支持(如 `subscriptionLifecycle`、`workflowSettingsDefaults`、`planModeEffort` 设置键)。缺失时明确报错,不能静默降级。
102
+
103
+ Session 观察通过 `onStatus` 区分 live/interrupted/closed;重连中的提示由应用自身管理,不存在公共 `reconnecting` 状态。Workflow/Learning 订阅的 `ready` 仅代表注册成功;重新订阅后等待 ready,再读取快照,读取期间通知作为再次刷新信号。断连恢复不重放业务 mutation,Run 的 `unknown` 结算也不等于网络断连。
104
+
105
+ ## 7. 已移除与仍保留的能力
106
+
107
+ 本分支移除了通用 operation envelope/receipt、持久事件 journal/replay、旧 exit-settlement/rollback 协议和 Worker-hosted embedded Runtime。它们的迁移明细见[移除表](../public_docs/sdk/embedder-guide.md#migrating-to-v0797)。不能继续依赖旧 event cursor 跨重启续传,或把断连自动重发解释成恰好一次。
108
+
109
+ 独立 coding/Agent/LLM 库、显式 inline embedded Runtime、daemon、构造工具 handler worker、语义分析 worker 等并未因此全部退役。历史 ADR/feature 文档描述的是当时决策;当前产品行为以本迁移指南、Client 契约和实现为准。版本号相同也可能加载了不同源码/构建,升级后需要重新加载 SDK 进程;启动器不会强停忙碌 Host。
110
+
111
+ ## 8. 接入验收
112
+
113
+ 迁移完成至少验证以下行为,而不只验证 TypeScript 能编译:
114
+
115
+ 1. 两个 Client 看到同一 Session 设置、交互与执行事实;断开一个 Client 不停止另一方的工作。
116
+ 2. 提交后保留输入身份;排队、撤回、steer/redirect、Stop 和迟到回答使用各自回执,不丢失或重复输入。
117
+ 3. 对 completed/failed/interrupted/unknown 和传输拒绝分别显示;重新连接不重复启动任务。
118
+ 4. 多轮、多工具、长正文和同文不同输入跨显示窗口后仍能准确读取;分页修订变化有可见恢复路径。
119
+ 5. 命令通知经 Host 后仍可见且不进入模型上下文;失败只报告,不重跑有副作用命令。
120
+ 6. Learning/Workflow 订阅注册失败、运行中故障、主动关闭和重连,均不会假报 Run 完成。
121
+ 7. 产品消费者不持有 SessionStorage、可执行 Runtime 对象或客户端 MCP owner;底层宿主代码单独标明职责。
122
+
123
+ 仓库现有验证入口:`src/sdk-client*.test.ts`、`src/session-view*.test.ts`、`tests/repl-pty-acceptance.mjs`、`tests/repl-history-browse-acceptance.mjs`。具体回归记录见[Issues 345–347 and 352 验证指南](test-guides/ISSUE_352_v0.7.96_REGRESSION_GUIDE.md)。这些测试不证明所有外部应用已经迁移。
@@ -0,0 +1,139 @@
1
+ # Space 的 Product Client / Host 接缝
2
+
3
+ 基线为 Space 已验证的 `0.7.97-alpha.1`;以下补齐属于当前工作树,需要重新构建 SDK 与 Host,不表示 npm 已发布。业务操作采用 `/client`;可信 Main 负责授权与宿主配置,Space 负责输入身份、队列展示、view、IPC 与 Renderer 状态迁移。
4
+
5
+ ## 可信执行授权
6
+
7
+ `connectKodaXClient` / `ensureKodaXClient` 的可选 `authorizeExecution(request, services)` 只在可信 Main 进程执行。回调使用同一连接的 `services.credentials` 与 `services.hostTools` 注册现有 lease,为本次操作返回非秘密 `credential` / `hostTools` binding。回调与凭据值不会作为产品输入发送到 Host。配置回调的连接要求 `productExecutionAuthorization:1`;旧 Host 明确拒绝,不能忽略 binding 继续执行。
8
+
9
+ `kind` 为 `input`、`command`、`review`、`agents_lean`、`tool`、`workflow`、`agent_spawn`、`agent_followup` 或 `compaction`,`input` 是对应业务意图的独立快照。Main 根据自己的 Session 授权、Provider allowlist 和操作用途作决策。SDK 丢弃产品 payload 中的授权字段,再附加 Main 返回的 binding。拒绝应抛出错误;返回 `undefined` 明确选择原有无 binding 路径,不代表拒绝。
10
+
11
+ ```ts
12
+ import { connectKodaXClient } from '@kodax-ai/kodax/client';
13
+ import type { RuntimeScopedCredentialRequest } from '@kodax-ai/kodax/runtime';
14
+
15
+ // Main owns these values/functions; Renderer cannot supply them.
16
+ declare const approvedSessions: ReadonlySet<string>;
17
+ declare const readAuthorizedKeychainSecret:
18
+ (request: RuntimeScopedCredentialRequest) => Promise<string | undefined>;
19
+ let lease: Promise<{ readonly id: string }> | undefined;
20
+ const client = await connectKodaXClient({
21
+ async authorizeExecution(request, services) {
22
+ const sessionId = request.input.sessionId;
23
+ if (!sessionId || !approvedSessions.has(sessionId)) throw new Error('Session is not authorized.');
24
+ lease ??= services.credentials.registerScoped({ providers: ['anthropic'] }, readAuthorizedKeychainSecret);
25
+ return { credential: { leaseId: (await lease).id, mode: 'scoped', providers: ['anthropic'] } };
26
+ },
27
+ });
28
+ ```
29
+
30
+ 同一回调可用 `services.hostTools.register(descriptors, handlers)` 注册 Artifact/Office/Space Control 的不可变描述符,再返回 `hostTools: {leaseId}`。注册不构成 ambient 授权。broker 仍需核验 Host 提供的 Session、目标身份、Provider 与 purpose;工具 handler 使用 Host 提供的 sessionId/runId/invocationId。秘密只经既有专用反向桥供给单次 Provider 请求,不进入输入、历史、配置或事件。
31
+
32
+ | 入口 | 授权归属 |
33
+ | --- | --- |
34
+ | 普通输入、Skill、command、review、显式工具 | 实际创建的 Run;可信准备、hooks、模型与工具执行共享该 Run 的授权,保留该 Session 的 MCP/extension 配置 |
35
+ | 排队消费 | 接收时保存非秘密授权上下文,实际消费时绑定 Run;不同授权不合批,也不注入另一授权的活动 Run |
36
+ | steer | 目标 Run 原有授权;不同授权返回 conflict,不替换或扩大它 |
37
+ | redirect | 旧 Run 保持原授权,新排队意图带自身授权 |
38
+ | Workflow | binding 要求明确 sessionId;实际 Run 与既有派生 Actor/Workflow scope,子任务按现有规则收窄 Provider 权限 |
39
+ | manual compaction | 仅使用 scoped credential;Host 创建 `session.compact` operation 身份,工具 lease 不参与 |
40
+ | automatic compaction、fallback、classifier、sidecar | 使用现有 Run resolver,每次实际请求重新检查 Provider 与 purpose |
41
+
42
+ 实际 Provider 请求的 purpose 表示请求用途;Workflow 子 Agent 的普通模型请求仍可为 primary,目标为带 parentRunId 的 actor_turn。不能仅从 purpose 推断它不属于 Workflow。撤销、到期、断连和 Host 替换遵循现有 lease 生命周期。授权失效后的排队消费不会借用别的 Run 的授权;Host 诊断报告消费失败,尚未创建 Run 的输入仍可保持 queued,Space 可明确撤回/重新提交,不能无限等待一个不存在的 Run。未知 Host Tool 副作用不自动重放。
43
+
44
+ 独立 `agents.spawn/followup` 使用同一 Main 回调,连接要求 `productActorAuthorization:1`。新 native turn 必须使用 scoped credential;Host 为实际 Actor/turn 创建独立执行上下文及 Run,不借用父 Run 的授权。broker 的 target 为 `actor_turn`,Provider allowlist 与 purpose 逐请求检查。Main 可返回 `tools: ['read', 'space_read']` 作为额外工具上限:模型 schema、实际调用、Host Tool runtime 和后代均收窄,仍执行 Session 的权限、Shell 与管理员策略。其他入口不接受该 `tools` 字段。
45
+
46
+ 新 turn 的 followup 重新授权;正在执行的 turn 保留原授权,不能用 followup 替换其 credential。独立子树有自己的客户端归属,其他客户端停止根 Run 不取消该子树。External Actor 使用原有 executor/credentialRef,不能绑定 native Provider credential、Host Tool runtime 或 native tools ceiling。授权和 handler 闭包不持久化;Host 重启恢复既有中断/未知事实,新执行须重新授权,旧工具副作用不重放。
47
+
48
+ ## 客户端退出与恢复
49
+
50
+ Product 连接要求 `productExitControl:1`。`disconnect()` 释放连接;`host.shutdown()` 仍是空闲 Host 的普通退出请求。完整客户端退出使用以下公开接口:
51
+
52
+ ```ts
53
+ const receipt = await client.lifecycle.requestExit({ requestId: 'space-exit-123', shutdownHost: true });
54
+ const current = await client.lifecycle.readExit(receipt.requestId);
55
+ const unfinished = await client.lifecycle.listPendingExits();
56
+ // Main 保存原 clientInfo.instanceId / instanceSecret;断连、原 Host 已退出时也可查询。
57
+ const recovered = await readKodaXClientExits({ homeDir, profile, clientInfo });
58
+ ```
59
+
60
+ `readKodaXClientExits` 从 `/client` 导出,只读退出回执,不连接或启动 Host,不重放工作,也不清理 Space 资源。稳定 instanceId 和至少 32 字符的 instanceSecret 由 Main 持有;退出回执按该客户端身份隔离。断连后用同一身份重连可查询并重试清理。新的客户端实例使用新身份,保存旧身份供旧退出查询;已接受退出的身份不能在同一 Host 再接收新工作。
61
+
62
+ | 事实 | 含义 |
63
+ | --- | --- |
64
+ | `accepted: true` | 退出意图已持久化;不证明清理或进程退出 |
65
+ | `cleanup.state: pending` | 本客户端工作正在结算 |
66
+ | `cleanup.state: succeeded` | 本客户端队列撤回、Run/Actor/compaction 取消与受管 Shell 清理已确认 |
67
+ | `cleanup.state: unknown/failed` | executor 或清理证据未确认,或明确失败;保留 issues 与目标身份,不推断成功 |
68
+ | `host.state: protected` | 其他客户端或受管工作仍占用 Host,退出请求被保护策略拒绝 |
69
+ | `host.state: accepted` | Host 接受退出控制;实际进程退出仍未证明 |
70
+ | `host.state: succeeded` | 原 owner 的持久化清理成功记录、PID generation 和 Windows Job/supervisor 退出已核验 |
71
+ | `host.state: unknown/failed` | 缺少证据或实际清理失败;连接 EOF 不作为成功证据 |
72
+
73
+ 取消只作用于本客户端的排队输入、Run、独立 Actor 子树、显式 compaction 与 SDK 托管的 Memory 后台工作;其他客户端的 Run、Actor 和队列继续运行。Actor 持久化 interrupted 与 executor 已结束分别判断;受管 Shell identity 保留至精确清理验证成功。回执返回 runIds、actorTurns、operationIds、withdrawnInputs 及 issues。
74
+
75
+ 同一 requestId 与同一退出意图幂等;Host 存活时可再次提交以重试未确认清理或先前 protected 的退出。回执持久化在 Host profile,断连后清理继续;Host 重启时旧请求只查询旧 owner,不作用于替代 Host。旧 pending 在 owner 丢失后返回 unknown,不能永久显示仍在处理。`replacementRunning` 表示原 Host 已核验退出且替代 Host 运行。inline Host 或缺少平台精确进程/containment 证据时不承诺实际进程退出。关闭自身窗口、IPC、Office/Artifact 与其他 Space 资源由 Space 完成。
76
+
77
+ 退出保护在 Host 的 draining 边界内按 principal 判断,只豁免退出方自己的连接;A 断连后仍在线的空闲 B 也会阻止 Host 退出。退出 fence 同时覆盖 `/runtime` 的 `runs.submitInput`:after_turn 的新 Run 登记和 interrupt 的实际入队都需再次校验。取消并行触发,不等待不合作 compaction 才取消其他工作;有限结算等待后保留 operationIds 和 unknown,之后可重查、重试。未证明 executor 结束时不填成功,也不强迫任意进程内 custom adapter 退出。
78
+
79
+ ## 统计与执行事实
80
+
81
+ Product 连接要求 `productExecutionFacts:1`。权威统计来自 `statistics.read(sessionId)`、`statistics.readRequests(sessionId, {cursor, limit})` 和 `statistics.readTools(sessionId, {cursor, limit})`。事实在执行边界持久化,断连后继续采集;Host 重启保留累计值和稳定身份。旧 Session 采集前的用量不能补算,返回 `coverage: partial` 与 issues。coverage 表示采集边界是否完整;执行完成与用量完整性仍需查看逐请求 state/usage 和 requestsWithoutUsage。
82
+
83
+ | 接口内容 | 公开语义 |
84
+ | --- | --- |
85
+ | 累计 `usage` | 全部已观察请求的归一化 input/output/cache/thought 用量;按稳定 requestId 更新去重。total 是 input+output,thought/cache 是相关分量,不再次叠加。Rewind/compaction 不清零已消耗用量;Fork 的新 Session 记录自己的新请求。缺失 usage 不猜算,查看 requestsWithoutUsage |
86
+ | `physicalRequestCount` / `operationCount` | 实际可观察的 wire 请求与只能观察到的 adapter operation 分开计数;requestCount 是两者总数 |
87
+ | `contexts[]` | 各根/子 context 最近一次请求准备时的 pressure、tokenBreakdown、窗口/保留量、target、runtimeId、contextRevision(如有)及 revision。属于带时间的估算快照,空闲或重启后不代表新请求已重新计算 |
88
+ | 请求事实 | requestId、logicalRequestId、provider/model、attempt、purpose、Run/Actor turn/compaction target、state/usage。原生 HTTP adapter 的 fetch 边界包括 SDK 内部 retry;首个 wire 请求细化已记录的 pending operation,保持 ID |
89
+ | fallback | 非 streaming fallback 保留 purpose=fallback;跨 Provider 子任务 fallback 另带 route.chainId/attempt/fromProvider,credential purpose 保持实际用途。previousRequestId 与 fallback 标志用于归属,不能仅凭 Provider 名称推断 |
90
+ | 工具事实 | Host 为每次实际调用生成 id;toolId 是 Provider 来源身份,重复 toolId 不合并调用。prepared/executing/completed/not_executed/unknown、结构化结果及实际 sandbox observation 序列分别保留 |
91
+ | Sandbox | applied 含实际 backend;fallback 含实际 reason/执行策略;not_selected 表示未选。空序列表示 adapter 未报告,不从 permissionMode 推断 backend |
92
+
93
+ 分页 cursor 绑定 Session 与记录种类,限定开始分页时的条目数量;记录可以继续更新,消费方按 ID/revision upsert,完成分页后重新读取获得新条目。Host 崩溃后未完成请求/工具在原 owner 被确认失效时转 unknown,不自动重试,不填造 usage 或成功结果。custom/CLI adapter 未暴露内部 wire 时明确使用 `boundary: provider_operation, dispatch: unknown`,并报告 partial;不会把一次调用冒充其内部物理请求。统计不提供货币价格账本,也不要求解析 costReport。
94
+
95
+ Actor 观测身份独立于 credential lease:普通 ambient 子 Actor 也带实际 actorPath/turnId,工具与预算保留子 turn。Sandbox observation 按原顺序转发。SDK invocation 的 executionId 贯穿 prepared、执行、结果、观察和 bridge target;并发重复 Provider toolId 不合并,结果与恢复附件各自关联。`contextRevision` 是进程内 context/compaction 快照版本,不是跨重启的 CAS token;持久化读取使用事实 revision。
96
+
97
+ 执行中的 operation-only adapter 返回 partial。原生 HTTP adapter 的暂态带 `wireObservation: pending`,首个 fetch 同 ID 细化为 `observed`;它不会因为暂态永久污染 coverage。无物理观察能力的 operation 带 `unavailable`。异常或取消后的 usage 仅保存 adapter 实际返回且已归一化的值,缺失用量不推测。
98
+
99
+ ## canonical 操作边界
100
+
101
+ `readHistory` 返回分页/正文读取身份 `revision`、canonical 存储身份 `sourceRevision`、`status: resolved|partial|ambiguous` 和原有有界 `issues`。可证明 canonical 位置的条目带 `historyBoundary: {entryId, sourceRevision}`;同一消息的显示块共享该边界。记录原样回传,不能从显示 item ID、search entryIndex 或正文推导。
102
+
103
+ 当前 Product 连接要求 `productHistoryBoundaries:1`,使旧 Host 缺失质量字段或 Retry 边界支持时在连接阶段明确失败。
104
+
105
+ | 动作 | 公共输入 |
106
+ | --- | --- |
107
+ | Fork | `forkSession(sessionId, {historyBoundary: item.historyBoundary})`,包含边界消息 |
108
+ | Retry | `forkSession(sessionId, {historyBoundary: userItem.historyBoundary, before: true})`,在查询前派生,再用新 inputId 提交原查询 |
109
+ | Rewind | `rewindSession(sessionId, {historyBoundary: item.historyBoundary, expectedHead})`,expectedHead 来自所见 lineage |
110
+
111
+ Retry 包括第一条查询之前的空历史;`before` 需要 canonical boundary。长查询须通过 `readHistoryEntry` 补读正文。Fork/Retry 不改变源 Session;这些动作都不回滚文件副作用。sourceRevision 失效返回 `resync_required`,head 变化返回 conflict;刷新后重新选择,不自动扩大选择范围。partial/ambiguous 不表示已浏览完整历史,也不保证每条记录都有可操作边界。
112
+
113
+ ## 宿主配置与支持范围
114
+
115
+ | Space 能力 | 当前公开接入与限制 |
116
+ | --- | --- |
117
+ | 手册/可信系统指令 | Host 安装的 extension `provider:before` hook 用 `replaceSystemPrompt` 合并可信手册,随 Host integrations 生命周期加载。低层显式 Run 保留 `context.systemPromptOverride`(SA)/`agentProfile.instructions`(AMA);产品输入不开放任意 prompt/context。共享 Host hook 的适用范围由可信宿主策略选择。 |
118
+ | Shell | 可信 `/runtime` 的 Session `shellExecution` 设置,采用现有规范化 Shell contract 与 revision CAS;Product settings 只暴露已列出的业务选择。 |
119
+ | 工具/执行策略 | permissionMode、Plan 与审批经 `/client`;Host `execPolicy.adminRules/trustedProjectRoots`、`autoReview` 在 owner 启动时注入,附着已有 Host不覆盖它。Skill/command 的 allowedTools、hooks 来自可信注册来源;Host Tool 描述符仅在绑定 Run 中提供。 |
120
+ | 结构化历史附件 | `readHistory().items[].attachments` 暴露 canonical 用户图片块/工具结果图片的 path、mediaType。原始 picker source/name、附件字节、任意 Office/Artifact 对象不在该接口中。file/video 尚不能作为 Provider prompt 附件;Space 可通过 Host Tools 提供业务读取结果。 |
121
+ | 详细统计 | 使用上述 statistics 结构化事实。view.activity.usage 保留最新活动展示语义;SDK 不提供货币价格账本。 |
122
+ | 退出/崩溃恢复 | 使用上述 lifecycle 与离线回执查询;SDK 结算自身受管工作,Space 管理自身资源。Host 重启不自动续跑队列、Provider 或未知工具调用。 |
123
+
124
+ 回归入口:
125
+
126
+ ```text
127
+ npx vitest run src/sdk-client.host-authorization.test.ts src/sdk-client.exit.test.ts src/sdk-client.statistics.test.ts src/sdk-client.derive.test.ts src/execution-facts.test.ts src/runtime-daemon/client-lifecycle.test.ts packages/coding/src/agent-runtime/__contract-tests__/cap-024-tool-dispatch.contract.test.ts
128
+ node --test tests/bundled-product-exit.test.mjs
129
+ ```
130
+
131
+ 这些测试覆盖真实 Host 上的 credential/tool bridge、排队授权隔离、steer 拒绝授权替换、Skill/command/review/Workflow/compaction、伪造 payload、撤销、canonical Fork/Retry/Rewind 与历史图片引用。退出专项覆盖已退出身份的 after_turn/interrupt 拒绝、异步准入竞态、不响应 abort 的 compaction 与其他任务并行取消;统计专项覆盖普通 ambient 子 Actor 归属、子工具 Sandbox 转发、重复 toolId 的执行/结果/附件隔离、bridge 目标身份,以及运行中的 operation-only adapter 质量。bundle 退出专项已纳入 `test:bundle`。其他现有 Provider/用途/生命周期边界仍由既有 Runtime 和反向桥回归验证。
132
+
133
+ `packages/coding/src/child-executor.test.ts` 另行验证 Actor/specialist 工具上限、只读子任务,以及 digest/structured-output repair 的无工具边界;Host Tool lease 不绕过这些限制。
134
+
135
+ 本轮验收需同时包含独立 Actor 工具上限/客户端归属、显式 compaction 取消、累计用量、物理 retry、重复工具来源 ID、事实恢复,以及 bundle 的真实 daemon 退出与替代 Host 保护。构建和类型消费者检查不能由仅运行源码测试替代。尚未发布 npm 包。
136
+
137
+ 事实存储、退出控制、客户端工作归属和 Provider observation 模块的 scoped coverage:语句 92.3%、分支 85.43%、函数 94.8%、行 95.93%;不是全仓覆盖率声明。
138
+
139
+ 2026-10-09 本轮本地验收:关联回归 97 文件、977 测试通过;最终增量专项 7 文件、31 测试,以及工具分发合同 12 测试通过。bundle 的 2 项真实 daemon 测试验证立即断连后的空闲 peer 保护、精确进程退出及替代 Host 保护。packages、SDK bundle、声明构建、源码/测试类型检查,以及不加载 Node ambient types 的 Product Client 类型消费者均通过。Standards / Spec 最终复核无明确残余。未全量复跑仓库全部测试,未发布 npm,Space 安装包尚未更新。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodax-ai/kodax",
3
- "version": "0.7.96",
3
+ "version": "0.7.97-alpha.2",
4
4
  "description": "KodaX lightweight coding agent - TypeScript implementation with 16 built-in LLM provider aliases, published as a Node-free single-file CLI and SDK",
5
5
  "type": "module",
6
6
  "private": false,
@@ -15,8 +15,6 @@
15
15
  "integrationConfigResilience": 1,
16
16
  "managedRunDurability": 1,
17
17
  "runtimeAutoModeGuardrail": 6,
18
- "runtimeExitSettlement": 2,
19
- "sessionEventJournal": 1,
20
18
  "sharedSessionSettings": 2,
21
19
  "liveOutputSegments": 1
22
20
  },
@@ -65,6 +63,10 @@
65
63
  "types": "./dist/sdk-session.d.ts",
66
64
  "import": "./dist/sdk-session.js"
67
65
  },
66
+ "./client": {
67
+ "types": "./dist/sdk-client.d.ts",
68
+ "import": "./dist/sdk-client.js"
69
+ },
68
70
  "./runtime": {
69
71
  "types": "./dist/sdk-runtime.d.ts",
70
72
  "import": "./dist/sdk-runtime.js"
@@ -103,7 +105,7 @@
103
105
  "build:binary": "node scripts/build-binary.mjs",
104
106
  "build:binary:all": "node scripts/build-binary.mjs --all",
105
107
  "test": "vitest run",
106
- "test:bundle": "node --test tests/bundled-provider-credentials.test.mjs tests/bundled-daemon-compaction.test.mjs tests/bundled-memory-review-shutdown.test.mjs tests/bundled-text-permissions.test.mjs tests/bundled-image-validation.test.mjs tests/bundled-text-recovery.test.mjs tests/image-codec-release.test.mjs tests/asrt-wfp-probe.test.mjs tests/asrt-wfp-build.test.mjs",
108
+ "test:bundle": "node --test tests/bundled-provider-credentials.test.mjs tests/bundled-daemon-compaction.test.mjs tests/bundled-memory-review-shutdown.test.mjs tests/bundled-product-exit.test.mjs tests/bundled-text-permissions.test.mjs tests/bundled-image-validation.test.mjs tests/bundled-text-recovery.test.mjs tests/image-codec-release.test.mjs tests/asrt-wfp-probe.test.mjs tests/asrt-wfp-build.test.mjs",
107
109
  "test:native": "node scripts/test-native.mjs",
108
110
  "test:packed-native": "node scripts/test-packed-native.mjs",
109
111
  "test:fast": "vitest run -c vitest.fast.config.ts",
@@ -117,6 +119,7 @@
117
119
  "test:eval": "vitest run -c vitest.eval.config.ts",
118
120
  "test:electron-daemon": "npm run build && node scripts/test-electron-daemon-smoke.mjs",
119
121
  "test:electron-daemon:built": "node scripts/test-electron-daemon-smoke.mjs",
122
+ "test:repl-pty:built": "node tests/repl-pty-acceptance.mjs",
120
123
  "bench:perf": "tsx benchmark/perf/repl-render-perf.bench.ts",
121
124
  "bench:perf:e2e": "tsx benchmark/perf/repl-render-engine-e2e.bench.ts",
122
125
  "bench:repo-intel": "tsx benchmark/perf/repo-intelligence-index.bench.ts",
@@ -218,7 +221,6 @@
218
221
  "dist/chunks",
219
222
  "dist/provider-capabilities.json",
220
223
  "dist/semantic-worker.js",
221
- "dist/runtime-worker.js",
222
224
  "dist/constructed-handler-worker.js",
223
225
  "dist/types-chunks",
224
226
  "dist/native",
@@ -231,6 +233,9 @@
231
233
  "README_CN.md",
232
234
  "public_docs/README.md",
233
235
  "public_docs/sdk/embedder-guide.md",
236
+ "docs/CLIENT_CONTRACT.md",
237
+ "docs/SDK_MIGRATION.md",
238
+ "docs/SPACE_SDK_SEAMS.md",
234
239
  "public_docs/configuration",
235
240
  "public_docs/getting-started",
236
241
  "LICENSE",
@@ -1,136 +1,16 @@
1
1
  # KodaX Documentation
2
2
 
3
- Public documentation for KodaX users and SDK integrators.
3
+ Documentation for KodaX users, product-client integrators and trusted Host developers.
4
4
 
5
- The current release is `v0.7.96`; npm publication remains a separate
6
- manual maintainer action. The seventh beta adds multimodal result
7
- fidelity (text/image tool results survive dispatch, Workers, MCP adapters;
8
- MCP images persist as attachments), typed local failure propagation through
9
- Actor metadata and Runtime/daemon status, and stable interrupt entry
10
- references across context rewrites and conversation pagination. Beta.6
11
- makes prompt-cache diagnostics mirror the
12
- provider wire (retained orphan calls are answered with the interrupted-tool
13
- marker; a 224-case wire contract suite covers every provider). Beta.5 moves the built-in `deepseek` provider to
14
- DeepSeek's official Anthropic-compatible endpoint with new default model
15
- `deepseek-flash` (native image input), repairs replayed restored-session
16
- histories with an explicit interrupted-tool marker for orphaned `tool_use`
17
- calls, and advances Windows sandbox setup to generation 11 (Issue 333) with
18
- Codex-compatible profile/SSH ACL exclusions. The beta.4 compaction summary
19
- policy, the beta.3 Windows WFP probe repair, credential-bridge retirement,
20
- and strict production/source-test checks are retained.
21
-
22
- Beta.2 adds long-session context-boundary recovery,
23
- keeps bundled Provider credential scopes shared across SDK/CLI/Worker
24
- requests, and closes Issues 329-332 (structured Child Agent Provider failures,
25
- exact run-scoped credential verification, and strict-vLLM empty-tools
26
- compatibility). Beta.1 carries
27
- the alpha.4 permission profiles, sandbox-first routing, JSONC Exec Policy,
28
- Auto[LLM] host-boundary review, and Full Access, and completes Windows sandbox
29
- concurrency/self-healing without adding a command lock, queue, or permission restriction.
30
- The alpha.3 line adds the v2 scoped Provider credential
31
- broker (ADR-068): Provider secrets stay in the OS keychain and resolve per
32
- wire call for one closed purpose inside revocable leases, shared-daemon
33
- internal Agent turns require explicit scoped bindings and fail closed
34
- without one, and daemons may expose bounded, display-only client inventory
35
- (`daemonClientInventory:1`). It separates trusted text transactions from platform shell
36
- containment on Windows, Linux, and macOS: controlled text tools commit in the
37
- trusted KodaX Runtime with per-file kernel locking, revision CAS, and flushed
38
- atomic replacement, while Windows shell commands run through the native
39
- restricted-token runner (0.7.96 native shell protocol version 10/setup
40
- generation 10, Windows `sandboxRuntime:11`, interactive startup recovery
41
- through the setup-only boundary, and no command-lifetime global admission
42
- lock). It replaces the
43
- local tool-result capacity hard gate with capacity-debt admission and a
44
- bounded recovery ladder (`capacityDebt` metadata, floor-bounded output
45
- reserve, `failureKind: "context_capacity"` with structured `contextTokens`),
46
- exposes one credential-safe `failureDetail` across failure events, Run
47
- result/status, and Session diagnostics, and registers the
48
- `deepseek-v4-flash-vision-exp` and `glm-5.3-flash` models plus the custom
49
- provider `imageInput` flag. On top of v0.7.95: self-healing
50
- Windows sandbox cleanup (Windows `sandboxRuntime:5`,
51
- `runtimeExitSettlement:2`),
52
- Issue 301 learning-lock / fullscreen-terminal / Explicit-Skill recovery, and
53
- Issue 302 coding-result finalization before the public completion signal, on
54
- top of the v0.7.94 concurrent
55
- sandboxed text mutations, Issue 300 authorized-root git trust, scheduled
56
- shutdown failure reporting, missing-workspace Run start, and
57
- `conversationHistory:2`, the
58
- v0.7.93 failed-exit fast settlement, previous-boot ACL recovery, and isolated
59
- provider abort classification, plus the v0.7.92 filesystem-effect
60
- operation-token coordinator, recorded-release owners, managed Session-before-
61
- completion ordering, canonical-first resume reconstruction, `sandboxRuntime:4`,
62
- and `crashOutcomeModel:2`. Issue 256's
63
- lost-ancestor descendant-closure boundary remains open. The same guidance still
64
- covers the v0.7.89 Issue 293
65
- topology-transparent conversation projection, FEATURE_293 zero-service web
66
- search fallback, and FEATURE_294 run-scoped Host Tools. The host-tool surface is
67
- leased to one Run, registry-first, revocation-safe, and absent from unrelated
68
- CLI runs. Its custom web-search endpoint remains isolated. The v0.7.88 SDK
69
- guidance adds the GLM-5.3 Coding Plan
70
- routes with verbatim model IDs, keeps GLM-5.2 selectable, defaults
71
- `zhipu-coding`, `zai-coding`, and `ark-coding` to 5.3, and documents the GLM-5.3
72
- always-thinking effort mapping. It also covers atomic Runtime owner
73
- recovery, process-start identity locks, Windows sandbox termination attestation,
74
- durable ACL owner markers, and Windows workspace Shell PATH/executable scoping
75
- with quoted `cmd.exe` argument preservation. POSIX workspace sessions initialize
76
- fresh-home policy roots, settle workspace-local warm-up within the Shell
77
- abort/deadline, retire invalid sessions after lease-cleanup failure, and fail closed when process-tree cleanup is unconfirmed,
78
- in addition to the v0.7.85 Session-scoped
79
- Runtime Event Journals, the `sessionEventJournal:1` daemon contract,
80
- conversation-first Memory management, the additive experimental Memory
81
- management facade, and the startup/Worker lifecycle boundaries. Issue 256's
82
- remaining Worker owner-lease boundary remains open after v0.7.89; this release
83
- assigns no replacement target.
84
-
85
- The current source additionally documents structured, credential-safe Runtime
86
- `failureDetail`. Stable KodaX classification stays separate from optional
87
- bounded upstream identifiers, and failure/settlement events, Run result/status,
88
- and Session diagnostics project the same fact when it exists. This additive
89
- contract ships in `v0.7.96-alpha.3`; consumers of older published packages must
90
- tolerate an absent field.
91
-
92
- The v0.7.90 SDK guidance also documents orderly retirement for timed-out
93
- workspace sessions, actionable daemon Error/aggregate/cause diagnostics, direct
94
- clone-predecessor lineage and topology-correct archive markers, and provider-
95
- valid object schemas for run-scoped tools. npm publication remains a manual
96
- operator step.
97
-
98
- The v0.7.91 SDK guidance adds the crash-resumable
99
- `settleKodaXRuntimeExit()` transaction and `runtimeExitSettlement:1` capability,
100
- effective live output segments (`responseId` + `providerRequestId`), and
101
- standalone lazy provider dependency bundling. It also documents bounded
102
- AskUser/permission deadlines, owner AbortSignal propagation,
103
- `handleRuntimePermissionRequest()`, validated default answers, and stale
104
- prepared-Session-tail recovery after a `data_changed` race.
105
-
106
- The v0.7.94 SDK guidance documents concurrent sandboxed text mutations,
107
- authorized-root git trust (`gitSafeDirectory: authorized-repo-roots`),
108
- byte-bounded linked-worktree and submodule relationship reads, observed
109
- text-helper stdin failures, scheduled shutdown failure reporting, omitting
110
- the text sandbox when the workspace directory does not exist,
111
- `conversationHistory:2`, independent explicit Skill invocation, diagnosed
112
- invalid `allowed-tools` / malformed hook JSON, `PostToolUse` after an
113
- embedder observer throw, fail-closed Run terminal settlement, observed
114
- sandbox/managed-child cleanup rejection, typed daemon disconnect facts,
115
- bounded credential-safe `failureKind`, and exact-`runId` result recovery. An
116
- admitted Run is queried and awaited after reconnect; it is never started
117
- again. `sandboxRuntime:4` and `crashOutcomeModel:2` are unchanged.
118
-
119
- The v0.7.93 SDK guidance documents that a durable Windows `failed` shutdown
120
- outcome ends the orderly exit wait, previous-boot shared ACL markers may be
121
- recovered after a verified boot change, and Anthropic/OpenAI abort wrappers
122
- are classified by isolated SDK class identity. Capability versions are
123
- unchanged.
124
-
125
- The v0.7.92 SDK guidance adds `sandboxRuntime:4` and `crashOutcomeModel:2` as
126
- pre-start facts. Auto-start replaces an idle older daemon and fails closed
127
- while it is busy. Managed `onComplete` is not terminal authority. Hosts must
128
- not delete ProgramData lock files to recover a stuck coordinator. Resume
129
- reconstruction uses canonical Session `messages` as the transcript; `uiHistory`
130
- may overlay tool cards and display-only entries but cannot hide ordinary
131
- conversation. Presentation-only `agent-completed` / `task-completed` events
132
- stay host-owned when a non-empty CLI `uiHistory` exists.
5
+ This development tree implements the unified Product Client contract under
6
+ FEATURE_298/299. The package baseline is the stable `0.7.96`; the design target is
7
+ `v0.7.97`, and npm publication is a separate maintainer action. Historical release
8
+ notes do not override the current Client contract or establish that a package
9
+ has been published.
133
10
 
11
+ For TUI, desktop/IDE clients and shared-Session automation, start with
12
+ `@kodax-ai/kodax/client`. The Host owns execution, settings and persistence.
13
+ Independent library and trusted Host APIs remain separate integration layers.
134
14
  ## Getting Started
135
15
 
136
16
  - [Overview](./getting-started/overview.md) — What KodaX is and how it compares
@@ -147,10 +27,9 @@ stay host-owned when a non-empty CLI `uiHistory` exists.
147
27
 
148
28
  ## SDK
149
29
 
150
- - [Embedder Guide](./sdk/embedder-guide.md) — Full SDK integration guide for
151
- host applications, including
152
- [structured credential-safe Runtime failures](./sdk/embedder-guide.md#structured-credential-safe-runtime-failures),
153
- explicit-vs-model Skill invocation, and dynamic-context policy
30
+ - [Product Client integration](./sdk/embedder-guide.md#product-client-integration) — default entry for shared-Session applications; also links to scoped low-level Host/library reference.
31
+ - [SDK migration](../docs/SDK_MIGRATION.md) — old-to-new calls, lifecycle and migration acceptance (Chinese).
32
+ - [Client contract](../docs/CLIENT_CONTRACT.md) — complete Product method inventory, observation, history and error semantics.
154
33
 
155
34
  ## Guides
156
35
 
@@ -21,8 +21,7 @@ every supported core setting.
21
21
  ```json
22
22
  {
23
23
  "provider": "zhipu-coding",
24
- "effort": "auto",
25
- "runtimeMode": "daemon"
24
+ "effort": "auto"
26
25
  }
27
26
  ```
28
27
 
@@ -44,27 +43,22 @@ overrides:
44
43
  |---|---|---|
45
44
  | `provider` | `KODAX_PROVIDER` | — (prompted on first run) |
46
45
  | `effort` | `KODAX_EFFORT` | `auto` |
47
- | `runtimeMode` | `KODAX_RUNTIME_MODE` | `embedded` |
48
46
  | (home dir) | `KODAX_HOME` | `<OS user home>/.kodax` |
49
47
 
50
48
  JSON names stay camelCase while environment names use `KODAX_UPPER_SNAKE_CASE`.
51
49
 
52
- ## Runtime mode
50
+ ## Shared Host ownership
53
51
 
54
- Two Runtime hosting modes are available:
55
-
56
- - **`embedded`** (default) — inline, lowest latency, private
57
- - **`daemon`** — process-isolated, shared across multiple clients
58
-
59
- Worker isolation is an SDK/host option inside embedded mode, expressed as
60
- `{ mode: 'embedded', isolation: 'worker' }`; `worker` is not a valid
61
- `runtimeMode` configuration value.
52
+ The product CLI uses a shared daemon Host. `runtimeMode`, `KODAX_RUNTIME_MODE`
53
+ and `--runtime-mode` are removed; do not use them to select an execution owner.
54
+ Product SDK applications use `ensureKodaXClient` or passive `connectKodaXClient`.
55
+ Explicit low-level `/runtime` embedding remains separate, and Worker-hosted
56
+ embedded Runtime is removed. See the [SDK migration guide](../../docs/SDK_MIGRATION.md).
62
57
 
63
58
  ```bash
64
59
  kodax daemon start
60
+ kodax -p "Review this repository"
65
61
  kodax daemon stop --profile default
66
- kodax --runtime-mode daemon
67
- kodax -p "Review this repository" --runtime-mode daemon
68
62
  ```
69
63
 
70
64
  By default, daemon state, config, and runtime session storage use the exact