chainlesschain 0.162.193 → 0.162.198

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 (215) hide show
  1. package/README.md +29 -6
  2. package/completions/_cc +2 -2
  3. package/completions/cc.bash +2 -2
  4. package/completions/cc.fish +2 -2
  5. package/completions/cc.ps1 +2 -2
  6. package/package.json +1 -1
  7. package/src/assets/web-panel/assets/{AIOps-DBLkaTje.js → AIOps-CSN-D2xb.js} +1 -1
  8. package/src/assets/web-panel/assets/{ActionButton-BAy-Qebo.js → ActionButton-CBSMlGzv.js} +1 -1
  9. package/src/assets/web-panel/assets/{Analytics-Dfb1Mlau.js → Analytics-3yr3Nt2t.js} +3 -3
  10. package/src/assets/web-panel/assets/{AppLayout-BbFkN8m0.js → AppLayout-1b-o3lMH.js} +4 -4
  11. package/src/assets/web-panel/assets/{Artifacts-kM4-cEEH.js → Artifacts-Dr8rJi17.js} +1 -1
  12. package/src/assets/web-panel/assets/{Audit-BSQfYWf3.js → Audit-2V689HC2.js} +1 -1
  13. package/src/assets/web-panel/assets/{BackgroundAgents-CWDbI_fG.js → BackgroundAgents-DIxkNrD_.js} +1 -1
  14. package/src/assets/web-panel/assets/{Backup-BxLPbq_Q.js → Backup-Pg6BcwrE.js} +1 -1
  15. package/src/assets/web-panel/assets/{BaseInput-DuIbdrp6.js → BaseInput-CLUpqyfH.js} +1 -1
  16. package/src/assets/web-panel/assets/{Chat-NEmjGahU.js → Chat-qVS8rD4G.js} +5 -5
  17. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DfJEo-5_.js → ChatBubbleRenderer-ti49X12Q.js} +1 -1
  18. package/src/assets/web-panel/assets/{Checkbox-CaoeG3Ns.js → Checkbox-Bs9AaEay.js} +1 -1
  19. package/src/assets/web-panel/assets/{Codegen-BFf_g3xY.js → Codegen-Dvc1mq8q.js} +1 -1
  20. package/src/assets/web-panel/assets/{Col-CNOd8mdQ.js → Col-C4_biO7A.js} +1 -1
  21. package/src/assets/web-panel/assets/{Community-BhpDqz-i.js → Community-al25XQUV.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compact-CQ42T7Z6.js → Compact-D-ZDB8M1.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compliance-DI5PcLMN.js → Compliance-6lIfDz1W.js} +1 -1
  24. package/src/assets/web-panel/assets/{Cowork-wYYZe0wR.js → Cowork-DdI48XMJ.js} +3 -3
  25. package/src/assets/web-panel/assets/{Cron-Dlq03DD_.js → Cron-DF5HZd2g.js} +2 -2
  26. package/src/assets/web-panel/assets/{Crosschain-BzqS8PP3.js → Crosschain-DuxeSvt3.js} +1 -1
  27. package/src/assets/web-panel/assets/{DID-It55Yem7.js → DID-B9yHkUTd.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dashboard-9HkH6oxn.js → Dashboard-Z5EuI3IM.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dropdown-00e2YWRB.js → Dropdown-vuRfO3dY.js} +1 -1
  30. package/src/assets/web-panel/assets/{EmailListRenderer-By-ugRDL.js → EmailListRenderer-QFLCc1uL.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C396yu5m.js → FamilyGuardDashboard-BZ7EXkFJ.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-BME5sbZY.js → Federation-DycIEg2s.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-B4TEZCr-.js → FormItemContext-Ba0H_7yG.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-_9CX9ieY.js → GenericCardRenderer--JgSTK-C.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-BrS6WVSr.js → Git-DEvTbldE.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-BMdCWnKF.js → Governance-BJIljy18.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-Bcp3vzcA.js → Inference-CVyW3G3q.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-DlLuqGY5.js → KnowledgeGraph-v8-borge.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-D-W_6x09.js → Logs-BCdS7gGo.js} +2 -2
  40. package/src/assets/web-panel/assets/{MarkdownRenderer-DElGPxCZ.js → MarkdownRenderer-CU-JB2Ns.js} +1 -1
  41. package/src/assets/web-panel/assets/{Marketplace-Dzn2guvI.js → Marketplace-AN6tGA2B.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-uPict-KL.js → McpTools-DGViXASN.js} +6 -6
  43. package/src/assets/web-panel/assets/{Memory-BCw43kOb.js → Memory-Bpvmx9X4.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-DmV8Wv7F.js → MobileBridge-CTP-DOTC.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-C-HaCmSM.js → MobileProjects-C8qfktxn.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-C6jxJ34Y.js → Mtc-ndYr0M1s.js} +5 -5
  47. package/src/assets/web-panel/assets/{MtcAudit-Za8ExwhQ.js → MtcAudit-Ci0-YK7W.js} +5 -5
  48. package/src/assets/web-panel/assets/{Multisig-KKDbuEgb.js → Multisig-BehSTFW7.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-Dj97zbCk.js → NLProgramming-B91_YBLv.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-DBXvMraU.js → Notes-BQlJ0-gq.js} +4 -4
  51. package/src/assets/web-panel/assets/{NotificationSettings-DOxITLYl.js → NotificationSettings-CDgYMjYK.js} +1 -1
  52. package/src/assets/web-panel/assets/{OrderTableRenderer-7DVjZwMM.js → OrderTableRenderer-BJkSlKeH.js} +1 -1
  53. package/src/assets/web-panel/assets/{Organization-D1i73mjb.js → Organization-B-b3cWCp.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-kW6Q3rvg.js → Overflow-CILUL4nL.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P-C-v_8p2v.js → P2P-BTCFBkF0.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-tUbbY64W.js → PdhVaultBrowser-BAR6AUx5.js} +5 -5
  57. package/src/assets/web-panel/assets/{Permissions-DkHxEZ58.js → Permissions-RRf6HbWJ.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-DWuMPGrK.js → PersonalDataHub-BGTMiICa.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-30IYXWWm.js → Pipeline-945qY9YF.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-DZNQ4RrH.js → Privacy-DPZwI6lJ.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-De2MCElf.js → ProjectInit-BPH2NRKc.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-5uHk9wsC.js → ProjectSettings-BZCRNCvb.js} +2 -2
  63. package/src/assets/web-panel/assets/{Projects-XjDfrFLb.js → Projects-BTI__tBt.js} +1 -1
  64. package/src/assets/web-panel/assets/{Providers-Bgwj6gcE.js → Providers-DDCf_nIw.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-gKql9umv.js → QrScannerModal-N6rbqt1r.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-BWvmwkh7.js → QuickAsk-DrwjPS7M.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-Uok4hZPd.js → Recommend-Cog9Wd99.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-DLJzTk9a.js → RemoteSession-DC9pynjM.js} +3 -3
  69. package/src/assets/web-panel/assets/{Reputation-ZVwIPMSO.js → Reputation-D4th4gKS.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-CN04HxWR.js → Row-ogiWR6v9.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-BdSrEG4g.js → RssFeed-uYlk-2Oj.js} +3 -3
  72. package/src/assets/web-panel/assets/{Search-5PwVd0IR.js → Search-DYzzwvtM.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-DdBo4zjN.js → Security-Da7YOyX6.js} +4 -4
  74. package/src/assets/web-panel/assets/{Services-D3letU7M.js → Services-CLI1VM1X.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton--Jb83f1v.js → Skeleton-DK77dzDC.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-Bg-CulHX.js → Skills-C_z7Lmhl.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-7QOa7S-X.js → Sla-D6413Q8L.js} +1 -1
  78. package/src/assets/web-panel/assets/{SpeechSettings-DQwppjRw.js → SpeechSettings-C07ydbj2.js} +1 -1
  79. package/src/assets/web-panel/assets/{SyncSettings-dNPQGL-s.js → SyncSettings-DGOm2W22.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-Ggs-Z48q.js → Tasks-Cr_PVyLM.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-78TYHgRO.js → Templates-BhL2mZ0t.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-xHwwv9vO.js → Tenant-CPk5oyUr.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-BJXSJfm4.js → Terminal-ClhqUsqV.js} +2 -2
  84. package/src/assets/web-panel/assets/{TimelineRenderer-fLbjRhJw.js → TimelineRenderer-BCC7MV5a.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-oMSBSBmB.js → Tokens-DD1Jt4oO.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-CfnY_wX_.js → Trigger-BCydFvN2.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-AdyTgYKO.js → Trust-DDHT1noa.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-C5K_81dS.js → UkeySign-CWPZC7oI.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-vcGVDqki.js → VideoEditing-9Ea0nJR0.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-hhOc3hlY.js → Wallet-BjxhLxTf.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-CVloC11s.js → WebAuthn-C6uCye67.js} +4 -4
  92. package/src/assets/web-panel/assets/{WorkflowEditor-CYeE32R5.js → WorkflowEditor-d2g4reYo.js} +1 -1
  93. package/src/assets/web-panel/assets/{chat-CNROR5bN.js → chat-frTc6ScX.js} +1 -1
  94. package/src/assets/web-panel/assets/{colors-Cjx-cnwU.js → colors-B5K6lG3v.js} +1 -1
  95. package/src/assets/web-panel/assets/{compact-item-DOIfelvD.js → compact-item-Cdn46r8D.js} +1 -1
  96. package/src/assets/web-panel/assets/{createContext-DfA7UZ8u.js → createContext-DU1jqVQi.js} +1 -1
  97. package/src/assets/web-panel/assets/devWarning-CP-jEUyw.js +1 -0
  98. package/src/assets/web-panel/assets/{hasIn-BMSCzcfM.js → hasIn-DdNH-aW_.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CAnvhwg6.js → index-32ajXmTb.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BEMwBBHk.js → index-7ehytj1K.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CVL27kXC.js → index-BC4eGkar.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-FBc_CJBd.js → index-BVLL-mq_.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-dCd8cSUq.js → index-BXKhhx9V.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BemJ2u_E.js → index-BcGwGIaR.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CVm1_i3t.js → index-Be4OtL-N.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Cs6l7uRu.js → index-BoFak7le.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DPAWBrMf.js → index-BwlIxAmX.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DLmn0BoK.js → index-CGiwfwB9.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-B7gf77CJ.js → index-CHmkkdfT.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-m2vG9gG_.js → index-CQorP1Ng.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-ClNMrqEY.js → index-CUoNAmE8.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DHtpHZAQ.js → index-Cj6P9Nst.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C2K9SNVX.js → index-CtRPi4YC.js} +1 -1
  114. package/src/assets/web-panel/assets/index-CzrCHrFy.js +1 -0
  115. package/src/assets/web-panel/assets/{index-BolaOQxx.js → index-D1qIC4GR.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BM1y_9hM.js → index-D23xGYjM.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Cyweh0Hy.js → index-D4l82Me1.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-By61ojUx.js → index-D4miNkWv.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BbQ2eQ8H.js → index-DIVyTmZ3.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Icdoqmzt.js → index-DM5FmPZU.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DjEsxO5h.js → index-DRzBBdQ0.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B4iYzpkL.js → index-Dca_i7H8.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-C3L5gdiD.js → index-DftZuyA7.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CdYBye8B.js → index-DtBCCkC4.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-AWg-0M1S.js → index-HjCvXHf5.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CEKMcOyU.js → index-LaivuXyF.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BxOk9vkG.js → index-MM4Zz2OE.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CNC5onm4.js → index-NmEXVjzt.js} +1 -1
  129. package/src/assets/web-panel/assets/index-OJsGskZw.js +1 -0
  130. package/src/assets/web-panel/assets/{index-BUonmKSE.js → index-PjAS0sIZ.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B5Udeb_6.js → index-VDM2KKo9.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-5-HXgOX5.js → index-cYaWV4Mq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DBpWXFed.js → index-gg3QPC3i.js} +3 -3
  134. package/src/assets/web-panel/assets/{index-C7xn0Nub.js → index-kVO_MDm-.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-ti_lnTWl.js → index-mgU3Q-lN.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CshQbilz.js → index-t_OBzIP4.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-mTpHoEzr.js → index-yZRuZpwK.js} +1 -1
  138. package/src/assets/web-panel/assets/{initDefaultProps-Bu8k7H1Y.js → initDefaultProps-DwLTRNdo.js} +1 -1
  139. package/src/assets/web-panel/assets/{motion-s3iVK41k.js → motion-BchZDXnh.js} +1 -1
  140. package/src/assets/web-panel/assets/{move-B6B-E5Jz.js → move-e8M-zZFl.js} +1 -1
  141. package/src/assets/web-panel/assets/{mtc-parser-BiYgTidA.js → mtc-parser-Ci40fQb3.js} +1 -1
  142. package/src/assets/web-panel/assets/{omit-pU1RdUDA.js → omit-C7110_f2.js} +1 -1
  143. package/src/assets/web-panel/assets/{pickAttrs-Cdoq_SeM.js → pickAttrs-skteMgnM.js} +1 -1
  144. package/src/assets/web-panel/assets/{placementArrow-DIuvAn2K.js → placementArrow-MGZ-lh2B.js} +1 -1
  145. package/src/assets/web-panel/assets/{responsiveObserve-8w16YR2D.js → responsiveObserve-N4Sd7uy-.js} +1 -1
  146. package/src/assets/web-panel/assets/{slide-VZ01cZe3.js → slide-C7HDGRaa.js} +1 -1
  147. package/src/assets/web-panel/assets/{statusUtils-lh8YMN8Z.js → statusUtils-BhRexlgy.js} +1 -1
  148. package/src/assets/web-panel/assets/{styleChecker-CmDyreec.js → styleChecker-ChEoQkN2.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFlexGapSupport-hiJWMU5y.js → useFlexGapSupport-CDbG1s2Y.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFs-Thnu-Iaj.js → useFs-CUIx0tcJ.js} +1 -1
  151. package/src/assets/web-panel/assets/{usePersonalDataHub-LBdOxjwY.js → usePersonalDataHub-bkO7L7ec.js} +1 -1
  152. package/src/assets/web-panel/assets/{vnode-Cg6lFY_X.js → vnode-B_ZvABIG.js} +1 -1
  153. package/src/assets/web-panel/assets/{zoom-DVfsR1YO.js → zoom-D5shjpS8.js} +1 -1
  154. package/src/assets/web-panel/index.html +1 -1
  155. package/src/command-help-index.json +4 -4
  156. package/src/command-manifest.json +214 -50
  157. package/src/command-surface-policy.js +115 -0
  158. package/src/commands/agent.js +3 -3
  159. package/src/commands/background-session.js +145 -0
  160. package/src/commands/mcp.js +125 -7
  161. package/src/commands/serve.js +1 -1
  162. package/src/commands/session-show.js +131 -0
  163. package/src/commands/session.js +50 -106
  164. package/src/commands/skill.js +87 -50
  165. package/src/data/changelog.json +18 -5
  166. package/src/gateways/ws/ws-agent-handler.js +8 -1
  167. package/src/harness/jsonl-session-store.js +428 -25
  168. package/src/harness/mcp-client.js +2652 -404
  169. package/src/harness/session-list-index.js +65 -7
  170. package/src/lazy-dispatch.js +76 -8
  171. package/src/lib/abort-utils.js +68 -0
  172. package/src/lib/agent-core.js +1 -59
  173. package/src/lib/chat-core.js +24 -6
  174. package/src/lib/cowork-mcp-tools.js +47 -2
  175. package/src/lib/cowork-task-runner.js +11 -3
  176. package/src/lib/doctor-checkup.js +9 -7
  177. package/src/lib/learning/skill-improver.js +21 -2
  178. package/src/lib/mcp-call-ledger-store.js +116 -3
  179. package/src/lib/mcp-call-ledger.js +59 -14
  180. package/src/lib/mcp-client.js +1 -0
  181. package/src/lib/mcp-stdio-executable-identity.js +598 -0
  182. package/src/lib/mcp-stdio-execution-authority.js +363 -0
  183. package/src/lib/mcp-tool-metadata.js +436 -0
  184. package/src/lib/mcp-tool-result.js +367 -0
  185. package/src/lib/observability/index.js +71 -0
  186. package/src/lib/pr-link-ledger.js +8 -27
  187. package/src/lib/pr-link-store.js +26 -0
  188. package/src/lib/process-execution-broker/index.js +14 -0
  189. package/src/lib/process-tree-termination.js +253 -0
  190. package/src/lib/public-ide-capability-manifest.js +6 -0
  191. package/src/lib/session-host-snapshot.js +9 -5
  192. package/src/lib/session-projection.js +5 -1
  193. package/src/lib/session-tail.js +31 -1
  194. package/src/lib/skill-budget.js +222 -0
  195. package/src/lib/skill-execution-authority.js +381 -0
  196. package/src/lib/skill-execution-identity.js +39 -2
  197. package/src/lib/skill-loader.js +322 -86
  198. package/src/lib/skill-mcp.js +43 -1
  199. package/src/repl/agent-repl.js +349 -46
  200. package/src/repl/bg-dashboard.js +81 -28
  201. package/src/repl/chat-repl.js +77 -12
  202. package/src/repl/prompt-interactions.js +67 -7
  203. package/src/repl/slash-command-registry.js +3 -4
  204. package/src/runtime/agent-core.js +340 -108
  205. package/src/runtime/agent-runtime.js +26 -3
  206. package/src/runtime/headless-runner.js +150 -23
  207. package/src/runtime/headless-stream.js +309 -59
  208. package/src/runtime/mcp-config.js +157 -10
  209. package/src/runtime/mcp-tool-search.js +0 -0
  210. package/src/runtime/output-backpressure.js +366 -0
  211. package/src/runtime/pipe-safety.js +56 -21
  212. package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +0 -1
  213. package/src/assets/web-panel/assets/index-Q2IajL54.js +0 -1
  214. package/src/assets/web-panel/assets/index-bRkHgOMc.js +0 -1
  215. package/src/lib/skill-process-broker.js +0 -85
