@intentic/sandbox-contract 1.232.0 → 1.233.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 (500) hide show
  1. package/README.md +7 -2
  2. package/dist/agent-catalog.d.ts +2 -1
  3. package/dist/agent-catalog.d.ts.map +1 -1
  4. package/dist/agent-catalog.js +1 -1
  5. package/dist/agent-catalog.js.map +1 -1
  6. package/dist/chores/chores.d.ts +1 -1
  7. package/dist/chores/chores.d.ts.map +1 -1
  8. package/dist/chores/probes.d.ts +1 -1
  9. package/dist/chores/probes.d.ts.map +1 -1
  10. package/dist/chores/stack.d.ts.map +1 -1
  11. package/dist/chores/stack.js +2 -1
  12. package/dist/chores/stack.js.map +1 -1
  13. package/dist/chores/verdict.d.ts +1 -1
  14. package/dist/chores/verdict.d.ts.map +1 -1
  15. package/dist/command-classes.d.ts +14 -0
  16. package/dist/command-classes.d.ts.map +1 -0
  17. package/dist/command-classes.js +168 -0
  18. package/dist/command-classes.js.map +1 -0
  19. package/dist/contracts/activity.contract.js +1 -1
  20. package/dist/contracts/activity.contract.js.map +1 -1
  21. package/dist/contracts/agent.contract.d.ts +40 -2
  22. package/dist/contracts/agent.contract.d.ts.map +1 -1
  23. package/dist/contracts/agent.contract.js +4 -1
  24. package/dist/contracts/agent.contract.js.map +1 -1
  25. package/dist/contracts/agents.contract.d.ts +24 -0
  26. package/dist/contracts/agents.contract.d.ts.map +1 -1
  27. package/dist/contracts/agents.contract.js +5 -1
  28. package/dist/contracts/agents.contract.js.map +1 -1
  29. package/dist/contracts/automations.contract.js +2 -1
  30. package/dist/contracts/automations.contract.js.map +1 -1
  31. package/dist/contracts/capabilities.contract.d.ts +63 -0
  32. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  33. package/dist/contracts/capabilities.contract.js +3 -1
  34. package/dist/contracts/capabilities.contract.js.map +1 -1
  35. package/dist/contracts/chores.contract.d.ts.map +1 -1
  36. package/dist/contracts/chores.contract.js +2 -1
  37. package/dist/contracts/chores.contract.js.map +1 -1
  38. package/dist/contracts/ci.contract.js +2 -1
  39. package/dist/contracts/ci.contract.js.map +1 -1
  40. package/dist/contracts/claude.contract.js +2 -1
  41. package/dist/contracts/claude.contract.js.map +1 -1
  42. package/dist/contracts/cursor.contract.js +2 -1
  43. package/dist/contracts/cursor.contract.js.map +1 -1
  44. package/dist/contracts/drafts.contract.d.ts.map +1 -1
  45. package/dist/contracts/drafts.contract.js +2 -1
  46. package/dist/contracts/drafts.contract.js.map +1 -1
  47. package/dist/contracts/endpoints.contract.d.ts.map +1 -1
  48. package/dist/contracts/endpoints.contract.js +2 -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 +2 -1
  52. package/dist/contracts/exit.contract.js.map +1 -1
  53. package/dist/contracts/extensions.contract.d.ts +42 -0
  54. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  55. package/dist/contracts/extensions.contract.js +4 -1
  56. package/dist/contracts/extensions.contract.js.map +1 -1
  57. package/dist/contracts/git.contract.d.ts.map +1 -1
  58. package/dist/contracts/git.contract.js +4 -1
  59. package/dist/contracts/git.contract.js.map +1 -1
  60. package/dist/contracts/grok.contract.d.ts.map +1 -1
  61. package/dist/contracts/grok.contract.js +2 -1
  62. package/dist/contracts/grok.contract.js.map +1 -1
  63. package/dist/contracts/history.contract.d.ts.map +1 -1
  64. package/dist/contracts/history.contract.js +2 -1
  65. package/dist/contracts/history.contract.js.map +1 -1
  66. package/dist/contracts/host.contract.d.ts +7 -0
  67. package/dist/contracts/host.contract.d.ts.map +1 -1
  68. package/dist/contracts/host.contract.js +4 -1
  69. package/dist/contracts/host.contract.js.map +1 -1
  70. package/dist/contracts/intentic.contract.d.ts.map +1 -1
  71. package/dist/contracts/intentic.contract.js +2 -1
  72. package/dist/contracts/intentic.contract.js.map +1 -1
  73. package/dist/contracts/inventory.contract.js +1 -1
  74. package/dist/contracts/inventory.contract.js.map +1 -1
  75. package/dist/contracts/logs.contract.d.ts.map +1 -1
  76. package/dist/contracts/logs.contract.js +1 -1
  77. package/dist/contracts/logs.contract.js.map +1 -1
  78. package/dist/contracts/loops.contract.js +2 -1
  79. package/dist/contracts/loops.contract.js.map +1 -1
  80. package/dist/contracts/panels.contract.d.ts.map +1 -1
  81. package/dist/contracts/panels.contract.js +2 -1
  82. package/dist/contracts/panels.contract.js.map +1 -1
  83. package/dist/contracts/personas.contract.js +2 -1
  84. package/dist/contracts/personas.contract.js.map +1 -1
  85. package/dist/contracts/ports.contract.d.ts.map +1 -1
  86. package/dist/contracts/ports.contract.js +2 -1
  87. package/dist/contracts/ports.contract.js.map +1 -1
  88. package/dist/contracts/prepush.contract.d.ts.map +1 -1
  89. package/dist/contracts/prepush.contract.js +2 -1
  90. package/dist/contracts/prepush.contract.js.map +1 -1
  91. package/dist/contracts/providers.contract.d.ts.map +1 -1
  92. package/dist/contracts/providers.contract.js +2 -1
  93. package/dist/contracts/providers.contract.js.map +1 -1
  94. package/dist/contracts/public.contract.d.ts.map +1 -1
  95. package/dist/contracts/public.contract.js +2 -1
  96. package/dist/contracts/public.contract.js.map +1 -1
  97. package/dist/contracts/push.contract.d.ts.map +1 -1
  98. package/dist/contracts/push.contract.js +2 -1
  99. package/dist/contracts/push.contract.js.map +1 -1
  100. package/dist/contracts/runner.contract.d.ts +45 -2
  101. package/dist/contracts/runner.contract.d.ts.map +1 -1
  102. package/dist/contracts/runner.contract.js +10 -2
  103. package/dist/contracts/runner.contract.js.map +1 -1
  104. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  105. package/dist/contracts/secrets.contract.js +2 -1
  106. package/dist/contracts/secrets.contract.js.map +1 -1
  107. package/dist/contracts/sessions.contract.js +1 -1
  108. package/dist/contracts/sessions.contract.js.map +1 -1
  109. package/dist/contracts/settings.contract.d.ts +20 -0
  110. package/dist/contracts/settings.contract.d.ts.map +1 -1
  111. package/dist/contracts/settings.contract.js +3 -1
  112. package/dist/contracts/settings.contract.js.map +1 -1
  113. package/dist/contracts/share.contract.d.ts.map +1 -1
  114. package/dist/contracts/share.contract.js +2 -1
  115. package/dist/contracts/share.contract.js.map +1 -1
  116. package/dist/contracts/skills.contract.d.ts.map +1 -1
  117. package/dist/contracts/skills.contract.js +2 -1
  118. package/dist/contracts/skills.contract.js.map +1 -1
  119. package/dist/contracts/system.contract.d.ts +31 -16
  120. package/dist/contracts/system.contract.d.ts.map +1 -1
  121. package/dist/contracts/system.contract.js +6 -1
  122. package/dist/contracts/system.contract.js.map +1 -1
  123. package/dist/contracts/translator.contract.d.ts.map +1 -1
  124. package/dist/contracts/translator.contract.js +4 -1
  125. package/dist/contracts/translator.contract.js.map +1 -1
  126. package/dist/contracts/usage.contract.js +1 -1
  127. package/dist/contracts/usage.contract.js.map +1 -1
  128. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  129. package/dist/contracts/vpn.contract.js +2 -1
  130. package/dist/contracts/vpn.contract.js.map +1 -1
  131. package/dist/contracts/webext.contract.d.ts +45 -0
  132. package/dist/contracts/webext.contract.d.ts.map +1 -0
  133. package/dist/contracts/webext.contract.js +12 -0
  134. package/dist/contracts/webext.contract.js.map +1 -0
  135. package/dist/contracts/workflows.contract.js +2 -1
  136. package/dist/contracts/workflows.contract.js.map +1 -1
  137. package/dist/contracts/workspace.contract.d.ts +2 -2
  138. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  139. package/dist/contracts/workspace.contract.js +7 -1
  140. package/dist/contracts/workspace.contract.js.map +1 -1
  141. package/dist/definition-action.d.ts +7 -0
  142. package/dist/definition-action.d.ts.map +1 -0
  143. package/dist/definition-action.js +3 -0
  144. package/dist/definition-action.js.map +1 -0
  145. package/dist/definition.d.ts +124 -21
  146. package/dist/definition.d.ts.map +1 -1
  147. package/dist/definition.js +29 -7
  148. package/dist/definition.js.map +1 -1
  149. package/dist/events.d.ts +101 -0
  150. package/dist/events.d.ts.map +1 -1
  151. package/dist/events.js +25 -1
  152. package/dist/events.js.map +1 -1
  153. package/dist/fast-tier.d.ts +1 -1
  154. package/dist/fast-tier.d.ts.map +1 -1
  155. package/dist/history-state.d.ts.map +1 -1
  156. package/dist/history-state.js +1 -0
  157. package/dist/history-state.js.map +1 -1
  158. package/dist/index.d.ts +355 -103
  159. package/dist/index.d.ts.map +1 -1
  160. package/dist/index.js +51 -1
  161. package/dist/index.js.map +1 -1
  162. package/dist/listener-protocol.js +1 -1
  163. package/dist/listener-protocol.js.map +1 -1
  164. package/dist/quick-model.d.ts +1 -1
  165. package/dist/quick-model.d.ts.map +1 -1
  166. package/dist/runner-protocol.d.ts +18 -0
  167. package/dist/runner-protocol.d.ts.map +1 -1
  168. package/dist/runner-protocol.js +8 -4
  169. package/dist/runner-protocol.js.map +1 -1
  170. package/dist/schemas/activity.d.ts +112 -0
  171. package/dist/schemas/activity.d.ts.map +1 -0
  172. package/dist/schemas/activity.js +70 -0
  173. package/dist/schemas/activity.js.map +1 -0
  174. package/dist/schemas/agent.d.ts +189 -0
  175. package/dist/schemas/agent.d.ts.map +1 -0
  176. package/dist/schemas/agent.js +170 -0
  177. package/dist/schemas/agent.js.map +1 -0
  178. package/dist/schemas/agents.d.ts +690 -0
  179. package/dist/schemas/agents.d.ts.map +1 -0
  180. package/dist/schemas/agents.js +314 -0
  181. package/dist/schemas/agents.js.map +1 -0
  182. package/dist/schemas/automations.d.ts +736 -0
  183. package/dist/schemas/automations.d.ts.map +1 -0
  184. package/dist/schemas/automations.js +218 -0
  185. package/dist/schemas/automations.js.map +1 -0
  186. package/dist/schemas/capabilities.d.ts +753 -0
  187. package/dist/schemas/capabilities.d.ts.map +1 -0
  188. package/dist/schemas/capabilities.js +269 -0
  189. package/dist/schemas/capabilities.js.map +1 -0
  190. package/dist/schemas/ci.d.ts +179 -0
  191. package/dist/schemas/ci.d.ts.map +1 -0
  192. package/dist/schemas/ci.js +99 -0
  193. package/dist/schemas/ci.js.map +1 -0
  194. package/dist/schemas/claude-gate.d.ts +13 -0
  195. package/dist/schemas/claude-gate.d.ts.map +1 -0
  196. package/dist/schemas/claude-gate.js +8 -0
  197. package/dist/schemas/claude-gate.js.map +1 -0
  198. package/dist/schemas/codebase-health.d.ts +56 -0
  199. package/dist/schemas/codebase-health.d.ts.map +1 -0
  200. package/dist/schemas/codebase-health.js +43 -0
  201. package/dist/schemas/codebase-health.js.map +1 -0
  202. package/dist/schemas/computers.d.ts +386 -0
  203. package/dist/schemas/computers.d.ts.map +1 -0
  204. package/dist/schemas/computers.js +107 -0
  205. package/dist/schemas/computers.js.map +1 -0
  206. package/dist/schemas/drafts.d.ts +84 -0
  207. package/dist/schemas/drafts.d.ts.map +1 -0
  208. package/dist/schemas/drafts.js +44 -0
  209. package/dist/schemas/drafts.js.map +1 -0
  210. package/dist/schemas/environment.d.ts +349 -0
  211. package/dist/schemas/environment.d.ts.map +1 -0
  212. package/dist/schemas/environment.js +111 -0
  213. package/dist/schemas/environment.js.map +1 -0
  214. package/dist/schemas/exit.d.ts +151 -0
  215. package/dist/schemas/exit.d.ts.map +1 -0
  216. package/dist/schemas/exit.js +115 -0
  217. package/dist/schemas/exit.js.map +1 -0
  218. package/dist/schemas/extension-updates.d.ts +1014 -0
  219. package/dist/schemas/extension-updates.d.ts.map +1 -0
  220. package/dist/schemas/extension-updates.js +197 -0
  221. package/dist/schemas/extension-updates.js.map +1 -0
  222. package/dist/schemas/fast-mode.d.ts +8 -0
  223. package/dist/schemas/fast-mode.d.ts.map +1 -0
  224. package/dist/schemas/fast-mode.js +3 -0
  225. package/dist/schemas/fast-mode.js.map +1 -0
  226. package/dist/schemas/git-history.d.ts +238 -0
  227. package/dist/schemas/git-history.d.ts.map +1 -0
  228. package/dist/schemas/git-history.js +152 -0
  229. package/dist/schemas/git-history.js.map +1 -0
  230. package/dist/schemas/git.d.ts +471 -0
  231. package/dist/schemas/git.d.ts.map +1 -0
  232. package/dist/schemas/git.js +204 -0
  233. package/dist/schemas/git.js.map +1 -0
  234. package/dist/schemas/history.d.ts +100 -0
  235. package/dist/schemas/history.d.ts.map +1 -0
  236. package/dist/schemas/history.js +54 -0
  237. package/dist/schemas/history.js.map +1 -0
  238. package/dist/schemas/hosts.d.ts +41 -0
  239. package/dist/schemas/hosts.d.ts.map +1 -0
  240. package/dist/schemas/hosts.js +18 -0
  241. package/dist/schemas/hosts.js.map +1 -0
  242. package/dist/schemas/intentic.d.ts +5 -0
  243. package/dist/schemas/intentic.d.ts.map +1 -0
  244. package/dist/schemas/intentic.js +3 -0
  245. package/dist/schemas/intentic.js.map +1 -0
  246. package/dist/schemas/internal.d.ts +8 -0
  247. package/dist/schemas/internal.d.ts.map +1 -0
  248. package/dist/schemas/internal.js +12 -0
  249. package/dist/schemas/internal.js.map +1 -0
  250. package/dist/schemas/inventory.d.ts +171 -0
  251. package/dist/schemas/inventory.d.ts.map +1 -0
  252. package/dist/schemas/inventory.js +51 -0
  253. package/dist/schemas/inventory.js.map +1 -0
  254. package/dist/schemas/logs.d.ts +67 -0
  255. package/dist/schemas/logs.d.ts.map +1 -0
  256. package/dist/schemas/logs.js +54 -0
  257. package/dist/schemas/logs.js.map +1 -0
  258. package/dist/schemas/loops.d.ts +415 -0
  259. package/dist/schemas/loops.d.ts.map +1 -0
  260. package/dist/schemas/loops.js +188 -0
  261. package/dist/schemas/loops.js.map +1 -0
  262. package/dist/schemas/maintenance.d.ts +557 -0
  263. package/dist/schemas/maintenance.d.ts.map +1 -0
  264. package/dist/schemas/maintenance.js +201 -0
  265. package/dist/schemas/maintenance.js.map +1 -0
  266. package/dist/schemas/marketplace.d.ts +64 -0
  267. package/dist/schemas/marketplace.d.ts.map +1 -0
  268. package/dist/schemas/marketplace.js +17 -0
  269. package/dist/schemas/marketplace.js.map +1 -0
  270. package/dist/schemas/panels.d.ts +61 -0
  271. package/dist/schemas/panels.d.ts.map +1 -0
  272. package/dist/schemas/panels.js +51 -0
  273. package/dist/schemas/panels.js.map +1 -0
  274. package/dist/schemas/personas.d.ts +122 -0
  275. package/dist/schemas/personas.d.ts.map +1 -0
  276. package/dist/schemas/personas.js +102 -0
  277. package/dist/schemas/personas.js.map +1 -0
  278. package/dist/schemas/plan-limits.d.ts +172 -0
  279. package/dist/schemas/plan-limits.d.ts.map +1 -0
  280. package/dist/schemas/plan-limits.js +126 -0
  281. package/dist/schemas/plan-limits.js.map +1 -0
  282. package/dist/schemas/ports.d.ts +71 -0
  283. package/dist/schemas/ports.d.ts.map +1 -0
  284. package/dist/schemas/ports.js +42 -0
  285. package/dist/schemas/ports.js.map +1 -0
  286. package/dist/schemas/provider-oauth.d.ts +128 -0
  287. package/dist/schemas/provider-oauth.d.ts.map +1 -0
  288. package/dist/schemas/provider-oauth.js +91 -0
  289. package/dist/schemas/provider-oauth.js.map +1 -0
  290. package/dist/schemas/provider-subscriptions.d.ts +9 -0
  291. package/dist/schemas/provider-subscriptions.d.ts.map +1 -0
  292. package/dist/schemas/provider-subscriptions.js +3 -0
  293. package/dist/schemas/provider-subscriptions.js.map +1 -0
  294. package/dist/schemas/public.d.ts +32 -0
  295. package/dist/schemas/public.d.ts.map +1 -0
  296. package/dist/schemas/public.js +29 -0
  297. package/dist/schemas/public.js.map +1 -0
  298. package/dist/schemas/push.d.ts +55 -0
  299. package/dist/schemas/push.d.ts.map +1 -0
  300. package/dist/schemas/push.js +60 -0
  301. package/dist/schemas/push.js.map +1 -0
  302. package/dist/schemas/secrets.d.ts +86 -0
  303. package/dist/schemas/secrets.d.ts.map +1 -0
  304. package/dist/schemas/secrets.js +51 -0
  305. package/dist/schemas/secrets.js.map +1 -0
  306. package/dist/schemas/sessions.d.ts +32 -0
  307. package/dist/schemas/sessions.d.ts.map +1 -0
  308. package/dist/schemas/sessions.js +11 -0
  309. package/dist/schemas/sessions.js.map +1 -0
  310. package/dist/schemas/settings.d.ts +548 -0
  311. package/dist/schemas/settings.d.ts.map +1 -0
  312. package/dist/schemas/settings.js +259 -0
  313. package/dist/schemas/settings.js.map +1 -0
  314. package/dist/schemas/share.d.ts +49 -0
  315. package/dist/schemas/share.d.ts.map +1 -0
  316. package/dist/schemas/share.js +26 -0
  317. package/dist/schemas/share.js.map +1 -0
  318. package/dist/schemas/shared.d.ts +22 -0
  319. package/dist/schemas/shared.d.ts.map +1 -0
  320. package/dist/schemas/shared.js +16 -0
  321. package/dist/schemas/shared.js.map +1 -0
  322. package/dist/schemas/system.d.ts +86 -0
  323. package/dist/schemas/system.d.ts.map +1 -0
  324. package/dist/schemas/system.js +64 -0
  325. package/dist/schemas/system.js.map +1 -0
  326. package/dist/schemas/terminal.d.ts +230 -0
  327. package/dist/schemas/terminal.d.ts.map +1 -0
  328. package/dist/schemas/terminal.js +133 -0
  329. package/dist/schemas/terminal.js.map +1 -0
  330. package/dist/schemas/usage.d.ts +113 -0
  331. package/dist/schemas/usage.d.ts.map +1 -0
  332. package/dist/schemas/usage.js +91 -0
  333. package/dist/schemas/usage.js.map +1 -0
  334. package/dist/schemas/vpn.d.ts +229 -0
  335. package/dist/schemas/vpn.d.ts.map +1 -0
  336. package/dist/schemas/vpn.js +115 -0
  337. package/dist/schemas/vpn.js.map +1 -0
  338. package/dist/schemas/webext.d.ts +98 -0
  339. package/dist/schemas/webext.d.ts.map +1 -0
  340. package/dist/schemas/webext.js +36 -0
  341. package/dist/schemas/webext.js.map +1 -0
  342. package/dist/schemas/workflows.d.ts +881 -0
  343. package/dist/schemas/workflows.d.ts.map +1 -0
  344. package/dist/schemas/workflows.js +164 -0
  345. package/dist/schemas/workflows.js.map +1 -0
  346. package/dist/schemas/workspace-repos.d.ts +143 -0
  347. package/dist/schemas/workspace-repos.d.ts.map +1 -0
  348. package/dist/schemas/workspace-repos.js +87 -0
  349. package/dist/schemas/workspace-repos.js.map +1 -0
  350. package/dist/schemas/workspace-search.d.ts +170 -0
  351. package/dist/schemas/workspace-search.d.ts.map +1 -0
  352. package/dist/schemas/workspace-search.js +85 -0
  353. package/dist/schemas/workspace-search.js.map +1 -0
  354. package/dist/schemas/workspace-setup.d.ts +48 -0
  355. package/dist/schemas/workspace-setup.d.ts.map +1 -0
  356. package/dist/schemas/workspace-setup.js +26 -0
  357. package/dist/schemas/workspace-setup.js.map +1 -0
  358. package/dist/schemas/workspace-tree.d.ts +120 -0
  359. package/dist/schemas/workspace-tree.d.ts.map +1 -0
  360. package/dist/schemas/workspace-tree.js +111 -0
  361. package/dist/schemas/workspace-tree.js.map +1 -0
  362. package/dist/webext-links.d.ts +13 -0
  363. package/dist/webext-links.d.ts.map +1 -0
  364. package/dist/webext-links.js +24 -0
  365. package/dist/webext-links.js.map +1 -0
  366. package/dist/webext-protocol.d.ts +8 -0
  367. package/dist/webext-protocol.d.ts.map +1 -0
  368. package/dist/webext-protocol.js +7 -0
  369. package/dist/webext-protocol.js.map +1 -0
  370. package/dist/workflow-faults.d.ts +1 -1
  371. package/dist/workflow-faults.d.ts.map +1 -1
  372. package/dist/workspace-state.d.ts +2 -2
  373. package/dist/workspace-state.d.ts.map +1 -1
  374. package/dist/workspace-state.js +2 -2
  375. package/dist/workspace-state.js.map +1 -1
  376. package/package.json +15 -4
  377. package/src/agent-catalog.test.ts +1 -1
  378. package/src/agent-catalog.ts +4 -11
  379. package/src/chores/chores.ts +1 -1
  380. package/src/chores/probes.ts +1 -1
  381. package/src/chores/stack.test.ts +19 -0
  382. package/src/chores/stack.ts +19 -3
  383. package/src/chores/verdict.test.ts +11 -1
  384. package/src/chores/verdict.ts +1 -1
  385. package/src/command-classes.test.ts +378 -0
  386. package/src/command-classes.ts +378 -0
  387. package/src/contracts/activity.contract.ts +1 -1
  388. package/src/contracts/agent.contract.ts +4 -13
  389. package/src/contracts/agents.contract.ts +6 -6
  390. package/src/contracts/automations.contract.ts +2 -2
  391. package/src/contracts/capabilities.contract.ts +3 -4
  392. package/src/contracts/chores.contract.ts +2 -1
  393. package/src/contracts/ci.contract.ts +2 -2
  394. package/src/contracts/claude.contract.ts +2 -2
  395. package/src/contracts/cursor.contract.ts +2 -2
  396. package/src/contracts/drafts.contract.ts +2 -1
  397. package/src/contracts/endpoints.contract.ts +2 -1
  398. package/src/contracts/exit.contract.ts +2 -1
  399. package/src/contracts/extensions.contract.ts +5 -5
  400. package/src/contracts/git.contract.ts +19 -18
  401. package/src/contracts/grok.contract.ts +2 -1
  402. package/src/contracts/history.contract.ts +2 -1
  403. package/src/contracts/host.contract.ts +4 -1
  404. package/src/contracts/intentic.contract.ts +2 -1
  405. package/src/contracts/inventory.contract.ts +1 -1
  406. package/src/contracts/logs.contract.ts +7 -1
  407. package/src/contracts/loops.contract.ts +2 -2
  408. package/src/contracts/panels.contract.ts +2 -1
  409. package/src/contracts/personas.contract.ts +3 -3
  410. package/src/contracts/ports.contract.ts +3 -2
  411. package/src/contracts/prepush.contract.ts +2 -1
  412. package/src/contracts/providers.contract.ts +2 -1
  413. package/src/contracts/public.contract.ts +3 -2
  414. package/src/contracts/push.contract.ts +2 -1
  415. package/src/contracts/runner.contract.ts +18 -2
  416. package/src/contracts/secrets.contract.ts +2 -1
  417. package/src/contracts/sessions.contract.ts +1 -1
  418. package/src/contracts/settings.contract.ts +3 -9
  419. package/src/contracts/share.contract.ts +3 -2
  420. package/src/contracts/skills.contract.ts +2 -1
  421. package/src/contracts/system.contract.ts +6 -9
  422. package/src/contracts/translator.contract.ts +4 -1
  423. package/src/contracts/usage.contract.ts +1 -1
  424. package/src/contracts/vpn.contract.ts +2 -8
  425. package/src/contracts/webext.contract.ts +37 -0
  426. package/src/contracts/workflows.contract.ts +2 -2
  427. package/src/contracts/workspace.contract.ts +10 -12
  428. package/src/conversation-ids.test.ts +1 -1
  429. package/src/definition-action.ts +8 -0
  430. package/src/definition.ts +74 -10
  431. package/src/events.ts +84 -22
  432. package/src/fast-tier.ts +1 -1
  433. package/src/history-state.ts +5 -0
  434. package/src/host-protocol.ts +1 -1
  435. package/src/hostnames.test.ts +2 -2
  436. package/src/index.ts +60 -1
  437. package/src/listener-protocol.ts +1 -1
  438. package/src/quick-model.ts +1 -1
  439. package/src/runner-protocol.ts +35 -5
  440. package/src/schemas/activity.ts +123 -0
  441. package/src/schemas/agent.ts +409 -0
  442. package/src/schemas/agents.ts +802 -0
  443. package/src/schemas/automations.ts +510 -0
  444. package/src/schemas/capabilities.ts +729 -0
  445. package/src/schemas/ci.ts +235 -0
  446. package/src/schemas/claude-gate.ts +13 -0
  447. package/src/schemas/codebase-health.ts +64 -0
  448. package/src/schemas/computers.ts +287 -0
  449. package/src/schemas/drafts.ts +108 -0
  450. package/src/schemas/environment.ts +276 -0
  451. package/src/schemas/exit.ts +222 -0
  452. package/src/schemas/extension-updates.ts +322 -0
  453. package/src/schemas/fast-mode.ts +8 -0
  454. package/src/schemas/git-history.ts +265 -0
  455. package/src/schemas/git.ts +430 -0
  456. package/src/schemas/history.ts +112 -0
  457. package/src/schemas/hosts.ts +37 -0
  458. package/src/schemas/intentic.ts +2 -0
  459. package/src/schemas/internal.ts +17 -0
  460. package/src/schemas/inventory.ts +68 -0
  461. package/src/schemas/logs.ts +96 -0
  462. package/src/schemas/loops.ts +401 -0
  463. package/src/schemas/maintenance.ts +421 -0
  464. package/src/schemas/marketplace.ts +23 -0
  465. package/src/schemas/panels.ts +99 -0
  466. package/src/schemas/personas.ts +281 -0
  467. package/src/schemas/plan-limits.ts +255 -0
  468. package/src/schemas/ports.ts +84 -0
  469. package/src/schemas/provider-oauth.ts +191 -0
  470. package/src/schemas/provider-subscriptions.ts +11 -0
  471. package/src/schemas/public.ts +52 -0
  472. package/src/schemas/push.ts +112 -0
  473. package/src/schemas/secrets.ts +68 -0
  474. package/src/schemas/sessions.ts +16 -0
  475. package/src/schemas/settings.ts +932 -0
  476. package/src/schemas/share.ts +71 -0
  477. package/src/schemas/shared.ts +32 -0
  478. package/src/schemas/system.ts +156 -0
  479. package/src/schemas/terminal.ts +286 -0
  480. package/src/schemas/usage.ts +303 -0
  481. package/src/{schemas.test.ts → schemas/version-seam.test.ts} +4 -2
  482. package/src/schemas/vpn.ts +215 -0
  483. package/src/schemas/webext.ts +79 -0
  484. package/src/schemas/workflows.ts +413 -0
  485. package/src/schemas/workspace-repos.ts +123 -0
  486. package/src/schemas/workspace-search.ts +141 -0
  487. package/src/schemas/workspace-setup.ts +43 -0
  488. package/src/schemas/workspace-tree.ts +234 -0
  489. package/src/title.test.ts +1 -1
  490. package/src/webext-links.ts +80 -0
  491. package/src/webext-protocol.ts +27 -0
  492. package/src/workflow-faults.test.ts +1 -1
  493. package/src/workflow-faults.ts +1 -1
  494. package/src/workspace-state.test.ts +3 -3
  495. package/src/workspace-state.ts +8 -13
  496. package/dist/schemas.d.ts +0 -9909
  497. package/dist/schemas.d.ts.map +0 -1
  498. package/dist/schemas.js +0 -4288
  499. package/dist/schemas.js.map +0 -1
  500. package/src/schemas.ts +0 -10090
