@intentic/sandbox-contract 1.337.0 → 1.338.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 (263) hide show
  1. package/README.md +36 -0
  2. package/dist/chores/probes.d.ts.map +1 -1
  3. package/dist/chores/probes.js +4 -7
  4. package/dist/chores/probes.js.map +1 -1
  5. package/dist/contracts/agent.contract.d.ts +32 -23
  6. package/dist/contracts/agent.contract.d.ts.map +1 -1
  7. package/dist/contracts/agents.contract.d.ts +6016 -5994
  8. package/dist/contracts/agents.contract.d.ts.map +1 -1
  9. package/dist/contracts/agents.contract.js +3 -0
  10. package/dist/contracts/agents.contract.js.map +1 -1
  11. package/dist/contracts/approvals.contract.d.ts +8 -0
  12. package/dist/contracts/approvals.contract.d.ts.map +1 -1
  13. package/dist/contracts/automations.contract.d.ts +3 -3
  14. package/dist/contracts/capabilities.contract.d.ts +28 -0
  15. package/dist/contracts/capabilities.contract.d.ts.map +1 -1
  16. package/dist/contracts/capabilities.contract.js +11 -1
  17. package/dist/contracts/capabilities.contract.js.map +1 -1
  18. package/dist/contracts/device.contract.d.ts +225 -0
  19. package/dist/contracts/device.contract.d.ts.map +1 -1
  20. package/dist/contracts/device.contract.js +10 -0
  21. package/dist/contracts/device.contract.js.map +1 -1
  22. package/dist/contracts/extensions.contract.d.ts +16 -0
  23. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  24. package/dist/contracts/needs.contract.d.ts +22 -7
  25. package/dist/contracts/needs.contract.d.ts.map +1 -1
  26. package/dist/contracts/org.contract.d.ts +35 -0
  27. package/dist/contracts/org.contract.d.ts.map +1 -0
  28. package/dist/contracts/org.contract.js +14 -0
  29. package/dist/contracts/org.contract.js.map +1 -0
  30. package/dist/contracts/privacy.contract.d.ts +115 -0
  31. package/dist/contracts/privacy.contract.d.ts.map +1 -1
  32. package/dist/contracts/privacy.contract.js +11 -2
  33. package/dist/contracts/privacy.contract.js.map +1 -1
  34. package/dist/contracts/runner.contract.d.ts +11 -7
  35. package/dist/contracts/runner.contract.d.ts.map +1 -1
  36. package/dist/contracts/secrets.contract.d.ts +85 -0
  37. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  38. package/dist/contracts/secrets.contract.js +48 -1
  39. package/dist/contracts/secrets.contract.js.map +1 -1
  40. package/dist/contracts/sessions.contract.d.ts +4 -1
  41. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  42. package/dist/contracts/settings.contract.d.ts +11 -3
  43. package/dist/contracts/settings.contract.d.ts.map +1 -1
  44. package/dist/contracts/system.contract.d.ts +20 -2
  45. package/dist/contracts/system.contract.d.ts.map +1 -1
  46. package/dist/events/agent-events.d.ts +17 -4
  47. package/dist/events/agent-events.d.ts.map +1 -1
  48. package/dist/events/requests.d.ts +4 -0
  49. package/dist/events/requests.d.ts.map +1 -1
  50. package/dist/events/requests.js +1 -1
  51. package/dist/events/requests.js.map +1 -1
  52. package/dist/events/system-events.d.ts +4 -0
  53. package/dist/events/system-events.d.ts.map +1 -1
  54. package/dist/events/system-events.js +2 -0
  55. package/dist/events/system-events.js.map +1 -1
  56. package/dist/events/transcript.d.ts +27 -6
  57. package/dist/events/transcript.d.ts.map +1 -1
  58. package/dist/index.d.ts +7555 -7426
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +31 -257
  61. package/dist/index.js.map +1 -1
  62. package/dist/policy/identity-assertion.d.ts.map +1 -1
  63. package/dist/policy/identity-assertion.js +2 -8
  64. package/dist/policy/identity-assertion.js.map +1 -1
  65. package/dist/policy/keyring-seal.d.ts +48 -0
  66. package/dist/policy/keyring-seal.d.ts.map +1 -0
  67. package/dist/policy/keyring-seal.js +94 -0
  68. package/dist/policy/keyring-seal.js.map +1 -0
  69. package/dist/policy/message-limits.d.ts +2 -0
  70. package/dist/policy/message-limits.d.ts.map +1 -1
  71. package/dist/policy/message-limits.js +2 -0
  72. package/dist/policy/message-limits.js.map +1 -1
  73. package/dist/policy/org-locks.d.ts +58 -0
  74. package/dist/policy/org-locks.d.ts.map +1 -0
  75. package/dist/policy/org-locks.js +113 -0
  76. package/dist/policy/org-locks.js.map +1 -0
  77. package/dist/policy/reserved-servers.d.ts.map +1 -1
  78. package/dist/policy/reserved-servers.js +1 -1
  79. package/dist/policy/reserved-servers.js.map +1 -1
  80. package/dist/protocol/doors/webext-links.d.ts +3 -0
  81. package/dist/protocol/doors/webext-links.d.ts.map +1 -1
  82. package/dist/protocol/doors/webext-links.js +3 -0
  83. package/dist/protocol/doors/webext-links.js.map +1 -1
  84. package/dist/protocol/raw/raw-json-routes.d.ts +269 -0
  85. package/dist/protocol/raw/raw-json-routes.d.ts.map +1 -1
  86. package/dist/protocol/raw/raw-json-routes.js +14 -1
  87. package/dist/protocol/raw/raw-json-routes.js.map +1 -1
  88. package/dist/protocol/raw/raw-routes.d.ts +70 -0
  89. package/dist/protocol/raw/raw-routes.d.ts.map +1 -1
  90. package/dist/protocol/raw/raw-routes.js +18 -0
  91. package/dist/protocol/raw/raw-routes.js.map +1 -1
  92. package/dist/protocol/route-meta.d.ts.map +1 -1
  93. package/dist/protocol/route-meta.js.map +1 -1
  94. package/dist/protocol/routes.d.ts +4 -0
  95. package/dist/protocol/routes.d.ts.map +1 -1
  96. package/dist/protocol/routes.js +12 -0
  97. package/dist/protocol/routes.js.map +1 -1
  98. package/dist/schemas/agents.d.ts +1 -0
  99. package/dist/schemas/agents.d.ts.map +1 -1
  100. package/dist/schemas/agents.js +1 -0
  101. package/dist/schemas/agents.js.map +1 -1
  102. package/dist/schemas/approvals.d.ts +20 -0
  103. package/dist/schemas/approvals.d.ts.map +1 -1
  104. package/dist/schemas/approvals.js +10 -0
  105. package/dist/schemas/approvals.js.map +1 -1
  106. package/dist/schemas/capabilities.d.ts +26 -0
  107. package/dist/schemas/capabilities.d.ts.map +1 -1
  108. package/dist/schemas/capabilities.js +17 -0
  109. package/dist/schemas/capabilities.js.map +1 -1
  110. package/dist/schemas/data-protection.d.ts +5 -0
  111. package/dist/schemas/data-protection.d.ts.map +1 -1
  112. package/dist/schemas/data-protection.js +29 -0
  113. package/dist/schemas/data-protection.js.map +1 -1
  114. package/dist/schemas/devices.d.ts +11 -0
  115. package/dist/schemas/devices.d.ts.map +1 -1
  116. package/dist/schemas/devices.js +2 -1
  117. package/dist/schemas/devices.js.map +1 -1
  118. package/dist/schemas/extension-updates.d.ts +32 -0
  119. package/dist/schemas/extension-updates.d.ts.map +1 -1
  120. package/dist/schemas/git/git.d.ts +19 -0
  121. package/dist/schemas/git/git.d.ts.map +1 -1
  122. package/dist/schemas/git/git.js +12 -1
  123. package/dist/schemas/git/git.js.map +1 -1
  124. package/dist/schemas/hosts.d.ts +2 -0
  125. package/dist/schemas/hosts.d.ts.map +1 -1
  126. package/dist/schemas/hosts.js +11 -1
  127. package/dist/schemas/hosts.js.map +1 -1
  128. package/dist/schemas/keyring.d.ts +421 -0
  129. package/dist/schemas/keyring.d.ts.map +1 -0
  130. package/dist/schemas/keyring.js +176 -0
  131. package/dist/schemas/keyring.js.map +1 -0
  132. package/dist/schemas/links.d.ts +208 -0
  133. package/dist/schemas/links.d.ts.map +1 -0
  134. package/dist/schemas/links.js +116 -0
  135. package/dist/schemas/links.js.map +1 -0
  136. package/dist/schemas/maintenance.d.ts.map +1 -1
  137. package/dist/schemas/maintenance.js.map +1 -1
  138. package/dist/schemas/members.d.ts.map +1 -1
  139. package/dist/schemas/members.js +2 -0
  140. package/dist/schemas/members.js.map +1 -1
  141. package/dist/schemas/needs.d.ts +25 -8
  142. package/dist/schemas/needs.d.ts.map +1 -1
  143. package/dist/schemas/needs.js +15 -3
  144. package/dist/schemas/needs.js.map +1 -1
  145. package/dist/schemas/organisation.d.ts +106 -0
  146. package/dist/schemas/organisation.d.ts.map +1 -0
  147. package/dist/schemas/organisation.js +52 -0
  148. package/dist/schemas/organisation.js.map +1 -0
  149. package/dist/schemas/privacy.d.ts +232 -0
  150. package/dist/schemas/privacy.d.ts.map +1 -1
  151. package/dist/schemas/privacy.js +154 -4
  152. package/dist/schemas/privacy.js.map +1 -1
  153. package/dist/schemas/secrets.d.ts +151 -0
  154. package/dist/schemas/secrets.d.ts.map +1 -1
  155. package/dist/schemas/secrets.js +71 -8
  156. package/dist/schemas/secrets.js.map +1 -1
  157. package/dist/schemas/settings.d.ts +8 -0
  158. package/dist/schemas/settings.d.ts.map +1 -1
  159. package/dist/schemas/settings.js +4 -0
  160. package/dist/schemas/settings.js.map +1 -1
  161. package/dist/schemas/speech.d.ts +12 -0
  162. package/dist/schemas/speech.d.ts.map +1 -1
  163. package/dist/schemas/speech.js +23 -0
  164. package/dist/schemas/speech.js.map +1 -1
  165. package/dist/schemas/terminal.d.ts +15 -0
  166. package/dist/schemas/terminal.d.ts.map +1 -1
  167. package/dist/schemas/terminal.js +11 -2
  168. package/dist/schemas/terminal.js.map +1 -1
  169. package/dist/schemas/voice.d.ts +3 -0
  170. package/dist/schemas/voice.d.ts.map +1 -1
  171. package/dist/schemas/voice.js +7 -0
  172. package/dist/schemas/voice.js.map +1 -1
  173. package/dist/schemas/webext.d.ts +17 -0
  174. package/dist/schemas/webext.d.ts.map +1 -1
  175. package/dist/schemas/webext.js +7 -1
  176. package/dist/schemas/webext.js.map +1 -1
  177. package/dist/state/contract-lock.d.ts +3 -1
  178. package/dist/state/contract-lock.d.ts.map +1 -1
  179. package/dist/state/contract-lock.js +34 -9
  180. package/dist/state/contract-lock.js.map +1 -1
  181. package/dist/state/contract-modules.d.ts +4 -0
  182. package/dist/state/contract-modules.d.ts.map +1 -0
  183. package/dist/state/contract-modules.js +28 -0
  184. package/dist/state/contract-modules.js.map +1 -0
  185. package/dist/state/daemon-floor.d.ts +4 -0
  186. package/dist/state/daemon-floor.d.ts.map +1 -0
  187. package/dist/state/daemon-floor.js +8 -0
  188. package/dist/state/daemon-floor.js.map +1 -0
  189. package/dist/state/definition.d.ts +34 -0
  190. package/dist/state/definition.d.ts.map +1 -1
  191. package/dist/state/history-state.d.ts.map +1 -1
  192. package/dist/state/history-state.js +7 -0
  193. package/dist/state/history-state.js.map +1 -1
  194. package/dist/text/documents.d.ts +3 -1
  195. package/dist/text/documents.d.ts.map +1 -1
  196. package/dist/text/documents.js +30 -0
  197. package/dist/text/documents.js.map +1 -1
  198. package/dist/text/pages.d.ts.map +1 -1
  199. package/dist/text/pages.js +3 -7
  200. package/dist/text/pages.js.map +1 -1
  201. package/package.json +27 -5
  202. package/src/chores/probes.ts +4 -6
  203. package/src/contracts/agents.contract.ts +5 -0
  204. package/src/contracts/capabilities.contract.ts +14 -0
  205. package/src/contracts/device.contract.ts +30 -0
  206. package/src/contracts/org.contract.ts +19 -0
  207. package/src/contracts/privacy.contract.ts +13 -1
  208. package/src/contracts/secrets.contract.ts +64 -0
  209. package/src/events/requests.ts +3 -1
  210. package/src/events/system-events.ts +9 -0
  211. package/src/index.ts +41 -279
  212. package/src/policy/identity-assertion.ts +2 -8
  213. package/src/policy/keyring-seal.test.ts +93 -0
  214. package/src/policy/keyring-seal.ts +148 -0
  215. package/src/policy/message-limits.ts +3 -0
  216. package/src/policy/org-locks.ts +173 -0
  217. package/src/policy/reserved-servers.ts +3 -2
  218. package/src/policy/tests/org-locks.test.ts +92 -0
  219. package/src/policy/tests/reserved-servers.test.ts +3 -2
  220. package/src/protocol/doors/listener-protocol.ts +1 -1
  221. package/src/protocol/doors/webext-links.ts +13 -0
  222. package/src/protocol/ingress-contract.fixture.json +2 -0
  223. package/src/protocol/pairing-redeem.ts +1 -1
  224. package/src/protocol/peer-dial.test.ts +6 -6
  225. package/src/protocol/peer-mcp-server.test.ts +2 -1
  226. package/src/protocol/raw/raw-json-routes.ts +31 -1
  227. package/src/protocol/raw/raw-routes.ts +35 -1
  228. package/src/protocol/route-meta.ts +2 -1
  229. package/src/protocol/routes.test.ts +33 -1
  230. package/src/protocol/routes.ts +18 -0
  231. package/src/protocol/sse.ts +1 -1
  232. package/src/schemas/agent.ts +1 -1
  233. package/src/schemas/agents.ts +1 -0
  234. package/src/schemas/approvals.ts +14 -0
  235. package/src/schemas/capabilities.ts +25 -0
  236. package/src/schemas/data-protection.ts +47 -0
  237. package/src/schemas/devices.ts +8 -1
  238. package/src/schemas/git/git.ts +22 -2
  239. package/src/schemas/hosts.ts +14 -1
  240. package/src/schemas/keyring.ts +277 -0
  241. package/src/schemas/links.ts +180 -0
  242. package/src/schemas/maintenance.ts +1 -0
  243. package/src/schemas/members.ts +4 -0
  244. package/src/schemas/needs.ts +21 -5
  245. package/src/schemas/organisation.ts +110 -0
  246. package/src/schemas/privacy.test.ts +63 -0
  247. package/src/schemas/privacy.ts +213 -5
  248. package/src/schemas/secrets.ts +96 -8
  249. package/src/schemas/settings.ts +8 -0
  250. package/src/schemas/speech.ts +38 -1
  251. package/src/schemas/terminal.ts +13 -2
  252. package/src/schemas/voice.ts +11 -0
  253. package/src/schemas/webext.ts +16 -1
  254. package/src/state/contract-lock.test.ts +12 -12
  255. package/src/state/contract-lock.ts +43 -12
  256. package/src/state/contract-modules.ts +41 -0
  257. package/src/state/daemon-floor.test.ts +81 -0
  258. package/src/state/daemon-floor.ts +32 -0
  259. package/src/state/history-state.ts +14 -0
  260. package/src/state/workspace-state.ts +1 -1
  261. package/src/text/documents.test.ts +30 -1
  262. package/src/text/documents.ts +43 -1
  263. package/src/text/pages.ts +5 -7
