@cleocode/cleo 2026.10.3 → 2026.10.5-rc.ci.672
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/README.md +7 -0
- package/bin/cleo.js +11 -1
- package/dist/cli/adapter-OUQRSFZL.js +159 -0
- package/dist/cli/add-4SRRJL4U.js +443 -0
- package/dist/cli/add-batch-TSWICA5J.js +164 -0
- package/dist/cli/admin-L3F6CDYH.js +1428 -0
- package/dist/cli/admin-YMU55YCU.js +341 -0
- package/dist/cli/adr-XESRMFMP.js +172 -0
- package/dist/cli/agent-TAFPIYUU.js +2404 -0
- package/dist/cli/agent-outputs-HVJJIPS4.js +84 -0
- package/dist/cli/analyze-YQ22QVGW.js +49 -0
- package/dist/cli/archive-W5XX6AH7.js +65 -0
- package/dist/cli/archive-stats-HP2KPAJU.js +101 -0
- package/dist/cli/attention-7JBDCRZX.js +124 -0
- package/dist/cli/attention-ZXZANHKC.js +168 -0
- package/dist/cli/audit-ICA2SEFN.js +122 -0
- package/dist/cli/auth-DXIG5OG7.js +491 -0
- package/dist/cli/backfill-LBSYBWLR.js +156 -0
- package/dist/cli/backup-NUGBZ7NA.js +588 -0
- package/dist/cli/backup-inspect-PDRXI45A.js +26 -0
- package/dist/cli/backup-recover-TVKAPERB.js +29 -0
- package/dist/cli/blockers-ZOPCGHDW.js +55 -0
- package/dist/cli/brain-EJOBKL4A.js +397 -0
- package/dist/cli/briefing-RDQJ6WHS.js +213 -0
- package/dist/cli/caamp-Z3XPKEHB.js +181 -0
- package/dist/cli/cancel-S7EHLCJN.js +85 -0
- package/dist/cli/canon-NPF5RODM.js +142 -0
- package/dist/cli/canon-docs-2GTOLF7Y.js +26 -0
- package/dist/cli/cant-CHNN6O57.js +239 -0
- package/dist/cli/changeset-RYPHPN2B.js +246 -0
- package/dist/cli/check-C67YAU7W.js +759 -0
- package/dist/cli/check-DHMURGHC.js +924 -0
- package/dist/cli/checkpoint-UWDFOGYQ.js +128 -0
- package/dist/cli/chunk-22YPFZYB.js +91 -0
- package/dist/cli/chunk-2MGFDMDF.js +272 -0
- package/dist/cli/chunk-47JYZAMS.js +30 -0
- package/dist/cli/chunk-4JYHPP4C.js +76 -0
- package/dist/cli/chunk-4PEODTHY.js +278 -0
- package/dist/cli/chunk-4RGSNUUP.js +950 -0
- package/dist/cli/chunk-4VASFLUW.js +35 -0
- package/dist/cli/chunk-5PNI276X.js +124 -0
- package/dist/cli/chunk-6JSJNYH2.js +114 -0
- package/dist/cli/chunk-6N6WGLXE.js +63 -0
- package/dist/cli/chunk-75UH3BLS.js +210 -0
- package/dist/cli/chunk-7ACK4EIN.js +92 -0
- package/dist/cli/chunk-7NMKLVMI.js +107 -0
- package/dist/cli/chunk-7SINJXB6.js +110 -0
- package/dist/cli/chunk-7UARFJYS.js +46 -0
- package/dist/cli/chunk-7ZYPQV4N.js +90 -0
- package/dist/cli/chunk-AQCYT3L4.js +72 -0
- package/dist/cli/chunk-BQK6XTOH.js +57 -0
- package/dist/cli/chunk-C3B7C43W.js +16 -0
- package/dist/cli/chunk-CAPAGD5E.js +98 -0
- package/dist/cli/chunk-CHGEDCKG.js +77 -0
- package/dist/cli/chunk-COXFJ3PT.js +74 -0
- package/dist/cli/chunk-D7BAQNV2.js +55 -0
- package/dist/cli/chunk-EIUXVHNF.js +258 -0
- package/dist/cli/chunk-EUGB6P5V.js +173 -0
- package/dist/cli/chunk-EW2CKNNZ.js +304 -0
- package/dist/cli/chunk-FSKN4DWC.js +108 -0
- package/dist/cli/chunk-FVKLULL7.js +48 -0
- package/dist/cli/chunk-GAGUBU4Z.js +280 -0
- package/dist/cli/chunk-GKRFH2YG.js +171 -0
- package/dist/cli/chunk-GRU74UE4.js +270 -0
- package/dist/cli/chunk-GZFVDR44.js +320 -0
- package/dist/cli/chunk-HFLLZE6A.js +83 -0
- package/dist/cli/chunk-HXRXT3XU.js +78 -0
- package/dist/cli/chunk-IIOGUY3B.js +258 -0
- package/dist/cli/chunk-ILWWL462.js +60 -0
- package/dist/cli/chunk-J5USPJKZ.js +48 -0
- package/dist/cli/chunk-KEQS36GD.js +88 -0
- package/dist/cli/chunk-L7ONYSV6.js +2497 -0
- package/dist/cli/chunk-LVGIFMCV.js +163 -0
- package/dist/cli/chunk-NEFMQYLE.js +656 -0
- package/dist/cli/chunk-NU6CQQVB.js +4501 -0
- package/dist/cli/chunk-OILHT47L.js +252 -0
- package/dist/cli/chunk-PKKZPOOP.js +352 -0
- package/dist/cli/chunk-PN4WW5VX.js +66 -0
- package/dist/cli/chunk-PSJ33WVO.js +56 -0
- package/dist/cli/chunk-QA6T2LQ5.js +71 -0
- package/dist/cli/chunk-QJJWWCIC.js +288 -0
- package/dist/cli/chunk-QKMBWYAS.js +93 -0
- package/dist/cli/chunk-QWNKLLLG.js +84 -0
- package/dist/cli/chunk-QWUFFDL3.js +85 -0
- package/dist/cli/chunk-QY76BRUZ.js +35 -0
- package/dist/cli/chunk-R45KVF5Y.js +117 -0
- package/dist/cli/chunk-RRKP7HLU.js +66 -0
- package/dist/cli/chunk-SXXOC6KZ.js +209 -0
- package/dist/cli/chunk-T6GZJYL3.js +108 -0
- package/dist/cli/chunk-TLQ37HRE.js +67 -0
- package/dist/cli/chunk-TPTNEJZJ.js +52 -0
- package/dist/cli/chunk-TYC7G5LF.js +100 -0
- package/dist/cli/chunk-UWCZY52R.js +766 -0
- package/dist/cli/chunk-VB3LDPL5.js +46 -0
- package/dist/cli/chunk-VLEYOOPH.js +31 -0
- package/dist/cli/chunk-W3JLYKKY.js +140 -0
- package/dist/cli/chunk-WWCYZYSN.js +56 -0
- package/dist/cli/chunk-XA5WISNV.js +52 -0
- package/dist/cli/chunk-XHRZ7OYZ.js +132 -0
- package/dist/cli/chunk-XLPMIGJJ.js +148 -0
- package/dist/cli/chunk-YY66LFZF.js +29 -0
- package/dist/cli/chunk-ZMGDZMSJ.js +210 -0
- package/dist/cli/claim-IGOG2QOC.js +97 -0
- package/dist/cli/classify-MG4N7GMQ.js +117 -0
- package/dist/cli/cli-A23Q335V.js +51 -0
- package/dist/cli/cloud-SILYJVKO.js +731 -0
- package/dist/cli/cockpit-RZKLGYPN.js +790 -0
- package/dist/cli/code-H2FQCVMW.js +178 -0
- package/dist/cli/complete-JLX7NBI4.js +35 -0
- package/dist/cli/complexity-OKV7PVZH.js +57 -0
- package/dist/cli/compliance-QMGZHJNQ.js +277 -0
- package/dist/cli/conduit-4H32UYEA.js +308 -0
- package/dist/cli/conduit-EY54WTZA.js +535 -0
- package/dist/cli/config-TDYOC7XO.js +519 -0
- package/dist/cli/consensus-4XCOFPPT.js +122 -0
- package/dist/cli/context-FN4YTGHD.js +142 -0
- package/dist/cli/contribution-7RWFBJLC.js +112 -0
- package/dist/cli/curator-HKZJCVRL.js +139 -0
- package/dist/cli/current-B2NU7V3G.js +43 -0
- package/dist/cli/daemon-GBD4TVCD.js +452 -0
- package/dist/cli/dash-IGDANIE5.js +71 -0
- package/dist/cli/decide-26SXC2V6.js +416 -0
- package/dist/cli/decompose-LQ76TEZG.js +78 -0
- package/dist/cli/decomposition-WFRWNUSJ.js +122 -0
- package/dist/cli/delete-T5DUQHOX.js +69 -0
- package/dist/cli/deps-UTPZJBXL.js +462 -0
- package/dist/cli/detect-FFZSMVDT.js +46 -0
- package/dist/cli/detect-drift-TVCJOFYJ.js +408 -0
- package/dist/cli/diagnostics-GN5CVD3N.js +93 -0
- package/dist/cli/diagnostics-ZNBKH6GX.js +133 -0
- package/dist/cli/docs-CLQKEEUK.js +1710 -0
- package/dist/cli/docs-DPPDFTWR.js +3098 -0
- package/dist/cli/doctor-GPENOP4N.js +1270 -0
- package/dist/cli/doctor-ac-bindings-S3IOEFP4.js +26 -0
- package/dist/cli/doctor-acceptance-drift-VNFKPBSQ.js +26 -0
- package/dist/cli/doctor-credentials-A5H4JMTF.js +26 -0
- package/dist/cli/doctor-db-substrate-FGCISE4Z.js +27 -0
- package/dist/cli/doctor-dep-cycles-BKKKHHYG.js +26 -0
- package/dist/cli/doctor-exodus-ND2DH2KP.js +26 -0
- package/dist/cli/doctor-exodus-residue-4EMRYMEQ.js +26 -0
- package/dist/cli/doctor-fk-check-VY3RIQV3.js +26 -0
- package/dist/cli/doctor-global-delivery-JN6IGHUL.js +26 -0
- package/dist/cli/doctor-heavy-command-hook-XSN44WXU.js +26 -0
- package/dist/cli/doctor-legacy-backups-QAG5NHYP.js +26 -0
- package/dist/cli/doctor-legacy-reaper-CIRGFE6R.js +26 -0
- package/dist/cli/doctor-malformed-ids-WL7HT4TB.js +26 -0
- package/dist/cli/doctor-manifest-rows-SMQCKJ2T.js +26 -0
- package/dist/cli/doctor-memory-guard-LJDOJG76.js +26 -0
- package/dist/cli/doctor-migrations-ETQPFNUP.js +26 -0
- package/dist/cli/doctor-nexus-residency-A4JMKBEJ.js +26 -0
- package/dist/cli/doctor-project-identity-FFQJ5LNX.js +26 -0
- package/dist/cli/doctor-projects-MFUTKRHP.js +30 -0
- package/dist/cli/doctor-projects-registry-76X6VTGM.js +26 -0
- package/dist/cli/doctor-release-readiness-QJCOPFTK.js +26 -0
- package/dist/cli/doctor-repair-AU76FIKY.js +26 -0
- package/dist/cli/doctor-row-identity-KW6JYZQE.js +26 -0
- package/dist/cli/doctor-skill-fixtures-G3T7JUHS.js +26 -0
- package/dist/cli/doctor-split-brain-FUW6L7FS.js +26 -0
- package/dist/cli/doctor-superseded-store-DUHGSBLC.js +26 -0
- package/dist/cli/doctor-sync-journal-SXMUIKF7.js +26 -0
- package/dist/cli/doctor-sync-triggers-6WNJZFRM.js +26 -0
- package/dist/cli/doctor-tool-locks-66LSLUBN.js +26 -0
- package/dist/cli/doctor-twin-collapse-AYBYBFC4.js +26 -0
- package/dist/cli/doctor-worktree-stores-C5XEH5OG.js +26 -0
- package/dist/cli/done-R64XRZ32.js +196 -0
- package/dist/cli/dynamic-RR4HB7BB.js +29 -0
- package/dist/cli/entities-3JIHDIOK.js +361 -0
- package/dist/cli/event-45KEWV5H.js +372 -0
- package/dist/cli/exists-BEDZS5RI.js +65 -0
- package/dist/cli/exodus-DUX62344.js +401 -0
- package/dist/cli/export-C5PQIQ5O.js +93 -0
- package/dist/cli/export-tasks-CUXDZPJB.js +97 -0
- package/dist/cli/federation-ESM35EGG.js +145 -0
- package/dist/cli/find-5EUZHHQJ.js +178 -0
- package/dist/cli/focus-6AH4KLRO.js +368 -0
- package/dist/cli/focus-ANKAIRO5.js +56 -0
- package/dist/cli/gateway-2GW2KTK3.js +77 -0
- package/dist/cli/gateway-auto-start-EDK7XI6E.js +36 -0
- package/dist/cli/gc-CTOQLUSA.js +291 -0
- package/dist/cli/go-YJPNHHYT.js +206 -0
- package/dist/cli/goal-4GW4G77D.js +213 -0
- package/dist/cli/grade-25WSZH4X.js +57 -0
- package/dist/cli/graph-JUO3TMF3.js +879 -0
- package/dist/cli/history-NACNUQTC.js +138 -0
- package/dist/cli/hook-UF7J7R6D.js +57 -0
- package/dist/cli/hook-entry.js +244 -19
- package/dist/cli/hygiene-3QZ2NI7P.js +55 -0
- package/dist/cli/import-7ESGL5SS.js +89 -0
- package/dist/cli/import-tasks-FLE2RPBR.js +109 -0
- package/dist/cli/index.js +601 -94637
- package/dist/cli/init-AN4DZ2XO.js +40 -0
- package/dist/cli/inject-HQWA5GWY.js +83 -0
- package/dist/cli/install-global-YQV4W5OG.js +95 -0
- package/dist/cli/intelligence-OFFNQGHE.js +238 -0
- package/dist/cli/intelligence-QIC4SN4X.js +182 -0
- package/dist/cli/issue-P5RNMRDG.js +159 -0
- package/dist/cli/janitor-ZNCFQ7E3.js +111 -0
- package/dist/cli/labels-ORBM3T57.js +88 -0
- package/dist/cli/lifecycle-MHR22TVI.js +273 -0
- package/dist/cli/list-LB6GCYYU.js +109 -0
- package/dist/cli/llm-H7LZWQKX.js +130 -0
- package/dist/cli/llm-OTJWPMGI.js +704 -0
- package/dist/cli/llm-cost-MLMXEAR4.js +25 -0
- package/dist/cli/llm-stream-AAEUNKRP.js +27 -0
- package/dist/cli/log-W2A5M2NA.js +76 -0
- package/dist/cli/login-SIXFFZSP.js +45 -0
- package/dist/cli/logout-G3KVLQQM.js +74 -0
- package/dist/cli/manifest-G4T6EBSI.js +354 -0
- package/dist/cli/map-VU5M72TK.js +53 -0
- package/dist/cli/memory-2E27G2G5.js +1952 -0
- package/dist/cli/memory-IAEYKXG6.js +1895 -0
- package/dist/cli/migrate-agents-v2-A52QIYNJ.js +33 -0
- package/dist/cli/migrate-claude-mem-TPDW3R4Z.js +206 -0
- package/dist/cli/next-SVH4LIDY.js +57 -0
- package/dist/cli/nexus-FPQV2EAF.js +1059 -0
- package/dist/cli/nexus-XSFXN5E6.js +2924 -0
- package/dist/cli/ops-K6LHY5J6.js +52 -0
- package/dist/cli/orchestrate-CZ2J6W3L.js +1650 -0
- package/dist/cli/orchestrate-HURUCQFT.js +950 -0
- package/dist/cli/otel-JCNPVJLZ.js +188 -0
- package/dist/cli/phase-VDFRASSO.js +221 -0
- package/dist/cli/pipeline-TCZPOEDR.js +697 -0
- package/dist/cli/pivot-V5MSQZ7L.js +88 -0
- package/dist/cli/plan-SQUGCKSM.js +49 -0
- package/dist/cli/playbook-L47GLDQD.js +230 -0
- package/dist/cli/playbook-NJVO4R6P.js +33 -0
- package/dist/cli/project-YZEC7GYF.js +331 -0
- package/dist/cli/promote-FINF4HVK.js +53 -0
- package/dist/cli/provenance-3TUWVBFR.js +141 -0
- package/dist/cli/provenance-YZG33JGM.js +129 -0
- package/dist/cli/provider-23JVLLG3.js +213 -0
- package/dist/cli/reason-FHN54O7O.js +138 -0
- package/dist/cli/reconcile-MOM5T4AX.js +128 -0
- package/dist/cli/refresh-memory-3OSTRAVK.js +45 -0
- package/dist/cli/relates-6FWUFUS2.js +260 -0
- package/dist/cli/release-G2DPSG5M.js +347 -0
- package/dist/cli/release-URX6JHZ2.js +525 -0
- package/dist/cli/remote-VIULU2T5.js +279 -0
- package/dist/cli/renderers-TGSW77J4.js +37 -0
- package/dist/cli/reorder-UIPN6TQY.js +87 -0
- package/dist/cli/reparent-ALOWWUIU.js +59 -0
- package/dist/cli/req-RH2Y3H7A.js +130 -0
- package/dist/cli/research-G2Y72HRC.js +366 -0
- package/dist/cli/restore-VBR5XNML.js +470 -0
- package/dist/cli/revert-32LDNSGP.js +240 -0
- package/dist/cli/roadmap-LFU3AG7D.js +62 -0
- package/dist/cli/run-HXRILSR7.js +245 -0
- package/dist/cli/safestop-Z5UC7NGQ.js +89 -0
- package/dist/cli/saga-Y6FZS6AM.js +286 -0
- package/dist/cli/schema-OOOKLWUE.js +195 -0
- package/dist/cli/self-update-26SOTJMH.js +504 -0
- package/dist/cli/selfimprove-4SMOCLUV.js +89 -0
- package/dist/cli/selfimprove-EB4RQLP4.js +139 -0
- package/dist/cli/sentient-QPETVE53.js +254 -0
- package/dist/cli/sentient-RGMWR4XJ.js +1088 -0
- package/dist/cli/sequence-H7DSAJPF.js +94 -0
- package/dist/cli/service-EK5MGB2D.js +156 -0
- package/dist/cli/service-GLOMZWPQ.js +437 -0
- package/dist/cli/session-HYUXAQGC.js +708 -0
- package/dist/cli/session-N5ISU56W.js +568 -0
- package/dist/cli/setup-L3YYV53D.js +323 -0
- package/dist/cli/show-364V3KY2.js +123 -0
- package/dist/cli/skill-F2KR6HW5.js +84 -0
- package/dist/cli/skills-FS3DCP6E.js +929 -0
- package/dist/cli/smoke-provider-SKUFMZXU.js +218 -0
- package/dist/cli/snapshot-EGXEQ5PR.js +120 -0
- package/dist/cli/src-LYLXHXHH.js +80 -0
- package/dist/cli/start-6DXOCCKL.js +68 -0
- package/dist/cli/stats-UVUQEGYC.js +96 -0
- package/dist/cli/status-XLKYLN42.js +157 -0
- package/dist/cli/sticky-VSTQ2I2O.js +264 -0
- package/dist/cli/sticky-XZXZDCFW.js +339 -0
- package/dist/cli/stop-VNOAFWNB.js +43 -0
- package/dist/cli/sync-YYPARW3A.js +155 -0
- package/dist/cli/tasks-C24KHTFF.js +1118 -0
- package/dist/cli/tasks-LBJC7CZV.js +175 -0
- package/dist/cli/telemetry-CU7W5WAY.js +120 -0
- package/dist/cli/templates-G42JBUY4.js +609 -0
- package/dist/cli/testing-HSRITHEY.js +147 -0
- package/dist/cli/token-J74E7TSU.js +221 -0
- package/dist/cli/tools-BI74W7VE.js +652 -0
- package/dist/cli/transcript-RGK7RSGQ.js +440 -0
- package/dist/cli/tui-BPUFHYKK.js +51 -0
- package/dist/cli/update-2KQWA27S.js +478 -0
- package/dist/cli/update-check-entry.js +124 -0
- package/dist/cli/update-notice-6SQ6WPQG.js +68 -0
- package/dist/cli/upgrade-E2MJAPC7.js +136 -0
- package/dist/cli/upgrade-XRSQ4RWH.js +243 -0
- package/dist/cli/verify-WASRGDBA.js +191 -0
- package/dist/cli/web-NJ3P67EU.js +275 -0
- package/dist/cli/workgraph-OHJ2VKJD.js +232 -0
- package/dist/cli/worktree-FVQLORFY.js +371 -0
- package/dist/cli/worktree-ZJ6JTQNG.js +287 -0
- package/package.json +13 -13
- package/studio-dist/client/_app/immutable/chunks/{DMj27Pxj.js → AH7dIemv.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/{Dc2owyvE.js → BDgH40i3.js} +1 -1
- package/studio-dist/client/_app/immutable/chunks/BXDCSJ7U.js +1 -0
- package/studio-dist/client/_app/immutable/chunks/{qq3pe1aT.js → Gg4iYl59.js} +1 -1
- package/studio-dist/client/_app/immutable/entry/{app.CHWXLeE9.js → app.DUDNK-37.js} +2 -2
- package/studio-dist/client/_app/immutable/entry/start.DNmZ0pA4.js +1 -0
- package/studio-dist/client/_app/immutable/nodes/{0.DmKQGvFh.js → 0.DWqP3ail.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{1.DqJk_REO.js → 1.CZGVUP5B.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{15.GUy6kdW1.js → 15.DGaflZRS.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{16.CcnKZ8f9.js → 16.uYlarGXl.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{17.DAlQF3lQ.js → 17.CZMR0E47.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{18.vQFr-vFj.js → 18.CBC-AKH_.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{20.GVOj5j_r.js → 20.BGi43MvQ.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{24.2-wC6DOh.js → 24.Dv8ftCyR.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/25.DQPVlTDQ.js +39 -0
- package/studio-dist/client/_app/immutable/nodes/{26.C3rNqzZF.js → 26.Cl800304.js} +1 -1
- package/studio-dist/client/_app/immutable/nodes/{3.b-7pzc3M.js → 3.D_fQKj9f.js} +1 -1
- package/studio-dist/client/_app/version.json +1 -1
- package/studio-dist/server/chunks/{0-BaCce-O1.js → 0-BpOagOst.js} +3 -3
- package/studio-dist/server/chunks/1-D0oRGR-C.js +9 -0
- package/studio-dist/server/chunks/{15-DRMOSIC9.js → 15-BcjHz7Tv.js} +3 -3
- package/studio-dist/server/chunks/{16-BulXhoZZ.js → 16-CXm8TUk7.js} +3 -3
- package/studio-dist/server/chunks/{17-DUEOCM0H.js → 17-mSgUK-cp.js} +3 -3
- package/studio-dist/server/chunks/{18-DP7Q8zPs.js → 18-BtfnIw1d.js} +3 -3
- package/studio-dist/server/chunks/{20-9ta6MI7q.js → 20-By1e4QDS.js} +3 -3
- package/studio-dist/server/chunks/{24-DysdL1ab.js → 24-0i2YLVxG.js} +3 -3
- package/studio-dist/server/chunks/{dist-CdoCt9zT.js → 25-DPsrqbrh.js} +797 -10736
- package/studio-dist/server/chunks/{26-Df4YXgg0.js → 26-P0XkOibm.js} +3 -3
- package/studio-dist/server/chunks/{3-BEhOhYpL.js → 3-WudjUK7e.js} +3 -3
- package/studio-dist/server/chunks/{_layout.svelte-CnLcXYG-.js → _layout.svelte-D9m81Rle.js} +4 -4
- package/studio-dist/server/chunks/{_page.svelte-DGhXqeRc.js → _page.svelte-2PDLOF83.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-Dv8tmDEC.js → _page.svelte-BjE3jm2K.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-C0qgUvzA.js → _page.svelte-Clc0vmiZ.js} +4 -4
- package/studio-dist/server/chunks/{_page.svelte-ui7LnWkL.js → _page.svelte-DABdRT3h.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-HUqTICJR.js → _page.svelte-DG3PjiHj.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-DzcZljiy.js → _page.svelte-Edy9CaE8.js} +20 -7
- package/studio-dist/server/chunks/{_page.svelte-DOl0DGOO.js → _page.svelte-Hrf3-ZR8.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-Da4q5l93.js → _page.svelte-VB4O4Nl5.js} +3 -3
- package/studio-dist/server/chunks/{_page.svelte-CbyEPj2j.js → _page.svelte-d3jEgjsI.js} +3 -3
- package/studio-dist/server/chunks/{_server.ts-P4wVVksg.js → _server.ts-BcRFsyo3.js} +4 -5
- package/studio-dist/server/chunks/{_server.ts-Cr57EKWf.js → _server.ts-CEWpIFrj.js} +6 -5
- package/studio-dist/server/chunks/{_server.ts-CnKVmf_s.js → _server.ts-CLVdVIF9.js} +2 -2
- package/studio-dist/server/chunks/{_server.ts-C0evMKCk.js → _server.ts-D_j7aSy5.js} +6 -5
- package/studio-dist/server/chunks/{_server.ts-2BazvYRP.js → _server.ts-QEZF8h2q.js} +4 -5
- package/studio-dist/server/chunks/{client-CPM4LrO2.js → client-Kp1dP1od.js} +2 -2
- package/studio-dist/server/chunks/{error.svelte-ShcZo43D.js → error.svelte-WOCioJVX.js} +3 -3
- package/studio-dist/server/chunks/{hooks.server-D2qbf3Zp.js → hooks.server-DH9zkIrJ.js} +3 -1
- package/studio-dist/server/chunks/{http-BiQjEmVU.js → http-DT5kxaWk.js} +5 -4
- package/studio-dist/server/chunks/{internal-Cgsrya1j.js → internal-z0vqd5_u.js} +3 -3
- package/studio-dist/server/chunks/operations-registry-DdzmYzqX.js +10584 -0
- package/studio-dist/server/chunks/{stores-BGrpEDMK.js → stores-s2kaL315.js} +2 -2
- package/studio-dist/server/index.js +1 -1
- package/studio-dist/server/manifest.js +17 -17
- package/studio-dist/client/_app/immutable/chunks/Bw6J8NDM.js +0 -1
- package/studio-dist/client/_app/immutable/entry/start.C9bwPpvc.js +0 -1
- package/studio-dist/client/_app/immutable/nodes/25.D1vYaH8g.js +0 -39
- package/studio-dist/server/chunks/1-CVo7Nk6d.js +0 -9
- package/studio-dist/server/chunks/25-CYsps38R.js +0 -366
|
@@ -0,0 +1,1270 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const _installed = Symbol.for('cleocode.cli.sqliteWarningFilter');
|
|
3
|
+
if (globalThis[_installed]) return;
|
|
4
|
+
globalThis[_installed] = true;
|
|
5
|
+
const _origEmitWarning = process.emitWarning;
|
|
6
|
+
process.emitWarning = function(warning, type, code, ctor) {
|
|
7
|
+
if (typeof warning === 'object' && warning.name === 'ExperimentalWarning' && typeof warning.message === 'string' && /SQLite is an experimental feature/i.test(warning.message)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (typeof warning === 'string' && /SQLite is an experimental feature/i.test(warning)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
return _origEmitWarning.call(process, warning, type, code, ctor);
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
import {
|
|
17
|
+
createDoctorProgress
|
|
18
|
+
} from "./chunk-W3JLYKKY.js";
|
|
19
|
+
import {
|
|
20
|
+
doctorSupersededStoreCommand
|
|
21
|
+
} from "./chunk-KEQS36GD.js";
|
|
22
|
+
import {
|
|
23
|
+
doctorSyncJournalCommand
|
|
24
|
+
} from "./chunk-TPTNEJZJ.js";
|
|
25
|
+
import {
|
|
26
|
+
doctorSyncTriggersCommand
|
|
27
|
+
} from "./chunk-ILWWL462.js";
|
|
28
|
+
import {
|
|
29
|
+
doctorToolLocksCommand
|
|
30
|
+
} from "./chunk-R45KVF5Y.js";
|
|
31
|
+
import {
|
|
32
|
+
doctorTwinCollapseCommand
|
|
33
|
+
} from "./chunk-GKRFH2YG.js";
|
|
34
|
+
import {
|
|
35
|
+
doctorWorktreeStoresCommand
|
|
36
|
+
} from "./chunk-BQK6XTOH.js";
|
|
37
|
+
import {
|
|
38
|
+
readMigrationConflicts
|
|
39
|
+
} from "./chunk-IIOGUY3B.js";
|
|
40
|
+
import {
|
|
41
|
+
doctorProjectIdentityCommand
|
|
42
|
+
} from "./chunk-PN4WW5VX.js";
|
|
43
|
+
import {
|
|
44
|
+
doctorRegistryCommand
|
|
45
|
+
} from "./chunk-7NMKLVMI.js";
|
|
46
|
+
import {
|
|
47
|
+
runDoctorProjects
|
|
48
|
+
} from "./chunk-EUGB6P5V.js";
|
|
49
|
+
import {
|
|
50
|
+
doctorReleaseReadinessCommand
|
|
51
|
+
} from "./chunk-4PEODTHY.js";
|
|
52
|
+
import {
|
|
53
|
+
doctorRepairCommand
|
|
54
|
+
} from "./chunk-CAPAGD5E.js";
|
|
55
|
+
import {
|
|
56
|
+
doctorRowIdentityCommand
|
|
57
|
+
} from "./chunk-WWCYZYSN.js";
|
|
58
|
+
import {
|
|
59
|
+
doctorSkillFixturesCommand
|
|
60
|
+
} from "./chunk-T6GZJYL3.js";
|
|
61
|
+
import {
|
|
62
|
+
doctorSplitBrainCommand
|
|
63
|
+
} from "./chunk-7ACK4EIN.js";
|
|
64
|
+
import {
|
|
65
|
+
doctorHeavyCommandHookCommand
|
|
66
|
+
} from "./chunk-COXFJ3PT.js";
|
|
67
|
+
import {
|
|
68
|
+
doctorLegacyBackupsCommand
|
|
69
|
+
} from "./chunk-7ZYPQV4N.js";
|
|
70
|
+
import {
|
|
71
|
+
doctorLegacyReaperCommand
|
|
72
|
+
} from "./chunk-FVKLULL7.js";
|
|
73
|
+
import {
|
|
74
|
+
doctorMalformedIdsCommand
|
|
75
|
+
} from "./chunk-PSJ33WVO.js";
|
|
76
|
+
import {
|
|
77
|
+
doctorManifestRowsCommand
|
|
78
|
+
} from "./chunk-22YPFZYB.js";
|
|
79
|
+
import {
|
|
80
|
+
doctorMemoryGuardCommand
|
|
81
|
+
} from "./chunk-HXRXT3XU.js";
|
|
82
|
+
import {
|
|
83
|
+
doctorMigrationsCommand
|
|
84
|
+
} from "./chunk-7UARFJYS.js";
|
|
85
|
+
import {
|
|
86
|
+
doctorNexusResidencyCommand
|
|
87
|
+
} from "./chunk-XA5WISNV.js";
|
|
88
|
+
import {
|
|
89
|
+
doctorAcceptanceDriftCommand
|
|
90
|
+
} from "./chunk-TLQ37HRE.js";
|
|
91
|
+
import {
|
|
92
|
+
doctorCredentialsCommand
|
|
93
|
+
} from "./chunk-4JYHPP4C.js";
|
|
94
|
+
import {
|
|
95
|
+
doctorDbSubstrateCommand
|
|
96
|
+
} from "./chunk-75UH3BLS.js";
|
|
97
|
+
import {
|
|
98
|
+
doctorDepCyclesCommand
|
|
99
|
+
} from "./chunk-J5USPJKZ.js";
|
|
100
|
+
import {
|
|
101
|
+
doctorExodusResidueCommand
|
|
102
|
+
} from "./chunk-7SINJXB6.js";
|
|
103
|
+
import {
|
|
104
|
+
doctorExodusCommand
|
|
105
|
+
} from "./chunk-AQCYT3L4.js";
|
|
106
|
+
import {
|
|
107
|
+
doctorFkCheckCommand
|
|
108
|
+
} from "./chunk-FSKN4DWC.js";
|
|
109
|
+
import {
|
|
110
|
+
doctorGlobalDeliveryCommand
|
|
111
|
+
} from "./chunk-HFLLZE6A.js";
|
|
112
|
+
import {
|
|
113
|
+
doctorAcBindingsCommand
|
|
114
|
+
} from "./chunk-CHGEDCKG.js";
|
|
115
|
+
import "./chunk-47JYZAMS.js";
|
|
116
|
+
import "./chunk-C3B7C43W.js";
|
|
117
|
+
import {
|
|
118
|
+
isSubCommandDispatch
|
|
119
|
+
} from "./chunk-YY66LFZF.js";
|
|
120
|
+
import {
|
|
121
|
+
dispatchFromCli,
|
|
122
|
+
dispatchRaw
|
|
123
|
+
} from "./chunk-L7ONYSV6.js";
|
|
124
|
+
import "./chunk-6N6WGLXE.js";
|
|
125
|
+
import "./chunk-4VASFLUW.js";
|
|
126
|
+
import {
|
|
127
|
+
defineCommand
|
|
128
|
+
} from "./chunk-PKKZPOOP.js";
|
|
129
|
+
import "./chunk-QKMBWYAS.js";
|
|
130
|
+
import {
|
|
131
|
+
cliError,
|
|
132
|
+
cliOutput,
|
|
133
|
+
humanLine
|
|
134
|
+
} from "./chunk-4RGSNUUP.js";
|
|
135
|
+
import "./chunk-6JSJNYH2.js";
|
|
136
|
+
import "./chunk-D7BAQNV2.js";
|
|
137
|
+
import "./chunk-TYC7G5LF.js";
|
|
138
|
+
|
|
139
|
+
// packages/cleo/src/cli/commands/doctor.ts
|
|
140
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
141
|
+
import { join } from "node:path";
|
|
142
|
+
import { renderInvariantAuditLines } from "@cleocode/core/doctor/invariant-audit-render.js";
|
|
143
|
+
import { pushWarning } from "@cleocode/core/output";
|
|
144
|
+
import { getProjectRoot as getProjectRoot2 } from "@cleocode/core/project-scope";
|
|
145
|
+
import {
|
|
146
|
+
quarantineRogueCleoDir,
|
|
147
|
+
scanRogueCleoDirs
|
|
148
|
+
} from "@cleocode/core/system/rogue-cleo-detector.js";
|
|
149
|
+
|
|
150
|
+
// packages/cleo/src/cli/commands/doctor-knowledge.ts
|
|
151
|
+
import { readFile } from "node:fs/promises";
|
|
152
|
+
import {
|
|
153
|
+
applyPreparedKnowledgeRepair,
|
|
154
|
+
cancelPreparedKnowledgeRepair,
|
|
155
|
+
createKnowledgeRepairInvocation,
|
|
156
|
+
inspectPreparedKnowledgeRepair,
|
|
157
|
+
KnowledgeRepairError,
|
|
158
|
+
listPreparedKnowledgeRepairs,
|
|
159
|
+
parseKnowledgeRepairProposal,
|
|
160
|
+
prepareKnowledgeRepair,
|
|
161
|
+
prepareKnowledgeRollback,
|
|
162
|
+
resumePreparedKnowledgeRepair,
|
|
163
|
+
runKnowledgeDoctor
|
|
164
|
+
} from "@cleocode/core/doctor/knowledge.js";
|
|
165
|
+
import { getProjectRoot } from "@cleocode/core/paths.js";
|
|
166
|
+
var doctorKnowledgeSubcommand = defineCommand({
|
|
167
|
+
meta: {
|
|
168
|
+
name: "knowledge",
|
|
169
|
+
description: "Assess project knowledge and apply bounded, sourced, reversible repairs"
|
|
170
|
+
},
|
|
171
|
+
args: {
|
|
172
|
+
fix: {
|
|
173
|
+
type: "boolean",
|
|
174
|
+
description: "Apply deterministic repairs to confirmed derived defects"
|
|
175
|
+
},
|
|
176
|
+
"dry-run": { type: "boolean", description: "Preview findings and proposals without mutations" },
|
|
177
|
+
resolve: { type: "string", description: "Apply a sourced repair proposal from a JSON file" },
|
|
178
|
+
prepare: { type: "string", description: "Persist a sourced JSON proposal without applying it" },
|
|
179
|
+
apply: {
|
|
180
|
+
type: "string",
|
|
181
|
+
description: "Apply an immutable prepared job under a fresh bounded attempt"
|
|
182
|
+
},
|
|
183
|
+
jobs: {
|
|
184
|
+
type: "boolean",
|
|
185
|
+
description: "Discover durable repairs for an explicit original actor"
|
|
186
|
+
},
|
|
187
|
+
cursor: { type: "string", description: "Exact JSON nextCursor from the preceding --jobs page" },
|
|
188
|
+
inspect: {
|
|
189
|
+
type: "string",
|
|
190
|
+
description: "Inspect a prepared job, retained receipts and lifecycle ledger"
|
|
191
|
+
},
|
|
192
|
+
cancel: {
|
|
193
|
+
type: "string",
|
|
194
|
+
description: "Request cancellation; committed repair effects are preserved"
|
|
195
|
+
},
|
|
196
|
+
resume: {
|
|
197
|
+
type: "string",
|
|
198
|
+
description: "Explicitly retry recoverable work while retaining prior attempts"
|
|
199
|
+
},
|
|
200
|
+
actor: {
|
|
201
|
+
type: "string",
|
|
202
|
+
description: "Explicit stable repair actor; must match prepared work"
|
|
203
|
+
},
|
|
204
|
+
"proposal-id": {
|
|
205
|
+
type: "string",
|
|
206
|
+
description: "Immutable proposal identity for job operations or new rollback"
|
|
207
|
+
},
|
|
208
|
+
limit: {
|
|
209
|
+
type: "string",
|
|
210
|
+
description: "Page size: --jobs 1\u2013100 (default 25); inspection 1\u20131000 (default 100)"
|
|
211
|
+
},
|
|
212
|
+
offset: { type: "string", default: "0", description: "Inspection ledger page offset" },
|
|
213
|
+
rollback: {
|
|
214
|
+
type: "string",
|
|
215
|
+
description: "Restore a prior repair receipt after checking its post-state"
|
|
216
|
+
},
|
|
217
|
+
decision: {
|
|
218
|
+
type: "string",
|
|
219
|
+
description: "Assess explicit decision-to-task-to-code evidence and supported linking actions"
|
|
220
|
+
},
|
|
221
|
+
task: {
|
|
222
|
+
type: "string",
|
|
223
|
+
description: "Include evidence-derived footprint findings for one task"
|
|
224
|
+
},
|
|
225
|
+
"budget-ms": {
|
|
226
|
+
type: "string",
|
|
227
|
+
default: "2000",
|
|
228
|
+
description: "Shared invocation budget in milliseconds (1\u2013120000), default 2000; synchronous work is cooperative"
|
|
229
|
+
},
|
|
230
|
+
json: { type: "boolean", description: "Output one structured envelope" }
|
|
231
|
+
},
|
|
232
|
+
async run({ args }) {
|
|
233
|
+
const startedAt = Date.now();
|
|
234
|
+
const root = getProjectRoot();
|
|
235
|
+
let context;
|
|
236
|
+
let pending;
|
|
237
|
+
try {
|
|
238
|
+
const budgetMs = Number(args["budget-ms"]);
|
|
239
|
+
if (!Number.isSafeInteger(budgetMs) || budgetMs < 1 || budgetMs > 12e4)
|
|
240
|
+
throw new KnowledgeRepairError(
|
|
241
|
+
"E_REPAIR_INPUT",
|
|
242
|
+
"--budget-ms must be an integer between 1 and 120000."
|
|
243
|
+
);
|
|
244
|
+
const deadlineAt = startedAt + budgetMs;
|
|
245
|
+
const actions = [
|
|
246
|
+
args.fix,
|
|
247
|
+
args.resolve,
|
|
248
|
+
args.rollback,
|
|
249
|
+
args.prepare,
|
|
250
|
+
args.apply,
|
|
251
|
+
args.inspect,
|
|
252
|
+
args.cancel,
|
|
253
|
+
args.resume,
|
|
254
|
+
args.jobs
|
|
255
|
+
];
|
|
256
|
+
if (actions.filter(Boolean).length > 1)
|
|
257
|
+
throw new KnowledgeRepairError(
|
|
258
|
+
"E_REPAIR_INPUT",
|
|
259
|
+
"Select exactly one repair lifecycle action."
|
|
260
|
+
);
|
|
261
|
+
if (args["dry-run"] && (args.prepare || args.apply || args.inspect || args.cancel || args.resume || args.rollback || args.jobs))
|
|
262
|
+
throw new KnowledgeRepairError(
|
|
263
|
+
"E_REPAIR_INPUT",
|
|
264
|
+
"--dry-run cannot execute a repair lifecycle action."
|
|
265
|
+
);
|
|
266
|
+
const lifecycle = actions.some(Boolean) && !args["dry-run"];
|
|
267
|
+
if (lifecycle && !args.actor?.trim())
|
|
268
|
+
throw new KnowledgeRepairError(
|
|
269
|
+
"E_REPAIR_ACTOR",
|
|
270
|
+
"--actor explicitly identifies the stable repair caller."
|
|
271
|
+
);
|
|
272
|
+
if ((args.apply || args.inspect || args.cancel || args.resume || args.rollback) && !args["proposal-id"]?.trim())
|
|
273
|
+
throw new KnowledgeRepairError(
|
|
274
|
+
"E_REPAIR_INPUT",
|
|
275
|
+
"--proposal-id must identify the immutable prepared input or new rollback."
|
|
276
|
+
);
|
|
277
|
+
if (args.cursor && !args.jobs)
|
|
278
|
+
throw new KnowledgeRepairError("E_REPAIR_INPUT", "--cursor requires --jobs.");
|
|
279
|
+
if (args.jobs) {
|
|
280
|
+
if (args["proposal-id"] || Number(args.offset) !== 0)
|
|
281
|
+
throw new KnowledgeRepairError(
|
|
282
|
+
"E_REPAIR_INPUT",
|
|
283
|
+
"--jobs uses its returned cursor, not proposal identity or offset."
|
|
284
|
+
);
|
|
285
|
+
context = await createKnowledgeRepairInvocation(
|
|
286
|
+
root,
|
|
287
|
+
args.actor,
|
|
288
|
+
"knowledge-inventory",
|
|
289
|
+
deadlineAt
|
|
290
|
+
);
|
|
291
|
+
cliOutput(
|
|
292
|
+
await listPreparedKnowledgeRepairs(context, {
|
|
293
|
+
limit: Number(args.limit ?? "25"),
|
|
294
|
+
after: args.cursor === void 0 ? void 0 : JSON.parse(args.cursor)
|
|
295
|
+
}),
|
|
296
|
+
{ command: "doctor", operation: "doctor.knowledge" }
|
|
297
|
+
);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
let proposal = args.prepare || args.resolve ? parseKnowledgeRepairProposal(await readFile(args.prepare || args.resolve, "utf8")) : void 0;
|
|
301
|
+
if (proposal && args["proposal-id"] && proposal.id !== args["proposal-id"])
|
|
302
|
+
throw new KnowledgeRepairError(
|
|
303
|
+
"E_REPAIR_INPUT",
|
|
304
|
+
"--proposal-id differs from the sourced proposal."
|
|
305
|
+
);
|
|
306
|
+
if (!lifecycle || args.fix) {
|
|
307
|
+
const report = await runKnowledgeDoctor(root, {
|
|
308
|
+
budgetMs: Math.max(0, deadlineAt - Date.now()),
|
|
309
|
+
fix: args.fix,
|
|
310
|
+
dryRun: true,
|
|
311
|
+
proposal,
|
|
312
|
+
taskId: args.task,
|
|
313
|
+
decisionId: args.decision
|
|
314
|
+
});
|
|
315
|
+
if (!lifecycle || report.health.coverage.maintenanceState === "pending" || !report.proposals[0]) {
|
|
316
|
+
cliOutput(report, { command: "doctor", operation: "doctor.knowledge" });
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
proposal = report.proposals[0];
|
|
320
|
+
}
|
|
321
|
+
if (proposal && args["proposal-id"] && proposal.id !== args["proposal-id"])
|
|
322
|
+
throw new KnowledgeRepairError(
|
|
323
|
+
"E_REPAIR_INPUT",
|
|
324
|
+
"--proposal-id differs from the assessed proposal."
|
|
325
|
+
);
|
|
326
|
+
const proposalId = proposal?.id ?? args["proposal-id"];
|
|
327
|
+
if (!proposalId || !args.actor)
|
|
328
|
+
throw new KnowledgeRepairError(
|
|
329
|
+
"E_REPAIR_INPUT",
|
|
330
|
+
"Explicit actor and immutable proposal identity are required."
|
|
331
|
+
);
|
|
332
|
+
context = await createKnowledgeRepairInvocation(root, args.actor, proposalId, deadlineAt);
|
|
333
|
+
if (args.inspect) {
|
|
334
|
+
cliOutput(
|
|
335
|
+
await inspectPreparedKnowledgeRepair(
|
|
336
|
+
context,
|
|
337
|
+
args.inspect,
|
|
338
|
+
Number(args.limit ?? "100"),
|
|
339
|
+
Number(args.offset)
|
|
340
|
+
),
|
|
341
|
+
{ command: "doctor", operation: "doctor.knowledge" }
|
|
342
|
+
);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (args.cancel) {
|
|
346
|
+
cliOutput(await cancelPreparedKnowledgeRepair(context, args.cancel), {
|
|
347
|
+
command: "doctor",
|
|
348
|
+
operation: "doctor.knowledge"
|
|
349
|
+
});
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (proposal) pending = await prepareKnowledgeRepair(context, proposal);
|
|
353
|
+
else if (args.rollback) pending = await prepareKnowledgeRollback(context, args.rollback);
|
|
354
|
+
if (args.prepare) {
|
|
355
|
+
cliOutput(pending, { command: "doctor", operation: "doctor.knowledge" });
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const jobId = pending?.jobId ?? args.apply ?? args.resume;
|
|
359
|
+
if (!jobId) throw new KnowledgeRepairError("E_REPAIR_INPUT", "A prepared job is required.");
|
|
360
|
+
const result = args.resume ? await resumePreparedKnowledgeRepair(context, jobId) : await applyPreparedKnowledgeRepair(context, jobId);
|
|
361
|
+
cliOutput(result, { command: "doctor", operation: "doctor.knowledge" });
|
|
362
|
+
} catch (error) {
|
|
363
|
+
cliError(
|
|
364
|
+
error instanceof Error ? error.message : String(error),
|
|
365
|
+
6,
|
|
366
|
+
{
|
|
367
|
+
name: error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : "E_REPAIR_INPUT",
|
|
368
|
+
details: {
|
|
369
|
+
prepared: pending,
|
|
370
|
+
attemptFailure: error instanceof KnowledgeRepairError ? error.attemptFailure : void 0,
|
|
371
|
+
recoveryState: error instanceof KnowledgeRepairError ? error.recoveryState : void 0,
|
|
372
|
+
deadlineAt: context?.deadlineAt,
|
|
373
|
+
elapsedMs: Date.now() - startedAt
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
{ operation: "doctor.knowledge" }
|
|
377
|
+
);
|
|
378
|
+
process.exitCode = 6;
|
|
379
|
+
} finally {
|
|
380
|
+
context?.close();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// packages/cleo/src/cli/commands/doctor.ts
|
|
386
|
+
var FIXTURE_ID_PATTERNS = [/^E\d+$/, /^T\d+EP$/];
|
|
387
|
+
var FIXTURE_TITLE_KEYWORDS = [
|
|
388
|
+
"test epic",
|
|
389
|
+
"with no files",
|
|
390
|
+
"standalone epic",
|
|
391
|
+
"fixture"
|
|
392
|
+
];
|
|
393
|
+
async function scanTestFixturesInProd(projectRoot) {
|
|
394
|
+
const { getDb, getNativeDb } = await import("@cleocode/core/store/sqlite.js");
|
|
395
|
+
await getDb(projectRoot);
|
|
396
|
+
const nativeDb = getNativeDb(projectRoot);
|
|
397
|
+
if (!nativeDb) return [];
|
|
398
|
+
const rows = nativeDb.prepare("SELECT id, title, type, status FROM tasks WHERE status != 'deleted' LIMIT 2000").all();
|
|
399
|
+
const matches = [];
|
|
400
|
+
for (const row of rows) {
|
|
401
|
+
const lower = (row.title ?? "").toLowerCase();
|
|
402
|
+
const idPatternMatch = FIXTURE_ID_PATTERNS.some((p) => p.test(row.id));
|
|
403
|
+
const titleKeywordMatch = FIXTURE_TITLE_KEYWORDS.find((kw) => lower.includes(kw));
|
|
404
|
+
if (idPatternMatch) {
|
|
405
|
+
matches.push({
|
|
406
|
+
id: row.id,
|
|
407
|
+
title: row.title ?? "",
|
|
408
|
+
type: row.type ?? "",
|
|
409
|
+
confidence: "HIGH",
|
|
410
|
+
rationale: `id matches fixture pattern (^E\\d+$ or ^T\\d+EP$)`
|
|
411
|
+
});
|
|
412
|
+
} else if (titleKeywordMatch) {
|
|
413
|
+
matches.push({
|
|
414
|
+
id: row.id,
|
|
415
|
+
title: row.title ?? "",
|
|
416
|
+
type: row.type ?? "",
|
|
417
|
+
confidence: "MED",
|
|
418
|
+
rationale: `title contains fixture keyword "${titleKeywordMatch}"`
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return matches;
|
|
423
|
+
}
|
|
424
|
+
async function quarantineTestFixtures(projectRoot, matches) {
|
|
425
|
+
if (matches.length === 0) return 0;
|
|
426
|
+
const cleoDir = join(projectRoot, ".cleo");
|
|
427
|
+
const quarantineDir = join(
|
|
428
|
+
cleoDir,
|
|
429
|
+
"quarantine",
|
|
430
|
+
`fixture-scan-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`
|
|
431
|
+
);
|
|
432
|
+
mkdirSync(quarantineDir, { recursive: true });
|
|
433
|
+
const manifest = matches.map((m) => ({ ...m, quarantinedAt: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
434
|
+
writeFileSync(
|
|
435
|
+
join(quarantineDir, "manifest.jsonl"),
|
|
436
|
+
manifest.map((m) => JSON.stringify(m)).join("\n") + "\n"
|
|
437
|
+
);
|
|
438
|
+
const { getNativeDb } = await import("@cleocode/core/store/sqlite.js");
|
|
439
|
+
const nativeDb = getNativeDb();
|
|
440
|
+
if (nativeDb) {
|
|
441
|
+
for (const m of matches) {
|
|
442
|
+
try {
|
|
443
|
+
nativeDb.prepare(
|
|
444
|
+
"UPDATE tasks SET labels_json = json_insert(COALESCE(labels_json, '[]'), '$[#]', 'fixture-quarantine'), status = 'cancelled' WHERE id = ?"
|
|
445
|
+
).run(m.id);
|
|
446
|
+
} catch {
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return matches.length;
|
|
451
|
+
}
|
|
452
|
+
function renderHookMatrixHuman(data) {
|
|
453
|
+
const { events, providers, matrix, summary, caampVersion, detectedProvider } = data;
|
|
454
|
+
humanLine(`
|
|
455
|
+
Provider Hook Matrix (CAAMP ${caampVersion} canonical taxonomy)
|
|
456
|
+
`);
|
|
457
|
+
if (detectedProvider) {
|
|
458
|
+
humanLine(`Detected provider: ${detectedProvider}
|
|
459
|
+
`);
|
|
460
|
+
}
|
|
461
|
+
if (providers.length === 0) {
|
|
462
|
+
humanLine("No providers found in CAAMP registry.");
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
const EVENT_COL = Math.max(...events.map((e) => e.length), "Event".length);
|
|
466
|
+
const provCols = providers.map((p) => Math.max(p.length, 5));
|
|
467
|
+
const headerParts = [
|
|
468
|
+
"Event".padEnd(EVENT_COL),
|
|
469
|
+
...providers.map((p, i) => p.padEnd(provCols[i]))
|
|
470
|
+
];
|
|
471
|
+
humanLine(` ${headerParts.join(" ")}`);
|
|
472
|
+
const sepParts = ["-".repeat(EVENT_COL), ...provCols.map((w) => "-".repeat(w))];
|
|
473
|
+
humanLine(` ${sepParts.join(" ")}`);
|
|
474
|
+
for (const event of events) {
|
|
475
|
+
const cells = providers.map((p, i) => {
|
|
476
|
+
const supported = matrix[event]?.[p] === true;
|
|
477
|
+
const symbol = supported ? "\u2713" : "-";
|
|
478
|
+
return symbol.padEnd(provCols[i]);
|
|
479
|
+
});
|
|
480
|
+
humanLine(` ${event.padEnd(EVENT_COL)} ${cells.join(" ")}`);
|
|
481
|
+
}
|
|
482
|
+
humanLine("");
|
|
483
|
+
const coverageParts = summary.map(
|
|
484
|
+
(s) => `${s.providerId} ${s.supportedCount}/${s.totalCanonical} (${s.coverage}%)`
|
|
485
|
+
);
|
|
486
|
+
humanLine(`Coverage: ${coverageParts.join(", ")}
|
|
487
|
+
`);
|
|
488
|
+
}
|
|
489
|
+
function renderInvariantAuditHuman(result) {
|
|
490
|
+
for (const line of renderInvariantAuditLines(result)) {
|
|
491
|
+
humanLine(line);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
var doctorCommand = defineCommand({
|
|
495
|
+
meta: { name: "doctor", description: "Run system diagnostics and health checks" },
|
|
496
|
+
subCommands: {
|
|
497
|
+
knowledge: doctorKnowledgeSubcommand,
|
|
498
|
+
// T10307 / Saga T10281 / Epic T10282 — DB-substrate walker
|
|
499
|
+
"db-substrate": doctorDbSubstrateCommand,
|
|
500
|
+
// T10309 / Saga T10281 / Epic T10282 — Legacy-backup walker
|
|
501
|
+
"legacy-backups": doctorLegacyBackupsCommand,
|
|
502
|
+
// T12131 — the reaper that kills live Codex sessions
|
|
503
|
+
"legacy-reaper": doctorLegacyReaperCommand,
|
|
504
|
+
// T12128 — task ids that fail the write-path validator
|
|
505
|
+
"malformed-ids": doctorMalformedIdsCommand,
|
|
506
|
+
// T12796 — the migration journal of each store (read-only; the live journal count)
|
|
507
|
+
migrations: doctorMigrationsCommand,
|
|
508
|
+
// T12686 — manifest rows whose metadata violates the stored field contract (+ --repair/--rollback)
|
|
509
|
+
"manifest-rows": doctorManifestRowsCommand,
|
|
510
|
+
// T12095 — pre-dual-scope store files still on disk under their old LIVE names
|
|
511
|
+
"superseded-store": doctorSupersededStoreCommand,
|
|
512
|
+
// T12535 — twin collapses (bare schema_meta / sticky_tags → prefixed twins): report + --retry
|
|
513
|
+
"twin-collapse": doctorTwinCollapseCommand,
|
|
514
|
+
// T12460 — project stores stranded inside CLEO worktrees (read-only report)
|
|
515
|
+
"worktree-stores": doctorWorktreeStoresCommand,
|
|
516
|
+
// T12097 — machine-wide guard for test runs started OUTSIDE cleo verify
|
|
517
|
+
"memory-guard": doctorMemoryGuardCommand,
|
|
518
|
+
// T13124 — the heavy-command hook per agent harness in use (+ --fix installs it)
|
|
519
|
+
"heavy-command-hook": doctorHeavyCommandHookCommand,
|
|
520
|
+
// T12353 · T12716 — tracked .cleo/project.json / project-id vs project-info.json (+ --resolve migrate / re-key)
|
|
521
|
+
"project-identity": doctorProjectIdentityCommand,
|
|
522
|
+
// T12596 · T12598 — ~/.cleo, the global hub and every harness skill install must resolve
|
|
523
|
+
"global-delivery": doctorGlobalDeliveryCommand,
|
|
524
|
+
// T13231 — the explicit from-scratch row-identity refill (dry run; --refill --apply)
|
|
525
|
+
"row-identity": doctorRowIdentityCommand,
|
|
526
|
+
// T12987 — repair diff of suspect sync tables (read-only plan; + --repair)
|
|
527
|
+
"sync-journal": doctorSyncJournalCommand,
|
|
528
|
+
// T12754 — project store triggers incl. ones referencing missing objects (+ --repair)
|
|
529
|
+
"sync-triggers": doctorSyncTriggersCommand,
|
|
530
|
+
// T12645 — caamp test fixtures left in the real skills root (quarantine with a receipt)
|
|
531
|
+
"skill-fixtures": doctorSkillFixturesCommand,
|
|
532
|
+
// T12471 — machine-wide registry integrity: rebind moved by id, flag split/missing/temp
|
|
533
|
+
projects: doctorRegistryCommand,
|
|
534
|
+
// T12329 — import rows only a diverged store copy has, under new ids (dry-run first)
|
|
535
|
+
"split-brain": doctorSplitBrainCommand,
|
|
536
|
+
// T12157 — the two acceptance stores (json column vs text+child rows) must agree
|
|
537
|
+
"acceptance-drift": doctorAcceptanceDriftCommand,
|
|
538
|
+
// T12790 — evidence bindings whose AC row is gone (no FK): report + --fix (audited)
|
|
539
|
+
"ac-bindings": doctorAcBindingsCommand,
|
|
540
|
+
// T12886 — stored task dependency cycles + repair plan (read-only)
|
|
541
|
+
"dep-cycles": doctorDepCyclesCommand,
|
|
542
|
+
// T12158 — tables nexus resolves by bare name must actually live where it assumes
|
|
543
|
+
"nexus-residency": doctorNexusResidencyCommand,
|
|
544
|
+
// T12113 (gh#1222) — evidence-tool semaphore holders + orphan reaping
|
|
545
|
+
"tool-locks": doctorToolLocksCommand,
|
|
546
|
+
// T12326 — project credentials still keyed by project PATH (+ --fix re-keys)
|
|
547
|
+
credentials: doctorCredentialsCommand,
|
|
548
|
+
// T11777 / Saga T11242 / Epic T11249 — exodus stranded-residue check (+ --fix)
|
|
549
|
+
"exodus-residue": doctorExodusResidueCommand,
|
|
550
|
+
// T11837 / Saga T11242 / Epic T11833 — read-only exodus health report
|
|
551
|
+
"exodus-health": doctorExodusCommand,
|
|
552
|
+
// T11530 / Saga T11242 / Epic T11249 — consolidated FK integrity check
|
|
553
|
+
"fk-check": doctorFkCheckCommand,
|
|
554
|
+
// T11829 / Saga T11242 / Epic T11833 — DHQ-060 malformed-DB repair entry point
|
|
555
|
+
repair: doctorRepairCommand,
|
|
556
|
+
// T10458 / Saga T10431 / Epic T10436 — Release-readiness preflight
|
|
557
|
+
"release-readiness": doctorReleaseReadinessCommand
|
|
558
|
+
},
|
|
559
|
+
args: {
|
|
560
|
+
detailed: {
|
|
561
|
+
type: "boolean",
|
|
562
|
+
description: "Show detailed health check results"
|
|
563
|
+
},
|
|
564
|
+
comprehensive: {
|
|
565
|
+
type: "boolean",
|
|
566
|
+
description: "Run comprehensive doctor report"
|
|
567
|
+
},
|
|
568
|
+
full: {
|
|
569
|
+
type: "boolean",
|
|
570
|
+
description: "Run operational smoke tests across all domains"
|
|
571
|
+
},
|
|
572
|
+
fix: {
|
|
573
|
+
type: "boolean",
|
|
574
|
+
description: "Auto-fix failed checks"
|
|
575
|
+
},
|
|
576
|
+
coherence: {
|
|
577
|
+
type: "boolean",
|
|
578
|
+
description: "Run coherence check across task data"
|
|
579
|
+
},
|
|
580
|
+
hooks: {
|
|
581
|
+
type: "boolean",
|
|
582
|
+
description: "Show cross-provider hook support matrix (CAAMP canonical taxonomy)"
|
|
583
|
+
},
|
|
584
|
+
"all-projects": {
|
|
585
|
+
type: "boolean",
|
|
586
|
+
description: "Probe DB + config health for every registered project (nexus.db)"
|
|
587
|
+
},
|
|
588
|
+
"ignore-unreachable": {
|
|
589
|
+
type: "boolean",
|
|
590
|
+
description: "When used with --all-projects, exit 1 instead of 2 on unreachable projects"
|
|
591
|
+
},
|
|
592
|
+
"scan-rogue-cleo-dirs": {
|
|
593
|
+
type: "boolean",
|
|
594
|
+
description: "Scan for rogue .cleo/ directories inside sub-packages and print forensic report"
|
|
595
|
+
},
|
|
596
|
+
"quarantine-rogue-cleo-dirs": {
|
|
597
|
+
type: "boolean",
|
|
598
|
+
description: "Move all rogue .cleo/ sub-package directories to .cleo/quarantine/ (never deletes)"
|
|
599
|
+
},
|
|
600
|
+
"scan-stray-nexus-dbs": {
|
|
601
|
+
type: "boolean",
|
|
602
|
+
description: "Scan ~/.local/share/cleo/ for orphaned nexus.db files and print report (T9052)"
|
|
603
|
+
},
|
|
604
|
+
"audit-worktrees": {
|
|
605
|
+
type: "boolean",
|
|
606
|
+
description: "Audit orphaned agent worktree directories and report what cleo gc --worktrees would remove (T9043)"
|
|
607
|
+
},
|
|
608
|
+
/**
|
|
609
|
+
* T9790: list orphan `.cleo/` directories under
|
|
610
|
+
* `<projectRoot>/.claude/worktrees/` with full provenance. Read-only.
|
|
611
|
+
*/
|
|
612
|
+
"audit-worktree-orphans": {
|
|
613
|
+
type: "boolean",
|
|
614
|
+
description: "List orphan .cleo/ directories under .claude/worktrees/ (T9790, fallout from T9550/T9580)"
|
|
615
|
+
},
|
|
616
|
+
/**
|
|
617
|
+
* T9962: timeout in seconds for --audit-worktree-orphans and
|
|
618
|
+
* --prune-worktree-orphans. On expiry the scan returns a partial result.
|
|
619
|
+
* Default: 30 seconds.
|
|
620
|
+
*/
|
|
621
|
+
timeout: {
|
|
622
|
+
type: "string",
|
|
623
|
+
description: "Timeout in seconds for worktree-orphan audit/prune scan (default: 30). Partial results are returned on expiry."
|
|
624
|
+
},
|
|
625
|
+
/**
|
|
626
|
+
* T9962: per-level fan-out cap for --audit-worktree-orphans.
|
|
627
|
+
* Default: 500.
|
|
628
|
+
*/
|
|
629
|
+
"max-entries-per-level": {
|
|
630
|
+
type: "string",
|
|
631
|
+
description: "Per-level entry hard-stop for worktree-orphan scan (default: 500). Scan aborts with partial result when exceeded."
|
|
632
|
+
},
|
|
633
|
+
/**
|
|
634
|
+
* T9790: archive then remove every orphan reported by
|
|
635
|
+
* `--audit-worktree-orphans`. Combine with `--dry-run` to preview
|
|
636
|
+
* without touching the filesystem.
|
|
637
|
+
*/
|
|
638
|
+
"prune-worktree-orphans": {
|
|
639
|
+
type: "boolean",
|
|
640
|
+
description: "Archive then remove orphan .cleo/ directories under .claude/worktrees/ (T9790)"
|
|
641
|
+
},
|
|
642
|
+
"audit-temp": {
|
|
643
|
+
type: "boolean",
|
|
644
|
+
description: "Audit orphaned CLEO-generated temp directories and report what cleo gc --temp would remove (T9043)"
|
|
645
|
+
},
|
|
646
|
+
/**
|
|
647
|
+
* T10119: audit every Saga (`type='epic'` + `label='saga'`) for
|
|
648
|
+
* ADR-073 §1.2 invariant violations (I5/I7 + depth ladder) and
|
|
649
|
+
* auto-close drift. Read-only; non-zero exit when any I-invariant
|
|
650
|
+
* fails so the check is CI-gateable.
|
|
651
|
+
*
|
|
652
|
+
* As of T10340 (R6), `--audit-sagas` is a focused alias on top of
|
|
653
|
+
* `--audit-invariants` — it filters the registry walk to ADR-073
|
|
654
|
+
* only. The implementation re-uses the central walker so the two
|
|
655
|
+
* surfaces stay in lock-step.
|
|
656
|
+
*
|
|
657
|
+
* @task T10119
|
|
658
|
+
* @task T10340
|
|
659
|
+
* @saga T10113
|
|
660
|
+
* @epic T10209
|
|
661
|
+
*/
|
|
662
|
+
"audit-sagas": {
|
|
663
|
+
type: "boolean",
|
|
664
|
+
description: "Audit every Saga for ADR-073 \xA71.2 invariant violations (I5/I7/depth) + auto-close drift \u2014 focused alias on top of --audit-invariants (T10119, T10340)"
|
|
665
|
+
},
|
|
666
|
+
/**
|
|
667
|
+
* T10340: walk the central `INVARIANTS_REGISTRY` and audit every
|
|
668
|
+
* registered invariant against the project's current state.
|
|
669
|
+
*
|
|
670
|
+
* Output groups violations by ADR + severity and includes an
|
|
671
|
+
* actionable repair command per violation. Supports `--json` for
|
|
672
|
+
* machine consumption. Exit code is non-zero when any
|
|
673
|
+
* `severity:'error'` violation is observed.
|
|
674
|
+
*
|
|
675
|
+
* @task T10340 — R6
|
|
676
|
+
* @epic T10327 — E-INVARIANT-REGISTRY-SSOT
|
|
677
|
+
* @saga T10326 — SG-SUBSTRATE-RECONCILIATION
|
|
678
|
+
*/
|
|
679
|
+
"audit-invariants": {
|
|
680
|
+
type: "boolean",
|
|
681
|
+
description: "Walk the central INVARIANTS_REGISTRY and audit every registered invariant \u2014 groups by ADR + severity with repair commands (T10340 / Saga T10326 R6)"
|
|
682
|
+
},
|
|
683
|
+
/**
|
|
684
|
+
* T9983: migrate the worktree-include file location from
|
|
685
|
+
* `<root>/.cleo/worktree-include` (legacy) to `<root>/.worktreeinclude`
|
|
686
|
+
* (canonical, matches Claude Code Desktop + worktrunk-core). Backs the
|
|
687
|
+
* legacy file up to `.cleo/backups/worktree-include-<iso>.bak` before
|
|
688
|
+
* removing it from the legacy path. Combine with `--dry-run` to preview.
|
|
689
|
+
*/
|
|
690
|
+
"migrate-worktree-include": {
|
|
691
|
+
type: "boolean",
|
|
692
|
+
description: "Migrate <root>/.cleo/worktree-include (legacy) \u2192 <root>/.worktreeinclude (canonical, T9983). Combine with --dry-run to preview."
|
|
693
|
+
},
|
|
694
|
+
/**
|
|
695
|
+
* T11489 — DHQ-037/019: detect and auto-heal a leaked `core.worktree` key
|
|
696
|
+
* in the shared `.git/config`. Reports E_WT_CONFIG_LEAK when found; heals
|
|
697
|
+
* automatically unless `--dry-run` is passed.
|
|
698
|
+
*/
|
|
699
|
+
"check-worktree-config": {
|
|
700
|
+
type: "boolean",
|
|
701
|
+
description: "Detect and auto-heal a leaked core.worktree key in .git/config (T11489 / DHQ-037). Combine with --dry-run to report without healing."
|
|
702
|
+
},
|
|
703
|
+
"dry-run": {
|
|
704
|
+
type: "boolean",
|
|
705
|
+
description: "With --quarantine-rogue-cleo-dirs, --scan-stray-nexus-dbs, or --check-worktree-config: print what would be done without acting"
|
|
706
|
+
},
|
|
707
|
+
/**
|
|
708
|
+
* Show brain.db health dashboard (T1908 / BBTT-W2-4).
|
|
709
|
+
* Aggregates 8 named flags: row counts, dedup ratio, last consolidation,
|
|
710
|
+
* recency violations, learnings ratio, pattern bloat, fixture pollution,
|
|
711
|
+
* daemon liveness. Exits 1 on any P0 flag failure.
|
|
712
|
+
*/
|
|
713
|
+
brain: {
|
|
714
|
+
type: "boolean",
|
|
715
|
+
description: "Show brain.db health dashboard with 8 named BBTT flags (T1908)"
|
|
716
|
+
},
|
|
717
|
+
/**
|
|
718
|
+
* T1909 / BBTT-W3-3: Scan tasks.db for test-fixture rows using heuristics.
|
|
719
|
+
*
|
|
720
|
+
* Detects rows matching: id ^E\d+$, id ^T\d+EP$, or title containing
|
|
721
|
+
* "Test Epic", "with no files", "standalone epic", "fixture".
|
|
722
|
+
* Reports each match with a confidence score (HIGH/MED/LOW).
|
|
723
|
+
*
|
|
724
|
+
* Pass --quarantine to move matched rows to .cleo/quarantine/
|
|
725
|
+
* (T1864 pattern — NEVER deletes). Dry-run by default.
|
|
726
|
+
*/
|
|
727
|
+
"scan-test-fixtures-in-prod": {
|
|
728
|
+
type: "boolean",
|
|
729
|
+
description: "Scan tasks.db for test-fixture rows using heuristics (T1909)"
|
|
730
|
+
},
|
|
731
|
+
quarantine: {
|
|
732
|
+
type: "boolean",
|
|
733
|
+
description: "With --scan-test-fixtures-in-prod: move matches to .cleo/quarantine/ (no delete)"
|
|
734
|
+
},
|
|
735
|
+
// Global output format flags — read directly from args (no optsWithGlobals in citty)
|
|
736
|
+
json: {
|
|
737
|
+
type: "boolean",
|
|
738
|
+
description: "Output as JSON"
|
|
739
|
+
},
|
|
740
|
+
human: {
|
|
741
|
+
type: "boolean",
|
|
742
|
+
description: "Force human-readable output"
|
|
743
|
+
},
|
|
744
|
+
quiet: {
|
|
745
|
+
type: "boolean",
|
|
746
|
+
description: "Suppress non-essential output"
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
async run({ args, cmd, rawArgs }) {
|
|
750
|
+
if (isSubCommandDispatch(rawArgs, cmd.subCommands)) return;
|
|
751
|
+
const isHuman = args.human === true || !!process.stdout.isTTY && args.json !== true;
|
|
752
|
+
const progress = createDoctorProgress(isHuman);
|
|
753
|
+
progress.start();
|
|
754
|
+
try {
|
|
755
|
+
if (args["check-worktree-config"]) {
|
|
756
|
+
const { execFileSync: execFile } = await import("node:child_process");
|
|
757
|
+
const { join: pathJoin } = await import("node:path");
|
|
758
|
+
const { existsSync } = await import("node:fs");
|
|
759
|
+
const { detectAndHealCoreWorktreeLeak } = await import("@cleocode/worktree");
|
|
760
|
+
const projectRoot = getProjectRoot2();
|
|
761
|
+
let gitRoot = projectRoot;
|
|
762
|
+
try {
|
|
763
|
+
gitRoot = execFile("git", ["rev-parse", "--show-toplevel"], {
|
|
764
|
+
cwd: projectRoot,
|
|
765
|
+
encoding: "utf-8",
|
|
766
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
767
|
+
}).trim();
|
|
768
|
+
} catch {
|
|
769
|
+
}
|
|
770
|
+
const isDryRun = args["dry-run"] === true;
|
|
771
|
+
progress.step(0, "Checking for leaked core.worktree in .git/config");
|
|
772
|
+
if (isDryRun) {
|
|
773
|
+
const gitConfigPath = pathJoin(gitRoot, ".git", "config");
|
|
774
|
+
let leakedValue;
|
|
775
|
+
if (existsSync(gitConfigPath)) {
|
|
776
|
+
try {
|
|
777
|
+
leakedValue = execFile("git", ["config", "--file", gitConfigPath, "--get", "core.worktree"], {
|
|
778
|
+
encoding: "utf-8",
|
|
779
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
780
|
+
}).trim() || void 0;
|
|
781
|
+
} catch {
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
const report = {
|
|
785
|
+
gitRoot,
|
|
786
|
+
gitConfigPath,
|
|
787
|
+
leakDetected: !!leakedValue,
|
|
788
|
+
leakedValue,
|
|
789
|
+
healed: false,
|
|
790
|
+
dryRun: true,
|
|
791
|
+
message: leakedValue ? `DRY-RUN: core.worktree="${leakedValue}" found \u2014 would unset` : "No core.worktree leak detected"
|
|
792
|
+
};
|
|
793
|
+
progress.complete(report.message);
|
|
794
|
+
cliOutput(report, { command: "doctor", operation: "doctor.check-worktree-config" });
|
|
795
|
+
if (leakedValue) process.exitCode = 2;
|
|
796
|
+
} else {
|
|
797
|
+
const result = detectAndHealCoreWorktreeLeak(gitRoot);
|
|
798
|
+
const report = {
|
|
799
|
+
gitRoot,
|
|
800
|
+
...result,
|
|
801
|
+
dryRun: false,
|
|
802
|
+
message: result.leakDetected ? result.healed ? `E_WT_CONFIG_LEAK healed: removed core.worktree="${result.leakedValue}"` : `E_WT_CONFIG_LEAK detected but heal FAILED: ${result.healError}` : "No core.worktree leak detected"
|
|
803
|
+
};
|
|
804
|
+
progress.complete(report.message);
|
|
805
|
+
cliOutput(report, { command: "doctor", operation: "doctor.check-worktree-config" });
|
|
806
|
+
if (result.leakDetected && !result.healed) process.exitCode = 1;
|
|
807
|
+
}
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
if (args.brain) {
|
|
811
|
+
const { computeBrainHealthDashboard } = await import("@cleocode/core/memory/brain-health-dashboard.js");
|
|
812
|
+
const projectRoot = getProjectRoot2();
|
|
813
|
+
const dashboard = await computeBrainHealthDashboard(projectRoot);
|
|
814
|
+
cliOutput(dashboard, { command: "doctor", operation: "doctor.brain" });
|
|
815
|
+
if (dashboard.hasP0Failure) {
|
|
816
|
+
process.exitCode = 1;
|
|
817
|
+
}
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
if (args["scan-test-fixtures-in-prod"]) {
|
|
821
|
+
const projectRoot = getProjectRoot2();
|
|
822
|
+
const matches = await scanTestFixturesInProd(projectRoot);
|
|
823
|
+
const dryRun = args["dry-run"] !== false && args.quarantine !== true;
|
|
824
|
+
const quarantined = !dryRun && matches.length > 0 ? await quarantineTestFixtures(projectRoot, matches) : void 0;
|
|
825
|
+
cliOutput(
|
|
826
|
+
{ matches, dryRun, quarantined },
|
|
827
|
+
{ command: "doctor", operation: "doctor.scan-test-fixtures" }
|
|
828
|
+
);
|
|
829
|
+
if (matches.some((m) => m.confidence === "HIGH")) {
|
|
830
|
+
process.exitCode = 1;
|
|
831
|
+
}
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
if (args["all-projects"]) {
|
|
835
|
+
progress.step(0, "Probing registered projects");
|
|
836
|
+
await runDoctorProjects({
|
|
837
|
+
json: args.json === true,
|
|
838
|
+
quiet: args.quiet === true,
|
|
839
|
+
ignoreUnreachable: args["ignore-unreachable"] === true
|
|
840
|
+
});
|
|
841
|
+
progress.complete("Project health report complete");
|
|
842
|
+
} else if (args.hooks) {
|
|
843
|
+
progress.step(0, "Building provider hook matrix");
|
|
844
|
+
if (isHuman) {
|
|
845
|
+
const response = await dispatchRaw("query", "admin", "hooks.matrix", {
|
|
846
|
+
detectProvider: true
|
|
847
|
+
});
|
|
848
|
+
progress.complete("Hook matrix complete");
|
|
849
|
+
if (response.success && response.data) {
|
|
850
|
+
renderHookMatrixHuman(response.data);
|
|
851
|
+
} else {
|
|
852
|
+
cliError(response.error?.message ?? "Failed to build hook matrix", 1, {
|
|
853
|
+
name: "E_INTERNAL"
|
|
854
|
+
});
|
|
855
|
+
process.exitCode = 1;
|
|
856
|
+
}
|
|
857
|
+
} else {
|
|
858
|
+
await dispatchFromCli(
|
|
859
|
+
"query",
|
|
860
|
+
"admin",
|
|
861
|
+
"hooks.matrix",
|
|
862
|
+
{ detectProvider: true },
|
|
863
|
+
{ command: "doctor", operation: "admin.hooks.matrix" }
|
|
864
|
+
);
|
|
865
|
+
progress.complete("Hook matrix complete");
|
|
866
|
+
}
|
|
867
|
+
} else if (args.full) {
|
|
868
|
+
progress.step(0, "Running operational smoke tests");
|
|
869
|
+
await dispatchFromCli(
|
|
870
|
+
"query",
|
|
871
|
+
"admin",
|
|
872
|
+
"smoke",
|
|
873
|
+
{},
|
|
874
|
+
{ command: "doctor", operation: "admin.smoke" }
|
|
875
|
+
);
|
|
876
|
+
progress.complete("Smoke tests complete");
|
|
877
|
+
} else if (args.coherence) {
|
|
878
|
+
progress.step(0, "Running coherence check");
|
|
879
|
+
await dispatchFromCli(
|
|
880
|
+
"query",
|
|
881
|
+
"check",
|
|
882
|
+
"coherence",
|
|
883
|
+
{},
|
|
884
|
+
{ command: "doctor", operation: "check.coherence" }
|
|
885
|
+
);
|
|
886
|
+
progress.complete("Coherence check complete");
|
|
887
|
+
} else if (args.fix) {
|
|
888
|
+
progress.step(4, "Applying fixes");
|
|
889
|
+
await dispatchFromCli(
|
|
890
|
+
"mutate",
|
|
891
|
+
"admin",
|
|
892
|
+
"health",
|
|
893
|
+
{ mode: "repair" },
|
|
894
|
+
{ command: "doctor", operation: "admin.health" }
|
|
895
|
+
);
|
|
896
|
+
progress.complete("Fixes applied");
|
|
897
|
+
} else if (args.comprehensive) {
|
|
898
|
+
progress.step(0, "Checking CLEO directory");
|
|
899
|
+
await dispatchFromCli(
|
|
900
|
+
"query",
|
|
901
|
+
"admin",
|
|
902
|
+
"health",
|
|
903
|
+
{ mode: "diagnose" },
|
|
904
|
+
{ command: "doctor", operation: "admin.health" }
|
|
905
|
+
);
|
|
906
|
+
progress.complete("Comprehensive diagnostics complete");
|
|
907
|
+
} else if (args["scan-rogue-cleo-dirs"]) {
|
|
908
|
+
progress.step(0, "Scanning for rogue .cleo/ directories");
|
|
909
|
+
const projectRoot = getProjectRoot2();
|
|
910
|
+
const reports = scanRogueCleoDirs(projectRoot);
|
|
911
|
+
progress.complete(
|
|
912
|
+
`Found ${reports.length} rogue .cleo/ director${reports.length === 1 ? "y" : "ies"}`
|
|
913
|
+
);
|
|
914
|
+
cliOutput(reports, { command: "doctor", operation: "doctor.scan-rogue-cleo-dirs" });
|
|
915
|
+
} else if (args["quarantine-rogue-cleo-dirs"]) {
|
|
916
|
+
const isDryRun = args["dry-run"] === true;
|
|
917
|
+
progress.step(0, `${isDryRun ? "[DRY RUN] " : ""}Scanning for rogue .cleo/ directories`);
|
|
918
|
+
const projectRoot = getProjectRoot2();
|
|
919
|
+
const reports = scanRogueCleoDirs(projectRoot);
|
|
920
|
+
if (reports.length === 0) {
|
|
921
|
+
progress.complete("No rogue .cleo/ directories found \u2014 nothing to quarantine");
|
|
922
|
+
cliOutput(
|
|
923
|
+
{ quarantined: [] },
|
|
924
|
+
{ command: "doctor", operation: "doctor.quarantine-rogue-dirs" }
|
|
925
|
+
);
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const quarantined = [];
|
|
929
|
+
const errors = [];
|
|
930
|
+
for (const report of reports) {
|
|
931
|
+
if (isDryRun) {
|
|
932
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
933
|
+
const targetPath = `${projectRoot}/.cleo/quarantine/${report.packageName}-${timestamp}`;
|
|
934
|
+
quarantined.push({
|
|
935
|
+
packageName: report.packageName,
|
|
936
|
+
from: report.path,
|
|
937
|
+
to: targetPath
|
|
938
|
+
});
|
|
939
|
+
} else {
|
|
940
|
+
try {
|
|
941
|
+
const { quarantinePath } = quarantineRogueCleoDir(report, projectRoot);
|
|
942
|
+
quarantined.push({
|
|
943
|
+
packageName: report.packageName,
|
|
944
|
+
from: report.path,
|
|
945
|
+
to: quarantinePath
|
|
946
|
+
});
|
|
947
|
+
} catch (err) {
|
|
948
|
+
errors.push({
|
|
949
|
+
packageName: report.packageName,
|
|
950
|
+
path: report.path,
|
|
951
|
+
error: err instanceof Error ? err.message : String(err)
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
const verb = isDryRun ? "Would quarantine" : "Quarantined";
|
|
957
|
+
progress.complete(
|
|
958
|
+
`${verb} ${quarantined.length} director${quarantined.length === 1 ? "y" : "ies"}${errors.length > 0 ? `, ${errors.length} failed` : ""}`
|
|
959
|
+
);
|
|
960
|
+
cliOutput(
|
|
961
|
+
{ dryRun: isDryRun, quarantined, errors },
|
|
962
|
+
{ command: "doctor", operation: "doctor.quarantine-rogue-dirs" }
|
|
963
|
+
);
|
|
964
|
+
if (errors.length > 0) {
|
|
965
|
+
process.exitCode = 1;
|
|
966
|
+
}
|
|
967
|
+
} else if (args["scan-stray-nexus-dbs"]) {
|
|
968
|
+
progress.step(0, "Scanning for stray nexus.db files");
|
|
969
|
+
const { detectAndRemoveLegacyGlobalFiles, detectAndRemoveStrayProjectNexus } = await import("@cleocode/core/store/cleanup-legacy.js");
|
|
970
|
+
const { getCleoHome } = await import("@cleocode/core/core-paths");
|
|
971
|
+
const cleoHome = getCleoHome();
|
|
972
|
+
const projectRoot = getProjectRoot2();
|
|
973
|
+
const legacyResult = detectAndRemoveLegacyGlobalFiles(cleoHome);
|
|
974
|
+
const strayResult = detectAndRemoveStrayProjectNexus(projectRoot);
|
|
975
|
+
const isDryRun = args["dry-run"] === true;
|
|
976
|
+
const report = {
|
|
977
|
+
cleoHome,
|
|
978
|
+
projectRoot,
|
|
979
|
+
legacy: {
|
|
980
|
+
removed: legacyResult.removed.length,
|
|
981
|
+
files: legacyResult.removed
|
|
982
|
+
},
|
|
983
|
+
stray: {
|
|
984
|
+
removed: strayResult.removed,
|
|
985
|
+
path: strayResult.path
|
|
986
|
+
},
|
|
987
|
+
dryRun: isDryRun
|
|
988
|
+
};
|
|
989
|
+
progress.complete(
|
|
990
|
+
`Found ${legacyResult.removed.length} legacy + ${strayResult.removed ? 1 : 0} stray nexus.db`
|
|
991
|
+
);
|
|
992
|
+
cliOutput(report, { command: "doctor", operation: "doctor.scan-stray-nexus-dbs" });
|
|
993
|
+
} else if (args["audit-worktrees"]) {
|
|
994
|
+
progress.step(0, "Auditing orphaned agent worktrees");
|
|
995
|
+
const { auditOrphanWorktrees } = await import("@cleocode/core/gc/index.js");
|
|
996
|
+
const checkResult = auditOrphanWorktrees();
|
|
997
|
+
progress.complete(`Worktree audit complete \u2014 ${checkResult.status}`);
|
|
998
|
+
cliOutput(checkResult, { command: "doctor", operation: "doctor.audit-worktrees" });
|
|
999
|
+
if (checkResult.details?.["orphans"] && checkResult.details["orphans"].length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1000
|
+
process.exitCode = 2;
|
|
1001
|
+
}
|
|
1002
|
+
} else if (args["audit-worktree-orphans"]) {
|
|
1003
|
+
progress.step(0, "Comprehensive worktree anomaly audit (T9808 / council D009)");
|
|
1004
|
+
const { auditWorktreeOrphansComprehensive, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
|
|
1005
|
+
const projectRoot = getProjectRoot2();
|
|
1006
|
+
const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
|
|
1007
|
+
const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
|
|
1008
|
+
const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
|
|
1009
|
+
const [comprehensive, legacyScanResult] = await Promise.all([
|
|
1010
|
+
auditWorktreeOrphansComprehensive(projectRoot),
|
|
1011
|
+
scanWorktreeOrphansBudgeted(projectRoot, {
|
|
1012
|
+
timeoutMs,
|
|
1013
|
+
maxEntriesPerLevel: Number.isFinite(maxEntriesPerLevel) ? maxEntriesPerLevel : 500
|
|
1014
|
+
})
|
|
1015
|
+
]);
|
|
1016
|
+
const legacyOrphans = legacyScanResult.orphans;
|
|
1017
|
+
const totalAnomalies = comprehensive.count;
|
|
1018
|
+
if (legacyScanResult.softWarnMessage) {
|
|
1019
|
+
pushWarning({
|
|
1020
|
+
code: "W_DOCTOR_SCAN_SOFT_WARN",
|
|
1021
|
+
message: legacyScanResult.softWarnMessage,
|
|
1022
|
+
severity: "warn"
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
if (legacyScanResult.isPartial) {
|
|
1026
|
+
const reason = legacyScanResult.partialReason === "timeout" ? `timed out after ${timeoutSecs}s (use --timeout <seconds> to adjust)` : `per-level entry cap of ${maxEntriesPerLevel} exceeded (use --max-entries-per-level <n> to adjust)`;
|
|
1027
|
+
pushWarning({
|
|
1028
|
+
code: "W_DOCTOR_SCAN_PARTIAL",
|
|
1029
|
+
message: `legacy orphan scan is PARTIAL \u2014 ${reason}. Results may be incomplete.`,
|
|
1030
|
+
severity: "warn",
|
|
1031
|
+
context: {
|
|
1032
|
+
partialReason: legacyScanResult.partialReason,
|
|
1033
|
+
timeoutSecs,
|
|
1034
|
+
maxEntriesPerLevel
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
progress.complete(
|
|
1039
|
+
`Found ${totalAnomalies} anomal${totalAnomalies === 1 ? "y" : "ies"}` + (legacyOrphans.length > 0 ? ` (${legacyOrphans.length} legacy orphan(s))` : "") + (legacyScanResult.isPartial ? " [PARTIAL]" : "")
|
|
1040
|
+
);
|
|
1041
|
+
cliOutput(
|
|
1042
|
+
{
|
|
1043
|
+
projectRoot,
|
|
1044
|
+
comprehensive,
|
|
1045
|
+
legacyOrphans,
|
|
1046
|
+
legacyScanPartial: legacyScanResult.isPartial,
|
|
1047
|
+
legacyScanPartialReason: legacyScanResult.partialReason,
|
|
1048
|
+
count: totalAnomalies
|
|
1049
|
+
},
|
|
1050
|
+
{ command: "doctor", operation: "doctor.audit-worktree-orphans" }
|
|
1051
|
+
);
|
|
1052
|
+
if (totalAnomalies > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1053
|
+
process.exitCode = 2;
|
|
1054
|
+
}
|
|
1055
|
+
} else if (args["prune-worktree-orphans"]) {
|
|
1056
|
+
const isDryRun = args["dry-run"] === true;
|
|
1057
|
+
progress.step(
|
|
1058
|
+
0,
|
|
1059
|
+
`${isDryRun ? "[DRY RUN] " : ""}Scanning + pruning worktree-orphan .cleo/ directories`
|
|
1060
|
+
);
|
|
1061
|
+
const { pruneWorktreeOrphans, scanWorktreeOrphansBudgeted } = await import("@cleocode/core/doctor/worktree-orphans.js");
|
|
1062
|
+
const projectRoot = getProjectRoot2();
|
|
1063
|
+
const timeoutSecs = args["timeout"] !== void 0 ? Number.parseInt(String(args["timeout"]), 10) : 30;
|
|
1064
|
+
const timeoutMs = Number.isFinite(timeoutSecs) && timeoutSecs > 0 ? timeoutSecs * 1e3 : 3e4;
|
|
1065
|
+
const maxEntriesPerLevel = args["max-entries-per-level"] !== void 0 ? Number.parseInt(String(args["max-entries-per-level"]), 10) : 500;
|
|
1066
|
+
const scanResult = await scanWorktreeOrphansBudgeted(projectRoot, {
|
|
1067
|
+
timeoutMs,
|
|
1068
|
+
maxEntriesPerLevel: Number.isFinite(maxEntriesPerLevel) ? maxEntriesPerLevel : 500
|
|
1069
|
+
});
|
|
1070
|
+
if (scanResult.softWarnMessage) {
|
|
1071
|
+
pushWarning({
|
|
1072
|
+
code: "W_DOCTOR_SCAN_SOFT_WARN",
|
|
1073
|
+
message: scanResult.softWarnMessage,
|
|
1074
|
+
severity: "warn"
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
if (scanResult.isPartial) {
|
|
1078
|
+
const reason = scanResult.partialReason === "timeout" ? `timed out after ${timeoutSecs}s (use --timeout <seconds> to adjust)` : `per-level entry cap of ${maxEntriesPerLevel} exceeded (use --max-entries-per-level <n> to adjust)`;
|
|
1079
|
+
pushWarning({
|
|
1080
|
+
code: "W_DOCTOR_SCAN_PARTIAL",
|
|
1081
|
+
message: `orphan scan is PARTIAL \u2014 ${reason}. Only orphans found before abort will be pruned.`,
|
|
1082
|
+
severity: "warn",
|
|
1083
|
+
context: {
|
|
1084
|
+
partialReason: scanResult.partialReason,
|
|
1085
|
+
timeoutSecs,
|
|
1086
|
+
maxEntriesPerLevel
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
const orphans = scanResult.orphans;
|
|
1091
|
+
if (orphans.length === 0) {
|
|
1092
|
+
progress.complete(
|
|
1093
|
+
`No worktree orphans found \u2014 nothing to prune${scanResult.isPartial ? " [PARTIAL SCAN]" : ""}`
|
|
1094
|
+
);
|
|
1095
|
+
cliOutput(
|
|
1096
|
+
{
|
|
1097
|
+
projectRoot,
|
|
1098
|
+
dryRun: isDryRun,
|
|
1099
|
+
archivePath: null,
|
|
1100
|
+
pruned: [],
|
|
1101
|
+
rejected: [],
|
|
1102
|
+
totalSizeBytes: 0,
|
|
1103
|
+
scanPartial: scanResult.isPartial,
|
|
1104
|
+
scanPartialReason: scanResult.partialReason
|
|
1105
|
+
},
|
|
1106
|
+
{ command: "doctor", operation: "doctor.prune-worktree-orphans" }
|
|
1107
|
+
);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const archiveDir = join(projectRoot, ".cleo", "backups");
|
|
1111
|
+
const auditLogPath = join(projectRoot, ".cleo", "audit", "worktree-prune.jsonl");
|
|
1112
|
+
const result = await pruneWorktreeOrphans(orphans, {
|
|
1113
|
+
archiveDir,
|
|
1114
|
+
auditLogPath,
|
|
1115
|
+
dryRun: isDryRun,
|
|
1116
|
+
projectRoot
|
|
1117
|
+
});
|
|
1118
|
+
const verb = isDryRun ? "Would prune" : "Pruned";
|
|
1119
|
+
progress.complete(
|
|
1120
|
+
`${verb} ${result.pruned.length} orphan${result.pruned.length === 1 ? "" : "s"}${result.rejected.length > 0 ? `, ${result.rejected.length} rejected` : ""}${scanResult.isPartial ? " [PARTIAL SCAN]" : ""}`
|
|
1121
|
+
);
|
|
1122
|
+
cliOutput(
|
|
1123
|
+
{
|
|
1124
|
+
projectRoot,
|
|
1125
|
+
...result,
|
|
1126
|
+
scanPartial: scanResult.isPartial,
|
|
1127
|
+
scanPartialReason: scanResult.partialReason
|
|
1128
|
+
},
|
|
1129
|
+
{ command: "doctor", operation: "doctor.prune-worktree-orphans" }
|
|
1130
|
+
);
|
|
1131
|
+
if (result.rejected.length > 0) {
|
|
1132
|
+
process.exitCode = 1;
|
|
1133
|
+
}
|
|
1134
|
+
} else if (args["migrate-worktree-include"]) {
|
|
1135
|
+
const isDryRun = args["dry-run"] === true;
|
|
1136
|
+
progress.step(
|
|
1137
|
+
0,
|
|
1138
|
+
`${isDryRun ? "[DRY RUN] " : ""}Migrating .cleo/worktree-include \u2192 .worktreeinclude`
|
|
1139
|
+
);
|
|
1140
|
+
const { migrateWorktreeIncludeFile } = await import("@cleocode/core/scaffold/migrate-worktree-include");
|
|
1141
|
+
const projectRoot = getProjectRoot2();
|
|
1142
|
+
const result = await migrateWorktreeIncludeFile(projectRoot, { dryRun: isDryRun });
|
|
1143
|
+
progress.complete(`Migration ${result.action}`);
|
|
1144
|
+
cliOutput(result, { command: "doctor", operation: "doctor.migrate-worktree-include" });
|
|
1145
|
+
} else if (args["audit-temp"]) {
|
|
1146
|
+
progress.step(0, "Auditing orphaned CLEO temp directories");
|
|
1147
|
+
const { auditOrphanTempDirs } = await import("@cleocode/core/gc/index.js");
|
|
1148
|
+
const checkResult = await auditOrphanTempDirs();
|
|
1149
|
+
progress.complete(`Temp audit complete \u2014 ${checkResult.status}`);
|
|
1150
|
+
cliOutput(checkResult, { command: "doctor", operation: "doctor.audit-temp" });
|
|
1151
|
+
if (checkResult.details?.["orphans"] && checkResult.details["orphans"].length > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1152
|
+
process.exitCode = 2;
|
|
1153
|
+
}
|
|
1154
|
+
} else if (args["audit-invariants"] || args["audit-sagas"]) {
|
|
1155
|
+
const isFocusedAlias = args["audit-sagas"] === true && args["audit-invariants"] !== true;
|
|
1156
|
+
const adrFilter = isFocusedAlias ? "ADR-073" : void 0;
|
|
1157
|
+
const stepLabel = isFocusedAlias ? "Auditing Saga hierarchy for ADR-073 invariants" : "Walking central INVARIANTS_REGISTRY";
|
|
1158
|
+
progress.step(0, stepLabel);
|
|
1159
|
+
const { auditInvariantRegistry } = await import("@cleocode/core/doctor/invariant-audit.js");
|
|
1160
|
+
const projectRoot = getProjectRoot2();
|
|
1161
|
+
const result = await auditInvariantRegistry(projectRoot, { adrFilter });
|
|
1162
|
+
const operation = isFocusedAlias ? "doctor.audit-sagas" : "doctor.audit-invariants";
|
|
1163
|
+
const summary = `Invariant audit complete \u2014 ${result.totalCount} entries walked, ${result.errorCount} error / ${result.warningCount} warning / ${result.infoCount} info violation(s), ${result.notApplicableCount} not-applicable, ${result.documentedCount} documented`;
|
|
1164
|
+
progress.complete(summary);
|
|
1165
|
+
if (isHuman && args.json !== true) {
|
|
1166
|
+
renderInvariantAuditHuman(result);
|
|
1167
|
+
}
|
|
1168
|
+
cliOutput(result, { command: "doctor", operation });
|
|
1169
|
+
if (result.errorCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1170
|
+
process.exitCode = 2;
|
|
1171
|
+
}
|
|
1172
|
+
} else {
|
|
1173
|
+
progress.step(0, "Checking CLEO directory");
|
|
1174
|
+
await dispatchFromCli(
|
|
1175
|
+
"query",
|
|
1176
|
+
"admin",
|
|
1177
|
+
"health",
|
|
1178
|
+
{ detailed: args.detailed },
|
|
1179
|
+
{ command: "doctor", operation: "admin.health" }
|
|
1180
|
+
);
|
|
1181
|
+
try {
|
|
1182
|
+
const projectRoot = getProjectRoot2();
|
|
1183
|
+
const conflicts = readMigrationConflicts(projectRoot);
|
|
1184
|
+
if (conflicts.length > 0) {
|
|
1185
|
+
progress.complete(
|
|
1186
|
+
`Health check complete \u2014 ${conflicts.length} agent migration conflict(s) detected`
|
|
1187
|
+
);
|
|
1188
|
+
humanLine(
|
|
1189
|
+
`
|
|
1190
|
+
[MIGRATE-AGENTS-V2-CONFLICT] ${conflicts.length} agent(s) have conflicting .cant content between disk and signaldock.db:`
|
|
1191
|
+
);
|
|
1192
|
+
for (const c of conflicts) {
|
|
1193
|
+
humanLine(
|
|
1194
|
+
` - ${c.agentName} (${c.filePath})
|
|
1195
|
+
disk sha256: ${c.newSha256 ?? "unknown"}
|
|
1196
|
+
registry sha256: ${c.existingSha256 ?? "unknown"}
|
|
1197
|
+
Resolve: inspect the conflict and either update the registry via
|
|
1198
|
+
'cleo agent install --force <path>' or remove the conflicting file.`
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
humanLine(` Audit log: .cleo/audit/migration-agents-v2.jsonl
|
|
1202
|
+
`);
|
|
1203
|
+
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
1204
|
+
process.exitCode = 2;
|
|
1205
|
+
}
|
|
1206
|
+
} else {
|
|
1207
|
+
progress.complete("Health check complete");
|
|
1208
|
+
}
|
|
1209
|
+
} catch {
|
|
1210
|
+
progress.complete("Health check complete");
|
|
1211
|
+
}
|
|
1212
|
+
try {
|
|
1213
|
+
const projectRoot = getProjectRoot2();
|
|
1214
|
+
const { auditSagaHierarchy } = await import("@cleocode/core/doctor/saga-audit.js");
|
|
1215
|
+
const sagaAudit = await auditSagaHierarchy(projectRoot);
|
|
1216
|
+
if (sagaAudit.sagas.length === 0) {
|
|
1217
|
+
humanLine("\nSaga Hierarchy: no sagas found in tasks.db");
|
|
1218
|
+
} else {
|
|
1219
|
+
const header = `
|
|
1220
|
+
Saga Hierarchy (${sagaAudit.sagas.length} saga(s), ${sagaAudit.count} violation(s), ${sagaAudit.driftCount} drift warning(s)):`;
|
|
1221
|
+
humanLine(header);
|
|
1222
|
+
for (const s of sagaAudit.sagas) {
|
|
1223
|
+
const violationSuffix = s.violations.length > 0 ? `, ${s.violations.length} violation(s)` : "";
|
|
1224
|
+
humanLine(
|
|
1225
|
+
` ${s.sagaId} \xB7 status=${s.status} \xB7 ${s.doneCount}/${s.memberCount} members done${violationSuffix}`
|
|
1226
|
+
);
|
|
1227
|
+
for (const v of s.violations) {
|
|
1228
|
+
humanLine(` [${v.kind}] ${v.message}`);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
if (sagaAudit.count > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1233
|
+
process.exitCode = 2;
|
|
1234
|
+
}
|
|
1235
|
+
} catch (err) {
|
|
1236
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1237
|
+
humanLine(`
|
|
1238
|
+
Saga Hierarchy: audit skipped (${msg})`);
|
|
1239
|
+
}
|
|
1240
|
+
try {
|
|
1241
|
+
const { scanDependencyCycles } = await import("@cleocode/core/doctor/dependency-cycles.js");
|
|
1242
|
+
const cycles = await scanDependencyCycles(getProjectRoot2());
|
|
1243
|
+
humanLine(
|
|
1244
|
+
`
|
|
1245
|
+
Dependency cycles: ${cycles.cycleCount} (${cycles.edgeCount} edge(s) checked)`
|
|
1246
|
+
);
|
|
1247
|
+
for (const c of cycles.components) humanLine(` ${c.cycle.join(" \u2192 ")}`);
|
|
1248
|
+
if (cycles.repairPlan.length > 0) {
|
|
1249
|
+
humanLine(" Repair plan (review first; `cleo doctor dep-cycles` for JSON):");
|
|
1250
|
+
for (const r of cycles.repairPlan) humanLine(` ${r.command}`);
|
|
1251
|
+
}
|
|
1252
|
+
if (cycles.cycleCount > 0 && (process.exitCode === void 0 || process.exitCode === 0)) {
|
|
1253
|
+
process.exitCode = 2;
|
|
1254
|
+
}
|
|
1255
|
+
} catch (err) {
|
|
1256
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1257
|
+
humanLine(`
|
|
1258
|
+
Dependency cycles: check skipped (${msg})`);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
} catch (err) {
|
|
1262
|
+
progress.error("Health check failed");
|
|
1263
|
+
throw err;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
export {
|
|
1268
|
+
doctorCommand
|
|
1269
|
+
};
|
|
1270
|
+
//# sourceMappingURL=doctor-GPENOP4N.js.map
|