create-walle 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/lib/release-schema.json +2 -2
- package/lib/runtime-closure-policy.json +8 -7
- package/package.json +1 -1
- package/template/coding-task-manager/api-prompts.js +45 -7
- package/template/coding-task-manager/bin/claude-hook.js +55 -1
- package/template/coding-task-manager/bin/ctm-relay-client.js +35 -12
- package/template/coding-task-manager/bin/land.js +2069 -0
- package/template/coding-task-manager/bin/memory-census.js +4 -2
- package/template/coding-task-manager/bin/memory-sync-verify.js +151 -0
- package/template/coding-task-manager/bin/probe-refusal-scope.js +530 -0
- package/template/coding-task-manager/db.js +156 -32
- package/template/coding-task-manager/lib/acp/acp-client.js +383 -0
- package/template/coding-task-manager/lib/acp/dsh-context-truth.js +176 -0
- package/template/coding-task-manager/lib/acp/dsh-launch-model.js +302 -0
- package/template/coding-task-manager/lib/acp/dsh-mcp-servers.js +194 -0
- package/template/coding-task-manager/lib/acp/dsh-prompt-lane.js +616 -0
- package/template/coding-task-manager/lib/acp/dsh-route-patch.js +308 -0
- package/template/coding-task-manager/lib/acp/dsh-session-runtime.js +522 -0
- package/template/coding-task-manager/lib/acp/dsh-transcript.js +395 -0
- package/template/coding-task-manager/lib/acp/dsh-usage-log.js +162 -0
- package/template/coding-task-manager/lib/acp/ndjson-stdio-transport.js +225 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +47 -11
- package/template/coding-task-manager/lib/adopted-launch-environment.js +123 -0
- package/template/coding-task-manager/lib/agent-auto-update-runtime.js +0 -3
- package/template/coding-task-manager/lib/agent-auto-update.js +26 -10
- package/template/coding-task-manager/lib/agent-bundle/build.js +657 -0
- package/template/coding-task-manager/lib/agent-bundle/codex-install.js +558 -0
- package/template/coding-task-manager/lib/agent-bundle/drift.js +120 -0
- package/template/coding-task-manager/lib/agent-bundle/gc.js +522 -0
- package/template/coding-task-manager/lib/agent-bundle/inventory.js +346 -0
- package/template/coding-task-manager/lib/agent-bundle/push.js +717 -0
- package/template/coding-task-manager/lib/agent-bundle/skill-transfer.js +724 -0
- package/template/coding-task-manager/lib/agent-bundle/spawn.js +119 -0
- package/template/coding-task-manager/lib/agent-bundle/store.js +568 -0
- package/template/coding-task-manager/lib/agent-capabilities.js +142 -12
- package/template/coding-task-manager/lib/agent-cli-cache.js +30 -5
- package/template/coding-task-manager/lib/agent-definitions.js +19 -0
- package/template/coding-task-manager/lib/agent-hooks-codex-toml.js +28 -16
- package/template/coding-task-manager/lib/agent-hooks-codex-workspace.js +9 -1
- package/template/coding-task-manager/lib/agent-hooks-installer.js +23 -8
- package/template/coding-task-manager/lib/agent-hooks-prune.js +37 -11
- package/template/coding-task-manager/lib/agent-hooks-shim.js +105 -0
- package/template/coding-task-manager/lib/agent-presets.js +84 -1
- package/template/coding-task-manager/lib/agent-upgrade-jobs.js +12 -1
- package/template/coding-task-manager/lib/agent-version-service.js +74 -11
- package/template/coding-task-manager/lib/all-sessions-query.js +6 -2
- package/template/coding-task-manager/lib/api/agent-bundles.js +436 -0
- package/template/coding-task-manager/lib/api/backup-retention.js +83 -0
- package/template/coding-task-manager/lib/api/conversation-sync-routes.js +124 -0
- package/template/coding-task-manager/lib/api/diagnostics.js +549 -69
- package/template/coding-task-manager/lib/api/fleet.js +118 -0
- package/template/coding-task-manager/lib/api/hub-bridge.js +243 -0
- package/template/coding-task-manager/lib/api/ingress.js +9 -1
- package/template/coding-task-manager/lib/api/landing.js +403 -0
- package/template/coding-task-manager/lib/api/machines.js +691 -2
- package/template/coding-task-manager/lib/api/memory-sync-routes.js +335 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +8 -3
- package/template/coding-task-manager/lib/api/remote-sessions.js +1326 -0
- package/template/coding-task-manager/lib/api/session-attach.js +623 -0
- package/template/coding-task-manager/lib/api/session-messages.js +1384 -0
- package/template/coding-task-manager/lib/api/sessions.js +77 -51
- package/template/coding-task-manager/lib/api/setup-network.js +544 -16
- package/template/coding-task-manager/lib/api/setup-wizard-handlers.js +884 -0
- package/template/coding-task-manager/lib/api/setup.js +829 -10
- package/template/coding-task-manager/lib/api/walle-bridge.js +9 -1
- package/template/coding-task-manager/lib/attachment-reconciler-wiring.js +5 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +23 -0
- package/template/coding-task-manager/lib/auth-rules.js +292 -21
- package/template/coding-task-manager/lib/background-stop.js +369 -0
- package/template/coding-task-manager/lib/best-of-attempts.js +4 -1
- package/template/coding-task-manager/lib/best-of-launch-plan.js +52 -0
- package/template/coding-task-manager/lib/box-keep-awake.js +89 -0
- package/template/coding-task-manager/lib/broadcast-reason-stats.js +152 -0
- package/template/coding-task-manager/lib/broadcast-serialize.js +5 -0
- package/template/coding-task-manager/lib/build-info.js +4 -2
- package/template/coding-task-manager/lib/claude-model-truth.js +13 -2
- package/template/coding-task-manager/lib/claude-transcript-terminal-renderer.js +17 -13
- package/template/coding-task-manager/lib/client-diag-handler.js +64 -2
- package/template/coding-task-manager/lib/codex-app-server-client.js +14 -16
- package/template/coding-task-manager/lib/codex-configuration-history.js +55 -0
- package/template/coding-task-manager/lib/codex-harness-qualification.js +43 -20
- package/template/coding-task-manager/lib/codex-rollout-history.js +743 -0
- package/template/coding-task-manager/lib/coding-agent-models.js +27 -12
- package/template/coding-task-manager/lib/coding-cli-skill-installer.js +44 -14
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +43 -2
- package/template/coding-task-manager/lib/coding-session-model-owner.js +1 -1
- package/template/coding-task-manager/lib/coding-session-model-public.js +7 -1
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +23 -4
- package/template/coding-task-manager/lib/coding-session-model-scan.js +31 -0
- package/template/coding-task-manager/lib/coding-session-model-state.js +7 -0
- package/template/coding-task-manager/lib/conversation-freshness-diagnostics.js +280 -0
- package/template/coding-task-manager/lib/conversation-item-clock.js +261 -0
- package/template/coding-task-manager/lib/conversation-source-registry.js +5 -0
- package/template/coding-task-manager/lib/conversation-store-v2.js +44 -0
- package/template/coding-task-manager/lib/conversation-sync.js +355 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +96 -12
- package/template/coding-task-manager/lib/create/worker-role-profile.js +4 -4
- package/template/coding-task-manager/lib/create-intent-lease.js +51 -0
- package/template/coding-task-manager/lib/ctm-session-context-api.js +97 -6
- package/template/coding-task-manager/lib/db-domain-tables.js +1 -0
- package/template/coding-task-manager/lib/db-domains.js +1 -0
- package/template/coding-task-manager/lib/db-owner-dispatch-probe.js +32 -0
- package/template/coding-task-manager/lib/db-owner-request-counts.js +178 -0
- package/template/coding-task-manager/lib/db-owner-worker-client.js +68 -14
- package/template/coding-task-manager/lib/db-schema-source-files.js +5 -0
- package/template/coding-task-manager/lib/deferred-restore-attempt.js +6 -2
- package/template/coding-task-manager/lib/feature-manifest.js +4 -0
- package/template/coding-task-manager/lib/fleet-conversation-route.js +97 -0
- package/template/coding-task-manager/lib/fleet-fanout.js +78 -0
- package/template/coding-task-manager/lib/fleet-hub.js +762 -0
- package/template/coding-task-manager/lib/fleet-origin-follower.js +252 -0
- package/template/coding-task-manager/lib/fleet-resolver-effects.js +147 -0
- package/template/coding-task-manager/lib/fleet-resolver-tick.js +148 -0
- package/template/coding-task-manager/lib/fleet-resolver.js +454 -0
- package/template/coding-task-manager/lib/fleet-session-list-routes.js +114 -0
- package/template/coding-task-manager/lib/fleet-session-lists.js +672 -0
- package/template/coding-task-manager/lib/fleet-update.js +798 -0
- package/template/coding-task-manager/lib/fs-watcher-root-watch.js +141 -0
- package/template/coding-task-manager/lib/fs-watcher.js +58 -42
- package/template/coding-task-manager/lib/harness-history-transition.js +50 -9
- package/template/coding-task-manager/lib/headless-term-service.js +84 -8
- package/template/coding-task-manager/lib/hermetic-agent-launch-guard.js +10 -0
- package/template/coding-task-manager/lib/history-transition-read-op.js +175 -8
- package/template/coding-task-manager/lib/host-cpu-categories.js +310 -0
- package/template/coding-task-manager/lib/host-fseventsd-sampler.js +399 -0
- package/template/coding-task-manager/lib/host-handoff.js +16 -19
- package/template/coding-task-manager/lib/host-stats.js +150 -3
- package/template/coding-task-manager/lib/hosted-sync-worker.js +43 -320
- package/template/coding-task-manager/lib/hub-bridge-access.js +798 -0
- package/template/coding-task-manager/lib/hub-bridge-box.js +409 -0
- package/template/coding-task-manager/lib/hub-bridge-mcp.js +380 -0
- package/template/coding-task-manager/lib/hub-bridge-mesh.js +313 -0
- package/template/coding-task-manager/lib/hub-bridge-ops.js +721 -0
- package/template/coding-task-manager/lib/hub-bridge.js +398 -0
- package/template/coding-task-manager/lib/idle-notify.js +491 -0
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +8 -0
- package/template/coding-task-manager/lib/instance-manifest.js +5 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +18 -8
- package/template/coding-task-manager/lib/landing/agent-rule.txt +1 -0
- package/template/coding-task-manager/lib/landing/batch-runner.js +366 -0
- package/template/coding-task-manager/lib/landing/config.js +536 -0
- package/template/coding-task-manager/lib/landing/ctm-view.js +256 -0
- package/template/coding-task-manager/lib/landing/gate.js +360 -0
- package/template/coding-task-manager/lib/landing/git.js +344 -0
- package/template/coding-task-manager/lib/landing/lease.js +247 -0
- package/template/coding-task-manager/lib/landing/merge-delta.js +380 -0
- package/template/coding-task-manager/lib/landing/proof.js +223 -0
- package/template/coding-task-manager/lib/landing/queue.js +998 -0
- package/template/coding-task-manager/lib/landing/radar.js +489 -0
- package/template/coding-task-manager/lib/landing/resolve-cli.js +424 -0
- package/template/coding-task-manager/lib/landing/state.js +263 -0
- package/template/coding-task-manager/lib/landing/stop.js +49 -0
- package/template/coding-task-manager/lib/landing/sync-cli.js +475 -0
- package/template/coding-task-manager/lib/landing/sync.js +456 -0
- package/template/coding-task-manager/lib/landing/train.js +885 -0
- package/template/coding-task-manager/lib/landing/window.js +57 -0
- package/template/coding-task-manager/lib/launch-environment.js +121 -0
- package/template/coding-task-manager/lib/launch-model-override.js +36 -10
- package/template/coding-task-manager/lib/launch-plan-pool.js +2 -1
- package/template/coding-task-manager/lib/launch-plan-warm-cache.js +6 -0
- package/template/coding-task-manager/lib/lead-model-observer.js +57 -1
- package/template/coding-task-manager/lib/lead-model-options.js +160 -3
- package/template/coding-task-manager/lib/lead-model-restore-reconciliation.js +106 -24
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +352 -68
- package/template/coding-task-manager/lib/lead-model-switch.js +114 -10
- package/template/coding-task-manager/lib/lead-model-transition-runtime.js +14 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +24 -6
- package/template/coding-task-manager/lib/lead-route-preflight.js +179 -0
- package/template/coding-task-manager/lib/lead-switch-history-mode.js +110 -0
- package/template/coding-task-manager/lib/lead-wire-agent.js +7 -0
- package/template/coding-task-manager/lib/lifecycle-wake-experiment.js +9 -2
- package/template/coding-task-manager/lib/live-defer-announce.js +45 -0
- package/template/coding-task-manager/lib/machine-registry.js +750 -5
- package/template/coding-task-manager/lib/macos-capabilities.js +32 -15
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +433 -53
- package/template/coding-task-manager/lib/mainloop-observability.js +14 -9
- package/template/coding-task-manager/lib/media-draft-owner.js +16 -3
- package/template/coding-task-manager/lib/memory-join.js +337 -0
- package/template/coding-task-manager/lib/memory-sync-verify.js +393 -0
- package/template/coding-task-manager/lib/memory-sync.js +565 -0
- package/template/coding-task-manager/lib/migrations/v57-delegate-pref-mirror-opencode.js +68 -0
- package/template/coding-task-manager/lib/migrations/v58-subagent-launch-native-subagents.js +42 -0
- package/template/coding-task-manager/lib/migrations/v59-coding-session-model-state-dsh.js +73 -0
- package/template/coding-task-manager/lib/migrations/v60-delegate-pref-mirror-dsh.js +78 -0
- package/template/coding-task-manager/lib/migrations/v61-conversation-item-clock.js +71 -0
- package/template/coding-task-manager/lib/model-availability.js +727 -0
- package/template/coding-task-manager/lib/model-execution-recipe-metadata.js +4 -6
- package/template/coding-task-manager/lib/model-host-receipt.js +6 -3
- package/template/coding-task-manager/lib/model-id-rule.js +19 -0
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/auto-mode-review.js +110 -23
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/generation-probe.js +60 -17
- package/template/coding-task-manager/lib/model-proxy/historical-tool-declarations.js +37 -0
- package/template/coding-task-manager/lib/model-proxy/lead-request-validation.js +1 -0
- package/template/coding-task-manager/lib/model-proxy/lead-token-admin.js +130 -0
- package/template/coding-task-manager/lib/model-proxy/refusal-scope.js +151 -0
- package/template/coding-task-manager/lib/model-proxy/request-budget-store.js +11 -2
- package/template/coding-task-manager/lib/model-proxy/tokens.js +69 -5
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-agent-model-args.js +25 -22
- package/template/coding-task-manager/lib/native-history-control.js +6 -4
- package/template/coding-task-manager/lib/native-lead-settings-client.js +44 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +173 -36
- package/template/coding-task-manager/lib/online-backup-worker-client.js +2 -0
- package/template/coding-task-manager/lib/opencode-cli.js +480 -0
- package/template/coding-task-manager/lib/opencode-launch-model.js +471 -0
- package/template/coding-task-manager/lib/opencode-v1-plugin/model-carrier.mjs +35 -0
- package/template/coding-task-manager/lib/opencode-v2-plugin/server.js +118 -0
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +1 -1
- package/template/coding-task-manager/lib/park-composer-draft.js +54 -0
- package/template/coding-task-manager/lib/park-fresh-relaunch.js +41 -10
- package/template/coding-task-manager/lib/perf-phase-trace.js +72 -0
- package/template/coding-task-manager/lib/perf-summary.js +7 -0
- package/template/coding-task-manager/lib/perf-tracker.js +63 -2
- package/template/coding-task-manager/lib/project-config.js +7 -0
- package/template/coding-task-manager/lib/prompt-purge-v2.js +52 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +72 -15
- package/template/coding-task-manager/lib/provider-login-tab.js +10 -2
- package/template/coding-task-manager/lib/read-pool-client.js +89 -2
- package/template/coding-task-manager/lib/read-pool-worker-handle.js +29 -4
- package/template/coding-task-manager/lib/recent-catalog-query.js +15 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +67 -10
- package/template/coding-task-manager/lib/recovery-evidence.js +26 -11
- package/template/coding-task-manager/lib/relay-client.js +57 -3
- package/template/coding-task-manager/lib/relink-audit.js +34 -5
- package/template/coding-task-manager/lib/remote-machine-catalog.js +321 -26
- package/template/coding-task-manager/lib/remote-machine-create.js +576 -36
- package/template/coding-task-manager/lib/remote-machine-link.js +546 -59
- package/template/coding-task-manager/lib/remote-machine-proxy.js +143 -9
- package/template/coding-task-manager/lib/remote-session-forward.js +65 -7
- package/template/coding-task-manager/lib/remote-terminal-target.js +9 -2
- package/template/coding-task-manager/lib/restart-guard.js +18 -6
- package/template/coding-task-manager/lib/restore-seed-modes.js +87 -0
- package/template/coding-task-manager/lib/restored-scrollback-hydration-runtime.js +22 -2
- package/template/coding-task-manager/lib/resume-admission.js +17 -3
- package/template/coding-task-manager/lib/review-repo-registry.js +58 -19
- package/template/coding-task-manager/lib/root-delivery-runtime.js +2 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +1 -1
- package/template/coding-task-manager/lib/runtime-contract.js +3 -1
- package/template/coding-task-manager/lib/schema-indexes.js +1 -0
- package/template/coding-task-manager/lib/session-context-locator.js +742 -0
- package/template/coding-task-manager/lib/session-create/attachment.js +2 -2
- package/template/coding-task-manager/lib/session-create/create-phases.js +118 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +86 -16
- package/template/coding-task-manager/lib/session-create/dsh-session.js +930 -0
- package/template/coding-task-manager/lib/session-create/lead-route-launch.js +186 -13
- package/template/coding-task-manager/lib/session-create/native-lead-lifetime.js +55 -3
- package/template/coding-task-manager/lib/session-create/opencode-lead-provider.js +50 -0
- package/template/coding-task-manager/lib/session-create/prepared.js +162 -38
- package/template/coding-task-manager/lib/session-create/provider-process.js +160 -28
- package/template/coding-task-manager/lib/session-create/response.js +7 -7
- package/template/coding-task-manager/lib/session-create/structured-session.js +27 -0
- package/template/coding-task-manager/lib/session-create/subagent-pick-table.js +3 -1
- package/template/coding-task-manager/lib/session-create/subagent-pick.js +458 -9
- package/template/coding-task-manager/lib/session-create/transcript.js +1 -1
- package/template/coding-task-manager/lib/session-create/worker-budget-setup.js +21 -2
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +7 -1
- package/template/coding-task-manager/lib/session-create/worker-launch-sandbox.js +39 -10
- package/template/coding-task-manager/lib/session-create/worker-observability.js +2 -2
- package/template/coding-task-manager/lib/session-empty.js +13 -10
- package/template/coding-task-manager/lib/session-host-manager.js +60 -0
- package/template/coding-task-manager/lib/session-jobs.js +3 -1
- package/template/coding-task-manager/lib/session-lifecycle.js +10 -4
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +6 -2
- package/template/coding-task-manager/lib/session-model-intent-contract.js +11 -8
- package/template/coding-task-manager/lib/session-park.js +738 -0
- package/template/coding-task-manager/lib/session-path-grant.js +13 -4
- package/template/coding-task-manager/lib/session-status-ledger.js +106 -4
- package/template/coding-task-manager/lib/session-transport.js +17 -0
- package/template/coding-task-manager/lib/session-workspace-projection.js +54 -5
- package/template/coding-task-manager/lib/session-workspace-tracking-runtime.js +213 -1
- package/template/coding-task-manager/lib/skill-autocomplete-query.js +120 -3
- package/template/coding-task-manager/lib/skill-autocomplete.js +15 -1
- package/template/coding-task-manager/lib/sqlite-file-set.js +39 -0
- package/template/coding-task-manager/lib/standup-search-adapter.js +16 -2
- package/template/coding-task-manager/lib/state-sync/client-ledger.js +12 -0
- package/template/coding-task-manager/lib/state-sync/frame-emitter.js +319 -100
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +4 -1
- package/template/coding-task-manager/lib/storage/delegate-pref-mirror-store.js +32 -9
- package/template/coding-task-manager/lib/structured-session-boot-sweep.js +235 -0
- package/template/coding-task-manager/lib/submission-ack.js +90 -2
- package/template/coding-task-manager/lib/systemd-scope.js +115 -0
- package/template/coding-task-manager/lib/telemetry-receiver.js +39 -0
- package/template/coding-task-manager/lib/terminal-attach-geometry.js +985 -0
- package/template/coding-task-manager/lib/terminal-bootstrap.js +30 -0
- package/template/coding-task-manager/lib/terminal-draft-operation.js +357 -0
- package/template/coding-task-manager/lib/terminal-input-admission.js +17 -1
- package/template/coding-task-manager/lib/terminal-input-prepared.js +563 -0
- package/template/coding-task-manager/lib/transcript-cache-temps.js +171 -0
- package/template/coding-task-manager/lib/transcript-frame-cache.js +8 -3
- package/template/coding-task-manager/lib/transcript-source.js +36 -4
- package/template/coding-task-manager/lib/transcript-store.js +9 -0
- package/template/coding-task-manager/lib/typing-interaction-trace.js +106 -3
- package/template/coding-task-manager/lib/usage-ledger/backfill.js +40 -5
- package/template/coding-task-manager/lib/usage-ledger/client.js +4 -1
- package/template/coding-task-manager/lib/usage-ledger/dsh-parse.js +152 -0
- package/template/coding-task-manager/lib/usage-ledger/dsh-read.js +73 -0
- package/template/coding-task-manager/lib/usage-ledger/ingest.js +34 -6
- package/template/coding-task-manager/lib/usage-ledger/live.js +35 -8
- package/template/coding-task-manager/lib/usage-ledger/read.js +29 -20
- package/template/coding-task-manager/lib/usage-ledger/schema.js +61 -1
- package/template/coding-task-manager/lib/usage-ledger/task-coordinator.js +4 -2
- package/template/coding-task-manager/lib/wake-skip-reasons.js +1 -0
- package/template/coding-task-manager/lib/walle/turn.js +1 -1
- package/template/coding-task-manager/lib/walle-history-serve.js +838 -0
- package/template/coding-task-manager/lib/walle-kill-authority.js +2 -2
- package/template/coding-task-manager/lib/walle-log-rotation.js +164 -1
- package/template/coding-task-manager/lib/walle-mcp-auto-config.js +56 -2
- package/template/coding-task-manager/lib/walle-row-history.js +495 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +33 -14
- package/template/coding-task-manager/lib/watch-worker-client.js +203 -0
- package/template/coding-task-manager/lib/worker-terminal-output.js +5 -2
- package/template/coding-task-manager/lib/ws/hub-bridge.js +35 -0
- package/template/coding-task-manager/lib/ws/lifecycle.js +6 -11
- package/template/coding-task-manager/lib/ws/misc.js +1 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +106 -4
- package/template/coding-task-manager/lib/ws/terminal-attach.js +91 -0
- package/template/coding-task-manager/oauth-proxy.js +112 -115
- package/template/coding-task-manager/package-lock.json +10 -94
- package/template/coding-task-manager/package.json +4 -3
- package/template/coding-task-manager/protocol/message-table.json +10 -0
- package/template/coding-task-manager/protocol/messages.js +10 -0
- package/template/coding-task-manager/protocol/ws-schema.json +20 -0
- package/template/coding-task-manager/protocol/ws-schema.md +2 -0
- package/template/coding-task-manager/public/css/app.css +170 -0
- package/template/coding-task-manager/public/css/walle-session.css +4 -0
- package/template/coding-task-manager/public/index.html +473 -243
- package/template/coding-task-manager/public/js/agent-command.js +86 -0
- package/template/coding-task-manager/public/js/app/backups-panel.js +111 -5
- package/template/coding-task-manager/public/js/app/coding-agent-upgrade.js +103 -4
- package/template/coding-task-manager/public/js/app/machines-page.js +1328 -8
- package/template/coding-task-manager/public/js/app/models-tab.js +113 -38
- package/template/coding-task-manager/public/js/app/restart-banner.js +53 -0
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +184 -2
- package/template/coding-task-manager/public/js/background-work.js +196 -27
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +138 -10
- package/template/coding-task-manager/public/js/core/active-session-groups.js +179 -0
- package/template/coding-task-manager/public/js/core/pending-create.js +238 -0
- package/template/coding-task-manager/public/js/core/recent-machine-source.js +228 -0
- package/template/coding-task-manager/public/js/core/session-commands.js +180 -14
- package/template/coding-task-manager/public/js/dashboard-client-function-order.json +8 -0
- package/template/coding-task-manager/public/js/document-review-links.js +9 -1
- package/template/coding-task-manager/public/js/file-resolution-client.js +52 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +22 -2
- package/template/coding-task-manager/public/js/machine-pool-shared.js +558 -3
- package/template/coding-task-manager/public/js/message-renderer.js +4 -3
- package/template/coding-task-manager/public/js/model-picker.js +3 -1
- package/template/coding-task-manager/public/js/native-subagent-review.js +15 -2
- package/template/coding-task-manager/public/js/new-session-agent-grid.js +346 -0
- package/template/coding-task-manager/public/js/pasted-content.js +236 -0
- package/template/coding-task-manager/public/js/pe-private-content-lifetime.js +39 -7
- package/template/coding-task-manager/public/js/private-model-lifetime.js +6 -2
- package/template/coding-task-manager/public/js/prompts.js +11 -10
- package/template/coding-task-manager/public/js/protocol.js +10 -0
- package/template/coding-task-manager/public/js/restart-banner-policy.js +29 -1
- package/template/coding-task-manager/public/js/session-model-picker.js +447 -57
- package/template/coding-task-manager/public/js/session-search-utils.js +18 -2
- package/template/coding-task-manager/public/js/session-usage-view.js +2 -1
- package/template/coding-task-manager/public/js/session-workspace-tracking.js +51 -1
- package/template/coding-task-manager/public/js/state-sync-client.js +10 -1
- package/template/coding-task-manager/public/js/stream-view.js +6 -5
- package/template/coding-task-manager/public/js/terminal/conv-only-session.js +287 -0
- package/template/coding-task-manager/public/js/terminal/runtime-09.js +2 -0
- package/template/coding-task-manager/public/js/terminal/runtime-10.js +5 -5
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +8 -1
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +1 -1
- package/template/coding-task-manager/public/js/terminal-attachment-draft.js +67 -13
- package/template/coding-task-manager/public/js/terminal-image-orchestration.js +52 -6
- package/template/coding-task-manager/public/js/terminal-wheel.js +23 -3
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +4 -4
- package/template/coding-task-manager/public/js/walle.js +6 -0
- package/template/coding-task-manager/public/js/ws/live-dispatch.js +10 -0
- package/template/coding-task-manager/public/m/app.css +140 -0
- package/template/coding-task-manager/public/m/app.js +507 -68
- package/template/coding-task-manager/public/m/index.html +17 -0
- package/template/coding-task-manager/public/m/machines.js +838 -4
- package/template/coding-task-manager/public/m/private-api.js +31 -1
- package/template/coding-task-manager/public/usage.html +1 -0
- package/template/coding-task-manager/scripts/dev-route-fixture/synthetic-route-upstream.js +104 -0
- package/template/coding-task-manager/scripts/dev-route-fixture.js +339 -0
- package/template/coding-task-manager/scripts/opencode-lead-route-probe.js +195 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/fake-anthropic.js +168 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe/probe-plugin/server.js +95 -0
- package/template/coding-task-manager/scripts/opencode-v2-contract-probe.js +673 -0
- package/template/coding-task-manager/server.js +1950 -11679
- package/template/coding-task-manager/session-integrity.js +64 -4
- package/template/coding-task-manager/workers/db-owner-worker.js +19 -2
- package/template/coding-task-manager/workers/online-backup-worker.js +1 -0
- package/template/coding-task-manager/workers/read-pool-model-collector.js +51 -3
- package/template/coding-task-manager/workers/read-pool-worker.js +76 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +6 -6
- package/template/coding-task-manager/workers/session-host-process.js +5 -5
- package/template/coding-task-manager/workers/watch-worker.js +105 -0
- package/template/coding-task-manager/workers/worktree-worker.js +168 -33
- package/template/ctm-relay/lib/protocol.js +14 -1
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/shared/backup-retention.js +82 -0
- package/template/shared/conversation-admission.js +2 -0
- package/template/shared/conversation-provenance.js +3 -7
- package/template/shared/conversation-storage-v2-contract.js +5 -0
- package/template/shared/linked-worktree.js +51 -0
- package/template/shared/macos-fda-target.js +57 -0
- package/template/shared/orphan-parents.js +55 -0
- package/template/shared/release-schema.json +2 -2
- package/template/shared/storage/contract.js +3 -0
- package/template/wall-e/adapters/imessage.js +12 -0
- package/template/wall-e/agent.js +71 -4
- package/template/wall-e/api-walle.js +21 -1
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +2 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +5 -5
- package/template/wall-e/brain/brain-join.js +859 -0
- package/template/wall-e/brain/brain-sync-membership.js +20 -0
- package/template/wall-e/brain/brain-sync-store.js +131 -77
- package/template/wall-e/brain/brain-sync-v2-schema.js +203 -0
- package/template/wall-e/brain/brain-sync-v2.js +578 -0
- package/template/wall-e/brain/delegate-model-prefs-store.js +13 -4
- package/template/wall-e/brain/deterministic-id.js +51 -0
- package/template/wall-e/brain/memories.js +2 -2
- package/template/wall-e/brain/migrations.js +40 -6
- package/template/wall-e/brain/model-identity-migration.js +1 -1
- package/template/wall-e/brain/owner-call-whitelist.js +23 -7
- package/template/wall-e/brain/schema.js +45 -85
- package/template/wall-e/brain.js +171 -35
- package/template/wall-e/chat.js +3 -3
- package/template/wall-e/coding/agent-shell-env.js +7 -2
- package/template/wall-e/coding/prompt-bundle.js +66 -21
- package/template/wall-e/config/main-loop-exemptions.json +2 -2
- package/template/wall-e/http/admin-api.js +37 -0
- package/template/wall-e/http/gws-api.js +4 -0
- package/template/wall-e/http/helper-rules-api.js +7 -1
- package/template/wall-e/http/model-admin.js +8 -1
- package/template/wall-e/http/model-delegate-pref-admin.js +3 -3
- package/template/wall-e/http/model-proxy-providers.js +174 -1
- package/template/wall-e/http/model-route-health.js +157 -0
- package/template/wall-e/http/sync-api.js +278 -464
- package/template/wall-e/jobs/job-runner.js +28 -1
- package/template/wall-e/lib/brain-owner-op-priority.js +9 -1
- package/template/wall-e/lib/ctm-data-dir.js +26 -0
- package/template/wall-e/lib/derivation-home.js +147 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +50 -9
- package/template/wall-e/lib/helper-rules/grade.js +51 -8
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +38 -5
- package/template/wall-e/lib/helper-rules/store.js +4 -2
- package/template/wall-e/lib/landing-mcp-tools.js +170 -0
- package/template/wall-e/lib/mcp-client-config.js +133 -14
- package/template/wall-e/lib/mcp-gateway-migrate.js +28 -64
- package/template/wall-e/lib/mcp-integration.js +58 -13
- package/template/wall-e/lib/parent-death.js +7 -1
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -4
- package/template/wall-e/llm/delegate-lead-prefs.js +16 -1
- package/template/wall-e/llm/delegate-vendor-default.js +12 -5
- package/template/wall-e/llm/model-roles.js +1 -1
- package/template/wall-e/llm/native-delegate-selection.js +56 -8
- package/template/wall-e/llm/worker-delegate-args.js +72 -7
- package/template/wall-e/llm/worker-mcp-routing.js +66 -17
- package/template/wall-e/loops/brain-custom-writes.js +19 -0
- package/template/wall-e/loops/ingest.js +17 -1
- package/template/wall-e/loops/think.js +19 -4
- package/template/wall-e/mcp-contract.js +222 -6
- package/template/wall-e/mcp-protocol-contract.js +40 -5
- package/template/wall-e/mcp-server.js +128 -29
- package/template/wall-e/mcp-worker-schemas.js +5 -5
- package/template/wall-e/memory/ctm-context-client.js +85 -0
- package/template/wall-e/memory/ctm-session-context.js +9 -3
- package/template/wall-e/memory/hub-bridge-client.js +388 -0
- package/template/wall-e/memory/replica-origin.js +56 -0
- package/template/wall-e/memory/session-pool.js +135 -0
- package/template/wall-e/runtime/live-capabilities.js +8 -3
- package/template/wall-e/server.js +4 -2
- package/template/wall-e/shared/release-schema.json +2 -2
- package/template/wall-e/shared/sqlite-file-set.js +39 -0
- package/template/wall-e/shared/storage/contract.js +3 -0
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +7 -1
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +4 -4
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +6 -6
- package/template/wall-e/skills/_templates/fleet-sync/VERSION +1 -0
- package/template/wall-e/skills/_templates/fleet-sync/released-sha256.json +16 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/claude/SKILL.md +64 -0
- package/template/wall-e/skills/_templates/fleet-sync/templates/codex/SKILL.md +64 -0
- package/template/wall-e/tools/chrome-automation.js +6 -0
- package/template/wall-e/training/setup-cuda-train-env.sh +2 -2
- package/template/wall-e/workers/brain-owner-worker.js +18 -4
- package/template/wall-e/workers/mcp-gateway-process.js +5 -5
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Landing-throughput WP-6 shard S11 (design doc §5 D-10 "move-only", §6 "Shard module
|
|
4
|
+
// seam"): the idle-notify cluster (checkIdleNotify + its four private helpers) moves out of
|
|
5
|
+
// server.js VERBATIM into this module behind the same configure(deps) seam as
|
|
6
|
+
// lib/api/session-attach.js and lib/terminal-attach-geometry.js (S6), lib/walle-history-serve.js
|
|
7
|
+
// (S8), lib/codex-rollout-history.js (S9) and lib/terminal-input-prepared.js (S10). It registers
|
|
8
|
+
// NO route and NO socket handler: server.js keeps the five pass-through call sites (the
|
|
9
|
+
// _statusBindings probeIdle arrow, the _suppressionReplay factory, the session-create service
|
|
10
|
+
// bindings object, the sessionAttachApi bindings object and the adopted-pty flush) as
|
|
11
|
+
// idleNotify.checkIdleNotify(...), plus this configure() seam.
|
|
12
|
+
// Bodies are identical to server.js declarations except for the `_deps.` prefix on every
|
|
13
|
+
// identifier that used to resolve to a server.js top-level binding (D-10 rule 1), proven by
|
|
14
|
+
// `node bin/move-only-check.js`. No moved body contains an inline `require(...)`, so there is no
|
|
15
|
+
// require rebase here (unlike S1/S3/S6/S8).
|
|
16
|
+
//
|
|
17
|
+
// The module deliberately lives at lib/idle-notify.js and NOT under lib/ws/: checkIdleNotify is
|
|
18
|
+
// the output-quiet idle/waiting detector, not a ws-router handler.
|
|
19
|
+
//
|
|
20
|
+
// Injected deps, per function:
|
|
21
|
+
// _idlePromptDetections: IDLE_PROMPT_PATTERNS, _providerGenerationGateState, _providerIdFromCmd, _providerTurnFinishedDetection, _providerWaitingInputDetection, approvalAgent, recordSessionDiagnostic, terminalChoice
|
|
22
|
+
// _unconfirmedPatternWait: (none)
|
|
23
|
+
// _prioritizeIdlePromptDetections: (none)
|
|
24
|
+
// _runningEvidenceHoldUntil: IDLE_NOTIFY_DELAY_MS, _providerRunningHoldMsForSession, _serverObservedTimeMs, _sessionCapture, idleNotifyState
|
|
25
|
+
// checkIdleNotify: IDLE_NOTIFY_DELAY_MS, STATUS_EVIDENCE, _clearServerWaitingForInput, _composerMayClose, _deriveApprovalBannerLabel, _getHeadlessViewportRead, _isActivePtyChunk, _isStatusOnlyPtyChunk, _markBackgroundAgentsEvidence, _markServerSessionTurnClosed, _markServerSessionTurnEvidence, _markTerminalLifecycleChanged, _providerActivelyGenerating, _providerIdFromCmd, _recheckHeadlessApprovalPrompt, _recordWaitCleared, _selectionCardFpForSession, _statusBindings, _suppressCtmUiRefreshActivity, _suppressionReplay, _wordsMayUnstickWait, autoApprovalBuffers, broadcastToAll, dispatchMobileNotification, idleNotifyState, isSessionAtLivePrompt, mobileNotifications, reconcileSessionWaitState, recordSessionDiagnostic, restoreRuntime, sessionPolicy, statusRuntime, stripAnsi, telemetryReceiver
|
|
26
|
+
//
|
|
27
|
+
// Mutable module state (D-10 rule 2 / S9 lesson 7): _sessionCapture is a server.js `let`
|
|
28
|
+
// reassigned once during boot (in the boot sequence), so it is injected as a GETTER -- never a
|
|
29
|
+
// copy. Every other dep is a by-value reference, and no moved body writes a server.js binding
|
|
30
|
+
// (checked with an acorn walk), so there is no get/set pair here. Calls between the five moved
|
|
31
|
+
// functions stay direct (no _deps.).
|
|
32
|
+
|
|
33
|
+
let _deps = null;
|
|
34
|
+
|
|
35
|
+
function configure(deps = {}) {
|
|
36
|
+
_deps = deps;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function _idlePromptDetections(session, lastLines, rawTail) {
|
|
40
|
+
const detections = [];
|
|
41
|
+
const providerId = session?._providerId || _deps._providerIdFromCmd(session?.cmd || '');
|
|
42
|
+
for (const { pattern, test, reason, provider } of _deps.IDLE_PROMPT_PATTERNS) {
|
|
43
|
+
if (provider && provider !== providerId) continue;
|
|
44
|
+
if ((test && test(lastLines)) || (pattern && pattern.test(lastLines))) {
|
|
45
|
+
detections.push({ reason, source: 'pattern' });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const choice = _deps.terminalChoice.extractTerminalChoice(rawTail || lastLines);
|
|
50
|
+
if (choice && (choice.kind === 'numbered' || choice.kind === 'form')) {
|
|
51
|
+
detections.push({ reason: 'choice', source: 'terminal-choice', fingerprint: choice.fingerprint });
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
_deps.recordSessionDiagnostic(session?.id || '', 'terminal-choice-detection-error', {
|
|
55
|
+
error: e && e.message || String(e),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const providerDetection = _deps._providerWaitingInputDetection(session, rawTail || lastLines);
|
|
59
|
+
if (providerDetection) detections.push({ ...providerDetection, source: providerDetection.source || 'provider' });
|
|
60
|
+
if (_deps._providerTurnFinishedDetection(session, rawTail || lastLines)) {
|
|
61
|
+
detections.push({ reason: 'finished', source: 'provider-ready-composer' });
|
|
62
|
+
}
|
|
63
|
+
// "Agent is actively generating" gate (provider-aware). Under the Claude V2 rule (the default) generation is the
|
|
64
|
+
// busy status-line shape or live background-agent evidence, NOT the "esc to interrupt" footer (that phrase is
|
|
65
|
+
// ignored: it lingers in scrollback). When the provider reports it is
|
|
66
|
+
// generating, the agent is NOT blocked on the user, so drop EVERY blocker reason —
|
|
67
|
+
// including 'input', which the composer-footer gate below deliberately keeps. This
|
|
68
|
+
// is what stops a long, output-quiet tool turn (the bare `❯` composer is still
|
|
69
|
+
// painted, so the `❯` idle-notify pattern fires) from being mislabeled "Needs You".
|
|
70
|
+
// A genuinely idle composer lacks this footer, so real idle-notify is unaffected.
|
|
71
|
+
// Claude's per-chunk busy channel also gives this gate bounded memory: a single
|
|
72
|
+
// footer-less repaint cannot leak a false input wait between live status paints.
|
|
73
|
+
// The memory arm applies only to the non-blocking input reason; approval and
|
|
74
|
+
// choice remain positive blocking assertions and are never hidden by stale work.
|
|
75
|
+
const generation = _deps._providerGenerationGateState(session, rawTail || lastLines);
|
|
76
|
+
if (generation.activelyGenerating || generation.heldByRecentEvidence) {
|
|
77
|
+
const isBlocker = generation.activelyGenerating
|
|
78
|
+
? (d) => d.reason === 'input' || d.reason === 'approval' || d.reason === 'choice'
|
|
79
|
+
: (d) => d.reason === 'input';
|
|
80
|
+
const blockers = detections.filter(isBlocker);
|
|
81
|
+
if (blockers.length) {
|
|
82
|
+
_deps.recordSessionDiagnostic(session?.id || '', 'waiting-input-generating-gated', {
|
|
83
|
+
suppressed: blockers.map((d) => `${d.reason}:${d.source}`).join(','),
|
|
84
|
+
});
|
|
85
|
+
return detections.filter((d) => !isBlocker(d));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Negative "not at a live prompt" gate. A live approval/choice widget REPLACES
|
|
89
|
+
// the composer, so positive evidence that the agent is idle/generating at its
|
|
90
|
+
// ready prompt is decisive proof it is NOT blocked at a permission prompt or a
|
|
91
|
+
// selection menu. Two independent, provider-spanning signals:
|
|
92
|
+
// (1) `hasComposerStatusFooter` — the agent's own composer/working footer is on
|
|
93
|
+
// screen. This vocabulary is Claude-specific (esc to interrupt, shift+tab to
|
|
94
|
+
// cycle, ? for shortcuts), so on its own it does NOT cover Codex/Cursor.
|
|
95
|
+
// (2) a `finished` detection from the provider's own state detector
|
|
96
|
+
// (`_providerTurnFinishedDetection` → e.g. Claude/Codex
|
|
97
|
+
// `detectTurnFinished`, which
|
|
98
|
+
// returns false when a REAL pending widget like CODEX_PENDING_PROMPT_RE is on
|
|
99
|
+
// screen). This makes the gate provider-aware for free: a Codex/any-provider
|
|
100
|
+
// session that has repainted its ready composer suppresses the bogus banner.
|
|
101
|
+
// Without this, a session merely DISPLAYING approval-shaped prose (a coding agent's
|
|
102
|
+
// numbered to-do list, this very tool discussing approvals) raised a false
|
|
103
|
+
// "Approval needed" banner. Only the blocker reasons are gated: 'input' is the
|
|
104
|
+
// normal ready-composer idle-notify state and 'finished' is itself a positive idle
|
|
105
|
+
// signal, so both pass through.
|
|
106
|
+
const composerFooter = _deps.approvalAgent.hasComposerStatusFooter(rawTail || lastLines);
|
|
107
|
+
const turnFinished = detections.some((d) => d.reason === 'finished');
|
|
108
|
+
if (detections.some((d) => d.reason === 'approval' || d.reason === 'choice') &&
|
|
109
|
+
(composerFooter || turnFinished)) {
|
|
110
|
+
const filtered = detections.filter((d) => d.reason !== 'approval' && d.reason !== 'choice');
|
|
111
|
+
_deps.recordSessionDiagnostic(session?.id || '', 'waiting-input-composer-gated', {
|
|
112
|
+
via: composerFooter ? (turnFinished ? 'composer+finished' : 'composer') : 'finished',
|
|
113
|
+
suppressed: detections
|
|
114
|
+
.filter((d) => d.reason === 'approval' || d.reason === 'choice')
|
|
115
|
+
.map((d) => `${d.reason}:${d.source}`)
|
|
116
|
+
.join(','),
|
|
117
|
+
});
|
|
118
|
+
return filtered;
|
|
119
|
+
}
|
|
120
|
+
return detections;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function _unconfirmedPatternWait(source, liveConfirmed) {
|
|
124
|
+
return source === 'pattern' && !liveConfirmed;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function _prioritizeIdlePromptDetections(detections) {
|
|
128
|
+
const rank = (d) => {
|
|
129
|
+
if (d?.reason === 'approval') return 0;
|
|
130
|
+
if (d?.reason === 'choice') return 1;
|
|
131
|
+
if (d?.reason === 'input') return 2;
|
|
132
|
+
if (d?.reason === 'finished') return 4;
|
|
133
|
+
return 3;
|
|
134
|
+
};
|
|
135
|
+
return [...detections].sort((a, b) => rank(a) - rank(b));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function _runningEvidenceHoldUntil(sessionId, session, now = Date.now()) {
|
|
139
|
+
const holdMs = Math.max(_deps.IDLE_NOTIFY_DELAY_MS, _deps._providerRunningHoldMsForSession(session));
|
|
140
|
+
const candidates = [];
|
|
141
|
+
const st = _deps.idleNotifyState.get(sessionId);
|
|
142
|
+
if (st && st.lastSignificantOutput) candidates.push(st.lastSignificantOutput);
|
|
143
|
+
if (session && session.lastPtyActivity) candidates.push(_deps._serverObservedTimeMs(session.lastPtyActivity, now, session, 'lastPtyActivity', 'idle-notify'));
|
|
144
|
+
if (_deps._sessionCapture && typeof _deps._sessionCapture.getStatus === 'function') {
|
|
145
|
+
for (const id of [sessionId, session?._claudeSessionId].filter(Boolean)) {
|
|
146
|
+
try {
|
|
147
|
+
const projected = _deps._sessionCapture.getStatus(id);
|
|
148
|
+
if (projected && projected.status === 'running' && projected.lastActivity) {
|
|
149
|
+
candidates.push(_deps._serverObservedTimeMs(projected.lastActivity, now, session, 'captureLastActivity', 'idle-notify'));
|
|
150
|
+
}
|
|
151
|
+
} catch {}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const newest = Math.max(0, ...candidates.filter((ms) => Number.isFinite(ms) && ms > 0));
|
|
155
|
+
if (!newest) return 0;
|
|
156
|
+
return newest + holdMs;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function checkIdleNotify(sessionId, session, data, delayMs = _deps.IDLE_NOTIFY_DELAY_MS) {
|
|
160
|
+
if (!_deps.sessionPolicy(session).humanAttention) return; // worker-session-class WP-5: no human attends a headless worker
|
|
161
|
+
const hasAuthoritativeSource = _deps.telemetryReceiver.hasAuthoritativeSource(sessionId);
|
|
162
|
+
let st = _deps.idleNotifyState.get(sessionId);
|
|
163
|
+
if (!st) {
|
|
164
|
+
st = { timer: null, notified: false, reason: '', notifiedAt: 0, lastOutput: Date.now(), buf: '', freshBuf: '', _lastCheck: 0, suppressedFresh: '', suppressReplayTimer: null };
|
|
165
|
+
_deps.idleNotifyState.set(sessionId, st);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Accumulate output — cheap string concat only, no regex per-chunk
|
|
169
|
+
st.buf += data;
|
|
170
|
+
if (st.buf.length > 4096) st.buf = st.buf.slice(-3000);
|
|
171
|
+
st.freshBuf += data; // Track content since last check
|
|
172
|
+
|
|
173
|
+
st.lastOutput = Date.now();
|
|
174
|
+
|
|
175
|
+
// Throttle the expensive work: only process every 500ms instead of per-chunk
|
|
176
|
+
const now = Date.now();
|
|
177
|
+
if (now - st._lastCheck < 500) return;
|
|
178
|
+
st._lastCheck = now;
|
|
179
|
+
|
|
180
|
+
// Only reset notified flag if FRESH output (since last check) has substantial content.
|
|
181
|
+
// Strip comprehensively (CSI, OSC, charset, control). Check for word characters
|
|
182
|
+
// (letters/digits) to distinguish real text from TUI spinner glyphs (✢✳✶✻·⠂).
|
|
183
|
+
const freshChunk = st.freshBuf;
|
|
184
|
+
const freshStripped = _deps.stripAnsi(freshChunk).trim();
|
|
185
|
+
st.freshBuf = ''; // Reset for next interval
|
|
186
|
+
// Tab activation / resize / reflow makes the agent's TUI repaint a full frame,
|
|
187
|
+
// and the deferred-restore replay does the same. That redraw is NOT fresh agent
|
|
188
|
+
// activity, so it must not bump significant-output bookkeeping or (below) reset a
|
|
189
|
+
// waiting session — the exact false Idle/Needs-You → Running flip seen on click.
|
|
190
|
+
// Honor the same UI-refresh / restore suppression the main PTY data handler
|
|
191
|
+
// already applies (genuine work is still caught via the busy-status path).
|
|
192
|
+
const refreshSuppressed = _deps._suppressCtmUiRefreshActivity(session) ||
|
|
193
|
+
_deps.restoreRuntime.restoreActivitySuppressed(session, now);
|
|
194
|
+
const wordsPresent = _deps._isActivePtyChunk(session, freshChunk) &&
|
|
195
|
+
!_deps._isStatusOnlyPtyChunk(session, freshChunk) &&
|
|
196
|
+
/\w/.test(freshStripped) &&
|
|
197
|
+
freshStripped.length > 5;
|
|
198
|
+
const hasWords = !refreshSuppressed && wordsPresent;
|
|
199
|
+
// The window swallowed real content — arm the once-only replay so this text still
|
|
200
|
+
// gets a detection pass when the suppression window closes.
|
|
201
|
+
if (refreshSuppressed && wordsPresent) {
|
|
202
|
+
_deps._suppressionReplay.armPromptReplay(sessionId, session, st, freshChunk);
|
|
203
|
+
}
|
|
204
|
+
if (hasWords) {
|
|
205
|
+
st.lastSignificantOutput = now;
|
|
206
|
+
if (session?._activeTurnOpen && !_deps.statusRuntime.viewerProvoked(session, now)) _deps._markServerSessionTurnEvidence(session, now, 'terminal-output', { ledger: false });
|
|
207
|
+
}
|
|
208
|
+
// Authority inversion: when telemetry/hooks own this session, generic word
|
|
209
|
+
// output may not clear a waiting state into Running — the structured source
|
|
210
|
+
// (codex user_prompt/tool_decision, claude start hook) or the strict
|
|
211
|
+
// busy-status line does that. Without a structured source, words remain the
|
|
212
|
+
// unstick signal.
|
|
213
|
+
if (hasWords && st.notified && !_deps.statusRuntime.viewerProvoked(session, now) && !_deps._statusBindings.keepBlockingWait(session) && _deps._wordsMayUnstickWait(session, now, hasAuthoritativeSource)) { // F-B: viewer-provoked words never clear a wait
|
|
214
|
+
const hasUnsubmittedWaitingInput = !!(session?._waitingForInput &&
|
|
215
|
+
session._lastNonResolvingWaitingInputAt &&
|
|
216
|
+
(!session._lastWaitingResolveInputAt ||
|
|
217
|
+
session._lastNonResolvingWaitingInputAt > session._lastWaitingResolveInputAt));
|
|
218
|
+
if (!hasUnsubmittedWaitingInput) {
|
|
219
|
+
st.notified = false;
|
|
220
|
+
st.reason = '';
|
|
221
|
+
st.notifiedAt = 0;
|
|
222
|
+
if (session) {
|
|
223
|
+
_deps._recordWaitCleared(session, 'terminal-output');
|
|
224
|
+
session._waitingForInput = false;
|
|
225
|
+
session._waitingForInputLiveConfirmed = null;
|
|
226
|
+
session._waitingForInputReason = '';
|
|
227
|
+
session._waitingForInputMessage = '';
|
|
228
|
+
session._waitingForInputAt = 0;
|
|
229
|
+
}
|
|
230
|
+
// Tell clients this session is no longer idle — clears _waitingForInput
|
|
231
|
+
_deps.broadcastToAll({ type: 'session-resumed', id: sessionId });
|
|
232
|
+
// If a provider hook missed the next start transition, real terminal
|
|
233
|
+
// output is enough to unstick the sidebar until the hook catches up.
|
|
234
|
+
if (hasAuthoritativeSource) {
|
|
235
|
+
_deps.broadcastToAll({ type: 'session.status', id: sessionId, working: true, source: 'terminal-output', timestamp: Date.now() });
|
|
236
|
+
}
|
|
237
|
+
_deps.recordSessionDiagnostic(sessionId, 'status-running', { source: 'terminal-output', reason: 'significant-output' });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Only reset the idle timer when significant output arrives.
|
|
242
|
+
// Spinner noise should NOT reset — let the existing countdown continue.
|
|
243
|
+
if (hasWords) {
|
|
244
|
+
if (st.timer) { clearTimeout(st.timer); st.timer = null; }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Set timer if none is running — after IDLE_NOTIFY_DELAY_MS of no significant output,
|
|
248
|
+
// check if we're at a prompt marker.
|
|
249
|
+
function armIdlePromptTimer(delayMs) {
|
|
250
|
+
st.timer = setTimeout(async () => {
|
|
251
|
+
st.timer = null;
|
|
252
|
+
// Waiting-input state must be based on the current terminal viewport, not
|
|
253
|
+
// on the rolling PTY text buffer. The rolling buffer can contain old
|
|
254
|
+
// approval widgets that were already handled, which caused stale
|
|
255
|
+
// "Do you want to proceed?" prompts to reappear as fresh user blockers.
|
|
256
|
+
// No viewport, no evidence: record nothing and say so (the rolling PTY buffer is historical, never judged as the screen).
|
|
257
|
+
const viewportRead = await _deps._getHeadlessViewportRead(sessionId);
|
|
258
|
+
if (!viewportRead.ok) {
|
|
259
|
+
// D-5: one re-arm 1 s later (the trigger of a card that just painted must not be lost to one slow read); a second failure records.
|
|
260
|
+
if (!st.readRetried) { st.readRetried = true; armIdlePromptTimer(1000); return; }
|
|
261
|
+
st.readRetried = false;
|
|
262
|
+
_deps.recordSessionDiagnostic(sessionId, 'viewport-read-failed', { source: 'idle-settle', reason: viewportRead.reason || 'unknown' });
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
st.readRetried = false;
|
|
266
|
+
const waitingSource = viewportRead.text;
|
|
267
|
+
// Background-agent evidence: VIEWPORT only (a raw chunk can carry replayed scrollback).
|
|
268
|
+
if (!_deps._suppressCtmUiRefreshActivity(session) && !_deps.restoreRuntime.restoreActivitySuppressed(session, Date.now())) {
|
|
269
|
+
_deps._markBackgroundAgentsEvidence(session, waitingSource, Date.now());
|
|
270
|
+
}
|
|
271
|
+
const clean = _deps.stripAnsi(waitingSource);
|
|
272
|
+
// Get last non-empty lines
|
|
273
|
+
const lines = clean.split('\n').filter(l => l.trim().length > 0);
|
|
274
|
+
const lastLines = lines.slice(-8).join('\n');
|
|
275
|
+
|
|
276
|
+
// Plan-card convergence (secondary detector + clear-when-gone). The shadow
|
|
277
|
+
// approver is the primary, output-driven detector; this output-quiet pass
|
|
278
|
+
// catches what it missed and, crucially, CLEARS the plan Needs-You/render
|
|
279
|
+
// state once the card leaves the viewport. Judged against the AUTHORITATIVE
|
|
280
|
+
// viewport (`clean`), and short-circuits the generic detection loop so it
|
|
281
|
+
// can't clobber the 'plan' wait reason with a generic 'input'/'finished'.
|
|
282
|
+
if (session && typeof session._planCardOnDetect === 'function') {
|
|
283
|
+
const card = _deps._selectionCardFpForSession(session, clean);
|
|
284
|
+
if (card.fp) {
|
|
285
|
+
// Render convergence for ANY card type (plan / AskUserQuestion / permission).
|
|
286
|
+
session._planCardOnDetect(card.fp, card.reason);
|
|
287
|
+
// Only the plan card's Needs-You is owned by convergence, so only it short-circuits
|
|
288
|
+
// the generic loop. A choice/approval card FALLS THROUGH so the canonical reconcile
|
|
289
|
+
// keeps owning its banner exactly as before (render-only generalization).
|
|
290
|
+
if (card.reason === 'plan') return;
|
|
291
|
+
} else if (session._planCardPending) {
|
|
292
|
+
session._clearPlanDecisionPending('card-gone');
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const detections = _prioritizeIdlePromptDetections(_idlePromptDetections(session, lastLines, waitingSource));
|
|
297
|
+
// Active-generation clear for a stale non-blocking 'input' wait. The gate in
|
|
298
|
+
// _idlePromptDetections suppresses NEW 'input' detections while the agent is
|
|
299
|
+
// generating, but it cannot clear an 'input' _waitingForInput that an EARLIER
|
|
300
|
+
// output-quiet window already set. The word-output clear path (the hasWords
|
|
301
|
+
// branch above) is the only other clear, and a long status-only turn — a
|
|
302
|
+
// "Wrangling… esc to interrupt" spinner, or a backgrounded sub-agent painting
|
|
303
|
+
// "Waiting for N background agents…" — emits no words, so the stale flag sticks
|
|
304
|
+
// for the whole turn. Because _isServerWaitingForInput then feeds the phase
|
|
305
|
+
// projection a needs_you condition (strength 5) that outranks the running spine
|
|
306
|
+
// (strength 3), the session reads "Needs You" for minutes while it is plainly
|
|
307
|
+
// working. So once we POSITIVELY confirm generation, clear it here. This mirrors
|
|
308
|
+
// reconcileSessionWaitState's _clearWaitCard('actively-generating', …) for the
|
|
309
|
+
// choice/approval cards it owns. Only the non-blocking 'input' reason is cleared;
|
|
310
|
+
// real approval/choice/plan blockers (a live widget REPLACES the footer, so it is
|
|
311
|
+
// never "generating") are owned by reconcile and left untouched.
|
|
312
|
+
if (session && session._waitingForInput &&
|
|
313
|
+
String(session._waitingForInputReason || '') === 'input' &&
|
|
314
|
+
_deps._providerActivelyGenerating(session, waitingSource)) {
|
|
315
|
+
_deps._clearServerWaitingForInput(sessionId, session, st);
|
|
316
|
+
_deps.broadcastToAll({ type: 'session-resumed', id: sessionId });
|
|
317
|
+
_deps.recordSessionDiagnostic(sessionId, 'waiting-cleared-generating', { reason: 'input', source: 'idle-settle' });
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// Approval/choice cards have ONE owner: the canonical reconcile. Routing the
|
|
321
|
+
// output-quiet trigger through it (instead of the old edge-emit below) keeps
|
|
322
|
+
// the card idempotent and consistent with the warm tick + restart. The warm
|
|
323
|
+
// tick is the safety net for prompts this idle detector misses entirely.
|
|
324
|
+
if (detections.some((d) => d.reason === 'approval' || d.reason === 'choice')) {
|
|
325
|
+
await _deps.reconcileSessionWaitState(sessionId);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
for (const detection of detections) {
|
|
329
|
+
const { reason, source } = detection;
|
|
330
|
+
if (reason === 'input') {
|
|
331
|
+
const deferUntil = _runningEvidenceHoldUntil(sessionId, session, Date.now());
|
|
332
|
+
if (deferUntil > Date.now()) {
|
|
333
|
+
armIdlePromptTimer(Math.max(250, Math.min(_deps.IDLE_NOTIFY_DELAY_MS, deferUntil - Date.now() + 50)));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Approval prompts are first-class and may be handled by the
|
|
338
|
+
// auto-approver. Generic numbered choice menus are different: they
|
|
339
|
+
// need user input, but are not approvals and must not be suppressed
|
|
340
|
+
// just because the approval detector correctly returns "not approval".
|
|
341
|
+
if (reason === 'approval') {
|
|
342
|
+
const buf = _deps.autoApprovalBuffers.get(sessionId);
|
|
343
|
+
if (buf && !buf.reviewing && !buf._workerPending) {
|
|
344
|
+
buf._workerPending = true;
|
|
345
|
+
const result = await _deps._recheckHeadlessApprovalPrompt(sessionId);
|
|
346
|
+
if (!result.hasApproval) {
|
|
347
|
+
if (_deps.autoApprovalBuffers.get(sessionId) === buf) buf._workerPending = false;
|
|
348
|
+
_deps.recordSessionDiagnostic(sessionId, 'stale-waiting-input-suppressed', {
|
|
349
|
+
source: 'terminal-prompt',
|
|
350
|
+
reason,
|
|
351
|
+
rawDetected: !!result.rawDetected,
|
|
352
|
+
gateReason: result.gateReason || '',
|
|
353
|
+
snippet: lastLines.trim().split('\n').slice(-3).join('\n').slice(0, 200),
|
|
354
|
+
});
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
// The recheck result is also delivered to the shared approver
|
|
358
|
+
// handler, which owns waiting_input transitions for real approval
|
|
359
|
+
// widgets. Do not duplicate that state change here.
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (reason === 'finished') {
|
|
365
|
+
// Positive "agent returned to its ready prompt" signal (e.g. Codex's
|
|
366
|
+
// idle composer with no Working… line). Close the active turn so the
|
|
367
|
+
// session settles to Idle rather than riding the long open-turn hold.
|
|
368
|
+
// This is NOT a user blocker — do not set _waitingForInput.
|
|
369
|
+
const busyNow = _deps._providerActivelyGenerating(session, waitingSource); // gated on the LEDGER (R-3/W-4/D-2): composerMayClose
|
|
370
|
+
if (_deps._composerMayClose(session, Date.now(), busyNow)) {
|
|
371
|
+
_deps._markServerSessionTurnClosed(session, Date.now(), source || 'ready-composer', { kind: _deps.STATUS_EVIDENCE.AGENT_READY_COMPOSER });
|
|
372
|
+
_deps._markTerminalLifecycleChanged(session, 'turn-finished');
|
|
373
|
+
_deps.recordSessionDiagnostic(sessionId, 'status-idle', {
|
|
374
|
+
source: source || 'ready-composer',
|
|
375
|
+
snippet: lastLines.trim().split('\n').slice(-3).join('\n').slice(0, 200),
|
|
376
|
+
});
|
|
377
|
+
_deps.broadcastToAll({ type: 'session.status', id: sessionId, working: false, source: 'terminal-idle', timestamp: Date.now() });
|
|
378
|
+
// The turn just settled to its idle prompt — force a clean final
|
|
379
|
+
// render (SIGWINCH repaint + authoritative snapshot to all clients)
|
|
380
|
+
// so the browser never sticks on a stale mid-repaint frame. Provider-
|
|
381
|
+
// agnostic: both Claude and Codex 'finished' detections route here.
|
|
382
|
+
if (typeof session._forceCleanFinalRenderOnIdle === 'function') {
|
|
383
|
+
session._forceCleanFinalRenderOnIdle(sessionId, source || 'ready-composer');
|
|
384
|
+
}
|
|
385
|
+
} else if (_deps._statusBindings.composerRetryMs(session, Date.now(), busyNow) > 0) {
|
|
386
|
+
armIdlePromptTimer(_deps._statusBindings.composerRetryMs(session, Date.now(), busyNow)); // N-2: only the W-4 age rule said no
|
|
387
|
+
}
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
if (!st.notified) {
|
|
391
|
+
st.notified = true;
|
|
392
|
+
const waitingAt = Date.now();
|
|
393
|
+
const providerId = session?._providerId || _deps._providerIdFromCmd(session?.cmd || '');
|
|
394
|
+
// Compute prompt authority before mutating liveness. An unconfirmed
|
|
395
|
+
// pattern wait is visible to the user, but cannot erase the open-turn
|
|
396
|
+
// and busy evidence that would disprove it on the next heartbeat.
|
|
397
|
+
const liveConfirmed = source === 'terminal-choice'
|
|
398
|
+
|| _deps.isSessionAtLivePrompt(providerId, waitingSource).live;
|
|
399
|
+
const unconfirmedPattern = _unconfirmedPatternWait(source, liveConfirmed);
|
|
400
|
+
st.reason = reason;
|
|
401
|
+
st.notifiedAt = waitingAt;
|
|
402
|
+
if (session) {
|
|
403
|
+
// D-14: an idle composer of a lease-only provider is no wait: the ledger reads it as a ready composer below.
|
|
404
|
+
if (!(reason === 'input' && _deps._statusBindings.inputWaitIsIdle(session))) {
|
|
405
|
+
session._waitingForInput = true;
|
|
406
|
+
session._waitingForInputLiveConfirmed = liveConfirmed;
|
|
407
|
+
session._waitingForInputReason = reason;
|
|
408
|
+
session._waitingForInputAt = waitingAt;
|
|
409
|
+
session._lastNonResolvingWaitingInputAt = 0;
|
|
410
|
+
session._lastWaitingResolveInputAt = 0;
|
|
411
|
+
}
|
|
412
|
+
if (!unconfirmedPattern) {
|
|
413
|
+
session._lastBusyStatusAt = 0;
|
|
414
|
+
session._lastBusyStatusSource = reason ? `waiting:${reason}` : 'waiting';
|
|
415
|
+
_deps._markServerSessionTurnClosed(session, waitingAt, `waiting:${reason || 'input'}`);
|
|
416
|
+
} else {
|
|
417
|
+
_deps.recordSessionDiagnostic(sessionId, 'waiting-input-leak-veto', {
|
|
418
|
+
source,
|
|
419
|
+
reason,
|
|
420
|
+
preservedOpenTurn: session._activeTurnOpen === true,
|
|
421
|
+
preservedBusyEvidence: Number(session._lastBusyStatusAt || 0) > 0,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
_deps._markTerminalLifecycleChanged(session, `waiting-for-input:${reason}`);
|
|
425
|
+
}
|
|
426
|
+
// Provider hooks are useful, but a visible prompt is stronger evidence
|
|
427
|
+
// than a stale "working" hook that never received its stop event.
|
|
428
|
+
if (hasAuthoritativeSource) {
|
|
429
|
+
_deps.broadcastToAll({ type: 'session.status', id: sessionId, working: false, source: 'terminal-prompt', timestamp: Date.now() });
|
|
430
|
+
}
|
|
431
|
+
const promptSnippet = lastLines.trim().split('\n').slice(-3).join('\n').slice(0, 200);
|
|
432
|
+
// Banner label = the actual command/prompt, NOT the session title and NOT
|
|
433
|
+
// the menu/box-drawing junk at the bottom of the widget. For approvals we
|
|
434
|
+
// reuse the auto-approver's own parser (escalationCommandParts) to surface
|
|
435
|
+
// the real command (e.g. the Bash command). Falls back to a junk-filtered
|
|
436
|
+
// prompt line, then the title, so the label is never empty or a bare divider.
|
|
437
|
+
// The fixed-size headless grid can clip a tall command box; pass the wider
|
|
438
|
+
// rolling PTY buffer (ANSI-stripped) so the label can recover the command.
|
|
439
|
+
const labelBuffer = _deps.stripAnsi(String(st.buf || '').slice(-8000));
|
|
440
|
+
const derivedPromptLabel = _deps._deriveApprovalBannerLabel(providerId, clean, lines, reason, labelBuffer) || '';
|
|
441
|
+
const promptLabel = derivedPromptLabel || session.title || session.label || '';
|
|
442
|
+
// Stable per-prompt fingerprint so a user-dismissed false banner stays
|
|
443
|
+
// dismissed until the on-screen prompt actually changes (client compares the
|
|
444
|
+
// incoming fingerprint against the one it dismissed).
|
|
445
|
+
const promptFingerprint = detection.fingerprint || ('snip:' + promptLabel);
|
|
446
|
+
// Only a positive, anchored widget confirms a LIVE prompt the Approve/Deny
|
|
447
|
+
// buttons may act on (they inject '1'/Esc keystrokes): a highlighted
|
|
448
|
+
// terminal-choice menu, or the provider state detector's authoritative
|
|
449
|
+
// isSessionAtLivePrompt. A bare global-pattern match over the whole rendered
|
|
450
|
+
// tail is not trustworthy enough to inject a keystroke, so the client shows
|
|
451
|
+
// it Review-only.
|
|
452
|
+
_deps.recordSessionDiagnostic(sessionId, 'status-waiting', {
|
|
453
|
+
source: source || 'terminal-prompt',
|
|
454
|
+
reason,
|
|
455
|
+
liveConfirmed,
|
|
456
|
+
snippet: promptSnippet,
|
|
457
|
+
});
|
|
458
|
+
if (session) session._waitingForInputMessage = derivedPromptLabel;
|
|
459
|
+
_deps.broadcastToAll({
|
|
460
|
+
type: 'waiting-for-input',
|
|
461
|
+
id: sessionId,
|
|
462
|
+
reason,
|
|
463
|
+
label: promptLabel,
|
|
464
|
+
snippet: promptSnippet,
|
|
465
|
+
fingerprint: promptFingerprint,
|
|
466
|
+
liveConfirmed,
|
|
467
|
+
timestamp: waitingAt,
|
|
468
|
+
});
|
|
469
|
+
_deps.dispatchMobileNotification(_deps.mobileNotifications.notifyWaitingInput({
|
|
470
|
+
sessionId,
|
|
471
|
+
source: 'server-waiting-for-input',
|
|
472
|
+
createdAt: waitingAt,
|
|
473
|
+
privatePreview: lastLines.trim().split('\n').slice(-1).join(' ').slice(0, 64),
|
|
474
|
+
}));
|
|
475
|
+
}
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
}, Math.max(0, Number(delayMs) || 0));
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (!st.timer) armIdlePromptTimer(delayMs);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
module.exports = {
|
|
485
|
+
configure,
|
|
486
|
+
_idlePromptDetections,
|
|
487
|
+
_unconfirmedPatternWait,
|
|
488
|
+
_prioritizeIdlePromptDetections,
|
|
489
|
+
_runningEvidenceHoldUntil,
|
|
490
|
+
checkIdleNotify,
|
|
491
|
+
};
|
|
@@ -64,6 +64,14 @@ const INSTANCE_ID_COLUMN_MANIFEST = [
|
|
|
64
64
|
},
|
|
65
65
|
|
|
66
66
|
// --- provenance: historical, never restamped ---
|
|
67
|
+
{
|
|
68
|
+
table: 'conversation_item_clock', column: 'origin_instance_id', classification: 'provenance',
|
|
69
|
+
note: 'shared-memory WP-5 (migration v61): the machine that authored a conversation item — the replica feed addresses a change by (origin, seq), so it must never be restamped.',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
table: 'conversation_vv', column: 'origin_instance_id', classification: 'provenance',
|
|
73
|
+
note: 'shared-memory WP-5 (migration v61): per-origin version vector key — one row per authoring machine; never restamped.',
|
|
74
|
+
},
|
|
67
75
|
{
|
|
68
76
|
table: 'ctm_sessions', column: 'origin_instance_id', classification: 'provenance',
|
|
69
77
|
note: 'Historical: which instance a session was originally created on. Documented at db.js ~line 1234.',
|
|
@@ -108,9 +108,13 @@ function buildInstanceManifest(options = {}) {
|
|
|
108
108
|
// name; favorite/hidden ride the manifest as booleans so every primary reads the same values.
|
|
109
109
|
const machineSelf = options.machineSelf && typeof options.machineSelf === 'object' ? options.machineSelf : null;
|
|
110
110
|
const selfDisplayName = _limitedString(machineSelf && machineSelf.displayName, '');
|
|
111
|
+
// The unset default is the box's hostname (mDNS `.local` dropped), never a relative label: a hub
|
|
112
|
+
// shows this name on every remote session's chip, and a literal "Local CTM" from each box made
|
|
113
|
+
// every pooled machine read as this one.
|
|
114
|
+
const hostLabel = hostname === 'unknown-host' ? 'Local CTM' : hostname.replace(/\.local$/i, '');
|
|
111
115
|
const displayName = selfDisplayName || _limitedString(
|
|
112
116
|
env.CTM_EXECUTION_HOST_DISPLAY_NAME || env.CTM_INSTANCE_DISPLAY_NAME,
|
|
113
|
-
executionHostKind === 'hosted' ? hostname :
|
|
117
|
+
executionHostKind === 'hosted' ? hostname : hostLabel
|
|
114
118
|
);
|
|
115
119
|
const deploymentMode = _deploymentMode(env, executionHostKind);
|
|
116
120
|
const serviceManager = _serviceManager(env);
|
|
@@ -52,6 +52,17 @@ function _phaseEnabledBySchema(hybridEnabled, hasOwnership, hasOutbox) {
|
|
|
52
52
|
return hybridEnabled && hasOwnership && hasOutbox;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// The v2 memory round's last report, wherever the worker keeps it: the peers loop records it
|
|
56
|
+
// under lastResult.machineProbe, the machines-only loop under machines (both are the
|
|
57
|
+
// _sweepMachines result). null when no sweep has reached a machine yet.
|
|
58
|
+
function _brainSyncFromWorker(worker) {
|
|
59
|
+
const probe = worker.lastResult && worker.lastResult.machineProbe;
|
|
60
|
+
if (probe && probe.brainSync && typeof probe.brainSync === 'object') return probe.brainSync;
|
|
61
|
+
const machines = worker.machines;
|
|
62
|
+
if (machines && machines.brainSync && typeof machines.brainSync === 'object') return machines.brainSync;
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
function buildInstanceSyncStatus(options = {}) {
|
|
56
67
|
const env = options.env || process.env;
|
|
57
68
|
const manifest = options.manifest || {};
|
|
@@ -134,14 +145,13 @@ function buildInstanceSyncStatus(options = {}) {
|
|
|
134
145
|
// {peer, lastAttemptAt, lastOkAt, lastDeliveredSeq, lastError}.
|
|
135
146
|
pull: Array.isArray(worker.lastResult && worker.lastResult.results) ? worker.lastResult.results : [],
|
|
136
147
|
push: Array.isArray(worker.push) ? worker.push : [],
|
|
137
|
-
// WP-
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
brainPrune: worker.brainPrune && typeof worker.brainPrune === 'object' ? worker.brainPrune : null,
|
|
148
|
+
// WP-3 §6.6 + WP-6 (§11): the v2 memory round (lib/memory-sync.js runBrainMemberRound,
|
|
149
|
+
// driven by the machine-registry sweep) is the ONLY brain transport left — the v1
|
|
150
|
+
// outbox pair and its local prune were retired with migration 104. The round's report
|
|
151
|
+
// ({ok, members:[...]}) rides the sweep result: `lastResult.machineProbe.brainSync` in
|
|
152
|
+
// the peers loop, `machines.brainSync` in the machines-only loop. null before the first
|
|
153
|
+
// tick that reached a machine.
|
|
154
|
+
brainSync: _brainSyncFromWorker(worker),
|
|
145
155
|
},
|
|
146
156
|
// S-30 (WP-0, remote-machine-hub-sessions-2026-10-22.html): the machine registry's rollup —
|
|
147
157
|
// how many boxes this hub knows and where they stand. The CALLER supplies it
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
To integrate finished work: commit on your branch, then run land submit and report its job id; never merge or fast-forward <target> yourself. Do not merge <target> into your branch to land it; merge only when land submit or the queue reports a conflict.
|