@intentic/sandbox-contract 1.248.0 → 1.250.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 (879) hide show
  1. package/README.md +18 -15
  2. package/dist/chores/chores.d.ts.map +1 -1
  3. package/dist/chores/chores.js.map +1 -1
  4. package/dist/chores/digest.d.ts.map +1 -1
  5. package/dist/chores/digest.js.map +1 -1
  6. package/dist/chores/extension-update.d.ts.map +1 -1
  7. package/dist/chores/extension-update.js.map +1 -1
  8. package/dist/chores/fix-deps.d.ts.map +1 -1
  9. package/dist/chores/fix-deps.js.map +1 -1
  10. package/dist/chores/index.d.ts +2 -2
  11. package/dist/chores/index.d.ts.map +1 -1
  12. package/dist/chores/index.js +1 -1
  13. package/dist/chores/index.js.map +1 -1
  14. package/dist/chores/probes.d.ts.map +1 -1
  15. package/dist/chores/probes.js.map +1 -1
  16. package/dist/chores/prompt.d.ts.map +1 -1
  17. package/dist/chores/prompt.js.map +1 -1
  18. package/dist/chores/stack.d.ts.map +1 -1
  19. package/dist/chores/stack.js.map +1 -1
  20. package/dist/chores/verdict.d.ts +7 -1
  21. package/dist/chores/verdict.d.ts.map +1 -1
  22. package/dist/chores/verdict.js +8 -0
  23. package/dist/chores/verdict.js.map +1 -1
  24. package/dist/contracts/accounts.contract.d.ts.map +1 -1
  25. package/dist/contracts/accounts.contract.js.map +1 -1
  26. package/dist/contracts/activity.contract.d.ts +1 -0
  27. package/dist/contracts/activity.contract.d.ts.map +1 -1
  28. package/dist/contracts/agent.contract.d.ts +12 -205
  29. package/dist/contracts/agent.contract.d.ts.map +1 -1
  30. package/dist/contracts/agent.contract.js +2 -1
  31. package/dist/contracts/agent.contract.js.map +1 -1
  32. package/dist/contracts/agents.contract.d.ts +228 -54
  33. package/dist/contracts/agents.contract.d.ts.map +1 -1
  34. package/dist/contracts/agents.contract.js +11 -2
  35. package/dist/contracts/agents.contract.js.map +1 -1
  36. package/dist/contracts/automations.contract.d.ts +35 -17
  37. package/dist/contracts/automations.contract.d.ts.map +1 -1
  38. package/dist/contracts/automations.contract.js +10 -1
  39. package/dist/contracts/automations.contract.js.map +1 -1
  40. package/dist/contracts/capabilities.contract.d.ts +0 -12
  41. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  42. package/dist/contracts/capabilities.contract.js +1 -1
  43. package/dist/contracts/capabilities.contract.js.map +1 -1
  44. package/dist/contracts/chores.contract.d.ts.map +1 -1
  45. package/dist/contracts/chores.contract.js.map +1 -1
  46. package/dist/contracts/ci.contract.d.ts +9 -0
  47. package/dist/contracts/ci.contract.d.ts.map +1 -1
  48. package/dist/contracts/endpoints.contract.d.ts.map +1 -1
  49. package/dist/contracts/endpoints.contract.js.map +1 -1
  50. package/dist/contracts/exit.contract.d.ts.map +1 -1
  51. package/dist/contracts/exit.contract.js +1 -1
  52. package/dist/contracts/exit.contract.js.map +1 -1
  53. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  54. package/dist/contracts/extensions.contract.js.map +1 -1
  55. package/dist/contracts/git.contract.d.ts +45 -6
  56. package/dist/contracts/git.contract.d.ts.map +1 -1
  57. package/dist/contracts/git.contract.js +9 -9
  58. package/dist/contracts/git.contract.js.map +1 -1
  59. package/dist/contracts/host.contract.d.ts +2 -0
  60. package/dist/contracts/host.contract.d.ts.map +1 -1
  61. package/dist/contracts/host.contract.js.map +1 -1
  62. package/dist/contracts/intentic.contract.js +1 -1
  63. package/dist/contracts/intentic.contract.js.map +1 -1
  64. package/dist/contracts/logs.contract.d.ts.map +1 -1
  65. package/dist/contracts/logs.contract.js.map +1 -1
  66. package/dist/contracts/loops.contract.d.ts.map +1 -1
  67. package/dist/contracts/loops.contract.js.map +1 -1
  68. package/dist/contracts/personas.contract.d.ts +1 -0
  69. package/dist/contracts/personas.contract.d.ts.map +1 -1
  70. package/dist/contracts/personas.contract.js +1 -1
  71. package/dist/contracts/personas.contract.js.map +1 -1
  72. package/dist/contracts/providers.contract.d.ts.map +1 -1
  73. package/dist/contracts/providers.contract.js.map +1 -1
  74. package/dist/contracts/runner.contract.d.ts +97 -171
  75. package/dist/contracts/runner.contract.d.ts.map +1 -1
  76. package/dist/contracts/runner.contract.js +2 -2
  77. package/dist/contracts/runner.contract.js.map +1 -1
  78. package/dist/contracts/safety.contract.d.ts.map +1 -1
  79. package/dist/contracts/safety.contract.js +1 -1
  80. package/dist/contracts/safety.contract.js.map +1 -1
  81. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  82. package/dist/contracts/secrets.contract.js.map +1 -1
  83. package/dist/contracts/sessions.contract.d.ts +2 -41
  84. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  85. package/dist/contracts/sessions.contract.js +1 -1
  86. package/dist/contracts/sessions.contract.js.map +1 -1
  87. package/dist/contracts/settings.contract.d.ts +8 -18
  88. package/dist/contracts/settings.contract.d.ts.map +1 -1
  89. package/dist/contracts/settings.contract.js.map +1 -1
  90. package/dist/contracts/share.contract.d.ts.map +1 -1
  91. package/dist/contracts/share.contract.js.map +1 -1
  92. package/dist/contracts/skills.contract.d.ts +6 -0
  93. package/dist/contracts/skills.contract.d.ts.map +1 -1
  94. package/dist/contracts/skills.contract.js +13 -4
  95. package/dist/contracts/skills.contract.js.map +1 -1
  96. package/dist/contracts/system.contract.d.ts +49 -73
  97. package/dist/contracts/system.contract.d.ts.map +1 -1
  98. package/dist/contracts/system.contract.js +12 -2
  99. package/dist/contracts/system.contract.js.map +1 -1
  100. package/dist/contracts/usage.contract.d.ts.map +1 -1
  101. package/dist/contracts/usage.contract.js.map +1 -1
  102. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  103. package/dist/contracts/vpn.contract.js +1 -1
  104. package/dist/contracts/vpn.contract.js.map +1 -1
  105. package/dist/contracts/webext.contract.d.ts.map +1 -1
  106. package/dist/contracts/webext.contract.js.map +1 -1
  107. package/dist/contracts/workflows.contract.d.ts +7 -6
  108. package/dist/contracts/workflows.contract.d.ts.map +1 -1
  109. package/dist/contracts/workflows.contract.js +12 -3
  110. package/dist/contracts/workflows.contract.js.map +1 -1
  111. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  112. package/dist/contracts/workspace.contract.js.map +1 -1
  113. package/dist/events/agent-events.d.ts +1237 -0
  114. package/dist/events/agent-events.d.ts.map +1 -0
  115. package/dist/events/agent-events.js +226 -0
  116. package/dist/events/agent-events.js.map +1 -0
  117. package/dist/events/cards.d.ts +404 -0
  118. package/dist/events/cards.d.ts.map +1 -0
  119. package/dist/events/cards.js +179 -0
  120. package/dist/events/cards.js.map +1 -0
  121. package/dist/events/resume.d.ts +23 -0
  122. package/dist/events/resume.d.ts.map +1 -0
  123. package/dist/events/resume.js +31 -0
  124. package/dist/events/resume.js.map +1 -0
  125. package/dist/events/system-events.d.ts +615 -0
  126. package/dist/events/system-events.d.ts.map +1 -0
  127. package/dist/events/system-events.js +64 -0
  128. package/dist/events/system-events.js.map +1 -0
  129. package/dist/events/transcript.d.ts +1755 -0
  130. package/dist/events/transcript.d.ts.map +1 -0
  131. package/dist/events/transcript.js +205 -0
  132. package/dist/events/transcript.js.map +1 -0
  133. package/dist/ids/conversation-ids.d.ts +8 -0
  134. package/dist/ids/conversation-ids.d.ts.map +1 -0
  135. package/dist/{conversation-ids.js → ids/conversation-ids.js} +13 -0
  136. package/dist/ids/conversation-ids.js.map +1 -0
  137. package/dist/ids/hostnames.d.ts.map +1 -0
  138. package/dist/ids/hostnames.js.map +1 -0
  139. package/dist/ids/session-names.d.ts.map +1 -0
  140. package/dist/ids/session-names.js.map +1 -0
  141. package/dist/ids/share-paths.d.ts.map +1 -0
  142. package/dist/ids/share-paths.js.map +1 -0
  143. package/dist/{tunnel-ids.d.ts → ids/tunnel-ids.d.ts} +1 -0
  144. package/dist/ids/tunnel-ids.d.ts.map +1 -0
  145. package/dist/{tunnel-ids.js → ids/tunnel-ids.js} +1 -0
  146. package/dist/ids/tunnel-ids.js.map +1 -0
  147. package/dist/index.d.ts +429 -450
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +54 -46
  150. package/dist/index.js.map +1 -1
  151. package/dist/{agent-catalog.d.ts → models/agent-catalog.d.ts} +2 -2
  152. package/dist/models/agent-catalog.d.ts.map +1 -0
  153. package/dist/models/agent-catalog.js.map +1 -0
  154. package/dist/models/agent-runtimes.d.ts.map +1 -0
  155. package/dist/models/agent-runtimes.js.map +1 -0
  156. package/dist/{fast-tier.d.ts → models/fast-tier.d.ts} +1 -1
  157. package/dist/models/fast-tier.d.ts.map +1 -0
  158. package/dist/models/fast-tier.js.map +1 -0
  159. package/dist/models/model-order.d.ts.map +1 -0
  160. package/dist/{model-order.js → models/model-order.js} +2 -0
  161. package/dist/models/model-order.js.map +1 -0
  162. package/dist/{model-pins.d.ts → models/model-pins.d.ts} +1 -1
  163. package/dist/models/model-pins.d.ts.map +1 -0
  164. package/dist/models/model-pins.js.map +1 -0
  165. package/dist/{model-roles.d.ts → models/model-roles.d.ts} +0 -33
  166. package/dist/models/model-roles.d.ts.map +1 -0
  167. package/dist/{model-roles.js → models/model-roles.js} +0 -35
  168. package/dist/models/model-roles.js.map +1 -0
  169. package/dist/{plan-pools.d.ts → models/plan-pools.d.ts} +1 -1
  170. package/dist/models/plan-pools.d.ts.map +1 -0
  171. package/dist/models/plan-pools.js.map +1 -0
  172. package/dist/models/prompt-complexity.d.ts.map +1 -0
  173. package/dist/models/prompt-complexity.js.map +1 -0
  174. package/dist/models/provider-specs.d.ts.map +1 -0
  175. package/dist/models/provider-specs.js.map +1 -0
  176. package/dist/policy/approvals-execution.d.ts.map +1 -0
  177. package/dist/policy/approvals-execution.js.map +1 -0
  178. package/dist/{batch-runs.d.ts → policy/batch-runs.d.ts} +5 -1
  179. package/dist/policy/batch-runs.d.ts.map +1 -0
  180. package/dist/{batch-runs.js → policy/batch-runs.js} +10 -7
  181. package/dist/policy/batch-runs.js.map +1 -0
  182. package/dist/policy/capability-env.d.ts.map +1 -0
  183. package/dist/policy/capability-env.js.map +1 -0
  184. package/dist/policy/capability-secrets.d.ts.map +1 -0
  185. package/dist/policy/capability-secrets.js.map +1 -0
  186. package/dist/{card-status.d.ts → policy/card-status.d.ts} +2 -2
  187. package/dist/policy/card-status.d.ts.map +1 -0
  188. package/dist/{card-status.js → policy/card-status.js} +1 -5
  189. package/dist/policy/card-status.js.map +1 -0
  190. package/dist/{command-classes.d.ts → policy/command-classes.d.ts} +6 -2
  191. package/dist/policy/command-classes.d.ts.map +1 -0
  192. package/dist/{command-classes.js → policy/command-classes.js} +48 -11
  193. package/dist/policy/command-classes.js.map +1 -0
  194. package/dist/{command-run.d.ts → policy/command-run.d.ts} +1 -1
  195. package/dist/policy/command-run.d.ts.map +1 -0
  196. package/dist/policy/command-run.js.map +1 -0
  197. package/dist/policy/control-scopes.d.ts +16 -0
  198. package/dist/policy/control-scopes.d.ts.map +1 -0
  199. package/dist/policy/control-scopes.js +26 -0
  200. package/dist/policy/control-scopes.js.map +1 -0
  201. package/dist/policy/credential-material.d.ts.map +1 -0
  202. package/dist/policy/credential-material.js.map +1 -0
  203. package/dist/policy/needs-action.d.ts.map +1 -0
  204. package/dist/policy/needs-action.js.map +1 -0
  205. package/dist/policy/output-fields.d.ts.map +1 -0
  206. package/dist/policy/output-fields.js.map +1 -0
  207. package/dist/policy/overlay-lint.d.ts.map +1 -0
  208. package/dist/policy/overlay-lint.js.map +1 -0
  209. package/dist/policy/owner-ticket.d.ts.map +1 -0
  210. package/dist/{owner-ticket.js → policy/owner-ticket.js} +1 -1
  211. package/dist/policy/owner-ticket.js.map +1 -0
  212. package/dist/{safety-policy.d.ts → policy/safety-policy.d.ts} +6 -5
  213. package/dist/policy/safety-policy.d.ts.map +1 -0
  214. package/dist/{safety-policy.js → policy/safety-policy.js} +12 -12
  215. package/dist/policy/safety-policy.js.map +1 -0
  216. package/dist/policy/search-globs.d.ts.map +1 -0
  217. package/dist/policy/search-globs.js.map +1 -0
  218. package/dist/protocol/container-requirements.d.ts +20 -0
  219. package/dist/protocol/container-requirements.d.ts.map +1 -0
  220. package/dist/protocol/container-requirements.js +23 -0
  221. package/dist/protocol/container-requirements.js.map +1 -0
  222. package/dist/{host-protocol.d.ts → protocol/host-protocol.d.ts} +1 -0
  223. package/dist/protocol/host-protocol.d.ts.map +1 -0
  224. package/dist/{host-protocol.js → protocol/host-protocol.js} +1 -0
  225. package/dist/protocol/host-protocol.js.map +1 -0
  226. package/dist/protocol/ingress-contract.d.ts.map +1 -0
  227. package/dist/{ingress-contract.js → protocol/ingress-contract.js} +1 -1
  228. package/dist/protocol/ingress-contract.js.map +1 -0
  229. package/dist/protocol/ingress-protocol.d.ts.map +1 -0
  230. package/dist/protocol/ingress-protocol.js.map +1 -0
  231. package/dist/protocol/listener-protocol.d.ts.map +1 -0
  232. package/dist/{listener-protocol.js → protocol/listener-protocol.js} +1 -1
  233. package/dist/protocol/listener-protocol.js.map +1 -0
  234. package/dist/{peer-dial.d.ts → protocol/peer-dial.d.ts} +4 -1
  235. package/dist/protocol/peer-dial.d.ts.map +1 -0
  236. package/dist/{peer-dial.js → protocol/peer-dial.js} +51 -10
  237. package/dist/protocol/peer-dial.js.map +1 -0
  238. package/dist/protocol/peer-mcp-server.d.ts.map +1 -0
  239. package/dist/protocol/peer-mcp-server.js.map +1 -0
  240. package/dist/protocol/request-id.d.ts.map +1 -0
  241. package/dist/protocol/request-id.js.map +1 -0
  242. package/dist/protocol/routes.d.ts.map +1 -0
  243. package/dist/protocol/routes.js.map +1 -0
  244. package/dist/{runner-protocol.d.ts → protocol/runner-protocol.d.ts} +1 -0
  245. package/dist/protocol/runner-protocol.d.ts.map +1 -0
  246. package/dist/{runner-protocol.js → protocol/runner-protocol.js} +2 -1
  247. package/dist/protocol/runner-protocol.js.map +1 -0
  248. package/dist/protocol/sse.d.ts.map +1 -0
  249. package/dist/protocol/sse.js.map +1 -0
  250. package/dist/{terminal-protocol.d.ts → protocol/terminal-protocol.d.ts} +1 -3
  251. package/dist/protocol/terminal-protocol.d.ts.map +1 -0
  252. package/dist/protocol/terminal-protocol.js.map +1 -0
  253. package/dist/protocol/webext-links.d.ts.map +1 -0
  254. package/dist/protocol/webext-links.js.map +1 -0
  255. package/dist/{webext-protocol.d.ts → protocol/webext-protocol.d.ts} +1 -0
  256. package/dist/protocol/webext-protocol.d.ts.map +1 -0
  257. package/dist/{webext-protocol.js → protocol/webext-protocol.js} +1 -0
  258. package/dist/protocol/webext-protocol.js.map +1 -0
  259. package/dist/schemas/activity.d.ts +2 -0
  260. package/dist/schemas/activity.d.ts.map +1 -1
  261. package/dist/schemas/activity.js +4 -0
  262. package/dist/schemas/activity.js.map +1 -1
  263. package/dist/schemas/agent.d.ts +16 -4
  264. package/dist/schemas/agent.d.ts.map +1 -1
  265. package/dist/schemas/agent.js +21 -4
  266. package/dist/schemas/agent.js.map +1 -1
  267. package/dist/schemas/agents.d.ts +17 -4
  268. package/dist/schemas/agents.d.ts.map +1 -1
  269. package/dist/schemas/agents.js +15 -4
  270. package/dist/schemas/agents.js.map +1 -1
  271. package/dist/schemas/approvals.d.ts.map +1 -1
  272. package/dist/schemas/approvals.js.map +1 -1
  273. package/dist/schemas/automations.d.ts +54 -28
  274. package/dist/schemas/automations.d.ts.map +1 -1
  275. package/dist/schemas/automations.js +26 -8
  276. package/dist/schemas/automations.js.map +1 -1
  277. package/dist/schemas/capabilities.d.ts +0 -8
  278. package/dist/schemas/capabilities.d.ts.map +1 -1
  279. package/dist/schemas/capabilities.js +0 -4
  280. package/dist/schemas/capabilities.js.map +1 -1
  281. package/dist/schemas/ci.d.ts +10 -0
  282. package/dist/schemas/ci.d.ts.map +1 -1
  283. package/dist/schemas/ci.js +9 -1
  284. package/dist/schemas/ci.js.map +1 -1
  285. package/dist/schemas/codebase-health.d.ts.map +1 -1
  286. package/dist/schemas/codebase-health.js.map +1 -1
  287. package/dist/schemas/devices.d.ts +92 -0
  288. package/dist/schemas/devices.d.ts.map +1 -1
  289. package/dist/schemas/devices.js +12 -1
  290. package/dist/schemas/devices.js.map +1 -1
  291. package/dist/schemas/engines.d.ts.map +1 -1
  292. package/dist/schemas/engines.js.map +1 -1
  293. package/dist/schemas/environment.d.ts.map +1 -1
  294. package/dist/schemas/environment.js.map +1 -1
  295. package/dist/schemas/exit.d.ts.map +1 -1
  296. package/dist/schemas/exit.js.map +1 -1
  297. package/dist/schemas/extension-updates.d.ts.map +1 -1
  298. package/dist/schemas/extension-updates.js.map +1 -1
  299. package/dist/schemas/git-history.d.ts.map +1 -1
  300. package/dist/schemas/git-history.js.map +1 -1
  301. package/dist/schemas/git.d.ts +80 -16
  302. package/dist/schemas/git.d.ts.map +1 -1
  303. package/dist/schemas/git.js +37 -25
  304. package/dist/schemas/git.js.map +1 -1
  305. package/dist/schemas/history.d.ts.map +1 -1
  306. package/dist/schemas/history.js.map +1 -1
  307. package/dist/schemas/hosts.d.ts.map +1 -1
  308. package/dist/schemas/hosts.js.map +1 -1
  309. package/dist/schemas/inventory.d.ts.map +1 -1
  310. package/dist/schemas/inventory.js.map +1 -1
  311. package/dist/schemas/issues.d.ts +0 -1
  312. package/dist/schemas/issues.d.ts.map +1 -1
  313. package/dist/schemas/issues.js +0 -1
  314. package/dist/schemas/issues.js.map +1 -1
  315. package/dist/schemas/logs.d.ts.map +1 -1
  316. package/dist/schemas/logs.js.map +1 -1
  317. package/dist/schemas/loops.d.ts.map +1 -1
  318. package/dist/schemas/loops.js +1 -1
  319. package/dist/schemas/loops.js.map +1 -1
  320. package/dist/schemas/maintenance.d.ts.map +1 -1
  321. package/dist/schemas/maintenance.js.map +1 -1
  322. package/dist/schemas/marketplace.d.ts +0 -4
  323. package/dist/schemas/marketplace.d.ts.map +1 -1
  324. package/dist/schemas/panels.d.ts.map +1 -1
  325. package/dist/schemas/panels.js.map +1 -1
  326. package/dist/schemas/personas.d.ts +2 -1
  327. package/dist/schemas/personas.d.ts.map +1 -1
  328. package/dist/schemas/personas.js +6 -2
  329. package/dist/schemas/personas.js.map +1 -1
  330. package/dist/schemas/plan-limits.d.ts +2 -4
  331. package/dist/schemas/plan-limits.d.ts.map +1 -1
  332. package/dist/schemas/plan-limits.js +5 -8
  333. package/dist/schemas/plan-limits.js.map +1 -1
  334. package/dist/schemas/ports.d.ts.map +1 -1
  335. package/dist/schemas/ports.js.map +1 -1
  336. package/dist/schemas/provider-oauth.d.ts.map +1 -1
  337. package/dist/schemas/provider-oauth.js.map +1 -1
  338. package/dist/schemas/provider-subscriptions.d.ts +1 -1
  339. package/dist/schemas/provider-subscriptions.d.ts.map +1 -1
  340. package/dist/schemas/provider-subscriptions.js +1 -1
  341. package/dist/schemas/provider-subscriptions.js.map +1 -1
  342. package/dist/schemas/public.d.ts.map +1 -1
  343. package/dist/schemas/public.js.map +1 -1
  344. package/dist/schemas/push.d.ts.map +1 -1
  345. package/dist/schemas/push.js.map +1 -1
  346. package/dist/schemas/secrets.d.ts.map +1 -1
  347. package/dist/schemas/secrets.js.map +1 -1
  348. package/dist/schemas/settings.d.ts +11 -9
  349. package/dist/schemas/settings.d.ts.map +1 -1
  350. package/dist/schemas/settings.js +22 -7
  351. package/dist/schemas/settings.js.map +1 -1
  352. package/dist/schemas/share.d.ts.map +1 -1
  353. package/dist/schemas/share.js.map +1 -1
  354. package/dist/schemas/shared.d.ts +4 -0
  355. package/dist/schemas/shared.d.ts.map +1 -1
  356. package/dist/schemas/shared.js +3 -0
  357. package/dist/schemas/shared.js.map +1 -1
  358. package/dist/schemas/system.d.ts +6 -0
  359. package/dist/schemas/system.d.ts.map +1 -1
  360. package/dist/schemas/system.js +10 -0
  361. package/dist/schemas/system.js.map +1 -1
  362. package/dist/schemas/terminal.d.ts.map +1 -1
  363. package/dist/schemas/terminal.js.map +1 -1
  364. package/dist/schemas/usage.d.ts.map +1 -1
  365. package/dist/schemas/usage.js.map +1 -1
  366. package/dist/schemas/vpn.d.ts.map +1 -1
  367. package/dist/schemas/vpn.js.map +1 -1
  368. package/dist/schemas/webext.d.ts.map +1 -1
  369. package/dist/schemas/webext.js.map +1 -1
  370. package/dist/schemas/workflows.d.ts +66 -9
  371. package/dist/schemas/workflows.d.ts.map +1 -1
  372. package/dist/schemas/workflows.js +6 -5
  373. package/dist/schemas/workflows.js.map +1 -1
  374. package/dist/schemas/workspace-repos.d.ts.map +1 -1
  375. package/dist/schemas/workspace-repos.js.map +1 -1
  376. package/dist/schemas/workspace-search.d.ts.map +1 -1
  377. package/dist/schemas/workspace-search.js.map +1 -1
  378. package/dist/schemas/workspace-setup.d.ts.map +1 -1
  379. package/dist/schemas/workspace-setup.js.map +1 -1
  380. package/dist/schemas/workspace-tree.d.ts.map +1 -1
  381. package/dist/schemas/workspace-tree.js.map +1 -1
  382. package/dist/state/arrival.d.ts.map +1 -0
  383. package/dist/{arrival.js → state/arrival.js} +1 -1
  384. package/dist/state/arrival.js.map +1 -0
  385. package/dist/state/contract-lock.d.ts.map +1 -0
  386. package/dist/{contract-lock.js → state/contract-lock.js} +1 -1
  387. package/dist/state/contract-lock.js.map +1 -0
  388. package/dist/{definition.d.ts → state/definition.d.ts} +21 -17
  389. package/dist/state/definition.d.ts.map +1 -0
  390. package/dist/{definition.js → state/definition.js} +4 -4
  391. package/dist/state/definition.js.map +1 -0
  392. package/dist/state/history-state.d.ts.map +1 -0
  393. package/dist/{history-state.js → state/history-state.js} +1 -0
  394. package/dist/state/history-state.js.map +1 -0
  395. package/dist/state/runtime-state.d.ts.map +1 -0
  396. package/dist/state/runtime-state.js.map +1 -0
  397. package/dist/state/starter.d.ts.map +1 -0
  398. package/dist/state/starter.js.map +1 -0
  399. package/dist/state/state-portability.d.ts.map +1 -0
  400. package/dist/state/state-portability.js.map +1 -0
  401. package/dist/state/versions.d.ts.map +1 -0
  402. package/dist/state/versions.js.map +1 -0
  403. package/dist/{workspace-state.d.ts → state/workspace-state.d.ts} +8 -0
  404. package/dist/state/workspace-state.d.ts.map +1 -0
  405. package/dist/{workspace-state.js → state/workspace-state.js} +25 -0
  406. package/dist/state/workspace-state.js.map +1 -0
  407. package/dist/{documents.d.ts → text/documents.d.ts} +1 -1
  408. package/dist/text/documents.d.ts.map +1 -0
  409. package/dist/{documents.js → text/documents.js} +1 -1
  410. package/dist/text/documents.js.map +1 -0
  411. package/dist/text/embed.d.ts.map +1 -0
  412. package/dist/text/embed.js.map +1 -0
  413. package/dist/text/mentions.d.ts.map +1 -0
  414. package/dist/text/mentions.js.map +1 -0
  415. package/dist/text/model-answer.d.ts +3 -0
  416. package/dist/text/model-answer.d.ts.map +1 -0
  417. package/dist/text/model-answer.js +3 -0
  418. package/dist/text/model-answer.js.map +1 -0
  419. package/dist/text/path-refs.d.ts.map +1 -0
  420. package/dist/text/path-refs.js.map +1 -0
  421. package/dist/{shell-regions.d.ts → text/shell-regions.d.ts} +1 -1
  422. package/dist/text/shell-regions.d.ts.map +1 -0
  423. package/dist/text/shell-regions.js.map +1 -0
  424. package/dist/text/title.d.ts.map +1 -0
  425. package/dist/text/title.js.map +1 -0
  426. package/dist/{transcript-fold.d.ts → text/transcript-fold.d.ts} +2 -1
  427. package/dist/text/transcript-fold.d.ts.map +1 -0
  428. package/dist/{transcript-fold.js → text/transcript-fold.js} +2 -16
  429. package/dist/text/transcript-fold.js.map +1 -0
  430. package/dist/text/whisper.d.ts +3 -0
  431. package/dist/text/whisper.d.ts.map +1 -0
  432. package/dist/text/whisper.js +11 -0
  433. package/dist/text/whisper.js.map +1 -0
  434. package/dist/{workflow-faults.d.ts → text/workflow-faults.d.ts} +1 -1
  435. package/dist/text/workflow-faults.d.ts.map +1 -0
  436. package/dist/{workflow-faults.js → text/workflow-faults.js} +1 -1
  437. package/dist/text/workflow-faults.js.map +1 -0
  438. package/package.json +70 -70
  439. package/src/chores/chores.test.ts +4 -10
  440. package/src/chores/chores.ts +148 -392
  441. package/src/chores/digest.ts +8 -28
  442. package/src/chores/extension-update.ts +3 -8
  443. package/src/chores/fix-deps.ts +4 -18
  444. package/src/chores/index.ts +2 -2
  445. package/src/chores/probes.test.ts +7 -43
  446. package/src/chores/probes.ts +62 -167
  447. package/src/chores/prompt.ts +10 -34
  448. package/src/chores/stack.test.ts +6 -45
  449. package/src/chores/stack.ts +27 -118
  450. package/src/chores/verdict.test.ts +101 -80
  451. package/src/chores/verdict.ts +54 -99
  452. package/src/contracts/accounts.contract.ts +4 -19
  453. package/src/contracts/agent.contract.ts +7 -22
  454. package/src/contracts/agents.contract.ts +25 -71
  455. package/src/contracts/automations.contract.ts +14 -30
  456. package/src/contracts/capabilities.contract.ts +8 -35
  457. package/src/contracts/chores.contract.ts +4 -15
  458. package/src/contracts/endpoints.contract.ts +5 -22
  459. package/src/contracts/exit.contract.ts +7 -30
  460. package/src/contracts/extensions.contract.ts +8 -30
  461. package/src/contracts/git.contract.ts +25 -49
  462. package/src/contracts/host.contract.ts +9 -44
  463. package/src/contracts/intentic.contract.ts +1 -1
  464. package/src/contracts/logs.contract.ts +3 -13
  465. package/src/contracts/loops.contract.ts +9 -40
  466. package/src/contracts/personas.contract.ts +10 -35
  467. package/src/contracts/providers.contract.ts +4 -17
  468. package/src/contracts/runner.contract.ts +12 -39
  469. package/src/contracts/safety.contract.ts +5 -14
  470. package/src/contracts/secrets.contract.ts +4 -22
  471. package/src/contracts/sessions.contract.ts +1 -1
  472. package/src/contracts/settings.contract.ts +4 -10
  473. package/src/contracts/share.contract.ts +3 -9
  474. package/src/contracts/skills.contract.ts +21 -19
  475. package/src/contracts/system.contract.ts +26 -52
  476. package/src/contracts/usage.contract.ts +7 -21
  477. package/src/contracts/vpn.contract.ts +9 -16
  478. package/src/contracts/webext.contract.ts +9 -25
  479. package/src/contracts/workflows.contract.ts +34 -58
  480. package/src/contracts/workspace.contract.ts +19 -50
  481. package/src/events/agent-events.ts +345 -0
  482. package/src/events/cards.ts +286 -0
  483. package/src/{events.test.ts → events/resume.test.ts} +4 -19
  484. package/src/events/resume.ts +60 -0
  485. package/src/events/system-events.ts +139 -0
  486. package/src/events/transcript.ts +320 -0
  487. package/src/{conversation-ids.test.ts → ids/conversation-ids.test.ts} +25 -13
  488. package/src/ids/conversation-ids.ts +178 -0
  489. package/src/ids/hostnames.ts +129 -0
  490. package/src/ids/session-names.ts +29 -0
  491. package/src/ids/share-paths.ts +43 -0
  492. package/src/{tunnel-ids.test.ts → ids/tunnel-ids.test.ts} +1 -14
  493. package/src/ids/tunnel-ids.ts +29 -0
  494. package/src/index.ts +71 -87
  495. package/src/{agent-catalog.test.ts → models/agent-catalog.test.ts} +19 -93
  496. package/src/models/agent-catalog.ts +174 -0
  497. package/src/models/agent-runtimes.ts +201 -0
  498. package/src/models/capability-ledger.test.ts +84 -0
  499. package/src/{fast-tier.test.ts → models/fast-tier.test.ts} +7 -18
  500. package/src/models/fast-tier.ts +36 -0
  501. package/src/{model-order.test.ts → models/model-order.test.ts} +54 -40
  502. package/src/models/model-order.ts +171 -0
  503. package/src/{model-pins.test.ts → models/model-pins.test.ts} +12 -46
  504. package/src/models/model-pins.ts +57 -0
  505. package/src/models/model-roles.test.ts +38 -0
  506. package/src/models/model-roles.ts +180 -0
  507. package/src/{plan-pools.test.ts → models/plan-pools.test.ts} +6 -11
  508. package/src/models/plan-pools.ts +65 -0
  509. package/src/{prompt-complexity.test.ts → models/prompt-complexity.test.ts} +8 -60
  510. package/src/models/prompt-complexity.ts +215 -0
  511. package/src/{provider-specs.test.ts → models/provider-specs.test.ts} +18 -47
  512. package/src/models/provider-specs.ts +272 -0
  513. package/src/policy/approvals-execution.ts +58 -0
  514. package/src/{batch-runs.test.ts → policy/batch-runs.test.ts} +4 -20
  515. package/src/policy/batch-runs.ts +137 -0
  516. package/src/policy/capability-secrets.ts +5 -0
  517. package/src/{card-status.ts → policy/card-status.ts} +11 -26
  518. package/src/{command-classes.test.ts → policy/command-classes.test.ts} +11 -118
  519. package/src/policy/command-classes.ts +395 -0
  520. package/src/policy/command-run.ts +65 -0
  521. package/src/policy/control-scopes.ts +38 -0
  522. package/src/{credential-material.test.ts → policy/credential-material.test.ts} +4 -26
  523. package/src/policy/credential-material.ts +91 -0
  524. package/src/policy/needs-action.ts +5 -0
  525. package/src/policy/output-fields.ts +86 -0
  526. package/src/policy/overlay-lint.ts +100 -0
  527. package/src/{owner-ticket.test.ts → policy/owner-ticket.test.ts} +1 -1
  528. package/src/{owner-ticket.ts → policy/owner-ticket.ts} +9 -31
  529. package/src/policy/safety-policy.test.ts +84 -0
  530. package/src/policy/safety-policy.ts +142 -0
  531. package/src/policy/search-globs.ts +60 -0
  532. package/src/protocol/container-requirements.test.ts +72 -0
  533. package/src/protocol/container-requirements.ts +58 -0
  534. package/src/protocol/host-protocol.ts +29 -0
  535. package/src/protocol/ingress-contract.ts +103 -0
  536. package/src/{ingress-protocol.test.ts → protocol/ingress-protocol.test.ts} +25 -90
  537. package/src/protocol/ingress-protocol.ts +441 -0
  538. package/src/protocol/listener-protocol.ts +75 -0
  539. package/src/{peer-dial.test.ts → protocol/peer-dial.test.ts} +52 -1
  540. package/src/protocol/peer-dial.ts +207 -0
  541. package/src/{peer-mcp-server.ts → protocol/peer-mcp-server.ts} +16 -41
  542. package/src/protocol/request-id.ts +5 -0
  543. package/src/{routes.test.ts → protocol/routes.test.ts} +14 -22
  544. package/src/protocol/routes.ts +159 -0
  545. package/src/protocol/runner-protocol.ts +197 -0
  546. package/src/protocol/terminal-protocol.ts +13 -0
  547. package/src/protocol/webext-links.ts +50 -0
  548. package/src/protocol/webext-protocol.ts +24 -0
  549. package/src/schemas/activity.ts +22 -30
  550. package/src/schemas/agent.ts +130 -238
  551. package/src/schemas/agents.ts +165 -483
  552. package/src/schemas/approvals.ts +23 -71
  553. package/src/schemas/automations.ts +142 -250
  554. package/src/schemas/capabilities.ts +127 -414
  555. package/src/schemas/ci.ts +56 -108
  556. package/src/schemas/codebase-health.ts +7 -11
  557. package/src/schemas/devices.ts +103 -321
  558. package/src/schemas/engines.ts +16 -44
  559. package/src/schemas/environment.ts +41 -91
  560. package/src/schemas/exit.ts +24 -81
  561. package/src/schemas/extension-updates.ts +42 -87
  562. package/src/schemas/git-history.ts +30 -84
  563. package/src/schemas/git.ts +141 -256
  564. package/src/schemas/history.ts +14 -40
  565. package/src/schemas/hosts.ts +9 -15
  566. package/src/schemas/inventory.ts +8 -10
  567. package/src/schemas/issues.ts +66 -134
  568. package/src/schemas/logs.ts +15 -34
  569. package/src/schemas/loops.ts +46 -163
  570. package/src/schemas/maintenance.ts +47 -172
  571. package/src/schemas/panels.ts +20 -45
  572. package/src/schemas/personas.ts +50 -200
  573. package/src/schemas/plan-limits.ts +58 -197
  574. package/src/schemas/ports.ts +14 -32
  575. package/src/schemas/provider-oauth.ts +23 -76
  576. package/src/schemas/provider-subscriptions.ts +4 -13
  577. package/src/schemas/public.ts +4 -15
  578. package/src/schemas/push.ts +8 -36
  579. package/src/schemas/secrets.ts +20 -64
  580. package/src/schemas/settings.ts +182 -602
  581. package/src/schemas/share.ts +14 -32
  582. package/src/schemas/shared.ts +14 -13
  583. package/src/schemas/system.ts +46 -78
  584. package/src/schemas/terminal.ts +41 -120
  585. package/src/schemas/usage.ts +44 -233
  586. package/src/schemas/version-seam.test.ts +9 -26
  587. package/src/schemas/vpn.ts +27 -64
  588. package/src/schemas/webext.ts +22 -53
  589. package/src/schemas/workflows.ts +57 -183
  590. package/src/schemas/workspace-repos.ts +12 -24
  591. package/src/schemas/workspace-search.ts +17 -35
  592. package/src/schemas/workspace-setup.ts +4 -11
  593. package/src/schemas/workspace-tree.ts +32 -91
  594. package/src/state/arrival.ts +109 -0
  595. package/src/state/contract-lock.test.ts +17 -0
  596. package/src/state/contract-lock.ts +49 -0
  597. package/src/state/definition.ts +143 -0
  598. package/src/state/history-state.ts +103 -0
  599. package/src/{runtime-state.test.ts → state/runtime-state.test.ts} +3 -10
  600. package/src/state/runtime-state.ts +63 -0
  601. package/src/state/starter.ts +5 -0
  602. package/src/state/state-portability.ts +27 -0
  603. package/src/state/versions.ts +26 -0
  604. package/src/{workspace-state.test.ts → state/workspace-state.test.ts} +65 -172
  605. package/src/state/workspace-state.ts +669 -0
  606. package/src/{documents.test.ts → text/documents.test.ts} +1 -1
  607. package/src/text/documents.ts +42 -0
  608. package/src/text/embed.ts +132 -0
  609. package/src/text/mentions.ts +21 -0
  610. package/src/text/model-answer.ts +9 -0
  611. package/src/text/path-refs.ts +39 -0
  612. package/src/text/shell-regions.ts +224 -0
  613. package/src/{title.test.ts → text/title.test.ts} +13 -32
  614. package/src/text/title.ts +202 -0
  615. package/src/{transcript-fold.test.ts → text/transcript-fold.test.ts} +5 -83
  616. package/src/{transcript-fold.ts → text/transcript-fold.ts} +65 -170
  617. package/src/text/whisper.test.ts +19 -0
  618. package/src/text/whisper.ts +17 -0
  619. package/src/{workflow-faults.test.ts → text/workflow-faults.test.ts} +6 -24
  620. package/src/{workflow-faults.ts → text/workflow-faults.ts} +20 -60
  621. package/dist/agent-catalog.d.ts.map +0 -1
  622. package/dist/agent-catalog.js.map +0 -1
  623. package/dist/agent-runtimes.d.ts.map +0 -1
  624. package/dist/agent-runtimes.js.map +0 -1
  625. package/dist/approvals-execution.d.ts.map +0 -1
  626. package/dist/approvals-execution.js.map +0 -1
  627. package/dist/arrival.d.ts.map +0 -1
  628. package/dist/arrival.js.map +0 -1
  629. package/dist/batch-runs.d.ts.map +0 -1
  630. package/dist/batch-runs.js.map +0 -1
  631. package/dist/capability-env.d.ts.map +0 -1
  632. package/dist/capability-env.js.map +0 -1
  633. package/dist/capability-secrets.d.ts.map +0 -1
  634. package/dist/capability-secrets.js.map +0 -1
  635. package/dist/card-status.d.ts.map +0 -1
  636. package/dist/card-status.js.map +0 -1
  637. package/dist/command-classes.d.ts.map +0 -1
  638. package/dist/command-classes.js.map +0 -1
  639. package/dist/command-run.d.ts.map +0 -1
  640. package/dist/command-run.js.map +0 -1
  641. package/dist/contract-lock.d.ts.map +0 -1
  642. package/dist/contract-lock.js.map +0 -1
  643. package/dist/conversation-ids.d.ts +0 -4
  644. package/dist/conversation-ids.d.ts.map +0 -1
  645. package/dist/conversation-ids.js.map +0 -1
  646. package/dist/credential-material.d.ts.map +0 -1
  647. package/dist/credential-material.js.map +0 -1
  648. package/dist/definition.d.ts.map +0 -1
  649. package/dist/definition.js.map +0 -1
  650. package/dist/documents.d.ts.map +0 -1
  651. package/dist/documents.js.map +0 -1
  652. package/dist/embed.d.ts.map +0 -1
  653. package/dist/embed.js.map +0 -1
  654. package/dist/events.d.ts +0 -4336
  655. package/dist/events.d.ts.map +0 -1
  656. package/dist/events.js +0 -725
  657. package/dist/events.js.map +0 -1
  658. package/dist/fast-tier.d.ts.map +0 -1
  659. package/dist/fast-tier.js.map +0 -1
  660. package/dist/history-state.d.ts.map +0 -1
  661. package/dist/history-state.js.map +0 -1
  662. package/dist/host-protocol.d.ts.map +0 -1
  663. package/dist/host-protocol.js.map +0 -1
  664. package/dist/hostnames.d.ts.map +0 -1
  665. package/dist/hostnames.js.map +0 -1
  666. package/dist/ingress-contract.d.ts.map +0 -1
  667. package/dist/ingress-contract.js.map +0 -1
  668. package/dist/ingress-protocol.d.ts.map +0 -1
  669. package/dist/ingress-protocol.js.map +0 -1
  670. package/dist/listener-protocol.d.ts.map +0 -1
  671. package/dist/listener-protocol.js.map +0 -1
  672. package/dist/mentions.d.ts.map +0 -1
  673. package/dist/mentions.js.map +0 -1
  674. package/dist/model-order.d.ts.map +0 -1
  675. package/dist/model-order.js.map +0 -1
  676. package/dist/model-pins.d.ts.map +0 -1
  677. package/dist/model-pins.js.map +0 -1
  678. package/dist/model-roles.d.ts.map +0 -1
  679. package/dist/model-roles.js.map +0 -1
  680. package/dist/needs-action.d.ts.map +0 -1
  681. package/dist/needs-action.js.map +0 -1
  682. package/dist/output-fields.d.ts.map +0 -1
  683. package/dist/output-fields.js.map +0 -1
  684. package/dist/overlay-lint.d.ts.map +0 -1
  685. package/dist/overlay-lint.js.map +0 -1
  686. package/dist/owner-ticket.d.ts.map +0 -1
  687. package/dist/owner-ticket.js.map +0 -1
  688. package/dist/path-refs.d.ts.map +0 -1
  689. package/dist/path-refs.js.map +0 -1
  690. package/dist/peer-dial.d.ts.map +0 -1
  691. package/dist/peer-dial.js.map +0 -1
  692. package/dist/peer-mcp-server.d.ts.map +0 -1
  693. package/dist/peer-mcp-server.js.map +0 -1
  694. package/dist/plan-pools.d.ts.map +0 -1
  695. package/dist/plan-pools.js.map +0 -1
  696. package/dist/prompt-complexity.d.ts.map +0 -1
  697. package/dist/prompt-complexity.js.map +0 -1
  698. package/dist/provider-specs.d.ts.map +0 -1
  699. package/dist/provider-specs.js.map +0 -1
  700. package/dist/request-id.d.ts.map +0 -1
  701. package/dist/request-id.js.map +0 -1
  702. package/dist/routes.d.ts.map +0 -1
  703. package/dist/routes.js.map +0 -1
  704. package/dist/runner-protocol.d.ts.map +0 -1
  705. package/dist/runner-protocol.js.map +0 -1
  706. package/dist/runtime-state.d.ts.map +0 -1
  707. package/dist/runtime-state.js.map +0 -1
  708. package/dist/safety-policy.d.ts.map +0 -1
  709. package/dist/safety-policy.js.map +0 -1
  710. package/dist/search-globs.d.ts.map +0 -1
  711. package/dist/search-globs.js.map +0 -1
  712. package/dist/session-names.d.ts.map +0 -1
  713. package/dist/session-names.js.map +0 -1
  714. package/dist/share-paths.d.ts.map +0 -1
  715. package/dist/share-paths.js.map +0 -1
  716. package/dist/shell-regions.d.ts.map +0 -1
  717. package/dist/shell-regions.js.map +0 -1
  718. package/dist/sse.d.ts.map +0 -1
  719. package/dist/sse.js.map +0 -1
  720. package/dist/starter.d.ts.map +0 -1
  721. package/dist/starter.js.map +0 -1
  722. package/dist/state-portability.d.ts.map +0 -1
  723. package/dist/state-portability.js.map +0 -1
  724. package/dist/terminal-protocol.d.ts.map +0 -1
  725. package/dist/terminal-protocol.js.map +0 -1
  726. package/dist/title.d.ts.map +0 -1
  727. package/dist/title.js.map +0 -1
  728. package/dist/transcript-fold.d.ts.map +0 -1
  729. package/dist/transcript-fold.js.map +0 -1
  730. package/dist/tunnel-ids.d.ts.map +0 -1
  731. package/dist/tunnel-ids.js.map +0 -1
  732. package/dist/versions.d.ts.map +0 -1
  733. package/dist/versions.js.map +0 -1
  734. package/dist/webext-links.d.ts.map +0 -1
  735. package/dist/webext-links.js.map +0 -1
  736. package/dist/webext-protocol.d.ts.map +0 -1
  737. package/dist/webext-protocol.js.map +0 -1
  738. package/dist/workflow-faults.d.ts.map +0 -1
  739. package/dist/workflow-faults.js.map +0 -1
  740. package/dist/workspace-state.d.ts.map +0 -1
  741. package/dist/workspace-state.js.map +0 -1
  742. package/src/agent-catalog.ts +0 -316
  743. package/src/agent-runtimes.ts +0 -419
  744. package/src/approvals-execution.ts +0 -96
  745. package/src/arrival.ts +0 -160
  746. package/src/batch-runs.ts +0 -188
  747. package/src/capability-ledger.test.ts +0 -140
  748. package/src/capability-secrets.ts +0 -20
  749. package/src/command-classes.ts +0 -617
  750. package/src/command-run.ts +0 -78
  751. package/src/contract-lock.test.ts +0 -23
  752. package/src/contract-lock.ts +0 -66
  753. package/src/conversation-ids.ts +0 -207
  754. package/src/credential-material.ts +0 -181
  755. package/src/definition.ts +0 -207
  756. package/src/documents.ts +0 -67
  757. package/src/embed.ts +0 -164
  758. package/src/events.ts +0 -1870
  759. package/src/fast-tier.ts +0 -72
  760. package/src/history-state.ts +0 -174
  761. package/src/host-protocol.ts +0 -36
  762. package/src/hostnames.ts +0 -180
  763. package/src/ingress-contract.ts +0 -157
  764. package/src/ingress-protocol.ts +0 -625
  765. package/src/listener-protocol.ts +0 -96
  766. package/src/mentions.ts +0 -25
  767. package/src/model-order.ts +0 -262
  768. package/src/model-pins.ts +0 -132
  769. package/src/model-roles.test.ts +0 -52
  770. package/src/model-roles.ts +0 -320
  771. package/src/needs-action.ts +0 -14
  772. package/src/output-fields.ts +0 -111
  773. package/src/overlay-lint.ts +0 -116
  774. package/src/path-refs.ts +0 -59
  775. package/src/peer-dial.ts +0 -163
  776. package/src/plan-pools.ts +0 -92
  777. package/src/prompt-complexity.ts +0 -334
  778. package/src/provider-specs.ts +0 -432
  779. package/src/request-id.ts +0 -41
  780. package/src/routes.ts +0 -219
  781. package/src/runner-protocol.ts +0 -239
  782. package/src/runtime-state.ts +0 -140
  783. package/src/safety-policy.test.ts +0 -88
  784. package/src/safety-policy.ts +0 -258
  785. package/src/search-globs.ts +0 -76
  786. package/src/session-names.ts +0 -44
  787. package/src/share-paths.ts +0 -68
  788. package/src/shell-regions.ts +0 -289
  789. package/src/starter.ts +0 -13
  790. package/src/state-portability.ts +0 -56
  791. package/src/terminal-protocol.ts +0 -16
  792. package/src/title.ts +0 -267
  793. package/src/tunnel-ids.ts +0 -57
  794. package/src/versions.ts +0 -48
  795. package/src/webext-links.ts +0 -90
  796. package/src/webext-protocol.ts +0 -27
  797. package/src/workspace-state.ts +0 -1090
  798. /package/dist/{hostnames.d.ts → ids/hostnames.d.ts} +0 -0
  799. /package/dist/{hostnames.js → ids/hostnames.js} +0 -0
  800. /package/dist/{session-names.d.ts → ids/session-names.d.ts} +0 -0
  801. /package/dist/{session-names.js → ids/session-names.js} +0 -0
  802. /package/dist/{share-paths.d.ts → ids/share-paths.d.ts} +0 -0
  803. /package/dist/{share-paths.js → ids/share-paths.js} +0 -0
  804. /package/dist/{agent-catalog.js → models/agent-catalog.js} +0 -0
  805. /package/dist/{agent-runtimes.d.ts → models/agent-runtimes.d.ts} +0 -0
  806. /package/dist/{agent-runtimes.js → models/agent-runtimes.js} +0 -0
  807. /package/dist/{fast-tier.js → models/fast-tier.js} +0 -0
  808. /package/dist/{model-order.d.ts → models/model-order.d.ts} +0 -0
  809. /package/dist/{model-pins.js → models/model-pins.js} +0 -0
  810. /package/dist/{plan-pools.js → models/plan-pools.js} +0 -0
  811. /package/dist/{prompt-complexity.d.ts → models/prompt-complexity.d.ts} +0 -0
  812. /package/dist/{prompt-complexity.js → models/prompt-complexity.js} +0 -0
  813. /package/dist/{provider-specs.d.ts → models/provider-specs.d.ts} +0 -0
  814. /package/dist/{provider-specs.js → models/provider-specs.js} +0 -0
  815. /package/dist/{approvals-execution.d.ts → policy/approvals-execution.d.ts} +0 -0
  816. /package/dist/{approvals-execution.js → policy/approvals-execution.js} +0 -0
  817. /package/dist/{capability-env.d.ts → policy/capability-env.d.ts} +0 -0
  818. /package/dist/{capability-env.js → policy/capability-env.js} +0 -0
  819. /package/dist/{capability-secrets.d.ts → policy/capability-secrets.d.ts} +0 -0
  820. /package/dist/{capability-secrets.js → policy/capability-secrets.js} +0 -0
  821. /package/dist/{command-run.js → policy/command-run.js} +0 -0
  822. /package/dist/{credential-material.d.ts → policy/credential-material.d.ts} +0 -0
  823. /package/dist/{credential-material.js → policy/credential-material.js} +0 -0
  824. /package/dist/{needs-action.d.ts → policy/needs-action.d.ts} +0 -0
  825. /package/dist/{needs-action.js → policy/needs-action.js} +0 -0
  826. /package/dist/{output-fields.d.ts → policy/output-fields.d.ts} +0 -0
  827. /package/dist/{output-fields.js → policy/output-fields.js} +0 -0
  828. /package/dist/{overlay-lint.d.ts → policy/overlay-lint.d.ts} +0 -0
  829. /package/dist/{overlay-lint.js → policy/overlay-lint.js} +0 -0
  830. /package/dist/{owner-ticket.d.ts → policy/owner-ticket.d.ts} +0 -0
  831. /package/dist/{search-globs.d.ts → policy/search-globs.d.ts} +0 -0
  832. /package/dist/{search-globs.js → policy/search-globs.js} +0 -0
  833. /package/dist/{ingress-contract.d.ts → protocol/ingress-contract.d.ts} +0 -0
  834. /package/dist/{ingress-protocol.d.ts → protocol/ingress-protocol.d.ts} +0 -0
  835. /package/dist/{ingress-protocol.js → protocol/ingress-protocol.js} +0 -0
  836. /package/dist/{listener-protocol.d.ts → protocol/listener-protocol.d.ts} +0 -0
  837. /package/dist/{peer-mcp-server.d.ts → protocol/peer-mcp-server.d.ts} +0 -0
  838. /package/dist/{peer-mcp-server.js → protocol/peer-mcp-server.js} +0 -0
  839. /package/dist/{request-id.d.ts → protocol/request-id.d.ts} +0 -0
  840. /package/dist/{request-id.js → protocol/request-id.js} +0 -0
  841. /package/dist/{routes.d.ts → protocol/routes.d.ts} +0 -0
  842. /package/dist/{routes.js → protocol/routes.js} +0 -0
  843. /package/dist/{sse.d.ts → protocol/sse.d.ts} +0 -0
  844. /package/dist/{sse.js → protocol/sse.js} +0 -0
  845. /package/dist/{terminal-protocol.js → protocol/terminal-protocol.js} +0 -0
  846. /package/dist/{webext-links.d.ts → protocol/webext-links.d.ts} +0 -0
  847. /package/dist/{webext-links.js → protocol/webext-links.js} +0 -0
  848. /package/dist/{arrival.d.ts → state/arrival.d.ts} +0 -0
  849. /package/dist/{contract-lock.d.ts → state/contract-lock.d.ts} +0 -0
  850. /package/dist/{history-state.d.ts → state/history-state.d.ts} +0 -0
  851. /package/dist/{runtime-state.d.ts → state/runtime-state.d.ts} +0 -0
  852. /package/dist/{runtime-state.js → state/runtime-state.js} +0 -0
  853. /package/dist/{starter.d.ts → state/starter.d.ts} +0 -0
  854. /package/dist/{starter.js → state/starter.js} +0 -0
  855. /package/dist/{state-portability.d.ts → state/state-portability.d.ts} +0 -0
  856. /package/dist/{state-portability.js → state/state-portability.js} +0 -0
  857. /package/dist/{versions.d.ts → state/versions.d.ts} +0 -0
  858. /package/dist/{versions.js → state/versions.js} +0 -0
  859. /package/dist/{embed.d.ts → text/embed.d.ts} +0 -0
  860. /package/dist/{embed.js → text/embed.js} +0 -0
  861. /package/dist/{mentions.d.ts → text/mentions.d.ts} +0 -0
  862. /package/dist/{mentions.js → text/mentions.js} +0 -0
  863. /package/dist/{path-refs.d.ts → text/path-refs.d.ts} +0 -0
  864. /package/dist/{path-refs.js → text/path-refs.js} +0 -0
  865. /package/dist/{shell-regions.js → text/shell-regions.js} +0 -0
  866. /package/dist/{title.d.ts → text/title.d.ts} +0 -0
  867. /package/dist/{title.js → text/title.js} +0 -0
  868. /package/src/{hostnames.test.ts → ids/hostnames.test.ts} +0 -0
  869. /package/src/{share-paths.test.ts → ids/share-paths.test.ts} +0 -0
  870. /package/src/{capability-env.ts → policy/capability-env.ts} +0 -0
  871. /package/src/{overlay-lint.test.ts → policy/overlay-lint.test.ts} +0 -0
  872. /package/src/{search-globs.test.ts → policy/search-globs.test.ts} +0 -0
  873. /package/src/{ingress-contract.test.ts → protocol/ingress-contract.test.ts} +0 -0
  874. /package/src/{peer-mcp-server.test.ts → protocol/peer-mcp-server.test.ts} +0 -0
  875. /package/src/{sse.ts → protocol/sse.ts} +0 -0
  876. /package/src/{versions.test.ts → state/versions.test.ts} +0 -0
  877. /package/src/{embed.test.ts → text/embed.test.ts} +0 -0
  878. /package/src/{mentions.test.ts → text/mentions.test.ts} +0 -0
  879. /package/src/{path-refs.test.ts → text/path-refs.test.ts} +0 -0
