@intentic/sandbox-contract 1.307.0 → 1.308.2

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 (260) hide show
  1. package/README.md +12 -0
  2. package/dist/contracts/accounts.contract.d.ts +6 -6
  3. package/dist/contracts/accounts.contract.js +7 -7
  4. package/dist/contracts/accounts.contract.js.map +1 -1
  5. package/dist/contracts/activity.contract.d.ts +2 -2
  6. package/dist/contracts/activity.contract.js +3 -3
  7. package/dist/contracts/activity.contract.js.map +1 -1
  8. package/dist/contracts/agent.contract.d.ts +10 -10
  9. package/dist/contracts/agent.contract.d.ts.map +1 -1
  10. package/dist/contracts/agent.contract.js +21 -11
  11. package/dist/contracts/agent.contract.js.map +1 -1
  12. package/dist/contracts/agents.contract.d.ts +41 -27
  13. package/dist/contracts/agents.contract.d.ts.map +1 -1
  14. package/dist/contracts/agents.contract.js +44 -28
  15. package/dist/contracts/agents.contract.js.map +1 -1
  16. package/dist/contracts/approvals.contract.d.ts +3 -3
  17. package/dist/contracts/approvals.contract.js +4 -4
  18. package/dist/contracts/approvals.contract.js.map +1 -1
  19. package/dist/contracts/areas.contract.d.ts +3 -3
  20. package/dist/contracts/areas.contract.d.ts.map +1 -1
  21. package/dist/contracts/areas.contract.js +5 -4
  22. package/dist/contracts/areas.contract.js.map +1 -1
  23. package/dist/contracts/automations.contract.d.ts +11 -11
  24. package/dist/contracts/automations.contract.js +12 -12
  25. package/dist/contracts/automations.contract.js.map +1 -1
  26. package/dist/contracts/capabilities.contract.d.ts +13 -13
  27. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  28. package/dist/contracts/capabilities.contract.js +18 -14
  29. package/dist/contracts/capabilities.contract.js.map +1 -1
  30. package/dist/contracts/chores.contract.d.ts +3 -3
  31. package/dist/contracts/chores.contract.js +4 -4
  32. package/dist/contracts/chores.contract.js.map +1 -1
  33. package/dist/contracts/ci.contract.d.ts +5 -5
  34. package/dist/contracts/ci.contract.js +6 -6
  35. package/dist/contracts/ci.contract.js.map +1 -1
  36. package/dist/contracts/diff.contract.d.ts +1 -1
  37. package/dist/contracts/diff.contract.js +2 -2
  38. package/dist/contracts/diff.contract.js.map +1 -1
  39. package/dist/contracts/endpoints.contract.d.ts +4 -4
  40. package/dist/contracts/endpoints.contract.js +5 -5
  41. package/dist/contracts/endpoints.contract.js.map +1 -1
  42. package/dist/contracts/exit.contract.d.ts +7 -7
  43. package/dist/contracts/exit.contract.d.ts.map +1 -1
  44. package/dist/contracts/exit.contract.js +9 -8
  45. package/dist/contracts/exit.contract.js.map +1 -1
  46. package/dist/contracts/extensions.contract.d.ts +17 -17
  47. package/dist/contracts/extensions.contract.js +18 -18
  48. package/dist/contracts/extensions.contract.js.map +1 -1
  49. package/dist/contracts/git.contract.d.ts +47 -45
  50. package/dist/contracts/git.contract.d.ts.map +1 -1
  51. package/dist/contracts/git.contract.js +46 -46
  52. package/dist/contracts/git.contract.js.map +1 -1
  53. package/dist/contracts/history.contract.d.ts +4 -4
  54. package/dist/contracts/history.contract.js +5 -5
  55. package/dist/contracts/history.contract.js.map +1 -1
  56. package/dist/contracts/intentic.contract.d.ts +3 -3
  57. package/dist/contracts/intentic.contract.d.ts.map +1 -1
  58. package/dist/contracts/intentic.contract.js +5 -4
  59. package/dist/contracts/intentic.contract.js.map +1 -1
  60. package/dist/contracts/inventory.contract.d.ts +3 -3
  61. package/dist/contracts/inventory.contract.js +4 -4
  62. package/dist/contracts/inventory.contract.js.map +1 -1
  63. package/dist/contracts/issues.contract.d.ts +5 -5
  64. package/dist/contracts/issues.contract.js +6 -6
  65. package/dist/contracts/issues.contract.js.map +1 -1
  66. package/dist/contracts/logs.contract.d.ts +3 -3
  67. package/dist/contracts/logs.contract.d.ts.map +1 -1
  68. package/dist/contracts/logs.contract.js +6 -4
  69. package/dist/contracts/logs.contract.js.map +1 -1
  70. package/dist/contracts/loops.contract.d.ts +6 -6
  71. package/dist/contracts/loops.contract.js +7 -7
  72. package/dist/contracts/loops.contract.js.map +1 -1
  73. package/dist/contracts/netdisk.contract.d.ts +3 -3
  74. package/dist/contracts/netdisk.contract.d.ts.map +1 -1
  75. package/dist/contracts/netdisk.contract.js +5 -4
  76. package/dist/contracts/netdisk.contract.js.map +1 -1
  77. package/dist/contracts/panels.contract.d.ts +3 -3
  78. package/dist/contracts/panels.contract.js +4 -4
  79. package/dist/contracts/panels.contract.js.map +1 -1
  80. package/dist/contracts/personas.contract.d.ts +8 -8
  81. package/dist/contracts/personas.contract.d.ts.map +1 -1
  82. package/dist/contracts/personas.contract.js +10 -9
  83. package/dist/contracts/personas.contract.js.map +1 -1
  84. package/dist/contracts/ports.contract.d.ts +3 -3
  85. package/dist/contracts/ports.contract.d.ts.map +1 -1
  86. package/dist/contracts/ports.contract.js +5 -4
  87. package/dist/contracts/ports.contract.js.map +1 -1
  88. package/dist/contracts/prepush.contract.d.ts +3 -3
  89. package/dist/contracts/prepush.contract.js +4 -4
  90. package/dist/contracts/prepush.contract.js.map +1 -1
  91. package/dist/contracts/providers.contract.d.ts +2 -2
  92. package/dist/contracts/providers.contract.d.ts.map +1 -1
  93. package/dist/contracts/providers.contract.js +5 -3
  94. package/dist/contracts/providers.contract.js.map +1 -1
  95. package/dist/contracts/public.contract.d.ts +3 -3
  96. package/dist/contracts/public.contract.js +4 -4
  97. package/dist/contracts/public.contract.js.map +1 -1
  98. package/dist/contracts/push.contract.d.ts +4 -4
  99. package/dist/contracts/push.contract.d.ts.map +1 -1
  100. package/dist/contracts/push.contract.js +9 -5
  101. package/dist/contracts/push.contract.js.map +1 -1
  102. package/dist/contracts/safety.contract.d.ts +3 -3
  103. package/dist/contracts/safety.contract.js +4 -4
  104. package/dist/contracts/safety.contract.js.map +1 -1
  105. package/dist/contracts/secrets.contract.d.ts +9 -9
  106. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  107. package/dist/contracts/secrets.contract.js +13 -10
  108. package/dist/contracts/secrets.contract.js.map +1 -1
  109. package/dist/contracts/sessions.contract.d.ts +2 -2
  110. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  111. package/dist/contracts/sessions.contract.js +5 -3
  112. package/dist/contracts/sessions.contract.js.map +1 -1
  113. package/dist/contracts/settings.contract.d.ts +11 -9
  114. package/dist/contracts/settings.contract.d.ts.map +1 -1
  115. package/dist/contracts/settings.contract.js +11 -10
  116. package/dist/contracts/settings.contract.js.map +1 -1
  117. package/dist/contracts/share.contract.d.ts +4 -4
  118. package/dist/contracts/share.contract.js +5 -5
  119. package/dist/contracts/share.contract.js.map +1 -1
  120. package/dist/contracts/skills.contract.d.ts +5 -5
  121. package/dist/contracts/skills.contract.js +6 -6
  122. package/dist/contracts/skills.contract.js.map +1 -1
  123. package/dist/contracts/system.contract.d.ts +22 -19
  124. package/dist/contracts/system.contract.d.ts.map +1 -1
  125. package/dist/contracts/system.contract.js +27 -20
  126. package/dist/contracts/system.contract.js.map +1 -1
  127. package/dist/contracts/translator.contract.d.ts +5 -5
  128. package/dist/contracts/translator.contract.js +6 -6
  129. package/dist/contracts/translator.contract.js.map +1 -1
  130. package/dist/contracts/usage.contract.d.ts +4 -4
  131. package/dist/contracts/usage.contract.js +5 -5
  132. package/dist/contracts/usage.contract.js.map +1 -1
  133. package/dist/contracts/vpn.contract.d.ts +4 -4
  134. package/dist/contracts/vpn.contract.d.ts.map +1 -1
  135. package/dist/contracts/vpn.contract.js +6 -5
  136. package/dist/contracts/vpn.contract.js.map +1 -1
  137. package/dist/contracts/workflows.contract.d.ts +9 -9
  138. package/dist/contracts/workflows.contract.js +10 -10
  139. package/dist/contracts/workflows.contract.js.map +1 -1
  140. package/dist/contracts/workspace.contract.d.ts +30 -30
  141. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  142. package/dist/contracts/workspace.contract.js +46 -31
  143. package/dist/contracts/workspace.contract.js.map +1 -1
  144. package/dist/events/land-breakage.d.ts +4 -0
  145. package/dist/events/land-breakage.d.ts.map +1 -0
  146. package/dist/events/land-breakage.js +4 -0
  147. package/dist/events/land-breakage.js.map +1 -0
  148. package/dist/events/system-events.d.ts +2 -0
  149. package/dist/events/system-events.d.ts.map +1 -1
  150. package/dist/index.d.ts +9379 -9350
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +13 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/protocol/procedure-types.d.ts +10 -0
  155. package/dist/protocol/procedure-types.d.ts.map +1 -0
  156. package/dist/protocol/procedure-types.js +2 -0
  157. package/dist/protocol/procedure-types.js.map +1 -0
  158. package/dist/protocol/raw-routes.d.ts +417 -0
  159. package/dist/protocol/raw-routes.d.ts.map +1 -0
  160. package/dist/protocol/raw-routes.js +140 -0
  161. package/dist/protocol/raw-routes.js.map +1 -0
  162. package/dist/protocol/route-meta.d.ts +18 -0
  163. package/dist/protocol/route-meta.d.ts.map +1 -0
  164. package/dist/protocol/route-meta.js +3 -0
  165. package/dist/protocol/route-meta.js.map +1 -0
  166. package/dist/protocol/routes.d.ts +3 -0
  167. package/dist/protocol/routes.d.ts.map +1 -1
  168. package/dist/protocol/routes.js +47 -14
  169. package/dist/protocol/routes.js.map +1 -1
  170. package/dist/schemas/agent.d.ts +33 -0
  171. package/dist/schemas/agent.d.ts.map +1 -1
  172. package/dist/schemas/agent.js +22 -3
  173. package/dist/schemas/agent.js.map +1 -1
  174. package/dist/schemas/agents.d.ts +4 -0
  175. package/dist/schemas/agents.d.ts.map +1 -1
  176. package/dist/schemas/agents.js +4 -0
  177. package/dist/schemas/agents.js.map +1 -1
  178. package/dist/schemas/automations.d.ts +1 -0
  179. package/dist/schemas/automations.d.ts.map +1 -1
  180. package/dist/schemas/devices.d.ts.map +1 -1
  181. package/dist/schemas/devices.js +2 -2
  182. package/dist/schemas/devices.js.map +1 -1
  183. package/dist/schemas/git/git.d.ts +3 -0
  184. package/dist/schemas/git/git.d.ts.map +1 -1
  185. package/dist/schemas/hosts.d.ts +1 -0
  186. package/dist/schemas/hosts.d.ts.map +1 -1
  187. package/dist/schemas/hosts.js +1 -0
  188. package/dist/schemas/hosts.js.map +1 -1
  189. package/dist/schemas/settings.d.ts +1 -0
  190. package/dist/schemas/settings.d.ts.map +1 -1
  191. package/dist/schemas/settings.js +4 -0
  192. package/dist/schemas/settings.js.map +1 -1
  193. package/dist/state/definition.d.ts +4 -0
  194. package/dist/state/definition.d.ts.map +1 -1
  195. package/dist/state/history-state.d.ts.map +1 -1
  196. package/dist/state/history-state.js +2 -12
  197. package/dist/state/history-state.js.map +1 -1
  198. package/dist/state/landed-commit.d.ts +4 -0
  199. package/dist/state/landed-commit.d.ts.map +1 -0
  200. package/dist/state/landed-commit.js +12 -0
  201. package/dist/state/landed-commit.js.map +1 -0
  202. package/package.json +5 -5
  203. package/src/contracts/accounts.contract.ts +7 -7
  204. package/src/contracts/activity.contract.ts +3 -3
  205. package/src/contracts/agent.contract.ts +25 -11
  206. package/src/contracts/agents.contract.ts +48 -30
  207. package/src/contracts/approvals.contract.ts +4 -4
  208. package/src/contracts/areas.contract.ts +5 -4
  209. package/src/contracts/automations.contract.ts +12 -12
  210. package/src/contracts/capabilities.contract.ts +23 -14
  211. package/src/contracts/chores.contract.ts +4 -4
  212. package/src/contracts/ci.contract.ts +6 -6
  213. package/src/contracts/diff.contract.ts +2 -2
  214. package/src/contracts/endpoints.contract.ts +5 -5
  215. package/src/contracts/exit.contract.ts +11 -8
  216. package/src/contracts/extensions.contract.ts +18 -18
  217. package/src/contracts/git.contract.ts +46 -46
  218. package/src/contracts/history.contract.ts +5 -5
  219. package/src/contracts/intentic.contract.ts +5 -4
  220. package/src/contracts/inventory.contract.ts +4 -4
  221. package/src/contracts/issues.contract.ts +6 -6
  222. package/src/contracts/logs.contract.ts +8 -4
  223. package/src/contracts/loops.contract.ts +7 -7
  224. package/src/contracts/netdisk.contract.ts +7 -4
  225. package/src/contracts/panels.contract.ts +4 -4
  226. package/src/contracts/personas.contract.ts +10 -9
  227. package/src/contracts/ports.contract.ts +6 -4
  228. package/src/contracts/prepush.contract.ts +4 -4
  229. package/src/contracts/providers.contract.ts +5 -3
  230. package/src/contracts/public.contract.ts +4 -4
  231. package/src/contracts/push.contract.ts +12 -5
  232. package/src/contracts/safety.contract.ts +4 -4
  233. package/src/contracts/secrets.contract.ts +16 -10
  234. package/src/contracts/sessions.contract.ts +6 -3
  235. package/src/contracts/settings.contract.ts +11 -10
  236. package/src/contracts/share.contract.ts +5 -5
  237. package/src/contracts/skills.contract.ts +6 -6
  238. package/src/contracts/system.contract.ts +32 -20
  239. package/src/contracts/translator.contract.ts +6 -6
  240. package/src/contracts/usage.contract.ts +5 -5
  241. package/src/contracts/vpn.contract.ts +8 -5
  242. package/src/contracts/workflows.contract.ts +10 -10
  243. package/src/contracts/workspace.contract.ts +49 -31
  244. package/src/events/land-breakage.ts +11 -0
  245. package/src/index.ts +23 -1
  246. package/src/models/capability-ledger.test.ts +1 -1
  247. package/src/protocol/procedure-types.ts +24 -0
  248. package/src/protocol/raw-routes.ts +191 -0
  249. package/src/protocol/route-meta.ts +39 -0
  250. package/src/protocol/routes.test.ts +65 -2
  251. package/src/protocol/routes.ts +88 -27
  252. package/src/schemas/agent.test.ts +66 -0
  253. package/src/schemas/agent.ts +184 -154
  254. package/src/schemas/agents.ts +6 -0
  255. package/src/schemas/devices.ts +2 -2
  256. package/src/schemas/hosts.ts +4 -0
  257. package/src/schemas/settings.ts +9 -0
  258. package/src/state/history-state.ts +14 -29
  259. package/src/state/landed-commit.test.ts +18 -0
  260. package/src/state/landed-commit.ts +17 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/sandbox-contract",