@@ -0,0 +1,191 @@
1
+ import { z } from "zod";
2
+ import { AccountUsageSchema } from "./plan-limits.js";
3
+ import { KeyedProviderSchema } from "./provider-subscriptions.js";
4
+ // Claude uses the PKCE authorize-URL + paste-back handshake (start → exchange). Codex uses OpenAI's device-code
5
+ // flow (start → poll): the browser signs in at verificationUri and enters userCode; the daemon polls until done.
6
+ // A sandbox can hold several accounts per provider side by side: `id` is the daemon-minted store key, `label`
7
+ // the user's display name (auto-filled from the sign-in identity where the token carries one). Tokens never
8
+ // ride this shape, connection status is existence in the list.
9
+
10
+ export const OauthAccountSchema = z.object({
11
+ id: z.string().describe("The account's id, which is what a turn names to spend on it and what disconnecting takes."),
12
+ label: z.string().describe("What it is called here, which somebody can change."),
13
+ // WHO this account signs in as, in the provider's own words. Anthropic returns the email and the
14
+ // organization alongside the tokens, so a connection can name itself instead of arriving as a second row
15
+ // called "Claude". Kept BESIDE `label` rather than folded into it: the label is the user's to rename, and a
16
+ // renamed account still has to be able to say whose it is. Absent when the provider tells us nothing (a
17
+ // pasted API key carries no identity), which is exactly when renaming is the only answer, so every
18
+ // sandbox-owned account can be renamed.
19
+ email: z
20
+ .string()
21
+ .optional()
22
+ .describe(
23
+ "Who it signs in as, in the provider's own words. Kept beside the label rather than folded into it, so a renamed account can still say whose it is. Absent when the provider says nothing, which is exactly when renaming is the only answer.",
24
+ ),
25
+ organization: z.string().optional().describe("Which organisation it belongs to, where the provider says."),
26
+ scope: z.string().optional().describe("What the credential is permitted to do, in the provider's terms."),
27
+ connectedAt: z.number().describe("When it was connected, in milliseconds."),
28
+ // Set only when the account's stored credential can no longer be refreshed (revoked/expired refresh token)
29
+ //, the user must reconnect. Absent ⇒ healthy or not-yet-probed; `detail` carries the reason for the UI.
30
+ // Provider-agnostic; only Codex probes it today (Claude refreshes on-demand, Grok's tokens are OpenCode's).
31
+ needsReauth: z
32
+ .boolean()
33
+ .optional()
34
+ .describe("Its stored credential can no longer be renewed and somebody has to sign in again. Absent means healthy, or not checked yet."),
35
+ detail: z.string().optional().describe("Why, in words a person can act on."),
36
+ // The account's last known subscription-usage snapshot, so the picker can show what's left on each account
37
+ // before the user commits a turn to one. Absent until a reading exists for it, an unmeasured account reads
38
+ // as unknown, never 0%. Claude is the provider that fills it here, because its stream reports the windows;
39
+ // the routed subscriptions carry the identical field on TranslatorAccount, filled by a pulled reading.
40
+ usage: AccountUsageSchema.optional().describe(
41
+ "How full its plan limits were when last measured, so a picker can show what is left before committing work to it. Absent until a reading exists, which reads as unknown rather than as nothing left.",
42
+ ),
43
+ });
44
+ export type OauthAccount = z.infer<typeof OauthAccountSchema>;
45
+ export const OauthAccountListSchema = z.object({
46
+ accounts: z
47
+ .array(OauthAccountSchema)
48
+ .describe("The connected accounts. Tokens never travel in this shape: being in this list is what connected means."),
49
+ });
50
+ export type OauthAccountList = z.infer<typeof OauthAccountListSchema>;
51
+ /* RE-MEASURE THIS PROVIDER'S PLAN LIMITS BEFORE ANSWERING, rather than serving whatever reading is current
52
+ * enough by the daemon's own bound. Every ordinary read of the list wants that bound, it is what keeps a page
53
+ * load off the upstream quota endpoint, but a person who has just changed something about the account
54
+ * (a seat downgraded, a plan swapped, another device's spend) is asking precisely whether the reading they can
55
+ * see is still true, and an answer from the last minute cannot tell them. Read off the query string, so the
56
+ * caller says it as `?force=1`. */
57
+ export const AccountListQuerySchema = z.object({
58
+ force: z
59
+ .stringbool()
60
+ .default(false)
61
+ .describe(
62
+ "Measure the plan limits again before answering, rather than serving a recent reading. Slower, and the right thing when somebody has just changed a plan and is asking whether what they can see is still true.",
63
+ ),
64
+ });
65
+ // Address one account of a provider (disconnect, and the turn's `account`).
66
+ export const AccountIdSchema = z.object({ id: z.string().min(1).describe("Which account.") });
67
+ // Rename one account of a provider whose credential the sandbox owns (Claude, Kimi). Blank ⇒ the daemon falls
68
+ // back to the derived name, so clearing a label restores the sign-in identity rather than leaving a nameless
69
+ // row. Grok is absent for the same reason it holds one account: OpenCode owns that credential, not this store.
70
+ export const AccountRenameSchema = z.object({
71
+ id: z.string().min(1).describe("Which account."),
72
+ label: z.string().max(80).describe("The new name. Blank restores the one derived from the sign-in, rather than leaving a nameless row."),
73
+ });
74
+ // The completing calls carry the user-chosen label (blank ⇒ the daemon derives one from the sign-in identity
75
+ // or a provider default).
76
+ export const OauthExchangeSchema = z.object({
77
+ code: z.string().min(1).describe("The code the sign-in handed back."),
78
+ verifier: z.string().min(1).describe("The proof from the start of the handshake, which is what stops somebody else's code being redeemed here."),
79
+ state: z.string().min(1).describe("The handshake this belongs to. A mismatch is refused."),
80
+ label: z.string().optional().describe("What to call the account. Blank derives one from the sign-in."),
81
+ });
82
+ export const AuthorizeChallengeSchema = z.object({
83
+ authorizeUrl: z.string().describe("Where to send somebody to sign in."),
84
+ verifier: z.string().describe("Keep this and send it back when finishing. It is what proves the code that comes back belongs to this handshake."),
85
+ state: z.string().describe("The handshake's own id, sent back with it."),
86
+ });
87
+ /* CURSOR'S SIGN-IN START. A third login shape, and the reason it is not one of the two above is where the
88
+ * SECRET lives during the handshake.
89
+ *
90
+ * Claude's is paste-back: the browser receives a code and the caller hands it plus its verifier to `exchange`,
91
+ * so the handshake's proof has to travel on the wire and AuthorizeChallengeSchema carries it. Cursor's PKCE
92
+ * verifier must never leave the process that generated it, anyone holding it can redeem the login and mint a
93
+ * durable key, so the daemon starts the whole flow, keeps the verifier in memory, polls Cursor itself, and
94
+ * writes the account when it lands. Nothing redeemable is on this shape at all.
95
+ *
96
+ * Which makes it behave like a DEVICE flow from the caller's side (open the page, then watch the account list),
97
+ * except that there is no one-time code to display: the login page is addressed to this handshake already. So
98
+ * DeviceStartSchema's `code` would be a permanently blank field on every card, and TranslatorStartSchema's
99
+ * `state` a value nothing sends back. `handshake` is neither, it is a cancellation handle. */
100
+ export const CursorLoginStartSchema = z.object({
101
+ url: z.string().describe("The page to open and sign in on. It is already addressed to this attempt, so there is no code to type."),
102
+ handshake: z
103
+ .string()
104
+ .describe(
105
+ "This attempt's id, for abandoning it. Not a credential and not redeemable: the proof that finishes the sign-in never leaves the sandbox.",
106
+ ),
107
+ expiresAt: z.number().describe("When this attempt stops being answerable, in milliseconds, so a card can stop waiting instead of spinning."),
108
+ });
109
+ export type CursorLoginStart = z.infer<typeof CursorLoginStartSchema>;
110
+ // Abandon a sign-in nobody completed, so the daemon stops polling Cursor for it. Ordinary tidiness rather than
111
+ // a security boundary: an unanswered attempt also times out on its own (see `expiresAt`).
112
+ export const CursorLoginCancelSchema = z.object({ handshake: z.string().min(1).describe("Which attempt to stop waiting on.") });
113
+ // xAI Grok (via OpenCode) uses subscription OAuth via the headless device-code method. `start` returns the
114
+ // `url` the user opens (xAI's verification_uri_complete, which pre-fills the code) and `code`, the same
115
+ // one-time code, surfaced so the card matches x.ai exactly. There is no paste-back: OpenCode polls to
116
+ // completion and the UI polls `/grok/accounts`.
117
+ // ponytail: OpenCode holds one xAI auth per data dir, so Grok stays single-account, the list is 0 or 1. Per
118
+ // account would need an OpenCode server per data dir; add when there's demand.
119
+ // A device-code login start: the verification URL + the one-time code the user enters there. The native Grok
120
+ // flow (via OpenCode), see TranslatorStartSchema for the routed-provider connect, which adds `state`.
121
+ export const DeviceStartSchema = z.object({
122
+ url: z.string().describe("The page to open, which already has the code in it."),
123
+ code: z
124
+ .string()
125
+ .describe(
126
+ "The one-time code, shown as well so the page and the card say the same thing. Nothing is pasted back: the sandbox waits for the sign-in to complete on its own.",
127
+ ),
128
+ });
129
+ // A routed-provider subscription login start (codex/grok/kimi/gemini via CLIProxyAPI). Device flows poll to
130
+ // completion after the user approves upstream; redirect flows need the browser's landing URL pasted back. The
131
+ // explicit flow discriminator matters even when a provider's verification URL already embeds its optional code.
132
+ export const TranslatorStartSchema = z.object({
133
+ url: z.string().describe("The page to open."),
134
+ code: z.string().describe("The one-time code, where the provider uses one."),
135
+ state: z.string().describe("The handshake's id, which the finishing call sends back."),
136
+ flow: z
137
+ .enum(["device", "redirect"])
138
+ .describe(
139
+ "Which shape this is. A device sign-in finishes by itself and you poll the account list; a redirect needs the address it landed on handed back. Said outright rather than guessed at from whether a code happens to exist.",
140
+ ),
141
+ });
142
+ // The paste-back half of a redirect login: the URL the provider sent the browser to, carrying the grant as
143
+ // ?code=&state=. `state` ties it to the handshake that issued it, the translator rejects a mismatch.
144
+ export const TranslatorCompleteSchema = z.object({
145
+ provider: KeyedProviderSchema.describe("Which provider."),
146
+ redirectUrl: z.string().min(1).describe("The address the browser was sent to, whole. The grant is inside it."),
147
+ state: z.string().min(1).describe("The handshake this belongs to. A mismatch is refused."),
148
+ });
149
+ // A provider's model catalog, resolved daemon-side from live discovery with a persisted last-known-good list and
150
+ // a seed floor (Grok via opencode.ts xaiModels, Codex via codex-models.ts, Claude via the Agent SDK's
151
+ // supportedModels), never empty, so the picker is never blank. `label` is the provider's display name; `default`
152
+ // is the model a fresh chat on that provider seeds (always present). Served by the one catalog route every
153
+ // provider shares. `efforts` is the reasoning-effort tiers the model accepts (Claude reports them per model);
154
+ // empty ⇒ the client's default tiers.
155
+ //
156
+ // EVERY field here is provider-reported, nothing about a model is curated in this repo, so a new release or a
157
+ // renamed family flows to the UI with no code change. Providers differ in how much they publish: the Claude
158
+ // Agent SDK reports a display name, a capability description, effort tiers, and capability flags, while the
159
+ // Some OpenAI-compatible /v1/models endpoints report ids only, those rows render label-only, and that absence
160
+ // is the honest answer rather than something to paper over with a hand-written table.
161
+ //
162
+ // ORDER IS MEANINGFUL: `models` arrives in the provider's own preference order, which is what the picker sorts
163
+ // by, and `default` is the provider's own default. Neither is re-ranked locally.
164
+ export const ModelBadgeSchema = z.enum(["reasoning", "fast"]);
165
+ export type ModelBadge = z.infer<typeof ModelBadgeSchema>;
166
+ export const ModelSchema = z.object({
167
+ id: z.string().describe("What to name when asking for this model."),
168
+ label: z.string().describe("What to call it on screen."),
169
+ efforts: z.array(z.string()).optional().describe("The thinking levels it accepts, where the provider says. Empty means use your own defaults."),
170
+ description: z
171
+ .string()
172
+ .optional()
173
+ .describe(
174
+ "What it is good for, in the provider's own words. Absent where the provider publishes only ids, which is the honest answer rather than something to paper over with a hand-written table.",
175
+ ),
176
+ badges: z.array(ModelBadgeSchema).optional().describe("What it is known for, where the provider says so."),
177
+ /* HOW MUCH THE SERVER WILL ACCEPT IN ONE REQUEST, where the server says so, and the one field here that a
178
+ * turn is refused against rather than merely rendered (agent/context-budget.ts).
179
+ *
180
+ * The SERVED window, never the weights' training length. An inference server takes its context size from a
181
+ * flag and then clamps it to the memory it actually has, so a 3B model whose GGUF advertises 131k can be
182
+ * serving 16k, and it is the 16k that refuses the request. Read from llama.cpp's /props and vLLM's
183
+ * `max_model_len`; absent for every provider that publishes no such number, which is most of them, and
184
+ * absent means unknown rather than unlimited: nothing gates on a window it was never told. */
185
+ contextWindow: z.number().optional().describe("How many tokens this model will accept in one request, where the server publishes it."),
186
+ });
187
+ export type Model = z.infer<typeof ModelSchema>;
188
+ export const ModelsSchema = z.object({
189
+ models: z.array(ModelSchema).describe("What this provider serves, in its own preference order, which is not rearranged here. Never empty."),
190
+ default: z.string().describe("Which one a fresh conversation starts on. Always present."),
191
+ });
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ // The providers whose model can run UNDER the Claude Code harness through the bundled translator (CLIProxyAPI),
3
+ // which holds their SUBSCRIPTION OAuth and re-serves it behind an Anthropic endpoint. The `claude` provider is
4
+ // absent, native Anthropic OAuth serves it directly, without the translator. Codex, Grok and Gemini also have a
5
+ // native runtime and so carry the harness axis; Kimi is routed-only, so its turns always use Claude Code.
6
+ //
7
+ // Gemini is in BOTH camps and that is not a contradiction: its native runtime (OpenCode) reaches Google through
8
+ // this same translator and these same auth files. The harness axis picks the loop; the translator is the road
9
+ // under either.
10
+ export const KeyedProviderSchema = z.enum(["codex", "grok", "kimi", "gemini"]);
11
+ export type KeyedProvider = z.infer<typeof KeyedProviderSchema>;
@@ -0,0 +1,52 @@
1
+ // public: the workspace outbox
2
+ import { z } from "zod";
3
+ // The mirror image of the reference shelf. Files under the workspace's `public/` directory are served as static
4
+ // files at public-<slot>-<sandboxId>.<zone>, with no auth in front of them, the process-free half of preview
5
+ // (a panel needs a running dev server; a file needs nothing). The directory's existence is the switch: it is
6
+ // absent until something is published and removed again when the last file leaves, so "publishing is off" is
7
+ // the resting state rather than a flag someone has to remember to set back.
8
+
9
+ export const PublicFileSchema = z.object({
10
+ // Outbox-relative, forward-slash ("report.pdf", "site/index.html").
11
+ path: z.string().describe("Where it sits inside the outbox."),
12
+ size: z.number().describe("Size in bytes."),
13
+ modifiedAt: z.number().describe("When it last changed, in milliseconds."),
14
+ // The file's public URL. Absent when the sandbox has no tunnel, or when a guard refuses this file.
15
+ url: z.string().optional().describe("Its public address. Absent when this sandbox has no outside address, or when the file is being refused."),
16
+ // Why a file sitting in the outbox is NOT served, a hidden name, a credential-shaped name, contents that
17
+ // match a known token format, or sheer size. The publisher reads it here; a stranger requesting the same
18
+ // file only ever gets the same 404 every other miss returns, so this list can't be probed from outside.
19
+ blocked: z
20
+ .string()
21
+ .optional()
22
+ .describe(
23
+ "Why a file sitting in the outbox is not being served: a hidden name, a credential-shaped name, contents that look like a token, or sheer size. Only the publisher sees this; a stranger asking for the same file gets the same nothing every other miss gets.",
24
+ ),
25
+ });
26
+ export type PublicFile = z.infer<typeof PublicFileSchema>;
27
+ // `url` is the outbox root, the base every file's URL hangs off, and what the view shows as "your public
28
+ // address". Absent on a loopback/no-tunnel sandbox, which has nowhere to publish to.
29
+ export const PublicListSchema = z.object({
30
+ url: z.string().optional().describe("Your public address, which every file's own hangs off. Absent on a sandbox with nowhere to publish to."),
31
+ files: z.array(PublicFileSchema).describe("What the outbox holds."),
32
+ });
33
+ export type PublicList = z.infer<typeof PublicListSchema>;
34
+ // A WORKSPACE-relative path (the space the file tree speaks) to copy into the outbox. A copy, not a move: the
35
+ // repo a build output came from must not lose it because someone shared it.
36
+ export const PublishSchema = z.object({
37
+ path: z
38
+ .string()
39
+ .min(1)
40
+ .describe(
41
+ "What to publish, as a workspace path. It is copied rather than moved, so a repository does not lose its build output because somebody shared it.",
42
+ ),
43
+ });
44
+ // An OUTBOX-relative path to withdraw, the path space PublicFile.path speaks, not the workspace's.
45
+ export const UnpublishSchema = z.object({
46
+ path: z.string().min(1).describe("What to withdraw, as a path inside the outbox rather than a workspace path."),
47
+ });
48
+ export const PublishResultSchema = z.object({
49
+ path: z.string().describe("Where it landed inside the outbox."),
50
+ url: z.string().optional().describe("Its public address. Absent on a sandbox with nowhere to publish to."),
51
+ });
52
+ export type PublishResult = z.infer<typeof PublishResultSchema>;
@@ -0,0 +1,112 @@
1
+ // push: notifications to the owner's devices
2
+ import { z } from "zod";
3
+ // The daemon is the only tier that knows what the agent is doing, so it is the sender. A registration is
4
+ // per-DEVICE and comes in two kinds, distinguished by who can be posted to directly:
5
+ // webpush a browser (including the Android TWA, which IS Chrome). The endpoint is minted by that
6
+ // browser's push service and the daemon sends to it directly, end-to-end encrypted.
7
+ // relay a native app install (the iOS shell), whose OS push service (APNs) only accepts sends from
8
+ // the app's vendor. The daemon posts plain JSON to the platform's push relay, which holds the
9
+ // vendor credential and forwards. The payload transits the relay readable, the price of Apple
10
+ // requiring the vendor in the loop, which is why the channel records WHERE to post (`url`)
11
+ // rather than the daemon knowing any platform by name.
12
+ // Channels live here and not on the platform because the daemon is on the command path: the platform would
13
+ // have to be told about every turn to be useful.
14
+
15
+ // A browser's PushSubscription, in the exact shape `web-push` consumes, the browser produces it via
16
+ // PushManager.subscribe() and the client posts it back verbatim, so the daemon never reshapes it.
17
+ export const WebPushChannelSchema = z.object({
18
+ kind: z.literal("webpush").describe("A browser, which the sandbox can reach directly and encrypt end to end."),
19
+ endpoint: z.url().describe("Where that browser's push service accepts sends. It also identifies the device everywhere else in this group."),
20
+ keys: z
21
+ .object({
22
+ p256dh: z.string().min(1).describe("The browser's public key, for encrypting what is sent."),
23
+ auth: z.string().min(1).describe("The browser's secret, for the same."),
24
+ })
25
+ .describe("What the browser handed you when it subscribed. Post it back exactly as it came; nothing reshapes it."),
26
+ });
27
+ export type WebPushChannel = z.infer<typeof WebPushChannelSchema>;
28
+ // A native install, addressed through a push relay. `secret` is the send capability the relay minted at
29
+ // registration, the daemon proves it may notify this device by presenting it; the relay never learns which
30
+ // sandbox is calling. `deviceId` doubles as the channel's identity (see channelId below).
31
+ export const RelayChannelSchema = z.object({
32
+ kind: z
33
+ .literal("relay")
34
+ .describe(
35
+ "A native app, whose operating system only accepts sends from the app's publisher, so the sandbox posts through a relay instead. The message passes through that relay readable, which is the price of the publisher having to be in the loop.",
36
+ ),
37
+ // The absolute URL the daemon POSTs a send to, minted by the relay at registration, stored verbatim.
38
+ url: z.url().describe("Where to post a send. Recorded rather than assumed, so the sandbox need not know any platform by name."),
39
+ deviceId: z.string().min(1).describe("The device's id, which also identifies this registration everywhere else in this group."),
40
+ secret: z.string().min(1).describe("Proof that this sandbox may notify this device. The relay never learns which sandbox is calling."),
41
+ });
42
+ export type RelayChannel = z.infer<typeof RelayChannelSchema>;
43
+ export const PushChannelSchema = z.discriminatedUnion("kind", [WebPushChannelSchema, RelayChannelSchema]);
44
+ export type PushChannel = z.infer<typeof PushChannelSchema>;
45
+ // The one identity every push route speaks: subscribe upserts by it, unsubscribe and the config probe name
46
+ // devices by it. Shape-derived so the daemon and the web app can never disagree about what identifies a row,
47
+ // a browser is its push endpoint, a native install is the deviceId its relay registration minted.
48
+ export const channelId = (channel: PushChannel): string => (channel.kind === "webpush" ? channel.endpoint : channel.deviceId);
49
+ // What the service worker renders. `url` is the in-app route the notification opens (the click handler
50
+ // focuses an existing tab there rather than spawning a new one); `tag` collapses repeats, a second
51
+ // "waiting on you" for the same conversation REPLACES the first instead of stacking. Push payloads are
52
+ // capped by the push services themselves (~4KB after encryption), which is why nothing here carries a
53
+ // transcript or a diff, the notification is a pointer back into the workspace, not a delivery mechanism
54
+ // for content.
55
+ export const PushNotificationSchema = z.object({
56
+ title: z.string().min(1).describe("The headline."),
57
+ body: z
58
+ .string()
59
+ .describe(
60
+ "The line under it. Push services cap the whole payload at a few kilobytes, which is why nothing here carries a transcript or a diff: a notification is a pointer back, not a delivery.",
61
+ ),
62
+ url: z.string().optional().describe("Where tapping it goes. An existing tab is focused rather than a new one opened."),
63
+ tag: z
64
+ .string()
65
+ .optional()
66
+ .describe("Collapses repeats: a second notification with the same tag replaces the first instead of stacking beside it."),
67
+ // Whether the notification stays on screen until dismissed. Set for the "agent is blocked on you" cases,
68
+ // where a notification that auto-dismisses is a request that silently went unanswered.
69
+ requireInteraction: z
70
+ .boolean()
71
+ .optional()
72
+ .describe(
73
+ "Keep it on screen until it is dismissed. Used when the agent is waiting for you, where one that fades away is a question that went unanswered in silence.",
74
+ ),
75
+ });
76
+ export type PushNotification = z.infer<typeof PushNotificationSchema>;
77
+ // The VAPID public key a browser needs to subscribe (native shells ignore it), plus whether the asking
78
+ // device's channel is already known, so the settings toggle can render its true state instead of trusting
79
+ // the device's permission alone (a granted permission with no daemon-side row would notify nothing).
80
+ export const PushConfigSchema = z.object({
81
+ publicKey: z.string().describe("The key a browser needs in order to subscribe. Native apps ignore it."),
82
+ subscribed: z
83
+ .boolean()
84
+ .describe(
85
+ "Whether the asking device is already registered, so a toggle can show its real state instead of trusting the device's own permission, which can be granted with nothing behind it.",
86
+ ),
87
+ });
88
+ export const PushChannelIdSchema = z.object({
89
+ id: z.string().min(1).describe("Which device: a browser's push address, or a native install's device id."),
90
+ });
91
+ // The optional `id` says WHICH device is asking (see channelId); without it `subscribed` could only speak
92
+ // for the sandbox as a whole, which is never the question the settings toggle needs answered.
93
+ export const PushConfigQuerySchema = z.object({
94
+ id: z
95
+ .string()
96
+ .min(1)
97
+ .optional()
98
+ .describe("Which device is asking. Without it the answer can only speak for the sandbox as a whole, which is rarely the question."),
99
+ });
100
+ // What a test send actually achieved. `{ ok: true }` would be a lie the one place it matters most: the button
101
+ // exists to prove a chain the user cannot inspect, so "the daemon accepted the request" is not the answer to
102
+ // the question being asked. A count separates "your OS swallowed it" from "nothing was sent at all".
103
+ export const PushTestSchema = z.object({
104
+ delivered: z
105
+ .number()
106
+ .int()
107
+ .nonnegative()
108
+ .describe(
109
+ "How many devices actually accepted it. A count rather than a yes, because this button exists to prove a chain nobody can inspect, and the sandbox having accepted the request is not the question being asked.",
110
+ ),
111
+ });
112
+ export type PushTest = z.infer<typeof PushTestSchema>;
@@ -0,0 +1,68 @@
1
+ // secrets: user-supplied env-var secrets the daemon writes to desired-state/.env
2
+ import { z } from "zod";
3
+ // The web posts a Cloudflare token / GitHub PAT / another-host SSH key straight to the sandbox daemon (never
4
+ // through the platform); `apply` reloads .env each run so a new secret is picked up with NO restart. `list`
5
+ // returns KEYS ONLY, the values never leave the sandbox; `reveal` is the one deliberate, owner-only exception.
6
+ export const SecretSetSchema = z.object({
7
+ key: z
8
+ .string()
9
+ .regex(/^[A-Za-z_][A-Za-z0-9_]*$/)
10
+ .max(128)
11
+ .describe("The name to store it under, which is the name a process will find it by."),
12
+ value: z.string().min(1).describe("The value. It goes straight to your sandbox and never through the platform."),
13
+ });
14
+ export const SecretKeysSchema = z.object({
15
+ keys: z.array(z.string()).describe("The names that exist here. Only the names: the values never leave the sandbox."),
16
+ });
17
+ export const SecretKeyParamSchema = z.object({ key: z.string().describe("Which secret, by name.") });
18
+ export const SecretRevealSchema = z.object({ value: z.string().describe("The value itself. The only place in this API one is ever returned.") });
19
+ // One entry per secret the sandbox knows about, across every store: intent env secrets and intentic-generated
20
+ // passwords (from the desired-state repo), capability credentials, and AI-provider accounts. Values never ride
21
+ // this shape, `revealable` says whether `reveal` can return one (everything but provider accounts).
22
+ export const SecretInventoryEntrySchema = z.object({
23
+ // Env-var key for env|generated; `<provider>:<accountId>` for provider entries; capability instance id
24
+ // otherwise. Unique within the inventory, several accounts of one provider each get their own entry.
25
+ key: z.string().describe("What identifies it. Unique across the whole inventory, so several accounts of one provider each get their own entry."),
26
+ kind: z
27
+ .enum(["env", "generated", "capability", "provider"])
28
+ .describe("Where it came from: you set it, the sandbox generated it, a connection needs it, or it is a model account's credential."),
29
+ // Display name for provider entries: "<ProviderName> · <accountLabel>". Absent on env/generated entries.
30
+ label: z.string().optional().describe("A friendlier name, for entries that have one."),
31
+ status: z.enum(["missing", "set", "connected"]).describe("Whether it exists and, for a connection, whether it is working."),
32
+ // The artifact resources referencing this secret ({$secret} refs); [] for capability/provider entries.
33
+ requiredBy: z
34
+ .array(z.object({ resourceId: z.string().describe("Which resource."), type: z.string().describe("What kind of resource it is.") }))
35
+ .describe("What is waiting on it. Empty for a connection's or an account's own credential."),
36
+ // Human-readable provenance, e.g. "desired-state/.env", the UI's "where does this live" line.
37
+ storedAt: z.string().describe("Where it actually lives, in words."),
38
+ revealable: z.boolean().describe("Whether its value can be shown at all. Everything except a model account's credential can be."),
39
+ // Forgejo Actions replication state, present only after adopt on env|generated entries.
40
+ ci: z
41
+ .object({
42
+ synced: z.boolean().describe("Whether the pipeline has it."),
43
+ pushedAt: z.string().optional().describe("When it was last sent there."),
44
+ })
45
+ .optional()
46
+ .describe("Whether a copy has been given to the build pipeline."),
47
+ /* The newest row of the use ledger that concerns this entry, when the agent last SPENT it, on which lane
48
+ * (a shell command, a JS run's script, a browser field), and where it went (the head of the command or
49
+ * script, or the page's host). Names and destinations only, never values. Absent while a secret has never
50
+ * been used, which most never are. */
51
+ lastUse: z
52
+ .object({
53
+ at: z.number().describe("When, in milliseconds."),
54
+ lane: z.enum(["shell", "code", "browser"]).describe("How it was used: a command, a script, or typed into a page."),
55
+ detail: z
56
+ .string()
57
+ .optional()
58
+ .describe("Where it went: the start of the command or script, or the site. Names and destinations only, never values."),
59
+ })
60
+ .optional()
61
+ .describe("The last time an agent actually spent this secret. Absent while it never has been, which most never are."),
62
+ });
63
+ export type SecretInventoryEntry = z.infer<typeof SecretInventoryEntrySchema>;
64
+ export const SecretInventorySchema = z.object({
65
+ entries: z
66
+ .array(SecretInventoryEntrySchema)
67
+ .describe("One entry per secret this sandbox knows about, from every place they live. No values, ever."),
68
+ });
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import { MatchSnippetSchema } from "./agents.js";
3
+ export const SessionIdParamSchema = z.object({ id: z.string().describe("Which past conversation.") });
4
+ export const SessionSummarySchema = z.object({
5
+ id: z.string().describe("Its id."),
6
+ title: z.string().describe("What it is called."),
7
+ updatedAt: z.number().describe("When it last moved, in milliseconds."),
8
+ // Why a searched session matched: the line the query hit, windowed around it, and who said it. Absent on an
9
+ // unfiltered list, and on a match the title already shows, a snippet repeating the row's own heading is
10
+ // noise, not evidence. See AgentMatchSchema for the same field on the fleet's side.
11
+ snippet: MatchSnippetSchema.optional().describe(
12
+ "Why a search matched: the line it hit, with a little around it, and who said it. Absent on an unfiltered list, and on a match the title already shows, where repeating it would be noise rather than evidence.",
13
+ ),
14
+ });
15
+ export type SessionSummary = z.infer<typeof SessionSummarySchema>;
16
+ export const SessionsListSchema = z.object({ sessions: z.array(SessionSummarySchema).describe("Past conversations, newest first.") });