@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UsageSnapshot } from "../domains/quota/types.js";
|
|
1
2
|
import { type TaskBoardSnapshot, type TaskBoardStore, taskBoardCounts } from "../domains/session/task-board.js";
|
|
2
3
|
import { Text, type TUI, visibleWidth, wrapTextWithAnsi } from "../engine/tui.js";
|
|
3
4
|
import {
|
|
@@ -28,6 +29,7 @@ export interface InteractiveTickersDeps {
|
|
|
28
29
|
dispatchBoardStore: InteractiveDispatchStore;
|
|
29
30
|
contextActivityStore: InteractiveContextActivityStore;
|
|
30
31
|
getOverlayState: () => string;
|
|
32
|
+
getQuotaSnapshots?: () => ReadonlyArray<UsageSnapshot>;
|
|
31
33
|
isFooterExpanded: () => boolean;
|
|
32
34
|
/** Bound to TaskBoardStore.cachedSnapshot; repaint must never fold the session ledger. */
|
|
33
35
|
getTaskBoard?: TaskBoardStore["cachedSnapshot"];
|
|
@@ -126,7 +128,11 @@ export function createInteractiveTickers(deps: InteractiveTickersDeps): Interact
|
|
|
126
128
|
taskIslandHidden = hidden;
|
|
127
129
|
if (rows.length > 0)
|
|
128
130
|
taskIsland.setText(
|
|
129
|
-
formatTaskIslandLines(
|
|
131
|
+
formatTaskIslandLines(
|
|
132
|
+
rows,
|
|
133
|
+
Math.max(1, Math.min(4, Math.floor((taskIslandHeight - 8) / 10))),
|
|
134
|
+
deps.getQuotaSnapshots?.() ?? [],
|
|
135
|
+
).join("\n"),
|
|
130
136
|
);
|
|
131
137
|
else if (board) taskIsland.setText(formatTaskBoardIslandLines(board).join("\n"));
|
|
132
138
|
taskIsland.invalidate();
|
|
@@ -1,8 +1,123 @@
|
|
|
1
1
|
import { foldWorkingSet } from "../domains/context/working-set/fold.js";
|
|
2
2
|
import { projectWorkingSet } from "../domains/context/working-set/project.js";
|
|
3
|
+
import {
|
|
4
|
+
type ContinuityForkBinding,
|
|
5
|
+
type ContinuityProjection,
|
|
6
|
+
continuityReplayBlocks,
|
|
7
|
+
resolveContinuityProjection,
|
|
8
|
+
} from "../domains/session/continuity/projection.js";
|
|
9
|
+
import type { SessionContract } from "../domains/session/contract.js";
|
|
3
10
|
import type { SessionEntry } from "../domains/session/entries.js";
|
|
4
11
|
import type { AgentMessage } from "../engine/types.js";
|
|
5
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
activeEntriesBeforeCompactionCut,
|
|
14
|
+
buildReplayAgentMessagesFromTurns,
|
|
15
|
+
type RehydrateChatPanelOptions,
|
|
16
|
+
} from "./chat-renderer.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The session-ownership facts continuity needs, which a renderer does not have.
|
|
20
|
+
*
|
|
21
|
+
* Supplying this is what separates a fork's own transactions from the ones it
|
|
22
|
+
* inherited. Without it a reader owns nothing: inherited recall still projects,
|
|
23
|
+
* because losing the note is the one outcome that is never safe, but no
|
|
24
|
+
* transaction can reach execution authority.
|
|
25
|
+
*/
|
|
26
|
+
export interface ContinuityReplayContext {
|
|
27
|
+
/** The opened session's actual id, from `session.current()`. */
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
/** `meta.parentSessionId` / `meta.parentTurnId`, when this session is a fork. */
|
|
30
|
+
fork?: ContinuityForkBinding;
|
|
31
|
+
/**
|
|
32
|
+
* True only for a genuine historical cut of this session's own transactions.
|
|
33
|
+
* A live `/tree` selection is not one, even though the renderer passes
|
|
34
|
+
* `uptoTurnId` for both.
|
|
35
|
+
*/
|
|
36
|
+
historical?: boolean;
|
|
37
|
+
/** Parse failures the reader counted, so a torn record cannot become permission. */
|
|
38
|
+
unreadableRecords?: number;
|
|
39
|
+
nowMs?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ModelReplayOptions extends RehydrateChatPanelOptions {
|
|
43
|
+
continuity?: ContinuityReplayContext;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Derive replay ownership from the open session.
|
|
48
|
+
*
|
|
49
|
+
* `meta.parentSessionId` and `meta.parentTurnId` are what `enrichForkMeta`
|
|
50
|
+
* stamps on a child, and together they are the fork binding. The header's
|
|
51
|
+
* `parentSession` is a path to the parent's ledger, a different fact, and is
|
|
52
|
+
* deliberately not used as a session id. A session with no fork pointers
|
|
53
|
+
* publishes no binding, so a foreign-origin record in a session that never
|
|
54
|
+
* forked stays unprojected instead of being read as inheritance.
|
|
55
|
+
*
|
|
56
|
+
* `historical` is never set here. A replay is historical only when a caller
|
|
57
|
+
* standing at a past turn says so; deriving it from the renderer's `uptoTurnId`
|
|
58
|
+
* would make an ordinary `/tree` selection permanently surrender this session's
|
|
59
|
+
* ownership of its own transactions.
|
|
60
|
+
*/
|
|
61
|
+
export function continuityContextFromSession(
|
|
62
|
+
/** Narrowed to the one method this needs, so partial session owners qualify. */
|
|
63
|
+
session: Pick<SessionContract, "current"> | undefined,
|
|
64
|
+
): ContinuityReplayContext {
|
|
65
|
+
const meta = session?.current();
|
|
66
|
+
if (!meta) return {};
|
|
67
|
+
const parentSessionId = meta.parentSessionId ?? null;
|
|
68
|
+
const parentTurnId = meta.parentTurnId ?? null;
|
|
69
|
+
return {
|
|
70
|
+
sessionId: meta.id,
|
|
71
|
+
...(parentSessionId !== null && parentTurnId !== null ? { fork: { parentSessionId, parentTurnId } } : {}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the continuity projection for a replay.
|
|
77
|
+
*
|
|
78
|
+
* Folded over the active path **before** the compaction cut and before the
|
|
79
|
+
* working-set projection, because both of those remove records the fold needs:
|
|
80
|
+
* a commit, a pause or an operator control request older than the cut is still
|
|
81
|
+
* the evidence for the state the note describes. `withContinuityReplay` is the
|
|
82
|
+
* exported entry point, so the transcript and the model always render blocks
|
|
83
|
+
* from one resolution rather than two.
|
|
84
|
+
*/
|
|
85
|
+
function resolveReplayContinuity(
|
|
86
|
+
entries: ReadonlyArray<SessionEntry>,
|
|
87
|
+
options: ModelReplayOptions = {},
|
|
88
|
+
): ContinuityProjection {
|
|
89
|
+
const context = options.continuity ?? {};
|
|
90
|
+
return resolveContinuityProjection({
|
|
91
|
+
// The positional cut applies only to a real historical selection. A live
|
|
92
|
+
// /tree switch passes `uptoTurnId` for display and must still see the
|
|
93
|
+
// sidecars anchored after the selected message, because they are part of
|
|
94
|
+
// its own branch's current state.
|
|
95
|
+
entries: activeEntriesBeforeCompactionCut(entries, options, context.historical === true),
|
|
96
|
+
...(context.sessionId === undefined ? {} : { sessionId: context.sessionId }),
|
|
97
|
+
...(context.fork === undefined ? {} : { fork: context.fork }),
|
|
98
|
+
...(context.historical === undefined ? {} : { historical: context.historical }),
|
|
99
|
+
...(context.unreadableRecords === undefined ? {} : { unreadableRecords: context.unreadableRecords }),
|
|
100
|
+
...(context.nowMs === undefined ? {} : { nowMs: context.nowMs }),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Resolve continuity once and hand the same finished blocks to both surfaces.
|
|
106
|
+
*
|
|
107
|
+
* The transcript and the model must show byte-identical note text, so the
|
|
108
|
+
* projection is resolved here and the rendered blocks travel on the options
|
|
109
|
+
* object that `rehydrateChatPanelFromTurns` and
|
|
110
|
+
* `buildModelReplayAgentMessagesFromTurns` both receive. Resolving it twice
|
|
111
|
+
* would be two chances to disagree.
|
|
112
|
+
*/
|
|
113
|
+
export function withContinuityReplay(
|
|
114
|
+
turns: ReadonlyArray<SessionEntry>,
|
|
115
|
+
options: RehydrateChatPanelOptions,
|
|
116
|
+
session: Pick<SessionContract, "current"> | undefined,
|
|
117
|
+
): ModelReplayOptions {
|
|
118
|
+
const merged: ModelReplayOptions = { ...options, continuity: continuityContextFromSession(session) };
|
|
119
|
+
return { ...merged, continuityBlocks: continuityReplayBlocks(resolveReplayContinuity(turns, merged)) };
|
|
120
|
+
}
|
|
6
121
|
|
|
7
122
|
/**
|
|
8
123
|
* Build provider-facing replay messages from the durable session ledger.
|
|
@@ -10,12 +125,24 @@ import { buildReplayAgentMessagesFromTurns, type RehydrateChatPanelOptions } fro
|
|
|
10
125
|
* setting gates creation of new evictions, not replay of durable state.
|
|
11
126
|
* Visible transcript and export callers intentionally keep using the raw
|
|
12
127
|
* rehydration helpers so eviction remains a model projection, not data loss.
|
|
128
|
+
*
|
|
129
|
+
* Continuity is resolved first, from the complete pre-cut ledger, so the
|
|
130
|
+
* accepted note survives both the working-set projection and the compaction
|
|
131
|
+
* cut. It is carried as labelled data and never becomes a synthetic operator
|
|
132
|
+
* instruction.
|
|
13
133
|
*/
|
|
14
134
|
export function buildModelReplayAgentMessagesFromTurns(
|
|
15
135
|
entries: ReadonlyArray<SessionEntry>,
|
|
16
|
-
options:
|
|
136
|
+
options: ModelReplayOptions = {},
|
|
17
137
|
): AgentMessage[] {
|
|
18
138
|
const activeLeafTurnId = options.activeLeafTurnId ?? options.uptoTurnId;
|
|
139
|
+
// A caller that already resolved the projection passes its blocks through,
|
|
140
|
+
// so the transcript beside this replay renders the identical bytes.
|
|
141
|
+
const blocks = options.continuityBlocks ?? continuityReplayBlocks(resolveReplayContinuity(entries, options));
|
|
19
142
|
const projected = projectWorkingSet(entries, foldWorkingSet(entries, activeLeafTurnId), activeLeafTurnId);
|
|
20
|
-
return buildReplayAgentMessagesFromTurns(projected, {
|
|
143
|
+
return buildReplayAgentMessagesFromTurns(projected, {
|
|
144
|
+
...options,
|
|
145
|
+
skillContextEntries: entries,
|
|
146
|
+
continuityBlocks: blocks,
|
|
147
|
+
});
|
|
21
148
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one preflight output reservation a turn asks for.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the submit guard in `chat-loop.ts` so the guard and the live
|
|
5
|
+
* budget view quote the same number instead of growing a second formula. It
|
|
6
|
+
* resolves through `resolveReservedOutputTokens`, which applies the configured
|
|
7
|
+
* output budget, the model's advertised cap, and the remaining-context clamp
|
|
8
|
+
* the `openai-completions` and `ollama-native` transports already perform on
|
|
9
|
+
* the wire. The capability-resolved cap is the input, because that is what the
|
|
10
|
+
* runtime resolution decided this target may actually be asked for.
|
|
11
|
+
*
|
|
12
|
+
* This is a preflight reservation, not a guarantee of the final wire ceiling:
|
|
13
|
+
* `remainingContextMaxTokens` re-derives the ceiling at request time against
|
|
14
|
+
* the context the transport is about to send.
|
|
15
|
+
*
|
|
16
|
+
* It is not the compaction-threshold reserve. `ContextSnapshot.categories.reserve`
|
|
17
|
+
* is window headroom held back so auto-compaction fires before a request is
|
|
18
|
+
* refused, and the two figures are unrelated.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { resolveReservedOutputTokens } from "../engine/apis/output-budget.js";
|
|
22
|
+
import type { AgentRuntime } from "./turn-state.js";
|
|
23
|
+
|
|
24
|
+
export function resolveTurnOutputReserve(agentRuntime: AgentRuntime, inputTokens: number): number {
|
|
25
|
+
// A runtime resolution always carries capability decisions in production. The
|
|
26
|
+
// optional read is for a partially built runtime: an absent cap is the
|
|
27
|
+
// resolver's own "no advertised limit" case, which falls back to the
|
|
28
|
+
// configured budget and then the product floor, rather than a crash on a path
|
|
29
|
+
// that now runs during ordinary accounting.
|
|
30
|
+
return resolveReservedOutputTokens(agentRuntime.runtimeResolution.capabilityDecisions?.maxTokens, {
|
|
31
|
+
api: agentRuntime.agent.state.model?.api ?? "",
|
|
32
|
+
contextWindow: agentRuntime.runtimeResolution.contextWindowDetails.effectiveContextWindow,
|
|
33
|
+
inputTokens,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -23,7 +23,6 @@ import { formatUserTaskHandoff } from "../domains/user-tasks/handoff.js";
|
|
|
23
23
|
import type { UserTasksStore } from "../domains/user-tasks/store.js";
|
|
24
24
|
import type { TUI } from "../engine/tui.js";
|
|
25
25
|
import { type OpenContextOverlayOptions, openContextOverlay } from "./context-overlay.js";
|
|
26
|
-
import { openCostOverlay } from "./cost-overlay.js";
|
|
27
26
|
import {
|
|
28
27
|
type createDispatchBoardView,
|
|
29
28
|
isDispatchBoardRowCancellable,
|
|
@@ -43,6 +42,7 @@ import { openFleetRunApprovalOverlay } from "./overlays/fleet-run-approval.js";
|
|
|
43
42
|
import { openSideQuestionOverlay } from "./overlays/side-question.js";
|
|
44
43
|
import type { ContextClearCommandOptions } from "./slash-commands.js";
|
|
45
44
|
import { openTasksOverlay } from "./tasks-overlay.js";
|
|
45
|
+
import { openUsageOverlay } from "./usage-overlay.js";
|
|
46
46
|
import { type ArtifactProviderDeps, createDefaultArtifactProviders } from "./view/artifacts.js";
|
|
47
47
|
import { openViewOverlay } from "./view/view-overlay.js";
|
|
48
48
|
|
|
@@ -51,6 +51,8 @@ export interface OverlayGeneralOpenersDeps {
|
|
|
51
51
|
tui: TUI;
|
|
52
52
|
transitions: OverlayTransitions;
|
|
53
53
|
observability: ObservabilityContract;
|
|
54
|
+
getQuotaSnapshots?: () => ReadonlyArray<import("../domains/quota/types.js").UsageSnapshot>;
|
|
55
|
+
getDispatchRows?: () => ReadonlyArray<import("./dispatch-board.js").DispatchBoardRow>;
|
|
54
56
|
getSessionId?: () => string | null;
|
|
55
57
|
getContextLedger: () => ContextLedger;
|
|
56
58
|
contextChat: NonNullable<OpenContextOverlayOptions["chat"]>;
|
|
@@ -80,7 +82,7 @@ export interface OverlayGeneralOpenersDeps {
|
|
|
80
82
|
startDispatchBoardTicker: () => void;
|
|
81
83
|
closeOverlay: () => void;
|
|
82
84
|
showOverlayFrame?: typeof showClioOverlayFrame;
|
|
83
|
-
|
|
85
|
+
openUsageOverlay?: typeof openUsageOverlay;
|
|
84
86
|
openContextOverlay?: typeof openContextOverlay;
|
|
85
87
|
openContextResetOverlay?: typeof openContextResetOverlay;
|
|
86
88
|
openTasksOverlay?: typeof openTasksOverlay;
|
|
@@ -121,7 +123,7 @@ export interface OverlayGeneralOpenersDeps {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
export interface OverlayGeneralOpeners {
|
|
124
|
-
|
|
126
|
+
openUsage(): void;
|
|
125
127
|
openContextView(): void;
|
|
126
128
|
openContextReset(): void;
|
|
127
129
|
toggleFooter(): void;
|
|
@@ -136,7 +138,7 @@ export interface OverlayGeneralOpeners {
|
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
export function createOverlayGeneralOpeners(deps: OverlayGeneralOpenersDeps): OverlayGeneralOpeners {
|
|
139
|
-
const
|
|
141
|
+
const openUsageOverlayFactory = deps.openUsageOverlay ?? openUsageOverlay;
|
|
140
142
|
const openContextOverlayFactory = deps.openContextOverlay ?? openContextOverlay;
|
|
141
143
|
const openContextResetOverlayFactory = deps.openContextResetOverlay ?? openContextResetOverlay;
|
|
142
144
|
const openTasksOverlayFactory = deps.openTasksOverlay ?? openTasksOverlay;
|
|
@@ -146,11 +148,13 @@ export function createOverlayGeneralOpeners(deps: OverlayGeneralOpenersDeps): Ov
|
|
|
146
148
|
const showOverlayFrameFactory = deps.showOverlayFrame ?? showClioOverlayFrame;
|
|
147
149
|
const openSideQuestionOverlayFactory = deps.openSideQuestionOverlay ?? openSideQuestionOverlay;
|
|
148
150
|
|
|
149
|
-
const
|
|
151
|
+
const openUsage = (): void => {
|
|
150
152
|
if (deps.transitions.state !== "closed") return;
|
|
151
|
-
deps.transitions.state = "
|
|
152
|
-
deps.transitions.handle =
|
|
153
|
+
deps.transitions.state = "usage";
|
|
154
|
+
deps.transitions.handle = openUsageOverlayFactory(deps.tui, deps.observability, {
|
|
153
155
|
sessionId: deps.getSessionId?.() ?? null,
|
|
156
|
+
...(deps.getQuotaSnapshots ? { getQuotaSnapshots: deps.getQuotaSnapshots } : {}),
|
|
157
|
+
...(deps.getDispatchRows ? { getDispatchRows: deps.getDispatchRows } : {}),
|
|
154
158
|
...(deps.readSessionEntries
|
|
155
159
|
? {
|
|
156
160
|
getSessionEntries: () => deps.readSessionEntries?.() ?? [],
|
|
@@ -525,7 +529,7 @@ export function createOverlayGeneralOpeners(deps: OverlayGeneralOpenersDeps): Ov
|
|
|
525
529
|
};
|
|
526
530
|
|
|
527
531
|
return {
|
|
528
|
-
|
|
532
|
+
openUsage,
|
|
529
533
|
openContextView,
|
|
530
534
|
openContextReset,
|
|
531
535
|
toggleFooter,
|
|
@@ -7,7 +7,7 @@ export type OverlayState =
|
|
|
7
7
|
| "permission-confirm"
|
|
8
8
|
| "dispatch-board"
|
|
9
9
|
| "auth"
|
|
10
|
-
| "
|
|
10
|
+
| "usage"
|
|
11
11
|
| "context-view"
|
|
12
12
|
| "context-reset"
|
|
13
13
|
| "tasks"
|
|
@@ -213,8 +213,8 @@ function routeAuthOverlayKey(data: string, deps: CloseOverlayKeyDeps): boolean {
|
|
|
213
213
|
return false;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
/**
|
|
217
|
-
function
|
|
216
|
+
/** Esc closes an inspection overlay; callers decide how to route its remaining keys. */
|
|
217
|
+
function routeReadOnlyOverlayKey(data: string, deps: CloseOverlayKeyDeps): boolean {
|
|
218
218
|
if (isEscapeKey(data)) {
|
|
219
219
|
deps.closeOverlay();
|
|
220
220
|
return true;
|
|
@@ -262,19 +262,16 @@ export function routeOverlayKey(
|
|
|
262
262
|
return true;
|
|
263
263
|
}
|
|
264
264
|
if (overlayState === "auth") return routeAuthOverlayKey(data, deps);
|
|
265
|
-
if (overlayState === "
|
|
266
|
-
routeCostOverlayKey(data, deps);
|
|
267
|
-
return true;
|
|
268
|
-
}
|
|
265
|
+
if (overlayState === "usage") return routeReadOnlyOverlayKey(data, deps);
|
|
269
266
|
if (overlayState === "context-view") {
|
|
270
|
-
|
|
267
|
+
routeReadOnlyOverlayKey(data, deps);
|
|
271
268
|
return true;
|
|
272
269
|
}
|
|
273
270
|
// Esc is the only key the side-question overlay answers: it aborts a round
|
|
274
271
|
// that is still streaming and closes one that has settled. Everything else is
|
|
275
272
|
// swallowed so a keystroke cannot reach the composer behind it.
|
|
276
273
|
if (overlayState === "side-question") {
|
|
277
|
-
|
|
274
|
+
routeReadOnlyOverlayKey(data, deps);
|
|
278
275
|
return true;
|
|
279
276
|
}
|
|
280
277
|
// The handoff review overlay owns Enter, `e`, the arrows, and Esc itself, so
|
|
@@ -75,6 +75,8 @@ function interopProposalsFor(
|
|
|
75
75
|
|
|
76
76
|
export interface OverlayLifecycleRuntimeDeps {
|
|
77
77
|
app: OverlayLifecycleApplicationDeps;
|
|
78
|
+
getQuotaSnapshots?: () => ReadonlyArray<import("../domains/quota/types.js").UsageSnapshot>;
|
|
79
|
+
getDispatchRows?: () => ReadonlyArray<import("./dispatch-board.js").DispatchBoardRow>;
|
|
78
80
|
tui: import("../engine/tui.js").TUI;
|
|
79
81
|
footer: import("./footer/dashboard.js").FooterDashboardPanel;
|
|
80
82
|
interactiveTickers: import("./interactive-tickers.js").InteractiveTickers;
|
|
@@ -117,7 +119,7 @@ export interface OverlayLifecycleRuntimeDeps {
|
|
|
117
119
|
openTreeOverlay?: typeof import("./overlays/tree-selector.js").openTreeOverlay;
|
|
118
120
|
openMessagePickerOverlay?: typeof import("./overlays/message-picker.js").openMessagePickerOverlay;
|
|
119
121
|
openCwdFallbackOverlay?: typeof import("./overlays/cwd-fallback.js").openCwdFallbackOverlay;
|
|
120
|
-
|
|
122
|
+
openUsageOverlay?: typeof import("./usage-overlay.js").openUsageOverlay;
|
|
121
123
|
openContextOverlay?: typeof import("./context-overlay.js").openContextOverlay;
|
|
122
124
|
openContextResetOverlay?: typeof import("./overlays/context-reset.js").openContextResetOverlay;
|
|
123
125
|
openTasksOverlay?: typeof import("./tasks-overlay.js").openTasksOverlay;
|
|
@@ -140,7 +142,7 @@ export interface OverlayLifecycleController {
|
|
|
140
142
|
isAskUserWaiting(): boolean;
|
|
141
143
|
resetAskUserCancellation(): void;
|
|
142
144
|
refreshSettingsOverlay(): void;
|
|
143
|
-
|
|
145
|
+
openUsageOverlayState(): void;
|
|
144
146
|
openContextViewOverlayState(): void;
|
|
145
147
|
openContextResetOverlayState(): void;
|
|
146
148
|
toggleFooterDashboardState(): void;
|
|
@@ -207,7 +209,7 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
|
|
|
207
209
|
openTreeOverlay: openTreeOverlayFactory,
|
|
208
210
|
openMessagePickerOverlay: openMessagePickerOverlayFactory,
|
|
209
211
|
openCwdFallbackOverlay: openCwdFallbackOverlayFactory,
|
|
210
|
-
|
|
212
|
+
openUsageOverlay: openUsageOverlayFactory,
|
|
211
213
|
openContextOverlay: openContextOverlayFactory,
|
|
212
214
|
openContextResetOverlay: openContextResetOverlayFactory,
|
|
213
215
|
openTasksOverlay: openTasksOverlayFactory,
|
|
@@ -417,6 +419,8 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
|
|
|
417
419
|
tui,
|
|
418
420
|
transitions: overlayTransitions,
|
|
419
421
|
observability: deps.app.observability,
|
|
422
|
+
...(deps.getQuotaSnapshots ? { getQuotaSnapshots: deps.getQuotaSnapshots } : {}),
|
|
423
|
+
...(deps.getDispatchRows ? { getDispatchRows: deps.getDispatchRows } : {}),
|
|
420
424
|
...(deps.app.getSessionId ? { getSessionId: deps.app.getSessionId } : {}),
|
|
421
425
|
getContextLedger: () => deps.app.chat.contextLedger(),
|
|
422
426
|
contextChat: deps.app.chat,
|
|
@@ -445,7 +449,7 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
|
|
|
445
449
|
startDispatchBoardTicker: () => interactiveTickers.startDispatchBoardTicker(),
|
|
446
450
|
closeOverlay,
|
|
447
451
|
showOverlayFrame,
|
|
448
|
-
...(
|
|
452
|
+
...(openUsageOverlayFactory ? { openUsageOverlay: openUsageOverlayFactory } : {}),
|
|
449
453
|
...(openContextOverlayFactory ? { openContextOverlay: openContextOverlayFactory } : {}),
|
|
450
454
|
...(openContextResetOverlayFactory ? { openContextResetOverlay: openContextResetOverlayFactory } : {}),
|
|
451
455
|
...(openTasksOverlayFactory ? { openTasksOverlay: openTasksOverlayFactory } : {}),
|
|
@@ -462,7 +466,7 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
|
|
|
462
466
|
const openResumeOverlayState = overlaySessions.openResume;
|
|
463
467
|
const openTreeOverlayState = overlaySessions.openTree;
|
|
464
468
|
const openMessagePickerOverlayState = overlaySessions.openMessagePicker;
|
|
465
|
-
const
|
|
469
|
+
const openUsageOverlayState = overlayGeneralOpeners.openUsage;
|
|
466
470
|
const openContextViewOverlayState = overlayGeneralOpeners.openContextView;
|
|
467
471
|
const openContextResetOverlayState = overlayGeneralOpeners.openContextReset;
|
|
468
472
|
const toggleFooterDashboardState = overlayGeneralOpeners.toggleFooter;
|
|
@@ -484,7 +488,7 @@ export function createOverlayLifecycle(deps: OverlayLifecycleRuntimeDeps): Overl
|
|
|
484
488
|
isAskUserWaiting: overlayAskUser.isWaiting,
|
|
485
489
|
resetAskUserCancellation: overlayAskUser.resetCancellation,
|
|
486
490
|
refreshSettingsOverlay: overlayModelSelectors.refreshSettingsOverlay,
|
|
487
|
-
|
|
491
|
+
openUsageOverlayState,
|
|
488
492
|
openContextViewOverlayState,
|
|
489
493
|
openContextResetOverlayState,
|
|
490
494
|
toggleFooterDashboardState,
|
|
@@ -20,7 +20,7 @@ import type { ChatPanel } from "./chat-panel.js";
|
|
|
20
20
|
import { rehydrateChatPanelFromTurns } from "./chat-renderer.js";
|
|
21
21
|
import { emitCommandNotice } from "./command-fallbacks.js";
|
|
22
22
|
import type { InteractiveNoticeLevel } from "./interactive-subscriptions.js";
|
|
23
|
-
import { buildModelReplayAgentMessagesFromTurns } from "./model-session-replay.js";
|
|
23
|
+
import { buildModelReplayAgentMessagesFromTurns, withContinuityReplay } from "./model-session-replay.js";
|
|
24
24
|
import type { OverlayTransitions } from "./overlay-transitions.js";
|
|
25
25
|
import { openCwdFallbackOverlay } from "./overlays/cwd-fallback.js";
|
|
26
26
|
import { openHandoffReviewOverlay } from "./overlays/handoff-review.js";
|
|
@@ -92,7 +92,7 @@ export interface OverlaySessionLifecycle {
|
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
94
|
* The target and model a session started under, so reseeded calls land in the
|
|
95
|
-
* same `/
|
|
95
|
+
* same `/usage` bucket the live path writes to. Without it a single target read
|
|
96
96
|
* as two providers, one under the target id and one under the runtime name.
|
|
97
97
|
*/
|
|
98
98
|
function sessionUsageDefaults(session: SessionContract): { target?: string | null; model?: string | null } {
|
|
@@ -120,7 +120,7 @@ function restorePriorSessionOrReopen(
|
|
|
120
120
|
|
|
121
121
|
export function createOverlaySessionLifecycle(deps: OverlaySessionLifecycleDeps): OverlaySessionLifecycle {
|
|
122
122
|
/**
|
|
123
|
-
* Point every running number the footer and `/
|
|
123
|
+
* Point every running number the footer and `/usage` show at one branch. The
|
|
124
124
|
* session total and the last-turn line are read off the same lineage in the
|
|
125
125
|
* same call, so a switch cannot move one and leave the other behind.
|
|
126
126
|
*/
|
|
@@ -188,7 +188,7 @@ export function createOverlaySessionLifecycle(deps: OverlaySessionLifecycleDeps)
|
|
|
188
188
|
// after it (a compaction summary covering the leaf, above all)
|
|
189
189
|
// still belong on screen. uptoTurnId is the historical-truncation
|
|
190
190
|
// variant `/tree` uses.
|
|
191
|
-
const replayOptions = leafTurnId ? { activeLeafTurnId: leafTurnId } : {};
|
|
191
|
+
const replayOptions = withContinuityReplay(turns, leafTurnId ? { activeLeafTurnId: leafTurnId } : {}, session);
|
|
192
192
|
deps.resetTranscript();
|
|
193
193
|
rehydrateChatPanelFromTurns(deps.chatPanel, turns, replayOptions);
|
|
194
194
|
const replayMessages = buildModelReplayAgentMessagesFromTurns(turns, replayOptions);
|
|
@@ -240,11 +240,17 @@ export function createOverlaySessionLifecycle(deps: OverlaySessionLifecycleDeps)
|
|
|
240
240
|
if (!sessionId) throw new Error("no current session after turn switch");
|
|
241
241
|
const turns = deps.readStructuredEntries(sessionId);
|
|
242
242
|
deps.resetTranscript();
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
// `uptoTurnId` truncates the display at the selected turn. It is
|
|
244
|
+
// deliberately not a continuity `historical` flag: a live /tree
|
|
245
|
+
// selection is still this session's own branch, and treating every
|
|
246
|
+
// display truncation as a historical fork would surrender ownership
|
|
247
|
+
// of its own transactions for good.
|
|
248
|
+
const replayOptions = withContinuityReplay(turns, { uptoTurnId: turnId }, session);
|
|
249
|
+
rehydrateChatPanelFromTurns(deps.chatPanel, turns, replayOptions);
|
|
250
|
+
const replayMessages = buildModelReplayAgentMessagesFromTurns(turns, replayOptions);
|
|
245
251
|
deps.chat.resetForSession(turnId, replayMessages);
|
|
246
252
|
// The same branch the transcript above was just scoped to. Without the
|
|
247
|
-
// leaf, /
|
|
253
|
+
// leaf, /usage, the footer Σ, and the last-turn line kept reporting the
|
|
248
254
|
// abandoned turns.
|
|
249
255
|
rescopeToBranch(session, turns, turnId);
|
|
250
256
|
} catch (error) {
|
|
@@ -324,12 +330,12 @@ export function createOverlaySessionLifecycle(deps: OverlaySessionLifecycleDeps)
|
|
|
324
330
|
function replayFork(forkedSessionId: string, parentTurnId: string, session: SessionContract): void {
|
|
325
331
|
try {
|
|
326
332
|
const turns = deps.readStructuredEntries(forkedSessionId);
|
|
327
|
-
rehydrateChatPanelFromTurns(deps.chatPanel, turns);
|
|
328
333
|
const leafTurnId = session.tree(forkedSessionId).leafId ?? parentTurnId;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
);
|
|
334
|
+
// The child is already current here, so its own id and fork pointers are
|
|
335
|
+
// what separate the transactions it inherited from any it later mints.
|
|
336
|
+
const replayOptions = withContinuityReplay(turns, leafTurnId ? { activeLeafTurnId: leafTurnId } : {}, session);
|
|
337
|
+
rehydrateChatPanelFromTurns(deps.chatPanel, turns, replayOptions);
|
|
338
|
+
const replayMessages = buildModelReplayAgentMessagesFromTurns(turns, replayOptions);
|
|
333
339
|
deps.chat.resetForSession(leafTurnId, replayMessages);
|
|
334
340
|
rescopeToBranch(session, turns, leafTurnId);
|
|
335
341
|
} catch (error) {
|
|
@@ -617,8 +623,9 @@ export function createOverlaySessionLifecycle(deps: OverlaySessionLifecycleDeps)
|
|
|
617
623
|
try {
|
|
618
624
|
const turns = deps.readStructuredEntries(toSessionId);
|
|
619
625
|
deps.resetTranscript();
|
|
620
|
-
|
|
621
|
-
deps.
|
|
626
|
+
const replayOptions = withContinuityReplay(turns, {}, session);
|
|
627
|
+
rehydrateChatPanelFromTurns(deps.chatPanel, turns, replayOptions);
|
|
628
|
+
deps.chat.resetForSession(null, buildModelReplayAgentMessagesFromTurns(turns, replayOptions));
|
|
622
629
|
rescopeToBranch(session, turns, null);
|
|
623
630
|
} catch (error) {
|
|
624
631
|
deps.stderr(`[/handoff] seeding replay failed: ${error instanceof Error ? error.message : String(error)}\n`);
|