@intentic/sandbox-contract 1.337.0 → 1.339.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 (316) hide show
  1. package/README.md +41 -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 +6020 -5994
  8. package/dist/contracts/agents.contract.d.ts.map +1 -1
  9. package/dist/contracts/agents.contract.js +13 -1
  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/phone.contract.d.ts +1 -0
  31. package/dist/contracts/phone.contract.d.ts.map +1 -1
  32. package/dist/contracts/privacy.contract.d.ts +115 -0
  33. package/dist/contracts/privacy.contract.d.ts.map +1 -1
  34. package/dist/contracts/privacy.contract.js +11 -2
  35. package/dist/contracts/privacy.contract.js.map +1 -1
  36. package/dist/contracts/runner.contract.d.ts +11 -7
  37. package/dist/contracts/runner.contract.d.ts.map +1 -1
  38. package/dist/contracts/secrets.contract.d.ts +85 -0
  39. package/dist/contracts/secrets.contract.d.ts.map +1 -1
  40. package/dist/contracts/secrets.contract.js +48 -1
  41. package/dist/contracts/secrets.contract.js.map +1 -1
  42. package/dist/contracts/sessions.contract.d.ts +4 -1
  43. package/dist/contracts/sessions.contract.d.ts.map +1 -1
  44. package/dist/contracts/settings.contract.d.ts +11 -3
  45. package/dist/contracts/settings.contract.d.ts.map +1 -1
  46. package/dist/contracts/system.contract.d.ts +23 -2
  47. package/dist/contracts/system.contract.d.ts.map +1 -1
  48. package/dist/events/agent-events.d.ts +17 -4
  49. package/dist/events/agent-events.d.ts.map +1 -1
  50. package/dist/events/requests.d.ts +4 -0
  51. package/dist/events/requests.d.ts.map +1 -1
  52. package/dist/events/requests.js +1 -1
  53. package/dist/events/requests.js.map +1 -1
  54. package/dist/events/system-events.d.ts +4 -0
  55. package/dist/events/system-events.d.ts.map +1 -1
  56. package/dist/events/system-events.js +2 -0
  57. package/dist/events/system-events.js.map +1 -1
  58. package/dist/events/transcript.d.ts +27 -6
  59. package/dist/events/transcript.d.ts.map +1 -1
  60. package/dist/index.d.ts +7562 -7426
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +31 -257
  63. package/dist/index.js.map +1 -1
  64. package/dist/models/agent-lanes.d.ts +30 -0
  65. package/dist/models/agent-lanes.d.ts.map +1 -0
  66. package/dist/models/agent-lanes.js +67 -0
  67. package/dist/models/agent-lanes.js.map +1 -0
  68. package/dist/models/agent-standing.d.ts +55 -0
  69. package/dist/models/agent-standing.d.ts.map +1 -0
  70. package/dist/models/agent-standing.js +82 -0
  71. package/dist/models/agent-standing.js.map +1 -0
  72. package/dist/models/agent-starter.d.ts +10 -0
  73. package/dist/models/agent-starter.d.ts.map +1 -0
  74. package/dist/models/agent-starter.js +16 -0
  75. package/dist/models/agent-starter.js.map +1 -0
  76. package/dist/netd/generated/wire.d.ts +1 -1
  77. package/dist/netd/generated/wire.d.ts.map +1 -1
  78. package/dist/policy/identity-assertion.d.ts.map +1 -1
  79. package/dist/policy/identity-assertion.js +2 -8
  80. package/dist/policy/identity-assertion.js.map +1 -1
  81. package/dist/policy/keyring-seal.d.ts +48 -0
  82. package/dist/policy/keyring-seal.d.ts.map +1 -0
  83. package/dist/policy/keyring-seal.js +94 -0
  84. package/dist/policy/keyring-seal.js.map +1 -0
  85. package/dist/policy/message-limits.d.ts +2 -0
  86. package/dist/policy/message-limits.d.ts.map +1 -1
  87. package/dist/policy/message-limits.js +2 -0
  88. package/dist/policy/message-limits.js.map +1 -1
  89. package/dist/policy/org-locks.d.ts +58 -0
  90. package/dist/policy/org-locks.d.ts.map +1 -0
  91. package/dist/policy/org-locks.js +113 -0
  92. package/dist/policy/org-locks.js.map +1 -0
  93. package/dist/policy/persona-capability.d.ts +14 -0
  94. package/dist/policy/persona-capability.d.ts.map +1 -0
  95. package/dist/policy/persona-capability.js +23 -0
  96. package/dist/policy/persona-capability.js.map +1 -0
  97. package/dist/policy/reserved-servers.d.ts.map +1 -1
  98. package/dist/policy/reserved-servers.js +1 -1
  99. package/dist/policy/reserved-servers.js.map +1 -1
  100. package/dist/protocol/doors/phone-links.d.ts +5 -0
  101. package/dist/protocol/doors/phone-links.d.ts.map +1 -1
  102. package/dist/protocol/doors/phone-links.js +3 -1
  103. package/dist/protocol/doors/phone-links.js.map +1 -1
  104. package/dist/protocol/doors/webext-links.d.ts +3 -0
  105. package/dist/protocol/doors/webext-links.d.ts.map +1 -1
  106. package/dist/protocol/doors/webext-links.js +3 -0
  107. package/dist/protocol/doors/webext-links.js.map +1 -1
  108. package/dist/protocol/raw/raw-json-routes.d.ts +270 -0
  109. package/dist/protocol/raw/raw-json-routes.d.ts.map +1 -1
  110. package/dist/protocol/raw/raw-json-routes.js +14 -1
  111. package/dist/protocol/raw/raw-json-routes.js.map +1 -1
  112. package/dist/protocol/raw/raw-routes.d.ts +70 -0
  113. package/dist/protocol/raw/raw-routes.d.ts.map +1 -1
  114. package/dist/protocol/raw/raw-routes.js +18 -0
  115. package/dist/protocol/raw/raw-routes.js.map +1 -1
  116. package/dist/protocol/route-meta.d.ts.map +1 -1
  117. package/dist/protocol/route-meta.js.map +1 -1
  118. package/dist/protocol/routes.d.ts +4 -0
  119. package/dist/protocol/routes.d.ts.map +1 -1
  120. package/dist/protocol/routes.js +12 -0
  121. package/dist/protocol/routes.js.map +1 -1
  122. package/dist/schemas/agents-list.d.ts +5 -0
  123. package/dist/schemas/agents-list.d.ts.map +1 -1
  124. package/dist/schemas/agents-list.js +8 -0
  125. package/dist/schemas/agents-list.js.map +1 -1
  126. package/dist/schemas/agents.d.ts +1 -0
  127. package/dist/schemas/agents.d.ts.map +1 -1
  128. package/dist/schemas/agents.js +1 -0
  129. package/dist/schemas/agents.js.map +1 -1
  130. package/dist/schemas/approvals.d.ts +20 -0
  131. package/dist/schemas/approvals.d.ts.map +1 -1
  132. package/dist/schemas/approvals.js +10 -0
  133. package/dist/schemas/approvals.js.map +1 -1
  134. package/dist/schemas/capabilities.d.ts +26 -0
  135. package/dist/schemas/capabilities.d.ts.map +1 -1
  136. package/dist/schemas/capabilities.js +17 -0
  137. package/dist/schemas/capabilities.js.map +1 -1
  138. package/dist/schemas/data-protection.d.ts +5 -0
  139. package/dist/schemas/data-protection.d.ts.map +1 -1
  140. package/dist/schemas/data-protection.js +29 -0
  141. package/dist/schemas/data-protection.js.map +1 -1
  142. package/dist/schemas/devices.d.ts +20 -0
  143. package/dist/schemas/devices.d.ts.map +1 -1
  144. package/dist/schemas/devices.js +5 -1
  145. package/dist/schemas/devices.js.map +1 -1
  146. package/dist/schemas/extension-updates.d.ts +32 -0
  147. package/dist/schemas/extension-updates.d.ts.map +1 -1
  148. package/dist/schemas/git/git.d.ts +19 -0
  149. package/dist/schemas/git/git.d.ts.map +1 -1
  150. package/dist/schemas/git/git.js +12 -1
  151. package/dist/schemas/git/git.js.map +1 -1
  152. package/dist/schemas/hosts.d.ts +2 -0
  153. package/dist/schemas/hosts.d.ts.map +1 -1
  154. package/dist/schemas/hosts.js +11 -1
  155. package/dist/schemas/hosts.js.map +1 -1
  156. package/dist/schemas/intentic-os.d.ts +218 -0
  157. package/dist/schemas/intentic-os.d.ts.map +1 -1
  158. package/dist/schemas/intentic-os.js +166 -0
  159. package/dist/schemas/intentic-os.js.map +1 -1
  160. package/dist/schemas/keyring.d.ts +421 -0
  161. package/dist/schemas/keyring.d.ts.map +1 -0
  162. package/dist/schemas/keyring.js +176 -0
  163. package/dist/schemas/keyring.js.map +1 -0
  164. package/dist/schemas/links.d.ts +208 -0
  165. package/dist/schemas/links.d.ts.map +1 -0
  166. package/dist/schemas/links.js +116 -0
  167. package/dist/schemas/links.js.map +1 -0
  168. package/dist/schemas/maintenance.d.ts.map +1 -1
  169. package/dist/schemas/maintenance.js.map +1 -1
  170. package/dist/schemas/members.d.ts.map +1 -1
  171. package/dist/schemas/members.js +2 -0
  172. package/dist/schemas/members.js.map +1 -1
  173. package/dist/schemas/needs.d.ts +25 -8
  174. package/dist/schemas/needs.d.ts.map +1 -1
  175. package/dist/schemas/needs.js +15 -3
  176. package/dist/schemas/needs.js.map +1 -1
  177. package/dist/schemas/organisation.d.ts +106 -0
  178. package/dist/schemas/organisation.d.ts.map +1 -0
  179. package/dist/schemas/organisation.js +52 -0
  180. package/dist/schemas/organisation.js.map +1 -0
  181. package/dist/schemas/phone.d.ts +3 -0
  182. package/dist/schemas/phone.d.ts.map +1 -1
  183. package/dist/schemas/phone.js +1 -0
  184. package/dist/schemas/phone.js.map +1 -1
  185. package/dist/schemas/privacy.d.ts +232 -0
  186. package/dist/schemas/privacy.d.ts.map +1 -1
  187. package/dist/schemas/privacy.js +154 -4
  188. package/dist/schemas/privacy.js.map +1 -1
  189. package/dist/schemas/secrets.d.ts +151 -0
  190. package/dist/schemas/secrets.d.ts.map +1 -1
  191. package/dist/schemas/secrets.js +71 -8
  192. package/dist/schemas/secrets.js.map +1 -1
  193. package/dist/schemas/settings.d.ts +8 -0
  194. package/dist/schemas/settings.d.ts.map +1 -1
  195. package/dist/schemas/settings.js +4 -0
  196. package/dist/schemas/settings.js.map +1 -1
  197. package/dist/schemas/speech.d.ts +12 -0
  198. package/dist/schemas/speech.d.ts.map +1 -1
  199. package/dist/schemas/speech.js +23 -0
  200. package/dist/schemas/speech.js.map +1 -1
  201. package/dist/schemas/system.d.ts +2 -0
  202. package/dist/schemas/system.d.ts.map +1 -1
  203. package/dist/schemas/system.js +1 -1
  204. package/dist/schemas/system.js.map +1 -1
  205. package/dist/schemas/terminal.d.ts +15 -0
  206. package/dist/schemas/terminal.d.ts.map +1 -1
  207. package/dist/schemas/terminal.js +11 -2
  208. package/dist/schemas/terminal.js.map +1 -1
  209. package/dist/schemas/voice.d.ts +3 -0
  210. package/dist/schemas/voice.d.ts.map +1 -1
  211. package/dist/schemas/voice.js +7 -0
  212. package/dist/schemas/voice.js.map +1 -1
  213. package/dist/schemas/webext.d.ts +17 -0
  214. package/dist/schemas/webext.d.ts.map +1 -1
  215. package/dist/schemas/webext.js +7 -1
  216. package/dist/schemas/webext.js.map +1 -1
  217. package/dist/state/contract-lock.d.ts +3 -1
  218. package/dist/state/contract-lock.d.ts.map +1 -1
  219. package/dist/state/contract-lock.js +34 -9
  220. package/dist/state/contract-lock.js.map +1 -1
  221. package/dist/state/contract-modules.d.ts +4 -0
  222. package/dist/state/contract-modules.d.ts.map +1 -0
  223. package/dist/state/contract-modules.js +28 -0
  224. package/dist/state/contract-modules.js.map +1 -0
  225. package/dist/state/daemon-floor.d.ts +4 -0
  226. package/dist/state/daemon-floor.d.ts.map +1 -0
  227. package/dist/state/daemon-floor.js +8 -0
  228. package/dist/state/daemon-floor.js.map +1 -0
  229. package/dist/state/definition.d.ts +34 -0
  230. package/dist/state/definition.d.ts.map +1 -1
  231. package/dist/state/history-state.d.ts.map +1 -1
  232. package/dist/state/history-state.js +8 -0
  233. package/dist/state/history-state.js.map +1 -1
  234. package/dist/text/documents.d.ts +3 -1
  235. package/dist/text/documents.d.ts.map +1 -1
  236. package/dist/text/documents.js +30 -0
  237. package/dist/text/documents.js.map +1 -1
  238. package/dist/text/pages.d.ts.map +1 -1
  239. package/dist/text/pages.js +3 -7
  240. package/dist/text/pages.js.map +1 -1
  241. package/package.json +27 -5
  242. package/src/chores/probes.ts +4 -6
  243. package/src/contracts/agents.contract.ts +18 -1
  244. package/src/contracts/capabilities.contract.ts +14 -0
  245. package/src/contracts/device.contract.ts +30 -0
  246. package/src/contracts/org.contract.ts +19 -0
  247. package/src/contracts/privacy.contract.ts +13 -1
  248. package/src/contracts/secrets.contract.ts +64 -0
  249. package/src/events/requests.ts +3 -1
  250. package/src/events/system-events.ts +9 -0
  251. package/src/index.ts +41 -279
  252. package/src/models/agent-lanes.ts +152 -0
  253. package/src/models/agent-standing.ts +279 -0
  254. package/src/models/agent-starter.ts +26 -0
  255. package/src/netd/generated/netd-wire.json +2 -1
  256. package/src/netd/generated/wire.ts +1 -1
  257. package/src/policy/identity-assertion.ts +2 -8
  258. package/src/policy/keyring-seal.test.ts +93 -0
  259. package/src/policy/keyring-seal.ts +148 -0
  260. package/src/policy/message-limits.ts +3 -0
  261. package/src/policy/org-locks.ts +173 -0
  262. package/src/policy/persona-capability.ts +57 -0
  263. package/src/policy/reserved-servers.ts +3 -2
  264. package/src/policy/tests/org-locks.test.ts +92 -0
  265. package/src/policy/tests/reserved-servers.test.ts +3 -2
  266. package/src/protocol/doors/listener-protocol.ts +1 -1
  267. package/src/protocol/doors/phone-links.ts +11 -2
  268. package/src/protocol/doors/phone-protocol.test.ts +8 -1
  269. package/src/protocol/doors/webext-links.ts +13 -0
  270. package/src/protocol/ingress-contract.fixture.json +2 -0
  271. package/src/protocol/pairing-redeem.ts +1 -1
  272. package/src/protocol/peer-dial.test.ts +6 -6
  273. package/src/protocol/peer-mcp-server.test.ts +2 -1
  274. package/src/protocol/raw/raw-json-routes.ts +31 -1
  275. package/src/protocol/raw/raw-routes.ts +35 -1
  276. package/src/protocol/route-meta.ts +2 -1
  277. package/src/protocol/routes.test.ts +33 -1
  278. package/src/protocol/routes.ts +18 -0
  279. package/src/protocol/sse.ts +1 -1
  280. package/src/schemas/agent.ts +1 -1
  281. package/src/schemas/agents-list.ts +13 -0
  282. package/src/schemas/agents.ts +1 -0
  283. package/src/schemas/approvals.ts +14 -0
  284. package/src/schemas/capabilities.ts +25 -0
  285. package/src/schemas/data-protection.ts +47 -0
  286. package/src/schemas/devices.ts +15 -1
  287. package/src/schemas/git/git.ts +22 -2
  288. package/src/schemas/hosts.ts +14 -1
  289. package/src/schemas/intentic-os.test.ts +148 -0
  290. package/src/schemas/intentic-os.ts +259 -0
  291. package/src/schemas/keyring.ts +277 -0
  292. package/src/schemas/links.ts +180 -0
  293. package/src/schemas/maintenance.ts +1 -0
  294. package/src/schemas/members.ts +4 -0
  295. package/src/schemas/needs.ts +21 -5
  296. package/src/schemas/organisation.ts +110 -0
  297. package/src/schemas/phone.ts +3 -0
  298. package/src/schemas/privacy.test.ts +63 -0
  299. package/src/schemas/privacy.ts +213 -5
  300. package/src/schemas/secrets.ts +96 -8
  301. package/src/schemas/settings.ts +8 -0
  302. package/src/schemas/speech.ts +38 -1
  303. package/src/schemas/system.ts +5 -2
  304. package/src/schemas/terminal.ts +13 -2
  305. package/src/schemas/voice.ts +11 -0
  306. package/src/schemas/webext.ts +16 -1
  307. package/src/state/contract-lock.test.ts +12 -12
  308. package/src/state/contract-lock.ts +43 -12
  309. package/src/state/contract-modules.ts +41 -0
  310. package/src/state/daemon-floor.test.ts +81 -0
  311. package/src/state/daemon-floor.ts +32 -0
  312. package/src/state/history-state.ts +17 -0
  313. package/src/state/workspace-state.ts +1 -1
  314. package/src/text/documents.test.ts +30 -1
  315. package/src/text/documents.ts +43 -1
  316. package/src/text/pages.ts +5 -7
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);
@@ -0,0 +1,152 @@
1
+ import type { AgentAttention } from "../schemas/agents.js";
2
+ import type { AutomationApproval } from "../schemas/automations.js";
3
+ import { parentOf } from "./agent-starter.js";
4
+ import {
5
+ type AgentStanding,
6
+ blocked,
7
+ heardByParent,
8
+ limitScheduled,
9
+ onlyOwnerCanAnswer,
10
+ scheduledSend,
11
+ turnInFlight,
12
+ turnWorking,
13
+ watching,
14
+ } from "./agent-standing.js";
15
+
16
+ // The lane every surface files a conversation in, and what of a fleet calls the person. Moved here from the editor
17
+ // (_editor/web/src/models/agent-status/agentStatus-lanes.ts, which re-exports it) on 2026-10-16, so the daemon's
18
+ // `agents.attention` (what the desktop app's status bar and `ic sandbox attention` read) counts by the board's own rules.
19
+
20
+ // Whether what a child agent stopped on is the reader's to answer rather than its parent's, given the lanes both stand
21
+ // in and when the parent last moved. An ask only the owner can answer always is; anything else it stopped on (a spent
22
+ // allowance, a failure, a stop, a question, a land conflict) is its parent's news while the parent supervises, and the
23
+ // reader's once it no longer does: nothing running there to hear it and nothing armed to wake it, which is a parent out
24
+ // of Active. That holds only until the parent moves past it (heardByParent). After that the stop is the family's
25
+ // history, drawn in the tray, and no longer something the reader owes a press. The sandbox draws the same line for a
26
+ // child's land news (subagents/child-lands.ts): the parent's while it has a live turn, the owner's after.
27
+ export const callsOwner = (
28
+ child: AgentStanding & { readonly updatedAt: number },
29
+ family: { readonly child: FleetLane; readonly parent: FleetLane; readonly parentAt: number },
30
+ ): boolean => onlyOwnerCanAnswer(child) || (family.child === "attention" && family.parent !== "active" && !heardByParent(child, family.parentAt));
31
+
32
+ export type FleetLane = "attention" | "active" | "finished";
33
+
34
+ // Nothing owed to the user. The one "no attention" block in the app: a client-only card has no daemon account of
35
+ // what a turn asked, and two copies of this would let two surfaces place the same conversation differently.
36
+ export const NO_ATTENTION: AgentAttention = {
37
+ plan: false,
38
+ question: false,
39
+ permission: false,
40
+ capability: false,
41
+ credential: false,
42
+ conflict: false,
43
+ };
44
+
45
+ // The lane projection every surface must agree with (see the header). Pure reading of the state machine:
46
+ // "finished" needs no explicit timer since auto-land already flips a cleanly-completed turn to landed/idle within
47
+ // ms, and any follow-up message moves the card back to active. Unread stays a badge, not a lane.
48
+ export const laneOf = (agent: AgentStanding): FleetLane => {
49
+ // A spent allowance nothing is booked for reaches Attention through `blocked` alone, no branch of its own, and ahead
50
+ // of the `watching` branch below: a watch is the agent's own plan for waiting, a spent allowance an obstacle in
51
+ // the way of it, and a watch firing into a shut window runs nothing (turn-admission.ts holds its words back).
52
+ if (blocked(agent) || agent.status === "awaiting" || agent.status === "conflict") {
53
+ return "attention";
54
+ }
55
+ // Settled from the press, ahead of the in-flight check below, rather than routed through Active: a waved-away turn
56
+ // is one the user is already done with (unlike `stopping`, which rests in Attention), and a land spends no model at
57
+ // all. Active means a turn in progress, so a land must end in the lane it was pressed in.
58
+ if (agent.status === "dismissing" || agent.status === "landing") {
59
+ return "finished";
60
+ }
61
+ // `resuming` is why in-flight must outrank the settled readings below: without this order the card would drop
62
+ // into Finished for the seconds a credential takes to re-mint, then climb back out.
63
+ if (turnInFlight(agent) || agent.status === "draft") {
64
+ return "active";
65
+ }
66
+ // An armed watch is Active, not Finished: nothing is running, but the conversation restarts itself later, and
67
+ // filing it Finished would announce as over work that resumes at 3am. Active rather than Attention since nothing
68
+ // is owed by the user. Checked after the in-flight readings: an agent that armed a watch and is now running again
69
+ // is running.
70
+ if (watching(agent)) {
71
+ return "active";
72
+ }
73
+ // A stranded turn booked to go again is Active: at the reset, or on the resume pass's next beat for a move to another
74
+ // account. Reached only because `blocked` let it through; stated explicitly or the card would fall through to
75
+ // Finished, which would announce as over work that resumes by itself.
76
+ if (limitScheduled(agent)) {
77
+ return "active";
78
+ }
79
+ // Messages booked for later are the same: the conversation starts again by itself, at a time or once the agent it
80
+ // waits for has landed, so filing it Finished would announce as done work that has not started yet.
81
+ if (scheduledSend(agent)) {
82
+ return "active";
83
+ }
84
+ // `landed`/`idle`/`ready` all finish here: `ready` is work held on the branch because auto-land is off, still
85
+ // finished rather than attention since nothing is failing. `resumed` lands here too: nothing running, nothing
86
+ // owed.
87
+ return "finished";
88
+ };
89
+
90
+ // How many cards the board's Attention lane draws for one fleet, as the board folds child agents under their parents
91
+ // (models/fleet/board/childFold.ts): an agent in Attention is a card of its own, except a child agent whose parent is in the
92
+ // fleet, which rides under its family's one card and lifts that card to Attention only when it calls the reader
93
+ // (callsOwner). A family counts once however many of its children call, and not again when its own card is in
94
+ // Attention already; a child with words left in its composer keeps a card of its own, as on the board. The rail
95
+ // badge's count, for this sandbox's fleet and another's alike, so the badge cannot disagree with the lane it names.
96
+ export const attentionCards = (agents: readonly CallerStanding[]): number => new Set(attentionCalls(agents).map((call) => call.card)).size;
97
+
98
+ // Enough of a fleet's agent to say whether it calls the reader, and through which card.
99
+ export type CallerStanding = AgentStanding & {
100
+ readonly id: string;
101
+ readonly updatedAt: number;
102
+ readonly startedBy?: string | undefined;
103
+ readonly unsent?: boolean | undefined;
104
+ };
105
+
106
+ // Every agent calling the reader, each with the card it is drawn on: its own, or its family's where it rides one. The
107
+ // count above is the cards; the browser tab's chime wants the callers, so a second child calling under a family already
108
+ // in Attention is news although the lane's count does not move.
109
+ export const attentionCalls = (agents: readonly CallerStanding[]): readonly { readonly id: string; readonly card: string }[] => {
110
+ type Standing = (typeof agents)[number];
111
+ const byId = new Map(agents.map((agent) => [agent.id, agent] as const));
112
+ const parentIn = (agent: Standing): Standing | undefined => {
113
+ const id = parentOf(agent.startedBy);
114
+ return id === undefined ? undefined : byId.get(id);
115
+ };
116
+ // The card a child rides under: its eldest ancestor in this fleet, walked with a guard against a record naming its
117
+ // own descendant as its parent.
118
+ const familyOf = (agent: Standing): string => {
119
+ const seen = new Set([agent.id]);
120
+ let top = agent;
121
+ for (let above = parentIn(top); above !== undefined && !seen.has(above.id); above = parentIn(top)) {
122
+ seen.add(above.id);
123
+ top = above;
124
+ }
125
+ return top.id;
126
+ };
127
+ const calls: { readonly id: string; readonly card: string }[] = [];
128
+ for (const agent of agents) {
129
+ const parent = parentIn(agent);
130
+ if (parent === undefined || agent.unsent === true) {
131
+ if (laneOf(agent) === "attention") {
132
+ calls.push({ id: agent.id, card: agent.id });
133
+ }
134
+ } else if (callsOwner(agent, { child: laneOf(agent), parent: laneOf(parent), parentAt: parent.updatedAt })) {
135
+ calls.push({ id: agent.id, card: familyOf(agent) });
136
+ }
137
+ }
138
+ return calls;
139
+ };
140
+
141
+ // What one fleet owes the person and how much of it is under way, as the desktop app's status bar and the sandbox
142
+ // switcher count it: the Attention lane's cards as the board draws them (attentionCards) plus held automation wakes,
143
+ // which lead that lane with no card of their own; and the turns producing something right now (turnWorking).
144
+ export interface FleetAttention {
145
+ readonly needsYou: number;
146
+ readonly working: number;
147
+ }
148
+
149
+ export const fleetAttention = (agents: readonly CallerStanding[], held: readonly Pick<AutomationApproval, "id">[]): FleetAttention => ({
150
+ needsYou: attentionCards(agents) + held.length,
151
+ working: agents.filter(turnWorking).length,
152
+ });