@iowarp/clio-coder 0.5.0 → 0.5.2
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/.claude-plugin/marketplace.json +4 -4
- package/CHANGELOG.md +35 -0
- package/CONTRIBUTING.md +9 -0
- package/README.md +12 -9
- package/ROADMAP.md +30 -5
- package/dist/{acp-KS7ARGV6.js → acp-F6PGOFZ4.js} +2 -2
- package/dist/{agents-YOGJ2YEJ.js → agents-ZHP4R6EX.js} +22 -21
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-CEDCO6O6.js → auth-N75U2H3Z.js} +4 -4
- package/dist/{chunk-D3KWFOUT.js → chunk-23UIXH6Z.js} +3 -3
- package/dist/{chunk-ZR5YA6ZF.js → chunk-36XVK5P5.js} +5 -5
- package/dist/{chunk-AVSR2HKI.js → chunk-3DZ4LPLS.js} +6 -6
- package/dist/{chunk-LYJJ6546.js → chunk-3GSPCWFX.js} +12 -12
- package/dist/{chunk-CRHPCPZP.js → chunk-4KC4CHKJ.js} +2 -2
- package/dist/{chunk-4VDHLCF5.js → chunk-4WJBWKMI.js} +2 -2
- package/dist/{chunk-KBUTSJSR.js → chunk-4XBYHXGK.js} +2 -2
- package/dist/{chunk-6W75D37F.js → chunk-53P775GE.js} +6 -3
- package/dist/{chunk-XZWSP67B.js → chunk-5APYAXCB.js} +2 -2
- package/dist/{chunk-D65E25JG.js → chunk-67HPYNTJ.js} +2 -2
- package/dist/{chunk-5JQR5B4D.js → chunk-6KV4KCQZ.js} +4 -4
- package/dist/{chunk-V4XJWDHR.js → chunk-6UKFRTXI.js} +2 -1
- package/dist/{chunk-NDPF2N2L.js → chunk-7DW7CJW2.js} +2 -2
- package/dist/{chunk-5KQEUIWM.js → chunk-7LUEQODV.js} +4 -4
- package/dist/{chunk-LNOXCGN2.js → chunk-7UFDIOBT.js} +3 -3
- package/dist/{chunk-DXSETN72.js → chunk-7WUGNN43.js} +2 -2
- package/dist/{chunk-V35KZDUZ.js → chunk-AA3GRZWS.js} +2 -2
- package/dist/{chunk-X4CEFOSG.js → chunk-ADO3OQIC.js} +4 -4
- package/dist/{chunk-UX2L5CUD.js → chunk-AI36V3ON.js} +3 -3
- package/dist/{chunk-B7GY6QER.js → chunk-B26OUMJW.js} +2 -2
- package/dist/{chunk-LAR7DX5E.js → chunk-B5TASTCK.js} +153 -62
- package/dist/{chunk-TGWZXJ7L.js → chunk-BEMQK5Q7.js} +92 -84
- package/dist/{chunk-RNDCROSG.js → chunk-CNXU7TR2.js} +3 -3
- package/dist/{chunk-3JLTRPN7.js → chunk-CVMUXT64.js} +35 -66
- package/dist/{chunk-733ZBT5P.js → chunk-E74MJF6G.js} +4 -4
- package/dist/{chunk-T2MDZES3.js → chunk-EBMTBE76.js} +3 -3
- package/dist/{chunk-OZ76TLGU.js → chunk-EEITU7S6.js} +2 -2
- package/dist/{chunk-GRHOXDKB.js → chunk-ELDJWJKM.js} +97 -14
- package/dist/{chunk-GCQFN7YI.js → chunk-EMYEQLWO.js} +2 -2
- package/dist/{chunk-LTWH2ACR.js → chunk-EQPFEDFV.js} +222 -127
- package/dist/{chunk-TDGYTWM6.js → chunk-F4I3H56H.js} +2 -2
- package/dist/chunk-F6KCJO3U.js +523 -0
- package/dist/{chunk-FGSQHUCK.js → chunk-F6VKWTTY.js} +5 -5
- package/dist/{chunk-UJD5MPP6.js → chunk-FLNXQQ5B.js} +2 -2
- package/dist/{chunk-EX57VVWW.js → chunk-FOSRJ2VZ.js} +4 -4
- package/dist/{chunk-ZARZ4POR.js → chunk-G5ZDQQE3.js} +3 -3
- package/dist/{chunk-HQVN7G4F.js → chunk-G62JBPXN.js} +7 -7
- package/dist/{chunk-ZJPORZTC.js → chunk-GIAI7A2K.js} +2 -2
- package/dist/chunk-GPTR6OTU.js +2551 -0
- package/dist/{chunk-EZD2BXGP.js → chunk-GUFQPTQK.js} +2 -2
- package/dist/{chunk-OPD7GL6F.js → chunk-H6FQVNZC.js} +8 -7
- package/dist/chunk-H7REJ7L5.js +80 -0
- package/dist/{chunk-EYTLV3W3.js → chunk-HTWTORF7.js} +2 -2
- package/dist/{chunk-DF6PI6GN.js → chunk-I6UKQPGS.js} +3 -3
- package/dist/{chunk-ISHUS7HC.js → chunk-JRW236JT.js} +3 -3
- package/dist/{chunk-DE2LU267.js → chunk-KKAJGT3B.js} +3 -2
- package/dist/{chunk-OV62D6KO.js → chunk-KQMYL5GR.js} +3 -3
- package/dist/{chunk-QDUUOZ3S.js → chunk-KWMFC7FN.js} +3 -3
- package/dist/{chunk-R7FGRZNF.js → chunk-LXYHCCIZ.js} +9 -9
- package/dist/{chunk-NFSK2VNU.js → chunk-LZMTVVN4.js} +2 -2
- package/dist/{chunk-62UK7AGW.js → chunk-M5PMRZSR.js} +397 -44
- package/dist/chunk-MMZMM6SW.js +131 -0
- package/dist/{chunk-FFYTC2KQ.js → chunk-MNABNEBX.js} +2 -2
- package/dist/{chunk-XMDBTYCH.js → chunk-N3CWOGVF.js} +3 -3
- package/dist/{chunk-VYRQHORQ.js → chunk-NMQSO6Z6.js} +4 -3
- package/dist/{chunk-R2UUNSNQ.js → chunk-O3ZAF7UY.js} +18 -5
- package/dist/{chunk-4SYHGVDE.js → chunk-OQNCLZI4.js} +4 -4
- package/dist/{chunk-EG4ARXPC.js → chunk-OX6QTA4N.js} +3 -3
- package/dist/{chunk-P4GNZPXO.js → chunk-OYUS3UZP.js} +2 -2
- package/dist/{chunk-OQ2EOAHA.js → chunk-PF36KOGI.js} +291 -112
- package/dist/{chunk-55RMDDFM.js → chunk-PGQG7ZMW.js} +2 -2
- package/dist/{chunk-CBAQPTDU.js → chunk-PIU6BXXW.js} +2 -2
- package/dist/{chunk-EKV4UBCM.js → chunk-PZBQUJ2F.js} +2 -2
- package/dist/{chunk-7RET77VB.js → chunk-Q2HKY32Y.js} +2 -2
- package/dist/{chunk-U6YTUVOX.js → chunk-Q4RMNWMZ.js} +4 -4
- package/dist/chunk-Q6FRR3AQ.js +48 -0
- package/dist/{chunk-6RJMYYIE.js → chunk-QJSIAJBY.js} +3 -3
- package/dist/{chunk-DOUISWEE.js → chunk-QOJ4ERMU.js} +5 -5
- package/dist/{chunk-IFPDAD7R.js → chunk-RWSRKXLT.js} +3 -3
- package/dist/{chunk-T33IYTZM.js → chunk-SAASVMIY.js} +3 -3
- package/dist/{chunk-2DTIWSAW.js → chunk-SEQDH6JC.js} +3 -3
- package/dist/{chunk-BRCOSE7O.js → chunk-SZUO5BSE.js} +2 -2
- package/dist/{chunk-HOEDA42N.js → chunk-T7HZ7KJF.js} +2 -2
- package/dist/{chunk-OJXOA6YU.js → chunk-TL6LNERH.js} +2 -2
- package/dist/{chunk-UCINIRHW.js → chunk-TPCZXWLT.js} +3 -3
- package/dist/{chunk-ZUKUCZYZ.js → chunk-TQ2KTH4A.js} +2 -2
- package/dist/{chunk-4WOOTKFD.js → chunk-U3FETNQB.js} +341 -20
- package/dist/{chunk-5B3RTYAK.js → chunk-UGDSB4AN.js} +2 -2
- package/dist/{chunk-VKHLUZNO.js → chunk-UZ7YBL43.js} +3 -3
- package/dist/{chunk-QNUQ7K7D.js → chunk-VKMSEO7Y.js} +4 -4
- package/dist/{chunk-IN7DGBVS.js → chunk-VLX5VZ35.js} +5 -5
- package/dist/{chunk-SJGS3GDI.js → chunk-WAGBMMNX.js} +5 -5
- package/dist/{chunk-BFOSV5EZ.js → chunk-WX2YCH7F.js} +2 -2
- package/dist/{chunk-3LT34CAM.js → chunk-XBIGUILU.js} +32 -17
- package/dist/{chunk-XDHUDE5K.js → chunk-XKYBFRWR.js} +5 -5
- package/dist/{chunk-U5QU5ZOD.js → chunk-XYPWFSU5.js} +3 -3
- package/dist/{chunk-YBUECLAF.js → chunk-YEJQDODA.js} +2 -2
- package/dist/{chunk-YQ6XEFVK.js → chunk-Z74OGONW.js} +39 -7
- package/dist/{chunk-I4ELN5BX.js → chunk-ZTNOEJRI.js} +2 -2
- package/dist/cli/index.js +26 -26
- package/dist/{clio-K2PBVCEM.js → clio-4IKFE25F.js} +2 -2
- package/dist/{clio-context-tools-GR4OHFSO.js → clio-context-tools-OHJXYX4R.js} +25 -23
- package/dist/{code-nav-4X3OI6DK.js → code-nav-XPM3MY5I.js} +7 -7
- package/dist/{config-Q5J7UBAB.js → config-343YS25T.js} +43 -41
- package/dist/{config-graph-P3555574.js → config-graph-WI263KDX.js} +43 -41
- package/dist/{configure-KIJ32ZO6.js → configure-GZDG4HER.js} +21 -21
- package/dist/{context-LFBQOSXT.js → context-4OFO7N7Y.js} +12 -12
- package/dist/{context-WBH3KSVR.js → context-JLK2RLOG.js} +42 -40
- package/dist/{context-NNLBES2Y.js → context-O6DIWCF6.js} +23 -21
- package/dist/{context-clear-YOHMQ6SQ.js → context-clear-MR7KOGQI.js} +42 -40
- package/dist/{context-working-set-MRAEVDNV.js → context-working-set-YZAD3KWO.js} +14 -13
- package/dist/{data-tool-JJPBGMQJ.js → data-tool-EKD7DFHG.js} +7 -7
- package/dist/{detail-RHJOTGN4.js → detail-YZPHFEVJ.js} +43 -41
- package/dist/{dispatch-runner-NC7PYNIO.js → dispatch-runner-VKVXVTWJ.js} +44 -42
- package/dist/{doctor-S5KZ2GTN.js → doctor-53AVQXAO.js} +17 -16
- package/dist/{doctor-deep-2EJQSHIZ.js → doctor-deep-BLRB2NCG.js} +5 -5
- package/dist/{eval-3D6M36N7.js → eval-P3BQSLQE.js} +21 -20
- package/dist/{evidence-XNVPPLVK.js → evidence-6LLI6SZH.js} +44 -42
- package/dist/{evidence-6IYN52ET.js → evidence-HTN3JLUO.js} +42 -40
- package/dist/{evidence-JVECPI3F.js → evidence-NJRE3R5H.js} +42 -40
- package/dist/{evolve-TLPUDJDM.js → evolve-WWZHJVJP.js} +42 -40
- package/dist/{fleet-WKVBF5SZ.js → fleet-GGZ4BVJE.js} +64 -62
- package/dist/{fleet-6RJWIOEO.js → fleet-QG3IIWWM.js} +44 -42
- package/dist/{fleet-commands-L6WFT7KZ.js → fleet-commands-J2ZIKISQ.js} +7 -7
- package/dist/{fleet-decisions-BTQMWU5A.js → fleet-decisions-Y2Q7375Q.js} +8 -8
- package/dist/{fleet-graph-553DZ67Q.js → fleet-graph-TCBCCCBP.js} +11 -11
- package/dist/{fleet-inspect-236FZPRB.js → fleet-inspect-KOLKBC56.js} +44 -42
- package/dist/{fleet-preflight-NZQHABWO.js → fleet-preflight-44UNCC4Y.js} +27 -25
- package/dist/{fleet-validate-7NLAE26R.js → fleet-validate-K2FXRZVA.js} +13 -13
- package/dist/{fleet-verify-E3RO6A5W.js → fleet-verify-AS444WDW.js} +42 -40
- package/dist/{fleet-view-KMZQY7YJ.js → fleet-view-X4JU4J6O.js} +43 -41
- package/dist/gui/ops-worker.js +9 -9
- package/dist/gui/reads-worker.js +9 -8
- package/dist/{init-DV5B6HQG.js → init-VSOWFHVL.js} +54 -52
- package/dist/{interactive-OXGYZYAS.js → interactive-JRCBENLZ.js} +1733 -577
- package/dist/{interop-J7UOBOSF.js → interop-JR6BCY7R.js} +10 -10
- package/dist/{inventory-OEGIL6PY.js → inventory-3JUGLVJI.js} +43 -41
- package/dist/{library-ROZAMUIL.js → library-7BOH3Y7N.js} +15 -15
- package/dist/{library-B3UPGY4V.js → library-7PFONXUI.js} +9 -9
- package/dist/{library-MXQA5DLT.js → library-TUYZMFIA.js} +7 -7
- package/dist/{library-import-2LTWOVBD.js → library-import-TJVXKLDK.js} +10 -10
- package/dist/{library-inventory-LJ3XHLWO.js → library-inventory-MD3AYTP4.js} +9 -9
- package/dist/{library-validation-DARHHUNW.js → library-validation-ZDLITEA3.js} +7 -7
- package/dist/{mcp-2GSPYQ54.js → mcp-EFCWUPUR.js} +3 -3
- package/dist/{memory-J3STUUIK.js → memory-Q2YVOKK5.js} +42 -40
- package/dist/{models-Y3GMFJ2V.js → models-M7BOCW7F.js} +17 -16
- package/dist/{monitor-LHNH577J.js → monitor-2HD3MC67.js} +47 -45
- package/dist/{orchestrator-DTAPXULA.js → orchestrator-OUW3ZN6Y.js} +1894 -226
- package/dist/{panes-A743ONZ5.js → panes-TTPPSYCL.js} +3 -3
- package/dist/{preload-OJBMAIXF.js → preload-A47C2NUF.js} +42 -40
- package/dist/{providers-CMETPZNS.js → providers-T43W7EL4.js} +4 -4
- package/dist/{resources-FY6XYFN2.js → resources-TP6X2V6W.js} +20 -11
- package/dist/{run-H64MEVTA.js → run-LDSBPMCS.js} +61 -59
- package/dist/{share-CAFMMQLM.js → share-URHKKMHR.js} +9 -9
- package/dist/{skills-ERKQUC7L.js → skills-E477MOOO.js} +13 -11
- package/dist/{skills-eval-CQ23MYQK.js → skills-eval-AIBR2L7H.js} +583 -93
- package/dist/{skills-inventory-TVUYJDVN.js → skills-inventory-HLMKY3R5.js} +13 -11
- package/dist/{slash-commands-ROG3KIFJ.js → slash-commands-LIIZKA5Y.js} +28 -26
- package/dist/{startup-background-KDWCQMWT.js → startup-background-JR2KDK6R.js} +43 -41
- package/dist/{steer-KKYXJSH4.js → steer-D7RTAPCM.js} +3 -3
- package/dist/{system-ZDW44ZGX.js → system-X2P5N4IY.js} +14 -13
- package/dist/{targets-AJWA6E7Z.js → targets-VFFAKUFM.js} +25 -24
- package/dist/{tasks-6L2JJRC5.js → tasks-ERAWZA22.js} +6 -6
- package/dist/{terminal-lease-YFUSDPAD.js → terminal-lease-V2N2BIKQ.js} +2 -2
- package/dist/{trace-LA5MVR4Y.js → trace-MA5BT7XY.js} +3 -3
- package/dist/{usage-XSILDHKF.js → usage-WYFY2L6M.js} +50 -48
- package/dist/{verifiers-ECA5GIHL.js → verifiers-TYIW2XKF.js} +7 -7
- package/dist/{verify-R6QQCCEB.js → verify-242UFYTP.js} +6 -6
- package/dist/{web-fetch-PVZNMBOB.js → web-fetch-LRAGYU6Y.js} +3 -3
- package/dist/{wiki-generate-RP22WP5K.js → wiki-generate-OFKOX2T6.js} +53 -51
- package/dist/worker/entry.js +31 -29
- package/docs/architecture/architecture.md +1 -0
- package/docs/architecture/context-engine.md +4 -2
- package/docs/architecture/observability.md +6 -4
- package/docs/architecture/prompt-envelope-and-tools.md +1 -1
- package/docs/architecture/session-lifecycle.md +1 -1
- package/docs/architecture/tui-design.md +12 -9
- package/docs/gui/parity/02-slash-and-surfaces.md +1 -1
- package/docs/guide/commands-and-modes.md +91 -5
- package/docs/guide/configuration-and-targets.md +2 -2
- package/docs/guide/context-continuity.md +49 -0
- package/docs/guide/proactive-memory.md +6 -3
- package/library/registry.yaml +292 -32
- package/library/skills/README.md +27 -2
- package/library/skills/context/context-handoff/SKILL.md +10 -4
- package/library/skills/meta/clio-coder-dev/SKILL.md +92 -88
- package/library/skills/meta/clio-coder-dev/evals.md +51 -46
- package/library/skills/meta/clio-coder-dev/plugin.json +2 -2
- package/library/skills/meta/clio-coder-dev/references/change-map.md +49 -0
- package/library/skills/meta/clio-coder-test/SKILL.md +89 -142
- package/library/skills/meta/clio-coder-test/evals.md +58 -62
- package/library/skills/meta/clio-coder-test/plugin.json +2 -2
- package/library/skills/meta/clio-coder-test/references/harness.md +3 -3
- package/library/skills/meta/clio-coder-test/references/lifecycle-validation.md +30 -0
- package/library/skills/meta/clio-coder-test/references/test-map.md +60 -89
- package/library/skills/registry.yaml +5 -5
- package/library/skills/skill-marketplace.json +12 -14
- package/package.json +1 -1
- package/src/cli/skills-eval.ts +1064 -54
- package/src/cli/usage.ts +2 -2
- package/src/core/clio-repo.ts +3 -0
- package/src/core/tool-names.ts +1 -0
- package/src/domains/context/budget/inspection.ts +9 -0
- package/src/domains/context/budget/live-view.ts +418 -0
- package/src/domains/context/budget/pressure.ts +393 -0
- package/src/domains/context/budget/request-fit.ts +15 -0
- package/src/domains/evidence/build.ts +24 -0
- package/src/domains/gateway/mcp/client.ts +1 -1
- package/src/domains/memory/commit-state.ts +160 -0
- package/src/domains/memory/operations.ts +18 -10
- package/src/domains/memory/prompt-cache.ts +95 -0
- package/src/domains/memory/prompt-section.ts +50 -7
- package/src/domains/memory/relevance.ts +93 -0
- package/src/domains/memory/restoration.ts +78 -0
- package/src/domains/memory/store.ts +39 -1
- package/src/domains/middleware/memory-intervention.ts +116 -24
- package/src/domains/observability/background-memory-usage.ts +1 -1
- package/src/domains/observability/cost.ts +3 -3
- package/src/domains/observability/extension.ts +1 -1
- package/src/domains/observability/metrics.ts +1 -1
- package/src/domains/prompts/compiler.ts +1 -1
- package/src/domains/prompts/extension.ts +38 -1
- package/src/domains/quota/anthropic-max-provider.ts +134 -0
- package/src/domains/quota/anthropic-usage.ts +220 -0
- package/src/domains/quota/antigravity-provider.ts +339 -0
- package/src/domains/quota/cache.ts +87 -0
- package/src/domains/quota/claude-code-provider.ts +169 -0
- package/src/domains/quota/codex-provider.ts +237 -0
- package/src/domains/quota/presentation.ts +240 -0
- package/src/domains/quota/registry.ts +23 -0
- package/src/domains/quota/service.ts +93 -0
- package/src/domains/quota/summary-feed.ts +86 -0
- package/src/domains/quota/types.ts +84 -0
- package/src/domains/resources/index.ts +11 -0
- package/src/domains/resources/skills/catalog-view.ts +571 -0
- package/src/domains/resources/skills/lexical-match.ts +136 -0
- package/src/domains/resources/skills/loader.ts +38 -0
- package/src/domains/resources/skills/promotion.ts +1 -55
- package/src/domains/resources/skills/provenance-pin.ts +50 -20
- package/src/domains/safety/action-classifier.ts +1 -0
- package/src/domains/session/compaction/branch-summary.ts +4 -1
- package/src/domains/session/compaction/compact.ts +18 -2
- package/src/domains/session/compaction/cut-point.ts +20 -1
- package/src/domains/session/compaction/tokens.ts +48 -3
- package/src/domains/session/context-accounting.ts +8 -1
- package/src/domains/session/continuity/carry.ts +59 -0
- package/src/domains/session/continuity/contract.ts +592 -0
- package/src/domains/session/continuity/evidence.ts +290 -0
- package/src/domains/session/continuity/fold.ts +1075 -0
- package/src/domains/session/continuity/note.ts +79 -0
- package/src/domains/session/continuity/operator-request.ts +104 -0
- package/src/domains/session/continuity/persistence.ts +408 -0
- package/src/domains/session/continuity/ports.ts +231 -0
- package/src/domains/session/continuity/projection.ts +538 -0
- package/src/domains/session/continuity/validate.ts +352 -0
- package/src/domains/session/entries.ts +50 -3
- package/src/domains/session/index.ts +48 -0
- package/src/domains/session/migrations/index.ts +7 -3
- package/src/domains/session/tree/fork.ts +15 -1
- package/src/domains/session/usage.ts +2 -2
- package/src/engine/acp/commands.ts +1 -1
- package/src/engine/agent.ts +133 -9
- package/src/engine/session.ts +13 -6
- package/src/entry/orchestrator.ts +116 -33
- package/src/interactive/chat-loop-messages.ts +2 -2
- package/src/interactive/chat-loop.ts +219 -63
- package/src/interactive/chat-renderer.ts +99 -8
- package/src/interactive/context-overlay.ts +24 -3
- package/src/interactive/continuity-controller.ts +526 -0
- package/src/interactive/dispatch-board.ts +21 -3
- package/src/interactive/footer/dashboard.ts +25 -1
- package/src/interactive/footer/key-hints.ts +2 -2
- package/src/interactive/footer/pages.ts +70 -27
- package/src/interactive/footer/widgets.ts +32 -7
- package/src/interactive/footer-panel.ts +1 -1
- package/src/interactive/interactive-application.ts +7 -2
- package/src/interactive/interactive-input-runtime.ts +2 -2
- package/src/interactive/interactive-presentation.ts +15 -0
- package/src/interactive/interactive-slash-runtime.ts +45 -8
- package/src/interactive/interactive-tickers.ts +7 -1
- package/src/interactive/model-session-replay.ts +130 -3
- package/src/interactive/output-reserve.ts +35 -0
- package/src/interactive/overlay-general-openers.ts +12 -8
- package/src/interactive/overlay-key-routing.ts +6 -9
- package/src/interactive/overlay-lifecycle.ts +10 -6
- package/src/interactive/overlay-session-lifecycle.ts +21 -14
- package/src/interactive/quota-view.ts +229 -0
- package/src/interactive/session-last-turn.ts +1 -1
- package/src/interactive/session-transcript.ts +2 -1
- package/src/interactive/session-usage-reseed.ts +2 -2
- package/src/interactive/side-question.ts +2 -2
- package/src/interactive/slash-commands.ts +28 -9
- package/src/interactive/turn-context.ts +686 -63
- package/src/interactive/turn-middleware.ts +39 -6
- package/src/interactive/turn-persistence.ts +15 -2
- package/src/interactive/turn-prewarm.ts +1 -1
- package/src/interactive/turn-runtime.ts +48 -5
- package/src/interactive/{cost-overlay.ts → usage-overlay.ts} +121 -33
- package/src/interactive/welcome-dashboard.ts +26 -3
- package/src/tools/agent-tools.ts +3 -1
- package/src/tools/bootstrap.ts +6 -0
- package/src/tools/builtin-tool-catalog.ts +9 -0
- package/src/tools/context/index.ts +148 -113
- package/src/tools/context/surface.ts +11 -7
- package/src/tools/core-bootstrap.ts +4 -0
- package/src/tools/observation.ts +8 -2
- package/src/tools/policy.ts +3 -0
- package/src/tools/self-compact.ts +31 -0
- package/src/tools/surface.ts +1 -0
- package/src/tools/tasks.ts +1 -1
- package/dist/chunk-CTFPFW3H.js +0 -44
- package/dist/chunk-EOJPDNUP.js +0 -1325
- package/dist/chunk-I4Y4WKZR.js +0 -386
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { costAggregateForAmount, formatCostAggregate } from "../domains/observability/index.js";
|
|
2
|
+
import {
|
|
3
|
+
foldDuplicateAccounts,
|
|
4
|
+
formatPct,
|
|
5
|
+
primaryWindow,
|
|
6
|
+
type QuotaSeverity,
|
|
7
|
+
severityForPct,
|
|
8
|
+
windowSeverity,
|
|
9
|
+
} from "../domains/quota/presentation.js";
|
|
10
|
+
import type { UsageSnapshot } from "../domains/quota/types.js";
|
|
11
|
+
import { sanitizeCallTargetText } from "../domains/safety/call-target.js";
|
|
12
|
+
import { redactSecretString } from "../domains/safety/redaction.js";
|
|
13
|
+
import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../engine/tui.js";
|
|
14
|
+
import type { DispatchBoardRow } from "./dispatch-board.js";
|
|
15
|
+
import { formatFooterTokens } from "./footer-panel.js";
|
|
16
|
+
import { type ClioToken, clioTheme, formatCompactMs } from "./theme/index.js";
|
|
17
|
+
|
|
18
|
+
const clean = (text: string) => sanitizeCallTargetText(redactSecretString(text));
|
|
19
|
+
const tone = (severity: QuotaSeverity): ClioToken =>
|
|
20
|
+
severity === "critical" ? "error" : severity === "normal" ? "accent" : "warning";
|
|
21
|
+
|
|
22
|
+
/** Filled cells always mean consumed usage, on every surface. */
|
|
23
|
+
export function quotaMeter(usedPct: number, cells: number, severity: QuotaSeverity = severityForPct(usedPct)): string {
|
|
24
|
+
const count = Math.max(1, Math.floor(cells));
|
|
25
|
+
const used = Math.max(0, Math.min(100, Number.isFinite(usedPct) ? usedPct : 0));
|
|
26
|
+
const filled = Math.round((used / 100) * count);
|
|
27
|
+
const theme = clioTheme();
|
|
28
|
+
return theme.fg(tone(severity), "━".repeat(filled)) + theme.fg("frame", "─".repeat(count - filled));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function quotaResetLabel(
|
|
32
|
+
reset: string | null,
|
|
33
|
+
now = Date.now(),
|
|
34
|
+
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
35
|
+
): string {
|
|
36
|
+
const timestamp = reset === null ? NaN : Date.parse(reset);
|
|
37
|
+
if (!Number.isFinite(timestamp)) return "Reset time not reported";
|
|
38
|
+
const absolute = new Intl.DateTimeFormat("en-US", {
|
|
39
|
+
month: "short",
|
|
40
|
+
day: "numeric",
|
|
41
|
+
hour: "numeric",
|
|
42
|
+
minute: "2-digit",
|
|
43
|
+
timeZone,
|
|
44
|
+
}).format(timestamp);
|
|
45
|
+
const minutes = Math.max(0, Math.ceil((timestamp - now) / 60_000));
|
|
46
|
+
const duration =
|
|
47
|
+
minutes >= 1440
|
|
48
|
+
? `${Math.floor(minutes / 1440)}d ${Math.floor((minutes % 1440) / 60)}h`
|
|
49
|
+
: minutes >= 60
|
|
50
|
+
? `${Math.floor(minutes / 60)}h ${minutes % 60}m`
|
|
51
|
+
: `${minutes}m`;
|
|
52
|
+
return minutes === 0
|
|
53
|
+
? `Reset time passed · awaiting provider update (${absolute} · ${timeZone})`
|
|
54
|
+
: `Resets in ${duration} · ${absolute} (${timeZone})`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Account-wide facts only: never infer a worker's share from changing percentages. */
|
|
58
|
+
export function renderQuotaAccounts(
|
|
59
|
+
snapshots: ReadonlyArray<UsageSnapshot>,
|
|
60
|
+
width: number,
|
|
61
|
+
options: { compact?: boolean; now?: number; timeZone?: string } = {},
|
|
62
|
+
): string[] {
|
|
63
|
+
const theme = clioTheme();
|
|
64
|
+
const now = options.now ?? Date.now();
|
|
65
|
+
const accounts = foldDuplicateAccounts(snapshots).filter((account) => account.status !== "no_credentials");
|
|
66
|
+
if (!accounts.length) return [theme.fg("dim", "Subscriptions · loading")];
|
|
67
|
+
const out: string[] = [];
|
|
68
|
+
for (const account of accounts) {
|
|
69
|
+
const title = clean(`${account.displayName}${account.plan ? ` (${account.plan})` : ""}`);
|
|
70
|
+
const age =
|
|
71
|
+
account.fetchedAt === null ? null : Math.max(0, Math.floor((now - Date.parse(account.fetchedAt)) / 60_000));
|
|
72
|
+
const freshness = account.stale
|
|
73
|
+
? "STALE · last good reading"
|
|
74
|
+
: age === null || !Number.isFinite(age)
|
|
75
|
+
? ""
|
|
76
|
+
: age === 0
|
|
77
|
+
? "updated just now"
|
|
78
|
+
: `updated ${age}m ago`;
|
|
79
|
+
if (options.compact) {
|
|
80
|
+
const window = primaryWindow(account);
|
|
81
|
+
const ordered =
|
|
82
|
+
window && ["warning", "critical"].includes(windowSeverity(window))
|
|
83
|
+
? [window, ...account.windows.filter((item) => item !== window)]
|
|
84
|
+
: account.windows;
|
|
85
|
+
const windows = ordered
|
|
86
|
+
.map(
|
|
87
|
+
(item) =>
|
|
88
|
+
`${item.scope && item.scope !== item.label ? `${item.scope} ` : ""}${item.label} ${formatPct(item.usedPct)} used`,
|
|
89
|
+
)
|
|
90
|
+
.join(" · ");
|
|
91
|
+
const detail =
|
|
92
|
+
account.status !== "ok"
|
|
93
|
+
? (account.message ?? account.status)
|
|
94
|
+
: account.providerId === "local"
|
|
95
|
+
? "$0.00 · no subscription window consumed"
|
|
96
|
+
: windows || account.credits?.display || "no windows reported";
|
|
97
|
+
const meter = window && width >= 65 ? `${quotaMeter(window.usedPct, 8, windowSeverity(window))} ` : "";
|
|
98
|
+
out.push(
|
|
99
|
+
truncateToWidth(
|
|
100
|
+
`${meter}${theme.fg(account.status !== "ok" || account.stale ? "warning" : "muted", `${account.stale ? "STALE · " : ""}${title}`)} ${clean(detail)}`,
|
|
101
|
+
width,
|
|
102
|
+
"…",
|
|
103
|
+
true,
|
|
104
|
+
),
|
|
105
|
+
);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (out.length) out.push("");
|
|
109
|
+
out.push(theme.style("accent", title, { bold: true }));
|
|
110
|
+
if (freshness) out.push(theme.fg(account.stale ? "warning" : "dim", freshness));
|
|
111
|
+
if (account.status !== "ok")
|
|
112
|
+
out.push(theme.fg("warning", clean(`${account.status} · ${account.message ?? "usage unavailable"}`)));
|
|
113
|
+
let scope: string | undefined;
|
|
114
|
+
for (const window of account.windows) {
|
|
115
|
+
if (window.scope && scope !== window.scope) {
|
|
116
|
+
scope = window.scope;
|
|
117
|
+
out.push(theme.style("muted", clean(scope), { bold: true }));
|
|
118
|
+
}
|
|
119
|
+
const label = `${window.key.startsWith("weekly_scoped.") ? "Weekly" : window.label} · ${formatPct(window.usedPct)} used · ${formatPct(Math.max(0, 100 - window.usedPct))} remaining${window.active ? " · active limit" : ""}`;
|
|
120
|
+
out.push(clean(label));
|
|
121
|
+
out.push(quotaMeter(window.usedPct, Math.max(1, Math.min(48, width)), windowSeverity(window)));
|
|
122
|
+
out.push(theme.fg("dim", quotaResetLabel(window.resetsAt, now, options.timeZone)));
|
|
123
|
+
}
|
|
124
|
+
if (account.credits) {
|
|
125
|
+
out.push(
|
|
126
|
+
clean(
|
|
127
|
+
`${account.providerId === "local" ? "Local inference" : "Usage credits"} · ${account.credits.display}${account.credits.usedPct === null ? "" : ` · ${formatPct(account.credits.usedPct)} used`}`,
|
|
128
|
+
),
|
|
129
|
+
);
|
|
130
|
+
if (account.credits.usedPct !== null) out.push(quotaMeter(account.credits.usedPct, Math.min(48, width)));
|
|
131
|
+
}
|
|
132
|
+
if (account.status === "ok" && account.message)
|
|
133
|
+
out.push(theme.fg(account.stale ? "warning" : "dim", clean(account.message)));
|
|
134
|
+
if (account.status === "ok" && !account.windows.length && !account.credits && !account.message)
|
|
135
|
+
out.push(theme.fg("dim", "Connected · no usage windows reported"));
|
|
136
|
+
if (account.retryAfterSeconds != null) out.push(theme.fg("warning", `Retry after ${account.retryAfterSeconds}s`));
|
|
137
|
+
}
|
|
138
|
+
return out.flatMap((line) => (visibleWidth(line) > width ? wrapTextWithAnsi(line, Math.max(1, width)) : [line]));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** The route must share the credential owner read by the quota adapter. */
|
|
142
|
+
function routeAccount(
|
|
143
|
+
route: Pick<DispatchBoardRow, "runtimeId" | "node">,
|
|
144
|
+
snapshots: ReadonlyArray<UsageSnapshot>,
|
|
145
|
+
): UsageSnapshot | undefined {
|
|
146
|
+
if (route.node && route.node !== "local") return undefined;
|
|
147
|
+
const provider = (
|
|
148
|
+
{
|
|
149
|
+
"claude-code": "claude-code",
|
|
150
|
+
"claude-sdk": "claude-code",
|
|
151
|
+
"anthropic-max": "anthropic-max",
|
|
152
|
+
"antigravity-code": "antigravity",
|
|
153
|
+
} as Record<string, string>
|
|
154
|
+
)[route.runtimeId];
|
|
155
|
+
// Clio's openai-codex OAuth storage is independent of Codex CLI auth.json.
|
|
156
|
+
return snapshots.find((item) => item.providerId === provider);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A weekly badge only when both the account and model group are known. */
|
|
160
|
+
export function routeWeeklyQuota(
|
|
161
|
+
route: Pick<DispatchBoardRow, "runtimeId" | "wireModelId" | "node">,
|
|
162
|
+
snapshots: ReadonlyArray<UsageSnapshot>,
|
|
163
|
+
): { label: string; account: string; severity: QuotaSeverity } | null {
|
|
164
|
+
const account = routeAccount(route, snapshots);
|
|
165
|
+
if (account?.status !== "ok") return null;
|
|
166
|
+
const weekly = account.windows.filter((window) => window.key === "weekly" || window.key.endsWith(".weekly"));
|
|
167
|
+
const model = route.wireModelId.toLowerCase();
|
|
168
|
+
const matches =
|
|
169
|
+
account.providerId === "antigravity"
|
|
170
|
+
? weekly.filter((window) => {
|
|
171
|
+
const scope = window.scope?.toLowerCase() ?? "";
|
|
172
|
+
if (model.includes("gemini")) return scope.includes("gemini");
|
|
173
|
+
if (/claude|opus|sonnet|haiku/.test(model)) return scope.includes("claude");
|
|
174
|
+
if (model.includes("gpt")) return scope.includes("gpt");
|
|
175
|
+
return false;
|
|
176
|
+
})
|
|
177
|
+
: weekly.filter((window) => !window.scope);
|
|
178
|
+
if (matches.length !== 1) return null;
|
|
179
|
+
const window = matches[0];
|
|
180
|
+
if (!window) return null;
|
|
181
|
+
return {
|
|
182
|
+
label: `${account.stale ? "STALE · " : ""}weekly ${formatPct(Math.max(0, Math.min(100, 100 - window.usedPct)))} left`,
|
|
183
|
+
account: account.displayName,
|
|
184
|
+
severity: windowSeverity(window),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function workerQuotaLabel(
|
|
189
|
+
row: Pick<DispatchBoardRow, "runtimeId" | "node">,
|
|
190
|
+
snapshots: ReadonlyArray<UsageSnapshot>,
|
|
191
|
+
): string {
|
|
192
|
+
// Remote workers and generic transports may use different credentials. Only
|
|
193
|
+
// known local credential owners can be associated with this process's reads.
|
|
194
|
+
if (row.node && row.node !== "local") return "Account quota unavailable for remote credentials";
|
|
195
|
+
const account = routeAccount(row, snapshots);
|
|
196
|
+
if (!account) return "Account quota not linked to this runtime";
|
|
197
|
+
if (account.status !== "ok") return `${account.displayName} · ${account.message ?? account.status}`;
|
|
198
|
+
return `Shared ${account.displayName}${account.stale ? " · STALE" : ""} · ${account.windows.map((window) => `${window.scope && window.scope !== window.label ? `${window.scope} ` : ""}${window.label} ${formatPct(Math.max(0, 100 - window.usedPct))} left`).join(" · ") || "no windows reported"}`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function renderWorkerUsage(
|
|
202
|
+
rows: ReadonlyArray<DispatchBoardRow>,
|
|
203
|
+
snapshots: ReadonlyArray<UsageSnapshot>,
|
|
204
|
+
width: number,
|
|
205
|
+
): string[] {
|
|
206
|
+
const theme = clioTheme();
|
|
207
|
+
const out = [theme.fg("dim", "Active and recent workers · recorded tokens and cost · account limits are shared.")];
|
|
208
|
+
if (!rows.length) out.push("", "No worker invocations recorded.");
|
|
209
|
+
for (const row of rows) {
|
|
210
|
+
const cost = formatCostAggregate(costAggregateForAmount(row.costUsd, row.costProvenance)) ?? "cost not reported";
|
|
211
|
+
out.push(
|
|
212
|
+
"",
|
|
213
|
+
theme.style("agent", clean(`${row.agentId} · ${row.status} · ${formatCompactMs(row.elapsedMs)}`), { bold: true }),
|
|
214
|
+
);
|
|
215
|
+
out.push(clean(`${row.targetId} / ${row.wireModelId}${row.node ? ` · ${row.node}` : ""}`));
|
|
216
|
+
out.push(
|
|
217
|
+
row.tokenCount > 0 || row.inputTokens > 0 || row.outputTokens > 0 || row.progress?.inputTokens !== undefined
|
|
218
|
+
? `${formatFooterTokens(row.tokenCount)} recorded tokens · input ${formatFooterTokens(row.inputTokens)} · output ${formatFooterTokens(row.outputTokens)} · ${cost}`
|
|
219
|
+
: `Token usage not reported · ${cost}`,
|
|
220
|
+
);
|
|
221
|
+
if (row.lastContextTokens !== undefined)
|
|
222
|
+
out.push(
|
|
223
|
+
`Context ${formatFooterTokens(row.lastContextTokens)}${row.contextWindow ? ` / ${formatFooterTokens(row.contextWindow)}` : ""}`,
|
|
224
|
+
);
|
|
225
|
+
out.push(theme.fg("muted", clean(workerQuotaLabel(row, snapshots))));
|
|
226
|
+
out.push(theme.fg("dim", clean(`/view dispatch:${row.runId}`)));
|
|
227
|
+
}
|
|
228
|
+
return out.flatMap((line) => wrapTextWithAnsi(line, Math.max(1, width)));
|
|
229
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The line is a live accumulator: it describes whatever turn this process last
|
|
5
5
|
* ran. current.jsonl is append-only, so after a `/tree` switch that turn can sit
|
|
6
6
|
* on a branch the reader just left, and the line kept describing it while the Σ
|
|
7
|
-
* total and `/
|
|
7
|
+
* total and `/usage` beside it had already been rescoped by the usage reseed. One
|
|
8
8
|
* footer, two branches, no way to tell which line belonged to which.
|
|
9
9
|
*
|
|
10
10
|
* The fold reads the same lineage the reseed does, through
|
|
@@ -3,7 +3,7 @@ import { collectSessionEntries } from "../domains/session/compaction/session-ent
|
|
|
3
3
|
import type { SessionContract, SessionEntry } from "../domains/session/index.js";
|
|
4
4
|
import { openSession, sessionPaths } from "../engine/session.js";
|
|
5
5
|
import type { ChatLoop } from "./chat-loop.js";
|
|
6
|
-
import { buildModelReplayAgentMessagesFromTurns } from "./model-session-replay.js";
|
|
6
|
+
import { buildModelReplayAgentMessagesFromTurns, continuityContextFromSession } from "./model-session-replay.js";
|
|
7
7
|
|
|
8
8
|
type SessionOwner = Pick<SessionContract, "create" | "current">;
|
|
9
9
|
type SessionChat = Pick<ChatLoop, "resetForSession">;
|
|
@@ -89,6 +89,7 @@ export function createSessionTranscript(deps: SessionTranscriptDeps): SessionTra
|
|
|
89
89
|
leafTurnId,
|
|
90
90
|
buildModelReplayAgentMessagesFromTurns(turns, {
|
|
91
91
|
...(leafTurnId ? { activeLeafTurnId: leafTurnId } : {}),
|
|
92
|
+
continuity: continuityContextFromSession(deps.session),
|
|
92
93
|
}),
|
|
93
94
|
);
|
|
94
95
|
deps.refreshStatus();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rebuild the running usage totals from a session's own ledger.
|
|
3
3
|
*
|
|
4
|
-
* The `/
|
|
4
|
+
* The `/usage` overlay and the footer both render one process-lifetime
|
|
5
5
|
* accumulator, and only `startNewSession` ever reset it. Resuming did not, so a
|
|
6
6
|
* resumed session showed the *previous* session's numbers under the resumed
|
|
7
7
|
* session's id: one process, two sessions, byte-identical totals relabelled.
|
|
@@ -56,7 +56,7 @@ export interface SessionUsageSink {
|
|
|
56
56
|
* `activeLeafTurnId` scopes the fold to one branch, through the same
|
|
57
57
|
* `filterEntriesToActivePath` the transcript replays through. current.jsonl is
|
|
58
58
|
* append-only, so after a `/tree` switch the abandoned sibling turns are still
|
|
59
|
-
* in the file: the transcript stopped showing them and `/
|
|
59
|
+
* in the file: the transcript stopped showing them and `/usage` and the footer Σ
|
|
60
60
|
* kept counting them, which put a session total on screen for turns the reader
|
|
61
61
|
* had just been told were not on this branch. Omitted, the fold follows the
|
|
62
62
|
* newest message's ancestry, the same fallback an offline read of the transcript
|
|
@@ -100,7 +100,7 @@ function positive(value: unknown): number {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Normalize one provider usage object into the shape `/
|
|
103
|
+
* Normalize one provider usage object into the shape `/usage` and the
|
|
104
104
|
* out-of-turn usage store take. Shared with the session pre-warm, which is
|
|
105
105
|
* another call billed beside the session rather than inside it.
|
|
106
106
|
*/
|
|
@@ -144,7 +144,7 @@ function textFromMessage(message: unknown): string {
|
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
* Run the side-question round. Resolves with the answer, the provider usage
|
|
147
|
-
* (which is still real money and is reported to `/
|
|
147
|
+
* (which is still real money and is reported to `/usage`), and whether the
|
|
148
148
|
* operator aborted it. Provider failures reject; the caller renders the reason
|
|
149
149
|
* in the overlay.
|
|
150
150
|
*/
|
|
@@ -144,6 +144,7 @@ type SlashCommandVariant =
|
|
|
144
144
|
| { kind: "context-refresh" }
|
|
145
145
|
/** `ref` is the turnId an `[evicted ...]` marker names. */
|
|
146
146
|
| { kind: "context-recall"; ref: string }
|
|
147
|
+
| { kind: "context-recover"; handoffId: string; action: "reduce" | "deliver" }
|
|
147
148
|
| {
|
|
148
149
|
kind: "resources";
|
|
149
150
|
family?: "extensions" | "plugins";
|
|
@@ -183,7 +184,7 @@ type SlashCommandVariant =
|
|
|
183
184
|
| { kind: "fleet-run-usage"; reason?: string }
|
|
184
185
|
| { kind: "fleet" }
|
|
185
186
|
| { kind: "agents"; connect?: boolean }
|
|
186
|
-
| { kind: "
|
|
187
|
+
| { kind: "usage" }
|
|
187
188
|
| { kind: "context-view" }
|
|
188
189
|
| { kind: "tasks" }
|
|
189
190
|
| { kind: "decisions" }
|
|
@@ -706,7 +707,7 @@ export interface SlashCommandContext {
|
|
|
706
707
|
}>;
|
|
707
708
|
exportShareArchive?: (outPath: string) => { fileCount: number; path: string };
|
|
708
709
|
importShareArchive?: (path: string, options: { dryRun?: boolean; force?: boolean }) => ShareImportPlan;
|
|
709
|
-
|
|
710
|
+
openUsage: () => void;
|
|
710
711
|
/**
|
|
711
712
|
* `/doctor [deep]`: the CLI doctor's findings, rendered as one notice.
|
|
712
713
|
* `deep` adds the live tool probe on the session's targets and the
|
|
@@ -823,6 +824,7 @@ export interface SlashCommandContext {
|
|
|
823
824
|
* appends a compactionSummary entry. No-op when no session is open, so the
|
|
824
825
|
* handler prints an actionable stderr line instead.
|
|
825
826
|
*/
|
|
827
|
+
runHandoffRecovery?: (handoffId: string, action: "reduce" | "deliver") => void;
|
|
826
828
|
runCompact: (instructions: string | undefined) => void;
|
|
827
829
|
/**
|
|
828
830
|
* Escape hatch for the `view verify` entry: verify a receipt file on disk
|
|
@@ -1686,23 +1688,24 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1686
1688
|
},
|
|
1687
1689
|
},
|
|
1688
1690
|
{
|
|
1689
|
-
name: "
|
|
1690
|
-
description: "Show session token and cost totals",
|
|
1691
|
+
name: "usage",
|
|
1692
|
+
description: "Show subscription quota, credits, and session token and cost totals",
|
|
1691
1693
|
group: "Inspect",
|
|
1692
|
-
kinds: ["
|
|
1694
|
+
kinds: ["usage"],
|
|
1693
1695
|
args: {},
|
|
1694
|
-
fromArgs: fromArgsOrUsage("
|
|
1696
|
+
fromArgs: fromArgsOrUsage("usage", { kind: "usage" }),
|
|
1695
1697
|
handle(_command, ctx) {
|
|
1696
|
-
ctx.
|
|
1698
|
+
ctx.openUsage();
|
|
1697
1699
|
},
|
|
1698
1700
|
},
|
|
1699
1701
|
{
|
|
1700
1702
|
name: "context",
|
|
1701
1703
|
description: "Context hub: window overlay plus compact, recall, init, refresh, and reset",
|
|
1702
1704
|
group: "Inspect",
|
|
1703
|
-
kinds: ["context-view", "compact", "context-recall", "init", "context-clear", "context-refresh"],
|
|
1705
|
+
kinds: ["context-view", "compact", "context-recover", "context-recall", "init", "context-clear", "context-refresh"],
|
|
1704
1706
|
subcommandDescriptions: {
|
|
1705
1707
|
compact: "Compact session context",
|
|
1708
|
+
recover: "Recover a paused handoff: ID reduce|deliver",
|
|
1706
1709
|
recall: "Recall an evicted result",
|
|
1707
1710
|
init: "Initialize project context",
|
|
1708
1711
|
refresh: "Refresh project context",
|
|
@@ -1711,6 +1714,12 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1711
1714
|
args: {
|
|
1712
1715
|
subcommands: {
|
|
1713
1716
|
compact: { positionals: [...COMPACT_POSITIONALS] },
|
|
1717
|
+
recover: {
|
|
1718
|
+
positionals: [
|
|
1719
|
+
{ name: "handoffId", required: true },
|
|
1720
|
+
{ name: "action", required: true },
|
|
1721
|
+
],
|
|
1722
|
+
},
|
|
1714
1723
|
recall: { positionals: [...RECALL_POSITIONALS] },
|
|
1715
1724
|
init: {
|
|
1716
1725
|
flags: CONTEXT_INIT_FLAG_TABLE.flatMap(({ flag, aliases = [] }) => [flag, ...aliases].map((name) => ({ name }))),
|
|
@@ -1724,6 +1733,12 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1724
1733
|
switch (parsed.subcommand) {
|
|
1725
1734
|
case "compact":
|
|
1726
1735
|
return { kind: "compact", instructions: parsed.rest };
|
|
1736
|
+
case "recover": {
|
|
1737
|
+
const [handoffId, action] = parsed.positionals;
|
|
1738
|
+
return handoffId && (action === "reduce" || action === "deliver")
|
|
1739
|
+
? { kind: "context-recover", handoffId, action }
|
|
1740
|
+
: { kind: "usage-error", command: "context", reason: "Use /context recover <handoffId> <reduce|deliver>" };
|
|
1741
|
+
}
|
|
1727
1742
|
case "recall":
|
|
1728
1743
|
return { kind: "context-recall", ref: parsed.positionals[0] ?? "" };
|
|
1729
1744
|
case "init": {
|
|
@@ -1752,6 +1767,10 @@ export const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [
|
|
|
1752
1767
|
case "compact":
|
|
1753
1768
|
ctx.runCompact(command.instructions);
|
|
1754
1769
|
return;
|
|
1770
|
+
case "context-recover":
|
|
1771
|
+
if (ctx.runHandoffRecovery) ctx.runHandoffRecovery(command.handoffId, command.action);
|
|
1772
|
+
else ctx.notice("error", "native handoff recovery is unavailable");
|
|
1773
|
+
return;
|
|
1755
1774
|
case "context-recall":
|
|
1756
1775
|
if (ctx.runContextRecall) {
|
|
1757
1776
|
ctx.runContextRecall(command.ref);
|
|
@@ -2648,7 +2667,7 @@ const COMMAND_ORDER = [
|
|
|
2648
2667
|
"memory",
|
|
2649
2668
|
"view",
|
|
2650
2669
|
"panes",
|
|
2651
|
-
"
|
|
2670
|
+
"usage",
|
|
2652
2671
|
"doctor",
|
|
2653
2672
|
"decisions",
|
|
2654
2673
|
"library",
|