@@ -0,0 +1,367 @@
1
+ import { isProxy } from "node:util/types";
2
+
3
+ // Final tools/call results cross several amplification boundaries after the
4
+ // transport frame is parsed: ledger hashing, stream projection, session/model
5
+ // serialization, and direct IDE/host consumers. Admit one strict JSON snapshot
6
+ // under a smaller result-specific budget before any of those consumers run.
7
+
8
+ export const MCP_TOOL_RESULT_LIMITS = Object.freeze({
9
+ maxBytes: 1024 * 1024,
10
+ maxDepth: 64,
11
+ maxNodes: 50_000,
12
+ });
13
+
14
+ const MCP_TOOL_RESULT_ERROR_CODES = new Set([
15
+ "CC_MCP_TOOL_RESULT_INVALID",
16
+ "CC_MCP_TOOL_RESULT_TOO_LARGE",
17
+ "CC_MCP_TOOL_RESULT_DEPTH_EXCEEDED",
18
+ "CC_MCP_TOOL_RESULT_NODES_EXCEEDED",
19
+ ]);
20
+
21
+ const admittedToolResults = new WeakMap();
22
+
23
+ function tightenedLimit(configured, ceiling) {
24
+ if (Number.isFinite(configured) && configured > 0) {
25
+ return Math.min(ceiling, Math.max(1, Math.floor(configured)));
26
+ }
27
+ return ceiling;
28
+ }
29
+
30
+ export function resolveMcpToolResultLimits(config = {}) {
31
+ return Object.freeze({
32
+ maxBytes: tightenedLimit(
33
+ config?.maxToolResultBytes,
34
+ MCP_TOOL_RESULT_LIMITS.maxBytes,
35
+ ),
36
+ maxDepth: tightenedLimit(
37
+ config?.maxToolResultDepth,
38
+ MCP_TOOL_RESULT_LIMITS.maxDepth,
39
+ ),
40
+ maxNodes: tightenedLimit(
41
+ config?.maxToolResultNodes,
42
+ MCP_TOOL_RESULT_LIMITS.maxNodes,
43
+ ),
44
+ });
45
+ }
46
+
47
+ function resultError(code, message, details = {}) {
48
+ const error = new Error(message);
49
+ error.name = "McpToolResultAdmissionError";
50
+ error.code = code;
51
+ error.dispatched = true;
52
+ error.outcomeUnknown = true;
53
+ error.retryable = false;
54
+ if (details.limitBytes != null) error.limitBytes = details.limitBytes;
55
+ if (details.limitDepth != null) error.limitDepth = details.limitDepth;
56
+ if (details.limitNodes != null) error.limitNodes = details.limitNodes;
57
+ return error;
58
+ }
59
+
60
+ export function isMcpToolResultAdmissionError(error) {
61
+ if (!error || typeof error !== "object") return false;
62
+ try {
63
+ if (isProxy(error)) return false;
64
+ const descriptor = Object.getOwnPropertyDescriptor(error, "code");
65
+ return Boolean(
66
+ descriptor &&
67
+ Object.hasOwn(descriptor, "value") &&
68
+ MCP_TOOL_RESULT_ERROR_CODES.has(descriptor.value),
69
+ );
70
+ } catch {
71
+ return false;
72
+ }
73
+ }
74
+
75
+ function denseArraySnapshot(value) {
76
+ if (!value || typeof value !== "object") return null;
77
+ try {
78
+ if (isProxy(value) || !Array.isArray(value)) return null;
79
+ const length = Object.getOwnPropertyDescriptor(value, "length")?.value;
80
+ if (!Number.isSafeInteger(length) || length < 0) return null;
81
+ const keys = Reflect.ownKeys(value);
82
+ if (
83
+ keys.length !== length + 1 ||
84
+ keys.some((key) => typeof key === "symbol")
85
+ ) {
86
+ return null;
87
+ }
88
+ const descriptors = [];
89
+ for (let index = 0; index < length; index += 1) {
90
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
91
+ if (
92
+ !descriptor ||
93
+ !Object.hasOwn(descriptor, "value") ||
94
+ descriptor.enumerable !== true
95
+ ) {
96
+ return null;
97
+ }
98
+ descriptors.push(descriptor);
99
+ }
100
+ return descriptors;
101
+ } catch {
102
+ return null;
103
+ }
104
+ }
105
+
106
+ function plainObjectSnapshot(value) {
107
+ if (!value || typeof value !== "object") return null;
108
+ try {
109
+ if (isProxy(value) || Array.isArray(value)) return null;
110
+ const prototype = Object.getPrototypeOf(value);
111
+ if (prototype !== Object.prototype && prototype !== null) return null;
112
+ const keys = Reflect.ownKeys(value);
113
+ if (keys.some((key) => typeof key === "symbol")) return null;
114
+ const descriptors = Object.create(null);
115
+ for (const key of keys) {
116
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
117
+ if (
118
+ !descriptor ||
119
+ !Object.hasOwn(descriptor, "value") ||
120
+ descriptor.enumerable !== true
121
+ ) {
122
+ return null;
123
+ }
124
+ descriptors[key] = descriptor;
125
+ }
126
+ return { keys, descriptors };
127
+ } catch {
128
+ return null;
129
+ }
130
+ }
131
+
132
+ function boundedJsonStringBytes(value, available) {
133
+ let bytes = 2;
134
+ if (bytes > available) return available + 1;
135
+ for (let index = 0; index < value.length; index += 1) {
136
+ const code = value.charCodeAt(index);
137
+ if (code === 0x22 || code === 0x5c) {
138
+ bytes += 2;
139
+ } else if (
140
+ code === 0x08 ||
141
+ code === 0x09 ||
142
+ code === 0x0a ||
143
+ code === 0x0c ||
144
+ code === 0x0d
145
+ ) {
146
+ bytes += 2;
147
+ } else if (code <= 0x1f) {
148
+ bytes += 6;
149
+ } else if (code <= 0x7f) {
150
+ bytes += 1;
151
+ } else if (code <= 0x7ff) {
152
+ bytes += 2;
153
+ } else if (code >= 0xd800 && code <= 0xdbff) {
154
+ const trailing = value.charCodeAt(index + 1);
155
+ if (trailing >= 0xdc00 && trailing <= 0xdfff) {
156
+ bytes += 4;
157
+ index += 1;
158
+ } else {
159
+ bytes += 6;
160
+ }
161
+ } else if (code >= 0xdc00 && code <= 0xdfff) {
162
+ bytes += 6;
163
+ } else {
164
+ bytes += 3;
165
+ }
166
+ if (bytes > available) return available + 1;
167
+ }
168
+ return bytes;
169
+ }
170
+
171
+ function consumeBytes(state, bytes) {
172
+ if (!Number.isSafeInteger(bytes) || bytes < 0 || bytes > state.bytesLeft) {
173
+ state.issue = "bytes";
174
+ return false;
175
+ }
176
+ state.bytesLeft -= bytes;
177
+ return true;
178
+ }
179
+
180
+ function consumeNodes(state, count = 1) {
181
+ if (!Number.isSafeInteger(count) || count < 0 || count > state.nodesLeft) {
182
+ state.issue = "nodes";
183
+ return false;
184
+ }
185
+ state.nodesLeft -= count;
186
+ return true;
187
+ }
188
+
189
+ function cloneJsonValue(value, state, depth) {
190
+ if (!consumeNodes(state)) return undefined;
191
+
192
+ if (value === null) {
193
+ consumeBytes(state, 4);
194
+ return null;
195
+ }
196
+ if (typeof value === "string") {
197
+ consumeBytes(state, boundedJsonStringBytes(value, state.bytesLeft));
198
+ return value;
199
+ }
200
+ if (typeof value === "boolean") {
201
+ consumeBytes(state, value ? 4 : 5);
202
+ return value;
203
+ }
204
+ if (typeof value === "number" && Number.isFinite(value)) {
205
+ consumeBytes(state, Buffer.byteLength(JSON.stringify(value), "utf8"));
206
+ return value;
207
+ }
208
+ if (!value || typeof value !== "object") {
209
+ state.issue = "invalid";
210
+ return undefined;
211
+ }
212
+ if (depth > state.maxDepth) {
213
+ state.issue = "depth";
214
+ return undefined;
215
+ }
216
+ state.maxDepthSeen = Math.max(state.maxDepthSeen, depth);
217
+ try {
218
+ if (isProxy(value) || state.seen.has(value)) {
219
+ state.issue = "invalid";
220
+ return undefined;
221
+ }
222
+ state.seen.add(value);
223
+ } catch {
224
+ state.issue = "invalid";
225
+ return undefined;
226
+ }
227
+
228
+ if (Array.isArray(value)) {
229
+ const descriptors = denseArraySnapshot(value);
230
+ if (!descriptors || !consumeBytes(state, 2)) {
231
+ if (!state.issue) state.issue = "invalid";
232
+ return undefined;
233
+ }
234
+ const clean = [];
235
+ for (let index = 0; index < descriptors.length; index += 1) {
236
+ if (index > 0 && !consumeBytes(state, 1)) return undefined;
237
+ const cloned = cloneJsonValue(descriptors[index].value, state, depth + 1);
238
+ if (state.issue) return undefined;
239
+ clean.push(cloned);
240
+ }
241
+ return clean;
242
+ }
243
+
244
+ const snapshot = plainObjectSnapshot(value);
245
+ if (!snapshot || !consumeBytes(state, 2)) {
246
+ if (!state.issue) state.issue = "invalid";
247
+ return undefined;
248
+ }
249
+ if (!consumeNodes(state, snapshot.keys.length)) return undefined;
250
+ const clean = {};
251
+ for (let index = 0; index < snapshot.keys.length; index += 1) {
252
+ const key = snapshot.keys[index];
253
+ if (index > 0 && !consumeBytes(state, 1)) return undefined;
254
+ if (
255
+ !consumeBytes(state, boundedJsonStringBytes(key, state.bytesLeft)) ||
256
+ !consumeBytes(state, 1)
257
+ ) {
258
+ return undefined;
259
+ }
260
+ const cloned = cloneJsonValue(
261
+ snapshot.descriptors[key].value,
262
+ state,
263
+ depth + 1,
264
+ );
265
+ if (state.issue) return undefined;
266
+ Object.defineProperty(clean, key, {
267
+ value: cloned,
268
+ enumerable: true,
269
+ configurable: true,
270
+ writable: true,
271
+ });
272
+ }
273
+ return clean;
274
+ }
275
+
276
+ function freezeJsonSnapshot(value) {
277
+ const stack = [value];
278
+ while (stack.length > 0) {
279
+ const current = stack.pop();
280
+ if (!current || typeof current !== "object" || Object.isFrozen(current)) {
281
+ continue;
282
+ }
283
+ for (const key of Object.keys(current)) {
284
+ const child = current[key];
285
+ if (child && typeof child === "object") stack.push(child);
286
+ }
287
+ Object.freeze(current);
288
+ }
289
+ return value;
290
+ }
291
+
292
+ function admissionError(issue, limits) {
293
+ if (issue === "bytes") {
294
+ return resultError(
295
+ "CC_MCP_TOOL_RESULT_TOO_LARGE",
296
+ `MCP tool result exceeded the ${limits.maxBytes}-byte host budget`,
297
+ { limitBytes: limits.maxBytes },
298
+ );
299
+ }
300
+ if (issue === "depth") {
301
+ return resultError(
302
+ "CC_MCP_TOOL_RESULT_DEPTH_EXCEEDED",
303
+ `MCP tool result exceeded the ${limits.maxDepth}-level host depth budget`,
304
+ { limitDepth: limits.maxDepth },
305
+ );
306
+ }
307
+ if (issue === "nodes") {
308
+ return resultError(
309
+ "CC_MCP_TOOL_RESULT_NODES_EXCEEDED",
310
+ `MCP tool result exceeded the ${limits.maxNodes}-node host budget`,
311
+ { limitNodes: limits.maxNodes },
312
+ );
313
+ }
314
+ return resultError(
315
+ "CC_MCP_TOOL_RESULT_INVALID",
316
+ "MCP server returned an invalid tool result",
317
+ );
318
+ }
319
+
320
+ export function admitMcpToolResult(_serverName, value, config = {}) {
321
+ const limits = resolveMcpToolResultLimits(config);
322
+ if (value && typeof value === "object") {
323
+ const prior = admittedToolResults.get(value);
324
+ if (
325
+ prior &&
326
+ prior.bytes <= limits.maxBytes &&
327
+ prior.depth <= limits.maxDepth &&
328
+ prior.nodes <= limits.maxNodes
329
+ ) {
330
+ return Object.freeze({
331
+ result: value,
332
+ bytes: prior.bytes,
333
+ depth: prior.depth,
334
+ nodes: prior.nodes,
335
+ limits,
336
+ });
337
+ }
338
+ }
339
+
340
+ const state = {
341
+ issue: null,
342
+ bytesLeft: limits.maxBytes,
343
+ nodesLeft: limits.maxNodes,
344
+ maxDepth: limits.maxDepth,
345
+ maxDepthSeen: 0,
346
+ seen: new WeakSet(),
347
+ };
348
+ const result = cloneJsonValue(value, state, 1);
349
+ if (
350
+ !state.issue &&
351
+ (!result || typeof result !== "object" || Array.isArray(result))
352
+ ) {
353
+ state.issue = "invalid";
354
+ }
355
+ if (state.issue) throw admissionError(state.issue, limits);
356
+
357
+ const bytes = limits.maxBytes - state.bytesLeft;
358
+ const nodes = limits.maxNodes - state.nodesLeft;
359
+ freezeJsonSnapshot(result);
360
+ const metrics = Object.freeze({
361
+ bytes,
362
+ depth: state.maxDepthSeen,
363
+ nodes,
364
+ });
365
+ admittedToolResults.set(result, metrics);
366
+ return Object.freeze({ result, ...metrics, limits });
367
+ }
@@ -136,6 +136,73 @@ export class ObservabilityRuntime {
136
136
  ]);
