create-walle 0.10.1 → 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 +7 -1
- 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 +11 -8
- package/package.json +1 -1
- package/template/bin/deps-doctor.js +1 -1
- package/template/bin/node-bin.sh +11 -0
- package/template/coding-task-manager/api-prompts.js +55 -29
- package/template/coding-task-manager/bin/claude-hook.js +62 -4
- 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/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/lead-wait-census.js +1348 -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/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/write-lock-bench.js +111 -0
- package/template/coding-task-manager/db.js +860 -317
- package/template/coding-task-manager/git-utils.js +44 -0
- 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 -7
- 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 +99 -1
- 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/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/host-stats.js +98 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +43 -12
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- 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 +1150 -0
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +25 -5
- package/template/coding-task-manager/lib/api/providers.js +53 -6
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/resume-from-store.js +25 -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 +237 -59
- 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/transcript-history.js +17 -4
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- 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/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-context.js +32 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +64 -1
- package/template/coding-task-manager/lib/auth-rules.js +474 -62
- 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 +7 -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/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- 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/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +69 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +55 -20
- 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-paths.js +2 -1
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +48 -42
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +70 -4
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +24 -6
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +17 -0
- package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -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 +104 -13
- 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-boot-lifecycle.js +17 -1
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +8 -0
- package/template/coding-task-manager/lib/db-domains.js +22 -2
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -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 +6 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +5 -1
- 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 +61 -44
- package/template/coding-task-manager/lib/harness-history-transition.js +52 -11
- 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 +139 -25
- 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-control-dial.js +167 -0
- 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-orchestrator.js +16 -2
- package/template/coding-task-manager/lib/host-handoff.js +50 -15
- 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 +475 -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 +141 -310
- 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 +12 -0
- package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
- package/template/coding-task-manager/lib/instance-manifest.js +18 -2
- package/template/coding-task-manager/lib/instance-sync-status.js +33 -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 +193 -8
- 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/launch-plan-worker.js +59 -2
- 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 +409 -72
- package/template/coding-task-manager/lib/lead-model-switch.js +115 -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 +85 -9
- 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/legacy-draft-cancellation-recovery.js +111 -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/login-tripwire.js +1 -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 +1494 -0
- package/template/coding-task-manager/lib/machine-self.js +66 -0
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +485 -57
- 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/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/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/v56-host-samples-and-machine-pool.js +76 -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/mirror-feed-sanitize.js +12 -3
- 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 +8 -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 +6 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
- 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/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/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/stream-accounting.js +205 -0
- package/template/coding-task-manager/lib/model-proxy/tokens.js +147 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +18 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +7 -5
- package/template/coding-task-manager/lib/native-lead-settings-client.js +46 -5
- package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +776 -75
- 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 +15 -1
- package/template/coding-task-manager/lib/painted-row-recorder.js +9 -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/prompt-submission-contract.js +21 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +264 -24
- package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- 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/read-pool-client.js +94 -4
- package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +41 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +76 -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-command-context.js +12 -0
- package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
- package/template/coding-task-manager/lib/remote-machine-catalog.js +1357 -0
- package/template/coding-task-manager/lib/remote-machine-create.js +1233 -0
- package/template/coding-task-manager/lib/remote-machine-link.js +1426 -0
- package/template/coding-task-manager/lib/remote-machine-proxy.js +654 -0
- package/template/coding-task-manager/lib/remote-session-forward.js +364 -0
- package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
- 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/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/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/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 +74 -18
- package/template/coding-task-manager/lib/root-delivery-runtime.js +74 -17
- package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
- package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +168 -34
- 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/scrollback-archive-store.js +7 -4
- package/template/coding-task-manager/lib/session-analysis-memory.js +2 -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/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/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +179 -20
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/identity.js +20 -1
- 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 +201 -9
- 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 +193 -64
- package/template/coding-task-manager/lib/session-create/response.js +37 -19
- 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 +14 -5
- 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 +50 -2
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
- package/template/coding-task-manager/lib/session-create/worker-observability.js +101 -9
- 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-empty.js +13 -10
- package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
- package/template/coding-task-manager/lib/session-host-manager.js +212 -206
- package/template/coding-task-manager/lib/session-jobs.js +20 -10
- package/template/coding-task-manager/lib/session-lifecycle.js +28 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +15 -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-resource-sampler.js +19 -9
- package/template/coding-task-manager/lib/session-standup.js +67 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +147 -6
- package/template/coding-task-manager/lib/session-status-runtime.js +45 -1
- 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/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/startup-pointer-write.js +57 -0
- 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/state-sync/painted-frame-field.js +11 -0
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +25 -23
- 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/surviving-owner-bootstrap.js +7 -2
- package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
- 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-http-status.js +25 -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-archiver.js +229 -229
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +20 -5
- 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 +44 -7
- package/template/coding-task-manager/lib/transcript-store.js +49 -0
- package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
- package/template/coding-task-manager/lib/typing-interaction-trace.js +198 -3
- package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
- 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/visible-revision-watchdog.js +8 -12
- package/template/coding-task-manager/lib/wake-skip-reasons.js +47 -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 +130 -27
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
- 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 +125 -6
- package/template/coding-task-manager/lib/ws/terminal-attach.js +123 -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 +211 -170
- package/template/coding-task-manager/package-lock.json +34 -94
- package/template/coding-task-manager/package.json +7 -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/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 +449 -1
- package/template/coding-task-manager/public/css/reviews.css +4 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +766 -465
- 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 +2572 -0
- package/template/coding-task-manager/public/js/app/models-tab.js +658 -73
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +191 -7
- package/template/coding-task-manager/public/js/background-work.js +203 -28
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +181 -13
- 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 +847 -5
- package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
- 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 +48 -4
- 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 +991 -0
- 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/private-state-scope.js +31 -3
- package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
- package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
- 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/queue-panel-submission-reconcile.js +174 -1
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -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 +4 -2
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +64 -21
- 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 +14 -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-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-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 +60 -3
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +16 -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 +211 -74
- 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-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +62 -5
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +15 -7
- package/template/coding-task-manager/public/js/walle-session.js +30 -7
- 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 +366 -8
- package/template/coding-task-manager/public/m/app.js +1006 -74
- package/template/coding-task-manager/public/m/index.html +55 -1
- package/template/coding-task-manager/public/m/machines.js +2147 -0
- package/template/coding-task-manager/public/m/pool-failover.js +391 -0
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- 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/public/usage.html +1 -0
- package/template/coding-task-manager/queue-engine.js +13 -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/approvals.js +5 -6
- package/template/coding-task-manager/server/boot.js +136 -17
- package/template/coding-task-manager/server.js +2819 -11885
- package/template/coding-task-manager/session-integrity.js +71 -13
- package/template/coding-task-manager/workers/db-owner-worker.js +72 -9
- 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 +93 -12
- package/template/coding-task-manager/workers/session-host-pool-process.js +24 -10
- package/template/coding-task-manager/workers/session-host-process.js +19 -8
- package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +202 -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/scripts/conversation-storage-v2-migration.js +78 -11
- 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 +47 -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/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/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 +38 -3
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +92 -4
- package/template/wall-e/api-walle.js +26 -1
- package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +14 -8
- 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/helper-rules-schema.js +129 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +91 -28
- package/template/wall-e/brain/model-deployment-facts.js +31 -1
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +39 -7
- package/template/wall-e/brain/schema-ensures.js +22 -0
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +172 -36
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/journal-dispatcher.js +51 -0
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/coding/session-journal.js +28 -40
- package/template/wall-e/coding-orchestrator.js +23 -26
- 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/auth.js +18 -1
- package/template/wall-e/http/blog-views-api.js +318 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +327 -0
- 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 +177 -2
- 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/http/telemetry-api.js +12 -0
- package/template/wall-e/jobs/job-runner.js +28 -1
- 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/brain-owner-op-priority.js +9 -1
- 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/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- 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 +398 -0
- package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
- package/template/wall-e/lib/helper-rules/grade.js +320 -0
- package/template/wall-e/lib/helper-rules/label.js +247 -0
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +555 -0
- package/template/wall-e/lib/helper-rules/store.js +669 -0
- 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 +63 -19
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/runtime-worker-pool.js +1 -0
- package/template/wall-e/lib/scheduler-worker-jobs.js +12 -4
- 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/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-catalog.js +13 -4
- package/template/wall-e/llm/model-roles.js +7 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- 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-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +117 -7
- package/template/wall-e/llm/worker-route.js +43 -1
- package/template/wall-e/loops/brain-custom-writes.js +64 -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 +77 -2
- package/template/wall-e/mcp-server.js +141 -31
- package/template/wall-e/mcp-worker-schemas.js +25 -7
- package/template/wall-e/memory/ctm-context-client.js +110 -5
- 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 +3 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/sqlite-write-lock.js +361 -223
- package/template/wall-e/shared/storage/contract.js +38 -3
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +13 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +11 -6
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +13 -8
- 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/tools/local-tools.js +6 -4
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +27 -4
- package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
- package/template/wall-e/workers/telemetry-worker.js +8 -0
|
@@ -4,24 +4,35 @@
|
|
|
4
4
|
// shape, keyed PER CLIENT (a "delivery" = sessionId + clientId + socketGeneration) instead of
|
|
5
5
|
// per-session, because CTM (unlike 0.9.33) fans one session out to more than one viewer.
|
|
6
6
|
//
|
|
7
|
+
// WP-1 (docs/state-sync-pipelined-deltas-echo-never-waits-for-ack-2026-10-31.html §5 D-1..D-5):
|
|
8
|
+
// the single in-flight slot is replaced IN PLACE by a BOUNDED WINDOW of unacked frames per delivery
|
|
9
|
+
// (Mosh's rule: diff each frame against the last state SENT, and let an ack advance only what is
|
|
10
|
+
// assumed received). No flag: the window is the only code path.
|
|
11
|
+
//
|
|
7
12
|
// The whole state machine, per delivery:
|
|
8
|
-
// mirror updated ->
|
|
9
|
-
// -> else rate gate
|
|
10
|
-
// -> owedKeyframe/dims changed -> keyframe (else diff vs
|
|
13
|
+
// mirror updated -> window full (≥8 frames or ≥256 KiB)? dirty=true, refuse('window-full')
|
|
14
|
+
// -> else rate gate refuse('rate')
|
|
15
|
+
// -> owedKeyframe/dims changed -> keyframe (else diff vs sentGrid)
|
|
11
16
|
// -> nothing changed (rows+cursor) -> nothing
|
|
12
|
-
// ack(seq) ->
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
17
|
+
// ack(seq) -> an entry SEQUENCE === seq is in the window -> retire every entry with
|
|
18
|
+
// seq ≤ seq in order (advance ackedSeq/ackedGridRevision/ackedGrid to that
|
|
19
|
+
// entry, retire its scroll-out counts, sample RTT from THAT entry only,
|
|
20
|
+
// never a resent one), then flush one dirty catch-up (bypass rate).
|
|
21
|
+
// Any other seq -> ignore. NO proofs, NO dispositions, NO suppression.
|
|
22
|
+
// keyframe req -> ALWAYS served for a known delivery (reset base, clear window, force) UNLESS
|
|
23
|
+
// a KEYFRAME already in the window is newer than the client's haveSeq (WP-2
|
|
24
|
+
// D-6: that keyframe IS the answer). Unknown delivery -> attach, then serve.
|
|
25
|
+
// Never refused.
|
|
26
|
+
// undeliverable -> the named seq is in the window: drop every entry with seq ≥ it, keep the
|
|
27
|
+
// rest (they still reach the client, in order), owe ONE keyframe whose
|
|
28
|
+
// scroll-out base is the newest kept grid (rows the client already has are not
|
|
29
|
+
// re-donated). A seq not in the window is a no-op. Do not emit here.
|
|
30
|
+
// sweep -> the OLDEST entry past stallMs -> clear the window, force a keyframe. Nothing else.
|
|
20
31
|
// attach/detach -> create/delete the delivery. Nothing else remembers a client.
|
|
21
32
|
//
|
|
22
33
|
// No suppression latch, no no-audience stand-down, no nack-episode/content-fence bookkeeping, no
|
|
23
34
|
// client-fault squelch, no interactive-supersession lane, no revision-store eviction/fencing. A
|
|
24
|
-
// delivery
|
|
35
|
+
// delivery has a bounded window of unacked frames; a keyframe either fixes it or the sweep does.
|
|
25
36
|
|
|
26
37
|
const { computeAnsiPatch } = require('./cell-diff'); const { stripWrapPrefix } = require('./row-serializer');const { paintedFrameField } = require('./painted-frame-field');
|
|
27
38
|
const { frameDue, noteEmit } = require('./frame-rate');
|
|
@@ -31,6 +42,12 @@ const { normalizeMouseTracking, normalizeMouseEncoding } = require('./surface-mo
|
|
|
31
42
|
const EMPTY_GRID = { cols: 0, rows: 0, rowAnsi: [] };
|
|
32
43
|
const DEFAULT_SCROLL_OUT_MAX = 400;
|
|
33
44
|
const DEFAULT_MAX_ACTIVE_CLIENTS = 32;
|
|
45
|
+
// WP-1 (§5 D-2, §6): the per-delivery unacked window. Module constants, never env flags -- the
|
|
46
|
+
// rollback is branch isolation + git revert. Frames are 2–19 KB measured, so 8 frames ≈ 152 KB <
|
|
47
|
+
// 256 KiB < the 1 MiB stream high-water; at the 16 ms frame floor 8 frames = 128 ms of output ahead
|
|
48
|
+
// of the oldest ack. Overridable ONLY by the test injection (deps.windowFrames / deps.windowBytes).
|
|
49
|
+
const STATE_SYNC_WINDOW_FRAMES = 8;
|
|
50
|
+
const STATE_SYNC_WINDOW_BYTES = 262144;
|
|
34
51
|
|
|
35
52
|
function parseScrollOutMax(value) {
|
|
36
53
|
if (value === null || value === undefined || value === '') return DEFAULT_SCROLL_OUT_MAX;
|
|
@@ -173,10 +190,18 @@ function newDeliveryState() {
|
|
|
173
190
|
ackedGrid: EMPTY_GRID,
|
|
174
191
|
ackedSeq: 0,
|
|
175
192
|
ackedGridRevision: 0,
|
|
193
|
+
// WP-1 (§5 D-1/D-2): the unacked window, ordered oldest→newest, and the last state SENT (the
|
|
194
|
+
// assumed receiver state a fresh delta diffs against). inFlightSeq/inFlightKind/inFlightAt are
|
|
195
|
+
// DERIVED from the OLDEST entry by syncOldest() and kept for readers/tests.
|
|
196
|
+
inFlight: [],
|
|
197
|
+
inFlightBytes: 0,
|
|
176
198
|
inFlightSeq: 0,
|
|
177
|
-
inFlightGrid: null,
|
|
178
199
|
inFlightAt: 0,
|
|
179
200
|
inFlightKind: '', // report-only, for onRefused's gate name
|
|
201
|
+
sentGrid: EMPTY_GRID,
|
|
202
|
+
sentSeq: 0,
|
|
203
|
+
sentGridRevision: 0,
|
|
204
|
+
resetBaseGrid: null, // D-5: the scroll-out base for the keyframe after a mid-window drop
|
|
180
205
|
dirty: false,
|
|
181
206
|
owedKeyframe: false,
|
|
182
207
|
fr: { lastEmitAt: 0 },
|
|
@@ -186,12 +211,17 @@ function newDeliveryState() {
|
|
|
186
211
|
lastAckClientId: '',
|
|
187
212
|
pendingScrollbackRows: [],
|
|
188
213
|
pendingScrollbackElidedCount: 0,
|
|
189
|
-
|
|
190
|
-
inFlightScrollbackElidedCount: 0,
|
|
191
|
-
pendingClearScrollback: false, // a clearScrollback request coalesced behind an in-flight frame
|
|
214
|
+
pendingClearScrollback: false, // a clearScrollback request coalesced behind a full window
|
|
192
215
|
surfaceEpoch: 0,
|
|
193
216
|
surfaceIdentity: null,
|
|
194
217
|
sweepResends: 0, // how many times sweepStalledInFlight has re-emitted into this delivery since its last ack
|
|
218
|
+
// WP-2 (§5 D-5, docs/remote-relay-ack-rate-limit-typing-delay-2026-10-28.html): this delivery's
|
|
219
|
+
// own measured ack RTT (RFC 6298 §2 SRTT/RTTVAR), so the lost-ack watchdog is sized from the
|
|
220
|
+
// real round trip instead of one global 3 s constant. Per DELIVERY, so a slow viewer's history
|
|
221
|
+
// never inflates a fast viewer's stall.
|
|
222
|
+
srttMs: 0,
|
|
223
|
+
rttvarMs: 0,
|
|
224
|
+
rttSamples: 0,
|
|
195
225
|
};
|
|
196
226
|
}
|
|
197
227
|
|
|
@@ -199,17 +229,92 @@ function deliveryKey(clientId, socketGeneration) {
|
|
|
199
229
|
return JSON.stringify([String(clientId || ''), Number(socketGeneration || 0)]);
|
|
200
230
|
}
|
|
201
231
|
|
|
232
|
+
// WP-1 (§5 D-1, §6): the ONE place the derived oldest-entry fields are maintained. Called after
|
|
233
|
+
// every window change (push, retire, clear) so inFlightSeq/inFlightKind/inFlightAt always name the
|
|
234
|
+
// OLDEST unacked entry (0/''/0 when the window is empty), which is what the sweep and the
|
|
235
|
+
// diagnostics read.
|
|
236
|
+
function syncOldest(s) {
|
|
237
|
+
const oldest = s.inFlight[0];
|
|
238
|
+
s.inFlightSeq = oldest ? oldest.seq : 0;
|
|
239
|
+
s.inFlightKind = oldest ? oldest.kind : '';
|
|
240
|
+
s.inFlightAt = oldest ? oldest.at : 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// WP-0 (D-4c): hand one lost-ack recovery to the caller's report-only hook. The recovery has
|
|
244
|
+
// ALREADY happened by the time this runs, so a throwing hook is swallowed rather than allowed to
|
|
245
|
+
// abort the sweep mid-loop.
|
|
246
|
+
function _noteRecovered(opts, id, info) {
|
|
247
|
+
try {
|
|
248
|
+
if (opts && typeof opts.onRecovered === 'function') opts.onRecovered(id, info);
|
|
249
|
+
} catch {
|
|
250
|
+
// expected: diagnostics hook fault never breaks recovery
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// WP-0 (D-5, docs/state-sync-pipelined-deltas-echo-never-waits-for-ack-2026-10-31.html §5 D-5,
|
|
255
|
+
// §9 S-11): hand ONE matched ack's round trip to the caller's report-only hook, while both legs are
|
|
256
|
+
// still knowable — the host leg is measured here (send -> ack), the main leg is passed through from
|
|
257
|
+
// the worker (`ctx.mainRttMs`, the ledger's own sentAt delta). Diagnostics only: the ack has already
|
|
258
|
+
// been applied by the time this runs, so a throwing hook is swallowed rather than allowed to abort
|
|
259
|
+
// the delivery's ack path.
|
|
260
|
+
function _noteAcked(deps, id, info) {
|
|
261
|
+
try {
|
|
262
|
+
if (deps && typeof deps.onAcked === 'function') deps.onAcked(id, info);
|
|
263
|
+
} catch {
|
|
264
|
+
/* expected: report-only diagnostics hook must never break the ack path */
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// WP-2 (RFC 6298 §2, docs/remote-relay-ack-rate-limit-typing-delay-2026-10-28.html §5 D-5, §6):
|
|
269
|
+
// fold one measured ack RTT into the delivery's SRTT/RTTVAR. The first sample seeds SRTT = R and
|
|
270
|
+
// RTTVAR = R/2; every later sample uses RTTVAR = 3/4·RTTVAR + 1/4·|SRTT − R| then
|
|
271
|
+
// SRTT = 7/8·SRTT + 1/8·R. A non-finite or negative sample (clock skew, a stale inFlightAt) is
|
|
272
|
+
// dropped rather than allowed to poison the estimate.
|
|
273
|
+
function noteAckRtt(state, sampleMs) {
|
|
274
|
+
if (!state) return;
|
|
275
|
+
const r = Number(sampleMs);
|
|
276
|
+
if (!Number.isFinite(r) || r < 0) return;
|
|
277
|
+
if (!Number(state.rttSamples)) {
|
|
278
|
+
state.srttMs = r;
|
|
279
|
+
state.rttvarMs = r / 2;
|
|
280
|
+
} else {
|
|
281
|
+
const srtt = Number(state.srttMs) || 0;
|
|
282
|
+
state.rttvarMs = 0.75 * (Number(state.rttvarMs) || 0) + 0.25 * Math.abs(srtt - r);
|
|
283
|
+
state.srttMs = 0.875 * srtt + 0.125 * r;
|
|
284
|
+
}
|
|
285
|
+
state.rttSamples = Number(state.rttSamples || 0) + 1;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// A delivery with no ack sample yet keeps the caller's CEILING (today's fixed 3 s), so the very
|
|
289
|
+
// first attach can never be spuriously recovered. Once sampled, the stall is clamp(SRTT + 4·RTTVAR)
|
|
290
|
+
// bounded below by the private-path floor (mosh's MIN_RTO intuition, §5 P3) and above by the same
|
|
291
|
+
// ceiling (the CTM_STATE_SYNC_INFLIGHT_STALL_MS override).
|
|
292
|
+
function stallMsFor(state, opts) {
|
|
293
|
+
const ceilingMs = Number(opts && opts.ceilingMs);
|
|
294
|
+
const ceiling = Number.isFinite(ceilingMs) ? ceilingMs : 0;
|
|
295
|
+
const rawFloor = Number(opts && opts.floorMs);
|
|
296
|
+
const floor = Number.isFinite(rawFloor) ? rawFloor : 250;
|
|
297
|
+
if (!state || !Number(state.rttSamples)) return ceiling;
|
|
298
|
+
const rto = (Number(state.srttMs) || 0) + 4 * (Number(state.rttvarMs) || 0);
|
|
299
|
+
return Math.min(ceiling, Math.max(floor, rto));
|
|
300
|
+
}
|
|
301
|
+
|
|
202
302
|
function createFrameEmitter(deps) {
|
|
203
303
|
deps = deps || {};
|
|
204
304
|
const send = deps.send || (() => {});
|
|
205
305
|
// WP-0b (§5 D-2, §6): report-only hook so a caller can attribute a refused emit to its exact
|
|
206
|
-
// gate. WP-
|
|
207
|
-
//
|
|
306
|
+
// gate. WP-1 reduces the enum to the two gates that still exist: window-full | rate (see
|
|
307
|
+
// lib/typing-interaction-trace.js GATES; the old in-flight-* names are kept there so pre-WP-1
|
|
308
|
+
// rows still parse).
|
|
208
309
|
const onRefused = deps.onRefused || (() => {});
|
|
209
310
|
const log = deps.log || (() => {});
|
|
210
311
|
const extractGrid = deps.extractGrid || (() => EMPTY_GRID);
|
|
211
312
|
const now = deps.now || (() => Date.now());
|
|
212
313
|
const frameOpts = deps.frameOpts || {};
|
|
314
|
+
// §5 D-2/D-8: the window bounds are module constants, overridable ONLY by the test injection --
|
|
315
|
+
// never an env flag.
|
|
316
|
+
const windowFrames = Math.max(1, Number(deps.windowFrames) || STATE_SYNC_WINDOW_FRAMES);
|
|
317
|
+
const windowBytes = Math.max(1, Number(deps.windowBytes) || STATE_SYNC_WINDOW_BYTES);
|
|
213
318
|
const scrollOutMax = parseScrollOutMax(
|
|
214
319
|
deps.scrollOutMax ?? frameOpts.scrollOutMax ?? process.env.CTM_STATE_SYNC_SCROLL_OUT_MAX
|
|
215
320
|
);
|
|
@@ -277,36 +382,49 @@ function createFrameEmitter(deps) {
|
|
|
277
382
|
return { rows, elided };
|
|
278
383
|
}
|
|
279
384
|
|
|
280
|
-
// The one send path.
|
|
281
|
-
// (nothing in flight). Gate 2 budget: ≤60 lines / 8 ifs / 6 returns.
|
|
385
|
+
// The one send path. Gate 2 budget: ≤72 lines / 8 ifs / 6 returns.
|
|
282
386
|
function emit(id, delivery, opts = {}) {
|
|
283
387
|
const session = st(id);
|
|
284
388
|
const s = delivery.state;
|
|
285
389
|
const t = now();
|
|
286
390
|
const grid = extractGrid(id) || EMPTY_GRID;
|
|
287
|
-
const ackedGrid = s.ackedGrid || EMPTY_GRID;
|
|
288
391
|
const identityChanged = surfaceIdentityChanged(s, grid);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
392
|
+
// §5 D-1: a delta diffs against the last state SENT (the assumed receiver state), not the last
|
|
393
|
+
// acked one -- with a window, several frames can be unacked and each must build on its
|
|
394
|
+
// predecessor. The first frame of a delivery (or after any reset) is still a keyframe: the
|
|
395
|
+
// keyframe rule keys on sentSeq === 0, never ackedSeq (which stays 0 until the first ack, so
|
|
396
|
+
// every emit before it would otherwise be a keyframe).
|
|
397
|
+
const keyframeFrame = !!opts.force || !!s.owedKeyframe || identityChanged || Number(s.sentSeq || 0) === 0;
|
|
398
|
+
// §5 D-5: after a mid-window drop the next keyframe re-donates scroll-out rows against the
|
|
399
|
+
// newest KEPT entry's grid (the client already has those rows), then the override is consumed.
|
|
400
|
+
const baseGrid = keyframeFrame
|
|
401
|
+
? (s.resetBaseGrid || s.ackedGrid || EMPTY_GRID)
|
|
402
|
+
: (s.sentGrid || EMPTY_GRID);
|
|
403
|
+
if (keyframeFrame) s.resetBaseGrid = null;
|
|
404
|
+
const cursorMoved = !cursorsEqual(grid.cursor, baseGrid.cursor);
|
|
405
|
+
// No pending-scrollback term: a refused update leaves nothing owed, because the next emit
|
|
406
|
+
// recomputes its scroll-out rows against sentGrid (and a drop forces a keyframe, D-5).
|
|
407
|
+
if (!keyframeFrame && !cursorMoved && !opts.clearScrollback && gridsEqual(grid, baseGrid)) {
|
|
293
408
|
return false;
|
|
294
409
|
}
|
|
295
|
-
//
|
|
296
|
-
//
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
410
|
+
// Each frame carries exactly the scroll-out rows between ITS base and its grid. For a delta that
|
|
411
|
+
// is the predecessor frame's grid; for a keyframe it is the delivery's own last-known grid (a
|
|
412
|
+
// WIRE reset declares baseSeq 0, but the internal diff base is only discarded by
|
|
413
|
+
// resetDeliveryBaseline -- a snapshot/restore reset, where ackedGrid is already EMPTY_GRID here
|
|
414
|
+
// and scrollOutRecovery is naturally a no-op) or the kept base a drop left behind (D-5).
|
|
415
|
+
const recovery = scrollOutRecovery(id, baseGrid, grid);
|
|
416
|
+
const batch = recovery.delta > 0 ? scrollbackBatch(baseGrid, recovery.delta, recovery.rows, recovery.elided) : { rows: [], elided: 0 };
|
|
417
|
+
// The frame's (and its window entry's) scroll-out counts are THIS frame's batch only -- a later
|
|
418
|
+
// frame must never re-advertise rows/elision an earlier unacked frame carried (the client draws
|
|
419
|
+
// one elision marker per frame that reports scrollbackElidedCount > 0). pendingScrollback* is
|
|
420
|
+
// the queue of rows carried by the unacked frames; onAck retires each entry's share in order.
|
|
303
421
|
if (keyframeFrame || opts.clearScrollback) { s.pendingScrollbackRows = []; s.pendingScrollbackElidedCount = 0; }
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const pendingRowCount =
|
|
307
|
-
const pendingElidedCount =
|
|
422
|
+
s.pendingScrollbackRows = s.pendingScrollbackRows.concat(batch.rows);
|
|
423
|
+
s.pendingScrollbackElidedCount += batch.elided;
|
|
424
|
+
const pendingRowCount = batch.rows.length;
|
|
425
|
+
const pendingElidedCount = batch.elided;
|
|
308
426
|
const scrollbackDelta = recovery.delta;
|
|
309
|
-
let patch = computeAnsiPatch(
|
|
427
|
+
let patch = computeAnsiPatch(baseGrid, grid, {
|
|
310
428
|
scrolledOutRows: batch.rows, scrolledOutElidedCount: batch.elided,
|
|
311
429
|
clearScrollback: opts.clearScrollback, keyframe: keyframeFrame,
|
|
312
430
|
});
|
|
@@ -323,7 +441,7 @@ function createFrameEmitter(deps) {
|
|
|
323
441
|
if (cursorMoved && !keyframeFrame) {
|
|
324
442
|
const cursorRows = new Set(Array.isArray(patch.changedRows) ? patch.changedRows : []);
|
|
325
443
|
const gridRows = Number(grid.rows) || 0;
|
|
326
|
-
for (const row of [Number(
|
|
444
|
+
for (const row of [Number(baseGrid.cursor?.row || 0), Number(grid.cursor?.row || 0)]) {
|
|
327
445
|
if (row > 0 && row <= gridRows) cursorRows.add(row);
|
|
328
446
|
}
|
|
329
447
|
patch = { ...patch, changedRows: Array.from(cursorRows).sort((a, b) => a - b) };
|
|
@@ -331,14 +449,14 @@ function createFrameEmitter(deps) {
|
|
|
331
449
|
}
|
|
332
450
|
const authority = frameAuthority(s, grid, patch, keyframeFrame, identityChanged);
|
|
333
451
|
const frame = {
|
|
334
|
-
type: 'frame', id, seq, gridRevision: seq, baseGridRevision: keyframeFrame ? 0 : Number(s.
|
|
452
|
+
type: 'frame', id, seq, gridRevision: seq, baseGridRevision: keyframeFrame ? 0 : Number(s.sentGridRevision || 0),
|
|
335
453
|
...authority,
|
|
336
454
|
keyframe: keyframeFrame, displayStable: keyframeFrame,
|
|
337
|
-
...paintedFrameField(deps, id, keyframeFrame,
|
|
455
|
+
...paintedFrameField(deps, id, keyframeFrame, baseGrid, grid), // D-6: the reader's painted-row position (and the rows this viewer lacks)
|
|
338
456
|
scrollbackDelta,
|
|
339
457
|
...(pendingRowCount > 0 ? { scrollbackRowCount: pendingRowCount } : {}),
|
|
340
458
|
...(pendingElidedCount > 0 ? { scrollbackElidedCount: pendingElidedCount } : {}),
|
|
341
|
-
baseSeq: keyframeFrame ? 0 : s.
|
|
459
|
+
baseSeq: keyframeFrame ? 0 : Number(s.sentSeq || 0),
|
|
342
460
|
ansiPatch: patch.ansi,
|
|
343
461
|
cursor: grid.cursor || null,
|
|
344
462
|
rows: Number(grid.rows) || 0,
|
|
@@ -352,12 +470,19 @@ function createFrameEmitter(deps) {
|
|
|
352
470
|
...(opts.requestToken ? { requestToken: String(opts.requestToken) } : {}),
|
|
353
471
|
};
|
|
354
472
|
send(id, frame);
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
s.
|
|
359
|
-
|
|
360
|
-
|
|
473
|
+
// §5 D-2/D-3: the entry is the retire-on-ack record -- its byte cost bounds the window, and its
|
|
474
|
+
// scroll-out counts are retired when (and only when) this seq is acked.
|
|
475
|
+
const bytes = Buffer.byteLength(String(patch.ansi || ''), 'utf8');
|
|
476
|
+
s.inFlight.push({
|
|
477
|
+
seq, at: t, kind: keyframeFrame ? 'keyframe' : 'delta', grid, bytes,
|
|
478
|
+
scrollbackRowCount: pendingRowCount,
|
|
479
|
+
scrollbackElidedCount: pendingElidedCount,
|
|
480
|
+
});
|
|
481
|
+
s.inFlightBytes += bytes;
|
|
482
|
+
s.sentGrid = grid;
|
|
483
|
+
s.sentSeq = seq;
|
|
484
|
+
s.sentGridRevision = seq;
|
|
485
|
+
syncOldest(s);
|
|
361
486
|
return true;
|
|
362
487
|
}
|
|
363
488
|
|
|
@@ -371,19 +496,25 @@ function createFrameEmitter(deps) {
|
|
|
371
496
|
state.ackedGrid = EMPTY_GRID;
|
|
372
497
|
state.ackedSeq = 0;
|
|
373
498
|
state.ackedGridRevision = 0;
|
|
499
|
+
// §5 D-5: the SENT baseline is gone too -- the next emit is a keyframe (sentSeq 0 still fails
|
|
500
|
+
// the keyframe rule) and must not diff against a state the client never had.
|
|
501
|
+
state.sentGrid = EMPTY_GRID;
|
|
502
|
+
state.sentSeq = 0;
|
|
503
|
+
state.sentGridRevision = 0;
|
|
504
|
+
state.resetBaseGrid = null;
|
|
374
505
|
}
|
|
375
506
|
|
|
376
507
|
// A keyframe-req / lost-ack recovery is a WIRE reset (frame.baseSeq/baseGridRevision go to 0 --
|
|
377
|
-
// the client repaints everything) but internally keeps the delivery's own last-known
|
|
378
|
-
//
|
|
379
|
-
// desync resync would silently drop whatever scrolled out of view since the last ack.
|
|
508
|
+
// the client repaints everything) but internally keeps the delivery's own last-known grid as the
|
|
509
|
+
// scroll-out diff base, exactly like the sweep's lost-ack recovery always has -- otherwise a
|
|
510
|
+
// desync resync would silently drop whatever scrolled out of view since the last ack. WP-1 (§5
|
|
511
|
+
// D-2): "clear in flight" now means EMPTY THE WHOLE WINDOW.
|
|
380
512
|
function clearInFlightOnly(state) {
|
|
381
|
-
state.
|
|
382
|
-
state.
|
|
383
|
-
state.inFlightScrollbackRowCount = 0;
|
|
384
|
-
state.inFlightScrollbackElidedCount = 0;
|
|
513
|
+
state.inFlight = [];
|
|
514
|
+
state.inFlightBytes = 0;
|
|
385
515
|
state.pendingClearScrollback = false;
|
|
386
516
|
state.dirty = false;
|
|
517
|
+
syncOldest(state);
|
|
387
518
|
}
|
|
388
519
|
|
|
389
520
|
// The clientId-less keyframe entry point (resize / set-visibility / restore-hold release / a
|
|
@@ -432,17 +563,22 @@ function createFrameEmitter(deps) {
|
|
|
432
563
|
let sent = false;
|
|
433
564
|
forEachDelivery(id, (delivery) => {
|
|
434
565
|
const s = delivery.state;
|
|
435
|
-
|
|
566
|
+
// §5 D-2: refuse ONLY when the window is full -- one frame in flight no longer holds a
|
|
567
|
+
// newer echo back. The bound is frames OR bytes; nothing else refuses.
|
|
568
|
+
if (s.inFlight.length >= windowFrames || s.inFlightBytes >= windowBytes) {
|
|
436
569
|
s.dirty = true;
|
|
437
570
|
if (ctx.clearScrollback) s.pendingClearScrollback = true;
|
|
438
|
-
onRefused(id,
|
|
439
|
-
|
|
440
|
-
|
|
571
|
+
onRefused(id, 'window-full', {
|
|
572
|
+
inFlightCount: s.inFlight.length, inFlightBytes: s.inFlightBytes,
|
|
573
|
+
oldestSeq: s.inFlightSeq, oldestKind: s.inFlightKind,
|
|
574
|
+
oldestAgeMs: Math.max(0, now() - Number(s.inFlightAt || now())),
|
|
441
575
|
});
|
|
442
576
|
return;
|
|
443
577
|
}
|
|
444
578
|
const t = now();
|
|
445
|
-
|
|
579
|
+
// §5 D-1: "the first frame of this delivery" is sentSeq === 0, not ackedSeq === 0 -- with a
|
|
580
|
+
// window, every emit before the first ack would otherwise be a forced keyframe.
|
|
581
|
+
const forced = !!s.owedKeyframe || Number(s.sentSeq || 0) === 0;
|
|
446
582
|
if (!forced && !ctx.bypassRate && !frameDue(s.fr, t, { ...frameOpts, flooding: s.flooding })) {
|
|
447
583
|
onRefused(id, 'rate', {});
|
|
448
584
|
return;
|
|
@@ -458,43 +594,66 @@ function createFrameEmitter(deps) {
|
|
|
458
594
|
return sent;
|
|
459
595
|
},
|
|
460
596
|
|
|
461
|
-
//
|
|
462
|
-
//
|
|
597
|
+
// §5 D-3: a CUMULATIVE ack -- retire every in-flight entry with seq ≤ n in order, advance the
|
|
598
|
+
// committed base to entry n, flush one dirty catch-up. A seq with no matching entry is ignored:
|
|
599
|
+
// no proofs, no dispositions, no suppression. Gate 2 budget: ≤32 lines / 3 ifs / 3 returns.
|
|
463
600
|
onAck(id, seq, ctx) {
|
|
464
601
|
const session = st(id);
|
|
465
602
|
const n = Number(seq || 0);
|
|
466
603
|
const clientKey = deliveryKey(ctx && ctx.clientId, ctx && ctx.socketGeneration);
|
|
467
604
|
const delivery = ctx && ctx.clientId ? session.clients.get(clientKey) : null;
|
|
468
|
-
if (!n || !delivery
|
|
605
|
+
if (!n || !delivery) return false;
|
|
469
606
|
const s = delivery.state;
|
|
607
|
+
const entry = s.inFlight.find((e) => e.seq === n);
|
|
608
|
+
if (!entry) return false; // stale/reordered/unknown seq: touch nothing
|
|
609
|
+
// WP-0 (D-5, §9 S-11): report this ack's two round-trip legs BEFORE the window is retired --
|
|
610
|
+
// `entry.at` names the send time of the seq just matched.
|
|
611
|
+
_noteAcked(deps, id, {
|
|
612
|
+
seq: n,
|
|
613
|
+
clientId: String((ctx && ctx.clientId) || ''),
|
|
614
|
+
socketGeneration: Number((ctx && ctx.socketGeneration) || 0),
|
|
615
|
+
hostRttMs: Math.max(0, now() - Number(entry.at || now())),
|
|
616
|
+
mainRttMs: (ctx && ctx.mainRttMs) ?? -1,
|
|
617
|
+
windowFrames: STATE_SYNC_WINDOW_FRAMES,
|
|
618
|
+
});
|
|
619
|
+
// WP-2 (D-5, P4/Karn): sample the RTT of EXACTLY the entry named. A sweep re-emit mints a NEW
|
|
620
|
+
// seq, so its ack is unambiguous and samples; a late ack for a swept seq matches no entry.
|
|
621
|
+
noteAckRtt(s, now() - Number(entry.at || now()));
|
|
622
|
+
// Retire every entry at or below n, in order: exactly the scroll-out rows/elision each of
|
|
623
|
+
// those frames carried are now represented in the client's own scrollback -- never more.
|
|
624
|
+
for (const retired of s.inFlight) {
|
|
625
|
+
if (retired.seq > n) break;
|
|
626
|
+
if (retired.scrollbackRowCount > 0) s.pendingScrollbackRows.splice(0, retired.scrollbackRowCount);
|
|
627
|
+
if (retired.scrollbackElidedCount > 0) {
|
|
628
|
+
s.pendingScrollbackElidedCount = Math.max(0, s.pendingScrollbackElidedCount - retired.scrollbackElidedCount);
|
|
629
|
+
}
|
|
630
|
+
s.inFlightBytes = Math.max(0, s.inFlightBytes - Number(retired.bytes || 0));
|
|
631
|
+
}
|
|
632
|
+
s.inFlight = s.inFlight.filter((e) => e.seq > n);
|
|
470
633
|
s.ackedSeq = n;
|
|
471
634
|
s.ackedGridRevision = n; // this module's own convention: gridRevision === the seq that minted it
|
|
472
|
-
s.ackedGrid =
|
|
473
|
-
s.inFlightSeq = 0;
|
|
474
|
-
s.inFlightGrid = null;
|
|
475
|
-
// Retire-on-ack: exactly the scroll-out rows/elision THIS frame carried are now represented
|
|
476
|
-
// in the client's own scrollback -- never more (a later drop must not re-donate them).
|
|
477
|
-
if (s.inFlightScrollbackRowCount > 0) s.pendingScrollbackRows.splice(0, s.inFlightScrollbackRowCount);
|
|
478
|
-
if (s.inFlightScrollbackElidedCount > 0) {
|
|
479
|
-
s.pendingScrollbackElidedCount = Math.max(0, s.pendingScrollbackElidedCount - s.inFlightScrollbackElidedCount);
|
|
480
|
-
}
|
|
481
|
-
s.inFlightScrollbackRowCount = 0;
|
|
482
|
-
s.inFlightScrollbackElidedCount = 0;
|
|
635
|
+
s.ackedGrid = entry.grid || s.ackedGrid || EMPTY_GRID;
|
|
483
636
|
s.sweepResends = 0;
|
|
484
637
|
s.lastAckAt = now();
|
|
485
638
|
s.lastAckClientId = String(ctx.clientId || '');
|
|
639
|
+
syncOldest(s);
|
|
486
640
|
// holdCatchUp is pacing, not refusal: the caller is mid synchronized-output block and its
|
|
487
641
|
// own held-emit retry calls onMirrorUpdated when the block closes; dirty stays set.
|
|
488
642
|
if (!s.dirty || ctx.holdCatchUp) return false;
|
|
643
|
+
if (s.inFlight.length >= windowFrames || s.inFlightBytes >= windowBytes) return false;
|
|
489
644
|
s.dirty = false;
|
|
490
645
|
const clearScrollback = s.pendingClearScrollback;
|
|
491
646
|
s.pendingClearScrollback = false;
|
|
492
|
-
return emit(id, delivery, { bypassRate: true, clearScrollback });
|
|
647
|
+
return emit(id, delivery, { bypassRate: true, clearScrollback, echoedThroughSeq: Number(session.latestEchoedThroughSeq || 0) });
|
|
493
648
|
},
|
|
494
649
|
|
|
495
650
|
// ALWAYS served for a known delivery. An unknown delivery is attached (subject to the same
|
|
496
|
-
// capacity cap any other attach honors), then served -- never refused.
|
|
497
|
-
//
|
|
651
|
+
// capacity cap any other attach honors), then served -- never refused. WP-2 (D-6): a request
|
|
652
|
+
// naming the client's own baseline seq is a NO-OP when this delivery already has a KEYFRAME in
|
|
653
|
+
// flight whose seq is ABOVE that baseline -- that keyframe IS the answer, so forcing another
|
|
654
|
+
// would double-send. Any other shape (no haveSeq, a delta in flight, an older-or-equal
|
|
655
|
+
// baseline, an unknown delivery) is served exactly as before. Gate 2 budget: ≤20 lines /
|
|
656
|
+
// 3 ifs / 3 returns.
|
|
498
657
|
onKeyframeReq(id, ctx) {
|
|
499
658
|
ctx = ctx || {};
|
|
500
659
|
if (!ctx.clientId) return keyframeAllDeliveries(id, ctx);
|
|
@@ -509,8 +668,13 @@ function createFrameEmitter(deps) {
|
|
|
509
668
|
// double-send. A blank cold attach ships nothing, so fall through and force one below.
|
|
510
669
|
// A worker bootstrap reservation for this client (reserveBootstrap) attaches without a
|
|
511
670
|
// delivery -- the bootstrap's base IS its first keyframe; nothing to force here.
|
|
512
|
-
if (!delivery || delivery.state.
|
|
671
|
+
if (!delivery || delivery.state.inFlight.length > 0) return true;
|
|
513
672
|
}
|
|
673
|
+
// §5 D-6: a KEYFRAME anywhere in the window whose seq is above the client's baseline already
|
|
674
|
+
// answers this request (the client will apply it and move its baseline), so re-serving would
|
|
675
|
+
// double-send. Any other shape (no haveSeq, deltas only, an older-or-equal baseline) is served.
|
|
676
|
+
if (Number.isSafeInteger(ctx.haveSeq) && ctx.haveSeq >= 0
|
|
677
|
+
&& delivery.state.inFlight.some((e) => e.kind === 'keyframe' && Number(e.seq) > ctx.haveSeq)) return true;
|
|
514
678
|
clearInFlightOnly(delivery.state);
|
|
515
679
|
return emit(id, delivery, {
|
|
516
680
|
force: true, requestToken: ctx.requestToken,
|
|
@@ -541,33 +705,59 @@ function createFrameEmitter(deps) {
|
|
|
541
705
|
if (!delivery) return false;
|
|
542
706
|
resetDeliveryBaseline(delivery.state);
|
|
543
707
|
if (ctx.deferIfBlank && gridIsBlankAtHome(extractGrid(id) || EMPTY_GRID)) return false;
|
|
544
|
-
return emit(id, delivery, { force: true });
|
|
708
|
+
return emit(id, delivery, { force: true, echoedThroughSeq: Number(session.latestEchoedThroughSeq || 0) });
|
|
545
709
|
},
|
|
546
710
|
|
|
547
|
-
// Lost-ack watchdog:
|
|
548
|
-
//
|
|
549
|
-
// keyframe of the LATEST grid
|
|
550
|
-
//
|
|
551
|
-
//
|
|
711
|
+
// Lost-ack watchdog (§5 D-5b): the OLDEST unacked entry past its stall is treated as lost.
|
|
712
|
+
// Clear the WHOLE window (does NOT advance ackedGrid -- no apply was ever confirmed) and force a
|
|
713
|
+
// fresh keyframe of the LATEST grid under a NEW seq (Karn: no seq is ever re-sent). A
|
|
714
|
+
// session with no viewers (opts.hasViewers false) is not a lost frame: nothing is re-sent to it
|
|
715
|
+
// (primary 2026-09-28: 581 resends to a hidden tab); the window is cleared with a keyframe owed,
|
|
716
|
+
// and regaining a viewer forces it. Gate 2 budget: ≤24 lines / 4 ifs / 2 returns.
|
|
717
|
+
// WP-0 (D-4c, docs/remote-relay-ack-rate-limit-typing-delay-2026-10-28.html §5 D-4c, §9 S-9):
|
|
718
|
+
// every recovery is reported to `opts.onRecovered(id, {inFlightKind, inFlightAgeMs, stallMs,
|
|
719
|
+
// hidden})` — diagnostics only, read BEFORE the in-flight slot is cleared.
|
|
720
|
+
// WP-2 (D-5, §9 S-9): the stall is now PER DELIVERY (`stallMsFor`, sized from that delivery's
|
|
721
|
+
// own measured ack RTT); `opts.stallMs` is the ceiling and `opts.floorMs` the floor (default
|
|
722
|
+
// 250 ms when absent). The reported `stallMs` is the per-delivery value actually used.
|
|
723
|
+
// WP-2 fix-1 (RFC 6298 §5.5 timer backoff): a resend mints a NEW seq, so the late ack for the
|
|
724
|
+
// old seq misses the guard and samples nothing (Karn) — the estimate cannot grow on its own, and
|
|
725
|
+
// a large keyframe on a slow relay would otherwise be re-emitted on the floor's cadence forever.
|
|
726
|
+
// Back the timer off ×2 per consecutive unacked resend (`sweepResends`, incremented below and
|
|
727
|
+
// reset to 0 by onAck), capped at the ceiling. An unsampled delivery is already at the ceiling,
|
|
728
|
+
// so the backoff only binds once sampled.
|
|
552
729
|
sweepStalledInFlight(nowTs, opts) {
|
|
553
730
|
const t = Number(nowTs);
|
|
554
731
|
const stallMs = Number(opts && opts.stallMs);
|
|
555
732
|
if (!Number.isFinite(t) || !Number.isFinite(stallMs) || stallMs <= 0) return 0;
|
|
733
|
+
const rawFloor = Number(opts && opts.floorMs);
|
|
734
|
+
const floorMs = Number.isFinite(rawFloor) ? rawFloor : 250;
|
|
556
735
|
let recovered = 0;
|
|
557
736
|
for (const [id, session] of sessions) {
|
|
558
737
|
if (session.clients.size === 0) continue;
|
|
559
738
|
const hidden = !!(opts && opts.hasViewers) && !opts.hasViewers(id);
|
|
560
739
|
for (const delivery of session.clients.values()) {
|
|
561
740
|
const s = delivery.state;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
741
|
+
const deliveryStallMs = Math.min(
|
|
742
|
+
stallMs,
|
|
743
|
+
stallMsFor(s, { floorMs, ceilingMs: stallMs }) * 2 ** Math.min(Number(s.sweepResends || 0), 6)
|
|
744
|
+
);
|
|
745
|
+
if (!s.inFlight.length || t - Number(s.inFlightAt || 0) <= deliveryStallMs) continue;
|
|
746
|
+
const inFlightKind = s.inFlightKind;
|
|
747
|
+
const inFlightAgeMs = t - Number(s.inFlightAt || 0);
|
|
748
|
+
s.inFlight = [];
|
|
749
|
+
s.inFlightBytes = 0;
|
|
565
750
|
s.dirty = false;
|
|
566
751
|
s.owedKeyframe = s.owedKeyframe || hidden;
|
|
567
|
-
|
|
752
|
+
syncOldest(s);
|
|
753
|
+
const reEmitted = !hidden && emit(id, delivery, {
|
|
754
|
+
force: true, echoedThroughSeq: Number(session.latestEchoedThroughSeq || 0),
|
|
755
|
+
});
|
|
756
|
+
if (reEmitted) {
|
|
568
757
|
s.sweepResends = Number(s.sweepResends || 0) + 1;
|
|
569
758
|
recovered += 1;
|
|
570
759
|
}
|
|
760
|
+
if (hidden || reEmitted) _noteRecovered(opts, id, { inFlightKind, inFlightAgeMs, stallMs: deliveryStallMs, hidden });
|
|
571
761
|
}
|
|
572
762
|
}
|
|
573
763
|
return recovered;
|
|
@@ -595,6 +785,7 @@ function createFrameEmitter(deps) {
|
|
|
595
785
|
socketGeneration: Number(delivery.socketGeneration || 0),
|
|
596
786
|
inFlightSeq: s.inFlightSeq,
|
|
597
787
|
inFlightKind: s.inFlightKind,
|
|
788
|
+
inFlightCount: s.inFlight.length,
|
|
598
789
|
ackedSeq: s.ackedSeq,
|
|
599
790
|
lastAckAgeMs,
|
|
600
791
|
lastAckClientId: s.lastAckClientId || '',
|
|
@@ -606,9 +797,28 @@ function createFrameEmitter(deps) {
|
|
|
606
797
|
return out;
|
|
607
798
|
},
|
|
608
799
|
|
|
609
|
-
//
|
|
610
|
-
//
|
|
611
|
-
|
|
800
|
+
// §6: read-only window telemetry for one delivery (null when unknown). oldestAgeMs is 0 for an
|
|
801
|
+
// empty window.
|
|
802
|
+
getWindowStats(id, clientId, socketGeneration) {
|
|
803
|
+
const session = sessions.get(id);
|
|
804
|
+
if (!session) return null;
|
|
805
|
+
const delivery = session.clients.get(deliveryKey(clientId, socketGeneration));
|
|
806
|
+
if (!delivery) return null;
|
|
807
|
+
const s = delivery.state;
|
|
808
|
+
return {
|
|
809
|
+
inFlightCount: s.inFlight.length,
|
|
810
|
+
inFlightBytes: Number(s.inFlightBytes || 0),
|
|
811
|
+
oldestAgeMs: s.inFlight.length ? Math.max(0, now() - Number(s.inFlightAt || now())) : 0,
|
|
812
|
+
windowFrames: windowFrames,
|
|
813
|
+
windowBytes: windowBytes,
|
|
814
|
+
};
|
|
815
|
+
},
|
|
816
|
+
|
|
817
|
+
// §5 D-5a: the fan-out reported this exact frame never left the wire (backpressure skip /
|
|
818
|
+
// restore hold). Drop every entry with seq ≥ the named one and keep the rest -- those still
|
|
819
|
+
// reach the client, in order -- then owe ONE keyframe whose scroll-out base is the newest kept
|
|
820
|
+
// grid (so rows the client already has are not re-donated). A seq not in the window touches
|
|
821
|
+
// nothing: the frame it names already left, or was itself cleared by a later event.
|
|
612
822
|
noteUndeliverable(id, ctx) {
|
|
613
823
|
ctx = ctx || {};
|
|
614
824
|
const session = st(id);
|
|
@@ -616,16 +826,15 @@ function createFrameEmitter(deps) {
|
|
|
616
826
|
const delivery = ctx.clientId ? session.clients.get(clientKey) : null;
|
|
617
827
|
if (!delivery) return false;
|
|
618
828
|
const s = delivery.state;
|
|
619
|
-
// A skip notice names the seq it is about. A notice for a seq that is no longer the
|
|
620
|
-
// in-flight one (already acked, already re-sent, or simply stale/reordered) is about an
|
|
621
|
-
// OLDER frame -- it must never clear or otherwise touch whatever is in flight NOW.
|
|
622
829
|
const noticeSeq = Number(ctx.seq || 0);
|
|
623
|
-
if (
|
|
624
|
-
const
|
|
625
|
-
s.
|
|
626
|
-
s.
|
|
830
|
+
if (!s.inFlight.some((e) => e.seq === noticeSeq)) return false;
|
|
831
|
+
const kept = s.inFlight.filter((e) => e.seq < noticeSeq);
|
|
832
|
+
s.inFlight = kept;
|
|
833
|
+
s.inFlightBytes = kept.reduce((sum, e) => sum + Number(e.bytes || 0), 0);
|
|
834
|
+
s.resetBaseGrid = kept.length ? kept[kept.length - 1].grid : (s.ackedGrid || EMPTY_GRID);
|
|
835
|
+
s.owedKeyframe = true;
|
|
627
836
|
s.dirty = true;
|
|
628
|
-
|
|
837
|
+
syncOldest(s);
|
|
629
838
|
return true;
|
|
630
839
|
},
|
|
631
840
|
|
|
@@ -705,6 +914,13 @@ function createFrameEmitter(deps) {
|
|
|
705
914
|
state.ackedGrid = reservation.grid;
|
|
706
915
|
state.ackedGridRevision = reservation.gridRevision;
|
|
707
916
|
state.ackedSeq = reservation.baseSeq;
|
|
917
|
+
// WP-1 (D-1): the keyframe rule keys on sentSeq, not ackedSeq. A reservation IS a known
|
|
918
|
+
// receiver state (the client holds the bootstrap snapshot at this base), so the exit state
|
|
919
|
+
// must seed the SENT base too -- otherwise the first post-activation frame would be a
|
|
920
|
+
// spurious full keyframe instead of D-9's delta on the reservation base.
|
|
921
|
+
state.sentGrid = reservation.grid;
|
|
922
|
+
state.sentGridRevision = reservation.gridRevision;
|
|
923
|
+
state.sentSeq = reservation.baseSeq;
|
|
708
924
|
state.surfaceEpoch = reservation.surfaceEpoch;
|
|
709
925
|
state.surfaceIdentity = {
|
|
710
926
|
rows: Number(reservation.grid.rows || 0), cols: Number(reservation.grid.cols || 0),
|
|
@@ -765,4 +981,7 @@ function createFrameEmitter(deps) {
|
|
|
765
981
|
return emitter;
|
|
766
982
|
}
|
|
767
983
|
|
|
768
|
-
module.exports = {
|
|
984
|
+
module.exports = {
|
|
985
|
+
createFrameEmitter, EMPTY_GRID, gridsEqual, gridIsBlankAtHome, noteAckRtt, stallMsFor,
|
|
986
|
+
STATE_SYNC_WINDOW_FRAMES, STATE_SYNC_WINDOW_BYTES,
|
|
987
|
+
};
|