3
- "version": "1.307.0",
3
+ "version": "1.308.2",
4
4
  "description": "oRPC wire contract for the intentic sandbox daemon, shared by the daemon and its browser client",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -218,10 +218,10 @@
218
218
  }
219
219
  },
220
220
  "dependencies": {
221
- "@intentic/base": "1.307.0",
222
- "@intentic/constants": "1.307.0",
223
- "@intentic/extension-manifest": "1.307.0",
224
- "@intentic/registry": "1.307.0",
221
+ "@intentic/base": "1.308.2",
222
+ "@intentic/constants": "1.308.2",
223
+ "@intentic/extension-manifest": "1.308.2",
224
+ "@intentic/registry": "1.308.2",
225
225
  "@orpc/contract": "1.14.13",
226
226
  "tslib": "2.8.1",
227
227
  "zod": "4.5.4"
@@ -1,4 +1,4 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
2
  import { NativeProviderParamSchema } from "../schemas/agent.js";
3
3
  import {
4
4
  AccountIdSchema,
@@ -18,7 +18,7 @@ import { OkSchema } from "../schemas/shared.js";
18
18
  // slice per provider. Distinct from the translator routes (subscriptions proxied through CLIProxyAPI): these
19
19
  // credentials live in this daemon's own auth tree, and no credential ever rides in an answer.
20
20
  export const accountsContract = {
21
- start: oc
21
+ start: procedure
22
22
  .route({
23
23
  method: "POST",
24
24
  path: "/accounts/{provider}/login/start",
@@ -28,7 +28,7 @@ export const accountsContract = {
28
28
  })
29
29
  .input(NativeProviderParamSchema.extend(LoginRequestSchema.shape))
30
30
  .output(LoginStartSchema),
31
- complete: oc
31
+ complete: procedure
32
32
  .route({
33
33
  method: "POST",
34
34
  path: "/accounts/{provider}/login/complete",
@@ -38,7 +38,7 @@ export const accountsContract = {
38
38
  })
39
39
  .input(NativeProviderParamSchema.extend(LoginCompleteSchema.shape))
40
40
  .output(LoginCompletedSchema),
41
- cancel: oc
41
+ cancel: procedure
42
42
  .route({
43
43
  method: "POST",
44
44
  path: "/accounts/{provider}/login/cancel",
@@ -48,7 +48,7 @@ export const accountsContract = {
48
48
  .input(NativeProviderParamSchema.extend(LoginCancelSchema.shape))
49
49
  .output(OkSchema),
50
50
  // `force` re-measures before answering; a provider with nothing to measure accepts it and answers at once.
51
- accounts: oc
51
+ accounts: procedure
52
52
  .route({
53
53
  method: "GET",
54
54
  path: "/accounts/{provider}",
@@ -58,7 +58,7 @@ export const accountsContract = {
58
58
  })
59
59
  .input(NativeProviderParamSchema.extend(AccountListQuerySchema.shape))
60
60
  .output(OauthAccountListSchema),
61
- rename: oc
61
+ rename: procedure
62
62
  .route({
63
63
  method: "POST",
64
64
  path: "/accounts/{provider}/rename",
@@ -67,7 +67,7 @@ export const accountsContract = {
67
67
  })
68
68
  .input(NativeProviderParamSchema.extend(AccountRenameSchema.shape))
69
69
  .output(OauthAccountSchema),
70
- disconnect: oc
70
+ disconnect: procedure
71
71
  .route({
72
72
  method: "POST",
73
73
  path: "/accounts/{provider}/disconnect",
@@ -1,10 +1,10 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
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.
6
6
  export const activityContract = {
7
- list: oc
7
+ list: procedure
8
8
  .route({
9
9
  method: "GET",
10
10
  path: "/activity",
@@ -14,7 +14,7 @@ export const activityContract = {
14
14
  })
15
15
  .input(ActivityQuerySchema)
16
16
  .output(ActivityListSchema),
17
- status: oc
17
+ status: procedure
18
18
  .route({
19
19
  method: "GET",
20
20
  path: "/activity/status",
@@ -1,4 +1,4 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
2
  import { streamOf } from "../protocol/routes.js";
3
3
  import { AgentCommandsQuerySchema, AgentCommandsSchema } from "../events/requests.js";
4
4
  import { AttachFrameSchema } from "../events/agent-events.js";
@@ -12,7 +12,7 @@ import { OkSchema } from "../schemas/shared.js";
12
12
  // (replay then live, no special stream for the initiator), `reply` un-parks it, `steer` injects a message, `stop`
13
13
  // hard-cancels it.
14
14
  export const agentContract = {
15
- run: oc
15
+ run: procedure
16
16
  .route({
17
17
  method: "POST",
18
18
  path: "/agent",
@@ -20,9 +20,11 @@ export const agentContract = {
20
20
  description:
21
21
  "Starts a turn and answers immediately with its id; the work runs inside the sandbox whether or not anybody stays connected. Watch it by attaching. Naming a conversation that does not exist yet opens it.",
22
22
  })
23
+ // Driving agents is the collaborator grant; what leaves the sandbox stays at the maintainer default.
24
+ .meta({ floor: "collaborator", guest: true, control: "editor" })
23
25
  .input(AgentTurnSchema)
24
26
  .output(StartedTurnSchema),
25
- attach: oc
27
+ attach: procedure
26
28
  .route({
27
29
  method: "POST",
28
30
  path: "/agent/attach",
@@ -30,9 +32,11 @@ export const agentContract = {
30
32
  description:
31
33
  "Streams everything the agent does: its words, the tools it reaches for, and the answers it gets. Give it the point you have already seen and it replays from there before going live, so a reload loses nothing. The window that started the turn holds no special claim, and any number of watchers on any number of devices see the same thing.",
32
34
  })
35
+ // Watching a live turn is reading, POST or not, so the read rung reaches it too.
36
+ .meta({ floor: "viewer", guest: true, stream: true, control: "read" })
33
37
  .input(AttachTurnSchema)
34
38
  .output(streamOf(AttachFrameSchema)),
35
- reply: oc
39
+ reply: procedure
36
40
  .route({
37
41
  method: "POST",
38
42
  path: "/agent/reply",
@@ -40,9 +44,10 @@ export const agentContract = {
40
44
  description:
41
45
  "Un-parks a turn that is waiting on you: approving a plan, choosing between options, or permitting a tool. The turn picks up where it stopped.",
42
46
  })
47
+ .meta({ floor: "collaborator", guest: true, control: "editor" })
43
48
  .input(AgentReplySchema)
44
49
  .output(OkSchema),
45
- steer: oc
50
+ steer: procedure
46
51
  .route({
47
52
  method: "POST",
48
53
  path: "/agent/steer",
@@ -50,19 +55,21 @@ export const agentContract = {
50
55
  description:
51
56
  "Slips a message into a turn already under way, without stopping it. This is how you redirect an agent mid-thought rather than waiting for it to finish being wrong.",
52
57
  })
58
+ .meta({ floor: "collaborator", guest: true })
53
59
  .input(SteerSchema)
54
60
  .output(OkSchema),
55
- stop: oc
61
+ stop: procedure
56
62
  .route({
57
63
  method: "POST",
58
64
  path: "/agent/stop",
59
65
  summary: "Stop a turn now",
60
66
  description: "Cancels the running turn inside the sandbox. Whatever it had already written to disk stays written.",
61
67
  })
68
+ .meta({ floor: "collaborator", guest: true })
62
69
  .input(StopTurnSchema)
63
70
  .output(OkSchema),
64
71
  // NOT_FOUND when nothing is held (superseded, or the daemon restarted): the client should fall back to `run`.
65
- resume: oc
72
+ resume: procedure
66
73
  .route({
67
74
  method: "POST",
68
75
  path: "/agent/resume",
@@ -70,10 +77,12 @@ export const agentContract = {
70
77
  description:
71
78
  "Sends the same turn again when the model provider's allowance refused it, with everything it originally carried except who serves it: the caller may name a different provider, harness or account, which is the usual answer to a spent allowance. It repeats the request rather than adding a new message to the conversation, so pressing it twice costs nothing and the agent is never told to continue work it has not started.",
72
79
  })
80
+ // The same turn again with all it carried; refused, a collaborator's automation sticks at its first refusal.
81
+ .meta({ floor: "collaborator", guest: true })
73
82
  .input(ResumeTurnSchema)
74
83
  .output(StartedTurnSchema),
75
84
  // CONFLICT while a turn is running; NOT_FOUND when the message has no checkpoint.
76
- rewind: oc
85
+ rewind: procedure
77
86
  .route({
78
87
  method: "POST",
79
88
  path: "/agent/rewind",
@@ -81,9 +90,10 @@ export const agentContract = {
81
90
  description:
82
91
  "Puts the files back as they stood at that point, drops every message after it, and forgets what the model remembered, so the next thing you say starts from there cleanly. Refused while a turn is running, because a restore cannot overwrite files an agent is editing, and refused for a message with no saved state to return to.",
83
92
  })
93
+ .meta({ floor: "collaborator", guest: true })
84
94
  .input(RewindTurnSchema)
85
95
  .output(RewindResultSchema),
86
- commands: oc
96
+ commands: procedure
87
97
  .route({
88
98
  method: "GET",
89
99
  path: "/agent/commands",
@@ -91,11 +101,12 @@ export const agentContract = {
91
101
  description:
92
102
  "The commands a provider published the last time one of its turns ran, so a composer can offer them before this conversation has run anything. A running turn's own list wins over this one.",
93
103
  })
104
+ .meta({ guest: true })
94
105
  .input(AgentCommandsQuerySchema)
95
106
  .output(AgentCommandsSchema),
96
107
  // Never throws: no offer, no personas, no model, or a deadline are all "nothing chosen" with a reason; the composer
97
108
  // is waiting.
98
- routeChat: oc
109
+ routeChat: procedure
99
110
  .route({
100
111
  method: "POST",
101
112
  path: "/agent/route-chat",
@@ -103,9 +114,11 @@ export const agentContract = {
103
114
  description:
104
115
  "Reads a new chat's opening message once and answers whichever of two questions it still has: the model, effort and account that conversation should run on, from what is connected and still has allowance left, and which of this sandbox's personas should handle it. `model` and `persona` on the ask say which halves to answer, and only those are put to the model. Asked once per chat, on the message actually sent, and never again: every turn after it runs on what the chat is wearing, which you are free to change. Answers with nothing, and a reason, whenever it cannot choose — a chat is never held up by this.",
105
116
  })
117
+ // A read shaped as a POST, costing one model call the tier about to spend a whole turn may spend.
118
+ .meta({ floor: "collaborator" })
106
119
  .input(ChatRouteAskSchema)
107
120
  .output(ChatRouteSchema),
108
- refusals: oc
121
+ refusals: procedure
109
122
  .route({
110
123
  method: "GET",
111
124
  path: "/agent/refusals",
@@ -113,5 +126,6 @@ export const agentContract = {
113
126
  description:
114
127
  "What each model provider most recently refused and why. Read this alongside an account's usage: the usage says how full it was when last checked, this says whether it has since started turning work away.",
115
128
  })
129
+ .meta({ guest: true })
116
130
  .output(ProviderRefusalsSchema),
117
131
  };
@@ -1,4 +1,4 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
2
  import { AgentToolChildrenSchema, AgentTranscriptSchema } from "../events/transcript.js";
3
3
  import {
4
4
  AgentArchiveSchema,
@@ -33,7 +33,7 @@ import { ConversationPromptSchema } from "../schemas/system-prompt.js";
33
33
  // `archive` is the non-destructive counterpart to `discard` (worktree committed, entry kept); `purge` is `discard`
34
34
  // applied to every already-archived agent.
35
35
  export const agentsContract = {
36
- list: oc
36
+ list: procedure
37
37
  .route({
38
38
  method: "GET",
39
39
  path: "/agents",
@@ -41,8 +41,9 @@ export const agentsContract = {
41
41
  description:
42
42
  "The fleet as the board draws it: each conversation with its title, what it is doing, when it last moved and whether anybody has read it since. Archived conversations are not in here.",
43
43
  })
44
+ .meta({ guest: true })
44
45
  .output(AgentsListSchema),
45
- archived: oc
46
+ archived: procedure
46
47
  .route({
47
48
  method: "GET",
48
49
  path: "/agents/archived",
@@ -50,9 +51,10 @@ export const agentsContract = {
50
51
  description:
51
52
  "The same shape as the live fleet, for the conversations somebody has decided are finished. Their work is kept, and any one of them can be brought back.",
52
53
  })
54
+ .meta({ guest: true })
53
55
  .output(AgentsListSchema),
54
56
  // Never-carded conversations (neither live nor archived) are `sessions.list`'s query, matching by the same rule.
55
- search: oc
57
+ search: procedure
56
58
  .route({
57
59
  method: "GET",
58
60
  path: "/agents/search",
@@ -62,16 +64,17 @@ export const agentsContract = {
62
64
  })
63
65
  .input(AgentSearchQuerySchema)
64
66
  .output(AgentSearchResultSchema),
65
- get: oc
67
+ get: procedure
66
68
  .route({
67
69
  method: "GET",
68
70
  path: "/agents/{id}",
69
71
  summary: "One conversation's card",
70
72
  description: "Everything the board shows for a single conversation: its title, state, working branch, unread marker and timestamps.",
71
73
  })
74
+ .meta({ guest: true })
72
75
  .input(AgentIdSchema)
73
76
  .output(AgentSummarySchema),
74
- transcript: oc
77
+ transcript: procedure
75
78
  .route({
76
79
  method: "GET",
77
80
  path: "/agents/{id}/transcript",
@@ -79,9 +82,10 @@ export const agentsContract = {
79
82
  description:
80
83
  "The most recent turns of one conversation, in order, including the tool calls and their results: what the chat replays and the next turn is seeded from. A page, not the whole record — pass the answer's `from` back as `before` to walk further back, until `more` reads false.",
81
84
  })
85
+ .meta({ guest: true })
82
86
  .input(AgentTranscriptQuerySchema)
83
87
  .output(AgentTranscriptSchema),
84
- systemPrompt: oc
88
+ systemPrompt: procedure
85
89
  .route({
86
90
  method: "GET",
87
91
  path: "/agents/{id}/system-prompt",
@@ -91,7 +95,7 @@ export const agentsContract = {
91
95
  })
92
96
  .input(AgentIdSchema)
93
97
  .output(ConversationPromptSchema),
94
- toolChildren: oc
98
+ toolChildren: procedure
95
99
  .route({
96
100
  method: "GET",
97
101
  path: "/agents/{id}/transcript/tools/{toolId}",
@@ -103,7 +107,7 @@ export const agentsContract = {
103
107
  .output(AgentToolChildrenSchema),
104
108
  // Also forgets the provider session, rewind-style, so the next fresh session reads the placed line as the agent's
105
109
  // own.
106
- place: oc
110
+ place: procedure
107
111
  .route({
108
112
  method: "POST",
109
113
  path: "/agents/{id}/place",
@@ -113,7 +117,7 @@ export const agentsContract = {
113
117
  })
114
118
  .input(AgentPlaceSchema)
115
119
  .output(OkSchema),
116
- rename: oc
120
+ rename: procedure
117
121
  .route({
118
122
  method: "POST",
119
123
  path: "/agents/{id}/rename",
@@ -121,9 +125,10 @@ export const agentsContract = {
121
125
  description:
122
126
  "Sets the title a person chose, replacing the one that was generated. Allowed while the conversation is working, and it does not count as activity.",
123
127
  })
128
+ .meta({ floor: "collaborator", guest: true })
124
129
  .input(AgentRenameSchema)
125
130
  .output(AgentSummarySchema),
126
- autoLand: oc
131
+ autoLand: procedure
127
132
  .route({
128
133
  method: "POST",
129
134
  path: "/agents/{id}/auto-land",
@@ -135,7 +140,7 @@ export const agentsContract = {
135
140
  .output(AgentSummarySchema),
136
141
  // Legal for a workspace conversation too (unlike autoLand): an outage kills a main-tree chat just as readily.
137
142
  // Also offered on the card, not just in chat: a limit reopens hours later, so the decider is usually at a board.
138
- breakPolicy: oc
143
+ breakPolicy: procedure
139
144
  .route({
140
145
  method: "POST",
141
146
  path: "/agents/{id}/break-policy",
@@ -143,9 +148,10 @@ export const agentsContract = {
143
148
  description:
144
149
  "One answer per ending — a spent usage limit, a provider outage, a turn that stopped short — overriding the sandbox-wide policy for one conversation; clear it to follow the default again. The answers are mutually exclusive by construction, so nothing here can arm two automations over the same wall. Every ending starts at `wait` unless asked otherwise, because a re-run spends the user's own allowance on a turn they sent once.",
145
150
  })
151
+ .meta({ floor: "collaborator" })
146
152
  .input(AgentBreakPolicySchema)
147
153
  .output(AgentSummarySchema),
148
- seen: oc
154
+ seen: procedure
149
155
  .route({
150
156
  method: "POST",
151
157
  path: "/agents/{id}/seen",
@@ -153,10 +159,11 @@ export const agentsContract = {
153
159
  description:
154
160
  "Stamps the read marker behind the unread badge on one card. Allowed while the conversation is working, and reading never counts as activity.",
155
161
  })
162
+ .meta({ floor: "collaborator", guest: true })
156
163
  .input(AgentIdSchema)
157
164
  .output(AgentSummarySchema),
158
165
  // A finer-grained ask (watch this, not that) goes through the chat, not a per-watch id here.
159
- stopWatching: oc
166
+ stopWatching: procedure
160
167
  .route({
161
168
  method: "POST",
162
169
  path: "/agents/{id}/stop-watching",
@@ -166,15 +173,16 @@ export const agentsContract = {
166
173
  })
167
174
  .input(AgentStopWatchingSchema)
168
175
  .output(AgentSummarySchema),
169
- seenAll: oc
176
+ seenAll: procedure
170
177
  .route({
171
178
  method: "POST",
172
179
  path: "/agents/seen",
173
180
  summary: "Mark every conversation read",
174
181
  description: "Clears the unread badge across the whole fleet at once, and hands the refreshed list back.",
175
182
  })
183
+ .meta({ floor: "collaborator", guest: true })
176
184
  .output(AgentsListSchema),
177
- diff: oc
185
+ diff: procedure
178
186
  .route({
179
187
  method: "GET",
180
188
  path: "/agents/{id}/diff",
@@ -186,7 +194,7 @@ export const agentsContract = {
186
194
  .output(AgentChangesSchema),
187
195
  // Costs a `git log` per repo: ask only once `diff` reports something absorbed. Reading a file here reuses
188
196
  // `fileDiff`.
189
- history: oc
197
+ history: procedure
190
198
  .route({
191
199
  method: "GET",
192
200
  path: "/agents/{id}/history",
@@ -196,7 +204,7 @@ export const agentsContract = {
196
204
  })
197
205
  .input(AgentIdSchema)
198
206
  .output(AgentHistorySchema),
199
- fileDiff: oc
207
+ fileDiff: procedure
200
208
  .route({
201
209
  method: "GET",
202
210
  path: "/agents/{id}/{repo}/file-diff",
@@ -207,7 +215,7 @@ export const agentsContract = {
207
215
  .output(FileDiffSchema),
208
216
  // Stages rather than commits: the next capture commits it like the rest of the work, with nothing to unwind if the
209
217
  // conversation's next turn moves it.
210
- includeScratch: oc
218
+ includeScratch: procedure
211
219
  .route({
212
220
  method: "POST",
213
221
  path: "/agents/{id}/scratch/include",
@@ -217,7 +225,7 @@ export const agentsContract = {
217
225
  })
218
226
  .input(AgentScratchSchema)
219
227
  .output(OkSchema),
220
- deleteScratch: oc
228
+ deleteScratch: procedure
221
229
  .route({
222
230
  method: "POST",
223
231
  path: "/agents/{id}/scratch/delete",
@@ -227,7 +235,7 @@ export const agentsContract = {
227
235
  })
228
236
  .input(AgentScratchSchema)
229
237
  .output(OkSchema),
230
- land: oc
238
+ land: procedure
231
239
  .route({
232
240
  method: "POST",
233
241
  path: "/agents/{id}/land",
@@ -235,10 +243,12 @@ export const agentsContract = {
235
243
  description:
236
244
  "Brings the conversation's branches into the main tree, one repo at a time. A conflict is reported rather than raised and nothing is lost when it fails. Refused while a turn is running, and refused for a conversation that works directly in the shared tree, which has nothing to merge.",
237
245
  })
246
+ // The irreversible press a program may hold, kept to its own rung apart from the work.
247
+ .meta({ control: "land" })
238
248
  .input(AgentLandSchema)
239
249
  .output(LandResultSchema),
240
250
  // Stamps `AgentSummarySchema.landRequested` with the caller's identity.
241
- requestLand: oc
251
+ requestLand: procedure
242
252
  .route({
243
253
  method: "POST",
244
254
  path: "/agents/{id}/request-land",
@@ -246,11 +256,13 @@ export const agentsContract = {
246
256
  description:
247
257
  "For a collaborator who is not allowed to merge: marks the conversation as waiting for review, with who asked. The request shows on every maintainer's board and clears when somebody merges or discards it.",
248
258
  })
259
+ // A collaborator's landings are only requests.
260
+ .meta({ floor: "collaborator" })
249
261
  .input(AgentIdSchema)
250
262
  .output(AgentSummarySchema),
251
263
  // Sets `AgentSummarySchema.owner`. Who may: the current owner (handing over), a maintainer or the sandbox owner
252
264
  // (taking over), and anyone at the driving tier when nobody owns it yet (claiming).
253
- assign: oc
265
+ assign: procedure
254
266
  .route({
255
267
  method: "POST",
256
268
  path: "/agents/{id}/assign",
@@ -258,11 +270,12 @@ export const agentsContract = {
258
270
  description:
259
271
  "Hands a conversation to a member: its owner is who answers its questions and who a reviewer asks about its work. Its owner may hand it to anyone; a maintainer may reassign any conversation; one nobody owns may be claimed by anyone allowed to drive agents. Refused for an address that is not a member's. Nothing about the conversation's own work changes.",
260
272
  })
273
+ // Changing hands is driving, not shipping; the route itself decides whose hands may do it.
274
+ .meta({ floor: "collaborator" })
261
275
  .input(AgentAssignSchema)
262
276
  .output(AgentSummarySchema),
263
- // Floored at viewer (auth/role-floor.ts), unlike every other write here: marking a conversation is expression, not
264
- // operating authority.
265
- react: oc
277
+ // Floored at viewer, unlike every other write here: marking a conversation is expression, not operating authority.
278
+ react: procedure
266
279
  .route({
267
280
  method: "POST",
268
281
  path: "/agents/{id}/react",
@@ -270,9 +283,10 @@ export const agentsContract = {
270
283
  description:
271
284
  "Puts your mark on a conversation, or takes it back. Everyone sharing the sandbox sees it, with who left it, which is what makes it worth more than a private bookmark. One mark per person per emoji; nothing about the conversation's own work changes.",
272
285
  })
286
+ .meta({ floor: "viewer", guest: true })
273
287
  .input(AgentReactSchema)
274
288
  .output(AgentSummarySchema),
275
- discard: oc
289
+ discard: procedure
276
290
  .route({
277
291
  method: "POST",
278
292
  path: "/agents/{id}/discard",
@@ -280,9 +294,10 @@ export const agentsContract = {
280
294
  description:
281
295
  "Deletes the conversation's working copies, its branches and its entry. Nothing is kept. Refused while a turn is running, and refused for a conversation working in the shared tree.",
282
296
  })
297
+ .meta({ control: "land" })
283
298
  .input(AgentIdSchema)
284
299
  .output(OkSchema),
285
- archive: oc
300
+ archive: procedure
286
301
  .route({
287
302
  method: "POST",
288
303
  path: "/agents/archive",
@@ -290,9 +305,10 @@ export const agentsContract = {
290
305
  description:
291
306
  "The gentle counterpart to discarding. Commits whatever the conversation still has in progress onto its own branch, releases its working copy, and keeps the entry and the record. Its scratch is not committed and goes with the copy. It leaves the live fleet and joins the archive. Refused for a conversation that is running.",
292
307
  })
308
+ .meta({ floor: "collaborator", guest: true })
293
309
  .input(AgentArchiveSchema)
294
310
  .output(AgentsArchivedSchema),
295
- unarchive: oc
311
+ unarchive: procedure
296
312
  .route({
297
313
  method: "POST",
298
314
  path: "/agents/unarchive",
@@ -300,9 +316,10 @@ export const agentsContract = {
300
316
  description:
301
317
  "Returns archived conversations to the live fleet. The next turn picks up a fresh working copy from the branch that was kept.",
302
318
  })
319
+ .meta({ floor: "collaborator", guest: true })
303
320
  .input(AgentIdsSchema)
304
321
  .output(AgentsMovedSchema),
305
- purge: oc
322
+ purge: procedure
306
323
  .route({
307
324
  method: "POST",
308
325
  path: "/agents/purge",
@@ -310,5 +327,6 @@ export const agentsContract = {
310
327
  description:
311
328
  "Discards every conversation already in the archive: working copies, branches and entries. The whole archive rather than a chosen few, because the archive is the pile somebody has already decided is over. A teardown that fails on one conversation leaves that one behind instead of taking the rest down with it.",
312
329
  })
330
+ .meta({ control: "land" })
313
331
  .output(AgentsRemovedSchema),
314
332
  };
@@ -1,4 +1,4 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
2
  import { ApprovalIdParamSchema, ApprovalsListSchema, ApprovalSummarySchema } from "../schemas/approvals.js";
3
3
  import { OkSchema } from "../schemas/shared.js";
4
4
 
@@ -7,7 +7,7 @@ import { OkSchema } from "../schemas/shared.js";
7
7
  // edit / reschedule / retry (all a plain re-post with a field changed, like the automations enabled toggle),
8
8
  // `remove` is reject. The verbs are the same whatever the kind, which is the point of one queue.
9
9
  export const approvalsContract = {
10
- list: oc
10
+ list: procedure
11
11
  .route({
12
12
  method: "GET",
13
13
  path: "/approvals",
@@ -16,7 +16,7 @@ export const approvalsContract = {
16
16
  "Everything an agent has prepared and would like to do: posts to publish, actions to carry out. Nothing here has happened yet.",
17
17
  })
18
18
  .output(ApprovalsListSchema),
19
- upsert: oc
19
+ upsert: procedure
20
20
  .route({
21
21
  method: "POST",
22
22
  path: "/approvals",
@@ -25,7 +25,7 @@ export const approvalsContract = {
25
25
  })
26
26
  .input(ApprovalSummarySchema)
27
27
  .output(OkSchema),
28
- remove: oc
28
+ remove: procedure
29
29
  .route({
30
30
  method: "DELETE",
31
31
  path: "/approvals/{id}",
@@ -1,4 +1,4 @@
1
- import { oc } from "@orpc/contract";
1
+ import { procedure } from "../protocol/route-meta.js";
2
2
  import { OkSchema } from "../schemas/shared.js";
3
3
  import { AreaIdParamSchema, AreaSchema, AreasListSchema } from "../schemas/areas.js";
4
4
 
@@ -7,7 +7,7 @@ import { AreaIdParamSchema, AreaSchema, AreasListSchema } from "../schemas/areas
7
7
  // which is the one decision a revokable grant must not make, so the two writes below are owner-gated in-route the way
8
8
  // the roster is.
9
9
  export const areasContract = {
10
- list: oc
10
+ list: procedure
11
11
  .route({
12
12
  method: "GET",
13
13
  path: "/areas",
@@ -15,9 +15,10 @@ export const areasContract = {
15
15
  description:
16
16
  "Each area with the folders it admits. Access is granted in these rather than in folder lists per person, so widening what a team sees is one edit here instead of one edit per member.",
17
17
  })
18
+ .meta({ guest: true })
18
19
  .output(AreasListSchema),
19
20
  // Upsert by id, re-saving the same id edits that area.
20
- save: oc
21
+ save: procedure
21
22
  .route({
22
23
  method: "POST",
23
24
  path: "/areas",
@@ -29,7 +30,7 @@ export const areasContract = {
29
30
  .output(OkSchema),
30
31
  // Refused while anyone still holds it: a member row pointing at an area that no longer exists would either fail
31
32
  // open (everything) or fail shut (nothing), and neither is a decision anybody made.
32
- remove: oc
33
+ remove: procedure
33
34
  .route({
34
35
  method: "DELETE",
35
36
  path: "/areas/{id}",