@@ -8,6 +8,22 @@ import { LoopbackCatchEventSchema, LoopbackCatchSchema } from "../schemas/loopba
8
8
  import { OkSchema } from "../schemas/shared.js";
9
9
  import { ProjectDeliveryResultSchema, ProjectDeliverySchema } from "../schemas/project-delivery.js";
10
10
  import { DialLoopbackSchema, StageArtifactResultSchema, StageArtifactSchema } from "../schemas/device-artifacts.js";
11
+ import {
12
+ KeyringCopiesSchema,
13
+ KeyringInboxItemSchema,
14
+ KeyringInboxResultSchema,
15
+ KeyringReleaseResultSchema,
16
+ KeyringSharesSchema,
17
+ KeyringSyncDeliverResultSchema,
18
+ KeyringSyncDeliverSchema,
19
+ KeyringSyncOutboxSchema,
20
+ KeyringSyncPairResultSchema,
21
+ KeyringSyncPairSchema,
22
+ KeyringSyncStateSchema,
23
+ KeyringTypeInputSchema,
24
+ KeyringTypeResultSchema,
25
+ SignedKeyringGrantSchema,
26
+ } from "../schemas/keyring.js";
11
27
 
12
28
  // What a connected device can be asked, over the socket it opened; the machine is the oRPC server, the daemon the
