@iowarp/clio-coder 0.3.1 → 0.3.3
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/CHANGELOG.md +233 -373
- package/CONTRIBUTING.md +23 -23
- package/README.md +284 -613
- package/dist/{acp-FPR54DGL.js → acp-P2AQILE2.js} +43 -53
- package/dist/{agents-OGPIHPJH.js → agents-72W3BI7I.js} +43 -26
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-IC3K6NIZ.js → auth-5TWEIYDN.js} +20 -12
- package/dist/chunk-2DJ2KNFG.js +2095 -0
- package/dist/{chunk-IS3ONKU3.js → chunk-2IR2NMPA.js} +6 -4
- package/dist/chunk-2SFS6XQE.js +122 -0
- package/dist/{chunk-PV4JUBVJ.js → chunk-2TLUCQVG.js} +40 -21
- package/dist/chunk-2VTFPG5O.js +48 -0
- package/dist/chunk-4BJ5BYCE.js +61 -0
- package/dist/{chunk-474KN5II.js → chunk-4BPJXDWC.js} +111 -181
- package/dist/chunk-4VP4KH3K.js +962 -0
- package/dist/chunk-4XUGQOHA.js +797 -0
- package/dist/chunk-4ZG3XFUR.js +77 -0
- package/dist/chunk-5B2AEOW5.js +5407 -0
- package/dist/{chunk-K2ITRMHZ.js → chunk-5TSRNF4G.js} +6 -138
- package/dist/{chunk-4QKXUHSR.js → chunk-5UFT4SUX.js} +70 -20
- package/dist/{chunk-OLBBMFRD.js → chunk-5UUP6MWO.js} +24 -62
- package/dist/chunk-65DEGPJ6.js +52 -0
- package/dist/chunk-6EJMN2Y3.js +17 -0
- package/dist/chunk-6N5PTWMY.js +136 -0
- package/dist/chunk-6SGHMWE3.js +277 -0
- package/dist/chunk-6XLNIQDB.js +27 -0
- package/dist/chunk-7CR24IG7.js +242 -0
- package/dist/chunk-7MNJORFF.js +22 -0
- package/dist/{chunk-KY56HMHH.js → chunk-A3CYT5EX.js} +125 -31
- package/dist/chunk-AGYYIBLL.js +1069 -0
- package/dist/{chunk-GB6QRBXN.js → chunk-APJ265NV.js} +54 -1187
- package/dist/{chunk-673JJUWJ.js → chunk-BMEMKKIT.js} +2 -2
- package/dist/chunk-CBCAPZAA.js +229 -0
- package/dist/chunk-CMZWFGD2.js +352 -0
- package/dist/chunk-COU2UHX6.js +400 -0
- package/dist/chunk-DSELYM6W.js +1077 -0
- package/dist/chunk-DUYJ5IO6.js +644 -0
- package/dist/chunk-ECH6PKUQ.js +39 -0
- package/dist/chunk-ED4KHGC3.js +143 -0
- package/dist/chunk-EKMEHE4H.js +340 -0
- package/dist/chunk-FCSXB6T2.js +338 -0
- package/dist/chunk-FJ3H4MN5.js +48 -0
- package/dist/{chunk-RPTR2H26.js → chunk-FNTMWMX5.js} +21 -15
- package/dist/chunk-FQ4SKYE4.js +29 -0
- package/dist/chunk-G4BMMOKF.js +182 -0
- package/dist/{chunk-ZPY3JZ5E.js → chunk-GGXXDWE4.js} +183 -1233
- package/dist/chunk-HC4CLZ2Y.js +68 -0
- package/dist/{chunk-LU4TK2PR.js → chunk-HFSBBKSQ.js} +5 -56
- package/dist/{chunk-PIUMUEMV.js → chunk-HKIYEGME.js} +10 -6
- package/dist/chunk-I4HZDVNP.js +73 -0
- package/dist/chunk-IKCO5N3L.js +162 -0
- package/dist/chunk-IR4CFBFN.js +56 -0
- package/dist/{chunk-R5KLMSBV.js → chunk-J5Q24KAG.js} +2 -2
- package/dist/chunk-J7CWMCQD.js +255 -0
- package/dist/{chunk-K5XEMXTI.js → chunk-JVCV3ICN.js} +1 -1
- package/dist/chunk-KZWTDYJF.js +217 -0
- package/dist/chunk-LBMZMYH2.js +285 -0
- package/dist/{chunk-G34LV2PF.js → chunk-LM5TQCJZ.js} +84 -170
- package/dist/chunk-LW6DSM3M.js +5135 -0
- package/dist/chunk-LWLEKMDQ.js +3482 -0
- package/dist/{chunk-H6F6BYOH.js → chunk-LZSJBIVT.js} +7003 -7434
- package/dist/{chunk-HQQID6OA.js → chunk-M6SHUN7Q.js} +5 -5
- package/dist/{chunk-FST4FYJB.js → chunk-MFFY33HR.js} +99 -140
- package/dist/{chunk-BSU2YIWB.js → chunk-MVVUPGPW.js} +131 -136
- package/dist/chunk-OAO4GE4M.js +619 -0
- package/dist/{chunk-Q3RUPKEJ.js → chunk-OC7FIQPC.js} +58 -189
- package/dist/chunk-OKGUZO2U.js +34 -0
- package/dist/{chunk-GAEBEQVI.js → chunk-OOJYHWRB.js} +32 -346
- package/dist/{chunk-Q5WJOSJ7.js → chunk-OQ33BKR3.js} +2 -1
- package/dist/chunk-OQE5J4C6.js +73 -0
- package/dist/{chunk-KKNLWXI6.js → chunk-ORBHGJC5.js} +8 -8
- package/dist/{chunk-MAR7Y6HW.js → chunk-PAJK6MAQ.js} +23 -16
- package/dist/{chunk-M5T5VO65.js → chunk-PIWWS5BL.js} +837 -635
- package/dist/chunk-POHLU5DW.js +1186 -0
- package/dist/chunk-QKMUKYO7.js +4961 -0
- package/dist/chunk-SRDMMSEP.js +16405 -0
- package/dist/chunk-SST6Z5JA.js +80 -0
- package/dist/chunk-STBPMHSX.js +2456 -0
- package/dist/chunk-T6YILFSB.js +80 -0
- package/dist/chunk-TZK7PACC.js +174 -0
- package/dist/chunk-TZTZS7QK.js +227 -0
- package/dist/{chunk-ASND7OZK.js → chunk-UFIIWP2H.js} +13 -13
- package/dist/chunk-UOV2BYIW.js +107 -0
- package/dist/{chunk-PFEFKVGL.js → chunk-V6RTAOC2.js} +13 -11
- package/dist/chunk-VAKQQHWR.js +434 -0
- package/dist/chunk-VG7TBQIY.js +128 -0
- package/dist/chunk-VJWL6YS5.js +244 -0
- package/dist/{chunk-EYOKLTMF.js → chunk-VPAYEGVX.js} +17 -3
- package/dist/chunk-WEH5XRJQ.js +32 -0
- package/dist/chunk-X4RCMKVQ.js +641 -0
- package/dist/{chunk-TEKV33Q5.js → chunk-X6IAEBZR.js} +65 -33
- package/dist/chunk-XBXAASKX.js +18 -0
- package/dist/chunk-XN3L4EYL.js +46 -0
- package/dist/{chunk-RDLVBZEO.js → chunk-YCWGATWI.js} +6 -4
- package/dist/chunk-YHZX5GEU.js +193 -0
- package/dist/chunk-YXLYO42X.js +91 -0
- package/dist/{chunk-NMOX6HFD.js → chunk-ZDOOVTXZ.js} +29 -77
- package/dist/chunk-ZI647VB5.js +37 -0
- package/dist/{chunk-C4PTHK7P.js → chunk-ZWLZP4ZT.js} +5 -5
- package/dist/chunk-ZWMF7253.js +1882 -0
- package/dist/cli/index.js +62 -54
- package/dist/clio-JOU4FXVA.js +25 -0
- package/dist/code-nav-7AX6FYE6.js +600 -0
- package/dist/codewiki/build-worker.js +66 -0
- package/dist/compile-cache-CVJMMODC.js +18 -0
- package/dist/{components-DMAOEKFB.js → components-KELWS457.js} +11 -6
- package/dist/{config-IRUQ7SE4.js → config-XCDVKR23.js} +92 -55
- package/dist/configure-4GAP54ZW.js +42 -0
- package/dist/{context-5RADCKTR.js → context-4UOGGLQ5.js} +71 -35
- package/dist/context-5VKGUVJJ.js +866 -0
- package/dist/{context-3KWFLHJG.js → context-77FM5DV5.js} +15 -13
- package/dist/{context-clear-7TSNPAAI.js → context-clear-XXJRLCJJ.js} +54 -28
- package/dist/{context-index-W4RLWOQH.js → context-index-BZ4UYMTC.js} +30 -24
- package/dist/dispatch-runner-QPRDDBDX.js +1997 -0
- package/dist/{docs-5AWSPS37.js → docs-2C2LTVT2.js} +23 -10
- package/dist/{doctor-UC5NAJYQ.js → doctor-HR46URBJ.js} +27 -17
- package/dist/{eval-U6TJHRLX.js → eval-XSSNATB4.js} +29 -16
- package/dist/{evidence-YEGUW4L3.js → evidence-6HG2PY2B.js} +46 -26
- package/dist/{evolve-TXARCTPG.js → evolve-K7YU3NCY.js} +45 -25
- package/dist/{extensions-OZFJ3A3G.js → extensions-QVDOHDGJ.js} +16 -7
- package/dist/{fleet-6G3DHNYE.js → fleet-VY3HHKN6.js} +163 -54
- package/dist/{fleet-preflight-DSNT37JK.js → fleet-preflight-DDN536IT.js} +7 -4
- package/dist/{init-KZ5QTF6M.js → init-JYGXI3FK.js} +69 -32
- package/dist/{memory-73ESV5YC.js → memory-WFZMGYHX.js} +48 -27
- package/dist/{models-A4PVNWJK.js → models-I5QWSEOM.js} +39 -25
- package/dist/monitor-GE4ID3IA.js +661 -0
- package/dist/{chunk-FCIH3BIZ.js → orchestrator-EM5MC3HM.js} +15979 -12407
- package/dist/{paths-C4H6IV77.js → paths-UXLN5YYZ.js} +10 -5
- package/dist/{preload-6WVMHX3A.js → preload-P6DGH2PZ.js} +2 -2
- package/dist/{reset-BGW6OGMV.js → reset-L2FQEE3E.js} +16 -10
- package/dist/{run-YTPEYQOH.js → run-ZU3QMZPZ.js} +101 -61
- package/dist/{share-YIFFV4NQ.js → share-S5BZQC5I.js} +15 -8
- package/dist/{skills-2V6RA3OQ.js → skills-X5VXCRNQ.js} +34 -14
- package/dist/{skills-eval-S2TVJO4F.js → skills-eval-WKIHWTHR.js} +70 -34
- package/dist/steer-GGWFUJUD.js +77 -0
- package/dist/{targets-TYXLPB23.js → targets-SNCPI2NR.js} +43 -27
- package/dist/terminal-lease-BNAHVHBS.js +395 -0
- package/dist/{trace-GGOJ6Q6Z.js → trace-PNCASAXC.js} +41 -16
- package/dist/{chunk-N6F52NLF.js → tree-sitter-HGKH6LG4.js} +28 -2306
- package/dist/{uninstall-LLLT4F4W.js → uninstall-FZCQCDKC.js} +10 -5
- package/dist/{upgrade-33G2LMM5.js → upgrade-JQHHPQ4K.js} +45 -25
- package/dist/{usage-ZAFSXKKG.js → usage-OR4O5SMZ.js} +62 -31
- package/dist/verify-375KUB3Y.js +716 -0
- package/dist/web-fetch-2YHJ3KTG.js +638 -0
- package/dist/{wiki-generate-NUQCVOQ3.js → wiki-generate-UEXP2ARI.js} +74 -34
- package/dist/worker/entry.js +221 -36
- package/dist/workspace-G4ZWUIPR.js +22 -0
- package/docs/README.md +22 -17
- package/docs/acp.md +168 -16
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +136 -7
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +114 -71
- package/docs/config-knobs-audit.md +1 -3
- package/docs/configuration-and-targets.md +174 -46
- package/docs/context-engine.md +29 -6
- package/docs/development-pipeline.md +26 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +2 -2
- package/docs/documentation-guide.md +1 -1
- package/docs/environment-variables.md +13 -5
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +2 -2
- package/docs/exit-codes-and-output.md +15 -9
- package/docs/extensions-and-sharing.md +9 -9
- package/docs/fleet-dispatch.md +7 -5
- package/docs/git-commit-provenance.md +120 -0
- package/docs/glossary.md +1 -1
- package/docs/installation-and-lifecycle.md +34 -27
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +45 -14
- package/docs/observability.md +8 -5
- package/docs/performance-methodology.md +491 -0
- package/docs/pi-boundary.md +72 -0
- package/docs/proactive-memory.md +3 -3
- package/docs/prompt-envelope-and-tools.md +24 -3
- package/docs/provider-adapter-cookbook.md +57 -4
- package/docs/release-cut-checklist.md +129 -115
- package/docs/safety-model.md +9 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +55 -12
- package/docs/skills-marketplace.md +12 -8
- package/docs/time-conventions.md +1 -1
- package/docs/tool-usage.md +3 -3
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +10 -7
- package/docs/tui-design.md +47 -10
- package/docs/worker-dispatch-mechanics.md +1 -1
- package/package.json +19 -22
- package/skills/coding/ast-grep/SKILL.md +136 -0
- package/skills/coding/ast-grep/evals.md +56 -0
- package/skills/coding/ast-grep/references/rule_reference.md +297 -0
- package/skills/coding/coding-standards/SKILL.md +113 -0
- package/skills/coding/coding-standards/evals.md +34 -0
- package/skills/coding/prototype/SKILL.md +86 -0
- package/skills/coding/prototype/evals.md +42 -0
- package/skills/coding/prototype/references/LOGIC.md +67 -0
- package/skills/coding/prototype/references/UI.md +112 -0
- package/skills/coding/tdd/SKILL.md +101 -0
- package/skills/coding/tdd/evals.md +41 -0
- package/skills/coding/tdd/references/mocking.md +59 -0
- package/skills/coding/tdd/references/tests.md +77 -0
- package/skills/context/context-handoff/SKILL.md +126 -0
- package/skills/context/context-handoff/evals.md +57 -0
- package/skills/context/context-handoff/scripts/new-handoff.sh +26 -0
- package/skills/context/context-prime/SKILL.md +95 -0
- package/skills/context/context-prime/evals.md +54 -0
- package/skills/meta/clio-dev/SKILL.md +91 -0
- package/skills/meta/clio-dev/evals.md +45 -0
- package/skills/meta/clio-test/SKILL.md +130 -0
- package/skills/meta/clio-test/evals.md +43 -0
- package/skills/meta/clio-test/references/harness.md +97 -0
- package/skills/meta/clio-test/references/test-map.md +59 -0
- package/skills/meta/credentials/SKILL.md +125 -0
- package/skills/meta/credentials/evals.md +104 -0
- package/skills/meta/find-skills/SKILL.md +72 -0
- package/skills/meta/find-skills/evals.md +47 -0
- package/skills/meta/herdr/SKILL.md +127 -0
- package/skills/meta/herdr/evals.md +38 -0
- package/skills/meta/skill-craft/SKILL.md +102 -0
- package/skills/meta/skill-craft/evals.md +41 -0
- package/skills/planning/architecture/SKILL.md +129 -0
- package/skills/planning/architecture/evals.md +36 -0
- package/skills/planning/backlog/SKILL.md +90 -0
- package/skills/planning/backlog/evals.md +43 -0
- package/skills/planning/prd/SKILL.md +82 -0
- package/skills/planning/prd/evals.md +49 -0
- package/skills/planning/product-intent/SKILL.md +112 -0
- package/skills/planning/product-intent/evals.md +36 -0
- package/skills/planning/tech-spec/SKILL.md +115 -0
- package/skills/planning/tech-spec/evals.md +47 -0
- package/skills/registry.yaml +136 -0
- package/skills/research/arxiv-literature/SKILL.md +104 -0
- package/skills/research/arxiv-literature/evals.md +58 -0
- package/skills/research/experiment-protocol/SKILL.md +122 -0
- package/skills/research/experiment-protocol/evals.md +91 -0
- package/skills/research/scientific-debugging/SKILL.md +119 -0
- package/skills/research/scientific-debugging/evals.md +138 -0
- package/skills/research/scientific-modernization/SKILL.md +138 -0
- package/skills/research/scientific-modernization/evals.md +84 -0
- package/skills/workflow/design-council/SKILL.md +139 -0
- package/skills/workflow/design-council/evals.md +97 -0
- package/skills/workflow/grill-me/SKILL.md +186 -0
- package/skills/workflow/grill-me/evals.md +78 -0
- package/skills/workflow/workflow-distiller/SKILL.md +136 -0
- package/skills/workflow/workflow-distiller/evals.md +107 -0
- package/src/cli/acp.ts +31 -4
- package/src/cli/clio.ts +68 -6
- package/src/cli/config-inspect.ts +28 -22
- package/src/cli/configure.ts +47 -9
- package/src/cli/context-clear.ts +2 -2
- package/src/cli/context-index.ts +21 -23
- package/src/cli/context.ts +13 -8
- package/src/cli/default-target.ts +9 -17
- package/src/cli/docs.ts +11 -5
- package/src/cli/evidence.ts +4 -1
- package/src/cli/extensions.ts +10 -1
- package/src/cli/fleet.ts +47 -6
- package/src/cli/index.ts +55 -26
- package/src/cli/memory.ts +3 -1
- package/src/cli/models.ts +1 -1
- package/src/cli/modes/json-stream.ts +37 -1
- package/src/cli/modes/print.ts +24 -9
- package/src/cli/run.ts +2 -2
- package/src/cli/skills-eval.ts +23 -8
- package/src/cli/skills.ts +19 -4
- package/src/cli/targets.ts +4 -0
- package/src/cli/text-layout.ts +15 -5
- package/src/cli/trace.ts +62 -14
- package/src/cli/upgrade.ts +18 -2
- package/src/cli/usage.ts +10 -3
- package/src/cli/wiki-generate.ts +2 -1
- package/src/core/agent-environment.ts +7 -0
- package/src/core/bash-exec.ts +72 -1
- package/src/core/boot-trace.ts +9 -4
- package/src/core/bus-events.ts +20 -4
- package/src/core/commit-attribution.ts +157 -0
- package/src/core/compile-cache.ts +159 -0
- package/src/core/config.ts +131 -2
- package/src/core/defaults.ts +39 -5
- package/src/core/domain-loader.ts +12 -5
- package/src/core/git-commit-attribution.ts +387 -0
- package/src/core/incomplete-installation.ts +45 -0
- package/src/core/response-schema.ts +1 -1
- package/src/core/safe-exec.ts +13 -1
- package/src/core/settings-layers.ts +155 -21
- package/src/core/skill-activation.ts +1 -1
- package/src/core/startup-timer.ts +3 -3
- package/src/core/state-file-lock.ts +13 -1
- package/src/core/termination.ts +78 -5
- package/src/domains/config/classify.ts +15 -3
- package/src/domains/config/extension.ts +19 -13
- package/src/domains/config/index.ts +10 -0
- package/src/domains/config/keybindings.ts +45 -9
- package/src/domains/context/bootstrap-prompt.ts +1 -1
- package/src/domains/context/bootstrap.ts +111 -18
- package/src/domains/context/clear.ts +16 -11
- package/src/domains/context/clio-md.ts +111 -9
- package/src/domains/context/codewiki/artifact.ts +400 -0
- package/src/domains/context/codewiki/build-worker-protocol.ts +24 -0
- package/src/domains/context/codewiki/build-worker.ts +54 -0
- package/src/domains/context/codewiki/coordinator.ts +182 -0
- package/src/domains/context/codewiki/indexer.ts +59 -144
- package/src/domains/context/codewiki/paths.ts +67 -0
- package/src/domains/context/codewiki/schema.ts +80 -0
- package/src/domains/context/codewiki/tree-sitter.ts +1 -1
- package/src/domains/context/contract.ts +11 -5
- package/src/domains/context/extension.ts +94 -143
- package/src/domains/context/fingerprint.ts +3 -1
- package/src/domains/context/index.ts +12 -22
- package/src/domains/context/project-metadata.ts +19 -0
- package/src/domains/context/prompt-context.ts +9 -10
- package/src/domains/context/refresh.ts +29 -21
- package/src/domains/context/runtime.ts +17 -0
- package/src/domains/context/wiki/generate.ts +39 -34
- package/src/domains/context/wiki/plan.ts +1 -1
- package/src/domains/context/wiki/prompts.ts +21 -8
- package/src/domains/dispatch/code-step.ts +20 -1
- package/src/domains/dispatch/extension.ts +158 -21
- package/src/domains/dispatch/failure-classification.ts +6 -0
- package/src/domains/dispatch/fleet-commit-attribution.ts +56 -0
- package/src/domains/dispatch/orphan-recovery.ts +50 -8
- package/src/domains/dispatch/receipt-integrity.ts +5 -0
- package/src/domains/dispatch/state.ts +31 -6
- package/src/domains/dispatch/transport.ts +2 -1
- package/src/domains/dispatch/types.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +21 -2
- package/src/domains/eval/metrics/context.ts +1 -1
- package/src/domains/eval/types.ts +0 -1
- package/src/domains/evidence/build.ts +41 -1
- package/src/domains/lifecycle/migrations/2026-08-18-lmstudio-runtime-id.ts +52 -0
- package/src/domains/lifecycle/migrations/index.ts +24 -4
- package/src/domains/middleware/hooks-io.ts +12 -0
- package/src/domains/middleware/skills-reminder.ts +30 -15
- package/src/domains/prompts/compiler.ts +142 -84
- package/src/domains/prompts/contract.ts +18 -2
- package/src/domains/prompts/extension.ts +39 -7
- package/src/domains/prompts/fragment-loader.ts +0 -1
- package/src/domains/prompts/fragments/identity/clio.md +2 -4
- package/src/domains/prompts/fragments/identity/docs-routing.md +10 -0
- package/src/domains/prompts/fragments/identity/self-awareness.md +1 -45
- package/src/domains/prompts/fragments/operating/contract.md +4 -50
- package/src/domains/prompts/fragments/operating/delegation.md +42 -0
- package/src/domains/prompts/fragments/operating/skills.md +26 -0
- package/src/domains/prompts/fragments/operating/worker.md +16 -0
- package/src/domains/prompts/fragments/safety/auto-edit.md +5 -5
- package/src/domains/prompts/fragments/safety/full-auto.md +3 -3
- package/src/domains/prompts/fragments/safety/read-only.md +4 -4
- package/src/domains/prompts/fragments/safety/suggest.md +2 -2
- package/src/domains/prompts/fragments/wiki/page.md +10 -0
- package/src/domains/prompts/fragments/wiki/plan.md +10 -0
- package/src/domains/prompts/preload.ts +3 -3
- package/src/domains/providers/auth/api-key.ts +1 -1
- package/src/domains/providers/auth/backend-file.ts +20 -10
- package/src/domains/providers/auth/backend-memory.ts +59 -4
- package/src/domains/providers/auth/boot-status.ts +65 -0
- package/src/domains/providers/auth/oauth.ts +2 -1
- package/src/domains/providers/auth/storage.ts +97 -38
- package/src/domains/providers/capabilities.ts +12 -4
- package/src/domains/providers/contract.ts +15 -4
- package/src/domains/providers/extension.ts +18 -6
- package/src/domains/providers/model-runtime-capabilities.ts +15 -4
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +118 -35
- package/src/domains/providers/plugins.ts +5 -3
- package/src/domains/providers/probe/fingerprint.ts +25 -5
- package/src/domains/providers/registry.ts +31 -10
- package/src/domains/providers/runtimes/boot-manifest.ts +55 -0
- package/src/domains/providers/runtimes/builtins.ts +2 -2
- package/src/domains/providers/runtimes/common/lmstudio-http.ts +423 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +6 -7
- package/src/domains/providers/runtimes/local-native/lmstudio.ts +241 -0
- package/src/domains/providers/support.ts +6 -3
- package/src/domains/providers/types/local-model-quirks.ts +7 -9
- package/src/domains/providers/types/runtime-descriptor.ts +12 -1
- package/src/domains/providers/types/target-descriptor.ts +22 -0
- package/src/domains/resources/contract.ts +0 -1
- package/src/domains/resources/extension.ts +1 -3
- package/src/domains/resources/loader.ts +3 -4
- package/src/domains/resources/prompts/loader.ts +16 -2
- package/src/domains/resources/prompts/substitute.ts +1 -65
- package/src/domains/resources/skills/content-hash.ts +2 -0
- package/src/domains/resources/skills/install.ts +17 -0
- package/src/domains/resources/skills/loader.ts +17 -10
- package/src/domains/resources/skills/marketplace.ts +55 -9
- package/src/domains/safety/action-classifier.ts +4 -2
- package/src/domains/safety/audit.ts +8 -2
- package/src/domains/safety/extension.ts +1 -1
- package/src/domains/session/compaction/branch-summary.ts +3 -2
- package/src/domains/session/compaction/cut-point.ts +2 -1
- package/src/domains/session/compaction/tokens.ts +2 -1
- package/src/domains/session/context-ledger.ts +14 -0
- package/src/domains/session/contract.ts +15 -0
- package/src/domains/session/decision-board.ts +190 -0
- package/src/domains/session/entries.ts +66 -3
- package/src/domains/session/extension.ts +93 -12
- package/src/domains/session/retry.ts +10 -18
- package/src/domains/session/session-artifacts.ts +107 -0
- package/src/domains/session/task-board.ts +207 -13
- package/src/domains/session/tree/active-path.ts +44 -5
- package/src/domains/session/tree/fork.ts +26 -27
- package/src/domains/session/tree/preview.ts +2 -2
- package/src/domains/session/workspace/git-probe.ts +17 -11
- package/src/domains/user-tasks/store.ts +297 -0
- package/src/engine/acp/errors.ts +96 -0
- package/src/engine/acp/server.ts +1728 -146
- package/src/engine/acp/transport.ts +135 -14
- package/src/engine/acp/types.ts +26 -0
- package/src/engine/agent.ts +3 -3
- package/src/engine/ai.ts +32 -27
- package/src/engine/alcf-oauth.ts +26 -19
- package/src/engine/api-registry.ts +223 -0
- package/src/engine/apis/index.ts +3 -7
- package/src/engine/apis/llamacpp-residency.ts +49 -9
- package/src/engine/apis/lmstudio-residency.ts +5 -21
- package/src/engine/apis/lmstudio.ts +243 -0
- package/src/engine/apis/ollama-native.ts +24 -3
- package/src/engine/apis/openai-completions.ts +170 -91
- package/src/engine/apis/residency.ts +139 -3
- package/src/engine/apis/types.ts +16 -0
- package/src/engine/env-api-keys.ts +98 -0
- package/src/engine/gemma-channel-filter.ts +223 -0
- package/src/engine/instrumented-tui.ts +192 -0
- package/src/engine/messages.ts +14 -0
- package/src/engine/models.ts +42 -0
- package/src/engine/oauth.ts +16 -12
- package/src/engine/prompt-templates.ts +1 -0
- package/src/engine/provider-payload.ts +16 -59
- package/src/engine/strip-tokenizer-sentinels.ts +1 -1
- package/src/engine/truncate.ts +9 -0
- package/src/engine/tui.ts +17 -9
- package/src/engine/types.ts +3 -6
- package/src/engine/worker-runtime-capabilities.ts +5 -0
- package/src/engine/worker-runtime.ts +1 -1
- package/src/engine/worker-tools.ts +9 -4
- package/src/entry/boot-options.ts +50 -0
- package/src/entry/orchestrator.ts +288 -150
- package/src/interactive/application-controller.ts +89 -2
- package/src/interactive/chat-loop.ts +266 -41
- package/src/interactive/chat-panel.ts +715 -278
- package/src/interactive/chat-renderer.ts +306 -85
- package/src/interactive/clio-editor.ts +3 -8
- package/src/interactive/command-fallbacks.ts +2 -2
- package/src/interactive/context-overlay.ts +27 -1
- package/src/interactive/editor-submit.ts +253 -24
- package/src/interactive/export-html/ansi-to-html.ts +161 -0
- package/src/interactive/export-html/index.ts +51 -0
- package/src/interactive/export-html/template.ts +45 -0
- package/src/interactive/export-html/tool-renderer.ts +54 -0
- package/src/interactive/footer/dashboard.ts +4 -0
- package/src/interactive/footer/notifications.ts +1 -1
- package/src/interactive/footer/widgets.ts +42 -22
- package/src/interactive/footer-panel.ts +8 -3
- package/src/interactive/format-time.ts +14 -2
- package/src/interactive/interactive-application.ts +203 -17
- package/src/interactive/interactive-event-projection.ts +18 -1
- package/src/interactive/interactive-input-runtime.ts +50 -4
- package/src/interactive/interactive-presentation.ts +151 -19
- package/src/interactive/interactive-shell.ts +268 -14
- package/src/interactive/interactive-slash-runtime.ts +184 -117
- package/src/interactive/interactive-tickers.ts +38 -7
- package/src/interactive/keybinding-manager.ts +1 -1
- package/src/interactive/layout.ts +40 -3
- package/src/interactive/overlay-frame.ts +1 -1
- package/src/interactive/overlay-general-openers.ts +58 -1
- package/src/interactive/overlay-key-routing.ts +3 -0
- package/src/interactive/overlay-lifecycle.ts +13 -0
- package/src/interactive/overlay-permission-lifecycle.ts +2 -1
- package/src/interactive/overlay-session-lifecycle.ts +69 -12
- package/src/interactive/overlays/ask-user.ts +146 -24
- package/src/interactive/overlays/decisions.ts +300 -0
- package/src/interactive/overlays/help-reference.ts +15 -10
- package/src/interactive/overlays/model-selector.ts +34 -16
- package/src/interactive/overlays/session-selector.ts +18 -0
- package/src/interactive/overlays/settings.ts +105 -17
- package/src/interactive/overlays/skills-hub.ts +4 -4
- package/src/interactive/overlays/tree-selector.ts +41 -6
- package/src/interactive/render-trace.ts +499 -90
- package/src/interactive/renderers/compaction-summary.ts +2 -2
- package/src/interactive/renderers/diff.ts +115 -104
- package/src/interactive/renderers/mermaid.ts +53 -0
- package/src/interactive/renderers/tool-execution.ts +516 -168
- package/src/interactive/renderers/worker-entry.ts +20 -4
- package/src/interactive/session-switch-settlement.ts +10 -0
- package/src/interactive/slash-autocomplete.ts +6 -114
- package/src/interactive/slash-commands.ts +135 -47
- package/src/interactive/slash-spec.ts +9 -38
- package/src/interactive/status/controller.ts +5 -1
- package/src/interactive/status/index.ts +12 -1
- package/src/interactive/status/reasoning.ts +87 -0
- package/src/interactive/status/summary.ts +13 -2
- package/src/interactive/stdout-backpressure.ts +99 -0
- package/src/interactive/stream-pacer.ts +530 -0
- package/src/interactive/stream-pacing-policy.ts +66 -0
- package/src/interactive/tasks-overlay.ts +368 -14
- package/src/interactive/terminal-lease.ts +485 -0
- package/src/interactive/theme/tokens.ts +1 -1
- package/src/interactive/transcript-detail.ts +120 -0
- package/src/interactive/turn-context.ts +4 -3
- package/src/interactive/turn-persistence.ts +30 -13
- package/src/interactive/turn-queues.ts +12 -0
- package/src/interactive/turn-recovery.ts +25 -8
- package/src/interactive/turn-runtime.ts +79 -12
- package/src/interactive/turn-state.ts +10 -0
- package/src/interactive/view/artifacts.ts +114 -4
- package/src/interactive/view/view-overlay.ts +3 -0
- package/src/interactive/welcome-dashboard.ts +17 -16
- package/src/interactive/worker-receipts.ts +52 -3
- package/src/interactive/worker-stream.ts +5 -1
- package/src/tools/agent-tools.ts +23 -3
- package/src/tools/artifact.ts +2 -2
- package/src/tools/ask-user.ts +23 -13
- package/src/tools/bash.ts +30 -2
- package/src/tools/bootstrap.ts +34 -431
- package/src/tools/builtin-tool-catalog.ts +271 -0
- package/src/tools/codewiki/code-nav-surface.ts +29 -0
- package/src/tools/codewiki/code-nav.ts +8 -22
- package/src/tools/codewiki/shared.ts +41 -38
- package/src/tools/context/docs-engine.ts +14 -3
- package/src/tools/context/index.ts +107 -28
- package/src/tools/context/surface.ts +19 -0
- package/src/tools/core-bootstrap.ts +168 -0
- package/src/tools/credential-present.ts +5 -5
- package/src/tools/dispatch-admission.ts +533 -0
- package/src/tools/dispatch-background.ts +54 -0
- package/src/tools/dispatch-event-text.ts +6 -0
- package/src/tools/dispatch-plan.ts +9 -4
- package/src/tools/dispatch-run-events.ts +238 -0
- package/src/tools/dispatch-runner.ts +2370 -0
- package/src/tools/dispatch-scout-admission.ts +295 -0
- package/src/tools/dispatch-types.ts +77 -0
- package/src/tools/dispatch.ts +67 -3161
- package/src/tools/find.ts +4 -2
- package/src/tools/grep.ts +2 -2
- package/src/tools/lazy-tool.ts +60 -0
- package/src/tools/ledger.ts +3 -3
- package/src/tools/monitor-surface.ts +36 -0
- package/src/tools/monitor.ts +2 -32
- package/src/tools/observers.ts +2 -2
- package/src/tools/presentation.ts +107 -0
- package/src/tools/registry.ts +45 -27
- package/src/tools/safe-exec.ts +2 -2
- package/src/tools/steer-surface.ts +17 -0
- package/src/tools/steer.ts +2 -13
- package/src/tools/tasks.ts +108 -11
- package/src/tools/truncate.ts +25 -184
- package/src/tools/verify/frontend.ts +3 -1
- package/src/tools/verify/index.ts +3 -38
- package/src/tools/verify/surface.ts +46 -0
- package/src/tools/web-fetch-surface.ts +23 -0
- package/src/tools/web-fetch.ts +2 -20
- package/src/tools/write.ts +7 -2
- package/src/worker/entry.ts +39 -2
- package/src/worker/spec-contract.ts +26 -5
- package/dist/chunk-7SS2CTV2.js +0 -61361
- package/dist/chunk-DKGKUHFA.js +0 -924
- package/dist/chunk-GEP36Y4X.js +0 -12796
- package/dist/chunk-XYWBQRDM.js +0 -137
- package/dist/clio-BZVGEUFJ.js +0 -58
- package/dist/configure-S7S6F6CL.js +0 -32
- package/docs/html/agents_blueprint.html +0 -936
- package/docs/html/alcf_blueprint.html +0 -324
- package/docs/html/architecture_blueprint.html +0 -850
- package/docs/html/commands_blueprint.html +0 -939
- package/docs/html/config_knobs_audit_blueprint.html +0 -178
- package/docs/html/configuration_blueprint.html +0 -1080
- package/docs/html/context_blueprint.html +0 -603
- package/docs/html/documentation_blueprint.html +0 -832
- package/docs/html/environment_blueprint.html +0 -404
- package/docs/html/eval_blueprint.html +0 -743
- package/docs/html/evals_internal_blueprint.html +0 -190
- package/docs/html/evolution_blueprint.html +0 -674
- package/docs/html/extensions_blueprint.html +0 -2065
- package/docs/html/fleet_dispatch_blueprint.html +0 -286
- package/docs/html/index.html +0 -919
- package/docs/html/lifecycle_blueprint.html +0 -723
- package/docs/html/memory_blueprint.html +0 -699
- package/docs/html/middleware_blueprint.html +0 -664
- package/docs/html/models_blueprint.html +0 -2366
- package/docs/html/observability_blueprint.html +0 -683
- package/docs/html/provider_adapter_blueprint.html +0 -245
- package/docs/html/safety_blueprint.html +0 -1386
- package/docs/html/shared.css +0 -571
- package/docs/html/shared.js +0 -143
- package/docs/html/skills_blueprint.html +0 -671
- package/docs/html/soak_blueprint.html +0 -182
- package/docs/html/tool_usage_blueprint.html +0 -350
- package/docs/html/tools_blueprint.html +0 -2249
- package/docs/html/trace_blueprint.html +0 -235
- package/docs/html/tui_design_blueprint.html +0 -374
- package/docs/html/validation_blueprint.html +0 -961
- package/docs/html/worker_dispatch_blueprint.html +0 -231
- package/src/core/release.ts +0 -2
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +0 -32
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +0 -491
- package/src/engine/apis/lmstudio-native.ts +0 -1438
- package/src/engine/apis/thinking-replay.ts +0 -11
- package/src/tools/string-enum.ts +0 -15
|
@@ -14,14 +14,16 @@ import type { ObservabilityContract } from "../domains/observability/index.js";
|
|
|
14
14
|
import type { ProvidersContract, ThinkingLevel } from "../domains/providers/index.js";
|
|
15
15
|
import type { ResourcesContract } from "../domains/resources/index.js";
|
|
16
16
|
import type { FleetNodeSnapshot } from "../domains/scheduling/cluster.js";
|
|
17
|
+
import type { DecisionLedgerEntry } from "../domains/session/entries.js";
|
|
17
18
|
import type { SessionContract, SessionEntry, TaskBoardSnapshot } from "../domains/session/index.js";
|
|
18
19
|
import type { ShareContract } from "../domains/share/index.js";
|
|
20
|
+
import type { UserTasksStore } from "../domains/user-tasks/store.js";
|
|
19
21
|
import { createAgentProgress } from "../engine/tui.js";
|
|
20
22
|
import type { ImageContent } from "../engine/types.js";
|
|
21
23
|
import type { AskUserHandler } from "../tools/ask-user.js";
|
|
22
24
|
import type { ToolRegistry } from "../tools/registry.js";
|
|
23
25
|
import { APPLICATION_DOUBLE_TAP_MS, type ApplicationController } from "./application-controller.js";
|
|
24
|
-
import type { ChatLoop } from "./chat-loop.js";
|
|
26
|
+
import type { ChatLoop, ChatLoopEvent } from "./chat-loop.js";
|
|
25
27
|
import { emitCommandNotice } from "./command-fallbacks.js";
|
|
26
28
|
import { appendNotice } from "./command-output.js";
|
|
27
29
|
import { createDispatchSteering } from "./dispatch-steering.js";
|
|
@@ -29,12 +31,13 @@ import { createEditorSubmitController } from "./editor-submit.js";
|
|
|
29
31
|
import { createInteractiveEventProjection } from "./interactive-event-projection.js";
|
|
30
32
|
import { createInteractiveInputRuntime } from "./interactive-input-runtime.js";
|
|
31
33
|
import { createInteractivePresentation } from "./interactive-presentation.js";
|
|
32
|
-
import { createProcessInteractiveShell } from "./interactive-shell.js";
|
|
34
|
+
import { createProcessInteractiveShell, getActiveRenderTrace } from "./interactive-shell.js";
|
|
33
35
|
import { createInteractiveSlashRuntime, resolveAvailableThinkingLevels } from "./interactive-slash-runtime.js";
|
|
34
36
|
import { createInteractiveSubscriptions } from "./interactive-subscriptions.js";
|
|
35
37
|
import { createInteractiveTickers } from "./interactive-tickers.js";
|
|
36
38
|
import { createOverlayLifecycle, type OverlayLifecycleController, type OverlayState } from "./overlay-lifecycle.js";
|
|
37
39
|
import { interopOverlaySurface } from "./overlays/interop.js";
|
|
40
|
+
import { settleChatBeforeSessionSwitch } from "./session-switch-settlement.js";
|
|
38
41
|
import { createSessionTranscript } from "./session-transcript.js";
|
|
39
42
|
import type {
|
|
40
43
|
ContextClearCommandOptions,
|
|
@@ -42,6 +45,8 @@ import type {
|
|
|
42
45
|
RunIo,
|
|
43
46
|
TaskMemorySeedCommandResult,
|
|
44
47
|
} from "./slash-commands.js";
|
|
48
|
+
import { processAutoPacingAllowed, resolveSmoothStreamingMode } from "./stream-pacing-policy.js";
|
|
49
|
+
import type { TerminalLease } from "./terminal-lease.js";
|
|
45
50
|
import { createWorkspaceFacts } from "./workspace-facts.js";
|
|
46
51
|
|
|
47
52
|
export {
|
|
@@ -105,6 +110,12 @@ export interface InteractiveDeps {
|
|
|
105
110
|
agents?: AgentsContract;
|
|
106
111
|
observability: ObservabilityContract;
|
|
107
112
|
chat: ChatLoop;
|
|
113
|
+
/** Fired once after the first real TUI render transaction issued all of its terminal writes. */
|
|
114
|
+
onFirstFrameCommit?: (frameId: number) => void;
|
|
115
|
+
/** Existing Stage 0 owner to hydrate in place. */
|
|
116
|
+
terminalLease?: TerminalLease;
|
|
117
|
+
/** Fired after the first committed frame containing the hydrated Stage 1 root. */
|
|
118
|
+
onHydratedFrameCommit?: (frameId: number | null) => void;
|
|
108
119
|
/** Startup notices collected before the TUI is ready; rendered in the transcript. */
|
|
109
120
|
initialNotices?: ReadonlyArray<string>;
|
|
110
121
|
resources?: ResourcesContract;
|
|
@@ -124,6 +135,12 @@ export interface InteractiveDeps {
|
|
|
124
135
|
readSessionEntries?: () => ReadonlyArray<SessionEntry>;
|
|
125
136
|
/** Live session task board for the footer tasks row and the /tasks overlay. */
|
|
126
137
|
getTaskBoard?: () => TaskBoardSnapshot | null;
|
|
138
|
+
/** Settled interview snapshots folded from the active session branch. */
|
|
139
|
+
getDecisionBoard?: () => ReadonlyArray<DecisionLedgerEntry>;
|
|
140
|
+
/** Append an acknowledged operator-authored decision revision. */
|
|
141
|
+
supersedeDecision?: (interviewId: string, key: string, correction?: string) => unknown;
|
|
142
|
+
/** Project-scoped operator task inbox used by `/tasks` subcommands. */
|
|
143
|
+
userTasks?: UserTasksStore;
|
|
127
144
|
/** Live, read-only task-memory state for status surfaces and the /memory overlay. */
|
|
128
145
|
getTaskMemoryStatus?: () => TaskMemoryOperatorStatus;
|
|
129
146
|
/** Newest structured handoff available for an opt-in seed, when enabled. */
|
|
@@ -174,7 +191,7 @@ export interface InteractiveDeps {
|
|
|
174
191
|
*/
|
|
175
192
|
onForkSession?: (parentTurnId: string) => void;
|
|
176
193
|
/**
|
|
177
|
-
* Run
|
|
194
|
+
* Run `/context compact` for the current session. Resolves the compaction model
|
|
178
195
|
* (settings.compaction.model with fallback to the orchestrator target),
|
|
179
196
|
* reads session entries, streams a summary via the session compaction
|
|
180
197
|
* engine, and persists a compactionSummary entry.
|
|
@@ -256,6 +273,8 @@ export interface KeyBindingDeps {
|
|
|
256
273
|
requestShutdown: () => void;
|
|
257
274
|
toggleStatus: () => void;
|
|
258
275
|
toggleDispatchBoard: () => void;
|
|
276
|
+
openTasks: () => void;
|
|
277
|
+
openDecisions: () => void;
|
|
259
278
|
backgroundDispatch: () => void;
|
|
260
279
|
openModelSelector: () => void;
|
|
261
280
|
openTree: () => void;
|
|
@@ -269,6 +288,7 @@ export interface KeyBindingDeps {
|
|
|
269
288
|
toggleAllThinkingExpansion: () => void;
|
|
270
289
|
openExternalEditor: () => void;
|
|
271
290
|
queueFollowUp: () => void;
|
|
291
|
+
interruptWithMessage: () => void;
|
|
272
292
|
restoreQueuedFollowUps: () => void;
|
|
273
293
|
}
|
|
274
294
|
|
|
@@ -314,6 +334,9 @@ export function dispatchInteractiveAction(id: ClioKeybinding, deps: KeyBindingDe
|
|
|
314
334
|
case "clio.message.followUp":
|
|
315
335
|
deps.queueFollowUp();
|
|
316
336
|
return true;
|
|
337
|
+
case "clio.message.interrupt":
|
|
338
|
+
deps.interruptWithMessage();
|
|
339
|
+
return true;
|
|
317
340
|
case "clio.message.dequeue":
|
|
318
341
|
deps.restoreQueuedFollowUps();
|
|
319
342
|
return true;
|
|
@@ -335,6 +358,12 @@ export function dispatchInteractiveAction(id: ClioKeybinding, deps: KeyBindingDe
|
|
|
335
358
|
case "clio.dispatchBoard.toggle":
|
|
336
359
|
deps.toggleDispatchBoard();
|
|
337
360
|
return true;
|
|
361
|
+
case "clio.tasks.open":
|
|
362
|
+
deps.openTasks();
|
|
363
|
+
return true;
|
|
364
|
+
case "clio.decisions.open":
|
|
365
|
+
deps.openDecisions();
|
|
366
|
+
return true;
|
|
338
367
|
case "clio.dispatch.background":
|
|
339
368
|
deps.backgroundDispatch();
|
|
340
369
|
return true;
|
|
@@ -363,6 +392,8 @@ export function routeInteractiveKey(data: string, deps: KeyBindingDeps): boolean
|
|
|
363
392
|
"clio.thinking.cycle",
|
|
364
393
|
"clio.session.tree",
|
|
365
394
|
"clio.dispatchBoard.toggle",
|
|
395
|
+
"clio.tasks.open",
|
|
396
|
+
"clio.decisions.open",
|
|
366
397
|
"clio.dispatch.background",
|
|
367
398
|
"clio.model.select",
|
|
368
399
|
// Match cycleBackward before cycleForward so a user rebind where one key
|
|
@@ -379,8 +410,48 @@ export function routeInteractiveKey(data: string, deps: KeyBindingDeps): boolean
|
|
|
379
410
|
}
|
|
380
411
|
|
|
381
412
|
export async function createInteractiveApplication(deps: InteractiveDeps): Promise<number> {
|
|
382
|
-
const
|
|
413
|
+
const initialSmoothStreaming = resolveSmoothStreamingMode(deps.getSettings?.().terminal.smoothStreaming ?? "off");
|
|
414
|
+
const initialAutoPacingAllowed = processAutoPacingAllowed(false);
|
|
415
|
+
const lease = deps.terminalLease;
|
|
416
|
+
const shell =
|
|
417
|
+
lease?.shell ??
|
|
418
|
+
createProcessInteractiveShell({
|
|
419
|
+
tuiMode: deps.getSettings?.().terminal.tuiMode ?? "regular",
|
|
420
|
+
streamPacingActive:
|
|
421
|
+
initialSmoothStreaming === "on" || (initialSmoothStreaming === "auto" && initialAutoPacingAllowed),
|
|
422
|
+
...(deps.onFirstFrameCommit ? { onFirstFrameCommit: deps.onFirstFrameCommit } : {}),
|
|
423
|
+
});
|
|
383
424
|
const { terminal, tui } = shell;
|
|
425
|
+
const renderTrace = getActiveRenderTrace();
|
|
426
|
+
const visibleEventIngress = new WeakMap<
|
|
427
|
+
object,
|
|
428
|
+
{ sequence: number; traceSequence: number; generation: number; ingressAt: number }
|
|
429
|
+
>();
|
|
430
|
+
let visibleEventSequence = 0;
|
|
431
|
+
let visibleEventGeneration = 0;
|
|
432
|
+
const recordChatEventIngress = (event: ChatLoopEvent): void => {
|
|
433
|
+
if (event.type === "agent_start") {
|
|
434
|
+
visibleEventGeneration += 1;
|
|
435
|
+
renderTrace?.beginGeneration();
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (event.type !== "text_delta" && event.type !== "thinking_delta") return;
|
|
439
|
+
visibleEventSequence += 1;
|
|
440
|
+
const ingress = {
|
|
441
|
+
sequence: visibleEventSequence,
|
|
442
|
+
traceSequence: visibleEventSequence,
|
|
443
|
+
generation: visibleEventGeneration,
|
|
444
|
+
ingressAt: performance.now(),
|
|
445
|
+
};
|
|
446
|
+
visibleEventIngress.set(event, ingress);
|
|
447
|
+
if (renderTrace) {
|
|
448
|
+
ingress.traceSequence = renderTrace.recordVisibleEvent({
|
|
449
|
+
kind: event.type === "text_delta" ? "text" : "thinking",
|
|
450
|
+
contentIndex: event.contentIndex,
|
|
451
|
+
delta: event.delta,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
};
|
|
384
455
|
let applicationController: ApplicationController;
|
|
385
456
|
const workspaceFacts = createWorkspaceFacts({
|
|
386
457
|
cwd: process.cwd(),
|
|
@@ -406,9 +477,20 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
406
477
|
* the footer reads it and the input runtime that flips it is built later.
|
|
407
478
|
*/
|
|
408
479
|
let leaderArmed = false;
|
|
480
|
+
/**
|
|
481
|
+
* A Ctrl+C armed the double tap and its 500ms window is still open. Owned
|
|
482
|
+
* here for the same reason as the leader flag above.
|
|
483
|
+
*/
|
|
484
|
+
let shutdownArmed = false;
|
|
409
485
|
const presentation = createInteractivePresentation({
|
|
410
486
|
bus: deps.bus,
|
|
411
487
|
getLeaderArmed: () => leaderArmed,
|
|
488
|
+
getShutdownArmed: () => shutdownArmed,
|
|
489
|
+
resolveVisibleEventSequence: (event) => visibleEventIngress.get(event)?.traceSequence ?? null,
|
|
490
|
+
resolveStreamIngress: (event) => visibleEventIngress.get(event) ?? null,
|
|
491
|
+
commitFrame: (reason) => shell.commitCurrentFrame(reason === "teardown" ? 300 : 30_000),
|
|
492
|
+
hasObservedBackpressure: () => shell.hasObservedBackpressure(),
|
|
493
|
+
onSmoothStreamingMode: (_mode, pacingActive) => shell.setStreamPacingActive(pacingActive),
|
|
412
494
|
providers: deps.providers,
|
|
413
495
|
dispatch: deps.dispatch,
|
|
414
496
|
observability: deps.observability,
|
|
@@ -417,7 +499,14 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
417
499
|
sessionTranscript,
|
|
418
500
|
tui,
|
|
419
501
|
terminal,
|
|
420
|
-
mount: (root, editor) => shell.mount(root, editor),
|
|
502
|
+
...(!lease ? { mount: (root, editor) => shell.mount(root, editor) } : {}),
|
|
503
|
+
...(lease
|
|
504
|
+
? {
|
|
505
|
+
editor: lease.editor,
|
|
506
|
+
keybindings: lease.keybindings,
|
|
507
|
+
bootPending: lease.pending,
|
|
508
|
+
}
|
|
509
|
+
: {}),
|
|
421
510
|
...(deps.getSettings ? { getSettings: deps.getSettings } : {}),
|
|
422
511
|
...(deps.resources ? { resources: deps.resources } : {}),
|
|
423
512
|
...(deps.session ? { session: deps.session } : {}),
|
|
@@ -448,8 +537,8 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
448
537
|
const agentProgress = createAgentProgress(terminal);
|
|
449
538
|
const busNoticeSink = {
|
|
450
539
|
appendReplayBlock: (renderBlock: Parameters<typeof chatPanel.appendReplayBlock>[0]) =>
|
|
451
|
-
chatPanel.appendReplayBlock(renderBlock),
|
|
452
|
-
requestRender: () =>
|
|
540
|
+
chatRenderer.mutate(() => chatPanel.appendReplayBlock(renderBlock), "bus-notice"),
|
|
541
|
+
requestRender: () => {},
|
|
453
542
|
};
|
|
454
543
|
const eventProjection = createInteractiveEventProjection({
|
|
455
544
|
bus: deps.bus,
|
|
@@ -458,6 +547,10 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
458
547
|
...(deps.initialNotices ? { initialNotices: deps.initialNotices } : {}),
|
|
459
548
|
...(deps.getSettings ? { getSettings: deps.getSettings } : {}),
|
|
460
549
|
getTerminalColumns: () => terminal.columns,
|
|
550
|
+
onChatEventIngress: (event) => {
|
|
551
|
+
recordChatEventIngress(event);
|
|
552
|
+
presentation.recordChatEvent(event);
|
|
553
|
+
},
|
|
461
554
|
applyChatEvent: (event) => chatRenderer.applyEvent(event),
|
|
462
555
|
setFollowUpMessages: (messages) => followUpQueuePanel.setMessages(messages),
|
|
463
556
|
isAskUserWaiting: () => overlayLifecycle.isAskUserWaiting(),
|
|
@@ -467,6 +560,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
467
560
|
recordToolEnd: (_toolName, toolCallId, isError, truncated) =>
|
|
468
561
|
presentation.recordToolEnd({ toolCallId, isError, truncated }),
|
|
469
562
|
setStatusLine: (line) => chatPanel.setStatusLine(line),
|
|
563
|
+
setLiveReasoning: (view) => chatPanel.setLiveReasoning(view),
|
|
470
564
|
setLastTurnSummary: (summary) => presentation.setLastTurnSummary(summary),
|
|
471
565
|
startTerminalProgress: () => agentProgress.start(),
|
|
472
566
|
stopTerminalProgress: () => agentProgress.stop(),
|
|
@@ -477,6 +571,12 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
477
571
|
dismissNotification: (key) => notifications.dismiss(key),
|
|
478
572
|
appendTranscriptNotice: (level, text) => appendNotice(level, text, busNoticeSink),
|
|
479
573
|
refreshSettingsOverlay: () => overlayLifecycle.refreshSettingsOverlay(),
|
|
574
|
+
onConfigHotReload: (settings) => {
|
|
575
|
+
const mode = resolveSmoothStreamingMode(settings.terminal.smoothStreaming);
|
|
576
|
+
const autoAllowed = processAutoPacingAllowed(shell.hasObservedBackpressure());
|
|
577
|
+
chatRenderer.setSmoothStreamingMode(mode);
|
|
578
|
+
shell.setStreamPacingActive(mode === "on" || (mode === "auto" && autoAllowed));
|
|
579
|
+
},
|
|
480
580
|
});
|
|
481
581
|
// The overlay reads the report this process already produced at boot; it
|
|
482
582
|
// never probes on a keystroke.
|
|
@@ -486,14 +586,22 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
486
586
|
io,
|
|
487
587
|
bus: deps.bus,
|
|
488
588
|
dispatch: deps.dispatch,
|
|
589
|
+
...(deps.session ? { session: deps.session } : {}),
|
|
489
590
|
providers: deps.providers,
|
|
490
591
|
chat: deps.chat,
|
|
491
|
-
chatPanel
|
|
592
|
+
chatPanel: {
|
|
593
|
+
appendReplayBlock: (...args) => chatRenderer.mutate(() => chatPanel.appendReplayBlock(...args), "slash-output"),
|
|
594
|
+
appendUser: (text) => chatRenderer.mutate(() => chatPanel.appendUser(text), "user-submit"),
|
|
595
|
+
clearFoldOverrides: () => chatRenderer.mutate(() => chatPanel.clearFoldOverrides(), "output-detail"),
|
|
596
|
+
},
|
|
597
|
+
beforeSemanticSubmit: () => chatRenderer.flush(),
|
|
598
|
+
settleVisibleFrame: (reason) => chatRenderer.flushAndCommit(reason),
|
|
492
599
|
...(deps.resources ? { resources: deps.resources } : {}),
|
|
493
600
|
...(deps.extensions ? { extensions: deps.extensions } : {}),
|
|
494
601
|
...(interopSurface ? { interop: interopSurface } : {}),
|
|
495
602
|
...(deps.agents ? { agents: deps.agents } : {}),
|
|
496
603
|
...(deps.share ? { share: deps.share } : {}),
|
|
604
|
+
...(deps.userTasks ? { userTasks: deps.userTasks } : {}),
|
|
497
605
|
...(deps.getSettings ? { getSettings: deps.getSettings } : {}),
|
|
498
606
|
...(deps.writeSettings ? { writeSettings: deps.writeSettings } : {}),
|
|
499
607
|
...(deps.commitSetting ? { commitSetting: deps.commitSetting } : {}),
|
|
@@ -516,6 +624,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
516
624
|
openCost: () => openCostOverlayState(),
|
|
517
625
|
openContextView: () => openContextViewOverlayState(),
|
|
518
626
|
openTasks: () => openTasksOverlayState(),
|
|
627
|
+
openDecisions: () => openDecisionsOverlayState(),
|
|
519
628
|
openMemory: () => openMemoryOverlayState(),
|
|
520
629
|
...(deps.seedTaskMemory ? { seedTaskMemory: deps.seedTaskMemory } : {}),
|
|
521
630
|
openView: (filter) => openViewOverlayState(filter),
|
|
@@ -545,8 +654,14 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
545
654
|
dispatch: deps.dispatch,
|
|
546
655
|
...(deps.session ? { session: deps.session } : {}),
|
|
547
656
|
sessionTranscript,
|
|
548
|
-
chatPanel
|
|
657
|
+
chatPanel: {
|
|
658
|
+
appendReplayBlock: (...args) =>
|
|
659
|
+
chatRenderer.mutate(() => chatPanel.appendReplayBlock(...args), "editor-command-output"),
|
|
660
|
+
},
|
|
661
|
+
beforeSemanticBoundary: () => chatRenderer.flush(),
|
|
662
|
+
settleVisibleFrame: (reason) => chatRenderer.flushAndCommit(reason),
|
|
549
663
|
dispatchCommand: slashRuntime.dispatchCommand,
|
|
664
|
+
dispatchCommandAsync: slashRuntime.admitCommand,
|
|
550
665
|
collapseLaunchpadBeforeSubmit: () => presentation.collapseWelcomeDashboard(),
|
|
551
666
|
expandSubmit: (text) => expandInteractiveSubmitAsync(text, deps.resources),
|
|
552
667
|
notify,
|
|
@@ -560,6 +675,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
560
675
|
contextActivityStore,
|
|
561
676
|
getOverlayState: () => overlayLifecycle?.getState() ?? "closed",
|
|
562
677
|
isFooterExpanded: () => footer.isExpanded(),
|
|
678
|
+
...(deps.getTaskBoard ? { getTaskBoard: deps.getTaskBoard } : {}),
|
|
563
679
|
});
|
|
564
680
|
/**
|
|
565
681
|
* The one transcript reset. The chat panel and the worker fold are two views
|
|
@@ -569,8 +685,10 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
569
685
|
* because the subscriptions that own the fold are built below.
|
|
570
686
|
*/
|
|
571
687
|
const resetTranscript = (): void => {
|
|
572
|
-
|
|
573
|
-
|
|
688
|
+
chatRenderer.reset(() => {
|
|
689
|
+
chatPanel.reset();
|
|
690
|
+
interactiveSubscriptions.workers.reset();
|
|
691
|
+
});
|
|
574
692
|
};
|
|
575
693
|
overlayLifecycle = createOverlayLifecycle({
|
|
576
694
|
app: deps,
|
|
@@ -599,6 +717,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
599
717
|
openContextViewOverlayState,
|
|
600
718
|
openContextResetOverlayState,
|
|
601
719
|
openTasksOverlayState,
|
|
720
|
+
openDecisionsOverlayState,
|
|
602
721
|
openMemoryOverlayState,
|
|
603
722
|
openViewOverlayState,
|
|
604
723
|
openModelOverlayState,
|
|
@@ -633,17 +752,20 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
633
752
|
const current = editor.getText();
|
|
634
753
|
editor.setText([restored.join("\n\n"), current].filter((part) => part.trim().length > 0).join("\n\n"));
|
|
635
754
|
}
|
|
755
|
+
chatRenderer.flush();
|
|
636
756
|
deps.chat.cancel();
|
|
637
757
|
deps.toolRegistry?.cancelParkedCalls("run cancelled by operator");
|
|
638
758
|
footer.refresh();
|
|
639
759
|
tui.requestRender();
|
|
640
760
|
};
|
|
641
761
|
|
|
642
|
-
const startNewSession = (): void => {
|
|
762
|
+
const startNewSession = async (): Promise<void> => {
|
|
643
763
|
if (!deps.onNewSession) {
|
|
644
764
|
emitCommandNotice(slashRuntime.notice, "error", "new", "session contract unavailable");
|
|
645
765
|
return;
|
|
646
766
|
}
|
|
767
|
+
const settlement = settleChatBeforeSessionSwitch(deps.chat);
|
|
768
|
+
if (settlement) await settlement;
|
|
647
769
|
deps.onNewSession();
|
|
648
770
|
deps.observability.resetSession();
|
|
649
771
|
presentation.resetForNewSession();
|
|
@@ -686,7 +808,7 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
686
808
|
// The reducer mutates one state object per assignment, so the panel is
|
|
687
809
|
// handed that object rather than a copy: a streamed delta reaches the
|
|
688
810
|
// screen by invalidating a cached render, not by rebuilding the entry.
|
|
689
|
-
applyWorkerState: (state) => chatPanel.applyWorkerState(state),
|
|
811
|
+
applyWorkerState: (state) => chatRenderer.mutate(() => chatPanel.applyWorkerState(state), "worker-state"),
|
|
690
812
|
recordWorkerRun: (fields) => {
|
|
691
813
|
// A `/run` is an operator action that produced durable state, so it
|
|
692
814
|
// opens a session the same way a local `!bash` line does. Persistence
|
|
@@ -722,6 +844,9 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
722
844
|
onLeaderStateChange: (pending) => {
|
|
723
845
|
leaderArmed = pending;
|
|
724
846
|
},
|
|
847
|
+
onShutdownArmedChange: (armed) => {
|
|
848
|
+
shutdownArmed = armed;
|
|
849
|
+
},
|
|
725
850
|
dispatchBoard,
|
|
726
851
|
steerSelectedDispatch,
|
|
727
852
|
cancelSelectedDispatch,
|
|
@@ -732,7 +857,25 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
732
857
|
editorSubmit,
|
|
733
858
|
requestRender: () => tui.requestRender(),
|
|
734
859
|
notifications,
|
|
735
|
-
chatPanel
|
|
860
|
+
chatPanel: {
|
|
861
|
+
toggleLastToolExpanded: () => chatPanel.toggleLastToolExpanded(),
|
|
862
|
+
toggleAllToolsExpanded: () => chatPanel.toggleAllToolsExpanded(),
|
|
863
|
+
toggleLiveToolOutput: () => chatPanel.toggleLiveToolOutput(),
|
|
864
|
+
toggleLastThinking: () => {
|
|
865
|
+
let changed = false;
|
|
866
|
+
chatRenderer.mutate(() => {
|
|
867
|
+
changed = chatPanel.toggleLastThinking();
|
|
868
|
+
}, "thinking-visibility");
|
|
869
|
+
return changed;
|
|
870
|
+
},
|
|
871
|
+
toggleAllThinking: () => {
|
|
872
|
+
let changed = false;
|
|
873
|
+
chatRenderer.mutate(() => {
|
|
874
|
+
changed = chatPanel.toggleAllThinking();
|
|
875
|
+
}, "thinking-visibility");
|
|
876
|
+
return changed;
|
|
877
|
+
},
|
|
878
|
+
},
|
|
736
879
|
shutdown: {
|
|
737
880
|
stopTickers: presentation.stopTickers,
|
|
738
881
|
disposeInteractiveTickers: interactiveTickers.dispose,
|
|
@@ -745,11 +888,54 @@ export async function createInteractiveApplication(deps: InteractiveDeps): Promi
|
|
|
745
888
|
disposeChat: () => deps.chat.dispose(),
|
|
746
889
|
disposeSubscriptions: interactiveSubscriptions.dispose,
|
|
747
890
|
},
|
|
748
|
-
|
|
891
|
+
beforeStopUi: (() => {
|
|
892
|
+
let settlement: Promise<void> | null = null;
|
|
893
|
+
return () => {
|
|
894
|
+
settlement ??= chatRenderer.flushAndCommit("teardown").finally(() => chatRenderer.dispose());
|
|
895
|
+
return settlement;
|
|
896
|
+
};
|
|
897
|
+
})(),
|
|
898
|
+
stopUi: () => {
|
|
899
|
+
if (lease) void lease.close();
|
|
900
|
+
else shell.stop();
|
|
901
|
+
},
|
|
749
902
|
cancelParkedCalls: (reason) => deps.toolRegistry?.cancelParkedCalls(reason),
|
|
750
|
-
onShutdown:
|
|
751
|
-
|
|
903
|
+
onShutdown: async () => {
|
|
904
|
+
try {
|
|
905
|
+
await deps.onShutdown();
|
|
906
|
+
} finally {
|
|
907
|
+
if (lease) await lease.close();
|
|
908
|
+
else await shell.settle();
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
registerInputListener: (listener) => {
|
|
912
|
+
if (lease) lease.registerApplicationInput(listener);
|
|
913
|
+
else tui.addInputListener(listener);
|
|
914
|
+
},
|
|
915
|
+
...(lease
|
|
916
|
+
? {
|
|
917
|
+
signals: lease.applicationSignals,
|
|
918
|
+
// The lease registered its exactly-once drain before hydration.
|
|
919
|
+
registerTerminalTeardown: () => {},
|
|
920
|
+
}
|
|
921
|
+
: {}),
|
|
922
|
+
...(renderTrace
|
|
923
|
+
? {
|
|
924
|
+
onInputIngress: (action, data) =>
|
|
925
|
+
renderTrace.recordInputIngress(action, Buffer.byteLength(data, "utf8"), action !== "no-visual-change"),
|
|
926
|
+
}
|
|
927
|
+
: {}),
|
|
752
928
|
});
|
|
753
929
|
|
|
930
|
+
if (lease) {
|
|
931
|
+
const adopted = lease.adopt({
|
|
932
|
+
root: presentation.root,
|
|
933
|
+
editorChrome: presentation.editorChrome,
|
|
934
|
+
admitSubmission: (submission) => editorSubmit.admitCapturedText(submission.rawText, lease.abortSignal),
|
|
935
|
+
...(deps.onHydratedFrameCommit ? { onHydratedFrame: deps.onHydratedFrameCommit } : {}),
|
|
936
|
+
});
|
|
937
|
+
if (!adopted) void applicationController.shutdown();
|
|
938
|
+
}
|
|
939
|
+
|
|
754
940
|
return applicationController.run;
|
|
755
941
|
}
|
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
type AgentStatus,
|
|
30
30
|
INLINE_STATUS_INDENT_COLS,
|
|
31
|
+
type ReasoningUsageView,
|
|
32
|
+
reasoningFromTally,
|
|
31
33
|
resolveInlineVerb,
|
|
32
34
|
type StatusPhase,
|
|
33
35
|
spinnerFrame,
|
|
@@ -57,6 +59,8 @@ export interface InteractiveEventProjectionDeps {
|
|
|
57
59
|
getSettings?: () => Readonly<ClioSettings>;
|
|
58
60
|
getTerminalColumns: () => number;
|
|
59
61
|
now?: () => number;
|
|
62
|
+
/** Canonical synchronous ingress hook, before any projection branch consumes the event. */
|
|
63
|
+
onChatEventIngress?: (event: ChatLoopEvent) => void;
|
|
60
64
|
applyChatEvent: (event: ChatLoopEvent) => void;
|
|
61
65
|
setFollowUpMessages: (messages: QueuedChatMessage[]) => void;
|
|
62
66
|
isAskUserWaiting: () => boolean;
|
|
@@ -65,6 +69,11 @@ export interface InteractiveEventProjectionDeps {
|
|
|
65
69
|
recordToolStart: (toolName: string, toolCallId: string) => void;
|
|
66
70
|
recordToolEnd: (toolName: string, toolCallId: string, isError: boolean, truncated: boolean) => void;
|
|
67
71
|
setStatusLine: (line: InteractiveStatusLine | null) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Publish the live turn's reasoning projection to the transcript. Optional so
|
|
74
|
+
* a host without a chat panel still gets every other projection.
|
|
75
|
+
*/
|
|
76
|
+
setLiveReasoning?: (view: ReasoningUsageView | null) => void;
|
|
68
77
|
setLastTurnSummary: (summary: TurnSummary) => void;
|
|
69
78
|
startTerminalProgress: () => void;
|
|
70
79
|
stopTerminalProgress: () => void;
|
|
@@ -75,6 +84,7 @@ export interface InteractiveEventProjectionDeps {
|
|
|
75
84
|
dismissNotification: (key: string) => void;
|
|
76
85
|
appendTranscriptNotice: (level: InteractiveTranscriptNoticeLevel, text: string) => void;
|
|
77
86
|
refreshSettingsOverlay: () => void;
|
|
87
|
+
onConfigHotReload?: (settings: Readonly<ClioSettings>) => void;
|
|
78
88
|
}
|
|
79
89
|
|
|
80
90
|
export interface InteractiveEventProjection {
|
|
@@ -123,6 +133,7 @@ export function createInteractiveEventProjection(deps: InteractiveEventProjectio
|
|
|
123
133
|
const remainingUnsubscribers: Array<() => void> = [];
|
|
124
134
|
primaryUnsubscribers.push(
|
|
125
135
|
deps.chat.onEvent((event) => {
|
|
136
|
+
deps.onChatEventIngress?.(event);
|
|
126
137
|
if (event.type === "notice") {
|
|
127
138
|
if (event.surface === "transcript") {
|
|
128
139
|
deps.applyChatEvent(event);
|
|
@@ -173,6 +184,11 @@ export function createInteractiveEventProjection(deps: InteractiveEventProjectio
|
|
|
173
184
|
let statusInlineFrame = 0;
|
|
174
185
|
primaryUnsubscribers.push(
|
|
175
186
|
deps.status.subscribe((status) => {
|
|
187
|
+
// One projection of the run tally reaches the transcript, so the live
|
|
188
|
+
// line, the turn receipt, and the footer state the same number.
|
|
189
|
+
deps.setLiveReasoning?.(
|
|
190
|
+
status.phase === "idle" || status.phase === "ended" ? null : reasoningFromTally(status.runTally),
|
|
191
|
+
);
|
|
176
192
|
if (status.phase === "idle") {
|
|
177
193
|
deps.setStatusLine(null);
|
|
178
194
|
} else if (status.phase === "ended") {
|
|
@@ -310,7 +326,8 @@ export function createInteractiveEventProjection(deps: InteractiveEventProjectio
|
|
|
310
326
|
deps.refreshFooter();
|
|
311
327
|
deps.requestRender();
|
|
312
328
|
}),
|
|
313
|
-
deps.bus.on(BusChannels.ConfigHotReload, () => {
|
|
329
|
+
deps.bus.on(BusChannels.ConfigHotReload, (payload) => {
|
|
330
|
+
deps.onConfigHotReload?.(payload.settings);
|
|
314
331
|
deps.refreshSettingsOverlay();
|
|
315
332
|
}),
|
|
316
333
|
deps.bus.on(BusChannels.ConfigReloadFailed, (payload) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getTerminationCoordinator } from "../core/termination.js";
|
|
2
2
|
import type { ClioKeybinding } from "../domains/config/keybindings.js";
|
|
3
|
-
import { isKeyRelease } from "../engine/tui.js";
|
|
3
|
+
import { isKeyRelease, type Keybinding } from "../engine/tui.js";
|
|
4
4
|
import {
|
|
5
5
|
type ApplicationClock,
|
|
6
6
|
type ApplicationController,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "./application-controller.js";
|
|
13
13
|
import { createLeaderKeyController, type LeaderTarget } from "./leader-key.js";
|
|
14
14
|
import { type OverlayState, routeOverlayKey } from "./overlay-lifecycle.js";
|
|
15
|
+
import type { RenderInputAction } from "./render-trace.js";
|
|
15
16
|
|
|
16
17
|
export interface InteractiveInputKeyActionDeps {
|
|
17
18
|
matches: (data: string, id: ClioKeybinding) => boolean;
|
|
@@ -20,6 +21,8 @@ export interface InteractiveInputKeyActionDeps {
|
|
|
20
21
|
requestShutdown: () => void;
|
|
21
22
|
toggleStatus: () => void;
|
|
22
23
|
toggleDispatchBoard: () => void;
|
|
24
|
+
openTasks: () => void;
|
|
25
|
+
openDecisions: () => void;
|
|
23
26
|
backgroundDispatch: () => void;
|
|
24
27
|
openModelSelector: () => void;
|
|
25
28
|
openTree: () => void;
|
|
@@ -33,12 +36,13 @@ export interface InteractiveInputKeyActionDeps {
|
|
|
33
36
|
toggleAllThinkingExpansion: () => void;
|
|
34
37
|
openExternalEditor: () => void;
|
|
35
38
|
queueFollowUp: () => void;
|
|
39
|
+
interruptWithMessage: () => void;
|
|
36
40
|
restoreQueuedFollowUps: () => void;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
export interface InteractiveInputRuntimeDeps {
|
|
40
44
|
keybindings: {
|
|
41
|
-
matches(data: string, id:
|
|
45
|
+
matches(data: string, id: Keybinding): boolean;
|
|
42
46
|
leaderTargets(): ReadonlyArray<LeaderTarget>;
|
|
43
47
|
};
|
|
44
48
|
dispatchAction: (id: ClioKeybinding, deps: InteractiveInputKeyActionDeps) => boolean;
|
|
@@ -61,10 +65,14 @@ export interface InteractiveInputRuntimeDeps {
|
|
|
61
65
|
toggleDispatchBoardOverlay(): void;
|
|
62
66
|
openModelOverlayState(): void;
|
|
63
67
|
openTreeOverlayState(): void;
|
|
68
|
+
openTasksOverlayState(): void;
|
|
69
|
+
openDecisionsOverlayState(): void;
|
|
64
70
|
};
|
|
65
71
|
refreshFooter: () => void;
|
|
66
72
|
/** Armed/disarmed transitions of the Ctrl+G leader, for the footer indicator. */
|
|
67
73
|
onLeaderStateChange?: (pending: boolean) => void;
|
|
74
|
+
/** Armed/disarmed transitions of the Ctrl+C double tap, for the same indicator row. */
|
|
75
|
+
onShutdownArmedChange?: (armed: boolean) => void;
|
|
68
76
|
dispatchBoard: {
|
|
69
77
|
selectPrevious(): void;
|
|
70
78
|
selectNext(): void;
|
|
@@ -78,6 +86,7 @@ export interface InteractiveInputRuntimeDeps {
|
|
|
78
86
|
editorSubmit: {
|
|
79
87
|
openExternalEditorForInput(): void;
|
|
80
88
|
queueFollowUpFromEditor(): void;
|
|
89
|
+
interruptFromEditor(): void;
|
|
81
90
|
restoreQueuedFollowUpsToEditor(): void;
|
|
82
91
|
};
|
|
83
92
|
requestRender: () => void;
|
|
@@ -106,12 +115,14 @@ export interface InteractiveInputRuntimeDeps {
|
|
|
106
115
|
disposeSubscriptions(): void;
|
|
107
116
|
};
|
|
108
117
|
stopUi: () => void;
|
|
118
|
+
beforeStopUi?: () => Promise<void>;
|
|
109
119
|
cancelParkedCalls: (reason: string) => void;
|
|
110
120
|
onShutdown: () => Promise<void>;
|
|
111
121
|
reportShutdownFailure?: (step: string, error: unknown) => void;
|
|
112
122
|
/** Defaults to the process termination coordinator's drain phase. */
|
|
113
|
-
registerTerminalTeardown?: (teardown: () => void) => void;
|
|
123
|
+
registerTerminalTeardown?: (teardown: () => void | Promise<void>) => void;
|
|
114
124
|
registerInputListener: (listener: (data: string) => ApplicationInputResult) => void;
|
|
125
|
+
onInputIngress?: (action: RenderInputAction, data: string) => void;
|
|
115
126
|
intervalsToClear?: ReadonlyArray<ApplicationIntervalHandle>;
|
|
116
127
|
clock?: ApplicationClock;
|
|
117
128
|
signals?: ApplicationSignalCoordinator;
|
|
@@ -133,6 +144,8 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
133
144
|
requestShutdown: () => void controller.shutdown(),
|
|
134
145
|
toggleStatus: deps.overlay.toggleFooterDashboardState,
|
|
135
146
|
toggleDispatchBoard: deps.overlay.toggleDispatchBoardOverlay,
|
|
147
|
+
openTasks: deps.overlay.openTasksOverlayState,
|
|
148
|
+
openDecisions: deps.overlay.openDecisionsOverlayState,
|
|
136
149
|
backgroundDispatch: deps.actions.backgroundActiveDispatch,
|
|
137
150
|
openModelSelector: deps.overlay.openModelOverlayState,
|
|
138
151
|
openTree: deps.overlay.openTreeOverlayState,
|
|
@@ -161,6 +174,7 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
161
174
|
},
|
|
162
175
|
openExternalEditor: deps.editorSubmit.openExternalEditorForInput,
|
|
163
176
|
queueFollowUp: deps.editorSubmit.queueFollowUpFromEditor,
|
|
177
|
+
interruptWithMessage: deps.editorSubmit.interruptFromEditor,
|
|
164
178
|
restoreQueuedFollowUps: deps.editorSubmit.restoreQueuedFollowUpsToEditor,
|
|
165
179
|
});
|
|
166
180
|
const leaderKeys = createLeaderKeyController({
|
|
@@ -212,6 +226,9 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
212
226
|
},
|
|
213
227
|
(input, id) => deps.keybindings.matches(input, id),
|
|
214
228
|
),
|
|
229
|
+
matchesEditorHistory: (data) =>
|
|
230
|
+
deps.keybindings.matches(data, "tui.editor.historyPrevious") ||
|
|
231
|
+
deps.keybindings.matches(data, "tui.editor.historyNext"),
|
|
215
232
|
matchesAction: (data, id) => deps.keybindings.matches(data, id),
|
|
216
233
|
dispatchAction: (id) => deps.dispatchAction(id, keyActionDeps()),
|
|
217
234
|
cancelActiveEditorBash: deps.cancelActiveEditorBash,
|
|
@@ -220,6 +237,13 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
220
237
|
getEditorText: () => deps.editor.getText(),
|
|
221
238
|
clearEditor: () => deps.editor.setText(""),
|
|
222
239
|
requestRender: deps.requestRender,
|
|
240
|
+
// The footer pulls the flag when it refreshes, so the refresh has to land
|
|
241
|
+
// before the controller asks for the frame. The controller owns the render
|
|
242
|
+
// request on this path, which is why this hook does not make one.
|
|
243
|
+
onShutdownArmedChange: (armed) => {
|
|
244
|
+
deps.onShutdownArmedChange?.(armed);
|
|
245
|
+
deps.refreshFooter();
|
|
246
|
+
},
|
|
223
247
|
closeOverlay: () => deps.overlay.closeOverlay(),
|
|
224
248
|
listNotifications: () => deps.notifications.list(),
|
|
225
249
|
dismissNotification: (id) => deps.notifications.dismiss(id),
|
|
@@ -242,6 +266,7 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
242
266
|
() => deps.shutdown.disposeSubscriptions(),
|
|
243
267
|
],
|
|
244
268
|
stopUi: deps.stopUi,
|
|
269
|
+
...(deps.beforeStopUi ? { beforeStopUi: deps.beforeStopUi } : {}),
|
|
245
270
|
cancelParkedCalls: deps.cancelParkedCalls,
|
|
246
271
|
onShutdown: deps.onShutdown,
|
|
247
272
|
registerTerminalTeardown:
|
|
@@ -256,6 +281,27 @@ export function createInteractiveInputRuntime(deps: InteractiveInputRuntimeDeps)
|
|
|
256
281
|
);
|
|
257
282
|
}),
|
|
258
283
|
});
|
|
259
|
-
deps.registerInputListener(
|
|
284
|
+
deps.registerInputListener((data) => {
|
|
285
|
+
deps.onInputIngress?.(classifyInputAction(data, deps), data);
|
|
286
|
+
return controller.handleInput(data);
|
|
287
|
+
});
|
|
260
288
|
return controller;
|
|
261
289
|
}
|
|
290
|
+
|
|
291
|
+
function classifyInputAction(data: string, deps: InteractiveInputRuntimeDeps): RenderInputAction {
|
|
292
|
+
if (data.length === 0 || isKeyRelease(data)) return "no-visual-change";
|
|
293
|
+
if (deps.keybindings.matches(data, "tui.input.submit")) return "submit";
|
|
294
|
+
const sgrMousePrefix = `${String.fromCharCode(27)}[<`;
|
|
295
|
+
if (
|
|
296
|
+
data.startsWith(`${sgrMousePrefix}64;`) ||
|
|
297
|
+
data.startsWith(`${sgrMousePrefix}65;`) ||
|
|
298
|
+
deps.keybindings.matches(data, "tui.altScreen.pageUp") ||
|
|
299
|
+
deps.keybindings.matches(data, "tui.altScreen.pageDown") ||
|
|
300
|
+
deps.keybindings.matches(data, "tui.editor.pageUp") ||
|
|
301
|
+
deps.keybindings.matches(data, "tui.editor.pageDown")
|
|
302
|
+
) {
|
|
303
|
+
return "scroll";
|
|
304
|
+
}
|
|
305
|
+
if (deps.overlay.getState() !== "closed") return "overlay";
|
|
306
|
+
return "editor";
|
|
307
|
+
}
|