@intentic/sandbox-contract 1.232.0 → 1.234.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 (538) hide show
  1. package/README.md +11 -5
  2. package/dist/agent-catalog.d.ts +4 -2
  3. package/dist/agent-catalog.d.ts.map +1 -1
  4. package/dist/agent-catalog.js +20 -14
  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/chores.js +36 -1
  9. package/dist/chores/chores.js.map +1 -1
  10. package/dist/chores/probes.d.ts +1 -1
  11. package/dist/chores/probes.d.ts.map +1 -1
  12. package/dist/chores/probes.js +70 -0
  13. package/dist/chores/probes.js.map +1 -1
  14. package/dist/chores/stack.d.ts.map +1 -1
  15. package/dist/chores/stack.js +2 -1
  16. package/dist/chores/stack.js.map +1 -1
  17. package/dist/chores/verdict.d.ts +1 -1
  18. package/dist/chores/verdict.d.ts.map +1 -1
  19. package/dist/command-classes.d.ts +17 -0
  20. package/dist/command-classes.d.ts.map +1 -0
  21. package/dist/command-classes.js +189 -0
  22. package/dist/command-classes.js.map +1 -0
  23. package/dist/contracts/activity.contract.js +1 -1
  24. package/dist/contracts/activity.contract.js.map +1 -1
  25. package/dist/contracts/agent.contract.d.ts +40 -2
  26. package/dist/contracts/agent.contract.d.ts.map +1 -1
  27. package/dist/contracts/agent.contract.js +4 -1
  28. package/dist/contracts/agent.contract.js.map +1 -1
  29. package/dist/contracts/agents.contract.d.ts +24 -0
  30. package/dist/contracts/agents.contract.d.ts.map +1 -1
  31. package/dist/contracts/agents.contract.js +5 -1
  32. package/dist/contracts/agents.contract.js.map +1 -1
  33. package/dist/contracts/automations.contract.d.ts +30 -0
  34. package/dist/contracts/automations.contract.d.ts.map +1 -1
  35. package/dist/contracts/automations.contract.js +2 -1
  36. package/dist/contracts/automations.contract.js.map +1 -1
  37. package/dist/contracts/capabilities.contract.d.ts +63 -0
  38. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  39. package/dist/contracts/capabilities.contract.js +3 -1
  40. package/dist/contracts/capabilities.contract.js.map +1 -1
  41. package/dist/contracts/chores.contract.d.ts +17 -0
  42. package/dist/contracts/chores.contract.d.ts.map +1 -1
  43. package/dist/contracts/chores.contract.js +2 -1
  44. package/dist/contracts/chores.contract.js.map +1 -1
  45. package/dist/contracts/ci.contract.js +2 -1
  46. package/dist/contracts/ci.contract.js.map +1 -1
  47. package/dist/contracts/claude.contract.js +2 -1
  48. package/dist/contracts/claude.contract.js.map +1 -1
  49. package/dist/contracts/cursor.contract.js +2 -1
  50. package/dist/contracts/cursor.contract.js.map +1 -1
  51. package/dist/contracts/drafts.contract.d.ts.map +1 -1
  52. package/dist/contracts/drafts.contract.js +2 -1
  53. package/dist/contracts/drafts.contract.js.map +1 -1
  54. package/dist/contracts/endpoints.contract.d.ts.map +1 -1
  55. package/dist/contracts/endpoints.contract.js +2 -1
  56. package/dist/contracts/endpoints.contract.js.map +1 -1
  57. package/dist/contracts/exit.contract.d.ts.map +1 -1
  58. package/dist/contracts/exit.contract.js +2 -1
  59. package/dist/contracts/exit.contract.js.map +1 -1
  60. package/dist/contracts/extensions.contract.d.ts +44 -0
  61. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  62. package/dist/contracts/extensions.contract.js +4 -1
  63. package/dist/contracts/extensions.contract.js.map +1 -1
  64. package/dist/contracts/git.contract.d.ts.map +1 -1
  65. package/dist/contracts/git.contract.js +4 -1
  66. package/dist/contracts/git.contract.js.map +1 -1
  67. package/dist/contracts/grok.contract.d.ts.map +1 -1
  68. package/dist/contracts/grok.contract.js +2 -1
  69. package/dist/contracts/grok.contract.js.map +1 -1
  70. package/dist/contracts/history.contract.d.ts.map +1 -1
  71. package/dist/contracts/history.contract.js +2 -1
  72. package/dist/contracts/history.contract.js.map +1 -1
  73. package/dist/contracts/host.contract.d.ts +7 -0
  74. package/dist/contracts/host.contract.d.ts.map +1 -1
  75. package/dist/contracts/host.contract.js +4 -1
  76. package/dist/contracts/host.contract.js.map +1 -1
  77. package/dist/contracts/intentic.contract.d.ts.map +1 -1
  78. package/dist/contracts/intentic.contract.js +2 -1
  79. package/dist/contracts/intentic.contract.js.map +1 -1
  80. package/dist/contracts/inventory.contract.js +1 -1
  81. package/dist/contracts/inventory.contract.js.map +1 -1
  82. package/dist/contracts/issues.contract.d.ts +89 -0
  83. package/dist/contracts/issues.contract.d.ts.map +1 -0
  84. package/dist/contracts/issues.contract.js +50 -0
  85. package/dist/contracts/issues.contract.js.map +1 -0
  86. package/dist/contracts/logs.contract.d.ts.map +1 -1
  87. package/dist/contracts/logs.contract.js +1 -1
  88. package/dist/contracts/logs.contract.js.map +1 -1
  89. package/dist/contracts/loops.contract.js +2 -1
  90. package/dist/contracts/loops.contract.js.map +1 -1
  91. package/dist/contracts/panels.contract.d.ts.map +1 -1
  92. package/dist/contracts/panels.contract.js +2 -1
  93. package/dist/contracts/panels.contract.js.map +1 -1
  94. package/dist/contracts/personas.contract.js +2 -1
  95. package/dist/contracts/personas.contract.js.map +1 -1
  96. package/dist/contracts/ports.contract.d.ts.map +1 -1
  97. package/dist/contracts/ports.contract.js +2 -1
  98. package/dist/contracts/ports.contract.js.map +1 -1
  99. package/dist/contracts/prepush.contract.d.ts.map +1 -1
  100. package/dist/contracts/prepush.contract.js +2 -1
  101. package/dist/contracts/prepush.contract.js.map +1 -1
  102. package/dist/contracts/providers.contract.d.ts.map +1 -1
  103. package/dist/contracts/providers.contract.js +2 -1
  104. package/dist/contracts/providers.contract.js.map +1 -1
  105. package/dist/contracts/public.contract.d.ts.map +1 -1
  106. package/dist/contracts/public.contract.js +2 -1
  107. package/dist/contracts/public.contract.js.map +1 -1
  108. package/dist/contracts/push.contract.d.ts.map +1 -1
  109. package/dist/contracts/push.contract.js +2 -1
  110. package/dist/contracts/push.contract.js.map +1 -1
  111. package/dist/contracts/runner.contract.d.ts +127 -84
  112. package/dist/contracts/runner.contract.d.ts.map +1 -1
  113. package/dist/contracts/runner.contract.js +10 -2
  114. package/dist/contracts/runner.contract.js.map +1 -1
  115. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  116. package/dist/contracts/secrets.contract.js +2 -1
  117. package/dist/contracts/secrets.contract.js.map +1 -1
  118. package/dist/contracts/sessions.contract.js +1 -1
  119. package/dist/contracts/sessions.contract.js.map +1 -1
  120. package/dist/contracts/settings.contract.d.ts +32 -0
  121. package/dist/contracts/settings.contract.d.ts.map +1 -1
  122. package/dist/contracts/settings.contract.js +3 -1
  123. package/dist/contracts/settings.contract.js.map +1 -1
  124. package/dist/contracts/share.contract.d.ts.map +1 -1
  125. package/dist/contracts/share.contract.js +2 -1
  126. package/dist/contracts/share.contract.js.map +1 -1
  127. package/dist/contracts/skills.contract.d.ts.map +1 -1
  128. package/dist/contracts/skills.contract.js +2 -1
  129. package/dist/contracts/skills.contract.js.map +1 -1
  130. package/dist/contracts/system.contract.d.ts +31 -16
  131. package/dist/contracts/system.contract.d.ts.map +1 -1
  132. package/dist/contracts/system.contract.js +6 -1
  133. package/dist/contracts/system.contract.js.map +1 -1
  134. package/dist/contracts/translator.contract.d.ts.map +1 -1
  135. package/dist/contracts/translator.contract.js +4 -1
  136. package/dist/contracts/translator.contract.js.map +1 -1
  137. package/dist/contracts/usage.contract.js +1 -1
  138. package/dist/contracts/usage.contract.js.map +1 -1
  139. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  140. package/dist/contracts/vpn.contract.js +2 -1
  141. package/dist/contracts/vpn.contract.js.map +1 -1
  142. package/dist/contracts/webext.contract.d.ts +45 -0
  143. package/dist/contracts/webext.contract.d.ts.map +1 -0
  144. package/dist/contracts/webext.contract.js +12 -0
  145. package/dist/contracts/webext.contract.js.map +1 -0
  146. package/dist/contracts/workflows.contract.js +2 -1
  147. package/dist/contracts/workflows.contract.js.map +1 -1
  148. package/dist/contracts/workspace.contract.d.ts +2 -2
  149. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  150. package/dist/contracts/workspace.contract.js +7 -1
  151. package/dist/contracts/workspace.contract.js.map +1 -1
  152. package/dist/credential-material.d.ts +2 -0
  153. package/dist/credential-material.d.ts.map +1 -0
  154. package/dist/credential-material.js +36 -0
  155. package/dist/credential-material.js.map +1 -0
  156. package/dist/definition-action.d.ts +7 -0
  157. package/dist/definition-action.d.ts.map +1 -0
  158. package/dist/definition-action.js +3 -0
  159. package/dist/definition-action.js.map +1 -0
  160. package/dist/definition.d.ts +132 -21
  161. package/dist/definition.d.ts.map +1 -1
  162. package/dist/definition.js +29 -7
  163. package/dist/definition.js.map +1 -1
  164. package/dist/events.d.ts +101 -0
  165. package/dist/events.d.ts.map +1 -1
  166. package/dist/events.js +25 -1
  167. package/dist/events.js.map +1 -1
  168. package/dist/fast-tier.d.ts +1 -1
  169. package/dist/fast-tier.d.ts.map +1 -1
  170. package/dist/history-state.d.ts.map +1 -1
  171. package/dist/history-state.js +2 -0
  172. package/dist/history-state.js.map +1 -1
  173. package/dist/hostnames.d.ts +2 -0
  174. package/dist/hostnames.d.ts.map +1 -1
  175. package/dist/hostnames.js +3 -1
  176. package/dist/hostnames.js.map +1 -1
  177. package/dist/index.d.ts +411 -7
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +56 -1
  180. package/dist/index.js.map +1 -1
  181. package/dist/listener-protocol.js +1 -1
  182. package/dist/listener-protocol.js.map +1 -1
  183. package/dist/quick-model.d.ts +1 -1
  184. package/dist/quick-model.d.ts.map +1 -1
  185. package/dist/runner-protocol.d.ts +18 -0
  186. package/dist/runner-protocol.d.ts.map +1 -1
  187. package/dist/runner-protocol.js +8 -4
  188. package/dist/runner-protocol.js.map +1 -1
  189. package/dist/runtime-state.d.ts +9 -0
  190. package/dist/runtime-state.d.ts.map +1 -1
  191. package/dist/runtime-state.js +3 -0
  192. package/dist/runtime-state.js.map +1 -1
  193. package/dist/schemas/activity.d.ts +112 -0
  194. package/dist/schemas/activity.d.ts.map +1 -0
  195. package/dist/schemas/activity.js +70 -0
  196. package/dist/schemas/activity.js.map +1 -0
  197. package/dist/schemas/agent.d.ts +195 -0
  198. package/dist/schemas/agent.d.ts.map +1 -0
  199. package/dist/schemas/agent.js +171 -0
  200. package/dist/schemas/agent.js.map +1 -0
  201. package/dist/schemas/agents.d.ts +690 -0
  202. package/dist/schemas/agents.d.ts.map +1 -0
  203. package/dist/schemas/agents.js +314 -0
  204. package/dist/schemas/agents.js.map +1 -0
  205. package/dist/schemas/automations.d.ts +781 -0
  206. package/dist/schemas/automations.d.ts.map +1 -0
  207. package/dist/schemas/automations.js +223 -0
  208. package/dist/schemas/automations.js.map +1 -0
  209. package/dist/schemas/capabilities.d.ts +753 -0
  210. package/dist/schemas/capabilities.d.ts.map +1 -0
  211. package/dist/schemas/capabilities.js +269 -0
  212. package/dist/schemas/capabilities.js.map +1 -0
  213. package/dist/schemas/ci.d.ts +179 -0
  214. package/dist/schemas/ci.d.ts.map +1 -0
  215. package/dist/schemas/ci.js +99 -0
  216. package/dist/schemas/ci.js.map +1 -0
  217. package/dist/schemas/claude-gate.d.ts +13 -0
  218. package/dist/schemas/claude-gate.d.ts.map +1 -0
  219. package/dist/schemas/claude-gate.js +8 -0
  220. package/dist/schemas/claude-gate.js.map +1 -0
  221. package/dist/schemas/codebase-health.d.ts +56 -0
  222. package/dist/schemas/codebase-health.d.ts.map +1 -0
  223. package/dist/schemas/codebase-health.js +43 -0
  224. package/dist/schemas/codebase-health.js.map +1 -0
  225. package/dist/schemas/computers.d.ts +386 -0
  226. package/dist/schemas/computers.d.ts.map +1 -0
  227. package/dist/schemas/computers.js +107 -0
  228. package/dist/schemas/computers.js.map +1 -0
  229. package/dist/schemas/drafts.d.ts +84 -0
  230. package/dist/schemas/drafts.d.ts.map +1 -0
  231. package/dist/schemas/drafts.js +44 -0
  232. package/dist/schemas/drafts.js.map +1 -0
  233. package/dist/schemas/environment.d.ts +349 -0
  234. package/dist/schemas/environment.d.ts.map +1 -0
  235. package/dist/schemas/environment.js +111 -0
  236. package/dist/schemas/environment.js.map +1 -0
  237. package/dist/schemas/exit.d.ts +151 -0
  238. package/dist/schemas/exit.d.ts.map +1 -0
  239. package/dist/schemas/exit.js +115 -0
  240. package/dist/schemas/exit.js.map +1 -0
  241. package/dist/schemas/extension-updates.d.ts +1016 -0
  242. package/dist/schemas/extension-updates.d.ts.map +1 -0
  243. package/dist/schemas/extension-updates.js +199 -0
  244. package/dist/schemas/extension-updates.js.map +1 -0
  245. package/dist/schemas/fast-mode.d.ts +8 -0
  246. package/dist/schemas/fast-mode.d.ts.map +1 -0
  247. package/dist/schemas/fast-mode.js +3 -0
  248. package/dist/schemas/fast-mode.js.map +1 -0
  249. package/dist/schemas/git-history.d.ts +238 -0
  250. package/dist/schemas/git-history.d.ts.map +1 -0
  251. package/dist/schemas/git-history.js +152 -0
  252. package/dist/schemas/git-history.js.map +1 -0
  253. package/dist/schemas/git.d.ts +471 -0
  254. package/dist/schemas/git.d.ts.map +1 -0
  255. package/dist/schemas/git.js +204 -0
  256. package/dist/schemas/git.js.map +1 -0
  257. package/dist/schemas/history.d.ts +100 -0
  258. package/dist/schemas/history.d.ts.map +1 -0
  259. package/dist/schemas/history.js +54 -0
  260. package/dist/schemas/history.js.map +1 -0
  261. package/dist/schemas/hosts.d.ts +41 -0
  262. package/dist/schemas/hosts.d.ts.map +1 -0
  263. package/dist/schemas/hosts.js +18 -0
  264. package/dist/schemas/hosts.js.map +1 -0
  265. package/dist/schemas/intentic.d.ts +5 -0
  266. package/dist/schemas/intentic.d.ts.map +1 -0
  267. package/dist/schemas/intentic.js +3 -0
  268. package/dist/schemas/intentic.js.map +1 -0
  269. package/dist/schemas/internal.d.ts +8 -0
  270. package/dist/schemas/internal.d.ts.map +1 -0
  271. package/dist/schemas/internal.js +12 -0
  272. package/dist/schemas/internal.js.map +1 -0
  273. package/dist/schemas/inventory.d.ts +171 -0
  274. package/dist/schemas/inventory.d.ts.map +1 -0
  275. package/dist/schemas/inventory.js +51 -0
  276. package/dist/schemas/inventory.js.map +1 -0
  277. package/dist/schemas/issues.d.ts +324 -0
  278. package/dist/schemas/issues.d.ts.map +1 -0
  279. package/dist/schemas/issues.js +107 -0
  280. package/dist/schemas/issues.js.map +1 -0
  281. package/dist/schemas/logs.d.ts +67 -0
  282. package/dist/schemas/logs.d.ts.map +1 -0
  283. package/dist/schemas/logs.js +54 -0
  284. package/dist/schemas/logs.js.map +1 -0
  285. package/dist/schemas/loops.d.ts +415 -0
  286. package/dist/schemas/loops.d.ts.map +1 -0
  287. package/dist/schemas/loops.js +188 -0
  288. package/dist/schemas/loops.js.map +1 -0
  289. package/dist/schemas/maintenance.d.ts +618 -0
  290. package/dist/schemas/maintenance.d.ts.map +1 -0
  291. package/dist/schemas/maintenance.js +222 -0
  292. package/dist/schemas/maintenance.js.map +1 -0
  293. package/dist/schemas/marketplace.d.ts +64 -0
  294. package/dist/schemas/marketplace.d.ts.map +1 -0
  295. package/dist/schemas/marketplace.js +17 -0
  296. package/dist/schemas/marketplace.js.map +1 -0
  297. package/dist/schemas/panels.d.ts +61 -0
  298. package/dist/schemas/panels.d.ts.map +1 -0
  299. package/dist/schemas/panels.js +51 -0
  300. package/dist/schemas/panels.js.map +1 -0
  301. package/dist/schemas/personas.d.ts +122 -0
  302. package/dist/schemas/personas.d.ts.map +1 -0
  303. package/dist/schemas/personas.js +102 -0
  304. package/dist/schemas/personas.js.map +1 -0
  305. package/dist/schemas/plan-limits.d.ts +172 -0
  306. package/dist/schemas/plan-limits.d.ts.map +1 -0
  307. package/dist/schemas/plan-limits.js +126 -0
  308. package/dist/schemas/plan-limits.js.map +1 -0
  309. package/dist/schemas/ports.d.ts +71 -0
  310. package/dist/schemas/ports.d.ts.map +1 -0
  311. package/dist/schemas/ports.js +42 -0
  312. package/dist/schemas/ports.js.map +1 -0
  313. package/dist/schemas/provider-oauth.d.ts +128 -0
  314. package/dist/schemas/provider-oauth.d.ts.map +1 -0
  315. package/dist/schemas/provider-oauth.js +91 -0
  316. package/dist/schemas/provider-oauth.js.map +1 -0
  317. package/dist/schemas/provider-subscriptions.d.ts +9 -0
  318. package/dist/schemas/provider-subscriptions.d.ts.map +1 -0
  319. package/dist/schemas/provider-subscriptions.js +3 -0
  320. package/dist/schemas/provider-subscriptions.js.map +1 -0
  321. package/dist/schemas/public.d.ts +32 -0
  322. package/dist/schemas/public.d.ts.map +1 -0
  323. package/dist/schemas/public.js +29 -0
  324. package/dist/schemas/public.js.map +1 -0
  325. package/dist/schemas/push.d.ts +55 -0
  326. package/dist/schemas/push.d.ts.map +1 -0
  327. package/dist/schemas/push.js +60 -0
  328. package/dist/schemas/push.js.map +1 -0
  329. package/dist/schemas/secrets.d.ts +86 -0
  330. package/dist/schemas/secrets.d.ts.map +1 -0
  331. package/dist/schemas/secrets.js +51 -0
  332. package/dist/schemas/secrets.js.map +1 -0
  333. package/dist/schemas/sessions.d.ts +32 -0
  334. package/dist/schemas/sessions.d.ts.map +1 -0
  335. package/dist/schemas/sessions.js +11 -0
  336. package/dist/schemas/sessions.js.map +1 -0
  337. package/dist/schemas/settings.d.ts +554 -0
  338. package/dist/schemas/settings.d.ts.map +1 -0
  339. package/dist/schemas/settings.js +263 -0
  340. package/dist/schemas/settings.js.map +1 -0
  341. package/dist/schemas/share.d.ts +49 -0
  342. package/dist/schemas/share.d.ts.map +1 -0
  343. package/dist/schemas/share.js +26 -0
  344. package/dist/schemas/share.js.map +1 -0
  345. package/dist/schemas/shared.d.ts +22 -0
  346. package/dist/schemas/shared.d.ts.map +1 -0
  347. package/dist/schemas/shared.js +16 -0
  348. package/dist/schemas/shared.js.map +1 -0
  349. package/dist/schemas/system.d.ts +86 -0
  350. package/dist/schemas/system.d.ts.map +1 -0
  351. package/dist/schemas/system.js +64 -0
  352. package/dist/schemas/system.js.map +1 -0
  353. package/dist/schemas/terminal.d.ts +230 -0
  354. package/dist/schemas/terminal.d.ts.map +1 -0
  355. package/dist/schemas/terminal.js +133 -0
  356. package/dist/schemas/terminal.js.map +1 -0
  357. package/dist/schemas/usage.d.ts +113 -0
  358. package/dist/schemas/usage.d.ts.map +1 -0
  359. package/dist/schemas/usage.js +91 -0
  360. package/dist/schemas/usage.js.map +1 -0
  361. package/dist/schemas/vpn.d.ts +229 -0
  362. package/dist/schemas/vpn.d.ts.map +1 -0
  363. package/dist/schemas/vpn.js +115 -0
  364. package/dist/schemas/vpn.js.map +1 -0
  365. package/dist/schemas/webext.d.ts +122 -0
  366. package/dist/schemas/webext.d.ts.map +1 -0
  367. package/dist/schemas/webext.js +45 -0
  368. package/dist/schemas/webext.js.map +1 -0
  369. package/dist/schemas/workflows.d.ts +881 -0
  370. package/dist/schemas/workflows.d.ts.map +1 -0
  371. package/dist/schemas/workflows.js +164 -0
  372. package/dist/schemas/workflows.js.map +1 -0
  373. package/dist/schemas/workspace-repos.d.ts +143 -0
  374. package/dist/schemas/workspace-repos.d.ts.map +1 -0
  375. package/dist/schemas/workspace-repos.js +87 -0
  376. package/dist/schemas/workspace-repos.js.map +1 -0
  377. package/dist/schemas/workspace-search.d.ts +170 -0
  378. package/dist/schemas/workspace-search.d.ts.map +1 -0
  379. package/dist/schemas/workspace-search.js +85 -0
  380. package/dist/schemas/workspace-search.js.map +1 -0
  381. package/dist/schemas/workspace-setup.d.ts +48 -0
  382. package/dist/schemas/workspace-setup.d.ts.map +1 -0
  383. package/dist/schemas/workspace-setup.js +26 -0
  384. package/dist/schemas/workspace-setup.js.map +1 -0
  385. package/dist/schemas/workspace-tree.d.ts +120 -0
  386. package/dist/schemas/workspace-tree.d.ts.map +1 -0
  387. package/dist/schemas/workspace-tree.js +111 -0
  388. package/dist/schemas/workspace-tree.js.map +1 -0
  389. package/dist/webext-links.d.ts +14 -0
  390. package/dist/webext-links.d.ts.map +1 -0
  391. package/dist/webext-links.js +25 -0
  392. package/dist/webext-links.js.map +1 -0
  393. package/dist/webext-protocol.d.ts +8 -0
  394. package/dist/webext-protocol.d.ts.map +1 -0
  395. package/dist/webext-protocol.js +7 -0
  396. package/dist/webext-protocol.js.map +1 -0
  397. package/dist/workflow-faults.d.ts +1 -1
  398. package/dist/workflow-faults.d.ts.map +1 -1
  399. package/dist/workspace-state.d.ts +12 -8
  400. package/dist/workspace-state.d.ts.map +1 -1
  401. package/dist/workspace-state.js +15 -10
  402. package/dist/workspace-state.js.map +1 -1
  403. package/package.json +19 -8
  404. package/src/agent-catalog.test.ts +56 -55
  405. package/src/agent-catalog.ts +33 -33
  406. package/src/capability-ledger.test.ts +11 -2
  407. package/src/chores/chores.test.ts +1 -1
  408. package/src/chores/chores.ts +67 -2
  409. package/src/chores/probes.test.ts +65 -0
  410. package/src/chores/probes.ts +133 -1
  411. package/src/chores/stack.test.ts +19 -0
  412. package/src/chores/stack.ts +19 -3
  413. package/src/chores/verdict.test.ts +40 -20
  414. package/src/chores/verdict.ts +1 -1
  415. package/src/command-classes.test.ts +445 -0
  416. package/src/command-classes.ts +468 -0
  417. package/src/contracts/activity.contract.ts +1 -1
  418. package/src/contracts/agent.contract.ts +4 -13
  419. package/src/contracts/agents.contract.ts +6 -6
  420. package/src/contracts/automations.contract.ts +2 -2
  421. package/src/contracts/capabilities.contract.ts +3 -4
  422. package/src/contracts/chores.contract.ts +2 -1
  423. package/src/contracts/ci.contract.ts +2 -2
  424. package/src/contracts/claude.contract.ts +2 -2
  425. package/src/contracts/cursor.contract.ts +2 -2
  426. package/src/contracts/drafts.contract.ts +2 -1
  427. package/src/contracts/endpoints.contract.ts +2 -1
  428. package/src/contracts/exit.contract.ts +2 -1
  429. package/src/contracts/extensions.contract.ts +8 -7
  430. package/src/contracts/git.contract.ts +19 -18
  431. package/src/contracts/grok.contract.ts +2 -1
  432. package/src/contracts/history.contract.ts +2 -1
  433. package/src/contracts/host.contract.ts +4 -1
  434. package/src/contracts/intentic.contract.ts +2 -1
  435. package/src/contracts/inventory.contract.ts +1 -1
  436. package/src/contracts/issues.contract.ts +60 -0
  437. package/src/contracts/logs.contract.ts +7 -1
  438. package/src/contracts/loops.contract.ts +2 -2
  439. package/src/contracts/panels.contract.ts +2 -1
  440. package/src/contracts/personas.contract.ts +3 -3
  441. package/src/contracts/ports.contract.ts +3 -2
  442. package/src/contracts/prepush.contract.ts +2 -1
  443. package/src/contracts/providers.contract.ts +2 -1
  444. package/src/contracts/public.contract.ts +3 -2
  445. package/src/contracts/push.contract.ts +2 -1
  446. package/src/contracts/runner.contract.ts +18 -2
  447. package/src/contracts/secrets.contract.ts +2 -1
  448. package/src/contracts/sessions.contract.ts +1 -1
  449. package/src/contracts/settings.contract.ts +3 -9
  450. package/src/contracts/share.contract.ts +3 -2
  451. package/src/contracts/skills.contract.ts +2 -1
  452. package/src/contracts/system.contract.ts +6 -9
  453. package/src/contracts/translator.contract.ts +4 -1
  454. package/src/contracts/usage.contract.ts +1 -1
  455. package/src/contracts/vpn.contract.ts +2 -8
  456. package/src/contracts/webext.contract.ts +37 -0
  457. package/src/contracts/workflows.contract.ts +2 -2
  458. package/src/contracts/workspace.contract.ts +10 -12
  459. package/src/conversation-ids.test.ts +1 -1
  460. package/src/credential-material.test.ts +120 -0
  461. package/src/credential-material.ts +100 -0
  462. package/src/definition-action.ts +8 -0
  463. package/src/definition.ts +74 -10
  464. package/src/events.ts +84 -22
  465. package/src/fast-tier.ts +1 -1
  466. package/src/history-state.ts +17 -0
  467. package/src/host-protocol.ts +1 -1
  468. package/src/hostnames.test.ts +2 -2
  469. package/src/hostnames.ts +18 -2
  470. package/src/index.ts +65 -1
  471. package/src/listener-protocol.ts +1 -1
  472. package/src/quick-model.ts +1 -1
  473. package/src/routes.test.ts +4 -2
  474. package/src/runner-protocol.ts +35 -5
  475. package/src/runtime-state.ts +16 -0
  476. package/src/schemas/activity.ts +123 -0
  477. package/src/schemas/agent.ts +422 -0
  478. package/src/schemas/agents.ts +802 -0
  479. package/src/schemas/automations.ts +522 -0
  480. package/src/schemas/capabilities.ts +729 -0
  481. package/src/schemas/ci.ts +235 -0
  482. package/src/schemas/claude-gate.ts +13 -0
  483. package/src/schemas/codebase-health.ts +64 -0
  484. package/src/schemas/computers.ts +287 -0
  485. package/src/schemas/drafts.ts +108 -0
  486. package/src/schemas/environment.ts +276 -0
  487. package/src/schemas/exit.ts +222 -0
  488. package/src/schemas/extension-updates.ts +324 -0
  489. package/src/schemas/fast-mode.ts +8 -0
  490. package/src/schemas/git-history.ts +265 -0
  491. package/src/schemas/git.ts +430 -0
  492. package/src/schemas/history.ts +112 -0
  493. package/src/schemas/hosts.ts +37 -0
  494. package/src/schemas/intentic.ts +2 -0
  495. package/src/schemas/internal.ts +17 -0
  496. package/src/schemas/inventory.ts +68 -0
  497. package/src/schemas/issues.ts +279 -0
  498. package/src/schemas/logs.ts +96 -0
  499. package/src/schemas/loops.ts +401 -0
  500. package/src/schemas/maintenance.ts +471 -0
  501. package/src/schemas/marketplace.ts +23 -0
  502. package/src/schemas/panels.ts +99 -0
  503. package/src/schemas/personas.ts +281 -0
  504. package/src/schemas/plan-limits.ts +255 -0
  505. package/src/schemas/ports.ts +84 -0
  506. package/src/schemas/provider-oauth.ts +191 -0
  507. package/src/schemas/provider-subscriptions.ts +11 -0
  508. package/src/schemas/public.ts +52 -0
  509. package/src/schemas/push.ts +112 -0
  510. package/src/schemas/secrets.ts +68 -0
  511. package/src/schemas/sessions.ts +16 -0
  512. package/src/schemas/settings.ts +964 -0
  513. package/src/schemas/share.ts +71 -0
  514. package/src/schemas/shared.ts +32 -0
  515. package/src/schemas/system.ts +156 -0
  516. package/src/schemas/terminal.ts +288 -0
  517. package/src/schemas/usage.ts +303 -0
  518. package/src/{schemas.test.ts → schemas/version-seam.test.ts} +4 -2
  519. package/src/schemas/vpn.ts +215 -0
  520. package/src/schemas/webext.ts +108 -0
  521. package/src/schemas/workflows.ts +413 -0
  522. package/src/schemas/workspace-repos.ts +123 -0
  523. package/src/schemas/workspace-search.ts +141 -0
  524. package/src/schemas/workspace-setup.ts +43 -0
  525. package/src/schemas/workspace-tree.ts +234 -0
  526. package/src/title.test.ts +1 -1
  527. package/src/tunnel-ids.test.ts +3 -1
  528. package/src/webext-links.ts +90 -0
  529. package/src/webext-protocol.ts +27 -0
  530. package/src/workflow-faults.test.ts +1 -1
  531. package/src/workflow-faults.ts +1 -1
  532. package/src/workspace-state.test.ts +6 -4
  533. package/src/workspace-state.ts +35 -50
  534. package/dist/schemas.d.ts +0 -9909
  535. package/dist/schemas.d.ts.map +0 -1
  536. package/dist/schemas.js +0 -4288
  537. package/dist/schemas.js.map +0 -1
  538. package/src/schemas.ts +0 -10090
