@intentic/sandbox-contract 1.311.0 → 1.313.0

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 (444) hide show
  1. package/README.md +32 -4
  2. package/dist/chores/chores.js +6 -6
  3. package/dist/chores/chores.js.map +1 -1
  4. package/dist/chores/index.d.ts +0 -1
  5. package/dist/chores/index.d.ts.map +1 -1
  6. package/dist/chores/index.js +0 -1
  7. package/dist/chores/index.js.map +1 -1
  8. package/dist/chores/prompt.d.ts.map +1 -1
  9. package/dist/chores/prompt.js +3 -2
  10. package/dist/chores/prompt.js.map +1 -1
  11. package/dist/contracts/accounts.contract.d.ts +69 -0
  12. package/dist/contracts/accounts.contract.d.ts.map +1 -1
  13. package/dist/contracts/agent.contract.d.ts +436 -0
  14. package/dist/contracts/agent.contract.d.ts.map +1 -1
  15. package/dist/contracts/agent.contract.js +11 -1
  16. package/dist/contracts/agent.contract.js.map +1 -1
  17. package/dist/contracts/agents.contract.d.ts +718 -90
  18. package/dist/contracts/agents.contract.d.ts.map +1 -1
  19. package/dist/contracts/agents.contract.js +30 -2
  20. package/dist/contracts/agents.contract.js.map +1 -1
  21. package/dist/contracts/capabilities.contract.js +1 -1
  22. package/dist/contracts/capabilities.contract.js.map +1 -1
  23. package/dist/contracts/device.contract.d.ts +20 -4
  24. package/dist/contracts/device.contract.d.ts.map +1 -1
  25. package/dist/contracts/device.contract.js +1 -1
  26. package/dist/contracts/device.contract.js.map +1 -1
  27. package/dist/contracts/extensions.contract.d.ts +13 -0
  28. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  29. package/dist/contracts/git.contract.d.ts +2 -0
  30. package/dist/contracts/git.contract.d.ts.map +1 -1
  31. package/dist/contracts/offload.contract.d.ts +107 -0
  32. package/dist/contracts/offload.contract.d.ts.map +1 -0
  33. package/dist/contracts/offload.contract.js +53 -0
  34. package/dist/contracts/offload.contract.js.map +1 -0
  35. package/dist/contracts/personas.contract.d.ts +2 -0
  36. package/dist/contracts/personas.contract.d.ts.map +1 -1
  37. package/dist/contracts/ports.contract.d.ts +5 -0
  38. package/dist/contracts/ports.contract.d.ts.map +1 -1
  39. package/dist/contracts/runner.contract.d.ts +204 -0
  40. package/dist/contracts/runner.contract.d.ts.map +1 -1
  41. package/dist/contracts/runner.contract.js +3 -1
  42. package/dist/contracts/runner.contract.js.map +1 -1
  43. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  44. package/dist/contracts/secrets.contract.js +1 -0
  45. package/dist/contracts/secrets.contract.js.map +1 -1
  46. package/dist/contracts/sessions.contract.d.ts +59 -0
  47. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  48. package/dist/contracts/settings.contract.d.ts +20 -8
  49. package/dist/contracts/settings.contract.d.ts.map +1 -1
  50. package/dist/contracts/settings.contract.js +2 -2
  51. package/dist/contracts/settings.contract.js.map +1 -1
  52. package/dist/contracts/system.contract.d.ts +230 -15
  53. package/dist/contracts/system.contract.d.ts.map +1 -1
  54. package/dist/contracts/translator.contract.d.ts +88 -0
  55. package/dist/contracts/translator.contract.d.ts.map +1 -1
  56. package/dist/contracts/workspace.contract.d.ts +217 -0
  57. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  58. package/dist/contracts/workspace.contract.js +40 -3
  59. package/dist/contracts/workspace.contract.js.map +1 -1
  60. package/dist/documents/conversions.d.ts +81 -0
  61. package/dist/documents/conversions.d.ts.map +1 -0
  62. package/dist/documents/conversions.js +213 -0
  63. package/dist/documents/conversions.js.map +1 -0
  64. package/dist/documents/index.d.ts +4 -0
  65. package/dist/documents/index.d.ts.map +1 -0
  66. package/dist/documents/index.js +4 -0
  67. package/dist/documents/index.js.map +1 -0
  68. package/dist/documents/passthrough.d.ts +13 -0
  69. package/dist/documents/passthrough.d.ts.map +1 -0
  70. package/dist/documents/passthrough.js +101 -0
  71. package/dist/documents/passthrough.js.map +1 -0
  72. package/dist/documents/read.d.ts +24 -0
  73. package/dist/documents/read.d.ts.map +1 -0
  74. package/dist/documents/read.js +81 -0
  75. package/dist/documents/read.js.map +1 -0
  76. package/dist/events/agent-events.d.ts +235 -0
  77. package/dist/events/agent-events.d.ts.map +1 -1
  78. package/dist/events/agent-events.js +3 -0
  79. package/dist/events/agent-events.js.map +1 -1
  80. package/dist/events/child-run.d.ts +9 -0
  81. package/dist/events/child-run.d.ts.map +1 -0
  82. package/dist/events/child-run.js +41 -0
  83. package/dist/events/child-run.js.map +1 -0
  84. package/dist/events/errands.d.ts +5 -0
  85. package/dist/events/errands.d.ts.map +1 -0
  86. package/dist/events/errands.js +19 -0
  87. package/dist/events/errands.js.map +1 -0
  88. package/dist/events/land-breakage.d.ts +3 -0
  89. package/dist/events/land-breakage.d.ts.map +1 -1
  90. package/dist/events/land-breakage.js +3 -0
  91. package/dist/events/land-breakage.js.map +1 -1
  92. package/dist/events/land-conflict.d.ts +3 -0
  93. package/dist/events/land-conflict.d.ts.map +1 -0
  94. package/dist/events/land-conflict.js +4 -0
  95. package/dist/events/land-conflict.js.map +1 -0
  96. package/dist/events/requests.d.ts +152 -0
  97. package/dist/events/requests.d.ts.map +1 -1
  98. package/dist/events/requests.js +26 -1
  99. package/dist/events/requests.js.map +1 -1
  100. package/dist/events/system-events.d.ts +74 -12
  101. package/dist/events/system-events.d.ts.map +1 -1
  102. package/dist/events/system-events.js +3 -1
  103. package/dist/events/system-events.js.map +1 -1
  104. package/dist/events/transcript.d.ts +387 -0
  105. package/dist/events/transcript.d.ts.map +1 -1
  106. package/dist/events/transcript.js +3 -0
  107. package/dist/events/transcript.js.map +1 -1
  108. package/dist/events/verify-nudge.d.ts.map +1 -1
  109. package/dist/events/verify-nudge.js.map +1 -1
  110. package/dist/front/browser-wire.d.ts +6 -0
  111. package/dist/front/browser-wire.d.ts.map +1 -0
  112. package/dist/front/browser-wire.js +4 -0
  113. package/dist/front/browser-wire.js.map +1 -0
  114. package/dist/front/front-wire.d.ts +6 -0
  115. package/dist/front/front-wire.d.ts.map +1 -0
  116. package/dist/front/front-wire.js +5 -0
  117. package/dist/front/front-wire.js.map +1 -0
  118. package/dist/front/generated/browser-wire.d.ts +19 -0
  119. package/dist/front/generated/browser-wire.d.ts.map +1 -0
  120. package/dist/front/generated/browser-wire.js +2 -0
  121. package/dist/front/generated/browser-wire.js.map +1 -0
  122. package/dist/front/generated/wire.d.ts +70 -1
  123. package/dist/front/generated/wire.d.ts.map +1 -1
  124. package/dist/ids/conversation-ids.d.ts +3 -0
  125. package/dist/ids/conversation-ids.d.ts.map +1 -1
  126. package/dist/ids/conversation-ids.js +4 -2
  127. package/dist/ids/conversation-ids.js.map +1 -1
  128. package/dist/ids/session-names.d.ts +3 -0
  129. package/dist/ids/session-names.d.ts.map +1 -1
  130. package/dist/ids/session-names.js +3 -0
  131. package/dist/ids/session-names.js.map +1 -1
  132. package/dist/index.d.ts +2052 -190
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +15 -1
  135. package/dist/index.js.map +1 -1
  136. package/dist/models/agent-catalog.d.ts.map +1 -1
  137. package/dist/models/agent-catalog.js +4 -6
  138. package/dist/models/agent-catalog.js.map +1 -1
  139. package/dist/models/agent-runtimes.d.ts +2 -1
  140. package/dist/models/agent-runtimes.d.ts.map +1 -1
  141. package/dist/models/agent-runtimes.js +7 -1
  142. package/dist/models/agent-runtimes.js.map +1 -1
  143. package/dist/models/plan-pools.d.ts +22 -1
  144. package/dist/models/plan-pools.d.ts.map +1 -1
  145. package/dist/models/plan-pools.js +86 -0
  146. package/dist/models/plan-pools.js.map +1 -1
  147. package/dist/policy/request-status.d.ts +1 -1
  148. package/dist/policy/request-status.d.ts.map +1 -1
  149. package/dist/policy/request-status.js +4 -11
  150. package/dist/policy/request-status.js.map +1 -1
  151. package/dist/policy/reserved-servers.d.ts.map +1 -1
  152. package/dist/policy/reserved-servers.js +2 -1
  153. package/dist/policy/reserved-servers.js.map +1 -1
  154. package/dist/policy/turned-away.d.ts.map +1 -1
  155. package/dist/policy/turned-away.js +1 -0
  156. package/dist/policy/turned-away.js.map +1 -1
  157. package/dist/protocol/container-requirements.d.ts +0 -1
  158. package/dist/protocol/container-requirements.d.ts.map +1 -1
  159. package/dist/protocol/container-requirements.js +1 -2
  160. package/dist/protocol/container-requirements.js.map +1 -1
  161. package/dist/protocol/edge-verdict.d.ts +2 -1
  162. package/dist/protocol/edge-verdict.d.ts.map +1 -1
  163. package/dist/protocol/edge-verdict.js +1 -1
  164. package/dist/protocol/edge-verdict.js.map +1 -1
  165. package/dist/protocol/ingress-contract.d.ts +1 -12
  166. package/dist/protocol/ingress-contract.d.ts.map +1 -1
  167. package/dist/protocol/ingress-contract.js +1 -1
  168. package/dist/protocol/ingress-contract.js.map +1 -1
  169. package/dist/protocol/raw-routes.d.ts +36 -26
  170. package/dist/protocol/raw-routes.d.ts.map +1 -1
  171. package/dist/protocol/raw-routes.js +17 -23
  172. package/dist/protocol/raw-routes.js.map +1 -1
  173. package/dist/protocol/route-meta.d.ts +22 -0
  174. package/dist/protocol/route-meta.d.ts.map +1 -1
  175. package/dist/protocol/route-meta.js +16 -0
  176. package/dist/protocol/route-meta.js.map +1 -1
  177. package/dist/protocol/runner-protocol.d.ts +34 -0
  178. package/dist/protocol/runner-protocol.d.ts.map +1 -1
  179. package/dist/protocol/runner-protocol.js +33 -0
  180. package/dist/protocol/runner-protocol.js.map +1 -1
  181. package/dist/protocol/tunnel-bulk.d.ts +2 -0
  182. package/dist/protocol/tunnel-bulk.d.ts.map +1 -0
  183. package/dist/protocol/tunnel-bulk.js +3 -0
  184. package/dist/protocol/tunnel-bulk.js.map +1 -0
  185. package/dist/protocol/x402.d.ts +17 -0
  186. package/dist/protocol/x402.d.ts.map +1 -0
  187. package/dist/protocol/x402.js +37 -0
  188. package/dist/protocol/x402.js.map +1 -0
  189. package/dist/schemas/activity.d.ts.map +1 -1
  190. package/dist/schemas/activity.js.map +1 -1
  191. package/dist/schemas/agent.d.ts +25 -0
  192. package/dist/schemas/agent.d.ts.map +1 -1
  193. package/dist/schemas/agent.js +14 -2
  194. package/dist/schemas/agent.js.map +1 -1
  195. package/dist/schemas/agents.d.ts +90 -18
  196. package/dist/schemas/agents.d.ts.map +1 -1
  197. package/dist/schemas/agents.js +49 -5
  198. package/dist/schemas/agents.js.map +1 -1
  199. package/dist/schemas/automations.d.ts +23 -6
  200. package/dist/schemas/automations.d.ts.map +1 -1
  201. package/dist/schemas/automations.js.map +1 -1
  202. package/dist/schemas/devices.d.ts +134 -7
  203. package/dist/schemas/devices.d.ts.map +1 -1
  204. package/dist/schemas/devices.js +43 -18
  205. package/dist/schemas/devices.js.map +1 -1
  206. package/dist/schemas/extension-updates.d.ts +26 -0
  207. package/dist/schemas/extension-updates.d.ts.map +1 -1
  208. package/dist/schemas/extension-updates.js +4 -0
  209. package/dist/schemas/extension-updates.js.map +1 -1
  210. package/dist/schemas/git/git.d.ts +19 -0
  211. package/dist/schemas/git/git.d.ts.map +1 -1
  212. package/dist/schemas/git/git.js +1 -0
  213. package/dist/schemas/git/git.js.map +1 -1
  214. package/dist/schemas/hosts.d.ts +35 -3
  215. package/dist/schemas/hosts.d.ts.map +1 -1
  216. package/dist/schemas/hosts.js +22 -6
  217. package/dist/schemas/hosts.js.map +1 -1
  218. package/dist/schemas/keep-warm.d.ts +2 -12
  219. package/dist/schemas/keep-warm.d.ts.map +1 -1
  220. package/dist/schemas/keep-warm.js +8 -10
  221. package/dist/schemas/keep-warm.js.map +1 -1
  222. package/dist/schemas/metrics.d.ts +29 -0
  223. package/dist/schemas/metrics.d.ts.map +1 -1
  224. package/dist/schemas/metrics.js +19 -3
  225. package/dist/schemas/metrics.js.map +1 -1
  226. package/dist/schemas/offload.d.ts +62 -0
  227. package/dist/schemas/offload.d.ts.map +1 -0
  228. package/dist/schemas/offload.js +23 -0
  229. package/dist/schemas/offload.js.map +1 -0
  230. package/dist/schemas/personas.d.ts +3 -0
  231. package/dist/schemas/personas.d.ts.map +1 -1
  232. package/dist/schemas/personas.js +12 -3
  233. package/dist/schemas/personas.js.map +1 -1
  234. package/dist/schemas/ports.d.ts +10 -0
  235. package/dist/schemas/ports.d.ts.map +1 -1
  236. package/dist/schemas/ports.js +8 -0
  237. package/dist/schemas/ports.js.map +1 -1
  238. package/dist/schemas/providers/plan-limits.d.ts +169 -0
  239. package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
  240. package/dist/schemas/providers/plan-limits.js +54 -1
  241. package/dist/schemas/providers/plan-limits.js.map +1 -1
  242. package/dist/schemas/providers/provider-oauth.d.ts +69 -0
  243. package/dist/schemas/providers/provider-oauth.d.ts.map +1 -1
  244. package/dist/schemas/providers/provider-oauth.js +6 -1
  245. package/dist/schemas/providers/provider-oauth.js.map +1 -1
  246. package/dist/schemas/settings-history.d.ts +55 -0
  247. package/dist/schemas/settings-history.d.ts.map +1 -0
  248. package/dist/schemas/settings-history.js +73 -0
  249. package/dist/schemas/settings-history.js.map +1 -0
  250. package/dist/schemas/settings.d.ts +188 -4
  251. package/dist/schemas/settings.d.ts.map +1 -1
  252. package/dist/schemas/settings.js +41 -26
  253. package/dist/schemas/settings.js.map +1 -1
  254. package/dist/schemas/speaker.d.ts +36 -0
  255. package/dist/schemas/speaker.d.ts.map +1 -0
  256. package/dist/schemas/speaker.js +62 -0
  257. package/dist/schemas/speaker.js.map +1 -0
  258. package/dist/schemas/state-plan.d.ts +46 -0
  259. package/dist/schemas/state-plan.d.ts.map +1 -0
  260. package/dist/schemas/state-plan.js +31 -0
  261. package/dist/schemas/state-plan.js.map +1 -0
  262. package/dist/schemas/system.d.ts +64 -0
  263. package/dist/schemas/system.d.ts.map +1 -1
  264. package/dist/schemas/system.js +12 -1
  265. package/dist/schemas/system.js.map +1 -1
  266. package/dist/schemas/workspace/mainline.d.ts +513 -0
  267. package/dist/schemas/workspace/mainline.d.ts.map +1 -0
  268. package/dist/schemas/workspace/mainline.js +182 -0
  269. package/dist/schemas/workspace/mainline.js.map +1 -0
  270. package/dist/schemas/workspace/workspace-tree.d.ts +23 -0
  271. package/dist/schemas/workspace/workspace-tree.d.ts.map +1 -1
  272. package/dist/schemas/workspace/workspace-tree.js +34 -0
  273. package/dist/schemas/workspace/workspace-tree.js.map +1 -1
  274. package/dist/state/contract-lock.d.ts +1 -0
  275. package/dist/state/contract-lock.d.ts.map +1 -1
  276. package/dist/state/contract-lock.js +47 -1
  277. package/dist/state/contract-lock.js.map +1 -1
  278. package/dist/state/definition.d.ts +44 -20
  279. package/dist/state/definition.d.ts.map +1 -1
  280. package/dist/state/definition.js.map +1 -1
  281. package/dist/state/fix-stance.d.ts +1 -1
  282. package/dist/state/fix-stance.d.ts.map +1 -1
  283. package/dist/state/fix-stance.js +2 -1
  284. package/dist/state/fix-stance.js.map +1 -1
  285. package/dist/state/history-state.d.ts.map +1 -1
  286. package/dist/state/history-state.js +7 -0
  287. package/dist/state/history-state.js.map +1 -1
  288. package/dist/state/landed-commit.d.ts +1 -0
  289. package/dist/state/landed-commit.d.ts.map +1 -1
  290. package/dist/state/landed-commit.js +2 -0
  291. package/dist/state/landed-commit.js.map +1 -1
  292. package/dist/state/red-streak.d.ts +7 -0
  293. package/dist/state/red-streak.d.ts.map +1 -0
  294. package/dist/state/red-streak.js +11 -0
  295. package/dist/state/red-streak.js.map +1 -0
  296. package/dist/state/runtime-state.d.ts +3 -0
  297. package/dist/state/runtime-state.d.ts.map +1 -1
  298. package/dist/state/runtime-state.js +1 -0
  299. package/dist/state/runtime-state.js.map +1 -1
  300. package/dist/state/workspace-state.d.ts +23 -1
  301. package/dist/state/workspace-state.d.ts.map +1 -1
  302. package/dist/state/workspace-state.js +33 -3
  303. package/dist/state/workspace-state.js.map +1 -1
  304. package/dist/text/shell-regions.d.ts +1 -0
  305. package/dist/text/shell-regions.d.ts.map +1 -1
  306. package/dist/text/shell-regions.js +1 -1
  307. package/dist/text/shell-regions.js.map +1 -1
  308. package/dist/text/transcript-fold.d.ts +1 -0
  309. package/dist/text/transcript-fold.d.ts.map +1 -1
  310. package/dist/text/transcript-fold.js +24 -8
  311. package/dist/text/transcript-fold.js.map +1 -1
  312. package/package.json +42 -42
  313. package/src/chores/chores.ts +6 -6
  314. package/src/chores/index.ts +0 -1
  315. package/src/chores/prompt.ts +3 -2
  316. package/src/contracts/agent.contract.ts +14 -0
  317. package/src/contracts/agents.contract.ts +36 -1
  318. package/src/contracts/capabilities.contract.ts +2 -2
  319. package/src/contracts/device.contract.ts +5 -3
  320. package/src/contracts/offload.contract.ts +60 -0
  321. package/src/contracts/runner.contract.ts +7 -1
  322. package/src/contracts/secrets.contract.ts +2 -0
  323. package/src/contracts/settings.contract.ts +2 -1
  324. package/src/contracts/workspace.contract.ts +54 -2
  325. package/src/documents/conversions.ts +402 -0
  326. package/src/documents/index.ts +7 -0
  327. package/src/documents/passthrough.ts +139 -0
  328. package/src/documents/read.ts +114 -0
  329. package/src/events/agent-events.ts +5 -0
  330. package/src/events/child-run.test.ts +81 -0
  331. package/src/events/child-run.ts +73 -0
  332. package/src/events/errands.test.ts +22 -0
  333. package/src/events/errands.ts +27 -0
  334. package/src/events/land-breakage.ts +12 -0
  335. package/src/events/land-conflict.ts +12 -0
  336. package/src/events/requests.ts +40 -1
  337. package/src/events/system-events.ts +9 -3
  338. package/src/events/transcript.ts +8 -0
  339. package/src/events/verify-nudge.ts +4 -3
  340. package/src/front/browser-wire.ts +20 -0
  341. package/src/front/front-wire.ts +15 -0
  342. package/src/front/generated/browser-wire.json +138 -0
  343. package/src/front/generated/browser-wire.ts +16 -0
  344. package/src/front/generated/front-wire.json +793 -0
  345. package/src/front/generated/tunnel.json +38 -0
  346. package/src/front/generated/wire.ts +37 -9
  347. package/src/front/wire-manifests.test.ts +61 -0
  348. package/src/ids/conversation-ids.ts +13 -5
  349. package/src/ids/session-names.ts +7 -0
  350. package/src/index.ts +15 -2
  351. package/src/models/agent-catalog.test.ts +6 -4
  352. package/src/models/agent-catalog.ts +4 -6
  353. package/src/models/agent-runtimes.ts +22 -7
  354. package/src/models/capability-ledger.test.ts +2 -0
  355. package/src/models/plan-pools.test.ts +121 -2
  356. package/src/models/plan-pools.ts +152 -2
  357. package/src/policy/request-status.ts +4 -12
  358. package/src/policy/reserved-servers.test.ts +6 -0
  359. package/src/policy/reserved-servers.ts +13 -10
  360. package/src/policy/turned-away.ts +3 -0
  361. package/src/protocol/container-requirements.test.ts +2 -3
  362. package/src/protocol/container-requirements.ts +1 -7
  363. package/src/protocol/edge-verdict.ts +13 -11
  364. package/src/protocol/ingress-contract.fixture.json +90 -0
  365. package/src/protocol/ingress-contract.test.ts +18 -26
  366. package/src/protocol/ingress-contract.ts +10 -25
  367. package/src/protocol/raw-routes.ts +22 -26
  368. package/src/protocol/route-meta.ts +39 -0
  369. package/src/protocol/runner-protocol.ts +53 -0
  370. package/src/protocol/tunnel-bulk.test.ts +37 -0
  371. package/src/protocol/tunnel-bulk.ts +7 -0
  372. package/src/protocol/x402.test.ts +29 -0
  373. package/src/protocol/x402.ts +61 -0
  374. package/src/schemas/activity.ts +3 -1
  375. package/src/schemas/agent.ts +28 -3
  376. package/src/schemas/agents.ts +83 -8
  377. package/src/schemas/automations.ts +4 -2
  378. package/src/schemas/devices.ts +106 -39
  379. package/src/schemas/extension-updates.ts +6 -0
  380. package/src/schemas/git/git.ts +5 -0
  381. package/src/schemas/hosts.ts +64 -13
  382. package/src/schemas/ic-shape-args.test.ts +64 -0
  383. package/src/schemas/keep-warm.test.ts +6 -13
  384. package/src/schemas/keep-warm.ts +15 -20
  385. package/src/schemas/metrics.ts +28 -3
  386. package/src/schemas/offload.ts +44 -0
  387. package/src/schemas/personas.ts +18 -3
  388. package/src/schemas/ports.ts +10 -0
  389. package/src/schemas/providers/plan-limits.ts +84 -1
  390. package/src/schemas/providers/provider-oauth.ts +10 -1
  391. package/src/schemas/settings-history.ts +108 -0
  392. package/src/schemas/settings.test.ts +54 -1
  393. package/src/schemas/settings.ts +88 -49
  394. package/src/schemas/speaker.ts +89 -0
  395. package/src/schemas/state-plan.test.ts +69 -0
  396. package/src/schemas/state-plan.ts +47 -0
  397. package/src/schemas/system.ts +24 -3
  398. package/src/schemas/workspace/mainline.test.ts +28 -0
  399. package/src/schemas/workspace/mainline.ts +268 -0
  400. package/src/schemas/workspace/workspace-tree.ts +47 -0
  401. package/src/state/contract-lock.test.ts +65 -4
  402. package/src/state/contract-lock.ts +70 -2
  403. package/src/state/definition.ts +3 -2
  404. package/src/state/fix-stance.test.ts +8 -0
  405. package/src/state/fix-stance.ts +3 -3
  406. package/src/state/history-state.ts +19 -0
  407. package/src/state/landed-commit.test.ts +12 -1
  408. package/src/state/landed-commit.ts +5 -0
  409. package/src/state/red-streak.test.ts +28 -0
  410. package/src/state/red-streak.ts +28 -0
  411. package/src/state/runtime-state.ts +4 -0
  412. package/src/state/workspace-state.test.ts +7 -1
  413. package/src/state/workspace-state.ts +45 -3
  414. package/src/text/shell-regions.test.ts +38 -0
  415. package/src/text/shell-regions.ts +3 -3
  416. package/src/text/transcript-fold.test.ts +46 -0
  417. package/src/text/transcript-fold.ts +31 -9
  418. package/dist/chores/fix-deps.d.ts +0 -10
  419. package/dist/chores/fix-deps.d.ts.map +0 -1
  420. package/dist/chores/fix-deps.js +0 -18
  421. package/dist/chores/fix-deps.js.map +0 -1
  422. package/dist/protocol/ingress-protocol.d.ts +0 -30
  423. package/dist/protocol/ingress-protocol.d.ts.map +0 -1
  424. package/dist/protocol/ingress-protocol.js +0 -300
  425. package/dist/protocol/ingress-protocol.js.map +0 -1
  426. package/dist/protocol/terminal-protocol.d.ts +0 -18
  427. package/dist/protocol/terminal-protocol.d.ts.map +0 -1
  428. package/dist/protocol/terminal-protocol.js +0 -2
  429. package/dist/protocol/terminal-protocol.js.map +0 -1
  430. package/dist/protocol/tunnel-heartbeat.d.ts +0 -19
  431. package/dist/protocol/tunnel-heartbeat.d.ts.map +0 -1
  432. package/dist/protocol/tunnel-heartbeat.js +0 -41
  433. package/dist/protocol/tunnel-heartbeat.js.map +0 -1
  434. package/dist/protocol/upgrade-relay.d.ts +0 -4
  435. package/dist/protocol/upgrade-relay.d.ts.map +0 -1
  436. package/dist/protocol/upgrade-relay.js +0 -25
  437. package/dist/protocol/upgrade-relay.js.map +0 -1
  438. package/src/chores/fix-deps.ts +0 -22
  439. package/src/protocol/ingress-protocol.test.ts +0 -579
  440. package/src/protocol/ingress-protocol.ts +0 -469
  441. package/src/protocol/terminal-protocol.ts +0 -13
  442. package/src/protocol/tunnel-heartbeat.test.ts +0 -75
  443. package/src/protocol/tunnel-heartbeat.ts +0 -67
  444. package/src/protocol/upgrade-relay.ts +0 -28