137
137
  }
138
138
 
139
+ /**
140
+ * Export one migrated-command invocation without command arguments or any
141
+ * session/workspace identity. Collection remains opt-in because a disabled
142
+ * OTLP runtime returns before constructing or queueing the metric payload.
143
+ */
144
+ exportCommandLifecycleInvocation(value = {}) {
145
+ if (!this.enabled) return false;
146
+ const command = normalizeLifecycleDimension(
147
+ value.command,
148
+ /^[a-z0-9][a-z0-9-]{0,63}$/,
149
+ "unknown",
150
+ );
151
+ const route = ["legacy", "replacement"].includes(value.route)
152
+ ? value.route
153
+ : "unknown";
154
+ const outcome = ["completed", "error"].includes(value.outcome)
155
+ ? value.outcome
156
+ : "unknown";
157
+ const version = normalizeLifecycleDimension(
158
+ value.version,
159
+ /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/,
160
+ "unknown",
161
+ );
162
+ const deprecatedSince = normalizeLifecycleDimension(
163
+ value.deprecatedSince,
164
+ /^\d+\.\d+\.\d+$/,
165
+ "unknown",
166
+ );
167
+ const removalNotBefore = normalizeLifecycleDimension(
168
+ value.removalNotBefore,
169
+ /^\d+\.\d+\.\d+$/,
170
+ "unknown",
171
+ );
172
+ const durationMs = Math.max(0, Number(value.durationMs) || 0);
173
+ const attributes = {
174
+ "command.name": command,
175
+ "command.route": route,
176
+ "command.outcome": outcome,
177
+ "cli.version": version,
178
+ "command.deprecated_since": deprecatedSince,
179
+ "command.removal_not_before": removalNotBefore,
180
+ };
181
+ try {
182
+ return this.exporter.exportMetrics([
183
+ {
184
+ name: "chainlesschain.cli.command.lifecycle.invocations",
185
+ type: "sum",
186
+ unit: "{invocation}",
187
+ value: 1,
188
+ monotonic: true,
189
+ attributes,
190
+ },
191
+ {
192
+ name: "chainlesschain.cli.command.lifecycle.duration",
193
+ type: "histogram",
194
+ unit: "ms",
195
+ count: 1,
196
+ sum: durationMs,
197
+ attributes,
198
+ },
199
+ ]);
200
+ } catch {
201
+ // Observability is advisory and must never change the command result.
202
+ return false;
203
+ }
204
+ }
205
+
139
206
  captureMetrics() {
140
207
  if (!this.enabled) return false;
141
208
  const metrics = collectedMetrics(this.metricsCollector);
@@ -156,6 +223,10 @@ export class ObservabilityRuntime {
156
223
  }
157
224
  }
