@intentic/sandbox-contract 1.326.0 → 1.327.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 (537) hide show
  1. package/README.md +24 -12
  2. package/dist/chores/chores.d.ts.map +1 -1
  3. package/dist/chores/chores.js +29 -20
  4. package/dist/chores/chores.js.map +1 -1
  5. package/dist/chores/probes.d.ts +1 -0
  6. package/dist/chores/probes.d.ts.map +1 -1
  7. package/dist/chores/probes.js +81 -12
  8. package/dist/chores/probes.js.map +1 -1
  9. package/dist/contracts/agent.contract.d.ts +1467 -6
  10. package/dist/contracts/agent.contract.d.ts.map +1 -1
  11. package/dist/contracts/agent.contract.js +2 -2
  12. package/dist/contracts/agent.contract.js.map +1 -1
  13. package/dist/contracts/agents.contract.d.ts +1391 -0
  14. package/dist/contracts/agents.contract.d.ts.map +1 -1
  15. package/dist/contracts/agents.contract.js +1 -1
  16. package/dist/contracts/automations.contract.d.ts +123 -4
  17. package/dist/contracts/automations.contract.d.ts.map +1 -1
  18. package/dist/contracts/automations.contract.js +13 -2
  19. package/dist/contracts/automations.contract.js.map +1 -1
  20. package/dist/contracts/capabilities.contract.d.ts +79 -8
  21. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  22. package/dist/contracts/chores.contract.d.ts +2 -0
  23. package/dist/contracts/chores.contract.d.ts.map +1 -1
  24. package/dist/contracts/ci.contract.d.ts +2 -0
  25. package/dist/contracts/ci.contract.d.ts.map +1 -1
  26. package/dist/contracts/device.contract.d.ts +52 -0
  27. package/dist/contracts/device.contract.d.ts.map +1 -1
  28. package/dist/contracts/device.contract.js +2 -0
  29. package/dist/contracts/device.contract.js.map +1 -1
  30. package/dist/contracts/endpoints.contract.d.ts +42 -33
  31. package/dist/contracts/endpoints.contract.d.ts.map +1 -1
  32. package/dist/contracts/endpoints.contract.js +17 -7
  33. package/dist/contracts/endpoints.contract.js.map +1 -1
  34. package/dist/contracts/extensions.contract.d.ts +192 -0
  35. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  36. package/dist/contracts/extensions.contract.js +37 -1
  37. package/dist/contracts/extensions.contract.js.map +1 -1
  38. package/dist/contracts/needs.contract.d.ts +1009 -0
  39. package/dist/contracts/needs.contract.d.ts.map +1 -1
  40. package/dist/contracts/pages.contract.d.ts +34 -0
  41. package/dist/contracts/pages.contract.d.ts.map +1 -0
  42. package/dist/contracts/pages.contract.js +49 -0
  43. package/dist/contracts/pages.contract.js.map +1 -0
  44. package/dist/contracts/phone.contract.d.ts +78 -0
  45. package/dist/contracts/phone.contract.d.ts.map +1 -0
  46. package/dist/contracts/phone.contract.js +11 -0
  47. package/dist/contracts/phone.contract.js.map +1 -0
  48. package/dist/contracts/privacy.contract.d.ts +20 -0
  49. package/dist/contracts/privacy.contract.d.ts.map +1 -1
  50. package/dist/contracts/privacy.contract.js +12 -2
  51. package/dist/contracts/privacy.contract.js.map +1 -1
  52. package/dist/contracts/runner.contract.d.ts +648 -127
  53. package/dist/contracts/runner.contract.d.ts.map +1 -1
  54. package/dist/contracts/runner.contract.js +1 -1
  55. package/dist/contracts/runner.contract.js.map +1 -1
  56. package/dist/contracts/secrets.contract.d.ts +88 -0
  57. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  58. package/dist/contracts/secrets.contract.js +20 -1
  59. package/dist/contracts/secrets.contract.js.map +1 -1
  60. package/dist/contracts/sessions.contract.d.ts +184 -0
  61. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  62. package/dist/contracts/settings.contract.d.ts +16 -58
  63. package/dist/contracts/settings.contract.d.ts.map +1 -1
  64. package/dist/contracts/settings.contract.js +10 -1
  65. package/dist/contracts/settings.contract.js.map +1 -1
  66. package/dist/contracts/system.contract.d.ts +227 -32
  67. package/dist/contracts/system.contract.d.ts.map +1 -1
  68. package/dist/contracts/system.contract.js +18 -1
  69. package/dist/contracts/system.contract.js.map +1 -1
  70. package/dist/documents/conversions.d.ts.map +1 -1
  71. package/dist/documents/conversions.js +2 -1
  72. package/dist/documents/conversions.js.map +1 -1
  73. package/dist/documents/read.d.ts.map +1 -1
  74. package/dist/documents/read.js +4 -4
  75. package/dist/documents/read.js.map +1 -1
  76. package/dist/events/agent-events.d.ts +747 -1
  77. package/dist/events/agent-events.d.ts.map +1 -1
  78. package/dist/events/agent-events.js +14 -1
  79. package/dist/events/agent-events.js.map +1 -1
  80. package/dist/events/requests.d.ts +40 -0
  81. package/dist/events/requests.d.ts.map +1 -1
  82. package/dist/events/requests.js +39 -0
  83. package/dist/events/requests.js.map +1 -1
  84. package/dist/events/system-events.d.ts +120 -0
  85. package/dist/events/system-events.d.ts.map +1 -1
  86. package/dist/events/transcript.d.ts +1131 -1
  87. package/dist/events/transcript.d.ts.map +1 -1
  88. package/dist/events/transcript.js +9 -1
  89. package/dist/events/transcript.js.map +1 -1
  90. package/dist/ids/hostnames.d.ts +2 -0
  91. package/dist/ids/hostnames.d.ts.map +1 -1
  92. package/dist/ids/hostnames.js +18 -15
  93. package/dist/ids/hostnames.js.map +1 -1
  94. package/dist/ids/sandbox-id.d.ts +2 -0
  95. package/dist/ids/sandbox-id.d.ts.map +1 -0
  96. package/dist/ids/sandbox-id.js +2 -0
  97. package/dist/ids/sandbox-id.js.map +1 -0
  98. package/dist/ids/tunnel-ids.d.ts +1 -1
  99. package/dist/ids/tunnel-ids.d.ts.map +1 -1
  100. package/dist/ids/tunnel-ids.js +1 -1
  101. package/dist/ids/tunnel-ids.js.map +1 -1
  102. package/dist/index.d.ts +4902 -177
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +25 -9
  105. package/dist/index.js.map +1 -1
  106. package/dist/models/agent-catalog.d.ts +0 -1
  107. package/dist/models/agent-catalog.d.ts.map +1 -1
  108. package/dist/models/agent-catalog.js +0 -1
  109. package/dist/models/agent-catalog.js.map +1 -1
  110. package/dist/models/agent-runtimes.d.ts +1 -1
  111. package/dist/models/agent-runtimes.d.ts.map +1 -1
  112. package/dist/models/agent-runtimes.js +1 -1
  113. package/dist/models/agent-runtimes.js.map +1 -1
  114. package/dist/models/provider-specs.d.ts +1 -0
  115. package/dist/models/provider-specs.d.ts.map +1 -1
  116. package/dist/models/provider-specs.js +11 -0
  117. package/dist/models/provider-specs.js.map +1 -1
  118. package/dist/netd/browser-wire.d.ts.map +1 -0
  119. package/dist/netd/browser-wire.js.map +1 -0
  120. package/dist/{front → netd}/generated/browser-wire.d.ts +8 -0
  121. package/dist/netd/generated/browser-wire.d.ts.map +1 -0
  122. package/dist/netd/generated/browser-wire.js.map +1 -0
  123. package/dist/{front → netd}/generated/wire.d.ts +20 -11
  124. package/dist/netd/generated/wire.d.ts.map +1 -0
  125. package/dist/{front → netd}/generated/wire.js.map +1 -1
  126. package/dist/netd/netd-wire.d.ts +9 -0
  127. package/dist/netd/netd-wire.d.ts.map +1 -0
  128. package/dist/netd/netd-wire.js +8 -0
  129. package/dist/netd/netd-wire.js.map +1 -0
  130. package/dist/policy/credential-material.d.ts +2 -0
  131. package/dist/policy/credential-material.d.ts.map +1 -1
  132. package/dist/policy/credential-material.js +14 -8
  133. package/dist/policy/credential-material.js.map +1 -1
  134. package/dist/policy/message-limits.d.ts +14 -0
  135. package/dist/policy/message-limits.d.ts.map +1 -0
  136. package/dist/policy/message-limits.js +15 -0
  137. package/dist/policy/message-limits.js.map +1 -0
  138. package/dist/policy/request-status.d.ts.map +1 -1
  139. package/dist/policy/request-status.js +9 -1
  140. package/dist/policy/request-status.js.map +1 -1
  141. package/dist/policy/reserved-servers.d.ts.map +1 -1
  142. package/dist/policy/reserved-servers.js +1 -0
  143. package/dist/policy/reserved-servers.js.map +1 -1
  144. package/dist/policy/turned-away.d.ts.map +1 -1
  145. package/dist/policy/turned-away.js +2 -0
  146. package/dist/policy/turned-away.js.map +1 -1
  147. package/dist/protocol/container-requirements.d.ts.map +1 -1
  148. package/dist/protocol/container-requirements.js +3 -4
  149. package/dist/protocol/container-requirements.js.map +1 -1
  150. package/dist/protocol/doors/host-protocol.d.ts.map +1 -0
  151. package/dist/protocol/doors/host-protocol.js.map +1 -0
  152. package/dist/protocol/{listener-protocol.d.ts → doors/listener-protocol.d.ts} +22 -0
  153. package/dist/protocol/doors/listener-protocol.d.ts.map +1 -0
  154. package/dist/protocol/doors/listener-protocol.js +38 -0
  155. package/dist/protocol/doors/listener-protocol.js.map +1 -0
  156. package/dist/protocol/doors/phone-links.d.ts +16 -0
  157. package/dist/protocol/doors/phone-links.d.ts.map +1 -0
  158. package/dist/protocol/doors/phone-links.js +28 -0
  159. package/dist/protocol/doors/phone-links.js.map +1 -0
  160. package/dist/protocol/doors/phone-protocol.d.ts +47 -0
  161. package/dist/protocol/doors/phone-protocol.d.ts.map +1 -0
  162. package/dist/protocol/doors/phone-protocol.js +33 -0
  163. package/dist/protocol/doors/phone-protocol.js.map +1 -0
  164. package/dist/protocol/doors/runner-protocol.d.ts.map +1 -0
  165. package/dist/protocol/{runner-protocol.js → doors/runner-protocol.js} +1 -1
  166. package/dist/protocol/doors/runner-protocol.js.map +1 -0
  167. package/dist/protocol/{webext-links.d.ts → doors/webext-links.d.ts} +1 -0
  168. package/dist/protocol/doors/webext-links.d.ts.map +1 -0
  169. package/dist/protocol/{webext-links.js → doors/webext-links.js} +1 -0
  170. package/dist/protocol/doors/webext-links.js.map +1 -0
  171. package/dist/protocol/doors/webext-protocol.d.ts.map +1 -0
  172. package/dist/protocol/doors/webext-protocol.js.map +1 -0
  173. package/dist/protocol/edge-verdict.d.ts +1 -1
  174. package/dist/protocol/edge-verdict.d.ts.map +1 -1
  175. package/dist/protocol/headers.d.ts +4 -0
  176. package/dist/protocol/headers.d.ts.map +1 -0
  177. package/dist/protocol/headers.js +4 -0
  178. package/dist/protocol/headers.js.map +1 -0
  179. package/dist/protocol/ingress-contract.d.ts +1 -1
  180. package/dist/protocol/ingress-contract.d.ts.map +1 -1
  181. package/dist/protocol/ingress-contract.js +1 -5
  182. package/dist/protocol/ingress-contract.js.map +1 -1
  183. package/dist/protocol/peer-dial.d.ts.map +1 -1
  184. package/dist/protocol/peer-dial.js +18 -36
  185. package/dist/protocol/peer-dial.js.map +1 -1
  186. package/dist/protocol/raw/extension-protocol.d.ts +47 -0
  187. package/dist/protocol/raw/extension-protocol.d.ts.map +1 -0
  188. package/dist/protocol/raw/extension-protocol.js +32 -0
  189. package/dist/protocol/raw/extension-protocol.js.map +1 -0
  190. package/dist/protocol/raw/raw-json-routes.d.ts +855 -0
  191. package/dist/protocol/raw/raw-json-routes.d.ts.map +1 -0
  192. package/dist/protocol/raw/raw-json-routes.js +28 -0
  193. package/dist/protocol/raw/raw-json-routes.js.map +1 -0
  194. package/dist/protocol/{raw-routes.d.ts → raw/raw-routes.d.ts} +50 -3
  195. package/dist/protocol/raw/raw-routes.d.ts.map +1 -0
  196. package/dist/protocol/{raw-routes.js → raw/raw-routes.js} +17 -3
  197. package/dist/protocol/raw/raw-routes.js.map +1 -0
  198. package/dist/protocol/raw/route-path.d.ts +3 -0
  199. package/dist/protocol/raw/route-path.d.ts.map +1 -0
  200. package/dist/protocol/raw/route-path.js +8 -0
  201. package/dist/protocol/raw/route-path.js.map +1 -0
  202. package/dist/protocol/route-meta.d.ts +1 -1
  203. package/dist/protocol/route-meta.d.ts.map +1 -1
  204. package/dist/protocol/routes.d.ts +1 -0
  205. package/dist/protocol/routes.d.ts.map +1 -1
  206. package/dist/protocol/routes.js +8 -0
  207. package/dist/protocol/routes.js.map +1 -1
  208. package/dist/protocol/sse.d.ts +2 -1
  209. package/dist/protocol/sse.d.ts.map +1 -1
  210. package/dist/protocol/sse.js +23 -12
  211. package/dist/protocol/sse.js.map +1 -1
  212. package/dist/protocol/tunnel-bulk.js +1 -1
  213. package/dist/protocol/tunnel-bulk.js.map +1 -1
  214. package/dist/protocol/vitals.d.ts +2 -1
  215. package/dist/protocol/vitals.d.ts.map +1 -1
  216. package/dist/protocol/vitals.js +1 -0
  217. package/dist/protocol/vitals.js.map +1 -1
  218. package/dist/schemas/activity.d.ts +1 -0
  219. package/dist/schemas/activity.d.ts.map +1 -1
  220. package/dist/schemas/activity.js.map +1 -1
  221. package/dist/schemas/agent.d.ts +6 -0
  222. package/dist/schemas/agent.d.ts.map +1 -1
  223. package/dist/schemas/agent.js +9 -4
  224. package/dist/schemas/agent.js.map +1 -1
  225. package/dist/schemas/agents-list.d.ts +404 -0
  226. package/dist/schemas/agents-list.d.ts.map +1 -0
  227. package/dist/schemas/agents-list.js +14 -0
  228. package/dist/schemas/agents-list.js.map +1 -0
  229. package/dist/schemas/agents.d.ts +203 -0
  230. package/dist/schemas/agents.d.ts.map +1 -1
  231. package/dist/schemas/agents.js +44 -0
  232. package/dist/schemas/agents.js.map +1 -1
  233. package/dist/schemas/automations.d.ts +235 -347
  234. package/dist/schemas/automations.d.ts.map +1 -1
  235. package/dist/schemas/automations.js +82 -13
  236. package/dist/schemas/automations.js.map +1 -1
  237. package/dist/schemas/capabilities.d.ts +43 -8
  238. package/dist/schemas/capabilities.d.ts.map +1 -1
  239. package/dist/schemas/capabilities.js +6 -2
  240. package/dist/schemas/capabilities.js.map +1 -1
  241. package/dist/schemas/ci.d.ts +4 -0
  242. package/dist/schemas/ci.d.ts.map +1 -1
  243. package/dist/schemas/ci.js +8 -0
  244. package/dist/schemas/ci.js.map +1 -1
  245. package/dist/schemas/devices.d.ts +67 -0
  246. package/dist/schemas/devices.d.ts.map +1 -1
  247. package/dist/schemas/devices.js +8 -0
  248. package/dist/schemas/devices.js.map +1 -1
  249. package/dist/schemas/engines.d.ts +57 -0
  250. package/dist/schemas/engines.d.ts.map +1 -1
  251. package/dist/schemas/engines.js +4 -0
  252. package/dist/schemas/engines.js.map +1 -1
  253. package/dist/schemas/extension-updates.d.ts +329 -0
  254. package/dist/schemas/extension-updates.d.ts.map +1 -1
  255. package/dist/schemas/extension-updates.js +68 -3
  256. package/dist/schemas/extension-updates.js.map +1 -1
  257. package/dist/schemas/git/git.d.ts +11 -0
  258. package/dist/schemas/git/git.d.ts.map +1 -1
  259. package/dist/schemas/git/git.js +4 -4
  260. package/dist/schemas/git/git.js.map +1 -1
  261. package/dist/schemas/history.d.ts +2 -0
  262. package/dist/schemas/history.d.ts.map +1 -1
  263. package/dist/schemas/history.js.map +1 -1
  264. package/dist/schemas/hosts.d.ts +74 -0
  265. package/dist/schemas/hosts.d.ts.map +1 -1
  266. package/dist/schemas/hosts.js +10 -1
  267. package/dist/schemas/hosts.js.map +1 -1
  268. package/dist/schemas/loopback-catch.d.ts +1 -0
  269. package/dist/schemas/loopback-catch.d.ts.map +1 -1
  270. package/dist/schemas/loopback-catch.js +1 -0
  271. package/dist/schemas/loopback-catch.js.map +1 -1
  272. package/dist/schemas/maintenance.d.ts +8 -0
  273. package/dist/schemas/maintenance.d.ts.map +1 -1
  274. package/dist/schemas/maintenance.js +6 -0
  275. package/dist/schemas/maintenance.js.map +1 -1
  276. package/dist/schemas/members.d.ts +58 -0
  277. package/dist/schemas/members.d.ts.map +1 -0
  278. package/dist/schemas/members.js +16 -0
  279. package/dist/schemas/members.js.map +1 -0
  280. package/dist/schemas/metrics.d.ts +10 -0
  281. package/dist/schemas/metrics.d.ts.map +1 -1
  282. package/dist/schemas/metrics.js +19 -3
  283. package/dist/schemas/metrics.js.map +1 -1
  284. package/dist/schemas/needs.d.ts +1159 -1
  285. package/dist/schemas/needs.d.ts.map +1 -1
  286. package/dist/schemas/needs.js +25 -3
  287. package/dist/schemas/needs.js.map +1 -1
  288. package/dist/schemas/offload.js +1 -1
  289. package/dist/schemas/offload.js.map +1 -1
  290. package/dist/schemas/peer-enrollment.d.ts +7 -0
  291. package/dist/schemas/peer-enrollment.d.ts.map +1 -0
  292. package/dist/schemas/peer-enrollment.js +6 -0
  293. package/dist/schemas/peer-enrollment.js.map +1 -0
  294. package/dist/schemas/phone.d.ts +231 -0
  295. package/dist/schemas/phone.d.ts.map +1 -0
  296. package/dist/schemas/phone.js +57 -0
  297. package/dist/schemas/phone.js.map +1 -0
  298. package/dist/schemas/privacy.d.ts +41 -0
  299. package/dist/schemas/privacy.d.ts.map +1 -1
  300. package/dist/schemas/privacy.js +20 -3
  301. package/dist/schemas/privacy.js.map +1 -1
  302. package/dist/schemas/project-delivery.d.ts +94 -0
  303. package/dist/schemas/project-delivery.d.ts.map +1 -0
  304. package/dist/schemas/project-delivery.js +35 -0
  305. package/dist/schemas/project-delivery.js.map +1 -0
  306. package/dist/schemas/providers/plan-limits.d.ts +7 -0
  307. package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
  308. package/dist/schemas/providers/plan-limits.js +22 -1
  309. package/dist/schemas/providers/plan-limits.js.map +1 -1
  310. package/dist/schemas/providers/usage.d.ts +1 -2
  311. package/dist/schemas/providers/usage.d.ts.map +1 -1
  312. package/dist/schemas/providers/usage.js +1 -2
  313. package/dist/schemas/providers/usage.js.map +1 -1
  314. package/dist/schemas/push.d.ts +1 -0
  315. package/dist/schemas/push.d.ts.map +1 -1
  316. package/dist/schemas/push.js.map +1 -1
  317. package/dist/schemas/secrets.d.ts +99 -0
  318. package/dist/schemas/secrets.d.ts.map +1 -1
  319. package/dist/schemas/secrets.js +34 -3
  320. package/dist/schemas/secrets.js.map +1 -1
  321. package/dist/schemas/settings-history.d.ts +1 -1
  322. package/dist/schemas/settings-history.d.ts.map +1 -1
  323. package/dist/schemas/settings-history.js +1 -0
  324. package/dist/schemas/settings-history.js.map +1 -1
  325. package/dist/schemas/settings.d.ts +13 -58
  326. package/dist/schemas/settings.d.ts.map +1 -1
  327. package/dist/schemas/settings.js +8 -13
  328. package/dist/schemas/settings.js.map +1 -1
  329. package/dist/schemas/terminal.d.ts +32 -0
  330. package/dist/schemas/terminal.d.ts.map +1 -1
  331. package/dist/schemas/terminal.js +37 -0
  332. package/dist/schemas/terminal.js.map +1 -1
  333. package/dist/schemas/updates.d.ts +1 -0
  334. package/dist/schemas/updates.d.ts.map +1 -1
  335. package/dist/schemas/updates.js +4 -0
  336. package/dist/schemas/updates.js.map +1 -1
  337. package/dist/schemas/workspace/workspace-search.d.ts +1 -0
  338. package/dist/schemas/workspace/workspace-search.d.ts.map +1 -1
  339. package/dist/schemas/workspace/workspace-search.js.map +1 -1
  340. package/dist/schemas/workspace/workspace-tree.d.ts +3 -0
  341. package/dist/schemas/workspace/workspace-tree.d.ts.map +1 -1
  342. package/dist/schemas/workspace/workspace-tree.js +22 -5
  343. package/dist/schemas/workspace/workspace-tree.js.map +1 -1
  344. package/dist/state/arrival.d.ts +59 -0
  345. package/dist/state/arrival.d.ts.map +1 -1
  346. package/dist/state/arrival.js +17 -0
  347. package/dist/state/arrival.js.map +1 -1
  348. package/dist/state/contract-lock.js +2 -2
  349. package/dist/state/contract-lock.js.map +1 -1
  350. package/dist/state/definition.d.ts +82 -16
  351. package/dist/state/definition.d.ts.map +1 -1
  352. package/dist/state/history-state.d.ts.map +1 -1
  353. package/dist/state/history-state.js +38 -0
  354. package/dist/state/history-state.js.map +1 -1
  355. package/dist/state/runtime-state.d.ts +6 -0
  356. package/dist/state/runtime-state.d.ts.map +1 -1
  357. package/dist/state/runtime-state.js +2 -0
  358. package/dist/state/runtime-state.js.map +1 -1
  359. package/dist/state/workspace-state.d.ts +24 -6
  360. package/dist/state/workspace-state.d.ts.map +1 -1
  361. package/dist/state/workspace-state.js +29 -7
  362. package/dist/state/workspace-state.js.map +1 -1
  363. package/dist/text/embed.d.ts +10 -0
  364. package/dist/text/embed.d.ts.map +1 -1
  365. package/dist/text/embed.js +25 -0
  366. package/dist/text/embed.js.map +1 -1
  367. package/dist/text/pages.d.ts +53 -0
  368. package/dist/text/pages.d.ts.map +1 -0
  369. package/dist/text/pages.js +230 -0
  370. package/dist/text/pages.js.map +1 -0
  371. package/dist/text/transcript-fold.d.ts +1 -0
  372. package/dist/text/transcript-fold.d.ts.map +1 -1
  373. package/dist/text/transcript-fold.js +30 -2
  374. package/dist/text/transcript-fold.js.map +1 -1
  375. package/dist/webext/index.d.ts +3 -2
  376. package/dist/webext/index.d.ts.map +1 -1
  377. package/dist/webext/index.js +3 -2
  378. package/dist/webext/index.js.map +1 -1
  379. package/package.json +77 -22
  380. package/src/chores/chores.ts +41 -21
  381. package/src/chores/{probes.test.ts → probes.integration.test.ts} +134 -1
  382. package/src/chores/probes.ts +128 -14
  383. package/src/chores/verdict.test.ts +29 -0
  384. package/src/contracts/agent.contract.ts +2 -2
  385. package/src/contracts/agents.contract.ts +1 -1
  386. package/src/contracts/automations.contract.ts +19 -1
  387. package/src/contracts/device.contract.ts +5 -0
  388. package/src/contracts/endpoints.contract.ts +32 -26
  389. package/src/contracts/extensions.contract.ts +49 -0
  390. package/src/contracts/pages.contract.ts +61 -0
  391. package/src/contracts/phone.contract.ts +21 -0
  392. package/src/contracts/privacy.contract.ts +13 -1
  393. package/src/contracts/runner.contract.ts +1 -1
  394. package/src/contracts/secrets.contract.ts +25 -0
  395. package/src/contracts/settings.contract.ts +10 -0
  396. package/src/contracts/system.contract.ts +26 -0
  397. package/src/documents/conversions.ts +3 -1
  398. package/src/documents/read.ts +4 -5
  399. package/src/events/agent-events.ts +27 -3
  400. package/src/events/requests.ts +47 -0
  401. package/src/events/transcript.ts +14 -0
  402. package/src/ids/hostnames.fixture.json +14 -10
  403. package/src/ids/hostnames.test.ts +21 -2
  404. package/src/ids/hostnames.ts +34 -15
  405. package/src/ids/sandbox-id.ts +3 -0
  406. package/src/ids/tunnel-ids.ts +1 -2
  407. package/src/index.ts +29 -12
  408. package/src/models/agent-catalog.ts +1 -2
  409. package/src/models/agent-runtimes.ts +12 -6
  410. package/src/models/provider-specs.test.ts +12 -0
  411. package/src/models/provider-specs.ts +16 -0
  412. package/src/{front → netd}/browser-wire.ts +1 -1
  413. package/src/{front → netd}/generated/browser-wire.json +80 -7
  414. package/src/{front → netd}/generated/browser-wire.ts +34 -7
  415. package/src/{front/generated/front-wire.json → netd/generated/netd-wire.json} +103 -41
  416. package/src/{front → netd}/generated/tunnel.json +15 -1
  417. package/src/{front → netd}/generated/wire.ts +26 -21
  418. package/src/netd/netd-wire.ts +24 -0
  419. package/src/{front → netd}/wire-manifests.test.ts +31 -11
  420. package/src/policy/credential-material.ts +39 -11
  421. package/src/policy/message-limits.ts +25 -0
  422. package/src/policy/request-status.ts +10 -1
  423. package/src/policy/reserved-servers.ts +3 -2
  424. package/src/policy/tests/credential-material.test.ts +49 -1
  425. package/src/policy/tests/message-limits.test.ts +27 -0
  426. package/src/policy/tests/reserved-servers.test.ts +3 -3
  427. package/src/policy/turned-away.ts +5 -1
  428. package/src/protocol/container-requirements.ts +4 -5
  429. package/src/protocol/{listener-protocol.ts → doors/listener-protocol.ts} +37 -15
  430. package/src/protocol/doors/phone-links.ts +50 -0
  431. package/src/protocol/doors/phone-protocol.test.ts +136 -0
  432. package/src/protocol/doors/phone-protocol.ts +71 -0
  433. package/src/protocol/{runner-protocol.ts → doors/runner-protocol.ts} +1 -1
  434. package/src/protocol/{webext-links.ts → doors/webext-links.ts} +4 -0
  435. package/src/protocol/edge-verdict.ts +1 -1
  436. package/src/protocol/headers.ts +14 -0
  437. package/src/protocol/ingress-contract.ts +6 -10
  438. package/src/protocol/peer-dial.test.ts +83 -4
  439. package/src/protocol/peer-dial.ts +33 -40
  440. package/src/protocol/raw/extension-protocol.ts +59 -0
  441. package/src/protocol/raw/raw-json-routes.ts +61 -0
  442. package/src/protocol/{raw-routes.ts → raw/raw-routes.ts} +40 -7
  443. package/src/protocol/raw/route-path.ts +13 -0
  444. package/src/protocol/route-meta.ts +4 -4
  445. package/src/protocol/routes.ts +12 -0
  446. package/src/protocol/sse.test.ts +49 -0
  447. package/src/protocol/sse.ts +29 -14
  448. package/src/protocol/tunnel-bulk.test.ts +1 -1
  449. package/src/protocol/tunnel-bulk.ts +2 -2
  450. package/src/protocol/vitals.test.ts +7 -7
  451. package/src/protocol/vitals.ts +12 -7
  452. package/src/schemas/activity.ts +1 -0
  453. package/src/schemas/agent.ts +11 -4
  454. package/src/schemas/agents-list.ts +24 -0
  455. package/src/schemas/agents.ts +71 -2
  456. package/src/schemas/automations.ts +126 -24
  457. package/src/schemas/capabilities.ts +13 -3
  458. package/src/schemas/ci.ts +10 -0
  459. package/src/schemas/devices.ts +24 -0
  460. package/src/schemas/engines.ts +7 -0
  461. package/src/schemas/extension-updates.ts +93 -3
  462. package/src/schemas/git/git.ts +15 -4
  463. package/src/schemas/history.ts +2 -0
  464. package/src/schemas/hosts.ts +23 -1
  465. package/src/schemas/loopback-catch.ts +6 -1
  466. package/src/schemas/maintenance.ts +9 -0
  467. package/src/schemas/members.ts +33 -0
  468. package/src/schemas/metrics.ts +21 -3
  469. package/src/schemas/needs.ts +36 -3
  470. package/src/schemas/offload.ts +1 -1
  471. package/src/schemas/peer-enrollment.ts +14 -0
  472. package/src/schemas/phone.ts +121 -0
  473. package/src/schemas/privacy.ts +36 -7
  474. package/src/schemas/project-delivery.ts +78 -0
  475. package/src/schemas/providers/plan-limits.ts +27 -3
  476. package/src/schemas/providers/usage.ts +3 -3
  477. package/src/schemas/push.ts +1 -0
  478. package/src/schemas/secrets.ts +54 -3
  479. package/src/schemas/settings-history.ts +2 -0
  480. package/src/schemas/settings.ts +20 -22
  481. package/src/schemas/terminal.ts +50 -0
  482. package/src/schemas/updates.test.ts +47 -0
  483. package/src/schemas/updates.ts +4 -0
  484. package/src/schemas/workspace/workspace-search.ts +2 -0
  485. package/src/schemas/workspace/workspace-tree.ts +40 -12
  486. package/src/state/arrival.ts +40 -0
  487. package/src/state/contract-lock.test.ts +1 -1
  488. package/src/state/contract-lock.ts +5 -5
  489. package/src/state/history-state.ts +72 -1
  490. package/src/state/runtime-state.ts +4 -0
  491. package/src/state/workspace-state.ts +65 -20
  492. package/src/text/embed.test.ts +21 -1
  493. package/src/text/embed.ts +50 -3
  494. package/src/text/pages.test.ts +161 -0
  495. package/src/text/pages.ts +344 -0
  496. package/src/text/transcript-fold.test.ts +22 -0
  497. package/src/text/transcript-fold.ts +41 -2
  498. package/src/webext/index.ts +3 -2
  499. package/dist/front/browser-wire.d.ts.map +0 -1
  500. package/dist/front/browser-wire.js.map +0 -1
  501. package/dist/front/front-wire.d.ts +0 -6
  502. package/dist/front/front-wire.d.ts.map +0 -1
  503. package/dist/front/front-wire.js +0 -5
  504. package/dist/front/front-wire.js.map +0 -1
  505. package/dist/front/generated/browser-wire.d.ts.map +0 -1
  506. package/dist/front/generated/browser-wire.js.map +0 -1
  507. package/dist/front/generated/wire.d.ts.map +0 -1
  508. package/dist/protocol/host-protocol.d.ts.map +0 -1
  509. package/dist/protocol/host-protocol.js.map +0 -1
  510. package/dist/protocol/listener-protocol.d.ts.map +0 -1
  511. package/dist/protocol/listener-protocol.js +0 -33
  512. package/dist/protocol/listener-protocol.js.map +0 -1
  513. package/dist/protocol/raw-routes.d.ts.map +0 -1
  514. package/dist/protocol/raw-routes.js.map +0 -1
  515. package/dist/protocol/request-id.d.ts +0 -2
  516. package/dist/protocol/request-id.d.ts.map +0 -1
  517. package/dist/protocol/request-id.js +0 -2
  518. package/dist/protocol/request-id.js.map +0 -1
  519. package/dist/protocol/runner-protocol.d.ts.map +0 -1
  520. package/dist/protocol/runner-protocol.js.map +0 -1
  521. package/dist/protocol/webext-links.d.ts.map +0 -1
  522. package/dist/protocol/webext-links.js.map +0 -1
  523. package/dist/protocol/webext-protocol.d.ts.map +0 -1
  524. package/dist/protocol/webext-protocol.js.map +0 -1
  525. package/src/front/front-wire.ts +0 -15
  526. package/src/protocol/request-id.ts +0 -2
  527. /package/dist/{front → netd}/browser-wire.d.ts +0 -0
  528. /package/dist/{front → netd}/browser-wire.js +0 -0
  529. /package/dist/{front → netd}/generated/browser-wire.js +0 -0
  530. /package/dist/{front → netd}/generated/wire.js +0 -0
  531. /package/dist/protocol/{host-protocol.d.ts → doors/host-protocol.d.ts} +0 -0
  532. /package/dist/protocol/{host-protocol.js → doors/host-protocol.js} +0 -0
  533. /package/dist/protocol/{runner-protocol.d.ts → doors/runner-protocol.d.ts} +0 -0
  534. /package/dist/protocol/{webext-protocol.d.ts → doors/webext-protocol.d.ts} +0 -0
  535. /package/dist/protocol/{webext-protocol.js → doors/webext-protocol.js} +0 -0
  536. /package/src/protocol/{host-protocol.ts → doors/host-protocol.ts} +0 -0
  537. /package/src/protocol/{webext-protocol.ts → doors/webext-protocol.ts} +0 -0
