chainlesschain 0.166.1 → 0.166.3

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 (174) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DwdhBUBc.js → AIOps-DZTvbk_H.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Dd1lBEeo.js → ActionButton-IaEVUN3o.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DuGuuI36.js → Analytics-CCQab0gl.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-CvHpSs3M.js → AppLayout-Bs_0GVpx.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BU9F3wJh.js → Artifacts-Bm83-yJv.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-DK_n_WFm.js → Audit-Bah1XDR5.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-qKsxF5tv.js → BackgroundAgents-BPZA0B5d.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-JS58pSyV.js → Backup-BMydWFiM.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-gGl6Ray1.js → BaseInput-lhopFSZz.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-B2FZNq3U.js → Chat-Bbbs5BP1.js} +5 -5
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZS_bLAr.js → ChatBubbleRenderer-BIAfOKCj.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-tsI0TE22.js → Checkbox-CLEMA9J4.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-D5kqhfAr.js → Codegen-deCSwmnK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DdN1TrqS.js → Col-CH-n8haq.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DgbEeh6V.js → Community-DJuAl6dw.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-FIm-fRB_.js → Compact-BMyLBmgs.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-B-N0pudf.js → Compliance-BK75Ss93.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CuMafBpi.js → Cowork-5XbJwKYq.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-BTwzNFHR.js → Cron-Ezgir7IZ.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DRoYbLOd.js → Crosschain-CKuMoYA7.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-CPhnNkz_.js → DID-CxS244cH.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DJQftix2.js → Dashboard-wrUKrsJy.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-PSAH1Kfy.js → Dropdown-A6I91Z2J.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-PVRqeMiZ.js → EmailListRenderer-BofaiRYY.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CYtnjqjl.js → FamilyGuardDashboard-D3eeNA64.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-_-53kTDz.js → Federation-DzK-3AjS.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-DTQ4qGuE.js → FormItemContext-Dm6mYA8b.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-ON_NfX8k.js → GenericCardRenderer-BeWL-Q1b.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DUc3w_Bf.js → Git-CtGCxg9p.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CktsJ2ku.js → Governance-DZvFB46G.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-4wUHQvju.js → Inference-ntqp4cmw.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-Dq4saPnZ.js → KnowledgeGraph-CrLYbqLe.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-Btb50m5s.js → Logs-CKA1PRhC.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-DtwoKxDJ.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-D3rSncxx.js → Marketplace-B8aPsXYv.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Bc6Mori_.js → McpTools-DQOgNdGS.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-C-ottUdN.js → Memory-i9IK9B0M.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-C0DITBmP.js → MobileBridge-BynYvpv9.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-O6cr0Nal.js → MobileProjects-DixivGuQ.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-B_MXKXvY.js → Mtc-OWPvWVNr.js} +4 -4
  42. package/src/assets/web-panel/assets/{MtcAudit-BDkUqWIT.js → MtcAudit-Cqpg5C4A.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-BaxNWm8c.js → Multisig-CT5kMJIZ.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-UD2GndZc.js → NLProgramming-BXD0Dz0h.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-pU7wtMwB.js → Notes-T1w5p8N5.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-BIs6ULr3.js → NotificationSettings-DFCThpKJ.js} +1 -1
  47. package/src/assets/web-panel/assets/OrderTableRenderer-BJOuM0Kl.js +1 -0
  48. package/src/assets/web-panel/assets/{Organization-C9o-n2lq.js → Organization-CSFcw86q.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-CEvMXxCS.js → Overflow-BxVMuLTk.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-C3gQMTK3.js → P2P-B8qxY_yX.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-D1LVpBOr.js → PdhVaultBrowser-Bcq27Exy.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-Dj5nIi0Y.js → Permissions-CGBvJVXP.js} +3 -3
  53. package/src/assets/web-panel/assets/{PersonalDataHub-uiLYuFcu.js → PersonalDataHub-DM9IEeJ3.js} +6 -6
  54. package/src/assets/web-panel/assets/{Pipeline-CIrmF89x.js → Pipeline-wEskx2-p.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-B3K1CUBa.js → Privacy-DIA02lLJ.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-C_wCZ0zW.js → ProjectInit-uMXlNLHV.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-iCitfuNJ.js → ProjectSettings-Sy3NOtt7.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BwimeXkW.js → Projects-xFjfOkQM.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-BLpepgr6.js → Providers-CNyOpbg8.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-DPy8tjXV.js → QrScannerModal-Dk1UVRwI.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CRq8VhID.js → QuickAsk-B-UqLoLG.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CirlWIiK.js → Recommend-CiTBVZvN.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-nlnJlKXO.js → RemoteSession-BhABd516.js} +3 -3
  64. package/src/assets/web-panel/assets/{Reputation-B5aaxee5.js → Reputation-Dq1xTCcN.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-lzsTQZlq.js → Row-DbFc4sc7.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C41AzjgC.js → RssFeed-D7IBkkLm.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-1Hxx3TZ3.js → Search-BVyMlGoa.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-8VqwRxAp.js → Security-BzMm9Be_.js} +3 -3
  69. package/src/assets/web-panel/assets/{Services-DCm0HHAD.js → Services-Dfk0kied.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-D6w5gpmW.js → Skeleton-C8B5mUit.js} +1 -1
  71. package/src/assets/web-panel/assets/Skills-BNTPoJn0.js +1 -0
  72. package/src/assets/web-panel/assets/{Sla-BkMj8Dxu.js → Sla-gnFelKfT.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-BOmLqW44.js → SpeechSettings-B12gCQkK.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-2xKSqFDO.js → SyncSettings-CHWk9cpj.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-B_zs9jkJ.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-CcOGWgZz.js → Templates-PjdppQrI.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-CAyzzQWN.js → Tenant-CH3aARxE.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-Daagerkm.js → Terminal-BqqrYyg3.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-1jGbMj7I.js → TimelineRenderer-Dx9soq9f.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CYQ-FQju.js → Tokens-C66KpDDZ.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-C70zRwuR.js → Trigger-DHxgGsap.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-CeqXfiX_.js → Trust-3cct4QxN.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-D0j6m1bU.js → UkeySign-Cs6UfDEH.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DFHpM7Yd.js → VideoEditing-jbu2EAQa.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BVC2J0Yx.js → Wallet-BIykFB9D.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-BceIN2Gn.js → WebAuthn-DFgqKmHG.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-Bgeb-i-S.js → WorkflowEditor-CNg5bBiH.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BmMBqgvz.js → chat-B-6wzojE.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-sjRzwnyw.js → colors-BHAq7y9y.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-DNt6m2bM.js → compact-item-CGJnSTnu.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DELaLit3.js → createContext-Cx0ZF512.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-CNq_RRw4.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-dfwk9O8x.js → hasIn-DibIw3z7.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Du62m6pG.js → index-0NWSa3Xq.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-LMfsEdLk.js → index-746-mNhw.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-Cbu3-zFd.js → index-Aaeca8o4.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BXJ68ObJ.js → index-B1jAbIxx.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-B4Z4HZcf.js → index-B28jdxwR.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Bs-mWOWt.js → index-B2rOMBeN.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B0wkOqE9.js → index-BAoFiV3n.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CtfYPnsY.js → index-BCtW4F8-.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CpVt6M_8.js → index-BEXM3qSV.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-1w7dha_a.js → index-BFTGp-aF.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C2Sxf7yC.js → index-BJhS6i02.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-B7qiZc2Z.js → index-BO-XxBD5.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DlYL8VP8.js → index-BR2BiNtx.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-dAF9qRVa.js → index-BRflLAdr.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BMnvNNEd.js → index-BTWb3sbj.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BvIQ9sZa.js → index-BZ7GbrgF.js} +1 -1
  110. package/src/assets/web-panel/assets/index-B_H-RZ9i.js +1 -0
  111. package/src/assets/web-panel/assets/{index-DC6FlHlP.js → index-BiMLsIwd.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-6bjBUhoH.js → index-Bmqjip63.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BSB9Gin8.js → index-BoySHSgZ.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-fNwu9CU_.js → index-Bz3J0eVB.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-dpDeFZNt.js → index-C6M2yHVE.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-WpEDoyTv.js → index-CH2A_Fdn.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CujMHspH.js → index-CUX9mq3M.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DFOYbzg-.js → index-CY2E4Y99.js} +1 -1
  119. package/src/assets/web-panel/assets/index-CkH9UQQL.js +1 -0
  120. package/src/assets/web-panel/assets/{index-CAIn5cS9.js → index-CoKu7Q9r.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-OC3qYV4-.js → index-CrjkH_QU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BzddvOOb.js → index-Cuity3gy.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Rt-fym5b.js → index-CwcWpW1q.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-BLbvXsxf.js → index-Cz5ety6j.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-aj9ObF2R.js → index-DXNcm44v.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-vCQ3l6DX.js → index-DjCJIttz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Clrqtycd.js → index-DnsVRqCa.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DnQOc5wo.js → index-SbQacweG.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CLSqyAcE.js → index-g0V_mLQ9.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DX3wwu3G.js → index-puIs3mTs.js} +3 -3
  131. package/src/assets/web-panel/assets/{index-DY2G1Th2.js → index-sI_1E0co.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DV8q_Hki.js → index-woOjtit-.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-DUt9Xj8y.js → initDefaultProps-Gbl9QOqg.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-DdiFPnv7.js → motion-BHh6ZzZu.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-BJ2VH7Y2.js → move-mX6Rwrd1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BCnX6oOJ.js → mtc-parser-CuzZa_kI.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-CyHxlDLV.js → omit-DjANYkpi.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-BJiGW3bY.js → pickAttrs-C_3v40wY.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-DhJ9Rhx8.js → placementArrow-L2HgRede.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-C6zpL9bC.js → responsiveObserve-DIkGMHyT.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DCbMFRF-.js → slide-C1hp5tD0.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-CNtVLsIq.js → statusUtils-DH1W2uFA.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-Z078OtUc.js → styleChecker-dEaKQcv2.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-w4RVmcGs.js → useFlexGapSupport-CD7j1zxt.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-D4Xw1XRt.js → useFs-C8jXMvEM.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-Bnbd1PgY.js → usePersonalDataHub-C4r-8mys.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DSOQxMFN.js → vnode-DDuI6wgY.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-DNPE1Wca.js → zoom-Dd-DteT6.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/team.js +239 -55
  151. package/src/data/changelog.json +26 -0
  152. package/src/lib/agent-team/task-lease.js +718 -6
  153. package/src/lib/agent-team/team-graph-projection.js +303 -0
  154. package/src/lib/agent-team/team-mailbox.js +508 -2
  155. package/src/lib/agent-team/team-message-bridge.js +722 -0
  156. package/src/lib/agent-team/team-message-tools.js +231 -0
  157. package/src/lib/agent-team/team-runner.js +1186 -10
  158. package/src/lib/agent-team/team-session-message-adapter.js +720 -0
  159. package/src/lib/app-server/cli-agent-kernel-adapter.js +1 -0
  160. package/src/lib/app-server/protocol.js +43 -0
  161. package/src/lib/app-server/server.js +8 -11
  162. package/src/lib/approval-grant-ledger.js +187 -0
  163. package/src/lib/session-message-fabric.js +265 -3
  164. package/src/lib/subagent-inheritance.js +5 -3
  165. package/src/runtime/agent-core.js +38 -0
  166. package/src/runtime/headless-runner.js +36 -3
  167. package/src/runtime/headless-stream.js +184 -19
  168. package/src/assets/web-panel/assets/MarkdownRenderer-Cre8P8HG.js +0 -1
  169. package/src/assets/web-panel/assets/OrderTableRenderer-0NuumnfG.js +0 -1
  170. package/src/assets/web-panel/assets/Skills-Bw_pUTJB.js +0 -1
  171. package/src/assets/web-panel/assets/Tasks-BPAnzVau.js +0 -1
  172. package/src/assets/web-panel/assets/devWarning-Ct8o3bu_.js +0 -1
  173. package/src/assets/web-panel/assets/index-D685kO6L.js +0 -1
  174. package/src/assets/web-panel/assets/index-DTlIRMqX.js +0 -1
@@ -0,0 +1,303 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ export const TEAM_GRAPH_PROJECTION_SCHEMA =
4
+ "chainlesschain.team-graph-projection/v1";
5
+
6
+ const SAFE_IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,159}$/u;
7
+ const CANONICAL_MESSAGE_STATUSES = new Set([
8
+ "admitted",
9
+ "delivered",
10
+ "read",
11
+ "processed",
12
+ "dead_letter",
13
+ ]);
14
+
15
+ function stableValue(value) {
16
+ if (Array.isArray(value)) return value.map(stableValue);
17
+ if (!value || typeof value !== "object") return value;
18
+ return Object.fromEntries(
19
+ Object.keys(value)
20
+ .sort()
21
+ .map((key) => [key, stableValue(value[key])]),
22
+ );
23
+ }
24
+
25
+ function cloneJson(value) {
26
+ return value == null ? value : JSON.parse(JSON.stringify(value));
27
+ }
28
+
29
+ export function teamGraphDigest(value, domain = "cc.team.graph/v1") {
30
+ return `sha256:${createHash("sha256")
31
+ .update(`${domain}\0${JSON.stringify(stableValue(value))}`, "utf8")
32
+ .digest("hex")}`;
33
+ }
34
+
35
+ function safeIdentifier(value, prefix) {
36
+ const candidate = String(value ?? "").trim();
37
+ if (SAFE_IDENTIFIER.test(candidate)) return candidate;
38
+ return `${prefix}:${teamGraphDigest(
39
+ candidate,
40
+ `cc.team.id/${prefix}/v1`,
41
+ ).slice(7)}`;
42
+ }
43
+
44
+ function optionalIdentifier(value, prefix) {
45
+ return value == null || String(value).trim().length === 0
46
+ ? null
47
+ : safeIdentifier(value, prefix);
48
+ }
49
+
50
+ function isoTimestamp(value) {
51
+ const milliseconds = Number(value);
52
+ return new Date(
53
+ Number.isFinite(milliseconds) ? milliseconds : 0,
54
+ ).toISOString();
55
+ }
56
+
57
+ function registryTasks(registry) {
58
+ if (registry && typeof registry.list === "function") return registry.list();
59
+ return Array.isArray(registry) ? registry : [];
60
+ }
61
+
62
+ function declaredTask(task) {
63
+ const metadata = cloneJson(task?.metadata || {});
64
+ for (const key of [
65
+ "lease",
66
+ "custodyHandoffs",
67
+ "attempts",
68
+ "result",
69
+ "lastError",
70
+ "adjudication",
71
+ ]) {
72
+ delete metadata[key];
73
+ }
74
+ return {
75
+ key: task?.key,
76
+ title: task?.title,
77
+ priority: task?.priority || "normal",
78
+ dependsOn: [...(task?.dependsOn || [])].sort(),
79
+ metadata,
80
+ };
81
+ }
82
+
83
+ export function computeTeamGraphRevisionDigest(registry) {
84
+ const tasks = registryTasks(registry)
85
+ .map(declaredTask)
86
+ .sort((left, right) => String(left.key).localeCompare(String(right.key)));
87
+ return teamGraphDigest(
88
+ { schema: "chainlesschain.team-definition/v1", tasks },
89
+ "cc.team.revision/v1",
90
+ );
91
+ }
92
+
93
+ export function computeTeamGraphAuthorityDigest(authority = {}) {
94
+ return teamGraphDigest(
95
+ { schema: "chainlesschain.team-authority/v1", authority },
96
+ "cc.team.authority/v1",
97
+ );
98
+ }
99
+
100
+ function attemptIdentifier(attempt = {}, fallbackHolder = "coordinator") {
101
+ const explicit = attempt?.attemptId || attempt?.id;
102
+ if (explicit) return safeIdentifier(explicit, "team-attempt");
103
+ const binding = {
104
+ holder: attempt?.holder || fallbackHolder,
105
+ taskKey: attempt?.taskKey || null,
106
+ leaseId: attempt?.leaseId || null,
107
+ fencingToken: attempt?.fencingToken ?? attempt?.fromFence ?? null,
108
+ };
109
+ return `team-attempt:${teamGraphDigest(binding, "cc.team.attempt/v1").slice(
110
+ 7,
111
+ )}`;
112
+ }
113
+
114
+ function mailboxSnapshot(mailbox) {
115
+ if (mailbox && typeof mailbox.snapshot === "function") {
116
+ return mailbox.snapshot();
117
+ }
118
+ return mailbox && typeof mailbox === "object" ? cloneJson(mailbox) : {};
119
+ }
120
+
121
+ function canonicalRecipients(message, registeredRecipients) {
122
+ if (message.to !== "*") return [String(message.to)];
123
+ return [...registeredRecipients]
124
+ .filter((recipient) => recipient !== message.from)
125
+ .sort((left, right) => left.localeCompare(right));
126
+ }
127
+
128
+ function canonicalMessageStatus(message, recipient, receipts, delivered) {
129
+ const receipt = receipts.get(`${recipient}\0${message.id}`);
130
+ if (receipt && CANONICAL_MESSAGE_STATUSES.has(receipt.status)) {
131
+ return receipt.status;
132
+ }
133
+ return Number(delivered.get(recipient) || 0) >= Number(message.id)
134
+ ? "delivered"
135
+ : "admitted";
136
+ }
137
+
138
+ function projectMessages(runId, snapshot, extraRecipients = []) {
139
+ const registeredRecipients = new Set([
140
+ ...(snapshot.recipients || []),
141
+ ...extraRecipients,
142
+ ]);
143
+ const receipts = new Map(snapshot.receipts || []);
144
+ const delivered = new Map(snapshot.delivered || []);
145
+ const messages = [...(snapshot.log || [])]
146
+ .sort((left, right) => Number(left.id) - Number(right.id))
147
+ .flatMap((message) =>
148
+ canonicalRecipients(message, registeredRecipients).map((recipient) => {
149
+ const toAgentId = safeIdentifier(recipient, "team-agent");
150
+ const mode = message.mode === "followup" ? "followup" : "send";
151
+ const payload = {
152
+ subject: cloneJson(message.subject ?? null),
153
+ body: cloneJson(message.body ?? null),
154
+ };
155
+ return {
156
+ id: safeIdentifier(
157
+ `team-message:${message.id}:${toAgentId}`,
158
+ "team-message",
159
+ ),
160
+ runId,
161
+ fromAttemptId: attemptIdentifier(
162
+ message.senderAttempt,
163
+ message.from || "coordinator",
164
+ ),
165
+ toAgentId,
166
+ causationId: optionalIdentifier(message.causationId, "causation"),
167
+ correlationId: optionalIdentifier(
168
+ message.correlationId,
169
+ "correlation",
170
+ ),
171
+ mode,
172
+ status: canonicalMessageStatus(
173
+ message,
174
+ recipient,
175
+ receipts,
176
+ delivered,
177
+ ),
178
+ payload,
179
+ payloadDigest: teamGraphDigest(
180
+ {
181
+ toAgentId,
182
+ mode,
183
+ payload,
184
+ causationId: message.causationId ?? null,
185
+ correlationId: message.correlationId ?? null,
186
+ },
187
+ "cc.team.message/v1",
188
+ ),
189
+ dataPolicy: {
190
+ origin: `team-mailbox:${String(message.from || "coordinator").slice(
191
+ 0,
192
+ 220,
193
+ )}`,
194
+ trust: "untrusted_content",
195
+ sensitivity: "internal",
196
+ allowedSinks: [`agent:${toAgentId}`],
197
+ },
198
+ createdAt: isoTimestamp(message.ts),
199
+ };
200
+ }),
201
+ );
202
+ const edges = messages
203
+ .filter((message) => ["read", "processed"].includes(message.status))
204
+ .map((message) => ({
205
+ from: message.fromAttemptId,
206
+ to: `agent:${message.toAgentId}`,
207
+ kind: "model_visible_message",
208
+ messageId: message.id,
209
+ causationId: message.causationId,
210
+ correlationId: message.correlationId,
211
+ status: message.status,
212
+ }));
213
+ return { messages, edges };
214
+ }
215
+
216
+ function projectHandoffs(runId, registry) {
217
+ const handoffs = registryTasks(registry)
218
+ .flatMap((task) =>
219
+ (task?.metadata?.custodyHandoffs || []).map((handoff) => ({
220
+ id: safeIdentifier(handoff.id, "team-handoff"),
221
+ runId,
222
+ nodeId: safeIdentifier(task.key, "team-node"),
223
+ fromAttemptId: attemptIdentifier(
224
+ {
225
+ holder: handoff.fromHolder,
226
+ taskKey: task.key,
227
+ leaseId: handoff.fromLeaseId,
228
+ fencingToken: handoff.fromFence,
229
+ },
230
+ handoff.fromHolder,
231
+ ),
232
+ toAgentId: safeIdentifier(handoff.toHolder, "team-agent"),
233
+ revisionDigest: handoff.revisionDigest,
234
+ authorityDigest: handoff.authorityDigest,
235
+ artifactIds: [...(handoff.artifactIds || [])].map((artifactId) =>
236
+ safeIdentifier(artifactId, "team-artifact"),
237
+ ),
238
+ status: handoff.status,
239
+ expiresAt: isoTimestamp(handoff.expiresAtMs),
240
+ })),
241
+ )
242
+ .sort(
243
+ (left, right) =>
244
+ left.expiresAt.localeCompare(right.expiresAt) ||
245
+ left.id.localeCompare(right.id),
246
+ );
247
+ const edges = handoffs.map((handoff) => ({
248
+ from: handoff.fromAttemptId,
249
+ to: `agent:${handoff.toAgentId}`,
250
+ kind: "custody_handoff",
251
+ handoffId: handoff.id,
252
+ nodeId: handoff.nodeId,
253
+ status: handoff.status,
254
+ }));
255
+ return { handoffs, edges };
256
+ }
257
+
258
+ /**
259
+ * Deterministically project Team's durable mailbox and task custody journal
260
+ * into the canonical protocol Message/Handoff vocabulary. This is read-only:
261
+ * TeamMailbox and TaskLeaseRegistry remain the authoritative writers.
262
+ */
263
+ export function projectTeamGraphCollaboration({
264
+ runId,
265
+ mailbox,
266
+ registry,
267
+ recipients = [],
268
+ revisionDigest = null,
269
+ authorityDigest = null,
270
+ } = {}) {
271
+ const canonicalRunId = safeIdentifier(runId, "team-run");
272
+ const snapshot = mailboxSnapshot(mailbox);
273
+ const messageGraph = projectMessages(canonicalRunId, snapshot, recipients);
274
+ const handoffGraph = projectHandoffs(canonicalRunId, registry);
275
+ const base = {
276
+ schema: TEAM_GRAPH_PROJECTION_SCHEMA,
277
+ runId: canonicalRunId,
278
+ revisionDigest: revisionDigest || computeTeamGraphRevisionDigest(registry),
279
+ authorityDigest:
280
+ authorityDigest || computeTeamGraphAuthorityDigest({ recipients }),
281
+ messageGraph,
282
+ handoffs: handoffGraph.handoffs,
283
+ custodyEdges: handoffGraph.edges,
284
+ };
285
+ const sourceDigest = teamGraphDigest(
286
+ {
287
+ mailbox: snapshot,
288
+ handoffs: registryTasks(registry).map((task) => ({
289
+ key: task.key,
290
+ custodyHandoffs: task?.metadata?.custodyHandoffs || [],
291
+ })),
292
+ },
293
+ "cc.team.projection-source/v1",
294
+ );
295
+ return {
296
+ ...base,
297
+ sourceDigest,
298
+ projectionDigest: teamGraphDigest(
299
+ { ...base, sourceDigest },
300
+ "cc.team.projection/v1",
301
+ ),
302
+ };
303
+ }