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
|
@@ -537,6 +537,32 @@ function catalogSessionIds(machineInstanceId) {
|
|
|
537
537
|
return entry ? new Set(entry.byId.keys()) : new Set();
|
|
538
538
|
}
|
|
539
539
|
|
|
540
|
+
/** WP-5: is this a multi-machine install at all? The sessions frame carries `machinesPending` ONLY
|
|
541
|
+
* then — zero registered machines keeps the payload byte-identical to the single-machine one. */
|
|
542
|
+
function hasEnabledMachines(deps = {}) {
|
|
543
|
+
return _enabledMachines(_d(deps)).length > 0;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* WP-5 (§5.4/§8 AC-5a, docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html):
|
|
548
|
+
* how many ENABLED machines have delivered NO session list since this hub booted.
|
|
549
|
+
*
|
|
550
|
+
* Their ids CAN still arrive (the machine sweep + catalog fetch land seconds to a minute after a hub
|
|
551
|
+
* restart), so a client restoring a `tab_order` that names one must not treat the id as dropped. A
|
|
552
|
+
* machine that delivered ONCE is settled — its ids were classified — even if it later drops, and
|
|
553
|
+
* health is deliberately irrelevant: an unreachable or still-'unknown' box that has never answered
|
|
554
|
+
* is exactly the pending case (its ids are the ones the client is waiting for).
|
|
555
|
+
*/
|
|
556
|
+
function catalogPendingCount(deps = {}) {
|
|
557
|
+
const d = _d(deps);
|
|
558
|
+
let pending = 0;
|
|
559
|
+
for (const machine of _enabledMachines(d)) {
|
|
560
|
+
const id = _string(machine.instanceId, 160);
|
|
561
|
+
if (id && !_catalogs.has(id)) pending += 1;
|
|
562
|
+
}
|
|
563
|
+
return pending;
|
|
564
|
+
}
|
|
565
|
+
|
|
540
566
|
/**
|
|
541
567
|
* S-3/AC-6a: fetch one machine's LIVE session list over the WP-3 machine link.
|
|
542
568
|
*
|
|
@@ -859,7 +885,13 @@ function mergeSessionRows(localRows, deps = {}) {
|
|
|
859
885
|
seen.add(id);
|
|
860
886
|
out.push(remote);
|
|
861
887
|
}
|
|
862
|
-
|
|
888
|
+
// WP-5: the pending count joins the signature so a pending->settled flip (a machine that finally
|
|
889
|
+
// delivered its first list) is never elided as a no-op broadcast with identical remote rows.
|
|
890
|
+
_lastMergeSignature = JSON.stringify([
|
|
891
|
+
machines.map((m) => `${m.instanceId}:${m.health}`),
|
|
892
|
+
catalogPendingCount(d),
|
|
893
|
+
out.slice(rows.length),
|
|
894
|
+
]);
|
|
863
895
|
return out;
|
|
864
896
|
}
|
|
865
897
|
|
|
@@ -883,19 +915,13 @@ function _machineRowForMirror(mirror, d) {
|
|
|
883
915
|
}
|
|
884
916
|
|
|
885
917
|
/**
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
* NOT in the hub's sessions Map).
|
|
918
|
+
* The shared middle of every mirror forwarder (lifecycle + WP-2's lead-model): resolve the mirror to
|
|
919
|
+
* the registry row that owns it and write the ONE refusal shape when the box cannot be reached. The
|
|
920
|
+
* three bodies below are byte-identical to what each forwarder used to write inline.
|
|
890
921
|
*
|
|
891
|
-
* @returns {
|
|
922
|
+
* @returns {{machine: object, machineName: string, proxy: object}|null} null = already refused here
|
|
892
923
|
*/
|
|
893
|
-
|
|
894
|
-
const d = _d(deps);
|
|
895
|
-
const verb = _string(action, 20);
|
|
896
|
-
if (!['park', 'revive', 'pin', 'wake'].includes(verb)) return false;
|
|
897
|
-
const mirror = getMirrorSessionMachine(sessionId, d);
|
|
898
|
-
if (!mirror) return false; // a LOCAL session takes the byte-identical existing path
|
|
924
|
+
function _forwardTarget(res, mirror, d) {
|
|
899
925
|
const machine = _machineRowForMirror(mirror, d);
|
|
900
926
|
const machineName = _string(machine ? machine.displayName : mirror.machineName, 200);
|
|
901
927
|
if (!machine) {
|
|
@@ -903,16 +929,16 @@ async function forwardLifecycleRequest(req, res, sessionId, action, deps = {}) {
|
|
|
903
929
|
ok: false, code: 'machine_unreachable', error: `Machine ${machineName || mirror.machineInstanceId} is not available`,
|
|
904
930
|
machine: mirror.machineInstanceId, machineName,
|
|
905
931
|
});
|
|
906
|
-
return
|
|
932
|
+
return null;
|
|
907
933
|
}
|
|
908
934
|
if (_string(machine.health, 40) === 'unreachable') {
|
|
909
|
-
// Never a local act:
|
|
910
|
-
//
|
|
935
|
+
// Never a local act: an action on a session the hub does not own is refused, not silently
|
|
936
|
+
// applied to a same-id session on this host (which does not exist anyway).
|
|
911
937
|
_sendJson(res, 503, {
|
|
912
938
|
ok: false, code: 'machine_unreachable', error: `Machine ${machineName} is unreachable`,
|
|
913
939
|
machine: mirror.machineInstanceId, machineName,
|
|
914
940
|
});
|
|
915
|
-
return
|
|
941
|
+
return null;
|
|
916
942
|
}
|
|
917
943
|
const proxy = _peer('proxy', d);
|
|
918
944
|
if (!proxy || typeof proxy.forwardMachineHttp !== 'function') {
|
|
@@ -920,15 +946,18 @@ async function forwardLifecycleRequest(req, res, sessionId, action, deps = {}) {
|
|
|
920
946
|
ok: false, code: 'machine_unreachable', error: `Machine ${machineName} could not be reached`,
|
|
921
947
|
machine: mirror.machineInstanceId, machineName,
|
|
922
948
|
});
|
|
923
|
-
return
|
|
949
|
+
return null;
|
|
924
950
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
951
|
+
return { machine, machineName, proxy };
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* The shared tail: a failed dial is the one refusal shape, and the box's own status + body are
|
|
956
|
+
* returned VERBATIM (§6.5) — the client parses the box's answer exactly as it parses the local one.
|
|
957
|
+
*
|
|
958
|
+
* @returns {true} always — the request was answered here.
|
|
959
|
+
*/
|
|
960
|
+
function _relayBoxAnswer(res, result, mirror, machineName) {
|
|
932
961
|
if (!result || !result.ok) {
|
|
933
962
|
_sendJson(res, 503, {
|
|
934
963
|
ok: false, code: (result && result.code) || 'machine_unreachable',
|
|
@@ -937,8 +966,6 @@ async function forwardLifecycleRequest(req, res, sessionId, action, deps = {}) {
|
|
|
937
966
|
});
|
|
938
967
|
return true;
|
|
939
968
|
}
|
|
940
|
-
// The box's own status and body are returned VERBATIM (§6.5): the client parses the box's answer
|
|
941
|
-
// exactly as it parses the local one.
|
|
942
969
|
if (!res.headersSent) {
|
|
943
970
|
res.writeHead(Number(result.status) || 502, { 'Content-Type': result.contentType || 'application/json' });
|
|
944
971
|
res.end(result.text || '');
|
|
@@ -946,6 +973,260 @@ async function forwardLifecycleRequest(req, res, sessionId, action, deps = {}) {
|
|
|
946
973
|
return true;
|
|
947
974
|
}
|
|
948
975
|
|
|
976
|
+
/**
|
|
977
|
+
* §7 ownership routing (AC-6b), HTTP half: `POST /api/sessions/:id/(park|revive|pin|wake)` for a
|
|
978
|
+
* MIRROR session must be acted on the BOX, never locally — the hub's `parkSession`/`getSession`
|
|
979
|
+
* would otherwise be asked about a session it does not have (OQ-4: mirror sessions are deliberately
|
|
980
|
+
* NOT in the hub's sessions Map).
|
|
981
|
+
*
|
|
982
|
+
* @returns {Promise<boolean>} true = the request was answered here (do NOT run the local handler)
|
|
983
|
+
*/
|
|
984
|
+
async function forwardLifecycleRequest(req, res, sessionId, action, deps = {}) {
|
|
985
|
+
const d = _d(deps);
|
|
986
|
+
const verb = _string(action, 20);
|
|
987
|
+
if (!['park', 'revive', 'pin', 'wake'].includes(verb)) return false;
|
|
988
|
+
const mirror = getMirrorSessionMachine(sessionId, d);
|
|
989
|
+
if (!mirror) return false; // a LOCAL session takes the byte-identical existing path
|
|
990
|
+
const target = _forwardTarget(res, mirror, d);
|
|
991
|
+
if (!target) return true;
|
|
992
|
+
const result = await target.proxy.forwardMachineHttp({
|
|
993
|
+
machine: target.machine,
|
|
994
|
+
pathname: `/api/sessions/${encodeURIComponent(mirror && sessionId)}/${verb}`,
|
|
995
|
+
method: 'POST',
|
|
996
|
+
body: '',
|
|
997
|
+
deps: d,
|
|
998
|
+
});
|
|
999
|
+
return _relayBoxAnswer(res, result, mirror, target.machineName);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// ---------------------------------------------------------------------------------------------
|
|
1003
|
+
// WP-2 (docs/remote-box-model-access-2026-10-26.html §1.3 C-6, §5.1 R-4/R-8, §5.3 D-4, §6.3) —
|
|
1004
|
+
// the model picker's four calls for a MIRROR session
|
|
1005
|
+
// ---------------------------------------------------------------------------------------------
|
|
1006
|
+
//
|
|
1007
|
+
// `GET .../lead-model/options`, `POST .../lead-model`, `GET .../lead-model/request` and
|
|
1008
|
+
// `DELETE .../lead-model/request` are answered hub-locally today, and for a mirror id that is a
|
|
1009
|
+
// `404 session_not_found` (the id is deliberately NOT in the hub's sessions Map, so
|
|
1010
|
+
// lib/lead-model-options.js can never serve it). The BOX owns the session, its CLI and its
|
|
1011
|
+
// servability rules (D-4), so the four calls are forwarded there exactly like the lifecycle verbs
|
|
1012
|
+
// above: a local id takes the byte-identical existing path, an unknown/down box is the shared 503
|
|
1013
|
+
// `machine_unreachable`, and otherwise the box's status + body come back VERBATIM.
|
|
1014
|
+
|
|
1015
|
+
/** kind → the BOX route it belongs to. `switch` is the only kind that carries a body. */
|
|
1016
|
+
const LEAD_MODEL_FORWARDS = Object.freeze({
|
|
1017
|
+
options: { method: 'GET', suffix: '/lead-model/options' },
|
|
1018
|
+
switch: { method: 'POST', suffix: '/lead-model' },
|
|
1019
|
+
request: { method: 'GET', suffix: '/lead-model/request' },
|
|
1020
|
+
'request-cancel': { method: 'DELETE', suffix: '/lead-model/request' },
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
// The local POST handler's own bound (lib/api/sessions.js handleLeadModelSwitch: 4 KiB), so a body
|
|
1024
|
+
// the hub itself would refuse is never dialled out. The bytes forwarded are the caller's, as-is.
|
|
1025
|
+
const LEAD_MODEL_BODY_LIMIT_BYTES = 4 * 1024;
|
|
1026
|
+
|
|
1027
|
+
/** The request's query string, unchanged ('' when there is none). */
|
|
1028
|
+
function _searchOf(req) {
|
|
1029
|
+
const raw = String((req && req.url) || '');
|
|
1030
|
+
const at = raw.indexOf('?');
|
|
1031
|
+
return at < 0 ? '' : raw.slice(at);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/** The request's own path — the part of `req.url` before `?`, never decoded/re-encoded. */
|
|
1035
|
+
function _pathOf(req) {
|
|
1036
|
+
const raw = String((req && req.url) || '');
|
|
1037
|
+
const at = raw.indexOf('?');
|
|
1038
|
+
return at < 0 ? raw : raw.slice(0, at);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// D-4 (lib/remote-session-forward.js:58-61): the hub's OWN device token and the picker's routing
|
|
1042
|
+
// param belong to the first hop and must never be dialled to the box — the box's own `getAuthToken`
|
|
1043
|
+
// prefers `?token=` over the peer Bearer, so a forwarded `token` would shadow the peer credential.
|
|
1044
|
+
const DELEGATE_PREFS_STRIPPED_PARAMS = Object.freeze(['token', 'machine']);
|
|
1045
|
+
|
|
1046
|
+
// WP-1 (docs/remote-session-delegate-pick-write-forward-2026-10-30.html D-1/D-2): the delegate-prefs
|
|
1047
|
+
// READ plus the two WRITES that set a rung of the box's own ladder cross the same peer leg. Any other
|
|
1048
|
+
// verb is not a delegate-prefs forward at all (the caller keeps its unchanged local path).
|
|
1049
|
+
const DELEGATE_PREFS_FORWARD_METHODS = Object.freeze(['GET', 'PUT', 'DELETE']);
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* The delegate-prefs read's query string with the hub's protocol params removed ('' when nothing is
|
|
1053
|
+
* left). `ctm_session_id` and `agent` — everything that is the box's business — cross unchanged.
|
|
1054
|
+
*/
|
|
1055
|
+
function _delegatePrefsSearch(req) {
|
|
1056
|
+
const raw = _searchOf(req);
|
|
1057
|
+
if (!raw) return '';
|
|
1058
|
+
const params = new URLSearchParams(raw);
|
|
1059
|
+
for (const key of DELEGATE_PREFS_STRIPPED_PARAMS) params.delete(key);
|
|
1060
|
+
const rest = params.toString();
|
|
1061
|
+
return rest ? `?${rest}` : '';
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/** The request body as the caller wrote it, bounded like the local handler. */
|
|
1065
|
+
function _readLeadModelBody(req) {
|
|
1066
|
+
return new Promise((resolve, reject) => {
|
|
1067
|
+
let raw = '';
|
|
1068
|
+
let size = 0;
|
|
1069
|
+
let done = false;
|
|
1070
|
+
const finish = (fn, value) => { if (done) return; done = true; fn(value); };
|
|
1071
|
+
req.on('data', (chunk) => {
|
|
1072
|
+
if (done) return;
|
|
1073
|
+
size += chunk.length;
|
|
1074
|
+
if (size > LEAD_MODEL_BODY_LIMIT_BYTES) { finish(reject, new Error('request_body_too_large')); return; }
|
|
1075
|
+
raw += chunk;
|
|
1076
|
+
});
|
|
1077
|
+
req.on('end', () => finish(resolve, raw));
|
|
1078
|
+
req.on('error', (error) => finish(reject, error));
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* Like forwardLifecycleRequest: true = the request was answered here (do NOT run the local handler).
|
|
1084
|
+
*
|
|
1085
|
+
* @param {'options'|'switch'|'request'|'request-cancel'} kind
|
|
1086
|
+
* @returns {Promise<boolean>}
|
|
1087
|
+
*/
|
|
1088
|
+
async function forwardLeadModelRequest(req, res, sessionId, kind, deps = {}) {
|
|
1089
|
+
const d = _d(deps);
|
|
1090
|
+
const spec = LEAD_MODEL_FORWARDS[_string(kind, 20)];
|
|
1091
|
+
if (!spec) return false;
|
|
1092
|
+
const mirror = getMirrorSessionMachine(sessionId, d);
|
|
1093
|
+
if (!mirror) return false; // a LOCAL session takes the byte-identical existing path
|
|
1094
|
+
const target = _forwardTarget(res, mirror, d);
|
|
1095
|
+
if (!target) return true;
|
|
1096
|
+
let body = '';
|
|
1097
|
+
if (spec.method === 'POST') {
|
|
1098
|
+
// Mirrors lib/api/sessions.js handleLeadModelSwitch's own admission (413 too large / 400
|
|
1099
|
+
// otherwise, same body) so the two agreement points cannot drift.
|
|
1100
|
+
try { body = await _readLeadModelBody(req); }
|
|
1101
|
+
catch (error) { return _sendJson(res, error && error.message === 'request_body_too_large' ? 413 : 400, { ok: false, code: 'invalid_request', message: error && error.message || 'Invalid request.' }); }
|
|
1102
|
+
}
|
|
1103
|
+
const result = await target.proxy.forwardMachineHttp({
|
|
1104
|
+
machine: target.machine,
|
|
1105
|
+
pathname: `/api/sessions/${encodeURIComponent(sessionId)}${spec.suffix}`,
|
|
1106
|
+
search: _searchOf(req),
|
|
1107
|
+
method: spec.method,
|
|
1108
|
+
body,
|
|
1109
|
+
deps: d,
|
|
1110
|
+
});
|
|
1111
|
+
return _relayBoxAnswer(res, result, mirror, target.machineName);
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
* WP-3 (docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html §5 D-4) GET,
|
|
1116
|
+
* and WP-1 (docs/remote-session-delegate-pick-write-forward-2026-10-30.html D-1/D-2/D-7) PUT/DELETE:
|
|
1117
|
+
* /api/models/delegate-prefs[?ctm_session_id=<id>&agent=<a>] for a BOX-owned session is answered by
|
|
1118
|
+
* the box's own Wall-E ladder (session pick > per-agent default > vendor), not the hub's — the READ,
|
|
1119
|
+
* and the per-session / per-agent WRITES that set those rungs, take the same peer leg. Returns true
|
|
1120
|
+
* when the response was written (forwarded or refused); false for a local/unclaimed id or an
|
|
1121
|
+
* unsupported verb (the caller takes the unchanged proxyHttp path).
|
|
1122
|
+
*
|
|
1123
|
+
* @returns {Promise<boolean>}
|
|
1124
|
+
*/
|
|
1125
|
+
async function forwardDelegatePrefsRequest(req, res, sessionId, deps = {}) {
|
|
1126
|
+
const d = _d(deps);
|
|
1127
|
+
const method = String((req && req.method) || '').toUpperCase();
|
|
1128
|
+
if (!DELEGATE_PREFS_FORWARD_METHODS.includes(method)) return false;
|
|
1129
|
+
const mirror = getMirrorSessionMachine(sessionId, d);
|
|
1130
|
+
if (!mirror) return false; // a LOCAL session takes the byte-identical existing path
|
|
1131
|
+
const target = _forwardTarget(res, mirror, d);
|
|
1132
|
+
if (!target) return true;
|
|
1133
|
+
let body = '';
|
|
1134
|
+
if (method === 'PUT') {
|
|
1135
|
+
// Mirrors lib/api/sessions.js handleLeadModelSwitch's own admission (413 too large / 400
|
|
1136
|
+
// otherwise, same body) so the two agreement points cannot drift.
|
|
1137
|
+
try { body = await _readLeadModelBody(req); }
|
|
1138
|
+
catch (error) { return _sendJson(res, error && error.message === 'request_body_too_large' ? 413 : 400, { ok: false, code: 'invalid_request', message: error && error.message || 'Invalid request.' }); }
|
|
1139
|
+
}
|
|
1140
|
+
const result = await target.proxy.forwardMachineHttp({
|
|
1141
|
+
machine: target.machine,
|
|
1142
|
+
pathname: _pathOf(req),
|
|
1143
|
+
search: _delegatePrefsSearch(req),
|
|
1144
|
+
method,
|
|
1145
|
+
body,
|
|
1146
|
+
deps: d,
|
|
1147
|
+
});
|
|
1148
|
+
return _relayBoxAnswer(res, result, mirror, target.machineName);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* WP-1/AC-1h (docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html): the
|
|
1153
|
+
* sidebar's "Clear N finished" retires a lead's finished workers by POSTing { lead } (or { ids }) to
|
|
1154
|
+
* /api/sessions/workers/retire. For a BOX-owned lead those rows live in the box's worker_sessions,
|
|
1155
|
+
* so the call is forwarded to the owning machine by looking the ids up in the mirror union.
|
|
1156
|
+
* Returns true when the response was written (forwarded, or refused); false when every id is local
|
|
1157
|
+
* or unclaimed (the caller runs the byte-identical local path).
|
|
1158
|
+
*
|
|
1159
|
+
* Unlike the per-session forwards above, this route carries the ids in its BODY, not in the path — so
|
|
1160
|
+
* the ownership decision is made here, after the caller has parsed and validated the JSON, and the
|
|
1161
|
+
* body is re-serialized byte-for-byte to the one machine that owns every id.
|
|
1162
|
+
*
|
|
1163
|
+
* @param {object} body the already-parsed, already-validated request body ({ ids?: string[], lead?: string })
|
|
1164
|
+
* @returns {Promise<boolean>}
|
|
1165
|
+
*/
|
|
1166
|
+
async function forwardWorkersRetireRequest(req, res, body, deps = {}) {
|
|
1167
|
+
const d = _d(deps);
|
|
1168
|
+
const raw = body && typeof body === 'object' ? body : {};
|
|
1169
|
+
const candidates = [];
|
|
1170
|
+
if (typeof raw.lead === 'string' && raw.lead.trim()) candidates.push(raw.lead.trim());
|
|
1171
|
+
if (Array.isArray(raw.ids)) {
|
|
1172
|
+
for (const entry of raw.ids) {
|
|
1173
|
+
const id = _string(entry, 200);
|
|
1174
|
+
if (id) candidates.push(id);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
if (!candidates.length) return false;
|
|
1178
|
+
const mirrors = candidates.map((id) => getMirrorSessionMachine(id, d));
|
|
1179
|
+
const claimed = mirrors.filter(Boolean);
|
|
1180
|
+
if (!claimed.length) return false; // every id is local or unclaimed: the byte-identical local path
|
|
1181
|
+
const machineInstanceId = claimed[0].machineInstanceId;
|
|
1182
|
+
// A mix of local and mirror ids, or mirrors of two different machines, has no single owner to send
|
|
1183
|
+
// the one POST to — never split the call, never apply half of it here.
|
|
1184
|
+
if (claimed.length !== candidates.length || claimed.some((m) => m.machineInstanceId !== machineInstanceId)) {
|
|
1185
|
+
_sendJson(res, 400, { ok: false, code: 'mixed_owners', message: 'Retire ids must all belong to one machine.' });
|
|
1186
|
+
return true;
|
|
1187
|
+
}
|
|
1188
|
+
const mirror = claimed[0];
|
|
1189
|
+
const target = _forwardTarget(res, mirror, d);
|
|
1190
|
+
if (!target) return true; // a refusal was already written
|
|
1191
|
+
const result = await target.proxy.forwardMachineHttp({
|
|
1192
|
+
machine: target.machine,
|
|
1193
|
+
pathname: '/api/sessions/workers/retire',
|
|
1194
|
+
search: '',
|
|
1195
|
+
method: 'POST',
|
|
1196
|
+
// forwardMachineHttp sets `Content-Type: application/json` itself for a non-GET/HEAD verb; the
|
|
1197
|
+
// caller's own JSON body crosses unmodified.
|
|
1198
|
+
body: JSON.stringify(raw),
|
|
1199
|
+
deps: d,
|
|
1200
|
+
});
|
|
1201
|
+
return _relayBoxAnswer(res, result, mirror, target.machineName);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/**
|
|
1205
|
+
* WP-1 (docs/remote-session-rename-forward-and-empty-rows-2026-10-30.html §5 D-1/D-2): a rename or
|
|
1206
|
+
* star of a BOX-owned session is the box's write. Body-keyed like forwardWorkersRetireRequest: the
|
|
1207
|
+
* caller has parsed and validated the JSON; the body is re-serialized to the owning box's same route.
|
|
1208
|
+
* Returns true when the response was written (forwarded or refused); false for a local/unclaimed id
|
|
1209
|
+
* (the caller runs the byte-identical local path).
|
|
1210
|
+
*
|
|
1211
|
+
* @param {object} body the already-parsed request body ({ sessionId?: string, id?: string, ... })
|
|
1212
|
+
* @returns {Promise<boolean>}
|
|
1213
|
+
*/
|
|
1214
|
+
async function forwardSessionTitleWrite(req, res, body, deps = {}) {
|
|
1215
|
+
const d = _d(deps);
|
|
1216
|
+
const raw = body && typeof body === 'object' ? body : {};
|
|
1217
|
+
const id = _string(raw.sessionId || raw.id, 200);
|
|
1218
|
+
if (!id) return false;
|
|
1219
|
+
const mirror = getMirrorSessionMachine(id, d);
|
|
1220
|
+
if (!mirror) return false;
|
|
1221
|
+
const target = _forwardTarget(res, mirror, d);
|
|
1222
|
+
if (!target) return true;
|
|
1223
|
+
const result = await target.proxy.forwardMachineHttp({
|
|
1224
|
+
machine: target.machine, pathname: _pathOf(req), search: '', method: 'POST',
|
|
1225
|
+
body: JSON.stringify(raw), deps: d,
|
|
1226
|
+
});
|
|
1227
|
+
return _relayBoxAnswer(res, result, mirror, target.machineName);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
949
1230
|
function _sendJson(res, status, payload) {
|
|
950
1231
|
const body = JSON.stringify(payload);
|
|
951
1232
|
if (res.headersSent) return true;
|
|
@@ -1045,6 +1326,9 @@ module.exports = {
|
|
|
1045
1326
|
ingestFenceCounters,
|
|
1046
1327
|
catalogFor,
|
|
1047
1328
|
catalogSessionIds,
|
|
1329
|
+
// WP-5 (§5.4): the hub's own truth for "a box tab may still be on its way" + the multi-machine gate.
|
|
1330
|
+
catalogPendingCount,
|
|
1331
|
+
hasEnabledMachines,
|
|
1048
1332
|
fetchCatalog,
|
|
1049
1333
|
refreshAll,
|
|
1050
1334
|
onLinkReady,
|
|
@@ -1056,6 +1340,17 @@ module.exports = {
|
|
|
1056
1340
|
mergeSessionRows,
|
|
1057
1341
|
lastMergeSignature,
|
|
1058
1342
|
forwardLifecycleRequest,
|
|
1343
|
+
// WP-2 (§6.3): the picker's four lead-model calls for a MIRROR session go to the box that owns it.
|
|
1344
|
+
forwardLeadModelRequest,
|
|
1345
|
+
// WP-3 (§5 D-4): the Delegate pane's ladder read for a BOX-owned session is answered by the box.
|
|
1346
|
+
forwardDelegatePrefsRequest,
|
|
1347
|
+
// WP-1 (docs/remote-session-child-transcript-model-truth-and-restart-2026-10-27.html AC-1h): the
|
|
1348
|
+
// body-keyed sibling — "Clear N finished" for a BOX-owned lead retires on the box that owns it.
|
|
1349
|
+
forwardWorkersRetireRequest,
|
|
1350
|
+
// WP-1 (docs/remote-session-rename-forward-and-empty-rows-2026-10-30.html §5 D-1/D-2, §8 WP-1): a
|
|
1351
|
+
// rename or star of a BOX-owned session is the box's write — the body-keyed sibling that forwards it
|
|
1352
|
+
// to the owning machine's same route instead of writing the hub's ledger for an id it does not own.
|
|
1353
|
+
forwardSessionTitleWrite,
|
|
1059
1354
|
resumeMachineFor,
|
|
1060
1355
|
forwardResumeOnMachine,
|
|
1061
1356
|
_resetForTests,
|