create-walle 0.10.0 → 0.10.2
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 +88 -41
- package/lib/owner-write-safety.js +135 -0
- package/lib/public-runtime.js +13 -5
- package/lib/release-schema.json +3 -2
- package/lib/runtime-closure-policy.json +7 -5
- package/package.json +10 -4
- package/template/bin/deps-doctor.js +1 -1
- package/template/bin/node-bin.sh +11 -0
- package/template/coding-task-manager/api-prompts.js +10 -22
- package/template/coding-task-manager/bin/capture-codex-rollout-records.js +417 -0
- package/template/coding-task-manager/bin/census-codex-lead-history.js +325 -0
- package/template/coding-task-manager/bin/claude-hook.js +7 -3
- package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
- package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
- package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
- package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
- package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
- package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
- package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
- package/template/coding-task-manager/bin/seam-replay-codex.js +301 -0
- package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
- package/template/coding-task-manager/db.js +705 -286
- package/template/coding-task-manager/git-utils.js +44 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
- package/template/coding-task-manager/lib/agent-presets.js +15 -0
- package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
- package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
- package/template/coding-task-manager/lib/api/host-stats.js +98 -0
- package/template/coding-task-manager/lib/api/ingress.js +35 -12
- package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
- package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
- package/template/coding-task-manager/lib/api/machines.js +461 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
- package/template/coding-task-manager/lib/api/providers.js +53 -6
- package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
- package/template/coding-task-manager/lib/api/sessions.js +160 -8
- package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
- package/template/coding-task-manager/lib/api/worktrees.js +38 -37
- package/template/coding-task-manager/lib/approval-drift.js +16 -1
- package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
- package/template/coding-task-manager/lib/approval-scope.js +68 -4
- package/template/coding-task-manager/lib/auth-context.js +32 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
- package/template/coding-task-manager/lib/auth-rules.js +186 -45
- package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
- package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
- package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
- package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
- package/template/coding-task-manager/lib/claude-session-title.js +6 -30
- package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
- package/template/coding-task-manager/lib/client-diag-handler.js +25 -0
- package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
- package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
- package/template/coding-task-manager/lib/codex-history-terminal-renderer.js +33 -33
- package/template/coding-task-manager/lib/codex-launch-health.js +29 -2
- package/template/coding-task-manager/lib/codex-link-preparation.js +9 -8
- package/template/coding-task-manager/lib/codex-local-links.js +267 -0
- package/template/coding-task-manager/lib/codex-markdown-lists.js +160 -0
- package/template/coding-task-manager/lib/codex-native-history-prefix.js +4 -0
- package/template/coding-task-manager/lib/codex-paths.js +2 -1
- package/template/coding-task-manager/lib/codex-source-handoff.js +186 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +21 -30
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
- package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
- package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
- package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
- package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
- package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
- package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
- package/template/coding-task-manager/lib/db-domains.js +21 -2
- package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +22 -0
- package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
- package/template/coding-task-manager/lib/feature-manifest.js +1 -3
- package/template/coding-task-manager/lib/fs-watcher.js +3 -2
- package/template/coding-task-manager/lib/harness-history-transition.js +41 -14
- package/template/coding-task-manager/lib/headless-inflight-ops.js +203 -0
- package/template/coding-task-manager/lib/headless-missing-reply.js +42 -0
- package/template/coding-task-manager/lib/headless-term-service.js +60 -23
- package/template/coding-task-manager/lib/history-transition-read-op.js +179 -23
- package/template/coding-task-manager/lib/host-control-dial.js +167 -0
- package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
- package/template/coding-task-manager/lib/host-handoff.js +51 -13
- package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
- package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
- package/template/coding-task-manager/lib/host-stats.js +328 -0
- package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
- package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
- package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
- package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
- package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
- package/template/coding-task-manager/lib/instance-manifest.js +13 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
- package/template/coding-task-manager/lib/kernel/diag-log.js +12 -0
- package/template/coding-task-manager/lib/launch-model-override.js +160 -1
- package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
- package/template/coding-task-manager/lib/lead-model-observer.js +17 -2
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
- package/template/coding-task-manager/lib/lead-model-switch.js +11 -2
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +42 -4
- package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
- package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
- package/template/coding-task-manager/lib/login-tripwire.js +18 -0
- package/template/coding-task-manager/lib/machine-pairing.js +238 -0
- package/template/coding-task-manager/lib/machine-pool.js +409 -0
- package/template/coding-task-manager/lib/machine-registry.js +749 -0
- package/template/coding-task-manager/lib/machine-self.js +66 -0
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +56 -4
- package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
- package/template/coding-task-manager/lib/media-journal.js +84 -27
- package/template/coding-task-manager/lib/media-store-options.js +43 -15
- package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
- package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +16 -3
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/collaboration-codec.js +94 -0
- package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
- package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
- package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
- package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
- package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
- package/template/coding-task-manager/lib/model-proxy/responses-face.js +24 -2
- package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
- package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-history-control.js +62 -14
- package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
- package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
- package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
- package/template/coding-task-manager/lib/prompt-admission-trace.js +69 -0
- package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
- package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
- package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
- package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
- package/template/coding-task-manager/lib/raw-history-block.js +3 -1
- package/template/coding-task-manager/lib/read-pool-client.js +36 -24
- package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
- package/template/coding-task-manager/lib/read-pool-telemetry.js +14 -5
- package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
- package/template/coding-task-manager/lib/remote-command-context.js +12 -0
- package/template/coding-task-manager/lib/remote-command-runtime.js +18 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
- package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
- package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
- package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
- package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
- package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
- package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
- package/template/coding-task-manager/lib/restart-preflight.js +9 -2
- package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
- package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
- package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
- package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
- package/template/coding-task-manager/lib/resume-cwd.js +13 -0
- package/template/coding-task-manager/lib/resume-from-store.js +12 -1
- package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
- package/template/coding-task-manager/lib/resume-preflight.js +21 -16
- package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
- package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
- package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
- package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
- package/template/coding-task-manager/lib/root-prompt-admission.js +43 -11
- package/template/coding-task-manager/lib/root-prompt-flow.js +175 -38
- package/template/coding-task-manager/lib/scrollback-archive-store.js +7 -4
- package/template/coding-task-manager/lib/server-memory-sampler-runtime.js +10 -0
- package/template/coding-task-manager/lib/server-memory-sampler.js +41 -2
- package/template/coding-task-manager/lib/session-analysis-memory.js +2 -0
- package/template/coding-task-manager/lib/session-create/codex-native-provider-gate.js +218 -0
- package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
- package/template/coding-task-manager/lib/session-create/identity.js +20 -1
- package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
- package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
- package/template/coding-task-manager/lib/session-create/provider-process.js +38 -39
- package/template/coding-task-manager/lib/session-create/response.js +30 -12
- package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
- package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
- package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
- package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
- package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
- package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
- package/template/coding-task-manager/lib/session-host-manager.js +152 -206
- package/template/coding-task-manager/lib/session-jobs.js +17 -9
- package/template/coding-task-manager/lib/session-lifecycle.js +20 -50
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +68 -3
- package/template/coding-task-manager/lib/session-resource-sampler.js +67 -9
- package/template/coding-task-manager/lib/session-standup.js +67 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +42 -3
- package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
- package/template/coding-task-manager/lib/session-status.js +2 -2
- package/template/coding-task-manager/lib/session-title-mirror.js +25 -57
- package/template/coding-task-manager/lib/session-transcript-trash.js +8 -1
- package/template/coding-task-manager/lib/startup-pointer-write.js +57 -0
- package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
- package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
- package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
- package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
- package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
- package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
- package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
- package/template/coding-task-manager/lib/transcript-link.js +77 -0
- package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
- package/template/coding-task-manager/lib/transcript-source.js +8 -3
- package/template/coding-task-manager/lib/transcript-store.js +40 -0
- package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
- package/template/coding-task-manager/lib/typing-interaction-trace.js +136 -2
- package/template/coding-task-manager/lib/typing-worker-stages.js +208 -1
- package/template/coding-task-manager/lib/usage-ledger/claude-parse.js +53 -2
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +13 -4
- package/template/coding-task-manager/lib/usage-ledger/read.js +14 -0
- package/template/coding-task-manager/lib/usage-ledger/schema.js +49 -1
- package/template/coding-task-manager/lib/usage-ledger/store.js +337 -6
- package/template/coding-task-manager/lib/usage-ledger/task-read.js +123 -5
- package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
- package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
- package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
- package/template/coding-task-manager/lib/ws/input.js +1 -0
- package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
- package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
- package/template/coding-task-manager/lib/ws-router.js +68 -1
- package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
- package/template/coding-task-manager/oauth-proxy.js +99 -55
- package/template/coding-task-manager/package-lock.json +24 -0
- package/template/coding-task-manager/package.json +3 -0
- package/template/coding-task-manager/protocol/message-table.json +0 -10
- package/template/coding-task-manager/protocol/messages.js +0 -10
- package/template/coding-task-manager/protocol/ws-schema.json +0 -20
- package/template/coding-task-manager/protocol/ws-schema.md +0 -2
- package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
- package/template/coding-task-manager/providers/codex-mcp.js +14 -5
- package/template/coding-task-manager/public/css/app.css +279 -2
- package/template/coding-task-manager/public/css/reviews.css +4 -0
- package/template/coding-task-manager/public/index.html +297 -240
- package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
- package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
- package/template/coding-task-manager/public/js/background-work.js +13 -7
- package/template/coding-task-manager/public/js/client-health-core.js +81 -0
- package/template/coding-task-manager/public/js/client-health-main.js +61 -0
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
- package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
- package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
- package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
- package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
- package/template/coding-task-manager/public/js/history-scroller.js +187 -9
- package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
- package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
- package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
- package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -4
- package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
- package/template/coding-task-manager/public/js/protocol.js +0 -10
- package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
- package/template/coding-task-manager/public/js/reviews.js +7 -3
- package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
- package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
- package/template/coding-task-manager/public/js/row-join.js +18 -3
- package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
- package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
- package/template/coding-task-manager/public/js/session-usage-view.js +1 -0
- package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
- package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
- package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
- package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
- package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
- package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
- package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
- package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -3
- package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
- package/template/coding-task-manager/public/js/walle-session.js +30 -7
- package/template/coding-task-manager/public/m/app.css +226 -8
- package/template/coding-task-manager/public/m/app.js +502 -9
- package/template/coding-task-manager/public/m/index.html +38 -1
- package/template/coding-task-manager/public/m/machines.js +1313 -0
- package/template/coding-task-manager/public/m/pool-failover.js +391 -0
- package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
- package/template/coding-task-manager/public/m/sw.js +5 -0
- package/template/coding-task-manager/queue-engine.js +13 -0
- package/template/coding-task-manager/server/approvals.js +5 -6
- package/template/coding-task-manager/server/boot.js +136 -17
- package/template/coding-task-manager/server.js +964 -425
- package/template/coding-task-manager/session-integrity.js +7 -9
- package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
- package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
- package/template/coding-task-manager/workers/session-host-process.js +14 -3
- package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
- package/template/coding-task-manager/workers/worktree-worker.js +34 -0
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/scripts/conversation-storage-v2-migration.js +78 -11
- package/template/shared/conversation-storage-v2-contract.js +42 -6
- package/template/shared/fixtures/worker-status-payloads.json +392 -0
- package/template/shared/git-remote-key.js +83 -0
- package/template/shared/host-identity.js +98 -2
- package/template/shared/owner-write-safety.js +135 -0
- package/template/shared/public-runtime.js +13 -5
- package/template/shared/release-schema.json +3 -2
- package/template/shared/report-citations.js +14 -0
- package/template/shared/sqlite-write-lock.js +361 -223
- package/template/shared/storage/contract.js +35 -3
- package/template/wall-e/agent.js +21 -0
- package/template/wall-e/api-walle.js +5 -0
- package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
- package/template/wall-e/brain/helper-rules-schema.js +129 -0
- package/template/wall-e/brain/migrations.js +51 -22
- package/template/wall-e/brain/model-deployment-facts.js +31 -1
- package/template/wall-e/brain/owner-call-whitelist.js +16 -0
- package/template/wall-e/brain/schema-ensures.js +22 -0
- package/template/wall-e/brain.js +1 -1
- package/template/wall-e/coding/host-capabilities.js +2 -2
- package/template/wall-e/coding/journal-dispatcher.js +51 -0
- package/template/wall-e/coding/session-journal.js +28 -40
- package/template/wall-e/coding-orchestrator.js +23 -26
- package/template/wall-e/fly.toml +1 -1
- package/template/wall-e/http/auth.js +18 -1
- package/template/wall-e/http/blog-views-api.js +318 -0
- package/template/wall-e/http/helper-rules-api.js +321 -0
- package/template/wall-e/http/model-proxy-providers.js +3 -1
- package/template/wall-e/http/telemetry-api.js +12 -0
- package/template/wall-e/lib/blog-view-policy.js +88 -0
- package/template/wall-e/lib/blog-view-store.js +169 -0
- package/template/wall-e/lib/client-config-lock.js +2 -1
- package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
- package/template/wall-e/lib/error-kinds.js +10 -1
- package/template/wall-e/lib/feature-manifest.js +1 -1
- package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
- package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
- package/template/wall-e/lib/helper-rules/grade.js +277 -0
- package/template/wall-e/lib/helper-rules/label.js +247 -0
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
- package/template/wall-e/lib/helper-rules/store.js +667 -0
- package/template/wall-e/lib/mcp-integration.js +5 -6
- package/template/wall-e/lib/runtime-worker-pool.js +1 -0
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
- package/template/wall-e/lib/telemetry-db-schema.js +37 -0
- package/template/wall-e/lib/telemetry-process-client.js +76 -1
- package/template/wall-e/llm/default-fallback.js +4 -0
- package/template/wall-e/llm/model-catalog.js +13 -4
- package/template/wall-e/llm/model-roles.js +6 -0
- package/template/wall-e/llm/portkey-http.js +150 -0
- package/template/wall-e/llm/portkey-sync.js +15 -145
- package/template/wall-e/llm/worker-mcp-routing.js +61 -0
- package/template/wall-e/llm/worker-route.js +43 -1
- package/template/wall-e/loops/brain-custom-writes.js +45 -0
- package/template/wall-e/mcp-protocol-contract.js +41 -1
- package/template/wall-e/mcp-server.js +13 -2
- package/template/wall-e/mcp-worker-schemas.js +20 -2
- package/template/wall-e/memory/ctm-context-client.js +25 -5
- package/template/wall-e/shared/release-schema.json +3 -2
- package/template/wall-e/shared/sqlite-write-lock.js +361 -223
- package/template/wall-e/shared/storage/contract.js +35 -3
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
- package/template/wall-e/tools/local-tools.js +12 -5
- package/template/wall-e/workers/brain-owner-worker.js +9 -0
- package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
- package/template/wall-e/workers/telemetry-worker.js +8 -0
- package/template/coding-task-manager/lib/giant-freeze-park.js +0 -31
|
@@ -456,7 +456,14 @@ function resolveCreateLaunchParams(ctx) {
|
|
|
456
456
|
// alias because startup_tasks still stores that legacy column.
|
|
457
457
|
const requestedTitle = String(msg.title || msg.label || '').replace(/^Resume:\s*/i, '').trim().slice(0, 120);
|
|
458
458
|
const walleResumeRequest = msg.resumeWalle === true && !msg._isRestore;
|
|
459
|
-
|
|
459
|
+
// D-1: every resume sender echoes the row's own DISPLAYED title back (`label`/`title`), and
|
|
460
|
+
// an echoed label is not user intent — so a resume never yields a tier-1 (user) name.
|
|
461
|
+
// D-13/WP-5: a CTM-composed label (`Shell:`, `Folder:`, `Code Review:`, a review session, a
|
|
462
|
+
// best-of attempt, the Claude Desktop fork) declares itself with `titleIntent:'default'`, so it is
|
|
463
|
+
// written at tier 3 like any other echo. An absent titleIntent keeps today's semantics (an old
|
|
464
|
+
// client causes no regression), and the New Session modal's typed label still lands tier 1.
|
|
465
|
+
const hasExplicitClientTitle = !msg._isRestore && !walleResumeRequest && !isResumeLaunch
|
|
466
|
+
&& msg.titleIntent !== 'default' && !!requestedTitle;
|
|
460
467
|
let title = requestedTitle;
|
|
461
468
|
if (!title) {
|
|
462
469
|
const agentName = cmd.includes('claude') ? 'Claude Code'
|
|
@@ -91,8 +91,9 @@ function ctmLifecycleJournalPath({ env = process.env, configDir = null, instance
|
|
|
91
91
|
return path.join(resolveEffectiveDataDir({ env, configDir }), 'logs', fileName);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
function appendCtmBootLine({ pid = process.pid, env = process.env, configDir = null, instanceTag = null, port = null } = {}) {
|
|
94
|
+
function appendCtmBootLine({ pid = process.pid, env = process.env, configDir = null, instanceTag = null, port = null, enteredAtServer = false } = {}) {
|
|
95
95
|
_reportLaunchdProcessTypeOnBoot(env);
|
|
96
|
+
_reportBootEntryOnBoot(env, { enteredAtServer });
|
|
96
97
|
return appendLifecycleLine(ctmLifecycleJournalPath({ env, configDir, instanceTag, port }), {
|
|
97
98
|
ts: new Date().toISOString(),
|
|
98
99
|
event: 'ctm-boot',
|
|
@@ -127,10 +128,25 @@ function _reportLaunchdProcessTypeOnBoot(env = process.env) {
|
|
|
127
128
|
} catch { /* expected: a boot-time advisory must never block boot; the plist may be unreadable on a hardened install */ }
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
// WP-2 (clock-free r6 OQ-6): report-only boot check for the OTHER install drift — a launchd-managed
|
|
132
|
+
// CTM whose plist still points at server.js directly, so bin/ctm-service-entry.js's conversation-storage
|
|
133
|
+
// boot gate never ran. Rather than diff the plist (a second source of truth, and one that can't tell a
|
|
134
|
+
// wrapper that execs the entry from a real bypass — D-2), the caller reports the RUNTIME fact
|
|
135
|
+
// `require.main === module`. Warns once per boot so the drift can't stay silent for a month; never blocks
|
|
136
|
+
// boot, never invokes launchctl, never reads or writes the plist. Only the real launchd-managed primary
|
|
137
|
+
// is checked — a /ctm-dev instance (CTM_MANAGED_BY_LAUNCHD unset/'0') or non-darwin host has no plist.
|
|
138
|
+
function _reportBootEntryOnBoot(env = process.env, { enteredAtServer = false, platform = process.platform, warn = console.warn } = {}) {
|
|
139
|
+
if (!enteredAtServer || env.CTM_MANAGED_BY_LAUNCHD !== '1' || platform !== 'darwin') return;
|
|
140
|
+
try {
|
|
141
|
+
warn('[launchd] CTM was started at server.js, so the conversation-storage boot gate did not run; re-run bin/install-service.sh or npx create-walle to enter through bin/ctm-service-entry.js');
|
|
142
|
+
} catch { /* expected: a boot-time advisory must never block boot */ }
|
|
143
|
+
}
|
|
144
|
+
|
|
130
145
|
module.exports = {
|
|
131
146
|
resolvePrimaryDataDir,
|
|
132
147
|
resolveEffectiveDataDir,
|
|
133
148
|
isPrimaryInstance,
|
|
134
149
|
ctmLifecycleJournalPath,
|
|
135
150
|
appendCtmBootLine,
|
|
151
|
+
_reportBootEntryOnBoot,
|
|
136
152
|
};
|
|
@@ -93,6 +93,13 @@ const TABLE_DOMAINS = Object.freeze({
|
|
|
93
93
|
// WP-3 (§6.4 S-12): where a shipped transcript landed on THIS instance. Same domain as
|
|
94
94
|
// agent_sessions (the identity row it is written alongside) so one handle serves the consumer.
|
|
95
95
|
sync_transcript_replicas: 'core',
|
|
96
|
+
// WP-0 (remote-machine-hub-sessions-2026-10-22.html §6.1): the hub machine registry.
|
|
97
|
+
machines: 'core',
|
|
98
|
+
// WP-1 (machine-pool-picker-pairing-dashboard-2026-10-24.html §6.1, D-4/D-6/D-11): the machine
|
|
99
|
+
// pool's own tables, same domain as `machines` — one 'core' handle serves the whole feature.
|
|
100
|
+
host_samples: 'core',
|
|
101
|
+
machine_self: 'core',
|
|
102
|
+
machine_pairing_offers: 'core',
|
|
96
103
|
// Legacy pre-v1 predecessors of ctm_sessions/agent_sessions/session_index.
|
|
97
104
|
// Superseded but their CREATE TABLE IF NOT EXISTS guards remain for
|
|
98
105
|
// fresh-v0 / mid-migration databases. Same domain as their successors
|
|
@@ -193,6 +193,26 @@ const CTM_WRITE_OPS = Object.freeze([
|
|
|
193
193
|
'deleteChain', 'deleteCtmSession', 'deleteFolder', 'deleteHook', 'deleteImage',
|
|
194
194
|
'deletePermissionRule', 'deletePrompt', 'deleteReview', 'deleteReviewComment',
|
|
195
195
|
'deleteSessionAnalysis', 'deleteStaleAnalyses', 'deleteTemplate',
|
|
196
|
+
// WP-2 (docs/remote-machine-hub-sessions-2026-10-22.html §6.1/§8, deferred from WP-0): the hub
|
|
197
|
+
// machine-registry writes. `machines` is domain 'core' (lib/db-domain-tables.js), and each op's
|
|
198
|
+
// OP_META row in shared/storage/contract.js carries the same tag — Gate 2c (CTM_WRITE_OPS →
|
|
199
|
+
// OP_META kind:'write' + domain) and Gate 2c-inventory (a domain-tagged write op outside this
|
|
200
|
+
// list) are exactly the two assertions that require the pair to land together.
|
|
201
|
+
'upsertMachineRow', 'recordMachineProbe', 'deleteMachineRow',
|
|
202
|
+
// WP-1 (machine-pool-picker-pairing-dashboard-2026-10-24.html §6.1, D-11): the 60 s host-sample
|
|
203
|
+
// write, on the same `core` handle as the machines rows above; its OP_META row in
|
|
204
|
+
// shared/storage/contract.js carries the matching kind:'write' + domain + tables:['host_samples'].
|
|
205
|
+
'recordHostSample',
|
|
206
|
+
// WP-2a (machine-pool-picker-pairing-dashboard-2026-10-24.html §6.1, D-4/P-5/P-6): the
|
|
207
|
+
// machine-owned settings write, the P-5 roster replacement (one transaction: upsert listed,
|
|
208
|
+
// delete unlisted, never self) and the leave() sweep. Each OP_META row in shared/storage/contract.js
|
|
209
|
+
// carries the matching kind:'write' + domain:'core'.
|
|
210
|
+
'setMachineSelf', 'replaceRosterMachines', 'deleteAllMachineRows',
|
|
211
|
+
// WP-3 (machine-pool-picker-pairing-dashboard-2026-10-24.html §6.3, D-6/D-9): the pairing-offer
|
|
212
|
+
// writes — mint, single-use redeem, and the 5-wrong-redeem burn. `machine_pairing_offers` is
|
|
213
|
+
// classified 'core' in lib/db-domain-tables.js and each op's OP_META row in
|
|
214
|
+
// shared/storage/contract.js carries the matching kind:'write' + domain + tables.
|
|
215
|
+
'insertPairingOffer', 'markPairingOfferRedeemed', 'burnLivePairingOffers',
|
|
196
216
|
'deleteWorkspace', 'detachPromotedProviderChildSessions', 'duplicatePrompt',
|
|
197
217
|
'enqueueSyncOutbox', 'flushSessionDiagnostics', 'flushSessionMetadataUpdates', 'heartbeatStartupTasks', 'incrementApprovalRuleMatch',
|
|
198
218
|
'markStartupTaskExited', 'markStartupTaskUserPromptInput', 'markSyncOutboxDeliveredThrough', 'recordSyncOutboxServed',
|
|
@@ -205,7 +225,7 @@ const CTM_WRITE_OPS = Object.freeze([
|
|
|
205
225
|
'supersedeHeldApprovalDecision', 'expireStaleHeldApprovalDecision', 'resolveApprovalDecision', 'claimWallePermissionResolution', 'commitWallePermissionResolution', 'expireOpenWallePermissions', 'restorePromptVersion', 'reviveStartupTask',
|
|
206
226
|
'saveApprovalAiRefinementRule', 'saveApprovalRescuePattern', 'saveImage',
|
|
207
227
|
'setAlwaysAsk', 'setPermRuleExceptions', 'setPromptParent',
|
|
208
|
-
'setScrollbackIdentity', 'setSessionStar', 'setSessionTitleMirror', 'setSessionTitleStatusNew',
|
|
228
|
+
'setScrollbackIdentity', 'setSessionStar', 'setSessionTitleMirror', 'setSessionTitleStatusNew', 'applyAgentTitleBackfillRows',
|
|
209
229
|
'setSetting', 'startAnalysisRun', 'toggleApprovalRule', 'toggleAutoApproval',
|
|
210
230
|
'toggleHook', 'trackPromptUsage', 'transferSessionOwnership', 'updateChain',
|
|
211
231
|
'updateCodingSessionModel', 'updateFolder', 'updateHarvestState',
|
|
@@ -256,7 +276,6 @@ const CTM_WRITE_OPS = Object.freeze([
|
|
|
256
276
|
'recordSyncPeerConflict', 'updateStartupTaskTitle', 'updateStartupTaskClaudeSession',
|
|
257
277
|
'updateStartupTaskAttentionDismissal', 'updateStartupTaskLifecycle',
|
|
258
278
|
'markStartupTaskParked', 'prepareScrollbackForSession', 'upsertAgentSessionIdentity',
|
|
259
|
-
'promoteStartupTaskTitleIfUserNamed', 'repairSessionTitlesFromStartupTasks',
|
|
260
279
|
'repairCodexRolloutAgentIdentities', 'cleanupOrphanScrollbackIdentities',
|
|
261
280
|
].concat(require('../../shared/storage/ctm-domain-operation-contract').WORKSPACE_ACTIVITY_OWNER_WRITE_OPS));
|
|
262
281
|
|
|
@@ -124,6 +124,13 @@ const RAW_DB_OWNER_OPS = {
|
|
|
124
124
|
updatePromptEffectiveness: { expectedMs: 5000, resumable: false },
|
|
125
125
|
applySafeRelinkRepairs: { expectedMs: 1000, resumable: false },
|
|
126
126
|
recoverSessionIntegrity: { expectedMs: 1000, resumable: false },
|
|
127
|
+
// WP-3 (worker-transcript-link-derived-not-discovered-2026-10-25.html §5 D-5): one bounded,
|
|
128
|
+
// idempotent boot pass that fills agent_sessions.jsonl_path for Claude rows whose transcript is
|
|
129
|
+
// already at the derived path. `expectedMs` is a budget HINT, not a deadline: the dispatch
|
|
130
|
+
// deadline is max(interactive floor 60s, expectedMs*8) (lib/db-owner-op-deadline.js), and the op
|
|
131
|
+
// is additionally bounded by payload.limit (<=500 rows). Not resumable: the caller is a
|
|
132
|
+
// fire-and-forget boot hook with no redrive, and a redrive could only re-run a no-op.
|
|
133
|
+
linkDerivedClaudeTranscripts: { expectedMs: 2000, resumable: false },
|
|
127
134
|
backfillSessionMessagesAsync: { expectedMs: 500, resumable: false },
|
|
128
135
|
runContentRowsBackfillSweep: { expectedMs: 500, resumable: false },
|
|
129
136
|
deleteStaleSessionAnalysesFromArtifact: {
|
|
@@ -937,12 +937,34 @@ class CtmDbOwnerWorkerClient {
|
|
|
937
937
|
}).catch(() => {});
|
|
938
938
|
}
|
|
939
939
|
|
|
940
|
+
// WP-A P-2 (freeze-probes): the up-to-`limit` OLDEST client requests still outstanding on this
|
|
941
|
+
// worker, each { op, ageMs, started } -- what a memory step should be read against. One pass over
|
|
942
|
+
// the Map with a bounded insert (never a sort of the whole pending set: this runs on the sampler path).
|
|
943
|
+
_oldestPendingOps(limit = 5) {
|
|
944
|
+
const now = Date.now();
|
|
945
|
+
const oldest = [];
|
|
946
|
+
for (const pending of this._pending.values()) {
|
|
947
|
+
const entry = {
|
|
948
|
+
op: String(pending?.op || 'unknown'),
|
|
949
|
+
ageMs: Math.max(0, now - (Number(pending?.enqueuedAt) || now)),
|
|
950
|
+
started: Number(pending?.startedAt) > 0,
|
|
951
|
+
};
|
|
952
|
+
let at = oldest.length;
|
|
953
|
+
while (at > 0 && oldest[at - 1].ageMs < entry.ageMs) at -= 1;
|
|
954
|
+
if (at >= limit) continue;
|
|
955
|
+
oldest.splice(at, 0, entry);
|
|
956
|
+
if (oldest.length > limit) oldest.pop();
|
|
957
|
+
}
|
|
958
|
+
return oldest;
|
|
959
|
+
}
|
|
960
|
+
|
|
940
961
|
getStatus() {
|
|
941
962
|
const s = {
|
|
942
963
|
...this._status,
|
|
943
964
|
ready: this._ready,
|
|
944
965
|
closed: this._closed,
|
|
945
966
|
pendingClientRequests: this._pending.size,
|
|
967
|
+
pendingOps: this._oldestPendingOps(),
|
|
946
968
|
degraded: this.isDegraded(),
|
|
947
969
|
degradedUntil: this._degradedUntil,
|
|
948
970
|
consecutiveTimeouts: this._consecutiveTimeouts,
|
|
@@ -39,6 +39,7 @@ const SCHEMA_SOURCE_FILES = Object.freeze([
|
|
|
39
39
|
'lib/migrations/v52-coding-session-launch-generations.js',
|
|
40
40
|
'lib/migrations/v53-session-model-intent.js',
|
|
41
41
|
'lib/migrations/v54-session-lead-model.js',
|
|
42
|
+
'lib/migrations/v56-host-samples-and-machine-pool.js',
|
|
42
43
|
'lib/migrations/v29-usage-accounting.js', 'lib/migrations/v30-usage-reporting.js', 'lib/migrations/v36-conversation-projection-deletes.js',
|
|
43
44
|
'../shared/usage-store.js', '../shared/usage-reporting-schema.js',
|
|
44
45
|
'lib/delete-ctm-session-saga.js',
|
|
@@ -612,8 +612,6 @@ const FEATURES = [
|
|
|
612
612
|
{ id: "ctm_ctm_fp_memo", env: "CTM_FP_MEMO", owner: "ctm-core-team", stage: "stable", defaultOn: true, since: "2026-08-24", expires: null },
|
|
613
613
|
// !== '0' comparison found; 1 site(s); first: lib/ws/state-sync.js:470
|
|
614
614
|
{ id: "ctm_ctm_frame_nack", env: "CTM_FRAME_NACK", owner: "ctm-core-team", stage: "stable", defaultOn: true, since: "2026-08-24", expires: null },
|
|
615
|
-
// !== '0' comparison found; 1 site(s); first: server.js:36110
|
|
616
|
-
{ id: "ctm_ctm_freeze_park_giant", env: "CTM_FREEZE_PARK_GIANT", owner: "ctm-core-team", stage: "stable", defaultOn: true, since: "2026-08-24", expires: null },
|
|
617
615
|
// numeric-tunable suffix/read shape; 1 site(s); first: lib/perf-tracker.js:829
|
|
618
616
|
{ id: "ctm_ctm_freeze_probe_ms", env: "CTM_FREEZE_PROBE_MS", owner: "ctm-core-team", stage: "ops", tunable: true, default: 0, since: "2026-08-24", expires: null, note: "numeric tunable" },
|
|
619
617
|
// !== '0' comparison found; 1 site(s); first: server.js:445
|
|
@@ -1559,7 +1557,7 @@ const FEATURES = [
|
|
|
1559
1557
|
// no polarity/tunable/config pattern matched; 1 site(s); first: db.js:4416
|
|
1560
1558
|
{ id: "ctm_ctm_sqlite_synchronous", env: "CTM_SQLITE_SYNCHRONOUS", owner: "ctm-core-team", stage: "ops", defaultOn: true, since: "2026-08-24", expires: null, note: "unclassified raw read; needs manual triage" },
|
|
1561
1559
|
// numeric-tunable suffix/read shape; 1 site(s); first: db.js:4373
|
|
1562
|
-
{ id: "ctm_ctm_sqlite_write_lock_stale_ms", env: "CTM_SQLITE_WRITE_LOCK_STALE_MS", owner: "ctm-core-team", stage: "
|
|
1560
|
+
{ id: "ctm_ctm_sqlite_write_lock_stale_ms", env: "CTM_SQLITE_WRITE_LOCK_STALE_MS", owner: "ctm-core-team", stage: "removed", defaultOn: false, since: "2026-08-24", expires: null, note: "retired 2026-10-23 (fsevents-churn WP-1, docs/fsevents-churn-kernel-write-lock-2026-10-23.html D-4): the SQLite write lock is a kernel lock on a .mutex lock DB released by the OS when its holder dies, so stale-claim recovery and its age knob were deleted; no read of this name survives." },
|
|
1563
1561
|
// !== '0' comparison found; 1 site(s); first: server.js:448
|
|
1564
1562
|
{ id: "ctm_ctm_stale_grid_embargo", env: "CTM_STALE_GRID_EMBARGO", owner: "ctm-core-team", stage: "stable", defaultOn: true, since: "2026-08-24", expires: null },
|
|
1565
1563
|
// !== '0' comparison found; 1 site(s); first: server.js:19764
|
|
@@ -4,6 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const EventEmitter = require('events');
|
|
5
5
|
const { namedInterval, runSync, wrap } = require('./perf-tracker');
|
|
6
6
|
const envFlags = require('./env-flags');
|
|
7
|
+
const { isWritableOnlyByOwner } = require('../../shared/owner-write-safety');
|
|
7
8
|
|
|
8
9
|
// Design doc mainloop-composer-freeze-2026-08-20.html §5 D-1, §6, §9 S-1/S-4. The 60s
|
|
9
10
|
// scan tick and the attach/reattach directory walk ran completely unwrapped, so the
|
|
@@ -103,7 +104,7 @@ function resolveRoot(root) {
|
|
|
103
104
|
result.refusalCode = 'wrong-owner';
|
|
104
105
|
return result;
|
|
105
106
|
}
|
|
106
|
-
if ((
|
|
107
|
+
if (!isWritableOnlyByOwner(targetStat)) {
|
|
107
108
|
result.validationStatus = 'refused';
|
|
108
109
|
result.refusalCode = 'unsafe-permissions';
|
|
109
110
|
return result;
|
|
@@ -159,7 +160,7 @@ async function resolveRootAsync(root) {
|
|
|
159
160
|
result.refusalCode = 'wrong-owner';
|
|
160
161
|
return result;
|
|
161
162
|
}
|
|
162
|
-
if ((
|
|
163
|
+
if (!isWritableOnlyByOwner(targetStat)) {
|
|
163
164
|
result.validationStatus = 'refused';
|
|
164
165
|
result.refusalCode = 'unsafe-permissions';
|
|
165
166
|
return result;
|
|
@@ -4,8 +4,14 @@ const NATIVE_ORIGINS = new Set(['native-codex', 'native-claude', 'native-opencod
|
|
|
4
4
|
const KNOWN_ORIGINS = new Set([...NATIVE_ORIGINS, 'routed-proxy', 'portable-transcript']);
|
|
5
5
|
// S-3: the adapter/schema ids and the version membership test come from the one qualified table.
|
|
6
6
|
const { CODEX_CONTROL_ADAPTER, CODEX_COMPACTION_SCHEMA_RECEIPT, CODEX_PRE_TURN_COMPACTION_SCHEMA,
|
|
7
|
-
isQualifiedCodexVersion } = require('./codex-harness-qualification');
|
|
8
|
-
|
|
7
|
+
isQualifiedCodexVersion, isNonElevatedCyberAccessProgram } = require('./codex-harness-qualification');
|
|
8
|
+
// S-4: the ONE portable-kind set. `native-media` is a message whose only non-text content parts are
|
|
9
|
+
// input_image parts (D-2); it is portable only to a Codex target, which is the planner's job below.
|
|
10
|
+
const PORTABLE_HISTORY_KINDS = new Set(['text', 'tool-pair', 'native-world-state', 'native-lifecycle', 'native-media']);
|
|
11
|
+
// D-5/D-6 (docs/codex-lead-routed-switch-history-handoff-2026-10-21.html §6.2): the plaintext handoff
|
|
12
|
+
// the source model writes is injected into the forked target, so it consumes target context that the
|
|
13
|
+
// source estimate does not count. 32 KiB of summary text is 8_192 tokens at four characters each.
|
|
14
|
+
const HANDOFF_TOKEN_RESERVE = 8_192;
|
|
9
15
|
|
|
10
16
|
function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}) {
|
|
11
17
|
if (signal?.aborted) return refuse('transition_cancelled');
|
|
@@ -17,9 +23,11 @@ function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}
|
|
|
17
23
|
const targetProviderId = nonempty(targetRecipe.providerId);
|
|
18
24
|
const origin = nonempty(sourceRecipe.origin);
|
|
19
25
|
const codexHistorySource = origin === 'native-codex' || sourceRecipe.harness === 'codex-cli';
|
|
26
|
+
// D-3: qualification is per record (D-1) plus the installed binary that performs the fork. The
|
|
27
|
+
// rollout's CREATOR version (session_meta.cli_version, written once at creation) is not the writer
|
|
28
|
+
// of its later records, so it is not a gate here.
|
|
20
29
|
const qualifiedCodexHistorySource = codexHistorySource
|
|
21
|
-
&& sourceRecipe.controlAdapterVersion === CODEX_CONTROL_ADAPTER
|
|
22
|
-
&& isQualifiedCodexVersion(sourceRecipe.programVersion);
|
|
30
|
+
&& sourceRecipe.controlAdapterVersion === CODEX_CONTROL_ADAPTER;
|
|
23
31
|
if (!origin) return refuse('source_origin_unknown');
|
|
24
32
|
if (!KNOWN_ORIGINS.has(origin)) return refuse('source_origin_unsupported');
|
|
25
33
|
if (!sourceProviderId || !targetProviderId) return refuse('provider_identity_unknown');
|
|
@@ -31,7 +39,7 @@ function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}
|
|
|
31
39
|
if (nativeSource && sourceProviderId === targetProviderId) {
|
|
32
40
|
return {
|
|
33
41
|
action: 'reuse', reason: 'same_provider_native_history', sourceCheckpoint,
|
|
34
|
-
estimateTokens, targetBudgetTokens: null, evidenceKind,
|
|
42
|
+
estimateTokens, targetBudgetTokens: null, evidenceKind, handoff: null,
|
|
35
43
|
};
|
|
36
44
|
}
|
|
37
45
|
|
|
@@ -40,12 +48,8 @@ function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}
|
|
|
40
48
|
if (!sourceCheckpoint) return refuse('source_checkpoint_unknown');
|
|
41
49
|
if (codexHistorySource && sourceProviderId !== targetProviderId
|
|
42
50
|
&& (!qualifiedCodexHistorySource
|
|
43
|
-
|| !
|
|
44
|
-
||
|
|
45
|
-
|| snapshot.previousSettings?.cyberAccessProgram !== null
|
|
46
|
-
|| (snapshot.previousSettings?.programVersion !== undefined
|
|
47
|
-
&& snapshot.previousSettings?.programVersion !== null
|
|
48
|
-
&& !isQualifiedCodexVersion(snapshot.previousSettings.programVersion))
|
|
51
|
+
|| !isNonElevatedCyberAccessProgram(sourceRecipe.cyberAccessProgram)
|
|
52
|
+
|| !isNonElevatedCyberAccessProgram(snapshot.previousSettings?.cyberAccessProgram)
|
|
49
53
|
|| targetRecipe.harness !== 'codex-cli' || !isQualifiedCodexVersion(targetRecipe.harnessVersion))) {
|
|
50
54
|
return refuse('native_fork_adapter_unqualified', { sourceCheckpoint });
|
|
51
55
|
}
|
|
@@ -71,7 +75,27 @@ function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}
|
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
if (snapshot.opaque === true || has(snapshot.historyKinds, 'opaque')) return refuse('opaque_history_not_portable', { sourceCheckpoint });
|
|
74
|
-
|
|
78
|
+
// D-2: native media is portable exactly when the target is Codex, which strips images the target
|
|
79
|
+
// cannot accept (core/src/context_manager/normalize.rs:346 @ rust-v0.163.0). A non-Codex target
|
|
80
|
+
// gets a plain refusal instead of a silent rewrite of the source history.
|
|
81
|
+
if (has(snapshot.historyKinds, 'native-media') && targetRecipe.harness !== 'codex-cli') {
|
|
82
|
+
return refuse('history_media_not_portable', { sourceCheckpoint });
|
|
83
|
+
}
|
|
84
|
+
// D-5/D-6: a sealed `compaction` item is carried by a plaintext handoff the SOURCE model writes
|
|
85
|
+
// before the switch. Exactly one sealed digest can be covered, and only the native openai source
|
|
86
|
+
// (whose own model can be asked to write it) can produce one; everything else keeps a named refusal.
|
|
87
|
+
const sealed = (Array.isArray(snapshot.encryptedCompactions) ? snapshot.encryptedCompactions : [])
|
|
88
|
+
.filter((sha) => typeof sha === 'string' && /^[a-f0-9]{64}$/.test(sha));
|
|
89
|
+
if (sealed.length > 1) return refuse('encrypted_compaction_multiple', { sourceCheckpoint });
|
|
90
|
+
const handoff = sealed.length === 1 && snapshot.handoffCovers !== true
|
|
91
|
+
? (qualifiedCodexHistorySource && origin === 'native-codex' && sourceProviderId === 'openai'
|
|
92
|
+
? { required: true, compactionSha256: sealed[0] } : null)
|
|
93
|
+
: null;
|
|
94
|
+
if (sealed.length === 1 && snapshot.handoffCovers !== true && !handoff) {
|
|
95
|
+
return refuse('encrypted_compaction_handoff_unavailable', { sourceCheckpoint });
|
|
96
|
+
}
|
|
97
|
+
// D-4: a plaintext compaction is portable. Codex fork rebuilds the window from
|
|
98
|
+
// replacement_history, and no test, doc or incident ever justified the blanket refusal.
|
|
75
99
|
if (snapshot.encrypted === true || has(snapshot.historyKinds, 'encrypted')) return refuse('encrypted_history_not_portable', { sourceCheckpoint });
|
|
76
100
|
if (!Array.isArray(snapshot.historyKinds) || snapshot.historyKinds.length === 0
|
|
77
101
|
|| snapshot.historyKinds.some((kind) => !PORTABLE_HISTORY_KINDS.has(kind))) {
|
|
@@ -126,7 +150,10 @@ function inspectTransition({ sourceRecipe, targetRecipe, snapshot, signal } = {}
|
|
|
126
150
|
: null;
|
|
127
151
|
const evidence = { sourceCheckpoint, estimateTokens, targetBudgetTokens, evidenceKind,
|
|
128
152
|
...(preTurnCompaction ? { preTurnCompaction } : {}) };
|
|
129
|
-
|
|
153
|
+
// The injected handoff is target context the source estimate cannot see, so the comparison
|
|
154
|
+
// reserves it while every reported evidence field keeps the measured source value.
|
|
155
|
+
const budgetTokens = handoff?.required ? estimateTokens + HANDOFF_TOKEN_RESERVE : estimateTokens;
|
|
156
|
+
if (budgetTokens <= targetBudgetTokens) return { action: 'reuse', reason: 'history_fits_target', ...evidence, handoff };
|
|
130
157
|
|
|
131
158
|
// Phase A has no qualified source-owned compact adapter. Native API acknowledgements alone
|
|
132
159
|
// are not durable checkpoint receipts, so a recipe flag cannot authorize mutation here.
|
|
@@ -191,4 +218,4 @@ function refuse(reason, details = {}) {
|
|
|
191
218
|
return { action: 'unsupported', reason, ...details };
|
|
192
219
|
}
|
|
193
220
|
|
|
194
|
-
module.exports = { inspectTransition, computeTargetBudget };
|
|
221
|
+
module.exports = { inspectTransition, computeTargetBudget, PORTABLE_HISTORY_KINDS, HANDOFF_TOKEN_RESERVE };
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// WP-0 (stale-pty-host-evacuation-2026-10-24.html, D-6 §5/§6, S-12): the ONE
|
|
4
|
+
// shared op-stamp slot pair in headless-term-service.js could only ever name
|
|
5
|
+
// whichever op had stamped last, and any op finishing zeroed it unconditionally.
|
|
6
|
+
// This module keeps a PER-SESSION in-flight op table instead, so a wedged op
|
|
7
|
+
// names its own session (and the depth of work queued behind it) even while
|
|
8
|
+
// another session is happily churning.
|
|
9
|
+
//
|
|
10
|
+
// Report-only by construction: nothing here can reject, time out, retry or
|
|
11
|
+
// reorder an op (AC-0e). Every entry is a plain value; `now` is injected so
|
|
12
|
+
// tests can grow an age without a wall clock.
|
|
13
|
+
|
|
14
|
+
// An op that has been in flight this long is worth a one-shot
|
|
15
|
+
// `headless-op-overdue` diagnostic (D-6 §6): long enough that a healthy host
|
|
16
|
+
// never trips it, short enough to name the wedge inside the watchdog's own
|
|
17
|
+
// minute-scale reporting.
|
|
18
|
+
const HEADLESS_OP_OVERDUE_MS = 30_000;
|
|
19
|
+
// How many entries a threadpool frame may carry (D-6 §6: the five oldest).
|
|
20
|
+
const HEADLESS_OP_FRAME_MAX = 5;
|
|
21
|
+
|
|
22
|
+
function _sidOf(value) {
|
|
23
|
+
return value == null ? '' : String(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// createInFlightOps({ now }) -> { begin, end, noteQueued, list, oldest }.
|
|
27
|
+
//
|
|
28
|
+
// `queued` is the number of ops enqueued for that session and not yet started,
|
|
29
|
+
// i.e. the depth waiting behind the running one. It is tracked in `waiting` (a
|
|
30
|
+
// session -> count map) rather than on the entry, so two ops enqueued
|
|
31
|
+
// synchronously -- before the chain's first microtask stamps either of them --
|
|
32
|
+
// still count correctly: enqueue bumps `waiting`, a start decrements it, and
|
|
33
|
+
// list()/begin() report the remainder.
|
|
34
|
+
function createInFlightOps({ now = Date.now } = {}) {
|
|
35
|
+
const entries = new Map(); // sessionId -> { sessionId, opType, startedAt, seq, queued }
|
|
36
|
+
const waiting = new Map(); // sessionId -> ops enqueued but not yet started
|
|
37
|
+
let seqCounter = 0;
|
|
38
|
+
|
|
39
|
+
const waitingFor = (sid) => waiting.get(sid) || 0;
|
|
40
|
+
|
|
41
|
+
function _setWaiting(sid, count) {
|
|
42
|
+
if (count > 0) waiting.set(sid, count);
|
|
43
|
+
else waiting.delete(sid);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Called when an op actually starts (the stamp site of the per-session chain,
|
|
47
|
+
// and ONLY that chain -- an op dispatched outside it, e.g. a direct
|
|
48
|
+
// getViewportText, must not register here: `entries` holds one row per session,
|
|
49
|
+
// so it would overwrite a wedged chain op and its end() would then delete the
|
|
50
|
+
// wedge). Returns its seq, which the caller passes back to end() so a stale
|
|
51
|
+
// finisher cannot delete a newer op.
|
|
52
|
+
function begin(sessionId, opType) {
|
|
53
|
+
const sid = _sidOf(sessionId);
|
|
54
|
+
const behind = Math.max(0, waitingFor(sid) - 1);
|
|
55
|
+
_setWaiting(sid, behind);
|
|
56
|
+
const seq = (seqCounter += 1);
|
|
57
|
+
entries.set(sid, {
|
|
58
|
+
sessionId: sid,
|
|
59
|
+
opType: opType == null || opType === '' ? 'none' : String(opType),
|
|
60
|
+
startedAt: now(),
|
|
61
|
+
seq,
|
|
62
|
+
queued: behind,
|
|
63
|
+
});
|
|
64
|
+
return seq;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Compare-and-clear: deletes the entry only if this seq is still the current
|
|
68
|
+
// one for the session. A late finisher from an earlier op is a no-op.
|
|
69
|
+
function end(sessionId, seq) {
|
|
70
|
+
const sid = _sidOf(sessionId);
|
|
71
|
+
const current = entries.get(sid);
|
|
72
|
+
if (!current || current.seq !== seq) return false;
|
|
73
|
+
entries.delete(sid);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Called at enqueue time, before the op starts.
|
|
78
|
+
function noteQueued(sessionId, delta = 1) {
|
|
79
|
+
const sid = _sidOf(sessionId);
|
|
80
|
+
const next = Math.max(0, waitingFor(sid) + (Number(delta) || 0));
|
|
81
|
+
_setWaiting(sid, next);
|
|
82
|
+
const current = entries.get(sid);
|
|
83
|
+
if (current) current.queued = next;
|
|
84
|
+
return next;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function list() {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const entry of entries.values()) {
|
|
90
|
+
out.push({ ...entry, queued: waitingFor(entry.sessionId) });
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// The n oldest in-flight ops, oldest first: { sid8, op, ageMs, queued, seq }.
|
|
96
|
+
// `at` defaults to now() so a test can assert a growing age on a frozen clock.
|
|
97
|
+
function oldest(n, at = now()) {
|
|
98
|
+
const limit = Number.isFinite(Number(n)) ? Math.max(0, Math.trunc(Number(n))) : 0;
|
|
99
|
+
const rows = [];
|
|
100
|
+
for (const entry of list()) {
|
|
101
|
+
rows.push({
|
|
102
|
+
sid8: entry.sessionId.slice(0, 8),
|
|
103
|
+
op: entry.opType,
|
|
104
|
+
startedAt: entry.startedAt,
|
|
105
|
+
seq: entry.seq,
|
|
106
|
+
ageMs: Math.max(0, at - entry.startedAt),
|
|
107
|
+
queued: entry.queued,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
rows.sort((a, b) => (a.startedAt - b.startedAt) || (a.seq - b.seq));
|
|
111
|
+
return rows.slice(0, limit);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { begin, end, noteQueued, list, oldest };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Frame-side sanitizer: the manager keeps only strings/numbers it can trust in
|
|
118
|
+
// the stored snapshot, capped at `max` entries, oldest first. Sorting by age
|
|
119
|
+
// here (not just at the producer) is what makes "≤5, oldest first" a property
|
|
120
|
+
// of the stored snapshot rather than of the transport. Anything unparseable is
|
|
121
|
+
// normalised rather than thrown away.
|
|
122
|
+
function sanitizeSessionOps(entries, max = HEADLESS_OP_FRAME_MAX) {
|
|
123
|
+
const limit = Number.isFinite(Number(max)) ? Math.max(0, Math.trunc(Number(max))) : HEADLESS_OP_FRAME_MAX;
|
|
124
|
+
const rows = [];
|
|
125
|
+
for (const raw of Array.isArray(entries) ? entries : []) {
|
|
126
|
+
const sid8 = _sidOf(raw?.sid8).slice(0, 8);
|
|
127
|
+
if (!sid8) continue;
|
|
128
|
+
const ageMs = Number(raw?.ageMs);
|
|
129
|
+
const queued = Number(raw?.queued);
|
|
130
|
+
const seq = Number(raw?.seq);
|
|
131
|
+
rows.push({
|
|
132
|
+
sid8,
|
|
133
|
+
op: raw?.op == null || raw.op === '' ? 'none' : String(raw.op),
|
|
134
|
+
ageMs: Number.isFinite(ageMs) ? ageMs : 0,
|
|
135
|
+
queued: Number.isFinite(queued) ? queued : 0,
|
|
136
|
+
seq: Number.isFinite(seq) ? seq : 0,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
rows.sort((a, b) => b.ageMs - a.ageMs); // stable: equal ages keep producer order
|
|
140
|
+
return rows.slice(0, limit);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Edge trigger for the report-only `headless-op-overdue` row (D-6 §6): at most
|
|
144
|
+
// one hit per (hostId, sid8, seq) at or above thresholdMs. Each host's dedupe
|
|
145
|
+
// set is re-derived from ITS OWN latest frame, so it can never grow past the ops
|
|
146
|
+
// actually present in that frame -- and a seq that leaves the frame and later
|
|
147
|
+
// returns is a NEW seq, so it reports again.
|
|
148
|
+
function createOverdueEdgeTrigger({ thresholdMs = HEADLESS_OP_OVERDUE_MS } = {}) {
|
|
149
|
+
// hostId -> Set<'sid8|seq'>. The set is PER HOST: one shared set pruned against
|
|
150
|
+
// whichever host framed last would drop another host's keys, and that host's
|
|
151
|
+
// next frame would then re-report an op it had already reported.
|
|
152
|
+
const reportedByHost = new Map();
|
|
153
|
+
const keyOf = (entry) => `${entry.sid8}|${entry.seq}`;
|
|
154
|
+
|
|
155
|
+
function next(frameEntries, hostId, resolveSessionId) {
|
|
156
|
+
const entries = Array.isArray(frameEntries) ? frameEntries : [];
|
|
157
|
+
const host = String(hostId);
|
|
158
|
+
const present = new Set();
|
|
159
|
+
for (const entry of entries) present.add(keyOf(entry));
|
|
160
|
+
if (!reportedByHost.has(host)) reportedByHost.set(host, new Set());
|
|
161
|
+
const reported = reportedByHost.get(host);
|
|
162
|
+
for (const key of reported) {
|
|
163
|
+
if (!present.has(key)) reported.delete(key);
|
|
164
|
+
}
|
|
165
|
+
if (reported.size === 0) reportedByHost.delete(host);
|
|
166
|
+
const hits = [];
|
|
167
|
+
for (const entry of entries) {
|
|
168
|
+
if (!(Number(entry.ageMs) >= thresholdMs)) continue;
|
|
169
|
+
const key = keyOf(entry);
|
|
170
|
+
let seen = reportedByHost.get(host);
|
|
171
|
+
if (!seen) { seen = new Set(); reportedByHost.set(host, seen); }
|
|
172
|
+
if (seen.has(key)) continue;
|
|
173
|
+
seen.add(key);
|
|
174
|
+
hits.push({
|
|
175
|
+
sessionId: typeof resolveSessionId === 'function' ? resolveSessionId(entry.sid8) : entry.sid8,
|
|
176
|
+
details: {
|
|
177
|
+
hostId: host,
|
|
178
|
+
op: String(entry.op),
|
|
179
|
+
ageMs: Number(entry.ageMs),
|
|
180
|
+
queued: Number(entry.queued) || 0,
|
|
181
|
+
seq: Number(entry.seq) || 0,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return hits;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function size() {
|
|
189
|
+
let total = 0;
|
|
190
|
+
for (const set of reportedByHost.values()) total += set.size;
|
|
191
|
+
return total;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return { next, size };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = {
|
|
198
|
+
createInFlightOps,
|
|
199
|
+
createOverdueEdgeTrigger,
|
|
200
|
+
sanitizeSessionOps,
|
|
201
|
+
HEADLESS_OP_OVERDUE_MS,
|
|
202
|
+
HEADLESS_OP_FRAME_MAX,
|
|
203
|
+
};
|
|
@@ -29,6 +29,48 @@ function headlessMissingReplies(message) {
|
|
|
29
29
|
switch (msg.type) {
|
|
30
30
|
case 'serialize':
|
|
31
31
|
return [{ type: 'serialized', ...base, data: '', cols: 0, rows: 0, fp: '', missing: true }];
|
|
32
|
+
// WP-1 (stale-pty-host-evacuation-2026-10-24.html §5 D-5, §6 missing-reply case, §9 S-11):
|
|
33
|
+
// 'serialize-bootstrap' shares its body with 'serialize' in handleMessage
|
|
34
|
+
// (lib/headless-term-service.js:1796-1804), so it must share the REPLY TYPE too. The bootstrap
|
|
35
|
+
// gate listens only for `type === 'serialized'` with its own requestId (server.js:40730) and
|
|
36
|
+
// clears the moment `bootstrap` is absent (server.js:40746-40749, reason 'serialize-invalid').
|
|
37
|
+
// The generic default answer below produced 'serialize-bootstrap-result', which the gate ignored
|
|
38
|
+
// -- an honest "missing" was indistinguishable from a hung host, and the cold client waited out
|
|
39
|
+
// the 3 s deadline (reason 'deadline', phase 'serializing').
|
|
40
|
+
case 'serialize-bootstrap':
|
|
41
|
+
return [{ type: 'serialized', ...base, data: '', cols: 0, rows: 0, fp: '', bootstrap: null, missing: true }];
|
|
42
|
+
// 'recheck' is answered with 'feed-result' on BOTH normal branches (lib/headless-term-service.js:1506-1510
|
|
43
|
+
// for a session with no mirror, :1532-1544 for a live one) -- server.js keys the pending approval
|
|
44
|
+
// entry on that type, so the generic 'recheck-result' left the caller waiting for a reply it never got.
|
|
45
|
+
case 'recheck':
|
|
46
|
+
return [{
|
|
47
|
+
type: 'feed-result', ...base, hasApproval: false, providerId: null, text: null,
|
|
48
|
+
rawDetected: false, rawText: null, debugLines: [], missing: true,
|
|
49
|
+
}];
|
|
50
|
+
// The bootstrap handshake's two post-serialize ops answer 'terminal-bootstrap-activated' /
|
|
51
|
+
// 'terminal-bootstrap-flushed', keyed by clientId + socketGeneration + requestId
|
|
52
|
+
// (lib/headless-term-service.js:1956-1960, :1969-1973). server.js clears its gate only when it can
|
|
53
|
+
// find the client by those three fields, and an `accepted: false` is what turns "there is no host
|
|
54
|
+
// state to activate/flush" into an immediate failure instead of the gate's phase deadline
|
|
55
|
+
// (server.js:31247-31260 activated, :31300-31346 flushed).
|
|
56
|
+
case 'terminal-bootstrap-ack':
|
|
57
|
+
return [{
|
|
58
|
+
type: 'terminal-bootstrap-activated', ...base,
|
|
59
|
+
clientId: String(msg.clientId || ''), socketGeneration: Number(msg.socketGeneration || 0),
|
|
60
|
+
accepted: false, missing: true,
|
|
61
|
+
}];
|
|
62
|
+
case 'terminal-bootstrap-flush':
|
|
63
|
+
return [{
|
|
64
|
+
type: 'terminal-bootstrap-flushed', ...base,
|
|
65
|
+
clientId: String(msg.clientId || ''), socketGeneration: Number(msg.socketGeneration || 0),
|
|
66
|
+
accepted: false, throughSeq: 0, missing: true,
|
|
67
|
+
}];
|
|
68
|
+
// The archive-quiesce barrier and the painted-row drop both always post their own reply type
|
|
69
|
+
// (lib/headless-term-service.js:2173, :2180) -- the caller matches on (type, sessionId, requestId).
|
|
70
|
+
case 'flush-archive':
|
|
71
|
+
return [{ type: 'archive-flushed', ...base, missing: true }];
|
|
72
|
+
case 'drop-painted':
|
|
73
|
+
return [{ type: 'painted-dropped', ...base, missing: true }];
|
|
32
74
|
case 'getViewportText':
|
|
33
75
|
return [{ type: 'viewport-text', ...base, text: '', missing: true, cols: 0, rows: 0 }];
|
|
34
76
|
case 'getText':
|