@adhdev/daemon-core 0.9.82-rc.48 → 0.9.82-rc.481
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
|
@@ -8,15 +8,79 @@
|
|
|
8
8
|
* 3. How to orchestrate work across nodes
|
|
9
9
|
*
|
|
10
10
|
* The prompt is generated dynamically from the current mesh state.
|
|
11
|
+
*
|
|
12
|
+
* User customization:
|
|
13
|
+
* ~/.adhdev/coordinator-prompts/<cliType>.md — full override
|
|
14
|
+
* ~/.adhdev/coordinator-prompts/<cliType>.append.md — appended to default
|
|
15
|
+
* ~/.adhdev/coordinator-prompts/default.md — full override (any CLI)
|
|
16
|
+
* ~/.adhdev/coordinator-prompts/default.append.md — appended to default (any CLI)
|
|
17
|
+
*
|
|
18
|
+
* CLI-specific files take precedence over default.* files. The override file
|
|
19
|
+
* still gets the node/policy facts substituted via the same {{placeholders}}
|
|
20
|
+
* the daemon understands; an override that doesn't reference them just gets
|
|
21
|
+
* a static prompt, which is also fine.
|
|
11
22
|
*/
|
|
12
23
|
|
|
24
|
+
import * as fs from 'node:fs';
|
|
25
|
+
import * as os from 'node:os';
|
|
26
|
+
import * as path from 'node:path';
|
|
27
|
+
|
|
13
28
|
import type {
|
|
14
29
|
LocalMeshEntry,
|
|
15
30
|
RepoMeshPolicy,
|
|
16
31
|
RepoMeshStatus,
|
|
17
32
|
RepoMeshNodeStatus,
|
|
18
33
|
} from '../repo-mesh-types.js';
|
|
19
|
-
import {
|
|
34
|
+
import { mergeAndNormalizePolicy } from '../repo-mesh-types.js';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Cheap, locally-derived "what just happened" snapshot for the coordinator
|
|
38
|
+
* prompt. Built at launch from the local ledger + work-queue stats — no remote
|
|
39
|
+
* peer probe. Surfaces the gap a fresh coordinator otherwise misses: it can't
|
|
40
|
+
* see recent failures / queue depth until it manually calls mesh_task_history.
|
|
41
|
+
*
|
|
42
|
+
* All fields are optional so callers that have nothing to report (or fail to
|
|
43
|
+
* read the ledger) simply omit the section — the prompt output stays identical
|
|
44
|
+
* to the pre-activity form in that case.
|
|
45
|
+
*/
|
|
46
|
+
export interface CoordinatorRecentActivity {
|
|
47
|
+
/** task_failed entries from the recent window, newest last. */
|
|
48
|
+
recentFailures?: Array<{
|
|
49
|
+
timestamp?: string;
|
|
50
|
+
nodeId?: string;
|
|
51
|
+
/** Short task title/message, already truncated by the caller. */
|
|
52
|
+
summary?: string;
|
|
53
|
+
}>;
|
|
54
|
+
/** Count of task_failed entries inside the recent window. */
|
|
55
|
+
recentFailureCount?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Size of the "recent" window in minutes. Drives the "failed in the last
|
|
58
|
+
* N min" phrasing. Omitted → defaults to 30, matching the prior hardcoded
|
|
59
|
+
* wording so existing callers render identically.
|
|
60
|
+
*/
|
|
61
|
+
windowMinutes?: number;
|
|
62
|
+
/** Pending (unclaimed) tasks in the work queue. */
|
|
63
|
+
pendingTasks?: number;
|
|
64
|
+
/** Assigned-but-not-yet-terminal tasks in the work queue. */
|
|
65
|
+
assignedTasks?: number;
|
|
66
|
+
/** Stalled tasks recorded in the ledger. */
|
|
67
|
+
stalledTasks?: number;
|
|
68
|
+
/** ISO timestamp of the most recent ledger activity, if any. */
|
|
69
|
+
lastActivityAt?: string | null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* One coordinator operating note — a runtime-accumulated lesson (provider
|
|
74
|
+
* quirk, pattern to avoid, recovery lesson) persisted in the ledger so it
|
|
75
|
+
* survives coordinator restarts and is provider-neutral (visible to codex /
|
|
76
|
+
* hermes / antigravity coordinators, not just Claude's memory).
|
|
77
|
+
*/
|
|
78
|
+
export interface CoordinatorOperatingNote {
|
|
79
|
+
text: string;
|
|
80
|
+
category?: 'provider_quirk' | 'pattern_to_avoid' | 'recovery_lesson';
|
|
81
|
+
createdAt?: string;
|
|
82
|
+
sourceCoordinator?: string;
|
|
83
|
+
}
|
|
20
84
|
|
|
21
85
|
// ─── Prompt Builder ─────────────────────────────
|
|
22
86
|
|
|
@@ -25,10 +89,157 @@ export interface CoordinatorPromptContext {
|
|
|
25
89
|
status?: RepoMeshStatus;
|
|
26
90
|
userInstruction?: string;
|
|
27
91
|
coordinatorCliType?: string;
|
|
92
|
+
/**
|
|
93
|
+
* M3: pre-rendered active mission section (from buildMissionPromptSection).
|
|
94
|
+
* Empty/undefined when the mesh has no active mission — the prompt output
|
|
95
|
+
* stays identical to the pre-M3 form in that case.
|
|
96
|
+
*/
|
|
97
|
+
missionSection?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Gap1: recent ledger/queue activity surfaced so a freshly-launched
|
|
100
|
+
* coordinator sees recent failures + queue depth without first calling
|
|
101
|
+
* mesh_task_history. Omitted → no "## Recent Activity" section.
|
|
102
|
+
*/
|
|
103
|
+
recentActivity?: CoordinatorRecentActivity;
|
|
104
|
+
/**
|
|
105
|
+
* Gap2-A: runtime-accumulated operating notes (provider-neutral lessons)
|
|
106
|
+
* read from the ledger at launch. Omitted/empty → no "## Operating Notes"
|
|
107
|
+
* section.
|
|
108
|
+
*/
|
|
109
|
+
operatingNotes?: CoordinatorOperatingNote[];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Compose the final coordinator prompt from four layers, in this precedence:
|
|
114
|
+
*
|
|
115
|
+
* 1. Per-launch `extraSystemPrompt` (always appended, as "## Additional
|
|
116
|
+
* Context"). Never wins as a base — it's launch-scope context.
|
|
117
|
+
* 2. Mesh-level append (`mesh.coordinator.systemPromptAppend` or the legacy
|
|
118
|
+
* `systemPromptSuffix`). Stacks after whichever base won.
|
|
119
|
+
* 3. User-file append (`~/.adhdev/coordinator-prompts/<cli>.append.md` or
|
|
120
|
+
* `default.append.md`). Also stacks; same placeholder expansion as the
|
|
121
|
+
* override path.
|
|
122
|
+
* 4. Base prompt, picked in this order:
|
|
123
|
+
* a. `mesh.coordinator.systemPromptOverride` (mesh-level override)
|
|
124
|
+
* b. user-file override (`~/.adhdev/coordinator-prompts/<cli>.md` or
|
|
125
|
+
* `default.md`)
|
|
126
|
+
* c. daemon default (assembled from identity/nodes/policy/tools/…)
|
|
127
|
+
*
|
|
128
|
+
* That layering lets a user customize prompts at three increasing scopes
|
|
129
|
+
* (machine, mesh, single launch) without losing the daemon's stock rules.
|
|
130
|
+
*/
|
|
131
|
+
/**
|
|
132
|
+
* 6-4: total prompt soft cap. When the assembled prompt exceeds this, we shed
|
|
133
|
+
* the two runtime-accumulated, daemon-generated sections — operating notes
|
|
134
|
+
* first, then recent activity — because they grow unboundedly from the ledger.
|
|
135
|
+
* We NEVER trim user append/override content or the fixed hardcoded sections
|
|
136
|
+
* (identity/nodes/policy/tools/workflow/onboarding/rules): those carry user
|
|
137
|
+
* intent or invariant instructions. If shedding both still overflows, we keep
|
|
138
|
+
* the prompt as-is rather than mangling protected content.
|
|
139
|
+
*/
|
|
140
|
+
const PROMPT_SOFT_CAP_BYTES = 60 * 1024;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Which daemon-generated optional sections to drop from the default base.
|
|
144
|
+
* Used only by the 6-4 soft-cap retry — an override base ignores these
|
|
145
|
+
* because its operating-notes/recent-activity content comes from the user's
|
|
146
|
+
* own {{placeholder}}s and is not ours to trim.
|
|
147
|
+
*/
|
|
148
|
+
interface DefaultPromptDropFlags {
|
|
149
|
+
dropOperatingNotes?: boolean;
|
|
150
|
+
dropRecentActivity?: boolean;
|
|
28
151
|
}
|
|
29
152
|
|
|
30
153
|
export function buildCoordinatorSystemPrompt(ctx: CoordinatorPromptContext): string {
|
|
31
|
-
|
|
154
|
+
// First pass: assemble with everything included.
|
|
155
|
+
let prompt = assembleCoordinatorPrompt(ctx, {});
|
|
156
|
+
if (byteLength(prompt) <= PROMPT_SOFT_CAP_BYTES) return prompt;
|
|
157
|
+
|
|
158
|
+
// Over the soft cap. Only the default base carries daemon-generated
|
|
159
|
+
// operating-notes / recent-activity sections we're allowed to shed; an
|
|
160
|
+
// override base is user content and stays whole. If we're on an override
|
|
161
|
+
// base there's nothing safe to trim, so return the first pass unchanged.
|
|
162
|
+
if (usesOverrideBase(ctx)) return prompt;
|
|
163
|
+
|
|
164
|
+
const shed: string[] = [];
|
|
165
|
+
|
|
166
|
+
// 1) Shed operating notes first.
|
|
167
|
+
prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true });
|
|
168
|
+
shed.push('operating notes');
|
|
169
|
+
if (byteLength(prompt) <= PROMPT_SOFT_CAP_BYTES) {
|
|
170
|
+
return appendTruncationNotice(prompt, shed);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 2) Still over → also shed recent activity.
|
|
174
|
+
prompt = assembleCoordinatorPrompt(ctx, { dropOperatingNotes: true, dropRecentActivity: true });
|
|
175
|
+
shed.push('recent activity');
|
|
176
|
+
return appendTruncationNotice(prompt, shed);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** True when the base prompt is a mesh-level or user-file override (not the daemon default). */
|
|
180
|
+
function usesOverrideBase(ctx: CoordinatorPromptContext): boolean {
|
|
181
|
+
if (ctx.mesh.coordinator?.systemPromptOverride?.trim()) return true;
|
|
182
|
+
return readUserPromptFile(ctx.coordinatorCliType, 'md') !== null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** UTF-8 byte length — the cap is a byte budget, not a code-unit count. */
|
|
186
|
+
function byteLength(s: string): number {
|
|
187
|
+
return Buffer.byteLength(s, 'utf8');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Append a single trailing line recording which daemon-generated sections were
|
|
192
|
+
* shed to fit the soft cap, so the coordinator (and anyone reading the prompt)
|
|
193
|
+
* knows the omission was deliberate, not a data-loss bug.
|
|
194
|
+
*/
|
|
195
|
+
function appendTruncationNotice(prompt: string, shed: string[]): string {
|
|
196
|
+
if (shed.length === 0) return prompt;
|
|
197
|
+
return `${prompt}\n\n_Prompt exceeded the ${Math.floor(PROMPT_SOFT_CAP_BYTES / 1024)}KB soft cap; omitted to fit: ${shed.join(', ')}. Full detail remains in the ledger (\`mesh_task_history\` / \`mesh_record_note\`)._`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function assembleCoordinatorPrompt(ctx: CoordinatorPromptContext, drop: DefaultPromptDropFlags): string {
|
|
201
|
+
const { mesh, userInstruction, coordinatorCliType } = ctx;
|
|
202
|
+
|
|
203
|
+
// ── Pick the base prompt ──
|
|
204
|
+
const meshOverride = mesh.coordinator?.systemPromptOverride?.trim();
|
|
205
|
+
let base: string;
|
|
206
|
+
if (meshOverride) {
|
|
207
|
+
base = expandPromptPlaceholders(meshOverride, ctx);
|
|
208
|
+
} else {
|
|
209
|
+
const userOverride = readUserPromptFile(coordinatorCliType, 'md');
|
|
210
|
+
if (userOverride !== null) {
|
|
211
|
+
base = expandPromptPlaceholders(userOverride, ctx);
|
|
212
|
+
} else {
|
|
213
|
+
base = buildDefaultCoordinatorPrompt(ctx, drop);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const sections: string[] = [base];
|
|
218
|
+
|
|
219
|
+
// ── User-level append runs after whichever base won ──
|
|
220
|
+
const userAppend = readUserPromptFile(coordinatorCliType, 'append.md');
|
|
221
|
+
if (userAppend !== null) {
|
|
222
|
+
sections.push(expandPromptPlaceholders(userAppend, ctx));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── Mesh-level append (prefer the new field, fall back to the legacy alias) ──
|
|
226
|
+
const meshAppend = (mesh.coordinator?.systemPromptAppend
|
|
227
|
+
?? mesh.coordinator?.systemPromptSuffix)?.trim();
|
|
228
|
+
if (meshAppend) {
|
|
229
|
+
sections.push(expandPromptPlaceholders(meshAppend, ctx));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ── Per-launch context lands last so it's the most recent thing the
|
|
233
|
+
// agent reads. Marked as Additional Context, not a rule update. ──
|
|
234
|
+
if (userInstruction) {
|
|
235
|
+
sections.push(`## Additional Context\n${userInstruction}`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return sections.join('\n\n');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function buildDefaultCoordinatorPrompt(ctx: CoordinatorPromptContext, drop: DefaultPromptDropFlags = {}): string {
|
|
242
|
+
const { mesh, status, coordinatorCliType } = ctx;
|
|
32
243
|
const sections: string[] = [];
|
|
33
244
|
|
|
34
245
|
// ── Identity ──
|
|
@@ -46,8 +257,27 @@ Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `\nDefault branch: \`
|
|
|
46
257
|
sections.push('## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.');
|
|
47
258
|
}
|
|
48
259
|
|
|
260
|
+
// ── Active Mission (M3) — only present when one exists ──
|
|
261
|
+
if (ctx.missionSection?.trim()) {
|
|
262
|
+
sections.push(ctx.missionSection.trim());
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// ── Recent Activity (Gap1) — only present when there's something to show.
|
|
266
|
+
// Shed under the 6-4 soft cap (drop.dropRecentActivity). ──
|
|
267
|
+
if (!drop.dropRecentActivity) {
|
|
268
|
+
const recentActivity = buildRecentActivitySection(ctx.recentActivity);
|
|
269
|
+
if (recentActivity) sections.push(recentActivity);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ── Operating Notes (Gap2-A) — only present when notes exist. Shed first
|
|
273
|
+
// under the 6-4 soft cap (drop.dropOperatingNotes). ──
|
|
274
|
+
if (!drop.dropOperatingNotes) {
|
|
275
|
+
const operatingNotes = buildOperatingNotesSection(ctx.operatingNotes);
|
|
276
|
+
if (operatingNotes) sections.push(operatingNotes);
|
|
277
|
+
}
|
|
278
|
+
|
|
49
279
|
// ── Policy ──
|
|
50
|
-
sections.push(buildPolicySection(
|
|
280
|
+
sections.push(buildPolicySection(mergeAndNormalizePolicy(undefined, mesh.policy)));
|
|
51
281
|
|
|
52
282
|
// ── Tools ──
|
|
53
283
|
sections.push(TOOLS_SECTION);
|
|
@@ -58,25 +288,102 @@ Repository: \`${mesh.repoIdentity}\`${mesh.defaultBranch ? `\nDefault branch: \`
|
|
|
58
288
|
// ── Workflow ──
|
|
59
289
|
sections.push(WORKFLOW_SECTION);
|
|
60
290
|
|
|
291
|
+
// ── Onboarding / Reinit ──
|
|
292
|
+
sections.push(ONBOARDING_SECTION);
|
|
293
|
+
|
|
61
294
|
// ── Rules ──
|
|
62
295
|
sections.push(buildRulesSection(coordinatorCliType));
|
|
63
296
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
sections.push(`## Additional Context\n${userInstruction}`);
|
|
67
|
-
}
|
|
297
|
+
return sections.join('\n\n');
|
|
298
|
+
}
|
|
68
299
|
|
|
69
|
-
|
|
70
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Look up a user-customization file under ~/.adhdev/coordinator-prompts/.
|
|
302
|
+
*
|
|
303
|
+
* Lookup order:
|
|
304
|
+
* 1. <cliType>.<suffix> — provider-specific
|
|
305
|
+
* 2. default.<suffix> — shared across providers
|
|
306
|
+
*
|
|
307
|
+
* Returns null when neither exists; an empty/whitespace-only file is also
|
|
308
|
+
* treated as "no override" so users can drop in a stub without affecting
|
|
309
|
+
* behavior. Read errors (permission, IO) are swallowed and logged-as-null
|
|
310
|
+
* intentionally: a broken override file should never block coordinator
|
|
311
|
+
* launch, it should just behave as if the file weren't there.
|
|
312
|
+
*/
|
|
313
|
+
function readUserPromptFile(cliType: string | undefined, suffix: string): string | null {
|
|
314
|
+
const dir = path.join(os.homedir(), '.adhdev', 'coordinator-prompts');
|
|
315
|
+
const candidates: string[] = [];
|
|
316
|
+
if (cliType) candidates.push(path.join(dir, `${cliType}.${suffix}`));
|
|
317
|
+
candidates.push(path.join(dir, `default.${suffix}`));
|
|
318
|
+
for (const p of candidates) {
|
|
319
|
+
try {
|
|
320
|
+
const text = fs.readFileSync(p, 'utf8');
|
|
321
|
+
if (text.trim()) return text;
|
|
322
|
+
} catch { /* missing file is the common case — keep going */ }
|
|
71
323
|
}
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
72
326
|
|
|
73
|
-
|
|
327
|
+
/**
|
|
328
|
+
* Expand `{{placeholder}}` tokens against current mesh state.
|
|
329
|
+
*
|
|
330
|
+
* Tokens we support today:
|
|
331
|
+
* {{meshName}} — mesh.name
|
|
332
|
+
* {{repo}} — mesh.repoIdentity
|
|
333
|
+
* {{defaultBranch}} — mesh.defaultBranch or empty
|
|
334
|
+
* {{cliType}} — coordinator CLI type or empty
|
|
335
|
+
* {{nodes}} — full node section (status if known, otherwise config)
|
|
336
|
+
* {{mission}} — active mission summary section (empty when none)
|
|
337
|
+
* {{recentActivity}} — recent failures + queue depth section (empty when none)
|
|
338
|
+
* {{operatingNotes}} — accumulated operating notes section (empty when none)
|
|
339
|
+
* {{policy}} — full policy section
|
|
340
|
+
* {{tools}} — the canonical tools table
|
|
341
|
+
* {{workflow}} — the canonical orchestration workflow
|
|
342
|
+
* {{onboarding}} — the guided init/reinit onboarding section
|
|
343
|
+
* {{rules}} — the canonical rules section (with coordinatorNote)
|
|
344
|
+
* {{toolExposurePreflight}} — the MCP-missing preflight reminder
|
|
345
|
+
*
|
|
346
|
+
* Unknown tokens are left as-is — that way typos are obvious in the rendered
|
|
347
|
+
* prompt instead of silently disappearing. Tokens are not recursive: an
|
|
348
|
+
* expanded value's own {{...}} content stays literal.
|
|
349
|
+
*/
|
|
350
|
+
function expandPromptPlaceholders(template: string, ctx: CoordinatorPromptContext): string {
|
|
351
|
+
const { mesh, status, coordinatorCliType } = ctx;
|
|
352
|
+
const nodesSection = status?.nodes?.length
|
|
353
|
+
? buildNodeStatusSection(status.nodes)
|
|
354
|
+
: mesh.nodes.length
|
|
355
|
+
? buildNodeConfigSection(mesh)
|
|
356
|
+
: '## Nodes\nNo nodes configured yet. Ask the user to add nodes with `adhdev mesh add-node`.';
|
|
357
|
+
const replacements: Record<string, string> = {
|
|
358
|
+
meshName: mesh.name,
|
|
359
|
+
repo: mesh.repoIdentity,
|
|
360
|
+
defaultBranch: mesh.defaultBranch || '',
|
|
361
|
+
cliType: coordinatorCliType || '',
|
|
362
|
+
nodes: nodesSection,
|
|
363
|
+
mission: ctx.missionSection?.trim() || '',
|
|
364
|
+
recentActivity: buildRecentActivitySection(ctx.recentActivity) || '',
|
|
365
|
+
operatingNotes: buildOperatingNotesSection(ctx.operatingNotes) || '',
|
|
366
|
+
policy: buildPolicySection(mergeAndNormalizePolicy(undefined, mesh.policy)),
|
|
367
|
+
tools: TOOLS_SECTION,
|
|
368
|
+
workflow: WORKFLOW_SECTION,
|
|
369
|
+
onboarding: ONBOARDING_SECTION,
|
|
370
|
+
rules: buildRulesSection(coordinatorCliType),
|
|
371
|
+
toolExposurePreflight: TOOL_EXPOSURE_PREFLIGHT_SECTION,
|
|
372
|
+
};
|
|
373
|
+
return template.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g, (m, key) => {
|
|
374
|
+
return Object.prototype.hasOwnProperty.call(replacements, key) ? replacements[key] : m;
|
|
375
|
+
});
|
|
74
376
|
}
|
|
75
377
|
|
|
76
378
|
// ─── Section Builders ───────────────────────────
|
|
77
379
|
|
|
78
380
|
function buildNodeStatusSection(nodes: RepoMeshNodeStatus[]): string {
|
|
79
|
-
const lines = [
|
|
381
|
+
const lines = [
|
|
382
|
+
'## Current Node Status',
|
|
383
|
+
'',
|
|
384
|
+
'Node labels are display context, not aliases. Use exact `nodeId` values in mesh tool calls; do not invent shorthand names such as M1/M2 unless they are explicitly configured labels.',
|
|
385
|
+
'',
|
|
386
|
+
];
|
|
80
387
|
for (const n of nodes) {
|
|
81
388
|
const healthIcon = n.health === 'online' ? '🟢' :
|
|
82
389
|
n.health === 'dirty' ? '🟡' :
|
|
@@ -85,31 +392,204 @@ function buildNodeStatusSection(nodes: RepoMeshNodeStatus[]): string {
|
|
|
85
392
|
? `sessions: ${n.activeSessions.join(', ')}`
|
|
86
393
|
: 'no active sessions';
|
|
87
394
|
const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : '';
|
|
88
|
-
|
|
89
|
-
|
|
395
|
+
// Render each provider with its detected version when known (T7 visibility)
|
|
396
|
+
// so the coordinator can eyeball a per-node provider-version skew inline —
|
|
397
|
+
// e.g. `claude-cli@1.2.3`. Providers without a reported version render bare.
|
|
398
|
+
const providerVersions = n.providerVersions && typeof n.providerVersions === 'object'
|
|
399
|
+
? n.providerVersions
|
|
400
|
+
: undefined;
|
|
401
|
+
const providersRendered = n.providers?.length
|
|
402
|
+
? n.providers
|
|
403
|
+
.map((p) => {
|
|
404
|
+
const version = providerVersions?.[p];
|
|
405
|
+
return version ? `${p}@${version}` : p;
|
|
406
|
+
})
|
|
407
|
+
.join(', ')
|
|
408
|
+
: '';
|
|
409
|
+
const buildVersion = typeof n.daemonBuildVersion === 'string' && n.daemonBuildVersion
|
|
410
|
+
? `build: ${n.daemonBuildVersion}`
|
|
411
|
+
: '';
|
|
412
|
+
const context = [
|
|
413
|
+
n.daemonId ? `daemon: \`${n.daemonId}\`` : '',
|
|
414
|
+
providersRendered ? `providers: ${providersRendered}` : '',
|
|
415
|
+
buildVersion,
|
|
416
|
+
].filter(Boolean).join(' | ');
|
|
417
|
+
lines.push(`- ${healthIcon} **${n.machineLabel}** (nodeId: \`${n.nodeId}\`)`);
|
|
418
|
+
lines.push(` workspace: \`${n.workspace}\`${context ? ` | ${context}` : ''} | ${branch} | ${sessions}`);
|
|
90
419
|
if (n.error) lines.push(` ⚠️ ${n.error}`);
|
|
420
|
+
const nodePrompt = typeof (n as any).systemPrompt === 'string' ? (n as any).systemPrompt.trim() : '';
|
|
421
|
+
if (nodePrompt) {
|
|
422
|
+
lines.push(` 📌 Node instruction: ${indentFollowing(nodePrompt, ' ')}`);
|
|
423
|
+
}
|
|
91
424
|
}
|
|
92
425
|
return lines.join('\n');
|
|
93
426
|
}
|
|
94
427
|
|
|
95
428
|
function buildNodeConfigSection(mesh: LocalMeshEntry): string {
|
|
96
|
-
const lines = [
|
|
429
|
+
const lines = [
|
|
430
|
+
'## Configured Nodes',
|
|
431
|
+
'',
|
|
432
|
+
'Node labels are display context, not aliases. Use exact `nodeId` values in mesh tool calls; do not invent shorthand names such as M1/M2 unless they are explicitly configured labels.',
|
|
433
|
+
'',
|
|
434
|
+
];
|
|
97
435
|
for (const n of mesh.nodes) {
|
|
98
436
|
const labels: string[] = [];
|
|
99
437
|
if (n.isLocalWorktree) labels.push('worktree');
|
|
100
438
|
if (n.policy?.readOnly) labels.push('read-only');
|
|
101
439
|
const suffix = labels.length ? ` [${labels.join(', ')}]` : '';
|
|
102
|
-
|
|
440
|
+
const explicitMachineLabel = typeof (n as any).machineLabel === 'string' ? (n as any).machineLabel : '';
|
|
441
|
+
const explicitLabel = explicitMachineLabel ? ` label: **${explicitMachineLabel}** |` : '';
|
|
442
|
+
const providerPriority = n.policy?.providerPriority?.length ? ` | providers: ${n.policy.providerPriority.join(', ')}` : '';
|
|
443
|
+
// Per-(node, provider) maxParallel cap. Only maxParallel is enforced by the
|
|
444
|
+
// queue; routing is governed by required_tags, not provider roles.
|
|
445
|
+
const providerRoles = Array.isArray(n.policy?.providerRoles)
|
|
446
|
+
? (n.policy!.providerRoles as Array<{ providerType?: unknown; maxParallel?: unknown }>)
|
|
447
|
+
.map(r => {
|
|
448
|
+
const type = typeof r?.providerType === 'string' ? r.providerType.trim() : '';
|
|
449
|
+
if (!type) return '';
|
|
450
|
+
const cap = Number.isFinite(Number(r?.maxParallel)) ? ` (max ${Math.floor(Number(r.maxParallel))})` : '';
|
|
451
|
+
return `${type}${cap}`;
|
|
452
|
+
})
|
|
453
|
+
.filter(Boolean)
|
|
454
|
+
: [];
|
|
455
|
+
const providerRolesSuffix = providerRoles.length ? ` | caps: ${providerRoles.join(', ')}` : '';
|
|
456
|
+
lines.push(`- ${explicitLabel} nodeId: \`${n.id}\` | workspace: \`${n.workspace}\`${n.daemonId ? ` | daemon: \`${n.daemonId}\`` : ''}${providerPriority}${providerRolesSuffix}${suffix}`);
|
|
457
|
+
const nodePrompt = typeof (n as any).systemPrompt === 'string' ? (n as any).systemPrompt.trim() : '';
|
|
458
|
+
if (nodePrompt) {
|
|
459
|
+
lines.push(` 📌 Node instruction: ${indentFollowing(nodePrompt, ' ')}`);
|
|
460
|
+
}
|
|
103
461
|
}
|
|
104
462
|
lines.push('', '_Use `mesh_status` to probe live health before delegating work._');
|
|
105
463
|
return lines.join('\n');
|
|
106
464
|
}
|
|
107
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Indent every line after the first by `pad`. Used so multi-line node
|
|
468
|
+
* instructions still visually nest under the node bullet without the
|
|
469
|
+
* second line dangling at column zero.
|
|
470
|
+
*/
|
|
471
|
+
function indentFollowing(text: string, pad: string): string {
|
|
472
|
+
const lines = text.split('\n');
|
|
473
|
+
if (lines.length === 1) return lines[0];
|
|
474
|
+
return [lines[0], ...lines.slice(1).map(l => pad + l)].join('\n');
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Gap1 — render the "## Recent Activity" section from the locally-derived
|
|
479
|
+
* activity snapshot. Returns '' (no section) when there's nothing worth
|
|
480
|
+
* surfacing: no recent failures, no queued work, no stalls. This keeps a quiet
|
|
481
|
+
* mesh's prompt identical to the pre-activity form.
|
|
482
|
+
*/
|
|
483
|
+
function buildRecentActivitySection(activity?: CoordinatorRecentActivity): string {
|
|
484
|
+
if (!activity) return '';
|
|
485
|
+
const failures = Array.isArray(activity.recentFailures) ? activity.recentFailures : [];
|
|
486
|
+
const pending = Number.isFinite(activity.pendingTasks) ? Number(activity.pendingTasks) : 0;
|
|
487
|
+
const assigned = Number.isFinite(activity.assignedTasks) ? Number(activity.assignedTasks) : 0;
|
|
488
|
+
const stalled = Number.isFinite(activity.stalledTasks) ? Number(activity.stalledTasks) : 0;
|
|
489
|
+
const recentFailureCount = Number.isFinite(activity.recentFailureCount)
|
|
490
|
+
? Number(activity.recentFailureCount)
|
|
491
|
+
: failures.length;
|
|
492
|
+
const windowMinutes = Number.isFinite(activity.windowMinutes) && Number(activity.windowMinutes) > 0
|
|
493
|
+
? Math.floor(Number(activity.windowMinutes))
|
|
494
|
+
: 30;
|
|
495
|
+
|
|
496
|
+
// Nothing actionable to show → omit the section entirely.
|
|
497
|
+
if (failures.length === 0 && pending === 0 && assigned === 0 && stalled === 0 && recentFailureCount === 0) {
|
|
498
|
+
return '';
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const lines: string[] = ['## Recent Activity', ''];
|
|
502
|
+
lines.push('A snapshot of this mesh\'s recent ledger/queue state at launch. Use it to decide what needs attention first; call `mesh_task_history` / `mesh_view_queue` for full detail.');
|
|
503
|
+
lines.push('');
|
|
504
|
+
|
|
505
|
+
const counts: string[] = [];
|
|
506
|
+
if (pending > 0) counts.push(`**${pending}** pending`);
|
|
507
|
+
if (assigned > 0) counts.push(`**${assigned}** assigned`);
|
|
508
|
+
if (stalled > 0) counts.push(`**${stalled}** stalled`);
|
|
509
|
+
if (recentFailureCount > 0) counts.push(`**${recentFailureCount}** failed in the last ${windowMinutes} min`);
|
|
510
|
+
if (counts.length) lines.push(`- Queue/ledger: ${counts.join(', ')}.`);
|
|
511
|
+
if (activity.lastActivityAt) lines.push(`- Last ledger activity: ${activity.lastActivityAt}.`);
|
|
512
|
+
|
|
513
|
+
if (failures.length > 0) {
|
|
514
|
+
// Newest first, capped to the 5 most recent so the prompt stays lean.
|
|
515
|
+
const recent = failures.slice(-5).reverse();
|
|
516
|
+
lines.push('', 'Recent failures (newest first):');
|
|
517
|
+
for (const f of recent) {
|
|
518
|
+
const when = f.timestamp ? `${f.timestamp} ` : '';
|
|
519
|
+
const node = f.nodeId ? `node \`${f.nodeId}\`` : 'unknown node';
|
|
520
|
+
const summary = (f.summary || '').trim();
|
|
521
|
+
lines.push(`- ${when}${node}${summary ? ` — ${summary}` : ''}`);
|
|
522
|
+
}
|
|
523
|
+
lines.push('', '_Check `mesh_task_history` before retrying; repeated failures on the same node mean reassign or escalate, not retry._');
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
return lines.join('\n');
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Gap2-A — render the "## Operating Notes" section from accumulated coordinator
|
|
531
|
+
* notes. Returns '' when there are none, so a mesh that has never recorded a
|
|
532
|
+
* note gets the unchanged prompt. Notes are runtime-accumulated lessons that
|
|
533
|
+
* persist across coordinator restarts and are provider-neutral.
|
|
534
|
+
*/
|
|
535
|
+
/**
|
|
536
|
+
* 6-4 prompt-build caps for the Operating Notes section. These bound how much
|
|
537
|
+
* of the ledger rides into every coordinator prompt — the ledger itself keeps
|
|
538
|
+
* more (keep-latest 100 prune lives in mesh-ledger.ts); this is a separate,
|
|
539
|
+
* tighter cap applied only when composing the prompt.
|
|
540
|
+
*/
|
|
541
|
+
const OPERATING_NOTES_PROMPT_CAP = 20;
|
|
542
|
+
const OPERATING_NOTE_MAX_CHARS = 300;
|
|
543
|
+
|
|
544
|
+
function buildOperatingNotesSection(notes?: CoordinatorOperatingNote[]): string {
|
|
545
|
+
const valid = Array.isArray(notes)
|
|
546
|
+
? notes.filter(n => n && typeof n.text === 'string' && n.text.trim())
|
|
547
|
+
: [];
|
|
548
|
+
if (valid.length === 0) return '';
|
|
549
|
+
|
|
550
|
+
const categoryLabel: Record<string, string> = {
|
|
551
|
+
provider_quirk: 'provider quirk',
|
|
552
|
+
pattern_to_avoid: 'pattern to avoid',
|
|
553
|
+
recovery_lesson: 'recovery lesson',
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
// Keep only the most recent OPERATING_NOTES_PROMPT_CAP notes in the prompt.
|
|
557
|
+
// `valid` is oldest-first (ledger order), so the newest are at the tail.
|
|
558
|
+
const omittedCount = Math.max(0, valid.length - OPERATING_NOTES_PROMPT_CAP);
|
|
559
|
+
const shown = omittedCount > 0 ? valid.slice(-OPERATING_NOTES_PROMPT_CAP) : valid;
|
|
560
|
+
|
|
561
|
+
const lines: string[] = ['## Operating Notes', ''];
|
|
562
|
+
lines.push('Lessons earlier coordinators on this mesh recorded via `mesh_record_note`. Treat them as accumulated operating knowledge — apply them. When you learn a durable lesson (a provider quirk, a pattern to avoid, a recovery lesson), record it with `mesh_record_note` so future coordinators inherit it.');
|
|
563
|
+
lines.push('');
|
|
564
|
+
for (const n of shown) {
|
|
565
|
+
const cat = n.category && categoryLabel[n.category] ? `[${categoryLabel[n.category]}] ` : '';
|
|
566
|
+
lines.push(`- ${cat}${truncateNote(n.text.trim())}`);
|
|
567
|
+
}
|
|
568
|
+
if (omittedCount > 0) {
|
|
569
|
+
lines.push('');
|
|
570
|
+
lines.push(`_${omittedCount} older note${omittedCount === 1 ? '' : 's'} omitted (kept in ledger; prune with \`mesh_forget_note\`)._`);
|
|
571
|
+
}
|
|
572
|
+
return lines.join('\n');
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Truncate a single operating note to OPERATING_NOTE_MAX_CHARS, appending an
|
|
577
|
+
* ellipsis marker so the coordinator knows the note was clipped in the prompt
|
|
578
|
+
* (the full text stays in the ledger).
|
|
579
|
+
*/
|
|
580
|
+
function truncateNote(text: string): string {
|
|
581
|
+
if (text.length <= OPERATING_NOTE_MAX_CHARS) return text;
|
|
582
|
+
return `${text.slice(0, OPERATING_NOTE_MAX_CHARS).trimEnd()}… [truncated]`;
|
|
583
|
+
}
|
|
584
|
+
|
|
108
585
|
function buildPolicySection(policy: RepoMeshPolicy): string {
|
|
109
586
|
const rules: string[] = [];
|
|
110
587
|
if (policy.requirePreTaskCheckpoint) rules.push('- Create a git checkpoint **before** starting each task');
|
|
111
588
|
if (policy.requirePostTaskCheckpoint) rules.push('- Create a git checkpoint **after** each task completes');
|
|
112
589
|
if (policy.requireApprovalForPush) rules.push('- **Ask for user approval** before pushing to remote');
|
|
590
|
+
if (policy.allowAutoPublishSubmoduleMainCommits) {
|
|
591
|
+
rules.push('- Refinery may auto-publish unreachable submodule gitlink commits to submodule origin/main with non-force pushes after validation and patch-equivalence pass');
|
|
592
|
+
}
|
|
113
593
|
if (policy.requireApprovalForDestructiveGit) rules.push('- **Ask for user approval** before destructive git operations (force push, reset, etc.)');
|
|
114
594
|
|
|
115
595
|
const dirtyBehavior = {
|
|
@@ -135,17 +615,44 @@ const TOOLS_SECTION = `## Available Tools
|
|
|
135
615
|
| \`mesh_queue_cancel\` | Cancel a queue task without deleting audit history |
|
|
136
616
|
| \`mesh_queue_requeue\` | Return a task to pending for retry; clears stale session targets |
|
|
137
617
|
| \`mesh_send_task\` | Legacy push: enqueue a task targeted at a specific node |
|
|
618
|
+
| \`mesh_mission_upsert\` | Create/update a persistent mission so a multi-task plan survives coordinator restarts; set status completed/abandoned when the outcome is decided |
|
|
619
|
+
| \`mesh_mission_list\` | List every mission with goal, status, and live task progress — the authority for "what work remains" (never hidden by status) |
|
|
138
620
|
| \`mesh_launch_session\` | Start a new agent session on a node |
|
|
139
621
|
| \`mesh_read_chat\` | Read recent chat messages from a delegated agent session |
|
|
140
622
|
| \`mesh_read_debug\` | Collect a daemon-side chat/parser debug bundle for a session |
|
|
141
623
|
| \`mesh_task_history\` | Read the task ledger — dispatches, completions, failures. Use to understand what has been done before deciding next steps |
|
|
624
|
+
| \`mesh_ledger_query\` | Read-only ledger query along the kind/time/node axes (complement to task-axis mesh_task_history): filter by kind, since, node, tail — answer "what happened on node X / what failed since T" without scanning transcripts |
|
|
625
|
+
| \`mesh_reconcile_ledger\` | Reconcile daemon-local ledgers over P2P — import missing entries from remote nodes into the coordinator local ledger |
|
|
626
|
+
| \`mesh_requeue_held_events\` | Restore recoverable held coordinator events (T6 quarantine / pending-trim) back to the pending queue; lossless, no double-requeue |
|
|
627
|
+
| \`mesh_wait_events\` | Long-poll blocking wait for coordinator events (worker completions/approvals/nudges) up to timeoutMs — drains immediately if any are pending, else blocks until they arrive. Use this instead of busy-polling mesh_status/mesh_view_queue after dispatching work |
|
|
628
|
+
| \`mesh_review_inbox\` | List local worktree nodes needing human review — merge candidates and Refinery-blocked results with evidence/diff summaries |
|
|
629
|
+
| \`mesh_record_note\` | Record a durable, provider-neutral operating note (provider quirk / pattern to avoid / recovery lesson). Future coordinators see it under "## Operating Notes" at launch |
|
|
630
|
+
| \`mesh_forget_note\` | Retract a stale/wrong operating note by note_id or exact text so it stops riding into future coordinators' prompts (append-only tombstone; history preserved) |
|
|
142
631
|
| \`mesh_git_status\` | Check git status on a specific node |
|
|
632
|
+
| \`mesh_read_node_logs\` | Fetch a remote node's daemon log tail directly over P2P (grep/since/byte-bounded, secrets redacted) — no session/PowerShell needed to debug a node's daemon |
|
|
633
|
+
| \`mesh_fast_forward_node\` | Safely dry-run or explicitly execute an obvious clean fast-forward without launching an agent session |
|
|
634
|
+
| \`mesh_restart_daemon\` | Update a node's daemon to the latest published version on its channel and restart it (the dashboard "preview update" path, as a mesh command) |
|
|
143
635
|
| \`mesh_checkpoint\` | Create a git checkpoint on a node |
|
|
144
636
|
| \`mesh_approve\` | Approve/reject a pending agent action |
|
|
637
|
+
| \`mesh_list_pending_approvals\` | List every session across the mesh awaiting an approval decision (the approval inbox) — read-only; enumerate all blocked sessions at once, then drive a mesh_approve for each |
|
|
145
638
|
| \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
|
|
146
639
|
| \`mesh_refine_node\` | Validate and merge a completed worktree node back into its base branch |
|
|
640
|
+
| \`mesh_refine_batch\` | Batch Refinery: converge multiple sibling worktree nodes onto the base branch in one conflict-aware sequential pipeline |
|
|
641
|
+
| \`mesh_refine_plan\` | Dry-run Refinery plan for a worktree node — config source, validation commands, merge/cleanup intent — without executing validation or git merge |
|
|
642
|
+
| \`mesh_refine_config\` | Refinery config helper (read-only) — unified entry for schema/validate/suggest via a required \`mode\` |
|
|
643
|
+
| \`mesh_change_impact_config\` | Change Impact config helper — unified entry for schema/validate/suggest via a required \`mode\` |
|
|
147
644
|
| \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |
|
|
148
|
-
| \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node
|
|
645
|
+
| \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |
|
|
646
|
+
| \`mesh_prune_stale_direct\` | Prune orphaned staleDirect dispatch records (dry-run by default); live/pending work and audit history preserved |
|
|
647
|
+
| \`mesh_init\` | Guided onboarding for a fresh repo: dry-run scan → suggest \`.adhdev/*\` configs (refine/bootstrap/change-impact) + providerPriority + current-config echo; gated write on approval |
|
|
648
|
+
| \`mesh_reinit\` | Re-onboard an already-configured repo: re-suggest with overwrite semantics + current-vs-suggested diff; dry-run preview first, per-section approval before write |
|
|
649
|
+
| \`mesh_write_mesh_json_config\` | Gated write of \`.adhdev/mesh.json\` (repo coordinator-prompt config) from the mesh entry — dry-run/overwrite like mesh_init |
|
|
650
|
+
| \`mesh_magi_review\` | Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers) instead of a single worker |
|
|
651
|
+
| \`mesh_magi_collect\` | Collect + synthesize a previously dispatched MAGI fan-out by its consensus group id (async companion to mesh_magi_review wait:false) |
|
|
652
|
+
| \`mesh_magi_panel_set\` | Upsert a named MAGI panel (standing set of independent node×provider members) into machine-local config |
|
|
653
|
+
| \`mesh_magi_panel_list\` | List configured MAGI panels and resolve each member's availability against the current mesh (read-only) |
|
|
654
|
+
| \`mesh_magi_kind_panel_set\` | Bind a task_kind → MAGI kind-panel slots (machine-local, wholesale replacement — approve current-vs-new first) |
|
|
655
|
+
| \`mesh_magi_kind_panel_list\` | List configured task_kind → MAGI kind-panel slot bindings (machine-local, read-only) |`;
|
|
149
656
|
|
|
150
657
|
const TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
|
|
151
658
|
|
|
@@ -154,17 +661,17 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
154
661
|
const WORKFLOW_SECTION = `## Orchestration Workflow
|
|
155
662
|
|
|
156
663
|
1. **Assess** — Call \`mesh_status\` to see which nodes are healthy and available. Check \`mesh_task_history\` to understand what has already been done in this mesh — previous delegations, completions, and failures.
|
|
157
|
-
2. **Plan** — Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist. If \`mesh_task_history\` shows a recent failure for a task, decide whether to retry or reassign.
|
|
664
|
+
2. **Plan** — Decompose the user's request into independent tasks for parallel execution, or sequential tasks when dependencies exist. If \`mesh_task_history\` shows a recent failure for a task, decide whether to retry or reassign. **For multi-task work, create a mission first**: call \`mesh_mission_upsert\` with a title and goal, then attach every enqueued task with \`mission_id\`. Express "B after A" ordering with \`depends_on\` on the queue task instead of waiting and polling — the system claims dependents automatically when their dependencies complete. When the mission's outcome is decided, update its status (\`completed\`/\`abandoned\`) via \`mesh_mission_upsert\`. If the prompt already shows an **Active Mission**, continue it from its current task state — do not re-enqueue tasks that already exist.
|
|
158
665
|
3. **Queue / Delegate** — The Mesh uses an autonomous pull-based Work Queue:
|
|
159
666
|
a. **General Tasks**: Enqueue tasks using \`mesh_enqueue_task\`. Idle node agents will automatically pull tasks from the queue and begin working.
|
|
160
667
|
b. **Node Preparation**: Reuse an existing idle session on the correct node/provider before launching a new chat/session. Call \`mesh_launch_session\` only when no suitable session exists, when the user explicitly asks for a fresh provider/session, or when branch/worktree isolation requires it. If you need branch isolation for parallel work, call \`mesh_clone_node\` to create a worktree node first.
|
|
161
668
|
c. **Targeted Tasks**: Use \`mesh_send_task\` only when you need to bypass the queue and force a specific node to execute a task immediately.
|
|
162
669
|
d. For the first dispatch of a new task, provide a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
|
|
163
670
|
e. For a continuation of the same issue in an existing session, send a concise **delta instruction**: current verified state, the exact failed/blocked step, the newly approved action, and final reporting requirements. Do not resend the full original task or open a new chat solely to continue the same work; that wastes coordinator and worker context.
|
|
164
|
-
4. **Monitor** — Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly.
|
|
671
|
+
4. **Monitor** — Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`. **Proactively parallelize new work.** When the user reports a new bug or asks for new work, start it immediately if it is independent of in-flight tasks and there is headroom under \`maxParallelTasks\` — do not wait for a current task to finish or for the user to prompt you to parallelize. Read-only diagnosis (\`live_debug_readonly\`) has no isolation or merge cost, so dispatch it in parallel right away. The no-polling / concurrency-limit rules constrain *re-checking or duplicating already-dispatched work*; they are **not** a reason to defer starting a new, independent task.
|
|
165
672
|
5. **Verify** — When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
166
673
|
6. **Checkpoint** — Call \`mesh_checkpoint\` to save the work.
|
|
167
|
-
7. **Converge branches** — Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary and \`mesh_refine_node\` for clean worktree branches when safe. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
674
|
+
7. **Converge branches** — Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`; unless \`allowAutoPublishSubmoduleMainCommits\` is explicitly enabled and Refinery reports successful non-force publish plus post-publish verification, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`. Do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
168
675
|
8. **Clean up** — Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
169
676
|
9. **Report** — Summarize what was done, what changed, any issues, and the branch convergence state.
|
|
170
677
|
|
|
@@ -181,6 +688,29 @@ Follow these recovery rules:
|
|
|
181
688
|
3. **If no recovery context**: The stop may be intentional (normal completion). Use \`mesh_read_chat\` once to verify, then move on.
|
|
182
689
|
4. **Always record what happened**: After handling a failure, briefly note the outcome in your report to the user.`;
|
|
183
690
|
|
|
691
|
+
const ONBOARDING_SECTION = `## Onboarding / Reinit
|
|
692
|
+
|
|
693
|
+
When the user asks to **set up / configure / onboard** this repo for Repo Mesh (or to **re-init / reconfigure** an already-onboarded repo), run ONE guided, approval-gated conversation. You draft, the user approves, the daemon writes. Never auto-write a heuristic suggestion without an explicit user approval turn.
|
|
694
|
+
|
|
695
|
+
**Save scopes — label every draft with its scope before asking for approval:**
|
|
696
|
+
- **repo-file (commit target)** — \`.adhdev/refine.json\`, \`.adhdev/worktree_bootstrap.json\`, \`.adhdev/change-impact.json\`, \`.adhdev/mesh.json\`. These are committed to the repository and shared with every machine/contributor.
|
|
697
|
+
- **machine-local** — MAGI kind→panel bindings and named MAGI panels, node providerPriority (\`~/.adhdev/meshes.json\`). These stay on this machine and are NOT committed.
|
|
698
|
+
|
|
699
|
+
**Guided sequence:**
|
|
700
|
+
1. **Scan (dry-run)** — Call \`mesh_init\` (write=false, the default). It returns per-domain suggested configs for refine / worktree_bootstrap / change-impact, a recommended providerPriority, AND \`currentConfig\` — the currently-saved config per domain (repo files + machine-local \`magiKindPanels\`). Nothing is written.
|
|
701
|
+
2. **Present drafts** — For each domain, show the user the suggested config with its **save scope label** (repo-file vs machine-local). When \`currentConfig\` already has a saved value for a domain (init on a partially-onboarded repo, or any reinit), present a **current-vs-suggested diff**, not just the suggestion.
|
|
702
|
+
3. **Approve → gated write** — Only after the user approves, call the matching gated-write tool:
|
|
703
|
+
- repo \`.adhdev/*\` config files → \`mesh_init\` with \`write=true\` (and \`overwrite=true\` ONLY for domains the user approved replacing).
|
|
704
|
+
- \`.adhdev/mesh.json\` (coordinator prompt / operating notes) → \`mesh_write_mesh_json_config\` (write=true, overwrite only if approved).
|
|
705
|
+
- machine-local MAGI kind→panel slots → \`mesh_magi_kind_panel_set\` (write=true). NOTE: a kind binding is a **wholesale replacement** of that kind's slot list — present the current-vs-new slots first.
|
|
706
|
+
- machine-local named MAGI panels → \`mesh_magi_panel_set\`. providerPriority → apply via node policy update.
|
|
707
|
+
|
|
708
|
+
**init vs reinit:**
|
|
709
|
+
- **\`mesh_init\`** — for a fresh, never-onboarded repo. Existing config files are kept (existing-wins) unless the user explicitly approves overwrite. Use for first-time setup.
|
|
710
|
+
- **\`mesh_reinit\`** — for a repo that is already onboarded and needs its config refreshed. It re-suggests with OVERWRITE semantics and returns the current-vs-suggested \`currentConfig\` echo. Its first call is a DRY-RUN preview: you MUST present the per-section current-vs-suggested diff and get EXPLICIT per-section approval before re-invoking with write=true. Overwrite is a wholesale replacement, so it silently drops operator hand-edits if you skip the diff — never do that.
|
|
711
|
+
|
|
712
|
+
`;
|
|
713
|
+
|
|
184
714
|
function buildRulesSection(coordinatorCliType?: string): string {
|
|
185
715
|
const coordinatorNote = coordinatorCliType
|
|
186
716
|
? `\n- **Coordinator runtime is not a delegation default.** This coordinator is running as \`${coordinatorCliType}\`, but delegated node sessions must follow the user's requested provider, not the coordinator's own runtime.`
|
|
@@ -188,19 +718,27 @@ function buildRulesSection(coordinatorCliType?: string): string {
|
|
|
188
718
|
|
|
189
719
|
return `## Rules
|
|
190
720
|
|
|
191
|
-
- **
|
|
192
|
-
- **
|
|
193
|
-
- **
|
|
194
|
-
- **
|
|
195
|
-
- **
|
|
196
|
-
- **
|
|
197
|
-
- **
|
|
198
|
-
- **
|
|
199
|
-
- **
|
|
200
|
-
- **
|
|
201
|
-
- **
|
|
202
|
-
- **
|
|
203
|
-
- **
|
|
204
|
-
- **
|
|
205
|
-
- **
|
|
721
|
+
- **Route, don't implement.** Delegate all code reading, analysis, and execution to node agents. Never read source files or run commands in the coordinator — keep context lean.
|
|
722
|
+
- **Front-load task messages.** Include everything the agent needs (files, problem, expected fix) in \`mesh_enqueue_task\` / \`mesh_send_task\`. Append a structured result request at the end: ask the worker to conclude with a JSON block containing \`status\`, \`changedFiles\`, \`gitStatus\`, \`validationResults\`, \`errors\`, \`nextAction\`. The daemon parses this automatically; you can read it from \`mesh_task_history\`.
|
|
723
|
+
- **Reuse idle sessions.** For follow-up, retry, commit/push, or cleanup on the same issue, send only the delta to the existing idle session. Start fresh only for independent work, provider mismatch, transcript contamination, or required worktree isolation.
|
|
724
|
+
- **Respect explicit provider requests.** Map: Hermes → \`hermes-cli\`, Claude/Claude Code → \`claude-cli\`, Codex → \`codex-cli\`, Gemini → \`gemini-cli\`, Antigravity → \`antigravity-cli\`. Never substitute the coordinator's own runtime.
|
|
725
|
+
- **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
|
|
726
|
+
- **Limit parallelism.** Start with 1–2 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load — it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
|
|
727
|
+
- **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
|
|
728
|
+
- **Sequence shared-base-moving merges.** Parallel dispatch is encouraged, but merging one worktree can advance another in-flight worktree's base — especially a shared submodule pointer — turning a clean fast-forward into a diverged rebase (patch-equivalence correctly blocks this). Before merging an in-flight worktree while siblings are also in flight, land in an intentional order, re-clone long-running worktrees from the advanced base, or expect to manually rebase + ff-only the laggards; merging an independent fix mid-flight can strand siblings into a rebase.
|
|
729
|
+
- **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
|
|
730
|
+
- **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
|
|
731
|
+
- **Submodule reachability = publish-needed.** \`submodule_reachability_failed\` → classify as \`blocked_review\`, request user approval to push to submodule main, then rerun \`mesh_refine_node\`.
|
|
732
|
+
- **Honor per-node instructions.** When a node carries a 📌 Node instruction in the nodes section, include the relevant parts of that instruction in the task message you send to that node. Don't paraphrase the instruction into your own words — quote it verbatim so the worker agent sees exactly what the user wrote.
|
|
733
|
+
- **Mission status does not update itself.** When a mission's tasks are all done or the work is abandoned, explicitly call \`mesh_mission_upsert\` to set status \`completed\` or \`abandoned\`. Never leave a finished mission in \`active\`. All-cancelled tasks with no further work → \`abandoned\`.
|
|
734
|
+
- **Never fabricate tool results.** Always call the actual tool.
|
|
735
|
+
- **Keep the user informed.** One or two sentences after each delegation round.${coordinatorNote}
|
|
736
|
+
|
|
737
|
+
### Task Messaging Requirements
|
|
738
|
+
|
|
739
|
+
When you compose the task message you dispatch to a node, include these requirements so the worker follows repo conventions the daemon can't enforce for it:
|
|
740
|
+
|
|
741
|
+
- **OSS English commits.** If a task commits anything under \`oss/\` (an AGPL public repo whose history external contributors read), tell the worker explicitly that commit messages in \`oss/\` MUST be English. Root-level commits (proprietary packages) may use any language.
|
|
742
|
+
- **Scoped test runs.** For a validation or code-change task, instruct the worker to run only the tests covering the changed files (\`vitest run <path>\` or \`-t <name>\`), not the whole suite. Run the full suite only when the task is explicitly a full-suite gate — a broad daemon-core run is minutes of wall-clock and the biggest source of worker slowness.
|
|
743
|
+
- **Branch convergence state.** For a worktree task, require the completion report to classify the touched branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. A task that ends on a non-main branch is not complete unless the report names that state and the next step.`;
|
|
206
744
|
}
|