create-walle 0.10.2 → 0.10.3
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/README.md +3 -1
- package/lib/release-schema.json +2 -2
- package/lib/runtime-closure-policy.json +8 -7
- package/package.json +1 -1
- package/template/coding-task-manager/api-prompts.js +45 -7
- package/template/coding-task-manager/bin/claude-hook.js +55 -1
- package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/memory-census.js +4 -2
- package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
- package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
- package/template/coding-task-manager/db.js +156 -32
- package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
- package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
- package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
- package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
- package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
- package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
- package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
- package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
- package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
- package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
- package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
- package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
- package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
- package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
- package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
- package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
- package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
- package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
- package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
- package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
- package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
- package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
- package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
- package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
- package/template/coding-task-manager/lib/agent-definitions.js +19 -0
- package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
- package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
- package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
- package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
- package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
- package/template/coding-task-manager/lib/agent-presets.js +84 -1
- package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
- package/template/coding-task-manager/lib/agent-version-service.js +74 -11
- package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
- package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
- package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
- package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
- package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
- package/template/coding-task-manager/lib/api/fleet.js +118 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +9 -1
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- package/template/coding-task-manager/lib/api/machines.js +691 -2
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/session-attach.js +623 -0
- package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
- package/template/coding-task-manager/lib/api/sessions.js +77 -51
- package/template/coding-task-manager/lib/api/setup-network.js +544 -16
- package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
- package/template/coding-task-manager/lib/api/setup.js +829 -10
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
- package/template/coding-task-manager/lib/auth-rules.js +292 -21
- package/template/coding-task-manager/lib/background-stop.js +369 -0
- package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
- package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
- package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
- package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
- package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
- package/template/coding-task-manager/lib/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
- package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
- package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
- package/template/coding-task-manager/lib/conversation-sync.js +355 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
- package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
- package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
- package/template/coding-task-manager/lib/db-domains.js +1 -0
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
- package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +4 -0
- package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
- package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
- package/template/coding-task-manager/lib/fleet-hub.js +762 -0
- package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
- package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
- package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
- package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
- package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
- package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
- package/template/coding-task-manager/lib/fleet-update.js +798 -0
- package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
- package/template/coding-task-manager/lib/fs-watcher.js +58 -42
- package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
- package/template/coding-task-manager/lib/headless-term-service.js +84 -8
- package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
- package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
- package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
- package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
- package/template/coding-task-manager/lib/host-handoff.js +16 -19
- package/template/coding-task-manager/lib/host-stats.js +150 -3
- package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
- package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
- package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
- package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
- package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
- package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
- package/template/coding-task-manager/lib/hub-bridge.js +398 -0
- package/template/coding-task-manager/lib/idle-notify.js +491 -0
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
- package/template/coding-task-manager/lib/instance-manifest.js +5 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
- package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
- package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
- package/template/coding-task-manager/lib/landing/config.js +536 -0
- package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
- package/template/coding-task-manager/lib/landing/gate.js +360 -0
- package/template/coding-task-manager/lib/landing/git.js +344 -0
- package/template/coding-task-manager/lib/landing/lease.js +247 -0
- package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
- package/template/coding-task-manager/lib/landing/proof.js +223 -0
- package/template/coding-task-manager/lib/landing/queue.js +998 -0
- package/template/coding-task-manager/lib/landing/radar.js +489 -0
- package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
- package/template/coding-task-manager/lib/landing/state.js +263 -0
- package/template/coding-task-manager/lib/landing/stop.js +49 -0
- package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
- package/template/coding-task-manager/lib/landing/sync.js +456 -0
- package/template/coding-task-manager/lib/landing/train.js +885 -0
- package/template/coding-task-manager/lib/landing/window.js +57 -0
- package/template/coding-task-manager/lib/launch-environment.js +121 -0
- package/template/coding-task-manager/lib/launch-model-override.js +36 -10
- package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
- package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
- package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
- package/template/coding-task-manager/lib/lead-model-options.js +160 -3
- package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
- package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
- package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
- package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
- package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
- package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
- package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
- package/template/coding-task-manager/lib/machine-registry.js +750 -5
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
- package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
- package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
- package/template/coding-task-manager/lib/memory-join.js +337 -0
- package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
- package/template/coding-task-manager/lib/memory-sync.js +565 -0
- package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
- package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
- package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
- package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
- package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
- package/template/coding-task-manager/lib/model-availability.js +727 -0
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
- package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
- package/template/coding-task-manager/lib/model-id-rule.js +19 -0
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
- package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
- package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
- package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
- package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
- package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +6 -4
- package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
- package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
- package/template/coding-task-manager/lib/opencode-cli.js +480 -0
- package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
- package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
- package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
- package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
- package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
- package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
- package/template/coding-task-manager/lib/perf-summary.js +7 -0
- package/template/coding-task-manager/lib/perf-tracker.js +63 -2
- package/template/coding-task-manager/lib/project-config.js +7 -0
- package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- package/template/coding-task-manager/lib/read-pool-client.js +89 -2
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
- package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
- package/template/coding-task-manager/lib/relay-client.js +57 -3
- package/template/coding-task-manager/lib/relink-audit.js +34 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
- package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
- package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
- package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
- package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
- package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
- package/template/coding-task-manager/lib/restart-guard.js +18 -6
- package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
- package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
- package/template/coding-task-manager/lib/resume-admission.js +17 -3
- package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
- package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
- package/template/coding-task-manager/lib/runtime-contract.js +3 -1
- package/template/coding-task-manager/lib/schema-indexes.js +1 -0
- package/template/coding-task-manager/lib/session-context-locator.js +742 -0
- package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
- package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
- package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
- package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
- package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
- package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
- package/template/coding-task-manager/lib/session-create/response.js +7 -7
- package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
- package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
- package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
- package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
- package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
- package/template/coding-task-manager/lib/session-empty.js +13 -10
- package/template/coding-task-manager/lib/session-host-manager.js +60 -0
- package/template/coding-task-manager/lib/session-jobs.js +3 -1
- package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
- package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
- package/template/coding-task-manager/lib/session-park.js +738 -0
- package/template/coding-task-manager/lib/session-path-grant.js +13 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
- package/template/coding-task-manager/lib/session-transport.js +17 -0
- package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
- package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
- package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
- package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
- package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
- package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
- package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
- package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
- package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
- package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
- package/template/coding-task-manager/lib/submission-ack.js +90 -2
- package/template/coding-task-manager/lib/systemd-scope.js +115 -0
- package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
- package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
- package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
- package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
- package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
- package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
- package/template/coding-task-manager/lib/transcript-source.js +36 -4
- package/template/coding-task-manager/lib/transcript-store.js +9 -0
- package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
- package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
- package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
- package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
- package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
- package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
- package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
- package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
- package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
- package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
- package/template/coding-task-manager/lib/walle/turn.js +1 -1
- package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
- package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
- package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
- package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
- package/template/coding-task-manager/lib/walle-row-history.js +495 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
- package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
- package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
- package/template/coding-task-manager/lib/ws/misc.js +1 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
- package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
- package/template/coding-task-manager/oauth-proxy.js +112 -115
- package/template/coding-task-manager/package-lock.json +10 -94
- package/template/coding-task-manager/package.json +4 -3
- package/template/coding-task-manager/protocol/message-table.json +10 -0
- package/template/coding-task-manager/protocol/messages.js +10 -0
- package/template/coding-task-manager/protocol/ws-schema.json +20 -0
- package/template/coding-task-manager/protocol/ws-schema.md +2 -0
- package/template/coding-task-manager/public/css/app.css +170 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +473 -243
- package/template/coding-task-manager/public/js/agent-command.js +86 -0
- package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
- package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
- package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
- package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
- package/template/coding-task-manager/public/js/background-work.js +196 -27
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
- package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
- package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
- package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
- package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
- package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
- package/template/coding-task-manager/public/js/document-review-links.js +9 -1
- package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
- package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
- package/template/coding-task-manager/public/js/message-renderer.js +4 -3
- package/template/coding-task-manager/public/js/model-picker.js +3 -1
- package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
- package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
- package/template/coding-task-manager/public/js/pasted-content.js +236 -0
- package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
- package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
- package/template/coding-task-manager/public/js/prompts.js +11 -10
- package/template/coding-task-manager/public/js/protocol.js +10 -0
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
- package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
- package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
- package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
- package/template/coding-task-manager/public/js/stream-view.js +6 -5
- package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
- package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
- package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
- package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
- package/template/coding-task-manager/public/js/walle.js +6 -0
- package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
- package/template/coding-task-manager/public/m/app.css +140 -0
- package/template/coding-task-manager/public/m/app.js +507 -68
- package/template/coding-task-manager/public/m/index.html +17 -0
- package/template/coding-task-manager/public/m/machines.js +838 -4
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- package/template/coding-task-manager/public/usage.html +1 -0
- package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
- package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
- package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
- package/template/coding-task-manager/server.js +1950 -11679
- package/template/coding-task-manager/session-integrity.js +64 -4
- package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
- package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
- package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
- package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
- package/template/coding-task-manager/workers/session-host-process.js +5 -5
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +168 -33
- package/template/ctm-relay/lib/protocol.js +14 -1
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/shared/backup-retention.js +82 -0
- package/template/shared/conversation-admission.js +2 -0
- package/template/shared/conversation-provenance.js +3 -7
- package/template/shared/conversation-storage-v2-contract.js +5 -0
- package/template/shared/linked-worktree.js +51 -0
- package/template/shared/macos-fda-target.js +57 -0
- package/template/shared/orphan-parents.js +55 -0
- package/template/shared/release-schema.json +2 -2
- package/template/shared/storage/contract.js +3 -0
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +71 -4
- package/template/wall-e/api-walle.js +21 -1
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
- package/template/wall-e/brain/brain-join.js +859 -0
- package/template/wall-e/brain/brain-sync-membership.js +20 -0
- package/template/wall-e/brain/brain-sync-store.js +131 -77
- package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
- package/template/wall-e/brain/brain-sync-v2.js +578 -0
- package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
- package/template/wall-e/brain/deterministic-id.js +51 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +40 -6
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +23 -7
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +171 -35
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/config/main-loop-exemptions.json +2 -2
- package/template/wall-e/http/admin-api.js +37 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +7 -1
- package/template/wall-e/http/model-admin.js +8 -1
- package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
- package/template/wall-e/http/model-proxy-providers.js +174 -1
- package/template/wall-e/http/model-route-health.js +157 -0
- package/template/wall-e/http/sync-api.js +278 -464
- package/template/wall-e/jobs/job-runner.js +28 -1
- package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
- package/template/wall-e/lib/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
- package/template/wall-e/lib/helper-rules/grade.js +51 -8
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
- package/template/wall-e/lib/helper-rules/store.js +4 -2
- package/template/wall-e/lib/landing-mcp-tools.js +170 -0
- package/template/wall-e/lib/mcp-client-config.js +133 -14
- package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
- package/template/wall-e/lib/mcp-integration.js +58 -13
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
- package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-roles.js +1 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- package/template/wall-e/llm/worker-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +66 -17
- package/template/wall-e/loops/brain-custom-writes.js +19 -0
- package/template/wall-e/loops/ingest.js +17 -1
- package/template/wall-e/loops/think.js +19 -4
- package/template/wall-e/mcp-contract.js +222 -6
- package/template/wall-e/mcp-protocol-contract.js +40 -5
- package/template/wall-e/mcp-server.js +128 -29
- package/template/wall-e/mcp-worker-schemas.js +5 -5
- package/template/wall-e/memory/ctm-context-client.js +85 -0
- package/template/wall-e/memory/ctm-session-context.js +9 -3
- package/template/wall-e/memory/hub-bridge-client.js +388 -0
- package/template/wall-e/memory/replica-origin.js +56 -0
- package/template/wall-e/memory/session-pool.js +135 -0
- package/template/wall-e/runtime/live-capabilities.js +8 -3
- package/template/wall-e/server.js +4 -2
- package/template/wall-e/shared/release-schema.json +2 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/storage/contract.js +3 -0
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
- package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
- package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
- package/template/wall-e/tools/chrome-automation.js +6 -0
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +18 -4
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-2 of docs/deepseek-harness-acp-agent-2026-10-28.html (§6.3; decisions D-1, D-2, D-5, D-6, D-9, D-10).
|
|
4
|
+
//
|
|
5
|
+
// One CTM dsh session owns exactly ONE child process (D-2) driven over the Agent Client Protocol on
|
|
6
|
+
// pipes — never node-pty (D-1). This module owns the child, the ACP client and the stop sequence; it
|
|
7
|
+
// renders nothing, writes no transcript (that is WP-3) and knows nothing about WebSockets (the caller
|
|
8
|
+
// injects `onUpdate`/`onRequestPermission`/`onExit`). Prompts, approvals and status are WP-4; restore
|
|
9
|
+
// after a CTM restart is WP-5 and spawns through `start({ resumeAcpSessionId })`.
|
|
10
|
+
//
|
|
11
|
+
// Everything that touches the outside world is a dep so a test never spawns the real binary (D-14):
|
|
12
|
+
// `resolveCliCommand` (the CLI cache), `realpath`, `execPath` (CTM's pinned Node), `spawnFn` (the
|
|
13
|
+
// ND-JSON transport's), the log sink and the timers.
|
|
14
|
+
|
|
15
|
+
const { spawnNdjsonTransport } = require('./ndjson-stdio-transport');
|
|
16
|
+
const { createAcpClient, AcpError } = require('./acp-client');
|
|
17
|
+
const { AGENT_DEFINITIONS } = require('../agent-definitions');
|
|
18
|
+
|
|
19
|
+
// WP-12: the name `dsh` is not unique (homebrew's `dsh` is the unrelated "Dancer's shell"), so a
|
|
20
|
+
// resolved binary is spawned only when its REALPATH is inside the @deepseek-ai/dsh package -- the
|
|
21
|
+
// same installIdentity rule the version service applies (lib/agent-version-service.js).
|
|
22
|
+
const DSH_INSTALL_IDENTITY = AGENT_DEFINITIONS.dsh.installIdentity;
|
|
23
|
+
|
|
24
|
+
const DSH_STOP_GRACE_MS = 5000; // SIGTERM this long after stdin end
|
|
25
|
+
const DSH_KILL_GRACE_MS = 1000; // SIGKILL this long after SIGTERM
|
|
26
|
+
const DSH_CLOSE_TIMEOUT_MS = 3000; // session/close budget before stdin end
|
|
27
|
+
const STDERR_TAIL_BYTES = 64 * 1024;
|
|
28
|
+
// WP-14: the bounded assistant text a completed turn leaves behind (see accumulateFinalText). Well
|
|
29
|
+
// above any real report, and small next to the 64 KB stderr ring.
|
|
30
|
+
const FINAL_TEXT_MAX_CHARS = 256 * 1024;
|
|
31
|
+
// A start failure names the child's exit in ONE line, so the tail it quotes is bounded well below the
|
|
32
|
+
// 64 KB ring it is cut from.
|
|
33
|
+
const STDERR_MESSAGE_CHARS = 400;
|
|
34
|
+
// D-1: a `.js`/`.cjs`/`.mjs` realpath is an npm entrypoint, not an executable — spawn it under the
|
|
35
|
+
// interpreter CTM pins (dsh needs Node >= 24.9) rather than whatever `node` PATH resolves to.
|
|
36
|
+
const JS_ENTRYPOINT_RE = /\.(?:js|cjs|mjs)$/i;
|
|
37
|
+
// WP-6 (§6.6, D-11): a ROUTED child talks to CTM's loopback proxy and carries the session token as
|
|
38
|
+
// its only credential, so every other provider credential or base URL inherited from the launch env
|
|
39
|
+
// is removed — otherwise pi-ai's own provider resolution (or a stale DEEPSEEK_API_KEY the user still
|
|
40
|
+
// has exported) could quietly win over the `--patch`.
|
|
41
|
+
const DSH_ROUTE_ENV_KEYS = Object.freeze([
|
|
42
|
+
'DEEPSEEK_API_KEY',
|
|
43
|
+
'ANTHROPIC_API_KEY',
|
|
44
|
+
'ANTHROPIC_BASE_URL',
|
|
45
|
+
'ANTHROPIC_OAUTH_TOKEN',
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {object} deps
|
|
50
|
+
* @param {(cmd: string) => string} deps.resolveCliCommand // lib/agent-cli-cache.js's resolver
|
|
51
|
+
* @param {(p: string) => Promise<string>|string} deps.realpath // async in production (no sync fs on the main loop)
|
|
52
|
+
* @param {string} deps.execPath // process.execPath
|
|
53
|
+
* @param {Function} [deps.spawnFn] // child_process.spawn stand-in for tests
|
|
54
|
+
* @param {Function} [deps.now]
|
|
55
|
+
* @param {Function} [deps.log] // ({level, msg}) => void
|
|
56
|
+
* @param {(ctmSessionId: string, update: object) => void} [deps.onUpdate]
|
|
57
|
+
* @param {(ctmSessionId: string, configOptions: Array<object>|null) => void} [deps.onConfigOptions]
|
|
58
|
+
* @param {(ctmSessionId: string, params: object) => Promise<object>} [deps.onRequestPermission]
|
|
59
|
+
* @param {(ctmSessionId: string, info: object) => void} [deps.onExit]
|
|
60
|
+
* @param {Function} [deps.setTimeout]
|
|
61
|
+
* @param {Function} [deps.clearTimeout]
|
|
62
|
+
*/
|
|
63
|
+
function createDshSessionRuntime(deps = {}) {
|
|
64
|
+
const {
|
|
65
|
+
resolveCliCommand = (cmd) => cmd,
|
|
66
|
+
realpath = (p) => p,
|
|
67
|
+
execPath = process.execPath,
|
|
68
|
+
spawnFn,
|
|
69
|
+
log = () => {},
|
|
70
|
+
} = deps;
|
|
71
|
+
const setTimeoutFn = deps.setTimeout || setTimeout;
|
|
72
|
+
const clearTimeoutFn = deps.clearTimeout || clearTimeout;
|
|
73
|
+
|
|
74
|
+
const entries = new Map(); // ctmSessionId → entry (ONE per id, D-2)
|
|
75
|
+
|
|
76
|
+
function logLine(level, msg) {
|
|
77
|
+
try {
|
|
78
|
+
log({ level, msg });
|
|
79
|
+
} catch (error) {
|
|
80
|
+
// expected: a broken log sink must never take down a session's start/stop path.
|
|
81
|
+
void error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The bounded stderr tail (D-5). Byte-trimmed so a chatty child cannot grow it without limit; the
|
|
86
|
+
// tail is diagnostic only and is NEVER logged at info (it can carry the child's own error text).
|
|
87
|
+
function trimTail(text) {
|
|
88
|
+
if (Buffer.byteLength(text, 'utf8') <= STDERR_TAIL_BYTES) return text;
|
|
89
|
+
return Buffer.from(text, 'utf8').subarray(-STDERR_TAIL_BYTES).toString('utf8');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function appendTail(state, line) {
|
|
93
|
+
state.stderrTail = trimTail(state.stderrTail ? `${state.stderrTail}\n${line}` : String(line));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function describeExit(info, tail) {
|
|
97
|
+
const code = info && info.code !== undefined && info.code !== null ? info.code : null;
|
|
98
|
+
const signal = info && info.signal ? info.signal : null;
|
|
99
|
+
const detail = code === null && !signal
|
|
100
|
+
? 'dsh exited during startup'
|
|
101
|
+
: `dsh exited during startup (code ${code}${signal ? `, signal ${signal}` : ''})`;
|
|
102
|
+
const quoted = String(tail || '').slice(-STDERR_MESSAGE_CHARS);
|
|
103
|
+
return quoted ? `${detail}: ${quoted}` : detail;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function scheduleSigkillEscalation(entry) {
|
|
107
|
+
const timer = setTimeoutFn(() => {
|
|
108
|
+
if (!entry.exited) entry.transport.kill('SIGKILL');
|
|
109
|
+
}, DSH_KILL_GRACE_MS);
|
|
110
|
+
if (timer && typeof timer.unref === 'function') timer.unref();
|
|
111
|
+
return timer;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// The child is gone: drop the registry row, release anyone waiting on the stop, and report the exit
|
|
115
|
+
// to the caller exactly once. An exit this runtime caused itself (stop, or a failed start) is
|
|
116
|
+
// either reported as intentional or not reported at all — never both.
|
|
117
|
+
function onChildExit(ctmSessionId, entry, info) {
|
|
118
|
+
if (entry.exited) return;
|
|
119
|
+
entry.exited = true;
|
|
120
|
+
entry.exitInfo = info || null;
|
|
121
|
+
if (entries.get(ctmSessionId) === entry) entries.delete(ctmSessionId);
|
|
122
|
+
if (typeof entry.resolveExit === 'function') entry.resolveExit();
|
|
123
|
+
// Before the handshake completes the child belongs to start(), which reports the failure itself.
|
|
124
|
+
if (!entry.started) return;
|
|
125
|
+
// WP-6: the routed token is released exactly ONCE per started child, on whichever path the child
|
|
126
|
+
// died (a stop, or a crash): `entry.exited` above already makes this a one-shot, and clearing the
|
|
127
|
+
// hook means a later re-entry can never fire it a second time.
|
|
128
|
+
if (typeof entry.onStopped === 'function') {
|
|
129
|
+
const release = entry.onStopped;
|
|
130
|
+
entry.onStopped = null;
|
|
131
|
+
try {
|
|
132
|
+
release();
|
|
133
|
+
} catch (error) {
|
|
134
|
+
// expected: a release observer must never break the transport's own teardown.
|
|
135
|
+
void error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const report = deps.onExit;
|
|
139
|
+
if (typeof report !== 'function') return;
|
|
140
|
+
try {
|
|
141
|
+
report(ctmSessionId, {
|
|
142
|
+
code: info && info.code !== undefined ? info.code : null,
|
|
143
|
+
signal: info && info.signal !== undefined ? info.signal : null,
|
|
144
|
+
stderrTail: entry.stderrTail,
|
|
145
|
+
intentional: entry.stopping === true,
|
|
146
|
+
});
|
|
147
|
+
} catch (error) {
|
|
148
|
+
// expected: an exit observer must never break the transport's own teardown.
|
|
149
|
+
void error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// WP-8 (§9b M-16, D-12/D-13): a `config_option_update` notification carries the bridge's WHOLE
|
|
154
|
+
// `configOptions` list — the same shape `session/new`/`session/resume` returned — so it replaces the
|
|
155
|
+
// entry's copy (which `get()` serves) and is handed to the caller's observer, which records the
|
|
156
|
+
// model-owner row. Any other update kind is passed through untouched, and a throwing observer can
|
|
157
|
+
// never break the ACP read loop that called it.
|
|
158
|
+
function acceptConfigOptions(ctmSessionId, entry, update) {
|
|
159
|
+
if (!update || update.sessionUpdate !== 'config_option_update') return;
|
|
160
|
+
const next = Array.isArray(update.configOptions) ? update.configOptions
|
|
161
|
+
: (update.configOption && typeof update.configOption === 'object' ? [update.configOption] : null);
|
|
162
|
+
if (next) entry.configOptions = next;
|
|
163
|
+
if (typeof entry.onConfigOptions !== 'function') return;
|
|
164
|
+
try {
|
|
165
|
+
entry.onConfigOptions(ctmSessionId, entry.configOptions);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
logLine('warn', `dsh-runtime: config-option observer failed for ${ctmSessionId} (${(error && error.message) || 'error'})`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// WP-14 (docs/deepseek-harness-acp-agent-2026-10-28.html §9b W-3, §6.4): the LAST assistant text the
|
|
172
|
+
// child produced, which is what a delegated dsh worker's report IS (its brief turn's final answer;
|
|
173
|
+
// the transcript writer appends the same chunks). The ACP wire has no "final message" field — the
|
|
174
|
+
// text arrives as `agent_message_chunk` updates — so this accumulates them per `messageId` and keeps
|
|
175
|
+
// the last id seen: a new id starts a new assistant message, exactly the grouping
|
|
176
|
+
// lib/acp/dsh-transcript.js's chunk writer uses (`pending.messageId`). Bounded, so a runaway child
|
|
177
|
+
// cannot grow the entry without limit; only text chunks count (thinking chunks are not an answer).
|
|
178
|
+
function accumulateFinalText(entry, update) {
|
|
179
|
+
if (!update || update.sessionUpdate !== 'agent_message_chunk') return;
|
|
180
|
+
const messageId = typeof update.messageId === 'string' && update.messageId ? update.messageId : entry.finalTextMessageId;
|
|
181
|
+
const content = update.content;
|
|
182
|
+
const text = typeof content === 'string' ? content
|
|
183
|
+
: content && typeof content.text === 'string' ? content.text : '';
|
|
184
|
+
if (!text) return;
|
|
185
|
+
if (messageId !== entry.finalTextMessageId) {
|
|
186
|
+
entry.finalTextMessageId = messageId;
|
|
187
|
+
entry.finalText = '';
|
|
188
|
+
}
|
|
189
|
+
entry.finalText = `${entry.finalText}${text}`.slice(-FINAL_TEXT_MAX_CHARS);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// WP-10 step A (C-6/D-16): `mcpServers` are the ACP entries the child mounts for THIS session
|
|
193
|
+
// (lib/acp/dsh-mcp-servers.js converts CTM's normalized map into them). They ride the
|
|
194
|
+
// `session/new`/`session/resume` JSON-RPC request -- never argv, never the child's process env --
|
|
195
|
+
// and an absent list is an empty one, so a session with no MCP profile is byte-for-byte what it
|
|
196
|
+
// was before WP-10.
|
|
197
|
+
async function start({ ctmSessionId, cwd, env, resumeAcpSessionId = null, patchPath = null, mcpServers = [], onStopped = null, onConfigOptions = null } = {}) {
|
|
198
|
+
if (entries.has(ctmSessionId)) {
|
|
199
|
+
return {
|
|
200
|
+
ok: false,
|
|
201
|
+
code: 'dsh_already_running',
|
|
202
|
+
message: `A DeepSeek Harness process is already running for session ${ctmSessionId}.`,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const bin = resolveCliCommand('dsh');
|
|
206
|
+
// `resolveCliCommand` returns its input unchanged when the CLI is not on this host (an absolute
|
|
207
|
+
// path it cannot find also comes back bare).
|
|
208
|
+
if (!bin || bin === 'dsh') {
|
|
209
|
+
return { ok: false, code: 'dsh_not_found', message: 'DeepSeek Harness (dsh) was not found on PATH' };
|
|
210
|
+
}
|
|
211
|
+
let real = bin;
|
|
212
|
+
try {
|
|
213
|
+
real = (await realpath(bin)) || bin;
|
|
214
|
+
} catch (error) {
|
|
215
|
+
// expected: the CLI cache can point at a path that has since been removed; spawn reports that
|
|
216
|
+
// as a start failure through the transport's exit channel, so no throw is needed here.
|
|
217
|
+
void error;
|
|
218
|
+
}
|
|
219
|
+
if (!DSH_INSTALL_IDENTITY.test(String(real))) {
|
|
220
|
+
return { ok: false, code: 'dsh_not_found', message: 'The dsh on PATH is not the DeepSeek Harness (@deepseek-ai/dsh)' };
|
|
221
|
+
}
|
|
222
|
+
const args = ['--profile', 'acp'];
|
|
223
|
+
if (patchPath) args.push('--patch', patchPath);
|
|
224
|
+
const isJsEntrypoint = JS_ENTRYPOINT_RE.test(real);
|
|
225
|
+
const command = isJsEntrypoint ? execPath : real;
|
|
226
|
+
const spawnArgs = isJsEntrypoint ? [real, ...args] : args;
|
|
227
|
+
const childEnv = { ...(env || {}) };
|
|
228
|
+
// WP-6 (§6.6): a routed child's provider comes from the patch and its credential is the session
|
|
229
|
+
// token; every other provider key/base URL in the launch env is dropped (see DSH_ROUTE_ENV_KEYS).
|
|
230
|
+
if (patchPath) for (const key of DSH_ROUTE_ENV_KEYS) delete childEnv[key];
|
|
231
|
+
// The bridge's own permission mode. Passed THROUGH to the child; never read back by CTM and never
|
|
232
|
+
// logged (it is launch context, not a CTM flag).
|
|
233
|
+
if (childEnv.DSH_PERMISSION_MODE === undefined) childEnv.DSH_PERMISSION_MODE = 'workspace-write';
|
|
234
|
+
|
|
235
|
+
const entry = {
|
|
236
|
+
acpSessionId: null,
|
|
237
|
+
client: null,
|
|
238
|
+
transport: null,
|
|
239
|
+
pid: undefined,
|
|
240
|
+
configOptions: null,
|
|
241
|
+
agentInfo: null,
|
|
242
|
+
// WP-11 (D-20): the child's LIVE image capability, read from the ACP `initialize` result
|
|
243
|
+
// (`agentCapabilities.promptCapabilities.image`). Absent/false means the bridge cannot accept
|
|
244
|
+
// an image content block, and the prompt lane refuses such a prompt rather than sending one.
|
|
245
|
+
imageInput: false,
|
|
246
|
+
// WP-14: the last assistant text seen for this child (accumulateFinalText above), and the
|
|
247
|
+
// messageId that text belongs to.
|
|
248
|
+
finalText: '',
|
|
249
|
+
finalTextMessageId: null,
|
|
250
|
+
stderrTail: '',
|
|
251
|
+
started: false,
|
|
252
|
+
startFailed: false,
|
|
253
|
+
stopping: false,
|
|
254
|
+
stopReason: '',
|
|
255
|
+
stopPromise: null,
|
|
256
|
+
exited: false,
|
|
257
|
+
exitInfo: null,
|
|
258
|
+
resolveExit: null,
|
|
259
|
+
exitPromise: null,
|
|
260
|
+
// WP-6: the caller's one-shot release hook (see onChildExit). Never called for a child whose
|
|
261
|
+
// start failed -- that child belongs to start(), which releases its own token.
|
|
262
|
+
onStopped: typeof onStopped === 'function' ? onStopped : null,
|
|
263
|
+
// WP-8: the caller's model-owner observer (see acceptConfigOptions). Fires for every
|
|
264
|
+
// `config_option_update` the child emits, including ones that arrive before the handshake ends.
|
|
265
|
+
onConfigOptions: typeof onConfigOptions === 'function' ? onConfigOptions : null,
|
|
266
|
+
};
|
|
267
|
+
entry.exitPromise = new Promise((resolve) => { entry.resolveExit = resolve; });
|
|
268
|
+
|
|
269
|
+
const transport = spawnNdjsonTransport({
|
|
270
|
+
command,
|
|
271
|
+
args: spawnArgs,
|
|
272
|
+
cwd,
|
|
273
|
+
env: childEnv,
|
|
274
|
+
...(spawnFn ? { spawnFn } : {}),
|
|
275
|
+
onStderrLine: (line) => appendTail(entry, line),
|
|
276
|
+
});
|
|
277
|
+
entry.transport = transport;
|
|
278
|
+
entry.pid = transport.pid;
|
|
279
|
+
transport.onExit((info) => onChildExit(ctmSessionId, entry, info));
|
|
280
|
+
|
|
281
|
+
const client = createAcpClient({
|
|
282
|
+
transport,
|
|
283
|
+
onSessionUpdate: (sessionId, update) => {
|
|
284
|
+
acceptConfigOptions(ctmSessionId, entry, update);
|
|
285
|
+
accumulateFinalText(entry, update);
|
|
286
|
+
if (typeof deps.onUpdate === 'function') deps.onUpdate(ctmSessionId, update);
|
|
287
|
+
else logLine('info', `dsh-runtime: session update for ${sessionId} dropped (no observer)`);
|
|
288
|
+
},
|
|
289
|
+
onRequestPermission: (params) => (typeof deps.onRequestPermission === 'function'
|
|
290
|
+
? deps.onRequestPermission(ctmSessionId, params)
|
|
291
|
+
: Promise.resolve({ outcome: 'cancelled' })),
|
|
292
|
+
log: (entryLog) => logLine(entryLog.level, entryLog.msg),
|
|
293
|
+
});
|
|
294
|
+
entry.client = client;
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
const initResult = await client.initialize();
|
|
298
|
+
const acpMcpServers = Array.isArray(mcpServers) ? mcpServers : [];
|
|
299
|
+
const sessionResult = resumeAcpSessionId
|
|
300
|
+
? await client.resumeSession({ sessionId: resumeAcpSessionId, cwd, mcpServers: acpMcpServers })
|
|
301
|
+
: await client.newSession({ cwd, mcpServers: acpMcpServers });
|
|
302
|
+
const acpSessionId = (sessionResult && (sessionResult.sessionId || sessionResult.session_id))
|
|
303
|
+
|| resumeAcpSessionId
|
|
304
|
+
|| null;
|
|
305
|
+
entry.acpSessionId = acpSessionId;
|
|
306
|
+
entry.configOptions = (sessionResult && sessionResult.configOptions) || null;
|
|
307
|
+
entry.agentInfo = (initResult && initResult.agentInfo) || null;
|
|
308
|
+
// WP-11 (D-20): the child's own answer to "can you take an image?". Read from the SAME
|
|
309
|
+
// initialize result the handshake gate above already validated; an absent or non-`true` value
|
|
310
|
+
// is false (a bridge that does not advertise image prompts cannot be given one).
|
|
311
|
+
entry.imageInput = !!(
|
|
312
|
+
initResult
|
|
313
|
+
&& initResult.agentCapabilities
|
|
314
|
+
&& initResult.agentCapabilities.promptCapabilities
|
|
315
|
+
&& initResult.agentCapabilities.promptCapabilities.image === true
|
|
316
|
+
);
|
|
317
|
+
entry.started = true;
|
|
318
|
+
entries.set(ctmSessionId, entry);
|
|
319
|
+
return {
|
|
320
|
+
ok: true,
|
|
321
|
+
acpSessionId,
|
|
322
|
+
configOptions: entry.configOptions,
|
|
323
|
+
agentInfo: entry.agentInfo,
|
|
324
|
+
imageInput: entry.imageInput,
|
|
325
|
+
};
|
|
326
|
+
} catch (error) {
|
|
327
|
+
// Nothing was registered, so the child must not outlive this call.
|
|
328
|
+
entry.startFailed = true;
|
|
329
|
+
transport.kill('SIGTERM');
|
|
330
|
+
entry.sigkillTimer = scheduleSigkillEscalation(entry);
|
|
331
|
+
if (error instanceof AcpError && error.code === 'dsh_acp_incompatible') {
|
|
332
|
+
return { ok: false, code: 'dsh_acp_incompatible', message: error.message };
|
|
333
|
+
}
|
|
334
|
+
if (entry.exited || (error instanceof AcpError && error.code === 'acp_child_exited')) {
|
|
335
|
+
return { ok: false, code: 'dsh_start_failed', message: describeExit(entry.exitInfo, entry.stderrTail) };
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
ok: false,
|
|
339
|
+
code: 'dsh_start_failed',
|
|
340
|
+
message: error && error.message ? String(error.message) : 'DeepSeek Harness failed to start',
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// D-10: session/close (bounded), stdin end, SIGTERM after DSH_STOP_GRACE_MS, SIGKILL
|
|
346
|
+
// DSH_KILL_GRACE_MS later if the child is still alive. Files are never touched.
|
|
347
|
+
// `closeAcpSession:false` (§6.7 cross-route relaunch) skips session/close: the SAME ACP session is
|
|
348
|
+
// resumed by the next child, so it must stay open.
|
|
349
|
+
async function stop(ctmSessionId, { reason, closeAcpSession = true } = {}) {
|
|
350
|
+
const entry = entries.get(ctmSessionId);
|
|
351
|
+
if (!entry) return { ok: true, alreadyStopped: true };
|
|
352
|
+
if (entry.stopPromise) return entry.stopPromise;
|
|
353
|
+
entry.stopping = true;
|
|
354
|
+
entry.stopReason = reason || '';
|
|
355
|
+
entry.stopPromise = (async () => {
|
|
356
|
+
if (closeAcpSession) {
|
|
357
|
+
try {
|
|
358
|
+
await Promise.race([
|
|
359
|
+
entry.client.closeSession({ sessionId: entry.acpSessionId }),
|
|
360
|
+
new Promise((resolve) => {
|
|
361
|
+
const timer = setTimeoutFn(resolve, DSH_CLOSE_TIMEOUT_MS);
|
|
362
|
+
if (timer && typeof timer.unref === 'function') timer.unref();
|
|
363
|
+
}),
|
|
364
|
+
]);
|
|
365
|
+
} catch (error) {
|
|
366
|
+
// The child may already be gone, or the bridge may not implement session/close (its
|
|
367
|
+
// capability is optional); the SIGTERM ladder below is the real guarantee.
|
|
368
|
+
logLine('warn', `dsh-runtime: session/close failed for ${ctmSessionId} (${(error && error.code) || 'error'})`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
entry.transport.endInput();
|
|
372
|
+
const termTimer = setTimeoutFn(() => {
|
|
373
|
+
if (!entry.exited) entry.transport.kill('SIGTERM');
|
|
374
|
+
}, DSH_STOP_GRACE_MS);
|
|
375
|
+
const killTimer = setTimeoutFn(() => {
|
|
376
|
+
if (!entry.exited) entry.transport.kill('SIGKILL');
|
|
377
|
+
}, DSH_STOP_GRACE_MS + DSH_KILL_GRACE_MS);
|
|
378
|
+
if (termTimer && typeof termTimer.unref === 'function') termTimer.unref();
|
|
379
|
+
if (killTimer && typeof killTimer.unref === 'function') killTimer.unref();
|
|
380
|
+
await entry.exitPromise;
|
|
381
|
+
clearTimeoutFn(termTimer);
|
|
382
|
+
clearTimeoutFn(killTimer);
|
|
383
|
+
return { ok: true };
|
|
384
|
+
})();
|
|
385
|
+
return entry.stopPromise;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function isRunning(ctmSessionId) {
|
|
389
|
+
const entry = entries.get(ctmSessionId);
|
|
390
|
+
return !!entry && !entry.exited;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// WP-8 step 3 (§6.7): the bridge admits ONE in-flight prompt per session, so a config-option write
|
|
394
|
+
// that arrived while a turn is open must be REFUSED, never queued (the caller's pick is a
|
|
395
|
+
// point-in-time choice, and a queued write would silently apply to a later turn). The predicate is
|
|
396
|
+
// injected (the prompt lane owns the turn registry) — absent a predicate nothing is ever in flight.
|
|
397
|
+
function isTurnInFlight(ctmSessionId) {
|
|
398
|
+
if (typeof deps.isTurnInFlight !== 'function') return false;
|
|
399
|
+
try {
|
|
400
|
+
return deps.isTurnInFlight(ctmSessionId) === true;
|
|
401
|
+
} catch (error) {
|
|
402
|
+
logLine('warn', `dsh-runtime: turn-in-flight probe failed for ${ctmSessionId} (${(error && error.message) || 'error'})`);
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// The ONE config-option write (§6.7). `value` is the OPAQUE option value the bridge itself
|
|
408
|
+
// advertised — never a hand-built string — so the caller must have found it in the entry's own
|
|
409
|
+
// `configOptions`. On success the returned list replaces the entry's copy and the SAME observer
|
|
410
|
+
// path `acceptConfigOptions` uses is invoked, so the model-owner row re-binds from one place.
|
|
411
|
+
async function applyConfigOption(ctmSessionId, configId, value) {
|
|
412
|
+
const entry = entries.get(ctmSessionId);
|
|
413
|
+
if (!entry || entry.exited) return { ok: false, code: 'acp_child_exited' };
|
|
414
|
+
if (!configId || typeof value !== 'string' || !value) return { ok: false, code: 'dsh_option_unavailable' };
|
|
415
|
+
if (isTurnInFlight(ctmSessionId)) return { ok: false, code: 'dsh_turn_in_flight' };
|
|
416
|
+
if (typeof entry.client?.setConfigOption !== 'function') return { ok: false, code: 'dsh_option_unavailable' };
|
|
417
|
+
let result;
|
|
418
|
+
try {
|
|
419
|
+
result = await entry.client.setConfigOption({
|
|
420
|
+
sessionId: entry.acpSessionId, configId, value,
|
|
421
|
+
});
|
|
422
|
+
} catch (error) {
|
|
423
|
+
// A child that died mid-write is reported as exited; anything else is the bridge refusing the
|
|
424
|
+
// option, which is exactly the `dsh_option_unavailable` the caller shows the user.
|
|
425
|
+
if (entry.exited) return { ok: false, code: 'acp_child_exited' };
|
|
426
|
+
logLine('warn', `dsh-runtime: set_config_option ${configId} failed for ${ctmSessionId} (${(error && error.code) || 'error'})`);
|
|
427
|
+
return { ok: false, code: 'dsh_option_unavailable' };
|
|
428
|
+
}
|
|
429
|
+
const next = result && Array.isArray(result.configOptions) ? result.configOptions : null;
|
|
430
|
+
if (next) {
|
|
431
|
+
entry.configOptions = next;
|
|
432
|
+
if (typeof entry.onConfigOptions === 'function') {
|
|
433
|
+
try {
|
|
434
|
+
entry.onConfigOptions(ctmSessionId, entry.configOptions);
|
|
435
|
+
} catch (error) {
|
|
436
|
+
logLine('warn', `dsh-runtime: config-option observer failed for ${ctmSessionId} (${(error && error.message) || 'error'})`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return { ok: true, configOptions: entry.configOptions };
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* §6.7: switch the ACP `model` option. `value` is the OPAQUE value from the entry's `configOptions`
|
|
445
|
+
* (the caller unwraps the entry's JSON pair; this layer never builds one).
|
|
446
|
+
*/
|
|
447
|
+
async function setModel(ctmSessionId, { value } = {}) {
|
|
448
|
+
return applyConfigOption(ctmSessionId, 'model', value);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** §6.7: switch the bridge-declared effort option (`reasoning_effort`), same contract as setModel. */
|
|
452
|
+
async function setEffort(ctmSessionId, level, { configId = 'reasoning_effort', value = null } = {}) {
|
|
453
|
+
return applyConfigOption(ctmSessionId, configId, value == null ? level : value);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function get(ctmSessionId) {
|
|
457
|
+
const entry = entries.get(ctmSessionId);
|
|
458
|
+
if (!entry) return null;
|
|
459
|
+
return {
|
|
460
|
+
acpSessionId: entry.acpSessionId,
|
|
461
|
+
client: entry.client,
|
|
462
|
+
pid: entry.pid,
|
|
463
|
+
configOptions: entry.configOptions,
|
|
464
|
+
// WP-11 (D-20): the live image capability of THIS child (`initialize`'s
|
|
465
|
+
// `agentCapabilities.promptCapabilities.image`). Absent reads false — a gone child reads
|
|
466
|
+
// `null` for the whole entry, which the prompt lane already treats as "not running".
|
|
467
|
+
imageInput: entry.imageInput === true,
|
|
468
|
+
stderrTail: () => entry.stderrTail,
|
|
469
|
+
// WP-14 (§9b W-3): the report source for a delegated dsh worker — `observer?.finalText ||
|
|
470
|
+
// runtime?.finalText` in delegate-worker.js's getWorkerStatus reads this through
|
|
471
|
+
// lib/session-create/dsh-session.js's `_dshFinalText` accessor. Empty until the child has
|
|
472
|
+
// produced assistant text; '' (never null) so a caller never has to type-check it.
|
|
473
|
+
finalText: entry.finalText || '',
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* WP-14 (§9b W-2): put ONE prompt on the wire for a caller that is not the interactive prompt lane
|
|
479
|
+
* — the delegated dsh worker's brief, which has no argv to ride. Returns the ACP prompt promise
|
|
480
|
+
* (the turn's own settle/status/cancel behaviour stays the prompt lane's business, exactly as it is
|
|
481
|
+
* for an interactive turn); a session with no live child is refused rather than throwing.
|
|
482
|
+
* `resetFinalText` starts the report's text from THIS turn: without it a run whose first turn was
|
|
483
|
+
* empty would report the previous turn's answer.
|
|
484
|
+
*
|
|
485
|
+
* @param {string} ctmSessionId
|
|
486
|
+
* @param {{text: string}} prompt
|
|
487
|
+
* @returns {Promise<{ok: true, prompt: Promise<any>}|{ok: false, code: string, message: string}>}
|
|
488
|
+
*/
|
|
489
|
+
function prompt(ctmSessionId, { text = '' } = {}) {
|
|
490
|
+
const entry = entries.get(ctmSessionId);
|
|
491
|
+
if (!entry || !entry.client || typeof entry.client.prompt !== 'function' || !entry.acpSessionId) {
|
|
492
|
+
return Promise.resolve({
|
|
493
|
+
ok: false,
|
|
494
|
+
code: 'dsh_not_running',
|
|
495
|
+
message: `No DeepSeek Harness process is running for session ${ctmSessionId}.`,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
entry.finalText = '';
|
|
499
|
+
entry.finalTextMessageId = null;
|
|
500
|
+
let pending;
|
|
501
|
+
try {
|
|
502
|
+
pending = entry.client.prompt({ sessionId: entry.acpSessionId, text: String(text) });
|
|
503
|
+
} catch (error) {
|
|
504
|
+
return Promise.resolve({
|
|
505
|
+
ok: false,
|
|
506
|
+
code: 'dsh_prompt_failed',
|
|
507
|
+
message: (error && error.message) ? String(error.message) : 'DeepSeek Harness refused the prompt',
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
return Promise.resolve({ ok: true, prompt: Promise.resolve(pending) });
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
return { start, stop, isRunning, get, prompt, setModel, setEffort, isTurnInFlight };
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
module.exports = {
|
|
517
|
+
createDshSessionRuntime,
|
|
518
|
+
DSH_STOP_GRACE_MS,
|
|
519
|
+
DSH_KILL_GRACE_MS,
|
|
520
|
+
DSH_CLOSE_TIMEOUT_MS,
|
|
521
|
+
DSH_ROUTE_ENV_KEYS,
|
|
522
|
+
};
|