158
225
 
226
+ function normalizeLifecycleDimension(value, pattern, fallback) {
227
+ return typeof value === "string" && pattern.test(value) ? value : fallback;
228
+ }
229
+
159
230
  let defaultRuntime = null;
160
231
 
161
232
  export function resolveOtlpEndpointFromArgv(argv = process.argv) {
@@ -16,10 +16,15 @@
16
16
  * result or a session listing.
17
17
  */
18
18
 
19
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
20
- import { join } from "node:path";
21
- import { getHomeDir } from "./paths.js";
19
+ import { writeFileSync } from "node:fs";
22
20
  import { executionBroker } from "./process-execution-broker/index.js";
21
+ import {
22
+ getPrLinks,
23
+ prLinkLedgerPath,
24
+ readPrLinkLedger,
25
+ } from "./pr-link-store.js";
26
+
27
+ export { getPrLinks, prLinkLedgerPath, readPrLinkLedger };
23
28
 
24
29
  export const _deps = {
25
30
  execFile: (...args) => executionBroker.execFile(...args),
@@ -29,21 +34,6 @@ export const _deps = {
29
34
  const MAX_LINKS_PER_SESSION = 20;
30
35
  const MAX_SESSIONS = 500;
31
36
 
32
- export function prLinkLedgerPath() {
33
- return join(getHomeDir(), "pr-links.json");
34
- }
35
-
36
- export function readPrLinkLedger() {
37
- try {
38
- const p = prLinkLedgerPath();
39
- if (!existsSync(p)) return {};
40
- const parsed = JSON.parse(readFileSync(p, "utf-8"));
41
- return parsed && typeof parsed === "object" ? parsed : {};
42
- } catch {
43
- return {}; // corrupt ledger degrades to empty, never throws
44
- }
45
- }
46
-
47
37
  function writeLedger(ledger) {
48
38
  const ids = Object.keys(ledger);
49
39
  if (ids.length > MAX_SESSIONS) {
@@ -138,15 +128,6 @@ export function recordPrLink(sessionId, ref, options = {}) {
138
128
  return incoming;
139
129
  }
140
130
 
141
- /** Links for a session, newest first. */
142
- export function getPrLinks(sessionId) {
143
- if (!sessionId) return [];
144
- const links = readPrLinkLedger()[sessionId];
145
- return Array.isArray(links)
146
- ? [...links].sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0))
147
- : [];
148
- }
149
-
150
131
  function ghPrForBranch(cwd, timeoutMs = 3000) {
151
132
  const run = (file, fileArgs) =>
152
133
  new Promise((resolve) => {
@@ -0,0 +1,26 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { getHomeDir } from "./paths.js";
4
+
5
+ export function prLinkLedgerPath() {
6
+ return join(getHomeDir(), "pr-links.json");
7
+ }
8
+
9
+ export function readPrLinkLedger() {
10
+ try {
11
+ const ledgerPath = prLinkLedgerPath();
12
+ if (!existsSync(ledgerPath)) return {};
13
+ const parsed = JSON.parse(readFileSync(ledgerPath, "utf-8"));
14
+ return parsed && typeof parsed === "object" ? parsed : {};
15
+ } catch {
16
+ return {};
17
+ }
18
+ }
19
+
20
+ export function getPrLinks(sessionId) {
21
+ if (!sessionId) return [];
22
+ const links = readPrLinkLedger()[sessionId];
23
+ return Array.isArray(links)
24
+ ? [...links].sort((a, b) => (b.updatedAt || 0) - (a.updatedAt || 0))
25
+ : [];
26
+ }
@@ -48,6 +48,7 @@ import { consumeIssuedPluginSandboxExecutionContract } from "../plugin-runtime/b
48
48
  import runtimeProvenanceLedger from "../runtime-provenance-ledger.js";
49
49
  import { credentialAgent } from "./credential-agent.js";
50
50
  import { WorkspaceTransactionManager } from "./workspace-transaction.js";
51
+ import { consumeMcpStdioExecutableIdentityAuthority } from "../mcp-stdio-executable-identity.js";
51
52
 
52
53
  const SUPPORTED_SANDBOX_BOUNDARIES = new Set(Object.values(SANDBOX_BOUNDARIES));
53
54
  const SUPPORTED_SANDBOX_PROFILES = new Set([
@@ -2717,6 +2718,10 @@ class ProcessExecutionBroker extends EventEmitter {
2717
2718
  const startTime = Date.now();
2718
2719
  const origin = options.origin || "unknown";
2719
2720
  const requestedCwd = options.cwd || process.cwd();
2721
+ const mcpStdioExecutableIdentityAuthority =
2722
+ options.mcpStdioExecutableIdentityAuthority;
2723
+ const identityCommand = command;
2724
+ const identityArgs = [...(args || [])];
2720
2725
  options = this._withWorkspaceTransactionBoundaries(options, requestedCwd, {
2721
2726
  command,
2722
2727
  args,
@@ -2764,6 +2769,7 @@ class ProcessExecutionBroker extends EventEmitter {
2764
2769
  sandboxRequired: [],
2765
2770
  sandboxGuarantees: [],
2766
2771
  sandboxBackend: null,
2772
+ mcpStdioExecutableIdentityDigest: null,
2767
2773
  };
2768
2774
 
2769
2775
  let sandboxPolicy;
@@ -2813,6 +2819,7 @@ class ProcessExecutionBroker extends EventEmitter {
2813
2819
  this._stripPluginControlOptions(spawnOpts);
2814
2820
  this._stripWorkspaceTransactionOptions(spawnOpts);
2815
2821
  this._stripAuditControlOptions(spawnOpts);
2822
+ delete spawnOpts.mcpStdioExecutableIdentityAuthority;
2816
2823
  if (traceCtx) {
2817
2824
  spawnOpts.env = { ...(spawnOpts.env || process.env) };
2818
2825
  spawnOpts.env.TRACEPARENT = traceCtx.traceparent;
@@ -2886,6 +2893,13 @@ class ProcessExecutionBroker extends EventEmitter {
2886
2893
  const nativeSpawnFn = this._native?.spawn || nativeSpawn;
2887
2894
  let proc;
2888
2895
  try {
2896
+ if (mcpStdioExecutableIdentityAuthority !== undefined) {
2897
+ const admitted = consumeMcpStdioExecutableIdentityAuthority(
2898
+ mcpStdioExecutableIdentityAuthority,
2899
+ { command: identityCommand, args: identityArgs },
2900
+ );
2901
+ auditEntry.mcpStdioExecutableIdentityDigest = admitted.identityDigest;
2902
+ }
2889
2903
  proc = nativeSpawnFn(command, args, optsForSpawn);
2890
2904
  this._bindWorkspaceTransactionProcess(auditEntry, proc);
2891
2905
  } catch (spawnError) {