@@ -0,0 +1,60 @@
1
+ // What the search box's second field means: VSCode's "files to include" grammar, read the same way everywhere it runs
2
+ // (the daemon, the recorded demo):
3
+ // - a bare name matches both the file and the folder (`p` and `p/**`)
4
+ // - a path matches at any depth unless it starts with `./` or `/` (anchored to the root)
5
+ // - a leading dot is an extension shorthand (`.ts` becomes `*.ts`); a trailing slash is dropped
6
+ // - commas split patterns, except inside `{...}` or `[...]`
7
+ // - a leading `!` excludes; this app's own addition, not VSCode's
8
+
9
+ // VSCode's splitGlobAware: the split character is inert inside a brace group or character class.
10
+ const splitPatterns = (include: string, splitChar: string): string[] => {
11
+ const segments: string[] = [];
12
+ let current = ``;
13
+ let inBraces = false;
14
+ let inBrackets = false;
15
+ for (const char of include) {
16
+ if (char === splitChar && !inBraces && !inBrackets) {
17
+ segments.push(current);
18
+ current = ``;
19
+ continue;
20
+ }
21
+ inBraces = char === `{` ? true : char === `}` ? false : inBraces;
22
+ inBrackets = char === `[` ? true : char === `]` ? false : inBrackets;
23
+ current += char;
24
+ }
25
+ segments.push(current);
26
+ return segments.map((segment) => segment.trim()).filter((segment) => segment !== ``);
27
+ };
28
+
29
+ // One typed segment maps to two globs: the file itself, and everything under a folder of that name. An anchored form
30
+ // (`./p`, `/p`) keeps its `./` prefix, since that's how the engine tells "anchored" from "any depth".
31
+ const expand = (segment: string): string[] => {
32
+ const trimmed = segment.replace(/\/+$/, ``);
33
+ if (trimmed === ``) {
34
+ return [];
35
+ }
36
+ const anchored = /^\.?\//.test(trimmed);
37
+ if (anchored) {
38
+ const path = trimmed.replace(/^\.?\//, ``).replace(/^\/+/, ``);
39
+ return path === `` ? [] : [`./${path}`, `./${path}/**`];
40
+ }
41
+ // ".ts" is how people write an extension filter; VSCode reads it as "*.ts" rather than a hidden file.
42
+ const pattern = trimmed.startsWith(`.`) ? `*${trimmed}` : trimmed;
43
+ return [`**/${pattern}`, `**/${pattern}/**`];
44
+ };
45
+
46
+ export interface IncludeGlobs {
47
+ // Files the search is limited to, empty means the whole workspace. OR'ed: any pattern matching admits.
48
+ readonly globs: readonly string[];
49
+ // Files kept out of it, whatever the includes said.
50
+ readonly notGlobs: readonly string[];
51
+ }
52
+
53
+ export const includeGlobs = (include: string | undefined): IncludeGlobs => {
54
+ const segments = splitPatterns(include ?? ``, `,`);
55
+ return {
56
+ globs: segments.filter((segment) => !segment.startsWith(`!`)).flatMap(expand),
57
+ // A bare "!" excludes nothing; without this it would expand into a glob that matches everything.
58
+ notGlobs: segments.filter((segment) => segment.startsWith(`!`)).flatMap((segment) => expand(segment.slice(1))),
59
+ };
60
+ };
@@ -0,0 +1,72 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { CONTAINER_REQUIREMENTS, containerDrift } from "./container-requirements.js";
3
+
4
+ // Healthy baseline: every case below removes one piece of it to produce a gap.
5
+ const CURRENT = {
6
+ SANDBOX_PUBLIC_URL: "https://sandbox-0738cd6b5027.sbx.intentic.dev",
7
+ SANDBOX_GRANT: "ig1.eyJzdWIiOiIwNzM4Y2Q2YjUwMjcifQ.sig",
8
+ INGRESS_URL: "https://ingress.intentic.dev",
9
+ };
10
+
11
+ describe(`containerDrift`, () => {
12
+ it(`says nothing about a container set up by a current release`, () => {
13
+ expect(containerDrift(CURRENT)).toEqual([]);
14
+ });
15
+
16
+ it(`names both keys a pre-migration container is missing, and what that costs`, () => {
17
+ const gaps = containerDrift({ SANDBOX_PUBLIC_URL: CURRENT.SANDBOX_PUBLIC_URL });
18
+ expect(gaps).toHaveLength(1);
19
+ expect(gaps[0]?.key).toBe(`reachability`);
20
+ expect(gaps[0]?.missing).toEqual([`SANDBOX_GRANT`, `INGRESS_URL`]);
21
+ expect(gaps[0]?.repair).toContain(`setup command`);
22
+ });
23
+
24
+ it(`reports only the half that is actually gone`, () => {
25
+ expect(containerDrift({ ...CURRENT, INGRESS_URL: undefined })[0]?.missing).toEqual([`INGRESS_URL`]);
26
+ expect(containerDrift({ ...CURRENT, SANDBOX_GRANT: undefined })[0]?.missing).toEqual([`SANDBOX_GRANT`]);
27
+ });
28
+
29
+ // Blank must count as missing: it is indistinguishable from a dropped value replayed through `-e NAME=`.
30
+ it(`counts blank and whitespace-only values as missing, not as set`, () => {
31
+ expect(containerDrift({ ...CURRENT, SANDBOX_GRANT: `` })[0]?.missing).toEqual([`SANDBOX_GRANT`]);
32
+ expect(containerDrift({ ...CURRENT, SANDBOX_GRANT: ` ` })[0]?.missing).toEqual([`SANDBOX_GRANT`]);
33
+ });
34
+
35
+ // No public address means no evidence of intent, so nothing is reported as missing.
36
+ it(`asks nothing of a sandbox that offers no evidence it was meant to be reachable`, () => {
37
+ expect(containerDrift({})).toEqual([]);
38
+ expect(containerDrift({ CONNECT_TOKEN: `tok`, WORKSPACE_ROOT: `/work` })).toEqual([]);
39
+ expect(containerDrift({ SANDBOX_PUBLIC_URL: `` })).toEqual([]);
40
+ });
41
+
42
+ // A hosted Fly microVM has no grant by design, so this reports nothing on it.
43
+ it(`stays quiet on a hosted machine, which serves its address without dialling out`, () => {
44
+ expect(containerDrift({ SANDBOX_PUBLIC_URL: CURRENT.SANDBOX_PUBLIC_URL, SANDBOX_VM: `1` })).toEqual([]);
45
+ });
46
+ });
47
+
48
+ describe(`CONTAINER_REQUIREMENTS`, () => {
49
+ it(`keys every row uniquely, so a UI can key and dedupe on it`, () => {
50
+ const keys = CONTAINER_REQUIREMENTS.map((requirement) => requirement.key);
51
+ expect(new Set(keys).size).toBe(keys.length);
52
+ });
53
+
54
+ // Overlapping `given`/`requires` would make the row impossible to fire.
55
+ // Empty `given` would make the row fire on every sandbox in the fleet.
56
+ it(`states evidence that is separate from what it demands`, () => {
57
+ for (const requirement of CONTAINER_REQUIREMENTS) {
58
+ expect(requirement.given.length).toBeGreaterThan(0);
59
+ expect(requirement.requires.length).toBeGreaterThan(0);
60
+ expect(requirement.given.filter((name) => requirement.requires.includes(name))).toEqual([]);
61
+ }
62
+ });
63
+
64
+ // Rendered verbatim in the product, so an empty string is a blank card, not just a missing test value.
65
+ it(`words every row for the person who has to fix it`, () => {
66
+ for (const requirement of CONTAINER_REQUIREMENTS) {
67
+ expect(requirement.enables.length).toBeGreaterThan(0);
68
+ expect(requirement.lost.length).toBeGreaterThan(0);
69
+ expect(requirement.repair.length).toBeGreaterThan(0);
70
+ }
71
+ });
72
+ });
@@ -0,0 +1,58 @@
1
+ // A row belongs only if its keys come from setup, their absence is settled, and other env proves intent.
2
+ // Add a row here, add it to `ic sandbox doctor`'s `classify_public` too: the two tables are not kept in sync.
3
+
4
+ /** `enables` and `lost` render verbatim to the user: word them for the product, not the env. */
5
+ export interface ContainerRequirement {
6
+ readonly key: string;
7
+ readonly requires: readonly string[];
8
+ // Absent `given` evidence means this sandbox never had the capability: not a fault, just unconfigured.
9
+ readonly given: readonly string[];
10
+ // Row stays silent if any `unless` key is present: an alternate mechanism already satisfies the evidence.
11
+ readonly unless?: readonly string[];
12
+ readonly enables: string;
13
+ readonly lost: string;
14
+ readonly repair: string;
15
+ }
16
+
17
+ /** Undefined and empty env values are equivalent: both count as missing. */
18
+ export type ContainerEnv = Readonly<Record<string, string | undefined>>;
19
+
20
+ const present = (env: ContainerEnv, name: string): boolean => (env[name] ?? "").trim() !== "";
21
+
22
+ export const CONTAINER_REQUIREMENTS: readonly ContainerRequirement[] = [
23
+ // A pre-migration container has the public name but nothing to serve it with: 502 at the edge, forever.
24
+ {
25
+ key: "reachability",
26
+ requires: ["SANDBOX_GRANT", "INGRESS_URL"],
27
+ given: ["SANDBOX_PUBLIC_URL"],
28
+ // A Fly microVM's edge replays directly to it, so it holds no grant by design.
29
+ unless: ["SANDBOX_VM"],
30
+ enables: "reaching this sandbox at its public address, from anywhere",
31
+ lost:
32
+ "Its public address answers 502 to everyone, including this browser when it is not on the same machine as the sandbox. " +
33
+ "On that machine the workspace still works, over a direct connection that never leaves it — which is why this can go unnoticed for a long time.",
34
+ repair: "Re-run this sandbox's setup command. It carries a freshly signed grant, and it keeps the workspace, its history and its Docker engine.",
35
+ },
36
+ ];
37
+
38
+ export interface ContainerGap {
39
+ readonly key: string;
40
+ readonly missing: readonly string[];
41
+ readonly enables: string;
42
+ readonly lost: string;
43
+ readonly repair: string;
44
+ }
45
+
46
+ /** Empty means every requirement is met or not applicable; non-empty always means a setup rerun is needed. */
47
+ export const containerDrift = (env: ContainerEnv): readonly ContainerGap[] =>
48
+ CONTAINER_REQUIREMENTS.filter(
49
+ (requirement) => requirement.given.every((name) => present(env, name)) && !(requirement.unless ?? []).some((name) => present(env, name)),
50
+ )
51
+ .map((requirement) => ({
52
+ key: requirement.key,
53
+ missing: requirement.requires.filter((name) => !present(env, name)),
54
+ enables: requirement.enables,
55
+ lost: requirement.lost,
56
+ repair: requirement.repair,
57
+ }))
58
+ .filter((gap) => gap.missing.length > 0);
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+
3
+ // The handshake on /system/hosts/connect, the one message on this socket that isn't oRPC. Proving whose socket it is
4
+ // can't itself be an oRPC call, so the machine's first frame is plain JSON; the daemon verifies it and only then
5
+ // attaches the typed link. Anything before that link exists is this frame or a closed socket.
6
+
7
+ // Shared with the daemon's peer bridge, which answers the handshake itself when the machine is asleep.
8
+ export const MCP_PROTOCOL_VERSION = "2025-06-18";
9
+
10
+ /* HOW OFTEN THIS DOOR PINGS A CONNECTED MACHINE, read by both sides of the socket: the daemon's hub pings on
11
+ * it (hosts/host-peer.ts) and the agent presumes a link dead after a few of them pass in silence
12
+ * (peer-dial.ts's peerLinkSilenceMs). Frequent enough to stay inside the idle timeout of every tunnel and proxy
13
+ * in the path, and it is the failure of a ping that tells the daemon a lid closed without a close frame ever
14
+ * arriving. One number, because the two sides disagreeing about it is a device that is either dropped while
15
+ * healthy or believed alive for as long as its socket stays open. */
16
+ export const HOST_HEARTBEAT_MS = 30_000;
17
+
18
+ export const HostHelloSchema = z.object({
19
+ type: z.literal("hello"),
20
+ // Sent in the first frame, never the URL (a WebSocket has no headers, and a URL gets logged everywhere).
21
+ token: z.string(),
22
+ // The build the machine runs, surfaced so an old binary is visible rather than mysteriously missing a tool.
23
+ version: z.string(),
24
+ });
25
+ export type HostHello = z.infer<typeof HostHelloSchema>;
26
+
27
+ // The URL the machine's agent dials, given the sandbox's public URL. Carries no credential (the token rides the hello
28
+ // frame); one place builds it, so the agent and the daemon route can't disagree.
29
+ export const hostConnectUrl = (sandboxUrl: string): string => `${sandboxUrl.replace(/^http/, "ws").replace(/\/$/, "")}/system/hosts/connect`;
@@ -0,0 +1,103 @@
1
+ import { createPrivateKey, createPublicKey, sign as edSign, verify as edVerify } from "node:crypto";
2
+ import { SANDBOX_ID } from "../ids/tunnel-ids.js";
3
+
4
+ // A sandbox proves identity with a signed grant; a hostname's embedded id resolves ownership by parsing, not a registry
5
+ // lookup. Platform, ingress and daemon must agree on every string here. Routing is per h2 stream, since one TLS
6
+ // connection can carry multiple sandboxes' hosts.
7
+
8
+ // The reachability grant
9
+
10
+ // Version prefix: an ingress that doesn't recognize it refuses the tunnel rather than negotiating a shape.
11
+ const GRANT_PREFIX = "ig1";
12
+
13
+ const base64url = (bytes: Buffer): string => bytes.toString("base64url");
14
+
15
+ // Signed claim; wire fields are `sub` (12-hex sandbox id) and `iat` (seconds). No expiry: the grant lives for a
16
+ // container's whole life, and revocation is deleting the sandbox row.
17
+ export interface ReachabilityGrant {
18
+ readonly sandboxId: string;
19
+ readonly issuedAt: number;
20
+ }
21
+
22
+ // Mints a grant: an Ed25519 signature over the JSON `{sub, iat}` payload, with a PEM/PKCS8 private key.
23
+ export const mintReachabilityGrant = (privateKeyPem: string, sandboxId: string, issuedAtMs: number): string => {
24
+ if (!SANDBOX_ID.test(sandboxId)) {
25
+ throw new Error(`a reachability grant names a 12-hex sandbox id, got "${sandboxId}"`);
26
+ }
27
+ const payload = Buffer.from(JSON.stringify({ sub: sandboxId, iat: Math.floor(issuedAtMs / 1000) }), "utf8");
28
+ const signature = edSign(null, payload, createPrivateKey(privateKeyPem));
29
+ return `${GRANT_PREFIX}.${base64url(payload)}.${base64url(signature)}`;
30
+ };
31
+
32
+ // Verifies a grant against the platform's public key; any malformed shape returns undefined instead of throwing.
33
+ export const verifyReachabilityGrant = (publicKeyPem: string, token: string): ReachabilityGrant | undefined => {
34
+ const parts = token.split(".");
35
+ if (parts.length !== 3 || parts[0] !== GRANT_PREFIX) {
36
+ return undefined;
37
+ }
38
+ try {
39
+ const payload = Buffer.from(parts[1] as string, "base64url");
40
+ const signature = Buffer.from(parts[2] as string, "base64url");
41
+ if (!edVerify(null, payload, createPublicKey(publicKeyPem), signature)) {
42
+ return undefined;
43
+ }
44
+ const parsed = JSON.parse(payload.toString("utf8")) as { sub?: unknown; iat?: unknown };
45
+ if (typeof parsed.sub !== "string" || !SANDBOX_ID.test(parsed.sub) || typeof parsed.iat !== "number") {
46
+ return undefined;
47
+ }
48
+ return { sandboxId: parsed.sub, issuedAt: parsed.iat };
49
+ } catch {
50
+ return undefined;
51
+ }
52
+ };
53
+
54
+ // Host to owner routing
55
+
56
+ // Resolves which sandbox owns a Host: the leftmost DNS label is `sandbox-<id>` or ends in `-<id>` (12-hex); anything
57
+ // else, including the loopback `<id>.local.<zone>` label, returns undefined.
58
+ export const hostOwnerId = (host: string): string | undefined => {
59
+ const label = host.split(":")[0]?.split(".")[0] ?? "";
60
+ const match = /-([0-9a-f]{12})$/.exec(label);
61
+ return match === null ? undefined : match[1];
62
+ };
63
+
64
+ // Wire constants
65
+
66
+ // Tunnel door on the ingress; versioned so a v2 session shape adds a new path instead of replacing this one.
67
+ export const INGRESS_TUNNEL_PATH = "/tunnel/v1";
68
+
69
+ // Grant travels as a header on the tunnel upgrade; this connection is never a browser's.
70
+ export const INGRESS_GRANT_HEADER = "x-intentic-grant";
71
+
72
+ // Env vars every lane hands the daemon; the daemon reads them directly, not the entrypoint.
73
+ export const ENV_INGRESS_URL = "INGRESS_URL";
74
+ export const ENV_SANDBOX_GRANT = "SANDBOX_GRANT";
75
+
76
+ // The daemon-side surface
77
+
78
+ // Daemon-side tunnel behavior this contract requires: dial, register, forward to the loopback listener, and reconnect
79
+ // forever with backoff, never giving up. `close()` is for shutdown and tests.
80
+ export interface IngressTunnelOptions {
81
+ // e.g. https://ingress.<zone>; the daemon derives the wss:// door itself via INGRESS_TUNNEL_PATH.
82
+ readonly url: string;
83
+ readonly grant: string;
84
+ // The daemon's own loopback listener; every h2 stream lands there as a plain HTTP/1.1 request or upgrade.
85
+ readonly targetPort: number;
86
+ readonly log: (message: string, error?: unknown) => void;
87
+ }
88
+
89
+ export interface IngressTunnelHandle {
90
+ readonly close: () => Promise<void>;
91
+ // For /health and the boot log: whether the tunnel currently holds a registered session.
92
+ readonly connected: () => boolean;
93
+ }
94
+
95
+ export type StartIngressTunnel = (options: IngressTunnelOptions) => IngressTunnelHandle;
96
+
97
+ // What the ingress side must also honor, enforced by ingress-protocol tests:
98
+ // - Register: verify the grant offline; if PLATFORM_URL is set, check the sandbox exists (GET /api/reachability/<id>)
99
+ // and cache the answer, failing open if the platform doesn't respond. A 404 refuses the tunnel.
100
+ // - Displacement: a new tunnel for an id closes the old session (code 4001) and takes the registration.
101
+ // - Liveness: WebSocket ping every 15s; a peer silent for 45s is unregistered.
102
+ // - Routing: host maps via hostOwnerId to a registered tunnel; no tunnel answers 502 naming the sandbox label.
103
+ // - The tunnel door and any host without a sandbox id are served directly by the ingress, never routed.
@@ -5,29 +5,16 @@ import { type Duplex, duplexPair } from "node:stream";
5
5
  import { afterAll, beforeAll, expect, test } from "vitest";
6
6
  import { openIngressSession, serveIngressSession } from "./ingress-protocol.js";
7
7
 
8
- /* THE WHOLE CHAIN, IN PROCESS, exactly as the two consumers wire it:
9
- *
10
- * node http client ─h1→ FRONT server (the ingress) ─h2 stream→ duplex pair ─h2 session→ DAEMON half ─h1→ TARGET
11
- *
12
- * Driven by node's own http client rather than by calling the exported functions with hand-built objects,
13
- * because every property worth pinning here is a property of the BYTES: that a 4MB body survives, that a
14
- * response arrives in pieces instead of being buffered whole, that a WebSocket's `Sec-WebSocket-Accept` is the
15
- * daemon's own and not a recomputation, that a half-close reaches the far end. A fake IncomingMessage proves
16
- * none of those, and each of them is a way this file can be wrong while type-checking perfectly.
17
- *
18
- * The front server IS the shape the ingress uses (request → forwardRequest, upgrade → forwardUpgrade, a 502
19
- * when either rejects with nothing yet said to the browser), so a regression in the promise contract fails
20
- * here rather than in the ingress package alone. */
8
+ // Drives the full ingress-to-daemon chain (front server, duplex pair, target) through node's real http client, in
9
+ // process, so streaming, half-close and header identity are pinned as bytes, not shapes.
21
10
 
22
11
  const listen = async (server: Server): Promise<number> => {
23
12
  await new Promise<void>((resolve) => void server.listen(0, "127.0.0.1", resolve));
24
13
  return (server.address() as AddressInfo).port;
25
14
  };
26
15
 
27
- /* Two halves of a test that have to happen in a fixed ORDER without either measuring time: the gate is opened
28
- * by the far end observing something, and the near end waits for that rather than for a duration. A gate that
29
- * is never opened fails as the suite's own hang bound, which is the correct report — "the bytes never arrived"
30
- * is the failure, and no duration in this file would be measuring anything else. */
16
+ // Coordinates a fixed order between two halves without measuring time: the near end waits on the far end's signal; an
17
+ // unopened gate fails as the suite's own hang timeout.
31
18
  const gate = <T = void>(): { readonly open: (value: T) => void; readonly opened: Promise<T> } => {
32
19
  let open = (_value: T): void => {};
33
20
  const opened = new Promise<T>((resolve) => {
@@ -38,8 +25,8 @@ const gate = <T = void>(): { readonly open: (value: T) => void; readonly opened:
38
25
 
39
26
  const HOST = "sandbox-0123456789ab.sbx.test";
40
27
 
41
- // What the target saw, as the target's own answer, so the assertions are about a real server's view of the
42
- // forwarded request rather than about the proxy's bookkeeping.
28
+ // What the target saw, mirrored back as its own response, so assertions read a real server's view rather than the
29
+ // proxy's bookkeeping.
43
30
  interface Seen {
44
31
  readonly method: string;
45
32
  readonly url: string;
@@ -62,14 +49,12 @@ const firstChunk = gate();
62
49
  const secondSent = gate();
63
50
  const uploadStarted = gate();
64
51
 
65
- // 64KB a write, so a `/flood` response keeps node's write queue non-empty and a reset lands on top of a write
66
- // that has not completed.
52
+ // 64KB per write, keeping node's write queue non-empty so a reset lands on an unfinished write.
67
53
  const FLOOD_CHUNK = Buffer.alloc(64 * 1024, 7);
68
54
 
69
55
  type Route = (request: IncomingMessage, response: ServerResponse) => void | Promise<void>;
70
56
 
71
- // One entry per property under test, rather than a chain of ifs: the routes are independent, and a reader
72
- // looking for "what does a cancelled request do" should find one function, not the fifth branch of one.
57
+ // One route per property under test, not a branch of one handler, so each behavior has its own function.
73
58
  const routes: Record<string, Route> = {
74
59
  "/seen": (request, response) => {
75
60
  const seen: Seen = {
@@ -87,8 +72,7 @@ const routes: Record<string, Route> = {
87
72
  response.writeHead(200, { "content-type": "application/octet-stream", "x-sha256": digest(bytes) });
88
73
  response.end(bytes);
89
74
  },
90
- // Two writes with the SECOND one held until the client has read the first: a proxy that buffers the whole
91
- // response before forwarding it deadlocks here instead of passing.
75
+ // Second write waits for the client to read the first; a proxy that buffers the whole response deadlocks here.
92
76
  "/drip": async (_request, response) => {
93
77
  response.writeHead(200, { "content-type": "text/event-stream" });
94
78
  response.write("one");
@@ -97,22 +81,20 @@ const routes: Record<string, Route> = {
97
81
  response.end();
98
82
  secondSent.open();
99
83
  },
100
- // The mirror image: the request body's first chunk must reach here before the client sends the rest.
84
+ // Mirror of /drip: the first body chunk must arrive here before the client sends the rest.
101
85
  "/slurp": async (request, response) => {
102
86
  request.once("data", () => uploadStarted.open());
103
87
  const bytes = await bodyOf(request);
104
88
  response.writeHead(200, { "content-type": "text/plain" });
105
89
  response.end(bytes.toString("utf8"));
106
90
  },
107
- // Never answered: the test asserts that the BROWSER giving up reaches this far, as a close on a response
108
- // this server is still holding — "aborted", never the "ended" of an exchange that completed.
91
+ // Never answered; asserts a client abort surfaces as "aborted", not the "ended" of a completed exchange.
109
92
  "/hangup": (_request, response) => {
110
93
  response.writeHead(200, { "content-type": "text/event-stream" });
111
94
  response.write("open");
112
95
  response.on("close", () => cancelled.open(response.writableEnded ? "ended" : "aborted"));
113
96
  },
114
- // A response big enough that writes are still pending when the client resets the stream: the interleaving
115
- // that the loopback bridge exists to survive.
97
+ // Large enough that writes are still pending when the client resets mid-stream.
116
98
  "/flood": (_request, response) => {
117
99
  response.writeHead(200, { "content-type": "application/octet-stream" });
118
100
  const pump = (): void => {
@@ -139,9 +121,8 @@ const target = createServer((request: IncomingMessage, response: ServerResponse)
139
121
 
140
122
  const cancelled = gate<string>();
141
123
 
142
- /* A real HTTP/1.1 upgrade, hand-written because this package depends on no WebSocket library and does not need
143
- * one: what the protocol has to carry is the 101 head and the bytes after it. `/refuse` answers instead of
144
- * upgrading, which is the other branch of the daemon's CONNECT handling. */
124
+ // Hand-written HTTP/1.1 upgrade carrying the 101 head plus the raw bytes after it. `/refuse` answers instead of
125
+ // upgrading.
145
126
  target.on("upgrade", (request: IncomingMessage, socket: Duplex, head: Buffer) => {
146
127
  if ((request.url ?? "") === "/refuse") {
147
128
  socket.end("HTTP/1.1 404 Not Found\r\nContent-Type: text/plain\r\nContent-Length: 7\r\n\r\nno dice");
@@ -152,8 +133,7 @@ target.on("upgrade", (request: IncomingMessage, socket: Duplex, head: Buffer) =>
152
133
  "HTTP/1.1 101 Switching Protocols",
153
134
  "Upgrade: websocket",
154
135
  "Connection: Upgrade",
155
- // Stands in for Sec-WebSocket-Accept: a value only this server can produce, so reading it back
156
- // proves the head travelled rather than being reconstructed by the proxy.
136
+ // A value only this server can produce; proves the head travelled rather than being reconstructed.
157
137
  `Sec-WebSocket-Accept: ${digest(Buffer.from(String(request.headers["sec-websocket-key"])))}`,
158
138
  `X-Seen-Host: ${String(request.headers.host)}`,
159
139
  `X-Seen-Path: ${String(request.url)}`,
@@ -165,12 +145,11 @@ target.on("upgrade", (request: IncomingMessage, socket: Duplex, head: Buffer) =>
165
145
  socket.write(head);
166
146
  }
167
147
  socket.on("data", (chunk: Buffer) => void socket.write(Buffer.concat([Buffer.from("echo:"), chunk])));
168
- // A FIN from the far end of the whole chain must arrive as a FIN here, or a WebSocket close handshake never
169
- // completes.
148
+ // A far-end FIN must arrive here or the close handshake never completes.
170
149
  socket.on("end", () => void socket.end("bye"));
171
150
  });
172
151
 
173
- // The ingress's shape: one session, every request routed through it per request.
152
+ // One session; every request is routed through it.
174
153
  const front = async (
175
154
  targetPort: number,
176
155
  ): Promise<{ readonly server: Server; readonly poison: (bytes: Buffer) => void; readonly close: () => void }> => {
@@ -194,8 +173,7 @@ const front = async (
194
173
  });
195
174
  return {
196
175
  server,
197
- // Garbage straight onto the wire the edge reads, interleaved with whatever the daemon half is sending:
198
- // what a wedged peer or a half-open socket that came back wrong looks like from the ingress's side.
176
+ // Writes garbage onto the wire the edge reads, simulating a wedged or corrupted peer.
199
177
  poison: (bytes: Buffer) => void daemonSide.write(bytes),
200
178
  close: () => {
201
179
  session.close();
@@ -208,9 +186,8 @@ const front = async (
208
186
  let edge: Awaited<ReturnType<typeof front>>;
209
187
  let edgePort = 0;
210
188
 
211
- /* Every ERR_INTERNAL_ASSERTION this module can produce arrives as an uncaught exception from inside node, with
212
- * none of our frames on the stack — so it is caught HERE or not at all, and a test that merely "passed" while
213
- * the process was dying is exactly the report that hid this the first time. */
189
+ // Node-internal assertion failures surface only as an uncaughtException with none of our frames on the stack; caught
190
+ // here or not at all.
214
191
  const uncaught: string[] = [];
215
192
 
216
193
  beforeAll(async () => {
@@ -245,7 +222,7 @@ const call = (
245
222
  test("a request round-trips with its authority, path and method, and no hop-by-hop header crosses", async () => {
246
223
  const answer = await call("/seen?q=1", {
247
224
  method: "PUT",
248
- // The three the browser must not be able to push through a hop, alongside two that must survive it.
225
+ // Three headers that must not cross a hop, plus two that must survive it.
249
226
  headers: { "x-custom": "kept", "x-forwarded-proto": "https", connection: "close", upgrade: "h2c", "keep-alive": "timeout=99" },
250
227
  body: Buffer.from("hi"),
251
228
  });
@@ -253,16 +230,9 @@ test("a request round-trips with its authority, path and method, and no hop-by-h
253
230
  expect(answer.status).toBe(201);
254
231
  expect(answer.headers["x-target"]).toBe("yes");
255
232
  const seen = JSON.parse(answer.body.toString("utf8")) as Seen;
256
- // The Host the browser used is what the daemon's own listener sees — how a preview, a forwarded port and
257
- // the daemon itself are told apart inside the container.
258
233
  expect(seen).toMatchObject({ method: "PUT", url: "/seen?q=1", host: HOST });
259
234
  expect(seen.headerNames).toContain("x-custom");
260
235
  expect(seen.headerNames).toContain("x-forwarded-proto");
261
- /* Hop-by-hop headers describe ONE hop and are re-derived on each, never forwarded. `connection` is the
262
- * assertion that says so by value: the browser sent `close`, and what reaches the target is the `keep-alive`
263
- * of the daemon's own loopback hop. Asserting merely that the target sees no `connection` would be asserting
264
- * something false — node writes one for its own hop — and would pass just as well if the browser's value had
265
- * been forwarded and then overwritten. */
266
236
  expect(seen.connection).toBe("keep-alive");
267
237
  expect(seen.headerNames).not.toContain("upgrade");
268
238
  expect(seen.headerNames).not.toContain("keep-alive");
@@ -274,8 +244,6 @@ test("a multi-megabyte body survives in both directions, byte for byte", async (
274
244
  const answer = await call("/echo", { method: "POST", body: payload });
275
245
 
276
246
  expect(answer.status).toBe(200);
277
- // The target's own digest of what it received, and ours of what came back: one assertion per direction,
278
- // and neither can pass on a truncated or re-ordered stream.
279
247
  expect(answer.headers["x-sha256"]).toBe(digest(payload));
280
248
  expect(digest(answer.body)).toBe(digest(payload));
281
249
  });
@@ -298,8 +266,6 @@ test("a response is streamed, not buffered: the client reads chunk one before th
298
266
  await secondSent.opened;
299
267
 
300
268
  expect(chunks.join("")).toBe("onetwo");
301
- // Two writes, two reads: coalesced into one would mean the proxy held the first until the body was
302
- // complete, which is the failure this asserts against.
303
269
  expect(chunks.length).toBeGreaterThan(1);
304
270
  });
305
271
 
@@ -336,8 +302,6 @@ test("an upgrade splices raw bytes, carries the far end's own handshake head, an
336
302
  });
337
303
 
338
304
  expect(upgraded.status).toBe(101);
339
- // Computed by the target from the key the browser sent, and therefore proof that the original request
340
- // headers reached it through the CONNECT envelope AND that its answer came back verbatim.
341
305
  expect(upgraded.headers["sec-websocket-accept"]).toBe(digest(Buffer.from(key)));
342
306
  expect(upgraded.headers["x-seen-host"]).toBe(HOST);
343
307
  expect(upgraded.headers["x-seen-path"]).toBe("/socket");
@@ -350,7 +314,6 @@ test("an upgrade splices raw bytes, carries the far end's own handshake head, an
350
314
  upgraded.socket.on("end", () => resolve(read));
351
315
  });
352
316
  upgraded.socket.write("abc");
353
- // Half-close: the far end must see the FIN, answer on the still-open direction, and then end.
354
317
  upgraded.socket.end();
355
318
 
356
319
  expect(await spliced).toBe("echo:abcbye");
@@ -386,15 +349,10 @@ test("a browser that gives up cancels the stream all the way to the target", asy
386
349
  });
387
350
  request.destroy();
388
351
 
389
- // Without the RST_STREAM this asserts, the target keeps generating a response for a browser that is gone,
390
- // for as long as the container lives.
391
352
  await expect(cancelled.opened).resolves.toBe("aborted");
392
353
  });
393
354
 
394
355
  test("a tunnel whose target is not listening fails the exchange rather than answering for it", async () => {
395
- // A port nothing serves: the daemon half cannot reach a listener, so the exchange must fail in a way the
396
- // ingress can turn into its own 502 — the body naming the host label is the ingress's to write, not this
397
- // module's.
398
356
  const dead = createServer();
399
357
  const deadPort = await listen(dead);
400
358
  await new Promise<void>((resolve) => void dead.close(() => resolve()));
@@ -402,8 +360,7 @@ test("a tunnel whose target is not listening fails the exchange rather than answ
402
360
  const [edgeSide, daemonSide] = duplexPair();
403
361
  const daemon = await serveIngressSession(daemonSide, { targetPort: deadPort });
404
362
  const session = await openIngressSession(edgeSide);
405
- // What the ingress needs to be true of the rejection, reported through the answer rather than asserted
406
- // inside a catch nothing awaits: it is free to write a status, so nothing was said to the browser first.
363
+ // True if a status was already written before the rejection handler runs.
407
364
  const said = gate<boolean>();
408
365
  const server = createServer((request, response) => {
409
366
  void session.forwardRequest(request, response).catch(() => {
@@ -429,23 +386,11 @@ test("a tunnel whose target is not listening fails the exchange rather than answ
429
386
  server.close();
430
387
  });
431
388
 
432
- /* THE REGRESSION THIS MODULE'S TRANSPORT EXISTS FOR. Reset a batch of streams that are mid-write and the h2
433
- * session emits control frames on top of writes that have not completed — which, run directly over a Duplex,
434
- * is node's one-write-per-turn JSStreamSocket invariant and an ERR_INTERNAL_ASSERTION out of an internal
435
- * callback. Measured twice over: the process died, AND the RST_STREAM never went out, so the cancellation
436
- * never reached the container.
437
- *
438
- * Driven entirely through the public API, so it keeps pinning the behaviour however the transport is built. If
439
- * someone removes the loopback bridge because "http2 takes a Duplex", this is the test that goes red. */
440
389
  test("a shutdown landing on top of pending writes neither crashes nor wedges the session", async () => {
441
390
  const own = await front((target.address() as AddressInfo).port);
442
391
  const ownPort = await listen(own.server);
443
392
 
444
- /* Eight responses actively writing, each confirmed to be delivering bytes before the shutdown, so node's
445
- * write queue is genuinely non-empty when the GOAWAY is produced. All eight stay live on purpose: an
446
- * earlier version of this test reset half of them first and passed against the broken transport, because
447
- * the resets drained the very pressure the shutdown has to land on top of. (The reset path has its own
448
- * test above; what is being pinned here is a control frame written over pending data.) */
393
+ // All eight stay live: resetting some first would drain the pending-write pressure the shutdown needs to land on.
449
394
  const flooding = Array.from({ length: 8 }, () =>
450
395
  new Promise<void>((resolve) => {
451
396
  const request = h1Request({ host: "127.0.0.1", port: ownPort, path: "/flood", headers: { host: HOST } }, (response) => {
@@ -461,19 +406,12 @@ test("a shutdown landing on top of pending writes neither crashes nor wedges the
461
406
  await new Promise((resolve) => setTimeout(resolve, 400));
462
407
  own.server.close();
463
408
 
464
- /* Two ways to fail, and the suite's own budget is the second one. Run straight over a Duplex this hangs:
465
- * the shutdown frame cannot be written, so `close()` never completes and the tunnel wedges holding every
466
- * stream on it — which is why a hang bound, rather than a duration, is the right report here. */
409
+ // If the shutdown frame can't be written, this hangs; the suite's timeout is the failure signal, not an assertion.
467
410
  expect(uncaught).toStrictEqual([]);
468
- // And the neighbours are untouched: the shared fixture's session still serves.
469
411
  const after = await call("/seen");
470
412
  expect(after.status).toBe(201);
471
413
  });
472
414
 
473
- /* CONTAINMENT: one tunnel's session dying must be one tunnel's problem. The ingress holds every sandbox's
474
- * session in a single process, so a peer that speaks nonsense — a wedged container, a half-open socket that
475
- * came back as garbage, anything that makes nghttp2 give up — is the failure most likely to be shared, and it
476
- * must not be. */
477
415
  test("a poisoned session dies alone and leaves another tunnel serving", async () => {
478
416
  const targetPort = (target.address() as AddressInfo).port;
479
417
  const poisoned = await front(targetPort);
@@ -493,15 +431,12 @@ test("a poisoned session dies alone and leaves another tunnel serving", async ()
493
431
  expect(await through(poisonedPort)).toBe(201);
494
432
  expect(await through(healthyPort)).toBe(201);
495
433
 
496
- // Not an h2 frame by any reading: the session must fail rather than try to interpret it.
434
+ // Not a valid h2 preface; the session must fail rather than parse it.
497
435
  poisoned.poison(Buffer.from("this is not a PRI * HTTP/2.0 preface, nor anything else nghttp2 accepts"));
498
436
  await new Promise((resolve) => setTimeout(resolve, 250));
499
437
 
500
- // The dead session refuses new streams, which the front turns into its 502 — the tunnel is gone, and that
501
- // is a routing fact rather than a crash.
502
438
  expect(await through(poisonedPort)).toBe(502);
503
439
  expect(uncaught).toStrictEqual([]);
504
- // The whole point: the other tunnel never noticed.
505
440
  expect(await through(healthyPort)).toBe(201);
506
441
 
507
442
  poisoned.close();