13
29
  // client. No `.route()`: the procedure path is the address, not HTTP. Every input is strict (devices.ts says why). `mcp` stays opaque (`z.unknown()`) so a machine
@@ -46,4 +62,18 @@ export const deviceContract = {
46
62
  // the connection, or throws (nothing listening there, the switch is off). Advertised with `programs`; the machine
47
63
  // allows it when "Run commands" or "Run programs this sandbox sends" is on, either of which already reaches it.
48
64
  dialLoopback: oc.input(DialLoopbackSchema).output(z.object({ ok: z.literal(true) })),
65
+ // The keyring on this computer (schemas/keyring.ts), relayed: the machine passes each call to intentic-keyring over its
66
+ // local pipe and carries the answer back, ciphertext both ways where a value rides. Only the daemon calls these,
67
+ // never a tool, so no turn can reach the keyring by naming a procedure; sent only to an agent advertising `keyring`.
68
+ // `keyringShares` answers for the asking sandbox alone: the machine names it from the link the call came in on.
69
+ keyringShares: oc.output(KeyringSharesSchema),
70
+ keyringRelease: oc.input(SignedKeyringGrantSchema).output(KeyringReleaseResultSchema),
71
+ keyringType: oc.input(KeyringTypeInputSchema).output(KeyringTypeResultSchema),
72
+ keyringInbox: oc.input(KeyringInboxItemSchema).output(KeyringInboxResultSchema),
73
+ keyringCopies: oc.output(KeyringCopiesSchema),
74
+ // Keeping two of the owner's keyrings in step through this sandbox, which carries only what is sealed between them.
75
+ keyringSyncState: oc.output(KeyringSyncStateSchema),
76
+ keyringSyncPair: oc.input(KeyringSyncPairSchema).output(KeyringSyncPairResultSchema),
77
+ keyringSyncOutbox: oc.output(KeyringSyncOutboxSchema),
78
+ keyringSyncDeliver: oc.input(KeyringSyncDeliverSchema).output(KeyringSyncDeliverResultSchema),
49
79
  };
