chainlesschain 0.166.46 → 0.166.48

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 (232) hide show
  1. package/README.md +6 -4
  2. package/package.json +4 -2
  3. package/src/assets/web-panel/assets/{AIOps-Cp8KiMmv.js → AIOps-BLGEffkh.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-B4d9BGsm.js → ActionButton-Cz1z2VGD.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-Cf9yXTkv.js → Analytics-C3j9cf6q.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-40UkmxtP.js → AppLayout-BR9ERuCA.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-Ckkb4oOA.js → Artifacts-CozJCm4y.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-Dnf569k5.js → Audit-DC5g9Ra2.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-CA6bLem4.js → BackgroundAgents-B1zrQ0dW.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-ChQU0I_Q.js → Backup-ChVnfjpm.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-BHeZXnNN.js → BaseInput-8_vLQsLf.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DcFVYB2E.js → Chat-Dct9bm6L.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-BvoSsCKh.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-2PDbejv2.js → Checkbox-DZQIsCIC.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-DJBn1RAu.js → Codegen-CdzHxmnq.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CPRq7n6y.js → Col-DdAN8LeW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-axvINFMi.js → Community-CNgjT9MA.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-_OX4Qbe0.js → Compact-BtQiX6G-.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-DWAkvzRL.js → Compliance-OGX5ma3j.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CUIJ25oj.js → Cowork-CgugQnGM.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-nR0m7H3_.js → Cron-Bpg7cPFD.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CgTLXzh_.js → Crosschain-D1hsuswf.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-BllzRB6Q.js → DID-miDRsMBw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C9f0IIBN.js → Dashboard-CGcl8htP.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BkahetiO.js → Dropdown-BFaxTdVE.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-rartVC-k.js → EmailListRenderer-BQdGLZIO.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-BqpG3XHV.js → EvolutionSettings-bMvgBk6r.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DgUdFvw1.js → FamilyGuardDashboard-c1WVC_--.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-oFpIQU6g.js → Federation-DyAcFrQY.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-BUH5xlyP.js → FormItemContext-CfwpfD2B.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-ilRa-ueg.js → GenericCardRenderer-DkJcbBpS.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-DlHHSF8j.js → Git-DgYIrPJh.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-yQiiXIWe.js → Governance-BF1tYPJ6.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-BUDRVGOP.js → Inference-BFkwRIrU.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-BaGyIoN1.js → KnowledgeGraph-DpCoqhBa.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-C1cO6zE0.js → Logs-DU2qAJmD.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-_z_Iaoes.js → MarkdownRenderer-QWv7UJLq.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-CM8cGL0K.js → Marketplace-Dz9NUrfo.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-CDqAMU0U.js → McpTools-B67I3d5v.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-CfB0-Ofv.js → Memory-crkElJSy.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-BL18ytvB.js → MobileBridge-BO20VbdX.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-PIyyxbuJ.js → MobileProjects-Ba-3gZZd.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-BTTrFCol.js → Mtc-BAHZM084.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-JHZn037c.js → MtcAudit-CL3DzajL.js} +4 -4
  45. package/src/assets/web-panel/assets/{Multisig-CMf9NEdB.js → Multisig-BSWWzvWH.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-Dhk3qaus.js → NLProgramming-fnxqXM_3.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-6F8EarNN.js → Notes-qUZPIQXT.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-gxdaVEit.js → NotificationSettings-x9Xrixqu.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-gVgXQWdc.js → OrderTableRenderer-BtMtQUt7.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-CzvHcDNO.js → Organization-C946Hzna.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-Dclx30Vv.js → Overflow-BYf8KIts.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-CM0Wm9vZ.js → P2P-Cbqf5dnv.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-rmxp0cuF.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-B_oATenG.js → Permissions-CZBw45EW.js} +3 -3
  55. package/src/assets/web-panel/assets/{PersonalDataHub-CptiVBh5.js → PersonalDataHub-BKwUAt43.js} +4 -4
  56. package/src/assets/web-panel/assets/{Pipeline-DkHzgyyI.js → Pipeline-DmFD2QW4.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-DzZvwcKh.js → Privacy-KpuwWvt5.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-CzkCs-5G.js → ProjectInit-Bt8UheX6.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-BB8dcxRD.js → ProjectSettings-2ZeAn9CP.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-B7PW9CFY.js → Projects-zBuet8Zs.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-Tfx-ti1V.js → Providers-DcEAnw6L.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-EvWlNhfX.js → QrScannerModal-qF7liYG9.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-CUspgbNC.js → QuickAsk-qiESlVBJ.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-COY2g77J.js → Recommend-Bk-cQyi9.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-BzMBU6E6.js → RemoteSession-CwrekErS.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-RtYRF4YP.js → Reputation-Bmw_UQtW.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-Bva3l9Lc.js → Row-CPdqZIUX.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-BhjzLvW3.js → RssFeed-D_W-xxvS.js} +2 -2
  69. package/src/assets/web-panel/assets/{Search-BYzT2PTR.js → Search-Hu0oDFj_.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-Bcl4-KTv.js → Security-DeRxUwmq.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-BRRa4A0f.js → Services-CsNmHFkf.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-DYQ016qy.js → Skeleton-gv_Vz0tN.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CAUKL9JA.js → Skills-Dgg-_rCB.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-BTyUqfuD.js → Sla-Bpu-bsEJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-CUjMihrs.js → SpeechSettings-CrhleHuF.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-CvfOSupr.js → SyncSettings-JHjUN6I9.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-EvjNXrWH.js → Tasks-DKRWKkl9.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-wPAp0EoM.js → Templates-leiWntLq.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-CP0D-q9Q.js → Tenant--1bYulvn.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-CQ0f2iFg.js → Terminal-C0y6FvSS.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-D3JrGSPb.js → TimelineRenderer-CQK4PVv4.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-yXf2PPp9.js → Tokens-DbIvF-DV.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-DfmMOoZ2.js → Trigger-CkXJ2vuq.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-BTCyMgf1.js → Trust-B02WXJPw.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-DKCwIBHi.js → UkeySign-VPMkfzmw.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-CQpDSzLO.js → VideoEditing-C5ezUnah.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-CyFrzC3K.js → Wallet-CYfvYRrY.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-D6Nr_1kd.js → WebAuthn-DtKl-kpr.js} +4 -4
  89. package/src/assets/web-panel/assets/{WorkflowEditor-CgR9tNrB.js → WorkflowEditor-DACITF-u.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-CRG_IeyP.js → chat-qnygfnLi.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-MdE3TStI.js → colors-D4mISLBD.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-B0LRuiNV.js → compact-item-BBPfxYGL.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-B_V5fjcX.js → createContext-Byx4ndHp.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-DBy6gsuI.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-DSL-c_hr.js → hasIn-CGjLkkn3.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DE7bSYmW.js → index-B8UpadHC.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BD0w-888.js → index-B9jH-h4X.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BbZZ7P_c.js → index-BN7_TSgU.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BIDCNwy6.js → index-BNe2lCk6.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CkN53KiJ.js → index-B_fHPZ8E.js} +1 -1
  101. package/src/assets/web-panel/assets/index-BfEDXk_E.js +1 -0
  102. package/src/assets/web-panel/assets/{index-BsAEd-Do.js → index-BklGH3YI.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CS3bOhV7.js → index-BmKYaaGP.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B3iW-mhn.js → index-BxQF1wCU.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-SmQfEHjp.js → index-ByA1NyFP.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-0200QxC4.js → index-BzeBBAl5.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-c8OqO3rq.js → index-C3abGsSW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C-aKWR2v.js → index-C9tcHs46.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BNhWoD6d.js → index-CD5Btq6p.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CVDi4rS9.js → index-CFMWjuav.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CEOAZm5j.js → index-CMj8qmpX.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C67dPW0L.js → index-CVUJjQAT.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-D3pJBTvo.js → index-CWhI8G14.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DtOTppk8.js → index-CZjNamSU.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DRRY44XP.js → index-CmHE-lY_.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Tg3yl8wc.js → index-CoA8WsVr.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CXMeisJK.js → index-Cpg3AWRy.js} +1 -1
  118. package/src/assets/web-panel/assets/index-CrxUwNM8.js +1 -0
  119. package/src/assets/web-panel/assets/{index-Bq8-2Ibv.js → index-CsVuQsY1.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BHp1nSur.js → index-CydHMjwc.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CPYshcic.js → index-DH6iC5b2.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DBwBZwio.js → index-DZXhKAk9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Didyuq2Z.js → index-D_g9mA1N.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CdHMc9LQ.js → index-DboTeuPF.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-C5dqieYX.js → index-DfgpKd64.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CdplnAS9.js → index-Dmfe0L2Z.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-KaSejHjf.js → index-Dzni_5Qw.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BpwGsAA-.js → index-J5JkStvY.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-OBhlHSMN.js → index-Ne8UGllV.js} +3 -3
  130. package/src/assets/web-panel/assets/{index-CZICtYJ0.js → index-O09jXbir.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DVgTf7CZ.js → index-Y7el_3WS.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BQAsL19t.js → index-c_tBkIlU.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BMm8tO2X.js → index-lKJWAmd4.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CNytQuFq.js → index-xzRKTy0R.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-P8SBN6Di.js → initDefaultProps-XuhfEIhB.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-BubbjUT_.js → motion-Cbxh6AxO.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Chcykv0I.js → move-C7IEnFly.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-DyiYuGDu.js → mtc-parser-lLADx4LL.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-Rdwb_Neb.js → omit-mIbic_k-.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-CCr0MYHl.js → pickAttrs-_xIYEqu3.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-B1ZXz3bb.js → placementArrow-ClB-E0ny.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-BGEdwej6.js → responsiveObserve-D36Bg2ut.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-CpnsUMaT.js → slide-CUuO08Bl.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-C7x-TVp_.js → statusUtils-BKahwLbv.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-CC5k_791.js → styleChecker-2pT-T8vy.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-BpZFKsJW.js → useFlexGapSupport-DyH5g7Rg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-CVq5HySy.js → useFs-CTOauB3X.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BGkdLryu.js → usePersonalDataHub-B02JYIMe.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-uLtOUEK-.js → vnode-Do22wQrc.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-BfVC9iUs.js → zoom-BfnL7rit.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +3 -3
  153. package/src/commands/agent.js +8 -0
  154. package/src/commands/background-session.js +31 -3
  155. package/src/commands/chat.js +5 -1
  156. package/src/commands/eval.js +86 -28
  157. package/src/commands/llm.js +104 -1
  158. package/src/commands/plugin.js +161 -1
  159. package/src/commands/sandbox.js +121 -2
  160. package/src/commands/serve.js +11 -2
  161. package/src/commands/skill.js +29 -0
  162. package/src/data/changelog.json +26 -0
  163. package/src/gateways/ws/session-protocol.js +13 -0
  164. package/src/gateways/ws/ws-agent-handler.js +17 -0
  165. package/src/gateways/ws/ws-server.js +3 -0
  166. package/src/gateways/ws/ws-session-state.js +131 -0
  167. package/src/generated/cc-agent-protocol.schema.json +48 -1
  168. package/src/lazy-dispatch.js +8 -1
  169. package/src/lib/agent-sandbox.js +337 -53
  170. package/src/lib/app-server/cli-agent-kernel-adapter.js +28 -0
  171. package/src/lib/app-server/server.js +93 -0
  172. package/src/lib/background-agent-keeper-client.js +2 -0
  173. package/src/lib/background-agent-keeper-protocol.js +7 -0
  174. package/src/lib/background-agent-list-index.js +222 -0
  175. package/src/lib/background-agent-supervisor.js +232 -47
  176. package/src/lib/codex-app-server-adapter.js +82 -27
  177. package/src/lib/context-memory-kernel/durable-memory-port.js +31 -8
  178. package/src/lib/context-memory-kernel/provider-context.js +118 -19
  179. package/src/lib/deferred-question-context.js +278 -0
  180. package/src/lib/eval/evidence.js +202 -64
  181. package/src/lib/eval/plugin-suite.js +1181 -0
  182. package/src/lib/eval/runner.js +10 -3
  183. package/src/lib/evolution/agent-evolution-runtime-composition.js +236 -1
  184. package/src/lib/evolution/agent-model-projection.js +97 -1
  185. package/src/lib/evolution/evidence-backed-wiki-maintainer.js +154 -1
  186. package/src/lib/evolution/evolution-artifact-ports.js +6 -0
  187. package/src/lib/evolution/evolution-deployment-loader.js +87 -3
  188. package/src/lib/evolution/evolution-eval-gate.js +8 -0
  189. package/src/lib/evolution/evolution-eval-runtime-composition.js +255 -0
  190. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +58 -2
  191. package/src/lib/evolution/evolution-ledger-file-backend.js +23 -2
  192. package/src/lib/evolution/evolution-ledger-manifest-chain.js +223 -7
  193. package/src/lib/evolution/evolution-ledger-v2-journal.js +525 -0
  194. package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +46 -2
  195. package/src/lib/evolution/evolution-ledger.js +57 -1
  196. package/src/lib/evolution/evolution-run-ledger-adapter.js +93 -0
  197. package/src/lib/evolution/evolution-run-wiki-evidence-resolver.js +259 -0
  198. package/src/lib/evolution/governed-hub-llm.js +238 -5
  199. package/src/lib/evolution/governed-hub-resolver.js +82 -4
  200. package/src/lib/evolution/governed-hub-skill.js +11 -5
  201. package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +10 -1
  202. package/src/lib/evolution/skill-runtime-revalidation-ledger-adapter.js +254 -0
  203. package/src/lib/evolution/skill-runtime-revalidation.js +530 -0
  204. package/src/lib/evolution/skill-target-matrix-eval.js +4 -4
  205. package/src/lib/evolution/wiki-evidence-commit-guard.js +366 -0
  206. package/src/lib/evolution/wiki-informed-skill-proposer.js +13 -1
  207. package/src/lib/goal-context.js +14 -5
  208. package/src/lib/interaction-adapter.js +166 -1
  209. package/src/lib/model-capabilities.js +271 -0
  210. package/src/lib/model-context-catalog.js +105 -0
  211. package/src/lib/model-context-window.js +4 -49
  212. package/src/lib/openai-responses.js +428 -0
  213. package/src/lib/plugin-runtime/scopes.js +7 -1
  214. package/src/lib/remote-read-loop-guard.js +2 -2
  215. package/src/lib/runtime-usage-ledger.js +16 -0
  216. package/src/lib/session-host-snapshot.js +16 -0
  217. package/src/lib/skill-loader.js +12 -0
  218. package/src/lib/with-file-lock.js +3 -1
  219. package/src/repl/agent-repl.js +5 -1
  220. package/src/runtime/agent-core.js +348 -23
  221. package/src/runtime/agent-runtime.js +7 -0
  222. package/src/runtime/coding-agent-contract-shared.cjs +13 -1
  223. package/src/runtime/headless-runner.js +4 -1
  224. package/src/runtime/headless-stream.js +283 -45
  225. package/src/runtime/runtime-factory.js +26 -2
  226. package/src/workers/background-agent-keeper.js +23 -13
  227. package/src/workers/background-agent-worker.js +27 -13
  228. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bi2SY9E_.js +0 -1
  229. package/src/assets/web-panel/assets/PdhVaultBrowser-fYmQzmTA.js +0 -7
  230. package/src/assets/web-panel/assets/devWarning-BtFLt3qI.js +0 -1
  231. package/src/assets/web-panel/assets/index-BhuWQHeG.js +0 -1
  232. package/src/assets/web-panel/assets/index-D-4tFek3.js +0 -1
@@ -0,0 +1,222 @@
1
+ import {
2
+ chmodSync,
3
+ lstatSync,
4
+ openSync,
5
+ closeSync,
6
+ readFileSync,
7
+ readdirSync,
8
+ renameSync,
9
+ rmSync,
10
+ statSync,
11
+ writeFileSync,
12
+ } from "node:fs";
13
+ import { createHash, randomBytes } from "node:crypto";
14
+ import { join } from "node:path";
15
+
16
+ export const BACKGROUND_AGENT_LIST_INDEX_SCHEMA =
17
+ "chainlesschain.background-agent-list-index/v1";
18
+ export const BACKGROUND_AGENT_LIST_INDEX_FILE =
19
+ ".background-agent-list-index-v1";
20
+
21
+ const STATE_FILE = /^(bg-[A-Za-z0-9-]+)\.json$/u;
22
+ const MAX_INDEX_BYTES = 64 * 1024 * 1024;
23
+ const MAX_INDEX_ENTRIES = 1_000_000;
24
+
25
+ function sha256(value, domain) {
26
+ return `sha256:${createHash("sha256")
27
+ .update(domain)
28
+ .update("\0")
29
+ .update(value)
30
+ .digest("hex")}`;
31
+ }
32
+
33
+ function stateFileSignature(directory, name, id) {
34
+ const target = join(directory, name);
35
+ const link = lstatSync(target);
36
+ if (!link.isFile() || link.isSymbolicLink()) {
37
+ throw new TypeError(`background agent state is not a regular file: ${id}`);
38
+ }
39
+ const stat = statSync(target, { bigint: true });
40
+ return {
41
+ id,
42
+ name,
43
+ size: String(stat.size),
44
+ mtimeNs: String(stat.mtimeNs),
45
+ ctimeNs: String(stat.ctimeNs),
46
+ dev: String(stat.dev),
47
+ ino: String(stat.ino),
48
+ };
49
+ }
50
+
51
+ function collectInventory(directory) {
52
+ const files = readdirSync(directory, { withFileTypes: true })
53
+ .map((entry) => {
54
+ const match = STATE_FILE.exec(entry.name);
55
+ if (!match || entry.name.includes(".job.")) return null;
56
+ if (!entry.isFile()) {
57
+ throw new TypeError(
58
+ `background agent state is not a regular file: ${match[1]}`,
59
+ );
60
+ }
61
+ return stateFileSignature(directory, entry.name, match[1]);
62
+ })
63
+ .filter(Boolean)
64
+ .sort((left, right) => left.name.localeCompare(right.name, "en"));
65
+ if (files.length > MAX_INDEX_ENTRIES) {
66
+ throw new RangeError(
67
+ `background agent list index exceeds ${MAX_INDEX_ENTRIES} entries`,
68
+ );
69
+ }
70
+ const encoded = JSON.stringify(files);
71
+ return {
72
+ files,
73
+ digest: sha256(encoded, "cc.background-agent-list-inventory/v1"),
74
+ };
75
+ }
76
+
77
+ function normalizeEntry(value, inventoryIds) {
78
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
79
+ if (!inventoryIds.has(value.id)) return null;
80
+ const startedAt = Number(value.startedAt);
81
+ if (!Number.isFinite(startedAt) || startedAt < 0) return null;
82
+ if (
83
+ typeof value.status !== "string" ||
84
+ value.status.length === 0 ||
85
+ value.status.length > 64
86
+ ) {
87
+ return null;
88
+ }
89
+ return { id: value.id, startedAt, status: value.status };
90
+ }
91
+
92
+ function readCachedIndex(directory, inventory) {
93
+ const target = join(directory, BACKGROUND_AGENT_LIST_INDEX_FILE);
94
+ try {
95
+ const stat = lstatSync(target);
96
+ if (
97
+ !stat.isFile() ||
98
+ stat.isSymbolicLink() ||
99
+ stat.size <= 0 ||
100
+ stat.size > MAX_INDEX_BYTES
101
+ ) {
102
+ return null;
103
+ }
104
+ const parsed = JSON.parse(readFileSync(target, "utf8"));
105
+ if (
106
+ !parsed ||
107
+ typeof parsed !== "object" ||
108
+ Array.isArray(parsed) ||
109
+ parsed.schema !== BACKGROUND_AGENT_LIST_INDEX_SCHEMA ||
110
+ parsed.inventoryDigest !== inventory.digest ||
111
+ parsed.fileCount !== inventory.files.length ||
112
+ !Array.isArray(parsed.entries) ||
113
+ parsed.entries.length > inventory.files.length
114
+ ) {
115
+ return null;
116
+ }
117
+ const inventoryIds = new Set(inventory.files.map((file) => file.id));
118
+ const entries = parsed.entries.map((entry) =>
119
+ normalizeEntry(entry, inventoryIds),
120
+ );
121
+ if (entries.some((entry) => entry === null)) return null;
122
+ if (new Set(entries.map((entry) => entry.id)).size !== entries.length) {
123
+ return null;
124
+ }
125
+ const contentDigest = sha256(
126
+ JSON.stringify({
127
+ schema: parsed.schema,
128
+ inventoryDigest: parsed.inventoryDigest,
129
+ fileCount: parsed.fileCount,
130
+ entries,
131
+ }),
132
+ "cc.background-agent-list-index/v1",
133
+ );
134
+ if (parsed.digest !== contentDigest) return null;
135
+ return entries;
136
+ } catch {
137
+ return null;
138
+ }
139
+ }
140
+
141
+ function writeCachedIndex(directory, inventory, entries) {
142
+ const target = join(directory, BACKGROUND_AGENT_LIST_INDEX_FILE);
143
+ const value = {
144
+ schema: BACKGROUND_AGENT_LIST_INDEX_SCHEMA,
145
+ inventoryDigest: inventory.digest,
146
+ fileCount: inventory.files.length,
147
+ entries,
148
+ };
149
+ value.digest = sha256(
150
+ JSON.stringify(value),
151
+ "cc.background-agent-list-index/v1",
152
+ );
153
+ const temporary = `${target}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`;
154
+ try {
155
+ const descriptor = openSync(temporary, "wx", 0o600);
156
+ try {
157
+ writeFileSync(descriptor, `${JSON.stringify(value)}\n`, "utf8");
158
+ } finally {
159
+ closeSync(descriptor);
160
+ }
161
+ if (process.platform !== "win32") chmodSync(temporary, 0o600);
162
+ renameSync(temporary, target);
163
+ } catch {
164
+ rmSync(temporary, { force: true });
165
+ }
166
+ }
167
+
168
+ function projectState(state, id) {
169
+ if (!state || typeof state !== "object" || String(state.id) !== id) {
170
+ return null;
171
+ }
172
+ const startedAt = Number(state.startedAt || 0);
173
+ if (!Number.isFinite(startedAt) || startedAt < 0) return null;
174
+ if (
175
+ typeof state.status !== "string" ||
176
+ state.status.length === 0 ||
177
+ state.status.length > 64
178
+ ) {
179
+ return null;
180
+ }
181
+ return { id, startedAt, status: state.status };
182
+ }
183
+
184
+ /**
185
+ * Load a content-free projection when it exactly matches every authority-file
186
+ * identity. A miss rebuilds from authority and retries the inventory fence;
187
+ * callers must fall back to their authoritative scan if a concurrent writer
188
+ * prevents a stable rebuild.
189
+ */
190
+ export function loadBackgroundAgentListIndex({ directory, readState }) {
191
+ if (typeof directory !== "string" || !directory) {
192
+ throw new TypeError("background agent list index directory is required");
193
+ }
194
+ if (typeof readState !== "function") {
195
+ throw new TypeError("background agent list index readState is required");
196
+ }
197
+ const inventory = collectInventory(directory);
198
+ const cached = readCachedIndex(directory, inventory);
199
+ if (cached) {
200
+ return Object.freeze({
201
+ source: "index",
202
+ entries: Object.freeze(cached.map((entry) => Object.freeze(entry))),
203
+ });
204
+ }
205
+
206
+ const entries = inventory.files
207
+ .map((file) => projectState(readState(file.id), file.id))
208
+ .filter(Boolean);
209
+ const verifiedInventory = collectInventory(directory);
210
+ if (verifiedInventory.digest !== inventory.digest) {
211
+ const error = new Error(
212
+ "background agent authority changed while rebuilding the list index",
213
+ );
214
+ error.code = "BACKGROUND_AGENT_LIST_INDEX_RACE";
215
+ throw error;
216
+ }
217
+ writeCachedIndex(directory, inventory, entries);
218
+ return Object.freeze({
219
+ source: "rebuilt",
220
+ entries: Object.freeze(entries.map((entry) => Object.freeze(entry))),
221
+ });
222
+ }
@@ -60,9 +60,12 @@ import {
60
60
  cleanupBackgroundAgentKeeperPipeDirectory,
61
61
  prepareBackgroundAgentKeeperPipePath,
62
62
  } from "./background-agent-keeper-protocol.js";
63
+ import { loadBackgroundAgentListIndex } from "./background-agent-list-index.js";
63
64
 
64
65
  export const DEFAULT_HEARTBEAT_INTERVAL_MS = 5000;
65
66
  export const DEFAULT_HEARTBEAT_STALE_MS = 120000;
67
+ export const DEFAULT_BACKGROUND_AGENT_PAGE_LIMIT = 50;
68
+ export const MAX_BACKGROUND_AGENT_PAGE_LIMIT = 200;
66
69
 
67
70
  /**
68
71
  * Pid identity tolerance (Gap 1: OS pid reuse). A pid alone does not identify
@@ -1370,7 +1373,14 @@ export function mutateBackgroundAgentState(id, updater, options = {}) {
1370
1373
  // A live numeric pid can belong to a later process after the lock owner
1371
1374
  // was killed. Use the lock acquisition timestamp as a one-sided identity
1372
1375
  // fence so only an owner which existed before acquisition still blocks.
1373
- _isOwnerAlive: isBackgroundAgentStateLockOwnerAlive,
1376
+ // Periodic telemetry may request a strict try-lock. In that mode an
1377
+ // incumbent is deliberately retained without a Windows PID/start-time
1378
+ // probe: a heartbeat must never synchronously stall a control channel
1379
+ // merely to determine whether it could reclaim a lock.
1380
+ _isOwnerAlive:
1381
+ options.probeLockOwner === false
1382
+ ? () => true
1383
+ : isBackgroundAgentStateLockOwnerAlive,
1374
1384
  },
1375
1385
  );
1376
1386
  }
@@ -1458,57 +1468,65 @@ export async function deliverBackgroundNeedsInputNotification(
1458
1468
  * the only authority to start or continue a turn: a terminal, deleted,
1459
1469
  * corrupt, differently-generated or already-owned record is never revived.
1460
1470
  */
1461
- export function claimBackgroundAgentHeartbeat(id, heartbeat = {}) {
1471
+ export function claimBackgroundAgentHeartbeat(
1472
+ id,
1473
+ heartbeat = {},
1474
+ options = {},
1475
+ ) {
1462
1476
  const workerPid = Number(heartbeat.workerPid ?? heartbeat.pid);
1463
1477
  const workerGeneration = heartbeat.workerGeneration;
1464
1478
  if (!Number.isInteger(workerPid) || workerPid <= 0) {
1465
1479
  throw new Error(`Invalid background worker pid: ${heartbeat.workerPid}`);
1466
1480
  }
1467
- return mutateBackgroundAgentState(id, (current) => {
1468
- if (!current || current.status !== "running") return null;
1469
- if (current.stopRequestedAt) return null;
1470
- if (
1471
- current.workerGeneration &&
1472
- current.workerGeneration !== workerGeneration
1473
- ) {
1474
- return null;
1475
- }
1476
- const claimedWorkerPid = Number(current.workerClaimedPid);
1477
- if (
1478
- current.workerClaimedPid != null &&
1479
- Number.isInteger(claimedWorkerPid) &&
1480
- claimedWorkerPid > 0 &&
1481
- claimedWorkerPid !== workerPid
1482
- ) {
1483
- return null;
1484
- }
1485
- const currentWorkerPid = Number(current.workerPid ?? current.pid);
1486
- if (
1487
- !current.workerGeneration &&
1488
- Number.isInteger(currentWorkerPid) &&
1489
- currentWorkerPid > 0 &&
1490
- currentWorkerPid !== workerPid &&
1491
- current.launchFinalizationUncertain !== true
1492
- ) {
1493
- return null;
1494
- }
1495
- return {
1496
- ...current,
1497
- ...heartbeat,
1498
- id,
1499
- pid: workerPid,
1500
- workerPid,
1501
- workerClaimedPid:
1481
+ return mutateBackgroundAgentState(
1482
+ id,
1483
+ (current) => {
1484
+ if (!current || current.status !== "running") return null;
1485
+ if (current.stopRequestedAt) return null;
1486
+ if (
1487
+ current.workerGeneration &&
1488
+ current.workerGeneration !== workerGeneration
1489
+ ) {
1490
+ return null;
1491
+ }
1492
+ const claimedWorkerPid = Number(current.workerClaimedPid);
1493
+ if (
1502
1494
  current.workerClaimedPid != null &&
1503
1495
  Number.isInteger(claimedWorkerPid) &&
1504
- claimedWorkerPid > 0
1505
- ? claimedWorkerPid
1506
- : workerPid,
1507
- workerClaimedAt: current.workerClaimedAt || Date.now(),
1508
- status: "running",
1509
- heartbeatAt: heartbeat.heartbeatAt ?? Date.now(),
1510
- };
1511
- });
1496
+ claimedWorkerPid > 0 &&
1497
+ claimedWorkerPid !== workerPid
1498
+ ) {
1499
+ return null;
1500
+ }
1501
+ const currentWorkerPid = Number(current.workerPid ?? current.pid);
1502
+ if (
1503
+ !current.workerGeneration &&
1504
+ Number.isInteger(currentWorkerPid) &&
1505
+ currentWorkerPid > 0 &&
1506
+ currentWorkerPid !== workerPid &&
1507
+ current.launchFinalizationUncertain !== true
1508
+ ) {
1509
+ return null;
1510
+ }
1511
+ return {
1512
+ ...current,
1513
+ ...heartbeat,
1514
+ id,
1515
+ pid: workerPid,
1516
+ workerPid,
1517
+ workerClaimedPid:
1518
+ current.workerClaimedPid != null &&
1519
+ Number.isInteger(claimedWorkerPid) &&
1520
+ claimedWorkerPid > 0
1521
+ ? claimedWorkerPid
1522
+ : workerPid,
1523
+ workerClaimedAt: current.workerClaimedAt || Date.now(),
1524
+ status: "running",
1525
+ heartbeatAt: heartbeat.heartbeatAt ?? Date.now(),
1526
+ };
1527
+ },
1528
+ options,
1529
+ );
1512
1530
  }
1513
1531
 
1514
1532
  function deleteBackgroundAgentState(id, predicate = () => true) {
@@ -2038,7 +2056,21 @@ export function effectiveBackgroundAgentState(state, options = {}) {
2038
2056
  return next;
2039
2057
  }
2040
2058
 
2041
- export function listBackgroundAgents(options = {}) {
2059
+ function backgroundAgentStartedAt(state) {
2060
+ const startedAt = Number(state?.startedAt);
2061
+ return Number.isFinite(startedAt) && startedAt >= 0 ? startedAt : 0;
2062
+ }
2063
+
2064
+ function compareBackgroundAgentListEntries(a, b) {
2065
+ const newestFirst = backgroundAgentStartedAt(b) - backgroundAgentStartedAt(a);
2066
+ if (newestFirst !== 0) return newestFirst;
2067
+ return String(a.id).localeCompare(String(b.id));
2068
+ }
2069
+
2070
+ function listBackgroundAgentEntries(
2071
+ options = {},
2072
+ { stableTieBreak = false } = {},
2073
+ ) {
2042
2074
  return (
2043
2075
  readdirSync(backgroundAgentsDir())
2044
2076
  .filter((name) => name.endsWith(".json") && !name.includes(".job."))
@@ -2046,7 +2078,11 @@ export function listBackgroundAgents(options = {}) {
2046
2078
  .filter(Boolean)
2047
2079
  .map((state) => effectiveBackgroundAgentState(state, options))
2048
2080
  .filter((state) => options.all || state.status === "running")
2049
- .sort((a, b) => (b.startedAt || 0) - (a.startedAt || 0))
2081
+ .sort(
2082
+ stableTieBreak
2083
+ ? compareBackgroundAgentListEntries
2084
+ : (a, b) => (b.startedAt || 0) - (a.startedAt || 0),
2085
+ )
2050
2086
  // Display-only enrichment: attach the canonical unified lifecycle state.
2051
2087
  // This is a list feed (never written back to disk), so the derived field
2052
2088
  // cannot leak into the on-disk schema the way it would in the mutate paths.
@@ -2054,6 +2090,155 @@ export function listBackgroundAgents(options = {}) {
2054
2090
  );
2055
2091
  }
2056
2092
 
2093
+ function normalizeBackgroundAgentPageLimit(value) {
2094
+ if (value === undefined || value === null) {
2095
+ return DEFAULT_BACKGROUND_AGENT_PAGE_LIMIT;
2096
+ }
2097
+ const limit =
2098
+ typeof value === "string" && /^\d+$/u.test(value) ? Number(value) : value;
2099
+ if (
2100
+ !Number.isSafeInteger(limit) ||
2101
+ limit < 1 ||
2102
+ limit > MAX_BACKGROUND_AGENT_PAGE_LIMIT
2103
+ ) {
2104
+ throw new TypeError(
2105
+ `background agent page limit must be an integer from 1 to ${MAX_BACKGROUND_AGENT_PAGE_LIMIT}`,
2106
+ );
2107
+ }
2108
+ return limit;
2109
+ }
2110
+
2111
+ function encodeBackgroundAgentPageCursor(state, all) {
2112
+ const payload = JSON.stringify({
2113
+ version: 1,
2114
+ all: all === true,
2115
+ startedAt: backgroundAgentStartedAt(state),
2116
+ id: safeId(state?.id),
2117
+ });
2118
+ return `bg1.${Buffer.from(payload).toString("base64url")}`;
2119
+ }
2120
+
2121
+ function decodeBackgroundAgentPageCursor(value) {
2122
+ if (value === undefined || value === null) return null;
2123
+ if (
2124
+ typeof value !== "string" ||
2125
+ value.length > 768 ||
2126
+ !/^bg1\.[A-Za-z0-9_-]+$/u.test(value)
2127
+ ) {
2128
+ throw new TypeError("background agent page cursor is invalid");
2129
+ }
2130
+ let payload;
2131
+ try {
2132
+ const encoded = value.slice(4);
2133
+ const decoded = Buffer.from(encoded, "base64url");
2134
+ if (decoded.toString("base64url") !== encoded) {
2135
+ throw new Error("cursor encoding is not canonical");
2136
+ }
2137
+ payload = JSON.parse(decoded.toString("utf8"));
2138
+ } catch {
2139
+ throw new TypeError("background agent page cursor is invalid");
2140
+ }
2141
+ if (
2142
+ !payload ||
2143
+ typeof payload !== "object" ||
2144
+ Array.isArray(payload) ||
2145
+ Object.keys(payload).length !== 4 ||
2146
+ payload.version !== 1 ||
2147
+ typeof payload.all !== "boolean" ||
2148
+ !Number.isSafeInteger(payload.startedAt) ||
2149
+ payload.startedAt < 0
2150
+ ) {
2151
+ throw new TypeError("background agent page cursor is invalid");
2152
+ }
2153
+ let id;
2154
+ try {
2155
+ id = safeId(payload.id);
2156
+ } catch {
2157
+ throw new TypeError("background agent page cursor is invalid");
2158
+ }
2159
+ return { all: payload.all, startedAt: payload.startedAt, id };
2160
+ }
2161
+
2162
+ function isBackgroundAgentAfterCursor(state, cursor) {
2163
+ const startedAt = backgroundAgentStartedAt(state);
2164
+ if (startedAt !== cursor.startedAt) return startedAt < cursor.startedAt;
2165
+ return String(state.id).localeCompare(cursor.id) > 0;
2166
+ }
2167
+
2168
+ /**
2169
+ * Return one stable, bounded page from the newest-first background session
2170
+ * feed. The cursor is an opaque ordering fence, not an authority token.
2171
+ *
2172
+ * State files are still read to preserve the current authoritative lifecycle
2173
+ * reconciliation. A future read-only index may reduce that I/O, but this API
2174
+ * immediately bounds the object graph and protocol response retained by a
2175
+ * caller.
2176
+ */
2177
+ export function listBackgroundAgentsPage(options = {}) {
2178
+ const limit = normalizeBackgroundAgentPageLimit(options.limit);
2179
+ const cursor = decodeBackgroundAgentPageCursor(options.cursor);
2180
+ if (cursor && cursor.all !== (options.all === true)) {
2181
+ throw new TypeError(
2182
+ "background agent page cursor does not match the requested filter",
2183
+ );
2184
+ }
2185
+ let indexed = null;
2186
+ try {
2187
+ indexed = loadBackgroundAgentListIndex({
2188
+ directory: backgroundAgentsDir(),
2189
+ readState: readBackgroundAgentState,
2190
+ });
2191
+ } catch {
2192
+ // The index is a disposable, content-free projection. Authority races,
2193
+ // corruption, or an unwritable cache must retain the full-scan behavior.
2194
+ }
2195
+ if (indexed) {
2196
+ const projected = [];
2197
+ const summaries = [...indexed.entries]
2198
+ .filter((state) => options.all || state.status === "running")
2199
+ .sort(compareBackgroundAgentListEntries);
2200
+ for (const summary of summaries) {
2201
+ if (cursor && !isBackgroundAgentAfterCursor(summary, cursor)) continue;
2202
+ const state = readBackgroundAgentState(summary.id);
2203
+ if (!state) continue;
2204
+ const effective = effectiveBackgroundAgentState(state, options);
2205
+ if (!effective || (!options.all && effective.status !== "running")) {
2206
+ continue;
2207
+ }
2208
+ if (cursor && !isBackgroundAgentAfterCursor(effective, cursor)) continue;
2209
+ projected.push(withLifecycleState(effective));
2210
+ if (projected.length > limit) break;
2211
+ }
2212
+ const sessions = projected.slice(0, limit);
2213
+ const nextCursor =
2214
+ projected.length > sessions.length
2215
+ ? encodeBackgroundAgentPageCursor(sessions.at(-1), options.all)
2216
+ : null;
2217
+ return Object.freeze({
2218
+ sessions: Object.freeze(sessions),
2219
+ nextCursor,
2220
+ });
2221
+ }
2222
+ const eligible = cursor
2223
+ ? listBackgroundAgentEntries(options, { stableTieBreak: true }).filter(
2224
+ (state) => isBackgroundAgentAfterCursor(state, cursor),
2225
+ )
2226
+ : listBackgroundAgentEntries(options, { stableTieBreak: true });
2227
+ const sessions = eligible.slice(0, limit);
2228
+ const nextCursor =
2229
+ eligible.length > sessions.length
2230
+ ? encodeBackgroundAgentPageCursor(sessions.at(-1), options.all)
2231
+ : null;
2232
+ return Object.freeze({
2233
+ sessions: Object.freeze(sessions),
2234
+ nextCursor,
2235
+ });
2236
+ }
2237
+
2238
+ export function listBackgroundAgents(options = {}) {
2239
+ return listBackgroundAgentEntries(options);
2240
+ }
2241
+
2057
2242
  function sleepSyncMs(ms) {
2058
2243
  try {
2059
2244
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);