@@ -0,0 +1,114 @@
1
+ import type { ManifestProblem } from "../schemas/system.js";
2
+ import { type Conversion, convertDocument, type Granularity } from "./conversions.js";
3
+ import { carryUnknown, type IdKeys, reemitQuarantined } from "./passthrough.js";
4
+
5
+ // The one reading of a stored document, shared by every store that keeps a file across versions: the daemon's
6
+ // jsonFile, jsonEntries and jsonDir, and an extension's sandboxDocument. The bytes as JSON, then the document's
7
+ // conversions, then this build's parse; what it could not read is named by a `reason` a reader matches on, never by its
8
+ // wording; and a change to what it read comes back through `carry`, which keeps what this build's parse dropped.
9
+
10
+ // What a reader needs of a document: the conversions its shape has had, and where they apply.
11
+ export interface DocumentShape {
12
+ readonly history: readonly Conversion[];
13
+ readonly granularity: Granularity;
14
+ }
15
+
16
+ type Report = (problem: ManifestProblem) => void;
17
+
18
+ export type DocumentParse<T> =
19
+ // The whole file as one value, undefined for one this build cannot read; `report` flags a problem within a valid one.
20
+ | { readonly kind: "whole"; readonly parse: (raw: unknown, report: Report) => T | undefined }
21
+ // A top-level array read one entry at a time: an entry this build cannot read, or whose conversion fails, is
22
+ // reported and quarantined (kept as written on the next save), never the file. `idKeys` pair a rebuilt entry with
23
+ // the one it replaces.
24
+ | {
25
+ readonly kind: "entries";
26
+ readonly entry: (raw: unknown, report: Report) => (T extends readonly (infer E)[] ? E : never) | undefined;
27
+ readonly idKeys?: IdKeys;
28
+ };
29
+
30
+ export interface DocumentRead<T> {
31
+ // Undefined when the file as a whole is unreadable; `problems` then leads with why.
32
+ readonly value: T | undefined;
33
+ // The bytes a change to `value` writes: the change, plus what the file held that this build does not know.
34
+ readonly carry: (updated: T) => unknown;
35
+ readonly problems: readonly ManifestProblem[];
36
+ }
37
+
38
+ const message = (error: unknown): string => (error instanceof Error ? error.message : String(error));
39
+
40
+ const unreadable = <T>(reason: NonNullable<ManifestProblem["reason"]>, detail: string): DocumentRead<T> => ({
41
+ value: undefined,
42
+ carry: (updated) => updated,
43
+ problems: [{ kind: "unreadable", reason, detail }],
44
+ });
45
+
46
+ // `checkSettles` is the daemon's development-build check (conversions.ts), off for an extension.
47
+ export const readDocument = <T>(text: string, shape: DocumentShape, how: DocumentParse<T>, checkSettles = false): DocumentRead<T> => {
48
+ let raw: unknown;
49
+ try {
50
+ raw = JSON.parse(text);
51
+ } catch {
52
+ return unreadable("not-json", "the file is not valid JSON");
53
+ }
54
+ const problems: ManifestProblem[] = [];
55
+ const report: Report = (problem) => problems.push(problem);
56
+ if (how.kind === "entries") {
57
+ if (!Array.isArray(raw)) {
58
+ return unreadable("rejected", "the file does not match what this build expects");
59
+ }
60
+ const perEntry = shape.granularity === "entries";
61
+ const entries: unknown[] = [];
62
+ const aligned: unknown[] = [];
63
+ const quarantined: { index: number; entry: unknown }[] = [];
64
+ let whole: readonly unknown[] = raw;
65
+ if (!perEntry && shape.history.length > 0) {
66
+ try {
67
+ const converted = convertDocument(shape.history, shape.granularity, raw, checkSettles).value;
68
+ whole = Array.isArray(converted) ? converted : [];
69
+ } catch (error) {
70
+ return unreadable("conversion-failed", `a conversion to this build's shape failed (${message(error)})`);
71
+ }
72
+ }
73
+ whole.forEach((written, index) => {
74
+ let candidates: readonly unknown[];
75
+ try {
76
+ const value = perEntry ? convertDocument(shape.history, "entries", [written], checkSettles).value : [written];
77
+ candidates = Array.isArray(value) ? value : [value];
78
+ } catch (error) {
79
+ quarantined.push({ index, entry: written });
80
+ report({
81
+ kind: "invalidEntry",
82
+ reason: "conversion-failed",
83
+ detail: `entry ${index} could not be converted to this build's shape (${message(error)}); it is kept as written`,
84
+ });
85
+ return;
86
+ }
87
+ for (const candidate of candidates) {
88
+ const parsed = how.entry(candidate, report);
89
+ if (parsed === undefined) {
90
+ quarantined.push({ index, entry: candidate });
91
+ report({ kind: "invalidEntry", reason: "rejected", detail: `entry ${index} is not one this build can read; it is kept as written` });
92
+ continue;
93
+ }
94
+ entries.push(parsed);
95
+ aligned.push(candidate);
96
+ }
97
+ });
98
+ return {
99
+ value: entries as T,
100
+ carry: (updated) => reemitQuarantined(carryUnknown(aligned, entries, updated, how.idKeys) as readonly unknown[], quarantined, how.idKeys),
101
+ problems,
102
+ };
103
+ }
104
+ try {
105
+ raw = convertDocument(shape.history, shape.granularity, raw, checkSettles).value;
106
+ } catch (error) {
107
+ return unreadable("conversion-failed", `a conversion to this build's shape failed (${message(error)})`);
108
+ }
109
+ const value = how.parse(raw, report);
110
+ if (value === undefined) {
111
+ return unreadable("rejected", "the file does not match what this build expects");
112
+ }
113
+ return { value, carry: (updated) => carryUnknown(raw, value, updated), problems };
114
+ };
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { PermissionModeSchema } from "../schemas/agent.js";
3
+ import { TurnErrandSchema } from "../schemas/speaker.js";
3
4
  import { LandConflictSchema } from "../schemas/agents.js";