@@ -0,0 +1,19 @@
1
+ import { procedure } from "../protocol/route-meta.js";
2
+ import { OrgPolicyStateSchema } from "../schemas/organisation.js";
3
+
4
+ // The organisation this sandbox belongs to, as the daemon enforces it (docs/architecture/organisations.md). The
5
+ // platform hands the policy over the sandbox's own connect token; this is the editor's read of the copy that decides,
6
+ // so the hub hides and locks what the daemon will refuse rather than what the platform last said. A guest may read it:
7
+ // it names the organisation and which sections are held, nothing about anyone.
8
+ export const orgContract = {
9
+ policy: procedure
10
+ .route({
11
+ method: "GET",
12
+ path: "/org/policy",
13
+ summary: "Which organisation manages this sandbox, and what it holds",
14
+ description:
15
+ "Unbound for a personal sandbox. For one an organisation manages: its policy as this sandbox enforces it, section by section, and when that edition arrived.",
16
+ })
17
+ .meta({ guest: true })
18
+ .output(OrgPolicyStateSchema),
19
+ };
@@ -8,6 +8,8 @@ import {
8
8
  PrivacyKnownSourceSchema,
9
9
  PrivacyKnownValueSchema,
10
10
  PrivacyLedgerEntrySchema,
11
+ PRIVACY_PREVIEW_MAX,
12
+ PrivacyPreviewSchema,
11
13
  PrivacyRevealSchema,
12
14
  PrivacyShieldPolicySchema,
13
15
  PrivacyShieldStatusSchema,
@@ -76,11 +78,21 @@ export const privacyContract = {
76
78
  path: "/privacy/dictionary",
77
79
  summary: "The name lists the shield finds names by",
78
80
  description:
79
- "Every list the dictionary holds (first names, surnames, words that are names only beside other evidence, titles), how many words each has and where they come from. With a query, what the dictionary makes of it as a name, and for one word the listed words starting with it.",
81
+ "Every list the dictionary holds (first names, surnames, words that are names only beside other evidence, titles), the owner's own lists among them, whether each is switched on, how many words each has and where they come from. With a query, what the dictionary as the owner set it makes of it as a name, and for one word the listed words starting with it.",
80
82
  })
81
83
  .meta({ agent: true })
82
84
  .input(z.object({ query: z.string().max(100).optional().describe("A word, the start of one, or a full name.") }))
83
85
  .output(PrivacyDictionarySchema),
86
+ preview: procedure
87
+ .route({
88
+ method: "POST",
89
+ path: "/privacy/preview",
90
+ summary: "Try the shield on a text",
91
+ description:
92
+ "What the shield would mask in the text with the policy as saved (every detector, the name lists, the owner's own rules, the values the vault knows) and what found each. Nothing is given a token or kept, whatever the switch says.",
93
+ })
94
+ .input(z.object({ text: z.string().max(PRIVACY_PREVIEW_MAX) }))
95
+ .output(PrivacyPreviewSchema),
84
96
  sources: procedure
