chainlesschain 0.162.180 → 0.162.182
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/package.json +7 -3
- package/scripts/build-windows-sandbox-helper.ps1 +163 -0
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-D_TIL54O.js → AIOps-DzZ5_xoj.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-eQwy9r-f.js → ActionButton-DeLXddIg.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D2eNuDgT.js → Analytics-rvDCmet1.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CFhwOFsf.js → AppLayout-Yt6QVDnp.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CJUMw6PB.js → Artifacts-BS112K5L.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CDB9V58o.js → Audit-0wJuQrNu.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-TBppYFjN.js → BackgroundAgents-B90PMgbn.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CYEOUpzJ.js → Backup-TkgMglQQ.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-C88fFT2u.js → BaseInput-CQVS9p1l.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-mkr1vC3N.js → Chat-YTjQHoC7.js} +6 -6
- package/src/assets/web-panel/assets/ChatBubbleRenderer-PR074hUN.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CVU4xqti.js → Checkbox-5bwaOabq.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-rrNcByz3.js → Codegen-BFmNQ_Xe.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Cqu-zCvh.js → Col-BT_u4Dzp.js} +1 -1
- package/src/assets/web-panel/assets/{Community-RGRlSgXV.js → Community-CJP52u5b.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DBm6epOK.js → Compact-BpzhJE9i.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BgKw5iaW.js → Compliance-Cg7rfslp.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BqQcNO3Z.js → Cowork-JisxL6Yy.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DO5gTFNb.js → Cron-Bu7Ug_MC.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B8hbJNuN.js → Crosschain-CvuqoLdj.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B08bFJ2C.js → DID-C2u9G8Pu.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-xNdy_ifo.js → Dashboard-BFt5Yv3d.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-D-KIZgWL.js → Dropdown-DIaT9Wxq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DKCvsaGo.js → EmailListRenderer-D_A601Y4.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D_cfqama.js → FamilyGuardDashboard--IyQ8I8w.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-B-UqQD68.js → Federation-BihWHxuY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BWWvWuJW.js → FormItemContext-BB8dOXc_.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CPchx6N7.js → GenericCardRenderer-DQYhj1HH.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Vx4co9Ff.js → Git-B-2QZxGf.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-D4x0pp_m.js → Governance-CusSb-nG.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-T3KvwPYR.js → Inference-BAjmvPPL.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Ddv3KUv3.js → KnowledgeGraph-DoNYWKYq.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DfH-Dkae.js → Logs-B8fKWD-n.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DHW3PbCq.js → MarkdownRenderer-BlJm1J7E.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-tjgb0R3D.js → Marketplace-CyOscbSL.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DHAk5nYX.js → McpTools-Ex6Om5da.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-A2Yx7thM.js → Memory-CDcD8l8r.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BEmTVfN5.js → MobileBridge-xfBqoFDg.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DuFHUgE4.js → MobileProjects-BwObMMA2.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BDSll0OZ.js → Mtc-CIWd36OV.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CuBvluaS.js → MtcAudit-CPX0ouuA.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BmXAA-Sb.js → Multisig-BDJsIUuW.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-ci2stZAe.js → NLProgramming-DEkbuD3N.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-D-1RpqnS.js → Notes-DJpHRhH1.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C0GyitIT.js → NotificationSettings-C1UZ-Qd5.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-U2bN-hj5.js → OrderTableRenderer-GlJtqLjT.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BNZgpPci.js → Organization-Bbhj0fac.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CDidKmUN.js → Overflow-1H04x3kx.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BnreBaXq.js → P2P-CDpPe3et.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DwJUxO9j.js → PdhVaultBrowser-MUX0Bpvw.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BQGgJPH0.js → Permissions-A07-0Ci1.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-k_fSkCwL.js → PersonalDataHub-DhhDWxAZ.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-WGqKMqau.js → Pipeline-CyfbJfe-.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DtHj9Ymq.js → Privacy-CNFps3ED.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B3wH2SFC.js → ProjectInit--T-u3Dr5.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Cd0cgcA1.js → ProjectSettings-DJmrK2fC.js} +2 -2
- package/src/assets/web-panel/assets/Projects-Qx_MdX9k.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DTpxEXur.js → Providers-DLzzbOZd.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-B2v6gR-C.js → QrScannerModal-CexOomKS.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D3Nr9xXR.js → QuickAsk-QklGi19_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-C9inoMky.js → Recommend-Bb9kwSw8.js} +1 -1
- package/src/assets/web-panel/assets/RemoteSession-DZuVNNN5.js +5 -0
- package/src/assets/web-panel/assets/{Reputation-41KFG646.js → Reputation-Dr5cLP0N.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DqAaqqCv.js → Row-oCQHYv5t.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CMDpCDKc.js → RssFeed-IFDEykIR.js} +3 -3
- package/src/assets/web-panel/assets/{Search-B6mtegNL.js → Search-CspVIxDc.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BaePFVZ8.js → Security-Bm66o_DH.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DeG3Qscl.js → Services-DvanNqXl.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D_QP7F90.js → Skeleton-CHjEe9_O.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DLGyUgIA.js → Skills-Cb8jWjMX.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BN2pxW1Q.js → Sla-DxZm1491.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BWsZPd8B.js → SpeechSettings-DWxEEclC.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-VOZRPODW.js → SyncSettings-FIvOFw5p.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CyuLnDFR.js +1 -0
- package/src/assets/web-panel/assets/{Templates-eJSob-q0.js → Templates-CaNjzV_t.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Bdwk8Rwy.js → Tenant-DjlP6TmH.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-DwzGMniO.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D5qkbPKT.js → TimelineRenderer-DoZ8y7y8.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DKgwn8hI.js → Tokens-390cg2TC.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-HlEHniGM.js → Trigger-CLrtCj5_.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CdPcsBpN.js → Trust-DpESfSPn.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-vAdXd-vG.js → UkeySign-CN6279O0.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-9hHBYFnH.js → VideoEditing-DPtAUlSe.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Dxh5d1yR.js → Wallet-nKOMV_1n.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BsFmLHkp.js → WebAuthn-HuXlSOc4.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-Cn0OIwLn.js → WorkflowEditor-CUfFjARi.js} +1 -1
- package/src/assets/web-panel/assets/chat-6Eq0PcZJ.js +1 -0
- package/src/assets/web-panel/assets/{colors-Du9jzLN0.js → colors-BP_Sf6Iy.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DhEscfzw.js → compact-item-BufMKIh5.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CwzEfF3i.js → createContext-BBMXxWSW.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DgVKduH2.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DT_GSE6J.js → hasIn-fUK_tRO2.js} +1 -1
- package/src/assets/web-panel/assets/{index-tND8-TDU.js → index-2A5ph8b2.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8s5FxJY.js → index-3FuwBewR.js} +1 -1
- package/src/assets/web-panel/assets/{index-53z1YUxX.js → index-6GmBa4Kg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFD0cEna.js → index-B2vS66eI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQWxDOvM.js → index-B7Etk0Te.js} +1 -1
- package/src/assets/web-panel/assets/{index-VeHs6qH0.js → index-B9WYSn4m.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGvgnfl9.js → index-BHy6yNiF.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3llLkYM.js → index-BMLHv389.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dny_ZnAO.js → index-BWKoBU8R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DzjzrOli.js → index-Bkg4ZePE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DN60VBn5.js → index-C44atv4k.js} +1 -1
- package/src/assets/web-panel/assets/{index-v5HLYCVa.js → index-CE2DdTP2.js} +1 -1
- package/src/assets/web-panel/assets/{index-BF-ZCVGE.js → index-CGjmILDm.js} +1 -1
- package/src/assets/web-panel/assets/{index-gFjYdstW.js → index-CW_G-MXw.js} +1 -1
- package/src/assets/web-panel/assets/{index-NA2oBLSB.js → index-CZ6Yt17L.js} +1 -1
- package/src/assets/web-panel/assets/{index-Mobw3PHs.js → index-CeASi4fr.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWL3SYN3.js → index-CgiECHu2.js} +1 -1
- package/src/assets/web-panel/assets/{index-1LoutPJd.js → index-Cp8vhyZy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnHhFnwt.js → index-CwSf5pnf.js} +1 -1
- package/src/assets/web-panel/assets/{index-B6QDWRLk.js → index-D4_MuGkd.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-QkW1fp.js → index-D9vU25ij.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4SN3by5.js → index-DASluSqY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyEhUJcu.js → index-DLpIs_P_.js} +1 -1
- package/src/assets/web-panel/assets/index-DOZTSoS7.js +1 -0
- package/src/assets/web-panel/assets/{index-BrkJ7JPm.js → index-DPdUNk1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cnok8mhZ.js → index-DVsqvI4M.js} +1 -1
- package/src/assets/web-panel/assets/index-DhpvjpqI.js +1 -0
- package/src/assets/web-panel/assets/{index-CAVW0cWM.js → index-DmkMXwnR.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cc9aPkv-.js → index-DocdRcbd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnVVYKCE.js → index-Dyngbd29.js} +20 -20
- package/src/assets/web-panel/assets/{index-D8gt0j7r.js → index-GwdRUZ-x.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIYTjbv_.js → index-LvCBfTLo.js} +1 -1
- package/src/assets/web-panel/assets/{index-DhXay17G.js → index-cpEli44X.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQWENaZf.js → index-fzaMtSJ8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfRDyY1q.js → index-pum7HYBA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgSR2WMG.js → index-t8N1tSeX.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5IytTND.js → index-uCbEN7cY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtRwLhee.js → index-wKTLbKyc.js} +1 -1
- package/src/assets/web-panel/assets/{index-D4kZoXNr.js → index-wV6iGdpY.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Cvt59c10.js → initDefaultProps-V5Fo95FM.js} +1 -1
- package/src/assets/web-panel/assets/{motion-D15pPEzl.js → motion-BYWU0hUT.js} +1 -1
- package/src/assets/web-panel/assets/{move-N55KeXJ7.js → move-Cr1M-J2h.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CyFO1bYP.js → mtc-parser-BysQKi2N.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B5IXfxU2.js → omit-D1zHU8GC.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CpVqsulV.js → pickAttrs-CUArxtfi.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ME36sMF3.js → placementArrow-ChoYEys0.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BXAIR1r-.js → responsiveObserve-BQRs3Mo7.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BkOX3-Dp.js → slide-B8zbsCkg.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Cy4Aklpt.js → statusUtils-C2U8Gs6h.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-gUd2T206.js → styleChecker-Dd8MgL_V.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CaVD4o99.js → useFlexGapSupport-hknqY5NH.js} +1 -1
- package/src/assets/web-panel/assets/{useFs--pFGl0KD.js → useFs-CLTAmcfw.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D45iP86i.js → usePersonalDataHub-ByegHbiB.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BayoChH_.js → vnode-DqlAy5DP.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CpP38poi.js → zoom-DiXiztQn.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +115 -3
- package/src/commands/agent.js +10 -1
- package/src/commands/background-session.js +2 -1
- package/src/commands/context.js +69 -2
- package/src/data/changelog.json +26 -0
- package/src/gateways/terminal/PtyManager.js +45 -4
- package/src/gateways/ws/background-agent-protocol.js +38 -0
- package/src/gateways/ws/message-dispatcher.js +1 -0
- package/src/gateways/ws/remote-session-protocol.js +65 -6
- package/src/gateways/ws/ws-server.js +18 -2
- package/src/harness/background-task-manager.js +70 -2
- package/src/harness/feature-flags.js +15 -8
- package/src/harness/mcp-client.js +618 -43
- package/src/harness/worktree-isolator.js +14 -3
- package/src/lazy-dispatch.js +30 -1
- package/src/lib/agent-authority.js +22 -0
- package/src/lib/agent-core.js +3 -0
- package/src/lib/agent-sandbox.js +161 -0
- package/src/lib/agent-schedule-store.js +45 -22
- package/src/lib/agent-team/team-runner.js +22 -0
- package/src/lib/artifact-store.js +35 -0
- package/src/lib/async-hook-supervisor.cjs +13 -2
- package/src/lib/audit-mtc.js +3 -2
- package/src/lib/background-agent-supervisor.js +104 -3
- package/src/lib/background-interaction-journal.js +407 -0
- package/src/lib/background-interaction-resolver.js +23 -34
- package/src/lib/background-session-transport.js +12 -2
- package/src/lib/capability-manifest.js +41 -3
- package/src/lib/capability-negotiation.js +1 -1
- package/src/lib/channels/channel-manager.js +33 -0
- package/src/lib/channels/telegram-channel.js +23 -5
- package/src/lib/channels/webhook-channel.js +38 -15
- package/src/lib/chrome-connector.js +169 -23
- package/src/lib/config-manager.js +23 -9
- package/src/lib/context-breakdown.js +31 -0
- package/src/lib/cowork-cron.js +274 -32
- package/src/lib/cross-chain-mtc.js +3 -2
- package/src/lib/durable-security-store.js +124 -0
- package/src/lib/event-runtime-host.js +67 -6
- package/src/lib/event-runtime-store.js +163 -0
- package/src/lib/goal-store.js +32 -12
- package/src/lib/headless-manifest.js +2 -1
- package/src/lib/hook-environment.cjs +58 -0
- package/src/lib/hook-manager.js +12 -5
- package/src/lib/hook-runner.cjs +122 -28
- package/src/lib/hook-runner.js +7 -2
- package/src/lib/hooks-v2-producers.js +36 -0
- package/src/lib/hooks-v2-runtime.js +329 -52
- package/src/lib/interaction-adapter.js +60 -19
- package/src/lib/interaction-binding.js +64 -0
- package/src/lib/json-schema-output.js +439 -14
- package/src/lib/json-schema-validate.js +514 -883
- package/src/lib/lan-pairing-tokens.js +115 -57
- package/src/lib/lsp/__tests__/lsp-client.test.js +32 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +25 -0
- package/src/lib/lsp/lsp-client.js +4 -0
- package/src/lib/lsp/lsp-manager.js +3 -0
- package/src/lib/lsp/lsp-server-registry.js +18 -0
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-oauth.js +35 -21
- package/src/lib/packer/pkg-config-generator.js +3 -0
- package/src/lib/permission-decision.js +99 -0
- package/src/lib/plugin-monitor-supervisor.js +3 -0
- package/src/lib/plugin-runtime/bin.js +1148 -70
- package/src/lib/plugin-runtime/capabilities.js +50 -0
- package/src/lib/plugin-runtime/capability-consent.js +42 -35
- package/src/lib/plugin-runtime/hooks.js +36 -9
- package/src/lib/plugin-runtime/install.js +23 -7
- package/src/lib/plugin-runtime/lsp.js +4 -0
- package/src/lib/plugin-runtime/manifest.js +112 -8
- package/src/lib/plugin-runtime/mcp.js +30 -5
- package/src/lib/plugin-runtime/monitors.js +11 -0
- package/src/lib/plugin-runtime/plugin-options.js +94 -38
- package/src/lib/plugin-runtime/policy.js +29 -2
- package/src/lib/plugin-runtime/sandbox-policy.js +84 -0
- package/src/lib/plugin-runtime/scopes.js +27 -13
- package/src/lib/plugin-runtime/trust.js +36 -31
- package/src/lib/process-execution-broker/credential-agent.js +114 -16
- package/src/lib/process-execution-broker/credential-transport-worker.js +312 -0
- package/src/lib/process-execution-broker/credential-transport.js +378 -0
- package/src/lib/process-execution-broker/index.js +765 -49
- package/src/lib/process-execution-broker/platform-sandbox.js +4233 -138
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +3856 -0
- package/src/lib/project-mcp-trust.js +21 -26
- package/src/lib/protocol-replay.js +19 -12
- package/src/lib/repl-bang-memorize.js +67 -10
- package/src/lib/settings-hooks.cjs +13 -0
- package/src/lib/skill-loader.js +83 -10
- package/src/lib/slash-commands.js +27 -4
- package/src/lib/sync-credentials.js +5 -4
- package/src/lib/turn-binding.js +8 -6
- package/src/repl/agent-repl.js +117 -31
- package/src/repl/repl-turn-binding.js +5 -2
- package/src/runtime/agent-core.js +699 -70
- package/src/runtime/agent-runtime.js +13 -1
- package/src/runtime/coding-agent-contract-shared.cjs +3 -3
- package/src/runtime/headless-runner.js +105 -7
- package/src/runtime/headless-stream.js +209 -23
- package/src/runtime/mcp-config.js +29 -17
- package/src/runtime/policies/agent-policy.js +2 -0
- package/src/workers/background-agent-worker.js +128 -13
- package/src/assets/web-panel/assets/ChatBubbleRenderer-C7bofJuA.js +0 -1
- package/src/assets/web-panel/assets/Projects-BbgmyQnS.js +0 -1
- package/src/assets/web-panel/assets/RemoteSession-Bqk3EYSu.js +0 -4
- package/src/assets/web-panel/assets/Tasks-3bDAUz8K.js +0 -1
- package/src/assets/web-panel/assets/Terminal-CsMLKIoV.js +0 -3
- package/src/assets/web-panel/assets/chat-CJ19O6Dh.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BBMFnsja.js +0 -1
- package/src/assets/web-panel/assets/index-Do8JMV4N.js +0 -1
- package/src/assets/web-panel/assets/index-UYAJ6iNM.js +0 -1
|
@@ -1,30 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `cc agent -p --json-schema <file>` — structured output for headless runs.
|
|
3
3
|
*
|
|
4
|
-
* The final answer must be JSON that validates against a
|
|
4
|
+
* The final answer must be JSON that validates against a Draft 2020-12 JSON
|
|
5
5
|
* Schema; invalid replies are retried with a corrective prompt (up to
|
|
6
|
-
* MAX_ATTEMPTS total). Implemented
|
|
7
|
-
* `deps.writeOut` capture seam
|
|
8
|
-
*
|
|
6
|
+
* MAX_ATTEMPTS total). Implemented around runAgentHeadless using its
|
|
7
|
+
* `deps.writeOut` capture seam: each attempt runs with output captured, and
|
|
8
|
+
* the validated JSON is the only thing printed.
|
|
9
9
|
*
|
|
10
|
-
* Constrained validation delegates to the
|
|
11
|
-
* in [[json-schema-validate.js]]
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `validateAgainstSchema` (loose `$.a.b` strings) stays exported for callers.
|
|
10
|
+
* Constrained validation delegates to the standards-backed Draft 2020-12
|
|
11
|
+
* adapter in [[json-schema-validate.js]], so retries get precise coded/pointered
|
|
12
|
+
* errors. External references are resolved before the turn starts through a
|
|
13
|
+
* bounded local/HTTPS loader. The legacy `validateAgainstSchema` helper stays
|
|
14
|
+
* exported for compatibility with callers that consume its `$.a.b` strings.
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
17
|
import fsDefault from "fs";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
20
|
import {
|
|
21
|
+
assertSchemaCompiles,
|
|
22
|
+
attachExternalSchemas,
|
|
20
23
|
validate,
|
|
21
24
|
validateSchema,
|
|
22
25
|
buildStructuredResultEvent,
|
|
23
26
|
computeSchemaDigest,
|
|
24
27
|
} from "./json-schema-validate.js";
|
|
28
|
+
import { checkAllowed, webFetch } from "./web-fetch.js";
|
|
25
29
|
|
|
26
30
|
export const MAX_ATTEMPTS = 3;
|
|
27
|
-
|
|
31
|
+
const DEFAULT_MAX_EXTERNAL_DOCUMENTS = 32;
|
|
32
|
+
const DEFAULT_MAX_EXTERNAL_DOCUMENT_BYTES = 1_000_000;
|
|
33
|
+
const DEFAULT_MAX_EXTERNAL_TOTAL_BYTES = 4_000_000;
|
|
34
|
+
const DEFAULT_EXTERNAL_TIMEOUT_MS = 10_000;
|
|
35
|
+
|
|
36
|
+
export const _deps = { fs: fsDefault, webFetch };
|
|
28
37
|
|
|
29
38
|
/**
|
|
30
39
|
* Build the terminal `structured_result` stream event for a value against a
|
|
@@ -37,7 +46,7 @@ export function buildStructuredResult(schema, value) {
|
|
|
37
46
|
|
|
38
47
|
export { computeSchemaDigest };
|
|
39
48
|
|
|
40
|
-
/**
|
|
49
|
+
/** Legacy subset validator. Returns error strings ([] = valid). */
|
|
41
50
|
export function validateAgainstSchema(value, schema, path = "$") {
|
|
42
51
|
const errors = [];
|
|
43
52
|
if (!schema || typeof schema !== "object") return errors;
|
|
@@ -225,7 +234,8 @@ export function loadSchemaFile(fs, schemaFile) {
|
|
|
225
234
|
// schema object, never a path (a filesystem path can't start with `{`). This
|
|
226
235
|
// lets `--json-schema '{"type":"object",...}'` work without a temp file.
|
|
227
236
|
const trimmed = String(schemaFile).trim();
|
|
228
|
-
const isInline =
|
|
237
|
+
const isInline =
|
|
238
|
+
trimmed.startsWith("{") || trimmed === "true" || trimmed === "false";
|
|
229
239
|
let raw;
|
|
230
240
|
if (isInline) {
|
|
231
241
|
raw = trimmed;
|
|
@@ -262,6 +272,413 @@ export function loadSchemaFile(fs, schemaFile) {
|
|
|
262
272
|
return parsed;
|
|
263
273
|
}
|
|
264
274
|
|
|
275
|
+
const SINGLE_SUBSCHEMA_KEYWORDS = [
|
|
276
|
+
"additionalProperties",
|
|
277
|
+
"contains",
|
|
278
|
+
"contentSchema",
|
|
279
|
+
"else",
|
|
280
|
+
"if",
|
|
281
|
+
"items",
|
|
282
|
+
"not",
|
|
283
|
+
"propertyNames",
|
|
284
|
+
"then",
|
|
285
|
+
"unevaluatedItems",
|
|
286
|
+
"unevaluatedProperties",
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
const ARRAY_SUBSCHEMA_KEYWORDS = [
|
|
290
|
+
"allOf",
|
|
291
|
+
"anyOf",
|
|
292
|
+
"oneOf",
|
|
293
|
+
"prefixItems",
|
|
294
|
+
];
|
|
295
|
+
|
|
296
|
+
const MAP_SUBSCHEMA_KEYWORDS = [
|
|
297
|
+
"$defs",
|
|
298
|
+
"definitions",
|
|
299
|
+
"dependentSchemas",
|
|
300
|
+
"patternProperties",
|
|
301
|
+
"properties",
|
|
302
|
+
];
|
|
303
|
+
|
|
304
|
+
function withoutFragment(uri) {
|
|
305
|
+
const parsed = new URL(uri);
|
|
306
|
+
parsed.hash = "";
|
|
307
|
+
return parsed.href;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function resolveSchemaUri(reference, baseUri) {
|
|
311
|
+
try {
|
|
312
|
+
return new URL(reference, baseUri || undefined).href;
|
|
313
|
+
} catch (cause) {
|
|
314
|
+
const error = new Error(
|
|
315
|
+
`Cannot resolve external JSON Schema reference "${reference}"${
|
|
316
|
+
baseUri ? ` from "${baseUri}"` : " without a base URI"
|
|
317
|
+
}`,
|
|
318
|
+
{ cause },
|
|
319
|
+
);
|
|
320
|
+
error.code = "JSON_SCHEMA_REF_INVALID";
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function scanSchemaDocument(
|
|
326
|
+
schema,
|
|
327
|
+
retrievalUri,
|
|
328
|
+
{ references, resources },
|
|
329
|
+
) {
|
|
330
|
+
const seen = new Set();
|
|
331
|
+
|
|
332
|
+
function visit(node, inheritedBase) {
|
|
333
|
+
if (
|
|
334
|
+
node === true ||
|
|
335
|
+
node === false ||
|
|
336
|
+
!node ||
|
|
337
|
+
typeof node !== "object" ||
|
|
338
|
+
Array.isArray(node) ||
|
|
339
|
+
seen.has(node)
|
|
340
|
+
) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
seen.add(node);
|
|
344
|
+
|
|
345
|
+
let baseUri = inheritedBase;
|
|
346
|
+
if (typeof node.$id === "string") {
|
|
347
|
+
baseUri = resolveSchemaUri(node.$id, inheritedBase);
|
|
348
|
+
resources.add(withoutFragment(baseUri));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
for (const keyword of ["$ref", "$dynamicRef"]) {
|
|
352
|
+
const reference = node[keyword];
|
|
353
|
+
if (typeof reference !== "string" || reference.startsWith("#")) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const uri = withoutFragment(resolveSchemaUri(reference, baseUri));
|
|
357
|
+
const origins = references.get(uri) || new Set();
|
|
358
|
+
origins.add(new URL(retrievalUri).protocol);
|
|
359
|
+
references.set(uri, origins);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
for (const keyword of SINGLE_SUBSCHEMA_KEYWORDS) {
|
|
363
|
+
visit(node[keyword], baseUri);
|
|
364
|
+
}
|
|
365
|
+
for (const keyword of ARRAY_SUBSCHEMA_KEYWORDS) {
|
|
366
|
+
if (!Array.isArray(node[keyword])) continue;
|
|
367
|
+
for (const child of node[keyword]) visit(child, baseUri);
|
|
368
|
+
}
|
|
369
|
+
for (const keyword of MAP_SUBSCHEMA_KEYWORDS) {
|
|
370
|
+
const map = node[keyword];
|
|
371
|
+
if (!map || typeof map !== "object" || Array.isArray(map)) continue;
|
|
372
|
+
for (const child of Object.values(map)) visit(child, baseUri);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
resources.add(withoutFragment(retrievalUri));
|
|
377
|
+
visit(schema, retrievalUri);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function parseExternalSchema(raw, uri) {
|
|
381
|
+
if (
|
|
382
|
+
raw === true ||
|
|
383
|
+
raw === false ||
|
|
384
|
+
(raw && typeof raw === "object" && !Array.isArray(raw))
|
|
385
|
+
) {
|
|
386
|
+
return raw;
|
|
387
|
+
}
|
|
388
|
+
if (typeof raw !== "string") {
|
|
389
|
+
throw new Error(
|
|
390
|
+
`External JSON Schema "${uri}" must be an object or boolean`,
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
try {
|
|
394
|
+
const parsed = JSON.parse(raw);
|
|
395
|
+
if (
|
|
396
|
+
parsed === true ||
|
|
397
|
+
parsed === false ||
|
|
398
|
+
(parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
399
|
+
) {
|
|
400
|
+
return parsed;
|
|
401
|
+
}
|
|
402
|
+
throw new TypeError("top-level value must be an object or boolean");
|
|
403
|
+
} catch (cause) {
|
|
404
|
+
throw new Error(`Invalid external JSON Schema "${uri}": ${cause.message}`, {
|
|
405
|
+
cause,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function assertExternalSchemaIsValid(schema, uri) {
|
|
411
|
+
const meta = validateSchema(schema);
|
|
412
|
+
if (meta.valid) return;
|
|
413
|
+
const detail = meta.errors
|
|
414
|
+
.slice(0, 5)
|
|
415
|
+
.map((error) => `${error.schemaPath || "/"}: ${error.message}`)
|
|
416
|
+
.join("; ");
|
|
417
|
+
throw new Error(`Invalid external JSON Schema "${uri}": ${detail}`);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function localSchemaPath(uri, rootDirectory, fs) {
|
|
421
|
+
const candidate = path.resolve(fileURLToPath(uri));
|
|
422
|
+
const checkedRoot =
|
|
423
|
+
typeof fs.realpathSync === "function"
|
|
424
|
+
? fs.realpathSync(rootDirectory)
|
|
425
|
+
: rootDirectory;
|
|
426
|
+
const checkedCandidate =
|
|
427
|
+
typeof fs.realpathSync === "function"
|
|
428
|
+
? fs.realpathSync(candidate)
|
|
429
|
+
: candidate;
|
|
430
|
+
const relative = path.relative(checkedRoot, checkedCandidate);
|
|
431
|
+
if (
|
|
432
|
+
relative === ".." ||
|
|
433
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
434
|
+
path.isAbsolute(relative)
|
|
435
|
+
) {
|
|
436
|
+
const error = new Error(
|
|
437
|
+
`Local JSON Schema reference escapes the root schema directory: ${candidate}`,
|
|
438
|
+
);
|
|
439
|
+
error.code = "JSON_SCHEMA_REF_PATH_ESCAPE";
|
|
440
|
+
throw error;
|
|
441
|
+
}
|
|
442
|
+
return candidate;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async function fetchExternalSchema(
|
|
446
|
+
uri,
|
|
447
|
+
{
|
|
448
|
+
allowedDomains,
|
|
449
|
+
allowFileReference,
|
|
450
|
+
fetchSchema,
|
|
451
|
+
fs,
|
|
452
|
+
maxDocumentBytes,
|
|
453
|
+
rootDirectory,
|
|
454
|
+
timeoutMs,
|
|
455
|
+
},
|
|
456
|
+
) {
|
|
457
|
+
const parsed = new URL(uri);
|
|
458
|
+
if (parsed.protocol === "file:") {
|
|
459
|
+
if (!rootDirectory || !allowFileReference) {
|
|
460
|
+
throw new Error(
|
|
461
|
+
`A file JSON Schema reference is only allowed from a local root graph: ${uri}`,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
const filename = localSchemaPath(uri, rootDirectory, fs);
|
|
465
|
+
const raw = fs.readFileSync(filename, "utf8");
|
|
466
|
+
const bytes = Buffer.byteLength(String(raw), "utf8");
|
|
467
|
+
if (bytes > maxDocumentBytes) {
|
|
468
|
+
throw new Error(
|
|
469
|
+
`External JSON Schema "${uri}" exceeds ${maxDocumentBytes} bytes`,
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
schema: parseExternalSchema(raw, uri),
|
|
474
|
+
bytes,
|
|
475
|
+
retrievalUri: uri,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (parsed.protocol !== "https:") {
|
|
480
|
+
const error = new Error(
|
|
481
|
+
`External JSON Schema references must use HTTPS: ${uri}`,
|
|
482
|
+
);
|
|
483
|
+
error.code = "JSON_SCHEMA_REF_PROTOCOL_BLOCKED";
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
|
+
if (parsed.username || parsed.password) {
|
|
487
|
+
const error = new Error(
|
|
488
|
+
`External JSON Schema references cannot contain credentials: ${uri}`,
|
|
489
|
+
);
|
|
490
|
+
error.code = "JSON_SCHEMA_REF_CREDENTIALS_BLOCKED";
|
|
491
|
+
throw error;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const policy = checkAllowed(uri, {
|
|
495
|
+
allowedDomains,
|
|
496
|
+
allowPrivateHosts: false,
|
|
497
|
+
});
|
|
498
|
+
if (!policy.allowed) {
|
|
499
|
+
const error = new Error(
|
|
500
|
+
`External JSON Schema reference blocked: ${policy.reason}`,
|
|
501
|
+
);
|
|
502
|
+
error.code = "JSON_SCHEMA_REF_BLOCKED";
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const response = await fetchSchema(uri, {
|
|
507
|
+
format: "json",
|
|
508
|
+
maxBytes: maxDocumentBytes,
|
|
509
|
+
timeout: timeoutMs,
|
|
510
|
+
config: {
|
|
511
|
+
allowedDomains,
|
|
512
|
+
allowPrivateHosts: false,
|
|
513
|
+
},
|
|
514
|
+
headers: {
|
|
515
|
+
Accept: "application/schema+json, application/json",
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
const responseEnvelope =
|
|
519
|
+
response &&
|
|
520
|
+
typeof response === "object" &&
|
|
521
|
+
(Object.prototype.hasOwnProperty.call(response, "statusCode") ||
|
|
522
|
+
Object.prototype.hasOwnProperty.call(response, "bytes") ||
|
|
523
|
+
Object.prototype.hasOwnProperty.call(response, "contentType") ||
|
|
524
|
+
Object.prototype.hasOwnProperty.call(response, "format") ||
|
|
525
|
+
Object.prototype.hasOwnProperty.call(response, "url") ||
|
|
526
|
+
(Object.prototype.hasOwnProperty.call(response, "error") &&
|
|
527
|
+
Object.keys(response).length <= 2));
|
|
528
|
+
if (responseEnvelope && response?.error) {
|
|
529
|
+
throw new Error(
|
|
530
|
+
`Could not load external JSON Schema "${uri}": ${response.error}`,
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
if (
|
|
534
|
+
Number.isFinite(response?.statusCode) &&
|
|
535
|
+
(response.statusCode < 200 || response.statusCode >= 300)
|
|
536
|
+
) {
|
|
537
|
+
throw new Error(
|
|
538
|
+
`Could not load external JSON Schema "${uri}": HTTP ${response.statusCode}`,
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const raw =
|
|
543
|
+
responseEnvelope &&
|
|
544
|
+
Object.prototype.hasOwnProperty.call(response, "content")
|
|
545
|
+
? response.content
|
|
546
|
+
: response;
|
|
547
|
+
const schema = parseExternalSchema(raw, uri);
|
|
548
|
+
const bytes =
|
|
549
|
+
Number.isFinite(response?.bytes) && response.bytes >= 0
|
|
550
|
+
? response.bytes
|
|
551
|
+
: Buffer.byteLength(JSON.stringify(schema), "utf8");
|
|
552
|
+
if (bytes > maxDocumentBytes) {
|
|
553
|
+
throw new Error(
|
|
554
|
+
`External JSON Schema "${uri}" exceeds ${maxDocumentBytes} bytes`,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
let retrievalUri = uri;
|
|
558
|
+
if (responseEnvelope && response?.url) {
|
|
559
|
+
retrievalUri = withoutFragment(
|
|
560
|
+
resolveSchemaUri(String(response.url), uri),
|
|
561
|
+
);
|
|
562
|
+
const redirected = new URL(retrievalUri);
|
|
563
|
+
const redirectPolicy = checkAllowed(retrievalUri, {
|
|
564
|
+
allowedDomains,
|
|
565
|
+
allowPrivateHosts: false,
|
|
566
|
+
});
|
|
567
|
+
if (
|
|
568
|
+
redirected.protocol !== "https:" ||
|
|
569
|
+
redirected.username ||
|
|
570
|
+
redirected.password ||
|
|
571
|
+
!redirectPolicy.allowed
|
|
572
|
+
) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`External JSON Schema redirect is blocked: ${retrievalUri}`,
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return { schema, bytes, retrievalUri };
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Load a root schema and resolve every external `$ref`/`$dynamicRef` before a
|
|
583
|
+
* turn starts. Local references are confined to the root schema directory.
|
|
584
|
+
* Remote references are HTTPS-only and use the shared DNS-rebinding/SSRF-safe
|
|
585
|
+
* fetch path with bounded document count, bytes, redirects and timeout.
|
|
586
|
+
*/
|
|
587
|
+
export async function loadSchemaFileWithRefs(
|
|
588
|
+
fs,
|
|
589
|
+
schemaFile,
|
|
590
|
+
options = {},
|
|
591
|
+
) {
|
|
592
|
+
const schema = loadSchemaFile(fs, schemaFile);
|
|
593
|
+
if (!schema || typeof schema !== "object") return schema;
|
|
594
|
+
|
|
595
|
+
const trimmed = String(schemaFile).trim();
|
|
596
|
+
const inline =
|
|
597
|
+
trimmed.startsWith("{") || trimmed === "true" || trimmed === "false";
|
|
598
|
+
const rootPath = inline ? null : path.resolve(schemaFile);
|
|
599
|
+
const retrievalUri = rootPath
|
|
600
|
+
? pathToFileURL(rootPath).href
|
|
601
|
+
: typeof schema.$id === "string"
|
|
602
|
+
? resolveSchemaUri(schema.$id, null)
|
|
603
|
+
: "urn:chainlesschain:inline-schema";
|
|
604
|
+
const rootDirectory = rootPath ? path.dirname(rootPath) : null;
|
|
605
|
+
const allowedDomains = Array.isArray(options.allowedDomains)
|
|
606
|
+
? options.allowedDomains
|
|
607
|
+
: ["*"];
|
|
608
|
+
const maxDocuments =
|
|
609
|
+
options.maxDocuments ?? DEFAULT_MAX_EXTERNAL_DOCUMENTS;
|
|
610
|
+
const maxDocumentBytes =
|
|
611
|
+
options.maxDocumentBytes ?? DEFAULT_MAX_EXTERNAL_DOCUMENT_BYTES;
|
|
612
|
+
const maxTotalBytes =
|
|
613
|
+
options.maxTotalBytes ?? DEFAULT_MAX_EXTERNAL_TOTAL_BYTES;
|
|
614
|
+
const timeoutMs =
|
|
615
|
+
options.timeoutMs ?? DEFAULT_EXTERNAL_TIMEOUT_MS;
|
|
616
|
+
const fetchSchema =
|
|
617
|
+
options.fetchSchema || _deps.webFetch;
|
|
618
|
+
|
|
619
|
+
const references = new Map();
|
|
620
|
+
const resources = new Set();
|
|
621
|
+
const fetched = new Set();
|
|
622
|
+
const registry = {};
|
|
623
|
+
let totalBytes = 0;
|
|
624
|
+
|
|
625
|
+
scanSchemaDocument(schema, retrievalUri, { references, resources });
|
|
626
|
+
|
|
627
|
+
while (true) {
|
|
628
|
+
const uri = [...references.keys()].find(
|
|
629
|
+
(candidate) =>
|
|
630
|
+
!resources.has(candidate) && !fetched.has(candidate),
|
|
631
|
+
);
|
|
632
|
+
if (!uri) break;
|
|
633
|
+
if (fetched.size >= maxDocuments) {
|
|
634
|
+
throw new Error(
|
|
635
|
+
`External JSON Schema graph exceeds ${maxDocuments} documents`,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
fetched.add(uri);
|
|
639
|
+
|
|
640
|
+
const loaded = await fetchExternalSchema(uri, {
|
|
641
|
+
allowedDomains,
|
|
642
|
+
allowFileReference: [...(references.get(uri) || [])].every(
|
|
643
|
+
(protocol) => protocol === "file:",
|
|
644
|
+
),
|
|
645
|
+
fetchSchema,
|
|
646
|
+
fs,
|
|
647
|
+
maxDocumentBytes,
|
|
648
|
+
rootDirectory,
|
|
649
|
+
timeoutMs,
|
|
650
|
+
});
|
|
651
|
+
totalBytes += loaded.bytes;
|
|
652
|
+
if (totalBytes > maxTotalBytes) {
|
|
653
|
+
throw new Error(
|
|
654
|
+
`External JSON Schema graph exceeds ${maxTotalBytes} bytes`,
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
assertExternalSchemaIsValid(loaded.schema, uri);
|
|
658
|
+
const redirected =
|
|
659
|
+
loaded.retrievalUri && loaded.retrievalUri !== uri;
|
|
660
|
+
if (redirected) {
|
|
661
|
+
registry[loaded.retrievalUri] = loaded.schema;
|
|
662
|
+
registry[uri] = { $ref: loaded.retrievalUri };
|
|
663
|
+
resources.add(uri);
|
|
664
|
+
scanSchemaDocument(loaded.schema, loaded.retrievalUri, {
|
|
665
|
+
references,
|
|
666
|
+
resources,
|
|
667
|
+
});
|
|
668
|
+
} else {
|
|
669
|
+
registry[uri] = loaded.schema;
|
|
670
|
+
scanSchemaDocument(loaded.schema, loaded.retrievalUri || uri, {
|
|
671
|
+
references,
|
|
672
|
+
resources,
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
attachExternalSchemas(schema, registry, { baseUri: retrievalUri });
|
|
678
|
+
assertSchemaCompiles(schema);
|
|
679
|
+
return schema;
|
|
680
|
+
}
|
|
681
|
+
|
|
265
682
|
/**
|
|
266
683
|
* Run a headless turn constrained to a schema, retrying on validation
|
|
267
684
|
* failure. Prints the validated JSON to writeOut; returns the exit code.
|
|
@@ -275,7 +692,15 @@ export async function runJsonSchemaConstrained(cfg = {}) {
|
|
|
275
692
|
const writeErr = cfg.writeErr || ((s) => process.stderr.write(s));
|
|
276
693
|
const maxAttempts = cfg.maxAttempts || MAX_ATTEMPTS;
|
|
277
694
|
|
|
278
|
-
const schema =
|
|
695
|
+
const schema =
|
|
696
|
+
cfg.schema ||
|
|
697
|
+
(await loadSchemaFileWithRefs(fs, cfg.schemaFile, {
|
|
698
|
+
...(cfg.schemaLoadOptions || {}),
|
|
699
|
+
fetchSchema:
|
|
700
|
+
cfg.schemaLoadOptions?.fetchSchema ||
|
|
701
|
+
cfg.deps?.webFetch ||
|
|
702
|
+
_deps.webFetch,
|
|
703
|
+
}));
|
|
279
704
|
const instruction = buildSchemaInstruction(schema);
|
|
280
705
|
const base = cfg.baseOptions || {};
|
|
281
706
|
|