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,480 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-0 of docs/opencode-lead-and-delegate-model-selection-2026-10-28.html (§6.1):
|
|
4
|
+
// the OpenCode CLI adapter. Dependency-free. It asks the installed `opencode`
|
|
5
|
+
// binary exactly two questions — its version, and its model catalog
|
|
6
|
+
// (`models --verbose`) — through an injectable `execFile`, so tests never spawn a
|
|
7
|
+
// real process and no caller has to know the output shapes.
|
|
8
|
+
//
|
|
9
|
+
// Everything here is deliberately total: `opencodeVersion` never rejects
|
|
10
|
+
// (a missing/timed-out binary is `null`); `opencodeCatalog` rejects only with
|
|
11
|
+
// `.code === 'opencode_catalog_unavailable'`.
|
|
12
|
+
|
|
13
|
+
const fs = require('node:fs');
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
const { execFile: nodeExecFile } = require('node:child_process');
|
|
16
|
+
|
|
17
|
+
const VERSION_TIMEOUT_MS = 5000;
|
|
18
|
+
const CATALOG_TIMEOUT_MS = 15000;
|
|
19
|
+
const CATALOG_CACHE_MS = 60000;
|
|
20
|
+
const MAX_BUFFER = 8 * 1024 * 1024;
|
|
21
|
+
// How far up from the binary's own directory `opencodeLine` looks for a
|
|
22
|
+
// package.json: the binary sits at `<pkg>/bin/opencode(.exe)` (1) or, for the
|
|
23
|
+
// scoped npm layout, `<pkg>/node_modules/@opencode/cli/bin/opencode.exe` — one
|
|
24
|
+
// level is enough, three leaves room for a wrapping shim.
|
|
25
|
+
const PACKAGE_LOOKUP_LEVELS = 3;
|
|
26
|
+
|
|
27
|
+
/** @typedef {{ major:number, minor:number, patch:number, raw:string, line:'v1'|'v2' }} OpencodeVersion */
|
|
28
|
+
/** @typedef {{ value:string, label:string, sublabel:string, kind:'model', provider:string,
|
|
29
|
+
* status:string, variants:string[], efforts:{ values:[], model_default:null } }} OpencodeLeadRow */
|
|
30
|
+
|
|
31
|
+
// Cache state, keyed by the resolved-bin key from _binCacheKey(). Version entries
|
|
32
|
+
// never expire (a binary's version only changes when its mtime changes); catalog
|
|
33
|
+
// entries carry the `now()` at which they were stored.
|
|
34
|
+
const versionCache = new Map();
|
|
35
|
+
const catalogCache = new Map();
|
|
36
|
+
// Last non-null async line detection (opencodeLine), keyed by the `bin` STRING as
|
|
37
|
+
// given (e.g. 'opencode') so the sync peekOpencodeLine() can answer the launch
|
|
38
|
+
// path without any fs. Only positive ('v1'/'v2') findings are stored: a `null` is
|
|
39
|
+
// never recorded, so a later opencodeVersion() can still supply the fallback.
|
|
40
|
+
const lineByBin = new Map();
|
|
41
|
+
// One in-flight child per (kind, bin key): concurrent callers await the same promise.
|
|
42
|
+
const inflight = new Map();
|
|
43
|
+
|
|
44
|
+
async function _isFile(candidate, fsImpl) {
|
|
45
|
+
try {
|
|
46
|
+
return (await fsImpl.stat(candidate)).isFile();
|
|
47
|
+
} catch {
|
|
48
|
+
/* expected: a missing or unreadable PATH candidate is simply not a match */
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// A bare name is resolved by walking env.PATH; a resolved file is keyed by
|
|
54
|
+
// realpath + mtimeMs so an upgrade (or a differently-installed copy) misses the
|
|
55
|
+
// cache. Anything unresolvable falls back to the raw bin string, which is what
|
|
56
|
+
// tests pass (a non-existent name) so their cache keys stay plain.
|
|
57
|
+
async function _binCacheKey(bin, env) {
|
|
58
|
+
const raw = String(bin == null ? '' : bin);
|
|
59
|
+
try {
|
|
60
|
+
let resolved = null;
|
|
61
|
+
if (raw.includes('/')) {
|
|
62
|
+
resolved = raw;
|
|
63
|
+
} else {
|
|
64
|
+
const pathEnv = (env && env.PATH) || '';
|
|
65
|
+
for (const dir of String(pathEnv).split(path.delimiter)) {
|
|
66
|
+
if (!dir) continue;
|
|
67
|
+
const candidate = path.join(dir, raw);
|
|
68
|
+
if (await _isFile(candidate, fs.promises)) { resolved = candidate; break; }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (resolved && await _isFile(resolved, fs.promises)) {
|
|
72
|
+
const real = await fs.promises.realpath(resolved);
|
|
73
|
+
const stat = await fs.promises.stat(real);
|
|
74
|
+
return `${real}:${stat.mtimeMs}`;
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
/* expected: an unresolvable bin falls back to the raw name as its cache key */
|
|
78
|
+
}
|
|
79
|
+
return raw;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// The callback contract, deliberately not `promisify(execFile)`: an AbortSignal
|
|
83
|
+
// deadline is enforced here, around the callback, so an injected fake that never
|
|
84
|
+
// calls back still settles. The signal is also handed to execFile, which kills a
|
|
85
|
+
// real child on abort; the listener settles the injected-fake case the same way.
|
|
86
|
+
function _run(execFileImpl, bin, argv, env, timeoutMs) {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
let settled = false;
|
|
89
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
90
|
+
const finish = (fn, value) => {
|
|
91
|
+
if (settled) return;
|
|
92
|
+
settled = true;
|
|
93
|
+
signal.removeEventListener('abort', onAbort);
|
|
94
|
+
fn(value);
|
|
95
|
+
};
|
|
96
|
+
const onAbort = () => {
|
|
97
|
+
const err = new Error(`opencode "${argv[0]}" timed out after ${timeoutMs} ms`);
|
|
98
|
+
err.code = 'opencode_timeout';
|
|
99
|
+
finish(reject, err);
|
|
100
|
+
};
|
|
101
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
102
|
+
try {
|
|
103
|
+
execFileImpl(bin, argv, {
|
|
104
|
+
env,
|
|
105
|
+
timeout: timeoutMs,
|
|
106
|
+
maxBuffer: MAX_BUFFER,
|
|
107
|
+
windowsHide: true,
|
|
108
|
+
signal,
|
|
109
|
+
}, (err, stdout) => {
|
|
110
|
+
if (err) finish(reject, err);
|
|
111
|
+
else finish(resolve, String(stdout == null ? '' : stdout));
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
finish(reject, err);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function _parseVersion(stdout) {
|
|
120
|
+
const match = String(stdout == null ? '' : stdout).match(/(\d+)\.(\d+)\.(\d+)/);
|
|
121
|
+
if (!match) return null;
|
|
122
|
+
const major = Number(match[1]);
|
|
123
|
+
return {
|
|
124
|
+
major,
|
|
125
|
+
minor: Number(match[2]),
|
|
126
|
+
patch: Number(match[3]),
|
|
127
|
+
raw: match[0],
|
|
128
|
+
line: major >= 2 ? 'v2' : 'v1',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function _catalogUnavailable(cause) {
|
|
133
|
+
const detail = cause && cause.message ? `: ${cause.message}` : '';
|
|
134
|
+
const err = new Error(`opencode_catalog_unavailable${detail}`);
|
|
135
|
+
err.code = 'opencode_catalog_unavailable';
|
|
136
|
+
if (cause !== undefined) err.cause = cause;
|
|
137
|
+
return err;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Index just past the JSON object starting at `start` (which must be '{'), or -1
|
|
141
|
+
// when it never closes. Brace depth is tracked with string/escape awareness so a
|
|
142
|
+
// `{` or `}` inside a model description cannot truncate the slice.
|
|
143
|
+
function _matchJsonObject(text, start) {
|
|
144
|
+
let depth = 0;
|
|
145
|
+
let inString = false;
|
|
146
|
+
let escaped = false;
|
|
147
|
+
for (let i = start; i < text.length; i += 1) {
|
|
148
|
+
const ch = text[i];
|
|
149
|
+
if (inString) {
|
|
150
|
+
if (escaped) escaped = false;
|
|
151
|
+
else if (ch === '\\') escaped = true;
|
|
152
|
+
else if (ch === '"') inString = false;
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (ch === '"') { inString = true; continue; }
|
|
156
|
+
if (ch === '{') depth += 1;
|
|
157
|
+
else if (ch === '}') {
|
|
158
|
+
depth -= 1;
|
|
159
|
+
if (depth === 0) return i + 1;
|
|
160
|
+
if (depth < 0) return -1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return -1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Parses `<bin> models --verbose` stdout: repeated blocks of one `provider/model`
|
|
168
|
+
* line (it may carry extra slashes and `@`, e.g.
|
|
169
|
+
* `doordash/@fireworks/accounts/fireworks/models/glm-5p2`) followed by exactly one
|
|
170
|
+
* pretty-printed JSON object. Garbage between blocks is skipped.
|
|
171
|
+
* @param {string} stdout
|
|
172
|
+
* @returns {Array<{ value: string, row: object }>}
|
|
173
|
+
*/
|
|
174
|
+
function parseModelsVerbose(stdout) {
|
|
175
|
+
const text = String(stdout == null ? '' : stdout);
|
|
176
|
+
const out = [];
|
|
177
|
+
let i = 0;
|
|
178
|
+
while (i < text.length) {
|
|
179
|
+
let lineEnd = text.indexOf('\n', i);
|
|
180
|
+
if (lineEnd < 0) lineEnd = text.length;
|
|
181
|
+
const value = text.slice(i, lineEnd).trim();
|
|
182
|
+
i = lineEnd + 1;
|
|
183
|
+
if (!value || value.includes('{') || !value.includes('/')) continue;
|
|
184
|
+
let j = i;
|
|
185
|
+
while (j < text.length && /\s/.test(text[j])) j += 1;
|
|
186
|
+
if (text[j] !== '{') continue;
|
|
187
|
+
const end = _matchJsonObject(text, j);
|
|
188
|
+
if (end < 0) continue;
|
|
189
|
+
let row = null;
|
|
190
|
+
try {
|
|
191
|
+
row = JSON.parse(text.slice(j, end));
|
|
192
|
+
} catch {
|
|
193
|
+
/* expected: a truncated or non-JSON block is skipped, not fatal */
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!row || typeof row !== 'object' || Array.isArray(row)) continue;
|
|
197
|
+
out.push({ value, row });
|
|
198
|
+
i = end;
|
|
199
|
+
}
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Pure. One catalog entry → one picker row.
|
|
205
|
+
* @param {string} value the `provider/model` id printed by the CLI
|
|
206
|
+
* @param {object} row the decoded JSON object
|
|
207
|
+
* @returns {OpencodeLeadRow}
|
|
208
|
+
*/
|
|
209
|
+
function opencodeRow(value, row) {
|
|
210
|
+
const r = row && typeof row === 'object' && !Array.isArray(row) ? row : {};
|
|
211
|
+
return {
|
|
212
|
+
value,
|
|
213
|
+
label: r.name || value,
|
|
214
|
+
sublabel: value,
|
|
215
|
+
kind: 'model',
|
|
216
|
+
provider: r.providerID || String(value).split('/')[0],
|
|
217
|
+
status: r.status || 'active',
|
|
218
|
+
variants: Object.keys(r.variants || {}),
|
|
219
|
+
efforts: { values: [], model_default: null },
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* `<bin> --version` (timeout VERSION_TIMEOUT_MS), cached per bin key forever.
|
|
225
|
+
* Resolves `null` — never rejects — when the binary is missing, times out, or
|
|
226
|
+
* prints no `x.y.z`. A failed call is not cached.
|
|
227
|
+
* @param {{ bin?:string, env?:object, execFile?:Function, now?:Function, timeoutMs?:number }} [opts]
|
|
228
|
+
* @returns {Promise<OpencodeVersion|null>}
|
|
229
|
+
*/
|
|
230
|
+
async function opencodeVersion(opts = {}) {
|
|
231
|
+
const {
|
|
232
|
+
bin = 'opencode',
|
|
233
|
+
env = process.env,
|
|
234
|
+
execFile = nodeExecFile,
|
|
235
|
+
now = Date.now, // eslint-disable-line no-unused-vars -- accepted for API symmetry
|
|
236
|
+
timeoutMs = VERSION_TIMEOUT_MS,
|
|
237
|
+
} = opts;
|
|
238
|
+
const key = await _binCacheKey(bin, env);
|
|
239
|
+
if (versionCache.has(key)) return versionCache.get(key);
|
|
240
|
+
|
|
241
|
+
const flightKey = `version:${key}`;
|
|
242
|
+
if (inflight.has(flightKey)) return inflight.get(flightKey);
|
|
243
|
+
|
|
244
|
+
const promise = (async () => {
|
|
245
|
+
try {
|
|
246
|
+
const stdout = await _run(execFile, bin, ['--version'], env, timeoutMs);
|
|
247
|
+
return { ok: true, value: _parseVersion(stdout) };
|
|
248
|
+
} catch {
|
|
249
|
+
/* expected: missing/timed-out/denied binary -> null, and not cached */
|
|
250
|
+
return { ok: false, value: null };
|
|
251
|
+
}
|
|
252
|
+
})();
|
|
253
|
+
inflight.set(flightKey, promise);
|
|
254
|
+
try {
|
|
255
|
+
const result = await promise;
|
|
256
|
+
if (result.ok) versionCache.set(key, result.value);
|
|
257
|
+
return result.value;
|
|
258
|
+
} finally {
|
|
259
|
+
inflight.delete(flightKey);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Pure. OpenCode 2.x `models` output → entries: one trimmed `provider/model` id per line (the id
|
|
265
|
+
* may hold more `/` and `@` after the provider); lines with spaces or no `/` are skipped, and a
|
|
266
|
+
* repeated id keeps its first entry. 2.x prints no metadata, so every `row` is `{}`.
|
|
267
|
+
* @param {string} stdout
|
|
268
|
+
* @returns {Array<{ value: string, row: object }>}
|
|
269
|
+
*/
|
|
270
|
+
function parseModelsList(stdout) {
|
|
271
|
+
const seen = new Set();
|
|
272
|
+
const out = [];
|
|
273
|
+
for (const raw of String(stdout == null ? '' : stdout).split('\n')) {
|
|
274
|
+
const value = raw.trim();
|
|
275
|
+
if (!/^[^\s/]+\/\S+$/.test(value) || seen.has(value)) continue;
|
|
276
|
+
seen.add(value);
|
|
277
|
+
out.push({ value, row: {} });
|
|
278
|
+
}
|
|
279
|
+
return out;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The catalog of the INSTALLED line (timeout CATALOG_TIMEOUT_MS): 1.x runs `<bin> models --verbose`;
|
|
284
|
+
* 2.x has no `--verbose` (it exits "Unrecognized flag") and runs `<bin> models --standalone`, a
|
|
285
|
+
* private server, so the providers of this process's own inline config are listed too (the shared
|
|
286
|
+
* background service ignores that config, docs/opencode-v2-model-switch-standalone-plugin-2026-10-30.html
|
|
287
|
+
* P-S4). `opts.line` is a test seam; by default the line comes from opencodeLine(). Deprecated rows are
|
|
288
|
+
* dropped and the rest sorted by label; the result is cached for
|
|
289
|
+
* CATALOG_CACHE_MS. Rejects with `.code === 'opencode_catalog_unavailable'`
|
|
290
|
+
* (cause preserved on `.cause`) on error, timeout, or zero parsed rows.
|
|
291
|
+
* @param {{ bin?:string, env?:object, execFile?:Function, now?:Function, timeoutMs?:number, line?:'v1'|'v2'|null }} [opts]
|
|
292
|
+
* @returns {Promise<OpencodeLeadRow[]>}
|
|
293
|
+
*/
|
|
294
|
+
async function opencodeCatalog(opts = {}) {
|
|
295
|
+
const {
|
|
296
|
+
bin = 'opencode',
|
|
297
|
+
env = process.env,
|
|
298
|
+
execFile = nodeExecFile,
|
|
299
|
+
now = Date.now,
|
|
300
|
+
timeoutMs = CATALOG_TIMEOUT_MS,
|
|
301
|
+
} = opts;
|
|
302
|
+
// One bin key (realpath + mtime) is one install, so it is one line: the cache needs no line in its key.
|
|
303
|
+
const key = await _binCacheKey(bin, env);
|
|
304
|
+
const cached = catalogCache.get(key);
|
|
305
|
+
if (cached && now() - cached.at < CATALOG_CACHE_MS) return cached.rows;
|
|
306
|
+
|
|
307
|
+
const flightKey = `catalog:${key}`;
|
|
308
|
+
if (inflight.has(flightKey)) return inflight.get(flightKey);
|
|
309
|
+
|
|
310
|
+
const promise = (async () => {
|
|
311
|
+
const line = opts.line !== undefined ? opts.line : await opencodeLine({ bin, env });
|
|
312
|
+
const argv = line === 'v2' ? ['models', '--standalone'] : ['models', '--verbose'];
|
|
313
|
+
let stdout;
|
|
314
|
+
try {
|
|
315
|
+
stdout = await _run(execFile, bin, argv, env, timeoutMs);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
throw _catalogUnavailable(err);
|
|
318
|
+
}
|
|
319
|
+
const parsed = line === 'v2' ? parseModelsList(stdout) : parseModelsVerbose(stdout);
|
|
320
|
+
if (!parsed.length) {
|
|
321
|
+
throw _catalogUnavailable(new Error(`no model rows parsed from \`${argv.join(' ')}\``));
|
|
322
|
+
}
|
|
323
|
+
const rows = parsed
|
|
324
|
+
.map(({ value, row }) => opencodeRow(value, row))
|
|
325
|
+
.filter((row) => row.status !== 'deprecated')
|
|
326
|
+
.sort((a, b) => a.label.localeCompare(b.label));
|
|
327
|
+
catalogCache.set(key, { at: now(), rows });
|
|
328
|
+
return rows;
|
|
329
|
+
})();
|
|
330
|
+
inflight.set(flightKey, promise);
|
|
331
|
+
try {
|
|
332
|
+
return await promise;
|
|
333
|
+
} finally {
|
|
334
|
+
inflight.delete(flightKey);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// A bare name is resolved by walking env.PATH; a path is used as-is. Either way
|
|
339
|
+
// the realpath is returned so the package.json walk starts at the real install
|
|
340
|
+
// location (a `bin/opencode` symlink is the common shape). Unresolvable → null.
|
|
341
|
+
async function _resolveBinFile(bin, env, fsImpl) {
|
|
342
|
+
const raw = String(bin == null ? '' : bin);
|
|
343
|
+
try {
|
|
344
|
+
if (raw.includes('/')) {
|
|
345
|
+
return (await _isFile(raw, fsImpl)) ? await fsImpl.realpath(raw) : null;
|
|
346
|
+
}
|
|
347
|
+
const pathEnv = (env && env.PATH) || '';
|
|
348
|
+
for (const dir of String(pathEnv).split(path.delimiter)) {
|
|
349
|
+
if (!dir) continue;
|
|
350
|
+
const candidate = path.join(dir, raw);
|
|
351
|
+
if (await _isFile(candidate, fsImpl)) return await fsImpl.realpath(candidate);
|
|
352
|
+
}
|
|
353
|
+
} catch {
|
|
354
|
+
/* expected: an unresolvable or broken bin has no line to report */
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function _readPackageJson(dir, fsImpl) {
|
|
361
|
+
try {
|
|
362
|
+
const parsed = JSON.parse(await fsImpl.readFile(path.join(dir, 'package.json'), 'utf8'));
|
|
363
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
364
|
+
} catch {
|
|
365
|
+
/* expected: a missing/invalid package.json is simply not a match */
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Only the two package names CTM has measured mean anything here; a version
|
|
371
|
+
// without a parseable major is treated as v1 (`opencode-ai` has always been 1.x
|
|
372
|
+
// where it accepted `--model`).
|
|
373
|
+
function _lineFromPackageJson(pkg) {
|
|
374
|
+
const name = String(pkg && pkg.name ? pkg.name : '').trim();
|
|
375
|
+
if (name === '@opencode/cli') return 'v2';
|
|
376
|
+
if (name === 'opencode-ai') {
|
|
377
|
+
const major = Number.parseInt(String(pkg.version || '').split('.')[0], 10);
|
|
378
|
+
return Number.isFinite(major) && major >= 2 ? 'v2' : 'v1';
|
|
379
|
+
}
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Async, no spawn. Resolves `bin` (bare name → walk env.PATH; a path → as is),
|
|
385
|
+
* realpath, then walks up at most PACKAGE_LOOKUP_LEVELS directories from the
|
|
386
|
+
* binary's directory for a package.json. name '@opencode/cli' → 'v2'; name
|
|
387
|
+
* 'opencode-ai' → 'v2' if version major >= 2 else 'v1'. Otherwise falls back to
|
|
388
|
+
* the cached result of a previous opencodeVersion() for the same cache key, else
|
|
389
|
+
* null. A non-null result is recorded in `lineByBin` under the `bin` string as
|
|
390
|
+
* given, so the sync peekOpencodeLine() can answer later without any fs. Never
|
|
391
|
+
* rejects.
|
|
392
|
+
* @param {{ bin?:string, env?:object, fsImpl?:object }} [opts]
|
|
393
|
+
* @returns {Promise<'v1'|'v2'|null>}
|
|
394
|
+
*/
|
|
395
|
+
async function opencodeLine({ bin = 'opencode', env = process.env, fsImpl = fs.promises } = {}) {
|
|
396
|
+
const binKey = String(bin == null ? '' : bin);
|
|
397
|
+
const key = await _binCacheKey(bin, env);
|
|
398
|
+
let line = null;
|
|
399
|
+
try {
|
|
400
|
+
const resolved = await _resolveBinFile(bin, env, fsImpl);
|
|
401
|
+
if (resolved) {
|
|
402
|
+
let dir = path.dirname(resolved);
|
|
403
|
+
for (let i = 0; i <= PACKAGE_LOOKUP_LEVELS && dir; i += 1) {
|
|
404
|
+
const pkg = await _readPackageJson(dir, fsImpl);
|
|
405
|
+
if (pkg) {
|
|
406
|
+
line = _lineFromPackageJson(pkg);
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
const parent = path.dirname(dir);
|
|
410
|
+
if (parent === dir) break;
|
|
411
|
+
dir = parent;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
} catch {
|
|
415
|
+
/* expected: any fs surprise degrades to the cached-version fallback */
|
|
416
|
+
line = null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (!line) {
|
|
420
|
+
const cachedVersion = versionCache.get(key);
|
|
421
|
+
line = (cachedVersion && cachedVersion.line) || null;
|
|
422
|
+
}
|
|
423
|
+
if (line) lineByBin.set(binKey, line);
|
|
424
|
+
return line;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* R-6 (docs/opencode-v2-model-switch-standalone-plugin-2026-10-30.html §5.1/§6.1): prime the line
|
|
429
|
+
* for `bin` ASYNCHRONOUSLY, before any OpenCode launch argv is built. server.js's handleCreate
|
|
430
|
+
* awaits this once, at the top of an OpenCode create/restore, so the sync argv path can then read
|
|
431
|
+
* the answer with no fs at all (peekOpencodeLine). Returns the peeked line when one is already
|
|
432
|
+
* known, else the result of opencodeLine() — which memoises into `lineByBin` and, by its own
|
|
433
|
+
* contract, never rejects (a missing/unreadable bin is `null`). Never rejects here either.
|
|
434
|
+
* @param {{ bin?:string, env?:object }} [opts]
|
|
435
|
+
* @returns {Promise<'v1'|'v2'|null>}
|
|
436
|
+
*/
|
|
437
|
+
async function primeOpencodeLine({ bin = 'opencode', env = process.env } = {}) {
|
|
438
|
+
const known = peekOpencodeLine({ bin });
|
|
439
|
+
if (known) return known;
|
|
440
|
+
try {
|
|
441
|
+
return await opencodeLine({ bin, env });
|
|
442
|
+
} catch {
|
|
443
|
+
/* expected: opencodeLine never rejects, but a prime must not be able to fail a launch */
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Sync, NO fs, NO spawn: the last non-null opencodeLine() result for this `bin`
|
|
450
|
+
* string, else null. The launch path calls this so it never blocks on the fs.
|
|
451
|
+
* @param {{ bin?:string }} [opts]
|
|
452
|
+
* @returns {'v1'|'v2'|null}
|
|
453
|
+
*/
|
|
454
|
+
function peekOpencodeLine({ bin = 'opencode' } = {}) {
|
|
455
|
+
const binKey = String(bin == null ? '' : bin);
|
|
456
|
+
return lineByBin.get(binKey) || null;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** Tests only: drop every cached version, catalog, line, and in-flight entry. */
|
|
460
|
+
function _resetOpencodeCliCache() {
|
|
461
|
+
versionCache.clear();
|
|
462
|
+
catalogCache.clear();
|
|
463
|
+
lineByBin.clear();
|
|
464
|
+
inflight.clear();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
module.exports = {
|
|
468
|
+
opencodeVersion,
|
|
469
|
+
opencodeCatalog,
|
|
470
|
+
opencodeLine,
|
|
471
|
+
primeOpencodeLine,
|
|
472
|
+
peekOpencodeLine,
|
|
473
|
+
opencodeRow,
|
|
474
|
+
parseModelsVerbose,
|
|
475
|
+
parseModelsList,
|
|
476
|
+
_resetOpencodeCliCache,
|
|
477
|
+
VERSION_TIMEOUT_MS,
|
|
478
|
+
CATALOG_TIMEOUT_MS,
|
|
479
|
+
CATALOG_CACHE_MS,
|
|
480
|
+
};
|