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
|
@@ -378,5 +378,35 @@
|
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
|
|
381
|
+
// The phone transcript page's one normalization: an array, `{messages}`, `{data}` or `{items}` all become
|
|
382
|
+
// the same page shape. Moved verbatim out of app.js (which is at its line ceiling) — one call site there.
|
|
383
|
+
function normalizeSessionMessagesPayload(data) {
|
|
384
|
+
if (Array.isArray(data)) {
|
|
385
|
+
return {
|
|
386
|
+
messages: data,
|
|
387
|
+
hasMore: false,
|
|
388
|
+
nextOffset: data.length,
|
|
389
|
+
total: data.length,
|
|
390
|
+
pageKind: 'messages',
|
|
391
|
+
conversationBudget: null,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
const messages = Array.isArray(data?.messages)
|
|
395
|
+
? data.messages
|
|
396
|
+
: (Array.isArray(data?.data) ? data.data : (Array.isArray(data?.items) ? data.items : []));
|
|
397
|
+
return {
|
|
398
|
+
messages,
|
|
399
|
+
hasMore: !!(data?.has_more || data?.hasMore),
|
|
400
|
+
nextOffset: Number.isFinite(Number(data?.next_offset ?? data?.nextOffset))
|
|
401
|
+
? Number(data?.next_offset ?? data?.nextOffset)
|
|
402
|
+
: messages.length,
|
|
403
|
+
total: Number.isFinite(Number(data?.total)) ? Number(data.total) : messages.length,
|
|
404
|
+
pageKind: String(data?.page_kind || data?.pageKind || ''),
|
|
405
|
+
conversationBudget: data?.conversationBudget && typeof data.conversationBudget === 'object'
|
|
406
|
+
? data.conversationBudget
|
|
407
|
+
: null,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return { createMobilePrivateApi, runPhoneModelRequest, createIdentityCache, createConditionalIdentityFetch, CONDITIONAL_PATHS, normalizeSessionMessagesPayload };
|
|
382
412
|
});
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
<details class="reporting-panel"><summary>Reports and observational budgets</summary><div id="usage-reporting-host"></div></details>
|
|
56
56
|
</main>
|
|
57
57
|
<script src="/js/usage-format.js"></script>
|
|
58
|
+
<script src="/js/pasted-content.js"></script>
|
|
58
59
|
<script src="/js/session-usage-view.js"></script>
|
|
59
60
|
<script src="/js/usage-reporting-view.js"></script>
|
|
60
61
|
<script>window.CTMSessionUsage.boot(document);</script>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-5 (coding-task-manager/docs/opencode-followups-agent-word-v2-waiting-dev-route-2026-10-31.html
|
|
4
|
+
// §4 "Synthetic route upstream", §6.5): the ONE loopback synthetic model upstream, extracted
|
|
5
|
+
// verbatim from tests/rendering/helpers/claude-routed-provider.js so that the render harness's
|
|
6
|
+
// routed-provider fixture and scripts/dev-route-fixture.js serve the same bytes from the same code.
|
|
7
|
+
//
|
|
8
|
+
// It is a synthetic upstream, never a provider: no credentials, no real vendor, no private source.
|
|
9
|
+
// GET /v1/models (or /models) -> the reachability answer a route probe reads
|
|
10
|
+
// POST /v1/chat/completions (or /chat/completions) -> a canned assistant turn (SSE when the
|
|
11
|
+
// request body says stream: true)
|
|
12
|
+
// anything else -> a bounded JSON 404
|
|
13
|
+
// `requests` records every request it answers (`{ method, url, body, model }`) so a caller can
|
|
14
|
+
// assert what a routed target actually sent. The canned turn is the constant SYNTHETIC_ROUTED_TURN
|
|
15
|
+
// under both the streaming and the non-streaming shape, so a routed turn can never hang here.
|
|
16
|
+
|
|
17
|
+
const http = require('node:http');
|
|
18
|
+
|
|
19
|
+
/** The one canned assistant turn; both the SSE delta and the JSON message carry it verbatim. */
|
|
20
|
+
const SYNTHETIC_ROUTED_TURN = 'SYNTHETIC_ROUTED_TURN';
|
|
21
|
+
|
|
22
|
+
function sendJson(res, status, body) {
|
|
23
|
+
const payload = JSON.stringify(body);
|
|
24
|
+
res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) });
|
|
25
|
+
res.end(payload);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function listen(server, host = '127.0.0.1') {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
server.once('error', reject);
|
|
31
|
+
server.listen(0, host, () => resolve(server.address().port));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Start the synthetic upstream on 127.0.0.1 (an OS-assigned port, never a fixed one -- a fixture
|
|
37
|
+
* that pinned a port would need a probe-close-rebind, which H-8 forbids).
|
|
38
|
+
*
|
|
39
|
+
* @param {{ wireModelId?: string }} [options] the model id this upstream lists and answers as.
|
|
40
|
+
* @returns {Promise<{ server: import('node:http').Server, port: number,
|
|
41
|
+
* requests: Array<{ method: string|undefined, url: string|undefined, body: string, model: string|null }>,
|
|
42
|
+
* close: () => Promise<void> }>}
|
|
43
|
+
*/
|
|
44
|
+
async function startSyntheticUpstream(options = {}) {
|
|
45
|
+
// Every caller names its wire model (the render fixture its WIRE_MODEL_ID, the dev fixture --model);
|
|
46
|
+
// shipped scripts carry no model id literal (model-roles lint R-4).
|
|
47
|
+
const wireModelId = String(options.wireModelId || '').trim();
|
|
48
|
+
if (!wireModelId) throw new TypeError('startSyntheticUpstream: wireModelId required');
|
|
49
|
+
const requests = [];
|
|
50
|
+
const server = http.createServer((req, res) => {
|
|
51
|
+
const chunks = [];
|
|
52
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
53
|
+
req.on('end', () => {
|
|
54
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
55
|
+
let parsed = {};
|
|
56
|
+
// expected: a body that is not JSON (an empty GET body, a probe) is recorded raw and still
|
|
57
|
+
// served the canned reply -- this upstream never fails on shape.
|
|
58
|
+
try { parsed = JSON.parse(raw); } catch { parsed = {}; }
|
|
59
|
+
requests.push({ method: req.method, url: req.url, body: raw, model: parsed?.model ?? null });
|
|
60
|
+
if (req.url === '/v1/models' || req.url === '/models') {
|
|
61
|
+
return sendJson(res, 200, { object: 'list', data: [{ id: wireModelId, object: 'model' }] });
|
|
62
|
+
}
|
|
63
|
+
if (req.url === '/v1/chat/completions' || req.url === '/chat/completions') {
|
|
64
|
+
if (parsed.stream) {
|
|
65
|
+
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
|
|
66
|
+
res.write(`data: ${JSON.stringify({ id: 'chatcmpl-synthetic', object: 'chat.completion.chunk',
|
|
67
|
+
model: wireModelId, choices: [{ index: 0, delta: { role: 'assistant', content: SYNTHETIC_ROUTED_TURN } }] })}\n\n`);
|
|
68
|
+
res.write(`data: ${JSON.stringify({ id: 'chatcmpl-synthetic', object: 'chat.completion.chunk',
|
|
69
|
+
model: wireModelId, choices: [{ index: 0, delta: {}, finish_reason: 'stop' }] })}\n\n`);
|
|
70
|
+
return res.end('data: [DONE]\n\n');
|
|
71
|
+
}
|
|
72
|
+
return sendJson(res, 200, { id: 'chatcmpl-synthetic', object: 'chat.completion', model: wireModelId,
|
|
73
|
+
choices: [{ index: 0, message: { role: 'assistant', content: SYNTHETIC_ROUTED_TURN }, finish_reason: 'stop' }],
|
|
74
|
+
usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 } });
|
|
75
|
+
}
|
|
76
|
+
return sendJson(res, 404, { error: 'not_found', path: req.url });
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
function close() {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
// Idempotent: a caller may close explicitly and again from its own finally (or after a
|
|
83
|
+
// signal handler already ran).
|
|
84
|
+
if (!server.listening) {
|
|
85
|
+
if (typeof server.closeAllConnections === 'function') server.closeAllConnections();
|
|
86
|
+
resolve();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// A keep-alive socket from a routed turn would otherwise hold close() open forever.
|
|
90
|
+
if (typeof server.closeAllConnections === 'function') server.closeAllConnections();
|
|
91
|
+
server.close((error) => (error ? reject(error) : resolve()));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const port = await listen(server);
|
|
96
|
+
return { server, port, requests, close };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
startSyntheticUpstream,
|
|
101
|
+
sendJson,
|
|
102
|
+
listen,
|
|
103
|
+
SYNTHETIC_ROUTED_TURN,
|
|
104
|
+
};
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// WP-5 (coding-task-manager/docs/opencode-followups-agent-word-v2-waiting-dev-route-2026-10-31.html
|
|
5
|
+
// §4 "Synthetic route upstream" / "Provider + registry write endpoints" / "Coding-catalog build",
|
|
6
|
+
// §5 D-9/D-10, §6.5): seed ONE synthetic routed model into a /ctm-dev instance and serve a loopback
|
|
7
|
+
// synthetic upstream for it, so routed model switching can be checked live on a fresh dev DB
|
|
8
|
+
// (bin/dev.sh --fresh deletes the dev databases, so a fresh instance has no routes at all).
|
|
9
|
+
//
|
|
10
|
+
// node scripts/dev-route-fixture.js --ctm-port <devPort> [--walle-port <n>]
|
|
11
|
+
// [--route-id dev-synthetic] [--model fixture/m-route]
|
|
12
|
+
// [--deadline-ms 7200000]
|
|
13
|
+
//
|
|
14
|
+
// Endpoint choice (§6.5 steps 3-4): CTM's lib/api/walle-bridge.js register() mounts
|
|
15
|
+
// { method: '*', prefix: '/api/models', handler: handleProxy }
|
|
16
|
+
// whose handleProxy pipes every /api/models* request straight to the instance's own WALL_E_PORT
|
|
17
|
+
// (proxyHttp, CTM never parses the body). Both writes -- and the coding-catalog read, and the
|
|
18
|
+
// teardown DELETE -- therefore go to --ctm-port; --walle-port is accepted, refused when it names the
|
|
19
|
+
// primary pair, and never used for a request.
|
|
20
|
+
//
|
|
21
|
+
// Field names come from the endpoints' own code, never from convenience:
|
|
22
|
+
// POST /api/models/providers spreads its body into the Wall-E brain upsertModelProvider
|
|
23
|
+
// upsertModelProvider({ id, name, type, baseUrl, apiKeyEncrypted, customHeaders, enabled,
|
|
24
|
+
// caCertPem, maxOutputTokens, reasoningField, reasoningEffortDefault }) -- CAMELCASE; the
|
|
25
|
+
// snake_case aliases (base_url/api_key/custom_headers) belong to /api/wall-e/setup/provider,
|
|
26
|
+
// not to this raw upsert route, and would be silently dropped here.
|
|
27
|
+
// POST /api/models/registry rejects any key outside MODEL_REGISTRY_POST_ALLOWED_FIELDS
|
|
28
|
+
// (wall-e/http/model-admin.js:77) with 400 `unknown field: <key>`, so this script sends that
|
|
29
|
+
// allowlist's spellings only.
|
|
30
|
+
// type 'openai-compatible' is what wall-e/llm/worker-route.js upstreamApisForRow() treats as
|
|
31
|
+
// routable on the openai-chat wire (the everything-else branch) -- the same type the render
|
|
32
|
+
// fixture's routeRow() uses.
|
|
33
|
+
//
|
|
34
|
+
// Exit codes: 0 clean shutdown (SIGTERM/SIGINT/--deadline-ms) after the teardown DELETE;
|
|
35
|
+
// 2 refused with NOT ONE request sent (missing --ctm-port, a primary --ctm-port/--walle-port, a
|
|
36
|
+
// port that is not a reachable dev CTM); 3 the coding catalog never listed a route for
|
|
37
|
+
// --route-id within 30 s (the catalog warnings are printed); 4 a write/read handshake failed.
|
|
38
|
+
//
|
|
39
|
+
// This script performs no filesystem I/O at all: it never reads or writes ~/.walle/data or any path
|
|
40
|
+
// outside the OS temp dir (the dev instance owns its own data dir).
|
|
41
|
+
|
|
42
|
+
const { startSyntheticUpstream } = require('./dev-route-fixture/synthetic-route-upstream');
|
|
43
|
+
|
|
44
|
+
// D-10: the user's live primary pair. Refused before any request, by either flag.
|
|
45
|
+
const PRIMARY_PORTS = new Set([3456, 3457]);
|
|
46
|
+
|
|
47
|
+
const POLL_INTERVAL_MS = 1000;
|
|
48
|
+
const POLL_DEADLINE_MS = 30_000;
|
|
49
|
+
const REQUEST_TIMEOUT_MS = 10_000;
|
|
50
|
+
const STATUS_TIMEOUT_MS = 5_000;
|
|
51
|
+
const PAGE_SIZE = 500;
|
|
52
|
+
const MAX_CATALOG_PAGES = 50;
|
|
53
|
+
const API_KEY = 'dev-synthetic-not-a-secret';
|
|
54
|
+
|
|
55
|
+
const DEFAULTS = Object.freeze({
|
|
56
|
+
routeId: 'dev-synthetic',
|
|
57
|
+
model: 'fixture/m-route',
|
|
58
|
+
deadlineMs: 7_200_000,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const FLAG_FIELDS = new Map([
|
|
62
|
+
['--ctm-port', 'ctmPort'],
|
|
63
|
+
['--walle-port', 'wallePort'],
|
|
64
|
+
['--route-id', 'routeId'],
|
|
65
|
+
['--model', 'model'],
|
|
66
|
+
['--deadline-ms', 'deadlineMs'],
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
/** A refusal (exit 2) or a handshake failure (exit 4) carrying the exit code its caller must use. */
|
|
70
|
+
class FixtureFailure extends Error {
|
|
71
|
+
constructor(exitCode, message) {
|
|
72
|
+
super(message);
|
|
73
|
+
this.name = 'FixtureFailure';
|
|
74
|
+
this.exitCode = exitCode;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function usageLine() {
|
|
79
|
+
return 'usage: node scripts/dev-route-fixture.js --ctm-port <devPort> [--walle-port <n>] '
|
|
80
|
+
+ '[--route-id dev-synthetic] [--model fixture/m-route] [--deadline-ms 7200000]';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function messageOf(error) {
|
|
84
|
+
return String(error?.message || error);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// REPORT + EXIT: every refusal is printed with the usage line and ends the process before the first
|
|
88
|
+
// network request (D-10). Never a throw the caller could swallow into a later request.
|
|
89
|
+
function refuse(message) {
|
|
90
|
+
process.stderr.write(`dev-route-fixture: refusing: ${message}\n${usageLine()}\n`);
|
|
91
|
+
process.exit(2);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function parsePort(raw, flag) {
|
|
95
|
+
if (raw === null || raw === undefined || raw === '') refuse(`${flag} needs a port number`);
|
|
96
|
+
const port = Number(raw);
|
|
97
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) refuse(`${flag} must be a port number (got ${JSON.stringify(raw)})`);
|
|
98
|
+
if (PRIMARY_PORTS.has(port)) refuse(`${flag} ${port} is the user's PRIMARY instance -- this fixture is dev-only (D-10)`);
|
|
99
|
+
return port;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Accepts `--flag value` and `--flag=value`; an unknown flag or a missing value refuses (a typo
|
|
103
|
+
// silently changing which instance is seeded would be worse than a refusal).
|
|
104
|
+
function parseArgs(argv) {
|
|
105
|
+
const args = { ...DEFAULTS, ctmPort: null, wallePort: null };
|
|
106
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
107
|
+
const token = argv[index];
|
|
108
|
+
const eq = token.indexOf('=');
|
|
109
|
+
const flag = eq === -1 ? token : token.slice(0, eq);
|
|
110
|
+
const field = FLAG_FIELDS.get(flag);
|
|
111
|
+
if (!field) refuse(`unknown argument ${JSON.stringify(token)}`);
|
|
112
|
+
let value = eq === -1 ? null : token.slice(eq + 1);
|
|
113
|
+
if (value === null) {
|
|
114
|
+
index += 1;
|
|
115
|
+
value = index < argv.length ? argv[index] : null;
|
|
116
|
+
if (value === null || value.startsWith('--')) refuse(`${flag} needs a value`);
|
|
117
|
+
}
|
|
118
|
+
args[field] = value;
|
|
119
|
+
}
|
|
120
|
+
args.ctmPort = parsePort(args.ctmPort, '--ctm-port');
|
|
121
|
+
args.wallePort = args.wallePort === null ? null : parsePort(args.wallePort, '--walle-port');
|
|
122
|
+
const deadlineMs = Number(args.deadlineMs);
|
|
123
|
+
if (!Number.isInteger(deadlineMs) || deadlineMs < 1_000) refuse(`--deadline-ms must be an integer >= 1000 (got ${JSON.stringify(args.deadlineMs)})`);
|
|
124
|
+
args.deadlineMs = deadlineMs;
|
|
125
|
+
args.model = String(args.model ?? '').trim();
|
|
126
|
+
if (!args.model) refuse('--model must not be empty');
|
|
127
|
+
args.routeId = String(args.routeId ?? '').trim();
|
|
128
|
+
if (!/^[A-Za-z0-9._:-]{1,80}$/.test(args.routeId)) refuse(`--route-id must match [A-Za-z0-9._:-]{1,80} (got ${JSON.stringify(args.routeId)})`);
|
|
129
|
+
return args;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function ctmBase(ctmPort) {
|
|
133
|
+
return `http://127.0.0.1:${ctmPort}`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// D-10 step 1: the port must really be a running CTM instance. Anything else refuses with no write.
|
|
137
|
+
async function requireDevInstance(ctmPort) {
|
|
138
|
+
const base = ctmBase(ctmPort);
|
|
139
|
+
let res = null;
|
|
140
|
+
let body = null;
|
|
141
|
+
try {
|
|
142
|
+
res = await fetch(`${base}/api/services/status`, { signal: AbortSignal.timeout(STATUS_TIMEOUT_MS) });
|
|
143
|
+
// expected: a non-JSON body is not a CTM status payload -- handled as `body = null` below, and
|
|
144
|
+
// read as a refusal rather than used.
|
|
145
|
+
try { body = await res.json(); } catch { body = null; }
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// REPORT + EXIT 2: nothing answered, so there is nothing to seed and nothing was sent.
|
|
148
|
+
refuse(`GET ${base}/api/services/status failed: ${messageOf(error)}`);
|
|
149
|
+
}
|
|
150
|
+
if (!res.ok) refuse(`GET ${base}/api/services/status -> HTTP ${res.status}`);
|
|
151
|
+
if (!body || body.ctm?.running !== true) refuse(`GET ${base}/api/services/status did not answer as a running CTM instance`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function postJson(url, body, what) {
|
|
155
|
+
let res = null;
|
|
156
|
+
try {
|
|
157
|
+
res = await fetch(url, {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: { 'Content-Type': 'application/json' },
|
|
160
|
+
body: JSON.stringify(body),
|
|
161
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
throw new FixtureFailure(4, `${what}: POST ${url} failed: ${messageOf(error)}`);
|
|
165
|
+
}
|
|
166
|
+
const text = await res.text();
|
|
167
|
+
if (!res.ok) throw new FixtureFailure(4, `${what}: POST ${url} -> HTTP ${res.status} ${text.slice(0, 400)}`);
|
|
168
|
+
return text;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function getJson(url) {
|
|
172
|
+
let res = null;
|
|
173
|
+
let body = null;
|
|
174
|
+
try {
|
|
175
|
+
res = await fetch(url, { signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
|
|
176
|
+
// expected: an error body that is not JSON is reported as the raw status line, never parsed.
|
|
177
|
+
try { body = await res.json(); } catch { body = null; }
|
|
178
|
+
} catch (error) {
|
|
179
|
+
throw new FixtureFailure(4, `GET ${url} failed: ${messageOf(error)}`);
|
|
180
|
+
}
|
|
181
|
+
if (!res.ok) throw new FixtureFailure(4, `GET ${url} -> HTTP ${res.status} ${body ? JSON.stringify(body).slice(0, 300) : ''}`);
|
|
182
|
+
return body;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// The provider row as the raw upsert route reads it (see the field-name note in the header).
|
|
186
|
+
function providerBody(args, upstreamPort) {
|
|
187
|
+
return {
|
|
188
|
+
id: args.routeId,
|
|
189
|
+
name: 'Dev synthetic',
|
|
190
|
+
type: 'openai-compatible',
|
|
191
|
+
baseUrl: `http://127.0.0.1:${upstreamPort}/v1`,
|
|
192
|
+
apiKeyEncrypted: API_KEY,
|
|
193
|
+
enabled: 1,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// The registry entry: MODEL_REGISTRY_POST_ALLOWED_FIELDS spellings only (id, providerId, modelId,
|
|
198
|
+
// displayName, capabilities, enabled, maxContextTokens, maxOutputTokens, source, verificationStatus).
|
|
199
|
+
function registryBody(args) {
|
|
200
|
+
return {
|
|
201
|
+
id: `${args.routeId}:${args.model}`,
|
|
202
|
+
providerId: args.routeId,
|
|
203
|
+
modelId: args.model,
|
|
204
|
+
displayName: `${args.model} (dev synthetic)`,
|
|
205
|
+
capabilities: ['chat', 'tools'],
|
|
206
|
+
enabled: 1,
|
|
207
|
+
maxContextTokens: 131072,
|
|
208
|
+
maxOutputTokens: 8192,
|
|
209
|
+
source: 'manual',
|
|
210
|
+
verificationStatus: 'verified',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function itemHasRoute(item, routeId) {
|
|
215
|
+
return Array.isArray(item?.routes) && item.routes.some((route) => route?.provider_id === routeId);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// One full paged walk of GET /api/models/coding-catalog, following next_page_token to the end the
|
|
219
|
+
// same way lib/walle-paged-read.js requestWalleAllPages does (a partial walk is never a verdict).
|
|
220
|
+
async function readCatalog(base) {
|
|
221
|
+
const items = [];
|
|
222
|
+
const warnings = [];
|
|
223
|
+
const seenTokens = new Set();
|
|
224
|
+
let token = '';
|
|
225
|
+
for (let page = 0; page < MAX_CATALOG_PAGES; page += 1) {
|
|
226
|
+
const query = new URLSearchParams({ page_size: String(PAGE_SIZE) });
|
|
227
|
+
if (token) query.set('page_token', token);
|
|
228
|
+
const body = await getJson(`${base}/api/models/coding-catalog?${query.toString()}`);
|
|
229
|
+
if (!Array.isArray(body?.models)) throw new FixtureFailure(4, 'GET /api/models/coding-catalog answered without a models array');
|
|
230
|
+
items.push(...body.models);
|
|
231
|
+
for (const warning of Array.isArray(body.catalog_warnings) ? body.catalog_warnings : []) warnings.push(warning);
|
|
232
|
+
if (typeof body.next_page_token !== 'string' || !body.next_page_token) return { items, warnings };
|
|
233
|
+
if (seenTokens.has(body.next_page_token)) throw new FixtureFailure(4, 'GET /api/models/coding-catalog repeated a next_page_token');
|
|
234
|
+
seenTokens.add(body.next_page_token);
|
|
235
|
+
token = body.next_page_token;
|
|
236
|
+
}
|
|
237
|
+
throw new FixtureFailure(4, `GET /api/models/coding-catalog did not finish within ${MAX_CATALOG_PAGES} pages`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function sleep(ms) {
|
|
241
|
+
return new Promise((resolve) => { setTimeout(resolve, ms); });
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// §6.5 step 4: poll every second for up to 30 s; the deadline is the loop's own bound, never a set
|
|
245
|
+
// number of attempts.
|
|
246
|
+
async function waitForCatalogRoute(base, routeId) {
|
|
247
|
+
const deadline = Date.now() + POLL_DEADLINE_MS;
|
|
248
|
+
for (;;) {
|
|
249
|
+
const catalog = await readCatalog(base);
|
|
250
|
+
if (catalog.items.some((item) => itemHasRoute(item, routeId))) return { ...catalog, found: true };
|
|
251
|
+
if (Date.now() >= deadline) return { ...catalog, found: false };
|
|
252
|
+
await sleep(POLL_INTERVAL_MS);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// §6.5 step 5: undo the provider row, then release the upstream. REPORT-only -- a cleanup that
|
|
257
|
+
// cannot reach a dev instance must never turn into a hang or hide the port release.
|
|
258
|
+
async function teardown({ base, routeId, upstream, deleteProvider }) {
|
|
259
|
+
if (deleteProvider) {
|
|
260
|
+
try {
|
|
261
|
+
const res = await fetch(`${base}/api/models/providers/${encodeURIComponent(routeId)}`, {
|
|
262
|
+
method: 'DELETE',
|
|
263
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
264
|
+
});
|
|
265
|
+
if (!res.ok) process.stderr.write(`dev-route-fixture: DELETE provider ${routeId} -> HTTP ${res.status}\n`);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// REPORT: the dev instance may already be gone; the row dies with its database.
|
|
268
|
+
process.stderr.write(`dev-route-fixture: DELETE provider ${routeId} failed: ${messageOf(error)}\n`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
await upstream.close();
|
|
273
|
+
} catch (error) {
|
|
274
|
+
// REPORT: a port that will not close is worth the line; there is nothing left to release it with.
|
|
275
|
+
process.stderr.write(`dev-route-fixture: closing the synthetic upstream failed: ${messageOf(error)}\n`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function waitForShutdown(deadlineMs) {
|
|
280
|
+
return new Promise((resolve) => {
|
|
281
|
+
const timer = setTimeout(() => resolve(`deadline ${deadlineMs}ms reached`), deadlineMs);
|
|
282
|
+
const stop = (signal) => {
|
|
283
|
+
clearTimeout(timer);
|
|
284
|
+
resolve(`received ${signal}`);
|
|
285
|
+
};
|
|
286
|
+
process.once('SIGTERM', () => stop('SIGTERM'));
|
|
287
|
+
process.once('SIGINT', () => stop('SIGINT'));
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async function main() {
|
|
292
|
+
const args = parseArgs(process.argv.slice(2));
|
|
293
|
+
const base = ctmBase(args.ctmPort);
|
|
294
|
+
await requireDevInstance(args.ctmPort);
|
|
295
|
+
const upstream = await startSyntheticUpstream({ wireModelId: args.model });
|
|
296
|
+
let providerWritten = false;
|
|
297
|
+
try {
|
|
298
|
+
await postJson(`${base}/api/models/providers`, providerBody(args, upstream.port), 'provider write');
|
|
299
|
+
providerWritten = true;
|
|
300
|
+
await postJson(`${base}/api/models/registry`, registryBody(args), 'registry write');
|
|
301
|
+
const catalog = await waitForCatalogRoute(base, args.routeId);
|
|
302
|
+
if (!catalog.found) {
|
|
303
|
+
for (const warning of catalog.warnings) {
|
|
304
|
+
process.stderr.write(`dev-route-fixture: catalog warning ${JSON.stringify(warning)}\n`);
|
|
305
|
+
}
|
|
306
|
+
process.stdout.write(`${JSON.stringify({
|
|
307
|
+
error: 'catalog_route_missing', ctm_port: args.ctmPort, route_id: args.routeId, warnings: catalog.warnings,
|
|
308
|
+
})}\n`);
|
|
309
|
+
await teardown({ base, routeId: args.routeId, upstream, deleteProvider: true });
|
|
310
|
+
process.exit(3);
|
|
311
|
+
}
|
|
312
|
+
} catch (error) {
|
|
313
|
+
// HANDLE + REPORT: undo the partial seed, then exit non-zero -- a half-seeded route must never
|
|
314
|
+
// be reported as success.
|
|
315
|
+
process.stderr.write(`dev-route-fixture: ${messageOf(error)}\n`);
|
|
316
|
+
await teardown({ base, routeId: args.routeId, upstream, deleteProvider: providerWritten });
|
|
317
|
+
process.exit(error?.exitCode || 4);
|
|
318
|
+
}
|
|
319
|
+
// `requests_log` is the synthetic upstream's live request log at print time (empty on a fresh
|
|
320
|
+
// start; the upstream itself records what a routed turn actually sent).
|
|
321
|
+
process.stdout.write(`${JSON.stringify({
|
|
322
|
+
ctm_port: args.ctmPort,
|
|
323
|
+
route_id: args.routeId,
|
|
324
|
+
model: args.model,
|
|
325
|
+
upstream_port: upstream.port,
|
|
326
|
+
requests_log: upstream.requests,
|
|
327
|
+
})}\n`);
|
|
328
|
+
const stopped = await waitForShutdown(args.deadlineMs);
|
|
329
|
+
await teardown({ base, routeId: args.routeId, upstream, deleteProvider: true });
|
|
330
|
+
process.stderr.write(`dev-route-fixture: ${stopped}; provider ${args.routeId} deleted\n`);
|
|
331
|
+
process.exit(0);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
main().catch((error) => {
|
|
335
|
+
// REPORT: anything reaching here is a bug in this script (a refusal already called process.exit),
|
|
336
|
+
// never a dev-instance state the caller can act on.
|
|
337
|
+
process.stderr.write(`dev-route-fixture: unexpected failure: ${error?.stack || error}\n`);
|
|
338
|
+
process.exit(4);
|
|
339
|
+
});
|