chainlesschain 0.165.10 → 0.166.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 (188) hide show
  1. package/completions/_cc +2 -1
  2. package/completions/cc.bash +2 -2
  3. package/completions/cc.fish +2 -2
  4. package/completions/cc.ps1 +2 -1
  5. package/package.json +1 -1
  6. package/src/assets/web-panel/assets/{AIOps-DoxapYEM.js → AIOps-D5_pwQ7M.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-DyiHvT2O.js → ActionButton-DgoYO32D.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-CAX06POB.js → Analytics-BIpoZ4QH.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-JXxcyn0R.js → AppLayout-BJ3XrCEe.js} +5 -5
  10. package/src/assets/web-panel/assets/{Artifacts-40nZDb9N.js → Artifacts-DUFs_izZ.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-B_wc8Kcq.js → Audit-BZdPwwfL.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-CReWOiQY.js → BackgroundAgents-DK9Fn-8B.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-sXrv9fE6.js → Backup-Bd6bOhV_.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-CHWmIERI.js → BaseInput-CRnWlXrd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-DgQrMZCb.js → Chat-D1G_yEl6.js} +6 -6
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Clpgj0fi.js → ChatBubbleRenderer-DDAlEtm-.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-DmRwzt3e.js → Checkbox-CP35SH7R.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-tllAfrrc.js → Codegen-DugeL4pj.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-CA_wqwEp.js → Col-DPuJsvKg.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-DQ_szKAv.js → Community-CZqNjNNp.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-CjkqX60k.js → Compact-eeyIPEAb.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-CfDNkDex.js → Compliance-MGzTw87k.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-PINc6CPv.js → Cowork-D3goVIA5.js} +3 -3
  24. package/src/assets/web-panel/assets/{Cron-snYq4WCj.js → Cron-9HA8hLLG.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-CKR7he4B.js → Crosschain-DCSOX3l6.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-Bp5xJSbE.js → DID-ji3lN5Bc.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-Dn-y6txl.js → Dashboard-DlZvF1E5.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-D0uEeunr.js → Dropdown-2FyZcow9.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-DIhjyeNw.js → EmailListRenderer-qH2bSpSY.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-D2Pv1Hnb.js → FamilyGuardDashboard-Bfx47wZj.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-D6oSp4P4.js → Federation-DhGcZbIv.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-s6bzlfQs.js → FormItemContext-BMgi9_YQ.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-B_NTgGP9.js → GenericCardRenderer-DugMac-4.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-Dk1lCoBr.js → Git-D943BpH-.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-xOnLBQzd.js → Governance-DZ66a8Aa.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-BFVHy-0I.js → Inference-B00Mp2tN.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BXzITB9_.js → KnowledgeGraph-BdwXXO2Q.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BD2M4NPu.js → Logs-_MVXyYWc.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-CDSwkj7Y.js → MarkdownRenderer-hOTeNyi7.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-awpllI_9.js → Marketplace-CxeHRsnO.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-tL0IgbIX.js → McpTools-BOieTxZ4.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-CrptLGSN.js → Memory-BQD26CM3.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DZX-l_BS.js → MobileBridge-CPJ8ZlvR.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-D7qRVu0y.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-dQ5-FjpQ.js → Mtc-BOyndGuk.js} +6 -6
  46. package/src/assets/web-panel/assets/{MtcAudit-U0nDxDlG.js → MtcAudit-CXQ_8ZoR.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-D1PpAtiq.js → Multisig-32Oh9KbH.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-phZr6nyZ.js → NLProgramming-CFAd00CX.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BPzSSUrX.js → Notes-BBCY_qJA.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-AypFEc7p.js → NotificationSettings-uaQ0PdmW.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-S3k1qjT-.js → OrderTableRenderer-kpBxJ-SG.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-BvdQXFPR.js → Organization-CmFn7Oeo.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-CUz_jbQC.js → Overflow-R_avat3a.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-C0xQ7H_2.js → P2P-BIhLFmkY.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DJKMjfB8.js → PdhVaultBrowser-DTJjk-_i.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-dkMtmDwK.js → Permissions-CkzYv8Yb.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-CyHE7fnn.js → PersonalDataHub--0QvN2Nz.js} +5 -5
  58. package/src/assets/web-panel/assets/{Pipeline-_dU0Nwy3.js → Pipeline-Bfw5gQCH.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-fqLyg57f.js → Privacy-DicjKfax.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-COybCr5d.js → ProjectInit-DUl_ykBp.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-B4DngMZW.js → ProjectSettings-CPYDvN8a.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-D0bMwUBm.js → Projects-DnZ9_fAr.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-Ba-7WNA8.js → Providers-BX1jP31w.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-X-I8dDMT.js → QrScannerModal-COab5qUl.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BCUP0a90.js → QuickAsk-CdKQ_JZ0.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DtFNmiQZ.js → Recommend-BPFHg8pK.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-INR5CIAI.js → RemoteSession-CqrfTJvO.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-B6NfaCc6.js → Reputation-DM-l8Pb3.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-Dmz76txh.js → Row-CKGBTeCw.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-B7qyFCea.js → RssFeed-Wb0YHIkc.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-Bi6eS0oY.js → Search-DiBjxKv-.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-D9_xim1L.js → Security-BAVEmbWP.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-PI1O-uYU.js → Services-A_a3TIRn.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-B8BrJnk8.js → Skeleton-CloHJ-I7.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-DvSm92dJ.js → Skills-CkvV5hKa.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BWyhCoRo.js → Sla-BYozxxsV.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-BL9H27jl.js → SpeechSettings-CWianiZF.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-B7r--6yN.js → SyncSettings-BR4G75do.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-sc64p2Jt.js → Tasks-D6gyUVrM.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DEK55RVb.js → Templates-DbfYIRzT.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-DElr8R1l.js → Tenant-BHutvukT.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-BywaLBgz.js → Terminal-CYEiy2wJ.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-B5NcgLyS.js → TimelineRenderer-D9s1AxfE.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-COFYqr6A.js → Tokens-ij9vxnoy.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CfnVS3ij.js → Trigger-Dq_DCVeQ.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-Bz94Gu5k.js → Trust-Bs6wdfoH.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-Be10drSk.js → UkeySign-CLazyr5t.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-CUB_cMem.js → VideoEditing-viWotIHA.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-DxBJJuvG.js → Wallet-DlZ-A78d.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-BZx5lwT8.js → WebAuthn-DSmOND3Y.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-B4sJikPT.js → WorkflowEditor-BempLOJi.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-Wl-95AgM.js → chat-CyJzf4JI.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-DUSwYVCg.js → colors-C62q7WrL.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-DkKRDHcU.js → compact-item-7dYM1KW3.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-B5nAVC_Y.js → createContext-CYTy7z2Q.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BdTg_AMF.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-rtotsRlA.js → hasIn-DHoclUqm.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DUS7KK-i.js → index-2C8Xx2UO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-JWQxvZ4x.js → index-3pI7AfmD.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-03w73yRM.js → index-4gWv-Ubg.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CDWNrtvg.js → index-94ktimZG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CbqotoPt.js → index-9uR7rc9a.js} +1 -1
  103. package/src/assets/web-panel/assets/index-B6WvFV4N.js +1 -0
  104. package/src/assets/web-panel/assets/index-BKgfptzA.js +1 -0
  105. package/src/assets/web-panel/assets/{index-Bj6mJ7tw.js → index-BMRmxFU_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B_KDhTdt.js → index-BMxvWauP.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cv38Cwx0.js → index-BghdJ87W.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DoBh4Ezg.js → index-Bzz0aJ86.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-1J_Q-Ovw.js → index-C2efftJb.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CJWpTdCW.js → index-C5YWYlW9.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BxAMRZR0.js → index-CVTnruDt.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CUqLWyY0.js → index-CW86F2Zw.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-X36Wyd1S.js → index-CZRBvN6i.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D7zQADRc.js → index-CjeViaU-.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-C3lcOYkZ.js → index-CnEZ4ZHj.js} +3 -3
  116. package/src/assets/web-panel/assets/{index-cKc70R9h.js → index-D6BC4mmz.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Ba8raWtd.js → index-DA-_807C.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CN2LNCWW.js → index-DAYanuSk.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-yt994jkW.js → index-DHgSRimK.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-btxpIsXs.js → index-DJzZaPlb.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CAdTY3kv.js → index-DK84lAS0.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DCCTgytM.js → index-DKdv8cju.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C7kGJlSA.js → index-DNLD3nZY.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DupOVIEb.js → index-DOFAwpUK.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CskW4gDB.js → index-DYKwGrAn.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DQhlLyT6.js → index-DghnbMlY.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-INU8TpRu.js → index-DhJjifZe.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CUDraKtq.js → index-DkczsbiP.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BMHNKa11.js → index-DvEtHpLc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CAtnIdx_.js → index-Dyq9tK5u.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-YANfaEyE.js → index-LK1MZoBj.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DfNeBiyO.js → index-NuNCstRO.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-D7Nx-jzS.js → index-QXtrdrub.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Dnbdqjxz.js → index-XrsAHHQN.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-Ch5SqZaK.js → index-ZXYp76IB.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-mwPG3TJQ.js → index-lHfNxiB5.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-Ck8wTHsR.js → initDefaultProps-CwCl5sFQ.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-teBWI8ni.js → motion-BFJFy70N.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BdxzRStQ.js → move-ByrtVGq8.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-DMpcDDsk.js → mtc-parser-BFiH1mT3.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-BwkyHyWr.js → omit-bdvgpivj.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-SlaxZUQd.js → pickAttrs-BlfuuE3s.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BlEZZ3cs.js → placementArrow-t2SC3DMy.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-Cl5uK6S5.js → responsiveObserve-CoEXv2Li.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-LlOJWbeE.js → slide-BfXCf0Fu.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-DxbwIpQR.js → statusUtils-DNsdyOuS.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-G_P9gils.js → styleChecker-9aHukmoG.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-BDS7KDuK.js → useFlexGapSupport-dTkPxzHN.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Xx3R_4Qk.js → useFs-DINwfItP.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-ChOtRWax.js → usePersonalDataHub-Bj_RriBV.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-CAUrMwRC.js → vnode-BzRAZrTc.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-Choqv7b5.js → zoom-CamPjkeK.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +3 -3
  155. package/src/command-manifest.json +1 -1
  156. package/src/commands/agent.js +1 -1
  157. package/src/commands/graph.js +100 -0
  158. package/src/commands/orchestrate.js +85 -18
  159. package/src/commands/serve.js +39 -0
  160. package/src/commands/team.js +2 -0
  161. package/src/data/changelog.json +14 -1
  162. package/src/generated/cc-agent-protocol.schema.json +1964 -0
  163. package/src/lib/app-server/bounded-queue.js +87 -0
  164. package/src/lib/app-server/cli-agent-kernel-adapter.js +309 -0
  165. package/src/lib/app-server/protocol.js +125 -0
  166. package/src/lib/app-server/rollout-store.js +603 -0
  167. package/src/lib/app-server/server.js +922 -0
  168. package/src/lib/app-server/sqlite-rollout-store.js +315 -0
  169. package/src/lib/app-server/stdio-transport.js +118 -0
  170. package/src/lib/codex-app-server-adapter.js +249 -0
  171. package/src/lib/graph-kernel/adapters.js +238 -0
  172. package/src/lib/graph-kernel/compiler.js +911 -0
  173. package/src/lib/graph-kernel/eval.js +207 -0
  174. package/src/lib/graph-kernel/event-store.js +101 -0
  175. package/src/lib/graph-kernel/index.js +7 -0
  176. package/src/lib/graph-kernel/runtime.js +2660 -0
  177. package/src/lib/graph-kernel/trace-reducer.js +315 -0
  178. package/src/lib/graph-kernel/trigger-adapter.js +183 -0
  179. package/src/lib/orchestrator.js +2 -1
  180. package/src/lib/record-replay/index.js +1 -0
  181. package/src/lib/record-replay/skill-recorder.js +386 -0
  182. package/src/lib/webhook-security.js +159 -0
  183. package/src/repl/agent-repl.js +5 -4
  184. package/src/repl/prompt-interactions.js +11 -1
  185. package/src/assets/web-panel/assets/MobileProjects-krNyADYi.js +0 -1
  186. package/src/assets/web-panel/assets/devWarning-DFO12EfA.js +0 -1
  187. package/src/assets/web-panel/assets/index-DaDlUWea.js +0 -1
  188. package/src/assets/web-panel/assets/index-xn89TjWJ.js +0 -1
@@ -0,0 +1,87 @@
1
+ export class QueueOverloadedError extends Error {
2
+ constructor(message, { retryAfterMs = 100, limit, queued } = {}) {
3
+ super(message);
4
+ this.name = "QueueOverloadedError";
5
+ this.code = "CC_APP_SERVER_OVERLOADED";
6
+ this.retryAfterMs = retryAfterMs;
7
+ this.limit = limit;
8
+ this.queued = queued;
9
+ }
10
+ }
11
+
12
+ export class BoundedAsyncQueue {
13
+ constructor({
14
+ maxItems = 256,
15
+ maxBytes = 4 * 1024 * 1024,
16
+ sizeOf = null,
17
+ } = {}) {
18
+ this.maxItems = Math.max(1, Number(maxItems) || 256);
19
+ this.maxBytes = Math.max(1, Number(maxBytes) || 4 * 1024 * 1024);
20
+ this.sizeOf =
21
+ sizeOf || ((value) => Buffer.byteLength(String(value), "utf8"));
22
+ this.items = [];
23
+ this.bytes = 0;
24
+ this.closed = false;
25
+ this.waiters = [];
26
+ }
27
+
28
+ push(value) {
29
+ if (this.closed) throw new Error("bounded queue is closed");
30
+ const bytes = Math.max(0, Number(this.sizeOf(value)) || 0);
31
+ if (
32
+ this.items.length >= this.maxItems ||
33
+ this.bytes + bytes > this.maxBytes
34
+ ) {
35
+ throw new QueueOverloadedError("App Server queue capacity exceeded", {
36
+ limit: this.maxItems,
37
+ queued: this.items.length,
38
+ });
39
+ }
40
+ const waiter = this.waiters.shift();
41
+ if (waiter) {
42
+ waiter.resolve({ value, done: false });
43
+ return;
44
+ }
45
+ this.items.push({ value, bytes });
46
+ this.bytes += bytes;
47
+ }
48
+
49
+ shift() {
50
+ const entry = this.items.shift();
51
+ if (!entry) return undefined;
52
+ this.bytes -= entry.bytes;
53
+ return entry.value;
54
+ }
55
+
56
+ async next() {
57
+ const value = this.shift();
58
+ if (value !== undefined) return { value, done: false };
59
+ if (this.closed) return { value: undefined, done: true };
60
+ return new Promise((resolve, reject) =>
61
+ this.waiters.push({ resolve, reject }),
62
+ );
63
+ }
64
+
65
+ close(error = null) {
66
+ if (this.closed) return;
67
+ this.closed = true;
68
+ for (const waiter of this.waiters.splice(0)) {
69
+ if (error) waiter.reject(error);
70
+ else waiter.resolve({ value: undefined, done: true });
71
+ }
72
+ }
73
+
74
+ snapshot() {
75
+ return Object.freeze({
76
+ queuedItems: this.items.length,
77
+ queuedBytes: this.bytes,
78
+ maxItems: this.maxItems,
79
+ maxBytes: this.maxBytes,
80
+ closed: this.closed,
81
+ });
82
+ }
83
+
84
+ [Symbol.asyncIterator]() {
85
+ return this;
86
+ }
87
+ }
@@ -0,0 +1,309 @@
1
+ import { PassThrough } from "node:stream";
2
+ import { randomUUID } from "node:crypto";
3
+ import {
4
+ assertSandboxAvailable,
5
+ normalizeAgentSandboxMode,
6
+ } from "../agent-sandbox.js";
7
+
8
+ const PERMISSION_MODES = new Set(["default", "manual", "dontAsk", "plan"]);
9
+
10
+ function adapterError(code, message) {
11
+ const error = new Error(message);
12
+ error.name = "CliAgentKernelAdapterError";
13
+ error.code = code;
14
+ return error;
15
+ }
16
+
17
+ function writeLine(input, value) {
18
+ if (input.destroyed || input.writableEnded) {
19
+ throw adapterError(
20
+ "CC_APP_SERVER_AGENT_SESSION_CLOSED",
21
+ "Agent Kernel input stream is closed",
22
+ );
23
+ }
24
+ input.write(`${JSON.stringify(value)}\n`);
25
+ }
26
+
27
+ function approvalBoolean(decision) {
28
+ return ["acceptOnce", "acceptForTurn", "acceptForSession"].includes(
29
+ decision?.kind,
30
+ );
31
+ }
32
+
33
+ function outputCollector(onEvent, onStderr) {
34
+ let stdout = "";
35
+ let stderr = "";
36
+ return {
37
+ writeOut(chunk) {
38
+ stdout += String(chunk);
39
+ for (;;) {
40
+ const index = stdout.indexOf("\n");
41
+ if (index < 0) break;
42
+ const line = stdout.slice(0, index).trim();
43
+ stdout = stdout.slice(index + 1);
44
+ if (!line) continue;
45
+ let event;
46
+ try {
47
+ event = JSON.parse(line);
48
+ } catch {
49
+ event = { type: "raw", subtype: "invalid_json", text: line };
50
+ }
51
+ onEvent(event);
52
+ }
53
+ return true;
54
+ },
55
+ writeErr(chunk) {
56
+ stderr += String(chunk);
57
+ for (;;) {
58
+ const index = stderr.indexOf("\n");
59
+ if (index < 0) break;
60
+ const line = stderr.slice(0, index).trim();
61
+ stderr = stderr.slice(index + 1);
62
+ if (line) onStderr(line);
63
+ }
64
+ return true;
65
+ },
66
+ flush() {
67
+ if (stdout.trim()) {
68
+ try {
69
+ onEvent(JSON.parse(stdout.trim()));
70
+ } catch {
71
+ onEvent({
72
+ type: "raw",
73
+ subtype: "invalid_json",
74
+ text: stdout.trim(),
75
+ });
76
+ }
77
+ }
78
+ if (stderr.trim()) onStderr(stderr.trim());
79
+ stdout = "";
80
+ stderr = "";
81
+ },
82
+ };
83
+ }
84
+
85
+ export class CliAgentKernelAdapter {
86
+ constructor({
87
+ cwd = process.cwd(),
88
+ sandboxMode = "workspace-write",
89
+ sandboxEngine = null,
90
+ allowedPermissionModes = PERMISSION_MODES,
91
+ sessionOptions = {},
92
+ dependencies = {},
93
+ } = {}) {
94
+ this.cwd = cwd;
95
+ this.sandboxMode = sandboxMode;
96
+ this.sandboxEngine = sandboxEngine;
97
+ this.allowedPermissionModes = new Set(allowedPermissionModes);
98
+ this.sessionOptions = { ...sessionOptions };
99
+ this.dependencies = dependencies;
100
+ this.sessions = new Map();
101
+ }
102
+
103
+ async _createSession(threadId, turnOptions = {}) {
104
+ const { runAgentHeadlessStream } =
105
+ await import("../../runtime/headless-stream.js");
106
+ const permissionMode = String(
107
+ turnOptions.permissionMode ||
108
+ this.sessionOptions.permissionMode ||
109
+ "default",
110
+ );
111
+ if (!this.allowedPermissionModes.has(permissionMode)) {
112
+ throw adapterError(
113
+ "CC_APP_SERVER_PERMISSION_MODE_DENIED",
114
+ `permission mode is not allowed by the App Server: ${permissionMode}`,
115
+ );
116
+ }
117
+ const sandbox = normalizeAgentSandboxMode(
118
+ this.sandboxMode,
119
+ this.sandboxEngine || true,
120
+ {
121
+ cwd: this.cwd,
122
+ network: false,
123
+ settings: {
124
+ enabled: true,
125
+ failIfUnavailable: true,
126
+ allowUnsandboxedCommands: false,
127
+ },
128
+ },
129
+ );
130
+ assertSandboxAvailable(sandbox);
131
+
132
+ const input = new PassThrough();
133
+ const session = {
134
+ threadId,
135
+ input,
136
+ current: null,
137
+ eventChain: Promise.resolve(),
138
+ closed: false,
139
+ failure: null,
140
+ runPromise: null,
141
+ collector: null,
142
+ };
143
+ const queueEvent = (event) => {
144
+ const current = session.current;
145
+ session.eventChain = session.eventChain.then(async () => {
146
+ if (!current) return;
147
+ await current.emit(event);
148
+ if (event.type === "approval_request") {
149
+ let decision = {
150
+ kind: "decline",
151
+ reason: "approval host unavailable",
152
+ };
153
+ try {
154
+ decision = await current.requestApproval(event);
155
+ } catch (error) {
156
+ decision = {
157
+ kind: "decline",
158
+ reason: String(error?.message || error).slice(0, 2048),
159
+ };
160
+ }
161
+ writeLine(input, {
162
+ type: "approval",
163
+ id: event.id,
164
+ approve: approvalBoolean(decision),
165
+ binding: event.binding,
166
+ });
167
+ }
168
+ if (event.type === "result") {
169
+ session.current = null;
170
+ current.resolve(event);
171
+ }
172
+ });
173
+ session.eventChain.catch((error) => {
174
+ if (session.current === current) session.current = null;
175
+ current?.reject(error);
176
+ });
177
+ };
178
+ const collector = outputCollector(queueEvent, (line) => {
179
+ const current = session.current;
180
+ if (!current) return;
181
+ queueEvent({ type: "raw", subtype: "stderr", text: line });
182
+ });
183
+ session.collector = collector;
184
+ session.runPromise = runAgentHeadlessStream(
185
+ {
186
+ ...this.sessionOptions,
187
+ model: turnOptions.model || this.sessionOptions.model,
188
+ provider: turnOptions.provider || this.sessionOptions.provider,
189
+ baseUrl: this.sessionOptions.baseUrl,
190
+ apiKey: this.sessionOptions.apiKey,
191
+ sessionId: threadId,
192
+ cwd: this.cwd,
193
+ permissionMode,
194
+ sandbox,
195
+ interactiveApprovals: true,
196
+ includePartialMessages: true,
197
+ ephemeral: false,
198
+ },
199
+ {
200
+ ...this.dependencies,
201
+ input,
202
+ writeOut: collector.writeOut,
203
+ writeErr: collector.writeErr,
204
+ },
205
+ )
206
+ .then(async (outcome) => {
207
+ collector.flush();
208
+ await session.eventChain;
209
+ session.closed = true;
210
+ if (session.current) {
211
+ session.current.reject(
212
+ adapterError(
213
+ "CC_APP_SERVER_AGENT_SESSION_CLOSED",
214
+ "Agent Kernel session closed before the turn completed",
215
+ ),
216
+ );
217
+ session.current = null;
218
+ }
219
+ return outcome;
220
+ })
221
+ .catch((error) => {
222
+ session.failure = error;
223
+ session.closed = true;
224
+ if (session.current) {
225
+ session.current.reject(error);
226
+ session.current = null;
227
+ }
228
+ throw error;
229
+ });
230
+ session.runPromise.catch(() => {});
231
+ this.sessions.set(threadId, session);
232
+ return session;
233
+ }
234
+
235
+ async _session(threadId, options) {
236
+ const existing = this.sessions.get(threadId);
237
+ if (existing && !existing.closed) return existing;
238
+ if (existing?.failure) throw existing.failure;
239
+ return this._createSession(threadId, options);
240
+ }
241
+
242
+ async startTurn({
243
+ threadId,
244
+ turnId,
245
+ input,
246
+ options = {},
247
+ emit,
248
+ requestApproval,
249
+ }) {
250
+ const session = await this._session(threadId, options);
251
+ if (session.current) {
252
+ throw adapterError(
253
+ "CC_APP_SERVER_TURN_ACTIVE",
254
+ `thread already has an active turn: ${threadId}`,
255
+ );
256
+ }
257
+ const prompt = String(input || "").trim();
258
+ if (!prompt) {
259
+ throw adapterError(
260
+ "CC_APP_SERVER_INVALID_INPUT",
261
+ "turn input must contain non-empty text",
262
+ );
263
+ }
264
+ const terminal = new Promise((resolve, reject) => {
265
+ session.current = {
266
+ turnId,
267
+ emit,
268
+ requestApproval,
269
+ resolve,
270
+ reject,
271
+ };
272
+ });
273
+ writeLine(session.input, {
274
+ type: "user",
275
+ text: prompt,
276
+ images: Array.isArray(options.images) ? options.images : undefined,
277
+ });
278
+ return terminal;
279
+ }
280
+
281
+ async interruptTurn(threadId, turnId) {
282
+ const session = this.sessions.get(threadId);
283
+ if (!session?.current || session.current.turnId !== turnId) return false;
284
+ writeLine(session.input, { type: "interrupt" });
285
+ return true;
286
+ }
287
+
288
+ async forkThread(sourceThreadId, requestId = randomUUID()) {
289
+ const { forkSession, sessionExists } =
290
+ await import("../../harness/jsonl-session-store.js");
291
+ if (!sessionExists(sourceThreadId)) return null;
292
+ return forkSession(sourceThreadId, { requestId });
293
+ }
294
+
295
+ async closeThread(threadId) {
296
+ const session = this.sessions.get(threadId);
297
+ if (!session) return false;
298
+ session.input.end();
299
+ await session.runPromise.catch(() => {});
300
+ this.sessions.delete(threadId);
301
+ return true;
302
+ }
303
+
304
+ async close() {
305
+ await Promise.all(
306
+ [...this.sessions.keys()].map((threadId) => this.closeThread(threadId)),
307
+ );
308
+ }
309
+ }
@@ -0,0 +1,125 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { validate } from "../json-schema-validate.js";
3
+
4
+ const schema = JSON.parse(
5
+ readFileSync(
6
+ new URL("../../generated/cc-agent-protocol.schema.json", import.meta.url),
7
+ "utf8",
8
+ ),
9
+ );
10
+
11
+ export const APP_SERVER_PROTOCOL_VERSION = schema["x-cc-protocol"].version;
12
+ export const APP_SERVER_MIN_PROTOCOL_VERSION =
13
+ schema["x-cc-protocol"].minimumCompatibleVersion;
14
+ export const APP_SERVER_FEATURES = Object.freeze([
15
+ ...schema["x-cc-protocol"].features,
16
+ ]);
17
+ export const APP_SERVER_SCHEMA = schema;
18
+
19
+ export const JSON_RPC_ERROR = Object.freeze({
20
+ PARSE_ERROR: -32700,
21
+ INVALID_REQUEST: -32600,
22
+ METHOD_NOT_FOUND: -32601,
23
+ INVALID_PARAMS: -32602,
24
+ INTERNAL_ERROR: -32603,
25
+ OVERLOADED: -32001,
26
+ NOT_INITIALIZED: -32002,
27
+ NOT_FOUND: -32004,
28
+ CONFLICT: -32009,
29
+ INTERRUPTED: -32010,
30
+ });
31
+
32
+ export class JsonRpcError extends Error {
33
+ constructor(code, message, data = null) {
34
+ super(message);
35
+ this.name = "JsonRpcError";
36
+ this.code = code;
37
+ this.data = data;
38
+ }
39
+ }
40
+
41
+ export function validateAppServerMessage(value) {
42
+ const result = validate(value, APP_SERVER_SCHEMA);
43
+ return Object.freeze({
44
+ ok: result.valid,
45
+ errors: Object.freeze(
46
+ result.errors.map((error) =>
47
+ Object.freeze({
48
+ path: error.instancePath || error.schemaPath || "#",
49
+ message: error.message || error.code || "invalid message",
50
+ }),
51
+ ),
52
+ ),
53
+ });
54
+ }
55
+
56
+ export function rpcResult(id, result) {
57
+ return { jsonrpc: "2.0", id, result: result ?? null };
58
+ }
59
+
60
+ export function rpcError(id, error) {
61
+ const code = Number.isInteger(error?.code)
62
+ ? error.code
63
+ : JSON_RPC_ERROR.INTERNAL_ERROR;
64
+ const output = {
65
+ jsonrpc: "2.0",
66
+ id: id ?? null,
67
+ error: {
68
+ code,
69
+ message:
70
+ code === JSON_RPC_ERROR.INTERNAL_ERROR
71
+ ? "Internal App Server error"
72
+ : String(error?.message || "Request failed").slice(0, 4096),
73
+ },
74
+ };
75
+ if (error?.data != null) output.error.data = error.data;
76
+ return output;
77
+ }
78
+
79
+ export function rpcNotification(method, params) {
80
+ return { jsonrpc: "2.0", method, params: params ?? null };
81
+ }
82
+
83
+ export function negotiateProtocol(params = {}) {
84
+ const clientMax = Number(params.protocolVersion);
85
+ const clientMin = Number(params.minimumProtocolVersion);
86
+ if (
87
+ !Number.isSafeInteger(clientMax) ||
88
+ !Number.isSafeInteger(clientMin) ||
89
+ clientMin > clientMax
90
+ ) {
91
+ throw new JsonRpcError(
92
+ JSON_RPC_ERROR.INVALID_PARAMS,
93
+ "initialize requires a valid protocol version range",
94
+ );
95
+ }
96
+ const minimum = Math.max(clientMin, APP_SERVER_MIN_PROTOCOL_VERSION);
97
+ const maximum = Math.min(clientMax, APP_SERVER_PROTOCOL_VERSION);
98
+ if (minimum > maximum) {
99
+ throw new JsonRpcError(
100
+ JSON_RPC_ERROR.INVALID_PARAMS,
101
+ "client and server protocol ranges do not overlap",
102
+ {
103
+ client: { minimum: clientMin, maximum: clientMax },
104
+ server: {
105
+ minimum: APP_SERVER_MIN_PROTOCOL_VERSION,
106
+ maximum: APP_SERVER_PROTOCOL_VERSION,
107
+ },
108
+ },
109
+ );
110
+ }
111
+ const requested = Array.isArray(params.features)
112
+ ? new Set(params.features.map(String))
113
+ : null;
114
+ const features = requested
115
+ ? APP_SERVER_FEATURES.filter((feature) => requested.has(feature))
116
+ : [...APP_SERVER_FEATURES];
117
+ return Object.freeze({
118
+ protocolVersion: maximum,
119
+ minimumProtocolVersion: APP_SERVER_MIN_PROTOCOL_VERSION,
120
+ features: Object.freeze(features),
121
+ downgraded:
122
+ maximum !== APP_SERVER_PROTOCOL_VERSION ||
123
+ features.length !== APP_SERVER_FEATURES.length,
124
+ });
125
+ }