chainlesschain 0.162.162 → 0.162.164
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 +3 -1
- package/src/assets/web-panel/assets/{AIOps-ClI2ALgv.js → AIOps-BqRkaHGb.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BDjRcJaK.js → ActionButton-DWO7OZLC.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DikSRsaT.js → Analytics-C5oaVezM.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-9mLhMFmz.js → AppLayout-CsUESDoZ.js} +3 -3
- package/src/assets/web-panel/assets/{Artifacts-BSr88BrH.js → Artifacts-Dragqu5k.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-CdvyimOF.js → Audit-CQsaHctY.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-D3_hCedh.js → BackgroundAgents-DdG1jNSM.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cyvv9RHf.js → Backup-DN6sjK4z.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BZM14kt8.js → BaseInput-Cxm_ZTCl.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DrQSokVz.js → Chat-DVXGmA56.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-HwJR-C6B.js → ChatBubbleRenderer-BdaCL_iE.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-bFLYeWMV.js → Checkbox-DEc4vD_A.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-7mN7xJXT.js → Codegen-CKiTcv36.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DAB5ZWm7.js → Col-Br9UUNN0.js} +1 -1
- package/src/assets/web-panel/assets/{Community-B_1TymaK.js → Community-NeUH_70T.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Bq1uSWLJ.js → Compact-BqR-z2Df.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CyiE1jEe.js → Compliance-DcWB_SgZ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Cpk0D7vm.js → Cowork-BfhgcudF.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-d_Lv3rdB.js → Cron-LaU29LgD.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DMqhHjMR.js → Crosschain-B2ZB9uwW.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Br-oPuBw.js → DID-BuHl38A2.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CfLW_RaP.js → Dashboard-m627yqvZ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DZnTOExV.js → Dropdown-C7bxF8F5.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DHIUHDv1.js → EmailListRenderer-DPLPQzLp.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bw3t3myu.js → FamilyGuardDashboard-cOiH6ike.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9cpQPAY.js → Federation-Bvkzg88z.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Jdczr9Mr.js → FormItemContext-BTsiA7h_.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BT8ZMpC5.js → GenericCardRenderer-BGnVE5qu.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DjARip2b.js → Git-DS_j6r25.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BgWbSRcj.js → Governance-CKRG3Rsl.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CfouJciM.js → Inference-DW8INoNQ.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-50l7mrAr.js → KnowledgeGraph-BhEYeFhC.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-rq50H84B.js → Logs-wqi0uxuR.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DUPIEdQH.js → MarkdownRenderer-DS8dE8ty.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BYgPDmHU.js → Marketplace-CMlTuPLT.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-5DVgcFdx.js → McpTools-CSx4m5JJ.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-B70LPk7f.js → Memory-vnQCUy-_.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-De8ssA5Y.js → MobileBridge-BV2NA742.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-Bw0k8e1B.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-RJsOTsIA.js → Mtc-CzK_FPB1.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Crh-6BEK.js → MtcAudit-Cb7G9oL3.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-wuoR5l3x.js → Multisig-qJxlUyzr.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-U2Mji4fZ.js → NLProgramming-DqaBJ7Te.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CdTZAyDH.js → Notes-CwhTJkRi.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-C-FucWE7.js → NotificationSettings-YDs4Fal4.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DCYFTeaI.js → OrderTableRenderer-CvEALpq7.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-an3OF85L.js → Organization-CEmQm9n8.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-C-1vmYFe.js → Overflow-zby_P_LA.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cwh47xKg.js → P2P-DsmDNFNT.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Dm38GT0k.js → PdhVaultBrowser-FWwFlZGF.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DS2Y8awD.js → Permissions-DuzQ6me5.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BQNziA0I.js → PersonalDataHub-DZbeN613.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-DF85L1ue.js → Pipeline-CoNSVAUS.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BuLornF-.js → Privacy-OYJEAaMC.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C3Y31IwX.js → ProjectInit-CWIapV--.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BCPiI8aD.js → ProjectSettings-CX8xMxZn.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BZ6s4k6g.js → Projects-BLCN8YyY.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-D3Wp022X.js → Providers-BV_sxp75.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CUJfQkH4.js → QrScannerModal-BTnRrHRp.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-UAc0EO8l.js → QuickAsk-D1KZg018.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BaxKupcs.js → Recommend-COm5cuNg.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C75NNnXZ.js → RemoteSession-0saWEkYI.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BVXynZAk.js → Reputation-Dr7iKLS2.js} +1 -1
- package/src/assets/web-panel/assets/{Row-C5MRZ0bi.js → Row-C1vpPBcr.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DAKkEYka.js → RssFeed-CxlWrtNj.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DvWv9YOA.js → Search-BT2V8dPN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-B5peafW1.js → Security-bm9V3c5k.js} +4 -4
- package/src/assets/web-panel/assets/{Services-UQmvPEaG.js → Services-CocH1yyX.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-C3bhWpuF.js → Skeleton-DHItlMdd.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DfkKf9_H.js → Skills-C59sLc4w.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DqMSjlBM.js → Sla-Crj4BMc8.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-C-WbxWUX.js → SpeechSettings-DX4KFceY.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CYuHZ4N2.js → SyncSettings-BD_iwQLr.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CyeAyB9d.js → Tasks-BmCTzYsH.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BTCeQnpq.js → Templates-BGUaxZYl.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BifQuA9Y.js → Tenant-BS0tJx2O.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-Bx_9Bocf.js → Terminal--tHSAsld.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BX0RFCOm.js → TimelineRenderer-D9-MFxS4.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CGHrCmUS.js → Tokens-CiCB485f.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DlqaY4SO.js → Trigger-SmCFuW_l.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DfOmj-ay.js → Trust-DkK3Rqe0.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B72jH5fE.js → UkeySign-CDM4LGdB.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BT-63fqv.js → VideoEditing-IDB7DJXt.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Dsul3sHr.js → Wallet-Bikj5cmt.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Izkwwdgy.js → WebAuthn-C9abWlAw.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-D3FHSiH1.js → WorkflowEditor-DrbRKVky.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CmVz5z3U.js → chat-CccCSDQf.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CuLgyJBp.js → colors-CXObXLhb.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Ml1YkXpw.js → compact-item-B5kfYAxC.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BvjJ48bs.js → createContext-DmiPBfip.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CvKrADNa.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DVC0157C.js → hasIn-Q6lYteAc.js} +1 -1
- package/src/assets/web-panel/assets/{index-C229ABfy.js → index-25Wlqps4.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ck_52dz_.js → index-33U29UNV.js} +1 -1
- package/src/assets/web-panel/assets/{index-QXzlT9KD.js → index-4oXBDczR.js} +1 -1
- package/src/assets/web-panel/assets/{index-4SBta3d7.js → index-BGYXvMc5.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0S8NzO6.js → index-BJCCa0s_.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJyN28Et.js → index-BJJ5DhKI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DC_OI9H2.js → index-BLOzViJ6.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_XuRgGn.js → index-BRrbUMoG.js} +1 -1
- package/src/assets/web-panel/assets/{index-wvb_FtaV.js → index-BUFpT17Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-KMqhcF7l.js → index-BkRDiqGc.js} +1 -1
- package/src/assets/web-panel/assets/{index-vG4XSJ1d.js → index-BsfvW6my.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYXHFr4r.js → index-By-kfPED.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuGszaWY.js → index-BzFTcQsc.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXkJH-lK.js → index-C2FXdboq.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dt5KMjwJ.js → index-C5XOlTHN.js} +1 -1
- package/src/assets/web-panel/assets/{index-4wcgvPoF.js → index-CLhBDS2w.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_H_S-DY.js → index-CMq7UeoT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BydjdZnl.js → index-CVMTWNKl.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjHBpRYZ.js → index-Caghi-yL.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bzr0rB5T.js → index-CdB6FuSH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbPtzB8M.js → index-CoK8-kWQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUt8kTIB.js → index-CsO3GUAY.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_vRgTl9.js → index-CwZBa20Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DukDVXCv.js → index-D-kASucw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbepULSc.js → index-D8eBw7vW.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfuKP4qe.js → index-D9wgifk4.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiC6dQZG.js → index-DAYCTc07.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmFNvNLZ.js → index-DF6Q8l2h.js} +1 -1
- package/src/assets/web-panel/assets/index-DTdFUWc_.js +1 -0
- package/src/assets/web-panel/assets/{index-KjgKdZe-.js → index-DgTLApS9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpFJHiTv.js → index-DgxVJ8pg.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cw0Rjy87.js → index-DlJvIqoR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFYVQMvu.js → index-Dw4eHfsG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CudmwNBV.js → index-Rh-ytwow.js} +3 -3
- package/src/assets/web-panel/assets/{index-DDGaOWBV.js → index-StAEt2pq.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3lD5qap.js → index-bzfw951k.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzG-x9p4.js → index-fSUMbMvv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_EvG_GW.js → index-tFHy5Wol.js} +1 -1
- package/src/assets/web-panel/assets/index-zQ0M_kz-.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-BDgd2YZ8.js → initDefaultProps-BNq7X72N.js} +1 -1
- package/src/assets/web-panel/assets/{motion-ErtrXdYe.js → motion-DOf9viTc.js} +1 -1
- package/src/assets/web-panel/assets/{move-_GPPNCgs.js → move-CRHTcW4x.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DRLL-8V2.js → mtc-parser-Cyoozgm2.js} +1 -1
- package/src/assets/web-panel/assets/{omit-p86sl023.js → omit-6-TjFNru.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BTu7cMLH.js → pickAttrs-DlUmO1zi.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BEKz6Isr.js → placementArrow-CFOL8mIR.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Ck42c9MP.js → responsiveObserve-BtaFK5zd.js} +1 -1
- package/src/assets/web-panel/assets/{slide-1CEvuPsB.js → slide-BIbc2bur.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BDfdx1GJ.js → statusUtils-BXX9d6-w.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B4K46m5w.js → styleChecker-BGv10Bpn.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DoIVpJNq.js → useFlexGapSupport-bKnKT8tw.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DdAWi-ln.js → useFs-FY4IL4jn.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-iUu6k8dx.js → usePersonalDataHub-Bwl9TEgu.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DZz4R6Tw.js → vnode-BM3OHxAT.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DXlf9sA3.js → zoom-D1fbFiHB.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agenda.js +320 -32
- package/src/commands/agent.js +105 -11
- package/src/commands/context.js +125 -14
- package/src/commands/doctor.js +85 -1
- package/src/commands/hook.js +181 -7
- package/src/commands/plugin.js +456 -1
- package/src/commands/review.js +363 -2
- package/src/commands/session.js +191 -0
- package/src/commands/team.js +19 -1
- package/src/data/changelog.json +10 -4
- package/src/gateways/ws/remote-session-protocol.js +39 -0
- package/src/gateways/ws/session-protocol.js +55 -2
- package/src/gateways/ws/ws-agent-handler.js +50 -0
- package/src/harness/jsonl-session-store.js +60 -0
- package/src/harness/worktree-isolator.js +140 -5
- package/src/lib/agent-schedule-store.js +318 -10
- package/src/lib/agent-team/team-worktree.js +37 -2
- package/src/lib/agent-tool-admission.js +125 -0
- package/src/lib/app-preview.js +360 -0
- package/src/lib/async-hook-supervisor.cjs +54 -0
- package/src/lib/capability-manifest.js +319 -0
- package/src/lib/capability-negotiation.js +23 -12
- package/src/lib/channels/channel-manager.js +54 -2
- package/src/lib/cli-context-engineering.js +9 -2
- package/src/lib/context-breakdown.js +116 -0
- package/src/lib/diagnostic-bundle.js +230 -0
- package/src/lib/doctor-checkup.js +275 -4
- package/src/lib/execution-location.js +286 -0
- package/src/lib/headless-manifest.js +13 -40
- package/src/lib/hook-event-log.cjs +193 -0
- package/src/lib/hook-stats-store.cjs +197 -0
- package/src/lib/idempotency.js +109 -0
- package/src/lib/interaction-adapter.js +34 -4
- package/src/lib/json-schema-output.js +46 -12
- package/src/lib/json-schema-validate.js +143 -3
- package/src/lib/jsonl-session-store.js +1 -0
- package/src/lib/lsp/__tests__/lsp-manager.test.js +58 -0
- package/src/lib/lsp/lsp-manager.js +56 -0
- package/src/lib/monitor-event.js +290 -0
- package/src/lib/operation-fingerprint.js +217 -0
- package/src/lib/plugin-runtime/bin.js +37 -0
- package/src/lib/plugin-runtime/capabilities.js +19 -0
- package/src/lib/plugin-runtime/capability-consent.js +203 -0
- package/src/lib/plugin-runtime/hooks.js +37 -0
- package/src/lib/plugin-runtime/lsp.js +38 -0
- package/src/lib/plugin-runtime/mcp.js +40 -0
- package/src/lib/plugin-runtime/monitors.js +37 -0
- package/src/lib/plugin-runtime/plugin-options.js +151 -0
- package/src/lib/plugin-runtime/policy.js +62 -0
- package/src/lib/plugin-runtime/scopes.js +20 -4
- package/src/lib/pr-automation-policy.js +224 -0
- package/src/lib/project-instructions.js +128 -0
- package/src/lib/remote-approval-bridge.js +66 -13
- package/src/lib/repl-goal.js +132 -0
- package/src/lib/repl-rewind.js +153 -0
- package/src/lib/review-comment-anchor.js +241 -0
- package/src/lib/review-pipeline.js +46 -7
- package/src/lib/runtime-checkup.js +221 -0
- package/src/lib/schedule-planner.js +17 -1
- package/src/lib/secret-scan.js +409 -0
- package/src/lib/session-branch.js +0 -0
- package/src/lib/settings-hook-events.cjs +13 -0
- package/src/lib/settings-loader.cjs +42 -0
- package/src/lib/side-effect-ledger-store.js +88 -0
- package/src/lib/side-effect-ledger.js +401 -0
- package/src/lib/skill-loader.js +32 -0
- package/src/lib/skill-path-scope.js +63 -0
- package/src/lib/sub-agent-context.js +110 -9
- package/src/lib/sub-agent-registry.js +19 -0
- package/src/lib/subagent-inheritance.js +112 -0
- package/src/lib/telemetry/span-recorder.js +17 -4
- package/src/lib/terminal-context.js +195 -0
- package/src/lib/turn-binding-store.js +119 -0
- package/src/lib/unattended-action-policy.js +182 -0
- package/src/lib/worktree-cleanup-safety.js +138 -0
- package/src/lib/worktree-isolator.js +8 -0
- package/src/lib/worktree-sparse.js +131 -0
- package/src/repl/agent-repl.js +280 -30
- package/src/repl/permission-tier.js +28 -0
- package/src/runtime/agent-core.js +565 -21
- package/src/runtime/coding-agent-contract-shared.cjs +60 -1
- package/src/runtime/diagnostics.js +60 -0
- package/src/runtime/headless-runner.js +393 -1
- package/src/runtime/headless-stream.js +60 -1
- package/src/assets/web-panel/assets/MobileProjects-D10VISps.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DhiGrbsh.js +0 -1
- package/src/assets/web-panel/assets/index-B7a1TrU6.js +0 -1
- package/src/assets/web-panel/assets/index-C2B1KRja.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -116,6 +116,7 @@ import { describeAskContext, raceLocalAndRemote } from "./remote-approval.js";
|
|
|
116
116
|
import {
|
|
117
117
|
parsePermissionTier,
|
|
118
118
|
parsePermissionModeArg,
|
|
119
|
+
permissionModeForTier,
|
|
119
120
|
describeTier,
|
|
120
121
|
nextTier,
|
|
121
122
|
} from "./permission-tier.js";
|
|
@@ -460,6 +461,10 @@ export async function startAgentRepl(options = {}) {
|
|
|
460
461
|
// tier but additionally activates the autoMode.decisions classifier wrapper
|
|
461
462
|
// (when settings customize it) — gateTierFor() maps mode → real gate tier.
|
|
462
463
|
let _sessionTier = "strict";
|
|
464
|
+
// `/goal <condition>`: an optional SESSION completion condition. When set, the
|
|
465
|
+
// condition is evaluated + reported after each turn (interactive — no auto
|
|
466
|
+
// re-drive; that autonomous loop is headless-only). null = no session goal.
|
|
467
|
+
let _sessionGoal = null;
|
|
463
468
|
const gateTierFor = (mode) =>
|
|
464
469
|
mode === "auto" ? "trusted" : mode === "dontAsk" ? "strict" : mode;
|
|
465
470
|
// dontAsk (headless parity, interactive form): anything that would prompt
|
|
@@ -1581,6 +1586,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
1581
1586
|
"/exit",
|
|
1582
1587
|
"/export",
|
|
1583
1588
|
"/fast",
|
|
1589
|
+
"/goal",
|
|
1584
1590
|
"/help",
|
|
1585
1591
|
"/hooks",
|
|
1586
1592
|
"/ide",
|
|
@@ -2182,7 +2188,10 @@ export async function startAgentRepl(options = {}) {
|
|
|
2182
2188
|
` ${chalk.cyan("/export")} Save this conversation to a Markdown file (/export [path])`,
|
|
2183
2189
|
);
|
|
2184
2190
|
logger.log(
|
|
2185
|
-
` ${chalk.cyan("/rewind")} Rewind to an earlier turn (double-Esc lists); ${chalk.cyan("/rewind clear")} restores a /clear`,
|
|
2191
|
+
` ${chalk.cyan("/rewind")} Rewind to an earlier turn (double-Esc lists); ${chalk.cyan("/rewind <n> --files|--conversation")} scopes it; ${chalk.cyan("/rewind <n> --branch")} forks a session; ${chalk.cyan("/rewind clear")} restores a /clear`,
|
|
2192
|
+
);
|
|
2193
|
+
logger.log(
|
|
2194
|
+
` ${chalk.cyan("/goal <cond>")} Set a session goal checked after each turn (exit-zero:/file-exists:/contains:/regex:/text); ${chalk.cyan("/goal")} shows, ${chalk.cyan("/goal clear")} drops`,
|
|
2186
2195
|
);
|
|
2187
2196
|
logger.log(
|
|
2188
2197
|
` ${chalk.cyan("/cd <dir>")} Change working directory mid-session (completion/memory follow)`,
|
|
@@ -3009,9 +3018,19 @@ export async function startAgentRepl(options = {}) {
|
|
|
3009
3018
|
pickCheckpointForTurn,
|
|
3010
3019
|
pruneMarksAfter,
|
|
3011
3020
|
restoreClearedConversation,
|
|
3021
|
+
buildRewindPlan,
|
|
3022
|
+
renderRewindWarnings,
|
|
3023
|
+
buildBranchPlan,
|
|
3024
|
+
renderBranchPlan,
|
|
3025
|
+
parseRewindArg,
|
|
3026
|
+
RESTORE_SCOPE,
|
|
3012
3027
|
} = await import("../lib/repl-rewind.js");
|
|
3013
3028
|
const arg = trimmed.slice("/rewind".length).trim();
|
|
3014
|
-
|
|
3029
|
+
// Parse the turn number + optional restore scope (--conversation /
|
|
3030
|
+
// --files / --both). Claude-Code parity: a rewind can restore the
|
|
3031
|
+
// conversation only, the files only, or both.
|
|
3032
|
+
const parsed = parseRewindArg(arg);
|
|
3033
|
+
if (parsed.command === "clear") {
|
|
3015
3034
|
// Restore the conversation stashed by /clear (Claude-Code 2.1.191).
|
|
3016
3035
|
const r = restoreClearedConversation(
|
|
3017
3036
|
messages,
|
|
@@ -3034,13 +3053,86 @@ export async function startAgentRepl(options = {}) {
|
|
|
3034
3053
|
prompt();
|
|
3035
3054
|
return;
|
|
3036
3055
|
}
|
|
3037
|
-
if (
|
|
3056
|
+
if (parsed.command === "branch") {
|
|
3057
|
+
// "从这里分支" (P0-3's fourth restore action): fork a NEW independent
|
|
3058
|
+
// session that keeps history up to the chosen turn and diverges from
|
|
3059
|
+
// there. The origin session is NEVER truncated (preservesParent), so
|
|
3060
|
+
// the live conversation continues unchanged.
|
|
3061
|
+
const targetTurn = listUserTurns(messages, { limit: 1000 }).find(
|
|
3062
|
+
(t) => t.n === parsed.n,
|
|
3063
|
+
);
|
|
3064
|
+
if (!targetTurn) {
|
|
3065
|
+
logger.error(`No such turn: ${parsed.n} — run /rewind to list.`);
|
|
3066
|
+
} else if (!sessionId) {
|
|
3067
|
+
logger.error(
|
|
3068
|
+
"Branch needs a persisted session — none is active yet.",
|
|
3069
|
+
);
|
|
3070
|
+
} else {
|
|
3071
|
+
const turnIndex = targetTurn.index;
|
|
3072
|
+
const plan = buildBranchPlan(
|
|
3073
|
+
messages,
|
|
3074
|
+
_checkpointMarks,
|
|
3075
|
+
turnIndex,
|
|
3076
|
+
{
|
|
3077
|
+
parentSessionId: sessionId,
|
|
3078
|
+
writeIntent: parsed.writeIntent,
|
|
3079
|
+
},
|
|
3080
|
+
);
|
|
3081
|
+
if (!plan || !plan.branchSessionId) {
|
|
3082
|
+
logger.error("Could not plan a branch from that turn.");
|
|
3083
|
+
} else {
|
|
3084
|
+
try {
|
|
3085
|
+
const { createBranchSession } =
|
|
3086
|
+
await import("../harness/jsonl-session-store.js");
|
|
3087
|
+
const res = createBranchSession({
|
|
3088
|
+
branchSessionId: plan.branchSessionId,
|
|
3089
|
+
parentSessionId: sessionId,
|
|
3090
|
+
parentTurnId: plan.parentTurnId,
|
|
3091
|
+
messages: messages.slice(0, turnIndex),
|
|
3092
|
+
meta: { title: `Branch of ${sessionId}` },
|
|
3093
|
+
});
|
|
3094
|
+
logger.log(
|
|
3095
|
+
chalk.green(
|
|
3096
|
+
res.created
|
|
3097
|
+
? `🌿 branched to ${res.branchSessionId} — ${res.messages} message(s) kept; parent ${sessionId} untouched`
|
|
3098
|
+
: `🌿 branch ${res.branchSessionId} already exists; parent ${sessionId} untouched`,
|
|
3099
|
+
),
|
|
3100
|
+
);
|
|
3101
|
+
for (const line of renderBranchPlan(plan))
|
|
3102
|
+
logger.log(chalk.yellow(line));
|
|
3103
|
+
logger.log(
|
|
3104
|
+
chalk.gray(
|
|
3105
|
+
` resume it with cc agent --resume ${res.branchSessionId}` +
|
|
3106
|
+
(plan.requiresWorktree
|
|
3107
|
+
? " (write task → branch into an isolated worktree)"
|
|
3108
|
+
: ""),
|
|
3109
|
+
),
|
|
3110
|
+
);
|
|
3111
|
+
} catch (e) {
|
|
3112
|
+
logger.error(`branch failed: ${e.message}`);
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
}
|
|
3116
|
+
prompt();
|
|
3117
|
+
return;
|
|
3118
|
+
}
|
|
3119
|
+
if (parsed.command === "list") {
|
|
3038
3120
|
logger.log(chalk.bold("\nRewind — pick a user turn (newest first):"));
|
|
3039
3121
|
logger.log(renderTurnList(listUserTurns(messages)));
|
|
3040
3122
|
const fileHint = _checkpointMarks.length
|
|
3041
3123
|
? " (restores files to that point too — checkpoints are on)"
|
|
3042
3124
|
: " (conversation only — start with --checkpoint / git to also rewind files)";
|
|
3043
3125
|
logger.log(chalk.gray(`Usage: /rewind <n>${fileHint}`));
|
|
3126
|
+
logger.log(
|
|
3127
|
+
chalk.gray(
|
|
3128
|
+
" scope: /rewind <n> --conversation | --files | --both (default)",
|
|
3129
|
+
),
|
|
3130
|
+
);
|
|
3131
|
+
logger.log(
|
|
3132
|
+
chalk.gray(
|
|
3133
|
+
" branch: /rewind <n> --branch [--write] forks an independent session (parent kept)",
|
|
3134
|
+
),
|
|
3135
|
+
);
|
|
3044
3136
|
if (_clearedConversation) {
|
|
3045
3137
|
logger.log(
|
|
3046
3138
|
chalk.gray(
|
|
@@ -3049,30 +3141,67 @@ export async function startAgentRepl(options = {}) {
|
|
|
3049
3141
|
);
|
|
3050
3142
|
}
|
|
3051
3143
|
} else {
|
|
3052
|
-
const
|
|
3053
|
-
|
|
3054
|
-
|
|
3144
|
+
const scope = parsed.scope;
|
|
3145
|
+
const rewindConversation = scope !== RESTORE_SCOPE.FILES;
|
|
3146
|
+
const restoreFiles = scope !== RESTORE_SCOPE.CONVERSATION;
|
|
3147
|
+
// Snapshot + locate the target turn BEFORE any truncation:
|
|
3148
|
+
// buildRewindPlan needs the turn still present to bind its checkpoint,
|
|
3149
|
+
// and a files-only rewind keeps the conversation intact entirely.
|
|
3150
|
+
const preRewind = messages.slice();
|
|
3151
|
+
const targetTurn = listUserTurns(messages, { limit: 1000 }).find(
|
|
3152
|
+
(t) => t.n === parsed.n,
|
|
3153
|
+
);
|
|
3154
|
+
if (!targetTurn) {
|
|
3155
|
+
logger.error(`No such turn: ${parsed.n} — run /rewind to list.`);
|
|
3055
3156
|
} else {
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
)
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3157
|
+
const turnIndex = targetTurn.index;
|
|
3158
|
+
// 1) Conversation rewind (skipped for files-only).
|
|
3159
|
+
if (rewindConversation) {
|
|
3160
|
+
const res = rewindToTurn(messages, parsed.n);
|
|
3161
|
+
logger.log(
|
|
3162
|
+
chalk.yellow(
|
|
3163
|
+
`⎌ rewound — dropped ${res.removed} message(s); edit and resend below`,
|
|
3164
|
+
),
|
|
3165
|
+
);
|
|
3166
|
+
} else {
|
|
3167
|
+
logger.log(
|
|
3168
|
+
chalk.yellow("⎌ files-only rewind — conversation left intact"),
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
// 2) Coverage-aware honesty for the CHOSEN scope (P1 turn/checkpoint
|
|
3172
|
+
// binding): print what a restore can and cannot promise — a shell/
|
|
3173
|
+
// external side-effect → PARTIAL, no checkpoint → files can't be
|
|
3174
|
+
// restored, and a scope-specific conversation/files drift. Derived
|
|
3175
|
+
// from the REPL's existing marks (no new agent-loop events);
|
|
3176
|
+
// best-effort so the advisory never blocks the rewind itself.
|
|
3177
|
+
try {
|
|
3178
|
+
const plan = buildRewindPlan(
|
|
3179
|
+
preRewind,
|
|
3180
|
+
_checkpointMarks,
|
|
3181
|
+
turnIndex,
|
|
3182
|
+
scope,
|
|
3183
|
+
);
|
|
3184
|
+
for (const line of renderRewindWarnings(plan))
|
|
3185
|
+
logger.log(chalk.yellow(line));
|
|
3186
|
+
} catch {
|
|
3187
|
+
/* advisory only — a rewind must never fail over its own warning */
|
|
3188
|
+
}
|
|
3189
|
+
// 3) File restore (skipped for conversation-only). Match the turn to
|
|
3190
|
+
// the snapshot taken just before it first mutated the tree, then
|
|
3191
|
+
// offer to roll the working tree back to it (undoable — the restore
|
|
3192
|
+
// takes its own safety checkpoint first). Prune dropped-turn marks
|
|
3193
|
+
// only when the conversation was actually truncated.
|
|
3194
|
+
const cp = restoreFiles
|
|
3195
|
+
? pickCheckpointForTurn(_checkpointMarks, turnIndex)
|
|
3196
|
+
: null;
|
|
3197
|
+
if (rewindConversation)
|
|
3198
|
+
pruneMarksAfter(_checkpointMarks, turnIndex);
|
|
3067
3199
|
if (cp) {
|
|
3068
3200
|
const q = (p) => new Promise((r) => rl.question(p, r));
|
|
3069
|
-
const
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
),
|
|
3074
|
-
)
|
|
3075
|
-
)
|
|
3201
|
+
const promptText = rewindConversation
|
|
3202
|
+
? ` Also restore files to before this turn? (checkpoint ${cp.id}) [Y/n] `
|
|
3203
|
+
: ` Restore files to before this turn? (checkpoint ${cp.id}) [Y/n] `;
|
|
3204
|
+
const ans = (await q(chalk.yellow(promptText)))
|
|
3076
3205
|
.trim()
|
|
3077
3206
|
.toLowerCase();
|
|
3078
3207
|
if (ans === "" || ans === "y" || ans === "yes") {
|
|
@@ -3089,7 +3218,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
3089
3218
|
);
|
|
3090
3219
|
} catch (e) {
|
|
3091
3220
|
logger.error(
|
|
3092
|
-
` file restore skipped: ${e.message} (conversation already rewound)`,
|
|
3221
|
+
` file restore skipped: ${e.message}${rewindConversation ? " (conversation already rewound)" : ""}`,
|
|
3093
3222
|
);
|
|
3094
3223
|
}
|
|
3095
3224
|
} else {
|
|
@@ -3099,9 +3228,19 @@ export async function startAgentRepl(options = {}) {
|
|
|
3099
3228
|
),
|
|
3100
3229
|
);
|
|
3101
3230
|
}
|
|
3231
|
+
} else if (restoreFiles && scope === RESTORE_SCOPE.FILES) {
|
|
3232
|
+
logger.log(
|
|
3233
|
+
chalk.gray(
|
|
3234
|
+
" no checkpoint captured for that turn — nothing to restore",
|
|
3235
|
+
),
|
|
3236
|
+
);
|
|
3102
3237
|
}
|
|
3103
3238
|
prompt();
|
|
3104
|
-
|
|
3239
|
+
// Prefill the input line with the turn's text only when the
|
|
3240
|
+
// conversation was rewound (edit-and-resend); files-only leaves the
|
|
3241
|
+
// conversation and the prompt untouched.
|
|
3242
|
+
if (rewindConversation && typeof targetTurn.content === "string")
|
|
3243
|
+
rl.write(targetTurn.content);
|
|
3105
3244
|
return;
|
|
3106
3245
|
}
|
|
3107
3246
|
}
|
|
@@ -3406,7 +3545,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
3406
3545
|
if (!_asyncHookSupervisor) {
|
|
3407
3546
|
const { AsyncHookSupervisor } =
|
|
3408
3547
|
await import("../lib/async-hook-supervisor.cjs");
|
|
3409
|
-
_asyncHookSupervisor = new AsyncHookSupervisor(
|
|
3548
|
+
_asyncHookSupervisor = new AsyncHookSupervisor({
|
|
3549
|
+
persistStats: true,
|
|
3550
|
+
});
|
|
3410
3551
|
}
|
|
3411
3552
|
dispatchAsyncHooks(_settingsHooks, "ConfigChange", payload, {
|
|
3412
3553
|
cwd,
|
|
@@ -3533,6 +3674,35 @@ export async function startAgentRepl(options = {}) {
|
|
|
3533
3674
|
}
|
|
3534
3675
|
|
|
3535
3676
|
// Stats
|
|
3677
|
+
if (trimmed === "/goal" || trimmed.startsWith("/goal ")) {
|
|
3678
|
+
// Session completion condition (distinct from `cc goal` OKR): set / show /
|
|
3679
|
+
// clear a condition that is evaluated + reported after each turn.
|
|
3680
|
+
try {
|
|
3681
|
+
const rg = await import("../lib/repl-goal.js");
|
|
3682
|
+
const cmd = rg.parseGoalCommand(trimmed.slice("/goal".length));
|
|
3683
|
+
if (cmd.action === "clear") {
|
|
3684
|
+
if (_sessionGoal) {
|
|
3685
|
+
_sessionGoal = null;
|
|
3686
|
+
logger.log(chalk.gray("◎ session goal cleared."));
|
|
3687
|
+
} else {
|
|
3688
|
+
logger.log(chalk.gray("No session goal to clear."));
|
|
3689
|
+
}
|
|
3690
|
+
} else if (cmd.action === "status") {
|
|
3691
|
+
for (const l of rg.renderGoalStatus(_sessionGoal))
|
|
3692
|
+
logger.log(chalk.gray(l));
|
|
3693
|
+
} else {
|
|
3694
|
+
// set — createReplGoal throws on a malformed spec (caught below).
|
|
3695
|
+
_sessionGoal = rg.createReplGoal(cmd.spec, { now: () => Date.now() });
|
|
3696
|
+
for (const l of rg.renderGoalStart(_sessionGoal))
|
|
3697
|
+
logger.log(chalk.cyan(l));
|
|
3698
|
+
}
|
|
3699
|
+
} catch (err) {
|
|
3700
|
+
logger.error(`/goal: ${err.message}`);
|
|
3701
|
+
}
|
|
3702
|
+
prompt();
|
|
3703
|
+
return;
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3536
3706
|
if (trimmed === "/stats") {
|
|
3537
3707
|
if (contextEngine) {
|
|
3538
3708
|
const stats = contextEngine.getStats();
|
|
@@ -4753,7 +4923,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
4753
4923
|
if (!_asyncHookSupervisor) {
|
|
4754
4924
|
const { AsyncHookSupervisor } =
|
|
4755
4925
|
await import("../lib/async-hook-supervisor.cjs");
|
|
4756
|
-
_asyncHookSupervisor = new AsyncHookSupervisor(
|
|
4926
|
+
_asyncHookSupervisor = new AsyncHookSupervisor({
|
|
4927
|
+
persistStats: true,
|
|
4928
|
+
});
|
|
4757
4929
|
}
|
|
4758
4930
|
dispatchAsyncHooks(
|
|
4759
4931
|
_settingsHooks,
|
|
@@ -5040,7 +5212,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
5040
5212
|
if (_settingsHooks && !_asyncHookSupervisor) {
|
|
5041
5213
|
const { AsyncHookSupervisor } =
|
|
5042
5214
|
await import("../lib/async-hook-supervisor.cjs");
|
|
5043
|
-
_asyncHookSupervisor = new AsyncHookSupervisor();
|
|
5215
|
+
_asyncHookSupervisor = new AsyncHookSupervisor({ persistStats: true });
|
|
5044
5216
|
}
|
|
5045
5217
|
const {
|
|
5046
5218
|
content: response,
|
|
@@ -5102,6 +5274,17 @@ export async function startAgentRepl(options = {}) {
|
|
|
5102
5274
|
denialLog: _recentDenials,
|
|
5103
5275
|
persistRecentDenials: true,
|
|
5104
5276
|
permissionMode: _sessionTier,
|
|
5277
|
+
// Seed the subagent-contract CEILING with the interactive session's
|
|
5278
|
+
// CURRENT approval tier (mapped back to a permission mode) so a spawned
|
|
5279
|
+
// sub-agent inherits/tightens from it (tighten-only), mirroring the
|
|
5280
|
+
// headless runner. An autopilot session hands children bypassPermissions
|
|
5281
|
+
// (→ allow confirmer); a mid-session Shift+Tab / `/permissions` change is
|
|
5282
|
+
// reflected because `_sessionTier` is read per turn. A strict session
|
|
5283
|
+
// resolves children to "default" exactly as before (byte-identical — the
|
|
5284
|
+
// previous absent ceiling also yielded "default").
|
|
5285
|
+
subAgentContract: {
|
|
5286
|
+
permissionMode: permissionModeForTier(_sessionTier),
|
|
5287
|
+
},
|
|
5105
5288
|
prepareCall,
|
|
5106
5289
|
approvalGate: _approvalGate,
|
|
5107
5290
|
permissionRules: _permissionRules,
|
|
@@ -5161,6 +5344,71 @@ export async function startAgentRepl(options = {}) {
|
|
|
5161
5344
|
if (used > 0) _ctxUsedTokens = used;
|
|
5162
5345
|
}
|
|
5163
5346
|
|
|
5347
|
+
// /goal (session completion condition): evaluate this turn's answer and
|
|
5348
|
+
// report met / not-yet / dropped. Deterministic conditions (exit-zero /
|
|
5349
|
+
// file-exists / contains / regex) run inline; a model condition reuses the
|
|
5350
|
+
// session model as an independent judge. Interactive → REPORT only, never
|
|
5351
|
+
// auto re-drive (that autonomous loop is headless-only). Best-effort — an
|
|
5352
|
+
// eval failure never disturbs the turn.
|
|
5353
|
+
if (_sessionGoal && !_sessionGoal.done) {
|
|
5354
|
+
try {
|
|
5355
|
+
const rg = await import("../lib/repl-goal.js");
|
|
5356
|
+
const fsMod = await import("node:fs");
|
|
5357
|
+
const cpMod = await import("node:child_process");
|
|
5358
|
+
const judge = async (cond, { finalText }) => {
|
|
5359
|
+
const { chatWithTools } = await import("../runtime/agent-core.js");
|
|
5360
|
+
const { firstBalancedJson } =
|
|
5361
|
+
await import("../lib/json-schema-output.js");
|
|
5362
|
+
const p =
|
|
5363
|
+
`Judge whether this coding session met a completion condition.\n` +
|
|
5364
|
+
`Condition: ${cond.text || cond.source}\n\n` +
|
|
5365
|
+
`Latest assistant output:\n${String(finalText || "").slice(0, 2000)}\n\n` +
|
|
5366
|
+
`Reply with STRICT JSON only: {"met": true|false, "reason": "<short>"}.`;
|
|
5367
|
+
const jr = await chatWithTools([{ role: "user", content: p }], {
|
|
5368
|
+
model: activeModel,
|
|
5369
|
+
provider,
|
|
5370
|
+
baseUrl,
|
|
5371
|
+
apiKey,
|
|
5372
|
+
enabledToolNames: [],
|
|
5373
|
+
});
|
|
5374
|
+
const text = jr?.message?.content || "";
|
|
5375
|
+
let met = false;
|
|
5376
|
+
let reason = "model judge returned no verdict";
|
|
5377
|
+
const block = firstBalancedJson(text, "{");
|
|
5378
|
+
if (block) {
|
|
5379
|
+
try {
|
|
5380
|
+
const parsed = JSON.parse(block);
|
|
5381
|
+
met = parsed.met === true;
|
|
5382
|
+
reason =
|
|
5383
|
+
typeof parsed.reason === "string" && parsed.reason.trim()
|
|
5384
|
+
? parsed.reason.trim()
|
|
5385
|
+
: met
|
|
5386
|
+
? "condition met"
|
|
5387
|
+
: "condition not met";
|
|
5388
|
+
} catch {
|
|
5389
|
+
/* a non-JSON verdict stays unmet */
|
|
5390
|
+
}
|
|
5391
|
+
}
|
|
5392
|
+
return { met, reason, evidence: { kind: "model" } };
|
|
5393
|
+
};
|
|
5394
|
+
const { decision, events, done } = await rg.evaluateReplGoalTurn(
|
|
5395
|
+
_sessionGoal,
|
|
5396
|
+
response || "",
|
|
5397
|
+
{
|
|
5398
|
+
cwd: process.cwd(),
|
|
5399
|
+
spawnSync: cpMod.spawnSync,
|
|
5400
|
+
existsSync: fsMod.existsSync,
|
|
5401
|
+
judge,
|
|
5402
|
+
},
|
|
5403
|
+
);
|
|
5404
|
+
for (const l of rg.renderGoalVerdict(decision, events))
|
|
5405
|
+
logger.log(chalk.cyan(l));
|
|
5406
|
+
if (done) _sessionGoal = null; // completed or exhausted → drop
|
|
5407
|
+
} catch (err) {
|
|
5408
|
+
logger.verbose(`/goal eval skipped: ${err.message}`);
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
|
|
5164
5412
|
// Fire AssistantResponse hook with rewrite/suppress support
|
|
5165
5413
|
const responseDirective = await fireAssistantResponse(
|
|
5166
5414
|
_hookDb,
|
|
@@ -5306,7 +5554,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
5306
5554
|
if (!_asyncHookSupervisor) {
|
|
5307
5555
|
const { AsyncHookSupervisor } =
|
|
5308
5556
|
await import("../lib/async-hook-supervisor.cjs");
|
|
5309
|
-
_asyncHookSupervisor = new AsyncHookSupervisor(
|
|
5557
|
+
_asyncHookSupervisor = new AsyncHookSupervisor({
|
|
5558
|
+
persistStats: true,
|
|
5559
|
+
});
|
|
5310
5560
|
}
|
|
5311
5561
|
dispatchAsyncHooks(
|
|
5312
5562
|
_settingsHooks,
|
|
@@ -72,6 +72,34 @@ export function parsePermissionModeArg(arg) {
|
|
|
72
72
|
return tier ? { tier, auto: false, dontAsk: false } : null;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Inverse of the tier mapping: turn a live REPL session tier back into a
|
|
77
|
+
* subagent-contract permission MODE, so a spawned sub-agent inherits/tightens
|
|
78
|
+
* from the interactive session's CURRENT approval tier (its run-mode ceiling).
|
|
79
|
+
* Lossy on the restrictive end (strict ← default/manual/plan) — "default" is the
|
|
80
|
+
* safe representative and resolves identically for a child — but the PERMISSIVE
|
|
81
|
+
* end (autopilot → bypassPermissions) is exact, which is what lets a bypass
|
|
82
|
+
* session hand its children the allow confirmer. `auto`/`dontAsk` carry through.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} tier strict | trusted | autopilot | auto | dontAsk
|
|
85
|
+
* @returns {"default"|"acceptEdits"|"bypassPermissions"|"auto"|"dontAsk"}
|
|
86
|
+
*/
|
|
87
|
+
export function permissionModeForTier(tier) {
|
|
88
|
+
switch (tier) {
|
|
89
|
+
case "autopilot":
|
|
90
|
+
return "bypassPermissions";
|
|
91
|
+
case "trusted":
|
|
92
|
+
return "acceptEdits";
|
|
93
|
+
case "auto":
|
|
94
|
+
return "auto";
|
|
95
|
+
case "dontAsk":
|
|
96
|
+
return "dontAsk";
|
|
97
|
+
case "strict":
|
|
98
|
+
default:
|
|
99
|
+
return "default";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
75
103
|
/** One-line description of what a tier auto-approves. */
|
|
76
104
|
export function describeTier(tier) {
|
|
77
105
|
switch (tier) {
|