chainlesschain 0.162.197 → 0.162.200

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 (233) hide show
  1. package/bin/chainlesschain.js +14 -6
  2. package/package.json +4 -1
  3. package/scripts/command-lifecycle-report.mjs +94 -0
  4. package/src/assets/web-panel/assets/{AIOps-D3Gu1a5d.js → AIOps-DcQ0bWKy.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-DrwAoKaz.js → ActionButton-GecwfFPt.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-C7Q-gd_3.js → Analytics-CD6iSt9v.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-DgBtae-n.js → AppLayout-CDEtuEYf.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-pQ6LcA-W.js → Artifacts-DS3jAjeW.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DK61tocB.js → Audit-CcSJA048.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-BOKgDFRh.js → BackgroundAgents-DRo9Morb.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-Bo9G4vTP.js → Backup-Vw5MrWft.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-Do_dE9_v.js → BaseInput-DNHIu823.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-COVvZzOL.js → Chat-DvAsO8-b.js} +4 -4
  14. package/src/assets/web-panel/assets/ChatBubbleRenderer-9aDuObay.js +1 -0
  15. package/src/assets/web-panel/assets/{Checkbox-Z9MJMolt.js → Checkbox-CKCa7tvn.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-BVzWKVbf.js → Codegen-CIFvZdaT.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-C8MnYcbT.js → Col-C79yz7bK.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-DQxqw15l.js → Community-DVvZskLJ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-BAUmrh3y.js → Compact-oaew61hV.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-jPAkQ3zK.js → Compliance-DqA7wmRx.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-BBQyxbh8.js → Cowork-B-qGadxa.js} +3 -3
  22. package/src/assets/web-panel/assets/{Cron-W5koq8Z5.js → Cron-CUlCl4sS.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-BQhnu5hS.js → Crosschain-CNOlr9DU.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-DD7PlI18.js → DID-DJqFCT_3.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-w_ILuwKI.js → Dashboard-CznGpphf.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-qiDUAyAo.js → Dropdown-_cJw218E.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-PDeBcI5H.js → EmailListRenderer-Dr-1BZ9C.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-SuArscRM.js → FamilyGuardDashboard-Dxf4xtSk.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-BCovZaUn.js → Federation-DOiG3i_1.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-DjlFdVFk.js → FormItemContext-BzbMcFB9.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-DoEZ7fcS.js → GenericCardRenderer-VbBrYttP.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-CV0-6GPI.js → Git-CLG8E6ED.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-B_SFN50w.js → Governance-LGJQfk_q.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-heI0Eo6k.js → Inference-DlQKx9lF.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-Cz5INS5p.js → KnowledgeGraph-DU8vEouV.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-BSFxiHkg.js → Logs-FZIQOdln.js} +2 -2
  37. package/src/assets/web-panel/assets/MarkdownRenderer-BJNWIrbw.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-0TWTpE7k.js → Marketplace-C_xd-zZI.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-CV4-wBLm.js → McpTools-q-YktphS.js} +5 -5
  40. package/src/assets/web-panel/assets/{Memory-x5bH5rw5.js → Memory-Cq9OhDin.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-DaBmUu9G.js → MobileBridge-B03_R98T.js} +1 -1
  42. package/src/assets/web-panel/assets/MobileProjects-DZrk-qmF.js +1 -0
  43. package/src/assets/web-panel/assets/{Mtc-B_zKEBif.js → Mtc-BidCKW28.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-BCfKD2yg.js → MtcAudit-r-iaMVM7.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-DgYfj6c_.js → Multisig-CgTUFvff.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-Dz09lFUm.js → NLProgramming-B7NvzfAV.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-Cuj6ugBE.js → Notes-80CWNqJI.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-DK2WXjhg.js → NotificationSettings-0H6xdiY3.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-D1IAOQoo.js → OrderTableRenderer-CKP4AFWy.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-9fqnPvTw.js → Organization-B8sxCV_h.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-n5xHkhow.js → Overflow-CW9JBBhQ.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-B5AUWwH-.js → P2P-bdSQV7oZ.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-CoUDV6dy.js → PdhVaultBrowser-DQad42nW.js} +4 -4
  54. package/src/assets/web-panel/assets/{Permissions-DPRmQf_H.js → Permissions-CueexxTR.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-B37bsbEN.js → PersonalDataHub-fqxflhR8.js} +6 -6
  56. package/src/assets/web-panel/assets/{Pipeline-CCAuPqu9.js → Pipeline-KFwwnIMC.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-B81msZdv.js → Privacy-ClnD9buY.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-B-Py2NbF.js → ProjectInit-CZEz6sm3.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-CYsneiRB.js → ProjectSettings-B6NzpmOI.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-Y975Mh6R.js → Projects-DYyuwPCs.js} +1 -1
  61. package/src/assets/web-panel/assets/Providers-C3tz_jdh.js +1 -0
  62. package/src/assets/web-panel/assets/{QrScannerModal-Bj_6gJ0l.js → QrScannerModal-BzuOBbqB.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-BgpBCMPE.js → QuickAsk-CmNO9qSj.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-DhUW3YUA.js → Recommend-VJNj3_NF.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-DdeyfbkA.js → RemoteSession-CrbdbSBF.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-fxW421xd.js → Reputation-DTyMd45j.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-De73w1og.js → Row-DHrQ-Icz.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-3US_Q_lj.js → RssFeed-DqWxY9c5.js} +2 -2
  69. package/src/assets/web-panel/assets/{Search-DbZ_DU74.js → Search-ctF1Ks3J.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-DoIU1vMF.js → Security-BrQz8uo5.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-DB_RGqpc.js → Services-D4scVFar.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-DnzLaayC.js → Skeleton-oUScaOjv.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-VzVXHENF.js → Skills-CL-y0eLt.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-DMfvjCAI.js → Sla-DQExhwXj.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-DQQOYWbF.js → SpeechSettings-iNp_I7kN.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-Bmx3FG1P.js → SyncSettings-CTDlMo0A.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-DOQyfb-2.js → Tasks-4kb8l3sc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-D6hTRT7c.js → Templates-BXcL9oXW.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-CTPQZAzs.js → Tenant-DLE8eS0D.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-B7vII3oH.js → Terminal-DGpUZPPK.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-BkiFJeXV.js → TimelineRenderer-C1pWXGPC.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-BPPdQMNo.js → Tokens-BYfbfqhZ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-BxG8JAEI.js → Trigger-K9YfLOCw.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-DHD7nMpM.js → Trust-Ctkq77Hy.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-B4BJpU47.js → UkeySign-C6_CSe9J.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-CRiGpFx2.js → VideoEditing-Be3rpOWs.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-BSDSNiem.js → Wallet-D0UIplxk.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-DLTUh5Zv.js → WebAuthn-CF9bM9I3.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-tW2MwjhD.js → WorkflowEditor-D0H1XVPY.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-SgsLQ3FC.js → chat-Cgzzbe0o.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-BHjjLIKO.js → colors-BwNxEVS0.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-VceErdKq.js → compact-item-D60Z4Hhs.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-BZ332MYl.js → createContext-MFk58XB0.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-BJiw369i.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-CBTjJOjn.js → hasIn-CRj2SvGO.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DaCCy6lq.js → index--s45_1cb.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CMVvxIS8.js → index--tquQ2ZG.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BhXZEUAc.js → index-1T1rhokn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BQSmZGgs.js → index-B-M82_rx.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BeiqkxJG.js → index-BE_el1Zs.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-29wVzi-k.js → index-BhRkR7IO.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-iYQNU9za.js → index-Bo0y96-K.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BRWhLbWF.js → index-CJgu5JUK.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BPXFLYdW.js → index-CLWwdebO.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Cr4rjlW5.js → index-CNAK5QG_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CaIS_TNX.js → index-CQjJjPRD.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-1n7xjKDU.js → index-CTDbAfae.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BETEjuNr.js → index-CVI_9sRK.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-By5jBtkV.js → index-CY14oMQK.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DgPvuIn2.js → index-CbiTJkZf.js} +1 -1
  111. package/src/assets/web-panel/assets/index-CiMouosn.js +1 -0
  112. package/src/assets/web-panel/assets/{index-CawpdGTW.js → index-CqWpxMqx.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-_PHrIO4O.js → index-CvB8lYUR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BOtvPdHt.js → index-D51XwtCY.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CrUgDQkf.js → index-D6HvK_1O.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BY1wexYG.js → index-D9jVIwLJ.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-C_B9rFQE.js → index-DA4tE98u.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B5KAGxNo.js → index-DBwOtXw0.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BC1xuQgX.js → index-DKdNzTIb.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-B2u26AS3.js → index-DRySdmvN.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DePOeMDM.js → index-DWzyTev7.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DXcKlwy7.js +1 -0
  123. package/src/assets/web-panel/assets/{index-BTlc-Bve.js → index-DYjs7jAP.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CLc19alH.js → index-DbROzMBp.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-fU7wNHDB.js → index-DhFtk5PR.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-D_SePDWj.js → index-Di2AbMLg.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-vIXOpcjD.js → index-DvmocQsM.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BcUenmCX.js → index-Dw-o0zEF.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DUkVN794.js → index-DysPoP38.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CtjLcCNU.js → index-LX9pJxm_.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B40dQn0G.js → index-OI_fXWx0.js} +3 -3
  132. package/src/assets/web-panel/assets/{index-FJ3zC9LK.js → index-eDTOX8Xj.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DdefYBSw.js → index-gWKDsTzF.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CpumS98o.js → index-q_GDUVAA.js} +1 -1
  135. package/src/assets/web-panel/assets/{initDefaultProps-D1oZNz0D.js → initDefaultProps-C61kZqEd.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-C8k6doMO.js → motion-DZnT5U1L.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-DJ4qSbYt.js → move-L8wzwbel.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-CdpJD85j.js → mtc-parser-DLdYSejc.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-B0V4slKA.js → omit-D53cbS59.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-Di5NiW1F.js → pickAttrs-Bbc5HPtu.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-B5OMHgEM.js → placementArrow-BkvmO860.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-C6U9IWql.js → responsiveObserve-u2y1ryS1.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-BMyTH3rN.js → slide-BBqj7svU.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-C7d6BG7Z.js → statusUtils-GN0mqu2d.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-CR50QnQy.js → styleChecker-BvwPKoBT.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-DBEeoMb8.js → useFlexGapSupport-CCt8tnfY.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-3r099cjv.js → useFs-DXAxl2SV.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-C5IYNdTK.js → usePersonalDataHub-DihlR2dj.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-DmEOLRHf.js → vnode-D7BOX2gi.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-DnpUiVCB.js → zoom-CVbO-nL7.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/command-help-index.json +4 -4
  153. package/src/commands/agent.js +3 -3
  154. package/src/commands/background-session.js +145 -0
  155. package/src/commands/mcp.js +244 -7
  156. package/src/commands/serve.js +1 -1
  157. package/src/commands/session-show.js +129 -0
  158. package/src/commands/session.js +97 -145
  159. package/src/commands/skill.js +87 -50
  160. package/src/data/changelog.json +40 -1
  161. package/src/gateways/ws/session-protocol.js +14 -4
  162. package/src/gateways/ws/ws-agent-handler.js +39 -1
  163. package/src/harness/jsonl-session-store.js +1547 -127
  164. package/src/harness/mcp-client.js +2690 -409
  165. package/src/harness/session-index.js +80 -80
  166. package/src/harness/session-list-index.js +210 -7
  167. package/src/lazy-dispatch.js +76 -8
  168. package/src/lib/abort-utils.js +68 -0
  169. package/src/lib/agent-core.js +1 -59
  170. package/src/lib/background-interaction-journal.js +2 -2
  171. package/src/lib/chat-core.js +24 -6
  172. package/src/lib/command-lifecycle-report.js +516 -0
  173. package/src/lib/cowork-mcp-tools.js +47 -2
  174. package/src/lib/cowork-task-runner.js +11 -3
  175. package/src/lib/doctor-checkup.js +9 -7
  176. package/src/lib/learning/skill-improver.js +21 -2
  177. package/src/lib/mcp-call-ledger-store.js +116 -3
  178. package/src/lib/mcp-call-ledger.js +59 -14
  179. package/src/lib/mcp-client.js +1 -0
  180. package/src/lib/mcp-stdio-environment.js +48 -0
  181. package/src/lib/mcp-stdio-executable-identity.js +1133 -0
  182. package/src/lib/mcp-stdio-execution-authority.js +363 -0
  183. package/src/lib/mcp-stdio-package-materialization.js +1424 -0
  184. package/src/lib/mcp-tool-metadata.js +436 -0
  185. package/src/lib/mcp-tool-result.js +367 -0
  186. package/src/lib/observability/index.js +71 -0
  187. package/src/lib/packer/native-update-state.js +979 -1
  188. package/src/lib/packer/pack-update-applier.js +1050 -125
  189. package/src/lib/packer/pkg-config-generator.js +1 -0
  190. package/src/lib/paths.js +53 -0
  191. package/src/lib/pr-link-ledger.js +8 -27
  192. package/src/lib/pr-link-store.js +26 -0
  193. package/src/lib/process-execution-broker/index.js +192 -35
  194. package/src/lib/process-execution-broker/platform-sandbox.js +291 -24
  195. package/src/lib/process-tree-termination.js +253 -0
  196. package/src/lib/recent-session.js +17 -17
  197. package/src/lib/secure-file-identity.js +47 -0
  198. package/src/lib/secure-fs.js +21 -2
  199. package/src/lib/session-anti-rollback-anchor.js +766 -0
  200. package/src/lib/session-host-lease.js +492 -0
  201. package/src/lib/session-host-snapshot.js +9 -5
  202. package/src/lib/session-persistence-failure.js +109 -0
  203. package/src/lib/session-picker.js +26 -3
  204. package/src/lib/session-projection.js +5 -1
  205. package/src/lib/session-search.js +25 -11
  206. package/src/lib/session-tail.js +31 -1
  207. package/src/lib/side-effect-ledger-store.js +2 -2
  208. package/src/lib/skill-budget.js +222 -0
  209. package/src/lib/skill-execution-authority.js +385 -0
  210. package/src/lib/skill-execution-identity.js +39 -2
  211. package/src/lib/skill-loader.js +322 -86
  212. package/src/lib/skill-mcp.js +43 -1
  213. package/src/lib/turn-binding-store.js +2 -2
  214. package/src/repl/agent-repl.js +483 -77
  215. package/src/repl/bg-dashboard.js +81 -28
  216. package/src/repl/chat-repl.js +77 -12
  217. package/src/runtime/agent-core.js +428 -113
  218. package/src/runtime/agent-runtime.js +26 -3
  219. package/src/runtime/cleanup-deadline.js +143 -0
  220. package/src/runtime/headless-runner.js +494 -149
  221. package/src/runtime/headless-stream.js +504 -75
  222. package/src/runtime/mcp-config.js +157 -10
  223. package/src/runtime/mcp-tool-search.js +0 -0
  224. package/src/runtime/output-backpressure.js +419 -0
  225. package/src/runtime/pipe-safety.js +56 -21
  226. package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +0 -1
  227. package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +0 -1
  228. package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +0 -1
  229. package/src/assets/web-panel/assets/Providers-uO-10aP1.js +0 -1
  230. package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +0 -1
  231. package/src/assets/web-panel/assets/index-0O5ePnUq.js +0 -1
  232. package/src/assets/web-panel/assets/index-ChAzPigF.js +0 -1
  233. package/src/lib/skill-process-broker.js +0 -85
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Durable, same-machine Skill execution authority.
3
+ *
4
+ * Every CLI process for the same OS user observes the same monotonically
5
+ * increasing generation, even when processes use different
6
+ * CHAINLESSCHAIN_HOME roots. Revocation is serialized by the canonical
7
+ * cross-process state lock in independent OS user security state and persisted
8
+ * with an atomic rename before any caller reports success. Active leases poll
9
+ * while they are alive, and every authority-sensitive transition also re-reads
10
+ * the store as a hard fence. Corruption, rollback observed by a live host, and
11
+ * lock/write failures fail closed.
12
+ */
13
+
14
+ import fs from "node:fs";
15
+ import path from "node:path";
16
+ import { randomUUID } from "node:crypto";
17
+ import { threadId } from "node:worker_threads";
18
+ import { getMachineSecurityAnchorDir } from "./paths.js";
19
+ import {
20
+ mutateSecurityStore,
21
+ readSecurityStore,
22
+ } from "./durable-security-store.js";
23
+
24
+ export const SKILL_EXECUTION_REVOKED_CODE = "CC_SKILL_EXECUTION_REVOKED";
25
+ export const SKILL_EXECUTION_AUTHORITY_UNAVAILABLE_CODE =
26
+ "CC_SKILL_EXECUTION_AUTHORITY_UNAVAILABLE";
27
+ export const SKILL_EXECUTION_AUTHORITY_ROLLBACK_CODE =
28
+ "CC_SKILL_EXECUTION_AUTHORITY_ROLLBACK";
29
+
30
+ const STORE_VERSION = 1;
31
+ const DEFAULT_POLL_INTERVAL_MS = 50;
32
+ const DEFAULT_REASON_CODE = "host-revocation";
33
+ const REASON_CODE_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
34
+ const defaultAuthorities = new Map();
35
+
36
+ function authorityError(code, message, cause, filePath) {
37
+ const error = new Error(message, cause ? { cause } : undefined);
38
+ error.name = "SkillExecutionAuthorityError";
39
+ error.code = code;
40
+ error.filePath = filePath;
41
+ return error;
42
+ }
43
+
44
+ export function skillExecutionRevokedError(generation, message) {
45
+ const error = new Error(
46
+ message || "Skill execution authorization was revoked by the host",
47
+ );
48
+ error.name = "AbortError";
49
+ error.code = SKILL_EXECUTION_REVOKED_CODE;
50
+ error.generation = String(generation);
51
+ return error;
52
+ }
53
+
54
+ function unavailableError(cause, filePath) {
55
+ return authorityError(
56
+ SKILL_EXECUTION_AUTHORITY_UNAVAILABLE_CODE,
57
+ "Skill execution authority is unavailable; execution is denied",
58
+ cause,
59
+ filePath,
60
+ );
61
+ }
62
+
63
+ function rollbackError(observed, current, filePath) {
64
+ const error = authorityError(
65
+ SKILL_EXECUTION_AUTHORITY_ROLLBACK_CODE,
66
+ `Skill execution authority generation rolled back from ${current} to ${observed}; execution is denied`,
67
+ null,
68
+ filePath,
69
+ );
70
+ error.observedGeneration = String(observed);
71
+ error.currentGeneration = String(current);
72
+ return error;
73
+ }
74
+
75
+ function parseGeneration(value, label) {
76
+ if (typeof value !== "string" || !/^(?:0|[1-9]\d*)$/.test(value)) {
77
+ throw new TypeError(`${label} must be a canonical non-negative integer`);
78
+ }
79
+ return BigInt(value);
80
+ }
81
+
82
+ function validateStore(store, { missing = false } = {}) {
83
+ if (missing && Object.keys(store).length === 0) {
84
+ return Object.freeze({ generation: 0n, events: Object.freeze([]) });
85
+ }
86
+ if (store.version !== STORE_VERSION) {
87
+ throw new TypeError(
88
+ `unsupported Skill execution authority version: ${String(store.version)}`,
89
+ );
90
+ }
91
+ const generation = parseGeneration(store.generation, "generation");
92
+ if (!Array.isArray(store.events)) {
93
+ throw new TypeError("events must be an array");
94
+ }
95
+
96
+ let previousGeneration = 0n;
97
+ for (const [index, event] of store.events.entries()) {
98
+ if (!event || typeof event !== "object" || Array.isArray(event)) {
99
+ throw new TypeError(`events[${index}] must be an object`);
100
+ }
101
+ const eventGeneration = parseGeneration(
102
+ event.generation,
103
+ `events[${index}].generation`,
104
+ );
105
+ const eventPrevious = parseGeneration(
106
+ event.previousGeneration,
107
+ `events[${index}].previousGeneration`,
108
+ );
109
+ if (
110
+ eventPrevious !== previousGeneration ||
111
+ eventGeneration !== previousGeneration + 1n
112
+ ) {
113
+ throw new TypeError(`events[${index}] breaks the generation chain`);
114
+ }
115
+ if (typeof event.eventId !== "string" || event.eventId.length === 0) {
116
+ throw new TypeError(
117
+ `events[${index}].eventId must be a non-empty string`,
118
+ );
119
+ }
120
+ if (
121
+ typeof event.revokedAt !== "string" ||
122
+ !Number.isFinite(Date.parse(event.revokedAt))
123
+ ) {
124
+ throw new TypeError(
125
+ `events[${index}].revokedAt must be an ISO timestamp`,
126
+ );
127
+ }
128
+ if (!Number.isSafeInteger(event.actorPid) || event.actorPid <= 0) {
129
+ throw new TypeError(`events[${index}].actorPid must be a positive PID`);
130
+ }
131
+ if (!Number.isSafeInteger(event.actorThreadId) || event.actorThreadId < 0) {
132
+ throw new TypeError(
133
+ `events[${index}].actorThreadId must be a non-negative integer`,
134
+ );
135
+ }
136
+ if (
137
+ typeof event.reasonCode !== "string" ||
138
+ !REASON_CODE_PATTERN.test(event.reasonCode)
139
+ ) {
140
+ throw new TypeError(`events[${index}].reasonCode is invalid`);
141
+ }
142
+ previousGeneration = eventGeneration;
143
+ }
144
+ if (previousGeneration !== generation) {
145
+ throw new TypeError("generation does not match the durable event chain");
146
+ }
147
+ return Object.freeze({
148
+ generation,
149
+ events: Object.freeze([...store.events]),
150
+ });
151
+ }
152
+
153
+ function safeReasonCode(options) {
154
+ try {
155
+ const candidate = options?.reasonCode;
156
+ if (typeof candidate === "string" && REASON_CODE_PATTERN.test(candidate)) {
157
+ return candidate;
158
+ }
159
+ } catch {
160
+ // Diagnostic metadata cannot prevent an emergency restriction.
161
+ }
162
+ return DEFAULT_REASON_CODE;
163
+ }
164
+
165
+ function safeMessage(options) {
166
+ try {
167
+ const candidate = options?.message;
168
+ if (typeof candidate === "string" && candidate.length > 0) return candidate;
169
+ } catch {
170
+ // Diagnostic metadata cannot prevent an emergency restriction.
171
+ }
172
+ return undefined;
173
+ }
174
+
175
+ export function getSkillExecutionAuthorityPath() {
176
+ return path.join(
177
+ getMachineSecurityAnchorDir(),
178
+ "skill-execution-authority-v1.json",
179
+ );
180
+ }
181
+
182
+ export class DurableSkillExecutionAuthority {
183
+ constructor({
184
+ filePath = getSkillExecutionAuthorityPath(),
185
+ pollIntervalMs = DEFAULT_POLL_INTERVAL_MS,
186
+ now = () => Date.now(),
187
+ createEventId = randomUUID,
188
+ lockOptions,
189
+ } = {}) {
190
+ if (!path.isAbsolute(filePath)) {
191
+ throw new TypeError("Skill execution authority path must be absolute");
192
+ }
193
+ this.filePath = path.resolve(filePath);
194
+ this.pollIntervalMs = Math.max(10, Number(pollIntervalMs) || 0);
195
+ this._now = now;
196
+ this._createEventId = createEventId;
197
+ this._lockOptions = lockOptions;
198
+ this._generation = 0n;
199
+ this._activeLeases = new Set();
200
+ this._pollTimer = null;
201
+ }
202
+
203
+ _abortActive(errorFactory) {
204
+ let interruptedLeases = 0;
205
+ for (const lease of [...this._activeLeases]) {
206
+ this._activeLeases.delete(lease);
207
+ if (lease.controller.signal.aborted) continue;
208
+ interruptedLeases += 1;
209
+ lease.controller.abort(errorFactory());
210
+ }
211
+ this._stopPollingIfIdle();
212
+ return interruptedLeases;
213
+ }
214
+
215
+ _failClosed(cause) {
216
+ const error =
217
+ cause?.code === SKILL_EXECUTION_AUTHORITY_ROLLBACK_CODE
218
+ ? cause
219
+ : unavailableError(cause, this.filePath);
220
+ this._abortActive(() => error);
221
+ return error;
222
+ }
223
+
224
+ _observeGeneration(generation, message) {
225
+ if (generation < this._generation) {
226
+ throw this._failClosed(
227
+ rollbackError(generation, this._generation, this.filePath),
228
+ );
229
+ }
230
+ if (generation === this._generation) return 0;
231
+ this._generation = generation;
232
+ return this._abortActive(() =>
233
+ skillExecutionRevokedError(generation, message),
234
+ );
235
+ }
236
+
237
+ _readSnapshot() {
238
+ let existed;
239
+ try {
240
+ existed = fs.existsSync(this.filePath);
241
+ return validateStore(
242
+ readSecurityStore(this.filePath, "Skill execution authority"),
243
+ { missing: !existed },
244
+ );
245
+ } catch (cause) {
246
+ throw this._failClosed(cause);
247
+ }
248
+ }
249
+
250
+ readGeneration() {
251
+ const snapshot = this._readSnapshot();
252
+ this._observeGeneration(snapshot.generation);
253
+ return this._generation;
254
+ }
255
+
256
+ assertGeneration(expectedGeneration) {
257
+ const current = this.readGeneration();
258
+ if (expectedGeneration !== current) {
259
+ throw skillExecutionRevokedError(current);
260
+ }
261
+ return current;
262
+ }
263
+
264
+ _startPolling() {
265
+ if (this._pollTimer || this._activeLeases.size === 0) return;
266
+ this._pollTimer = setInterval(() => {
267
+ if (this._activeLeases.size === 0) {
268
+ this._stopPollingIfIdle();
269
+ return;
270
+ }
271
+ try {
272
+ this.readGeneration();
273
+ } catch {
274
+ // readGeneration already failed closed and aborted every active lease.
275
+ }
276
+ }, this.pollIntervalMs);
277
+ this._pollTimer.unref?.();
278
+ }
279
+
280
+ _stopPollingIfIdle() {
281
+ if (this._activeLeases.size !== 0 || !this._pollTimer) return;
282
+ clearInterval(this._pollTimer);
283
+ this._pollTimer = null;
284
+ }
285
+
286
+ acquireLease({ skillId = "unknown" } = {}) {
287
+ const generation = this.readGeneration();
288
+ const controller = new AbortController();
289
+ const record = { controller, generation, skillId: String(skillId) };
290
+ this._activeLeases.add(record);
291
+ this._startPolling();
292
+
293
+ try {
294
+ const confirmedGeneration = this.readGeneration();
295
+ if (confirmedGeneration !== generation) {
296
+ throw (
297
+ controller.signal.reason ||
298
+ skillExecutionRevokedError(confirmedGeneration)
299
+ );
300
+ }
301
+ } catch (error) {
302
+ this._activeLeases.delete(record);
303
+ this._stopPollingIfIdle();
304
+ throw error;
305
+ }
306
+
307
+ let released = false;
308
+ return Object.freeze({
309
+ generation,
310
+ signal: controller.signal,
311
+ abort: (reason) => {
312
+ if (!controller.signal.aborted) controller.abort(reason);
313
+ },
314
+ release: () => {
315
+ if (released) return;
316
+ released = true;
317
+ this._activeLeases.delete(record);
318
+ this._stopPollingIfIdle();
319
+ },
320
+ });
321
+ }
322
+
323
+ revoke(options = {}) {
324
+ const message = safeMessage(options);
325
+ const reasonCode = safeReasonCode(options);
326
+ let generation;
327
+ try {
328
+ generation = mutateSecurityStore(
329
+ this.filePath,
330
+ "Skill execution authority",
331
+ (draft) => {
332
+ const snapshot = validateStore(draft, {
333
+ missing: !fs.existsSync(this.filePath),
334
+ });
335
+ if (snapshot.generation < this._generation) {
336
+ throw rollbackError(
337
+ snapshot.generation,
338
+ this._generation,
339
+ this.filePath,
340
+ );
341
+ }
342
+ const nextGeneration = snapshot.generation + 1n;
343
+ draft.version = STORE_VERSION;
344
+ draft.generation = String(nextGeneration);
345
+ draft.events = [
346
+ ...snapshot.events,
347
+ {
348
+ eventId: String(this._createEventId()),
349
+ generation: String(nextGeneration),
350
+ previousGeneration: String(snapshot.generation),
351
+ revokedAt: new Date(this._now()).toISOString(),
352
+ actorPid: process.pid,
353
+ actorThreadId: threadId,
354
+ reasonCode,
355
+ },
356
+ ];
357
+ return nextGeneration;
358
+ },
359
+ this._lockOptions,
360
+ );
361
+ } catch (cause) {
362
+ throw this._failClosed(cause);
363
+ }
364
+
365
+ const interruptedLeases = this._observeGeneration(generation, message);
366
+ return Object.freeze({
367
+ code: SKILL_EXECUTION_REVOKED_CODE,
368
+ generation: String(generation),
369
+ interruptedLeases,
370
+ authorityPath: this.filePath,
371
+ propagationIntervalMs: this.pollIntervalMs,
372
+ });
373
+ }
374
+ }
375
+
376
+ export function getSkillExecutionAuthority(options = {}) {
377
+ if (options.filePath) return new DurableSkillExecutionAuthority(options);
378
+ const filePath = path.resolve(getSkillExecutionAuthorityPath());
379
+ let authority = defaultAuthorities.get(filePath);
380
+ if (!authority) {
381
+ authority = new DurableSkillExecutionAuthority({ ...options, filePath });
382
+ defaultAuthorities.set(filePath, authority);
383
+ }
384
+ return authority;
385
+ }
@@ -1,6 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import {
5
+ assertSkillFileSize,
6
+ assertSkillTotalSize,
7
+ resolveSkillLimits,
8
+ } from "./skill-budget.js";
4
9
 
5
10
  export const SKILL_EXECUTION_IDENTITY_VERSION = 1;
6
11
 
@@ -56,6 +61,12 @@ function readStableRegularFile(file, options = {}) {
56
61
  );
57
62
  }
58
63
 
64
+ assertSkillFileSize(
65
+ options.component || path.basename(file),
66
+ before.size,
67
+ options.limits,
68
+ );
69
+
59
70
  const bytes = fs.readFileSync(file);
60
71
  const after = fs.lstatSync(file);
61
72
  if (
@@ -68,6 +79,11 @@ function readStableRegularFile(file, options = {}) {
68
79
  `Skill component changed while its identity was being captured: ${path.basename(file)}`,
69
80
  );
70
81
  }
82
+ assertSkillFileSize(
83
+ options.component || path.basename(file),
84
+ bytes.length,
85
+ options.limits,
86
+ );
71
87
  return Object.freeze({
72
88
  bytes,
73
89
  size: bytes.length,
@@ -85,10 +101,22 @@ export function captureSkillExecutionSnapshot(options = {}) {
85
101
  throw new TypeError("captureSkillExecutionSnapshot requires skillDir");
86
102
  }
87
103
  const rootRealPath = canonicalRealPath(options.skillDir);
104
+ const limits = resolveSkillLimits(options.limits);
88
105
  const skillMdPath = path.join(rootRealPath, "SKILL.md");
89
106
  const handlerPath = path.join(rootRealPath, "handler.js");
90
- const skillMd = readStableRegularFile(skillMdPath);
91
- const handler = readStableRegularFile(handlerPath, { optional: true });
107
+ const skillMd = readStableRegularFile(skillMdPath, {
108
+ component: "SKILL.md",
109
+ limits,
110
+ });
111
+ const handler = readStableRegularFile(handlerPath, {
112
+ optional: true,
113
+ component: "handler.js",
114
+ limits,
115
+ });
116
+ const componentBytes = assertSkillTotalSize(
117
+ skillMd.size + (handler?.size || 0),
118
+ limits,
119
+ );
92
120
  const skillId = String(options.skillId || path.basename(rootRealPath));
93
121
  const source = String(options.source || "unknown");
94
122
  const identityDigest = sha256([
@@ -112,6 +140,12 @@ export function captureSkillExecutionSnapshot(options = {}) {
112
140
  rootRealPath,
113
141
  handlerPresent: handler !== null,
114
142
  skillFileBytes: skillMd.size,
143
+ componentFileCount: handler === null ? 1 : 2,
144
+ componentBytes,
145
+ componentSizes: Object.freeze({
146
+ "SKILL.md": skillMd.size,
147
+ "handler.js": handler ? handler.size : null,
148
+ }),
115
149
  componentDigests: Object.freeze({
116
150
  "SKILL.md": skillMd.digest,
117
151
  "handler.js": handler?.digest || null,
@@ -130,6 +164,9 @@ export function executionIdentityMetadata(snapshot) {
130
164
  contentDigest: snapshot.contentDigest,
131
165
  rootRealPath: snapshot.rootRealPath,
132
166
  handlerPresent: snapshot.handlerPresent,
167
+ componentFileCount: snapshot.componentFileCount,
168
+ componentBytes: snapshot.componentBytes,
169
+ componentSizes: Object.freeze({ ...snapshot.componentSizes }),
133
170
  componentDigests: Object.freeze({ ...snapshot.componentDigests }),
134
171
  });
135
172
  }