85
97
  .route({
86
98
  method: "GET",
@@ -15,6 +15,14 @@ import {
15
15
  SecretHostGuardSetSchema,
16
16
  SecretHostGuardsSchema,
17
17
  SecretKeysSchema,
18
+ SecretProgramGuardSetResultSchema,
19
+ SecretProgramGuardSetSchema,
20
+ SecretProgramGuardsSchema,
21
+ SecretTypeIntoResultSchema,
22
+ SecretTypeIntoSchema,
23
+ SandboxKeyringPairResultSchema,
24
+ SandboxKeyringPairSchema,
25
+ SandboxKeyringsSchema,
18
26
  SecretRevealSchema,
19
27
  SecretSetSchema,
20
28
  } from "../schemas/secrets.js";
@@ -143,6 +151,62 @@ export const secretsContract = {
143
151
  .meta({ agent: true })
144
152
  .input(SecretHostGuardSetSchema)
145
153
  .output(SecretHostGuardSetResultSchema),
154
+ // The program guard, the host guard's counterpart for typing into windows on the owner's computers (schemas/secrets.ts
155
+ // SecretProgramsSchema): read by the agent so a use aims where it may go; narrowing is anybody's, widening the owner's.
156
+ programs: secretRoute
157
+ .route({
158
+ method: "GET",
159
+ path: "/secrets/programs",
160
+ summary: "Which programs each secret may be typed into",
161
+ description:
162
+ "Every sandbox-held secret whose program list is set: the programs on the owner's computers and the phone apps it goes into unasked. A secret held in a computer's keyring carries its own list, shown on its inventory row. Names and programs only, never values.",
163
+ })
164
+ .meta({ agent: true })
165
+ .output(SecretProgramGuardsSchema),
166
+ setPrograms: secretRoute
167
+ .route({
168
+ method: "PUT",
169
+ path: "/secrets/programs/{subject}",
170
+ summary: "Set which programs a secret may be typed into",
171
+ description:
172
+ "Replaces one sandbox-held secret's program list. Taking programs away, or turning `anyField` off, is open to anybody who may use secrets; adding one is the owner's: from the agent it raises a card for the owner in the live conversation and waits. Refused for a secret a computer's keyring holds, whose list is changed on that computer.",
173
+ })
174
+ .meta({ agent: true })
175
+ .input(SecretProgramGuardSetSchema)
176
+ .output(SecretProgramGuardSetResultSchema),
177
+ // The owner's own Type into…, never the agent's: it types into whatever has focus, which only a person at that
178
+ // computer can aim.
179
+ typeInto: secretRoute
180
+ .route({
181
+ method: "POST",
182
+ path: "/secrets/type-into",
183
+ summary: "Type a secret into the focused window on one of your computers",
184
+ description:
185
+ "After a short countdown, types one secret into whatever has focus on the computer named, through its keyring, which checks the window and still asks there when the entry's share says to. Answers what it went into, never the value.",
186
+ })
187
+ .meta({ panel: false })
188
+ .input(SecretTypeIntoSchema)
189
+ .output(SecretTypeIntoResultSchema),
190
+ keyrings: secretRoute
191
+ .route({
192
+ method: "GET",
193
+ path: "/secrets/keyrings",
194
+ summary: "The keyrings on your computers",
195
+ description:
196
+ "Every connected computer with a keyring this sandbox can reach: whether it answers and is unlocked, how many of its entries are shared here, and whom it is paired with. Names and counts only, never values.",
197
+ })
198
+ .output(SandboxKeyringsSchema),
199
+ keyringPair: secretRoute
200
+ .route({
201
+ method: "POST",
202
+ path: "/secrets/keyrings/pair",
203
+ summary: "Pair the keyrings on two of your computers",
204
+ description:
205
+ "Asks each computer's keyring to pair with the other: each shows a prompt with both fingerprints, and only a yes on both pairs them. After that each keeps the other's entries in step, sealed between them and carried by this sandbox, which cannot open what it carries.",
206
+ })
207
+ .meta({ panel: false })
208
+ .input(SandboxKeyringPairSchema)
209
+ .output(SandboxKeyringPairResultSchema),
146
210
  // The credential gateway's say over one connection: how its credential reaches the agent, and what it may do there.
147
211
  policy: secretRoute
148
212
  .route({
@@ -68,7 +68,9 @@ export const ChildAgentAskSchema = ChildRunSchema.extend({
68
68
  message: z
69
69
  .string()
70
70
  .optional()
71
- .describe("What the parent would say to it: the message it sends, or the answers it gives. Clipped for the request."),
71
+ .describe(
72
+ "What the parent would say to it: the prompt a described start opens on, the message it sends, or the answers it gives. Clipped for the request, with an ellipsis where it was cut.",
73
+ ),
72
74
  on: z.string().optional().describe('Which machine it runs on, when one is named: a runner, or "here" for this sandbox.'),
73
75
  proposed: ChildRunSchema.optional().describe(
74
76
  "What the agent asked to start it on, when the owner started it on something else instead. Present only once the request has settled that way.",
@@ -51,6 +51,15 @@ export const HelloSchema = z.object({
51
51
  workspaceId: z.string(),
52
52
  routes: z.array(z.string()).optional(),
53
53
  shapes: z.record(z.string(), z.string()).optional(),
54
+ // The same two for the hand-written routes (`POST /workspace/upload-diff`), which are half the daemon's surface and
55
+ // used to be advertised nowhere: a call onto a raw route an older daemon predates could only come back as a bare
56
+ // 404. Their own fields rather than more entries in `routes`, which an older browser reads as proof that it is
57
+ // itself the stale side. Absent means a daemon from before this field, and no evidence either way.
58
+ // `rawFingerprints` is what `shapes` is for a procedure, under the name the rest of the code gives it.
59
+ rawRoutes: z.array(z.string()).optional(),
60
+ rawFingerprints: z.record(z.string(), z.string()).optional(),
61
+ // `<version>:<newest mtime of the compiled tree>`, as every release since 1.0.0 sends it. The version at its head
62
+ // is what the browser holds against the oldest daemon it supports (state/daemon-floor.ts), so it stays first.
54
63
  build: z.string().optional(),
55
64
  boot: BootProgressSchema.optional(),
56
65
  // A project sandbox's folder, workspace-relative (`my-app` for /work/my-app): the owner's own folder, synced live
package/src/index.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import { getEventIteratorSchemaDetails, isContractProcedure } from "@orpc/contract";
2
2
  import type { z } from "zod";
3
+ import { RAW_JSON_ROUTES } from "./protocol/raw/raw-json-routes.js";
3
4
  import { RAW_ROUTE_LIST } from "./protocol/raw/raw-routes.js";
4
5
  import type { ContractRoute } from "./protocol/routes.js";
5
- import { contractRoutes, requestPathFor, routeForProcedure, routeNameForRequest, routeShapes, servedRoute } from "./protocol/routes.js";
6
+ import { contractRoutes, rawRouteFingerprintsOf, requestPathFor, routeForProcedure, routeNameForRequest, routeShapes, servedRoute } from "./protocol/routes.js";
6
7
  import { accountsContract } from "./contracts/accounts.contract.js";
7
8
  import { activityContract } from "./contracts/activity.contract.js";
8
9
  import { agentContract } from "./contracts/agent.contract.js";
9
10
  import { agentsContract } from "./contracts/agents.contract.js";
10
11
  import { approvalsContract } from "./contracts/approvals.contract.js";
11
- import { auditContract } from "./contracts/audit.contract.js";
12
12
  import { areasContract } from "./contracts/areas.contract.js";
13
+ import { auditContract } from "./contracts/audit.contract.js";
13
14
  import { automationsContract } from "./contracts/automations.contract.js";
14
15
  import { capabilitiesContract } from "./contracts/capabilities.contract.js";
15
16
  import { choresContract } from "./contracts/chores.contract.js";
@@ -19,7 +20,6 @@ import { diffContract } from "./contracts/diff.contract.js";
19
20
  import { endpointsContract } from "./contracts/endpoints.contract.js";
20
21
  import { exitContract } from "./contracts/exit.contract.js";
21
22
  import { extensionsContract } from "./contracts/extensions.contract.js";
22
- import { personasContract } from "./contracts/personas.contract.js";
23
23
  import { gitContract } from "./contracts/git.contract.js";
24
24
  import { historyContract } from "./contracts/history.contract.js";
25
25
  import { intenticContract } from "./contracts/intentic.contract.js";
@@ -27,17 +27,20 @@ import { inventoryContract } from "./contracts/inventory.contract.js";
27
27
  import { issuesContract } from "./contracts/issues.contract.js";
28
28
  import { logsContract } from "./contracts/logs.contract.js";
29
29
  import { loopsContract } from "./contracts/loops.contract.js";
30
+ import { needsContract } from "./contracts/needs.contract.js";
31
+ import { netdiskContract } from "./contracts/netdisk.contract.js";
32
+ import { offloadContract } from "./contracts/offload.contract.js";
33
+ import { orgContract } from "./contracts/org.contract.js";
30
34
  import { pagesContract } from "./contracts/pages.contract.js";
31
35
  import { panelsContract } from "./contracts/panels.contract.js";
36
+ import { personasContract } from "./contracts/personas.contract.js";
32
37
  import { portsContract } from "./contracts/ports.contract.js";
33
- import { runsContract } from "./contracts/runs.contract.js";
34
- import { publicContract } from "./contracts/public.contract.js";
35
- import { netdiskContract } from "./contracts/netdisk.contract.js";
38
+ import { privacyContract } from "./contracts/privacy.contract.js";
36
39
  import { providersContract } from "./contracts/providers.contract.js";
40
+ import { publicContract } from "./contracts/public.contract.js";
37
41
  import { pushContract } from "./contracts/push.contract.js";
38
- import { privacyContract } from "./contracts/privacy.contract.js";
42
+ import { runsContract } from "./contracts/runs.contract.js";
39
43
  import { safetyContract } from "./contracts/safety.contract.js";
40
- import { needsContract } from "./contracts/needs.contract.js";
41
44
  import { secretsContract } from "./contracts/secrets.contract.js";
42
45
  import { sessionsContract } from "./contracts/sessions.contract.js";
43
46
  import { settingsContract } from "./contracts/settings.contract.js";
@@ -46,267 +49,12 @@ import { skillsContract } from "./contracts/skills.contract.js";
46
49
  import { systemContract } from "./contracts/system.contract.js";
47
50
  import { translatorContract } from "./contracts/translator.contract.js";
48
51
  import { usageContract } from "./contracts/usage.contract.js";
49
- import { offloadContract } from "./contracts/offload.contract.js";
50
52
  import { vpnContract } from "./contracts/vpn.contract.js";
51
53
  import { workflowsContract } from "./contracts/workflows.contract.js";
52
54
  import { workspaceContract } from "./contracts/workspace.contract.js";
53
55
 
54
- export { accountsContract } from "./contracts/accounts.contract.js";
55
- export { activityContract } from "./contracts/activity.contract.js";
56
- export { auditContract } from "./contracts/audit.contract.js";
57
- export { agentContract } from "./contracts/agent.contract.js";
58
- export { agentsContract } from "./contracts/agents.contract.js";
59
- export { approvalsContract } from "./contracts/approvals.contract.js";
60
- export { areasContract } from "./contracts/areas.contract.js";
61
- export { automationsContract } from "./contracts/automations.contract.js";
62
- export { capabilitiesContract } from "./contracts/capabilities.contract.js";
63
- export { choresContract } from "./contracts/chores.contract.js";
64
- export { ciContract } from "./contracts/ci.contract.js";
65
- export { complianceContract } from "./contracts/compliance.contract.js";
66
- export {
67
- endpointsContract,
68
- type HostModelServer,
69
- HostModelServerSchema,
70
- type HostModelServers,
71
- HostModelServersSchema,
72
- LocalModelFitSchema,
73
- type LocalModelFitResponse,
74
- type LocalModelPrefetch,
75
- LocalModelPrefetchSchema,
76
- type TrialHealth,
77
- TrialStatusSchema,
78
- type TrialStatusResponse,
79
- } from "./contracts/endpoints.contract.js";
80
- export { exitContract } from "./contracts/exit.contract.js";
81
- export { extensionsContract } from "./contracts/extensions.contract.js";
82
- export { personasContract } from "./contracts/personas.contract.js";
83
- export { diffContract } from "./contracts/diff.contract.js";
84
- export { gitContract } from "./contracts/git.contract.js";
85
- export { historyContract } from "./contracts/history.contract.js";
86
- // Not part of `sandboxContract` below: spoken over a device's WebSocket, with the machine implementing it.
87
- export { deviceContract } from "./contracts/device.contract.js";
88
- // Same inversion, spoken over a browser extension's socket, with the extension implementing it.
89
- export { webextContract } from "./contracts/webext.contract.js";
90
- // Same inversion, spoken over a phone app's socket as JSON-RPC (protocol/doors/phone-protocol.ts), with the app implementing it.
91
- export { phoneContract } from "./contracts/phone.contract.js";
92
- // Same inversion again: spoken over a runner's WebSocket, with the runner implementing it.
93
- export { runnerContract } from "./contracts/runner.contract.js";
94
- export { intenticContract } from "./contracts/intentic.contract.js";
95
- export { inventoryContract } from "./contracts/inventory.contract.js";
96
- export { issuesContract } from "./contracts/issues.contract.js";
97
- export { logsContract } from "./contracts/logs.contract.js";
98
- export { CONNECT_TOKEN_HEADER, EXTENSION_TOKEN_HEADER, REQUEST_ID_HEADER } from "./protocol/headers.js";
99
- export * from "./protocol/edge-verdict.js";
100
- export * from "./protocol/vitals.js";
101
- export { loopsContract } from "./contracts/loops.contract.js";
102
- export { panelsContract } from "./contracts/panels.contract.js";
103
- export { portsContract } from "./contracts/ports.contract.js";
104
- export { runsContract } from "./contracts/runs.contract.js";
105
- export { pagesContract, PageAppCallResultSchema, PageAppCallSchema, PageErrorsResultSchema, PageErrorsSchema } from "./contracts/pages.contract.js";
106
- export { publicContract } from "./contracts/public.contract.js";
107
- export { providersContract, type RunnableProviders, RunnableProvidersSchema } from "./contracts/providers.contract.js";
108
- export { pushContract } from "./contracts/push.contract.js";
109
- export { privacyContract } from "./contracts/privacy.contract.js";
110
- export { safetyContract } from "./contracts/safety.contract.js";
111
- export { needsContract } from "./contracts/needs.contract.js";
112
- export { secretsContract } from "./contracts/secrets.contract.js";
113
- export { sessionsContract } from "./contracts/sessions.contract.js";
114
- export { settingsContract } from "./contracts/settings.contract.js";
115
- export { shareContract } from "./contracts/share.contract.js";
116
- export { skillsContract } from "./contracts/skills.contract.js";
117
- export { systemContract } from "./contracts/system.contract.js";
118
- export { translatorContract } from "./contracts/translator.contract.js";
119
- export { type PlanLimitsHeld, type PlanLimitsRefreshed, PlanLimitsRefreshedSchema, usageContract } from "./contracts/usage.contract.js";
120
- export { netdiskContract } from "./contracts/netdisk.contract.js";
121
- export { offloadContract } from "./contracts/offload.contract.js";
122
- export { vpnContract } from "./contracts/vpn.contract.js";
123
- export { workflowsContract } from "./contracts/workflows.contract.js";
124
- export { workspaceContract } from "./contracts/workspace.contract.js";
125
- export * from "./events/agent-events.js";
126
- export * from "./events/agent-ui.js";
127
- export * from "./events/agent-words.js";
128
- export * from "./events/requests.js";
129
- export * from "./events/resume.js";
130
- export * from "./events/sandbox-notice.js";
131
- export * from "./events/system-events.js";
132
- export * from "./events/transcript.js";
133
- export * from "./events/land-breakage.js";
134
- export * from "./events/land-conflict.js";
135
- export * from "./events/verify-nudge.js";
136
- export * from "./events/errands.js";
137
- export * from "./events/need-wake.js";
138
- export * from "./events/watch-wake.js";
139
- export * from "./policy/request-status.js";
140
- export * from "./events/child-run.js";
141
- export * from "./policy/turned-away.js";
142
- export * from "./text/mentions.js";
143
- export * from "./text/pages.js";
144
- export * from "./text/transcript-page.js";
145
- export * from "./protocol/sse.js";
146
- export * from "./protocol/routes.js";
147
- export { type ControlReach, defaultFloor, type RouteAccess, type RouteMeta, routeAccess } from "./protocol/route-meta.js";
148
- export { RAW_ROUTE_LIST, RAW_ROUTES, type RawRouteKey, type RawRouteParams, rawRoutePath, rawRouteUrl } from "./protocol/raw/raw-routes.js";
149
- export * from "./protocol/raw/raw-json-routes.js";
150
- export { fillRoutePath, type RoutePathParams } from "./protocol/raw/route-path.js";
151
- export { tunnelBulkRoutes } from "./protocol/tunnel-bulk.js";
152
- export type { SandboxCallInput, SandboxGroup, SandboxHandlerInput, SandboxHandlerOutput, SandboxProcedure } from "./protocol/procedure-types.js";
153
- export * from "./policy/control-scopes.js";
154
56
  // The container's directory layout, re-exported since extensions can't import @intentic/constants directly.
155
57
  export { HISTORY_ROOT, HOST_STATE_ROOT, STATE_DIR, WORKSPACE_ROOT } from "@intentic/constants";
156
- export * from "./state/workspace-state.js";
157
- export * from "./state/runtime-state.js";
158
- export * from "./state/state-portability.js";
159
- export * from "./state/history-state.js";
160
- export * from "./state/fix-stance.js";
161
- export * from "./state/landed-commit.js";
162
- export * from "./state/fix-attempt-plan.js";
163
- // Provider vocabulary bottom-up: agent-runtimes, provider-specs, agent-catalog; three modules since the dependency
164
- // points one way.
165
- export * from "./models/agent-runtimes.js";
166
- export * from "./models/provider-specs.js";
167
- export * from "./models/agent-catalog.js";
168
- export * from "./policy/capability-env.js";
169
- export * from "./policy/command-classes.js";
170
- export * from "./policy/command-run.js";
171
- export * from "./policy/device-programs.js";
172
- export * from "./policy/sandbox-power.js";
173
- export * from "./policy/safety-policy.js";
174
- export * from "./policy/reserved-servers.js";
175
- export * from "./policy/credential-material.js";
176
- export * from "./policy/capability-secrets.js";
177
- export * from "./policy/secret-hosts.js";
178
- export * from "./ids/conversation-ids.js";
179
- export * from "./text/documents.js";
180
- export * from "./protocol/doors/host-protocol.js";
181
- export * from "./protocol/doors/webext-protocol.js";
182
- export * from "./protocol/doors/webext-links.js";
183
- export * from "./protocol/doors/phone-protocol.js";
184
- export * from "./protocol/doors/phone-links.js";
185
- export * from "./protocol/doors/runner-protocol.js";
186
- export * from "./protocol/doors/listener-protocol.js";
187
- export * from "./protocol/container-requirements.js";
188
- export * from "./ids/hostnames.js";
189
- export { SANDBOX_ID } from "./ids/sandbox-id.js";
190
- export * from "./ids/project-dir.js";
191
- export * from "./policy/overlay-lint.js";
192
- export * from "./models/model-label.js";
193
- export * from "./models/model-order.js";
194
- export * from "./models/model-offer.js";
195
- export * from "./models/model-pins.js";
196
- export * from "./models/model-roles.js";
197
- export * from "./models/model-setups.js";
198
- export * from "./models/plan-pools.js";
199
- export * from "./text/path-refs.js";
200
- export * from "./text/archives.js";
201
- export * from "./policy/output-fields.js";
202
- export * from "./policy/approvals-execution.js";
203
- export * from "./policy/message-limits.js";
204
- // Wire shapes, one module per subject area, mirroring `contracts/`; a `{param}` in the route path merges into the same
205
- // flat object, split back into path/body/query. `schemas/internal.ts` is absent: it's vocabulary, not a wire shape.
206
- export * from "./schemas/activity.js";
207
- export * from "./schemas/audit.js";
208
- export * from "./schemas/agent.js";
209
- export * from "./schemas/areas.js";
210
- export * from "./policy/fence-paths.js";
211
- export * from "./policy/persona-home.js";
212
- export * from "./schemas/agents.js";
213
- export * from "./schemas/speaker.js";
214
- export * from "./schemas/speech.js";
215
- export * from "./schemas/voice.js";
216
- export * from "./schemas/approvals.js";
217
- export * from "./schemas/automations.js";
218
- export * from "./schemas/agents-list.js";
219
- export * from "./schemas/capabilities.js";
220
- export * from "./schemas/chat-route.js";
221
- export * from "./schemas/ci.js";
222
- export * from "./schemas/providers/claude-gate.js";
223
- export * from "./schemas/codebase-health.js";
224
- export * from "./schemas/context-trim.js";
225
- export * from "./schemas/devices.js";
226
- export * from "./schemas/device-swaps.js";
227
- export * from "./schemas/intentic-os.js";
228
- export * from "./schemas/project-delivery.js";
229
- export * from "./schemas/device-artifacts.js";
230
- export * from "./schemas/run-targets.js";
231
- export * from "./schemas/engines.js";
232
- export * from "./schemas/environment.js";
233
- export * from "./schemas/exit.js";
234
- export * from "./schemas/extension-updates.js";
235
- export * from "./schemas/providers/fast-mode.js";
236
- export * from "./schemas/diff.js";
237
- export * from "./schemas/git/git.js";
238
- export * from "./schemas/git/git-scope.js";
239
- export * from "./schemas/git/git-history.js";
240
- export * from "./schemas/history.js";
241
- export * from "./schemas/hosts.js";
242
- export * from "./schemas/loopback-catch.js";
243
- export * from "./schemas/peer-enrollment.js";
244
- export * from "./schemas/intentic.js";
245
- export * from "./schemas/inventory.js";
246
- export * from "./schemas/issues.js";
247
- export * from "./schemas/logs.js";
248
- export * from "./schemas/loops.js";
249
- export * from "./schemas/maintenance.js";
250
- export * from "./schemas/marketplace.js";
251
- export * from "./schemas/members.js";
252
- export * from "./schemas/metrics.js";
253
- export * from "./schemas/panels.js";
254
- export * from "./schemas/personas.js";
255
- export * from "./schemas/privacy.js";
256
- export * from "./schemas/providers/plan-limits.js";
257
- export * from "./schemas/providers/handoff.js";
258
- export * from "./schemas/platform-link.js";
259
- export * from "./schemas/project-bring-back.js";
260
- export * from "./schemas/ports.js";
261
- export * from "./schemas/providers/provider-oauth.js";
262
- export * from "./schemas/providers/provider-subscriptions.js";
263
- export * from "./schemas/public.js";
264
- export * from "./schemas/push.js";
265
- export * from "./schemas/git/remote-refs.js";
266
- export * from "./schemas/needs.js";
267
- export * from "./schemas/secrets.js";
268
- export * from "./schemas/netdisk.js";
269
- export * from "./schemas/sessions.js";
270
- export * from "./schemas/settings.js";
271
- export * from "./schemas/data-protection.js";
272
- export * from "./schemas/ai-literacy.js";
273
- export * from "./schemas/compliance.js";
274
- export * from "./schemas/settings-history.js";
275
- export * from "./schemas/share.js";
276
- export * from "./schemas/shared.js";
277
- export * from "./schemas/short-codes.js";
278
- export * from "./schemas/system-prompt.js";
279
- export * from "./schemas/system.js";
280
- export * from "./schemas/state-plan.js";
281
- export * from "./schemas/restart-intent.js";
282
- export * from "./schemas/updates.js";
283
- export * from "./schemas/terminal.js";
284
- export * from "./schemas/turn-break.js";
285
- export * from "./schemas/keep-warm.js";
286
- export * from "./schemas/providers/usage.js";
287
- export * from "./schemas/vpn.js";
288
- export * from "./schemas/offload.js";
289
- export * from "./schemas/webext.js";
290
- export * from "./schemas/phone.js";
291
- export * from "./schemas/workflows.js";
292
- export * from "./schemas/workspace/workspace-graph.js";
293
- export * from "./schemas/workspace/workspace-repos.js";
294
- export * from "./schemas/workspace/workspace-search.js";
295
- export * from "./schemas/workspace/workspace-setup.js";
296
- export * from "./schemas/workspace/workspace-tree.js";
297
- export * from "./schemas/workspace/workspace-upload.js";
298
- export * from "./state/arrival.js";
299
- export * from "./state/definition.js";
300
- export * from "./policy/search-globs.js";
301
- export * from "./state/starter.js";
302
- export * from "./text/title.js";
303
- export * from "./state/update-probation.js";
304
- export * from "./state/versions.js";
305
- export * from "./text/model-answer.js";
306
- export * from "./text/shell-regions.js";
307
- export * from "./text/workflow-faults.js";
308
- export * from "./text/emoji.js";
309
- export * from "./time/zone.js";
310
58
 
311
59
  // The aggregated contract; implemented server-side by per-domain route factories, consumed by the browser's typed oRPC
312
60
  // client. Mounted at the sandbox root, alongside plain Hono routes like /health and /workspace/raw.
@@ -316,8 +64,8 @@ export const sandboxContract = {
316
64
  agent: agentContract,
317
65
  agents: agentsContract,
318
66
  approvals: approvalsContract,
319
- audit: auditContract,
320
67
  areas: areasContract,
68
+ audit: auditContract,
321
69
  automations: automationsContract,
322
70
  capabilities: capabilitiesContract,
323
71
  chores: choresContract,
@@ -325,39 +73,40 @@ export const sandboxContract = {
325
73
  compliance: complianceContract,
326
74
  diff: diffContract,
327
75
  endpoints: endpointsContract,
76
+ exit: exitContract,
328
77
  extensions: extensionsContract,
329
- personas: personasContract,
330
- privacy: privacyContract,
331
- safety: safetyContract,
332
- sessions: sessionsContract,
333
- settings: settingsContract,
334
- share: shareContract,
335
- skills: skillsContract,
336
- intentic: intenticContract,
337
78
  git: gitContract,
338
79
  history: historyContract,
339
- workspace: workspaceContract,
80
+ intentic: intenticContract,
340
81
  inventory: inventoryContract,
341
82
  issues: issuesContract,
342
83
  logs: logsContract,
343
84
  loops: loopsContract,
85
+ needs: needsContract,
86
+ netdisk: netdiskContract,
87
+ offload: offloadContract,
88
+ org: orgContract,
344
89
  pages: pagesContract,
345
90
  panels: panelsContract,
91
+ personas: personasContract,
346
92
  ports: portsContract,
347
- runs: runsContract,
348
- public: publicContract,
93
+ privacy: privacyContract,
349
94
  providers: providersContract,
95
+ public: publicContract,
350
96
  push: pushContract,
351
- needs: needsContract,
97
+ runs: runsContract,
98
+ safety: safetyContract,
352
99
  secrets: secretsContract,
100
+ sessions: sessionsContract,
101
+ settings: settingsContract,
102
+ share: shareContract,
103
+ skills: skillsContract,
353
104
  system: systemContract,
354
105
  translator: translatorContract,
355
106
  usage: usageContract,
356
107
  vpn: vpnContract,
357
- offload: offloadContract,
358
- exit: exitContract,
359
- netdisk: netdiskContract,
360
108
  workflows: workflowsContract,
109
+ workspace: workspaceContract,
361
110
  };
362
111
 
363
112
  // Every route in this build, and the names advertised on the hello frame; bound here, not in routes.ts, to avoid a
@@ -373,6 +122,19 @@ export const SANDBOX_ROUTE_NAMES: readonly string[] = SANDBOX_ROUTES.map((route)
373
122
  let fingerprints: Readonly<Record<string, string>> | undefined;
374
123
  export const sandboxRouteFingerprints = (): Readonly<Record<string, string>> => (fingerprints ??= routeShapes(sandboxContract));
375
124
 
125
+ // The hand-written routes beside the procedures, advertised on their own field of the hello frame rather than mixed
126
+ // into `routes`: a browser older than this build reads an unknown name in `routes` as evidence that IT is the stale
127
+ // side, and every raw name arriving there at once would have had it say so on every connection. Absent, as from every
128
+ // daemon before the field, means no evidence — the same "assume it answers" an unknown route surface gets.
129
+ export const RAW_ROUTE_NAMES: readonly string[] = RAW_ROUTE_LIST.map((route) => route.name);
130
+
131
+ // Each raw JSON route's shape, memoised like the procedures' for the same reason: the walk turns every schema into JSON
132
+ // Schema, which is startup time a browser should only spend when it has a disagreement to explain. The routes that
133
+ // carry no schemas at all (a WebSocket upgrade, a byte stream) are named above but fingerprinted nowhere, and an
134
+ // unfingerprinted route is compared on nothing.
135
+ let rawFingerprints: Readonly<Record<string, string>> | undefined;
136
+ export const rawRouteFingerprints = (): Readonly<Record<string, string>> => (rawFingerprints ??= rawRouteFingerprintsOf(RAW_JSON_ROUTES));
137
+
376
138
  // The contract route a concrete browser request belongs to, bound to this build's route table.
377
139
  export const sandboxRouteName = (method: string, pathWithQuery: string): string | undefined =>
378
140
  routeNameForRequest(SANDBOX_ROUTES, method, pathWithQuery);
@@ -1,4 +1,5 @@
1
1
  import { createPrivateKey, createPublicKey, randomBytes, sign as edSign, verify as edVerify } from "node:crypto";
2
+ import { parseJsonWith } from "@intentic/base/json";
2
3
  import { z } from "zod";
3
4
  import { SANDBOX_ID } from "../ids/tunnel-ids.js";
4
5
 
@@ -92,14 +93,7 @@ const AssertionPayloadSchema = z.object({
92
93
  jti: z.string().min(16),
93
94
  });
94
95
 
95
- const parsePayload = (payload: Buffer): z.infer<typeof AssertionPayloadSchema> | undefined => {
96
- try {
97
- return AssertionPayloadSchema.safeParse(JSON.parse(payload.toString("utf8"))).data;
98
- } catch {
99
- // allow(silent-catch): a payload that is not JSON is an invalid assertion, which undefined is how this says.
100
- return undefined;
101
- }
102
- };
96
+ const parsePayload = (payload: Buffer): z.infer<typeof AssertionPayloadSchema> | undefined => parseJsonWith(payload.toString("utf8"), AssertionPayloadSchema);
103
97
 
104
98
  // Verifies an assertion against the platform's public key at nowMs; undefined for any way of being invalid (wrong
105
99
  // prefix, bad signature, malformed claim, expired, issued in the future, living longer than the daemon allows). The