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/commands/context.js
CHANGED
|
@@ -66,22 +66,21 @@ export function registerContextCommand(program) {
|
|
|
66
66
|
.argument("[id]", "Session ID (omit for the most-recent headless session)")
|
|
67
67
|
.option("--model <model>", "Size against this model's context window")
|
|
68
68
|
.option("--provider <provider>", "Provider (for the window default)")
|
|
69
|
+
.option(
|
|
70
|
+
"--sources",
|
|
71
|
+
"Also break tokens down by source (project-memory instruction files + message classes)",
|
|
72
|
+
)
|
|
69
73
|
.option("--json", "Output as JSON")
|
|
70
74
|
.action(async (id, options) => {
|
|
71
|
-
const {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
readEvents,
|
|
76
|
-
} = await import("../harness/jsonl-session-store.js");
|
|
77
|
-
const { estimateTokens, getContextWindow } = await import(
|
|
78
|
-
"../harness/prompt-compressor.js"
|
|
79
|
-
);
|
|
75
|
+
const { rebuildMessages, getLastSessionId, sessionExists, readEvents } =
|
|
76
|
+
await import("../harness/jsonl-session-store.js");
|
|
77
|
+
const { estimateTokens, getContextWindow } =
|
|
78
|
+
await import("../harness/prompt-compressor.js");
|
|
80
79
|
|
|
81
80
|
const sessionId = id || getLastSessionId();
|
|
82
81
|
if (!sessionId) {
|
|
83
82
|
logger.error(
|
|
84
|
-
|
|
83
|
+
"No session found. Run a headless agent with `--session <id>` first, or pass a session id.",
|
|
85
84
|
);
|
|
86
85
|
process.exitCode = 1;
|
|
87
86
|
return;
|
|
@@ -121,6 +120,55 @@ export function registerContextCommand(program) {
|
|
|
121
120
|
const used = window > 0 ? total / window : 0;
|
|
122
121
|
const remaining = Math.max(0, window - total);
|
|
123
122
|
|
|
123
|
+
// --sources (opt-in): attribute the project-memory instruction files that
|
|
124
|
+
// WOULD load for the current cwd (same instructionExcludes the agent
|
|
125
|
+
// honors), folded in with the session's message-role buckets. The base
|
|
126
|
+
// view is byte-for-byte unchanged when the flag is absent.
|
|
127
|
+
let sourceReport = null;
|
|
128
|
+
if (options.sources) {
|
|
129
|
+
try {
|
|
130
|
+
const { loadProjectInstructions } =
|
|
131
|
+
await import("../lib/project-instructions.js");
|
|
132
|
+
const { breakdownInstructionSources, rankContextSources } =
|
|
133
|
+
await import("../lib/context-breakdown.js");
|
|
134
|
+
const cwd = process.cwd();
|
|
135
|
+
let instructionExcludes;
|
|
136
|
+
try {
|
|
137
|
+
const { readStringArraySetting } =
|
|
138
|
+
await import("../lib/settings-loader.cjs");
|
|
139
|
+
instructionExcludes = readStringArraySetting(
|
|
140
|
+
"instructionExcludes",
|
|
141
|
+
{
|
|
142
|
+
cwd,
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
} catch {
|
|
146
|
+
instructionExcludes = undefined; // fail-open — load everything
|
|
147
|
+
}
|
|
148
|
+
const loaded = loadProjectInstructions({ cwd, instructionExcludes });
|
|
149
|
+
const instr = breakdownInstructionSources(
|
|
150
|
+
loaded.files,
|
|
151
|
+
estimateTokens,
|
|
152
|
+
cwd,
|
|
153
|
+
);
|
|
154
|
+
const ranked = rankContextSources({
|
|
155
|
+
instructionTotal: instr.total,
|
|
156
|
+
buckets,
|
|
157
|
+
counts,
|
|
158
|
+
});
|
|
159
|
+
sourceReport = {
|
|
160
|
+
cwd,
|
|
161
|
+
instructions: instr.sources,
|
|
162
|
+
instructionTokens: instr.total,
|
|
163
|
+
ranked: ranked.sources,
|
|
164
|
+
combinedTotal: ranked.total,
|
|
165
|
+
};
|
|
166
|
+
} catch {
|
|
167
|
+
// Best-effort — a source breakdown must never break the base view.
|
|
168
|
+
sourceReport = null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
124
172
|
if (options.json) {
|
|
125
173
|
console.log(
|
|
126
174
|
JSON.stringify(
|
|
@@ -136,6 +184,15 @@ export function registerContextCommand(program) {
|
|
|
136
184
|
breakdown: buckets,
|
|
137
185
|
counts,
|
|
138
186
|
overflows: total > window,
|
|
187
|
+
...(sourceReport
|
|
188
|
+
? {
|
|
189
|
+
sources: sourceReport.ranked,
|
|
190
|
+
instructions: sourceReport.instructions,
|
|
191
|
+
instructionTokens: sourceReport.instructionTokens,
|
|
192
|
+
combinedTotal: sourceReport.combinedTotal,
|
|
193
|
+
cwd: sourceReport.cwd,
|
|
194
|
+
}
|
|
195
|
+
: {}),
|
|
139
196
|
},
|
|
140
197
|
null,
|
|
141
198
|
2,
|
|
@@ -144,7 +201,9 @@ export function registerContextCommand(program) {
|
|
|
144
201
|
return;
|
|
145
202
|
}
|
|
146
203
|
|
|
147
|
-
logger.log(
|
|
204
|
+
logger.log(
|
|
205
|
+
chalk.bold(`Context — session ${chalk.gray(sessionId.slice(0, 28))}`),
|
|
206
|
+
);
|
|
148
207
|
logger.log(
|
|
149
208
|
chalk.gray(
|
|
150
209
|
` model ${model || "(default)"} · provider ${provider} · ` +
|
|
@@ -172,17 +231,69 @@ export function registerContextCommand(program) {
|
|
|
172
231
|
|
|
173
232
|
logger.log("");
|
|
174
233
|
const pct = (used * 100).toFixed(1);
|
|
175
|
-
const color =
|
|
234
|
+
const color =
|
|
235
|
+
used > 0.9 ? chalk.red : used > 0.7 ? chalk.yellow : chalk.green;
|
|
176
236
|
logger.log(
|
|
177
237
|
` ${chalk.bold("total".padEnd(11))} ${String(total).padStart(7)} ` +
|
|
178
238
|
`${color(bar(used))} ${color(`${pct}% of window`)}`,
|
|
179
239
|
);
|
|
180
240
|
logger.log(
|
|
181
|
-
chalk.gray(
|
|
241
|
+
chalk.gray(
|
|
242
|
+
` headroom ${String(remaining).padStart(7)} tokens remaining`,
|
|
243
|
+
),
|
|
182
244
|
);
|
|
183
245
|
if (total > window) {
|
|
184
246
|
logger.log(
|
|
185
|
-
chalk.red(
|
|
247
|
+
chalk.red(
|
|
248
|
+
" ⚠ exceeds the model context window — compaction required",
|
|
249
|
+
),
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (sourceReport) {
|
|
254
|
+
logger.log("");
|
|
255
|
+
logger.log(
|
|
256
|
+
chalk.bold("By source") +
|
|
257
|
+
chalk.gray(` (project memory for ${sourceReport.cwd})`),
|
|
258
|
+
);
|
|
259
|
+
if (sourceReport.instructions.length) {
|
|
260
|
+
for (const s of sourceReport.instructions) {
|
|
261
|
+
logger.log(
|
|
262
|
+
chalk.gray(` · ${String(s.scope).padEnd(7)} `) +
|
|
263
|
+
`${String(s.tokens).padStart(7)} ${s.source}` +
|
|
264
|
+
(s.truncated ? chalk.yellow(" (truncated)") : ""),
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
logger.log(
|
|
268
|
+
chalk.gray(" project-memory subtotal ") +
|
|
269
|
+
`${String(sourceReport.instructionTokens).padStart(7)} tokens`,
|
|
270
|
+
);
|
|
271
|
+
} else {
|
|
272
|
+
logger.log(
|
|
273
|
+
chalk.gray(" (no project-memory instruction files for this cwd)"),
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
logger.log("");
|
|
277
|
+
for (const s of sourceReport.ranked) {
|
|
278
|
+
logger.log(
|
|
279
|
+
` ${String(s.source).padEnd(30)} ${String(s.tokens).padStart(7)} ` +
|
|
280
|
+
`${chalk.cyan(bar(s.share))} ${String(Math.round(s.share * 100)).padStart(3)}%`,
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
logger.log(
|
|
284
|
+
chalk.gray(
|
|
285
|
+
" note: instructions reflect the current cwd (what a new run here",
|
|
286
|
+
),
|
|
287
|
+
);
|
|
288
|
+
logger.log(
|
|
289
|
+
chalk.gray(
|
|
290
|
+
" would load); messages are this session's stored turns. Skill / MCP",
|
|
291
|
+
),
|
|
292
|
+
);
|
|
293
|
+
logger.log(
|
|
294
|
+
chalk.gray(
|
|
295
|
+
" tool schemas load at runtime and are not counted here.",
|
|
296
|
+
),
|
|
186
297
|
);
|
|
187
298
|
}
|
|
188
299
|
});
|
package/src/commands/doctor.js
CHANGED
|
@@ -1,12 +1,80 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { existsSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join as pathJoin } from "node:path";
|
|
2
4
|
import logger from "../lib/logger.js";
|
|
3
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
collectDoctorReport,
|
|
7
|
+
collectWorktrees,
|
|
8
|
+
buildDoctorDiagnosticInput,
|
|
9
|
+
} from "../runtime/diagnostics.js";
|
|
10
|
+
import { getHomeDir } from "../lib/paths.js";
|
|
11
|
+
import { exportDiagnosticBundle } from "../lib/diagnostic-bundle.js";
|
|
4
12
|
import {
|
|
5
13
|
collectCheckupSections,
|
|
6
14
|
runCheckupFixes,
|
|
7
15
|
unsafeFixCommands,
|
|
8
16
|
} from "../lib/doctor-checkup.js";
|
|
9
17
|
|
|
18
|
+
/** Best-effort top-level `*.lock` files under the config home dir. */
|
|
19
|
+
function collectLockfiles() {
|
|
20
|
+
try {
|
|
21
|
+
const home = getHomeDir();
|
|
22
|
+
if (!home || !existsSync(home)) return [];
|
|
23
|
+
return readdirSync(home)
|
|
24
|
+
.filter((f) => f.endsWith(".lock"))
|
|
25
|
+
.map((f) => pathJoin(home, f));
|
|
26
|
+
} catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Assemble a de-identified diagnostic bundle from the live doctor report and
|
|
33
|
+
* run the mandatory secret-scan gate. On a clean gate, writes JSON to `outPath`
|
|
34
|
+
* (or prints it) and returns `{ ok: true }`. If the gate blocks (residual
|
|
35
|
+
* secret — defense-in-depth, should not happen post-redaction), prints the leak
|
|
36
|
+
* locations and returns `{ ok: false }` without exporting.
|
|
37
|
+
*/
|
|
38
|
+
export async function runExportBundle(report, outPath) {
|
|
39
|
+
const input = buildDoctorDiagnosticInput(report, {
|
|
40
|
+
env: process.env,
|
|
41
|
+
worktrees: collectWorktrees(),
|
|
42
|
+
lockfiles: collectLockfiles(),
|
|
43
|
+
});
|
|
44
|
+
const { ok, bundle, findings } = exportDiagnosticBundle(input);
|
|
45
|
+
|
|
46
|
+
if (!ok) {
|
|
47
|
+
logger.log(
|
|
48
|
+
chalk.red(
|
|
49
|
+
"\n ✖ Diagnostic bundle blocked by secret scan (not exported).",
|
|
50
|
+
),
|
|
51
|
+
);
|
|
52
|
+
for (const f of findings) {
|
|
53
|
+
logger.log(chalk.gray(` ${f.path || "?"}: ${f.category || "secret"}`));
|
|
54
|
+
}
|
|
55
|
+
process.exitCode = 1;
|
|
56
|
+
return { ok: false };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const json = JSON.stringify(bundle, null, 2);
|
|
60
|
+
if (outPath) {
|
|
61
|
+
writeFileSync(outPath, json, "utf-8");
|
|
62
|
+
logger.log(
|
|
63
|
+
chalk.green(
|
|
64
|
+
`\n ✔ De-identified diagnostic bundle written to ${outPath}`,
|
|
65
|
+
),
|
|
66
|
+
);
|
|
67
|
+
logger.log(
|
|
68
|
+
chalk.gray(
|
|
69
|
+
" Excludes source, API keys, cookies, env values and terminal output.",
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
} else {
|
|
73
|
+
console.log(json);
|
|
74
|
+
}
|
|
75
|
+
return { ok: true };
|
|
76
|
+
}
|
|
77
|
+
|
|
10
78
|
const LEVEL_ICON = {
|
|
11
79
|
ok: () => chalk.green("✔"),
|
|
12
80
|
warn: () => chalk.yellow("⚠"),
|
|
@@ -21,8 +89,24 @@ export function registerDoctorCommand(program) {
|
|
|
21
89
|
.description("Diagnose your ChainlessChain environment (alias: checkup)")
|
|
22
90
|
.option("--json", "Output as machine-readable JSON")
|
|
23
91
|
.option("--fix", "Apply safe fixes (stale job files, git worktree prune)")
|
|
92
|
+
.option(
|
|
93
|
+
"--export-bundle [path]",
|
|
94
|
+
"Export a de-identified diagnostic bundle (secret-scanned; excludes source/keys/env values). Writes to <path>, or stdout when no path is given.",
|
|
95
|
+
)
|
|
24
96
|
.action(async (options) => {
|
|
25
97
|
const report = await collectDoctorReport();
|
|
98
|
+
|
|
99
|
+
// One-click de-identified diagnostic bundle. Bypasses the human-readable
|
|
100
|
+
// render entirely: it is a support artifact, not a terminal read-out.
|
|
101
|
+
if (options.exportBundle !== undefined) {
|
|
102
|
+
const outPath =
|
|
103
|
+
typeof options.exportBundle === "string"
|
|
104
|
+
? options.exportBundle
|
|
105
|
+
: null;
|
|
106
|
+
await runExportBundle(report, outPath);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
26
110
|
const sections = await collectCheckupSections({ cwd: process.cwd() });
|
|
27
111
|
const fixResults = options.fix ? await runCheckupFixes(sections) : null;
|
|
28
112
|
|
package/src/commands/hook.js
CHANGED
|
@@ -101,10 +101,7 @@ export function registerHookCommand(program) {
|
|
|
101
101
|
}
|
|
102
102
|
const events = Object.keys(settingsHooks);
|
|
103
103
|
if (events.length > 0) {
|
|
104
|
-
const n = events.reduce(
|
|
105
|
-
(a, e) => a + settingsHooks[e].length,
|
|
106
|
-
0,
|
|
107
|
-
);
|
|
104
|
+
const n = events.reduce((a, e) => a + settingsHooks[e].length, 0);
|
|
108
105
|
logger.log(chalk.bold(`\n.claude/settings.json hooks (${n}):`));
|
|
109
106
|
for (const ev of events) {
|
|
110
107
|
if (options.event && ev !== options.event) continue;
|
|
@@ -145,7 +142,8 @@ export function registerHookCommand(program) {
|
|
|
145
142
|
settingsFile: options.settings,
|
|
146
143
|
});
|
|
147
144
|
const matched = collectHooks(hooks, event, tool);
|
|
148
|
-
const toolInput =
|
|
145
|
+
const toolInput =
|
|
146
|
+
args && args.length ? { command: args.join(" "), args } : {};
|
|
149
147
|
const payload = {
|
|
150
148
|
hook_event_name: event,
|
|
151
149
|
tool_name: tool,
|
|
@@ -156,14 +154,18 @@ export function registerHookCommand(program) {
|
|
|
156
154
|
|
|
157
155
|
if (!options.run) {
|
|
158
156
|
if (options.json) {
|
|
159
|
-
console.log(
|
|
157
|
+
console.log(
|
|
158
|
+
JSON.stringify({ event, tool, matched, payload }, null, 2),
|
|
159
|
+
);
|
|
160
160
|
} else if (matched.length === 0) {
|
|
161
161
|
logger.log(
|
|
162
162
|
chalk.gray(`no settings.json hooks match ${event} / ${tool}`),
|
|
163
163
|
);
|
|
164
164
|
} else {
|
|
165
165
|
logger.log(
|
|
166
|
-
chalk.bold(
|
|
166
|
+
chalk.bold(
|
|
167
|
+
`${matched.length} hook(s) would fire for ${event} / ${tool}:`,
|
|
168
|
+
),
|
|
167
169
|
);
|
|
168
170
|
for (const h of matched) logger.log(` ${chalk.gray(h.command)}`);
|
|
169
171
|
logger.log(chalk.dim(" (use --run to execute and see decisions)"));
|
|
@@ -201,6 +203,178 @@ export function registerHookCommand(program) {
|
|
|
201
203
|
}
|
|
202
204
|
});
|
|
203
205
|
|
|
206
|
+
// hook replay — replay a recorded hook delivery by event id (P2 event bus).
|
|
207
|
+
// Dry-run by default; --run executes observe-only hooks. A DECISION hook can
|
|
208
|
+
// re-gate control flow, so its replay is refused without an explicit sandbox
|
|
209
|
+
// (and, since a real sandbox executor is not yet available, is never executed
|
|
210
|
+
// — only its dry-run plan is shown).
|
|
211
|
+
hook
|
|
212
|
+
.command("replay <event-id>")
|
|
213
|
+
.description(
|
|
214
|
+
"Replay a recorded hook delivery (needs CC_HOOK_EVENT_LOG); dry-run by default, --run executes observe-only hooks",
|
|
215
|
+
)
|
|
216
|
+
.option("--run", "Execute the replayed hooks (observe-only events only)")
|
|
217
|
+
.option(
|
|
218
|
+
"--sandbox",
|
|
219
|
+
"Assert an explicit sandbox for a decision-hook replay",
|
|
220
|
+
)
|
|
221
|
+
.option("--file <path>", "Read from a specific hook event log file")
|
|
222
|
+
.option("--json", "Output as JSON")
|
|
223
|
+
.action(async (eventId, options) => {
|
|
224
|
+
try {
|
|
225
|
+
const { findHookEvent } = await import("../lib/hook-event-log.cjs");
|
|
226
|
+
const { planHookReplay } = await import("../lib/hook-event-bus.cjs");
|
|
227
|
+
const envelope = findHookEvent(eventId, { filePath: options.file });
|
|
228
|
+
if (!envelope) {
|
|
229
|
+
logger.error(
|
|
230
|
+
`hook event "${eventId}" not found` +
|
|
231
|
+
(options.file
|
|
232
|
+
? ""
|
|
233
|
+
: " (enable recording with CC_HOOK_EVENT_LOG=1)"),
|
|
234
|
+
);
|
|
235
|
+
process.exitCode = 1;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const plan = planHookReplay(envelope, {
|
|
239
|
+
sandbox: Boolean(options.sandbox),
|
|
240
|
+
});
|
|
241
|
+
if (!plan.ok) {
|
|
242
|
+
if (options.json) {
|
|
243
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
244
|
+
} else {
|
|
245
|
+
logger.error(`cannot replay: ${plan.reason}`);
|
|
246
|
+
}
|
|
247
|
+
process.exitCode = 1;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// Decision events re-gate flow; a real sandbox executor is still owed,
|
|
251
|
+
// so we never EXECUTE them — the dry-run plan is shown instead.
|
|
252
|
+
if (options.run && plan.requiresSandbox) {
|
|
253
|
+
const note =
|
|
254
|
+
"decision-hook execution needs a real sandbox executor (not yet available); showing dry-run plan";
|
|
255
|
+
if (options.json) {
|
|
256
|
+
console.log(
|
|
257
|
+
JSON.stringify({ ...plan, executed: false, note }, null, 2),
|
|
258
|
+
);
|
|
259
|
+
} else {
|
|
260
|
+
logger.warn(`${note}:`);
|
|
261
|
+
logger.log(JSON.stringify(plan.payload, null, 2));
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (!options.run) {
|
|
266
|
+
if (options.json) {
|
|
267
|
+
console.log(JSON.stringify({ ...plan, executed: false }, null, 2));
|
|
268
|
+
} else {
|
|
269
|
+
logger.log(
|
|
270
|
+
chalk.bold(
|
|
271
|
+
`replay (dry-run) of ${plan.event_type} [${plan.event_id}]`,
|
|
272
|
+
),
|
|
273
|
+
);
|
|
274
|
+
if (plan.requiresSandbox)
|
|
275
|
+
logger.log(chalk.dim(" (decision event — sandboxed)"));
|
|
276
|
+
logger.log(JSON.stringify(plan.payload, null, 2));
|
|
277
|
+
logger.log(
|
|
278
|
+
chalk.dim(" (use --run to execute observe-only hooks)"),
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
// observe-only + --run: re-collect and execute the matching hooks.
|
|
284
|
+
const { loadHooks, collectHooks } =
|
|
285
|
+
await import("../lib/settings-hooks.cjs");
|
|
286
|
+
const { runHooks } = await import("../lib/hook-runner.cjs");
|
|
287
|
+
const { hooks } = loadHooks({ cwd: process.cwd() });
|
|
288
|
+
const matched = collectHooks(
|
|
289
|
+
hooks,
|
|
290
|
+
plan.event_type,
|
|
291
|
+
plan.payload.tool_name || "",
|
|
292
|
+
);
|
|
293
|
+
const outcome = runHooks(matched, plan.payload, {
|
|
294
|
+
cwd: process.cwd(),
|
|
295
|
+
event: plan.event_type,
|
|
296
|
+
});
|
|
297
|
+
if (options.json) {
|
|
298
|
+
console.log(
|
|
299
|
+
JSON.stringify({ ...plan, executed: true, outcome }, null, 2),
|
|
300
|
+
);
|
|
301
|
+
} else {
|
|
302
|
+
logger.log(
|
|
303
|
+
chalk.bold(
|
|
304
|
+
`replayed ${plan.event_type} [${plan.event_id}] → ${outcome.results.length} hook(s)`,
|
|
305
|
+
),
|
|
306
|
+
);
|
|
307
|
+
for (const r of outcome.results) {
|
|
308
|
+
logger.log(
|
|
309
|
+
` ${chalk.gray(r.command)} → ${r.decision}` +
|
|
310
|
+
(r.exitCode != null ? ` (exit ${r.exitCode})` : ""),
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
} catch (err) {
|
|
315
|
+
logger.error(`hook replay failed: ${err.message}`);
|
|
316
|
+
process.exitCode = 1;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// hook events-log — list / verify the recorded hook delivery log.
|
|
321
|
+
hook
|
|
322
|
+
.command("events-log")
|
|
323
|
+
.description(
|
|
324
|
+
"List or verify the recorded hook delivery log (CC_HOOK_EVENT_LOG)",
|
|
325
|
+
)
|
|
326
|
+
.option("--limit <n>", "Max entries to show", "20")
|
|
327
|
+
.option("--verify", "Verify the hash chain instead of listing")
|
|
328
|
+
.option("--file <path>", "Read from a specific hook event log file")
|
|
329
|
+
.option("--json", "Output as JSON")
|
|
330
|
+
.action(async (options) => {
|
|
331
|
+
try {
|
|
332
|
+
const { listHookEvents, verifyHookEventChain, hookEventLogPath } =
|
|
333
|
+
await import("../lib/hook-event-log.cjs");
|
|
334
|
+
if (options.verify) {
|
|
335
|
+
const result = verifyHookEventChain({ filePath: options.file });
|
|
336
|
+
if (options.json) {
|
|
337
|
+
console.log(JSON.stringify(result, null, 2));
|
|
338
|
+
} else if (result.ok) {
|
|
339
|
+
logger.success(
|
|
340
|
+
`hook event log chain OK (${result.length} record(s))`,
|
|
341
|
+
);
|
|
342
|
+
} else {
|
|
343
|
+
logger.error(
|
|
344
|
+
`hook event log chain BROKEN at #${result.brokenAt}: ${result.reason}`,
|
|
345
|
+
);
|
|
346
|
+
process.exitCode = 1;
|
|
347
|
+
}
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const events = listHookEvents({
|
|
351
|
+
limit: parseInt(options.limit, 10) || 20,
|
|
352
|
+
filePath: options.file,
|
|
353
|
+
});
|
|
354
|
+
const logPath = options.file || hookEventLogPath();
|
|
355
|
+
if (options.json) {
|
|
356
|
+
console.log(JSON.stringify({ events, path: logPath }, null, 2));
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (events.length === 0) {
|
|
360
|
+
logger.info(
|
|
361
|
+
`No recorded hook events (enable with CC_HOOK_EVENT_LOG=1). Log: ${logPath}`,
|
|
362
|
+
);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
logger.log(chalk.bold(`Recorded hook events (${events.length}):\n`));
|
|
366
|
+
for (const e of events) {
|
|
367
|
+
logger.log(
|
|
368
|
+
` ${chalk.cyan(e.event_id)} ${chalk.yellow(e.event_type)}` +
|
|
369
|
+
(e.session_id ? ` session=${e.session_id}` : ""),
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
} catch (err) {
|
|
373
|
+
logger.error(`hook events-log failed: ${err.message}`);
|
|
374
|
+
process.exitCode = 1;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
204
378
|
// hook add
|
|
205
379
|
hook
|
|
206
380
|
.command("add")
|