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,743 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Landing-throughput WP-6 shard S9 (design doc §5 D-10 "move-only", §6 "Shard
|
|
4
|
+
// module seam"): the fourteen Codex-rollout-history render/compose functions move out
|
|
5
|
+
// of server.js VERBATIM into this module behind the same configure(deps) seam as
|
|
6
|
+
// lib/api/session-messages.js (S3), lib/api/session-attach.js and
|
|
7
|
+
// lib/terminal-attach-geometry.js (S6) and lib/walle-history-serve.js (S8). It
|
|
8
|
+
// registers NO route and NO socket handler: lib/ws/lifecycle.js and lib/ws/state-sync.js
|
|
9
|
+
// (wsLifecycleApi / wsStateSyncApi) and attachGeometry keep their tables and now receive
|
|
10
|
+
// this module's exports, while server.js keeps the pass-through callers
|
|
11
|
+
// (codexRolloutHistory.<name>) plus this by-value configure() seam.
|
|
12
|
+
// Bodies are identical to server.js's declarations except for the `_deps.` prefix on
|
|
13
|
+
// every identifier that used to resolve to a server.js top-level binding (D-10 rule 1),
|
|
14
|
+
// proven by `node bin/move-only-check.js`. No moved body contains an inline
|
|
15
|
+
// `require(...)`, so there is no require rebase here (unlike S1/S3/S6/S8).
|
|
16
|
+
//
|
|
17
|
+
// The module deliberately lives at lib/codex-rollout-history.js and NOT under lib/ws/:
|
|
18
|
+
// these are payload/render helpers, not ws-router handlers.
|
|
19
|
+
//
|
|
20
|
+
// Injected deps, per function:
|
|
21
|
+
// _codexRowCandidateIds: (none)
|
|
22
|
+
// _sessionHasFocusedViewer: (none)
|
|
23
|
+
// requestRowCursorRepublish: _codexHistoryCursorRepairAt, recordSessionDiagnostic,
|
|
24
|
+
// requestTargetedConversationImport
|
|
25
|
+
// _codexRowHistoryBase: dbModule
|
|
26
|
+
// _matchingPublishedCodexRollout: (none)
|
|
27
|
+
// _transcriptHistoryProvider: CTM_CODEX_ROLLOUT_HISTORY_ENABLED, detectAgentType
|
|
28
|
+
// _codexRolloutHistoryActive: (none)
|
|
29
|
+
// _codexHistoryRenderCacheEntry: CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION
|
|
30
|
+
// _codexHistoryRenderNull: recordSessionDiagnostic
|
|
31
|
+
// _codexHistoryRenderInputForBase: CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION
|
|
32
|
+
// _runCodexHistoryRenderQueue: CODEX_ROLLOUT_HISTORY_TAIL_MAX_MSGS,
|
|
33
|
+
// CODEX_ROLLOUT_HISTORY_TAIL_SEED_MSGS, CTM_READPOOL_INTERACTIVE_LANE_ENABLED,
|
|
34
|
+
// CTM_SNAPSHOT_SHALLOW_GUARD_ENABLED, RESUME_PRIORITY_LANE_ENABLED,
|
|
35
|
+
// _SESSION_MESSAGES_READPOOL_TIMEOUT_MS, _offthreadRead, _rolloutRenderBreaker,
|
|
36
|
+
// _scheduleSecondaryPush, _snapshotSessionScrollbackToFile,
|
|
37
|
+
// _testHistoryRenderNullsRemaining, dbModule, recordSessionDiagnostic, sessions
|
|
38
|
+
// _requestCodexHistoryRender: CTM_READPOOL_INTERACTIVE_LANE_ENABLED
|
|
39
|
+
// _scheduleCodexHistoryRender: (none)
|
|
40
|
+
// _composeCodexRolloutResp: CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION,
|
|
41
|
+
// CODEX_HISTORY_ROWS_STALE_ALARM_MS, CODEX_ROLLOUT_DURABLE_STALE_RENDER_MS,
|
|
42
|
+
// CODEX_ROLLOUT_HISTORY_MAX_LINES, CODEX_ROLLOUT_HISTORY_REFLOW_MAX_LINES,
|
|
43
|
+
// CTM_READPOOL_INTERACTIVE_LANE_ENABLED, CTM_SEAM_CONTENT_TRIM_ENABLED,
|
|
44
|
+
// RESUME_REPLAY_DEDUP_ENABLED, _buildCodexComposedMemoKey,
|
|
45
|
+
// _canReuseDurableHistoryRender, _codexViewportLooksSettled,
|
|
46
|
+
// _composeCodexHistorySnapshot, _decideCodexComposedMemoReuse,
|
|
47
|
+
// _hashCodexComposeViewport, _mirrorGridLinesForCompose,
|
|
48
|
+
// _observeCodexHistoryStaleRows, _selectCodexHistoryLineCap,
|
|
49
|
+
// _shouldSuppressMidTurnRestore, normalizeSnapshotScrollbackRows,
|
|
50
|
+
// recordSessionDiagnostic
|
|
51
|
+
//
|
|
52
|
+
// Mutable module state (D-10 rule 2): _testHistoryRenderNullsRemaining is the ONE
|
|
53
|
+
// server.js binding a moved body WRITES (_runCodexHistoryRenderQueue's
|
|
54
|
+
// `_testHistoryRenderNullsRemaining -= 1`), so it is injected as a getter/setter pair --
|
|
55
|
+
// exactly how S3 (lib/api/session-messages.js) re-homed the two bindings its moved
|
|
56
|
+
// bodies assign -- so the write reaches the same server.js binding instead of a copy
|
|
57
|
+
// frozen at configure() time. _codexHistoryCursorRepairAt is a const Map that is only
|
|
58
|
+
// mutated in place (never rebound), so it is passed by value like S8's per-session Maps.
|
|
59
|
+
// Every other dep is a by-value reference; calls between the fourteen moved functions
|
|
60
|
+
// stay direct (no _deps.).
|
|
61
|
+
|
|
62
|
+
let _deps = null;
|
|
63
|
+
|
|
64
|
+
function configure(deps = {}) {
|
|
65
|
+
_deps = deps;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function _codexRowCandidateIds(session, sessionId) {
|
|
69
|
+
const ids = [];
|
|
70
|
+
const add = (value) => {
|
|
71
|
+
const id = String(value || '').trim();
|
|
72
|
+
if (id && !ids.includes(id)) ids.push(id);
|
|
73
|
+
};
|
|
74
|
+
add(sessionId);
|
|
75
|
+
add(session && session._claudeSessionId);
|
|
76
|
+
return ids;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function _sessionHasFocusedViewer(session, sessionId) {
|
|
80
|
+
if (!session || !sessionId || !Array.isArray(session.clients)) return false;
|
|
81
|
+
return session.clients.some((ws) => (
|
|
82
|
+
ws?.readyState === 1
|
|
83
|
+
&& ws.focused === sessionId
|
|
84
|
+
&& (!(ws.viewing instanceof Set) || ws.viewing.has(sessionId))
|
|
85
|
+
));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function requestRowCursorRepublish(sessionId, sourceId) {
|
|
89
|
+
const id = String(sessionId || '');
|
|
90
|
+
const source = String(sourceId || id);
|
|
91
|
+
if (!id || !source) return false;
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
if (now - Number(_deps._codexHistoryCursorRepairAt.get(id) || 0) < 60000) return false;
|
|
94
|
+
_deps._codexHistoryCursorRepairAt.set(id, now);
|
|
95
|
+
void _deps.requestTargetedConversationImport(source, 'codex-history-stale-repair', { cursorOnly: false })
|
|
96
|
+
.then((result) => {
|
|
97
|
+
_deps.recordSessionDiagnostic(id, 'codex-history-row-cursor-republished', {
|
|
98
|
+
sourceId: source,
|
|
99
|
+
accepted: result?.accepted !== false,
|
|
100
|
+
completed: result?.completed !== false,
|
|
101
|
+
});
|
|
102
|
+
})
|
|
103
|
+
.catch((error) => {
|
|
104
|
+
_deps.recordSessionDiagnostic(id, 'codex-history-row-cursor-republish-failed', {
|
|
105
|
+
sourceId: source,
|
|
106
|
+
code: error?.code || '',
|
|
107
|
+
error: error?.message || String(error),
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
if (_deps._codexHistoryCursorRepairAt.size > 1000) {
|
|
111
|
+
for (const [repairId, at] of _deps._codexHistoryCursorRepairAt) {
|
|
112
|
+
if (now - at > 5 * 60 * 1000) _deps._codexHistoryCursorRepairAt.delete(repairId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function _codexRowHistoryBase(session, sessionId) {
|
|
119
|
+
for (const id of _codexRowCandidateIds(session, sessionId)) {
|
|
120
|
+
try {
|
|
121
|
+
const state = _deps.dbModule.getSessionRowSourceCursorState(id);
|
|
122
|
+
const count = Number(state?.rowCount || 0);
|
|
123
|
+
if (count > 0) {
|
|
124
|
+
const projectionEpoch = Math.max(0, Number(state.projectionEpoch || 0));
|
|
125
|
+
const renderFresh = state.renderFresh === true;
|
|
126
|
+
const version = [
|
|
127
|
+
count,
|
|
128
|
+
state.checked ? 1 : 0,
|
|
129
|
+
renderFresh ? 1 : 0,
|
|
130
|
+
Number(state.importedSize || 0),
|
|
131
|
+
Number(state.maxTranscriptEventId || 0),
|
|
132
|
+
Number(state.rowBackfillCursorEventId || 0),
|
|
133
|
+
projectionEpoch,
|
|
134
|
+
].join(':');
|
|
135
|
+
return {
|
|
136
|
+
id,
|
|
137
|
+
count,
|
|
138
|
+
fresh: !state.checked || state.fresh === true,
|
|
139
|
+
renderFresh,
|
|
140
|
+
state: String(state.state || ''),
|
|
141
|
+
cursorLagBytes: Math.max(0, Number(state.cursorLagBytes || 0)),
|
|
142
|
+
pendingEvents: Math.max(0, Number(state.pendingEvents || 0)),
|
|
143
|
+
parserVersion: Math.max(0, Number(state.parserVersion || 0)),
|
|
144
|
+
projectionEpoch,
|
|
145
|
+
projectionState: String(state.projectionState || 'ready'),
|
|
146
|
+
maxRowId: Math.max(0, Number(state.maxRowId || 0)),
|
|
147
|
+
version,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
} catch { /* registry publication is best-effort; retry on the next snapshot */ }
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Published metadata only: a cache miss never discovers a transcript on main.
|
|
156
|
+
function _matchingPublishedCodexRollout(session, sessionId) {
|
|
157
|
+
const threadId = session?._claudeSessionId || session?._providerResumeId || sessionId || session?.id;
|
|
158
|
+
const alias = session?._providerResumeId && session._providerResumeId !== threadId ? session._providerResumeId : '';
|
|
159
|
+
const cache = session?._codexRolloutPathCache;
|
|
160
|
+
return cache && cache.threadId === threadId
|
|
161
|
+
&& (cache.providerResumeId === undefined || cache.providerResumeId === alias) ? cache : null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// The provider-neutral transcript source for this session, or null if neither applies (wrong
|
|
165
|
+
// provider or codex's kill switch is off). Two independent consumers key off this: (1) the
|
|
166
|
+
// paged older-transcript-history API (apiSessionHistoryWindow / serveTranscriptHistoryV2),
|
|
167
|
+
// which serves both codex and claude and has no kill switch of its own for claude, and
|
|
168
|
+
// (2) the composed-terminal-seed gate (_codexRolloutHistoryActive below), which additionally
|
|
169
|
+
// requires 'codex' — WP-5 retired the composed seed for claude, not this provider lookup.
|
|
170
|
+
function _transcriptHistoryProvider(session) {
|
|
171
|
+
const agentType = _deps.detectAgentType((session && session.cmd) || '');
|
|
172
|
+
if (agentType === 'codex' && _deps.CTM_CODEX_ROLLOUT_HISTORY_ENABLED) return 'codex';
|
|
173
|
+
if (agentType === 'claude') return 'claude';
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Is the rollout-backed composed terminal seed active for this session? Codex only (WP-5
|
|
178
|
+
// retired the claude compose) + a usable durable row source. Terminal UX never reads JSONL
|
|
179
|
+
// directly; if rows are unavailable, callers behave exactly like today (serialize the
|
|
180
|
+
// headless blob) -- and a claude session always behaves like today now, unconditionally.
|
|
181
|
+
function _codexRolloutHistoryActive(session, sessionId) {
|
|
182
|
+
if (!session || _transcriptHistoryProvider(session) !== 'codex') return false;
|
|
183
|
+
return !!_codexRowHistoryBase(session, sessionId);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function _codexHistoryRenderCacheEntry(input, rendered) {
|
|
187
|
+
return {
|
|
188
|
+
key: input.renderKey,
|
|
189
|
+
ansi: rendered.ansi,
|
|
190
|
+
lineCount: rendered.lineCount,
|
|
191
|
+
renderedLineCount: rendered.renderedLineCount,
|
|
192
|
+
fellBack: rendered.fellBack,
|
|
193
|
+
messages: rendered.messages,
|
|
194
|
+
capped: !!rendered.capped,
|
|
195
|
+
elidedLines: Number(rendered.elidedLines || 0),
|
|
196
|
+
bound: input.historyLineCap,
|
|
197
|
+
source: input.sourceKey,
|
|
198
|
+
sourceKey: input.sourceKey,
|
|
199
|
+
lookupId: input.lookupId,
|
|
200
|
+
cols: input.cols,
|
|
201
|
+
rowMessages: Number(rendered.rowMessages || 0),
|
|
202
|
+
rowBaseCount: Number(input.rowBaseCount || 0),
|
|
203
|
+
rowBaseVersion: String(input.rowBaseVersion || ''),
|
|
204
|
+
sourceRowHwm: Math.max(0, Number(input.sourceRowHwm || 0)),
|
|
205
|
+
displayMode: rendered.displayMode || 'terminal-markdown',
|
|
206
|
+
historyLineCap: input.historyLineCap,
|
|
207
|
+
messageSpans: Array.isArray(rendered.spans) ? rendered.spans : [],
|
|
208
|
+
elidedMessages: Number(rendered.elidedMessages || 0),
|
|
209
|
+
rendererVersion: _deps.CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION,
|
|
210
|
+
historyRenderFidelity: true,
|
|
211
|
+
createdAt: Date.now(),
|
|
212
|
+
// WP-0: worker-measured render time (see workers/read-pool-worker.js 'renderRolloutHistory'),
|
|
213
|
+
// threaded through the cache entry so a cache-hit compose can still report it.
|
|
214
|
+
renderMs: Number.isFinite(Number(rendered.workerRenderMs)) ? Number(rendered.workerRenderMs) : undefined,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function _codexHistoryRenderNull(sessionId, reason, details = {}) {
|
|
219
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-history-render-null', { reason, ...details });
|
|
220
|
+
return { retryable: true, cause: reason };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function _codexHistoryRenderInputForBase(input, rowBase) {
|
|
224
|
+
const sourceKey = rowBase.renderFresh ? 'rows' : 'rows-stale';
|
|
225
|
+
return {
|
|
226
|
+
...input,
|
|
227
|
+
renderKey: `${input.agentType}:${sourceKey}:${rowBase.id}:${rowBase.version}:${input.cols}:${input.historyLineCap}:renderer${_deps.CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION}:fidelity1`,
|
|
228
|
+
lookupId: rowBase.id,
|
|
229
|
+
sourceKey,
|
|
230
|
+
rowBaseCount: rowBase.count || 0,
|
|
231
|
+
rowBaseVersion: rowBase.version,
|
|
232
|
+
sourceRowHwm: rowBase.maxRowId || 0,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function _runCodexHistoryRenderQueue(session) {
|
|
237
|
+
if (!session || session._codexHistoryRenderInFlight) return;
|
|
238
|
+
const queue = session._codexHistoryRenderQueue;
|
|
239
|
+
if (!Array.isArray(queue) || queue.length === 0) return;
|
|
240
|
+
const request = queue.shift();
|
|
241
|
+
if (_deps.sessions.get(request.sessionId) !== session) {
|
|
242
|
+
request.resolve(_codexHistoryRenderNull(request.sessionId, 'session-swap'));
|
|
243
|
+
setImmediate(() => _runCodexHistoryRenderQueue(session));
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const input = request.input;
|
|
247
|
+
session._codexHistoryRenderInFlight = request;
|
|
248
|
+
void _deps._offthreadRead({
|
|
249
|
+
breaker: _deps._rolloutRenderBreaker,
|
|
250
|
+
op: 'renderRolloutHistory',
|
|
251
|
+
timeoutMs: _deps._SESSION_MESSAGES_READPOOL_TIMEOUT_MS,
|
|
252
|
+
payload: {
|
|
253
|
+
dbPath: _deps.dbModule.getDbPath(),
|
|
254
|
+
rowSourceId: input.lookupId,
|
|
255
|
+
messageLimit: _deps.CODEX_ROLLOUT_HISTORY_TAIL_MAX_MSGS,
|
|
256
|
+
minSeedMessages: _deps.CODEX_ROLLOUT_HISTORY_TAIL_SEED_MSGS,
|
|
257
|
+
seedMsgs: Number(input.seedMsgs || 0),
|
|
258
|
+
agentType: input.agentType,
|
|
259
|
+
cols: input.cols,
|
|
260
|
+
cliVersion: input.cliVersion || '',
|
|
261
|
+
historyLineCap: input.historyLineCap,
|
|
262
|
+
historyRenderFidelity: true,
|
|
263
|
+
// WP-3 (terminal-memory-endgame S-11): the true store depth (session_message_rows
|
|
264
|
+
// COUNT), NOT the render window. The worker uses this — not the page's own `total`,
|
|
265
|
+
// which reflects whatever store getMessagesPage happens to read (v2 turns can be a
|
|
266
|
+
// much smaller count than the granular row store) — as the denominator for the
|
|
267
|
+
// elided-messages marker, so "N elided" is honest against the full transcript depth.
|
|
268
|
+
rowBaseCount: Number(input.rowBaseCount || 0),
|
|
269
|
+
telemetryReason: 'rollout-history-render',
|
|
270
|
+
},
|
|
271
|
+
// WI-7c: downgrade a durable (background persistence) render off the declared 'service'
|
|
272
|
+
// class so it can never head-of-line block a foreground render behind a bulk/durable
|
|
273
|
+
// backlog — see resolveReadPoolClass (a downgrade-only ceiling, never an escalation).
|
|
274
|
+
requestClass: _deps.CTM_READPOOL_INTERACTIVE_LANE_ENABLED && input.requestClass
|
|
275
|
+
? input.requestClass
|
|
276
|
+
: (_deps.RESUME_PRIORITY_LANE_ENABLED && input.durable ? 'batch' : undefined),
|
|
277
|
+
onSuccess: (result) => result && typeof result === 'object' ? result : null,
|
|
278
|
+
onFail: (error) => input.requestClass === 'interactive'
|
|
279
|
+
? {
|
|
280
|
+
composePending: true,
|
|
281
|
+
retryAfterMs: 1000,
|
|
282
|
+
errorCode: String(error?.code || ''),
|
|
283
|
+
}
|
|
284
|
+
: null,
|
|
285
|
+
}).then((renderedResult) => {
|
|
286
|
+
let rendered = renderedResult;
|
|
287
|
+
if (input.requestClass === 'interactive' && _deps._testHistoryRenderNullsRemaining > 0) {
|
|
288
|
+
_deps._testHistoryRenderNullsRemaining -= 1;
|
|
289
|
+
rendered = null;
|
|
290
|
+
_deps.recordSessionDiagnostic(request.sessionId, 'codex-history-render-null', {
|
|
291
|
+
reason: 'test-worker-null',
|
|
292
|
+
remaining: _deps._testHistoryRenderNullsRemaining,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
if (rendered?.composePending) {
|
|
296
|
+
session._codexHistoryComposePending = {
|
|
297
|
+
until: Date.now() + Math.max(250, Number(rendered.retryAfterMs) || 1000),
|
|
298
|
+
retryAfterMs: Math.max(250, Number(rendered.retryAfterMs) || 1000),
|
|
299
|
+
};
|
|
300
|
+
request.resolve(rendered);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (!rendered?.ansi || session._codexHistoryRenderInFlight !== request
|
|
304
|
+
|| _deps.sessions.get(request.sessionId) !== session) {
|
|
305
|
+
const reason = _deps.sessions.get(request.sessionId) !== session ? 'session-swap'
|
|
306
|
+
: (rendered?.composePending ? 'pool-fail' : 'worker-error');
|
|
307
|
+
request.resolve(rendered?.composePending || _codexHistoryRenderNull(request.sessionId, reason));
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const completedInput = request.input;
|
|
311
|
+
const current = _codexRowHistoryBase(session, request.sessionId);
|
|
312
|
+
if (!current || current.id !== completedInput.lookupId
|
|
313
|
+
|| current.version !== completedInput.rowBaseVersion) {
|
|
314
|
+
if (!current || current.id !== completedInput.lookupId) {
|
|
315
|
+
request.resolve(_codexHistoryRenderNull(request.sessionId, current ? 'source-swap' : 'session-swap'));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const completed = {
|
|
319
|
+
..._codexHistoryRenderCacheEntry(completedInput, rendered),
|
|
320
|
+
staleByVersions: true,
|
|
321
|
+
currentRowBaseVersion: current.version,
|
|
322
|
+
};
|
|
323
|
+
_deps.recordSessionDiagnostic(request.sessionId, 'codex-history-render-version-advanced', {
|
|
324
|
+
fromVersion: completedInput.rowBaseVersion,
|
|
325
|
+
toVersion: current.version,
|
|
326
|
+
});
|
|
327
|
+
request.resolve(completed);
|
|
328
|
+
_scheduleCodexHistoryRender(session, request.sessionId, _codexHistoryRenderInputForBase(completedInput, current));
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
session._rolloutHistoryTailSeed = Number(rendered.nextSeed || 0);
|
|
332
|
+
const cacheEntry = _codexHistoryRenderCacheEntry(completedInput, rendered);
|
|
333
|
+
session._codexHistoryRenderCache = cacheEntry;
|
|
334
|
+
session._codexHistoryComposePending = null;
|
|
335
|
+
// WP-4 (S-5/D-6): a DURABLE render request means the caller was
|
|
336
|
+
// _snapshotSessionScrollbackToFile's own compose attempt bailing (nothing cached
|
|
337
|
+
// yet) -- this render landing is exactly the deferred completion the shallow-
|
|
338
|
+
// overwrite guard above told the caller to wait for. Re-persist once now that a
|
|
339
|
+
// composed render exists, so the durable file catches up to full depth instead of
|
|
340
|
+
// waiting for the next periodic sweep (30s) or shutdown.
|
|
341
|
+
if (_deps.CTM_SNAPSHOT_SHALLOW_GUARD_ENABLED && completedInput.durable === true) {
|
|
342
|
+
setImmediate(() => {
|
|
343
|
+
if (_deps.sessions.get(request.sessionId) !== session) return;
|
|
344
|
+
_deps._snapshotSessionScrollbackToFile(request.sessionId, 5000).catch(() => { /* expected: best-effort re-persist -- a failure here just leaves the file at whatever the shallow-skip guard kept, which the next periodic sweep or shutdown snapshot still catches up */ });
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
_deps.recordSessionDiagnostic(request.sessionId, 'codex-rollout-history-render-ready', {
|
|
348
|
+
agent: completedInput.agentType,
|
|
349
|
+
cols: completedInput.cols,
|
|
350
|
+
rows: rendered.lineCount,
|
|
351
|
+
messages: rendered.messages,
|
|
352
|
+
capped: !!rendered.capped,
|
|
353
|
+
});
|
|
354
|
+
request.resolve(cacheEntry);
|
|
355
|
+
if (completedInput.settled === true
|
|
356
|
+
&& Number(session._ptyCols || 0) === Number(completedInput.cols)
|
|
357
|
+
&& typeof session._sendCleanSnapshot === 'function') {
|
|
358
|
+
setImmediate(() => {
|
|
359
|
+
if (_deps.sessions.get(request.sessionId) !== session) return;
|
|
360
|
+
session._sendCleanSnapshot(request.sessionId, null, {
|
|
361
|
+
restoreSource: 'rollout-history-render-ready',
|
|
362
|
+
reason: 'rollout-history-render-ready',
|
|
363
|
+
skipIfStale: true,
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (session._hasSecondaryViewers) _deps._scheduleSecondaryPush(session, request.sessionId, 'rollout-history-render-ready');
|
|
368
|
+
}).catch((err) => {
|
|
369
|
+
console.error('[rollout-history] worker render completion failed:', err.message);
|
|
370
|
+
request.resolve(_codexHistoryRenderNull(request.sessionId, 'worker-error', {
|
|
371
|
+
code: String(err?.code || ''),
|
|
372
|
+
}));
|
|
373
|
+
}).finally(() => {
|
|
374
|
+
if (session._codexHistoryRenderInFlight === request) session._codexHistoryRenderInFlight = null;
|
|
375
|
+
setImmediate(() => _runCodexHistoryRenderQueue(session));
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function _requestCodexHistoryRender(session, sessionId, input) {
|
|
380
|
+
if (!session || !input?.renderKey) return Promise.resolve(null);
|
|
381
|
+
const cached = session._codexHistoryRenderCache;
|
|
382
|
+
if (cached?.key === input.renderKey && cached.ansi) return Promise.resolve(cached);
|
|
383
|
+
|
|
384
|
+
const inFlight = session._codexHistoryRenderInFlight;
|
|
385
|
+
if (inFlight?.key === input.renderKey) {
|
|
386
|
+
if (input.settled === true) inFlight.input.settled = true;
|
|
387
|
+
return inFlight.promise;
|
|
388
|
+
}
|
|
389
|
+
if (!Array.isArray(session._codexHistoryRenderQueue)) session._codexHistoryRenderQueue = [];
|
|
390
|
+
const queued = session._codexHistoryRenderQueue.find((entry) => entry.key === input.renderKey);
|
|
391
|
+
if (queued) {
|
|
392
|
+
if (input.settled === true) queued.input.settled = true;
|
|
393
|
+
return queued.promise;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
let resolveRequest;
|
|
397
|
+
const promise = new Promise((resolve) => { resolveRequest = resolve; });
|
|
398
|
+
const request = {
|
|
399
|
+
key: input.renderKey,
|
|
400
|
+
sessionId,
|
|
401
|
+
input: { ...input },
|
|
402
|
+
promise,
|
|
403
|
+
resolve: resolveRequest,
|
|
404
|
+
};
|
|
405
|
+
if (_deps.CTM_READPOOL_INTERACTIVE_LANE_ENABLED && input.requestClass === 'interactive') {
|
|
406
|
+
session._codexHistoryRenderQueue.unshift(request);
|
|
407
|
+
} else {
|
|
408
|
+
session._codexHistoryRenderQueue.push(request);
|
|
409
|
+
}
|
|
410
|
+
_runCodexHistoryRenderQueue(session);
|
|
411
|
+
return promise;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function _scheduleCodexHistoryRender(session, sessionId, input) {
|
|
415
|
+
void _requestCodexHistoryRender(session, sessionId, input);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Given a serialize reply that was requested at scrollback:0 (the native live
|
|
419
|
+
// region only), prepend the rollout-synthesized settled history (rendered at the
|
|
420
|
+
// SAME cols so the client never reflows it) and return a resp with composed data.
|
|
421
|
+
// Codex only (WP-5 retired the claude compose path) — a non-codex session (including
|
|
422
|
+
// claude, whose local scrollback is now served exactly like any other normal-buffer
|
|
423
|
+
// session) returns resp UNCHANGED, never gets misrouted into this render path.
|
|
424
|
+
// FAIL-SAFE: any problem returns the original resp unchanged (the native viewport),
|
|
425
|
+
// so a bad render degrades to "live region only", never to corruption or a throw.
|
|
426
|
+
function _composeCodexRolloutResp(session, sessionId, resp, opts = {}) {
|
|
427
|
+
if (!resp || !resp.data) return resp;
|
|
428
|
+
const agentType = _transcriptHistoryProvider(session);
|
|
429
|
+
if (agentType !== 'codex') return resp;
|
|
430
|
+
// durable: this snapshot is being PERSISTED to file (cold-resume seed), not sent
|
|
431
|
+
// live. The interactive transcript pager is kept for live sends but dropped for
|
|
432
|
+
// durable persistence so a cold resume never restores into a dead pager.
|
|
433
|
+
const durable = !!(opts && opts.durable);
|
|
434
|
+
const isReflow = !!(opts && opts.reflow);
|
|
435
|
+
try {
|
|
436
|
+
const cols = Number(resp.cols) || session._ptyCols || 80;
|
|
437
|
+
const liveViewportData = String(resp.data || '');
|
|
438
|
+
const settled = _deps._codexViewportLooksSettled(liveViewportData);
|
|
439
|
+
const gridSample = _deps._mirrorGridLinesForCompose(session, resp);
|
|
440
|
+
const capPolicy = _deps._selectCodexHistoryLineCap({
|
|
441
|
+
isReflow,
|
|
442
|
+
cols,
|
|
443
|
+
lastComposedCols: session._lastCodexHistoryComposeCols,
|
|
444
|
+
normalMaxLines: _deps.CODEX_ROLLOUT_HISTORY_MAX_LINES,
|
|
445
|
+
reflowMaxLines: _deps.CODEX_ROLLOUT_HISTORY_REFLOW_MAX_LINES,
|
|
446
|
+
});
|
|
447
|
+
const historyLineCap = capPolicy.cap;
|
|
448
|
+
const rowBase = _codexRowHistoryBase(session, sessionId);
|
|
449
|
+
if (!rowBase) return resp;
|
|
450
|
+
const lookupId = rowBase && rowBase.id;
|
|
451
|
+
if (!lookupId) return resp;
|
|
452
|
+
const sourceKey = rowBase.renderFresh ? 'rows' : 'rows-stale';
|
|
453
|
+
// Cheap content-version so repeated snapshots of unchanged row history
|
|
454
|
+
// (tab-switch, reconnect, secondary-push, reflow at the same width) skip the
|
|
455
|
+
// row fetch + render entirely. Terminal compose is row-only; rollout JSONL
|
|
456
|
+
// tails are not merged into this surface.
|
|
457
|
+
const version = rowBase.version;
|
|
458
|
+
// agentType-prefixed so a cached codex render can never serve a claude session (the
|
|
459
|
+
// cache lives on the session object and is per-session anyway; this is paranoia).
|
|
460
|
+
const renderKey = `${agentType}:${sourceKey}:${lookupId}:${version}:${cols}:${historyLineCap}:renderer${_deps.CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION}:fidelity1`;
|
|
461
|
+
let historyAnsi; let lineCount; let renderedLineCount; let historyElidedLines = 0; let fellBack; let msgCount; let historyCapped = false; let displayMode = 'terminal-markdown'; let messageSpans = []; let historyElidedMessages = 0;
|
|
462
|
+
let source = sourceKey; let rowMsgCount = 0; let renderMs; // WP-0: worker-measured, undefined when not from a fresh/cached render
|
|
463
|
+
const rc = session._codexHistoryRenderCache;
|
|
464
|
+
const exactCacheHit = rc && rc.key === renderKey && !!rc.ansi;
|
|
465
|
+
const reusedStaleRender = !exactCacheHit && _deps._canReuseDurableHistoryRender({
|
|
466
|
+
durable,
|
|
467
|
+
cacheEntry: rc,
|
|
468
|
+
lookupId,
|
|
469
|
+
sourceKey,
|
|
470
|
+
cols,
|
|
471
|
+
historyLineCap,
|
|
472
|
+
rowBaseCount: rowBase.count || 0,
|
|
473
|
+
rendererVersion: _deps.CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION,
|
|
474
|
+
historyRenderFidelity: true,
|
|
475
|
+
settled,
|
|
476
|
+
now: Date.now(),
|
|
477
|
+
maxAgeMs: _deps.CODEX_ROLLOUT_DURABLE_STALE_RENDER_MS,
|
|
478
|
+
});
|
|
479
|
+
const cacheHit = exactCacheHit || reusedStaleRender;
|
|
480
|
+
if (cacheHit) {
|
|
481
|
+
({ ansi: historyAnsi, lineCount, renderedLineCount, fellBack, messages: msgCount } = rc);
|
|
482
|
+
messageSpans = Array.isArray(rc.messageSpans) ? rc.messageSpans : [];
|
|
483
|
+
historyElidedMessages = Number(rc.elidedMessages || 0);
|
|
484
|
+
displayMode = rc.displayMode || displayMode;
|
|
485
|
+
historyCapped = !!rc.capped;
|
|
486
|
+
historyElidedLines = Number(rc.elidedLines || 0);
|
|
487
|
+
source = rc.source || source;
|
|
488
|
+
rowMsgCount = Number(rc.rowMessages || 0);
|
|
489
|
+
renderMs = Number.isFinite(Number(rc.renderMs)) ? Number(rc.renderMs) : undefined;
|
|
490
|
+
} else {
|
|
491
|
+
const renderRequestClass = _deps.CTM_READPOOL_INTERACTIVE_LANE_ENABLED
|
|
492
|
+
? (opts.requestClass || (
|
|
493
|
+
durable
|
|
494
|
+
? 'batch'
|
|
495
|
+
: (_sessionHasFocusedViewer(session, sessionId) ? 'interactive' : 'service')
|
|
496
|
+
))
|
|
497
|
+
: undefined;
|
|
498
|
+
const pending = session._codexHistoryComposePending;
|
|
499
|
+
if (renderRequestClass === 'interactive' && Number(pending?.until) > Date.now()) {
|
|
500
|
+
return {
|
|
501
|
+
...resp,
|
|
502
|
+
data: null,
|
|
503
|
+
composePending: true,
|
|
504
|
+
retryAfterMs: Math.max(250, Number(pending.retryAfterMs) || 1000),
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
_scheduleCodexHistoryRender(session, sessionId, {
|
|
508
|
+
renderKey,
|
|
509
|
+
lookupId,
|
|
510
|
+
sourceKey,
|
|
511
|
+
rowBaseCount: rowBase.count || 0,
|
|
512
|
+
rowBaseVersion: rowBase.version,
|
|
513
|
+
agentType,
|
|
514
|
+
cols,
|
|
515
|
+
cliVersion: session._codexCliVersion || '',
|
|
516
|
+
historyLineCap,
|
|
517
|
+
seedMsgs: session._rolloutHistoryTailSeed || 0,
|
|
518
|
+
settled,
|
|
519
|
+
// WI-7c: a durable (persistence/cold-resume-seed) render is background work — it isn't
|
|
520
|
+
// shown to any connected client — so it must never queue ahead of a foreground render's
|
|
521
|
+
// own renderRolloutHistory read on the read pool (see _runCodexHistoryRenderQueue).
|
|
522
|
+
durable,
|
|
523
|
+
requestClass: renderRequestClass,
|
|
524
|
+
});
|
|
525
|
+
return resp;
|
|
526
|
+
}
|
|
527
|
+
// The live region is owned by Codex/state-sync. A flap/divergence-driven
|
|
528
|
+
// reflow (opts.deferMidTurn) that restores history while the turn is still
|
|
529
|
+
// streaming can reset over Codex's live inline repaint. Keep the current
|
|
530
|
+
// frame mid-turn; the settle-time reconcile applies H and then forces L.
|
|
531
|
+
// Returns data:null + a marker so the caller sends "keep-current".
|
|
532
|
+
if (_deps._shouldSuppressMidTurnRestore({
|
|
533
|
+
deferrableSource: !!(opts && opts.deferMidTurn),
|
|
534
|
+
settled,
|
|
535
|
+
forceMidTurnSnapshot: !!(opts && opts.forceMidTurnSnapshot),
|
|
536
|
+
})) {
|
|
537
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-midturn-restore-suppressed', { agent: agentType, cols, source });
|
|
538
|
+
return { ...resp, data: null, _codexMidTurnDeferred: true };
|
|
539
|
+
}
|
|
540
|
+
// WI-9 step 2: _composeCodexHistorySnapshot (seam compute + string concat of potentially
|
|
541
|
+
// multi-MB historyAnsi + liveViewportData) is a PURE function of (renderKey resolved above,
|
|
542
|
+
// the live viewport bytes, durable/reflow/rows/scrollbackRows) — a repeated snapshot request
|
|
543
|
+
// for a session sitting idle at the same settled screen (tab-switch, reconnect, secondary-
|
|
544
|
+
// push) recomputes byte-identical output every time. Memoize the COMPOSED result (not just
|
|
545
|
+
// the history render, already cached via session._codexHistoryRenderCache) per that tuple so
|
|
546
|
+
// an unchanged snapshot skips compose entirely.
|
|
547
|
+
const composeRows = Number(resp.rows) || Number(session._ptyRows) || 0;
|
|
548
|
+
const composeScrollbackRows = _deps.normalizeSnapshotScrollbackRows(session._snapshotScrollbackRows);
|
|
549
|
+
const composedMemoKey = _deps._buildCodexComposedMemoKey({
|
|
550
|
+
renderKey,
|
|
551
|
+
viewportHash: _deps._hashCodexComposeViewport(liveViewportData),
|
|
552
|
+
rows: composeRows,
|
|
553
|
+
durable,
|
|
554
|
+
reflow: isReflow,
|
|
555
|
+
scrollbackRows: composeScrollbackRows,
|
|
556
|
+
});
|
|
557
|
+
// Two memo slots (durable persistence vs live/client compose) so the interleaved durable
|
|
558
|
+
// scrollback-snapshot job and the client settle-reconcile composes stop EVICTING each other
|
|
559
|
+
// from a single slot — the cause of memo-hit=0 on a session with an active persistence job AND
|
|
560
|
+
// a viewer (prod 16864329 2026-07-22: 49 recomposes/2h, 0 memo hits, ~250 KB each). `durable`
|
|
561
|
+
// is already part of composedMemoKey, so a slot only ever reuses a same-durable payload;
|
|
562
|
+
// splitting slots changes hit rate, never correctness.
|
|
563
|
+
const composedMemoSlot = durable ? 'durable' : 'live';
|
|
564
|
+
const composedMemoStore = (session._codexComposedRespMemo && typeof session._codexComposedRespMemo === 'object')
|
|
565
|
+
? session._codexComposedRespMemo : null;
|
|
566
|
+
const composedMemo = composedMemoStore ? composedMemoStore[composedMemoSlot] : null;
|
|
567
|
+
const staleRows = !!(rowBase && !rowBase.renderFresh);
|
|
568
|
+
const staleAlarm = _deps._observeCodexHistoryStaleRows(session, {
|
|
569
|
+
staleRows,
|
|
570
|
+
lookupId,
|
|
571
|
+
count: rowBase.count || 0,
|
|
572
|
+
state: rowBase.state || '',
|
|
573
|
+
cursorLagBytes: rowBase.cursorLagBytes || 0,
|
|
574
|
+
pendingEvents: rowBase.pendingEvents || 0,
|
|
575
|
+
parserVersion: rowBase.parserVersion || 0,
|
|
576
|
+
now: Date.now(),
|
|
577
|
+
thresholdMs: _deps.CODEX_HISTORY_ROWS_STALE_ALARM_MS,
|
|
578
|
+
});
|
|
579
|
+
if (staleAlarm) {
|
|
580
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-history-rows-stale-persistent', { agent: agentType, ...staleAlarm });
|
|
581
|
+
requestRowCursorRepublish(sessionId, lookupId);
|
|
582
|
+
}
|
|
583
|
+
if (_deps._decideCodexComposedMemoReuse({
|
|
584
|
+
enabled: _deps.RESUME_REPLAY_DEDUP_ENABLED,
|
|
585
|
+
memoKey: composedMemoKey,
|
|
586
|
+
lastMemoKey: composedMemo && composedMemo.key,
|
|
587
|
+
hasComposedPayload: !!(composedMemo && composedMemo.payload),
|
|
588
|
+
})) {
|
|
589
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-rollout-history-composed-memo-hit', {
|
|
590
|
+
agent: agentType,
|
|
591
|
+
cols,
|
|
592
|
+
bytes: composedMemo.payload.data ? composedMemo.payload.data.length : 0,
|
|
593
|
+
});
|
|
594
|
+
return { ...resp, ...composedMemo.payload };
|
|
595
|
+
}
|
|
596
|
+
const composed = _deps._composeCodexHistorySnapshot({
|
|
597
|
+
historyAnsi,
|
|
598
|
+
viewportAnsi: liveViewportData,
|
|
599
|
+
gridLines: gridSample.gridLines,
|
|
600
|
+
messageSpans,
|
|
601
|
+
settled,
|
|
602
|
+
gridStable: true, // agentType is guaranteed 'codex' here (claude compose retired, WP-5)
|
|
603
|
+
contentTrim: _deps.CTM_SEAM_CONTENT_TRIM_ENABLED,
|
|
604
|
+
durable,
|
|
605
|
+
opts: {
|
|
606
|
+
seam: true,
|
|
607
|
+
cols,
|
|
608
|
+
stale: staleRows,
|
|
609
|
+
// State-sync owns the live grid. Live snapshots restore H only; the
|
|
610
|
+
// restore-applied ACK resets the diff baseline and forces L over the
|
|
611
|
+
// visible history tail. Durable files still include the native viewport
|
|
612
|
+
// because no client/keyframe handshake exists while persisting.
|
|
613
|
+
frameOwnedViewport: !durable,
|
|
614
|
+
// Blank-viewport padding when the alt-screen live region is dropped (claude
|
|
615
|
+
// fullscreen): keeps history + seam in scrollback instead of letting the next
|
|
616
|
+
// keyframe paint the live screen over the history tail. Live sends only (the
|
|
617
|
+
// compose ignores padRows for durable persists).
|
|
618
|
+
padRows: Number(resp.rows) || Number(session._ptyRows) || 0,
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
if (!composed || !composed.data) return resp;
|
|
622
|
+
const terminalSurface = {
|
|
623
|
+
agent: agentType,
|
|
624
|
+
viewport: composed.droppedAltViewport
|
|
625
|
+
? 'alt-screen'
|
|
626
|
+
: (composed.frameOwnedViewport ? 'frame-owned' : 'live'),
|
|
627
|
+
scrollback: {
|
|
628
|
+
witnessed: composed.witnessed,
|
|
629
|
+
recomposed: {
|
|
630
|
+
rows: Number(lineCount || 0),
|
|
631
|
+
cols,
|
|
632
|
+
bound: historyLineCap,
|
|
633
|
+
elided: historyElidedLines,
|
|
634
|
+
elidedMessages: historyElidedMessages,
|
|
635
|
+
parity: 'codex-tui',
|
|
636
|
+
stale: staleRows,
|
|
637
|
+
},
|
|
638
|
+
seam: {
|
|
639
|
+
present: !!(composed.seam && composed.seam.present),
|
|
640
|
+
text: (composed.seam && composed.seam.text) || '',
|
|
641
|
+
},
|
|
642
|
+
trimSkipReason: composed.trimSkipReason || '',
|
|
643
|
+
},
|
|
644
|
+
widths: {
|
|
645
|
+
pty: Number(resp.cols) || cols,
|
|
646
|
+
mirror: Number(resp.cols) || cols,
|
|
647
|
+
},
|
|
648
|
+
reason: opts && opts.reflow
|
|
649
|
+
? (capPolicy.reflowWidthChanged ? 'width-change' : 'same-width-reflow')
|
|
650
|
+
: (opts && opts.deferMidTurn ? 'settle-reconcile' : (durable ? 'durable-persist' : 'settle-reconcile')),
|
|
651
|
+
};
|
|
652
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-rollout-history-composed', {
|
|
653
|
+
agent: agentType,
|
|
654
|
+
cols,
|
|
655
|
+
source,
|
|
656
|
+
cached: cacheHit,
|
|
657
|
+
reusedStaleRender: reusedStaleRender || undefined,
|
|
658
|
+
settled,
|
|
659
|
+
historyLines: lineCount,
|
|
660
|
+
historyLineCap,
|
|
661
|
+
reflow: isReflow || undefined,
|
|
662
|
+
reflowWidthChanged: capPolicy.reflowWidthChanged || undefined,
|
|
663
|
+
messages: msgCount,
|
|
664
|
+
rowMessages: rowMsgCount || undefined,
|
|
665
|
+
staleRows: rowBase && !rowBase.renderFresh || undefined,
|
|
666
|
+
capped: historyCapped,
|
|
667
|
+
bound: historyLineCap,
|
|
668
|
+
elidedLines: historyElidedLines || undefined,
|
|
669
|
+
elidedMessages: historyElidedMessages || undefined,
|
|
670
|
+
contentTrimmedLines: Number(composed.trimmed) || undefined,
|
|
671
|
+
trimSkipReason: composed.trimSkipReason || undefined,
|
|
672
|
+
fellBack,
|
|
673
|
+
displayMode,
|
|
674
|
+
terminalSurface,
|
|
675
|
+
bytes: composed.data.length,
|
|
676
|
+
// WP-0: worker-measured renderRolloutHistoryTail duration (undefined when this
|
|
677
|
+
// compose reused a durable/stale-tolerant render entry with no timing recorded).
|
|
678
|
+
renderMs,
|
|
679
|
+
// Codex gpt-5.5's full-screen (alt-screen) native viewport can't be inlined
|
|
680
|
+
// after the main-buffer history — the compose drops it and serves
|
|
681
|
+
// history-only so the browser doesn't switch to the alt buffer and hide the
|
|
682
|
+
// composer. Surface that so the "no input box" garble is diagnosable.
|
|
683
|
+
droppedAltViewport: composed.droppedAltViewport || undefined,
|
|
684
|
+
});
|
|
685
|
+
_deps.recordSessionDiagnostic(sessionId, 'terminal-surface-decision', terminalSurface);
|
|
686
|
+
session._lastCodexHistoryComposeCols = cols;
|
|
687
|
+
session._lastCodexHistoryComposeAt = Date.now();
|
|
688
|
+
// Report the full requested scrollback budget so cache-reuse matching treats
|
|
689
|
+
// this as a full-scrollback snapshot (the composed history covers it).
|
|
690
|
+
// Tag the result so the client applies H, acknowledges the restore, and lets
|
|
691
|
+
// the forced state-sync keyframe paint L. Interactive alt-screen composes do
|
|
692
|
+
// not carry frameOwnedViewport and remain owned by their native viewport.
|
|
693
|
+
const composedPayload = {
|
|
694
|
+
data: composed.data,
|
|
695
|
+
codexRolloutComposed: true,
|
|
696
|
+
frameOwnedViewport: !!composed.frameOwnedViewport,
|
|
697
|
+
terminalDisplayMode: displayMode,
|
|
698
|
+
terminalSurface,
|
|
699
|
+
renderProjection: {
|
|
700
|
+
surface: 'terminal',
|
|
701
|
+
displayMode,
|
|
702
|
+
source: 'codex-rollout-history',
|
|
703
|
+
terminalSurface,
|
|
704
|
+
},
|
|
705
|
+
scrollback: _deps.normalizeSnapshotScrollbackRows(session._snapshotScrollbackRows),
|
|
706
|
+
snapshotScrollbackFp: composed.snapshotScrollbackFp || undefined,
|
|
707
|
+
snapshotViewportOffset: Number(composed.snapshotViewportOffset || 0),
|
|
708
|
+
rendererVersion: _deps.CODEX_HISTORY_EFFECTIVE_RENDERER_VERSION,
|
|
709
|
+
composedAt: Date.now(),
|
|
710
|
+
_durableViewportData: durable ? liveViewportData : undefined,
|
|
711
|
+
};
|
|
712
|
+
// WI-9 step 2: stash for the next compose call on this session — see the memo-key check
|
|
713
|
+
// near the top of this function. Only meaningful while the flag is on; harmless dead weight
|
|
714
|
+
// otherwise (never read when RESUME_REPLAY_DEDUP_ENABLED is false).
|
|
715
|
+
if (!session._codexComposedRespMemo || typeof session._codexComposedRespMemo !== 'object') {
|
|
716
|
+
session._codexComposedRespMemo = {};
|
|
717
|
+
}
|
|
718
|
+
session._codexComposedRespMemo[composedMemoSlot] = { key: composedMemoKey, payload: composedPayload, createdAt: Date.now() };
|
|
719
|
+
return { ...resp, ...composedPayload };
|
|
720
|
+
} catch (e) {
|
|
721
|
+
_deps.recordSessionDiagnostic(sessionId, 'codex-rollout-history-compose-error', { error: e.message });
|
|
722
|
+
return resp;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
module.exports = {
|
|
728
|
+
configure,
|
|
729
|
+
_codexRowCandidateIds,
|
|
730
|
+
_sessionHasFocusedViewer,
|
|
731
|
+
requestRowCursorRepublish,
|
|
732
|
+
_codexRowHistoryBase,
|
|
733
|
+
_matchingPublishedCodexRollout,
|
|
734
|
+
_transcriptHistoryProvider,
|
|
735
|
+
_codexRolloutHistoryActive,
|
|
736
|
+
_codexHistoryRenderCacheEntry,
|
|
737
|
+
_codexHistoryRenderNull,
|
|
738
|
+
_codexHistoryRenderInputForBase,
|
|
739
|
+
_runCodexHistoryRenderQueue,
|
|
740
|
+
_requestCodexHistoryRender,
|
|
741
|
+
_scheduleCodexHistoryRender,
|
|
742
|
+
_composeCodexRolloutResp,
|
|
743
|
+
};
|