@adhdev/daemon-core 0.9.82-rc.41 → 0.9.82-rc.410
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/dist/boot/daemon-lifecycle.d.ts +9 -0
- package/dist/boot/process-hardening.d.ts +50 -0
- package/dist/build-info.d.ts +37 -0
- package/dist/chat/source-machine.d.ts +166 -0
- package/dist/chat/source-resolver.d.ts +104 -0
- package/dist/chat/subscription-updates.d.ts +1 -0
- package/dist/cli-adapter-types.d.ts +68 -2
- package/dist/cli-adapters/cli-script-runner.d.ts +117 -0
- package/dist/cli-adapters/cli-state-engine.d.ts +200 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +126 -64
- package/dist/cli-adapters/provider-cli-parse.d.ts +5 -0
- package/dist/cli-adapters/provider-cli-runtime.d.ts +34 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +74 -0
- package/dist/cli-adapters/pty-write-chunking.d.ts +34 -0
- package/dist/cli-adapters/raw-terminal-io.d.ts +37 -0
- package/dist/cli-adapters/resolve-executable.d.ts +14 -0
- package/dist/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +6 -3
- package/dist/cli-adapters/terminal-backends/types.d.ts +10 -2
- package/dist/cli-adapters/terminal-screen.d.ts +4 -11
- package/dist/commands/chat-commands-debug-bundle.d.ts +14 -0
- package/dist/commands/chat-commands-read.d.ts +7 -0
- package/dist/commands/chat-commands-scope.d.ts +39 -0
- package/dist/commands/chat-commands-shared.d.ts +33 -0
- package/dist/commands/chat-commands-write.d.ts +14 -0
- package/dist/commands/chat-commands.d.ts +10 -23
- package/dist/commands/cli-manager.d.ts +15 -1
- package/dist/commands/handler.d.ts +125 -0
- package/dist/commands/high-family/index.d.ts +3 -0
- package/dist/commands/high-family/mesh-coordinator-launch.d.ts +2 -0
- package/dist/commands/high-family/mesh-events.d.ts +2 -0
- package/dist/commands/high-family/mesh-status.d.ts +2 -0
- package/dist/commands/high-family/types.d.ts +60 -0
- package/dist/commands/low-family/coordinator-prompt.d.ts +9 -0
- package/dist/commands/low-family/daemon-lifecycle.d.ts +2 -0
- package/dist/commands/low-family/diagnostics.d.ts +2 -0
- package/dist/commands/low-family/index.d.ts +3 -0
- package/dist/commands/low-family/mesh-ledger.d.ts +10 -0
- package/dist/commands/low-family/mesh-node-logs.d.ts +2 -0
- package/dist/commands/low-family/notification.d.ts +2 -0
- package/dist/commands/low-family/refine-config.d.ts +2 -0
- package/dist/commands/low-family/session-host.d.ts +2 -0
- package/dist/commands/low-family/spec-providerdev.d.ts +11 -0
- package/dist/commands/low-family/status-meta.d.ts +2 -0
- package/dist/commands/low-family/types.d.ts +33 -0
- package/dist/commands/med-family/cli-agent.d.ts +2 -0
- package/dist/commands/med-family/fast-forward.d.ts +2 -0
- package/dist/commands/med-family/ide.d.ts +10 -0
- package/dist/commands/med-family/index.d.ts +3 -0
- package/dist/commands/med-family/mesh-crud.d.ts +2 -0
- package/dist/commands/med-family/mesh-host-pairing.d.ts +2 -0
- package/dist/commands/med-family/mesh-queue.d.ts +2 -0
- package/dist/commands/med-family/mesh-restart.d.ts +2 -0
- package/dist/commands/med-family/types.d.ts +116 -0
- package/dist/commands/mesh-coordinator.d.ts +85 -1
- package/dist/commands/router.d.ts +256 -2
- package/dist/commands/upgrade-helper.d.ts +41 -1
- package/dist/config/chat-history.d.ts +9 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/config/mesh-config.d.ts +77 -1
- package/dist/config/mesh-json-config.d.ts +299 -0
- package/dist/daemon/dev-server.d.ts +0 -2
- package/dist/detection/ide-detector.d.ts +13 -0
- package/dist/detection/win32-ide-version.d.ts +37 -0
- package/dist/git/change-impact-config.d.ts +159 -0
- package/dist/git/git-commands.d.ts +11 -1
- package/dist/git/git-diff.d.ts +6 -0
- package/dist/git/git-executor.d.ts +11 -0
- package/dist/git/git-status.d.ts +57 -0
- package/dist/git/git-types.d.ts +2 -50
- package/dist/git/git-worktree.d.ts +71 -1
- package/dist/git/index.d.ts +3 -1
- package/dist/index.d.ts +57 -13
- package/dist/index.js +46445 -17229
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46052 -16978
- package/dist/index.mjs.map +1 -1
- package/dist/installer.d.ts +1 -4
- package/dist/ipc/local-ipc-server.d.ts +91 -0
- package/dist/launch.d.ts +1 -1
- package/dist/logging/async-batch-writer.d.ts +10 -0
- package/dist/logging/log-redactor.d.ts +24 -0
- package/dist/logging/log-tail-reader.d.ts +81 -0
- package/dist/logging/logger.d.ts +1 -1
- package/dist/mesh/contracts.d.ts +164 -0
- package/dist/mesh/coordinator-prompt.d.ts +89 -0
- package/dist/mesh/coordinator-registry.d.ts +59 -0
- package/dist/mesh/mesh-active-work.d.ts +174 -0
- package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
- package/dist/mesh/mesh-delivery-policy.d.ts +131 -0
- package/dist/mesh/mesh-event-classify.d.ts +5 -0
- package/dist/mesh/mesh-event-forwarding.d.ts +19 -0
- package/dist/mesh/mesh-event-trace.d.ts +21 -0
- package/dist/mesh/mesh-events-coordinator.d.ts +4 -0
- package/dist/mesh/mesh-events-pending.d.ts +55 -0
- package/dist/mesh/mesh-events-stale.d.ts +61 -0
- package/dist/mesh/mesh-events-utils.d.ts +75 -0
- package/dist/mesh/mesh-events.d.ts +6 -49
- package/dist/mesh/mesh-fast-forward.d.ts +81 -0
- package/dist/mesh/mesh-host-ownership.d.ts +9 -0
- package/dist/mesh/mesh-init.d.ts +86 -0
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
- package/dist/mesh/mesh-ledger.d.ts +77 -1
- package/dist/mesh/mesh-missions.d.ts +164 -0
- package/dist/mesh/mesh-node-identity.d.ts +289 -0
- package/dist/mesh/mesh-queue-assignment.d.ts +95 -0
- package/dist/mesh/mesh-reconcile-loop.d.ts +65 -0
- package/dist/mesh/mesh-refine-batch.d.ts +68 -0
- package/dist/mesh/mesh-refine-gates.d.ts +428 -0
- package/dist/mesh/mesh-refine-status.d.ts +62 -0
- package/dist/mesh/mesh-review-inbox.d.ts +90 -0
- package/dist/mesh/mesh-routing.d.ts +70 -0
- package/dist/mesh/mesh-runtime-store.d.ts +447 -0
- package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
- package/dist/mesh/mesh-task-stats.d.ts +49 -0
- package/dist/mesh/mesh-unresolved-forward-outbox.d.ts +30 -0
- package/dist/mesh/mesh-warmup-deadline.d.ts +68 -0
- package/dist/mesh/mesh-work-queue.d.ts +281 -5
- package/dist/mesh/preview-freshness.d.ts +18 -0
- package/dist/mesh/refine-config.d.ts +216 -0
- package/dist/mesh/worktree-bootstrap-config.d.ts +145 -0
- package/dist/providers/acp-provider-instance.d.ts +5 -0
- package/dist/providers/approval-utils.d.ts +20 -0
- package/dist/providers/chat-message-normalization.d.ts +31 -1
- package/dist/providers/cli-provider-instance.d.ts +197 -3
- package/dist/providers/contracts.d.ts +139 -6
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/manual-attendance.d.ts +63 -0
- package/dist/providers/native-history/antigravity-cli-transcript.d.ts +100 -0
- package/dist/providers/native-history/claude-cli-transcript.d.ts +70 -0
- package/dist/providers/native-history/codex-cli-transcript.d.ts +73 -0
- package/dist/providers/native-history/constants.d.ts +12 -0
- package/dist/providers/native-history/dispatcher.d.ts +27 -0
- package/dist/providers/native-history/hermes-cli-transcript.d.ts +30 -0
- package/dist/providers/native-history/index.d.ts +13 -0
- package/dist/providers/provider-instance-manager.d.ts +14 -0
- package/dist/providers/provider-instance.d.ts +23 -1
- package/dist/providers/provider-loader.d.ts +26 -4
- package/dist/providers/provider-trust.d.ts +31 -0
- package/dist/providers/read-chat-contract.d.ts +29 -0
- package/dist/providers/sdk/v1/builders/acp/detect-status.d.ts +68 -0
- package/dist/providers/sdk/v1/builders/cli/detect-status.d.ts +86 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval-squash.d.ts +59 -0
- package/dist/providers/sdk/v1/builders/cli/parse-approval.d.ts +65 -0
- package/dist/providers/sdk/v1/builders/cli/parse-session.d.ts +91 -0
- package/dist/providers/sdk/v1/builders/cli/visible-region.d.ts +42 -0
- package/dist/providers/sdk/v1/fixture-tooling/format.d.ts +126 -0
- package/dist/providers/sdk/v1/fixture-tooling/index.d.ts +8 -0
- package/dist/providers/sdk/v1/fixture-tooling/replay.d.ts +38 -0
- package/dist/providers/sdk/v1/index.d.ts +30 -0
- package/dist/providers/sdk/v1/sandbox/README-design.d.ts +193 -0
- package/dist/providers/sdk/v1/sandbox/require-whitelist.d.ts +74 -0
- package/dist/providers/sdk/v1/sandbox/script-runner.d.ts +98 -0
- package/dist/providers/sdk/v1/types/cli/index.d.ts +277 -0
- package/dist/providers/sdk/v1/types/common/index.d.ts +203 -0
- package/dist/providers/sdk/v1/validators/index.d.ts +5 -0
- package/dist/providers/sdk/v1/validators/manifest.d.ts +40 -0
- package/dist/providers/sdk/v1/validators/taint.d.ts +52 -0
- package/dist/providers/spec/adapter.d.ts +91 -0
- package/dist/providers/spec/cli-adapter.d.ts +223 -0
- package/dist/providers/spec/evaluator.d.ts +45 -0
- package/dist/providers/spec/fsm-driver.d.ts +407 -0
- package/dist/providers/spec/fsm-evaluator.d.ts +76 -0
- package/dist/providers/spec/fsm-loader.d.ts +14 -0
- package/dist/providers/spec/fsm-types.d.ts +174 -0
- package/dist/providers/spec/native-history-executor.d.ts +41 -0
- package/dist/providers/spec/pre-launch-trust.d.ts +16 -0
- package/dist/providers/spec/route.d.ts +4 -0
- package/dist/providers/spec/types.d.ts +222 -0
- package/dist/providers/status-monitor.d.ts +7 -7
- package/dist/providers/transcript-v2.d.ts +176 -0
- package/dist/providers/types/interactive-prompt.d.ts +84 -0
- package/dist/providers/working-dir.d.ts +17 -0
- package/dist/repo-mesh-types.d.ts +420 -13
- package/dist/runtime-defaults.d.ts +2 -0
- package/dist/sessions/registry.d.ts +6 -0
- package/dist/shared-types-extra.d.ts +2 -4
- package/dist/shared-types.d.ts +59 -2
- package/dist/status/normalize.d.ts +1 -1
- package/dist/status/normalize.js +1 -0
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +1 -0
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +2 -0
- package/dist/status/snapshot.d.ts +26 -0
- package/dist/system/hash.d.ts +8 -0
- package/dist/system/load-better-sqlite3.d.ts +21 -0
- package/dist/types.d.ts +5 -0
- package/package.json +7 -3
- package/src/agent-stream/poller.ts +2 -3
- package/src/agent-stream/provider-adapter.ts +1 -1
- package/src/boot/daemon-lifecycle.ts +63 -12
- package/src/boot/process-hardening.ts +89 -0
- package/src/build-info.ts +73 -0
- package/src/chat/source-machine.ts +534 -0
- package/src/chat/source-resolver.ts +0 -0
- package/src/chat/subscription-updates.ts +20 -1
- package/src/cli-adapter-types.d.ts +3 -1
- package/src/cli-adapter-types.ts +68 -2
- package/src/cli-adapters/cli-script-runner.ts +421 -0
- package/src/cli-adapters/cli-state-engine.ts +1246 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +914 -1144
- package/src/cli-adapters/provider-cli-parse.d.ts +2 -0
- package/src/cli-adapters/provider-cli-parse.ts +19 -0
- package/src/cli-adapters/provider-cli-runtime.ts +56 -7
- package/src/cli-adapters/provider-cli-shared.d.ts +4 -0
- package/src/cli-adapters/provider-cli-shared.ts +121 -11
- package/src/cli-adapters/pty-transport.ts +2 -1
- package/src/cli-adapters/pty-write-chunking.ts +106 -0
- package/src/cli-adapters/raw-terminal-io.ts +252 -0
- package/src/cli-adapters/resolve-executable.ts +90 -0
- package/src/cli-adapters/session-host-transport.ts +2 -1
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +63 -29
- package/src/cli-adapters/terminal-backends/types.ts +10 -3
- package/src/cli-adapters/terminal-screen.ts +16 -81
- package/src/commands/WINDOWS-UPGRADE-LOCK-FAILURE.md +198 -0
- package/src/commands/chat-commands-debug-bundle.ts +398 -0
- package/src/commands/chat-commands-read.ts +2327 -0
- package/src/commands/chat-commands-scope.ts +54 -0
- package/src/commands/chat-commands-shared.ts +114 -0
- package/src/commands/chat-commands-write.ts +891 -0
- package/src/commands/chat-commands.ts +19 -1841
- package/src/commands/cli-manager.ts +527 -26
- package/src/commands/handler.ts +841 -2
- package/src/commands/high-family/index.ts +28 -0
- package/src/commands/high-family/mesh-coordinator-launch.ts +673 -0
- package/src/commands/high-family/mesh-events.ts +80 -0
- package/src/commands/high-family/mesh-status.ts +678 -0
- package/src/commands/high-family/types.ts +76 -0
- package/src/commands/low-family/coordinator-prompt.ts +72 -0
- package/src/commands/low-family/daemon-lifecycle.ts +107 -0
- package/src/commands/low-family/diagnostics.ts +57 -0
- package/src/commands/low-family/index.ts +37 -0
- package/src/commands/low-family/mesh-ledger.ts +62 -0
- package/src/commands/low-family/mesh-node-logs.ts +87 -0
- package/src/commands/low-family/notification.ts +116 -0
- package/src/commands/low-family/refine-config.ts +106 -0
- package/src/commands/low-family/session-host.ts +274 -0
- package/src/commands/low-family/spec-providerdev.ts +217 -0
- package/src/commands/low-family/status-meta.ts +112 -0
- package/src/commands/low-family/types.ts +39 -0
- package/src/commands/med-family/cli-agent.ts +238 -0
- package/src/commands/med-family/fast-forward.ts +230 -0
- package/src/commands/med-family/ide.ts +163 -0
- package/src/commands/med-family/index.ts +37 -0
- package/src/commands/med-family/mesh-crud.ts +874 -0
- package/src/commands/med-family/mesh-host-pairing.ts +234 -0
- package/src/commands/med-family/mesh-queue.ts +131 -0
- package/src/commands/med-family/mesh-restart.ts +92 -0
- package/src/commands/med-family/types.ts +120 -0
- package/src/commands/mesh-coordinator.ts +334 -124
- package/src/commands/router.ts +2516 -3221
- package/src/commands/stream-commands.ts +8 -0
- package/src/commands/upgrade-helper.ts +310 -45
- package/src/config/chat-history.ts +483 -24
- package/src/config/config.ts +12 -0
- package/src/config/mesh-config.ts +353 -22
- package/src/config/mesh-json-config.ts +617 -0
- package/src/config/recent-activity.ts +8 -2
- package/src/daemon/dev-auto-implement.ts +3 -2
- package/src/daemon/dev-cli-debug.ts +10 -1
- package/src/daemon/dev-server.ts +0 -541
- package/src/detection/cli-detector.ts +28 -9
- package/src/detection/ide-detector.ts +55 -16
- package/src/detection/win32-ide-version.ts +106 -0
- package/src/git/change-impact-config.ts +354 -0
- package/src/git/git-commands.ts +59 -15
- package/src/git/git-diff.ts +81 -11
- package/src/git/git-executor.ts +12 -0
- package/src/git/git-status.ts +767 -48
- package/src/git/git-types.ts +14 -62
- package/src/git/git-worktree.ts +261 -4
- package/src/git/index.ts +17 -0
- package/src/index.ts +171 -12
- package/src/installer.d.ts +1 -1
- package/src/installer.ts +8 -6
- package/src/ipc/local-ipc-server.ts +278 -0
- package/src/launch.d.ts +1 -1
- package/src/launch.ts +37 -28
- package/src/logging/async-batch-writer.ts +55 -0
- package/src/logging/command-log.ts +7 -5
- package/src/logging/log-redactor.ts +100 -0
- package/src/logging/log-tail-reader.ts +341 -0
- package/src/logging/logger.ts +14 -7
- package/src/mesh/contracts.ts +338 -0
- package/src/mesh/coordinator-prompt.ts +381 -33
- package/src/mesh/coordinator-registry.ts +121 -0
- package/src/mesh/mesh-active-work.ts +645 -0
- package/src/mesh/mesh-coordinator-config.ts +97 -0
- package/src/mesh/mesh-delivery-policy.ts +315 -0
- package/src/mesh/mesh-event-classify.ts +51 -0
- package/src/mesh/mesh-event-forwarding.ts +1773 -0
- package/src/mesh/mesh-event-trace.ts +67 -0
- package/src/mesh/mesh-events-coordinator.ts +31 -0
- package/src/mesh/mesh-events-pending.ts +590 -0
- package/src/mesh/mesh-events-stale.ts +389 -0
- package/src/mesh/mesh-events-utils.ts +443 -0
- package/src/mesh/mesh-events.ts +32 -1035
- package/src/mesh/mesh-fast-forward.ts +843 -0
- package/src/mesh/mesh-host-ownership.ts +73 -0
- package/src/mesh/mesh-init.ts +260 -0
- package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
- package/src/mesh/mesh-ledger.ts +596 -102
- package/src/mesh/mesh-missions.ts +322 -0
- package/src/mesh/mesh-node-identity.ts +1887 -0
- package/src/mesh/mesh-queue-assignment.ts +1738 -0
- package/src/mesh/mesh-reconcile-loop.ts +1726 -0
- package/src/mesh/mesh-refine-batch.ts +205 -0
- package/src/mesh/mesh-refine-gates.ts +1666 -0
- package/src/mesh/mesh-refine-status.ts +231 -0
- package/src/mesh/mesh-review-inbox.ts +307 -0
- package/src/mesh/mesh-routing.ts +291 -0
- package/src/mesh/mesh-runtime-store.ts +1836 -0
- package/src/mesh/mesh-scheduling-runtime.ts +198 -0
- package/src/mesh/mesh-task-stats.ts +161 -0
- package/src/mesh/mesh-unresolved-forward-outbox.ts +185 -0
- package/src/mesh/mesh-warmup-deadline.ts +152 -0
- package/src/mesh/mesh-work-queue.ts +1205 -141
- package/src/mesh/preview-freshness.ts +118 -0
- package/src/mesh/refine-config.ts +423 -0
- package/src/mesh/worktree-bootstrap-config.ts +369 -0
- package/src/providers/acp-provider-instance.ts +43 -10
- package/src/providers/approval-utils.d.ts +5 -0
- package/src/providers/approval-utils.ts +57 -5
- package/src/providers/chat-message-normalization.ts +92 -4
- package/src/providers/cli-provider-instance.ts +1865 -104
- package/src/providers/contracts.d.ts +55 -0
- package/src/providers/contracts.ts +150 -6
- package/src/providers/extension-provider-instance.ts +12 -7
- package/src/providers/external-sources.ts +218 -0
- package/src/providers/ide-provider-instance.ts +35 -12
- package/src/providers/manual-attendance.ts +85 -0
- package/src/providers/native-history/antigravity-cli-transcript.ts +643 -0
- package/src/providers/native-history/claude-cli-transcript.ts +396 -0
- package/src/providers/native-history/codex-cli-transcript.ts +479 -0
- package/src/providers/native-history/constants.ts +19 -0
- package/src/providers/native-history/dispatcher.ts +339 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +230 -0
- package/src/providers/native-history/index.ts +30 -0
- package/src/providers/provider-instance-manager.ts +30 -0
- package/src/providers/provider-instance.ts +19 -1
- package/src/providers/provider-loader.ts +668 -50
- package/src/providers/provider-schema.ts +87 -14
- package/src/providers/provider-trust.ts +114 -0
- package/src/providers/read-chat-contract.ts +76 -16
- package/src/providers/sdk/README.md +49 -0
- package/src/providers/sdk/v1/builders/acp/detect-status.ts +144 -0
- package/src/providers/sdk/v1/builders/cli/detect-status.ts +313 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval-squash.ts +158 -0
- package/src/providers/sdk/v1/builders/cli/parse-approval.ts +250 -0
- package/src/providers/sdk/v1/builders/cli/parse-session.ts +276 -0
- package/src/providers/sdk/v1/builders/cli/visible-region.ts +143 -0
- package/src/providers/sdk/v1/fixture-tooling/format.ts +130 -0
- package/src/providers/sdk/v1/fixture-tooling/index.ts +22 -0
- package/src/providers/sdk/v1/fixture-tooling/replay.ts +352 -0
- package/src/providers/sdk/v1/index.ts +152 -0
- package/src/providers/sdk/v1/sandbox/README-design.ts +195 -0
- package/src/providers/sdk/v1/sandbox/require-whitelist.ts +472 -0
- package/src/providers/sdk/v1/sandbox/script-runner.ts +150 -0
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +504 -0
- package/src/providers/sdk/v1/schemas/primitives/acp-session-protocol-v1.json +131 -0
- package/src/providers/sdk/v1/schemas/primitives/native-history-codex-rollout-v1.json +66 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-approval-squash-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-assistant-block-v1.json +91 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-cue-ordering-v1.json +47 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-dispatch-order-v1.json +32 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-footer-chrome-v1.json +42 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-index-finder-v1.json +27 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-modal-v1.json +125 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-prompt-marker-v1.json +45 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-session-id-extraction-v1.json +46 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-settled-prompt-v1.json +71 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-spinner-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-transcript-pty-v1.json +83 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-visible-region-v1.json +57 -0
- package/src/providers/sdk/v1/schemas/primitives/tui-welcome-screen-v1.json +35 -0
- package/src/providers/sdk/v1/types/cli/index.ts +365 -0
- package/src/providers/sdk/v1/types/common/index.ts +229 -0
- package/src/providers/sdk/v1/validators/index.ts +19 -0
- package/src/providers/sdk/v1/validators/manifest.ts +110 -0
- package/src/providers/sdk/v1/validators/taint.ts +309 -0
- package/src/providers/spec/adapter.ts +235 -0
- package/src/providers/spec/cli-adapter.ts +1056 -0
- package/src/providers/spec/evaluator.ts +407 -0
- package/src/providers/spec/fsm-driver.ts +1304 -0
- package/src/providers/spec/fsm-evaluator.ts +272 -0
- package/src/providers/spec/fsm-loader.ts +120 -0
- package/src/providers/spec/fsm-types.ts +273 -0
- package/src/providers/spec/native-history-executor.ts +1128 -0
- package/src/providers/spec/pre-launch-trust.ts +104 -0
- package/src/providers/spec/route.ts +51 -0
- package/src/providers/spec/types.ts +262 -0
- package/src/providers/status-monitor.d.ts +7 -7
- package/src/providers/status-monitor.ts +37 -22
- package/src/providers/transcript-v2.ts +567 -0
- package/src/providers/types/interactive-prompt.ts +536 -0
- package/src/providers/version-archive.ts +64 -24
- package/src/providers/working-dir.ts +23 -0
- package/src/repo-mesh-types.ts +629 -14
- package/src/runtime-defaults.ts +39 -0
- package/src/sessions/registry.ts +6 -0
- package/src/shared-types-extra.ts +2 -4
- package/src/shared-types.d.ts +8 -0
- package/src/shared-types.ts +64 -1
- package/src/status/builders.ts +26 -6
- package/src/status/normalize.ts +2 -0
- package/src/status/reporter.ts +19 -1
- package/src/status/snapshot.ts +95 -26
- package/src/system/hash.ts +23 -0
- package/src/system/host-memory.ts +29 -12
- package/src/system/load-better-sqlite3.ts +68 -0
- package/src/types.ts +5 -0
- package/dist/cli-adapters/terminal-backends/xterm-backend.d.ts +0 -17
- package/dist/mesh/mesh-sync.d.ts +0 -53
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +0 -16
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +0 -97
- package/src/mesh/mesh-sync.ts +0 -111
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import type { CliAdapter, CliAdapterStatus } from '../../cli-adapter-types.js';
|
|
2
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
3
|
+
import { type InteractivePromptResponse } from '../types/interactive-prompt.js';
|
|
4
|
+
export declare class SpecCliAdapter implements CliAdapter {
|
|
5
|
+
readonly cliType: string;
|
|
6
|
+
readonly cliName: string;
|
|
7
|
+
readonly workingDir: string;
|
|
8
|
+
/**
|
|
9
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
10
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
11
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
12
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
13
|
+
* every turn until the 30s safety timeout because it expects the
|
|
14
|
+
* adapter to surface the final assistant message.
|
|
15
|
+
*/
|
|
16
|
+
readonly chatMessagesOwnedExternally: true;
|
|
17
|
+
private driver;
|
|
18
|
+
/** Common spec fields the adapter reads, present in both v3 and v4. */
|
|
19
|
+
private spec;
|
|
20
|
+
private lastEvent;
|
|
21
|
+
private latestState;
|
|
22
|
+
private latestModal;
|
|
23
|
+
private statusCallback;
|
|
24
|
+
private ptyDataCallback;
|
|
25
|
+
private partialResponse;
|
|
26
|
+
private activeInteractivePrompt;
|
|
27
|
+
private interactivePromptTransport;
|
|
28
|
+
private claudeTuiPromptCaptureInFlight;
|
|
29
|
+
/**
|
|
30
|
+
* Wall clock of the first frame on which a held interactive prompt was
|
|
31
|
+
* observed to have left the screen. Mirrors the approval FSM's
|
|
32
|
+
* `modalLostAt` hysteresis (see cli-state-engine.ts): claude-cli's TUI
|
|
33
|
+
* repaints the choice picker as several PTY chunks, so a single frame
|
|
34
|
+
* with no "Enter to select" footer is not proof the prompt is gone — it
|
|
35
|
+
* may just be mid-repaint. We only clear the held prompt once it has
|
|
36
|
+
* been absent across a short grace window. Reset to null the moment the
|
|
37
|
+
* prompt footer reappears.
|
|
38
|
+
*
|
|
39
|
+
* Without this, a choice prompt resolved *directly in the terminal* (the
|
|
40
|
+
* user picked an option without going through ADHDev's
|
|
41
|
+
* setInteractivePromptResponse) was never cleared from
|
|
42
|
+
* `activeInteractivePrompt`, so getStatus() re-emitted the same prompt
|
|
43
|
+
* forever — the choice-resolve-stuck bug.
|
|
44
|
+
*/
|
|
45
|
+
private interactivePromptLostAt;
|
|
46
|
+
private jsonLineTail;
|
|
47
|
+
private exited;
|
|
48
|
+
private spawned;
|
|
49
|
+
private providerSessionId;
|
|
50
|
+
/** Wall clock at the moment spawn() ran. Used as the cutoff for
|
|
51
|
+
* native-history file selection so a prior session's transcript
|
|
52
|
+
* can't leak into this session before the agent has written its
|
|
53
|
+
* own records. */
|
|
54
|
+
private spawnedAtMs;
|
|
55
|
+
/** Env vars the daemon set on the spawned child. Mesh coordinator
|
|
56
|
+
* points hermes at a per-coordinator HERMES_HOME so the dashboard's
|
|
57
|
+
* native-history reader needs that override to find the right
|
|
58
|
+
* state.db; without it the reader sees ~/.hermes/state.db which
|
|
59
|
+
* the coordinator-launched hermes never writes to. The choice to
|
|
60
|
+
* redirect HERMES_HOME is a workaround for an unresolved hermes
|
|
61
|
+
* upstream feature gap (see hermes-agent#23130 — runtime-supplied
|
|
62
|
+
* MCP config), so this routing keeps the dashboard honest until
|
|
63
|
+
* hermes ships a runtime MCP override. */
|
|
64
|
+
private spawnedEnv;
|
|
65
|
+
constructor(specPath: string, workingDir: string, cliArgs: string[], extraEnv: Record<string, string>, transportFactory?: PtyTransportFactory);
|
|
66
|
+
spawn(): Promise<void>;
|
|
67
|
+
sendMessage(text: string): Promise<void>;
|
|
68
|
+
getStatus(): CliAdapterStatus;
|
|
69
|
+
private maybeRefreshNativeHistory;
|
|
70
|
+
getScriptParsedStatus(): unknown;
|
|
71
|
+
getPartialResponse(): string;
|
|
72
|
+
shutdown(): void;
|
|
73
|
+
cancel(): void;
|
|
74
|
+
isProcessing(): boolean;
|
|
75
|
+
isReady(): boolean;
|
|
76
|
+
setOnStatusChange(cb: () => void): void;
|
|
77
|
+
setOnPtyData(cb: (data: string) => void): void;
|
|
78
|
+
writeRaw(data: string): void;
|
|
79
|
+
resize(cols: number, rows: number): void;
|
|
80
|
+
resolveModal(buttonIndex: number): void;
|
|
81
|
+
resolveAction(data: unknown): Promise<void>;
|
|
82
|
+
setInteractivePromptResponse(response: InteractivePromptResponse): Promise<void>;
|
|
83
|
+
isApprovalRecentlyResolved(): boolean;
|
|
84
|
+
clearHistory(): void;
|
|
85
|
+
updateRuntimeSettings(): void;
|
|
86
|
+
setServerConn(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Map an invokeScript(name, args) call onto a control_bar entry.
|
|
89
|
+
*
|
|
90
|
+
* scriptName is matched against control.id. The control's action.type
|
|
91
|
+
* drives the dispatch:
|
|
92
|
+
*
|
|
93
|
+
* send_keys → click_control (e.g. stop)
|
|
94
|
+
* open_picker → two roles, driven by the screen, not a hardcoded list:
|
|
95
|
+
* - LIST (no choice arg): open the picker, wait for it
|
|
96
|
+
* to render, parse the on-screen options via
|
|
97
|
+
* `extract_choices`, and return them as
|
|
98
|
+
* `controlResult.options` (+ `currentValue`). This is
|
|
99
|
+
* how the dashboard's Model/Mode controls learn what is
|
|
100
|
+
* actually selectable in this CLI right now.
|
|
101
|
+
* - SELECT (args.choiceIndex / args.choiceLabel): drive
|
|
102
|
+
* the picker to that option using `submit_key`.
|
|
103
|
+
* attach_image → attach_image dispatch; expects args.blob (data url
|
|
104
|
+
* or base64) and args.mime
|
|
105
|
+
*
|
|
106
|
+
* Callers that pass an unknown control id get a { not_found } response.
|
|
107
|
+
* No control matched, no driver call — keeps the surface honest.
|
|
108
|
+
*/
|
|
109
|
+
invokeScript(scriptName: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
110
|
+
/**
|
|
111
|
+
* Open an `open_picker` control and return the options the CLI is showing,
|
|
112
|
+
* parsed live from the screen via `extract_choices`. Nothing is selected —
|
|
113
|
+
* the picker is left open so a follow-up SELECT invoke can commit a choice.
|
|
114
|
+
*/
|
|
115
|
+
private openPickerAndListChoices;
|
|
116
|
+
/**
|
|
117
|
+
* Drive an already-listable picker to a specific option. The option can be
|
|
118
|
+
* named (choiceLabel — matched against the parsed on-screen labels) or
|
|
119
|
+
* positional (choiceIndex — the on-screen number). The actual keystrokes
|
|
120
|
+
* come from the spec's `submit_key` with `{index}` substituted, so the spec
|
|
121
|
+
* — not this code — decides how a selection is keyed for each CLI.
|
|
122
|
+
*/
|
|
123
|
+
private selectPickerChoice;
|
|
124
|
+
/** Parse the picker choices only if the picker already appears rendered on
|
|
125
|
+
* the live screen (its `wait_for` condition currently matches and at least
|
|
126
|
+
* one choice parses). Returns the parsed choices when open, else null so
|
|
127
|
+
* the caller knows it must send the trigger to open it. Used to de-dup the
|
|
128
|
+
* picker open in {@link selectPickerChoice}. */
|
|
129
|
+
private extractPickerChoicesIfRendered;
|
|
130
|
+
/** Poll the live screen until the picker's `wait_for` condition matches,
|
|
131
|
+
* up to a short budget. Returns true if it rendered, false on timeout. */
|
|
132
|
+
private waitForPickerRendered;
|
|
133
|
+
/** Parse the picker's `extract_choices` pattern against the live screen.
|
|
134
|
+
* Each match yields { index, label, current }. `current` is true for the
|
|
135
|
+
* line the CLI marks with its cursor glyph (❯ ›). Purely screen-driven —
|
|
136
|
+
* no model/mode names are baked in. */
|
|
137
|
+
private extractPickerChoices;
|
|
138
|
+
/** Live text of a named screen section (or the whole screen when no
|
|
139
|
+
* section is named), resolved from the driver's current sections. */
|
|
140
|
+
private readScreenSectionText;
|
|
141
|
+
getDebugSnapshot(): unknown;
|
|
142
|
+
getRuntimeMetadata(): unknown;
|
|
143
|
+
updateRuntimeMeta(meta?: Record<string, unknown>): void;
|
|
144
|
+
refreshProviderDefinition(): void;
|
|
145
|
+
private handleEvent;
|
|
146
|
+
private detectInteractivePromptFromPtyChunk;
|
|
147
|
+
private readCurrentScreenSections;
|
|
148
|
+
private extractProviderSessionIdFromScreen;
|
|
149
|
+
private readClaudeScreenAssistantMessages;
|
|
150
|
+
/**
|
|
151
|
+
* Grace window a held interactive prompt must be absent from the screen
|
|
152
|
+
* before we treat it as resolved-in-terminal and clear it. claude-cli
|
|
153
|
+
* repaints the picker across multiple PTY chunks, so a single
|
|
154
|
+
* footer-less frame is not proof the prompt is gone. Sized in the same
|
|
155
|
+
* spirit as the approval FSM's `approvalCooldown` modal-lost hysteresis.
|
|
156
|
+
*/
|
|
157
|
+
private static readonly INTERACTIVE_PROMPT_LOST_GRACE_MS;
|
|
158
|
+
/**
|
|
159
|
+
* Multi-question TUI capture: after Tabbing to a page, re-snapshot at this
|
|
160
|
+
* interval until its checkbox glyph column has settled, up to the timeout.
|
|
161
|
+
* The interval matches the legacy single fixed wait (120ms); the timeout
|
|
162
|
+
* bounds total capture time so a single-select page (which never shows
|
|
163
|
+
* glyphs) doesn't stall the capture indefinitely.
|
|
164
|
+
*/
|
|
165
|
+
private static readonly CLAUDE_TUI_PAGE_POLL_INTERVAL_MS;
|
|
166
|
+
private static readonly CLAUDE_TUI_PAGE_SETTLE_TIMEOUT_MS;
|
|
167
|
+
/**
|
|
168
|
+
* Clear a held interactive prompt once the user has resolved it directly
|
|
169
|
+
* in the terminal (the choice picker leaves the screen without going
|
|
170
|
+
* through setInteractivePromptResponse). The approval path already does
|
|
171
|
+
* this via the FSM's modal-lost hysteresis; the interactive-prompt path
|
|
172
|
+
* had no equivalent, so a terminal-side answer left activeInteractivePrompt
|
|
173
|
+
* set and getStatus() re-emitted the same choice modal forever.
|
|
174
|
+
*
|
|
175
|
+
* Detection mirrors capture: the claude TUI picker is on-screen exactly
|
|
176
|
+
* while its "Enter to select" footer is rendered. When the footer is gone
|
|
177
|
+
* for INTERACTIVE_PROMPT_LOST_GRACE_MS the prompt is genuinely resolved.
|
|
178
|
+
*/
|
|
179
|
+
private maybeClearResolvedClaudeTuiPrompt;
|
|
180
|
+
private maybeCaptureClaudeTuiPrompt;
|
|
181
|
+
/**
|
|
182
|
+
* The TUI prompt is captured on the FIRST frame that renders the
|
|
183
|
+
* "Enter to select" footer. At that instant the option rows' checkbox
|
|
184
|
+
* column may not have drawn yet, so `detectClaudeTuiMultiSelect` returns
|
|
185
|
+
* false and the prompt is frozen as single-select — the dashboard then
|
|
186
|
+
* renders radio buttons even though the picker is multi-select.
|
|
187
|
+
*
|
|
188
|
+
* While the same TUI prompt is still on screen, re-check the live snapshot:
|
|
189
|
+
* if checkbox glyphs have since appeared, promote any single-select
|
|
190
|
+
* question to multi-select and re-emit status. Promotion is one-way
|
|
191
|
+
* (false→true only) — once a question is known multi-select we never demote
|
|
192
|
+
* it, since the glyph column can scroll out of view on later frames.
|
|
193
|
+
*
|
|
194
|
+
* For MULTI-question prompts the per-page Tab capture is the actual source
|
|
195
|
+
* of the bug: pages 2..N are snapshotted ~120ms after the Tab keypress,
|
|
196
|
+
* before their option-row glyph column has redrawn, so those questions
|
|
197
|
+
* freeze as single-select while page 1 (already settled) is correct. We
|
|
198
|
+
* cannot upgrade blindly — the live snapshot shows only ONE focused page —
|
|
199
|
+
* but we CAN read that page's question text/header and upgrade the matching
|
|
200
|
+
* question. As the user navigates the picker (or it settles), each page is
|
|
201
|
+
* eventually re-read and repaired.
|
|
202
|
+
*/
|
|
203
|
+
private maybeUpgradeClaudeTuiMultiSelect;
|
|
204
|
+
private readClaudeTuiHeaders;
|
|
205
|
+
/**
|
|
206
|
+
* Snapshot the currently-focused claude TUI page, polling until its
|
|
207
|
+
* option-row checkbox glyph column has settled (or a bounded timeout).
|
|
208
|
+
*
|
|
209
|
+
* Why poll: right after a Tab keypress the newly-focused page's glyph
|
|
210
|
+
* column has not redrawn yet, so an immediate snapshot shows the question +
|
|
211
|
+
* option labels but NO per-option checkbox markers — freezing that page as
|
|
212
|
+
* single-select. A fixed delay either races (too short) or is wasteful (too
|
|
213
|
+
* long). Instead we re-snapshot at a fixed interval and stop as soon as the
|
|
214
|
+
* frame shows multi-select glyphs, falling back to the last frame at the
|
|
215
|
+
* timeout. Single-select pages never show glyphs, so they always poll to the
|
|
216
|
+
* timeout — bounded small to keep capture snappy.
|
|
217
|
+
*/
|
|
218
|
+
private snapshotSettledClaudeTuiPage;
|
|
219
|
+
private captureClaudeTuiPrompt;
|
|
220
|
+
getDebugState(): Record<string, any>;
|
|
221
|
+
getTraceState(limit?: number): Record<string, any>;
|
|
222
|
+
getProviderResolutionMeta(): Record<string, any>;
|
|
223
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { SectionDef, Condition, ExtractTitle, ExtractButtons } from './types.js';
|
|
2
|
+
export interface ResolvedSection {
|
|
3
|
+
id: string;
|
|
4
|
+
fromLine: number;
|
|
5
|
+
toLine: number;
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TraceEntry {
|
|
9
|
+
kind: 'section' | 'state_match' | 'state_skip' | 'modal' | 'control' | 'notification' | 'delegate';
|
|
10
|
+
text: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveSections(sectionsObj: Record<string, SectionDef>, lines: string[]): ResolvedSection[];
|
|
13
|
+
export declare function sectionText(sections: ResolvedSection[], sectionId: string | undefined, fullScreen: string): string;
|
|
14
|
+
export declare function evaluateCondition(cond: Condition, sections: ResolvedSection[], fullScreen: string, cursor: {
|
|
15
|
+
row: number;
|
|
16
|
+
col: number;
|
|
17
|
+
} | undefined, prevLines: string[] | undefined, trace: TraceEntry[], stateId: string): boolean;
|
|
18
|
+
export declare function extractTitle(rule: ExtractTitle, sections: ResolvedSection[], fullScreen: string): string | null;
|
|
19
|
+
export declare function extractButtonsFromRule(rule: ExtractButtons, hay: string): {
|
|
20
|
+
index: number;
|
|
21
|
+
label: string;
|
|
22
|
+
key: string;
|
|
23
|
+
current: boolean;
|
|
24
|
+
}[];
|
|
25
|
+
/**
|
|
26
|
+
* Reduce a top→bottom-ordered list of parsed numbered entries to only the
|
|
27
|
+
* bottom-most contiguous block — the run whose indices descend by exactly 1
|
|
28
|
+
* scanning upward from the last entry.
|
|
29
|
+
*
|
|
30
|
+
* Picker and approval choices always render as the LAST contiguous numbered
|
|
31
|
+
* block at the bottom of the modal section. The conversation history above can
|
|
32
|
+
* carry its own stray "1./2./3." numbered lists (and blockquote `>` lines), and
|
|
33
|
+
* because section anchoring can pull body lines into the modal section, a naive
|
|
34
|
+
* top-down scan would bind the low option indices to those body lines and drop
|
|
35
|
+
* the real choices (the dashboard would show, and an arrow-key picker would
|
|
36
|
+
* commit, the wrong row). Selecting the bottom block makes the on-screen picker
|
|
37
|
+
* win regardless of body content. Since pickers number their options 1..N
|
|
38
|
+
* contiguously and bodies use indices ≥ 1, the upward chain always breaks the
|
|
39
|
+
* moment it would need a "0." above the picker's "1." — so the picker block is
|
|
40
|
+
* isolated cleanly. Entries are assumed already in screen order; the returned
|
|
41
|
+
* slice keeps that order.
|
|
42
|
+
*/
|
|
43
|
+
export declare function lastContiguousNumberedBlock<T extends {
|
|
44
|
+
index: number;
|
|
45
|
+
}>(entries: T[]): T[];
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { type SpecPtyEvent } from './adapter.js';
|
|
2
|
+
import type { PtyTransportFactory } from '../../cli-adapters/pty-transport.js';
|
|
3
|
+
import { type TraceEntry } from './evaluator.js';
|
|
4
|
+
import { type TransitionEval } from './fsm-evaluator.js';
|
|
5
|
+
import { chunkPreservingSurrogates as chunkPreservingSurrogatesShared } from '../../cli-adapters/pty-write-chunking.js';
|
|
6
|
+
export type DashboardEvent = {
|
|
7
|
+
kind: 'pty_data';
|
|
8
|
+
chunk: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'state_changed';
|
|
11
|
+
state: {
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
title: string | null;
|
|
15
|
+
status: 'idle' | 'generating' | 'approval';
|
|
16
|
+
};
|
|
17
|
+
modal: {
|
|
18
|
+
title: string | null;
|
|
19
|
+
buttons: {
|
|
20
|
+
index: number;
|
|
21
|
+
label: string;
|
|
22
|
+
}[];
|
|
23
|
+
kind: 'approval' | 'picker' | 'confirm' | null;
|
|
24
|
+
} | null;
|
|
25
|
+
controls: {
|
|
26
|
+
id: string;
|
|
27
|
+
label: string;
|
|
28
|
+
action_type: string;
|
|
29
|
+
}[];
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'notification';
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
body: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'delegate';
|
|
37
|
+
id: string;
|
|
38
|
+
task: string;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'spec_trace';
|
|
41
|
+
entries: TraceEntry[];
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'exit';
|
|
44
|
+
exit_code: number;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'spec_error';
|
|
47
|
+
errors: string[];
|
|
48
|
+
};
|
|
49
|
+
export type DashboardCommand = {
|
|
50
|
+
kind: 'send_message';
|
|
51
|
+
text: string;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'pty_write';
|
|
54
|
+
data: string;
|
|
55
|
+
} | {
|
|
56
|
+
kind: 'click_control';
|
|
57
|
+
control_id: string;
|
|
58
|
+
payload?: unknown;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'click_modal_button';
|
|
61
|
+
index: number;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'attach_image';
|
|
64
|
+
blob: string;
|
|
65
|
+
mime: string;
|
|
66
|
+
} | {
|
|
67
|
+
kind: 'resize';
|
|
68
|
+
cols: number;
|
|
69
|
+
rows: number;
|
|
70
|
+
} | {
|
|
71
|
+
kind: 'cancel';
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'shutdown';
|
|
74
|
+
};
|
|
75
|
+
export interface DriverHistoryEntry {
|
|
76
|
+
stateId: string;
|
|
77
|
+
label: string;
|
|
78
|
+
at: number;
|
|
79
|
+
durationMs: number;
|
|
80
|
+
reason: string;
|
|
81
|
+
matchedStateId?: string;
|
|
82
|
+
matchedRules?: string[];
|
|
83
|
+
debounceKind?: string;
|
|
84
|
+
idleHoldMs?: number;
|
|
85
|
+
busyHoldMs?: number;
|
|
86
|
+
via?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A frozen snapshot of the FULL FSM evaluation captured at the instant a
|
|
90
|
+
* transition fired — the rich `transitions[]` table (per-transition eligible /
|
|
91
|
+
* hold countdown / per-condition CondResult + remainingMs) that `getFsmDebug()`
|
|
92
|
+
* otherwise only computes live for the current instant. Kept in a separate ring
|
|
93
|
+
* buffer from `stateHistory` (which stays intentionally lightweight) so the
|
|
94
|
+
* "why did this rule fire just before the transition" question is answerable
|
|
95
|
+
* after the fact. before-only: this is the evaluation that PRODUCED the
|
|
96
|
+
* transition, not the post-transition state.
|
|
97
|
+
*/
|
|
98
|
+
export interface FsmSnapshotEntry {
|
|
99
|
+
/** State we transitioned out of. */
|
|
100
|
+
stateFrom: string;
|
|
101
|
+
/** State we transitioned into (the fired transition's destination). */
|
|
102
|
+
stateTo: string;
|
|
103
|
+
/** Wall-clock time the transition committed (ms). */
|
|
104
|
+
at: number;
|
|
105
|
+
/** The fired transition's destination state id (== stateTo; kept explicit
|
|
106
|
+
* to mirror the rule that fired). */
|
|
107
|
+
firedTo: string;
|
|
108
|
+
/** Human label of the fired transition (e.g. "approval→busy"). */
|
|
109
|
+
firedLabel: string;
|
|
110
|
+
/** Why-it-fired summary, same shape produced for stateHistory.matchedRules. */
|
|
111
|
+
reason: string[];
|
|
112
|
+
/** Every outgoing transition from `stateFrom` as evaluated at `at`, each
|
|
113
|
+
* with its eligible / hold / per-condition CondResult + remainingMs. This
|
|
114
|
+
* is the full pre-transition evaluation table — the whole point of the
|
|
115
|
+
* snapshot. */
|
|
116
|
+
transitions: TransitionEval[];
|
|
117
|
+
}
|
|
118
|
+
export interface ISpecDriver {
|
|
119
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
120
|
+
start(): void;
|
|
121
|
+
dispatch(cmd: DashboardCommand): void;
|
|
122
|
+
snapshot(): string;
|
|
123
|
+
getCursorPosition(): {
|
|
124
|
+
row: number;
|
|
125
|
+
col: number;
|
|
126
|
+
};
|
|
127
|
+
getScreen(): string;
|
|
128
|
+
getSpecPath(): string;
|
|
129
|
+
shutdown(): void;
|
|
130
|
+
getStateHistory(): ReadonlyArray<DriverHistoryEntry>;
|
|
131
|
+
getSections(): Array<{
|
|
132
|
+
id: string;
|
|
133
|
+
text: string;
|
|
134
|
+
}> | null;
|
|
135
|
+
getLastBusyAt(): number;
|
|
136
|
+
hasIdleHoldPending(): boolean;
|
|
137
|
+
hasSeenReady(): boolean;
|
|
138
|
+
getCompletionIdleDebounceState(): {
|
|
139
|
+
active: boolean;
|
|
140
|
+
ageMs: number;
|
|
141
|
+
holdMs: number;
|
|
142
|
+
forceAfterMs: number;
|
|
143
|
+
} | null;
|
|
144
|
+
getFsmDebug?(): unknown;
|
|
145
|
+
getFsmSnapshotHistory?(): ReadonlyArray<FsmSnapshotEntry>;
|
|
146
|
+
getEventTimeline?(limit?: number): ReadonlyArray<SpecPtyEvent>;
|
|
147
|
+
}
|
|
148
|
+
export interface SpecDriverOpts {
|
|
149
|
+
specPath: string;
|
|
150
|
+
workingDir: string;
|
|
151
|
+
extraEnv?: Record<string, string>;
|
|
152
|
+
cols?: number;
|
|
153
|
+
rows?: number;
|
|
154
|
+
hotReload?: boolean;
|
|
155
|
+
emitTrace?: boolean;
|
|
156
|
+
transportFactory?: PtyTransportFactory;
|
|
157
|
+
extraCliArgs?: string[];
|
|
158
|
+
}
|
|
159
|
+
export declare function resolveSubmitDelayMs(specBeforeSubmit: number | undefined, text: string): number;
|
|
160
|
+
/** Re-export of the shared surrogate-safe splitter so existing imports of
|
|
161
|
+
* `chunkPreservingSurrogates` from this module keep working. The implementation
|
|
162
|
+
* lives in ../../cli-adapters/pty-write-chunking so the spec driver and the
|
|
163
|
+
* legacy adapter share one definition. */
|
|
164
|
+
export declare const chunkPreservingSurrogates: typeof chunkPreservingSurrogatesShared;
|
|
165
|
+
export declare function guessExt(mime: string): string;
|
|
166
|
+
type HistoryEntry = DriverHistoryEntry;
|
|
167
|
+
export declare class FsmDriver implements ISpecDriver {
|
|
168
|
+
private readonly opts;
|
|
169
|
+
private spec;
|
|
170
|
+
private adapter;
|
|
171
|
+
private listeners;
|
|
172
|
+
private currentStateId;
|
|
173
|
+
private stateEnteredAt;
|
|
174
|
+
private startedAtMs;
|
|
175
|
+
private prevScreenLines;
|
|
176
|
+
/** Per cursor_above region (key: cursor_above, -1 = whole screen) → last
|
|
177
|
+
* time that region's content changed. Drives stable_ms conditions. */
|
|
178
|
+
private regionLastChangedAt;
|
|
179
|
+
/** Timer that re-runs evaluate() when a time-condition would flip true
|
|
180
|
+
* with no PTY frame to trigger it. */
|
|
181
|
+
private wakeTimer;
|
|
182
|
+
/** Timer driving the focus-gated stall watchdog (refocus_when_stalled_ms).
|
|
183
|
+
* Re-arms itself while the machine is generating so a re-prime can fire
|
|
184
|
+
* even when the PTY has gone completely quiet. */
|
|
185
|
+
private stallTimer;
|
|
186
|
+
/** Wall-clock time the last stall re-prime was injected. The cooldown gate:
|
|
187
|
+
* after a re-prime we don't re-inject until the screen changes (which
|
|
188
|
+
* resets the stall reference) or another full stall window lapses. */
|
|
189
|
+
private lastRefocusAt;
|
|
190
|
+
/** Timer driving the win32 verification-based submit resend loop (see
|
|
191
|
+
* WIN32_SUBMIT_* and scheduleWin32Submit). Re-arms itself until the FSM
|
|
192
|
+
* leaves idle (submitted) or the resend budget is spent. */
|
|
193
|
+
private win32SubmitTimer;
|
|
194
|
+
/** Wall-clock (ms) of the most recent raw PTY output chunk. Advances on every
|
|
195
|
+
* on_pty_data — including the echo of text written into the composer — so the
|
|
196
|
+
* win32 submit settle-gate can tell when input has finished landing. */
|
|
197
|
+
private lastPtyDataAt;
|
|
198
|
+
/** Wall-clock (ms) of the most recent win32 message-body input write. Bridges
|
|
199
|
+
* the gap between writing a chunk and its echo so the settle-gate does not
|
|
200
|
+
* declare "quiet" mid-write. */
|
|
201
|
+
private lastWin32WriteAt;
|
|
202
|
+
/** Pending paced chunk-write timer for a large win32 body (see writeWin32Body). */
|
|
203
|
+
private win32WriteTimer;
|
|
204
|
+
/** Timer driving the win32 verification-based modal-confirm CR resend loop (see
|
|
205
|
+
* scheduleWin32ModalConfirm). A lone CR that confirms an approval/picker choice
|
|
206
|
+
* is absorbed by ConPTY the same way a send_message submit CR is, so the confirm
|
|
207
|
+
* must be resent until the modal actually resolves (status leaves 'approval'). */
|
|
208
|
+
private win32ModalConfirmTimer;
|
|
209
|
+
private currentEval;
|
|
210
|
+
private stateHistory;
|
|
211
|
+
private prevStateAt;
|
|
212
|
+
private readySeenOnce;
|
|
213
|
+
private pendingSends;
|
|
214
|
+
private pickerInProgress;
|
|
215
|
+
private delegateTimers;
|
|
216
|
+
private specWatcher;
|
|
217
|
+
/** Last full FSM evaluation, kept for the debugger. */
|
|
218
|
+
private lastFsmEval;
|
|
219
|
+
/** Ring buffer (max 20) of the full FSM evaluation captured at each
|
|
220
|
+
* transition — the rich pre-transition table that lastFsmEval only keeps
|
|
221
|
+
* for the single most recent evaluation. Separate from stateHistory. */
|
|
222
|
+
private fsmSnapshotHistory;
|
|
223
|
+
constructor(opts: SpecDriverOpts);
|
|
224
|
+
subscribe(listener: (ev: DashboardEvent) => void): () => void;
|
|
225
|
+
start(): void;
|
|
226
|
+
private scheduleSpawnPrime;
|
|
227
|
+
/** Write the declared `send_on_spawn` sequences to the PTY once. Used both
|
|
228
|
+
* at spawn (scheduleSpawnPrime) and, for focus-gated TUIs, by the stall
|
|
229
|
+
* watchdog to re-inject the focus-in wake mid-turn. No-op when the spec
|
|
230
|
+
* declares no prime, so non-focus-gated CLIs are never poked. */
|
|
231
|
+
private sendSpawnPrime;
|
|
232
|
+
dispatch(cmd: DashboardCommand): void;
|
|
233
|
+
snapshot(): string;
|
|
234
|
+
getCursorPosition(): {
|
|
235
|
+
row: number;
|
|
236
|
+
col: number;
|
|
237
|
+
};
|
|
238
|
+
getScreen(): string;
|
|
239
|
+
/** Scrollback-inclusive screen as line array — used only for modal/button
|
|
240
|
+
* content extraction so a tall prompt's off-screen anchors stay matchable.
|
|
241
|
+
* Falls back to the viewport snapshot if scrollback read is unavailable. */
|
|
242
|
+
private scrollbackLines;
|
|
243
|
+
getSpecPath(): string;
|
|
244
|
+
shutdown(): void;
|
|
245
|
+
getFsmDebug(): {
|
|
246
|
+
currentState: string;
|
|
247
|
+
label: string;
|
|
248
|
+
stateAgeMs: number;
|
|
249
|
+
status: string;
|
|
250
|
+
cursor: {
|
|
251
|
+
row: number;
|
|
252
|
+
col: number;
|
|
253
|
+
};
|
|
254
|
+
transitions: TransitionEval[];
|
|
255
|
+
};
|
|
256
|
+
getStateHistory(): ReadonlyArray<HistoryEntry>;
|
|
257
|
+
getFsmSnapshotHistory(): ReadonlyArray<FsmSnapshotEntry>;
|
|
258
|
+
/** Debug-only PTY input/output/resize/cursor timeline from the adapter. */
|
|
259
|
+
getEventTimeline(limit?: number): ReadonlyArray<SpecPtyEvent>;
|
|
260
|
+
getSections(): Array<{
|
|
261
|
+
id: string;
|
|
262
|
+
text: string;
|
|
263
|
+
}> | null;
|
|
264
|
+
/** v3-compat shims so the cli-adapter's existing debug snapshot keeps
|
|
265
|
+
* working without branching on driver type. */
|
|
266
|
+
getLastBusyAt(): number;
|
|
267
|
+
hasIdleHoldPending(): boolean;
|
|
268
|
+
/**
|
|
269
|
+
* True once the machine has reached its first non-initial idle state (the
|
|
270
|
+
* prompt is genuinely drawn — see maybeMarkReady). The cli-adapter surfaces
|
|
271
|
+
* this on its idle status so CliProviderInstance can re-arm the queue-claim
|
|
272
|
+
* agent:ready on the first genuine ready, independent of the boot-time
|
|
273
|
+
* starting→idle one-shot (which is consumed too early for specs whose
|
|
274
|
+
* initial state already reports idle).
|
|
275
|
+
*/
|
|
276
|
+
hasSeenReady(): boolean;
|
|
277
|
+
getCompletionIdleDebounceState(): {
|
|
278
|
+
active: boolean;
|
|
279
|
+
ageMs: number;
|
|
280
|
+
holdMs: number;
|
|
281
|
+
forceAfterMs: number;
|
|
282
|
+
} | null;
|
|
283
|
+
private loadSpecOrThrow;
|
|
284
|
+
private buildAdapterOpts;
|
|
285
|
+
private armSpecWatcher;
|
|
286
|
+
private emitInitialState;
|
|
287
|
+
private buildClock;
|
|
288
|
+
private evalFsmNow;
|
|
289
|
+
private reevaluate;
|
|
290
|
+
private commitTransition;
|
|
291
|
+
/** Snapshot the full FSM evaluation that produced a transition into the
|
|
292
|
+
* separate fsmSnapshotHistory ring buffer (max 20). The transitions[]
|
|
293
|
+
* table is captured by reference — it is freshly built per evaluation in
|
|
294
|
+
* evaluateFsm and never mutated after, so no clone is needed. */
|
|
295
|
+
private pushFsmSnapshot;
|
|
296
|
+
/** Re-derive the visible modal + controls for the current state and emit a
|
|
297
|
+
* state_changed if anything differs from the last emit. */
|
|
298
|
+
private emitStateChanged;
|
|
299
|
+
private deriveModal;
|
|
300
|
+
private deriveTitle;
|
|
301
|
+
private deriveControls;
|
|
302
|
+
/** Track which cursor_above regions changed since the previous frame so
|
|
303
|
+
* stable_ms conditions can measure quiet time. We record every region
|
|
304
|
+
* size referenced by a stable_ms condition in the spec, plus the whole
|
|
305
|
+
* screen (-1). */
|
|
306
|
+
private trackRegionChanges;
|
|
307
|
+
/** All cursor_above region sizes referenced by stable_ms conditions in the
|
|
308
|
+
* current state's outgoing transitions, plus whole-screen. Cached lazily
|
|
309
|
+
* per spec load would be nicer but the set is tiny. */
|
|
310
|
+
private stableRegionSizes;
|
|
311
|
+
/** Schedule a re-evaluation for the soonest pending time-condition on any
|
|
312
|
+
* outgoing transition (elapsed_ms / stable_ms / min_hold_ms). Without
|
|
313
|
+
* this, a state whose only exit is time-based would never leave once the
|
|
314
|
+
* PTY goes quiet. */
|
|
315
|
+
private scheduleWakeForState;
|
|
316
|
+
/** True when this spec opts into stall recovery (declares a positive
|
|
317
|
+
* refocus window AND a wake sequence to re-inject). */
|
|
318
|
+
private stallRecoveryEnabled;
|
|
319
|
+
/** Wall-clock time the screen last changed in the current state, falling
|
|
320
|
+
* back to state entry when it has not changed since (i.e. fully stalled
|
|
321
|
+
* from the start of the state). */
|
|
322
|
+
private lastScreenChangeAt;
|
|
323
|
+
/** Arm a timer to re-inject the focus-in prime if the screen stays frozen
|
|
324
|
+
* through a `generating` state. Only active for opted-in focus-gated specs;
|
|
325
|
+
* a no-op (and cleared) for every other CLI and every non-generating state.
|
|
326
|
+
* Re-arms itself so it keeps watching while the PTY is quiet. */
|
|
327
|
+
private scheduleStallWatchdog;
|
|
328
|
+
/** Fire when the stall window elapses: if the screen is still frozen and we
|
|
329
|
+
* are still generating, re-inject the focus-in wake once, then re-arm. */
|
|
330
|
+
private onStallTick;
|
|
331
|
+
private maybeMarkReady;
|
|
332
|
+
private fireNotifications;
|
|
333
|
+
private armOrCancelDelegateTimers;
|
|
334
|
+
private fireDelegate;
|
|
335
|
+
private handleSendMessage;
|
|
336
|
+
private actuallySendMessage;
|
|
337
|
+
/** The agent's current coarse status, derived from the FSM node we're in. */
|
|
338
|
+
private currentStatus;
|
|
339
|
+
/** Record a win32 body write so the settle-gate counts it as input activity
|
|
340
|
+
* even before the echo arrives. */
|
|
341
|
+
private markWin32Write;
|
|
342
|
+
/** Most recent win32 input activity — a write we issued OR a PTY output chunk
|
|
343
|
+
* (echo). The submit settle-gate waits for this to go quiet. */
|
|
344
|
+
private lastWin32InputActivityAt;
|
|
345
|
+
/**
|
|
346
|
+
* Write the message body to the PTY for win32, paced into bounded chunks. A
|
|
347
|
+
* single unbounded ConPTY write can overflow the input pipe and drop leading
|
|
348
|
+
* bytes; splitting it with a short inter-chunk gap keeps the console input
|
|
349
|
+
* buffer from overflowing. Small bodies still go out in a single write. Each
|
|
350
|
+
* chunk advances lastWin32WriteAt so the submit settle-gate keeps waiting until
|
|
351
|
+
* the final chunk is out and echoed.
|
|
352
|
+
*/
|
|
353
|
+
private writeWin32Body;
|
|
354
|
+
/**
|
|
355
|
+
* win32 submit. Two phases:
|
|
356
|
+
*
|
|
357
|
+
* Phase 1 (echo-gate): hold the first CR until the body text is CONFIRMED in the
|
|
358
|
+
* composer (its whitespace-collapsed tail appears in the rendered screen) AND the
|
|
359
|
+
* PTY output is then quiet for WIN32_SUBMIT_SETTLE_MS (the full, possibly multi-KB
|
|
360
|
+
* / multiline body has finished arriving). This replaces a bare output-quiet
|
|
361
|
+
* settle: an early write that races claude's boot is buffered, not dropped, so the
|
|
362
|
+
* screen can go quiet with the body NOT YET in the composer — a quiet-only gate
|
|
363
|
+
* would then fire a CR into an empty composer (no submit). Waiting on the echo
|
|
364
|
+
* closes that. Honors an initial minimum delay and a generous WIN32_ECHO_MAX_WAIT_MS
|
|
365
|
+
* last-resort blind fire so a body that truly never confirms still submits (carried
|
|
366
|
+
* by phase 2) rather than hanging. A settled session echoes immediately → no delay.
|
|
367
|
+
*
|
|
368
|
+
* Phase 2 (verified resend — unchanged): send the submit key, wait a gap, and
|
|
369
|
+
* if the FSM is still 'idle' (the CR was absorbed as a multiline-paste
|
|
370
|
+
* newline) resend, up to WIN32_SUBMIT_MAX_RESENDS. The first CR always fires
|
|
371
|
+
* (a stale/edge status never suppresses it); resends are gated on still being
|
|
372
|
+
* idle and stop the instant the agent leaves idle (submitted → generating /
|
|
373
|
+
* approval). This preserves the win32 lone-CR-swallow handling.
|
|
374
|
+
*/
|
|
375
|
+
private scheduleWin32Submit;
|
|
376
|
+
private handleClickControl;
|
|
377
|
+
private handleClickModalButton;
|
|
378
|
+
/**
|
|
379
|
+
* Submit a modal-confirm key sequence (the choice key + its trailing CR).
|
|
380
|
+
*
|
|
381
|
+
* On win32 the trailing CR is the SAME lone-CR-swallow case as a send_message
|
|
382
|
+
* submit: ConPTY can absorb a single CR as a literal newline instead of a
|
|
383
|
+
* confirm, so the approval/picker modal never resolves and the FSM flaps
|
|
384
|
+
* approval↔busy while auto-approve keeps firing into the void (APPROVESTUCK).
|
|
385
|
+
* So we split any non-CR prefix (e.g. the "1" of "1\r") off, write it once, and
|
|
386
|
+
* resend the CR on a fixed cadence until the modal actually resolves (status
|
|
387
|
+
* leaves 'approval'). Non-win32 keeps the single direct write — its CR submits
|
|
388
|
+
* on the first try.
|
|
389
|
+
*/
|
|
390
|
+
private submitModalConfirm;
|
|
391
|
+
/**
|
|
392
|
+
* win32 modal-confirm CR resend loop. Mirrors scheduleWin32Submit's phase-2
|
|
393
|
+
* verified resend, but gated on still being IN a modal (status 'approval')
|
|
394
|
+
* rather than still idle: the first CR fires immediately, then resends every
|
|
395
|
+
* WIN32_SUBMIT_RESEND_GAP_MS while the FSM is still showing the modal, up to
|
|
396
|
+
* WIN32_SUBMIT_MAX_RESENDS. The instant the modal resolves (status flips to
|
|
397
|
+
* generating/idle) we stop, so no stray CR leaks into the next turn's composer.
|
|
398
|
+
*/
|
|
399
|
+
private scheduleWin32ModalConfirm;
|
|
400
|
+
private handleAttachImage;
|
|
401
|
+
private tryAdvancePicker;
|
|
402
|
+
private handleExit;
|
|
403
|
+
private pushHistory;
|
|
404
|
+
private specTag;
|
|
405
|
+
private emit;
|
|
406
|
+
}
|
|
407
|
+
export {};
|