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,409 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-0 (docs/remote-session-hub-bridge-2026-10-30.html §5 R-2/R-7/R-8, §6.1, §6.2, §6.3, §8 WP-0):
|
|
4
|
+
// the BOX side of the box -> hub request lane.
|
|
5
|
+
//
|
|
6
|
+
// The BOX never dials the hub (NAT / corp networks — machine-registry.js:12-13). Instead the hub
|
|
7
|
+
// dials the box's /ws and keeps ONE CONTROL link per machine; the box identifies that link when the
|
|
8
|
+
// hub sends `hub-bridge-hello` (lib/hub-bridge.js `controlHelloFrame`). This module is the box's
|
|
9
|
+
// registry of those links plus the pending-request table:
|
|
10
|
+
//
|
|
11
|
+
// noteHello(ws, frame) record { hubInstanceId, hubDisplayName, ws } (dropped on ws 'close')
|
|
12
|
+
// status({session?}) { role, hubs:[…], poolMembers, self, session? } (R-5; see the fn doc)
|
|
13
|
+
// call({...}) mint a rid, send `hub-bridge-request` on the chosen hub, await the reply
|
|
14
|
+
// (R-3: the session's recorded creator hub is the default target)
|
|
15
|
+
//
|
|
16
|
+
// R-7, the rule this module exists to keep: a failure is a NAMED error — `hub_unreachable`,
|
|
17
|
+
// `hub_ambiguous`, `hub_bridge_disabled` — and NEVER a local fallback. Nothing here runs the op.
|
|
18
|
+
|
|
19
|
+
const crypto = require('node:crypto');
|
|
20
|
+
const { boolFlag } = require('./env-flags');
|
|
21
|
+
// The single admitted ws-send primitive (lib/ws-send-admission.js `sendFrame`): the peer-control
|
|
22
|
+
// lane carries protocol frames, not browser streaming traffic, so admission is skipped — but the
|
|
23
|
+
// send still goes through the choke point rather than a raw `ws.send(` (see bin/off-protocol-send-lint.js).
|
|
24
|
+
const { sendFrame } = require('./ws-send-admission');
|
|
25
|
+
|
|
26
|
+
const BRIDGE_VERSION = 1;
|
|
27
|
+
const DEFAULT_DEADLINE_MS = 30000;
|
|
28
|
+
const MAX_DEADLINE_MS = 122000; // R-8: exec 120 s + the Wall-E client's 2 s grace (wall-e/memory/hub-bridge-client.js)
|
|
29
|
+
|
|
30
|
+
let _deps = null;
|
|
31
|
+
// ws -> { hubInstanceId, hubDisplayName, ws }. One entry per live hub CONTROL link.
|
|
32
|
+
const _hubs = new Map();
|
|
33
|
+
// The sockets we have already bound a 'close' listener to (a hub may re-hello on the same socket).
|
|
34
|
+
const _bound = new WeakSet();
|
|
35
|
+
// rid -> { resolve, timer, ws }.
|
|
36
|
+
const _pending = new Map();
|
|
37
|
+
|
|
38
|
+
const DEFAULT_DEPS = {
|
|
39
|
+
randomUUID: () => crypto.randomUUID(),
|
|
40
|
+
setTimeoutFn: (fn, ms) => setTimeout(fn, ms),
|
|
41
|
+
clearTimeoutFn: (id) => clearTimeout(id),
|
|
42
|
+
// R-10: how many OTHER machines share this box's pool. Still REPORTED by status(), but no reader
|
|
43
|
+
// may gate on it (R-1: a session's `hub_*` visibility comes from `role` or its creator-hub record).
|
|
44
|
+
// Absent dep (or a roster fault) reports 0.
|
|
45
|
+
poolMemberCount: () => 0,
|
|
46
|
+
// R-5: this box's own identity (lib/hub-bridge.js `selfIdentity()`) — the same values the hello
|
|
47
|
+
// names. Absent dep (or an unready identity) reports empty strings.
|
|
48
|
+
selfIdentity: () => ({ instanceId: '', displayName: '' }),
|
|
49
|
+
// R-3/R-5: the authenticated creator-hub record for a CTM session id (`{hubPeerId, ...} | null`,
|
|
50
|
+
// lib/agent-bundle/store.js `sessionHubRecord`), written before the session spawns
|
|
51
|
+
// (lib/ws/terminal-attach.js). Absent/unconfigured reads as "no record".
|
|
52
|
+
sessionHubRecord: async () => null,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function configure(deps = {}) {
|
|
56
|
+
_deps = { ...DEFAULT_DEPS, ...(deps || {}) };
|
|
57
|
+
return _deps;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function _d() {
|
|
61
|
+
return _deps || DEFAULT_DEPS;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Flag read at CALL time so a test can flip CTM_HUB_BRIDGE per-process (never at module load). */
|
|
65
|
+
function isEnabled() {
|
|
66
|
+
return boolFlag('CTM_HUB_BRIDGE', true);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** A socket counts as connected while it is OPEN (a simple fake with no readyState counts too). */
|
|
70
|
+
function _isOpen(ws) {
|
|
71
|
+
if (!ws) return false;
|
|
72
|
+
return ws.readyState === undefined || ws.readyState === null || ws.readyState === 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Record a hub CONTROL link from its `hub-bridge-hello`. Idempotent per socket (a re-hello just
|
|
77
|
+
* refreshes the identity). The entry is dropped when the socket closes, and every pending request
|
|
78
|
+
* on it is settled with `hub_unreachable` (R-7 — a mid-request close is never retried locally).
|
|
79
|
+
*/
|
|
80
|
+
function noteHello(ws, frame) {
|
|
81
|
+
if (!ws) return null;
|
|
82
|
+
const entry = {
|
|
83
|
+
hubInstanceId: String((frame && frame.hubInstanceId) || ''),
|
|
84
|
+
hubDisplayName: String((frame && frame.hubDisplayName) || ''),
|
|
85
|
+
ws,
|
|
86
|
+
};
|
|
87
|
+
_hubs.set(ws, entry);
|
|
88
|
+
// WP-1 (§5 D-1/D-2, §9 S-2): a hub is attached to this box, so hold the box's own power
|
|
89
|
+
// assertion (lib/box-keep-awake.js) — no hub hello, no assertion. Best-effort and never awaited.
|
|
90
|
+
try {
|
|
91
|
+
require('./box-keep-awake').noteHubLinked();
|
|
92
|
+
} catch {
|
|
93
|
+
/* expected: keep-awake is best-effort and must never break the hub link */
|
|
94
|
+
}
|
|
95
|
+
if (!_bound.has(ws) && typeof ws.on === 'function') {
|
|
96
|
+
_bound.add(ws);
|
|
97
|
+
try {
|
|
98
|
+
ws.on('close', () => {
|
|
99
|
+
_hubs.delete(ws);
|
|
100
|
+
_failPendingOn(ws);
|
|
101
|
+
});
|
|
102
|
+
} catch {
|
|
103
|
+
// expected: a socket that cannot be listened to simply keeps its entry until the next status().
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return entry;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* R-10: the other pool members this box could ask for a hub session. `rosterMembers()` includes
|
|
111
|
+
* self, so self is subtracted; a fault is reported as 0. Nothing gates on the value any more (R-1) —
|
|
112
|
+
* it is reported because Wall-E's status reader still shows it.
|
|
113
|
+
*/
|
|
114
|
+
function _poolMemberCount() {
|
|
115
|
+
const d = _d();
|
|
116
|
+
if (typeof d.poolMemberCount !== 'function') return 0;
|
|
117
|
+
try {
|
|
118
|
+
const value = Math.trunc(Number(d.poolMemberCount()));
|
|
119
|
+
return Number.isFinite(value) && value > 0 ? value : 0;
|
|
120
|
+
} catch {
|
|
121
|
+
// REPORT via the 0 below: a roster fault reads as "no other members".
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** R-5 (§6.1): this box's own identity — `{instanceId, displayName}`, never a throw. */
|
|
127
|
+
function _selfIdentity() {
|
|
128
|
+
const d = _d();
|
|
129
|
+
try {
|
|
130
|
+
const identity = typeof d.selfIdentity === 'function' ? d.selfIdentity() : null;
|
|
131
|
+
return {
|
|
132
|
+
instanceId: String((identity && identity.instanceId) || ''),
|
|
133
|
+
displayName: String((identity && identity.displayName) || ''),
|
|
134
|
+
};
|
|
135
|
+
} catch {
|
|
136
|
+
// REPORT via the empty identity below: an unready identity is simply unnamed, never a fault.
|
|
137
|
+
return { instanceId: '', displayName: '' };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* R-3 (§6.2): the authenticated creator-hub record for `callerSessionId` (`{hubPeerId}`), or null.
|
|
143
|
+
* An invalid/absent id is null, and a read fault is REPORTED once and read as null — the caller then
|
|
144
|
+
* applies today's role/ambiguity rule, so a record fault can never invent a target hub.
|
|
145
|
+
*/
|
|
146
|
+
async function _readSessionHubRecord(callerSessionId) {
|
|
147
|
+
const d = _d();
|
|
148
|
+
if (typeof d.sessionHubRecord !== 'function') return null;
|
|
149
|
+
try {
|
|
150
|
+
const record = await d.sessionHubRecord(String(callerSessionId == null ? '' : callerSessionId));
|
|
151
|
+
if (!record || typeof record !== 'object') return null;
|
|
152
|
+
const hubPeerId = String(record.hubPeerId == null ? '' : record.hubPeerId).trim();
|
|
153
|
+
return hubPeerId ? { hubPeerId } : null;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
// REPORT: a record read fault is "no record" (R-3 keeps the wording rule below); the call still
|
|
156
|
+
// answers with a named refusal, and an explicit `machine` is untouched.
|
|
157
|
+
console.warn(`[hub-bridge] sessionHubRecord('${callerSessionId}') failed: ${error?.message || error}`);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* R-5 (§6.1): the `session` field of status(). The record's `hubPeerId` resolved against the hubs
|
|
164
|
+
* connected right now: `hubDisplayName` is the live hub's hello name, or the raw peer id when that
|
|
165
|
+
* hub is not connected. `null` when there is no record — never a 4xx (a reader treats null as "no
|
|
166
|
+
* record", an empty string as "no question").
|
|
167
|
+
*/
|
|
168
|
+
async function _sessionHubView(sessionId) {
|
|
169
|
+
const record = await _readSessionHubRecord(sessionId);
|
|
170
|
+
if (!record) return null;
|
|
171
|
+
const hub = _connectedHubs().find((entry) => String(entry.hubInstanceId || '') === record.hubPeerId) || null;
|
|
172
|
+
return {
|
|
173
|
+
hubInstanceId: record.hubPeerId,
|
|
174
|
+
hubDisplayName: hub ? String(hub.hubDisplayName || '') : record.hubPeerId,
|
|
175
|
+
connected: !!hub,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* R-5 (§6.1): who this box is, and — when `opts.session` names a CTM session — whether that session's
|
|
181
|
+
* creator hub is connected. `role`/`hubs`/`poolMembers` keep their names and meaning; `self` is new.
|
|
182
|
+
* Async because the optional session lookup reads the creator-hub record from disk.
|
|
183
|
+
*
|
|
184
|
+
* @param {{ session?: string }} [opts] a CTM session id (`?session=`); falsy => no `session` key.
|
|
185
|
+
*/
|
|
186
|
+
async function status(opts = {}) {
|
|
187
|
+
const hubs = [..._hubs.values()].map((entry) => ({
|
|
188
|
+
hubInstanceId: entry.hubInstanceId,
|
|
189
|
+
hubDisplayName: entry.hubDisplayName,
|
|
190
|
+
connected: _isOpen(entry.ws),
|
|
191
|
+
}));
|
|
192
|
+
const out = {
|
|
193
|
+
role: _hubs.size ? 'box' : 'none',
|
|
194
|
+
hubs,
|
|
195
|
+
poolMembers: _poolMemberCount(),
|
|
196
|
+
self: _selfIdentity(),
|
|
197
|
+
// WP-1 (§9 S-3): additive — whether this box is holding the keep-awake assertion.
|
|
198
|
+
keepAwake: require('./box-keep-awake').status(),
|
|
199
|
+
};
|
|
200
|
+
const sessionId = String((opts && opts.session) || '').trim();
|
|
201
|
+
if (sessionId) out.session = await _sessionHubView(sessionId);
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function _settle(rid, payload) {
|
|
206
|
+
const pending = _pending.get(rid);
|
|
207
|
+
if (!pending) return false;
|
|
208
|
+
_pending.delete(rid);
|
|
209
|
+
if (pending.timer) {
|
|
210
|
+
try {
|
|
211
|
+
_d().clearTimeoutFn(pending.timer);
|
|
212
|
+
} catch {
|
|
213
|
+
// expected: the injected timer already fired.
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
pending.resolve(payload);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function _failPendingOn(ws) {
|
|
221
|
+
for (const [rid, pending] of [..._pending.entries()]) {
|
|
222
|
+
if (pending.ws === ws) _settle(rid, { ok: false, error: { code: 'hub_unreachable', message: 'socket_closed' } });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Settle the pending request for `frame.rid` from a hub's `hub-bridge-response`. A late reply — one
|
|
228
|
+
* whose rid was already settled by the deadline or a socket close — is dropped silently (the design
|
|
229
|
+
* says so explicitly: the box-side deadline owns the outcome once it passes).
|
|
230
|
+
*/
|
|
231
|
+
function noteResponse(frame) {
|
|
232
|
+
if (!frame || typeof frame !== 'object') return false;
|
|
233
|
+
const rid = typeof frame.rid === 'string' ? frame.rid : '';
|
|
234
|
+
if (!rid || !_pending.has(rid)) return false;
|
|
235
|
+
const payload = frame.ok
|
|
236
|
+
? { ok: true, result: frame.result === undefined ? null : frame.result, ...(frame.truncated ? { truncated: true } : {}) }
|
|
237
|
+
: { ok: false, error: frame.error || { code: 'op_failed', message: '' } };
|
|
238
|
+
return _settle(rid, payload);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** A hub link we may send on: one that is registered and still open. */
|
|
242
|
+
function _connectedHubs() {
|
|
243
|
+
return [..._hubs.values()].filter((entry) => _isOpen(entry.ws));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** `id (Display Name)`, or just the id — the retry hint a `machine` refusal carries. */
|
|
247
|
+
function _hubLabel(entry) {
|
|
248
|
+
const name = String((entry && entry.hubDisplayName) || '').trim();
|
|
249
|
+
return name ? `${entry.hubInstanceId} (${name})` : String((entry && entry.hubInstanceId) || '');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Every connected hub, named — what an unreachable/ambiguous refusal must tell the agent. */
|
|
253
|
+
function _hubNames(hubs) {
|
|
254
|
+
return hubs.map(_hubLabel).join(', ') || '(none)';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* WP-5 (R-12): the connected hub a `machine` target names — by instance id first, then by display
|
|
259
|
+
* name case-insensitively. Null when nothing matches (the caller answers `hub_unreachable` naming
|
|
260
|
+
* the hubs it DID reach).
|
|
261
|
+
*/
|
|
262
|
+
function _matchHub(hubs, machine) {
|
|
263
|
+
const wanted = String(machine == null ? '' : machine).trim();
|
|
264
|
+
if (!wanted) return null;
|
|
265
|
+
const lower = wanted.toLowerCase();
|
|
266
|
+
return hubs.find((entry) => String(entry.hubInstanceId || '') === wanted)
|
|
267
|
+
|| hubs.find((entry) => String(entry.hubDisplayName || '').toLowerCase() === lower)
|
|
268
|
+
|| null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** R-3: the hub entry whose `hubInstanceId` is `hubInstanceId`, or null. */
|
|
272
|
+
function _hubByInstanceId(hubs, hubInstanceId) {
|
|
273
|
+
const wanted = String(hubInstanceId == null ? '' : hubInstanceId);
|
|
274
|
+
return hubs.find((entry) => String(entry.hubInstanceId || '') === wanted) || null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* R-3 (§6.2): pick the hub for one call and put the request frame on it. Every refusal is named and
|
|
279
|
+
* NOTHING is sent on it (R-7 — no local fallback).
|
|
280
|
+
*
|
|
281
|
+
* - `machine` non-empty: the connected hub it names, else `hub_unreachable` (naming the connected).
|
|
282
|
+
* - no `machine`: the session's recorded CREATOR hub — the authenticated peer written to
|
|
283
|
+
* `sessions/<id>.json` before the session spawned (`sessionHubRecord`, resolved through the dep
|
|
284
|
+
* below). A record whose hub is NOT connected is `hub_unreachable` naming that hub and the hubs
|
|
285
|
+
* that ARE connected; it is never silently swapped for another hub.
|
|
286
|
+
* - no record at all (or a record read fault): today's rule — exactly one connected hub -> it; more
|
|
287
|
+
* than one -> `hub_ambiguous`, naming them.
|
|
288
|
+
*/
|
|
289
|
+
async function _selectAndSend(resolve, { callerSessionId, op, args, machine, deadlineMs = DEFAULT_DEADLINE_MS }) {
|
|
290
|
+
if (!isEnabled()) {
|
|
291
|
+
return resolve({ ok: false, error: { code: 'hub_bridge_disabled', message: 'CTM_HUB_BRIDGE=0 on the box' } });
|
|
292
|
+
}
|
|
293
|
+
const hubs = _connectedHubs();
|
|
294
|
+
if (!hubs.length) {
|
|
295
|
+
return resolve({ ok: false, error: { code: 'hub_unreachable', message: 'no hub control link' } });
|
|
296
|
+
}
|
|
297
|
+
const wanted = String(machine == null ? '' : machine).trim();
|
|
298
|
+
let hub = null;
|
|
299
|
+
if (wanted) {
|
|
300
|
+
hub = _matchHub(hubs, wanted);
|
|
301
|
+
if (!hub) {
|
|
302
|
+
return resolve({
|
|
303
|
+
ok: false,
|
|
304
|
+
error: {
|
|
305
|
+
code: 'hub_unreachable',
|
|
306
|
+
message: `no connected hub matches machine '${wanted}' (connected hubs: ${_hubNames(hubs)})`,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
const record = await _readSessionHubRecord(callerSessionId);
|
|
312
|
+
if (record) {
|
|
313
|
+
hub = _hubByInstanceId(hubs, record.hubPeerId);
|
|
314
|
+
if (!hub) {
|
|
315
|
+
return resolve({
|
|
316
|
+
ok: false,
|
|
317
|
+
error: {
|
|
318
|
+
code: 'hub_unreachable',
|
|
319
|
+
message: `creator hub '${record.hubPeerId}' is not connected (connected hubs: ${_hubNames(hubs)})`,
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
} else if (hubs.length > 1) {
|
|
324
|
+
return resolve({
|
|
325
|
+
ok: false,
|
|
326
|
+
error: {
|
|
327
|
+
code: 'hub_ambiguous',
|
|
328
|
+
message: `${hubs.length} hubs are connected: ${_hubNames(hubs)} — pass 'machine' (an instance id or name) to choose one`,
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
} else {
|
|
332
|
+
hub = hubs[0];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
_send(hub, resolve, { callerSessionId, op, args, deadlineMs });
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Mint a rid, arm the deadline, and put the request frame on `hub` (the resolve is settled later). */
|
|
339
|
+
function _send(hub, resolve, { callerSessionId, op, args, deadlineMs }) {
|
|
340
|
+
const d = _d();
|
|
341
|
+
const rid = d.randomUUID();
|
|
342
|
+
const wait = Math.min(Math.max(1, Number(deadlineMs) || DEFAULT_DEADLINE_MS), MAX_DEADLINE_MS);
|
|
343
|
+
const entry = { resolve, timer: null, ws: hub.ws };
|
|
344
|
+
_pending.set(rid, entry);
|
|
345
|
+
entry.timer = d.setTimeoutFn(() => {
|
|
346
|
+
_settle(rid, { ok: false, error: { code: 'hub_unreachable', message: 'deadline' } });
|
|
347
|
+
}, wait);
|
|
348
|
+
if (entry.timer && typeof entry.timer.unref === 'function') entry.timer.unref();
|
|
349
|
+
const frame = {
|
|
350
|
+
type: 'hub-bridge-request',
|
|
351
|
+
v: BRIDGE_VERSION,
|
|
352
|
+
rid,
|
|
353
|
+
callerSessionId: String(callerSessionId || ''),
|
|
354
|
+
op: String(op || ''),
|
|
355
|
+
args: args === undefined ? {} : args,
|
|
356
|
+
deadlineMs: wait,
|
|
357
|
+
};
|
|
358
|
+
// REPORT: a send failure (or a socket that is already closed) is a named hub_unreachable, settled
|
|
359
|
+
// through the same table.
|
|
360
|
+
if (!sendFrame(hub.ws, JSON.stringify(frame))) {
|
|
361
|
+
_settle(rid, { ok: false, error: { code: 'hub_unreachable', message: 'send_failed' } });
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Ask the hub that dialled us to run `op`. Resolves `{ok:true, result}` or `{ok:false, error}` —
|
|
367
|
+
* never rejects, and never runs anything locally (R-7). Hub choice is `_selectAndSend` above.
|
|
368
|
+
*/
|
|
369
|
+
function call({ callerSessionId, op, args, machine, deadlineMs = DEFAULT_DEADLINE_MS } = {}) {
|
|
370
|
+
return new Promise((resolve) => {
|
|
371
|
+
// The executor is NOT async (an async executor would swallow a mid-flight throw into an unhandled
|
|
372
|
+
// rejection); the one async step is the creator-hub lookup, and this tail keeps R-7's "never
|
|
373
|
+
// rejects" contract even if that lookup faults.
|
|
374
|
+
_selectAndSend(resolve, { callerSessionId, op, args, machine, deadlineMs }).catch((error) => {
|
|
375
|
+
// REPORT: an unexpected throw still answers as a named refusal, never as a rejection.
|
|
376
|
+
console.warn(`[hub-bridge] call() failed: ${error?.message || error}`);
|
|
377
|
+
resolve({ ok: false, error: { code: 'hub_unreachable', message: 'internal_error' } });
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function listHubs() {
|
|
383
|
+
return [..._hubs.values()].map((entry) => ({ hubInstanceId: entry.hubInstanceId, hubDisplayName: entry.hubDisplayName }));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function pendingCount() {
|
|
387
|
+
return _pending.size;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function _resetForTests() {
|
|
391
|
+
_deps = null;
|
|
392
|
+
_hubs.clear();
|
|
393
|
+
_pending.clear();
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
module.exports = {
|
|
397
|
+
BRIDGE_VERSION,
|
|
398
|
+
DEFAULT_DEADLINE_MS,
|
|
399
|
+
MAX_DEADLINE_MS,
|
|
400
|
+
configure,
|
|
401
|
+
isEnabled,
|
|
402
|
+
noteHello,
|
|
403
|
+
noteResponse,
|
|
404
|
+
status,
|
|
405
|
+
call,
|
|
406
|
+
listHubs,
|
|
407
|
+
pendingCount,
|
|
408
|
+
_resetForTests,
|
|
409
|
+
};
|