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.
- package/bin/chainlesschain.js +14 -6
- package/package.json +4 -1
- package/scripts/command-lifecycle-report.mjs +94 -0
- package/src/assets/web-panel/assets/{AIOps-D3Gu1a5d.js → AIOps-DcQ0bWKy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DrwAoKaz.js → ActionButton-GecwfFPt.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C7Q-gd_3.js → Analytics-CD6iSt9v.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DgBtae-n.js → AppLayout-CDEtuEYf.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-pQ6LcA-W.js → Artifacts-DS3jAjeW.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DK61tocB.js → Audit-CcSJA048.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BOKgDFRh.js → BackgroundAgents-DRo9Morb.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Bo9G4vTP.js → Backup-Vw5MrWft.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Do_dE9_v.js → BaseInput-DNHIu823.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-COVvZzOL.js → Chat-DvAsO8-b.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-9aDuObay.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Z9MJMolt.js → Checkbox-CKCa7tvn.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BVzWKVbf.js → Codegen-CIFvZdaT.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C8MnYcbT.js → Col-C79yz7bK.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DQxqw15l.js → Community-DVvZskLJ.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BAUmrh3y.js → Compact-oaew61hV.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-jPAkQ3zK.js → Compliance-DqA7wmRx.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BBQyxbh8.js → Cowork-B-qGadxa.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-W5koq8Z5.js → Cron-CUlCl4sS.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BQhnu5hS.js → Crosschain-CNOlr9DU.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DD7PlI18.js → DID-DJqFCT_3.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-w_ILuwKI.js → Dashboard-CznGpphf.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-qiDUAyAo.js → Dropdown-_cJw218E.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-PDeBcI5H.js → EmailListRenderer-Dr-1BZ9C.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-SuArscRM.js → FamilyGuardDashboard-Dxf4xtSk.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BCovZaUn.js → Federation-DOiG3i_1.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DjlFdVFk.js → FormItemContext-BzbMcFB9.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DoEZ7fcS.js → GenericCardRenderer-VbBrYttP.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CV0-6GPI.js → Git-CLG8E6ED.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-B_SFN50w.js → Governance-LGJQfk_q.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-heI0Eo6k.js → Inference-DlQKx9lF.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cz5INS5p.js → KnowledgeGraph-DU8vEouV.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BSFxiHkg.js → Logs-FZIQOdln.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BJNWIrbw.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-0TWTpE7k.js → Marketplace-C_xd-zZI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CV4-wBLm.js → McpTools-q-YktphS.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-x5bH5rw5.js → Memory-Cq9OhDin.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DaBmUu9G.js → MobileBridge-B03_R98T.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-DZrk-qmF.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B_zKEBif.js → Mtc-BidCKW28.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BCfKD2yg.js → MtcAudit-r-iaMVM7.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DgYfj6c_.js → Multisig-CgTUFvff.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dz09lFUm.js → NLProgramming-B7NvzfAV.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cuj6ugBE.js → Notes-80CWNqJI.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DK2WXjhg.js → NotificationSettings-0H6xdiY3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D1IAOQoo.js → OrderTableRenderer-CKP4AFWy.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-9fqnPvTw.js → Organization-B8sxCV_h.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-n5xHkhow.js → Overflow-CW9JBBhQ.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-B5AUWwH-.js → P2P-bdSQV7oZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CoUDV6dy.js → PdhVaultBrowser-DQad42nW.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DPRmQf_H.js → Permissions-CueexxTR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B37bsbEN.js → PersonalDataHub-fqxflhR8.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-CCAuPqu9.js → Pipeline-KFwwnIMC.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B81msZdv.js → Privacy-ClnD9buY.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B-Py2NbF.js → ProjectInit-CZEz6sm3.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CYsneiRB.js → ProjectSettings-B6NzpmOI.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Y975Mh6R.js → Projects-DYyuwPCs.js} +1 -1
- package/src/assets/web-panel/assets/Providers-C3tz_jdh.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-Bj_6gJ0l.js → QrScannerModal-BzuOBbqB.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BgpBCMPE.js → QuickAsk-CmNO9qSj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhUW3YUA.js → Recommend-VJNj3_NF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DdeyfbkA.js → RemoteSession-CrbdbSBF.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-fxW421xd.js → Reputation-DTyMd45j.js} +1 -1
- package/src/assets/web-panel/assets/{Row-De73w1og.js → Row-DHrQ-Icz.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-3US_Q_lj.js → RssFeed-DqWxY9c5.js} +2 -2
- package/src/assets/web-panel/assets/{Search-DbZ_DU74.js → Search-ctF1Ks3J.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DoIU1vMF.js → Security-BrQz8uo5.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DB_RGqpc.js → Services-D4scVFar.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DnzLaayC.js → Skeleton-oUScaOjv.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-VzVXHENF.js → Skills-CL-y0eLt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DMfvjCAI.js → Sla-DQExhwXj.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DQQOYWbF.js → SpeechSettings-iNp_I7kN.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Bmx3FG1P.js → SyncSettings-CTDlMo0A.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DOQyfb-2.js → Tasks-4kb8l3sc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D6hTRT7c.js → Templates-BXcL9oXW.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CTPQZAzs.js → Tenant-DLE8eS0D.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B7vII3oH.js → Terminal-DGpUZPPK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BkiFJeXV.js → TimelineRenderer-C1pWXGPC.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BPPdQMNo.js → Tokens-BYfbfqhZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BxG8JAEI.js → Trigger-K9YfLOCw.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DHD7nMpM.js → Trust-Ctkq77Hy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B4BJpU47.js → UkeySign-C6_CSe9J.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CRiGpFx2.js → VideoEditing-Be3rpOWs.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BSDSNiem.js → Wallet-D0UIplxk.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DLTUh5Zv.js → WebAuthn-CF9bM9I3.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-tW2MwjhD.js → WorkflowEditor-D0H1XVPY.js} +1 -1
- package/src/assets/web-panel/assets/{chat-SgsLQ3FC.js → chat-Cgzzbe0o.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BHjjLIKO.js → colors-BwNxEVS0.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-VceErdKq.js → compact-item-D60Z4Hhs.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BZ332MYl.js → createContext-MFk58XB0.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BJiw369i.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CBTjJOjn.js → hasIn-CRj2SvGO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaCCy6lq.js → index--s45_1cb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMVvxIS8.js → index--tquQ2ZG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhXZEUAc.js → index-1T1rhokn.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQSmZGgs.js → index-B-M82_rx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeiqkxJG.js → index-BE_el1Zs.js} +1 -1
- package/src/assets/web-panel/assets/{index-29wVzi-k.js → index-BhRkR7IO.js} +1 -1
- package/src/assets/web-panel/assets/{index-iYQNU9za.js → index-Bo0y96-K.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRWhLbWF.js → index-CJgu5JUK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPXFLYdW.js → index-CLWwdebO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr4rjlW5.js → index-CNAK5QG_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaIS_TNX.js → index-CQjJjPRD.js} +1 -1
- package/src/assets/web-panel/assets/{index-1n7xjKDU.js → index-CTDbAfae.js} +1 -1
- package/src/assets/web-panel/assets/{index-BETEjuNr.js → index-CVI_9sRK.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5jBtkV.js → index-CY14oMQK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgPvuIn2.js → index-CbiTJkZf.js} +1 -1
- package/src/assets/web-panel/assets/index-CiMouosn.js +1 -0
- package/src/assets/web-panel/assets/{index-CawpdGTW.js → index-CqWpxMqx.js} +1 -1
- package/src/assets/web-panel/assets/{index-_PHrIO4O.js → index-CvB8lYUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOtvPdHt.js → index-D51XwtCY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CrUgDQkf.js → index-D6HvK_1O.js} +1 -1
- package/src/assets/web-panel/assets/{index-BY1wexYG.js → index-D9jVIwLJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_B9rFQE.js → index-DA4tE98u.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5KAGxNo.js → index-DBwOtXw0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BC1xuQgX.js → index-DKdNzTIb.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2u26AS3.js → index-DRySdmvN.js} +1 -1
- package/src/assets/web-panel/assets/{index-DePOeMDM.js → index-DWzyTev7.js} +1 -1
- package/src/assets/web-panel/assets/index-DXcKlwy7.js +1 -0
- package/src/assets/web-panel/assets/{index-BTlc-Bve.js → index-DYjs7jAP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLc19alH.js → index-DbROzMBp.js} +1 -1
- package/src/assets/web-panel/assets/{index-fU7wNHDB.js → index-DhFtk5PR.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_SePDWj.js → index-Di2AbMLg.js} +1 -1
- package/src/assets/web-panel/assets/{index-vIXOpcjD.js → index-DvmocQsM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUenmCX.js → index-Dw-o0zEF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUkVN794.js → index-DysPoP38.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtjLcCNU.js → index-LX9pJxm_.js} +1 -1
- package/src/assets/web-panel/assets/{index-B40dQn0G.js → index-OI_fXWx0.js} +3 -3
- package/src/assets/web-panel/assets/{index-FJ3zC9LK.js → index-eDTOX8Xj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdefYBSw.js → index-gWKDsTzF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpumS98o.js → index-q_GDUVAA.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D1oZNz0D.js → initDefaultProps-C61kZqEd.js} +1 -1
- package/src/assets/web-panel/assets/{motion-C8k6doMO.js → motion-DZnT5U1L.js} +1 -1
- package/src/assets/web-panel/assets/{move-DJ4qSbYt.js → move-L8wzwbel.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CdpJD85j.js → mtc-parser-DLdYSejc.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B0V4slKA.js → omit-D53cbS59.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Di5NiW1F.js → pickAttrs-Bbc5HPtu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B5OMHgEM.js → placementArrow-BkvmO860.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C6U9IWql.js → responsiveObserve-u2y1ryS1.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BMyTH3rN.js → slide-BBqj7svU.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C7d6BG7Z.js → statusUtils-GN0mqu2d.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CR50QnQy.js → styleChecker-BvwPKoBT.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DBEeoMb8.js → useFlexGapSupport-CCt8tnfY.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-3r099cjv.js → useFs-DXAxl2SV.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C5IYNdTK.js → usePersonalDataHub-DihlR2dj.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DmEOLRHf.js → vnode-D7BOX2gi.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DnpUiVCB.js → zoom-CVbO-nL7.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +4 -4
- package/src/commands/agent.js +3 -3
- package/src/commands/background-session.js +145 -0
- package/src/commands/mcp.js +244 -7
- package/src/commands/serve.js +1 -1
- package/src/commands/session-show.js +129 -0
- package/src/commands/session.js +97 -145
- package/src/commands/skill.js +87 -50
- package/src/data/changelog.json +40 -1
- package/src/gateways/ws/session-protocol.js +14 -4
- package/src/gateways/ws/ws-agent-handler.js +39 -1
- package/src/harness/jsonl-session-store.js +1547 -127
- package/src/harness/mcp-client.js +2690 -409
- package/src/harness/session-index.js +80 -80
- package/src/harness/session-list-index.js +210 -7
- package/src/lazy-dispatch.js +76 -8
- package/src/lib/abort-utils.js +68 -0
- package/src/lib/agent-core.js +1 -59
- package/src/lib/background-interaction-journal.js +2 -2
- package/src/lib/chat-core.js +24 -6
- package/src/lib/command-lifecycle-report.js +516 -0
- package/src/lib/cowork-mcp-tools.js +47 -2
- package/src/lib/cowork-task-runner.js +11 -3
- package/src/lib/doctor-checkup.js +9 -7
- package/src/lib/learning/skill-improver.js +21 -2
- package/src/lib/mcp-call-ledger-store.js +116 -3
- package/src/lib/mcp-call-ledger.js +59 -14
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-stdio-environment.js +48 -0
- package/src/lib/mcp-stdio-executable-identity.js +1133 -0
- package/src/lib/mcp-stdio-execution-authority.js +363 -0
- package/src/lib/mcp-stdio-package-materialization.js +1424 -0
- package/src/lib/mcp-tool-metadata.js +436 -0
- package/src/lib/mcp-tool-result.js +367 -0
- package/src/lib/observability/index.js +71 -0
- package/src/lib/packer/native-update-state.js +979 -1
- package/src/lib/packer/pack-update-applier.js +1050 -125
- package/src/lib/packer/pkg-config-generator.js +1 -0
- package/src/lib/paths.js +53 -0
- package/src/lib/pr-link-ledger.js +8 -27
- package/src/lib/pr-link-store.js +26 -0
- package/src/lib/process-execution-broker/index.js +192 -35
- package/src/lib/process-execution-broker/platform-sandbox.js +291 -24
- package/src/lib/process-tree-termination.js +253 -0
- package/src/lib/recent-session.js +17 -17
- package/src/lib/secure-file-identity.js +47 -0
- package/src/lib/secure-fs.js +21 -2
- package/src/lib/session-anti-rollback-anchor.js +766 -0
- package/src/lib/session-host-lease.js +492 -0
- package/src/lib/session-host-snapshot.js +9 -5
- package/src/lib/session-persistence-failure.js +109 -0
- package/src/lib/session-picker.js +26 -3
- package/src/lib/session-projection.js +5 -1
- package/src/lib/session-search.js +25 -11
- package/src/lib/session-tail.js +31 -1
- package/src/lib/side-effect-ledger-store.js +2 -2
- package/src/lib/skill-budget.js +222 -0
- package/src/lib/skill-execution-authority.js +385 -0
- package/src/lib/skill-execution-identity.js +39 -2
- package/src/lib/skill-loader.js +322 -86
- package/src/lib/skill-mcp.js +43 -1
- package/src/lib/turn-binding-store.js +2 -2
- package/src/repl/agent-repl.js +483 -77
- package/src/repl/bg-dashboard.js +81 -28
- package/src/repl/chat-repl.js +77 -12
- package/src/runtime/agent-core.js +428 -113
- package/src/runtime/agent-runtime.js +26 -3
- package/src/runtime/cleanup-deadline.js +143 -0
- package/src/runtime/headless-runner.js +494 -149
- package/src/runtime/headless-stream.js +504 -75
- package/src/runtime/mcp-config.js +157 -10
- package/src/runtime/mcp-tool-search.js +0 -0
- package/src/runtime/output-backpressure.js +419 -0
- package/src/runtime/pipe-safety.js +56 -21
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +0 -1
- package/src/assets/web-panel/assets/Providers-uO-10aP1.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +0 -1
- package/src/assets/web-panel/assets/index-0O5ePnUq.js +0 -1
- package/src/assets/web-panel/assets/index-ChAzPigF.js +0 -1
- 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) {
|