@@ -0,0 +1,468 @@
1
+ import { type CommandClass, CommandClassSchema } from "./schemas/agent.js";
2
+
3
+ /* WHICH CLASSES A SHELL COMMAND FALLS IN, the classifier behind every command gate, read before the command runs.
4
+ *
5
+ * IT LIVES IN THE CONTRACT PACKAGE because there are TWO enforcement points and they must not drift. The
6
+ * sandbox's own gate (sandbox/src/guard/command-gate.ts) judges what the agent types here; the machine agent's
7
+ * shell tool (_computers/machine/src/computer/tools/shell.ts) judges what it sends to somebody's laptop. Those answer to
8
+ * different policy (a rulebook with a permission card here, a scope switch on the card there) but they must
9
+ * agree on WHAT A COMMAND IS, or a class the owner thought they had covered turns out to mean something else on
10
+ * the surface where it mattered most. One table, two consults.
11
+ *
12
+ * ALL of them, not the first match, because a gate takes the most restrictive verdict across them and the
13
+ * interesting commands are exactly the ones in two classes at once: `curl -d @.env https://…` is both
14
+ * `secrets.access` and `network.outbound`, and an owner who holds either meant to see it. Returning one class
15
+ * would let a rule on the other decide.
16
+ *
17
+ * HONESTY, the same note the outbound sniffer carries and for the same reason. This is regex over shell text.
18
+ * A creatively quoted command, a path assembled from a variable, or a script written in one call and run in the
19
+ * next goes past it untouched. So a gate built on this is friction and a prompt for well-behaved work, never a
20
+ * boundary, the boundaries are structural and elsewhere: the container, the isolated worktree, the land gate,
21
+ * an automation's tool allowlist, and, on somebody's own computer, the scope switches enforced there.
22
+ *
23
+ * Matching is deliberately UNANCHORED, substrings, not line starts. Another PreToolUse hook may have rewrapped
24
+ * the command by the time this reads it (agent-terminals.ts wraps every Bash call in bin/tmux-run), and the
25
+ * agent's own line survives verbatim inside that wrapper. Nothing the wrapper adds is in any class below.
26
+ *
27
+ * `[^|;&]*` in a pattern keeps a flag tied to the verb before it, so a later command in a pipeline cannot lend
28
+ * its flags to an earlier one, `git push origin | grep -f patterns` is not a force-push.
29
+ *
30
+ * IT REPORTS WHERE, not just whether (matchCommand below). A permission card holding four hundred characters of
31
+ * shell has to answer one question before anything else on it can be read: which part of this is the part that
32
+ * stopped it. That answer only exists here, at the moment a pattern fires, and re-deriving it in the browser
33
+ * would be a second classifier with all the ways to disagree with this one. So every table hands back offsets
34
+ * and the card marks them; `classifyCommand` is the same walk with the offsets dropped.
35
+ *
36
+ * AND IT TAKES A FACT WHERE THE CALLER HAS ONE (CommandContext below). Every table here is a pattern over text,
37
+ * which is exactly the right instrument for a verb — `git push --force` means what it says, and no amount of
38
+ * looking at the repository makes it mean less. It is the WRONG instrument on its own for a class defined by a
39
+ * FILE: `secrets.access` fires on `~/.npmrc` because that path usually holds a token, and "usually" left this
40
+ * raising cards over registry config, over `.env` files holding a port number, over `~/.ssh/known_hosts`, and
41
+ * over files that were not there at all. Those cards are not near misses, they are noise, and noise is what
42
+ * teaches an owner to answer a card without reading it. A caller that can open the file (guard/credential-
43
+ * files.ts, on the sandbox that is about to run the command) answers the question the pattern could only guess
44
+ * at, and only ever in the direction of dropping a class it positively cleared — see credentialReads.
45
+ */
46
+
47
+ // A half-open slice of the command text, in UTF-16 code units, the offsets a renderer slices with.
48
+ export interface CommandSpan {
49
+ readonly start: number;
50
+ readonly end: number;
51
+ }
52
+
53
+ // One class the command fell in, and the fragments that put it there. `spans` is never empty: a class with
54
+ // nothing to point at is a class this walk does not report.
55
+ export interface CommandMatch {
56
+ readonly commandClass: CommandClass;
57
+ readonly spans: readonly CommandSpan[];
58
+ }
59
+
60
+ /* WHAT THE CALLER CAN CHECK THAT THE PATTERNS CANNOT. Optional everywhere: absent ⇒ every table answers from
61
+ * the command text alone, which is what the browser, the machine agent and every test that does not care get. */
62
+ export interface CommandContext {
63
+ /* Does the file at this path — as the command spells it, `~/.npmrc`, `.env`, `/work/app/.env.local` — hold
64
+ * credential material? (credential-material.ts says what that means; the caller says how to read a file.)
65
+ *
66
+ * THREE ANSWERS, and the third is the important one. `true` ⇒ it does. `false` ⇒ it was opened and read and
67
+ * there is no credential in it, or there is no such file. `undefined` ⇒ COULD NOT TELL: a path built from a
68
+ * variable, a glob, a directory, a file on another machine, an unreadable one. Only `false` drops a class;
69
+ * a rule that fell back to "no" whenever nobody could look would be a rule that quietly stopped applying
70
+ * exactly where checking was hardest. */
71
+ readonly holdsSecret?: (path: string) => boolean | undefined;
72
+ }
73
+
74
+ /* The `g` twin of a table's patterns, built once. The tables are written WITHOUT `g` because a lastIndex that
75
+ * survives a call is the classic way a shared regex starts skipping every other match, and `test` is what the
76
+ * verdict path wants. `matchAll` demands one, so the twins live here instead of being flagged in place.
77
+ * (`matchAll` clones the regex it is given, so these stay stateless too.) */
78
+ const globally = (patterns: readonly RegExp[]): readonly RegExp[] => patterns.map((pattern) => new RegExp(pattern.source, `${pattern.flags}g`));
79
+
80
+ // Every occurrence of every pattern, as spans over `command`. The WHOLE match, not a capture group: a pattern
81
+ // here is written to span the consequence (`git push … --force`, `curl … https://`), and cutting it back to a
82
+ // group would point at the flag while leaving the verb it belongs to unmarked.
83
+ const spansOf = (patterns: readonly RegExp[], command: string): CommandSpan[] =>
84
+ patterns.flatMap((pattern) => [...command.matchAll(pattern)].map((match) => ({ start: match.index, end: match.index + match[0].length })));
85
+
86
+ /* Sorted, with overlaps folded together. Two patterns firing on one fragment is ordinary here (a script's
87
+ * recursive delete matches both the with-a-literal-path pattern and the any-path one), and handing a renderer
88
+ * overlapping ranges makes it either double-paint or reinvent this. Adjacency is NOT merged: touching spans
89
+ * from genuinely different fragments read correctly as two marks. */
90
+ const normalize = (spans: readonly CommandSpan[]): CommandSpan[] => {
91
+ const merged: CommandSpan[] = [];
92
+ for (const span of [...spans].sort((left, right) => left.start - right.start || left.end - right.end)) {
93
+ const last = merged.at(-1);
94
+ if (last !== undefined && span.start < last.end) {
95
+ merged[merged.length - 1] = { start: last.start, end: Math.max(last.end, span.end) };
96
+ continue;
97
+ }
98
+ merged.push(span);
99
+ }
100
+ return merged;
101
+ };
102
+
103
+ const GIT_DESTRUCTIVE = [
104
+ /\bgit\s+push\b[^|;&]*\s(?:-f\b|--force\b|--force-with-lease\b|--delete\b)/,
105
+ /\bgit\s+reset\b[^|;&]*\s--hard\b/,
106
+ // Any `clean` that forces: it deletes untracked files, which is work no history holds a copy of.
107
+ /\bgit\s+clean\b[^|;&]*\s-{1,2}[a-zA-Z]*f/,
108
+ /\bgit\s+branch\b[^|;&]*\s(?:-D\b|--delete\s+--force\b|--force\s+--delete\b)/,
109
+ /\bgit\s+filter-branch\b/,
110
+ ];
111
+
112
+ /* THE CREDENTIAL THAT IS IN THE COMMAND, not in some file the command names. `{{secret:NAME}}` becomes the real
113
+ * value on the way into the process (agent/agent-secrets.ts), so a command carrying one is reading a credential
114
+ * by definition and there is nothing for a filesystem to add: this half of the class is never fact-checked.
115
+ *
116
+ * Without it the outside-content floor in guard/actions.ts is bypassed by writing a reference into a curl
117
+ * instead of reading a dotenv, which is the shorter route to the same place: `curl -d @.env` is held,
118
+ * `curl -d '{"t":"{{secret:X}}"}'` was not. The alphabet is REFERENCE's, from secrets/secret-registry.ts,
119
+ * respelled rather than imported to keep this table free of a dependency on the stores it describes. */
120
+ const SECRET_REFERENCES = [/\{\{secret:[A-Za-z0-9_./-]+\}\}/];
121
+
122
+ /* A PATH THAT USUALLY HOLDS A CREDENTIAL — a guess about a FILE, which is why every entry here is subject to
123
+ * CommandContext.holdsSecret and the table above is not. Each pattern spans as much of the path as it can, so
124
+ * the card marks `.ssh/id_ed25519` rather than `.ssh`, and so the word around it (enclosingPath) resolves.
125
+ *
126
+ * WHAT IS DELIBERATELY NOT HERE is as much of the definition as what is: the public half of a keypair, the
127
+ * host list beside it, and the checked-in templates that ship next to the real file in every repo. None of
128
+ * those is credential material in any file, so no fact-check is needed to know they do not belong — and each
129
+ * of them was, before this, an ordinary setup command earning a card that said "read credential material". */
130
+ /* The directory part in front of a filename, so a pattern spans `~/.aws/credentials` rather than the
131
+ * `.aws/credentials` inside it: what the card marks then reads as the file, and the word handed to the
132
+ * fact-check IS the file. Permissive about `~` and `${HOME}` on purpose — expanding those is the checker's job
133
+ * (guard/credential-files.ts), and a path this over-reaches on resolves to nothing, which changes nothing. */
134
+ const LEADING_PATH = String.raw`[\w~$.{}/\\-]*`;
135
+
136
+ const CREDENTIAL_PATHS = [
137
+ /* A dotenv file: `.env`, `.env.production`, `-d @.env`. NOT the checked-in templates that sit beside it in
138
+ * every repo, and not `process.env`, the lookbehind is what excludes the latter, which is otherwise the
139
+ * single most common string in this workspace's own commands and would hold every grep for it. */
140
+ /(?<![\w.])\.env(?!\.(?:example|sample|template))(?:\.[\w-]+)?\b/,
141
+ /* The ssh directory and what is under it, EXCEPT the three members that are public by design.
142
+ * `ssh-keyscan github.com >> ~/.ssh/known_hosts` is the first thing an agent does on a fresh box, `.pub` is
143
+ * the half of a keypair you are supposed to hand out, and `~/.ssh/config` is host aliases. The bare
144
+ * directory still counts (`cp -r ~/.ssh /tmp` is the copy that matters, and it names no file at all), which
145
+ * is why the lookaheads sit outside the optional path tail rather than inside it: an exclusion inside an
146
+ * optional group is one the regex backtracks around, matching `.ssh` and reporting the class anyway. */
147
+ /\.ssh(?!\w)(?!\/(?:known_hosts|config|authorized_keys|environment)(?!\w))(?!\/[\w.-]*\.pub(?!\w))(?:\/[\w.\-/]*)?/,
148
+ // A private key by its conventional name. `.pub` beside it is the public half and is not this.
149
+ /\bid_(?:rsa|dsa|ecdsa|ed25519)\b(?!\.pub\b)/,
150
+ new RegExp(String.raw`${LEADING_PATH}\.aws/credentials\b`),
151
+ // An npmrc, but not the checked-in template beside it — the `.env` exclusion, which this had been missing.
152
+ new RegExp(String.raw`${LEADING_PATH}\.npmrc(?!\.(?:example|sample|template))\b`),
153
+ new RegExp(String.raw`${LEADING_PATH}\.git-credentials\b`),
154
+ new RegExp(String.raw`${LEADING_PATH}\.credentials\.json\b`),
155
+ ];
156
+
157
+ const PACKAGE_PUBLISH = [
158
+ /\b(?:npm|pnpm|yarn|bun)\s+publish\b/,
159
+ /\bcargo\s+publish\b/,
160
+ /\bgh\s+release\s+create\b/,
161
+ /\bdocker\s+push\b/,
162
+ /\btwine\s+upload\b/,
163
+ ];
164
+
165
+ /* The loopback hosts, as a WHOLE HOST rather than a prefix. `localhost\b` reads as an exemption for
166
+ * `localhost.attacker.com`, because a `.` is a word boundary, and for `localhost@attacker.com`, where the
167
+ * loopback name is a URL's userinfo and curl connects to whatever follows the `@`. Either one is a host an
168
+ * attacker registers, so a prefix test hands it the exemption meant for this container talking to itself, and
169
+ * with it the outside-content envelope and the turn's taint bit: outsideSourceOf (guard/outside-results.ts) is
170
+ * built on this class, so a response judged loopback is never wrapped and never marks the turn. The trailing
171
+ * lookahead is what makes it a whole host, the port is optional, and a URL's authority can only end at one of
172
+ * `/?#`, whitespace, or a closing quote. */
173
+ const LOOPBACK = String.raw`(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?=[/?#\s'"\x60]|$)`;
174
+
175
+ // The sandbox talks to itself over loopback constantly, the host bridge, a dev server the agent just started,
176
+ // and none of that leaves the container, so the class is about reaching OUT rather than about curl.
177
+ const NETWORK_OUTBOUND = [
178
+ new RegExp(String.raw`\b(?:curl|wget)\b[^|;&]*\bhttps?://(?!${LOOPBACK})`),
179
+ /* The JS execution backend's curl: a literal non-loopback URL handed to `fetch(`. The classifier reads
180
+ * scripts with the same substring honesty it reads shell (the gate feeds it both, see command-gate's
181
+ * EXECUTION_SOURCES), so an owner's rule about reaching out covers both ways of doing it, and the
182
+ * outside-content seam wraps what a fetching script brings back exactly as it wraps a fetching curl's. A
183
+ * URL assembled at runtime walks past this, as the header already admits for shell variables. */
184
+ new RegExp(String.raw`\bfetch\(\s*['"\x60]https?://(?!${LOOPBACK})`),
185
+ ];
186
+
187
+ /* --- rm, parsed once ------------------------------------------------------------------------------------
188
+ *
189
+ * ONE PARSE, TWO CLASSES. `rm -rf build` and `rm -rf /` are the same verb with the same flags and wildly
190
+ * different consequences, and the whole reason the second is a class of its own is that its default differs:
191
+ * deleting a build directory is ordinary work in a disposable container, and deleting the root it sits in is
192
+ * the thing nothing here undoes. Splitting them needs the OPERANDS, not just the flags, so the invocation is
193
+ * taken apart once and both classes read the same result rather than two regexes drifting apart.
194
+ *
195
+ * An invocation ends at a pipeline separator: everything after `|`, `;`, `&`, or a newline belongs to the next
196
+ * command and must not be read as this one's targets. */
197
+ const RM_INVOCATION = /\brm\s+([^|;&\n]*)/g;
198
+
199
+ interface RmInvocation {
200
+ readonly recursive: boolean;
201
+ readonly force: boolean;
202
+ readonly operands: readonly string[];
203
+ // Where this invocation sits in the command, so a card can point at `rm -rf /work` rather than at the whole
204
+ // line it was buried in. The invocation as matched, verb through last operand.
205
+ readonly span: CommandSpan;
206
+ }
207
+
208
+ // A shell word with its quoting removed, so `"/work"`, `'/work'` and `/work` are one operand and not three.
209
+ const unquote = (word: string): string => word.replace(/^['"`]|['"`]$/g, "");
210
+
211
+ const parseRm = (command: string): RmInvocation[] => {
212
+ const parsed: RmInvocation[] = [];
213
+ for (const invocation of command.matchAll(RM_INVOCATION)) {
214
+ let recursive = false;
215
+ let force = false;
216
+ const operands: string[] = [];
217
+ for (const word of (invocation[1] as string).trim().split(/\s+/)) {
218
+ if (word === "") {
219
+ continue;
220
+ }
221
+ // A long flag is one whole word; a short cluster is a bag of letters. `--force` must not be read as
222
+ // the letters f-o-r-c-e, or every `rm --force` would look recursive too.
223
+ if (word.startsWith("--")) {
224
+ recursive ||= word === "--recursive";
225
+ force ||= word === "--force";
226
+ continue;
227
+ }
228
+ if (word.startsWith("-")) {
229
+ recursive ||= /[rR]/.test(word);
230
+ force ||= word.includes("f");
231
+ continue;
232
+ }
233
+ operands.push(unquote(word));
234
+ }
235
+ parsed.push({ recursive, force, operands, span: { start: invocation.index, end: invocation.index + invocation[0].trimEnd().length } });
236
+ }
237
+ return parsed;
238
+ };
239
+
240
+ /* A TARGET THAT IS A ROOT RATHER THAN SOMETHING INSIDE ONE. This is the whole difference between the two
241
+ * deletion classes, so it is deliberately a short, closed list of whole names rather than a clever heuristic:
242
+ * the filesystem root and the top-level directories an OS keeps, the two trees this product keeps state in, a
243
+ * home directory however it is spelled, and a Windows drive.
244
+ *
245
+ * `/tmp` is deliberately absent. It is scratch by definition and emptying it is a chore, not an incident. */
246
+ const ROOT_DIRECTORIES = new Set([
247
+ // The empty string is what the filesystem root normalizes to, see trimTarget.
248
+ "",
249
+ "/work",
250
+ "/history",
251
+ "/home",
252
+ "/root",
253
+ "/etc",
254
+ "/usr",
255
+ "/var",
256
+ "/opt",
257
+ "/boot",
258
+ "/bin",
259
+ "/sbin",
260
+ "/lib",
261
+ "/lib64",
262
+ "/srv",
263
+ "/dev",
264
+ "/sys",
265
+ "/proc",
266
+ "/mnt",
267
+ "/media",
268
+ "/Users",
269
+ "/Applications",
270
+ "/System",
271
+ "/Library",
272
+ ]);
273
+
274
+ const HOME_ALIAS = /^(?:~|\$HOME|\$\{HOME\}|%USERPROFILE%)$/;
275
+ const WINDOWS_DRIVE = /^[A-Za-z]:$/;
276
+
277
+ /* `/work`, `/work/` and `/work/*` are one target said three ways: a trailing separator or wildcard says
278
+ * "everything in it", which is what deleting the directory means anyway. A BARE `*` is left alone on purpose,
279
+ * it is relative to whatever the shell is standing in, and `rm -rf *` in a build directory is the ordinary
280
+ * case this class exists to stay out of the way of. */
281
+ const trimTarget = (operand: string): string => operand.replace(/[/\\]\*+$/, "").replace(/[/\\]+$/, "");
282
+
283
+ const isRootTarget = (operand: string): boolean => {
284
+ const target = trimTarget(operand);
285
+ if (HOME_ALIAS.test(target) || WINDOWS_DRIVE.test(target)) {
286
+ return true;
287
+ }
288
+ // Only an absolute path can name a root, and `""` is the root itself. A relative path is inside whatever
289
+ // the shell is standing in, which this cannot know and must not guess about.
290
+ return target === "" ? operand.startsWith("/") || operand.startsWith("\\") : ROOT_DIRECTORIES.has(target);
291
+ };
292
+
293
+ /* --- the JS execution backend's own deletes -------------------------------------------------------------
294
+ *
295
+ * THE SAME CONSEQUENCE, SPELLED IN NODE. The gate feeds this classifier the `mcp__code__run` script as well as
296
+ * the shell line (command-gate's EXECUTION_SOURCES), so `execSync("rm -rf /work")` inside a script already
297
+ * lands in the shell patterns above by substring. `fs.rmSync("/work", { recursive: true, force: true })` did
298
+ * not, and it is the shorter way to write the same afternoon's worth of lost work: the rule an owner wrote
299
+ * about deleting recursively has to mean the same thing on both backends or it does not mean much.
300
+ *
301
+ * RECURSIVE ALONE IS ENOUGH HERE, where the shell form needs recursive AND force. That is not an inconsistency:
302
+ * `rm -r` without `-f` stops on the first prompt and a script has no terminal to answer one, so the shell's
303
+ * recoverable spelling really is recoverable. `fs.rm(p, { recursive: true })` prompts nobody and deletes the
304
+ * tree, so the recoverable spelling does not exist on this side.
305
+ *
306
+ * TWO PATTERNS PER SPELLING, and the split matters: whether the script deletes recursively AT ALL is a
307
+ * different question from WHICH PATH it deletes, and only the first can be answered when the path is a
308
+ * variable. `rm(target, { recursive: true })` is files.destructive with no literal to read, and demanding one
309
+ * (as the first draft did) let exactly the ordinary way of writing it through.
310
+ *
311
+ * The header's honesty note applies here too, and one limit is worth naming: `[^)]*` cannot cross a closing
312
+ * paren, so `fs.rmSync(join(a, b), { recursive: true })` walks past. Same class of gap as a shell path built
313
+ * from a variable, and the same answer: this is friction for well-behaved work, not a boundary. */
314
+ const NODE_RECURSIVE_RM = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\([^)]*?recursive\s*:\s*true/;
315
+ const NODE_RECURSIVE_RM_PATH = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\(\s*(['"`])([^'"`]*)\1[^)]*?recursive\s*:\s*true/g;
316
+ // rimraf's whole purpose is the recursive force delete, so the call itself is the match; no options to read.
317
+ const RIMRAF = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(/;
318
+ const RIMRAF_PATH = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(\s*(['"`])([^'"`]*)\1/g;
319
+
320
+ // Where a script deletes a tree, however the path reaches it. Empty ⇒ it does not.
321
+ const recursiveDeletes = (program: string): CommandSpan[] => spansOf(globally([NODE_RECURSIVE_RM, RIMRAF]), program);
322
+
323
+ /* The literal paths a script hands to a recursive delete, each with the call it sits in. Empty when every path
324
+ * it deletes is computed, which is the honest answer rather than a guess: the class above already holds, only
325
+ * the root question goes unasked.
326
+ *
327
+ * The two `_PATH` patterns are already global, so they are used directly; matchAll clones them either way. */
328
+ const nodeDeleteTargets = (program: string): { readonly target: string; readonly span: CommandSpan }[] =>
329
+ [...program.matchAll(NODE_RECURSIVE_RM_PATH), ...program.matchAll(RIMRAF_PATH)].map((match) => ({
330
+ target: match[2] as string,
331
+ span: { start: match.index, end: match.index + match[0].length },
332
+ }));
333
+
334
+ /* --- state nothing brings back -------------------------------------------------------------------------
335
+ *
336
+ * THE CLASS WITH A FLOOR UNDER IT (guard/actions.ts commandRun holds it even where the owner wrote no rule),
337
+ * so its membership is chosen against a hard question: does anything in this product bring the state back?
338
+ *
339
+ * A worktree is restored from git, a checkpoint restores the tree, a container is recreated from its image,
340
+ * an npm package is re-installed. None of that reaches a formatted disk, a deleted Docker volume, or a home
341
+ * directory that is no longer there. Those are the members. Deliberately NOT members: `docker rm` (recreate
342
+ * it), `docker image prune` (pull it again), `git reset --hard` (that is git.destructive, and the reflog has
343
+ * it), `rm -rf node_modules` (install it again). The point of a floor is that it is rare enough to be worth
344
+ * stopping for; a floor that fires on ordinary work is one people learn to click through. */
345
+ const SYSTEM_DESTRUCTIVE = [
346
+ // Format, wipe or overwrite a block device. `dd` only counts when it is pointed AT a device: reading one
347
+ // into a file is how an image is taken, and holding a backup would be exactly the wrong lesson.
348
+ /\bmkfs(?:\.\w+)?\b/,
349
+ /\bwipefs\b/,
350
+ /\bblkdiscard\b/,
351
+ /\bsgdisk\b[^|;&]*\s(?:--zap-all|-Z)\b/,
352
+ /\bdd\b[^|;&]*\bof=(?:\/dev\/|['"`]\/dev\/)/,
353
+ /\bshred\b[^|;&]*\s\/dev\//,
354
+ // A redirect straight onto a disk device, which is the same wipe without the ceremony.
355
+ />\s*\/dev\/(?:[shv]d[a-z]|nvme\d|disk\d|mmcblk\d)/,
356
+ /* Docker state that is data rather than image. A named volume IS the database; `system prune` takes every
357
+ * unused one with it, and `compose down -v` is the spelling people reach for without reading the flag.
358
+ * In this sandbox these hit the nested engine (the host's socket is never mounted, see
359
+ * capabilities/handlers/docker.ts), so the blast radius is the dev databases the agent has been working
360
+ * against. Sent to somebody's own computer through the host agent, it is whatever they run on it. */
361
+ /\b(?:docker|podman)\s+volume\s+(?:rm|remove|prune)\b/,
362
+ /\b(?:docker|podman)\s+system\s+prune\b/,
363
+ /\b(?:docker(?:\s+compose|-compose)?|podman-compose)\s+down\b[^|;&]*\s(?:-v\b|--volumes\b)/,
364
+ ];
365
+
366
+ const recursiveForceRms = (command: string): CommandSpan[] =>
367
+ parseRm(command)
368
+ .filter((invocation) => invocation.recursive && invocation.force)
369
+ .map((invocation) => invocation.span);
370
+
371
+ // A recursive delete aimed at a root, in either spelling the gate can be handed: the shell's `rm -rf /` and
372
+ // the script's `fs.rmSync("/", { recursive: true })`.
373
+ const rootDeletes = (program: string): CommandSpan[] => [
374
+ ...parseRm(program)
375
+ .filter((invocation) => invocation.recursive && invocation.force && invocation.operands.some(isRootTarget))
376
+ .map((invocation) => invocation.span),
377
+ ...nodeDeleteTargets(program)
378
+ .filter((delete_) => isRootTarget(delete_.target))
379
+ .map((delete_) => delete_.span),
380
+ ];
381
+
382
+ // The `g` twins, built once at load rather than per call: a card is minted per held command and a classify runs
383
+ // per command the agent types, so recompiling six tables of patterns each time is work with no reader.
384
+ const GIT_DESTRUCTIVE_G = globally(GIT_DESTRUCTIVE);
385
+ const SECRET_REFERENCES_G = globally(SECRET_REFERENCES);
386
+ const CREDENTIAL_PATHS_G = globally(CREDENTIAL_PATHS);
387
+ const PACKAGE_PUBLISH_G = globally(PACKAGE_PUBLISH);
388
+ const NETWORK_OUTBOUND_G = globally(NETWORK_OUTBOUND);
389
+ const SYSTEM_DESTRUCTIVE_G = globally(SYSTEM_DESTRUCTIVE);
390
+
391
+ /* THE PATH A MATCHED FRAGMENT SITS IN, so the oracle is asked about the file the command would actually open
392
+ * rather than about the suffix that fired: `sed 's/…/' ~/.npmrc` fires on `.npmrc` and must ask about
393
+ * `~/.npmrc`, `curl -d @.env` fires on `.env` and must ask about `.env`.
394
+ *
395
+ * The shell word around the span, widened to whitespace or a separator on both sides, with the decoration a
396
+ * shell puts in FRONT of a path removed: a redirect's arrow, curl's `@` file-body marker, a `--flag=` prefix.
397
+ *
398
+ * DELIBERATELY DUMB, and it can afford to be: a word this gets wrong resolves to a path the caller cannot read,
399
+ * which is `undefined`, which leaves the class exactly where the pattern put it. The failure mode is the old
400
+ * behaviour, not a hole. */
401
+ const WORD_EDGE = /[\s'"`;|&()]/;
402
+ const enclosingPath = (command: string, span: CommandSpan): string => {
403
+ let start = span.start;
404
+ while (start > 0 && !WORD_EDGE.test(command[start - 1] as string)) {
405
+ start -= 1;
406
+ }
407
+ let end = span.end;
408
+ while (end < command.length && !WORD_EDGE.test(command[end] as string)) {
409
+ end += 1;
410
+ }
411
+ return command
412
+ .slice(start, end)
413
+ .replace(/^-{1,2}[\w-]+=/, "")
414
+ .replace(/^[@<>=]+/, "");
415
+ };
416
+
417
+ /* WHERE A COMMAND READS CREDENTIAL MATERIAL: every secret reference in it, plus every credential-shaped path the
418
+ * context did not positively clear.
419
+ *
420
+ * `!== false` is the whole fact-check, and the comparison is written against `false` rather than for `true` on
421
+ * purpose: `undefined` (nobody could look) has to behave like `true` (there is a credential in there), or the
422
+ * class would evaporate on every caller without a filesystem. */
423
+ const credentialReads = (command: string, context: CommandContext | undefined): CommandSpan[] => [
424
+ ...spansOf(SECRET_REFERENCES_G, command),
425
+ ...spansOf(CREDENTIAL_PATHS_G, command).filter((span) => context?.holdsSecret?.(enclosingPath(command, span)) !== false),
426
+ ];
427
+
428
+ // WHERE each class fires, one entry per class. Empty ⇒ the command is not in it, so membership and evidence are
429
+ // the same walk and cannot disagree: there is no way to be held for a class with nothing to show for it.
430
+ const MATCHES: Readonly<Record<CommandClass, (command: string, context: CommandContext | undefined) => CommandSpan[]>> = {
431
+ "git.destructive": (command) => spansOf(GIT_DESTRUCTIVE_G, command),
432
+ "files.destructive": (command) => [...recursiveForceRms(command), ...recursiveDeletes(command)],
433
+ "system.destructive": (command) => [...spansOf(SYSTEM_DESTRUCTIVE_G, command), ...rootDeletes(command)],
434
+ "secrets.access": credentialReads,
435
+ "package.publish": (command) => spansOf(PACKAGE_PUBLISH_G, command),
436
+ "network.outbound": (command) => spansOf(NETWORK_OUTBOUND_G, command),
437
+ };
438
+
439
+ /* Every class the command falls in AND the fragments that put it there, in the catalog's own order so a card and
440
+ * a log name them the same way twice. The primitive; classifyCommand is this with the offsets dropped.
441
+ *
442
+ * `context` is what a caller that can check a fact hands in (CommandContext); omitting it classifies from the
443
+ * command text alone, which is every caller that has no filesystem to consult. */
444
+ export const matchCommand = (command: string, context?: CommandContext): CommandMatch[] =>
445
+ CommandClassSchema.options.flatMap((commandClass) => {
446
+ const spans = normalize(MATCHES[commandClass](command, context));
447
+ return spans.length === 0 ? [] : [{ commandClass, spans }];
448
+ });
449
+
450
+ // Every class the command falls in, for the callers that only take a verdict from it (the gate's rulebook
451
+ // consult, the machine agent's scope switch).
452
+ export const classifyCommand = (command: string, context?: CommandContext): CommandClass[] =>
453
+ matchCommand(command, context).map((match) => match.commandClass);
454
+
455
+ // What the card says the command would DO. The class name is a settings key, not a sentence to show a person.
456
+ export const COMMAND_CLASS_LABELS: Readonly<Record<CommandClass, string>> = {
457
+ "git.destructive": "rewrite or discard git history",
458
+ "files.destructive": "delete files recursively",
459
+ "system.destructive": "wipe a disk, a container volume, or a whole home or root directory",
460
+ "secrets.access": "read credential material",
461
+ "package.publish": "publish or release a package",
462
+ "network.outbound": "send a request out to the internet",
463
+ };
464
+
465
+ /* THE CLASSES THE DAEMON HOLDS WHERE THE OWNER WROTE NO RULE, and the machine agent refuses without its own
466
+ * switch. Named here rather than at either consult, so "which commands are dangerous enough to stop by
467
+ * default" has one answer that both enforcement points read. */
468
+ export const FLOOR_CLASSES: ReadonlySet<CommandClass> = new Set<CommandClass>(["system.destructive"]);
@@ -1,5 +1,5 @@
1
1
  import { oc } from "@orpc/contract";
2
- import { ActivityListSchema, ActivityQuerySchema, ActivityStatusSchema } from "../schemas.js";
2
+ import { ActivityListSchema, ActivityQuerySchema, ActivityStatusSchema } from "../schemas/activity.js";
3
3
 
4
4
  // The activity audit feed (provider-agnostic; Discord is the first source). Read-only by design,
5
5
  // events are appended daemon-side only, so the log stays a trustworthy record of what the agent did.
@@ -1,18 +1,9 @@
1
1
  import { eventIterator, oc } from "@orpc/contract";
2
2
  import { AgentCommandsQuerySchema, AgentCommandsSchema, AttachFrameSchema } from "../events.js";
3
- import {
4
- AgentReplySchema,
5
- AgentTurnSchema,
6
- AttachTurnSchema,
7
- OkSchema,
8
- ProviderRefusalsSchema,
9
- ResumeTurnSchema,
10
- RewindResultSchema,
11
- RewindTurnSchema,
12
- StartedTurnSchema,
13
- SteerSchema,
14
- StopTurnSchema,
15
- } from "../schemas.js";
3
+ import { AgentTurnSchema, AttachTurnSchema, StartedTurnSchema } from "../schemas/agent.js";
4
+ import { RewindResultSchema, RewindTurnSchema } from "../schemas/history.js";
5
+ import { AgentReplySchema, ProviderRefusalsSchema, ResumeTurnSchema, SteerSchema, StopTurnSchema } from "../schemas/plan-limits.js";
6
+ import { OkSchema } from "../schemas/shared.js";
16
7
 
17
8
  // A turn EXECUTES as a detached daemon-side run: `run` starts it and acks with the run id; any number of
18
9
  // clients render it via `attach` (replay from a seq cursor, then live), the initiating window holds no
@@ -3,7 +3,6 @@ import { AgentTranscriptSchema } from "../events.js";
3
3
  import {
4
4
  AgentArchiveSchema,
5
5
  AgentAutoLandSchema,
6
- AgentChangesSchema,
7
6
  AgentFileDiffQuerySchema,
8
7
  AgentIdSchema,
9
8
  AgentIdsSchema,
@@ -11,17 +10,18 @@ import {
11
10
  AgentPlaceSchema,
12
11
  AgentRenameSchema,
13
12
  AgentResumeAfterOutageSchema,
13
+ AgentsArchivedSchema,
14
14
  AgentSearchQuerySchema,
15
15
  AgentSearchResultSchema,
16
- AgentsArchivedSchema,
17
- AgentsListSchema,
18
16
  AgentsMovedSchema,
19
17
  AgentsRemovedSchema,
20
18
  AgentSummarySchema,
21
- FileDiffSchema,
22
19
  LandResultSchema,
23
- OkSchema,
24
- } from "../schemas.js";
20
+ } from "../schemas/agents.js";
21
+ import { AgentsListSchema } from "../schemas/automations.js";
22
+ import { AgentChangesSchema } from "../schemas/git.js";
23
+ import { FileDiffSchema } from "../schemas/history.js";
24
+ import { OkSchema } from "../schemas/shared.js";
25
25
 
26
26
  // The fleet: every registered conversation-agent (see AgentSummarySchema). Registry-level actions (read,
27
27
  // rename, seen, archive) apply uniformly. For branch-backed conversations, `diff` is the worktree's CUMULATIVE
@@ -7,8 +7,8 @@ import {
7
7
  AutomationIdParamSchema,
8
8
  AutomationSchema,
9
9
  AutomationsListSchema,
10
- OkSchema,
11
- } from "../schemas.js";
10
+ } from "../schemas/automations.js";
11
+ import { OkSchema } from "../schemas/shared.js";
12
12
 
13
13
  // The sandbox's automations manifest (scheduled agent wake-ups). `list` returns each automation with its recent
14
14
  // runs + next fire time. `upsert` adds or edits by id (nothing to provision, the scheduler picks it up on its
@@ -12,10 +12,9 @@ import {
12
12
  CapabilitySchema,
13
13
  CapabilitySecretInputSchema,
14
14
  CapabilityStatusSchema,
15
- MarketplaceRequestSchema,
16
- MarketplaceSchema,
17
- OkSchema,
18
- } from "../schemas.js";
15
+ } from "../schemas/capabilities.js";
16
+ import { MarketplaceRequestSchema, MarketplaceSchema } from "../schemas/marketplace.js";
17
+ import { OkSchema } from "../schemas/shared.js";
19
18
 
20
19
  /* The sandbox's unified capability manifest. `list` returns each active capability with its live status, the
21
20
  * non-secret echo of its config, and the NAMES of the credentials it holds. `add` upserts a capability and
@@ -1,5 +1,6 @@
1
1
  import { oc } from "@orpc/contract";
2
- import { ChoreLedgerWriteSchema, ChoreProbeRequestSchema, ChoresReportSchema, OkSchema } from "../schemas.js";
2
+ import { ChoreLedgerWriteSchema, ChoreProbeRequestSchema, ChoresReportSchema } from "../schemas/maintenance.js";
3
+ import { OkSchema } from "../schemas/shared.js";
3
4
 
4
5
  /* Maintenance evidence: what every repo under /work currently measures, and what has already been done about it.
5
6
  * Three routes, because there are exactly three things the surface does, read the evidence, ask for a
@@ -6,8 +6,8 @@ import {
6
6
  CiRunParamSchema,
7
7
  CiRunsResponseSchema,
8
8
  CiSeenResponseSchema,
9
- OkSchema,
10
- } from "../schemas.js";
9
+ } from "../schemas/ci.js";
10
+ import { OkSchema } from "../schemas/shared.js";
11
11
 
12
12
  // Pipelines on the workspace repos' github/gitlab remotes. `runs` serves the Pipelines rail view (cache +
13
13
  // on-demand backfill; per-repo webhook warnings ride along); `rerun`/`cancel` proxy to the vendor; `fix`
@@ -7,8 +7,8 @@ import {
7
7
  OauthAccountListSchema,
8
8
  OauthAccountSchema,
9
9
  OauthExchangeSchema,
10
- OkSchema,
11
- } from "../schemas.js";
10
+ } from "../schemas/provider-oauth.js";
11
+ import { OkSchema } from "../schemas/shared.js";
12
12
 
13
13
  // Claude subscription OAuth, the sandbox owns the credential. `start` hands the browser the authorize URL +
14
14
  // PKCE material; `exchange` stores the resulting tokens as a new account and returns it; `accounts` lists the
@@ -7,8 +7,8 @@ import {
7
7
  CursorLoginStartSchema,
8
8
  OauthAccountListSchema,
9
9
  OauthAccountSchema,
10
- OkSchema,
11
- } from "../schemas.js";
10
+ } from "../schemas/provider-oauth.js";
11
+ import { OkSchema } from "../schemas/shared.js";
12
12
 
13
13
  /* Cursor subscription sign-in, the sandbox owns the credential and the platform never sees it, the same bargain
14
14
  * claude.contract.ts strikes. What differs is who finishes the handshake.
@@ -1,5 +1,6 @@
1
1
  import { oc } from "@orpc/contract";
2
- import { DraftIdParamSchema, DraftsListSchema, DraftSummarySchema, OkSchema } from "../schemas.js";
2
+ import { DraftIdParamSchema, DraftsListSchema, DraftSummarySchema } from "../schemas/drafts.js";
3
+ import { OkSchema } from "../schemas/shared.js";
3
4
 
4
5
  // The sandbox's post-drafts queue (agent-proposed posts awaiting approval). The agent creates draft files
5
6
  // directly, these routes are the OWNER's side: `list` is the approval inbox, `upsert` covers approve / edit /
@@ -1,6 +1,7 @@
1
1
  import { oc } from "@orpc/contract";
2
2
  import { z } from "zod";
3
- import { CapabilityIdParamSchema, ModelsSchema } from "../schemas.js";
3
+ import { CapabilityIdParamSchema } from "../schemas/capabilities.js";
4
+ import { ModelsSchema } from "../schemas/provider-oauth.js";
4
5
 
5
6
  // An `endpoint` capability's picker catalog, the models the configured server itself publishes, read from its
6
7
  // own /v1/models. Every other provider's catalog is one fixed route because there is one of each; endpoints are
@@ -1,6 +1,7 @@
1
1
  import { eventIterator, oc } from "@orpc/contract";
2
2
  import { IntenticLineSchema } from "../events.js";
3
- import { ExitCountriesSchema, ExitIdParamSchema, ExitListSchema, ExitObservationSchema, ExitUseInputSchema, OkSchema } from "../schemas.js";
3
+ import { ExitCountriesSchema, ExitIdParamSchema, ExitListSchema, ExitObservationSchema, ExitUseInputSchema } from "../schemas/exit.js";
4
+ import { OkSchema } from "../schemas/shared.js";
4
5
 
5
6
  // The live GEO EXIT surface. An exit is ADDED as an `exit` capability (which provider, a resting country,
6
7
  // whether it comes up on boot); it is STARTED, MOVED and ROTATED here. Same split as the vpn contract and for