@adhdev/daemon-core 0.9.82-rc.45 → 0.9.82-rc.450
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 +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 +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 +25 -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 +29 -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.d.ts +279 -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 +129 -1
- package/dist/config/mesh-json-config.d.ts +199 -0
- package/dist/config/repo-settings.d.ts +77 -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 +12 -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 +66 -14
- package/dist/index.js +48475 -17084
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49521 -18300
- 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-clone-grace.d.ts +8 -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 +41 -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 +69 -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 +115 -1
- package/dist/mesh/mesh-magi-status.d.ts +63 -0
- package/dist/mesh/mesh-missions.d.ts +189 -0
- package/dist/mesh/mesh-node-identity.d.ts +306 -0
- package/dist/mesh/mesh-queue-assignment.d.ts +113 -0
- package/dist/mesh/mesh-reconcile-loop.d.ts +79 -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 +450 -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 +300 -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 +32 -1
- package/dist/providers/cli-provider-instance.d.ts +254 -3
- package/dist/providers/contracts.d.ts +149 -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 +126 -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 +29 -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 +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 +444 -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 +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 +519 -13
- package/dist/runtime-defaults.d.ts +2 -0
- package/dist/session-host/managed-host.d.ts +64 -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 +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/WINDOWS-UPGRADE-LOCK-FAILURE.md +198 -0
- package/src/commands/chat-commands-debug-bundle.ts +398 -0
- package/src/commands/chat-commands-read.ts +2488 -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 +596 -27
- 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 +680 -0
- package/src/commands/high-family/mesh-events.ts +89 -0
- package/src/commands/high-family/mesh-status.ts +822 -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 +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 +1253 -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.ts +2893 -3536
- package/src/commands/stream-commands.ts +8 -0
- package/src/commands/upgrade-helper.ts +310 -45
- package/src/config/chat-history.ts +493 -24
- package/src/config/config.ts +12 -0
- package/src/config/mesh-config.ts +619 -23
- package/src/config/mesh-json-config.ts +376 -0
- package/src/config/recent-activity.ts +8 -2
- package/src/config/repo-settings.ts +111 -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 +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 +78 -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 +198 -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 +416 -34
- package/src/mesh/coordinator-registry.ts +121 -0
- package/src/mesh/mesh-active-work.ts +645 -0
- package/src/mesh/mesh-clone-grace.ts +68 -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 +1897 -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 +656 -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 +33 -1035
- package/src/mesh/mesh-fast-forward.ts +843 -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 +841 -102
- package/src/mesh/mesh-magi-status.ts +223 -0
- package/src/mesh/mesh-missions.ts +449 -0
- package/src/mesh/mesh-node-identity.ts +1985 -0
- package/src/mesh/mesh-queue-assignment.ts +1924 -0
- package/src/mesh/mesh-reconcile-loop.ts +2018 -0
- package/src/mesh/mesh-refine-batch.ts +205 -0
- package/src/mesh/mesh-refine-gates.ts +1673 -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 +1853 -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 +1254 -141
- package/src/mesh/preview-freshness.ts +118 -0
- package/src/mesh/refine-config.ts +423 -0
- package/src/mesh/worktree-bootstrap-config.ts +450 -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 +2177 -107
- 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 +85 -0
- package/src/providers/native-history/antigravity-cli-transcript.ts +1043 -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 +373 -0
- package/src/providers/native-history/hermes-cli-transcript.ts +260 -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 +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 +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 +1481 -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 +1174 -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 +758 -14
- package/src/runtime-defaults.ts +39 -0
- package/src/session-host/managed-host.ts +218 -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
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
* Migrated from @adhdev/core — this is now the single source of truth.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { exec } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
import { existsSync, statSync } from 'fs';
|
|
12
14
|
import { platform, homedir } from 'os';
|
|
13
15
|
import * as path from 'path';
|
|
14
16
|
import type { ProviderLoader } from '../providers/provider-loader.js';
|
|
17
|
+
import { isKnownWin32GuiExe, readWin32IdeVersionFromDisk } from './win32-ide-version.js';
|
|
15
18
|
|
|
16
19
|
// ─── Types ──────────────────────────────────────
|
|
17
20
|
|
|
@@ -73,25 +76,54 @@ function findCliCommand(command: string): string | null {
|
|
|
73
76
|
const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(candidate);
|
|
74
77
|
return existsSync(resolved) ? resolved : null;
|
|
75
78
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
const isWin = platform() === 'win32';
|
|
80
|
+
const paths = (process.env.PATH || '').split(isWin ? ';' : ':');
|
|
81
|
+
const exes = isWin ? ['.exe', '.cmd', '.bat', ''] : [''];
|
|
82
|
+
for (const p of paths) {
|
|
83
|
+
if (!p) continue;
|
|
84
|
+
for (const ext of exes) {
|
|
85
|
+
const fullPath = path.join(p, trimmed + ext);
|
|
86
|
+
try {
|
|
87
|
+
if (existsSync(fullPath)) {
|
|
88
|
+
const stat = statSync(fullPath);
|
|
89
|
+
if (stat.isFile() && (isWin || (stat.mode & 0o111))) {
|
|
90
|
+
return fullPath;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} catch { }
|
|
94
|
+
}
|
|
84
95
|
}
|
|
96
|
+
return null;
|
|
85
97
|
}
|
|
86
98
|
|
|
87
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Resolve an IDE version on demand (NOT at boot).
|
|
101
|
+
*
|
|
102
|
+
* Order of preference, all spawn-free where possible:
|
|
103
|
+
* 1. win32: read the bundled product.json/package.json next to the exe.
|
|
104
|
+
* 2. Otherwise spawn `<cli> --version` — but ONLY when the binary is not a
|
|
105
|
+
* known GUI executable (the #4 guard), so we never boot an IDE window.
|
|
106
|
+
*
|
|
107
|
+
* `win32ProcessNames` is provider.json `processNames.win32` (type → exe names),
|
|
108
|
+
* used to recognise GUI executables. Callers that have a ProviderLoader can
|
|
109
|
+
* pass `providerLoader.getWinProcessNames()`.
|
|
110
|
+
*/
|
|
111
|
+
export async function getIdeVersion(
|
|
112
|
+
cliCommand: string,
|
|
113
|
+
win32ProcessNames: Record<string, string[]> = {},
|
|
114
|
+
): Promise<string | null> {
|
|
115
|
+
if (platform() === 'win32') {
|
|
116
|
+
const fromDisk = readWin32IdeVersionFromDisk(cliCommand);
|
|
117
|
+
if (fromDisk) return fromDisk;
|
|
118
|
+
// Refuse to spawn a known GUI exe — it would launch the IDE window.
|
|
119
|
+
if (isKnownWin32GuiExe(cliCommand, win32ProcessNames)) return null;
|
|
120
|
+
}
|
|
88
121
|
try {
|
|
89
|
-
const
|
|
122
|
+
const { stdout } = await execAsync(`"${cliCommand}" --version`, {
|
|
90
123
|
encoding: 'utf-8',
|
|
91
124
|
timeout: 10000,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return result.split('\n')[0] || null;
|
|
125
|
+
});
|
|
126
|
+
return stdout.trim().split('\n')[0] || null;
|
|
95
127
|
} catch {
|
|
96
128
|
return null;
|
|
97
129
|
}
|
|
@@ -152,7 +184,14 @@ export async function detectIDEs(providerLoader?: ProviderLoader): Promise<IDEIn
|
|
|
152
184
|
const installed = os === 'darwin'
|
|
153
185
|
? !!(resolvedCli || appPath)
|
|
154
186
|
: !!resolvedCli;
|
|
155
|
-
|
|
187
|
+
// Boot-time IDE detection must NOT spawn `<cli> --version`. On Windows
|
|
188
|
+
// the resolved "CLI" is frequently the GUI Electron exe (case-insensitive
|
|
189
|
+
// FS matches `...\cursor\cursor.exe` against `Cursor.exe`), and running it
|
|
190
|
+
// with `--version` boots the IDE window. `installed` is decided purely by
|
|
191
|
+
// existsSync above, and the dashboard drops `version` anyway — the only
|
|
192
|
+
// real version consumer is provider-loader.resolve() at CDP attach time,
|
|
193
|
+
// which fetches the version lazily. So leave it null here.
|
|
194
|
+
const version: string | null = null;
|
|
156
195
|
|
|
157
196
|
results.push({
|
|
158
197
|
id: def.id,
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADHDev — Windows IDE version detection (execution-free)
|
|
3
|
+
*
|
|
4
|
+
* On Windows the resolved "CLI" for a VS Code fork (Cursor, Antigravity, …)
|
|
5
|
+
* frequently resolves to the GUI Electron executable itself, because the
|
|
6
|
+
* case-insensitive filesystem matches `...\cursor\cursor.exe` against the
|
|
7
|
+
* real `Cursor.exe`. Running `<that exe> --version` boots the GUI instead of
|
|
8
|
+
* printing a version (Electron ignores the unknown flag and opens a window).
|
|
9
|
+
*
|
|
10
|
+
* To learn the version WITHOUT spawning anything, we read the bundled
|
|
11
|
+
* `product.json` / `package.json` that ship next to the executable. VS Code
|
|
12
|
+
* forks embed their version there. This is a pure filesystem read.
|
|
13
|
+
*
|
|
14
|
+
* It also exposes a guard so any remaining `--version` exec path can refuse to
|
|
15
|
+
* spawn a binary that is a known GUI executable for an IDE provider.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as path from 'path';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Candidate locations for the version manifest relative to the GUI exe dir.
|
|
23
|
+
* VS Code forks place `resources/app/{product,package}.json` next to the exe.
|
|
24
|
+
*/
|
|
25
|
+
function manifestCandidates(exeDir: string): string[] {
|
|
26
|
+
return [
|
|
27
|
+
path.join(exeDir, 'resources', 'app', 'product.json'),
|
|
28
|
+
path.join(exeDir, 'resources', 'app', 'package.json'),
|
|
29
|
+
// Some packagings keep product.json one level up.
|
|
30
|
+
path.join(exeDir, 'product.json'),
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function parseVersionFromManifest(raw: string): string | null {
|
|
35
|
+
try {
|
|
36
|
+
const json = JSON.parse(raw) as Record<string, unknown>;
|
|
37
|
+
// product.json forks expose the IDE's own version here; package.json
|
|
38
|
+
// exposes the upstream VS Code engine version. Prefer the former.
|
|
39
|
+
const candidate = json.version;
|
|
40
|
+
if (typeof candidate === 'string' && candidate.trim()) {
|
|
41
|
+
return candidate.trim();
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
/* not valid JSON — ignore */
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Read an IDE version from disk (no process spawn).
|
|
51
|
+
*
|
|
52
|
+
* @param exePath Absolute path to the GUI executable (or any path inside the
|
|
53
|
+
* IDE install dir — we read the manifest relative to its directory).
|
|
54
|
+
* @returns The version string, or null if it could not be determined.
|
|
55
|
+
*/
|
|
56
|
+
export function readWin32IdeVersionFromDisk(exePath: string): string | null {
|
|
57
|
+
if (!exePath) return null;
|
|
58
|
+
let exeDir: string;
|
|
59
|
+
try {
|
|
60
|
+
exeDir = fs.statSync(exePath).isDirectory() ? exePath : path.dirname(exePath);
|
|
61
|
+
} catch {
|
|
62
|
+
exeDir = path.dirname(exePath);
|
|
63
|
+
}
|
|
64
|
+
for (const candidate of manifestCandidates(exeDir)) {
|
|
65
|
+
try {
|
|
66
|
+
if (!fs.existsSync(candidate)) continue;
|
|
67
|
+
const version = parseVersionFromManifest(fs.readFileSync(candidate, 'utf-8'));
|
|
68
|
+
if (version) return version;
|
|
69
|
+
} catch {
|
|
70
|
+
/* ignore unreadable manifest */
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* True when `binPath` resolves to a known GUI executable for some IDE.
|
|
78
|
+
*
|
|
79
|
+
* Used as a safety net: any code path about to run `<bin> --version` must skip
|
|
80
|
+
* the spawn when the binary is actually the GUI Electron exe, since that would
|
|
81
|
+
* launch the IDE window. Comparison is case-insensitive on the basename
|
|
82
|
+
* (Windows filesystem semantics) against every provider's `processNames.win32`.
|
|
83
|
+
*
|
|
84
|
+
* @param binPath Resolved binary path that would be exec'd.
|
|
85
|
+
* @param win32ProcessNames Map of provider type → list of GUI exe names
|
|
86
|
+
* (from provider.json `processNames.win32`, e.g. `["Cursor.exe"]`).
|
|
87
|
+
*/
|
|
88
|
+
export function isKnownWin32GuiExe(
|
|
89
|
+
binPath: string | null | undefined,
|
|
90
|
+
win32ProcessNames: Record<string, string[]>,
|
|
91
|
+
): boolean {
|
|
92
|
+
if (!binPath) return false;
|
|
93
|
+
// Use win32 basename semantics regardless of host OS: this matches Windows
|
|
94
|
+
// paths even when the daemon-core test/CI host is POSIX (where `/` is the
|
|
95
|
+
// only separator). On the real win32 target this is identical to basename().
|
|
96
|
+
const base = path.win32.basename(binPath).toLowerCase();
|
|
97
|
+
if (!base.endsWith('.exe')) return false;
|
|
98
|
+
for (const names of Object.values(win32ProcessNames)) {
|
|
99
|
+
for (const name of names) {
|
|
100
|
+
if (typeof name === 'string' && name.toLowerCase() === base) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import * as yaml from 'js-yaml';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* "Change Impact" — config-driven classification of which git changes between the
|
|
7
|
+
* live daemon's build commit and the workspace HEAD actually require a daemon
|
|
8
|
+
* rebuild/restart (vs. a web-only redeploy, vs. nothing).
|
|
9
|
+
*
|
|
10
|
+
* The daemon-core git surface only knows the FACTS (which files / packages changed
|
|
11
|
+
* between buildCommit..HEAD). The POLICY — which packages are daemon-runtime, which
|
|
12
|
+
* are web-only, which root files are non-runtime, and what command to recommend —
|
|
13
|
+
* is declarative config injected from outside. This keeps git-status.ts repo-agnostic
|
|
14
|
+
* while preserving ADHDev's exact built-in behavior when no config is present.
|
|
15
|
+
*
|
|
16
|
+
* SECURITY: config is declarative only. JSON/YAML are parsed; arbitrary JS config
|
|
17
|
+
* (.js) is intentionally NOT supported, so loading a config can never execute code.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** A change-impact classification bucket. */
|
|
21
|
+
export type ChangeImpactKind = 'daemon' | 'web' | 'none';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Recommended action for a given impact classification. `recommendedAction` is the
|
|
25
|
+
* stable classification key (always one of daemon|web|none, NOT config-overridable);
|
|
26
|
+
* config customizes only the human-facing `recommendedCommand` recipe.
|
|
27
|
+
*/
|
|
28
|
+
export interface ChangeImpactTarget {
|
|
29
|
+
/** Human-facing command/recipe to act on the impact (e.g. deploy + restart). */
|
|
30
|
+
recommendedCommand: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ChangeImpactConfig {
|
|
34
|
+
/**
|
|
35
|
+
* Package names (the `<name>` in `packages/<name>/`) whose change means the
|
|
36
|
+
* daemon runtime is stale and must be rebuilt/redeployed + restarted. When
|
|
37
|
+
* provided, this REPLACES the built-in daemon-runtime set.
|
|
38
|
+
*/
|
|
39
|
+
daemonRuntimePackages?: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Package names that are web-only — a change to one does not require a daemon
|
|
42
|
+
* restart, only a web redeploy. When provided, this REPLACES the built-in
|
|
43
|
+
* web-only set.
|
|
44
|
+
*/
|
|
45
|
+
webOnlyPackages?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* Glob patterns for root-level (non-package) files that demonstrably cannot
|
|
48
|
+
* change what the daemon runtime executes (markers, docs, license text). These
|
|
49
|
+
* are added on top of the built-in non-runtime root-file detection.
|
|
50
|
+
*/
|
|
51
|
+
nonRuntimeRootFilePatterns?: string[];
|
|
52
|
+
/** Recommended action/command per impact classification. Missing keys fall back to built-in defaults. */
|
|
53
|
+
impactTargets?: Partial<Record<ChangeImpactKind, ChangeImpactTarget>>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ChangeImpactConfigLoadResult {
|
|
57
|
+
config?: ChangeImpactConfig;
|
|
58
|
+
source: string;
|
|
59
|
+
sourceType: 'repo_file' | 'unavailable' | 'invalid';
|
|
60
|
+
path?: string;
|
|
61
|
+
error?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Stable identity of the config SOURCE, used as part of a cache key so a config
|
|
64
|
+
* edit invalidates any cached impact evaluation. Combines the resolved path and
|
|
65
|
+
* its mtime (or the path for the unavailable/invalid case).
|
|
66
|
+
*/
|
|
67
|
+
sourceKey: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const CHANGE_IMPACT_CONFIG_LOCATIONS = [
|
|
71
|
+
'.adhdev/change-impact.json',
|
|
72
|
+
'.adhdev/change-impact.yaml',
|
|
73
|
+
'.adhdev/change-impact.yml',
|
|
74
|
+
'.adhdev/repo-mesh-change-impact.json',
|
|
75
|
+
'.adhdev/repo-mesh-change-impact.yaml',
|
|
76
|
+
'.adhdev/repo-mesh-change-impact.yml',
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
export const CHANGE_IMPACT_CONFIG_SCHEMA = {
|
|
80
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
81
|
+
title: 'ADHDev Change Impact Config',
|
|
82
|
+
type: 'object',
|
|
83
|
+
additionalProperties: false,
|
|
84
|
+
properties: {
|
|
85
|
+
daemonRuntimePackages: { type: 'array', items: { type: 'string', minLength: 1 } },
|
|
86
|
+
webOnlyPackages: { type: 'array', items: { type: 'string', minLength: 1 } },
|
|
87
|
+
nonRuntimeRootFilePatterns: { type: 'array', items: { type: 'string', minLength: 1 } },
|
|
88
|
+
impactTargets: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
properties: {
|
|
92
|
+
daemon: { $ref: '#/$defs/target' },
|
|
93
|
+
web: { $ref: '#/$defs/target' },
|
|
94
|
+
none: { $ref: '#/$defs/target' },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
$defs: {
|
|
99
|
+
target: {
|
|
100
|
+
type: 'object',
|
|
101
|
+
additionalProperties: false,
|
|
102
|
+
required: ['recommendedCommand'],
|
|
103
|
+
properties: {
|
|
104
|
+
recommendedCommand: { type: 'string', minLength: 1 },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
} as const;
|
|
109
|
+
|
|
110
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
111
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function isStringArray(value: unknown): value is string[] {
|
|
115
|
+
return Array.isArray(value) && value.every(v => typeof v === 'string' && v.length > 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function validateTarget(value: unknown, key: string, errors: string[]): ChangeImpactTarget | undefined {
|
|
119
|
+
if (!isRecord(value)) {
|
|
120
|
+
errors.push(`impactTargets.${key} must be an object`);
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const { recommendedCommand } = value;
|
|
124
|
+
if (typeof recommendedCommand !== 'string' || !recommendedCommand.length) {
|
|
125
|
+
errors.push(`impactTargets.${key}.recommendedCommand must be a non-empty string`);
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
// recommendedAction is the fixed classification key; config supplies only the command.
|
|
129
|
+
for (const k of Object.keys(value)) {
|
|
130
|
+
if (k !== 'recommendedCommand') errors.push(`impactTargets.${key}.${k} is not a recognized field (only recommendedCommand)`);
|
|
131
|
+
}
|
|
132
|
+
return { recommendedCommand };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function validateChangeImpactConfig(raw: unknown, source = 'inline'): { valid: boolean; errors: string[]; config?: ChangeImpactConfig } {
|
|
136
|
+
const errors: string[] = [];
|
|
137
|
+
if (!isRecord(raw)) {
|
|
138
|
+
return { valid: false, errors: [`${source}: config must be an object`] };
|
|
139
|
+
}
|
|
140
|
+
const config: ChangeImpactConfig = {};
|
|
141
|
+
|
|
142
|
+
if (raw.daemonRuntimePackages !== undefined) {
|
|
143
|
+
if (isStringArray(raw.daemonRuntimePackages)) config.daemonRuntimePackages = [...raw.daemonRuntimePackages];
|
|
144
|
+
else errors.push('daemonRuntimePackages must be an array of non-empty strings');
|
|
145
|
+
}
|
|
146
|
+
if (raw.webOnlyPackages !== undefined) {
|
|
147
|
+
if (isStringArray(raw.webOnlyPackages)) config.webOnlyPackages = [...raw.webOnlyPackages];
|
|
148
|
+
else errors.push('webOnlyPackages must be an array of non-empty strings');
|
|
149
|
+
}
|
|
150
|
+
if (raw.nonRuntimeRootFilePatterns !== undefined) {
|
|
151
|
+
if (isStringArray(raw.nonRuntimeRootFilePatterns)) config.nonRuntimeRootFilePatterns = [...raw.nonRuntimeRootFilePatterns];
|
|
152
|
+
else errors.push('nonRuntimeRootFilePatterns must be an array of non-empty strings');
|
|
153
|
+
}
|
|
154
|
+
if (raw.impactTargets !== undefined) {
|
|
155
|
+
if (!isRecord(raw.impactTargets)) {
|
|
156
|
+
errors.push('impactTargets must be an object');
|
|
157
|
+
} else {
|
|
158
|
+
const targets: Partial<Record<ChangeImpactKind, ChangeImpactTarget>> = {};
|
|
159
|
+
for (const key of Object.keys(raw.impactTargets)) {
|
|
160
|
+
if (key !== 'daemon' && key !== 'web' && key !== 'none') {
|
|
161
|
+
errors.push(`impactTargets.${key} is not a recognized impact kind (daemon|web|none)`);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
const target = validateTarget(raw.impactTargets[key], key, errors);
|
|
165
|
+
if (target) targets[key as ChangeImpactKind] = target;
|
|
166
|
+
}
|
|
167
|
+
if (Object.keys(targets).length) config.impactTargets = targets;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Reject unknown top-level keys to catch typos early (mirrors additionalProperties:false).
|
|
171
|
+
for (const key of Object.keys(raw)) {
|
|
172
|
+
if (!['daemonRuntimePackages', 'webOnlyPackages', 'nonRuntimeRootFilePatterns', 'impactTargets'].includes(key)) {
|
|
173
|
+
errors.push(`unknown config key '${key}'`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : undefined };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function parseConfigText(path: string, text: string): unknown {
|
|
181
|
+
if (/\.json$/i.test(path)) return JSON.parse(text);
|
|
182
|
+
return yaml.load(text);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Locate and load the Change Impact config for a repo root. Declarative only —
|
|
187
|
+
* never executes config. Returns a sourceKey suitable for cache invalidation:
|
|
188
|
+
* config path + mtime, or the sentinel for the missing/invalid case.
|
|
189
|
+
*/
|
|
190
|
+
export function loadChangeImpactConfig(repoRoot: string): ChangeImpactConfigLoadResult {
|
|
191
|
+
for (const relative of CHANGE_IMPACT_CONFIG_LOCATIONS) {
|
|
192
|
+
const configPath = join(repoRoot, relative);
|
|
193
|
+
if (!existsSync(configPath)) continue;
|
|
194
|
+
try {
|
|
195
|
+
const text = readFileSync(configPath, 'utf-8');
|
|
196
|
+
let mtimeMs = 0;
|
|
197
|
+
try {
|
|
198
|
+
mtimeMs = statSync(configPath).mtimeMs;
|
|
199
|
+
} catch {
|
|
200
|
+
// Best-effort; fall back to content length so edits still perturb the key.
|
|
201
|
+
mtimeMs = text.length;
|
|
202
|
+
}
|
|
203
|
+
const parsed = parseConfigText(configPath, text);
|
|
204
|
+
const validation = validateChangeImpactConfig(parsed, relative);
|
|
205
|
+
if (!validation.valid) {
|
|
206
|
+
return {
|
|
207
|
+
source: relative,
|
|
208
|
+
sourceType: 'invalid',
|
|
209
|
+
path: configPath,
|
|
210
|
+
error: validation.errors.join('; '),
|
|
211
|
+
sourceKey: `invalid:${configPath}:${mtimeMs}`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
config: validation.config,
|
|
216
|
+
source: relative,
|
|
217
|
+
sourceType: 'repo_file',
|
|
218
|
+
path: configPath,
|
|
219
|
+
sourceKey: `file:${configPath}:${mtimeMs}`,
|
|
220
|
+
};
|
|
221
|
+
} catch (error: any) {
|
|
222
|
+
return {
|
|
223
|
+
source: relative,
|
|
224
|
+
sourceType: 'invalid',
|
|
225
|
+
path: configPath,
|
|
226
|
+
error: error?.message || String(error),
|
|
227
|
+
sourceKey: `error:${configPath}`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
source: 'unavailable',
|
|
233
|
+
sourceType: 'unavailable',
|
|
234
|
+
error: `No change-impact config found. Checked: ${CHANGE_IMPACT_CONFIG_LOCATIONS.join(', ')}`,
|
|
235
|
+
sourceKey: 'unavailable',
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Translate a config glob pattern into a RegExp matched against a forward-slash
|
|
241
|
+
* file path. Supports `**` (any path segments), `*` (any chars except `/`), and
|
|
242
|
+
* `?` (single non-slash char). No brace/character-class expansion — declarative,
|
|
243
|
+
* minimal, predictable. All other characters are matched literally.
|
|
244
|
+
*/
|
|
245
|
+
export function globToRegExp(pattern: string): RegExp {
|
|
246
|
+
let out = '';
|
|
247
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
248
|
+
const ch = pattern[i];
|
|
249
|
+
if (ch === '*') {
|
|
250
|
+
if (pattern[i + 1] === '*') {
|
|
251
|
+
// `**` → any sequence of characters including path separators.
|
|
252
|
+
out += '.*';
|
|
253
|
+
i++;
|
|
254
|
+
// Swallow a trailing slash after `**/` so `**/x` also matches `x`.
|
|
255
|
+
if (pattern[i + 1] === '/') i++;
|
|
256
|
+
} else {
|
|
257
|
+
out += '[^/]*';
|
|
258
|
+
}
|
|
259
|
+
} else if (ch === '?') {
|
|
260
|
+
out += '[^/]';
|
|
261
|
+
} else if ('.+^${}()|[]\\'.includes(ch)) {
|
|
262
|
+
out += '\\' + ch;
|
|
263
|
+
} else {
|
|
264
|
+
out += ch;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return new RegExp(`^${out}$`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface ChangeImpactConfigSuggestion {
|
|
271
|
+
/** A non-executable, declarative config draft a human can save verbatim. */
|
|
272
|
+
suggestedConfig: ChangeImpactConfig;
|
|
273
|
+
/** Per-field human-facing rationale for the proposed classification. */
|
|
274
|
+
notes: string[];
|
|
275
|
+
/** Package directories discovered under `packages/` (and `oss/packages/`). */
|
|
276
|
+
discoveredPackages: { daemon: string[]; web: string[]; unclassified: string[] };
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function listPackageDirs(packagesRoot: string): string[] {
|
|
280
|
+
try {
|
|
281
|
+
return readdirSync(packagesRoot, { withFileTypes: true })
|
|
282
|
+
.filter(entry => entry.isDirectory() && !entry.name.startsWith('.'))
|
|
283
|
+
.map(entry => entry.name);
|
|
284
|
+
} catch {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Inspect a repo's package layout and propose a reasonable, declarative Change
|
|
291
|
+
* Impact config draft. This is heuristic scaffold ONLY — it never executes
|
|
292
|
+
* anything and the draft must be reviewed/saved by a human before it takes
|
|
293
|
+
* effect. The heuristic mirrors ADHDev's own conventions:
|
|
294
|
+
* - `web-*` / `*-web` packages → web-only (web redeploy, no daemon restart)
|
|
295
|
+
* - everything else under packages/ → daemon-runtime (rebuild + restart)
|
|
296
|
+
* - docs/license/marker root files → non-runtime
|
|
297
|
+
* Callers are expected to prune the draft to their actual runtime topology.
|
|
298
|
+
*/
|
|
299
|
+
export function suggestChangeImpactConfig(repoRoot: string): ChangeImpactConfigSuggestion {
|
|
300
|
+
const notes: string[] = [];
|
|
301
|
+
const daemon = new Set<string>();
|
|
302
|
+
const web = new Set<string>();
|
|
303
|
+
const unclassified: string[] = [];
|
|
304
|
+
|
|
305
|
+
const roots = ['packages', join('oss', 'packages')];
|
|
306
|
+
for (const rel of roots) {
|
|
307
|
+
const packagesRoot = join(repoRoot, rel);
|
|
308
|
+
if (!existsSync(packagesRoot)) continue;
|
|
309
|
+
for (const name of listPackageDirs(packagesRoot)) {
|
|
310
|
+
if (/(^web[-.]|[-.]web$)/i.test(name) || /dashboard|frontend|ui$/i.test(name)) {
|
|
311
|
+
web.add(name);
|
|
312
|
+
} else {
|
|
313
|
+
daemon.add(name);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const daemonRuntimePackages = [...daemon].sort();
|
|
319
|
+
const webOnlyPackages = [...web].sort();
|
|
320
|
+
|
|
321
|
+
if (!daemonRuntimePackages.length && !webOnlyPackages.length) {
|
|
322
|
+
notes.push('No packages/ or oss/packages/ directories found — defaulting to an empty draft you should fill in by hand.');
|
|
323
|
+
} else {
|
|
324
|
+
if (daemonRuntimePackages.length) notes.push(`Classified ${daemonRuntimePackages.length} package(s) as daemon-runtime (change → rebuild/redeploy + restart).`);
|
|
325
|
+
if (webOnlyPackages.length) notes.push(`Classified ${webOnlyPackages.length} web-* package(s) as web-only (change → web redeploy, no daemon restart).`);
|
|
326
|
+
notes.push('Heuristic only: confirm each package actually matches its bucket before saving.');
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const nonRuntimeRootFilePatterns = [
|
|
330
|
+
'*.md',
|
|
331
|
+
'docs/**',
|
|
332
|
+
'LICENSE',
|
|
333
|
+
'LICENSE.*',
|
|
334
|
+
'.gitignore',
|
|
335
|
+
];
|
|
336
|
+
notes.push('nonRuntimeRootFilePatterns lists root files that demonstrably cannot change daemon runtime behavior; extend with your repo markers.');
|
|
337
|
+
|
|
338
|
+
const suggestedConfig: ChangeImpactConfig = {
|
|
339
|
+
...(daemonRuntimePackages.length ? { daemonRuntimePackages } : {}),
|
|
340
|
+
...(webOnlyPackages.length ? { webOnlyPackages } : {}),
|
|
341
|
+
nonRuntimeRootFilePatterns,
|
|
342
|
+
impactTargets: {
|
|
343
|
+
daemon: { recommendedCommand: 'rebuild + redeploy the daemon, then restart it' },
|
|
344
|
+
web: { recommendedCommand: 'redeploy the web app (no daemon restart required)' },
|
|
345
|
+
none: { recommendedCommand: 'no action required' },
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
return {
|
|
350
|
+
suggestedConfig,
|
|
351
|
+
notes,
|
|
352
|
+
discoveredPackages: { daemon: daemonRuntimePackages, web: webOnlyPackages, unclassified },
|
|
353
|
+
};
|
|
354
|
+
}
|