@@ -7,6 +7,7 @@ import { NetdiskConfigSchema } from "./netdisk.js";
7
7
  import { VpnConfigSchema } from "./vpn.js";
8
8
  // One-way: the browser extension bundles webext.js alone, so nothing there may reach back into this file.
9
9
  import { WebExtConfigSchema } from "./webext.js";
10
+ import { PhoneConfigSchema } from "./phone.js";
10
11
  // Everything a user adds is a capability with an idempotent apply plus a status check; the manifest is the source of
11
12
  // truth for what's active, and `mcp`-kind entries also feed the agent's MCP servers each turn.
12
13
 
@@ -26,6 +27,7 @@ export const CapabilityKindSchema = z.enum([
26
27
  "identity",
27
28
  "device",
28
29
  "webext",
30
+ "phone",
29
31
  "agent",
30
32
  "endpoint",
31
33
  "localmodel",
@@ -62,7 +64,9 @@ export const PluginConfigSchema = z.object({
62
64
  .string()
63
65
  .min(1)
64
66
  .optional()
65
- .describe("A branch, tag or commit to install from. Leave it out for the default branch. The install pins the commit it names at that moment."),
67
+ .describe(
68
+ "A branch, tag or commit to install from. Leave it out for the default branch. The install pins the commit it names at that moment.",
69
+ ),
66
70
  path: z
67
71
  .string()
68
72
  .min(1)
@@ -141,7 +145,9 @@ const STASHED_PREFIX = "__intentic_stashed__:";
141
145
  export const stashedMarker = (token: string): string => `${STASHED_PREFIX}${token}`;
142
146
  // The token a marker names; undefined for anything else (a real key, VAULTED, a blank).
143
147
  export const stashedToken = (value: unknown): string | undefined =>
144
- typeof value === "string" && value.startsWith(STASHED_PREFIX) && value.length > STASHED_PREFIX.length ? value.slice(STASHED_PREFIX.length) : undefined;
148
+ typeof value === "string" && value.startsWith(STASHED_PREFIX) && value.length > STASHED_PREFIX.length
149
+ ? value.slice(STASHED_PREFIX.length)
150
+ : undefined;
145
151
  // What is optional about the in-sandbox Docker Engine: `gpu` is an IMAGE option (rides the Dockerfile overlay, needs a
146
152
  // rebuild), everything else is an ENGINE option (rewrites daemon.json, restarts dockerd, no rebuild but stops running
147
153
  // containers). Flat strings, not nested booleans, to match the manifest's own two-state convention.
@@ -326,7 +332,6 @@ export const localModelChoice = (id: string): LocalModelChoice | undefined => LO
326
332
  export const LOCAL_MODEL_INSTANT: LocalModelChoice = LOCAL_MODELS.find((choice) => choice.tier === "instant")!;
327
333
  export const LocalModelConfigSchema = z.object({
328
334
  model: z.string().min(1),
329
- gpu: z.enum(["on", "off"]).default("off"),
330
335
  url: z.url().optional(),
331
336
  context: z.union([z.enum(LOCAL_MODEL_WINDOWS), z.literal("custom")]).default(LOCAL_MODEL_WINDOW_DEFAULT),
332
337
  // Coerced from a text field's string, like the ssh card's `port`; read only when `context` is "custom".
@@ -402,6 +407,10 @@ export const CapabilitySchema = z.discriminatedUnion("kind", [
402
407
  // from `browser`, the sandbox's own Chromium profile: this one is the person's, already signed into everything,
403
408
  // only ever borrowed.
404
409
  z.object({ id: entryId, kind: z.literal("webext"), config: WebExtConfigSchema }),
410
+ // The user's own phone, through the app they installed on it; one capability per phone. Its own kind rather than a
411
+ // `device` platform: a phone has no shell and no home folder, and what it grants (screen, apps, picked folders,
412
+ // notifications) is a different set of switches.
413
+ z.object({ id: entryId, kind: z.literal("phone"), config: PhoneConfigSchema }),
405
414
  z.object({ id: entryId, kind: z.literal("agent"), config: AcpAgentConfigSchema }),
406
415
  // The id becomes `endpoint/<id>` in the chat picker, the `agent` kind's precedent, since these two are the only
407
416
  // kinds that mint providers.
@@ -444,6 +453,7 @@ export const CapabilitySummarySchema = z.object({
444
453
  .default([])
445
454
  .describe("Which credentials it holds, by name. The values are on one route only, and it is not this one."),
446
455
  });
456
+ export type CapabilitySummary = z.infer<typeof CapabilitySummarySchema>;
447
457
  // A capability the workspace asks for but the manifest doesn't carry, derived from what's checked out under /work, not
448
458
  // from configuration; prevents illegible failures like a missing docker socket with no pointer back to the fix. Keyed
449
459
  // by catalog card, not kind, since several cards share one kind. Re-derived on every read, so it drops out once its
package/src/schemas/ci.ts CHANGED
@@ -76,6 +76,16 @@ export const PipelineJobSchema = z.object({
76
76
  .describe(
77
77
  "Which jobs in this run it declared it waits on: the real shape of the pipeline. Absent means nothing could be read, which is different from an empty list, which is the claim that it waits on nothing.",
78
78
  ),
79
+ declaredId: z
80
+ .string()
81
+ .optional()
82
+ .describe(
83
+ "The job's id in its workflow file, with a called workflow's job under its caller as `caller.job`. Present where the workflow could be read; it is what the forge orders its own drawing of the run by.",
84
+ ),
85
+ matrix: z
86
+ .string()
87
+ .optional()
88
+ .describe("The matrix job this is one leg of, by that job's name. Legs of one matrix are drawn together, apart from every other job."),
79
89
  startedAt: z.number().optional().describe("When it began, in milliseconds. Absent while it is queued."),
80
90
  finishedAt: z.number().optional().describe("When it ended, in milliseconds."),
81
91
  durationSeconds: z.number().optional().describe("How long it took."),
@@ -90,6 +90,17 @@ export const DeviceSandboxSchema = z.object({
90
90
  lastUpdate: UpdateOutcomeSchema.optional(),
91
91
  // Newest first: what `rollback` would return to, then the older versions kept on this machine for `rollback --to`.
92
92
  rollbackTargets: z.array(RollbackTargetSchema).optional(),
93
+ // The other side of this computer that keeps it (`windows`, `linux`; from 2026-10-05 `platform/env`, e.g.
94
+ // `linux/archlinux`, so two WSL distros are told apart). On Windows, ic on Windows and ic in WSL drive one Docker
95
+ // engine and each lists every sandbox on it, but only the side whose ic created a sandbox runs its background rounds
96
+ // (keeper, updates, backups, probation); absent for this side's own, and from an older ic.
97
+ keptElsewhere: z.string().optional(),
98
+ // How a person reads that side ("WSL (archlinux)", "Windows").
99
+ keptElsewhereName: z.string().optional(),
100
+ // The side that keeps it has gone silent (its keeper stopped writing `/history/.ic/keeper.json` for half an hour),
101
+ // so this side adopted it for its rounds: `keptElsewhere` is left out, and these say whose it was and since when.
102
+ adoptedFrom: z.string().optional(),
103
+ keeperSilentSince: z.number().optional(),
93
104
  });
94
105
  export type DeviceSandbox = z.infer<typeof DeviceSandboxSchema>;
95
106
  // One operation on one sandbox, streamed as lines ending in a `result` or `error` frame. `prepare` builds the pending
@@ -377,12 +388,21 @@ export const clearableOnDevice = (conflict: DeviceConflict): boolean =>
377
388
  // One paired sandbox as the local agent holds it; `localDir` is which folder on that device holds this sandbox's /work.
378
389
  export const DevicePairingSchema = z.object({
379
390
  sandboxId: z.string(),
391
+ // The account's name for the sandbox, stamped by the editor that reads the report (withSandboxNames), as a
392
+ // container's `name` is. A machine never sends one: all it knows is the folder, named once at setup.
393
+ name: z.string().optional(),
380
394
  mode: z.enum(["sync", "mirror"]),
381
395
  // Set only for mode "sync", and only for the sandbox being reported to.
382
396
  localDir: z.string().optional(),
383
397
  // Which sandbox folder `localDir` holds when it is not /work itself: a project pairing's `/work/<name>`, the
384
398
  // owner's own folder, which carries no state backup and no git bridge. Absent means /work.
385
399
  remoteDir: z.string().optional(),
400
+ // The folderless pairing that holds this machine's sync token for its own local sandbox, which project folders
401
+ // attach to (`intentic-machine sync attach`). Absent on every other pairing.
402
+ projectsHost: z.boolean().optional(),
403
+ // Whether landed work in this project folder is delivered to `localDir` by itself (`deliverProject`). Only a
404
+ // folder attached to the machine's own sandbox says "auto"; absent means Bring back by hand, as before.
405
+ deliver: z.enum(["auto", "off"]).optional(),
386
406
  // Machine-owned switch (agent's own `sync mirror off`); absent reads as "on", not merely unknown.
387
407
  mirroring: z.enum(["on", "off"]).optional(),
388
408
  // Mutagen's own status word, kept verbatim rather than reduced to a traffic light.
@@ -583,6 +603,10 @@ export const DeviceSchema = z.object({
583
603
  // report at all. Absent means nobody could look — a sync-only machine, a refusal, an unread device — never that
584
604
  // the machine holds none.
585
605
  sandboxes: z.array(DeviceSandboxSchema).optional(),
606
+ // Why `sandboxes` is absent, in the machine's own words, when it answered the listing with a refusal or a failure
607
+ // (a switch that is off, an `ic` too old to list). Absent when it listed, or when nothing answered at all. What a
608
+ // card falling back to a command says instead of "connect the computer": that computer IS connected (2026-10-07).
609
+ sandboxesUnread: z.string().optional(),
586
610
  gap: DeviceGapSchema.optional(),
587
611
  });
588
612
  export type Device = z.infer<typeof DeviceSchema>;
@@ -100,3 +100,10 @@ export const EngineAppliedSchema = z.object({
100
100
  // An in-process engine (`@cursor/sdk`) is picked up by the next turn; a running turn keeps its module.
101
101
  fromNextTurn: z.boolean().describe("Whether the change reaches turns already in flight, or only the next one."),
102
102
  });
103
+ // What every engine write answers: what it applied, null when there was nothing to do (a second tab's Update lost the
104
+ // race), and the whole view after it, never a patch to reconcile.
105
+ export const EngineWriteResultSchema = z.object({
106
+ applied: EngineAppliedSchema.nullable(),
107
+ engines: EnginesViewSchema,
108
+ });
109
+ export type EngineWriteResult = z.infer<typeof EngineWriteResultSchema>;
@@ -2,6 +2,7 @@
2
2
  // check found and what the owner decided to do about it.
3
3
  import { z } from "zod";
4
4
  import { ExtensionManifestSchema } from "@intentic/extension-manifest";
5
+ import { RegistryTrustSchema } from "@intentic/registry";
5
6
  // Each extension is addressed by its capability entry id (git-installed) or its manifest's `publisher.name`
6
7
  // (image-baked, no entry), hence the dot allowed here. A rotted checkout is skipped; its capability row still shows
7
8
  // status.
@@ -26,7 +27,8 @@ export const ExtensionUpdateSchema = z.object({
26
27
  version: z.string().optional().describe("What it calls itself."),
27
28
  url: z.string().describe("Where it comes from."),
28
29
  path: z.string().optional().describe("Where inside that repository it lives."),
29
- trust: z.enum(["verified", "listed"]).describe("Whether anybody vouched for it, or it is merely listed."),
30
+ // The registry's trust, less `blocked`: a blocked row is an advisory, never an update on offer.
31
+ trust: RegistryTrustSchema.exclude(["blocked"]).describe("Whether anybody vouched for it, or it is merely listed."),
30
32
  // The badge renders loud (urgent) when this is set.
31
33
  securityFix: z
32
34
  .boolean()
@@ -129,6 +131,42 @@ export const ExtensionUpdatesCheckedSchema = z.object({
129
131
  ok: z.literal(true).describe("The check ran."),
130
132
  checkedAt: z.string().describe("When, so a screen can date the answer."),
131
133
  });
134
+ // Dev mode: an extension installed from a repository, served from a source checkout in this workspace instead of its
135
+ // pinned clone (.intentic/local/extension-dev.json), so a change to its code is seen on reload without being landed.
136
+ // `path` and `conversation` are kept apart rather than joined into one display string: a screen says "in conversation
137
+ // <id>" in its own words.
138
+ export const ExtensionDevSchema = z.object({
139
+ path: z
140
+ .string()
141
+ .describe(
142
+ "The source checkout it was pointed at, such as extensions/maintenance: relative to the workspace, or to the conversation's own copy of it when `conversation` is set.",
143
+ ),
144
+ conversation: z
145
+ .string()
146
+ .optional()
147
+ .describe(
148
+ "The conversation whose isolated copy of the workspace holds that checkout. Absent means the workspace itself. That copy goes when the conversation does, and the pinned version runs again then.",
149
+ ),
150
+ uncommitted: z
151
+ .number()
152
+ .int()
153
+ .nonnegative()
154
+ .optional()
155
+ .describe("How many files in the checkout differ from its last commit, a rebuilt bundle included. Absent when git could not say."),
156
+ revision: z
157
+ .string()
158
+ .optional()
159
+ .describe(
160
+ "A short fingerprint of the browser bundle served from the checkout. It changes with every rebuild, which is how a screen tells the copy it loaded is behind. Absent while held, and for an extension with no browser half.",
161
+ ),
162
+ held: z
163
+ .string()
164
+ .optional()
165
+ .describe(
166
+ "Why the checkout is not what runs, as a sentence: it is gone, holds a different extension, is not built yet, or asks for powers the pinned version was never approved for. Present means the pinned version still runs.",
167
+ ),
168
+ });
169
+ export type ExtensionDev = z.infer<typeof ExtensionDevSchema>;
132
170
  export const ExtensionSummarySchema = z.object({
133
171
  id: extensionId.describe("The extension's id."),
134
172
  manifest: ExtensionManifestSchema.describe("What it declares about itself: what it contributes, what it needs, and what it may reach."),
@@ -166,9 +204,9 @@ export const ExtensionSummarySchema = z.object({
166
204
  backend: z
167
205
  .object({
168
206
  state: z
169
- .enum(["running", "error", "absent", "incompatible", "starting", "stopped"])
207
+ .enum(["running", "degraded", "error", "absent", "incompatible", "starting", "stopped"])
170
208
  .describe(
171
- "How its server half is doing. Absent means the code is not in this image at all; incompatible means it needs a different sandbox version.",
209
+ "How its server half is doing. Degraded means it serves but says something it relies on is not working; absent means the code is not in this image at all; incompatible means it needs a different sandbox version.",
172
210
  ),
173
211
  detail: z
174
212
  .string()
@@ -204,8 +242,60 @@ export const ExtensionSummarySchema = z.object({
204
242
  updatePolicy: ExtensionUpdatePolicySchema.optional().describe(
205
243
  "The owner's standing answer for this one: tell me, have an agent look, or just do it.",
206
244
  ),
245
+ dev: ExtensionDevSchema.optional().describe(
246
+ "Set while an extension installed from a repository is pointed at a source checkout in this workspace, for working on the extension itself: its code is served from there instead of the pinned copy. `commit` keeps naming the pinned version, which is what updates and the registry compare against.",
247
+ ),
207
248
  });
208
249
  export type ExtensionSummary = z.infer<typeof ExtensionSummarySchema>;
250
+ // The dev-mode verbs address an installed extension any of the ways a person names one.
251
+ const devTarget = z
252
+ .string()
253
+ .min(1)
254
+ .describe(
255
+ "Which installed extension: its connection id (intentic-maintenance), its manifest id (intentic.maintenance) or its short name (maintenance).",
256
+ );
257
+ export const ExtensionDevSetInputSchema = z.object({
258
+ id: devTarget,
259
+ path: z
260
+ .string()
261
+ .min(1)
262
+ .optional()
263
+ .describe(
264
+ "The checkout to run it from. From an agent in an isolated conversation, a relative or /work path reads against that conversation's own copy. Absent: the workspace repository cloned from the address it was installed from, the calling conversation's copy first.",
265
+ ),
266
+ });
267
+ export const ExtensionDevTargetSchema = z.object({ id: devTarget });
268
+ export const ExtensionDevStateSchema = z.object({
269
+ id: extensionId.describe("Its connection id."),
270
+ name: z.string().describe("Its manifest id, publisher.name."),
271
+ dev: ExtensionDevSchema.describe("Where it runs from now, or why the pinned version still runs."),
272
+ });
273
+ export const ExtensionDevClearedSchema = z.object({
274
+ id: extensionId.describe("Its connection id."),
275
+ name: z.string().describe("Its manifest id, publisher.name."),
276
+ cleared: z.boolean().describe("Whether it was pointed at a checkout. False means it already ran its pinned version and nothing changed."),
277
+ });
278
+ export const ExtensionDevListSchema = z.object({
279
+ extensions: z
280
+ .array(
281
+ z.object({
282
+ id: extensionId.describe("Its connection id."),
283
+ name: z.string().describe("Its manifest id, publisher.name."),
284
+ commit: z.string().describe("The pinned commit, in full."),
285
+ dev: ExtensionDevSchema.optional().describe("Present while it is pointed at a source checkout."),
286
+ checkout: z
287
+ .object({
288
+ path: z.string().describe("Relative to the workspace, or to the conversation's copy of it when `conversation` is set."),
289
+ conversation: z.string().optional().describe("Set when the calling conversation's own copy is the one found."),
290
+ })
291
+ .optional()
292
+ .describe(
293
+ "A checkout of its source repository in the workspace, which is where a change to it belongs. Absent when the workspace has none.",
294
+ ),
295
+ }),
296
+ )
297
+ .describe("Every extension installed from a repository. Built-in and workspace extensions are not here: they already run from their source."),
298
+ });
209
299
  // Read by both the Extensions tab and an authoring agent off GET /extensions.
210
300
  export const InvalidWorkspaceExtensionSchema = z.object({
211
301
  dir: z.string().describe("Which folder."),
@@ -13,6 +13,10 @@ import { RepoParamSchema } from "../shared.js";
13
13
  export const GitDiffSideSchema = z.enum(["staged", "unstaged", "conflicted"]);
14
14
  export type GitDiffSide = z.infer<typeof GitDiffSideSchema>;
15
15
 
16
+ // The origin that names the files no conversation landed: the owner's own edits, a terminal's, anything unattributed.
17
+ // Not a conversation id, so no session uuid can collide with it.
18
+ export const UNATTRIBUTED_ORIGIN = "yours";
19
+
16
20
  // What a bulk git action applies to, never simply a list of paths (unbounded, unlike a review's rows).
17
21
  // paths: exactly these, from a list a browser already drew.
18
22
  // scope: a description the daemon resolves against live status, so nothing here can be stale.
@@ -26,7 +30,9 @@ export const GitScopeSchema = z.object({
26
30
  .string()
27
31
  .min(1)
28
32
  .optional()
29
- .describe("Narrow to the files one conversation landed. Leave it out for everyone's, including your own edits."),
33
+ .describe(
34
+ `Narrow to the files one conversation landed, or "${UNATTRIBUTED_ORIGIN}" for the files none landed. Leave it out for everyone's, including your own edits.`,
35
+ ),
30
36
  });
31
37
  export type GitScope = z.infer<typeof GitScopeSchema>;
32
38
 
@@ -135,15 +141,19 @@ export const RepoTargetSchema = z
135
141
  .extend(GitTargetSchema.shape)
136
142
  .refine(oneTarget, ONE_TARGET);
137
143
  export type RepoTarget = z.infer<typeof RepoTargetSchema>;
144
+ // Git's vocabulary for what happened to a file, the one every change list, diff tab and status letter reads. Conflicted is
145
+ // git's unmerged state (`U`), not a kind of modification.
146
+ export const ChangeStatusSchema = z.enum(["added", "modified", "deleted", "renamed", "type-changed", "conflicted"]);
147
+ export type ChangeStatus = z.infer<typeof ChangeStatusSchema>;
138
148
  // One change to a file: an uncommitted working-tree change, an agent worktree's delta vs its base, or a file in a
139
149
  // commit. `additions`/`deletions` are numstat counts, absent for binary or untracked files.
140
150
  export const GitChangeSchema = z.object({
141
151
  // Forward slashes; for a rename this is the new path (`from` holds the old one).
142
152
  path: z.string().describe("The path, relative to the repository root. For a rename this is the new one."),
143
153
  // Git's unmerged state (`U`): stages 2/3 hold "ours"/"theirs", no stage 0 to commit.
144
- status: z
145
- .enum(["added", "modified", "deleted", "renamed", "type-changed", "conflicted"])
146
- .describe("What happened to it. Conflicted is not a kind of edit: nothing can be committed anywhere in the repository while one exists."),
154
+ status: ChangeStatusSchema.describe(
155
+ "What happened to it. Conflicted is not a kind of edit: nothing can be committed anywhere in the repository while one exists.",
156
+ ),
147
157
  from: z.string().optional().describe("Where a renamed file came from."),
148
158
  additions: z
149
159
  .number()
@@ -208,6 +218,7 @@ export const GitBranchesSchema = z.object({
208
218
  .array(GitRemoteBranchSchema)
209
219
  .describe("Branches on its remotes, as last seen. Sent together with the locals so a switcher never draws a half-filled list."),
210
220
  });
221
+ export type GitBranches = z.infer<typeof GitBranchesSchema>;
211
222
  // Creates at `start` (sha or ref; absent means HEAD); `checkout` switches to it immediately.
212
223
  export const GitBranchCreateAtSchema = RepoParamSchema.extend({
213
224
  name: RefNameSchema.describe("The new branch's name."),
@@ -24,6 +24,7 @@ export interface SnapshotTurn {
24
24
  readonly index: number;
25
25
  }
26
26
  export const SnapshotsListSchema = z.object({ snapshots: z.array(SnapshotSchema).describe("Every point you can go back to, newest first.") });
27
+ export type SnapshotsList = z.infer<typeof SnapshotsListSchema>;
27
28
  // Restores the workspace to that turn's checkpoint, drops every message after it, and forgets the provider session so
28
29
  // the next turn opens fresh. `messageId` is what makes `index` safe to act on: a position is only as current as the
29
30
  // transcript it was read from.
@@ -65,6 +66,7 @@ export type SnapshotChange = z.infer<typeof SnapshotChangeSchema>;
65
66
  export const SnapshotDiffSchema = z.object({
66
67
  changes: z.array(SnapshotChangeSchema).describe("Everything that differs between this saved point and the one before it."),
67
68
  });
69
+ export type SnapshotDiff = z.infer<typeof SnapshotDiffSchema>;
68
70
  export const SnapshotFileDiffQuerySchema = z.object({
69
71
  id: z.string().min(1).describe("Which saved point."),
70
72
  scope: z.string().min(1).describe("Which part of the workspace the path belongs to."),
@@ -20,6 +20,22 @@ export const MachineIdSchema = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{7,1
20
20
  export const derivedMachineId = (card: string): string => `card:${card}`;
21
21
  export const isDerivedMachineId = (machineId: string): boolean => machineId.startsWith("card:");
22
22
 
23
+ // How many skipped lines an agent sends in its upkeep summary at most; the counts cover the rest.
24
+ export const UPKEEP_SKIPPED_SHOWN = 10;
25
+
26
+ // What the machine agent's own upkeep found in this environment at its last pass (its device reconciler, run at start
27
+ // and every six hours): how many leftovers of each kind it found and how many it put right, and the first
28
+ // UPKEEP_SKIPPED_SHOWN of those it left, each with why. Kinds are the agent's words (`retired-files`, `trash`,
29
+ // `login-entry`…), read as strings, so a kind a newer agent adds is one more key rather than a facts row that fails to
30
+ // parse; for the same reason the cap on `skipped` is the sender's, not checked here. `at` is epoch ms.
31
+ export const DeviceUpkeepSchema = z.object({
32
+ at: z.number(),
33
+ found: z.record(z.string(), z.number()),
34
+ fixed: z.record(z.string(), z.number()),
35
+ skipped: z.array(z.object({ kind: z.string(), what: z.string(), why: z.string() })),
36
+ });
37
+ export type DeviceUpkeep = z.infer<typeof DeviceUpkeepSchema>;
38
+
23
39
  // What a machine reports once at connect (`host.describe`), cached until it reconnects: the skill pack says how to
24
40
  // drive Windows, this says which Windows it is.
25
41
  export const DeviceFactsSchema = z.object({
@@ -57,6 +73,9 @@ export const DeviceFactsSchema = z.object({
57
73
  // what explains `features` missing what this agent's release has (a stale ic has no logs verb and no `--set`).
58
74
  // Absent when ic is current, and from an agent older than the field.
59
75
  icOutOfDate: z.string().optional(),
76
+ // The agent's last upkeep pass in this environment (DeviceUpkeepSchema): whether a release brought this machine to
77
+ // the current shape, read rather than assumed. Absent before the first pass, and from an agent older than the field.
78
+ upkeep: DeviceUpkeepSchema.optional(),
60
79
  });
61
80
  export type DeviceFacts = z.infer<typeof DeviceFactsSchema>;
62
81
 
@@ -75,13 +94,16 @@ export type DeviceFacts = z.infer<typeof DeviceFactsSchema>;
75
94
  // - `background-prepare`: the `prepare-background` op, the next update downloaded under the unattended rules of the
76
95
  // agent's own timer (`ic sandbox prepare --auto`), which the update card sends when it opens; advertised only when
77
96
  // the agent's `ic sandbox prepare` takes `--auto`.
78
- export const DeviceFeatureSchema = z.enum(["reshape-later", "set-shape", "rollback-to", "loopback-catch", "background-prepare"]);
97
+ // - `project-delivery`: the `deliverProject` procedure, landed work written into a folder attached to this computer's
98
+ // sandbox (project-delivery.ts); an agent without it is never sent one, and the land waits for Bring back.
99
+ export const DeviceFeatureSchema = z.enum(["reshape-later", "set-shape", "rollback-to", "loopback-catch", "background-prepare", "project-delivery"]);
79
100
  export type DeviceFeature = z.infer<typeof DeviceFeatureSchema>;
80
101
  export const DEVICE_FEATURE_RESHAPE_LATER: DeviceFeature = "reshape-later";
81
102
  export const DEVICE_FEATURE_SET_SHAPE: DeviceFeature = "set-shape";
82
103
  export const DEVICE_FEATURE_ROLLBACK_TO: DeviceFeature = "rollback-to";
83
104
  export const DEVICE_FEATURE_LOOPBACK_CATCH: DeviceFeature = "loopback-catch";
84
105
  export const DEVICE_FEATURE_BACKGROUND_PREPARE: DeviceFeature = "background-prepare";
106
+ export const DEVICE_FEATURE_PROJECT_DELIVERY: DeviceFeature = "project-delivery";
85
107
  // The features an agent advertised that this build knows; an unknown one is a newer agent's and means nothing here.
86
108
  export const deviceFeatures = (facts: Pick<DeviceFacts, "features"> | undefined): DeviceFeature[] =>
87
109
  (facts?.features ?? []).flatMap((feature) => {
@@ -17,7 +17,8 @@ export const LoopbackCatchSchema = object({
17
17
  port: number().int().min(1).max(65535),
18
18
  // The path only, leading slash included; the query is the grant and is never matched.
19
19
  path: string().startsWith("/"),
20
- // Epoch ms; a catcher stops watching by itself here even if nobody aborts the stream.
20
+ // Epoch ms; a catcher stops watching by itself here even if nobody aborts the stream, and never later than
21
+ // LOOPBACK_CATCH_LONGEST_MS after it starts, however far away this is.
21
22
  expiresAt: number(),
22
23
  // Who the page thanks once the browser lands ("Claude"), so the tab says what just happened.
23
24
  title: string().min(1),
@@ -34,6 +35,10 @@ export const LoopbackCatchEventSchema = discriminatedUnion("type", [
34
35
  ]);
35
36
  export type LoopbackCatchEvent = z.infer<typeof LoopbackCatchEventSchema>;
36
37
 
38
+ // The longest any catcher watches, whatever `expiresAt` asks: a forgotten catch must not hold a port (a device) or a
39
+ // tab listener (a browser) for as long as a sandbox happened to ask. Both peers apply it, through `watchQueue`.
40
+ export const LOOPBACK_CATCH_LONGEST_MS = 30 * 60_000;
41
+
37
42
  // Advertised in a device's `features` and a browser's facts; only a peer that says it is asked.
38
43
  export const LOOPBACK_CATCH_FEATURE = "loopback-catch";
39
44
 
@@ -8,6 +8,13 @@ import { WorkspaceHotspotSchema, WorkspaceKeyModuleSchema } from "./codebase-hea
8
8
  export const PROBE_IDS = ["outdated", "audit", "knip", "jscpd", "ui", "bundle", "mutation"] as const;
9
9
  export const ProbeIdSchema = z.enum(PROBE_IDS);
10
10
  export type ProbeId = z.infer<typeof ProbeIdSchema>;
11
+ // Absent for the repo's own pnpm workspace, so every finding recorded before this field existed still reads right.
12
+ const StandaloneSchema = z
13
+ .string()
14
+ .optional()
15
+ .describe(
16
+ "The folder that declares it, when that folder is a package the pnpm workspace leaves out and installs on its own (the iOS shell, built with npm on a Mac). The fix goes in that folder's package.json, not the workspace catalog.",
17
+ );
11
18
  // `kind` is the semver distance; that's why this isn't collapsed to one number.
12
19
  export const OutdatedPackageSchema = z.object({
13
20
  name: z.string().describe("The dependency."),
@@ -22,6 +29,7 @@ export const OutdatedPackageSchema = z.object({
22
29
  section: z
23
30
  .string()
24
31
  .describe("Which part of the manifest declares it. A major version behind on a build-time tool is a different risk from one that ships."),
32
+ standalone: StandaloneSchema,
25
33
  });
26
34
  export type OutdatedPackage = z.infer<typeof OutdatedPackageSchema>;
27
35
  export const AdvisorySchema = z.object({
@@ -39,6 +47,7 @@ export const AdvisorySchema = z.object({
39
47
  "Which versions fix it. Absent means no fix has been published, which is exactly when nothing should offer to upgrade and something should say so instead.",
40
48
  ),
41
49
  dev: z.boolean().describe("Whether it only reaches build-time tooling, which is a different problem from one that reaches what you ship."),
50
+ standalone: StandaloneSchema,
42
51
  });
43
52
  export type Advisory = z.infer<typeof AdvisorySchema>;
44
53
  // A stale sample could send the agent chasing files already gone; it re-runs knip live anyway.
@@ -0,0 +1,33 @@
1
+ // members: the daemon's shared-access roster (GET/POST/DELETE /members), who besides the owner reaches this sandbox
2
+ import { z } from "zod";
3
+ import { GrantedRoleSchema } from "./shared.js";
4
+
5
+ // One person on the roster as the daemon answers it. `areas` fences what of the workspace they reach, and with it which
6
+ // assistants they may talk to: absent is the whole workspace, empty is nothing.
7
+ export const MemberSchema = z.object({
8
+ email: z.string().describe("Who, lowercased."),
9
+ role: GrantedRoleSchema.describe("The tier they were granted."),
10
+ areas: z.array(z.string()).optional().describe("The areas they are fenced to. Absent means the whole workspace."),
11
+ });
12
+ export type Member = z.infer<typeof MemberSchema>;
13
+
14
+ // What every roster write answers: the roster after it.
15
+ export const MembersListSchema = z.object({ members: z.array(MemberSchema) });
16
+ export type MembersList = z.infer<typeof MembersListSchema>;
17
+
18
+ // GET /members: the roster, plus the owner, an identity fact the roster file never holds. Absent before the first
19
+ // sign-in, on a loopback or test daemon.
20
+ export const MembersRosterSchema = MembersListSchema.extend({ owner: z.string().optional() });
21
+ export type MembersRoster = z.infer<typeof MembersRosterSchema>;
22
+
23
+ // POST /members: a grant is a role decision, so the role is required. Areas are optional, their absence being the whole
24
+ // workspace; a writer and a guest are refused without them, since for those two tiers the fence is the tier.
25
+ export const MemberGrantSchema = z.object({
26
+ email: z.string(),
27
+ role: GrantedRoleSchema,
28
+ areas: z.array(z.string().min(1)).max(20).optional(),
29
+ });
30
+ export type MemberGrant = z.infer<typeof MemberGrantSchema>;
31
+
32
+ // DELETE /members: whose access to take back.
33
+ export const MemberEmailSchema = z.object({ email: z.string() });
@@ -64,6 +64,14 @@ export const MemoryRoomSchema = z.object({
64
64
  personNeedBytes: z.number().describe("What a person's turn needs free to start without a warning: below it, the sandbox is short."),
65
65
  stallPercent: z.number().describe("Percent of the last ten seconds in which everything in the sandbox waited on memory (pressure `full`)."),
66
66
  stallLimitPercent: z.number().describe("The stall at or past which the sandbox counts as short of memory, whatever `freeBytes` says."),
67
+ stallSustainedPercent: z
68
+ .number()
69
+ .optional()
70
+ .describe("Percent of the last minute in which everything in the sandbox waited on memory. Absent from a daemon that predates it."),
71
+ stallSustainedLimitPercent: z
72
+ .number()
73
+ .optional()
74
+ .describe("The minute's stall at or past which the sandbox counts as short of memory. Absent from a daemon that predates it."),
67
75
  });
68
76
  export type MemoryRoom = z.infer<typeof MemoryRoomSchema>;
69
77
 
@@ -76,14 +84,24 @@ export const SandboxUsageSchema = z.object({
76
84
  memoryBytes: z
77
85
  .number()
78
86
  .describe(
79
- "Memory in use as the daemon admits work by it: resident memory less the file cache the kernel takes back on demand, plus what was pushed to swap.",
87
+ "Memory counted against the limit, as the daemon admits work by it: resident memory less the file cache the kernel takes back on demand, and once swap is full (`swapFull`) what was pushed to swap as well.",
80
88
  ),
81
89
  memoryLimitBytes: z
82
90
  .number()
83
91
  .describe(
84
92
  "The memory limit work is admitted against: where the kernel starts throttling the container (memory.high), else its hard limit, else the machine's memory.",
85
93
  ),
86
- swapBytes: z.number().optional().describe("Of `memoryBytes`, what was pushed out to swap. Absent where the sandbox cannot see its own memory."),
94
+ swapBytes: z
95
+ .number()
96
+ .optional()
97
+ .describe(
98
+ "What was pushed out to swap, counted in `memoryBytes` only once swap is full. Absent where the sandbox cannot see its own memory.",
99
+ ),
100
+ swapLimitBytes: z.number().optional().describe("What swap can hold. Absent where nothing bounds it, and from a daemon that predates it."),
101
+ swapFull: z
102
+ .boolean()
103
+ .optional()
104
+ .describe("Swap is nearly at `swapLimitBytes`: nothing more can be parked there, so what is swapped counts against the limit too."),
87
105
  memoryRoom: MemoryRoomSchema.optional().describe("What admission reads off the same reading. Absent from a daemon that predates it."),
88
106
  diskBytes: z.number().optional().describe("Space used on the volume the workspace lives on. Absent when the volume would not say."),
89
107
  diskTotalBytes: z.number().optional().describe("That volume's size. Absent when the volume would not say."),
@@ -233,7 +251,7 @@ export const StorageScanSchema = z.object({
233
251
  export type StorageScan = z.infer<typeof StorageScanSchema>;
234
252
 
235
253
  export const StorageReportSchema = z.object({
236
- scan: StorageScanSchema.optional().describe("The last scan that finished. Absent until one has, and again after the daemon restarts."),
254
+ scan: StorageScanSchema.optional().describe("The last scan that finished, kept across restarts; its `finishedAt` says how old it is. Absent until one has."),
237
255
  scanning: z.boolean().describe("Whether a scan is running now."),
238
256
  });
239
257
  export type StorageReport = z.infer<typeof StorageReportSchema>;
@@ -1,12 +1,17 @@
1
1
  import { z } from "zod";
2
+ import { AutomationSchema } from "./automations.js";
2
3
 
3
4
  // A need: something an agent cannot finish its task without that only a person can provide (a connection, a secret's
4
5
  // value, wider reach, a tool in the image). Unlike a parked card it outlives the turn that raised it: the sandbox keeps
5
6
  // it until someone answers, draws it wherever it is waiting, and wakes the conversation when it is met
6
7
  // (docs/architecture/needs.md). Every word on a need is the daemon's except `why`, the agent's own case.
7
8
 
8
- export const NEED_KINDS = ["capability", "secret", "grant", "release", "environment"] as const;
9
- export const NeedKindSchema = z.enum(NEED_KINDS).describe("What is being asked for: a connection, a secret's value, wider reach, a gated credential, or a tool in the image.");
9
+ export const NEED_KINDS = ["capability", "secret", "grant", "release", "environment", "automation"] as const;
10
+ export const NeedKindSchema = z
11
+ .enum(NEED_KINDS)
12
+ .describe(
13
+ "What is being asked for: a connection, a secret's value, wider reach, a gated credential, a tool in the image, or an automation to run unattended.",
14
+ );
10
15
  export type NeedKind = z.infer<typeof NeedKindSchema>;
11
16
 
12
17
  // `working` is a yes still being carried out: a connection whose form is open, an overlay approved but not yet built.
@@ -117,8 +122,33 @@ export const EnvironmentNeedSchema = z.object({
117
122
  });
118
123
  export type EnvironmentNeed = z.infer<typeof EnvironmentNeedSchema>;
119
124
 
125
+ // What its check sees today, run once as the automation was proposed, so the person deciding reads the watch working
126
+ // rather than a promise that it would. Absent for a guard command, which the agent ran itself before asking: run here
127
+ // it would carry the proposed persona's credentials before anyone approved them.
128
+ export const AutomationFirstCheckSchema = z.object({
129
+ pass: z.boolean().describe("Whether the check passes today, which for a watch waiting on one thing means it would fire at once."),
130
+ saw: z.string().describe("What it saw, or what it is still waiting for."),
131
+ at: z.number().describe("When it ran, in milliseconds."),
132
+ });
133
+ export type AutomationFirstCheck = z.infer<typeof AutomationFirstCheckSchema>;
134
+
135
+ export const AutomationNeedSchema = z.object({
136
+ kind: z.literal("automation"),
137
+ automation: AutomationSchema.describe("The automation as it would be saved, switched on, the moment a person approves it."),
138
+ replaces: z.boolean().optional().describe("An automation of this id already exists, and approving replaces it."),
139
+ firstCheck: AutomationFirstCheckSchema.optional(),
140
+ });
141
+ export type AutomationNeed = z.infer<typeof AutomationNeedSchema>;
142
+
120
143
  export const NeedSubjectSchema = z
121
- .discriminatedUnion("kind", [CapabilityNeedSchema, SecretNeedSchema, GrantNeedSchema, ReleaseNeedSchema, EnvironmentNeedSchema])
144
+ .discriminatedUnion("kind", [
145
+ CapabilityNeedSchema,
146
+ SecretNeedSchema,
147
+ GrantNeedSchema,
148
+ ReleaseNeedSchema,
149
+ EnvironmentNeedSchema,
150
+ AutomationNeedSchema,
151
+ ])
122
152
  .describe("What exactly is asked for.");
123
153
  export type NeedSubject = z.infer<typeof NeedSubjectSchema>;
124
154
 
@@ -164,6 +194,9 @@ export const NeedAskSchema = z.discriminatedUnion("kind", [
164
194
  }),
165
195
  z.object({ kind: z.literal("release"), subject: z.string().min(1) }),
166
196
  z.object({ kind: z.literal("environment"), tool: z.string().min(1).max(64), steps: z.string().min(1).max(20_000) }),
197
+ // Everything the agent proposes, switched on; the daemon checks it as the Automations page would save it, runs a
198
+ // source's check once for the card, and saves it only on a person's approval.
199
+ z.object({ kind: z.literal("automation"), automation: AutomationSchema }),
167
200
  ]);
168
201
  export type NeedAsk = z.infer<typeof NeedAskSchema>;
169
202
 
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { RunnerCommandFrameSchema, RunnerCommandSchema } from "../protocol/runner-protocol.js";
2
+ import { RunnerCommandFrameSchema, RunnerCommandSchema } from "../protocol/doors/runner-protocol.js";
3
3
 
4
4
  // OFFLOADED WORK, as the in-sandbox `offload-run` command and the editor see it (settings `offload`): a heavy line this
5
5
  // sandbox hands a runner on one of the owner's machines instead of running it itself.
@@ -0,0 +1,14 @@
1
+ // Named imports rather than the `z` namespace: this module is bundled into the browser extension (through the
2
+ // `./webext` entry), where the namespace keeps zod's locales. _devices/webext/scripts/size-budget.mjs holds the ceiling.
3
+ import { object, string } from "zod";
4
+ import type * as z from "zod";
5
+
6
+ // What POST /system/<door>/enroll answers once it redeems a pairing (peers/peer-routes.ts): the id the pairing was bound
7
+ // to and the durable token the peer presents from then on. A door may add fields of its own beside them; a reader
8
+ // needs only these two. A 401 is the expired-or-spent pairing, a 5xx a sandbox not ready yet. The sync key's door is
9
+ // a different route with its own answer (SyncEnrollmentAnswerSchema in devices.ts).
10
+ export const PeerEnrollmentAnswerSchema = object({
11
+ id: string(),
12
+ token: string().min(1),
13
+ });
14
+ export type PeerEnrollmentAnswer = z.infer<typeof PeerEnrollmentAnswerSchema>;