create-walle 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- 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 +6 -4
- 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 +10 -22
- package/template/coding-task-manager/bin/claude-hook.js +7 -3
- package/template/coding-task-manager/bin/claude-table-parity.js +307 -0
- package/template/coding-task-manager/bin/conversation-storage-auto-migration-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-generation-evidence.js +9 -2
- package/template/coding-task-manager/bin/conversation-storage-service-entry-lib.js +16 -1
- package/template/coding-task-manager/bin/conversation-storage-walle-owner.js +247 -0
- package/template/coding-task-manager/bin/ctm-machine-pair.js +160 -0
- package/template/coding-task-manager/bin/lead-wait-census.js +1348 -0
- package/template/coding-task-manager/bin/repair-foreign-clone.js +564 -0
- package/template/coding-task-manager/bin/repair-resume-echo-titles.js +248 -0
- package/template/coding-task-manager/bin/write-lock-bench.js +111 -0
- package/template/coding-task-manager/db.js +705 -286
- package/template/coding-task-manager/git-utils.js +44 -0
- package/template/coding-task-manager/lib/adopted-host-redial.js +4 -0
- package/template/coding-task-manager/lib/agent-presets.js +15 -0
- package/template/coding-task-manager/lib/agent-title-apply.js +88 -0
- package/template/coding-task-manager/lib/agent-title-backfill-read.js +92 -0
- package/template/coding-task-manager/lib/api/host-stats.js +98 -0
- package/template/coding-task-manager/lib/api/ingress.js +35 -12
- package/template/coding-task-manager/lib/api/machine-pairing.js +285 -0
- package/template/coding-task-manager/lib/api/machine-pool.js +307 -0
- package/template/coding-task-manager/lib/api/machines.js +461 -0
- package/template/coding-task-manager/lib/api/misc-ops.js +20 -5
- package/template/coding-task-manager/lib/api/providers.js +53 -6
- package/template/coding-task-manager/lib/api/resume-from-store.js +25 -0
- package/template/coding-task-manager/lib/api/sessions.js +160 -8
- package/template/coding-task-manager/lib/api/transcript-history.js +17 -4
- package/template/coding-task-manager/lib/api/worktrees.js +38 -37
- package/template/coding-task-manager/lib/approval-drift.js +16 -1
- package/template/coding-task-manager/lib/approval-logical-frame.js +5 -1
- package/template/coding-task-manager/lib/approval-scope.js +68 -4
- package/template/coding-task-manager/lib/auth-context.js +32 -2
- package/template/coding-task-manager/lib/auth-rate-limit.js +41 -1
- package/template/coding-task-manager/lib/auth-rules.js +186 -45
- package/template/coding-task-manager/lib/broadcast-serialize.js +2 -1
- package/template/coding-task-manager/lib/browser-session-broker.js +9 -1
- package/template/coding-task-manager/lib/browser-use-adapter.js +33 -2
- package/template/coding-task-manager/lib/claude-markdown-ansi.js +27 -85
- package/template/coding-task-manager/lib/claude-session-title.js +6 -30
- package/template/coding-task-manager/lib/claude-table-layout.js +322 -0
- package/template/coding-task-manager/lib/client-diag-handler.js +5 -0
- package/template/coding-task-manager/lib/codex-config-guard.js +33 -3
- package/template/coding-task-manager/lib/codex-harness-qualification.js +12 -0
- package/template/coding-task-manager/lib/codex-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/coding-agent-models.js +21 -30
- package/template/coding-task-manager/lib/coding-session-model-adapters.js +27 -2
- package/template/coding-task-manager/lib/coding-session-model-projection.js +5 -0
- package/template/coding-task-manager/lib/coding-session-model-runtime.js +1 -2
- package/template/coding-task-manager/lib/coding-session-model-state.js +10 -0
- package/template/coding-task-manager/lib/coding-session-model-sync-state.js +0 -1
- package/template/coding-task-manager/lib/conversation-import/cursor-guard-owner.js +10 -0
- package/template/coding-task-manager/lib/create/resolve-launch-params.js +8 -1
- package/template/coding-task-manager/lib/ctm-boot-lifecycle.js +17 -1
- package/template/coding-task-manager/lib/db-domain-tables.js +7 -0
- package/template/coding-task-manager/lib/db-domains.js +21 -2
- package/template/coding-task-manager/lib/db-owner-op-registry.js +7 -0
- package/template/coding-task-manager/lib/db-schema-source-files.js +1 -0
- package/template/coding-task-manager/lib/feature-manifest.js +1 -1
- package/template/coding-task-manager/lib/fs-watcher.js +3 -2
- package/template/coding-task-manager/lib/harness-history-transition.js +3 -3
- 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 +55 -17
- package/template/coding-task-manager/lib/host-control-dial.js +167 -0
- package/template/coding-task-manager/lib/host-handoff-orchestrator.js +16 -2
- package/template/coding-task-manager/lib/host-handoff.js +51 -13
- package/template/coding-task-manager/lib/host-health-ledger.js +164 -12
- package/template/coding-task-manager/lib/host-self-truth-watchdog.js +4 -0
- package/template/coding-task-manager/lib/host-stats.js +328 -0
- package/template/coding-task-manager/lib/host-threadpool-evacuation.js +160 -0
- package/template/coding-task-manager/lib/host-threadpool-monitor.js +14 -1
- package/template/coding-task-manager/lib/hosted-input-dispatch.js +203 -0
- package/template/coding-task-manager/lib/hosted-sync-worker.js +113 -5
- package/template/coding-task-manager/lib/instance-id-ownership-manifest.js +4 -0
- package/template/coding-task-manager/lib/instance-manifest-runtime.js +3 -0
- package/template/coding-task-manager/lib/instance-manifest.js +13 -1
- package/template/coding-task-manager/lib/instance-sync-status.js +15 -0
- package/template/coding-task-manager/lib/launch-model-override.js +160 -1
- package/template/coding-task-manager/lib/launch-plan-worker.js +59 -2
- package/template/coding-task-manager/lib/lead-model-switch-runtime.js +57 -4
- package/template/coding-task-manager/lib/lead-model-switch.js +3 -2
- package/template/coding-task-manager/lib/lead-model-transition-store.js +61 -3
- package/template/coding-task-manager/lib/legacy-draft-cancellation-recovery.js +111 -0
- package/template/coding-task-manager/lib/login-tripwire.js +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 +749 -0
- package/template/coding-task-manager/lib/machine-self.js +66 -0
- package/template/coding-task-manager/lib/main-thread-lint-exemptions.json +52 -4
- package/template/coding-task-manager/lib/media-journal-control-reader.js +473 -0
- package/template/coding-task-manager/lib/media-journal.js +84 -27
- package/template/coding-task-manager/lib/media-store-options.js +43 -15
- package/template/coding-task-manager/lib/migrations/v56-host-samples-and-machine-pool.js +76 -0
- package/template/coding-task-manager/lib/mirror-feed-sanitize.js +12 -3
- package/template/coding-task-manager/lib/model-proxy/anthropic-face.js +4 -0
- package/template/coding-task-manager/lib/model-proxy/chat-response-translators.js +3 -0
- package/template/coding-task-manager/lib/model-proxy/handoff.js +494 -0
- package/template/coding-task-manager/lib/model-proxy/lead-worker-picks.js +25 -0
- package/template/coding-task-manager/lib/model-proxy/native-lead-listener.js +61 -7
- package/template/coding-task-manager/lib/model-proxy/proxy-cli.js +200 -0
- package/template/coding-task-manager/lib/model-proxy/proxy-instance-record.js +257 -0
- package/template/coding-task-manager/lib/model-proxy/stream-accounting.js +205 -0
- package/template/coding-task-manager/lib/model-proxy/tokens.js +78 -0
- package/template/coding-task-manager/lib/model-proxy/upstream-outcome.js +9 -0
- package/template/coding-task-manager/lib/native-history-control.js +2 -2
- package/template/coding-task-manager/lib/native-lead-settings-client.js +2 -1
- package/template/coding-task-manager/lib/native-lead-tls.js +18 -4
- package/template/coding-task-manager/lib/oauth-proxy-supervisor.js +628 -64
- package/template/coding-task-manager/lib/owner-action-manifest-data.json +14 -0
- package/template/coding-task-manager/lib/painted-row-recorder.js +9 -1
- package/template/coding-task-manager/lib/prompt-submission-contract.js +21 -1
- package/template/coding-task-manager/lib/provider-login-broker.js +192 -9
- package/template/coding-task-manager/lib/provider-login-capture.js +153 -0
- package/template/coding-task-manager/lib/queue-draft-status-overlay.js +36 -0
- package/template/coding-task-manager/lib/raw-codex-history-window.js +5 -3
- package/template/coding-task-manager/lib/read-pool-client.js +5 -2
- package/template/coding-task-manager/lib/read-pool-op-registry.js +10 -1
- package/template/coding-task-manager/lib/recent-catalog-query.js +26 -0
- package/template/coding-task-manager/lib/recent-session-catalog-response.js +9 -0
- package/template/coding-task-manager/lib/remote-command-context.js +12 -0
- package/template/coding-task-manager/lib/remote-command-runtime.js +13 -1
- package/template/coding-task-manager/lib/remote-machine-catalog.js +1062 -0
- package/template/coding-task-manager/lib/remote-machine-create.js +693 -0
- package/template/coding-task-manager/lib/remote-machine-link.js +939 -0
- package/template/coding-task-manager/lib/remote-machine-proxy.js +520 -0
- package/template/coding-task-manager/lib/remote-session-forward.js +306 -0
- package/template/coding-task-manager/lib/remote-submission-status.js +6 -0
- package/template/coding-task-manager/lib/restart-outcome-truth.js +20 -3
- package/template/coding-task-manager/lib/restart-preflight.js +9 -2
- package/template/coding-task-manager/lib/restore-backoff-gate.js +10 -2
- package/template/coding-task-manager/lib/restore-prepare-retry.js +12 -5
- package/template/coding-task-manager/lib/restore-resume-batch.js +22 -1
- package/template/coding-task-manager/lib/resume-blocked-wire.js +62 -1
- package/template/coding-task-manager/lib/resume-cwd.js +13 -0
- package/template/coding-task-manager/lib/resume-from-store.js +12 -1
- package/template/coding-task-manager/lib/resume-origin-facts.js +38 -1
- package/template/coding-task-manager/lib/resume-preflight.js +21 -16
- package/template/coding-task-manager/lib/review-repo-admission.js +39 -6
- package/template/coding-task-manager/lib/review-repo-registry.js +17 -0
- package/template/coding-task-manager/lib/root-delivery-runtime.js +72 -15
- package/template/coding-task-manager/lib/root-delivery-selection.js +37 -1
- package/template/coding-task-manager/lib/root-prompt-admission.js +33 -2
- package/template/coding-task-manager/lib/root-prompt-flow.js +167 -33
- 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-create/codex-native-provider-gate.js +218 -0
- package/template/coding-task-manager/lib/session-create/codex-resume-exit-classify.js +52 -0
- package/template/coding-task-manager/lib/session-create/delegate-worker.js +95 -6
- package/template/coding-task-manager/lib/session-create/identity.js +20 -1
- package/template/coding-task-manager/lib/session-create/prepared.js +69 -1
- package/template/coding-task-manager/lib/session-create/provider-launch-context.js +77 -0
- package/template/coding-task-manager/lib/session-create/provider-process.js +34 -37
- package/template/coding-task-manager/lib/session-create/response.js +30 -12
- package/template/coding-task-manager/lib/session-create/transcript.js +13 -4
- package/template/coding-task-manager/lib/session-create/worker-continuation.js +43 -1
- package/template/coding-task-manager/lib/session-create/worker-notices.js +94 -5
- package/template/coding-task-manager/lib/session-create/worker-observability.js +99 -7
- package/template/coding-task-manager/lib/session-create/worker-stop.js +11 -3
- package/template/coding-task-manager/lib/session-create/worker-wait-watcher.js +315 -0
- package/template/coding-task-manager/lib/session-geometry-authority-handler.js +10 -1
- package/template/coding-task-manager/lib/session-host-manager.js +152 -206
- package/template/coding-task-manager/lib/session-jobs.js +17 -9
- package/template/coding-task-manager/lib/session-lifecycle.js +18 -0
- package/template/coding-task-manager/lib/session-model-action-preconditions.js +9 -0
- 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 +42 -3
- 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/startup-pointer-write.js +57 -0
- package/template/coding-task-manager/lib/state-sync/painted-frame-field.js +11 -0
- package/template/coding-task-manager/lib/storage/coding-session-model-store.js +21 -22
- package/template/coding-task-manager/lib/surviving-owner-bootstrap.js +7 -2
- package/template/coding-task-manager/lib/surviving-owner-recovery.js +2 -1
- package/template/coding-task-manager/lib/terminal-draft-http-status.js +25 -0
- package/template/coding-task-manager/lib/transcript-archiver.js +229 -229
- package/template/coding-task-manager/lib/transcript-frame-cache.js +12 -2
- package/template/coding-task-manager/lib/transcript-guard-job.js +55 -4
- package/template/coding-task-manager/lib/transcript-link.js +77 -0
- package/template/coding-task-manager/lib/transcript-manifest-store.js +8 -4
- package/template/coding-task-manager/lib/transcript-source.js +8 -3
- package/template/coding-task-manager/lib/transcript-store.js +40 -0
- package/template/coding-task-manager/lib/tunnel-lane-governor.js +6 -3
- package/template/coding-task-manager/lib/typing-interaction-trace.js +92 -0
- package/template/coding-task-manager/lib/typing-worker-stages.js +60 -0
- package/template/coding-task-manager/lib/visible-revision-watchdog.js +8 -12
- package/template/coding-task-manager/lib/wake-skip-reasons.js +46 -0
- package/template/coding-task-manager/lib/walle-supervisor.js +98 -14
- package/template/coding-task-manager/lib/worker-failure-classify.js +13 -1
- package/template/coding-task-manager/lib/ws/state-sync.js +19 -2
- package/template/coding-task-manager/lib/ws/terminal-attach.js +32 -1
- package/template/coding-task-manager/lib/ws-router.js +68 -1
- package/template/coding-task-manager/lib/ws-send-admission.js +22 -4
- package/template/coding-task-manager/oauth-proxy.js +99 -55
- package/template/coding-task-manager/package-lock.json +24 -0
- package/template/coding-task-manager/package.json +3 -0
- package/template/coding-task-manager/providers/codex-mcp-extract.js +121 -19
- package/template/coding-task-manager/providers/codex-mcp.js +14 -5
- package/template/coding-task-manager/public/css/app.css +279 -1
- package/template/coding-task-manager/public/css/reviews.css +4 -0
- package/template/coding-task-manager/public/index.html +294 -223
- package/template/coding-task-manager/public/js/app/machines-page.js +1252 -0
- package/template/coding-task-manager/public/js/app/models-tab.js +546 -36
- package/template/coding-task-manager/public/js/app/worktrees-panel.js +7 -5
- package/template/coding-task-manager/public/js/background-work.js +13 -7
- package/template/coding-task-manager/public/js/coding-session-model-presentation.js +44 -4
- package/template/coding-task-manager/public/js/core/session-commands.js +676 -0
- package/template/coding-task-manager/public/js/core/session-selectors.js +5 -1
- package/template/coding-task-manager/public/js/history-app-seam.js +26 -2
- package/template/coding-task-manager/public/js/history-painted-rows.js +17 -2
- package/template/coding-task-manager/public/js/history-reader-park.js +13 -1
- package/template/coding-task-manager/public/js/history-scroller.js +187 -9
- package/template/coding-task-manager/public/js/history-transcript-pages.js +5 -5
- package/template/coding-task-manager/public/js/machine-pool-shared.js +436 -0
- package/template/coding-task-manager/public/js/private-state-scope.js +31 -3
- package/template/coding-task-manager/public/js/prompt-submission-client.js +173 -8
- package/template/coding-task-manager/public/js/prompt-submission-tray.js +281 -0
- package/template/coding-task-manager/public/js/queue-panel-submission-reconcile.js +174 -1
- package/template/coding-task-manager/public/js/reviews.js +7 -3
- package/template/coding-task-manager/public/js/root-draft-lifetime.js +139 -2
- package/template/coding-task-manager/public/js/root-queue-builder-lifetime.js +16 -0
- package/template/coding-task-manager/public/js/row-join.js +4 -2
- package/template/coding-task-manager/public/js/session-model-picker.js +1 -1
- package/template/coding-task-manager/public/js/session-search-utils.js +46 -19
- package/template/coding-task-manager/public/js/state-sync-client.js +4 -0
- package/template/coding-task-manager/public/js/terminal/runtime-02.js +16 -7
- package/template/coding-task-manager/public/js/terminal/runtime-03.js +41 -0
- package/template/coding-task-manager/public/js/terminal/runtime-04.js +41 -4
- package/template/coding-task-manager/public/js/terminal/runtime-12.js +52 -2
- package/template/coding-task-manager/public/js/terminal/runtime-16.js +12 -12
- package/template/coding-task-manager/public/js/terminal/runtime-18.js +14 -0
- package/template/coding-task-manager/public/js/terminal/runtime-19.js +8 -4
- package/template/coding-task-manager/public/js/terminal/runtime-20.js +210 -73
- package/template/coding-task-manager/public/js/terminal/runtime-21.js +19 -6
- package/template/coding-task-manager/public/js/terminal/runtime-22.js +86 -0
- package/template/coding-task-manager/public/js/terminal-history-viewport.js +1 -1
- package/template/coding-task-manager/public/js/terminal-wheel.js +39 -2
- package/template/coding-task-manager/public/js/walle/chat-conversation.js +11 -3
- package/template/coding-task-manager/public/js/walle-session.js +30 -7
- package/template/coding-task-manager/public/m/app.css +226 -8
- package/template/coding-task-manager/public/m/app.js +502 -9
- package/template/coding-task-manager/public/m/index.html +38 -1
- package/template/coding-task-manager/public/m/machines.js +1313 -0
- package/template/coding-task-manager/public/m/pool-failover.js +391 -0
- package/template/coding-task-manager/public/m/private-queue-actions.js +26 -7
- package/template/coding-task-manager/public/m/sw.js +5 -0
- package/template/coding-task-manager/queue-engine.js +13 -0
- package/template/coding-task-manager/server/approvals.js +5 -6
- package/template/coding-task-manager/server/boot.js +136 -17
- package/template/coding-task-manager/server.js +902 -239
- package/template/coding-task-manager/session-integrity.js +7 -9
- package/template/coding-task-manager/workers/db-owner-worker.js +53 -7
- package/template/coding-task-manager/workers/read-pool-worker.js +17 -6
- package/template/coding-task-manager/workers/session-host-pool-process.js +18 -4
- package/template/coding-task-manager/workers/session-host-process.js +14 -3
- package/template/coding-task-manager/workers/transcript-archive-worker.js +1 -1
- package/template/coding-task-manager/workers/worktree-worker.js +34 -0
- package/template/package-lock.json +2 -2
- package/template/package.json +1 -1
- package/template/scripts/conversation-storage-v2-migration.js +78 -11
- package/template/shared/conversation-storage-v2-contract.js +42 -6
- package/template/shared/fixtures/worker-status-payloads.json +392 -0
- package/template/shared/git-remote-key.js +83 -0
- package/template/shared/host-identity.js +98 -2
- package/template/shared/owner-write-safety.js +135 -0
- package/template/shared/public-runtime.js +13 -5
- package/template/shared/release-schema.json +3 -2
- package/template/shared/report-citations.js +14 -0
- package/template/shared/sqlite-write-lock.js +361 -223
- package/template/shared/storage/contract.js +35 -3
- package/template/wall-e/agent.js +21 -0
- package/template/wall-e/api-walle.js +5 -0
- package/template/wall-e/bin/brain-purge-legacy-ctm.js +3 -2
- package/template/wall-e/bin/walle-mcp-stdio.js +12 -6
- package/template/wall-e/brain/helper-rules-schema.js +129 -0
- package/template/wall-e/brain/migrations.js +51 -22
- package/template/wall-e/brain/model-deployment-facts.js +31 -1
- package/template/wall-e/brain/owner-call-whitelist.js +16 -0
- package/template/wall-e/brain/schema-ensures.js +22 -0
- package/template/wall-e/brain.js +1 -1
- package/template/wall-e/coding/journal-dispatcher.js +51 -0
- package/template/wall-e/coding/session-journal.js +28 -40
- package/template/wall-e/coding-orchestrator.js +23 -26
- package/template/wall-e/http/auth.js +18 -1
- package/template/wall-e/http/blog-views-api.js +318 -0
- package/template/wall-e/http/helper-rules-api.js +321 -0
- package/template/wall-e/http/model-proxy-providers.js +3 -1
- package/template/wall-e/http/telemetry-api.js +12 -0
- package/template/wall-e/lib/blog-view-policy.js +88 -0
- package/template/wall-e/lib/blog-view-store.js +169 -0
- package/template/wall-e/lib/client-config-lock.js +2 -1
- package/template/wall-e/lib/coding-journal-writer-child-client.js +67 -18
- package/template/wall-e/lib/error-kinds.js +10 -1
- package/template/wall-e/lib/feature-manifest.js +1 -1
- package/template/wall-e/lib/helper-rules/cell-state.js +123 -0
- package/template/wall-e/lib/helper-rules/evaluate.js +357 -0
- package/template/wall-e/lib/helper-rules/explore-rubric.md +12 -0
- package/template/wall-e/lib/helper-rules/grade.js +277 -0
- package/template/wall-e/lib/helper-rules/label.js +247 -0
- package/template/wall-e/lib/helper-rules/lead-call-hook.js +522 -0
- package/template/wall-e/lib/helper-rules/store.js +667 -0
- package/template/wall-e/lib/mcp-integration.js +5 -6
- package/template/wall-e/lib/runtime-worker-pool.js +1 -0
- package/template/wall-e/lib/scheduler-worker-jobs.js +6 -0
- package/template/wall-e/lib/telemetry-db-schema.js +37 -0
- package/template/wall-e/lib/telemetry-process-client.js +76 -1
- package/template/wall-e/llm/default-fallback.js +4 -0
- package/template/wall-e/llm/model-catalog.js +13 -4
- package/template/wall-e/llm/model-roles.js +6 -0
- package/template/wall-e/llm/portkey-http.js +150 -0
- package/template/wall-e/llm/portkey-sync.js +15 -145
- package/template/wall-e/llm/worker-mcp-routing.js +61 -0
- package/template/wall-e/llm/worker-route.js +43 -1
- package/template/wall-e/loops/brain-custom-writes.js +45 -0
- package/template/wall-e/mcp-protocol-contract.js +41 -1
- package/template/wall-e/mcp-server.js +13 -2
- package/template/wall-e/mcp-worker-schemas.js +20 -2
- package/template/wall-e/memory/ctm-context-client.js +25 -5
- package/template/wall-e/shared/release-schema.json +3 -2
- package/template/wall-e/shared/sqlite-write-lock.js +361 -223
- package/template/wall-e/shared/storage/contract.js +35 -3
- package/template/wall-e/skills/_templates/delegate-worker/VERSION +1 -1
- package/template/wall-e/skills/_templates/delegate-worker/released-sha256.json +6 -0
- package/template/wall-e/skills/_templates/delegate-worker/templates/claude/SKILL.md +7 -2
- package/template/wall-e/skills/_templates/delegate-worker/templates/codex/SKILL.md +7 -2
- package/template/wall-e/tools/local-tools.js +6 -4
- package/template/wall-e/workers/brain-owner-worker.js +9 -0
- package/template/wall-e/workers/coding-journal-writer-child.js +8 -1
- package/template/wall-e/workers/telemetry-worker.js +8 -0
|
@@ -265,6 +265,11 @@ function _renderResumeLoadingOverlay(s) {
|
|
|
265
265
|
if (!s || !s.container) return false;
|
|
266
266
|
const overlay = s.container.querySelector('.snapshot-loading-overlay');
|
|
267
267
|
if (!overlay) return false;
|
|
268
|
+
// WP-4c (§5 OQ-4 = H-B, §8 WP-4c): the resume-blocked card shares this shell class (index.html
|
|
269
|
+
// ~3825); its copy is the CARD's, and a loading label written here is what made a stranded card
|
|
270
|
+
// read as a stuck resume. The card's renderer owns the shell until the server row's
|
|
271
|
+
// resumeBlocked:false clears the store lifecycle in onSessionsList.
|
|
272
|
+
if (_presentationStore.getSessionState(_resumeClientSessionId(s))?.lifecycle === 'resume-blocked') return false;
|
|
268
273
|
const lbl = overlay.querySelector('.snapshot-loading-text');
|
|
269
274
|
if (lbl) lbl.textContent = _resumeLoadingText(s);
|
|
270
275
|
const rs = _resumeStateForSession(s);
|
|
@@ -770,6 +775,32 @@ function _resumeBlockedAgentLabel(s, msg) {
|
|
|
770
775
|
|| 'The agent';
|
|
771
776
|
}
|
|
772
777
|
|
|
778
|
+
// D-14: the session a card is about. The label/cwd expressions are the ones the store rebuild already
|
|
779
|
+
// used (WP-6), lifted here so the identity line and the rebuild cannot drift apart.
|
|
780
|
+
function _resumeBlockedSessionLabel(s) {
|
|
781
|
+
return (s && s.meta && s.meta.title) || (s && s.title) || 'Session';
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function _resumeBlockedSessionCwd(s) {
|
|
785
|
+
return (s && s.meta && (s.meta.cwd || s.meta.projectPath || s.meta.project_path)) || (s && s.cwd) || '';
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// D-14/D-12: a folder is shown with the home prefix as `~`, so no absolute path reaches the card.
|
|
789
|
+
function _resumeBlockedFolder(cwd) {
|
|
790
|
+
return String(cwd || '').replace(/^\/(?:Users|home)\/[^/]+/, '~');
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// D-14: `{label} · {agent} · {folder} · last active {date}` — the folder and the date segments are
|
|
794
|
+
// dropped when CTM has nothing to put in them, never rendered empty.
|
|
795
|
+
function _resumeBlockedIdentity(s, msg) {
|
|
796
|
+
const parts = [_resumeBlockedSessionLabel(s), _resumeBlockedAgentLabel(s, msg)];
|
|
797
|
+
const folder = _resumeBlockedFolder(_resumeBlockedSessionCwd(s));
|
|
798
|
+
if (folder) parts.push(folder);
|
|
799
|
+
const seen = msg && msg.lastSeenAt ? new Date(msg.lastSeenAt) : null;
|
|
800
|
+
if (seen && !Number.isNaN(seen.getTime())) parts.push(`last active ${seen.toLocaleDateString()}`);
|
|
801
|
+
return parts.join(' · ');
|
|
802
|
+
}
|
|
803
|
+
|
|
773
804
|
// Leave the blocked card for the resuming cover (shared by Retry now and Resume from stored history).
|
|
774
805
|
function _enterResumingFromBlocked(s) {
|
|
775
806
|
s._resumeBlocked = false;
|
|
@@ -830,8 +861,31 @@ function _formatResumeBlockedBytes(bytes) {
|
|
|
830
861
|
return `${rounded} ${units[i]}`;
|
|
831
862
|
}
|
|
832
863
|
|
|
864
|
+
// D-13: ONE "why" sentence, built only from recorded facts, first match wins. It says what CTM knows
|
|
865
|
+
// happened; it never guesses, and it never asks the user to touch a file. Empty when nothing is known.
|
|
866
|
+
function _resumeBlockedWhy(msg, agent) {
|
|
867
|
+
const m = msg || {};
|
|
868
|
+
// ` on <date>` only when the recorded date parses: an older manifest without the key never renders "Invalid Date".
|
|
869
|
+
const on = (x) => { const t = x ? new Date(x) : null; return t && !Number.isNaN(t.getTime()) ? ` on ${t.toLocaleDateString()}` : ''; };
|
|
870
|
+
if (m.trashReason === 'archived') return `CTM's archiver moved it${on(m.trashedAt)}. CTM no longer does this.`;
|
|
871
|
+
if (m.trashReason === 'delete-session') return `It was moved to CTM's trash when this session was deleted${on(m.trashedAt)}.`;
|
|
872
|
+
if (m.localHistory === 'removed') {
|
|
873
|
+
const size = _formatResumeBlockedBytes(m.lastSeenBytes);
|
|
874
|
+
const seen = on(m.lastSeenAt);
|
|
875
|
+
return `CTM last saw it${seen || ' here'}${size ? ` (${size})` : ''}; it was removed outside CTM.`;
|
|
876
|
+
}
|
|
877
|
+
if (m.localHistory === 'never_seen') {
|
|
878
|
+
return 'CTM never saw it on this machine.'
|
|
879
|
+
+ (m.code === 'missing_codex_rollout' ? '' : ' Claude Code deletes transcripts older than its retention period, 30 days by default.');
|
|
880
|
+
}
|
|
881
|
+
return '';
|
|
882
|
+
}
|
|
883
|
+
|
|
833
884
|
// The missing-transcript card is a pure function of the facts on the message (origin,
|
|
834
885
|
// localHistory, resumeRung, storeTurns); see docs/resume-blocked-card-truth-transcript-gone-2026-10-07.html D-2.
|
|
886
|
+
// WP-3 (D-10..D-15): the RUNG picks the headline (localHistory and the trash reason only pick the "why"
|
|
887
|
+
// sentence), every missing-transcript card opens with an identity line, and no path ever reaches the
|
|
888
|
+
// title or the body — the paths live in the collapsed Details row the renderer builds.
|
|
835
889
|
function _resumeBlockedCopyForMsg(s, msg) {
|
|
836
890
|
const code = (msg && msg.code) || '';
|
|
837
891
|
const base = RESUME_BLOCKED_COPY[code];
|
|
@@ -839,8 +893,8 @@ function _resumeBlockedCopyForMsg(s, msg) {
|
|
|
839
893
|
if (!_resumeBlockedIsMissingTranscript(msg)) return base;
|
|
840
894
|
const agent = _resumeBlockedAgentLabel(s, msg);
|
|
841
895
|
const origin = msg.origin || 'unknown';
|
|
842
|
-
const lh = msg.localHistory;
|
|
843
896
|
const rung = msg.resumeRung || '';
|
|
897
|
+
const identity = _resumeBlockedIdentity(s, msg);
|
|
844
898
|
// WP-2 (multi-machine R-15): where the transcript lives, keyed on the server's `transcriptState` — a file
|
|
845
899
|
// deleted HERE and a file living on machine X are different truths and must not share a sentence. An
|
|
846
900
|
// older server (no transcriptState on the message) keeps the origin-only copy below, unchanged.
|
|
@@ -848,6 +902,7 @@ function _resumeBlockedCopyForMsg(s, msg) {
|
|
|
848
902
|
if (msg.transcriptState === 'on_other_machine') {
|
|
849
903
|
return {
|
|
850
904
|
tone: 'info',
|
|
905
|
+
identity,
|
|
851
906
|
title: `This session was created on ${host}.`,
|
|
852
907
|
body: msg.originIsPeer
|
|
853
908
|
? `Its ${agent} transcript is there. CTM copies it here once the session has exited there.`
|
|
@@ -855,55 +910,41 @@ function _resumeBlockedCopyForMsg(s, msg) {
|
|
|
855
910
|
};
|
|
856
911
|
}
|
|
857
912
|
if (msg.transcriptState === 'copy_pending') {
|
|
858
|
-
return { tone: 'info', title: `Copying this session's transcript from ${host}…`, body: 'Resume will work once the copy completes.' };
|
|
913
|
+
return { tone: 'info', identity, title: `Copying this session's transcript from ${host}…`, body: 'Resume will work once the copy completes.' };
|
|
859
914
|
}
|
|
860
915
|
if (msg.transcriptState === 'deleted_after_copy') {
|
|
861
916
|
return {
|
|
862
917
|
tone: 'info',
|
|
918
|
+
identity,
|
|
863
919
|
title: "This session's transcript was deleted from this machine.",
|
|
864
920
|
body: `It was copied here from ${host}; CTM does not know whether ${host} still has it.`,
|
|
865
921
|
};
|
|
866
922
|
}
|
|
867
923
|
if (!msg.transcriptState && origin === 'other_instance') {
|
|
868
|
-
return { tone: 'info', title: 'This session was created on another CTM instance.', body: `Its ${agent} transcript lives there.` };
|
|
869
|
-
}
|
|
870
|
-
if (lh === 'removed') {
|
|
871
|
-
const sizeText = _formatResumeBlockedBytes(msg.lastSeenBytes);
|
|
872
|
-
const dateText = msg.lastSeenAt ? new Date(msg.lastSeenAt).toLocaleString() : 'an earlier time';
|
|
873
|
-
const seenText = sizeText ? `${sizeText}, last seen ${dateText}` : `last seen ${dateText}`;
|
|
874
|
-
return {
|
|
875
|
-
tone: 'info',
|
|
876
|
-
title: "This session's transcript was deleted from this machine.",
|
|
877
|
-
body: `CTM read it here (${seenText}) and the file is gone, so ${agent} can't resume it natively.`,
|
|
878
|
-
};
|
|
924
|
+
return { tone: 'info', identity, title: 'This session was created on another CTM instance.', body: `Its ${agent} transcript lives there.` };
|
|
879
925
|
}
|
|
926
|
+
const why = _resumeBlockedWhy(msg, agent);
|
|
927
|
+
const st = msg.storeTurns || { human: 0, total: 0 };
|
|
880
928
|
if (rung === 'restore' || rung === 'trash') {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
};
|
|
929
|
+
let body = `Restore puts it back where ${agent} looks for it and resumes the session.`;
|
|
930
|
+
if (why) body += ` ${why}`;
|
|
931
|
+
if (msg.restoreError && msg.restoreError !== 'not_implemented') body += ` The last restore did not finish (${msg.restoreError}).`;
|
|
932
|
+
return { tone: 'info', identity, title: `${agent} can't find this session's transcript, but CTM kept a copy.`, body };
|
|
886
933
|
}
|
|
887
934
|
if (rung === 'store') {
|
|
888
|
-
|
|
935
|
+
const cc = String((msg.coverage && msg.coverage.storeComplete) || '');
|
|
936
|
+
const coverage = cc === 'yes' || cc === 'no' ? `, ${_resumeStoreCompleteText(cc)}` : '';
|
|
937
|
+
let body = `CTM saved ${Number(st.human) || 0} prompts (${Number(st.total) || 0} turns) of the conversation; ${agent} can start from them${coverage}.`;
|
|
938
|
+
if (why) body += ` ${why}`;
|
|
939
|
+
return { tone: 'info', identity, title: `${agent} can't find this session's transcript, and CTM has no copy of the file.`, body };
|
|
889
940
|
}
|
|
890
941
|
if (rung === '') {
|
|
891
|
-
// Unknown rung (the ladder could not answer): never the "nothing to resume" copy.
|
|
892
|
-
|
|
893
|
-
const sizeText = _formatResumeBlockedBytes(msg.lastSeenBytes);
|
|
894
|
-
const dateText = msg.lastSeenAt ? new Date(msg.lastSeenAt).toLocaleString() : 'an earlier time';
|
|
895
|
-
return {
|
|
896
|
-
tone: 'info',
|
|
897
|
-
title: removed ? "This session's transcript was deleted from this machine." : "This session's transcript is gone from this machine.",
|
|
898
|
-
body: 'CTM could not check what it has stored for this session.' + (removed ? ` CTM read it here (${sizeText ? `${sizeText}, last seen ${dateText}` : `last seen ${dateText}`}) and the file is gone, so ${agent} can't resume it natively.` : ''),
|
|
899
|
-
};
|
|
942
|
+
// Unknown rung (the ladder could not answer): never the "nothing to resume" copy.
|
|
943
|
+
return { tone: 'info', identity, title: "CTM couldn't check this session's history.", body: 'The check did not finish.' };
|
|
900
944
|
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
title: "This session's transcript is gone from this machine.",
|
|
905
|
-
body: `The file was removed before CTM stored any of its prompts${retention}. There is nothing to resume; start a fresh session in the same folder.`,
|
|
906
|
-
};
|
|
945
|
+
if (rung === 'native') return { tone: 'info', identity, title: "This session's transcript is back.", body: '' };
|
|
946
|
+
// rung 'fresh' (and any rung CTM does not recognise): nothing was stored, so there is nothing to resume.
|
|
947
|
+
return { tone: 'info', identity, title: `${agent} can't find this session's transcript, and CTM saved none of it.`, body: why || 'There is nothing to resume.' };
|
|
907
948
|
}
|
|
908
949
|
|
|
909
950
|
// Session-transcript-storage WP-6 (D-6, D-7, D-13): the missing-transcript card names the rung the
|
|
@@ -930,7 +971,7 @@ function _resumeBlockedStoredLine(msg) {
|
|
|
930
971
|
const tail = coverage && Number.isFinite(Number(coverage.turnsTotal))
|
|
931
972
|
? `, ${_resumeStoreCompleteText(coverage.storeComplete)}.`
|
|
932
973
|
: '.';
|
|
933
|
-
return `CTM has ${Number(st.human) || 0} prompts (${total} turns) of this conversation${tail}
|
|
974
|
+
return `CTM has ${Number(st.human) || 0} prompts (${total} turns) of this conversation${tail}`;
|
|
934
975
|
}
|
|
935
976
|
|
|
936
977
|
function _resumeCheckedRungWord(rung) {
|
|
@@ -944,15 +985,55 @@ function _resumeCheckedLine(checkedAt, rung) {
|
|
|
944
985
|
return `Checked ${time}: ${_resumeCheckedRungWord(rung)}`;
|
|
945
986
|
}
|
|
946
987
|
|
|
988
|
+
// D-12: the file facts live in ONE collapsed Details row under the buttons, never in the card's title,
|
|
989
|
+
// body or identity line (a path is not something the user should have to read, let alone act on). The
|
|
990
|
+
// row is rendered only when it would hold at least one value; lines are written with textContent only.
|
|
991
|
+
function _resumeBlockedDetailLines(msg, checked) {
|
|
992
|
+
const m = msg || {};
|
|
993
|
+
const rung = String(m.resumeRung || '');
|
|
994
|
+
const lines = [];
|
|
995
|
+
const transcript = String(m.originalPath || m.storedPath || '');
|
|
996
|
+
if (transcript) lines.push({ key: 'transcript', text: `Transcript: ${transcript}` });
|
|
997
|
+
const copyPath = String(m.trashPath || (rung === 'restore' ? 'CTM archive' : ''));
|
|
998
|
+
if (copyPath) lines.push({ key: 'copy', text: `Copy: ${copyPath}` });
|
|
999
|
+
if (checked) lines.push({ key: 'checked', text: _resumeCheckedLine(m.checkedAt, rung) });
|
|
1000
|
+
return lines;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function _renderResumeBlockedDetails(overlay, msg, checked) {
|
|
1004
|
+
const lines = _resumeBlockedIsMissingTranscript(msg) ? _resumeBlockedDetailLines(msg, checked) : [];
|
|
1005
|
+
let details = overlay.querySelector('.resume-blocked-details');
|
|
1006
|
+
if (!lines.length) {
|
|
1007
|
+
if (details) details.remove();
|
|
1008
|
+
return null;
|
|
1009
|
+
}
|
|
1010
|
+
if (!details) {
|
|
1011
|
+
details = document.createElement('details');
|
|
1012
|
+
details.className = 'resume-blocked-details';
|
|
1013
|
+
const summary = document.createElement('summary');
|
|
1014
|
+
summary.textContent = 'Details';
|
|
1015
|
+
details.appendChild(summary);
|
|
1016
|
+
overlay.appendChild(details);
|
|
1017
|
+
}
|
|
1018
|
+
for (const child of Array.from(details.children)) if (String(child.tagName || '').toLowerCase() !== 'summary') child.remove(); // HTML tagName is upper-case
|
|
1019
|
+
for (const line of lines) {
|
|
1020
|
+
const el = document.createElement('div');
|
|
1021
|
+
el.className = `resume-blocked-detail-line resume-blocked-detail-${line.key}`;
|
|
1022
|
+
el.textContent = line.text;
|
|
1023
|
+
details.appendChild(el);
|
|
1024
|
+
}
|
|
1025
|
+
return details;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
947
1028
|
function _resumeBlockedBodyWithStore(body, msg) {
|
|
948
1029
|
// D-2/D-4: the stored line rides on any card carrying store-turn facts, not only the missing codes.
|
|
949
1030
|
// A card with no ladder facts (storeTurns absent) keeps its body exactly as the code's copy wrote it.
|
|
950
1031
|
if (!msg || !msg.storeTurns || msg.storeTurns.known === undefined) return body;
|
|
1032
|
+
// WP-3 (D-10/D-15): on a missing-transcript card the stored coverage is the RUNG's own sentence (the
|
|
1033
|
+
// card copy already wrote it), so nothing is appended here. No card ever names a path or tells the user
|
|
1034
|
+
// to move a file: paths live in the Details row, and "Restore and resume" does the restore itself.
|
|
1035
|
+
if (_resumeBlockedIsMissingTranscript(msg)) return body;
|
|
951
1036
|
let text = [body, _resumeBlockedStoredLine(msg)].filter(Boolean).join(' ');
|
|
952
|
-
if (msg.trashPath) {
|
|
953
|
-
text += ` A copy is in CTM's transcript trash at ${msg.trashPath} \u2014 move it back to `
|
|
954
|
-
+ `${msg.originalPath || 'its original location'} and press Check again.`;
|
|
955
|
-
}
|
|
956
1037
|
if (msg.restoreError && msg.restoreError !== 'not_implemented') text += '\nRestore failed: ' + msg.restoreError;
|
|
957
1038
|
return text;
|
|
958
1039
|
}
|
|
@@ -993,8 +1074,8 @@ async function _resumeBlockedFromStore(s, msg, btn) {
|
|
|
993
1074
|
const sessionId = _resumeClientSessionId(s);
|
|
994
1075
|
if (!s || !sessionId) return;
|
|
995
1076
|
const provider = _clientNormalizeAgentType(msg.agentType || _clientAgentTypeForSession(s)) === 'codex' ? 'codex' : 'claude';
|
|
996
|
-
const cwd = (s
|
|
997
|
-
const label = (s
|
|
1077
|
+
const cwd = _resumeBlockedSessionCwd(s);
|
|
1078
|
+
const label = _resumeBlockedSessionLabel(s);
|
|
998
1079
|
const idle = btn.textContent;
|
|
999
1080
|
btn.disabled = true;
|
|
1000
1081
|
btn.textContent = 'Starting…';
|
|
@@ -1053,43 +1134,50 @@ function _resumeBlockedButton(actions, label, onclick, primary) {
|
|
|
1053
1134
|
return btn;
|
|
1054
1135
|
}
|
|
1055
1136
|
|
|
1137
|
+
// D-11: the third recovery option is a text link, not a fourth equal button. Same handler map.
|
|
1138
|
+
function _resumeBlockedLinkButton(actions, label, onclick) {
|
|
1139
|
+
const btn = document.createElement('button');
|
|
1140
|
+
btn.className = 'resume-blocked-link';
|
|
1141
|
+
btn.textContent = label;
|
|
1142
|
+
btn.onclick = () => onclick(btn);
|
|
1143
|
+
actions.appendChild(btn);
|
|
1144
|
+
return btn;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1056
1147
|
// Buttons of the card as data: a pure function of the message facts, no DOM (D-3). Missing-transcript
|
|
1057
1148
|
// cards offer only the actions their rung can honor; D-7 makes the store primary for an oversized Codex rollout.
|
|
1058
|
-
// D-4:
|
|
1059
|
-
//
|
|
1149
|
+
// D-4 (session-exit-close-truth): the store rebuild asks the ladder whether the native transcript is
|
|
1150
|
+
// gone. It is offered ONLY on a missing-transcript code whose rung is store, fresh or '' (unknown), or
|
|
1151
|
+
// when offerStoreFirst is true -- never on a non-missing code and never on rung native, restore or trash.
|
|
1060
1152
|
function _resumeBlockedActionsFor(msg) {
|
|
1061
1153
|
const missing = _resumeBlockedIsMissingTranscript(msg);
|
|
1154
|
+
const m = msg || {};
|
|
1062
1155
|
const fresh = { id: 'fresh', label: 'Start fresh here', primary: false };
|
|
1156
|
+
// D-11: at most two buttons and one text link, exactly one button primary. `link: true` marks the
|
|
1157
|
+
// action the renderer draws AFTER the buttons as a text-styled link (same handler map).
|
|
1063
1158
|
const conversation = { id: 'conversation', label: 'Open Conversation', primary: false };
|
|
1159
|
+
const conversationLink = { ...conversation, link: true };
|
|
1064
1160
|
const store = (primary) => ({ id: 'store', label: 'Resume from stored history', primary });
|
|
1065
|
-
const st = msg.storeTurns || { human: 0, total: 0 };
|
|
1066
|
-
const human = Number(st.human) > 0;
|
|
1067
|
-
if (!missing) return [{ id: 'retry', label: 'Retry now', primary: true }, ...(human ? [store(false)] : []), fresh, conversation];
|
|
1068
|
-
if (msg.offerStoreFirst === true) return [store(true), { id: 'retry', label: 'Retry now', primary: false }, fresh, conversation];
|
|
1069
|
-
const rung = String(msg.resumeRung || '');
|
|
1070
|
-
const hasStore = Number(st.total) > 0 || st.known === false;
|
|
1071
1161
|
const check = { id: 'check', label: 'Check again', primary: false };
|
|
1162
|
+
const st = m.storeTurns || { human: 0, total: 0 };
|
|
1163
|
+
const hasStore = Number(st.total) > 0;
|
|
1164
|
+
// Non-missing codes keep today's list exactly.
|
|
1165
|
+
if (!missing) return [{ id: 'retry', label: 'Retry now', primary: true }, fresh, conversation];
|
|
1166
|
+
if (m.offerStoreFirst === true) return [store(true), { id: 'retry', label: 'Retry now', primary: false }, conversationLink];
|
|
1167
|
+
const rung = String(m.resumeRung || '');
|
|
1072
1168
|
if (rung === 'restore' || rung === 'trash') {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
list.push(
|
|
1076
|
-
if (hasStore) list.push(conversation);
|
|
1077
|
-
list.push(check);
|
|
1169
|
+
// The rung can put the original back itself, so it leads and "Check again" is gone (D-11/I-5).
|
|
1170
|
+
const list = [{ id: 'restore', label: 'Restore and resume', primary: true }, fresh];
|
|
1171
|
+
if (hasStore) list.push(conversationLink);
|
|
1078
1172
|
return list;
|
|
1079
1173
|
}
|
|
1080
|
-
if (rung === 'store') return [store(true), fresh,
|
|
1081
|
-
if (rung === '') { // unknown: the answer is a re-check
|
|
1082
|
-
|
|
1083
|
-
if (Number(st.total) > 0) unknown.push(conversation);
|
|
1084
|
-
if (human) unknown.push(store(false));
|
|
1085
|
-
unknown.push(fresh);
|
|
1086
|
-
return unknown;
|
|
1174
|
+
if (rung === 'store') return [store(true), fresh, conversationLink];
|
|
1175
|
+
if (rung === '') { // unknown: the answer is a re-check -- the check itself is what failed
|
|
1176
|
+
return hasStore ? [{ ...check, primary: true }, fresh, conversationLink] : [{ ...check, primary: true }, fresh];
|
|
1087
1177
|
}
|
|
1088
|
-
|
|
1089
|
-
if (
|
|
1090
|
-
|
|
1091
|
-
list.push(check);
|
|
1092
|
-
return list;
|
|
1178
|
+
// rung native with a missing transcript: the file is back, so resuming leads and the store is gone.
|
|
1179
|
+
if (rung === 'native') return [{ id: 'retry', label: 'Resume', primary: true }, fresh];
|
|
1180
|
+
return [{ ...fresh, primary: true }];
|
|
1093
1181
|
}
|
|
1094
1182
|
|
|
1095
1183
|
function _appendResumeBlockedActions(actions, s, msg) {
|
|
@@ -1103,8 +1191,24 @@ function _appendResumeBlockedActions(actions, s, msg) {
|
|
|
1103
1191
|
conversation: () => _openBlockedResumeConversation(s),
|
|
1104
1192
|
check: (b) => _checkBlockedResumeAgain(s, b),
|
|
1105
1193
|
};
|
|
1106
|
-
|
|
1107
|
-
|
|
1194
|
+
const list = _resumeBlockedActionsFor(msg);
|
|
1195
|
+
for (const action of list.filter((a) => !a.link)) {
|
|
1196
|
+
const handler = handlers[action.id];
|
|
1197
|
+
// WP-0 (S-9/D-8): every click on a blocked card's button records which button it was before the
|
|
1198
|
+
// handler runs, so a card's outcome is attributable to the action the user actually pressed.
|
|
1199
|
+
const traced = typeof handler !== 'function' ? handler : (...args) => {
|
|
1200
|
+
send({ type: 'client-diag', id: _resumeClientSessionId(s), event: 'resume-blocked-action', details: { action: action.id, code: String(msg.code || '') } });
|
|
1201
|
+
return handler(...args);
|
|
1202
|
+
};
|
|
1203
|
+
_resumeBlockedButton(actions, action.label, traced, action.primary);
|
|
1204
|
+
}
|
|
1205
|
+
for (const action of list.filter((a) => a.link)) {
|
|
1206
|
+
const handler = handlers[action.id];
|
|
1207
|
+
const traced = typeof handler !== 'function' ? handler : (...args) => {
|
|
1208
|
+
send({ type: 'client-diag', id: _resumeClientSessionId(s), event: 'resume-blocked-action', details: { action: action.id, code: String(msg.code || '') } });
|
|
1209
|
+
return handler(...args);
|
|
1210
|
+
};
|
|
1211
|
+
_resumeBlockedLinkButton(actions, action.label, traced);
|
|
1108
1212
|
}
|
|
1109
1213
|
if (_resumeBlockedIsMissingTranscript(msg) && msg.restoreError === 'not_implemented') {
|
|
1110
1214
|
_resumeBlockedNote(s, 'Restore lands with the archive work');
|
|
@@ -1144,9 +1248,15 @@ function onResumeRetryNoop(msg) {
|
|
|
1144
1248
|
if (!s || !s._resumeCheckPending) return;
|
|
1145
1249
|
_clearResumeCheckPending(s);
|
|
1146
1250
|
const overlay = s.container && s.container.querySelector('.snapshot-loading-overlay');
|
|
1147
|
-
|
|
1148
|
-
const
|
|
1149
|
-
if (
|
|
1251
|
+
// D-12: the stamp goes in the Details row (written once, replaced in place) -- never into the body.
|
|
1252
|
+
const rendered = s._resumeBlockedMsg || msg;
|
|
1253
|
+
if (overlay) {
|
|
1254
|
+
_renderResumeBlockedDetails(overlay, {
|
|
1255
|
+
...rendered,
|
|
1256
|
+
resumeRung: rendered.resumeRung || s._resumeBlockedRung || '',
|
|
1257
|
+
checkedAt: msg.checkedAt,
|
|
1258
|
+
}, true);
|
|
1259
|
+
}
|
|
1150
1260
|
const actions = overlay && overlay.querySelector('.snapshot-loading-actions');
|
|
1151
1261
|
for (const b of (actions ? Array.from(actions.children) : [])) if (b.textContent === 'Checking\u2026') b.textContent = 'Check again';
|
|
1152
1262
|
}
|
|
@@ -1175,6 +1285,16 @@ function _renderResumeBlockedOverlay(s, msg, opts) {
|
|
|
1175
1285
|
clearTimeout(s._loadingOverlayTimer);
|
|
1176
1286
|
s._loadingOverlayTimer = null;
|
|
1177
1287
|
_projectSessionLifecycle(s, 'resume-blocked'); // the renderer mounts (or keeps) the shell
|
|
1288
|
+
// WP-0 (S-9/D-8): the card the user actually saw is recorded once per render, with the action list it
|
|
1289
|
+
// offered -- the server side alone cannot say which of the three cards for one code was painted.
|
|
1290
|
+
send({
|
|
1291
|
+
type: 'client-diag', id: _resumeClientSessionId(s), event: 'resume-blocked-card',
|
|
1292
|
+
details: {
|
|
1293
|
+
code: String(msg.code || ''), rung: String(msg.resumeRung || ''),
|
|
1294
|
+
storeHuman: Number(msg.storeTurns && msg.storeTurns.human) || 0,
|
|
1295
|
+
actions: _resumeBlockedActionsFor(msg).map((a) => a.id).join(','),
|
|
1296
|
+
},
|
|
1297
|
+
});
|
|
1178
1298
|
const overlay = s.container.querySelector('.snapshot-loading-overlay');
|
|
1179
1299
|
// Off the terminal the renderer withholds the element on purpose: the rail line represents the card.
|
|
1180
1300
|
if (!overlay) return typeof _terminalLifecycleOverlaySuppressed === 'function' && _terminalLifecycleOverlaySuppressed(s);
|
|
@@ -1189,6 +1309,18 @@ function _renderResumeBlockedOverlay(s, msg, opts) {
|
|
|
1189
1309
|
overlay.insertBefore(lbl, overlay.firstChild);
|
|
1190
1310
|
}
|
|
1191
1311
|
lbl.classList.add('is-static');
|
|
1312
|
+
// D-14: every missing-transcript card names its subject first, in its own dim line above the headline.
|
|
1313
|
+
let ident = overlay.querySelector('.resume-blocked-identity');
|
|
1314
|
+
if (copy.identity) {
|
|
1315
|
+
if (!ident) {
|
|
1316
|
+
ident = document.createElement('div');
|
|
1317
|
+
ident.className = 'resume-blocked-identity';
|
|
1318
|
+
overlay.insertBefore(ident, lbl);
|
|
1319
|
+
}
|
|
1320
|
+
ident.textContent = copy.identity;
|
|
1321
|
+
} else if (ident) {
|
|
1322
|
+
ident.remove();
|
|
1323
|
+
}
|
|
1192
1324
|
const agentLabel = _resumeBlockedAgentLabel(s, msg);
|
|
1193
1325
|
const attempts = Math.max(0, Number(msg?.attempts || 0));
|
|
1194
1326
|
let body = _resumeBlockedBodyWithStore(copy.body, msg);
|
|
@@ -1198,10 +1330,11 @@ function _renderResumeBlockedOverlay(s, msg, opts) {
|
|
|
1198
1330
|
body = `${agentLabel} is producing output but never painted its screen.`;
|
|
1199
1331
|
}
|
|
1200
1332
|
const remount = !!(opts && opts.remount);
|
|
1333
|
+
let checked = false;
|
|
1201
1334
|
if (!remount && s._resumeCheckPending && _resumeBlockedIsMissingTranscript(msg)) {
|
|
1202
|
-
// A Check again was in flight: this re-render is its answer.
|
|
1335
|
+
// A Check again was in flight: this re-render is its answer. D-12: the stamp lives in Details.
|
|
1203
1336
|
_clearResumeCheckPending(s);
|
|
1204
|
-
|
|
1337
|
+
checked = true;
|
|
1205
1338
|
}
|
|
1206
1339
|
lbl.textContent = copy.title + (body ? '\n' + body : '');
|
|
1207
1340
|
let detail = overlay.querySelector('.snapshot-loading-detail');
|
|
@@ -1224,10 +1357,14 @@ function _renderResumeBlockedOverlay(s, msg, opts) {
|
|
|
1224
1357
|
}
|
|
1225
1358
|
actions.innerHTML = '';
|
|
1226
1359
|
_appendResumeBlockedActions(actions, s, msg);
|
|
1360
|
+
if (typeof resumeBlockedOpenOnMachineAction === 'function') resumeBlockedOpenOnMachineAction(msg, actions, s); // hub WP-5
|
|
1227
1361
|
if (remount && s._resumeCheckPending) {
|
|
1228
1362
|
// A Check again is still in flight: a surface round trip is not its answer.
|
|
1229
1363
|
for (const b of Array.from(actions.children)) if (b.textContent === 'Check again') b.textContent = 'Checking\u2026';
|
|
1230
1364
|
}
|
|
1365
|
+
// D-12: the file facts are the LAST thing on the card, under the buttons -- a collapsed disclosure, not
|
|
1366
|
+
// something the user has to read or act on. Rendered after the actions so the DOM order is the visual order.
|
|
1367
|
+
_renderResumeBlockedDetails(overlay, msg, checked);
|
|
1231
1368
|
return true;
|
|
1232
1369
|
}
|
|
1233
1370
|
|
|
@@ -222,12 +222,23 @@ function _fitTerminalPreservingViewport(s, sessionId, opts) {
|
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
224
|
if (!opts.force && _terminalInputDisplayHoldActive(s)) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
225
|
+
// The input display hold keeps a focused draft's repaint stable; it does not pin a
|
|
226
|
+
// grid the pane no longer has. A local fit proposal whose rows are strictly below the
|
|
227
|
+
// current term.rows is positive evidence the rendered rows are already clipped, so that
|
|
228
|
+
// case continues through the normal fit pipeline below (which still owes its own
|
|
229
|
+
// geometry acceptance). Optional, equal-row, row-growth and invalid proposals keep the
|
|
230
|
+
// old defer-and-rearm behavior untouched.
|
|
231
|
+
const proposal = _terminalLocalFitProposal(s);
|
|
232
|
+
const clippedRows = !!proposal && Number.isFinite(proposal.cols) && proposal.cols > 0
|
|
233
|
+
&& Number.isFinite(proposal.rows) && proposal.rows > 0 && proposal.rows < s.term.rows;
|
|
234
|
+
if (!clippedRows) {
|
|
235
|
+
clearTimeout(s._terminalInputDeferredFitTimer);
|
|
236
|
+
s._terminalInputDeferredFitTimer = setTimeout(() => {
|
|
237
|
+
s._terminalInputDeferredFitTimer = null;
|
|
238
|
+
_fitTerminalPreservingViewport(s, sessionId, opts);
|
|
239
|
+
}, TERMINAL_ACTIVE_INPUT_HOLD_MS);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
231
242
|
}
|
|
232
243
|
if (!opts.force && _claudeTuiResizeHoldActive(s)) {
|
|
233
244
|
_scheduleClaudeDeferredFit(s, sessionId, opts, opts.resizeReason || 'fit-preserving-viewport');
|
|
@@ -600,6 +611,8 @@ function _launchResumedAgentSession(provider, agentSessionId, cwd, label, ctmSes
|
|
|
600
611
|
args: spec.args,
|
|
601
612
|
cwd: cwd || undefined,
|
|
602
613
|
label: (label || 'Resumed session').replace(/^Resume:\s*/i, '').slice(0, 60),
|
|
614
|
+
// D-13: the desktop fork's name is composed by CTM (or echoed from the row), never user intent.
|
|
615
|
+
titleIntent: 'default',
|
|
603
616
|
});
|
|
604
617
|
}
|
|
605
618
|
|
|
@@ -24,3 +24,89 @@ function _focusModalPanel(modalEl) {
|
|
|
24
24
|
modalEl.focus();
|
|
25
25
|
return true;
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
// WP-1 (session-exit-close-truth-2026-10-24.html §5 D-3, §8 WP-1): this table moved here verbatim
|
|
29
|
+
// from public/index.html, which is exactly at its file-size ceiling. The freed lines are intentional
|
|
30
|
+
// headroom for WP-3/WP-4. Loaded as a classic script before the dashboard's inline script, so the
|
|
31
|
+
// top-level `const` is a shared global; every reader uses it inside a function that runs later.
|
|
32
|
+
// WI-5: cause-specific, non-alarming copy for the enumerated deterministic resume_blocked reason
|
|
33
|
+
// codes the server can send (see server.js markSessionResumeBlocked / _notifyResumePreflightFailure).
|
|
34
|
+
// Branch ONLY on `msg.code` here — never on message text — so this stays correct even if the
|
|
35
|
+
// human-readable message wording changes server-side. An unrecognized code (contract drift, or a
|
|
36
|
+
// code we haven't special-cased yet) falls back to the same honest red failure banner
|
|
37
|
+
// onSessionRestoreFailed already renders, rather than inventing false calm.
|
|
38
|
+
const RESUME_BLOCKED_COPY = {
|
|
39
|
+
missing_claude_transcript: {
|
|
40
|
+
tone: 'info',
|
|
41
|
+
title: "This session's transcript is gone from this machine.",
|
|
42
|
+
body: 'The file was removed before CTM stored any of its prompts (Claude Code deletes transcripts older than '
|
|
43
|
+
+ 'its retention period, 30 days by default). There is nothing to resume; start a fresh session in the same folder.',
|
|
44
|
+
},
|
|
45
|
+
missing_codex_rollout: {
|
|
46
|
+
tone: 'info',
|
|
47
|
+
title: "This session's transcript is gone from this machine.",
|
|
48
|
+
body: 'The file was removed before CTM stored any of its prompts. There is nothing to resume; '
|
|
49
|
+
+ 'start a fresh session in the same folder.',
|
|
50
|
+
},
|
|
51
|
+
agent_cli_not_found: {
|
|
52
|
+
tone: 'warn',
|
|
53
|
+
title: 'The agent CLI isn’t available on this host.',
|
|
54
|
+
body: 'CTM could not find the CLI needed to resume this session on this machine. '
|
|
55
|
+
+ 'Install it (or fix PATH), then reload — or start fresh here.',
|
|
56
|
+
},
|
|
57
|
+
resume_exit_loop: {
|
|
58
|
+
tone: 'warn',
|
|
59
|
+
title: 'This session could not finish resuming.',
|
|
60
|
+
body: '',
|
|
61
|
+
},
|
|
62
|
+
// WP-1 (D-3): the create path's defensive name for a resume that never became ready but carried
|
|
63
|
+
// no explicit code (lib/session-create/response.js defer -> deferBlockForExit rule 1). Same truth
|
|
64
|
+
// as the resume_* entries around it; without this entry the enforcement test in
|
|
65
|
+
// tests/restore-failed-presentation.test.js found the block had no renderer at all.
|
|
66
|
+
resume_failed: {
|
|
67
|
+
tone: 'warn',
|
|
68
|
+
title: 'This session could not finish resuming.',
|
|
69
|
+
body: '',
|
|
70
|
+
},
|
|
71
|
+
resume_no_frame: {
|
|
72
|
+
tone: 'warn',
|
|
73
|
+
title: 'The session never painted a usable screen.',
|
|
74
|
+
body: '',
|
|
75
|
+
},
|
|
76
|
+
resume_no_output: {
|
|
77
|
+
tone: 'warn',
|
|
78
|
+
title: 'The agent did not respond while resuming.',
|
|
79
|
+
body: 'It may be waiting on authentication, blocked by configuration, or unavailable on this host.',
|
|
80
|
+
},
|
|
81
|
+
// Mixed-version compatibility: current servers normalize this internal
|
|
82
|
+
// lifecycle reason to resume_no_output before it reaches the browser.
|
|
83
|
+
no_provider_output: {
|
|
84
|
+
tone: 'warn',
|
|
85
|
+
title: 'The agent did not respond while resuming.',
|
|
86
|
+
body: 'It may be waiting on authentication, blocked by configuration, or unavailable on this host.',
|
|
87
|
+
},
|
|
88
|
+
// Compatibility for a server from before the resume lifecycle became provider-neutral.
|
|
89
|
+
codex_no_output: {
|
|
90
|
+
tone: 'warn',
|
|
91
|
+
title: 'Codex did not respond while resuming.',
|
|
92
|
+
body: 'It may be waiting on authentication, blocked by configuration, or unavailable on this host.',
|
|
93
|
+
},
|
|
94
|
+
restore_retries_exhausted: {
|
|
95
|
+
tone: 'warn',
|
|
96
|
+
title: 'CTM could not prepare this session after several tries.',
|
|
97
|
+
body: 'The launch planner kept timing out. Retry now, or start fresh here.',
|
|
98
|
+
},
|
|
99
|
+
// WP-1 (D-3, S-12): the two exit-truth codes `deferBlockForExit` (lib/resume-blocked-wire.js) can
|
|
100
|
+
// return. Without these the create-path defer fell through to the retryable "Preparing session…"
|
|
101
|
+
// cover with nothing the user could resolve.
|
|
102
|
+
session_crash_loop: {
|
|
103
|
+
tone: 'warn',
|
|
104
|
+
title: 'This session kept exiting and CTM stopped restarting it.',
|
|
105
|
+
body: 'The agent exited with an error after automatic restarts. Retry now, or start fresh here.',
|
|
106
|
+
},
|
|
107
|
+
session_crashed: {
|
|
108
|
+
tone: 'warn',
|
|
109
|
+
title: 'This session exited with an error.',
|
|
110
|
+
body: 'Retry now, or start fresh here.',
|
|
111
|
+
},
|
|
112
|
+
};
|
|
@@ -648,7 +648,7 @@
|
|
|
648
648
|
errorCode: String((error && error.code) || message || 'unknown'),
|
|
649
649
|
httpStatus,
|
|
650
650
|
ms: Date.now() - (Number(startedAt) || Date.now()),
|
|
651
|
-
attempts: 1,
|
|
651
|
+
attempts: 1, reason: String((error && (error.reason || error.coverageReason)) || '').slice(0, 64) || null, // source-missing diagnosis: the SERVER's own cause (`coverage.reason`/`meta.reason`, e.g. 'no-source'/'source-unreadable'), which err.reason does not carry for the raw-Codex lane. On this line (not its own): the file is at its size ceiling.
|
|
652
652
|
});
|
|
653
653
|
} catch { /* expected: the entry-failure beacon is best-effort and must never block the failure path */ }
|
|
654
654
|
};
|