4
5
  import { ContextTrimSchema } from "../schemas/context-trim.js";
5
6
  import { RateLimitInfoSchema } from "../schemas/providers/claude-gate.js";
@@ -65,6 +66,8 @@ export const AgentEventSchema = z.discriminatedUnion("kind", [
65
66
  sentAt: z.number(),
66
67
  attachments: z.array(z.string()).optional(),
67
68
  voice: z.enum(["sandbox", "agent"]).optional(),
69
+ // What a composed message is for, stamped on the row it becomes (TranscriptRow.errand).
70
+ errand: TurnErrandSchema.optional(),
68
71
  // The message's own id, stamped on the row it becomes (TranscriptRow.messageId).
69
72
  messageId: z.string().optional(),
70
73
  }),
@@ -271,6 +274,8 @@ export const AgentEventSchema = z.discriminatedUnion("kind", [
271
274
  .optional(),
272
275
  // rate_limit only: epoch seconds when the exhausted window reopens; absent when the reset instant is unknown.
273
276
  resetsAt: z.number().optional(),
277
+ // The daemon's word, never the window's guess: which account a reconnect badge or a spent pool belongs to.
278
+ account: z.string().optional().describe("Which of the provider's accounts served (or was refused for) the turn, where the sandbox holds it."),
274
279
  // Gated codes only: "scheduled" if this conversation arms the resume, "available" if one exists but isn't.
275
280
  autoResume: z.enum(["scheduled", "available"]).optional(),
276
281
  // "scheduled" only: epoch seconds the booked send actually fires. Distinct from `resetsAt` (the provider's fact
@@ -0,0 +1,81 @@
1
+ import type { ChildAgentAsk } from "./requests.js";
2
+ import type { TranscriptPermission } from "./transcript.js";
3
+ import { childRunOf, repointedChild, sameChildRun } from "./child-run.js";
4
+ import { settledRequests } from "../policy/request-status.js";
5
+
6
+ // A child's run is replaced whole when the owner re-points it on the card: an effort or an account chosen for one model
7
+ // means nothing on another, so nothing of the agent's own pick may leak into the owner's.
8
+
9
+ const asked: ChildAgentAsk = {
10
+ move: "spawn",
11
+ task: "Port the parser to zig",
12
+ provider: "claude",
13
+ model: "claude-opus-4-6",
14
+ effort: "max",
15
+ account: "work",
16
+ on: "rog",
17
+ };
18
+
19
+ describe("sameChildRun", () => {
20
+ test("the provider's own loop is the same run whether it is named or left out", () => {
21
+ expect(sameChildRun({ provider: "claude", model: "m" }, { provider: "claude", model: "m", harness: "native" })).toBe(true);
22
+ expect(sameChildRun({ provider: "claude", model: "m" }, { provider: "claude", model: "m", harness: "claude-code" })).toBe(false);
23
+ });
24
+
25
+ test("standard speed is the same run whether it is named or left out", () => {
26
+ expect(sameChildRun({ provider: "claude", model: "m" }, { provider: "claude", model: "m", fast: false })).toBe(true);
27
+ });
28
+
29
+ test("naming an effort is a different run from leaving it to the model", () => {
30
+ expect(sameChildRun({ provider: "claude", model: "m" }, { provider: "claude", model: "m", effort: "high" })).toBe(false);
31
+ });
32
+ });
33
+
34
+ describe("repointedChild", () => {
35
+ test("replaces the run whole and keeps what the agent asked for", () => {
36
+ const started = repointedChild(asked, { provider: "codex", model: "gpt-5.5" });
37
+ expect(started).toEqual({
38
+ move: "spawn",
39
+ task: "Port the parser to zig",
40
+ on: "rog",
41
+ provider: "codex",
42
+ model: "gpt-5.5",
43
+ proposed: { provider: "claude", model: "claude-opus-4-6", effort: "max", account: "work" },
44
+ });
45
+ });
46
+
47
+ test("leaves the request alone when the owner kept the agent's pick", () => {
48
+ expect(repointedChild(asked, childRunOf(asked))).toBe(asked);
49
+ });
50
+ });
51
+
52
+ describe("a settled child-agent request", () => {
53
+ const card: TranscriptPermission = { requestId: "r1", toolName: "agents.spawn", status: "pending", child: asked };
54
+
55
+ test("reads what actually started when the owner re-pointed it", () => {
56
+ const settled = settledRequests(
57
+ { permission: card },
58
+ { kind: "permission", requestId: "r1", decision: "once", child: { provider: "claude", model: "claude-sonnet-4-6" } },
59
+ );
60
+ expect(settled.permission?.status).toBe("allowed");
61
+ expect(settled.permission?.child).toMatchObject({ model: "claude-sonnet-4-6", proposed: { model: "claude-opus-4-6" } });
62
+ expect(settled.permission?.child).not.toHaveProperty("effort");
63
+ });
64
+
65
+ test("a no starts nothing, so it keeps what was asked", () => {
66
+ const settled = settledRequests(
67
+ { permission: card },
68
+ { kind: "permission", requestId: "r1", decision: "deny", child: { provider: "claude", model: "claude-sonnet-4-6" } },
69
+ );
70
+ expect(settled.permission?.child).toEqual(asked);
71
+ });
72
+
73
+ test("only a start can be re-pointed: a message to a child already running keeps its run", () => {
74
+ const sent: TranscriptPermission = { ...card, child: { ...asked, move: "send", child: "sub-1" } };
75
+ const settled = settledRequests(
76
+ { permission: sent },
77
+ { kind: "permission", requestId: "r1", decision: "once", child: { provider: "codex", model: "gpt-5.5" } },
78
+ );
79
+ expect(settled.permission?.child?.model).toBe("claude-opus-4-6");
80
+ });
81
+ });
@@ -0,0 +1,73 @@
1
+ import type { ChildAgentAsk, ChildRun } from "./requests.js";
2
+ import type { AgentReply } from "../schemas/providers/plan-limits.js";
3
+
4
+ // How a child agent's run is compared and replaced, stated once: the card deciding whether the owner changed anything,
5
+ // the settle rule recording what started, and the daemon starting it all replace the same fields in the same way.
6
+
7
+ /** A child's run alone, off anything that carries one; absent fields stay absent rather than arriving as undefined. */
8
+ export const childRunOf = (from: ChildRun): ChildRun => {
9
+ const run: ChildRun = { provider: from.provider, model: from.model };
10
+ if (from.harness !== undefined) {
11
+ run.harness = from.harness;
12
+ }
13
+ if (from.account !== undefined) {
14
+ run.account = from.account;
15
+ }
16
+ if (from.effort !== undefined) {
17
+ run.effort = from.effort;
18
+ }
19
+ if (from.thinking !== undefined) {
20
+ run.thinking = from.thinking;
21
+ }
22
+ if (from.fast !== undefined) {
23
+ run.fast = from.fast;
24
+ }
25
+ return run;
26
+ };
27
+
28
+ /**
29
+ * Whether two runs would start the same child. An absent harness is the provider's own loop, as a named `native` is,
30
+ * and an absent speed is the standard one. An absent effort or thinking setting is the model's own default, which is
31
+ * not the same as naming one.
32
+ */
33
+ export const sameChildRun = (left: ChildRun, right: ChildRun): boolean =>
34
+ left.provider === right.provider &&
35
+ left.model === right.model &&
36
+ (left.harness ?? "native") === (right.harness ?? "native") &&
37
+ left.account === right.account &&
38
+ left.effort === right.effort &&
39
+ left.thinking === right.thinking &&
40
+ (left.fast ?? false) === (right.fast ?? false);
41
+
42
+ /**
43
+ * The request as it reads once the owner started the child on `run`: the run replaced whole, with what the agent asked
44
+ * for kept as `proposed`. The same request, unchanged, when `run` is what the agent asked for anyway.
45
+ */
46
+ export const repointedChild = (ask: ChildAgentAsk, run: ChildRun): ChildAgentAsk => {
47
+ if (sameChildRun(ask, run)) {
48
+ return ask;
49
+ }
50
+ const {
51
+ provider: _provider,
52
+ model: _model,
53
+ harness: _harness,
54
+ account: _account,
55
+ effort: _effort,
56
+ thinking: _thinking,
57
+ fast: _fast,
58
+ ...about
59
+ } = ask;
60
+ return { ...about, ...childRunOf(run), proposed: childRunOf(ask) };
61
+ };
62
+
63
+ /**
64
+ * A permission card as a reply leaves its child: a start the owner allowed on a run of their own reads what actually
65
+ * started, so a settled card never names the model that didn't. Anything else, a no included, keeps the card as asked.
66
+ */
67
+ export const startedChildCard = <P extends { readonly child?: ChildAgentAsk | undefined }>(card: P, reply: AgentReply | undefined): P => {
68
+ const ask = card.child;
69
+ if (ask?.move !== "spawn" || reply?.kind !== "permission" || reply.decision === "deny" || reply.child === undefined) {
70
+ return card;
71
+ }
72
+ return { ...card, child: repointedChild(ask, reply.child) };
73
+ };
@@ -0,0 +1,22 @@
1
+ import { errandOfPrompt, errandOfRow } from "./errands.js";
2
+ import { landBreakagePrompt, landFixPrompt } from "./land-breakage.js";
3
+ import { LAND_CONFLICT_OPENING } from "./land-conflict.js";
4
+ import { verifyNudgePrompt } from "./verify-nudge.js";
5
+
6
+ // A row says what it is for since rows carry `errand`; one written before is still read by its opening.
7
+
8
+ describe(`which errand a message is`, () => {
9
+ test(`is what the row says it is, whatever its words`, () => {
10
+ expect(errandOfRow({ role: `user`, text: `Carry on from where you left off.`, errand: `land-fix-nudge` })).toBe(`land-fix-nudge`);
11
+ });
12
+
13
+ test(`is read by its opening on a row written before rows said, and on nothing but a message`, () => {
14
+ expect(errandOfPrompt(landBreakagePrompt([`- a failure`]))).toBe(`land-breakage`);
15
+ expect(errandOfPrompt(landFixPrompt([`- a failure`]))).toBe(`land-fix`);
16
+ expect(errandOfPrompt(verifyNudgePrompt([`x`]))).toBe(`verify-nudge`);
17
+ expect(errandOfPrompt(`${LAND_CONFLICT_OPENING}\n\nthe files`)).toBe(`land-conflict`);
18
+ expect(errandOfPrompt(`Please fix the parser`)).toBeUndefined();
19
+ expect(errandOfRow({ role: `assistant`, text: landFixPrompt([]) })).toBeUndefined();
20
+ expect(errandOfRow({ role: `user`, text: `hello` })).toBeUndefined();
21
+ });
22
+ });
@@ -0,0 +1,27 @@
1
+ import type { TurnErrand } from "../schemas/speaker.js";
2
+ import type { TranscriptRow } from "./transcript.js";
3
+ import { isLandBreakage, isLandFix } from "./land-breakage.js";
4
+ import { LAND_CONFLICT_OPENING } from "./land-conflict.js";
5
+ import { withoutResumeNote } from "./resume.js";
6
+ import { isVerifyNudge } from "./verify-nudge.js";
7
+
8
+ // Which errand a composed prompt is, read the old way: by its opening paragraph, for the rows and turns written before
9
+ // they carried `errand`. The openings are anchored on here, so each must stay byte-identical forever. A prompt the
10
+ // daemon restarted carries its resume note first, so it is read past.
11
+ export const errandOfPrompt = (prompt: string): TurnErrand | undefined => {
12
+ const text = withoutResumeNote(prompt.trim());
13
+ if (text.startsWith(LAND_CONFLICT_OPENING)) {
14
+ return "land-conflict";
15
+ }
16
+ if (isVerifyNudge(text)) {
17
+ return "verify-nudge";
18
+ }
19
+ if (isLandBreakage(text)) {
20
+ return "land-breakage";
21
+ }
22
+ return isLandFix(text) ? "land-fix" : undefined;
23
+ };
24
+
25
+ /** A message row's errand: what the row says, else what its opening names; none for anything but a message. */
26
+ export const errandOfRow = (row: Pick<TranscriptRow, "role" | "text" | "errand">): TurnErrand | undefined =>
27
+ row.role !== "user" ? undefined : (row.errand ?? errandOfPrompt(row.text));
@@ -9,3 +9,15 @@ export const landBreakagePrompt = (parts: readonly string[]): string => [LAND_BR
9
9
 
10
10
  // Whether a stored prompt is one.
11
11
  export const isLandBreakage = (prompt: string): boolean => prompt.startsWith(LAND_BREAKAGE_OPENING);
12
+
13
+ // The opening of a FRESH conversation the daemon starts on a red main-line check that the conversation that landed the
14
+ // work could not take: nobody could be named, several could, or the one named had gone cold or run out of room.
15
+ // Anchored on by the chat like the follow-up above, so it must stay unique and stable across releases.
16
+ export const LAND_FIX_OPENING =
17
+ "The main tree's own check went red after work landed, and no conversation still holding that work could take it, so this one was started to fix it. The failures, the lands they arrived with and where to read those conversations are below. Fix them in this isolated worktree and check the fix as you would any change; your work lands like any other turn.";
18
+
19
+ // The prompt a fresh fix-up is started with: its opening, then the evidence, each part already worded for the model.
20
+ export const landFixPrompt = (parts: readonly string[]): string => [LAND_FIX_OPENING, ...parts].join("\n\n");
21
+
22
+ // Whether a stored prompt is one.
23
+ export const isLandFix = (prompt: string): boolean => prompt.startsWith(LAND_FIX_OPENING);
@@ -0,0 +1,12 @@
1
+ import { withoutResumeNote } from "./resume.js";
2
+
3
+ // The turn the app sends a conversation whose land refused, asking it to rebase and resolve, recognised by its opening.
4
+ // Composed by the editor, but lives here because the fold must recognise it as well: that turn's own rebase notice
5
+ // would otherwise tell the reader the thing the turn was sent to fix.
6
+
7
+ // Anchored on by the chat and the fold, so it must stay unique and stable across releases.
8
+ export const LAND_CONFLICT_OPENING =
9
+ "Landing your work hit a merge conflict, none of it reached the user's workspace; it is all still on your branch. Rebase onto the main line and resolve the conflicts yourself. In each repo below (`root` is your working directory, any other name that subdirectory of it):";
10
+
11
+ // Whether a stored prompt is one. A turn the daemon re-ran carries the same prompt after its resume note.
12
+ export const isLandConflict = (prompt: string): boolean => withoutResumeNote(prompt.trim()).startsWith(LAND_CONFLICT_OPENING);
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { AgentProviderSchema } from "../schemas/agent.js";
2
+ import { AgentHarnessSchema, AgentProviderSchema } from "../schemas/agent.js";
3
3
  import { CredentialGateKindSchema, CredentialGateScopeSchema, CredentialLaneSchema } from "../schemas/secrets.js";
4
4
 
5
5
  // Requests a turn raises to ask the person something mid-turn; each pauses the turn until `POST /agent/reply` answers it.
@@ -40,6 +40,42 @@ export const ProgramAskSchema = z.object({
40
40
  });
41
41
  export type ProgramAsk = z.infer<typeof ProgramAskSchema>;
42
42
 
43
+ // What a child agent runs on: who serves it and how. The child-agent gate's request shows it, and the owner's allow may
44
+ // carry a replacement (the permission reply's `child`, plan-limits.ts).
45
+ export const ChildRunSchema = z.object({
46
+ provider: AgentProviderSchema.describe("Which provider serves it."),
47
+ model: z.string().min(1).describe("Which of that provider's models."),
48
+ harness: AgentHarnessSchema.optional().describe("Which agentic loop runs it. Absent is the provider's own."),
49
+ account: z
50
+ .string()
51
+ .optional()
52
+ .describe("Which of that provider's connected accounts pays for it. Absent is whichever has the most room when it starts."),
53
+ effort: z.string().optional().describe("How hard it thinks, where the model offers a choice. Absent is the model's own default."),
54
+ thinking: z.boolean().optional().describe("Whether it reasons before it answers, where the model offers the choice."),
55
+ fast: z.boolean().optional().describe("Whether it asks for the faster rate, at the higher price."),
56
+ });
57
+ export type ChildRun = z.infer<typeof ChildRunSchema>;
58
+
59
+ // A move a parent makes on a child agent that the owner's rules may hold for a yes.
60
+ export const ChildMoveSchema = z.enum(["spawn", "send", "answer"]);
61
+ export type ChildMove = z.infer<typeof ChildMoveSchema>;
62
+
63
+ // The child a held request is about, as the daemon's own record of the call has it, never as the agent describes it.
64
+ export const ChildAgentAskSchema = ChildRunSchema.extend({
65
+ move: ChildMoveSchema.describe("What the parent asks to do: start a new child, say something to one it started, or answer one's question."),
66
+ child: z.string().optional().describe("The child's id, for one that already exists."),
67
+ task: z.string().optional().describe("What the child is for, in a line."),
68
+ message: z
69
+ .string()
70
+ .optional()
71
+ .describe("What the parent would say to it: the message it sends, or the answers it gives. Clipped for the request."),
72
+ on: z.string().optional().describe('Which machine it runs on, when one is named: a runner, or "here" for this sandbox.'),
73
+ proposed: ChildRunSchema.optional().describe(
74
+ "What the agent asked to start it on, when the owner started it on something else instead. Present only once the request has settled that way.",
75
+ ),
76
+ });
77
+ export type ChildAgentAsk = z.infer<typeof ChildAgentAskSchema>;
78
+
43
79
  // One per-tool permission prompt (SDK's canUseTool, surfaced as a request); the daemon passes the bridge's own rendered
44
80
  // strings through unchanged. `alwaysLabel` is present only when the SDK offered a rule to persist.
45
81
  export const PermissionAskSchema = z.object({
@@ -62,6 +98,9 @@ export const PermissionAskSchema = z.object({
62
98
  program: ProgramAskSchema.optional().describe(
63
99
  "The program this request is holding, when the request is about one. Present on a command gate's request and absent on every other permission ask.",
64
100
  ),
101
+ child: ChildAgentAskSchema.optional().describe(
102
+ "The child agent this request would start or reach, and what it runs on. Present on the child-agent gate's request and absent on every other permission ask.",
103
+ ),
65
104
  // The judge's own sentence, present only when the title can't say it; never written by the agent being gated.
66
105
  explain: z
67
106
  .string()
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { AgentSummarySchema } from "../schemas/agents.js";
3
3
  import { AccountUsageSchema, ProviderRefusalSchema } from "../schemas/providers/plan-limits.js";
4
4
  import { MemberRoleSchema } from "../schemas/shared.js";
5
- import { SidecarStatusSchema } from "../schemas/workspace/workspace-tree.js";
5
+ import { SidecarStatusSchema, WorkspaceTreeDeltaSchema } from "../schemas/workspace/workspace-tree.js";
6
6
 
7
7
  // Frames about the sandbox rather than a turn: liveness, boot progress, what moved (repos, refs, running processes,
8
8
  // presence, the fleet), and account headroom. One stream carries them all.
@@ -128,13 +128,19 @@ export type AccountUsageChanged = z.infer<typeof AccountUsageChangedSchema>;
128
128
  export const ProviderRefusalChangedSchema = z.object({ kind: z.literal("providerRefusal"), provider: z.string(), refusal: ProviderRefusalSchema.optional() });
129
129
  export type ProviderRefusalChanged = z.infer<typeof ProviderRefusalChangedSchema>;
130
130
 
131
- // The /events stream union: hello, heartbeats, boot progress, workspace/repo/ref/runtime/shadow changes, presence and
132
- // fleet rosters, account headroom and refusal changes. oRPC validates every frame against this.
131
+ // What moved in the shared tree, once the daemon's resident copy re-listed a batch: a tab holding the generation it
132
+ // counts from patches its tree, and one holding any other fetches it afresh.
133
+ export const TreeChangedSchema = WorkspaceTreeDeltaSchema.extend({ kind: z.literal("treeChanged") });
134
+ export type TreeChanged = z.infer<typeof TreeChangedSchema>;
135
+
136
+ // The /events stream union: hello, heartbeats, boot progress, workspace/repo/ref/runtime/shadow/tree changes, presence
137
+ // and fleet rosters, account headroom and refusal changes. oRPC validates every frame against this.
133
138
  export const SystemEventSchema = z.discriminatedUnion("kind", [
134
139
  HelloSchema,
135
140
  HeartbeatSchema,
136
141
  BootSchema,
137
142
  WorkspaceChangedSchema,
143
+ TreeChangedSchema,
138
144
  DerivedChangedSchema,
139
145
  ReposChangedSchema,
140
146
  RefsChangedSchema,
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { AgentHarnessSchema, AgentProviderSchema } from "../schemas/agent.js";
3
3
  import { ShareDetailSchema } from "../schemas/share.js";
4
+ import { TurnErrandSchema, TurnSpeakerSchema } from "../schemas/speaker.js";
4
5
  import { SubagentKindSchema, SubagentStatusSchema, SubagentVerificationSchema } from "../schemas/terminal.js";
5
6
  import { RetryLadderSchema } from "../schemas/turn-break.js";
6
7
  import type { ToolCallContent, ToolCallLocation, ToolCallStatus, ToolKind} from "./requests.js";
@@ -245,6 +246,13 @@ export const TranscriptRowSchema = z.object({
245
246
  .describe(
246
247
  "What the sandbox added to this message before the model saw it. Carried on the message rather than as rows of their own, because they genuinely were part of what was sent.",
247
248
  ),
249
+ // Who spoke a message row, as the sandbox verified it (schemas/speaker.ts), and what a composed one is for: a reader
250
+ // shows the sandbox's own words as the sandbox's, never as the owner's. Absent on rows written before rows said so,
251
+ // which are read by their opening (events/errands.ts).
252
+ speaker: TurnSpeakerSchema.optional().describe("Who sent this message, as the sandbox verified it. Absent where it does not say."),
253
+ errand: TurnErrandSchema.optional().describe(
254
+ "What this message is for, when the sandbox or the app composed it rather than a person typing it. Absent on a person's own words.",
255
+ ),
248
256
  // The user wrote this as the agent, no turn behind it; marked for a human reader, never surfaced to the agent.
249
257
  placed: z
250
258
  .boolean()
@@ -1,6 +1,7 @@
1
- // The follow-up the daemon sends when a turn ended with work it could not confirm: the runtimes with no Stop hook get
2
- // their turn.ending asks this way (verify-nudge.ts), as an ordinary prompt. Its opening lives on the wire because the
3
- // chat has to recognise it coming back: a prompt nobody typed must not reach a reader as their own words.
1
+ // The follow-up the daemon USED to send when a turn ended with work it could not confirm. Nothing sends it any more:
2
+ // checks run after work lands, never inside a conversation (schemas/workspace/mainline.ts). It stays on the wire because
3
+ // records already hold it, and the chat has to go on recognising it: a prompt nobody typed must not reach a reader as
4
+ // their own words.
4
5
 
5
6
  // Anchored on by the reader, so it must stay unique and stable across releases — a reworded opening un-recognises every
6
7
  // nudge already in a record, and they read as the user's own typing again.
@@ -0,0 +1,20 @@
1
+ // Everything a browser sees of a sandbox's front and of the edge in front of it, outside the daemon's oRPC contract. The
2
+ // Rust crates are the definition (`browser-wire`, and `tunnel` for what the edge declares): their types arrive as
3
+ // TypeScript in generated/, and every value here is held to the manifest they write beside it (wire-manifests.test.ts),
4
+ // which contract.lock.json pins.
5
+
6
+ export type { EdgeVerdict, TerminalClientMessage, TerminalServerMessage } from "./generated/browser-wire.js";
7
+
8
+ // Where a terminal socket opens on a sandbox's address. It is a WebSocket whichever way its bytes ride: over TCP, or on a
9
+ // stream of the edge's WebTransport session, where the editor speaks the same protocol itself.
10
+ export const TERMINAL_PATH = "/system/terminal";
11
+
12
+ // Where a browser opens its WebTransport session, on the address of the sandbox the session's streams reach; the edge
13
+ // answers it, never the sandbox.
14
+ export const WEBTRANSPORT_PATH = "/system/transport";
15
+
16
+ // What an edge may declare it serves beyond HTTPS over TCP (the tunnel crate's `Transport`), each only because its own
17
+ // configuration binds it. Undeclared means not served: an editor opens WebTransport only where `webtransport` is named.
18
+ export type EdgeTransport = "quic" | "h3" | "webtransport";
19
+
20
+ export const EDGE_TRANSPORTS: readonly EdgeTransport[] = ["quic", "h3", "webtransport"];
@@ -0,0 +1,15 @@
1
+ // The control socket between intentic-front and the daemon. The Rust crate `front-wire` is the definition: its types
2
+ // arrive as TypeScript in generated/, and every value here is held to the manifest it writes beside it
3
+ // (wire-manifests.test.ts), which contract.lock.json pins.
4
+
5
+ export type * from "./generated/wire.js";
6
+
7
+ // Set by intentic-front on the daemon it spawns: where to dial the control socket, and where to serve HTTP.
8
+ export const FRONT_SOCKET_ENV = "INTENTIC_FRONT_SOCKET";
9
+ export const NODE_SOCKET_ENV = "INTENTIC_NODE_SOCKET";
10
+
11
+ // How long either side waits for the answer to a question it asked before giving up on it.
12
+ export const ASK_PATIENCE_MS = 5000;
13
+
14
+ // A frame is this many bytes of big-endian length, then that many bytes of JSON.
15
+ export const FRAME_LENGTH_BYTES = 4;