@co0ontty/wand 4.106.0 → 4.106.1

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 (279) hide show
  1. package/README.md +2 -2
  2. package/dist/ai-text-runner.js +24 -14
  3. package/dist/build-info.d.ts +2 -0
  4. package/dist/build-info.js +18 -0
  5. package/dist/build-info.json +3 -3
  6. package/dist/cli.js +8 -2
  7. package/dist/daemon-maintenance-state.js +1 -1
  8. package/dist/daemon-maintenance-targets.d.ts +1 -0
  9. package/dist/daemon-maintenance-targets.js +25 -9
  10. package/dist/daemon-maintenance.d.ts +3 -0
  11. package/dist/daemon-maintenance.js +60 -13
  12. package/dist/employee-im-types.d.ts +1 -1
  13. package/dist/employee-input-scheduling.d.ts +4 -0
  14. package/dist/employee-knowledge-cli.js +5 -5
  15. package/dist/employee-knowledge.d.ts +3 -1
  16. package/dist/employee-knowledge.js +24 -8
  17. package/dist/git-quick-commit.d.ts +2 -0
  18. package/dist/git-quick-commit.js +15 -2
  19. package/dist/git-worktree-batch.d.ts +26 -0
  20. package/dist/git-worktree-batch.js +139 -0
  21. package/dist/global-knowledge.d.ts +12 -0
  22. package/dist/global-knowledge.js +124 -0
  23. package/dist/iteration-log.d.ts +13 -5
  24. package/dist/iteration-log.js +120 -59
  25. package/dist/knowledge-types.d.ts +12 -1
  26. package/dist/knowledge-types.js +4 -0
  27. package/dist/middleware/api-scope.js +1 -0
  28. package/dist/model-groups.js +6 -3
  29. package/dist/models/parsers/opencode.js +31 -1
  30. package/dist/models.js +15 -14
  31. package/dist/npm-update-utils.d.ts +5 -2
  32. package/dist/npm-update-utils.js +34 -4
  33. package/dist/opencode-cli.d.ts +6 -0
  34. package/dist/opencode-cli.js +51 -0
  35. package/dist/opencode-system-fallback.d.ts +1 -0
  36. package/dist/opencode-system-fallback.js +16 -4
  37. package/dist/pi-native-event-bridge.js +55 -3
  38. package/dist/pi-native-input.d.ts +22 -0
  39. package/dist/pi-native-input.js +77 -0
  40. package/dist/pi-tmux-host.d.ts +14 -5
  41. package/dist/pi-tmux-host.js +68 -17
  42. package/dist/process-manager.js +17 -3
  43. package/dist/pty-tmux-backend.d.ts +27 -2
  44. package/dist/pty-tmux-backend.js +471 -70
  45. package/dist/pty-tmux-log.d.ts +1 -1
  46. package/dist/pty-tmux-log.js +23 -2
  47. package/dist/retention-protection.d.ts +1 -1
  48. package/dist/retention-protection.js +3 -2
  49. package/dist/retention.d.ts +5 -0
  50. package/dist/retention.js +11 -0
  51. package/dist/server-knowledge-routes.js +2 -2
  52. package/dist/server-session-input-routes.js +38 -19
  53. package/dist/server-session-lifecycle-routes.js +14 -1
  54. package/dist/server-session-worktree-routes.js +105 -12
  55. package/dist/server-task-routes.js +41 -12
  56. package/dist/server-workspace-routes.js +77 -9
  57. package/dist/server.js +67 -35
  58. package/dist/session-registry.d.ts +17 -3
  59. package/dist/session-registry.js +66 -13
  60. package/dist/session-service.js +1 -1
  61. package/dist/storage/internal.d.ts +4 -3
  62. package/dist/storage/internal.js +3 -3
  63. package/dist/storage/knowledge-repository.d.ts +5 -0
  64. package/dist/storage/knowledge-repository.js +75 -16
  65. package/dist/storage/mappers.d.ts +1 -0
  66. package/dist/storage/mappers.js +6 -1
  67. package/dist/storage/migrations.js +60 -0
  68. package/dist/storage/session-input-repository.d.ts +19 -0
  69. package/dist/storage/session-input-repository.js +35 -0
  70. package/dist/storage/task-workflow-repository.d.ts +29 -0
  71. package/dist/storage/task-workflow-repository.js +110 -0
  72. package/dist/storage/tasks-repository.d.ts +6 -1
  73. package/dist/storage/tasks-repository.js +94 -34
  74. package/dist/storage/workspaces-repository.d.ts +7 -0
  75. package/dist/storage/workspaces-repository.js +28 -2
  76. package/dist/storage-cleanup.d.ts +7 -2
  77. package/dist/storage-cleanup.js +16 -0
  78. package/dist/storage-schema.js +2 -0
  79. package/dist/storage.d.ts +5 -1
  80. package/dist/storage.js +12 -0
  81. package/dist/structured-exec-host.d.ts +4 -0
  82. package/dist/structured-exec-pump.d.ts +1 -0
  83. package/dist/structured-exec-pump.js +18 -11
  84. package/dist/structured-opencode-adapter.d.ts +2 -1
  85. package/dist/structured-opencode-adapter.js +32 -8
  86. package/dist/structured-pi-adapter.js +13 -2
  87. package/dist/structured-runner.d.ts +6 -0
  88. package/dist/structured-session-manager-replay.d.ts +2 -0
  89. package/dist/structured-session-manager-replay.js +27 -0
  90. package/dist/structured-session-manager.d.ts +32 -21
  91. package/dist/structured-session-manager.js +395 -118
  92. package/dist/structured-tmux-host.d.ts +23 -2
  93. package/dist/structured-tmux-host.js +143 -20
  94. package/dist/task-actions.js +5 -3
  95. package/dist/task-archive-policy.js +2 -1
  96. package/dist/task-comment-dispatch.d.ts +2 -1
  97. package/dist/task-comment-dispatch.js +19 -6
  98. package/dist/task-execution-queue.d.ts +2 -0
  99. package/dist/task-execution-queue.js +10 -10
  100. package/dist/task-hierarchy.js +1 -1
  101. package/dist/task-read-model.d.ts +1 -1
  102. package/dist/task-read-model.js +2 -1
  103. package/dist/task-types.d.ts +34 -3
  104. package/dist/task-types.js +21 -5
  105. package/dist/task-workflow-cli.d.ts +2 -0
  106. package/dist/task-workflow-cli.js +29 -0
  107. package/dist/task-workflow-runner.d.ts +4 -0
  108. package/dist/task-workflow-runner.js +36 -0
  109. package/dist/task-workflow.d.ts +13 -0
  110. package/dist/task-workflow.js +48 -0
  111. package/dist/terminal-daemon-server.js +12 -4
  112. package/dist/tmux-policy.d.ts +9 -0
  113. package/dist/tmux-policy.js +46 -0
  114. package/dist/tmux-terminal-host.js +5 -2
  115. package/dist/tui/commands.js +2 -1
  116. package/dist/types.d.ts +5 -0
  117. package/dist/wand-task-sync.js +5 -0
  118. package/dist/web-ui/content/ai-teams.js +9 -9
  119. package/dist/web-ui/content/module-manifest.json +1 -1
  120. package/dist/web-ui/content/modules/{52574891ef08e29b → 014fa5c6f973badf}/host.js +3 -3
  121. package/dist/web-ui/content/modules/0818b1d31a11d006/employee-profile.js +1 -0
  122. package/dist/web-ui/content/modules/{31157ceb6d23b809 → 0a58d9ec273078e4}/chunk.js +3 -3
  123. package/dist/web-ui/content/modules/{bf3ee58e0da44822 → 0a979dcd165cd0cc}/chunk.js +1 -1
  124. package/dist/web-ui/content/modules/{5f298a8f43dd0589 → 0c143928e8f96abc}/chunk.js +1 -1
  125. package/dist/web-ui/content/modules/0e9e42a319f6b8fc/workspace-window.js +1 -0
  126. package/dist/web-ui/content/modules/{b713cad51ca4c512 → 0f0d1769b732c0bd}/chunk.js +1 -1
  127. package/dist/web-ui/content/modules/{4970319a83432ec7 → 1447886e6a1e74a4}/chunk.js +1 -1
  128. package/dist/web-ui/content/modules/151c734cbca31da5/host.js +1 -0
  129. package/dist/web-ui/content/modules/{e5174201f9d918fb → 16e4ab9c5263fcfd}/chunk.js +1 -1
  130. package/dist/web-ui/content/modules/17e752fb53952753/host.js +1 -0
  131. package/dist/web-ui/content/modules/{913187c92a98a1ac → 20ed1454fc09fa6f}/chunk.js +1 -1
  132. package/dist/web-ui/content/modules/255a3baf59d2b734/home.js +6 -0
  133. package/dist/web-ui/content/modules/{2f801e53dda62770 → 296dd81886c42b45}/chunk.js +1 -1
  134. package/dist/web-ui/content/modules/{8891ca8165435ca1 → 2a01f4e525c0725e}/chunk.js +1 -1
  135. package/dist/web-ui/content/modules/2ab4409c82b44fba/markdown.js +1 -0
  136. package/dist/web-ui/content/modules/2c955eced11610c2/chunk.js +1 -0
  137. package/dist/web-ui/content/modules/2d7ee4f9e2c0aca4/panel.js +1 -0
  138. package/dist/web-ui/content/modules/{3f8830f8ad28decc → 33ae550e4a295c85}/chunk.js +1 -1
  139. package/dist/web-ui/content/modules/35f4aa4443696bd0/chunk.js +1 -0
  140. package/dist/web-ui/content/modules/388b37ffcce9d4ff/host.js +1 -0
  141. package/dist/web-ui/content/modules/39279604dcdac7c7/runtime.js +338 -0
  142. package/dist/web-ui/content/modules/{57c357d321db5df9 → 3a3cdff2a662b7d3}/chunk.js +1 -1
  143. package/dist/web-ui/content/modules/{d49f106c4d106057 → 3ab646be55514243}/chunk.js +1 -1
  144. package/dist/web-ui/content/modules/{16dab1297efd71a7 → 3ae88a5c5e1949d2}/chunk.js +1 -1
  145. package/dist/web-ui/content/modules/3e3b0e71d6ce80d8/chunk.js +1 -0
  146. package/dist/web-ui/content/modules/{ec33e17c00c1eb24 → 434aaaaf9604dc34}/chunk.js +1 -1
  147. package/dist/web-ui/content/modules/4385cd48771e1d4f/host.js +1 -0
  148. package/dist/web-ui/content/modules/{face3dbf117d63e3 → 4638129d60f549a0}/chunk.js +1 -1
  149. package/dist/web-ui/content/modules/47407209931b7011/host.js +13 -0
  150. package/dist/web-ui/content/modules/4829dd712d8b366b/chunk.js +1 -0
  151. package/dist/web-ui/content/modules/488d5b747bf374c8/chunk.js +1 -0
  152. package/dist/web-ui/content/modules/{ed7405f064944215 → 4ab085c195f7d76a}/sha256.js +1 -1
  153. package/dist/web-ui/content/modules/{f27a5d3c6c02a71c → 4c485bd44740fec7}/chunk.js +1 -1
  154. package/dist/web-ui/content/modules/{771439a41e737ee2 → 4ca0494308ab2bb3}/chunk.js +1 -1
  155. package/dist/web-ui/content/modules/4ec571218779ba3e/composer-surface-adapter.js +1 -0
  156. package/dist/web-ui/content/modules/{5933ce8965aa4004 → 5023bf0294c2e7cb}/chunk.js +1 -1
  157. package/dist/web-ui/content/modules/{e63582a3bce48f7d → 5456e3417600bf15}/chunk.js +1 -1
  158. package/dist/web-ui/content/modules/55c588b0f5b41a52/host-bridge.js +1 -0
  159. package/dist/web-ui/content/modules/{9d941d6ff39861b8 → 5c3c8237ba7d8460}/chunk.js +1 -1
  160. package/dist/web-ui/content/modules/624b858da9834757/host.js +1 -0
  161. package/dist/web-ui/content/modules/6290be936320d4b1/host.js +1 -0
  162. package/dist/web-ui/content/modules/66be408793048cc3/progress.js +1 -0
  163. package/dist/web-ui/content/modules/67a11176a563317b/chunk.js +1 -0
  164. package/dist/web-ui/content/modules/{e060508ecd50fa7e → 68ef6ec7d26d78cd}/chunk.js +1 -1
  165. package/dist/web-ui/content/modules/{41445c6589dba325 → 6ec3e41df31927d9}/host.js +2 -2
  166. package/dist/web-ui/content/modules/{97d7f267959fd385 → 6f10f369445bbcbe}/chunk.js +1 -1
  167. package/dist/web-ui/content/modules/{d47d75a78ae598e3 → 7295d9ff92d5e1e7}/chunk.js +1 -1
  168. package/dist/web-ui/content/modules/{f383d892fef73483 → 72cd613de1a5f69b}/chunk.js +1 -1
  169. package/dist/web-ui/content/modules/73aae1daafeea7e7/workspaces-panel.js +4 -0
  170. package/dist/web-ui/content/modules/{c2f09c8a472f5d83 → 73d2689f13b9a3e9}/dialog-modal.js +1 -1
  171. package/dist/web-ui/content/modules/{2f97ddba3842adaa → 75cf0c048e9b92ab}/chunk.js +1 -1
  172. package/dist/web-ui/content/modules/{4ba1e8c74bed7ef2 → 75dabda3b141296e}/chunk.js +1 -1
  173. package/dist/web-ui/content/modules/{f3cff7792ba39df8 → 76c10b58d5f92d02}/login-visual.js +1 -1
  174. package/dist/web-ui/content/modules/{b63e075f222a1266 → 783583a12f5010f8}/library-bridge.js +1 -1
  175. package/dist/web-ui/content/modules/7e13a8a4a981f2f1/group-editor.js +1 -0
  176. package/dist/web-ui/content/modules/{0d76e582a7a71b2f → 7e3034fea34c6dae}/chunk.js +1 -1
  177. package/dist/web-ui/content/modules/80bf3291f2577a68/host.js +1 -0
  178. package/dist/web-ui/content/modules/{cba6f13c0b2aec1c → 82c3e08f34a6b828}/chunk.js +1 -1
  179. package/dist/web-ui/content/modules/{dedd4a19bb70e327 → 83d1f4cf82c65f19}/page.js +3 -3
  180. package/dist/web-ui/content/modules/844f97958f25240c/shell-file-panel-drawer.js +1 -0
  181. package/dist/web-ui/content/modules/{62e0023451f428cf → 899cdc467044d418}/chunk.js +1 -1
  182. package/dist/web-ui/content/modules/{5083a5dbb5b155b7 → 8c7ca1fe72741c07}/chunk.js +1 -1
  183. package/dist/web-ui/content/modules/8dae4ca2261525e4/task-board-host.js +27 -0
  184. package/dist/web-ui/content/modules/92195c14c74929da/list-filter-panel.js +1 -0
  185. package/dist/web-ui/content/modules/{a61393bfa976d8d5 → 93793696af76bcbf}/chunk.js +1 -1
  186. package/dist/web-ui/content/modules/{db521a246e14e5e4 → 97cd6af3da5622b8}/chunk.js +4 -4
  187. package/dist/web-ui/content/modules/{8de8368570ab089d → 9d3179258249ec77}/chunk.js +1 -1
  188. package/dist/web-ui/content/modules/{579d486763d47c0d → a234c484078c0568}/chunk.js +1 -1
  189. package/dist/web-ui/content/modules/a4d215448a089a7d/host.js +1 -0
  190. package/dist/web-ui/content/modules/{c0a446100d969f3e → ae003f89901c5687}/chunk.js +1 -1
  191. package/dist/web-ui/content/modules/ae712bdd45b9917e/employee-card.js +1 -0
  192. package/dist/web-ui/content/modules/{a2caed0139df4b21 → b2a15293f7965d09}/chunk.js +1 -1
  193. package/dist/web-ui/content/modules/b4ee65e9998f0088/host.js +61 -0
  194. package/dist/web-ui/content/modules/{bd3daf04a8bf4422 → b666137d17f83be9}/chunk.js +1 -1
  195. package/dist/web-ui/content/modules/{831b6c7b43e800be → b66beb6c0185256b}/host.js +1 -1
  196. package/dist/web-ui/content/modules/{816eb9b3a000fb2c → bb03b17e877657de}/chunk.js +1 -1
  197. package/dist/web-ui/content/modules/{1eab7410d5586038 → bc343afc991db1a1}/chunk.js +1 -1
  198. package/dist/web-ui/content/modules/bca45976ff8fe2ac/host.js +69 -0
  199. package/dist/web-ui/content/modules/{d434edbb2f4672e5 → c2715dbfc9eaf510}/chunk.js +1 -1
  200. package/dist/web-ui/content/modules/{d6fffe2c2a3a738d → c30c220281f35d74}/toast-region.js +1 -1
  201. package/dist/web-ui/content/modules/c4cc46fa9b4adddc/dropdown-surface.js +1 -0
  202. package/dist/web-ui/content/modules/c6dd19ee3d3ffd59/brand-identity.js +1 -0
  203. package/dist/web-ui/content/modules/c7ea6a114e6ff8ae/host.js +1 -0
  204. package/dist/web-ui/content/modules/{a59734be368daa7e → c916d82c8acef9c8}/chunk.js +1 -1
  205. package/dist/web-ui/content/modules/{182929e188c1ab3a → cceaedda619a737a}/host.js +1 -1
  206. package/dist/web-ui/content/modules/cf67f52b076b9d2d/panel-host.js +1 -0
  207. package/dist/web-ui/content/modules/{9e163d54ff8fd1aa → d26c86558d422313}/chunk.js +1 -1
  208. package/dist/web-ui/content/modules/d2b8c6c6f3706032/queue-view-adapter.js +1 -0
  209. package/dist/web-ui/content/modules/d52ebe2ef12a9fa8/chunk.js +3 -0
  210. package/dist/web-ui/content/modules/{3fe11a75284ad8ae → d552b3bff2151eb6}/host.js +2 -2
  211. package/dist/web-ui/content/modules/d5d6b4511ac76a6e/chunk.js +3 -0
  212. package/dist/web-ui/content/modules/{bd7dc4bb46731ee7 → df42e151d625463b}/chunk.js +1 -1
  213. package/dist/web-ui/content/modules/{2a791cd2e14aa1e0 → e0a04f5ae56c68aa}/notice-view.js +1 -1
  214. package/dist/web-ui/content/modules/{438807b8bf112cd0 → e28e607c95d6f63a}/chunk.js +1 -1
  215. package/dist/web-ui/content/modules/{50da446c1377c220 → e3880df97ea62d0c}/chunk.js +1 -1
  216. package/dist/web-ui/content/modules/{87c7f50d9455d55e → e66196f1ece3e3ad}/chunk.js +1 -1
  217. package/dist/web-ui/content/modules/{9b12c2301f3a18f3 → eb76307444ac9d71}/chunk.js +1 -1
  218. package/dist/web-ui/content/modules/{c33935155289c22d → ebff7ca22cee1468}/chunk.js +1 -1
  219. package/dist/web-ui/content/modules/{4861eca9a8a87ad0 → ed1c712c569960d6}/chunk.js +1 -1
  220. package/dist/web-ui/content/modules/ee8b9c2d4bec63d4/chunk.js +1 -0
  221. package/dist/web-ui/content/modules/f458a194ce4208e2/chunk.js +1 -0
  222. package/dist/web-ui/content/modules/{11af5d14b30e57b6 → f938e826420cfe1b}/chunk.js +1 -1
  223. package/dist/web-ui/content/modules/fa7b9bf6cc84bfc1/chat-render.js +81 -0
  224. package/dist/web-ui/content/modules/{ea8fe4b9999fd2aa → fd1fb1834f5f06df}/chunk.js +1 -1
  225. package/dist/web-ui/content/modules/fd3084e562a3dbd6/host.js +1 -0
  226. package/dist/web-ui/content/styles.css +1 -1
  227. package/dist/web-ui/embedded-assets.d.ts +416 -413
  228. package/dist/web-ui/embedded-assets.js +5 -5
  229. package/dist/web-ui/page-route.js +2 -2
  230. package/dist/web-ui/react/workspaces/types.d.ts +3 -0
  231. package/dist/web-ui/thinking-efforts.d.ts +2 -0
  232. package/dist/web-ui/thinking-efforts.js +8 -0
  233. package/package.json +1 -2
  234. package/scripts/stage-render-binaries.js +0 -1
  235. package/skills/wand-knowledge/SKILL.md +5 -3
  236. package/dist/structured-bounded-keys.d.ts +0 -19
  237. package/dist/structured-bounded-keys.js +0 -47
  238. package/dist/web-ui/content/modules/00b168a19664439e/dropdown-surface.js +0 -1
  239. package/dist/web-ui/content/modules/059c5fb7f128d340/task-board-host.js +0 -27
  240. package/dist/web-ui/content/modules/07494f5a623e4471/chat-render.js +0 -76
  241. package/dist/web-ui/content/modules/0a743ad3b4db6874/chunk.js +0 -3
  242. package/dist/web-ui/content/modules/1858670c0f84fec5/employee-profile.js +0 -1
  243. package/dist/web-ui/content/modules/20c47dc0442f5a04/host.js +0 -1
  244. package/dist/web-ui/content/modules/226241b999d12008/host.js +0 -1
  245. package/dist/web-ui/content/modules/23c4b8d223ec64c5/host.js +0 -61
  246. package/dist/web-ui/content/modules/2882c97388ff4f7b/employee-card.js +0 -1
  247. package/dist/web-ui/content/modules/2c90c3be260e6cce/progress.js +0 -1
  248. package/dist/web-ui/content/modules/2d7be9935394f397/workspace-window.js +0 -1
  249. package/dist/web-ui/content/modules/389a5112332ec23a/host.js +0 -1
  250. package/dist/web-ui/content/modules/3ea13e8b3c2deaa4/panel-host.js +0 -1
  251. package/dist/web-ui/content/modules/42e5c34002fcffb7/chunk.js +0 -1
  252. package/dist/web-ui/content/modules/4a5d669c90f545cb/host.js +0 -1
  253. package/dist/web-ui/content/modules/5705d25468274534/host.js +0 -1
  254. package/dist/web-ui/content/modules/5961ab2947c86ca1/shell-file-panel-drawer.js +0 -1
  255. package/dist/web-ui/content/modules/5b6e1369df7dea69/chunk.js +0 -1
  256. package/dist/web-ui/content/modules/6787bdcf56f743a5/host.js +0 -1
  257. package/dist/web-ui/content/modules/67c39b0398186a9f/host.js +0 -1
  258. package/dist/web-ui/content/modules/6b16f35c0627bafb/chunk.js +0 -1
  259. package/dist/web-ui/content/modules/6dd4f3e2f619f7a0/chunk.js +0 -1
  260. package/dist/web-ui/content/modules/70a2e13e0ccc8549/panel.js +0 -1
  261. package/dist/web-ui/content/modules/710db590e9707f73/runtime.js +0 -338
  262. package/dist/web-ui/content/modules/7249950f8771dbeb/workspaces-panel.js +0 -4
  263. package/dist/web-ui/content/modules/87dcd516ffd9f688/composer-surface-adapter.js +0 -1
  264. package/dist/web-ui/content/modules/8b7cd7bffdfd69e7/brand-identity.js +0 -1
  265. package/dist/web-ui/content/modules/8bf9917f6c3429f6/host.js +0 -1
  266. package/dist/web-ui/content/modules/8e612d4881fa4118/home.js +0 -6
  267. package/dist/web-ui/content/modules/8e6178262ea63dec/markdown.js +0 -1
  268. package/dist/web-ui/content/modules/96f2ae970f8c576b/host.js +0 -1
  269. package/dist/web-ui/content/modules/ba89cd97627e6682/queue-view-adapter.js +0 -1
  270. package/dist/web-ui/content/modules/c351eb11e0bdec2c/sidebar-peek.js +0 -1
  271. package/dist/web-ui/content/modules/ca7ca5902a35d26e/chunk.js +0 -1
  272. package/dist/web-ui/content/modules/d5d28ec375826ef2/chunk.js +0 -3
  273. package/dist/web-ui/content/modules/d6b16dedb9011c33/chunk.js +0 -1
  274. package/dist/web-ui/content/modules/d8a7011760f61719/group-editor.js +0 -1
  275. package/dist/web-ui/content/modules/d9e2b65e9679ad39/host.js +0 -75
  276. package/dist/web-ui/content/modules/eac72f69716dba05/chunk.js +0 -1
  277. package/dist/web-ui/content/modules/ebc53dedc3945514/host.js +0 -1
  278. package/dist/web-ui/content/modules/f43da7050badf54c/host.js +0 -1
  279. package/dist/web-ui/content/modules/fb2356eced24c4cc/host-bridge.js +0 -1
