@adhdev/daemon-core 0.9.82-rc.48 → 0.9.82-rc.480
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 +220 -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 +69 -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 +23 -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 +51 -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 +64 -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 +48 -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 +152 -0
- package/dist/commands/mesh-coordinator.d.ts +85 -1
- package/dist/commands/router-aggregate-status.d.ts +24 -0
- package/dist/commands/router-mesh-session-owner.d.ts +59 -0
- package/dist/commands/router-refine.d.ts +137 -0
- package/dist/commands/router-worktree-cleanup.d.ts +133 -0
- package/dist/commands/router.d.ts +204 -15
- package/dist/commands/upgrade-helper.d.ts +41 -1
- package/dist/config/chat-history.d.ts +11 -0
- package/dist/config/config.d.ts +19 -0
- package/dist/config/mesh-config.d.ts +136 -1
- package/dist/config/mesh-json-config.d.ts +199 -0
- package/dist/config/registry-resolver.d.ts +54 -0
- package/dist/config/repo-settings.d.ts +77 -0
- package/dist/config/state-store.d.ts +30 -0
- package/dist/daemon/dev-server.d.ts +0 -2
- package/dist/detection/cli-detector.d.ts +17 -0
- 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 +26 -2
- 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 +73 -17
- package/dist/index.js +52979 -18657
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59496 -25355
- 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/debug-config.d.ts +16 -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 +230 -0
- package/dist/mesh/coordinator-prompt.d.ts +76 -0
- package/dist/mesh/coordinator-registry.d.ts +59 -0
- package/dist/mesh/mesh-active-work.d.ts +203 -0
- package/dist/mesh/mesh-clone-grace.d.ts +8 -0
- package/dist/mesh/mesh-completion-synthesis.d.ts +4 -0
- package/dist/mesh/mesh-coordinator-config.d.ts +21 -0
- package/dist/mesh/mesh-delivery-policy.d.ts +104 -0
- package/dist/mesh/mesh-event-classify.d.ts +7 -0
- package/dist/mesh/mesh-event-forwarding.d.ts +49 -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 +246 -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 +29 -0
- package/dist/mesh/mesh-init.d.ts +128 -0
- package/dist/mesh/mesh-ledger-reconciliation.d.ts +23 -4
- package/dist/mesh/mesh-ledger.d.ts +139 -1
- package/dist/mesh/mesh-magi-status.d.ts +63 -0
- package/dist/mesh/mesh-missions.d.ts +281 -0
- package/dist/mesh/mesh-node-identity.d.ts +310 -0
- package/dist/mesh/mesh-queue-assignment.d.ts +158 -0
- package/dist/mesh/mesh-reconcile-acked-hold.d.ts +17 -0
- package/dist/mesh/mesh-reconcile-config.d.ts +6 -0
- package/dist/mesh/mesh-reconcile-identity.d.ts +6 -0
- package/dist/mesh/mesh-reconcile-loop.d.ts +80 -0
- package/dist/mesh/mesh-reconcile-v2-backstop.d.ts +16 -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-remote-event-pull.d.ts +15 -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 +508 -0
- package/dist/mesh/mesh-scheduling-runtime.d.ts +78 -0
- package/dist/mesh/mesh-task-inflight.d.ts +46 -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 +363 -5
- package/dist/mesh/preview-freshness.d.ts +28 -0
- package/dist/mesh/refine-config.d.ts +216 -0
- package/dist/mesh/worktree-bootstrap-config.d.ts +219 -0
- package/dist/providers/acp-provider-instance.d.ts +5 -0
- package/dist/providers/approval-utils.d.ts +46 -0
- package/dist/providers/chat-message-normalization.d.ts +58 -1
- package/dist/providers/cli-provider-effect-format.d.ts +30 -0
- package/dist/providers/cli-provider-history-dedup.d.ts +17 -0
- package/dist/providers/cli-provider-input-prompt.d.ts +12 -0
- package/dist/providers/cli-provider-instance-types.d.ts +45 -0
- package/dist/providers/cli-provider-instance.d.ts +406 -30
- package/dist/providers/cli-provider-status-helpers.d.ts +46 -0
- package/dist/providers/cli-provider-transcript-merge.d.ts +7 -0
- package/dist/providers/contracts.d.ts +149 -6
- package/dist/providers/external-sources.d.ts +71 -0
- package/dist/providers/manual-attendance.d.ts +79 -0
- package/dist/providers/native-history/antigravity-claim-registry.d.ts +39 -0
- package/dist/providers/native-history/antigravity-cli-transcript.d.ts +137 -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 +44 -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 +29 -0
- package/dist/providers/provider-instance.d.ts +30 -1
- package/dist/providers/provider-loader.d.ts +42 -5
- 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 +98 -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 +449 -0
- package/dist/providers/spec/fsm-evaluator.d.ts +93 -0
- package/dist/providers/spec/fsm-loader.d.ts +14 -0
- package/dist/providers/spec/fsm-types.d.ts +202 -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 +244 -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 +629 -12
- package/dist/runtime-defaults.d.ts +2 -0
- package/dist/session-host/managed-host.d.ts +64 -0
- package/dist/session-host/runtime-surface.d.ts +10 -16
- package/dist/sessions/registry.d.ts +26 -0
- package/dist/shared-types-extra.d.ts +2 -4
- package/dist/shared-types.d.ts +98 -55
- package/dist/status/chat-tail-hot-sessions.d.ts +40 -0
- 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 +11 -4
- package/src/agent-stream/poller.ts +2 -3
- package/src/agent-stream/provider-adapter.ts +1 -1
- package/src/boot/daemon-lifecycle.ts +80 -14
- 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 +1282 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +954 -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 +204 -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/chat-commands-debug-bundle.ts +398 -0
- package/src/commands/chat-commands-read.ts +2767 -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.d.ts +2 -0
- package/src/commands/cli-manager.ts +659 -27
- package/src/commands/handler.ts +845 -2
- package/src/commands/high-family/index.ts +28 -0
- package/src/commands/high-family/mesh-coordinator-launch.ts +680 -0
- package/src/commands/high-family/mesh-events.ts +102 -0
- package/src/commands/high-family/mesh-status.ts +849 -0
- package/src/commands/high-family/types.ts +80 -0
- package/src/commands/low-family/coordinator-prompt.ts +72 -0
- package/src/commands/low-family/daemon-lifecycle.ts +120 -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 +282 -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 +241 -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 +1287 -0
- package/src/commands/med-family/mesh-host-pairing.ts +234 -0
- package/src/commands/med-family/mesh-queue.ts +167 -0
- package/src/commands/med-family/mesh-restart.ts +92 -0
- package/src/commands/med-family/types.ts +153 -0
- package/src/commands/mesh-coordinator.ts +334 -124
- package/src/commands/router-aggregate-status.ts +209 -0
- package/src/commands/router-mesh-session-owner.ts +114 -0
- package/src/commands/router-refine.ts +1711 -0
- package/src/commands/router-worktree-cleanup.ts +870 -0
- package/src/commands/router.ts +795 -4143
- package/src/commands/stream-commands.ts +8 -0
- package/src/commands/upgrade-helper.ts +310 -45
- package/src/config/chat-history.ts +517 -24
- package/src/config/config.ts +30 -0
- package/src/config/mesh-config.ts +632 -23
- package/src/config/mesh-json-config.ts +376 -0
- package/src/config/recent-activity.ts +8 -2
- package/src/config/registry-resolver.ts +100 -0
- package/src/config/repo-settings.ts +111 -0
- package/src/config/state-store.ts +55 -0
- 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 +94 -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 +112 -16
- 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 +213 -13
- 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/debug-config.ts +25 -0
- package/src/logging/debug-trace.ts +7 -2
- 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 +469 -0
- package/src/mesh/coordinator-prompt.ts +572 -34
- package/src/mesh/coordinator-registry.ts +121 -0
- package/src/mesh/mesh-active-work.ts +706 -0
- package/src/mesh/mesh-clone-grace.ts +68 -0
- package/src/mesh/mesh-completion-synthesis.ts +416 -0
- package/src/mesh/mesh-coordinator-config.ts +97 -0
- package/src/mesh/mesh-delivery-policy.ts +284 -0
- package/src/mesh/mesh-event-classify.ts +78 -0
- package/src/mesh/mesh-event-forwarding.ts +2002 -0
- package/src/mesh/mesh-event-trace.ts +67 -0
- package/src/mesh/mesh-events-coordinator.ts +32 -0
- package/src/mesh/mesh-events-pending.ts +1494 -0
- package/src/mesh/mesh-events-stale.ts +452 -0
- package/src/mesh/mesh-events-utils.ts +443 -0
- package/src/mesh/mesh-events.ts +43 -1035
- package/src/mesh/mesh-fast-forward.ts +856 -0
- package/src/mesh/mesh-host-ownership.ts +111 -0
- package/src/mesh/mesh-init.ts +350 -0
- package/src/mesh/mesh-ledger-reconciliation.ts +12 -7
- package/src/mesh/mesh-ledger.ts +898 -102
- package/src/mesh/mesh-magi-status.ts +223 -0
- package/src/mesh/mesh-missions.ts +695 -0
- package/src/mesh/mesh-node-identity.ts +2065 -0
- package/src/mesh/mesh-queue-assignment.ts +2263 -0
- package/src/mesh/mesh-reconcile-acked-hold.ts +230 -0
- package/src/mesh/mesh-reconcile-config.ts +66 -0
- package/src/mesh/mesh-reconcile-identity.ts +103 -0
- package/src/mesh/mesh-reconcile-loop.ts +1473 -0
- package/src/mesh/mesh-reconcile-v2-backstop.ts +62 -0
- package/src/mesh/mesh-refine-batch.ts +205 -0
- package/src/mesh/mesh-refine-gates.ts +1686 -0
- package/src/mesh/mesh-refine-status.ts +231 -0
- package/src/mesh/mesh-remote-event-pull.ts +279 -0
- package/src/mesh/mesh-review-inbox.ts +308 -0
- package/src/mesh/mesh-routing.ts +291 -0
- package/src/mesh/mesh-runtime-store.ts +2150 -0
- package/src/mesh/mesh-scheduling-runtime.ts +198 -0
- package/src/mesh/mesh-task-inflight.ts +70 -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 +1437 -147
- package/src/mesh/preview-freshness.ts +163 -0
- package/src/mesh/refine-config.ts +423 -0
- package/src/mesh/worktree-bootstrap-config.ts +599 -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 +100 -6
- package/src/providers/chat-message-normalization.ts +126 -4
- package/src/providers/cli-provider-effect-format.ts +53 -0
- package/src/providers/cli-provider-history-dedup.ts +75 -0
- package/src/providers/cli-provider-input-prompt.ts +133 -0
- package/src/providers/cli-provider-instance-types.ts +131 -0
- package/src/providers/cli-provider-instance.ts +2709 -499
- package/src/providers/cli-provider-status-helpers.ts +123 -0
- package/src/providers/cli-provider-transcript-merge.ts +114 -0
- package/src/providers/contracts.d.ts +55 -0
- package/src/providers/contracts.ts +160 -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 +105 -0
- package/src/providers/native-history/antigravity-claim-registry.ts +138 -0
- package/src/providers/native-history/antigravity-cli-transcript.ts +1275 -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 +617 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +312 -0
- package/src/providers/native-history/index.ts +30 -0
- package/src/providers/provider-instance-manager.ts +71 -0
- package/src/providers/provider-instance.ts +24 -1
- package/src/providers/provider-loader.ts +700 -55
- 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 +261 -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 +509 -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 +246 -0
- package/src/providers/spec/cli-adapter.ts +1064 -0
- package/src/providers/spec/evaluator.ts +407 -0
- package/src/providers/spec/fsm-driver.ts +1528 -0
- package/src/providers/spec/fsm-evaluator.ts +290 -0
- package/src/providers/spec/fsm-loader.ts +128 -0
- package/src/providers/spec/fsm-types.ts +301 -0
- package/src/providers/spec/native-history-executor.ts +1241 -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 +284 -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 +868 -13
- package/src/runtime-defaults.ts +39 -0
- package/src/session-host/managed-host.ts +218 -0
- package/src/session-host/runtime-surface.ts +20 -80
- package/src/sessions/registry.ts +44 -0
- package/src/shared-types-extra.ts +2 -4
- package/src/shared-types.d.ts +8 -0
- package/src/shared-types.ts +136 -55
- package/src/status/builders.ts +26 -6
- package/src/status/chat-tail-hot-sessions.ts +117 -2
- 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,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buildParseApprovalFromTui
|
|
3
|
+
*
|
|
4
|
+
* Turns a `tui/modal@1` block into a runtime
|
|
5
|
+
* `(input: CliApprovalInput) => CliApprovalModal | null` function.
|
|
6
|
+
*
|
|
7
|
+
* Contract rules enforced (sprint-2026-06):
|
|
8
|
+
* - Returns null when the question pattern is not visible.
|
|
9
|
+
* - Returns null when the button list is empty or shorter than minButtons.
|
|
10
|
+
* - Button labels are raw text; never rewritten (e.g. "Yes, and don't ask
|
|
11
|
+
* again for X" stays verbatim).
|
|
12
|
+
* - Modal scope respects between-last-two-separators / window-around-question
|
|
13
|
+
* / whole-screen to avoid false-positives from numbered lists in
|
|
14
|
+
* assistant prose.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type {
|
|
18
|
+
CliApprovalInput,
|
|
19
|
+
CliApprovalModal,
|
|
20
|
+
CliParseApprovalFn,
|
|
21
|
+
} from '../../types/cli/index.js';
|
|
22
|
+
import {
|
|
23
|
+
applyVisibleRegion,
|
|
24
|
+
type VisibleRegionSpec,
|
|
25
|
+
} from './visible-region.js';
|
|
26
|
+
|
|
27
|
+
// ─── Spec shapes ───────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
interface ModalQuestionVariant {
|
|
30
|
+
regex: string;
|
|
31
|
+
flags?: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface ModalContextHeader {
|
|
36
|
+
regex: string;
|
|
37
|
+
flags?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ModalTuiSpec {
|
|
41
|
+
$schema: 'adhdev:tui/modal@1';
|
|
42
|
+
questionPattern: string;
|
|
43
|
+
questionFlags?: string;
|
|
44
|
+
questionVariants?: ModalQuestionVariant[];
|
|
45
|
+
buttonPattern: string;
|
|
46
|
+
buttonFlags?: string;
|
|
47
|
+
buttonLabelGroup?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Optional fallback for terminals that render all options on a single line
|
|
50
|
+
* (e.g. Antigravity feedback survey: `[0] skip [1] yes [2] no [3] still using`).
|
|
51
|
+
* When per-line button extraction collects fewer than `minButtons`, the
|
|
52
|
+
* builder makes a second pass with this regex (global match, capture group 1
|
|
53
|
+
* is the label).
|
|
54
|
+
*/
|
|
55
|
+
inlineButtonPattern?: string;
|
|
56
|
+
inlineButtonFlags?: string;
|
|
57
|
+
scope?: 'between-last-two-separators' | 'window-around-question' | 'whole-screen';
|
|
58
|
+
scopeWindowLines?: number;
|
|
59
|
+
contextHeader?: ModalContextHeader;
|
|
60
|
+
continuationLines?: boolean;
|
|
61
|
+
minButtons?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ─── Helpers ───────────────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
// A horizontal rule line. Covers solid box-drawing rules (─ ━ ═) AND the dashed
|
|
67
|
+
// variants (╌ ╍ ┄ ┅ ┈ ┉) that Claude Code draws as the INNER separators around a
|
|
68
|
+
// Write/Edit diff body. This matches the coverage of the claude-cli v4 FSM spec
|
|
69
|
+
// anchor `^[─╌]+$` (issue #137) so the SDK-v1 parser recognizes the same modal
|
|
70
|
+
// frames the FSM does — a dashed rule is a separator, not modal content.
|
|
71
|
+
const SEPARATOR_RE = /^[─━═╌╍┄┅┈┉]{10,}\s*$/;
|
|
72
|
+
|
|
73
|
+
function compile(re: string, flags?: string): RegExp {
|
|
74
|
+
try {
|
|
75
|
+
return new RegExp(re, flags);
|
|
76
|
+
} catch (e) {
|
|
77
|
+
throw new Error(`Invalid regex /${re}/${flags ?? ''}: ${(e as Error).message}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function findQuestionLineIndex(
|
|
82
|
+
spec: ModalTuiSpec,
|
|
83
|
+
lines: string[],
|
|
84
|
+
): { index: number; matchedSource: 'primary' | string } | null {
|
|
85
|
+
const primary = compile(spec.questionPattern, spec.questionFlags ?? 'i');
|
|
86
|
+
// Search bottom-up to prefer the most recent modal.
|
|
87
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
88
|
+
if (primary.test(lines[i])) return { index: i, matchedSource: 'primary' };
|
|
89
|
+
}
|
|
90
|
+
for (const variant of spec.questionVariants ?? []) {
|
|
91
|
+
const re = compile(variant.regex, variant.flags ?? 'i');
|
|
92
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
93
|
+
if (re.test(lines[i])) return { index: i, matchedSource: variant.label ?? 'variant' };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function scopeLines(
|
|
100
|
+
spec: ModalTuiSpec,
|
|
101
|
+
lines: string[],
|
|
102
|
+
questionIndex: number,
|
|
103
|
+
): { start: number; end: number } {
|
|
104
|
+
const scope = spec.scope ?? 'between-last-two-separators';
|
|
105
|
+
if (scope === 'whole-screen') {
|
|
106
|
+
return { start: 0, end: lines.length };
|
|
107
|
+
}
|
|
108
|
+
if (scope === 'window-around-question') {
|
|
109
|
+
const window = spec.scopeWindowLines ?? 16;
|
|
110
|
+
return {
|
|
111
|
+
start: Math.max(0, questionIndex - 2),
|
|
112
|
+
end: Math.min(lines.length, questionIndex + window),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// between-last-two-separators
|
|
116
|
+
let lastSep = -1;
|
|
117
|
+
let prevSep = -1;
|
|
118
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
119
|
+
if (SEPARATOR_RE.test(lines[i].trim())) {
|
|
120
|
+
if (lastSep < 0) lastSep = i;
|
|
121
|
+
else if (prevSep < 0) {
|
|
122
|
+
prevSep = i;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Only scope to the separator frame when it actually BRACKETS the question
|
|
128
|
+
// line. Claude Write/Edit modals draw dashed (╌) inner rules around the diff
|
|
129
|
+
// body, so the last two separators can enclose the file diff while the
|
|
130
|
+
// question + button block sit BELOW the lower dashed rule. Scoping to that
|
|
131
|
+
// inner frame would drop every button (→ null → missed auto-approve, #137).
|
|
132
|
+
// When the question is outside the frame, fall through to a window around it.
|
|
133
|
+
if (lastSep >= 0 && prevSep >= 0 && questionIndex >= prevSep && questionIndex < lastSep + 1) {
|
|
134
|
+
return { start: prevSep, end: lastSep + 1 };
|
|
135
|
+
}
|
|
136
|
+
// Fallback: window around question line.
|
|
137
|
+
return {
|
|
138
|
+
start: Math.max(0, questionIndex - 4),
|
|
139
|
+
end: Math.min(lines.length, questionIndex + 16),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function extractButtons(
|
|
144
|
+
spec: ModalTuiSpec,
|
|
145
|
+
lines: string[],
|
|
146
|
+
windowStart: number,
|
|
147
|
+
windowEnd: number,
|
|
148
|
+
): string[] {
|
|
149
|
+
const buttonRe = compile(spec.buttonPattern, spec.buttonFlags ?? 'm');
|
|
150
|
+
const out: string[] = [];
|
|
151
|
+
const labelGroup = Number.isInteger(spec.buttonLabelGroup) && (spec.buttonLabelGroup ?? 0) > 0
|
|
152
|
+
? spec.buttonLabelGroup!
|
|
153
|
+
: 1;
|
|
154
|
+
let i = windowStart;
|
|
155
|
+
while (i < windowEnd) {
|
|
156
|
+
const line = lines[i];
|
|
157
|
+
const m = buttonRe.exec(line);
|
|
158
|
+
const captured = m?.[labelGroup] ?? (labelGroup === 1 && m && m.length > 2 ? m[m.length - 1] : undefined);
|
|
159
|
+
if (m && captured) {
|
|
160
|
+
let label = captured.trim();
|
|
161
|
+
// Continuation lines: when enabled, append indented lines below until
|
|
162
|
+
// the next button or blank.
|
|
163
|
+
if (spec.continuationLines) {
|
|
164
|
+
let j = i + 1;
|
|
165
|
+
while (j < windowEnd) {
|
|
166
|
+
const next = lines[j];
|
|
167
|
+
if (!next.trim()) break;
|
|
168
|
+
if (buttonRe.test(next)) break;
|
|
169
|
+
// continuation must be indented (not at column 0 like a new section).
|
|
170
|
+
if (!/^\s+/.test(next)) break;
|
|
171
|
+
label += ' ' + next.trim();
|
|
172
|
+
j += 1;
|
|
173
|
+
}
|
|
174
|
+
i = j;
|
|
175
|
+
} else {
|
|
176
|
+
i += 1;
|
|
177
|
+
}
|
|
178
|
+
out.push(label);
|
|
179
|
+
} else {
|
|
180
|
+
i += 1;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function buildMessage(
|
|
187
|
+
spec: ModalTuiSpec,
|
|
188
|
+
lines: string[],
|
|
189
|
+
questionIndex: number,
|
|
190
|
+
windowStart: number,
|
|
191
|
+
windowEnd: number,
|
|
192
|
+
): string {
|
|
193
|
+
const messageParts: string[] = [];
|
|
194
|
+
if (spec.contextHeader) {
|
|
195
|
+
const ctxRe = compile(spec.contextHeader.regex, (spec.contextHeader.flags ?? 'i') + 'm');
|
|
196
|
+
const haystack = lines.slice(windowStart, windowEnd).join('\n');
|
|
197
|
+
const m = ctxRe.exec(haystack);
|
|
198
|
+
if (m) messageParts.push(m[1] ? m[1].trim() : m[0].trim());
|
|
199
|
+
}
|
|
200
|
+
messageParts.push(lines[questionIndex].trim());
|
|
201
|
+
return messageParts.filter(Boolean).join(' — ');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// ─── Public builder ────────────────────────────────────────────────────
|
|
205
|
+
|
|
206
|
+
function extractInlineButtons(
|
|
207
|
+
spec: ModalTuiSpec,
|
|
208
|
+
lines: string[],
|
|
209
|
+
windowStart: number,
|
|
210
|
+
windowEnd: number,
|
|
211
|
+
): string[] {
|
|
212
|
+
if (!spec.inlineButtonPattern) return [];
|
|
213
|
+
// Always force the `g` flag so we can iterate all matches in the line.
|
|
214
|
+
const declaredFlags = spec.inlineButtonFlags ?? 'gi';
|
|
215
|
+
const flags = declaredFlags.includes('g') ? declaredFlags : declaredFlags + 'g';
|
|
216
|
+
const re = compile(spec.inlineButtonPattern, flags);
|
|
217
|
+
const out: string[] = [];
|
|
218
|
+
for (let i = windowStart; i < windowEnd; i += 1) {
|
|
219
|
+
let m: RegExpExecArray | null;
|
|
220
|
+
re.lastIndex = 0;
|
|
221
|
+
while ((m = re.exec(lines[i])) !== null) {
|
|
222
|
+
const label = (m[1] ?? m[0]).trim();
|
|
223
|
+
if (label && !out.includes(label)) out.push(label);
|
|
224
|
+
if (m.index === re.lastIndex) re.lastIndex += 1; // safety against zero-width matches
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function buildParseApprovalFromTui(
|
|
231
|
+
spec: ModalTuiSpec,
|
|
232
|
+
visibleRegion?: VisibleRegionSpec,
|
|
233
|
+
): CliParseApprovalFn {
|
|
234
|
+
const minButtons = spec.minButtons ?? 2;
|
|
235
|
+
|
|
236
|
+
return function parseApproval(input: CliApprovalInput): CliApprovalModal | null {
|
|
237
|
+
const rawText = input.screenText ?? input.buffer ?? '';
|
|
238
|
+
if (!rawText) return null;
|
|
239
|
+
const text = visibleRegion ? applyVisibleRegion(visibleRegion, rawText) : rawText;
|
|
240
|
+
const lines = text.split('\n');
|
|
241
|
+
const question = findQuestionLineIndex(spec, lines);
|
|
242
|
+
if (!question) return null;
|
|
243
|
+
const { start, end } = scopeLines(spec, lines, question.index);
|
|
244
|
+
if (question.index < start || question.index >= end) return null;
|
|
245
|
+
let buttons = extractButtons(spec, lines, question.index + 1, end);
|
|
246
|
+
// Inline fallback: when per-line extraction came up short, the terminal
|
|
247
|
+
// may have rendered every option on the same line ("[0] skip [1] yes …").
|
|
248
|
+
if (buttons.length < minButtons && spec.inlineButtonPattern) {
|
|
249
|
+
buttons = extractInlineButtons(spec, lines, question.index, end);
|
|
250
|
+
}
|
|
251
|
+
if (buttons.length < minButtons) return null;
|
|
252
|
+
const message = buildMessage(spec, lines, question.index, start, end);
|
|
253
|
+
return { message, buttons };
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export const __internal = {
|
|
258
|
+
findQuestionLineIndex,
|
|
259
|
+
scopeLines,
|
|
260
|
+
extractButtons,
|
|
261
|
+
};
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* buildParseSessionFromTui — synthesize a parseSession function from the
|
|
3
|
+
* manifest tui block alone.
|
|
4
|
+
*
|
|
5
|
+
* Composition:
|
|
6
|
+
* 1. detectStatus from tui.spinner/modal/settledPrompt/dispatchOrder
|
|
7
|
+
* (delegated to buildDetectStatusFromTui)
|
|
8
|
+
* 2. parseApproval from tui.modal (delegated to buildParseApprovalFromTui)
|
|
9
|
+
* 3. message extraction from tui.transcriptPty (this file)
|
|
10
|
+
*
|
|
11
|
+
* The result has the same shape as the legacy parse_output:
|
|
12
|
+
* { status, messages, activeModal, transcriptAuthority?, coverage?, providerSessionId? }
|
|
13
|
+
*
|
|
14
|
+
* Identity stamping (providerUnitKey, bubbleId, sequence, bubbleState) is
|
|
15
|
+
* applied by the caller, mirroring _shared/parse_session.js. We export the
|
|
16
|
+
* stamper as `normalizeMessageIdentity` for reuse.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { buildDetectStatusFromTui, type DetectStatusTuiSpec } from './detect-status.js'
|
|
20
|
+
import { buildParseApprovalFromTui, type ModalTuiSpec } from './parse-approval.js'
|
|
21
|
+
import * as crypto from 'node:crypto'
|
|
22
|
+
|
|
23
|
+
// ─── Schema types ────────────────────────────────
|
|
24
|
+
|
|
25
|
+
export interface PrefixSpec {
|
|
26
|
+
regex: string
|
|
27
|
+
flags?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ToolPrefixSpec extends PrefixSpec {
|
|
31
|
+
skip?: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ChromePatternSpec {
|
|
35
|
+
regex: string
|
|
36
|
+
flags?: string
|
|
37
|
+
label?: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface TranscriptPtySpec {
|
|
41
|
+
$schema?: 'adhdev:tui/transcript-pty@1'
|
|
42
|
+
assistantPrefix: PrefixSpec
|
|
43
|
+
userPrefix?: PrefixSpec
|
|
44
|
+
toolPrefix?: ToolPrefixSpec
|
|
45
|
+
continuationLine?: { indented?: boolean }
|
|
46
|
+
chromePatterns?: ChromePatternSpec[]
|
|
47
|
+
stripLeadingChrome?: boolean
|
|
48
|
+
scope?: 'screen' | 'buffer' | 'tail'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SessionIdExtractionSpec {
|
|
52
|
+
$schema?: 'adhdev:tui/session-id-extraction@1'
|
|
53
|
+
regex: string
|
|
54
|
+
flags?: string
|
|
55
|
+
scope?: 'screen' | 'tail' | 'buffer'
|
|
56
|
+
label?: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface ParseSessionTuiSpec {
|
|
60
|
+
spinner?: any
|
|
61
|
+
settledPrompt?: any
|
|
62
|
+
modal?: ModalTuiSpec
|
|
63
|
+
dispatchOrder?: any
|
|
64
|
+
transcriptPty: TranscriptPtySpec
|
|
65
|
+
sessionIdExtraction?: SessionIdExtractionSpec
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ─── Output shape ────────────────────────────────
|
|
69
|
+
|
|
70
|
+
export interface SynthesizedMessage {
|
|
71
|
+
role: 'user' | 'assistant'
|
|
72
|
+
kind?: 'standard' | 'tool'
|
|
73
|
+
content: string
|
|
74
|
+
receivedAt?: number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface SynthesizedSession {
|
|
78
|
+
status: string | null
|
|
79
|
+
messages: SynthesizedMessage[]
|
|
80
|
+
activeModal: { message: string; buttons: string[] } | null
|
|
81
|
+
modal: { message: string; buttons: string[] } | null
|
|
82
|
+
parsedStatus: string | null
|
|
83
|
+
transcriptAuthority?: 'provider' | 'daemon'
|
|
84
|
+
coverage?: 'full' | 'tail' | 'current-turn'
|
|
85
|
+
providerSessionId?: string
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ─── ANSI / line helpers ─────────────────────────
|
|
89
|
+
|
|
90
|
+
const ANSI_RE = /\x1b\[[0-?]*[ -/]*[@-~]/g
|
|
91
|
+
const OSC_RE = /\x1b\][^\x07\x1b\n]*(?:\x07|\x1b\\|(?=\n|$))/g
|
|
92
|
+
|
|
93
|
+
function stripAnsi(text: string): string {
|
|
94
|
+
return String(text || '')
|
|
95
|
+
.replace(/\x1b\[(\d*)C/g, (_m, n) => ' '.repeat(Math.max(1, Number(n) || 1)))
|
|
96
|
+
.replace(/\x1b\[\d*D/g, '')
|
|
97
|
+
.replace(ANSI_RE, '')
|
|
98
|
+
.replace(OSC_RE, '')
|
|
99
|
+
.replace(/\x1b[P^_X][\s\S]*?(?:\x07|\x1b\\)/g, '')
|
|
100
|
+
.replace(/\x1b(?:[@-Z\\-_])/g, '')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function splitLines(text: string): string[] {
|
|
104
|
+
return stripAnsi(text)
|
|
105
|
+
.replace(//g, '')
|
|
106
|
+
.split(/\r?\n/)
|
|
107
|
+
.map(l => l.replace(/\s+$/, ''))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function pickInputText(input: any, scope: TranscriptPtySpec['scope']): string {
|
|
111
|
+
if (!input) return ''
|
|
112
|
+
if (scope === 'screen') return String(input.screenText || input.screen?.text || '')
|
|
113
|
+
if (scope === 'tail') return String(input.tail || input.recentBuffer || input.buffer || '')
|
|
114
|
+
return String(input.buffer || input.rawBuffer || input.screenText || '')
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ─── Identity stamping (mirrors _shared/parse_session.js) ─────
|
|
118
|
+
|
|
119
|
+
function stableHash(value: string): string {
|
|
120
|
+
return crypto.createHash('sha1').update(String(value || '')).digest('hex').slice(0, 12)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function normalizeMessageIdentity<T extends { role?: string; kind?: string; content?: string }>(
|
|
124
|
+
messages: T[],
|
|
125
|
+
status: string,
|
|
126
|
+
): Array<T & {
|
|
127
|
+
providerUnitKey: string
|
|
128
|
+
bubbleId: string
|
|
129
|
+
sequence: number
|
|
130
|
+
_turnKey: string
|
|
131
|
+
bubbleState: 'streaming' | 'final'
|
|
132
|
+
}> {
|
|
133
|
+
const list = Array.isArray(messages) ? messages : []
|
|
134
|
+
let turnIndex = -1
|
|
135
|
+
return list.map((message, index) => {
|
|
136
|
+
const role = message?.role || 'assistant'
|
|
137
|
+
const kind = message?.kind || 'standard'
|
|
138
|
+
const content = typeof message?.content === 'string' ? message.content : ''
|
|
139
|
+
if (role === 'user' || turnIndex < 0) turnIndex += 1
|
|
140
|
+
const seed = [role, kind, '', index, content].join('\n')
|
|
141
|
+
const providerUnitKey = `v2-pty:${role}:${kind}:${index}:${stableHash(seed)}`
|
|
142
|
+
const bubbleId = `bubble:${providerUnitKey}`
|
|
143
|
+
const turnKey = `turn:${turnIndex}`
|
|
144
|
+
const isStreamingTail = status === 'generating' && role === 'assistant' && index === list.length - 1
|
|
145
|
+
return {
|
|
146
|
+
...message,
|
|
147
|
+
providerUnitKey,
|
|
148
|
+
bubbleId,
|
|
149
|
+
sequence: index,
|
|
150
|
+
_turnKey: turnKey,
|
|
151
|
+
bubbleState: isStreamingTail ? 'streaming' as const : 'final' as const,
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ─── Main builder ────────────────────────────────
|
|
157
|
+
|
|
158
|
+
export function buildParseSessionFromTui(spec: ParseSessionTuiSpec): (input: any) => SynthesizedSession {
|
|
159
|
+
if (!spec.transcriptPty) {
|
|
160
|
+
throw new Error('buildParseSessionFromTui: spec.transcriptPty is required')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Compile regexes once
|
|
164
|
+
const assistantRe = new RegExp(spec.transcriptPty.assistantPrefix.regex, spec.transcriptPty.assistantPrefix.flags || '')
|
|
165
|
+
const userRe = spec.transcriptPty.userPrefix
|
|
166
|
+
? new RegExp(spec.transcriptPty.userPrefix.regex, spec.transcriptPty.userPrefix.flags || '')
|
|
167
|
+
: null
|
|
168
|
+
const toolRe = spec.transcriptPty.toolPrefix
|
|
169
|
+
? new RegExp(spec.transcriptPty.toolPrefix.regex, spec.transcriptPty.toolPrefix.flags || '')
|
|
170
|
+
: null
|
|
171
|
+
const toolSkip = spec.transcriptPty.toolPrefix?.skip ?? false
|
|
172
|
+
const chromeRes = (spec.transcriptPty.chromePatterns || []).map(p =>
|
|
173
|
+
new RegExp(p.regex, p.flags || ''))
|
|
174
|
+
const requireIndentForContinuation = spec.transcriptPty.continuationLine?.indented ?? false
|
|
175
|
+
const stripLeadingChrome = spec.transcriptPty.stripLeadingChrome ?? true
|
|
176
|
+
const scope = spec.transcriptPty.scope ?? 'buffer'
|
|
177
|
+
|
|
178
|
+
// Compose detect + approval helpers if their inputs are present.
|
|
179
|
+
const detectStatus = (spec.spinner || spec.settledPrompt || spec.modal || spec.dispatchOrder)
|
|
180
|
+
? buildDetectStatusFromTui({
|
|
181
|
+
spinner: spec.spinner,
|
|
182
|
+
settledPrompt: spec.settledPrompt,
|
|
183
|
+
modal: spec.modal,
|
|
184
|
+
dispatchOrder: spec.dispatchOrder,
|
|
185
|
+
})
|
|
186
|
+
: () => null
|
|
187
|
+
const parseApproval = spec.modal ? buildParseApprovalFromTui(spec.modal) : () => null
|
|
188
|
+
|
|
189
|
+
// Optional session-id extraction (tui/session-id-extraction@1). Compile once
|
|
190
|
+
// so each parseSession call is a single regex.exec on the chosen scope.
|
|
191
|
+
const sessionIdRe = spec.sessionIdExtraction
|
|
192
|
+
? new RegExp(
|
|
193
|
+
spec.sessionIdExtraction.regex,
|
|
194
|
+
spec.sessionIdExtraction.flags ?? 'i',
|
|
195
|
+
)
|
|
196
|
+
: null
|
|
197
|
+
const sessionIdScope: TranscriptPtySpec['scope'] = spec.sessionIdExtraction?.scope ?? 'tail'
|
|
198
|
+
|
|
199
|
+
return function parseSession(input: any): SynthesizedSession {
|
|
200
|
+
// status + modal first
|
|
201
|
+
const status = detectStatus(input as any) ?? 'idle'
|
|
202
|
+
const modal = parseApproval(input as any)
|
|
203
|
+
|
|
204
|
+
const text = pickInputText(input, scope)
|
|
205
|
+
const lines = splitLines(text)
|
|
206
|
+
|
|
207
|
+
const messages: SynthesizedMessage[] = []
|
|
208
|
+
let seenFirstRoleLine = !stripLeadingChrome
|
|
209
|
+
|
|
210
|
+
for (const raw of lines) {
|
|
211
|
+
const line = raw
|
|
212
|
+
if (line.trim() === '') {
|
|
213
|
+
// Blank line: ends streaming continuation but doesn't add a message.
|
|
214
|
+
continue
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Chrome filter
|
|
218
|
+
let isChrome = false
|
|
219
|
+
for (const cre of chromeRes) {
|
|
220
|
+
if (cre.test(line)) { isChrome = true; break }
|
|
221
|
+
}
|
|
222
|
+
if (isChrome) continue
|
|
223
|
+
|
|
224
|
+
// Role detection
|
|
225
|
+
const userMatch = userRe ? line.match(userRe) : null
|
|
226
|
+
const toolMatch = toolRe ? line.match(toolRe) : null
|
|
227
|
+
const assistMatch = line.match(assistantRe)
|
|
228
|
+
|
|
229
|
+
if (userMatch) {
|
|
230
|
+
seenFirstRoleLine = true
|
|
231
|
+
const content = (userMatch[1] ?? userMatch[0]).trim()
|
|
232
|
+
if (content) messages.push({ role: 'user', kind: 'standard', content })
|
|
233
|
+
continue
|
|
234
|
+
}
|
|
235
|
+
if (toolMatch) {
|
|
236
|
+
seenFirstRoleLine = true
|
|
237
|
+
if (toolSkip) continue
|
|
238
|
+
const content = (toolMatch[1] ?? toolMatch[0]).trim()
|
|
239
|
+
if (content) messages.push({ role: 'assistant', kind: 'tool', content })
|
|
240
|
+
continue
|
|
241
|
+
}
|
|
242
|
+
if (assistMatch) {
|
|
243
|
+
seenFirstRoleLine = true
|
|
244
|
+
const content = (assistMatch[1] ?? assistMatch[0]).trim()
|
|
245
|
+
if (content) messages.push({ role: 'assistant', kind: 'standard', content })
|
|
246
|
+
continue
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!seenFirstRoleLine) continue
|
|
250
|
+
|
|
251
|
+
// Continuation rule
|
|
252
|
+
if (requireIndentForContinuation && !/^\s/.test(line)) continue
|
|
253
|
+
const last = messages[messages.length - 1]
|
|
254
|
+
if (!last) continue
|
|
255
|
+
const cont = line.replace(/^\s+/, '')
|
|
256
|
+
if (cont) last.content = last.content ? `${last.content}\n${cont}` : cont
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const result: SynthesizedSession = {
|
|
260
|
+
status,
|
|
261
|
+
messages,
|
|
262
|
+
activeModal: modal,
|
|
263
|
+
modal,
|
|
264
|
+
parsedStatus: status,
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (sessionIdRe) {
|
|
268
|
+
const haystack = stripAnsi(pickInputText(input, sessionIdScope))
|
|
269
|
+
const match = haystack.match(sessionIdRe)
|
|
270
|
+
const captured = match?.[1]?.trim()
|
|
271
|
+
if (captured) result.providerSessionId = captured
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return result
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* applyVisibleRegion
|
|
3
|
+
*
|
|
4
|
+
* Scopes the raw terminal text to the "visible region" declared by a
|
|
5
|
+
* `tui/visible-region@1` spec before handing it to detect-status and
|
|
6
|
+
* parse-approval matchers.
|
|
7
|
+
*
|
|
8
|
+
* Scope semantics:
|
|
9
|
+
* screen → full text unchanged (daemon already passes rendered screen)
|
|
10
|
+
* buffer → full text unchanged
|
|
11
|
+
* tail → last `tailChars` characters (default 4000)
|
|
12
|
+
* between-anchors → text between most recent (or first) top/bottom anchor
|
|
13
|
+
* regex matches; falls back to full text if anchors not found
|
|
14
|
+
*
|
|
15
|
+
* selectAnchor:
|
|
16
|
+
* "last" → use the LAST occurrence of the top anchor — useful for providers
|
|
17
|
+
* like Antigravity that redraw a separator + prompt on every turn;
|
|
18
|
+
* this excludes all scrollback above the current session frame.
|
|
19
|
+
* "first" → use the FIRST occurrence (default per schema).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// ─── Spec shape (mirrors tui-visible-region-v1.json) ───────────────────
|
|
23
|
+
|
|
24
|
+
interface AnchorPatternSpec {
|
|
25
|
+
pattern: string;
|
|
26
|
+
flags?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface AnchorsSpec {
|
|
30
|
+
top?: AnchorPatternSpec;
|
|
31
|
+
bottom?: AnchorPatternSpec;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface VisibleRegionSpec {
|
|
35
|
+
$schema?: 'adhdev:tui/visible-region@1';
|
|
36
|
+
scope: 'screen' | 'tail' | 'buffer' | 'between-anchors';
|
|
37
|
+
tailChars?: number;
|
|
38
|
+
anchors?: AnchorsSpec;
|
|
39
|
+
selectAnchor?: 'first' | 'last';
|
|
40
|
+
stripCues?: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ─── Helpers ───────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
function compile(re: string, flags?: string): RegExp {
|
|
46
|
+
try {
|
|
47
|
+
return new RegExp(re, flags ?? '');
|
|
48
|
+
} catch (e) {
|
|
49
|
+
throw new Error(`Invalid visible-region anchor regex /${re}/${flags ?? ''}: ${(e as Error).message}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Find all non-overlapping matches of `re` in `text`.
|
|
55
|
+
* Returns them in order of occurrence (earliest first).
|
|
56
|
+
*/
|
|
57
|
+
function findAllMatches(re: RegExp, text: string): RegExpExecArray[] {
|
|
58
|
+
const results: RegExpExecArray[] = [];
|
|
59
|
+
// Operate on a non-global copy with sticky-safe iteration to avoid
|
|
60
|
+
// mutating the caller's RegExp state.
|
|
61
|
+
const iter = new RegExp(re.source, re.flags.replace('g', '') + 'g');
|
|
62
|
+
let m: RegExpExecArray | null;
|
|
63
|
+
while ((m = iter.exec(text)) !== null) {
|
|
64
|
+
results.push(m);
|
|
65
|
+
// Advance past zero-width matches to prevent infinite loop.
|
|
66
|
+
if (m[0].length === 0) iter.lastIndex += 1;
|
|
67
|
+
}
|
|
68
|
+
return results;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ─── Public API ────────────────────────────────────────────────────────
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Apply the visible-region spec to `text` and return the scoped substring.
|
|
75
|
+
* Never throws on missing anchors — falls back to the full text instead.
|
|
76
|
+
*/
|
|
77
|
+
export function applyVisibleRegion(spec: VisibleRegionSpec, text: string): string {
|
|
78
|
+
if (!text) return text;
|
|
79
|
+
|
|
80
|
+
switch (spec.scope) {
|
|
81
|
+
case 'screen':
|
|
82
|
+
case 'buffer':
|
|
83
|
+
return text;
|
|
84
|
+
|
|
85
|
+
case 'tail': {
|
|
86
|
+
const limit = spec.tailChars ?? 4000;
|
|
87
|
+
if (text.length <= limit) return text;
|
|
88
|
+
return text.slice(-limit);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case 'between-anchors': {
|
|
92
|
+
const anchors = spec.anchors;
|
|
93
|
+
if (!anchors?.top && !anchors?.bottom) return text;
|
|
94
|
+
|
|
95
|
+
const selectLast = (spec.selectAnchor ?? 'first') === 'last';
|
|
96
|
+
|
|
97
|
+
// ── Top anchor ──
|
|
98
|
+
let topEnd = 0; // default: start of text
|
|
99
|
+
if (anchors.top) {
|
|
100
|
+
const topRe = compile(anchors.top.pattern, anchors.top.flags);
|
|
101
|
+
const topMatches = findAllMatches(topRe, text);
|
|
102
|
+
if (topMatches.length === 0) {
|
|
103
|
+
// Top anchor not found — fall back to full text.
|
|
104
|
+
return text;
|
|
105
|
+
}
|
|
106
|
+
const chosen = selectLast
|
|
107
|
+
? topMatches[topMatches.length - 1]
|
|
108
|
+
: topMatches[0];
|
|
109
|
+
// Region starts just after the end of the top anchor match.
|
|
110
|
+
topEnd = chosen.index + chosen[0].length;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ── Bottom anchor ──
|
|
114
|
+
let bottomStart = text.length; // default: end of text
|
|
115
|
+
if (anchors.bottom) {
|
|
116
|
+
const bottomRe = compile(anchors.bottom.pattern, anchors.bottom.flags);
|
|
117
|
+
// Only search the portion that comes AFTER the top anchor end so we
|
|
118
|
+
// always pick the immediately-following bottom anchor.
|
|
119
|
+
const searchFrom = topEnd;
|
|
120
|
+
const suffix = text.slice(searchFrom);
|
|
121
|
+
const bottomMatches = findAllMatches(bottomRe, suffix);
|
|
122
|
+
if (bottomMatches.length === 0) {
|
|
123
|
+
// Bottom anchor not found — fall back to full text.
|
|
124
|
+
return text;
|
|
125
|
+
}
|
|
126
|
+
const chosen = selectLast
|
|
127
|
+
? bottomMatches[bottomMatches.length - 1]
|
|
128
|
+
: bottomMatches[0];
|
|
129
|
+
bottomStart = searchFrom + chosen.index;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (topEnd >= bottomStart) {
|
|
133
|
+
// Degenerate / overlapping anchors — fall back to full text.
|
|
134
|
+
return text;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return text.slice(topEnd, bottomStart);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
default:
|
|
141
|
+
return text;
|
|
142
|
+
}
|
|
143
|
+
}
|