@iowarp/clio-coder 0.3.0 → 0.3.1
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 +33 -0
- package/README.md +50 -53
- package/dist/acp-FPR54DGL.js +138 -0
- package/dist/{agents-Q4MYPMUW.js → agents-OGPIHPJH.js} +33 -25
- package/dist/assets/codewiki.json +1 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/LICENSE +21 -0
- package/dist/assets/grammars/notices/@vscode__tree-sitter-wasm/cgmanifest.json +16 -0
- package/dist/assets/grammars/notices/tree-sitter-wasms/LICENSE +24 -0
- package/dist/assets/grammars/tree-sitter-c-sharp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-c.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-cpp.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-go.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-java.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-python.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-rust.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/assets/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/assets/grammars/tree-sitter.wasm +0 -0
- package/dist/{auth-O6HYIJ6J.js → auth-IC3K6NIZ.js} +22 -15
- package/dist/{chunk-KKKPTZLM.js → chunk-2STGEDFV.js} +8 -1
- package/dist/chunk-3I7MS7N2.js +40 -0
- package/dist/chunk-3R73A4XB.js +69 -0
- package/dist/{chunk-26BZQOAD.js → chunk-474KN5II.js} +86 -115
- package/dist/{chunk-NI4DEJMC.js → chunk-4QKXUHSR.js} +26 -3
- package/dist/{chunk-X3BR7HWV.js → chunk-5WIGXA4T.js} +7 -1
- package/dist/{chunk-TFSSEXL6.js → chunk-673JJUWJ.js} +14 -4
- package/dist/{chunk-GNGDQYDU.js → chunk-7SS2CTV2.js} +27922 -1249
- package/dist/{chunk-7RBKDI66.js → chunk-ASND7OZK.js} +104 -12
- package/dist/{chunk-X3NE4WVW.js → chunk-BNAZZHFG.js} +7 -1
- package/dist/{chunk-RQDWMVRB.js → chunk-BSU2YIWB.js} +9 -3
- package/dist/{chunk-CLJ5HLUD.js → chunk-C4PTHK7P.js} +24 -5
- package/dist/{chunk-QV47YRF4.js → chunk-CGKSTWHD.js} +7 -1
- package/dist/{chunk-BYEU76JP.js → chunk-DKGKUHFA.js} +34 -9
- package/dist/chunk-EYOKLTMF.js +170 -0
- package/dist/{chunk-PS4PFJQP.js → chunk-FCIH3BIZ.js} +15258 -14130
- package/dist/{chunk-2J63S4SF.js → chunk-FST4FYJB.js} +82 -14
- package/dist/{chunk-3DANZDGR.js → chunk-G34LV2PF.js} +34 -9
- package/dist/{chunk-BBUH4VAA.js → chunk-GAEBEQVI.js} +34 -21
- package/dist/chunk-GB6QRBXN.js +8543 -0
- package/dist/chunk-GEP36Y4X.js +12796 -0
- package/dist/{chunk-TKHQ4DGZ.js → chunk-H6F6BYOH.js} +496 -121
- package/dist/{chunk-UGYAX5YI.js → chunk-HQQID6OA.js} +10 -5
- package/dist/chunk-IHXBNWMM.js +137 -0
- package/dist/{chunk-ME6DNWIU.js → chunk-IS3ONKU3.js} +7 -1
- package/dist/{chunk-DXQNI4PC.js → chunk-IWHMRKLL.js} +8 -1
- package/dist/chunk-K2ITRMHZ.js +642 -0
- package/dist/{chunk-KBR4MZZR.js → chunk-K5XEMXTI.js} +7 -1
- package/dist/{chunk-AMFR5YA3.js → chunk-KKNLWXI6.js} +24 -10
- package/dist/{chunk-JWHCJDCI.js → chunk-KY56HMHH.js} +145 -61
- package/dist/{chunk-E3NYWENM.js → chunk-LU4TK2PR.js} +52 -7
- package/dist/{chunk-UWIJNAOB.js → chunk-M5T5VO65.js} +109 -42
- package/dist/{chunk-JPOWPFCU.js → chunk-MAR7Y6HW.js} +38 -16
- package/dist/chunk-N6F52NLF.js +6951 -0
- package/dist/{chunk-UHTSULZS.js → chunk-NMOX6HFD.js} +20 -7
- package/dist/{chunk-WD6AJM35.js → chunk-OLBBMFRD.js} +30 -13
- package/dist/{chunk-VOO7NYPP.js → chunk-PFEFKVGL.js} +22 -6
- package/dist/{chunk-6CWDTGUC.js → chunk-PIUMUEMV.js} +7 -1
- package/dist/chunk-PV4JUBVJ.js +462 -0
- package/dist/{chunk-527KG6XR.js → chunk-Q3RUPKEJ.js} +22 -4
- package/dist/{chunk-D5YD55AR.js → chunk-Q5WJOSJ7.js} +11 -1
- package/dist/{chunk-5N2FG33Q.js → chunk-R346GLFC.js} +7 -1
- package/dist/{chunk-4UQA7NCT.js → chunk-R5KLMSBV.js} +7 -2
- package/dist/{chunk-PIDUD6M2.js → chunk-RDLVBZEO.js} +11 -6
- package/dist/{chunk-O4EJEDHO.js → chunk-RPTR2H26.js} +40 -31
- package/dist/{chunk-HBU5MTAM.js → chunk-SVNXH4L2.js} +7 -1
- package/dist/{chunk-XNISANGE.js → chunk-TEKV33Q5.js} +122 -57
- package/dist/chunk-TXOTCRLG.js +15 -0
- package/dist/{chunk-VPAWTYLY.js → chunk-WEPFGWHJ.js} +7 -1
- package/dist/{chunk-HMYNFFY4.js → chunk-XPLRXC72.js} +7 -2
- package/dist/{chunk-UU3R62TT.js → chunk-XYWBQRDM.js} +13 -4
- package/dist/{chunk-7BHLZB3A.js → chunk-ZPY3JZ5E.js} +32 -10
- package/dist/cli/index.js +39 -33
- package/dist/clio-BZVGEUFJ.js +58 -0
- package/dist/{components-JVHMUBEB.js → components-DMAOEKFB.js} +26 -9
- package/dist/{config-ZFCDBMDC.js → config-IRUQ7SE4.js} +42 -31
- package/dist/configure-S7S6F6CL.js +32 -0
- package/dist/{context-CDXTP2MP.js → context-3KWFLHJG.js} +17 -11
- package/dist/{context-E3KIFVXI.js → context-5RADCKTR.js} +33 -28
- package/dist/{context-clear-3F4PLXOS.js → context-clear-7TSNPAAI.js} +36 -28
- package/dist/{context-index-Q7YSYTR3.js → context-index-W4RLWOQH.js} +10 -4
- package/dist/{docs-YIETIWZI.js → docs-5AWSPS37.js} +16 -10
- package/dist/doctor-UC5NAJYQ.js +77 -0
- package/dist/{eval-B3KZZESM.js → eval-U6TJHRLX.js} +77 -24
- package/dist/{evidence-V67CHM35.js → evidence-YEGUW4L3.js} +34 -26
- package/dist/{evolve-YDZSUQYA.js → evolve-TXARCTPG.js} +39 -26
- package/dist/{extensions-SRG7XCAH.js → extensions-OZFJ3A3G.js} +13 -7
- package/dist/{fleet-CA2CRTVG.js → fleet-6G3DHNYE.js} +45 -37
- package/dist/fleet-preflight-DSNT37JK.js +23 -0
- package/dist/{init-2OZDJE2D.js → init-KZ5QTF6M.js} +42 -34
- package/dist/{memory-3PIQQAKX.js → memory-73ESV5YC.js} +35 -27
- package/dist/{models-DY35XI7Y.js → models-A4PVNWJK.js} +34 -23
- package/dist/{paths-5OMXW7Z4.js → paths-C4H6IV77.js} +12 -6
- package/dist/preload-6WVMHX3A.js +13 -0
- package/dist/{reset-PIFYNOS3.js → reset-BGW6OGMV.js} +17 -11
- package/dist/{run-3VSPP24F.js → run-YTPEYQOH.js} +60 -48
- package/dist/{share-D36RQCXM.js → share-YIFFV4NQ.js} +16 -10
- package/dist/{skills-F2MRLELY.js → skills-2V6RA3OQ.js} +18 -11
- package/dist/{skills-eval-E2ZTW4PL.js → skills-eval-S2TVJO4F.js} +45 -36
- package/dist/{targets-DZMEZAH4.js → targets-TYXLPB23.js} +61 -59
- package/dist/{trace-7NYCUI2J.js → trace-GGOJ6Q6Z.js} +9 -3
- package/dist/{uninstall-AD3JWHBB.js → uninstall-LLLT4F4W.js} +14 -8
- package/dist/{upgrade-WYYBKGDY.js → upgrade-33G2LMM5.js} +45 -23
- package/dist/{usage-ULIDAGFF.js → usage-ZAFSXKKG.js} +35 -27
- package/dist/version-KGEG7EPO.js +21 -0
- package/dist/{wiki-generate-PKFIX6OB.js → wiki-generate-NUQCVOQ3.js} +55 -45
- package/dist/worker/entry.js +101 -43
- package/docs/README.md +12 -9
- package/docs/acp.md +28 -5
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +23 -2
- package/docs/artifact-placement.md +101 -0
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +4 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +125 -41
- package/docs/configuration-and-targets.md +88 -18
- package/docs/context-engine.md +6 -2
- package/docs/development-pipeline.md +77 -0
- package/docs/documentation-coverage.md +4 -4
- package/docs/documentation-guide.md +3 -3
- package/docs/environment-variables.md +2 -1
- package/docs/eval-runner.md +3 -3
- package/docs/evals-internal.md +2 -2
- package/docs/evidence-and-memory.md +6 -2
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +18 -11
- package/docs/fleet-demo-runbook.md +22 -23
- package/docs/fleet-dispatch.md +111 -12
- package/docs/glossary.md +107 -15
- package/docs/html/agents_blueprint.html +3 -3
- package/docs/html/alcf_blueprint.html +3 -3
- package/docs/html/architecture_blueprint.html +3 -3
- package/docs/html/commands_blueprint.html +187 -42
- package/docs/html/configuration_blueprint.html +7 -7
- package/docs/html/context_blueprint.html +3 -3
- package/docs/html/documentation_blueprint.html +1 -1
- package/docs/html/environment_blueprint.html +3 -3
- package/docs/html/eval_blueprint.html +4 -4
- package/docs/html/evals_internal_blueprint.html +3 -3
- package/docs/html/evolution_blueprint.html +3 -3
- package/docs/html/extensions_blueprint.html +3 -3
- package/docs/html/fleet_dispatch_blueprint.html +8 -8
- package/docs/html/index.html +5 -5
- package/docs/html/lifecycle_blueprint.html +4 -4
- package/docs/html/memory_blueprint.html +3 -3
- package/docs/html/middleware_blueprint.html +3 -3
- package/docs/html/models_blueprint.html +2 -2
- package/docs/html/observability_blueprint.html +2 -2
- package/docs/html/provider_adapter_blueprint.html +3 -3
- package/docs/html/safety_blueprint.html +3 -3
- package/docs/html/skills_blueprint.html +2 -2
- package/docs/html/soak_blueprint.html +3 -3
- package/docs/html/tool_usage_blueprint.html +4 -4
- package/docs/html/tools_blueprint.html +2 -2
- package/docs/html/trace_blueprint.html +3 -3
- package/docs/html/tui_design_blueprint.html +100 -40
- package/docs/html/validation_blueprint.html +1 -1
- package/docs/html/worker_dispatch_blueprint.html +3 -3
- package/docs/installation-and-lifecycle.md +62 -11
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +2 -2
- package/docs/observability.md +3 -3
- package/docs/proactive-memory.md +12 -12
- package/docs/prompt-envelope-and-tools.md +2 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +4 -0
- package/docs/safety-model.md +21 -5
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +2 -2
- package/docs/skills-marketplace.md +1 -1
- package/docs/time-conventions.md +101 -0
- package/docs/tool-usage.md +5 -4
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +83 -27
- package/docs/worker-dispatch-mechanics.md +3 -3
- package/package.json +16 -16
- package/skills/README.md +5 -6
- package/skills/git/file-ticket/SKILL.md +107 -0
- package/skills/git/file-ticket/evals.md +54 -0
- package/skills/git/fix-issue/SKILL.md +106 -0
- package/skills/git/fix-issue/evals.md +71 -0
- package/skills/git/ship/SKILL.md +92 -0
- package/skills/git/ship/evals.md +72 -0
- package/skills/skill-marketplace.json +12 -20
- package/src/cli/acp.ts +88 -0
- package/src/cli/agents.ts +60 -0
- package/src/cli/args.ts +280 -0
- package/src/cli/argv.ts +170 -0
- package/src/cli/ask.ts +34 -0
- package/src/cli/auth.ts +468 -0
- package/src/cli/bootstrap-generate.ts +498 -0
- package/src/cli/clio.ts +34 -0
- package/src/cli/components.ts +195 -0
- package/src/cli/config-inspect.ts +330 -0
- package/src/cli/config.ts +72 -0
- package/src/cli/configure-interop.ts +67 -0
- package/src/cli/configure-layout.ts +172 -0
- package/src/cli/configure.ts +1487 -0
- package/src/cli/context-clear.ts +76 -0
- package/src/cli/context-index.ts +102 -0
- package/src/cli/context.ts +316 -0
- package/src/cli/default-target.ts +63 -0
- package/src/cli/docs.ts +340 -0
- package/src/cli/doctor.ts +54 -0
- package/src/cli/eval.ts +315 -0
- package/src/cli/evidence.ts +222 -0
- package/src/cli/evolve.ts +219 -0
- package/src/cli/extensions.ts +205 -0
- package/src/cli/fleet.ts +827 -0
- package/src/cli/index.ts +309 -0
- package/src/cli/init.ts +219 -0
- package/src/cli/initial-message.ts +47 -0
- package/src/cli/internal-dispatch.ts +55 -0
- package/src/cli/memory.ts +180 -0
- package/src/cli/models.ts +257 -0
- package/src/cli/modes/json-stream.ts +85 -0
- package/src/cli/modes/jsonl.ts +9 -0
- package/src/cli/modes/print.ts +589 -0
- package/src/cli/oauth-manual-input.ts +72 -0
- package/src/cli/oauth-select.ts +36 -0
- package/src/cli/output-guard.ts +48 -0
- package/src/cli/paths.ts +44 -0
- package/src/cli/provider-target.ts +113 -0
- package/src/cli/removal.ts +72 -0
- package/src/cli/reset.ts +253 -0
- package/src/cli/run.ts +497 -0
- package/src/cli/share.ts +243 -0
- package/src/cli/shared.ts +60 -0
- package/src/cli/skills-eval.ts +1225 -0
- package/src/cli/skills.ts +470 -0
- package/src/cli/steer-channel.ts +86 -0
- package/src/cli/targets.ts +1150 -0
- package/src/cli/text-layout.ts +102 -0
- package/src/cli/trace.ts +274 -0
- package/src/cli/uninstall.ts +405 -0
- package/src/cli/upgrade.ts +270 -0
- package/src/cli/usage.ts +869 -0
- package/src/cli/validate-model.ts +28 -0
- package/src/cli/version.ts +7 -0
- package/src/cli/wiki-generate.ts +509 -0
- package/src/core/artifact-paths.ts +43 -0
- package/src/core/bash-exec.ts +242 -0
- package/src/core/boot-trace.ts +37 -0
- package/src/core/bus-events.ts +728 -0
- package/src/core/bus-trace.ts +53 -0
- package/src/core/c-header-language.ts +265 -0
- package/src/core/clio-repo.ts +78 -0
- package/src/core/config.ts +1593 -0
- package/src/core/context-floor.ts +33 -0
- package/src/core/defaults.ts +625 -0
- package/src/core/domain-loader.ts +170 -0
- package/src/core/event-bus.ts +94 -0
- package/src/core/file-references.ts +282 -0
- package/src/core/guardrails.ts +185 -0
- package/src/core/headless-permission.ts +21 -0
- package/src/core/init.ts +223 -0
- package/src/core/json-payload.ts +58 -0
- package/src/core/package-root.ts +54 -0
- package/src/core/path-canonical.ts +37 -0
- package/src/core/process-identity.ts +41 -0
- package/src/core/recent-models.ts +91 -0
- package/src/core/release.ts +2 -0
- package/src/core/residency-protection.ts +56 -0
- package/src/core/resolve-config-value.ts +88 -0
- package/src/core/response-schema.ts +279 -0
- package/src/core/run-overrides.ts +77 -0
- package/src/core/safe-exec.ts +193 -0
- package/src/core/safe-id.ts +37 -0
- package/src/core/safe-resource-write.ts +162 -0
- package/src/core/session-routing.ts +339 -0
- package/src/core/settings-layers.ts +220 -0
- package/src/core/shared-bus.ts +8 -0
- package/src/core/shell-quote.ts +26 -0
- package/src/core/skill-activation.ts +190 -0
- package/src/core/startup-timer.ts +37 -0
- package/src/core/state-file-lock.ts +207 -0
- package/src/core/termination.ts +202 -0
- package/src/core/timers.ts +38 -0
- package/src/core/tool-names.ts +65 -0
- package/src/core/verification-scripts.ts +13 -0
- package/src/core/workspace-files.ts +492 -0
- package/src/core/xdg.ts +177 -0
- package/src/domains/agents/builtins/architect.md +4 -4
- package/src/domains/agents/builtins/coder.md +3 -2
- package/src/domains/agents/builtins/debugger.md +1 -1
- package/src/domains/agents/builtins/documenter.md +1 -1
- package/src/domains/agents/builtins/git-master.md +3 -3
- package/src/domains/agents/builtins/provenance.md +1 -1
- package/src/domains/agents/builtins/researcher.md +1 -1
- package/src/domains/agents/builtins/scout.md +1 -1
- package/src/domains/agents/builtins/tester.md +1 -1
- package/src/domains/agents/builtins/verifier.md +1 -1
- package/src/domains/agents/builtins/wiki-writer.md +1 -1
- package/src/domains/agents/catalog.ts +172 -0
- package/src/domains/agents/contract.ts +16 -0
- package/src/domains/agents/extension.ts +110 -0
- package/src/domains/agents/fleet-commands.ts +154 -0
- package/src/domains/agents/fleet-contract.ts +797 -0
- package/src/domains/agents/frontmatter.ts +40 -0
- package/src/domains/agents/index.ts +102 -0
- package/src/domains/agents/manifest.ts +6 -0
- package/src/domains/agents/recipe-schema.ts +202 -0
- package/src/domains/agents/recipe.ts +125 -0
- package/src/domains/agents/registry.ts +111 -0
- package/src/domains/agents/result-contract.ts +1265 -0
- package/src/domains/agents/spec.ts +371 -0
- package/src/domains/agents/write-boundary.ts +109 -0
- package/src/domains/components/diff.ts +99 -0
- package/src/domains/components/hash.ts +21 -0
- package/src/domains/components/index.ts +3 -0
- package/src/domains/components/scan.ts +304 -0
- package/src/domains/components/snapshot.ts +108 -0
- package/src/domains/components/types.ts +82 -0
- package/src/domains/config/agent-namespace.ts +13 -0
- package/src/domains/config/classify.ts +94 -0
- package/src/domains/config/contract.ts +22 -0
- package/src/domains/config/extension.ts +136 -0
- package/src/domains/config/index.ts +13 -0
- package/src/domains/config/keybindings.ts +164 -0
- package/src/domains/config/manifest.ts +6 -0
- package/src/domains/config/watcher.ts +41 -0
- package/src/domains/context/adoption.ts +880 -0
- package/src/domains/context/bootstrap-prompt.ts +273 -0
- package/src/domains/context/bootstrap.ts +1409 -0
- package/src/domains/context/clear.ts +86 -0
- package/src/domains/context/clio-md.ts +327 -0
- package/src/domains/context/codewiki/cmake.ts +356 -0
- package/src/domains/context/codewiki/cooperative.ts +46 -0
- package/src/domains/context/codewiki/digest.ts +135 -0
- package/src/domains/context/codewiki/grammar-assets.ts +33 -0
- package/src/domains/context/codewiki/indexer.ts +1614 -0
- package/src/domains/context/codewiki/tree-sitter.ts +771 -0
- package/src/domains/context/contract.ts +62 -0
- package/src/domains/context/excluded-dirs.ts +1 -0
- package/src/domains/context/extension.ts +407 -0
- package/src/domains/context/fingerprint.ts +196 -0
- package/src/domains/context/index.ts +164 -0
- package/src/domains/context/init-options.ts +69 -0
- package/src/domains/context/manifest.ts +6 -0
- package/src/domains/context/operator-profile.ts +157 -0
- package/src/domains/context/project-metadata.ts +510 -0
- package/src/domains/context/project-rules.ts +227 -0
- package/src/domains/context/prompt-context.ts +62 -0
- package/src/domains/context/refresh.ts +170 -0
- package/src/domains/context/sibling-files.ts +10 -0
- package/src/domains/context/state.ts +237 -0
- package/src/domains/context/wiki/assemble.ts +303 -0
- package/src/domains/context/wiki/frontmatter.ts +210 -0
- package/src/domains/context/wiki/generate.ts +590 -0
- package/src/domains/context/wiki/layout.ts +111 -0
- package/src/domains/context/wiki/meta.ts +221 -0
- package/src/domains/context/wiki/plan-store.ts +217 -0
- package/src/domains/context/wiki/plan.ts +250 -0
- package/src/domains/context/wiki/prompts.ts +270 -0
- package/src/domains/context/wiki/staleness.ts +198 -0
- package/src/domains/dispatch/active-route-planner.ts +168 -0
- package/src/domains/dispatch/admission-queue.ts +150 -0
- package/src/domains/dispatch/admission.ts +334 -0
- package/src/domains/dispatch/agent-candidates.ts +307 -0
- package/src/domains/dispatch/agent-ledger-hub.ts +71 -0
- package/src/domains/dispatch/agent-ledger-store.ts +257 -0
- package/src/domains/dispatch/agent-ledger.ts +212 -0
- package/src/domains/dispatch/agent-plan-adapter.ts +85 -0
- package/src/domains/dispatch/assignment-events.ts +132 -0
- package/src/domains/dispatch/assignment-reconcile.ts +76 -0
- package/src/domains/dispatch/assignment-store.ts +162 -0
- package/src/domains/dispatch/assignment.ts +278 -0
- package/src/domains/dispatch/backoff.ts +59 -0
- package/src/domains/dispatch/batch-store.ts +134 -0
- package/src/domains/dispatch/batch-tracker.ts +66 -0
- package/src/domains/dispatch/capability-match.ts +155 -0
- package/src/domains/dispatch/capacity-lease.ts +413 -0
- package/src/domains/dispatch/code-step-store.ts +52 -0
- package/src/domains/dispatch/code-step.ts +368 -0
- package/src/domains/dispatch/contract.ts +278 -0
- package/src/domains/dispatch/dedup.ts +133 -0
- package/src/domains/dispatch/event-pump.ts +251 -0
- package/src/domains/dispatch/execution-handoff.ts +29 -0
- package/src/domains/dispatch/execution-plan.ts +328 -0
- package/src/domains/dispatch/execution-role.ts +277 -0
- package/src/domains/dispatch/execution-scheduler.ts +583 -0
- package/src/domains/dispatch/extension.ts +5869 -0
- package/src/domains/dispatch/failure-classification.ts +141 -0
- package/src/domains/dispatch/fleet-plan.ts +225 -0
- package/src/domains/dispatch/fleet-preflight.ts +394 -0
- package/src/domains/dispatch/gate-decisions.ts +1040 -0
- package/src/domains/dispatch/gate-role-prompts.ts +58 -0
- package/src/domains/dispatch/heartbeat.ts +27 -0
- package/src/domains/dispatch/index.ts +137 -0
- package/src/domains/dispatch/joint-route-adapter.ts +114 -0
- package/src/domains/dispatch/joint-route-resolver.ts +283 -0
- package/src/domains/dispatch/manifest.ts +6 -0
- package/src/domains/dispatch/orphan-recovery.ts +224 -0
- package/src/domains/dispatch/outcome.ts +109 -0
- package/src/domains/dispatch/phase-timing.ts +47 -0
- package/src/domains/dispatch/placement.ts +202 -0
- package/src/domains/dispatch/receipt-findings.ts +255 -0
- package/src/domains/dispatch/receipt-integrity.ts +378 -0
- package/src/domains/dispatch/recovery-candidates.ts +74 -0
- package/src/domains/dispatch/reproducibility.ts +48 -0
- package/src/domains/dispatch/reservation-store.ts +501 -0
- package/src/domains/dispatch/route-approval.ts +177 -0
- package/src/domains/dispatch/route-candidates.ts +57 -0
- package/src/domains/dispatch/route-decision.ts +1079 -0
- package/src/domains/dispatch/route-facts.ts +187 -0
- package/src/domains/dispatch/route-history.ts +238 -0
- package/src/domains/dispatch/route-observer.ts +488 -0
- package/src/domains/dispatch/route-policy.ts +327 -0
- package/src/domains/dispatch/route-quality.ts +256 -0
- package/src/domains/dispatch/route-readiness.ts +120 -0
- package/src/domains/dispatch/routing-intent.ts +287 -0
- package/src/domains/dispatch/run-identity.ts +56 -0
- package/src/domains/dispatch/scout-transition.ts +130 -0
- package/src/domains/dispatch/state.ts +277 -0
- package/src/domains/dispatch/tool-stats.ts +132 -0
- package/src/domains/dispatch/transport.ts +209 -0
- package/src/domains/dispatch/types.ts +785 -0
- package/src/domains/dispatch/validation-grounding.ts +154 -0
- package/src/domains/dispatch/validation.ts +721 -0
- package/src/domains/dispatch/worker-protocol.ts +275 -0
- package/src/domains/dispatch/worker-spawn.ts +566 -0
- package/src/domains/dispatch/write-boundary-enforcer.ts +97 -0
- package/src/domains/dispatch/write-boundary.ts +426 -0
- package/src/domains/eval/artifacts/redact.ts +42 -0
- package/src/domains/eval/artifacts/store.ts +173 -0
- package/src/domains/eval/compare/compare.ts +33 -0
- package/src/domains/eval/compare/gates.ts +66 -0
- package/src/domains/eval/compare/thresholds.ts +92 -0
- package/src/domains/eval/harness-metrics.ts +62 -0
- package/src/domains/eval/index.ts +66 -0
- package/src/domains/eval/metrics/chaos-stream.ts +93 -0
- package/src/domains/eval/metrics/context.ts +34 -0
- package/src/domains/eval/metrics/coverage.ts +21 -0
- package/src/domains/eval/metrics/evidence.ts +182 -0
- package/src/domains/eval/metrics/fleet-loop-stream.ts +196 -0
- package/src/domains/eval/metrics/invariants.ts +736 -0
- package/src/domains/eval/metrics/latency.ts +4 -0
- package/src/domains/eval/metrics/token-stream.ts +139 -0
- package/src/domains/eval/metrics/tokens.ts +51 -0
- package/src/domains/eval/metrics/tool-calls.ts +7 -0
- package/src/domains/eval/proactive-memory.ts +279 -0
- package/src/domains/eval/provenance.ts +35 -0
- package/src/domains/eval/report.ts +234 -0
- package/src/domains/eval/reports/json.ts +5 -0
- package/src/domains/eval/reports/junit.ts +23 -0
- package/src/domains/eval/reports/markdown.ts +20 -0
- package/src/domains/eval/reports/swe-jsonl.ts +16 -0
- package/src/domains/eval/reports/text.ts +25 -0
- package/src/domains/eval/run-compare.ts +274 -0
- package/src/domains/eval/runner.ts +244 -0
- package/src/domains/eval/runners/clio-run.ts +148 -0
- package/src/domains/eval/runners/context-index.ts +56 -0
- package/src/domains/eval/runners/context-init.ts +203 -0
- package/src/domains/eval/runners/external-command.ts +350 -0
- package/src/domains/eval/runtime-paths.ts +171 -0
- package/src/domains/eval/schema/artifact.ts +75 -0
- package/src/domains/eval/schema/suite.ts +235 -0
- package/src/domains/eval/schema/validate.ts +339 -0
- package/src/domains/eval/store.ts +392 -0
- package/src/domains/eval/suites/load.ts +74 -0
- package/src/domains/eval/suites/matrix.ts +19 -0
- package/src/domains/eval/suites/resolve.ts +44 -0
- package/src/domains/eval/suites/run.ts +325 -0
- package/src/domains/eval/task-file.ts +186 -0
- package/src/domains/eval/types.ts +141 -0
- package/src/domains/eval/verifiers/command.ts +27 -0
- package/src/domains/eval/verifiers/file-exists.ts +6 -0
- package/src/domains/eval/verifiers/patch.ts +22 -0
- package/src/domains/eval/workspaces/git.ts +41 -0
- package/src/domains/eval/workspaces/local.ts +17 -0
- package/src/domains/eval/workspaces/temp-copy.ts +29 -0
- package/src/domains/evidence/build.ts +1714 -0
- package/src/domains/evidence/eval.ts +605 -0
- package/src/domains/evidence/failure-attribution.ts +54 -0
- package/src/domains/evidence/finish-contract-map.ts +42 -0
- package/src/domains/evidence/index.ts +55 -0
- package/src/domains/evidence/provenance.ts +200 -0
- package/src/domains/evidence/redact.ts +81 -0
- package/src/domains/evidence/store.ts +291 -0
- package/src/domains/evidence/types.ts +325 -0
- package/src/domains/evolution/SELF_EDIT_GATE.md +91 -0
- package/src/domains/evolution/index.ts +26 -0
- package/src/domains/evolution/manifest.ts +154 -0
- package/src/domains/evolution/validate.ts +304 -0
- package/src/domains/extensions/contract.ts +22 -0
- package/src/domains/extensions/discovery.ts +193 -0
- package/src/domains/extensions/extension.ts +46 -0
- package/src/domains/extensions/index.ts +34 -0
- package/src/domains/extensions/manager.ts +30 -0
- package/src/domains/extensions/manifest.ts +6 -0
- package/src/domains/extensions/resources.ts +38 -0
- package/src/domains/extensions/state.ts +224 -0
- package/src/domains/extensions/types.ts +83 -0
- package/src/domains/interop/consent.ts +185 -0
- package/src/domains/interop/contract.ts +29 -0
- package/src/domains/interop/detect.ts +173 -0
- package/src/domains/interop/extension.ts +59 -0
- package/src/domains/interop/index.ts +34 -0
- package/src/domains/interop/manifest.ts +6 -0
- package/src/domains/interop/registry.ts +139 -0
- package/src/domains/interop/state.ts +92 -0
- package/src/domains/interop/types.ts +109 -0
- package/src/domains/lifecycle/contract.ts +11 -0
- package/src/domains/lifecycle/doctor.ts +536 -0
- package/src/domains/lifecycle/extension.ts +23 -0
- package/src/domains/lifecycle/index.ts +21 -0
- package/src/domains/lifecycle/install-method.ts +51 -0
- package/src/domains/lifecycle/manifest.ts +6 -0
- package/src/domains/lifecycle/migrations/index.ts +94 -0
- package/src/domains/lifecycle/state.ts +93 -0
- package/src/domains/lifecycle/upgrade-notice.ts +35 -0
- package/src/domains/lifecycle/version.ts +35 -0
- package/src/domains/memory/index.ts +128 -0
- package/src/domains/memory/operations.ts +143 -0
- package/src/domains/memory/prompt-section.ts +86 -0
- package/src/domains/memory/proposal.ts +180 -0
- package/src/domains/memory/store.ts +163 -0
- package/src/domains/memory/task-bank.ts +229 -0
- package/src/domains/memory/task-memory-handoff.ts +222 -0
- package/src/domains/memory/task-memory-policy.ts +602 -0
- package/src/domains/memory/task-memory-status.ts +58 -0
- package/src/domains/memory/task-memory-telemetry.ts +346 -0
- package/src/domains/memory/task-memory-trace.ts +89 -0
- package/src/domains/memory/types.ts +74 -0
- package/src/domains/memory/validate.ts +297 -0
- package/src/domains/middleware/budget.ts +216 -0
- package/src/domains/middleware/contract.ts +35 -0
- package/src/domains/middleware/dispatch-nudge.ts +469 -0
- package/src/domains/middleware/extension.ts +129 -0
- package/src/domains/middleware/hook-receipts.ts +70 -0
- package/src/domains/middleware/hooks-io.ts +174 -0
- package/src/domains/middleware/hooks.ts +432 -0
- package/src/domains/middleware/index.ts +154 -0
- package/src/domains/middleware/manifest.ts +6 -0
- package/src/domains/middleware/memory-intervention.ts +701 -0
- package/src/domains/middleware/rules.ts +42 -0
- package/src/domains/middleware/runtime.ts +333 -0
- package/src/domains/middleware/skills-reminder.ts +187 -0
- package/src/domains/middleware/snapshot.ts +71 -0
- package/src/domains/middleware/stalled-turn.ts +71 -0
- package/src/domains/middleware/task-board-reminder.ts +87 -0
- package/src/domains/middleware/task-nudge.ts +77 -0
- package/src/domains/middleware/tool-choice-control.ts +42 -0
- package/src/domains/middleware/types.ts +131 -0
- package/src/domains/middleware/validate.ts +329 -0
- package/src/domains/observability/accountability.ts +67 -0
- package/src/domains/observability/contract.ts +168 -0
- package/src/domains/observability/cost.ts +206 -0
- package/src/domains/observability/evidence-index.ts +123 -0
- package/src/domains/observability/extension.ts +281 -0
- package/src/domains/observability/index.ts +78 -0
- package/src/domains/observability/manifest.ts +10 -0
- package/src/domains/observability/metrics.ts +37 -0
- package/src/domains/observability/projection.ts +477 -0
- package/src/domains/observability/telemetry.ts +89 -0
- package/src/domains/observability/trace-store.ts +1454 -0
- package/src/domains/prompts/compiler.ts +556 -0
- package/src/domains/prompts/contract.ts +30 -0
- package/src/domains/prompts/extension.ts +304 -0
- package/src/domains/prompts/fragment-loader.ts +139 -0
- package/src/domains/prompts/fragments/identity/clio.md +3 -2
- package/src/domains/prompts/fragments/identity/self-awareness.md +63 -0
- package/src/domains/prompts/fragments/operating/contract.md +10 -1
- package/src/domains/prompts/hash.ts +73 -0
- package/src/domains/prompts/index.ts +32 -0
- package/src/domains/prompts/manifest.ts +8 -0
- package/src/domains/prompts/memory-intervention.ts +57 -0
- package/src/domains/prompts/preload.ts +82 -0
- package/src/domains/providers/auth/api-key.ts +47 -0
- package/src/domains/providers/auth/backend-file.ts +69 -0
- package/src/domains/providers/auth/backend-memory.ts +17 -0
- package/src/domains/providers/auth/index.ts +37 -0
- package/src/domains/providers/auth/oauth.ts +36 -0
- package/src/domains/providers/auth/storage.ts +667 -0
- package/src/domains/providers/capabilities.ts +50 -0
- package/src/domains/providers/catalog.ts +162 -0
- package/src/domains/providers/contract.ts +151 -0
- package/src/domains/providers/credentials.ts +20 -0
- package/src/domains/providers/eligibility.ts +24 -0
- package/src/domains/providers/errors.ts +64 -0
- package/src/domains/providers/extension.ts +536 -0
- package/src/domains/providers/index.ts +142 -0
- package/src/domains/providers/knowledge-base-path.ts +102 -0
- package/src/domains/providers/manifest.ts +6 -0
- package/src/domains/providers/model-capabilities.ts +136 -0
- package/src/domains/providers/model-discovery.ts +144 -0
- package/src/domains/providers/model-family.ts +32 -0
- package/src/domains/providers/model-runtime-capabilities.ts +712 -0
- package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +2 -2
- package/src/domains/providers/plugins.ts +59 -0
- package/src/domains/providers/probe/fingerprint.ts +44 -0
- package/src/domains/providers/probe/http.ts +114 -0
- package/src/domains/providers/probe/reasoning.ts +111 -0
- package/src/domains/providers/registry.ts +166 -0
- package/src/domains/providers/resolver.ts +156 -0
- package/src/domains/providers/runtime-resolution.ts +720 -0
- package/src/domains/providers/runtimes/antigravity/antigravity-code.ts +90 -0
- package/src/domains/providers/runtimes/builtins.ts +78 -0
- package/src/domains/providers/runtimes/claude/claude-code.ts +38 -0
- package/src/domains/providers/runtimes/claude/claude-sdk.ts +38 -0
- package/src/domains/providers/runtimes/claude/common.ts +55 -0
- package/src/domains/providers/runtimes/cloud/alcf.ts +171 -0
- package/src/domains/providers/runtimes/cloud/anthropic-max.ts +71 -0
- package/src/domains/providers/runtimes/cloud/anthropic.ts +43 -0
- package/src/domains/providers/runtimes/cloud/bedrock.ts +35 -0
- package/src/domains/providers/runtimes/cloud/deepseek.ts +50 -0
- package/src/domains/providers/runtimes/cloud/google.ts +41 -0
- package/src/domains/providers/runtimes/cloud/groq.ts +46 -0
- package/src/domains/providers/runtimes/cloud/mistral.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openai-codex.ts +49 -0
- package/src/domains/providers/runtimes/cloud/openai.ts +46 -0
- package/src/domains/providers/runtimes/cloud/openrouter.ts +111 -0
- package/src/domains/providers/runtimes/common/lmstudio-logger.ts +32 -0
- package/src/domains/providers/runtimes/common/local-synth.ts +165 -0
- package/src/domains/providers/runtimes/common/probe-helpers.ts +474 -0
- package/src/domains/providers/runtimes/local-native/lemonade-anthropic.ts +27 -0
- package/src/domains/providers/runtimes/local-native/lemonade-openai.ts +26 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-anthropic.ts +88 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-completion.ts +207 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-embed.ts +180 -0
- package/src/domains/providers/runtimes/local-native/llamacpp-rerank.ts +126 -0
- package/src/domains/providers/runtimes/local-native/llamacpp.ts +98 -0
- package/src/domains/providers/runtimes/local-native/lmstudio-native.ts +491 -0
- package/src/domains/providers/runtimes/local-native/ollama-native.ts +117 -0
- package/src/domains/providers/runtimes/local-native/sglang.ts +26 -0
- package/src/domains/providers/runtimes/local-native/vllm.ts +27 -0
- package/src/domains/providers/runtimes/protocol/anthropic-compat.ts +104 -0
- package/src/domains/providers/runtimes/protocol/anthropic-messages.ts +28 -0
- package/src/domains/providers/runtimes/protocol/bedrock.ts +26 -0
- package/src/domains/providers/runtimes/protocol/google.ts +27 -0
- package/src/domains/providers/runtimes/protocol/openai-compat.ts +145 -0
- package/src/domains/providers/support.ts +238 -0
- package/src/domains/providers/thinking-control-policy.ts +85 -0
- package/src/domains/providers/types/capability-flags.ts +114 -0
- package/src/domains/providers/types/cost-provenance.ts +7 -0
- package/src/domains/providers/types/inference.ts +41 -0
- package/src/domains/providers/types/knowledge-base.ts +156 -0
- package/src/domains/providers/types/local-model-quirks.ts +218 -0
- package/src/domains/providers/types/runtime-descriptor.ts +170 -0
- package/src/domains/providers/types/target-descriptor.ts +38 -0
- package/src/domains/resources/collision.ts +92 -0
- package/src/domains/resources/common-loader.ts +140 -0
- package/src/domains/resources/contract.ts +25 -0
- package/src/domains/resources/extension.ts +61 -0
- package/src/domains/resources/index.ts +74 -0
- package/src/domains/resources/loader.ts +86 -0
- package/src/domains/resources/manifest.ts +6 -0
- package/src/domains/resources/prompts/loader.ts +232 -0
- package/src/domains/resources/prompts/substitute.ts +65 -0
- package/src/domains/resources/skills/content-hash.ts +105 -0
- package/src/domains/resources/skills/evals.ts +175 -0
- package/src/domains/resources/skills/install.ts +410 -0
- package/src/domains/resources/skills/loader.ts +978 -0
- package/src/domains/resources/skills/marketplace.ts +255 -0
- package/src/domains/resources/skills/provenance-pin.ts +115 -0
- package/src/domains/safety/action-classifier.ts +268 -0
- package/src/domains/safety/approval-axis.ts +23 -0
- package/src/domains/safety/audit.ts +487 -0
- package/src/domains/safety/autonomy.ts +174 -0
- package/src/domains/safety/call-target.ts +59 -0
- package/src/domains/safety/contract.ts +65 -0
- package/src/domains/safety/damage-control.ts +44 -0
- package/src/domains/safety/default-path-policy.ts +117 -0
- package/src/domains/safety/extension.ts +383 -0
- package/src/domains/safety/finish-contract-registration.ts +128 -0
- package/src/domains/safety/finish-contract.ts +554 -0
- package/src/domains/safety/index.ts +44 -0
- package/src/domains/safety/loop-detector.ts +143 -0
- package/src/domains/safety/manifest.ts +6 -0
- package/src/domains/safety/path-policy.ts +164 -0
- package/src/domains/safety/policy-engine.ts +994 -0
- package/src/domains/safety/project-policy.ts +391 -0
- package/src/domains/safety/protected-artifacts-registration.ts +189 -0
- package/src/domains/safety/protected-artifacts.ts +993 -0
- package/src/domains/safety/rejection-feedback.ts +102 -0
- package/src/domains/safety/rigor.ts +72 -0
- package/src/domains/safety/rule-compiler.ts +48 -0
- package/src/domains/safety/rule-pack-loader.ts +92 -0
- package/src/domains/safety/run-effects.ts +197 -0
- package/src/domains/safety/scope.ts +61 -0
- package/src/domains/scheduling/budget.ts +35 -0
- package/src/domains/scheduling/cluster.ts +175 -0
- package/src/domains/scheduling/contract.ts +30 -0
- package/src/domains/scheduling/extension.ts +91 -0
- package/src/domains/scheduling/index.ts +12 -0
- package/src/domains/scheduling/manifest.ts +6 -0
- package/src/domains/session/archive-readers.ts +208 -0
- package/src/domains/session/checkpoint.ts +38 -0
- package/src/domains/session/compaction/auto.ts +89 -0
- package/src/domains/session/compaction/branch-summary.ts +186 -0
- package/src/domains/session/compaction/compact.ts +493 -0
- package/src/domains/session/compaction/cut-point.ts +171 -0
- package/src/domains/session/compaction/defaults.ts +34 -0
- package/src/domains/session/compaction/mask-observations.ts +265 -0
- package/src/domains/session/compaction/session-entries.ts +18 -0
- package/src/domains/session/compaction/tokens.ts +147 -0
- package/src/domains/session/context-accounting.ts +583 -0
- package/src/domains/session/context-ledger.ts +348 -0
- package/src/domains/session/contract.ts +144 -0
- package/src/domains/session/cwd-fallback.ts +65 -0
- package/src/domains/session/entries.ts +509 -0
- package/src/domains/session/extension.ts +322 -0
- package/src/domains/session/history.ts +172 -0
- package/src/domains/session/index.ts +84 -0
- package/src/domains/session/manager.ts +128 -0
- package/src/domains/session/manifest.ts +6 -0
- package/src/domains/session/migrations/index.ts +27 -0
- package/src/domains/session/prompt-manifest.ts +173 -0
- package/src/domains/session/protected-artifact-journal.ts +241 -0
- package/src/domains/session/protected-artifacts.ts +90 -0
- package/src/domains/session/retry.ts +238 -0
- package/src/domains/session/task-board.ts +375 -0
- package/src/domains/session/tree/active-path.ts +98 -0
- package/src/domains/session/tree/fork.ts +160 -0
- package/src/domains/session/tree/manager.ts +128 -0
- package/src/domains/session/tree/navigator.ts +177 -0
- package/src/domains/session/tree/preview.ts +259 -0
- package/src/domains/session/usage.ts +148 -0
- package/src/domains/session/workspace/git-probe.ts +161 -0
- package/src/domains/session/workspace/index.ts +4 -0
- package/src/domains/session/workspace/project-type.ts +217 -0
- package/src/domains/session/workspace/snapshot.ts +74 -0
- package/src/domains/share/archive.ts +684 -0
- package/src/domains/share/contract.ts +9 -0
- package/src/domains/share/extension.ts +26 -0
- package/src/domains/share/index.ts +28 -0
- package/src/domains/share/manifest.ts +6 -0
- package/src/engine/acp/adapter.ts +397 -0
- package/src/engine/acp/errors.ts +32 -0
- package/src/engine/acp/event-mapper.ts +154 -0
- package/src/engine/acp/server.ts +656 -0
- package/src/engine/acp/tool-mediator.ts +686 -0
- package/src/engine/acp/transport.ts +654 -0
- package/src/engine/acp/types.ts +170 -0
- package/src/engine/agent.ts +29 -0
- package/src/engine/ai.ts +202 -0
- package/src/engine/alcf-oauth.ts +198 -0
- package/src/engine/antigravity/subprocess-runtime.ts +205 -0
- package/src/engine/apis/degraded-inference.ts +95 -0
- package/src/engine/apis/index.ts +20 -0
- package/src/engine/apis/llamacpp-residency.ts +252 -0
- package/src/engine/apis/lmstudio-native.ts +1438 -0
- package/src/engine/apis/lmstudio-residency.ts +92 -0
- package/src/engine/apis/ollama-native.ts +507 -0
- package/src/engine/apis/openai-completions.ts +716 -0
- package/src/engine/apis/output-budget.ts +99 -0
- package/src/engine/apis/residency-lock.ts +29 -0
- package/src/engine/apis/residency.ts +640 -0
- package/src/engine/apis/resident-models.ts +42 -0
- package/src/engine/apis/sampling-overrides.ts +38 -0
- package/src/engine/apis/thinking-replay.ts +11 -0
- package/src/engine/claude/sdk-runtime.ts +685 -0
- package/src/engine/claude/session-id.ts +5 -0
- package/src/engine/claude/subprocess-runtime.ts +316 -0
- package/src/engine/claude/tool-safety.ts +400 -0
- package/src/engine/external-subprocess.ts +23 -0
- package/src/engine/harmony-response.ts +165 -0
- package/src/engine/loop-guard.ts +1127 -0
- package/src/engine/oauth.ts +192 -0
- package/src/engine/pi-mono-names.ts +13 -0
- package/src/engine/provider-payload.ts +315 -0
- package/src/engine/select-list.ts +53 -0
- package/src/engine/session.ts +834 -0
- package/src/engine/strip-tokenizer-sentinels.ts +125 -0
- package/src/engine/tui.ts +103 -0
- package/src/engine/types.ts +66 -0
- package/src/engine/worker-events.ts +100 -0
- package/src/engine/worker-runtime.ts +1022 -0
- package/src/engine/worker-tools.ts +203 -0
- package/src/entry/orchestrator.ts +1873 -0
- package/src/interactive/application-controller.ts +346 -0
- package/src/interactive/bus-notices.ts +265 -0
- package/src/interactive/chat-loop-messages.ts +626 -0
- package/src/interactive/chat-loop-policy.ts +18 -0
- package/src/interactive/chat-loop.ts +865 -0
- package/src/interactive/chat-panel.ts +1694 -0
- package/src/interactive/chat-renderer.ts +1038 -0
- package/src/interactive/clio-editor.ts +166 -0
- package/src/interactive/command-fallbacks.ts +23 -0
- package/src/interactive/command-output.ts +85 -0
- package/src/interactive/context-activity.ts +203 -0
- package/src/interactive/context-meter.ts +223 -0
- package/src/interactive/context-overlay.ts +220 -0
- package/src/interactive/cost-overlay.ts +279 -0
- package/src/interactive/dispatch-board.ts +1319 -0
- package/src/interactive/dispatch-steering.ts +86 -0
- package/src/interactive/editor-bash.ts +46 -0
- package/src/interactive/editor-steer.ts +51 -0
- package/src/interactive/editor-submit.ts +303 -0
- package/src/interactive/external-editor.ts +67 -0
- package/src/interactive/follow-up-queue-panel.ts +75 -0
- package/src/interactive/footer/dashboard.ts +534 -0
- package/src/interactive/footer/notifications.ts +275 -0
- package/src/interactive/footer/widgets.ts +1246 -0
- package/src/interactive/footer-panel.ts +187 -0
- package/src/interactive/format-time.ts +85 -0
- package/src/interactive/index.ts +11 -0
- package/src/interactive/interactive-application.ts +755 -0
- package/src/interactive/interactive-event-projection.ts +380 -0
- package/src/interactive/interactive-input-runtime.ts +261 -0
- package/src/interactive/interactive-presentation.ts +452 -0
- package/src/interactive/interactive-shell.ts +134 -0
- package/src/interactive/interactive-slash-runtime.ts +492 -0
- package/src/interactive/interactive-subscriptions.ts +111 -0
- package/src/interactive/interactive-tickers.ts +152 -0
- package/src/interactive/keybinding-manager.ts +496 -0
- package/src/interactive/layout.ts +20 -0
- package/src/interactive/leader-key.ts +143 -0
- package/src/interactive/loop-guard-interrupt.ts +101 -0
- package/src/interactive/memory-overlay.ts +280 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +110 -0
- package/src/interactive/overlay-auth-lifecycle.ts +308 -0
- package/src/interactive/overlay-frame.ts +502 -0
- package/src/interactive/overlay-general-openers.ts +217 -0
- package/src/interactive/overlay-key-routing.ts +213 -0
- package/src/interactive/overlay-lifecycle.ts +413 -0
- package/src/interactive/overlay-model-selectors.ts +127 -0
- package/src/interactive/overlay-permission-lifecycle.ts +344 -0
- package/src/interactive/overlay-resource-openers.ts +112 -0
- package/src/interactive/overlay-session-lifecycle.ts +270 -0
- package/src/interactive/overlay-transitions.ts +57 -0
- package/src/interactive/overlays/agents.ts +69 -0
- package/src/interactive/overlays/ask-user.ts +921 -0
- package/src/interactive/overlays/auth-dialog.ts +221 -0
- package/src/interactive/overlays/context-reset.ts +108 -0
- package/src/interactive/overlays/cwd-fallback.ts +141 -0
- package/src/interactive/overlays/extensions.ts +54 -0
- package/src/interactive/overlays/help-reference.ts +140 -0
- package/src/interactive/overlays/interop.ts +139 -0
- package/src/interactive/overlays/keybinding-detail.ts +90 -0
- package/src/interactive/overlays/list-overlay.ts +606 -0
- package/src/interactive/overlays/message-picker.ts +155 -0
- package/src/interactive/overlays/model-selector.ts +1091 -0
- package/src/interactive/overlays/prompts.ts +72 -0
- package/src/interactive/overlays/session-selector-search.ts +31 -0
- package/src/interactive/overlays/session-selector.ts +266 -0
- package/src/interactive/overlays/settings.ts +3363 -0
- package/src/interactive/overlays/skills-hub.ts +237 -0
- package/src/interactive/overlays/tree-selector.ts +387 -0
- package/src/interactive/permission-overlay.ts +170 -0
- package/src/interactive/render-trace.ts +125 -0
- package/src/interactive/renderers/branch-summary.ts +86 -0
- package/src/interactive/renderers/code-ink.ts +420 -0
- package/src/interactive/renderers/compaction-summary.ts +112 -0
- package/src/interactive/renderers/diff.ts +126 -0
- package/src/interactive/renderers/notice.ts +28 -0
- package/src/interactive/renderers/retry-status.ts +31 -0
- package/src/interactive/renderers/structured.ts +89 -0
- package/src/interactive/renderers/tool-execution.ts +1104 -0
- package/src/interactive/renderers/worker-entry.ts +264 -0
- package/src/interactive/session-last-turn.ts +186 -0
- package/src/interactive/session-transcript.ts +105 -0
- package/src/interactive/session-usage-reseed.ts +74 -0
- package/src/interactive/slash-autocomplete.ts +364 -0
- package/src/interactive/slash-commands.ts +1319 -0
- package/src/interactive/slash-spec.ts +453 -0
- package/src/interactive/status/controller.ts +256 -0
- package/src/interactive/status/index.ts +23 -0
- package/src/interactive/status/state-machine.ts +530 -0
- package/src/interactive/status/summary.ts +170 -0
- package/src/interactive/status/types.ts +121 -0
- package/src/interactive/status/verbs.ts +163 -0
- package/src/interactive/status/watchdog.ts +24 -0
- package/src/interactive/tasks-overlay.ts +186 -0
- package/src/interactive/theme/components.ts +55 -0
- package/src/interactive/theme/glyphs.ts +70 -0
- package/src/interactive/theme/index.ts +15 -0
- package/src/interactive/theme/labels.ts +88 -0
- package/src/interactive/theme/rules.ts +138 -0
- package/src/interactive/theme/segments.ts +88 -0
- package/src/interactive/theme/tokens.ts +121 -0
- package/src/interactive/thinking-level-policy.ts +6 -0
- package/src/interactive/tool-prose-loop.ts +122 -0
- package/src/interactive/tool-prose-registration.ts +48 -0
- package/src/interactive/turn-context.ts +854 -0
- package/src/interactive/turn-middleware.ts +283 -0
- package/src/interactive/turn-persistence.ts +441 -0
- package/src/interactive/turn-queues.ts +169 -0
- package/src/interactive/turn-recovery.ts +306 -0
- package/src/interactive/turn-runtime.ts +802 -0
- package/src/interactive/turn-state.ts +123 -0
- package/src/interactive/view/artifacts.ts +1342 -0
- package/src/interactive/view/view-overlay.ts +732 -0
- package/src/interactive/welcome-dashboard.ts +536 -0
- package/src/interactive/worker-receipts.ts +94 -0
- package/src/interactive/worker-replay.ts +111 -0
- package/src/interactive/worker-share.ts +100 -0
- package/src/interactive/worker-stream.ts +442 -0
- package/src/interactive/workspace-facts.ts +141 -0
- package/src/tools/agent-tools.ts +382 -0
- package/src/tools/artifact.ts +103 -0
- package/src/tools/ask-user.ts +656 -0
- package/src/tools/bash.ts +176 -0
- package/src/tools/bootstrap.ts +474 -0
- package/src/tools/codewiki/code-nav.ts +563 -0
- package/src/tools/codewiki/shared.ts +115 -0
- package/src/tools/compete-worktrees.ts +898 -0
- package/src/tools/context/docs-engine.ts +619 -0
- package/src/tools/context/index.ts +435 -0
- package/src/tools/credential-present.ts +151 -0
- package/src/tools/dispatch-arguments.ts +228 -0
- package/src/tools/dispatch-plan.ts +741 -0
- package/src/tools/dispatch-scout.ts +461 -0
- package/src/tools/dispatch.ts +3338 -0
- package/src/tools/edit-diff.ts +534 -0
- package/src/tools/edit.ts +128 -0
- package/src/tools/executables.ts +22 -0
- package/src/tools/file-mutation-queue.ts +35 -0
- package/src/tools/find.ts +292 -0
- package/src/tools/grep.ts +495 -0
- package/src/tools/ignore-policy.ts +169 -0
- package/src/tools/ledger.ts +206 -0
- package/src/tools/ls.ts +110 -0
- package/src/tools/monitor.ts +797 -0
- package/src/tools/network-policy.ts +29 -0
- package/src/tools/observation.ts +421 -0
- package/src/tools/observers.ts +99 -0
- package/src/tools/path-utils.ts +79 -0
- package/src/tools/policy.ts +154 -0
- package/src/tools/profiles.ts +108 -0
- package/src/tools/read.ts +173 -0
- package/src/tools/registry.ts +1157 -0
- package/src/tools/result-shaping.ts +204 -0
- package/src/tools/safe-exec.ts +128 -0
- package/src/tools/spawn-hygiene.ts +182 -0
- package/src/tools/steer.ts +88 -0
- package/src/tools/string-enum.ts +15 -0
- package/src/tools/tasks.ts +168 -0
- package/src/tools/truncate-utf8.ts +17 -0
- package/src/tools/truncate.ts +202 -0
- package/src/tools/verify/frontend.ts +685 -0
- package/src/tools/verify/index.ts +66 -0
- package/src/tools/verify/scripts.ts +108 -0
- package/src/tools/web-fetch.ts +777 -0
- package/src/tools/worker-evidence.ts +215 -0
- package/src/tools/write.ts +52 -0
- package/src/utils/exif-orientation.ts +192 -0
- package/src/utils/git.ts +24 -0
- package/src/utils/image-resize.ts +148 -0
- package/src/utils/photon.ts +103 -0
- package/src/worker/control-lane.ts +22 -0
- package/src/worker/entry.ts +257 -0
- package/src/worker/event-projection.ts +56 -0
- package/src/worker/heartbeat.ts +24 -0
- package/src/worker/ledger-mirror.ts +95 -0
- package/src/worker/ndjson.ts +40 -0
- package/src/worker/protocol.ts +529 -0
- package/src/worker/resource-facts.ts +79 -0
- package/src/worker/runtime-registry.ts +12 -0
- package/src/worker/spec-contract.ts +654 -0
- package/src/worker/stdin-demux.ts +316 -0
- package/dist/acp-UMLFVA3F.js +0 -92
- package/dist/chunk-262G75JS.js +0 -35
- package/dist/chunk-5LDRNKX2.js +0 -1063
- package/dist/chunk-67MTHP2E.js +0 -135
- package/dist/chunk-GOTUR54M.js +0 -9
- package/dist/chunk-TPOCL34A.js +0 -2876
- package/dist/chunk-XV4ZJ6ZM.js +0 -3177
- package/dist/clio-KIQ5SNDS.js +0 -53
- package/dist/configure-G4E3A2PG.js +0 -27
- package/dist/doctor-M5HJJZOL.js +0 -61
- package/dist/domains/agents/builtins/architect.md +0 -33
- package/dist/domains/agents/builtins/coder.md +0 -31
- package/dist/domains/agents/builtins/context-bootstrap.md +0 -38
- package/dist/domains/agents/builtins/debugger.md +0 -30
- package/dist/domains/agents/builtins/documenter.md +0 -31
- package/dist/domains/agents/builtins/git-master.md +0 -30
- package/dist/domains/agents/builtins/provenance.md +0 -30
- package/dist/domains/agents/builtins/researcher.md +0 -71
- package/dist/domains/agents/builtins/scout.md +0 -42
- package/dist/domains/agents/builtins/tester.md +0 -31
- package/dist/domains/agents/builtins/verifier.md +0 -30
- package/dist/domains/agents/builtins/wiki-writer.md +0 -41
- package/dist/fleet-preflight-CLIAX7YR.js +0 -21
- package/dist/preload-KZVHET2B.js +0 -11
- package/dist/version-ROZ6CZKH.js +0 -16
- package/skills/git/commit-crafting/SKILL.md +0 -79
- package/skills/git/commit-crafting/evals.md +0 -92
- package/skills/git/create-pr/SKILL.md +0 -116
- package/skills/git/create-pr/evals.md +0 -114
- package/skills/git/investigate-issue/SKILL.md +0 -139
- package/skills/git/investigate-issue/evals.md +0 -94
- package/skills/git/review-changes/SKILL.md +0 -103
- package/skills/git/review-changes/evals.md +0 -85
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export type SkillActivationTrigger = "slash-command" | "tool";
|
|
2
|
+
export type PendingSkillRequestSource = "slash-command" | "selector" | "marketplace" | "recipe";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The one reply shape every surface teaches for skill suggestions: the
|
|
6
|
+
* context(scope="skills") listing footer, the first-turn middleware
|
|
7
|
+
* reminder, and the operator-gate denial all cite this exact line so the
|
|
8
|
+
* model learns a single protocol.
|
|
9
|
+
*/
|
|
10
|
+
export const SKILL_SUGGESTION_ANCHOR = "Suggested skill: /skill:<name>";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The part of the anchor a real reply keeps once `<name>` is substituted.
|
|
14
|
+
*
|
|
15
|
+
* Surfaces that recognize a suggestion in live output must match this, not the
|
|
16
|
+
* template: no model ever writes the literal `<name>`, so a full-anchor test is
|
|
17
|
+
* always false. The chat panel's glyph guard was exactly that, and the
|
|
18
|
+
* suggestion held the turn's ✦ while the answer beneath it hung plain.
|
|
19
|
+
*/
|
|
20
|
+
export const SKILL_SUGGESTION_PREFIX = SKILL_SUGGESTION_ANCHOR.slice(0, SKILL_SUGGESTION_ANCHOR.indexOf("<name>"));
|
|
21
|
+
|
|
22
|
+
export interface PendingSkillRequest {
|
|
23
|
+
name: string;
|
|
24
|
+
args: string;
|
|
25
|
+
source: PendingSkillRequestSource;
|
|
26
|
+
installed: boolean;
|
|
27
|
+
filePath?: string;
|
|
28
|
+
marketplaceRef?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Tool surface a loaded SKILL.md declares for its own workflow. */
|
|
32
|
+
export interface SkillDeclaredToolPolicy {
|
|
33
|
+
allowedTools?: ReadonlyArray<string>;
|
|
34
|
+
disallowedTools?: ReadonlyArray<string>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface PendingSkillToolPolicy {
|
|
38
|
+
allowedSkillNames: ReadonlyArray<string>;
|
|
39
|
+
requests: ReadonlyArray<PendingSkillRequest>;
|
|
40
|
+
loadedSkillNames: Set<string>;
|
|
41
|
+
/** Declared tool policy per successfully loaded skill, recorded by context(scope=skills). */
|
|
42
|
+
loadedSkillPolicies: Map<string, SkillDeclaredToolPolicy>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Tools admitted regardless of any active skill narrowing: context so the
|
|
47
|
+
* remaining requested skills of the same turn can still load, and ask_user as
|
|
48
|
+
* the escape hatch the block message points at when a workflow genuinely
|
|
49
|
+
* needs a tool its skill did not declare.
|
|
50
|
+
*/
|
|
51
|
+
const SKILL_SURFACE_EXEMPT_TOOLS: ReadonlySet<string> = new Set(["context", "ask_user"]);
|
|
52
|
+
|
|
53
|
+
export interface SkillToolSurfaceViolation {
|
|
54
|
+
/** Every loaded skill that contributed a declaration to the merged surface. */
|
|
55
|
+
skills: ReadonlyArray<string>;
|
|
56
|
+
/** Merged allowed-tools union when allow-narrowing applies; null for a disallow hit. */
|
|
57
|
+
mergedAllowedTools: ReadonlyArray<string> | null;
|
|
58
|
+
/** Skills whose disallowed-tools name the tool directly. */
|
|
59
|
+
disallowedBy: ReadonlyArray<string>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Evaluate a tool call against the tool surface declared by the skills loaded
|
|
64
|
+
* so far under `policy`. Narrowing only ever blocks; it never grants anything
|
|
65
|
+
* the safety net or autonomy mapping would refuse. Merge semantics:
|
|
66
|
+
*
|
|
67
|
+
* - Denials win: a tool named in any loaded skill's disallowed-tools is out.
|
|
68
|
+
* - Allow-narrowing applies only while every loaded skill declares
|
|
69
|
+
* allowed-tools; the merged surface is their union. A loaded skill with no
|
|
70
|
+
* allowed-tools keeps the full surface for its own workflow, so it lifts
|
|
71
|
+
* the allow-narrowing (but not the denials) for the turn.
|
|
72
|
+
*
|
|
73
|
+
* Returns null when the call is inside the surface or no narrowing is active.
|
|
74
|
+
*/
|
|
75
|
+
export function evaluateSkillToolSurface(
|
|
76
|
+
policy: PendingSkillToolPolicy | undefined,
|
|
77
|
+
tool: string,
|
|
78
|
+
): SkillToolSurfaceViolation | null {
|
|
79
|
+
if (!policy || policy.loadedSkillPolicies.size === 0) return null;
|
|
80
|
+
if (SKILL_SURFACE_EXEMPT_TOOLS.has(tool)) return null;
|
|
81
|
+
const entries = [...policy.loadedSkillPolicies.entries()];
|
|
82
|
+
const skills = entries.map(([name]) => name);
|
|
83
|
+
const disallowedBy = entries
|
|
84
|
+
.filter(([, declared]) => declared.disallowedTools?.includes(tool) === true)
|
|
85
|
+
.map(([name]) => name);
|
|
86
|
+
if (disallowedBy.length > 0) return { skills, mergedAllowedTools: null, disallowedBy };
|
|
87
|
+
const allowLists = entries.map(([, declared]) => declared.allowedTools);
|
|
88
|
+
if (allowLists.some((list) => list === undefined || list.length === 0)) return null;
|
|
89
|
+
const merged = [...new Set(allowLists.flatMap((list) => [...(list ?? [])]))];
|
|
90
|
+
if (merged.includes(tool)) return null;
|
|
91
|
+
return { skills, mergedAllowedTools: merged, disallowedBy: [] };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Per-run skill policy for a dispatched worker whose agent recipe declares
|
|
96
|
+
* skills. The worker may load exactly these skill names; anything else gets
|
|
97
|
+
* the same deterministic rejection an unrequested skill gets interactively.
|
|
98
|
+
*/
|
|
99
|
+
export function agentSkillToolPolicy(skillNames: ReadonlyArray<string>): PendingSkillToolPolicy | undefined {
|
|
100
|
+
const allowedSkillNames = [...new Set(skillNames.map((name) => name.trim()).filter((name) => name.length > 0))];
|
|
101
|
+
if (allowedSkillNames.length === 0) return undefined;
|
|
102
|
+
return {
|
|
103
|
+
allowedSkillNames,
|
|
104
|
+
requests: allowedSkillNames.map((name) => ({ name, args: "", source: "recipe" as const, installed: true })),
|
|
105
|
+
loadedSkillNames: new Set<string>(),
|
|
106
|
+
loadedSkillPolicies: new Map<string, SkillDeclaredToolPolicy>(),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface SkillActivation {
|
|
111
|
+
name: string;
|
|
112
|
+
filePath: string;
|
|
113
|
+
hash: string;
|
|
114
|
+
source: string;
|
|
115
|
+
/** Precise root provenance, for example extension:user:<id> or codex-project. */
|
|
116
|
+
sourceOrigin?: string;
|
|
117
|
+
/** Pinned-manifest comparison verdict; "mismatch" records skill_drift. */
|
|
118
|
+
drift?: "match" | "mismatch";
|
|
119
|
+
triggeredBy: SkillActivationTrigger;
|
|
120
|
+
turnId?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Dispatch run whose worker performed this activation. Absent on
|
|
123
|
+
* main-agent activations; set when a dispatch completion folds a worker
|
|
124
|
+
* receipt's activations into the session ledger.
|
|
125
|
+
*/
|
|
126
|
+
runId?: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface SkillActivationSource {
|
|
130
|
+
name: string;
|
|
131
|
+
filePath: string;
|
|
132
|
+
hash: string;
|
|
133
|
+
source: string;
|
|
134
|
+
sourceOrigin?: string;
|
|
135
|
+
sourceInfo?: { source?: string };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function trimmedString(value: unknown): string | null {
|
|
139
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function skillActivationFromSource(
|
|
143
|
+
source: SkillActivationSource,
|
|
144
|
+
triggeredBy: SkillActivationTrigger,
|
|
145
|
+
turnId?: string,
|
|
146
|
+
): SkillActivation {
|
|
147
|
+
const sourceOrigin = trimmedString(source.sourceOrigin) ?? trimmedString(source.sourceInfo?.source);
|
|
148
|
+
return {
|
|
149
|
+
name: source.name,
|
|
150
|
+
filePath: source.filePath,
|
|
151
|
+
hash: source.hash,
|
|
152
|
+
source: source.source,
|
|
153
|
+
...(sourceOrigin ? { sourceOrigin } : {}),
|
|
154
|
+
triggeredBy,
|
|
155
|
+
...(turnId ? { turnId } : {}),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function skillActivationFromToolDetails(details: unknown, turnId?: string): SkillActivation | null {
|
|
160
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) return null;
|
|
161
|
+
const record = details as Record<string, unknown>;
|
|
162
|
+
const name = trimmedString(record.name);
|
|
163
|
+
const filePath = trimmedString(record.filePath) ?? trimmedString(record.path);
|
|
164
|
+
const hash = trimmedString(record.hash);
|
|
165
|
+
const source = trimmedString(record.source);
|
|
166
|
+
const sourceOrigin = trimmedString(record.sourceOrigin) ?? trimmedString(record.origin);
|
|
167
|
+
if (!name || !filePath || !hash || !source) return null;
|
|
168
|
+
const activation = skillActivationFromSource(
|
|
169
|
+
{ name, filePath, hash, source, ...(sourceOrigin ? { sourceOrigin } : {}) },
|
|
170
|
+
"tool",
|
|
171
|
+
turnId,
|
|
172
|
+
);
|
|
173
|
+
if (record.drift === "match" || record.drift === "mismatch") activation.drift = record.drift;
|
|
174
|
+
return activation;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function isSkillActivation(value: unknown): value is SkillActivation {
|
|
178
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
179
|
+
const record = value as Record<string, unknown>;
|
|
180
|
+
return (
|
|
181
|
+
typeof record.name === "string" &&
|
|
182
|
+
typeof record.filePath === "string" &&
|
|
183
|
+
typeof record.hash === "string" &&
|
|
184
|
+
typeof record.source === "string" &&
|
|
185
|
+
(record.sourceOrigin === undefined || typeof record.sourceOrigin === "string") &&
|
|
186
|
+
(record.triggeredBy === "slash-command" || record.triggeredBy === "tool") &&
|
|
187
|
+
(record.turnId === undefined || typeof record.turnId === "string") &&
|
|
188
|
+
(record.runId === undefined || typeof record.runId === "string")
|
|
189
|
+
);
|
|
190
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Micro-profiler for boot phases. Target budget is ≤800ms to first frame per spec §17.
|
|
3
|
+
*
|
|
4
|
+
* Marks double as boot-trace phase markers: each `mark()` forwards to
|
|
5
|
+
* `traceBoot`, so `CLIO_CODER_TRACE_BOOT=1` streams the same phases live to stderr
|
|
6
|
+
* (with elapsed-from-process-start) while the in-memory report stays relative
|
|
7
|
+
* to construction for the `CLIO_CODER_TIMING=1` summary.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { traceBoot } from "./boot-trace.js";
|
|
11
|
+
|
|
12
|
+
type Mark = { name: string; at: number };
|
|
13
|
+
|
|
14
|
+
export class StartupTimer {
|
|
15
|
+
private readonly start = performance.now();
|
|
16
|
+
private readonly marks: Mark[] = [];
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
traceBoot("boot start");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
mark(name: string): void {
|
|
23
|
+
this.marks.push({ name, at: performance.now() - this.start });
|
|
24
|
+
traceBoot(name);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
snapshot(): { totalMs: number; marks: ReadonlyArray<Mark> } {
|
|
28
|
+
return { totalMs: performance.now() - this.start, marks: [...this.marks] };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
report(): string {
|
|
32
|
+
const snap = this.snapshot();
|
|
33
|
+
const lines = [`Clio Coder boot total ${snap.totalMs.toFixed(1)}ms`];
|
|
34
|
+
for (const m of snap.marks) lines.push(` ${m.at.toFixed(1)}ms ${m.name}`);
|
|
35
|
+
return lines.join("\n");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { closeSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, utimesSync, writeSync } from "node:fs";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { processAlive, processBirthToken } from "./process-identity.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The one cross-process advisory file lock. Every durable lock in the tree runs
|
|
8
|
+
* through it (settings.yaml, the dispatch admission state file,
|
|
9
|
+
* credentials.yaml, residency mutations) so there is a single staleness policy
|
|
10
|
+
* instead of four that disagreed by a factor of 26.
|
|
11
|
+
*
|
|
12
|
+
* The lock is keyed by target path (`<target>.lock`) and records the owner's
|
|
13
|
+
* host, pid and birth token. A holder is presumed gone only when its pid is
|
|
14
|
+
* gone on this host; a record from another host is never adjudicated here. The
|
|
15
|
+
* age of the lockfile decides only for a record whose owner cannot be read, so
|
|
16
|
+
* staleness is a backstop rather than a cap on how long a critical section may
|
|
17
|
+
* legitimately take: the settings lock used to steal itself back from a healthy
|
|
18
|
+
* writer after five seconds. Async holders additionally refresh the lockfile mtime while
|
|
19
|
+
* they work, so even the backstop does not fire under a live holder. The sync
|
|
20
|
+
* path blocks the event loop by construction and cannot run that timer; pid
|
|
21
|
+
* liveness is what protects it.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** Consulted only when the owner cannot be identified. */
|
|
25
|
+
const STALE_LOCK_MS = 30_000;
|
|
26
|
+
/** Well under STALE_LOCK_MS, so a slow holder never reads as an abandoned one. */
|
|
27
|
+
const REFRESH_LOCK_MS = 5_000;
|
|
28
|
+
/**
|
|
29
|
+
* Default acquisition budget. Deliberately under DEFAULT_CAPACITY_LEASE_TTL_MS:
|
|
30
|
+
* the sync path blocks the event loop, so a process waiting here also stalls its
|
|
31
|
+
* own lease heartbeat, and a wait longer than a lease lives would let a live
|
|
32
|
+
* holder's lease expire under it. capacity-lease.ts asserts the relation.
|
|
33
|
+
*/
|
|
34
|
+
export const FILE_LOCK_ACQUIRE_TIMEOUT_MS = 20_000;
|
|
35
|
+
|
|
36
|
+
export interface StateFileLockOptions {
|
|
37
|
+
/** Acquisition budget. Default `FILE_LOCK_ACQUIRE_TIMEOUT_MS`. */
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
/**
|
|
40
|
+
* `run-unlocked` runs `fn` anyway when the lock cannot be taken. Residency
|
|
41
|
+
* mutations need it: serializing them is an optimization and must never fail
|
|
42
|
+
* or stall a turn. Everything else fails closed.
|
|
43
|
+
*/
|
|
44
|
+
onAcquireFailure?: "throw" | "run-unlocked";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface LockOwner {
|
|
48
|
+
/** Null on a record written before the field existed; read as this host. */
|
|
49
|
+
host: string | null;
|
|
50
|
+
pid: number;
|
|
51
|
+
birthToken: string | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function readLockOwner(lockPath: string): LockOwner | null {
|
|
55
|
+
try {
|
|
56
|
+
const raw = readFileSync(lockPath, "utf8").trim();
|
|
57
|
+
const record = raw.startsWith("{") ? (JSON.parse(raw) as Record<string, unknown>) : { pid: Number.parseInt(raw, 10) };
|
|
58
|
+
const { host, pid, birthToken } = record;
|
|
59
|
+
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0) return null;
|
|
60
|
+
return {
|
|
61
|
+
host: typeof host === "string" ? host : null,
|
|
62
|
+
pid,
|
|
63
|
+
birthToken: typeof birthToken === "string" ? birthToken : null,
|
|
64
|
+
};
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Mirrors compete-worktrees' ownerIsAlive: foreign hosts are never adjudicated, a null token cannot rule out pid reuse. */
|
|
71
|
+
function ownerIsAlive(owner: LockOwner): boolean {
|
|
72
|
+
if (owner.host !== null && owner.host !== hostname()) return true;
|
|
73
|
+
if (!processAlive(owner.pid)) return false;
|
|
74
|
+
if (owner.birthToken === null) return true;
|
|
75
|
+
const current = processBirthToken(owner.pid);
|
|
76
|
+
return current === null || current === owner.birthToken;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function lockfileAgeMs(lockPath: string): number | null {
|
|
80
|
+
try {
|
|
81
|
+
return Date.now() - statSync(lockPath).mtimeMs;
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** True once the lock is ours. Steals only from an owner that is provably gone. */
|
|
88
|
+
function tryAcquire(lockPath: string): boolean {
|
|
89
|
+
try {
|
|
90
|
+
const fd = openSync(lockPath, "wx", 0o600);
|
|
91
|
+
try {
|
|
92
|
+
writeSync(
|
|
93
|
+
fd,
|
|
94
|
+
`${JSON.stringify({ host: hostname(), pid: process.pid, birthToken: processBirthToken(), at: new Date().toISOString() })}\n`,
|
|
95
|
+
);
|
|
96
|
+
} finally {
|
|
97
|
+
closeSync(fd);
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
if ((err as NodeJS.ErrnoException).code !== "EEXIST") throw err;
|
|
102
|
+
}
|
|
103
|
+
const owner = readLockOwner(lockPath);
|
|
104
|
+
const ageMs = lockfileAgeMs(lockPath);
|
|
105
|
+
const abandoned = owner !== null ? !ownerIsAlive(owner) : ageMs !== null && ageMs > STALE_LOCK_MS;
|
|
106
|
+
if (abandoned) {
|
|
107
|
+
try {
|
|
108
|
+
unlinkSync(lockPath);
|
|
109
|
+
} catch {
|
|
110
|
+
// Another waiter reclaimed it first; the next attempt races normally.
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function timeoutError(lockPath: string, timeoutMs: number): Error {
|
|
117
|
+
return new Error(
|
|
118
|
+
`timed out after ${timeoutMs}ms waiting for ${lockPath} (owner pid=${readLockOwner(lockPath)?.pid ?? "?"}); delete it if no other clio process is running`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function backoffMs(attempt: number): number {
|
|
123
|
+
return Math.min(100, 5 * 2 ** Math.min(attempt, 5));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function release(lockPath: string): void {
|
|
127
|
+
// Only unlink a lock we still own. If ours was reclaimed as abandoned and a
|
|
128
|
+
// sibling now holds a fresh one, deleting here would open their section.
|
|
129
|
+
const owner = readLockOwner(lockPath);
|
|
130
|
+
if (owner?.pid !== process.pid || (owner.host !== null && owner.host !== hostname())) return;
|
|
131
|
+
try {
|
|
132
|
+
unlinkSync(lockPath);
|
|
133
|
+
} catch {
|
|
134
|
+
// Already gone; fine.
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Keep a held lock's mtime current so the staleness backstop cannot fire under
|
|
140
|
+
* a live holder. Only the async path can do this; see the module comment.
|
|
141
|
+
*/
|
|
142
|
+
function startRefresh(lockPath: string): () => void {
|
|
143
|
+
const timer = setInterval(() => {
|
|
144
|
+
const at = new Date();
|
|
145
|
+
try {
|
|
146
|
+
utimesSync(lockPath, at, at);
|
|
147
|
+
} catch {
|
|
148
|
+
// Released or stolen; `release` re-checks ownership either way.
|
|
149
|
+
}
|
|
150
|
+
}, REFRESH_LOCK_MS);
|
|
151
|
+
timer.unref();
|
|
152
|
+
return () => clearInterval(timer);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Synchronous variant for admission planners whose host API cannot yield. */
|
|
156
|
+
export function withStateFileLockSync<T>(targetPath: string, fn: () => T, options: StateFileLockOptions = {}): T {
|
|
157
|
+
const lockPath = `${targetPath}.lock`;
|
|
158
|
+
const timeoutMs = options.timeoutMs ?? FILE_LOCK_ACQUIRE_TIMEOUT_MS;
|
|
159
|
+
let held = false;
|
|
160
|
+
try {
|
|
161
|
+
mkdirSync(dirname(lockPath), { recursive: true });
|
|
162
|
+
const deadlineMs = Date.now() + timeoutMs;
|
|
163
|
+
for (let attempt = 1; !tryAcquire(lockPath); attempt += 1) {
|
|
164
|
+
if (Date.now() > deadlineMs) throw timeoutError(lockPath, timeoutMs);
|
|
165
|
+
// Atomics.wait rather than a timer: the callers of this variant are
|
|
166
|
+
// inside host APIs that cannot yield.
|
|
167
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, backoffMs(attempt));
|
|
168
|
+
}
|
|
169
|
+
held = true;
|
|
170
|
+
} catch (err) {
|
|
171
|
+
if (options.onAcquireFailure !== "run-unlocked") throw err;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
return fn();
|
|
175
|
+
} finally {
|
|
176
|
+
if (held) release(lockPath);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export async function withStateFileLock<T>(
|
|
181
|
+
targetPath: string,
|
|
182
|
+
fn: () => T | Promise<T>,
|
|
183
|
+
options: StateFileLockOptions = {},
|
|
184
|
+
): Promise<T> {
|
|
185
|
+
const lockPath = `${targetPath}.lock`;
|
|
186
|
+
const timeoutMs = options.timeoutMs ?? FILE_LOCK_ACQUIRE_TIMEOUT_MS;
|
|
187
|
+
let held = false;
|
|
188
|
+
try {
|
|
189
|
+
mkdirSync(dirname(lockPath), { recursive: true });
|
|
190
|
+
const deadlineMs = Date.now() + timeoutMs;
|
|
191
|
+
for (let attempt = 1; !tryAcquire(lockPath); attempt += 1) {
|
|
192
|
+
if (Date.now() > deadlineMs) throw timeoutError(lockPath, timeoutMs);
|
|
193
|
+
const base = backoffMs(attempt);
|
|
194
|
+
await new Promise((resolve) => setTimeout(resolve, base + Math.floor(Math.random() * base)));
|
|
195
|
+
}
|
|
196
|
+
held = true;
|
|
197
|
+
} catch (err) {
|
|
198
|
+
if (options.onAcquireFailure !== "run-unlocked") throw err;
|
|
199
|
+
}
|
|
200
|
+
const stopRefresh = held ? startRefresh(lockPath) : null;
|
|
201
|
+
try {
|
|
202
|
+
return await fn();
|
|
203
|
+
} finally {
|
|
204
|
+
stopRefresh?.();
|
|
205
|
+
if (held) release(lockPath);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shutdown coordinator implementing the four-phase sequence from spec §17:
|
|
3
|
+
* DRAIN stop accepting new input / dispatch
|
|
4
|
+
* TERMINATE kill active workers (wired in Phase 7)
|
|
5
|
+
* PERSIST atomic writes of domain state
|
|
6
|
+
* EXIT tear down TUI and process.exit
|
|
7
|
+
*
|
|
8
|
+
* Each registered hook runs under a per-hook timeout so a single slow or
|
|
9
|
+
* hanging hook cannot block the TUI from exiting. The cap is 500ms by
|
|
10
|
+
* default and can be overridden via CLIO_CODER_SHUTDOWN_HOOK_MS for tests.
|
|
11
|
+
* Timed-out hooks are logged and shutdown continues to the next hook.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { BusChannels } from "./bus-events.js";
|
|
15
|
+
import { getSharedBus } from "./shared-bus.js";
|
|
16
|
+
|
|
17
|
+
export type TerminationPhase = "idle" | "draining" | "terminating" | "persisting" | "exiting";
|
|
18
|
+
|
|
19
|
+
type Hook = () => void | Promise<void>;
|
|
20
|
+
|
|
21
|
+
/** Wall-clock budget per hook and per domain.stop() call. */
|
|
22
|
+
export const DEFAULT_SHUTDOWN_HOOK_MS = 500;
|
|
23
|
+
|
|
24
|
+
const SIGNAL_EXIT_CODES: Partial<Record<NodeJS.Signals, number>> = {
|
|
25
|
+
SIGHUP: 129,
|
|
26
|
+
SIGINT: 130,
|
|
27
|
+
SIGTERM: 143,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function resolveShutdownHookBudgetMs(): number {
|
|
31
|
+
const raw = process.env.CLIO_CODER_SHUTDOWN_HOOK_MS;
|
|
32
|
+
if (raw === undefined) return DEFAULT_SHUTDOWN_HOOK_MS;
|
|
33
|
+
const parsed = Number.parseInt(raw, 10);
|
|
34
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return DEFAULT_SHUTDOWN_HOOK_MS;
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Run `op` with a wall-clock cap. Resolves true when `op` completes within
|
|
40
|
+
* the budget, false when the cap fires first. Errors from `op` are swallowed
|
|
41
|
+
* and reported via `onError` so a rejecting hook cannot propagate past the
|
|
42
|
+
* shutdown coordinator.
|
|
43
|
+
*/
|
|
44
|
+
export async function runWithBudget(
|
|
45
|
+
op: () => void | Promise<void>,
|
|
46
|
+
budgetMs: number,
|
|
47
|
+
onError?: (err: unknown) => void,
|
|
48
|
+
): Promise<boolean> {
|
|
49
|
+
let timer: NodeJS.Timeout | undefined;
|
|
50
|
+
const timeout = new Promise<"timeout">((resolve) => {
|
|
51
|
+
timer = setTimeout(() => resolve("timeout"), budgetMs);
|
|
52
|
+
});
|
|
53
|
+
try {
|
|
54
|
+
const done = Promise.resolve()
|
|
55
|
+
.then(() => op())
|
|
56
|
+
.then(() => "done" as const)
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
onError?.(err);
|
|
59
|
+
return "done" as const;
|
|
60
|
+
});
|
|
61
|
+
const outcome = await Promise.race([done, timeout]);
|
|
62
|
+
return outcome === "done";
|
|
63
|
+
} finally {
|
|
64
|
+
if (timer) clearTimeout(timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class TerminationCoordinator {
|
|
69
|
+
private phase: TerminationPhase = "idle";
|
|
70
|
+
private readonly drainHooks: Hook[] = [];
|
|
71
|
+
private readonly terminateHooks: Hook[] = [];
|
|
72
|
+
private readonly persistHooks: Hook[] = [];
|
|
73
|
+
private exitCode = 0;
|
|
74
|
+
private started = false;
|
|
75
|
+
private signalHandler: ((signal: NodeJS.Signals) => void) | null = null;
|
|
76
|
+
|
|
77
|
+
getPhase(): TerminationPhase {
|
|
78
|
+
return this.phase;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The process exit code this shutdown will use. Set before any hook runs,
|
|
83
|
+
* so a hook sealing terminal accounting records the same status the process
|
|
84
|
+
* reports (130 for SIGINT, 143 for SIGTERM).
|
|
85
|
+
*/
|
|
86
|
+
getExitCode(): number {
|
|
87
|
+
return this.exitCode;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
onDrain(hook: Hook): void {
|
|
91
|
+
this.drainHooks.push(hook);
|
|
92
|
+
}
|
|
93
|
+
onTerminate(hook: Hook): void {
|
|
94
|
+
this.terminateHooks.push(hook);
|
|
95
|
+
}
|
|
96
|
+
onPersist(hook: Hook): void {
|
|
97
|
+
this.persistHooks.push(hook);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async shutdown(code = 0): Promise<void> {
|
|
101
|
+
if (this.started) return;
|
|
102
|
+
this.started = true;
|
|
103
|
+
this.exitCode = code;
|
|
104
|
+
const bus = getSharedBus();
|
|
105
|
+
const debug = process.env.CLIO_CODER_DEBUG_SHUTDOWN === "1";
|
|
106
|
+
const budgetMs = resolveShutdownHookBudgetMs();
|
|
107
|
+
const mark = debug ? process.hrtime.bigint() : 0n;
|
|
108
|
+
const log = (msg: string): void => {
|
|
109
|
+
if (!debug) return;
|
|
110
|
+
const ms = Number(process.hrtime.bigint() - mark) / 1e6;
|
|
111
|
+
process.stderr.write(`[clio:shutdown] +${ms.toFixed(1)}ms ${msg}\n`);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
this.phase = "draining";
|
|
115
|
+
bus.emit(BusChannels.ShutdownRequested, { phase: this.phase });
|
|
116
|
+
log("drain:start");
|
|
117
|
+
await this.runHooks(this.drainHooks, "drain", budgetMs, log);
|
|
118
|
+
log("drain:end");
|
|
119
|
+
bus.emit(BusChannels.ShutdownDrained, {});
|
|
120
|
+
|
|
121
|
+
this.phase = "terminating";
|
|
122
|
+
log("terminate:start");
|
|
123
|
+
await this.runHooks(this.terminateHooks, "terminate", budgetMs, log);
|
|
124
|
+
log("terminate:end");
|
|
125
|
+
bus.emit(BusChannels.ShutdownTerminated, {});
|
|
126
|
+
|
|
127
|
+
this.phase = "persisting";
|
|
128
|
+
log("persist:start");
|
|
129
|
+
await this.runHooks(this.persistHooks, "persist", budgetMs, log);
|
|
130
|
+
log("persist:end");
|
|
131
|
+
bus.emit(BusChannels.ShutdownPersisted, {});
|
|
132
|
+
|
|
133
|
+
this.phase = "exiting";
|
|
134
|
+
bus.emit(BusChannels.SessionEnd, { exitCode: this.exitCode });
|
|
135
|
+
log("process.exit");
|
|
136
|
+
process.exit(this.exitCode);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private async runHooks(hooks: Hook[], phase: string, budgetMs: number, log: (msg: string) => void): Promise<void> {
|
|
140
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
141
|
+
const hook = hooks[i];
|
|
142
|
+
if (!hook) continue;
|
|
143
|
+
const t0 = process.hrtime.bigint();
|
|
144
|
+
const completed = await runWithBudget(hook, budgetMs, (err) => {
|
|
145
|
+
console.error("[clio:termination] hook failed:", err);
|
|
146
|
+
});
|
|
147
|
+
const dt = Number(process.hrtime.bigint() - t0) / 1e6;
|
|
148
|
+
if (!completed) {
|
|
149
|
+
process.stderr.write(
|
|
150
|
+
`[clio:termination] ${phase}[${i}] exceeded ${budgetMs}ms budget; abandoning and continuing shutdown\n`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
log(` ${phase}[${i}] ${dt.toFixed(1)}ms${completed ? "" : " (timed out)"}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* SIGHUP is here for the same reason as SIGTERM. Without a listener Node
|
|
159
|
+
* takes its default action and the process dies with no shutdown at all,
|
|
160
|
+
* which on a TUI session means the terminal is never given back. Exit codes
|
|
161
|
+
* follow the 128+signal convention.
|
|
162
|
+
*/
|
|
163
|
+
installSignalHandlers(): void {
|
|
164
|
+
if (this.signalHandler) return;
|
|
165
|
+
const handler = (signal: NodeJS.Signals): void => {
|
|
166
|
+
process.stderr.write(`\nClio Coder: received ${signal}, shutting down...\n`);
|
|
167
|
+
void this.shutdown(SIGNAL_EXIT_CODES[signal] ?? 143);
|
|
168
|
+
};
|
|
169
|
+
this.signalHandler = handler;
|
|
170
|
+
process.once("SIGINT", handler);
|
|
171
|
+
process.once("SIGTERM", handler);
|
|
172
|
+
process.once("SIGHUP", handler);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Hand SIGINT to a foreground owner and return the call that takes it back.
|
|
177
|
+
*
|
|
178
|
+
* Boot arms this coordinator before any interactive surface exists, and Node
|
|
179
|
+
* runs signal listeners in registration order, so a TUI that merely added its
|
|
180
|
+
* own listener would lose every first press to a shutdown already underway.
|
|
181
|
+
* One owner holds the interrupt at a time and the transfer is explicit.
|
|
182
|
+
* SIGTERM is not part of the handover; it is never an interactive gesture.
|
|
183
|
+
*/
|
|
184
|
+
releaseInterruptOwnership(): () => void {
|
|
185
|
+
const handler = this.signalHandler;
|
|
186
|
+
if (!handler) return () => {};
|
|
187
|
+
process.off("SIGINT", handler);
|
|
188
|
+
let restored = false;
|
|
189
|
+
return () => {
|
|
190
|
+
if (restored) return;
|
|
191
|
+
restored = true;
|
|
192
|
+
process.once("SIGINT", handler);
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let coordinator: TerminationCoordinator | null = null;
|
|
198
|
+
|
|
199
|
+
export function getTerminationCoordinator(): TerminationCoordinator {
|
|
200
|
+
if (!coordinator) coordinator = new TerminationCoordinator();
|
|
201
|
+
return coordinator;
|
|
202
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Largest delay Node can schedule without overflowing to an approximately 1 ms timer. */
|
|
2
|
+
export const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Normalize optional/disable-capable timer inputs. Nonpositive and NaN values
|
|
6
|
+
* disable the timer; oversized and infinite values cap at Node's real limit.
|
|
7
|
+
*/
|
|
8
|
+
export function clampTimerDelayMs(value: number): number {
|
|
9
|
+
if (Number.isNaN(value) || value <= 0) return 0;
|
|
10
|
+
return value >= MAX_TIMER_DELAY_MS ? MAX_TIMER_DELAY_MS : Math.floor(value);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function sleep(ms: number): Promise<void> {
|
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let negativeDurations = 0;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Elapsed between two reads of the same clock, signed.
|
|
21
|
+
*
|
|
22
|
+
* A negative result means the clock moved backwards between the two reads —
|
|
23
|
+
* an NTP correction, a resume, or a duration derived across two hosts — and it
|
|
24
|
+
* is a bug in the caller, not a value to be silently swallowed. Clamping with
|
|
25
|
+
* `Math.max(0, …)` hides that, so the clamp belongs at the render boundary and
|
|
26
|
+
* nothing else. Every occurrence is counted; nothing is written to stderr,
|
|
27
|
+
* because the TUI owns that stream and this sits on hot measurement paths.
|
|
28
|
+
*/
|
|
29
|
+
export function rawDurationMs(start: number, end: number): number {
|
|
30
|
+
const elapsed = end - start;
|
|
31
|
+
if (elapsed < 0) negativeDurations += 1;
|
|
32
|
+
return elapsed;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** How many negative durations this process has produced since it started. */
|
|
36
|
+
export function negativeDurationCount(): number {
|
|
37
|
+
return negativeDurations;
|
|
38
|
+
}
|