@@ -22,6 +22,7 @@ export function startStructuredCli(options) {
22
22
  // history snapshot must not exhaust the raw-file quota before SAX can read it.
23
23
  const captureReader = options.stdoutFile ? options.createProtocolReader?.((line) => stdoutFile?.append(line + "\n")) : undefined;
24
24
  let settled = false;
25
+ let processExited = false;
25
26
  let stopRequested = false;
26
27
  let stopDelivered = false;
27
28
  // A pending spawn has no cancellable handle yet. Remember one request and
@@ -36,14 +37,14 @@ export function startStructuredCli(options) {
36
37
  catch { /* best-effort interruption */ }
37
38
  }
38
39
  function requestStop() {
39
- if (settled || stopRequested)
40
+ if (processExited || stopRequested)
40
41
  return;
41
42
  stopRequested = true;
42
43
  launchController?.abort();
43
44
  interruptSource();
44
45
  }
45
46
  let acknowledgeExit = () => { };
46
- const exited = new Promise((resolve) => { acknowledgeExit = resolve; });
47
+ const exited = new Promise((resolve) => { acknowledgeExit = () => { processExited = true; resolve(); }; });
47
48
  let resolveCompletion;
48
49
  let rejectCompletion;
49
50
  const completion = new Promise((resolve, reject) => {
@@ -78,7 +79,7 @@ export function startStructuredCli(options) {
78
79
  try {
79
80
  if (!protocolError && lineBuffer.trim())
80
81
  options.processLine(lineBuffer, ctx);
81
- const result = options.finalize(ctx, exitCode, signal, spawnError);
82
+ const result = { ...options.finalize(ctx, exitCode, signal, spawnError), processExited };
82
83
  resolveCompletion(beforeSpawn ? { ...result, primaryError: spawnError?.message ?? "Pi 实时事件文件初始化失败。",
83
84
  inputAccepted: false, retryForbidden: true, failure: { kind: "preflight", delivery: "rejected", retryable: false } }
84
85
  : protocolError ? { ...result, exitCode: 1, primaryError: protocolError.message,
@@ -185,7 +186,7 @@ export function startStructuredCli(options) {
185
186
  cwd: options.cwd,
186
187
  env: options.env,
187
188
  ...(options.stdinData !== undefined ? { stdinData: options.stdinData } : {}),
188
- ...(options.nativePi ? { nativePi: true } : {}),
189
+ ...(options.nativePi ? { nativePi: true, nativeInputMessageId: options.nativeInputMessageId } : {}),
189
190
  ...(options.requestId ? { requestId: options.requestId } : {}),
190
191
  ...(launchController ? { launchSignal: launchController.signal } : {}),
191
192
  };
@@ -209,7 +210,7 @@ export function startStructuredCli(options) {
209
210
  void host.spawnStructured(request).then((handle) => {
210
211
  source = { pid: handle.pid, interrupt: () => handle.interrupt() };
211
212
  // Replay and subscribe before applying a pending external cancellation.
212
- wireRemoteHandle(handle, captureStdout, handleStderrText, finish, acknowledgeExit, (event) => {
213
+ wireRemoteHandle(handle, captureStdout, handleStderrText, finish, acknowledgeExit, () => finish(1, null, undefined, new Error("CLI 输出连接中断,正在等待原进程停止;新消息会排队。")), (event) => {
213
214
  if (!settled && options.nativePi && event.stream === "stdout" && handle.protocolSource
214
215
  && protocolReader?.atBoundary && observer.isActive()) {
215
216
  options.checkpoint?.({ incarnationId: handle.incarnationId, source: handle.protocolSource, offset: event.seq });
@@ -236,7 +237,11 @@ export function startStructuredCli(options) {
236
237
  const stderrDecoder = createUtf8TextDecoder();
237
238
  child.stdout?.on("data", (chunk) => captureStdout(stdoutDecoder.write(chunk)));
238
239
  child.stderr?.on("data", (chunk) => handleStderrText(stderrDecoder.write(chunk)));
239
- child.on("error", (error) => finish(null, null, error));
240
+ child.on("error", (error) => {
241
+ if (!child.pid)
242
+ acknowledgeExit(); // Spawn failed before any process existed.
243
+ finish(null, null, error);
244
+ });
240
245
  child.stdin?.on("error", (error) => {
241
246
  requestStop();
242
247
  finish(null, null, error);
@@ -252,7 +257,7 @@ export function startStructuredCli(options) {
252
257
  }
253
258
  return execution;
254
259
  }
255
- function wireRemoteHandle(handle, onStdout, onStderr, finish, acknowledgeExit, afterStream) {
260
+ function wireRemoteHandle(handle, onStdout, onStderr, finish, acknowledgeExit, observationFailed, afterStream) {
256
261
  const stream = handle.onStream((event) => {
257
262
  if (event.stream === "stdout")
258
263
  onStdout(event.data);
@@ -264,11 +269,13 @@ function wireRemoteHandle(handle, onStdout, onStderr, finish, acknowledgeExit, a
264
269
  let ended = false;
265
270
  exit = handle.onExit((event) => {
266
271
  stream.dispose();
267
- if (event.processExited !== false) {
268
- ended = true;
269
- exit?.dispose();
270
- acknowledgeExit();
272
+ if (event.processExited === false) {
273
+ observationFailed();
274
+ return;
271
275
  }
276
+ ended = true;
277
+ exit?.dispose();
278
+ acknowledgeExit();
272
279
  finish(event.exitCode, signalNameFromNumber(event.signal));
273
280
  });
274
281
  if (ended)
@@ -3,7 +3,7 @@ import type { StructuredExecHost } from "./structured-exec-host.js";
3
3
  import type { StructuredRunnerAdapter, StructuredRunnerContext, StructuredRunnerExecution, StructuredRunnerObserver, StructuredRunnerTurnState } from "./structured-runner.js";
4
4
  import type { SessionSnapshot } from "./types.js";
5
5
  export type OpenCodeTurnState = StructuredRunnerTurnState;
6
- export declare function buildOpenCodeArgs(session: SessionSnapshot): string[];
6
+ export declare function buildOpenCodeArgs(session: SessionSnapshot, major?: number): string[];
7
7
  /** Apply one OpenCode NDJSON event to the current transport-neutral turn state. */
8
8
  export declare function applyOpenCodeEvent(turnState: OpenCodeTurnState, event: Record<string, unknown>, createId?: () => string): string | null;
9
9
  /** Production adapter for the external `opencode run --format json` process. */
@@ -12,4 +12,5 @@ export declare class OpenCodeRunner implements StructuredRunnerAdapter {
12
12
  private readonly execHost?;
13
13
  constructor(spawnProcess?: typeof spawn, execHost?: StructuredExecHost | undefined);
14
14
  start(context: StructuredRunnerContext, observer: StructuredRunnerObserver): StructuredRunnerExecution;
15
+ private startCli;
15
16
  }
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { spawn } from "node:child_process";
3
+ import { openCodeMajorVersion, openCodeModelArgs } from "./opencode-cli.js";
3
4
  import { startStructuredCli } from "./structured-exec-pump.js";
4
5
  import { asRecord } from "./structured-content.js";
5
6
  import { buildStructuredCliResult } from "./structured-failure.js";
@@ -19,14 +20,11 @@ function extractStructuredText(value) {
19
20
  }
20
21
  return "";
21
22
  }
22
- export function buildOpenCodeArgs(session) {
23
+ export function buildOpenCodeArgs(session, major = 1) {
23
24
  const args = ["run", "--format", "json", "--thinking"];
24
- const modelChoice = session.selectedModel?.trim();
25
- if (modelChoice && modelChoice !== "default")
26
- args.push("--model", modelChoice);
27
- const variant = thinkingEffortToOpenCodeVariant(session.thinkingEffort);
28
- if (variant)
29
- args.push("--variant", variant);
25
+ if (major >= 2)
26
+ args.push("--standalone");
27
+ args.push(...openCodeModelArgs(session.selectedModel, thinkingEffortToOpenCodeVariant(session.thinkingEffort), major));
30
28
  if (session.autoApprovePermissions === true
31
29
  || session.mode === "full-access"
32
30
  || session.mode === "managed"
@@ -121,7 +119,33 @@ export class OpenCodeRunner {
121
119
  this.execHost = execHost;
122
120
  }
123
121
  start(context, observer) {
124
- const args = buildOpenCodeArgs(context.session);
122
+ const abort = new AbortController();
123
+ let execution;
124
+ const spawnedAt = new Date().toISOString();
125
+ const completion = Promise.resolve().then(async () => {
126
+ const major = await openCodeMajorVersion(context.env, abort.signal);
127
+ if (abort.signal.aborted || !observer.isActive())
128
+ throw new Error("OpenCode 启动已取消。");
129
+ execution = this.startCli(context, observer, major);
130
+ return execution.completion;
131
+ }).catch((error) => {
132
+ // Once launched, keep the runner's delivery facts; preparation is the only known rejection.
133
+ if (execution)
134
+ throw error;
135
+ return {
136
+ state: { blocks: [], result: "", sessionId: context.session.claudeSessionId },
137
+ exitCode: 1, signal: null, stderr: "", primaryError: error instanceof Error ? error.message : "OpenCode 启动准备失败。",
138
+ processExited: true, inputAccepted: false, retryForbidden: true,
139
+ };
140
+ });
141
+ return { spawnedAt, completion,
142
+ get args() { return execution?.args ?? []; }, get pid() { return execution?.pid ?? null; },
143
+ exited: completion.then(() => execution?.exited, () => execution?.exited).then(() => { }),
144
+ interrupt() { abort.abort(); execution?.interrupt(); },
145
+ };
146
+ }
147
+ startCli(context, observer, major) {
148
+ const args = buildOpenCodeArgs(context.session, major);
125
149
  const state = {
126
150
  blocks: [],
127
151
  result: "",
@@ -296,6 +296,7 @@ export class PiRunner {
296
296
  const state = {
297
297
  blocks: [],
298
298
  result: "",
299
+ inputMessageId: [...(context.session.messages ?? [])].reverse().find(turn => turn.role === "user")?.messageId,
299
300
  sessionId: context.session.claudeSessionId,
300
301
  model: context.session.selectedModel ?? undefined,
301
302
  phase: "responding",
@@ -317,7 +318,7 @@ export class PiRunner {
317
318
  observer,
318
319
  execHost: this.execHost,
319
320
  spawnProcess: this.spawnProcess,
320
- ...(nativePi ? { nativePi: true } : { stdoutFile: this.outputFiles?.(context.session.id) ?? {} }),
321
+ ...(nativePi ? { nativePi: true, nativeInputMessageId: state.inputMessageId } : { stdoutFile: this.outputFiles?.(context.session.id) ?? {} }),
321
322
  requestId: context.session.structuredState?.activeRequestId ?? undefined,
322
323
  createState: () => state,
323
324
  createProtocolReader: (onLine) => new PiProtocolReader(onLine),
@@ -329,8 +330,18 @@ export class PiRunner {
329
330
  processLine: (line) => {
330
331
  if (!observer.isActive() || !line.trim())
331
332
  return;
333
+ let event;
334
+ try {
335
+ event = JSON.parse(line);
336
+ }
337
+ catch {
338
+ unparsedOutput = true;
339
+ return;
340
+ }
341
+ // Control/storage failures must reach the pump and stop this execution;
342
+ // they cannot be swallowed as harmless unparsed provider stdout.
343
+ context.onPiInputEvent?.(event, state);
332
344
  try {
333
- const event = JSON.parse(line);
334
345
  observer.onEvent?.(event);
335
346
  protocolEventObserved = true;
336
347
  const eventError = applyPiEvent(state, event, new Date().toISOString());
@@ -29,6 +29,8 @@ export interface StructuredCompactionNotice {
29
29
  export interface StructuredRunnerTurnState {
30
30
  blocks: ContentBlock[];
31
31
  result: string;
32
+ /** Native Pi segment identity, also retained in replay checkpoints. */
33
+ inputMessageId?: string;
32
34
  sessionId: string | null;
33
35
  model?: string;
34
36
  usage?: ConversationTurn["usage"];
@@ -51,6 +53,8 @@ export interface StructuredRunnerContext {
51
53
  modelGroupModels?: readonly string[];
52
54
  /** Core-only: synchronously persist one queued user turn and the preceding assistant segment. */
53
55
  takeSteering?(state: StructuredRunnerTurnState): string | null;
56
+ /** Native CLI control events, before the provider reducer mutates its segment. */
57
+ onPiInputEvent?(event: Record<string, unknown>, state: StructuredRunnerTurnState): void;
54
58
  }
55
59
  export interface StructuredRunnerObserver {
56
60
  isActive(): boolean;
@@ -67,6 +71,8 @@ export interface StructuredRunnerResult {
67
71
  signal: NodeJS.Signals | null;
68
72
  stderr: string;
69
73
  primaryError: string | null;
74
+ /** false means only observation settled; the CLI still owns its execution. */
75
+ processExited?: boolean;
70
76
  errors?: string[];
71
77
  stdoutTail?: string;
72
78
  stopReason?: "ask-user-question";
@@ -68,4 +68,6 @@ export declare function appendNoticeTurn(messages: ConversationTurn[] | undefine
68
68
  /** core 引擎的压缩通知 → 可持久化的会话上下文(历史不删,只记切点与摘要)。 */
69
69
  export declare function compactionToSessionContext(notice: StructuredCompactionNotice): HarnessSessionContext;
70
70
  export declare function cancelPendingResourceSelection(messages: ConversationTurn[] | undefined): ConversationTurn[] | undefined;
71
+ /** Replace one Pi segment after a native steering input; earlier turns stay untouched. */
72
+ export declare function upsertPiAssistantSegment(messages: ConversationTurn[] | undefined, turn: ConversationTurn, inputMessageId: string, complete?: boolean): ConversationTurn[];
71
73
  export declare function upsertAssistantMessage(messages: ConversationTurn[] | undefined, turn: ConversationTurn, complete?: boolean, stampNewTools?: boolean): ConversationTurn[];
@@ -373,6 +373,33 @@ export function cancelPendingResourceSelection(messages) {
373
373
  ...last.resourceSelection, status: "cancelled", label: "本轮自动选择已取消",
374
374
  } }];
375
375
  }
376
+ /** Replace one Pi segment after a native steering input; earlier turns stay untouched. */
377
+ export function upsertPiAssistantSegment(messages, turn, inputMessageId, complete = false) {
378
+ const msgs = [...(messages ?? [])];
379
+ let at = -1;
380
+ for (let index = msgs.length - 1; index >= 0; index--) {
381
+ if (msgs[index].role === "user" && msgs[index].messageId === inputMessageId) {
382
+ at = index;
383
+ break;
384
+ }
385
+ }
386
+ if (at < 0)
387
+ return upsertAssistantMessage(msgs, turn, complete, false);
388
+ const previous = msgs[at + 1]?.role === "assistant" && !msgs[at + 1].notice ? msgs[at + 1] : undefined;
389
+ const next = { ...turn, createdAt: previous?.createdAt ?? turn.createdAt ?? isoNow(),
390
+ content: stampNewToolUseTimes(turn.content, previous?.content, isoNow(), true),
391
+ ...(turn.resourceSelection ? {} : previous?.resourceSelection ? { resourceSelection: previous.resourceSelection } : {}),
392
+ };
393
+ if (complete)
394
+ next.completedAt = previous?.completedAt ?? isoNow();
395
+ else if (previous?.completedAt)
396
+ next.completedAt = previous.completedAt;
397
+ if (previous)
398
+ msgs[at + 1] = next;
399
+ else
400
+ msgs.splice(at + 1, 0, next);
401
+ return msgs;
402
+ }
376
403
  export function upsertAssistantMessage(messages, turn, complete = false, stampNewTools = true) {
377
404
  const msgs = [...(messages ?? [])];
378
405
  const last = msgs[msgs.length - 1];
@@ -1,5 +1,6 @@
1
1
  import { type OpenRouterFreeModelsService } from "./openrouter-free-models.js";
2
2
  import { type StructuredFailure } from "./structured-failure.js";
3
+ import type { StructuredInputReceipt } from "./storage/session-input-repository.js";
3
4
  import { type WorktreeSetupSpec } from "./git-worktree.js";
4
5
  import { SessionLogger } from "./session-logger.js";
5
6
  import { WandStorage } from "./storage.js";
@@ -73,6 +74,21 @@ interface CreateStructuredSessionOptions {
73
74
  * 按 automationId 前缀识别,重启后照样生效。
74
75
  */
75
76
  export type StructuredRelayHandler = (sessionId: string, text: string) => void | Promise<void>;
77
+ interface StructuredSendOptions {
78
+ interrupt?: boolean;
79
+ idempotencyKey?: string;
80
+ preserveQueue?: boolean;
81
+ queueAlreadyRemoved?: boolean;
82
+ immediateStart?: boolean;
83
+ teamRequestStarted?: (sessionId: string, requestId: string) => void;
84
+ source?: EmployeeInputScheduling["source"];
85
+ scheduling?: EmployeeInputScheduling;
86
+ onAccepted?: (receipt?: StructuredInputReceipt) => void;
87
+ promotion?: {
88
+ index: number;
89
+ expectedText?: string;
90
+ };
91
+ }
76
92
  export declare class StructuredSessionManager {
77
93
  private readonly storage;
78
94
  private readonly config;
@@ -100,19 +116,12 @@ export declare class StructuredSessionManager {
100
116
  private readonly interruptedImmediateStart;
101
117
  private employeeInputAdmission;
102
118
  private inputSequence;
119
+ private readonly dispatchingAcceptedInputs;
103
120
  /** Last wall-clock time (ms) a streaming checkpoint reached SQLite. */
104
121
  private readonly lastStreamSaveAt;
105
122
  private readonly lastPiCheckpointAt;
106
123
  private readonly streamCheckpointTimers;
107
124
  private readonly streamCheckpointDirty;
108
- /**
109
- * Idempotency keys we've already accepted, mapped to their wall-clock timestamp.
110
- * Android WebView 在进程恢复时偶尔会重发上一个未收到响应的 POST(HTTP/2 stream
111
- * reset 等场景),客户端 JS 没有重试逻辑也拦不住。这里用 (sessionId, key) 永
112
- * 久去重,重复就抛错让前端弹 toast 提示,**不**做任何处理。timestamp 仅用于
113
- * map 大小溢出时按时间裁剪。
114
- */
115
- private readonly seenIdempotencyKeys;
116
125
  private readonly relayHandlers;
117
126
  private readonly systemCallDrainReleases;
118
127
  private emitEvent;
@@ -141,6 +150,7 @@ export declare class StructuredSessionManager {
141
150
  private readonly unsupportedStructuredProviders;
142
151
  /** Structured CLI runs that were mid-flight when the previous web process died. */
143
152
  private pendingRecoveryIds;
153
+ private detachedInventoryReconciled;
144
154
  private detachedRecoveryPromise;
145
155
  private detachedRecoveryRetryTimer;
146
156
  private detachedRecoveryFailureLogged;
@@ -204,6 +214,7 @@ export declare class StructuredSessionManager {
204
214
  */
205
215
  collectNativeGarbage(options: {
206
216
  liveSessionIds: ReadonlySet<string>;
217
+ activeSessionIds?: ReadonlySet<string>;
207
218
  retentionMs: number;
208
219
  now?: number;
209
220
  }): PiNativeGcReport | null;
@@ -246,20 +257,12 @@ export declare class StructuredSessionManager {
246
257
  private throwUnacceptedInput;
247
258
  /** 往转发会话里追加别的参与者的发言。 */
248
259
  appendRelayTurns(id: string, turns: ConversationTurn[]): SessionSnapshot | null;
249
- sendMessage(id: string, input: string, opts?: {
250
- interrupt?: boolean;
251
- idempotencyKey?: string;
252
- preserveQueue?: boolean;
253
- queueAlreadyRemoved?: boolean;
254
- immediateStart?: boolean;
255
- teamRequestStarted?: (sessionId: string, requestId: string) => void;
256
- source?: EmployeeInputScheduling["source"];
257
- scheduling?: EmployeeInputScheduling;
258
- }): Promise<SessionSnapshot>;
260
+ sendMessage(id: string, input: string, opts?: StructuredSendOptions): Promise<SessionSnapshot>;
261
+ private withoutAcceptedQueueItem;
262
+ private sendAcceptedMessage;
263
+ private runAcceptedMessage;
259
264
  /** 群聊不起 CLI:先落下用户这句话,再交给转发方;转发失败以提示行告诉用户。 */
260
265
  private relayUserMessage;
261
- /** Rejects a repeated (session, key) pair; otherwise remembers it (bounded). */
262
- private claimIdempotencyKey;
263
266
  /**
264
267
  * While a turn is in flight, decide what this send does: recover a turn whose
265
268
  * runner is gone, interrupt the current turn, or queue the input. Returns the
@@ -299,7 +302,7 @@ export declare class StructuredSessionManager {
299
302
  * on the server prevents clients from re-sending the text while the original
300
303
  * queue entry remains available for the automatic flush path.
301
304
  */
302
- promoteQueuedMessage(sessionId: string, index: number, expectedText?: string, idempotencyKey?: string): Promise<SessionSnapshot>;
305
+ promoteQueuedMessage(sessionId: string, index: number, expectedText?: string, idempotencyKey?: string, onAccepted?: (receipt?: StructuredInputReceipt) => void): Promise<SessionSnapshot>;
303
306
  private assertExpectedQueue;
304
307
  /** Clear all queued messages. No-op when queue is already empty. */
305
308
  clearQueuedMessages(sessionId: string, expectedQueue?: readonly string[]): SessionSnapshot;
@@ -387,6 +390,14 @@ export declare class StructuredSessionManager {
387
390
  private publishQuietHeartbeat;
388
391
  private commentTerminalEvent;
389
392
  private emitStructuredSnapshot;
393
+ /** Native Pi claims one durable queue item; the reservation survives until its transcript commit. */
394
+ private reserveNativeInput;
395
+ /** A claim is the native transcript commit: persist the boundary and remove only that reservation. */
396
+ private commitNativeInput;
397
+ private handleNativeInputEvent;
398
+ /** Reconcile before any end-of-run flush. Claimed-but-unconfirmed input is never replayed. */
399
+ private settleNativeInputs;
400
+ private assertNativeInputMutable;
390
401
  private enqueueInput;
391
402
  private flushNextQueuedMessage;
392
403
  private emit;