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
|
@@ -31,17 +31,14 @@
|
|
|
31
31
|
// state across the intervening rows exactly as it should, since these rows
|
|
32
32
|
// are painted into the pane in that same order.
|
|
33
33
|
|
|
34
|
-
const { wrapToCells, truncateToCells
|
|
35
|
-
|
|
34
|
+
const { wrapToCells, truncateToCells } = require('./terminal-cell-width');
|
|
35
|
+
// WP-1 (reader-claude-table-layout-parity-2026-10-25): tables are laid out by Claude Code
|
|
36
|
+
// 2.1.310's own algorithm, ported in this module's sibling -- never by the Codex allocator this
|
|
37
|
+
// file used to borrow (see `emitTable`).
|
|
38
|
+
const { layoutClaudeTable, cardLines, inkWrapLines } = require('./claude-table-layout');
|
|
36
39
|
|
|
37
40
|
const RESET = '\x1b[0m';
|
|
38
41
|
|
|
39
|
-
// WP-2 (reader-seam-duplicates): the per-attribute "off" codes this module already closes every
|
|
40
|
-
// inline span with (22 un-bold, 23 un-italicize, 29 un-strike, 39 default fg). A table cell that
|
|
41
|
-
// WRAPS emits one of these at the end of each of its visual lines so a span left open by the
|
|
42
|
-
// wrapped text can never bleed past the `│` that closes the cell into the next column.
|
|
43
|
-
const SPAN_OFF = '\x1b[22;23;29;39m';
|
|
44
|
-
|
|
45
42
|
function _sgrOpen(codes) {
|
|
46
43
|
const list = (Array.isArray(codes) ? codes : [codes]).filter((c) => c !== undefined && c !== null && c !== '');
|
|
47
44
|
return list.length ? `\x1b[${list.join(';')}m` : '';
|
|
@@ -128,85 +125,30 @@ function emitCode(token, cols, indent, style) {
|
|
|
128
125
|
return lines.map((line) => ' '.repeat(indent) + closeRow(styleRow(truncateToCells(line, width), style.code)));
|
|
129
126
|
}
|
|
130
127
|
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
const total = Math.max(0, width - stringCellWidth(text));
|
|
140
|
-
if (align === 'center') {
|
|
141
|
-
const left = Math.floor(total / 2);
|
|
142
|
-
return ' '.repeat(left) + text + ' '.repeat(total - left);
|
|
143
|
-
}
|
|
144
|
-
return text + ' '.repeat(total); // left-align
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// WP-2 (reader-seam-duplicates): a table wider than the pane WRAPS its cells inside their own
|
|
148
|
-
// columns instead of truncating the row. Claude itself wraps a wide cell (it never ellipsizes
|
|
149
|
-
// one), so the re-drawn transcript and the live screen now agree. The fitting path below is
|
|
150
|
-
// byte-identical to the pre-WP-2 emitter; only a table that does not fit takes the wrap path,
|
|
151
|
-
// which sizes its columns through the Codex table module's own width allocator (rank cells by
|
|
152
|
-
// kind, shrink the slackiest column first) rather than inventing a second policy.
|
|
128
|
+
// Tables: the layout is Claude Code 2.1.310's OWN (design
|
|
129
|
+
// docs/reader-claude-table-layout-parity-2026-10-25.html -- §3.1 the algorithm read from the
|
|
130
|
+
// binary, §5 the rules R-1..R-8, §9 this site). The port lives in lib/claude-table-layout.js; it
|
|
131
|
+
// decides the form (bordered box or stacked key-value cards), the column widths and every line
|
|
132
|
+
// break, and it was verified byte-identical against three live captures
|
|
133
|
+
// (tests/golden/claude-transcript/table-captures/). This function only renders the cells and
|
|
134
|
+
// prefixes the indent -- no local table policy, because any "nicer" table is content the live
|
|
135
|
+
// screen never had and the seam proof then refuses the join (R-1, R-7).
|
|
153
136
|
function emitTable(token, cols, indent, style) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
137
|
+
// Cells are rendered through emitInline, so a link prints `label (href)` exactly like Claude's
|
|
138
|
+
// own `T()`; the port measures widths on that SGR-stripped rendering (R-3 -- never on
|
|
139
|
+
// inlineText, which drops the href and so under-measures every linked cell).
|
|
140
|
+
const header = (token.header || []).map((cell) => emitInline(cell.tokens, style));
|
|
141
|
+
const rows = (token.rows || []).map((row) => row.map((cell) => emitInline(cell.tokens, style)));
|
|
142
|
+
const layout = layoutClaudeTable({ header, rows, align: token.align }, cols);
|
|
143
|
+
// R-5: `cols` is the TERMINAL width; `indent` is a prefix on every row and is never subtracted
|
|
144
|
+
// from it. A bordered table is already inside `cols - 4`; the cards are re-wrapped a second
|
|
145
|
+
// time by Ink's box at `cols - indent` (D-5), which is what turns a 170-cell card line into the
|
|
146
|
+
// three painted rows of the tasks capture.
|
|
147
|
+
const lines = layout.kind === 'bordered'
|
|
148
|
+
? layout.lines
|
|
149
|
+
: inkWrapLines(cardLines(layout, cols, style), cols - indent);
|
|
165
150
|
const pad = ' '.repeat(indent);
|
|
166
|
-
|
|
167
|
-
const tableWidth = widths.reduce((sum, w) => sum + w, 0) + 3 * colCount + 1;
|
|
168
|
-
if (tableWidth <= budget) {
|
|
169
|
-
const emitRaw = (raw) => pad + closeRow(truncateToCells(raw, budget));
|
|
170
|
-
const border = (left, mid, right) => emitRaw(left + widths.map((w) => '─'.repeat(w + 2)).join(mid) + right);
|
|
171
|
-
const dataRow = (styledCells, align) => {
|
|
172
|
-
const cells = widths.map((w, i) => ` ${_cellPad(styledCells[i] || '', w, align)} `);
|
|
173
|
-
return emitRaw(`│${cells.join('│')}│`);
|
|
174
|
-
};
|
|
175
|
-
const rows = [border('┌', '┬', '┐'), dataRow(headerStyled, 'center')];
|
|
176
|
-
for (const row of bodyStyledRows) {
|
|
177
|
-
rows.push(border('├', '┼', '┤'));
|
|
178
|
-
rows.push(dataRow(row, 'left'));
|
|
179
|
-
}
|
|
180
|
-
rows.push(border('└', '┴', '┘'));
|
|
181
|
-
return rows;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// --- wrap path: the table does not fit, so wrap each cell inside its column ---
|
|
185
|
-
const available = budget - (3 * colCount + 1);
|
|
186
|
-
const metrics = collectColumnMetrics(headerPlain, bodyPlainRows, colCount, stringCellWidth);
|
|
187
|
-
let wrapWidths = computeColumnWidths(metrics, available);
|
|
188
|
-
// Null means even MIN_COLUMN_WIDTH (3) per column cannot fit: fall back to an even split (at
|
|
189
|
-
// least one cell wide each) rather than dropping columns or truncating.
|
|
190
|
-
if (!wrapWidths) wrapWidths = new Array(colCount).fill(Math.max(1, Math.floor(available / colCount)));
|
|
191
|
-
const emitWrappedRaw = (raw) => pad + closeRow(raw);
|
|
192
|
-
const wrapBorder = (left, mid, right) => emitWrappedRaw(left + wrapWidths.map((w) => '─'.repeat(w + 2)).join(mid) + right);
|
|
193
|
-
const wrappedRows = (styledCells, align) => {
|
|
194
|
-
const lines = wrapWidths.map((w, i) => wrapToCells(styledCells[i] || '', w));
|
|
195
|
-
const height = lines.reduce((max, l) => Math.max(max, l.length), 1);
|
|
196
|
-
const out = [];
|
|
197
|
-
for (let k = 0; k < height; k++) {
|
|
198
|
-
const cells = wrapWidths.map((w, i) => ` ${_cellPad(lines[i][k] || '', w, align)}${SPAN_OFF} `);
|
|
199
|
-
out.push(emitWrappedRaw(`│${cells.join('│')}│`));
|
|
200
|
-
}
|
|
201
|
-
return out;
|
|
202
|
-
};
|
|
203
|
-
const rows = [wrapBorder('┌', '┬', '┐'), ...wrappedRows(headerStyled, 'center')];
|
|
204
|
-
for (const row of bodyStyledRows) {
|
|
205
|
-
rows.push(wrapBorder('├', '┼', '┤'));
|
|
206
|
-
rows.push(...wrappedRows(row, 'left'));
|
|
207
|
-
}
|
|
208
|
-
rows.push(wrapBorder('└', '┴', '┘'));
|
|
209
|
-
return rows;
|
|
151
|
+
return lines.map((line) => pad + closeRow(line));
|
|
210
152
|
}
|
|
211
153
|
|
|
212
154
|
function emitBlockquote(token, cols, depth, style) {
|
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
// (this worktree), and is asserted by AC-0d (no `claude-agent-sdk` path ever appears in
|
|
7
7
|
// require.cache after a require() or a call through the `sdk` DI seam).
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// setClaudeSessionTitle resolves; it never throws — callers get a uniform
|
|
10
10
|
// { state: 'mirrored'|'unsupported'|'failed', reason, error } outcome instead.
|
|
11
|
+
//
|
|
12
|
+
// WP-2 (D-6): the inbound half (readClaudeSessionTitle, an SDK getSessionInfo round-trip whose
|
|
13
|
+
// merged fields conflate CTM tiers) is deleted. The agent's own name now comes from the
|
|
14
|
+
// transcript records CTM already parses — lib/agent-title-apply.js.
|
|
11
15
|
|
|
12
16
|
const { normalizeSessionTitle } = require('./session-title-signals');
|
|
13
17
|
|
|
@@ -66,32 +70,4 @@ async function setClaudeSessionTitle({ sessionId, title, dir, sdk } = {}) {
|
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
let resolvedSdk = sdk;
|
|
71
|
-
if (!resolvedSdk) {
|
|
72
|
-
try {
|
|
73
|
-
resolvedSdk = await _loadSdk();
|
|
74
|
-
} catch (error) {
|
|
75
|
-
// expected: SDK absent — read has nothing to report, caller treats null as "no data"
|
|
76
|
-
void error;
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
let info;
|
|
81
|
-
try {
|
|
82
|
-
info = await resolvedSdk.getSessionInfo(sessionId, dir ? { dir } : undefined);
|
|
83
|
-
} catch (error) {
|
|
84
|
-
// expected: read is best-effort — any SDK failure maps to "no data" rather than a throw
|
|
85
|
-
void error;
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
if (!info) return null;
|
|
89
|
-
const aiTitle = (!info.customTitle && info.summary && info.summary !== info.firstPrompt) ? info.summary : '';
|
|
90
|
-
return {
|
|
91
|
-
userName: info.customTitle || '',
|
|
92
|
-
aiTitle,
|
|
93
|
-
firstPrompt: info.firstPrompt || '',
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
module.exports = { setClaudeSessionTitle, readClaudeSessionTitle, _resetSdkCacheForTests };
|
|
73
|
+
module.exports = { setClaudeSessionTitle, _resetSdkCacheForTests };
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Port of Claude Code 2.1.310's Markdown-table layout, read from the installed CLI
|
|
4
|
+
// (the versioned CLI binary under the user's local Claude install, Mach-O arm64; the layout sits at byte
|
|
5
|
+
// offset ~= 243,694,000, the `kind:"vertical"` literal: functions jr / Q / Z / Y / _t / ce,
|
|
6
|
+
// constants Ke=4 _e=3 as=4 Or=200). Design: docs/reader-claude-table-layout-parity-2026-10-25.html
|
|
7
|
+
// §3.1 (the algorithm) and §5 (rules R-1..R-8).
|
|
8
|
+
//
|
|
9
|
+
// WHY THIS EXISTS: the reader re-draws a Claude transcript into rows and then proves the seam
|
|
10
|
+
// against what the live terminal painted. A table the transcript renderer draws differently from
|
|
11
|
+
// the TUI is content the screen never had, and the proof refuses (dup rows / an overlap). So this
|
|
12
|
+
// module reproduces Claude's own layout EXACTLY -- same branch choice, same column widths, same
|
|
13
|
+
// line breaks, same glyphs, same fallback to the stacked key-value "cards", quirks included
|
|
14
|
+
// (R-6: floor rounding in the proportional branch, `max(floor(E*C/W), 3)` in the hard branch,
|
|
15
|
+
// the `> 4` wrapped-line rule, `floor` vertical centring, the 200-row cap). No "improvement" here
|
|
16
|
+
// is a fix; every deviation is a bug (R-1).
|
|
17
|
+
//
|
|
18
|
+
// TWO FORMS: `bordered` (the box, lines carry NO indent and never exceed cols - 4) and `cards`
|
|
19
|
+
// (the vertical key-value form, re-wrapped a second time by Ink's box: see inkWrapLines). The
|
|
20
|
+
// caller (lib/claude-markdown-ansi.js emitTable) prefixes the 2-column message indent and closes
|
|
21
|
+
// each row; `cols` is the TERMINAL width and the indent is never subtracted from it (R-5).
|
|
22
|
+
//
|
|
23
|
+
// VERIFIED against three live captures (golden fixtures under
|
|
24
|
+
// tests/golden/claude-transcript/table-captures/, reproduced byte-for-byte by
|
|
25
|
+
// tests/claude-table-captures.test.js):
|
|
26
|
+
// lid-options-196 -- session 6ea59930 painted rows 4192-4197, cols 196, hard branch -> cards
|
|
27
|
+
// tasks-steps-171 -- session 3320adc3 painted rows 493-517, cols 171, proportional -> cards
|
|
28
|
+
// (the 170-cell card line re-wrapped at 169 by Ink's box)
|
|
29
|
+
// inject-ways-196 -- session 7cf57222 painted rows 8396-8408, cols 196, proportional -> bordered
|
|
30
|
+
// There is no runtime switch on the Claude version (R-8): drift is caught by those fixtures.
|
|
31
|
+
|
|
32
|
+
const { stringCellWidth } = require('./terminal-cell-width');
|
|
33
|
+
|
|
34
|
+
// wrap-ansi is ESM-only; Node's require(esm) (>= 22.12, the pinned 25.2.1 here) hands back the
|
|
35
|
+
// namespace, so `.default` is the function. Loaded ONCE at module top (D-4).
|
|
36
|
+
const wrapAnsiModule = require('wrap-ansi');
|
|
37
|
+
const wrapAnsi = wrapAnsiModule.default || wrapAnsiModule;
|
|
38
|
+
|
|
39
|
+
// Claude's own constants, by their de-minified names (Ke / _e / as / Or) plus the rule cap and
|
|
40
|
+
// the version/offset the port was read from (R-8).
|
|
41
|
+
const CLAUDE_TABLE = Object.freeze({
|
|
42
|
+
MARGIN: 4, // Ke: a bordered table must fit inside cols - 4
|
|
43
|
+
MIN_COL: 3, // _e: never allocate less than 3 columns to a cell
|
|
44
|
+
MAX_CELL_LINES: 4, // as: a cell wrapping to MORE lines than this sends the table to cards
|
|
45
|
+
MAX_ROWS: 200, // Or: rows beyond this are dropped and announced
|
|
46
|
+
RULE_MAX: 40, // the card separator is '─'.repeat(min(cols - 1, 40))
|
|
47
|
+
VERSION: '2.1.310',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const SGR_RE = /\x1b\[[0-9;?]*[ -\/]*[@-~]/g;
|
|
51
|
+
|
|
52
|
+
function stripSgr(text) {
|
|
53
|
+
return String(text == null ? '' : text).replace(SGR_RE, '');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Claude's `ce(text, width, {hard})`: wrap-ansi with `trimEnd()` first, `{hard, trim:false,
|
|
58
|
+
* wordWrap:true}`, empty lines dropped, `['']` when nothing is left. `width <= 0` returns the
|
|
59
|
+
* text untouched (Claude's own early return).
|
|
60
|
+
*/
|
|
61
|
+
function wrapCell(text, width, hard) {
|
|
62
|
+
const source = String(text == null ? '' : text);
|
|
63
|
+
if (width <= 0) return [source];
|
|
64
|
+
const lines = wrapAnsi(source.trimEnd(), width, { hard: !!hard, trim: false, wordWrap: true })
|
|
65
|
+
.split('\n')
|
|
66
|
+
.filter((line) => line.length > 0);
|
|
67
|
+
return lines.length > 0 ? carryExtendedColour(lines) : [''];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// wrap-ansi closes bold / italic / strike and the 16 basic colours at its own line break and re-opens
|
|
71
|
+
// them on the next line, but it has no closer for an EXTENDED colour selector (`38;5;n`, `38;2;r;g;b`):
|
|
72
|
+
// a coloured span that wraps inside a cell stays open past the cell's `│` and paints the border and
|
|
73
|
+
// the neighbouring cell. The live screen never does that -- painted-rows census 2026-10-26: 556 of
|
|
74
|
+
// 556 bordered rows carrying a 256-colour span close it before every border (Ink styles each text
|
|
75
|
+
// node on its own) -- so carry the colour across the break exactly the way wrap-ansi carries the
|
|
76
|
+
// other attributes: close it (`39`) at the end of the line, re-open it at the start of the next.
|
|
77
|
+
function carryExtendedColour(lines) {
|
|
78
|
+
let open = null;
|
|
79
|
+
return lines.map((line) => {
|
|
80
|
+
const prefix = open || '';
|
|
81
|
+
for (const m of line.matchAll(/\x1b\[([0-9;]*)m/g)) {
|
|
82
|
+
const codes = m[1] === '' ? [0] : m[1].split(';').map(Number);
|
|
83
|
+
for (let i = 0; i < codes.length; i += 1) {
|
|
84
|
+
const code = codes[i];
|
|
85
|
+
if (code === 38 && codes[i + 1] === 5) { open = `\x1b[38;5;${codes[i + 2]}m`; i += 2; }
|
|
86
|
+
else if (code === 38 && codes[i + 1] === 2) { open = `\x1b[38;2;${codes.slice(i + 2, i + 5).join(';')}m`; i += 4; }
|
|
87
|
+
else if (code === 0 || code === 39 || (code >= 30 && code <= 37) || (code >= 90 && code <= 97)) open = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return prefix + line + (open ? '\x1b[39m' : '');
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Claude's `bgr(text, width, align)` -- pad by VISIBLE width. `center` puts the odd space on the
|
|
95
|
+
// right (floor on the left), `right` pads all on the left, `left` all on the right.
|
|
96
|
+
function pad(text, width, align, strWidth) {
|
|
97
|
+
const total = Math.max(0, width - strWidth(stripSgr(text)));
|
|
98
|
+
if (align === 'center') {
|
|
99
|
+
const left = Math.floor(total / 2);
|
|
100
|
+
return ' '.repeat(left) + text + ' '.repeat(total - left);
|
|
101
|
+
}
|
|
102
|
+
if (align === 'right') return ' '.repeat(total) + text;
|
|
103
|
+
return text + ' '.repeat(total);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Lay a table out exactly as Claude Code 2.1.310 does.
|
|
108
|
+
*
|
|
109
|
+
* header: ANSI-rendered header cells (emitInline output) rows: ANSI-rendered body cells
|
|
110
|
+
* align: ('left'|'center'|'right'|null)[] cols: terminal columns (p)
|
|
111
|
+
*
|
|
112
|
+
* Returns the layout DECISION, never the indented rows:
|
|
113
|
+
* { kind:'bordered', widths, hard, branch:'natural'|'proportional'|'hard', lines }
|
|
114
|
+
* -- lines carry no indent; the widest is <= cols - 4
|
|
115
|
+
* { kind:'cards', branch, reason:'cellLines'|'tooWide'|'headerOnly', headers, rows, truncated }
|
|
116
|
+
* -- the vertical form's inputs, before Ink's box wrap (see cardLines/inkWrapLines)
|
|
117
|
+
*/
|
|
118
|
+
function layoutClaudeTable({ header, rows, align } = {}, cols, { strWidth = stringCellWidth } = {}) {
|
|
119
|
+
const p = Number(cols) || 0;
|
|
120
|
+
const headerCells = (header || []).map((cell) => String(cell == null ? '' : cell));
|
|
121
|
+
const everyRow = (rows || []).map((row) => (row || []).map((cell) => String(cell == null ? '' : cell)));
|
|
122
|
+
const truncated = Math.max(0, everyRow.length - CLAUDE_TABLE.MAX_ROWS);
|
|
123
|
+
const bodyRows = truncated > 0 ? everyRow.slice(0, CLAUDE_TABLE.MAX_ROWS) : everyRow;
|
|
124
|
+
|
|
125
|
+
const K = headerCells.length;
|
|
126
|
+
if (K === 0) return { kind: 'bordered', widths: [], hard: false, branch: 'natural', lines: [] };
|
|
127
|
+
|
|
128
|
+
// R-3: widths come from the SGR-stripped RENDERED cell (a link counts as `label (href)`).
|
|
129
|
+
// E[c] = the widest whitespace-separated word, H[c] = the widest whole cell, both floored at 3.
|
|
130
|
+
const wordWidth = (cell) => {
|
|
131
|
+
const words = stripSgr(cell).split(/\s+/).filter((word) => word.length > 0);
|
|
132
|
+
if (words.length === 0) return CLAUDE_TABLE.MIN_COL;
|
|
133
|
+
let widest = CLAUDE_TABLE.MIN_COL;
|
|
134
|
+
for (const word of words) widest = Math.max(widest, strWidth(word));
|
|
135
|
+
return widest;
|
|
136
|
+
};
|
|
137
|
+
const cellWidth = (cell) => Math.max(strWidth(stripSgr(cell)), CLAUDE_TABLE.MIN_COL);
|
|
138
|
+
|
|
139
|
+
const E = headerCells.map((cell, i) => {
|
|
140
|
+
let width = wordWidth(cell);
|
|
141
|
+
for (const row of bodyRows) width = Math.max(width, wordWidth(row[i] || ''));
|
|
142
|
+
return width;
|
|
143
|
+
});
|
|
144
|
+
const H = headerCells.map((cell, i) => {
|
|
145
|
+
let width = cellWidth(cell);
|
|
146
|
+
for (const row of bodyRows) width = Math.max(width, cellWidth(row[i] || ''));
|
|
147
|
+
return width;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const M = 1 + 3 * K;
|
|
151
|
+
const C = Math.max(p - M - CLAUDE_TABLE.MARGIN, K * CLAUDE_TABLE.MIN_COL);
|
|
152
|
+
const W = E.reduce((sum, w) => sum + w, 0);
|
|
153
|
+
const z = H.reduce((sum, w) => sum + w, 0);
|
|
154
|
+
|
|
155
|
+
let hard = false;
|
|
156
|
+
let branch;
|
|
157
|
+
let D;
|
|
158
|
+
if (z <= C) {
|
|
159
|
+
D = H;
|
|
160
|
+
branch = 'natural';
|
|
161
|
+
} else if (W <= C) {
|
|
162
|
+
// Proportional: hand out the slack in proportion to each column's (natural - minimum) want,
|
|
163
|
+
// floored (R-6: Claude floors, it does not round).
|
|
164
|
+
branch = 'proportional';
|
|
165
|
+
const slack = C - W;
|
|
166
|
+
const want = H.map((w, i) => w - E[i]);
|
|
167
|
+
const U = want.reduce((sum, w) => sum + w, 0);
|
|
168
|
+
D = E.map((w, i) => (U === 0 ? w : w + Math.floor((want[i] / U) * slack)));
|
|
169
|
+
} else {
|
|
170
|
+
// Hard: scale every minimum by C/W, never below 3.
|
|
171
|
+
branch = 'hard';
|
|
172
|
+
hard = true;
|
|
173
|
+
const ratio = C / W;
|
|
174
|
+
D = E.map((w) => Math.max(Math.floor(w * ratio), CLAUDE_TABLE.MIN_COL));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// > 4 wrapped lines anywhere -> the whole table becomes cards.
|
|
178
|
+
let maxLines = 1;
|
|
179
|
+
for (let i = 0; i < K; i += 1) maxLines = Math.max(maxLines, wrapCell(headerCells[i], D[i], hard).length);
|
|
180
|
+
for (const row of bodyRows) {
|
|
181
|
+
for (let i = 0; i < row.length; i += 1) maxLines = Math.max(maxLines, wrapCell(row[i] || '', D[i], hard).length);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// The vertical form's inputs: a header-only table has no labels and its one row is the header
|
|
185
|
+
// (so it draws as unlabeled lines). `headerOnly` names that shape; the bordered attempt still
|
|
186
|
+
// runs first, exactly as Claude's does (a header-only table that fits stays a box).
|
|
187
|
+
const cards = (cause) => ({
|
|
188
|
+
kind: 'cards',
|
|
189
|
+
branch,
|
|
190
|
+
reason: bodyRows.length === 0 ? 'headerOnly' : cause,
|
|
191
|
+
headers: bodyRows.length === 0 ? [] : headerCells.map((cell) => stripSgr(cell).trim()),
|
|
192
|
+
rows: (bodyRows.length === 0 ? [headerCells] : bodyRows).map((row) => row.slice()),
|
|
193
|
+
truncated,
|
|
194
|
+
});
|
|
195
|
+
if (maxLines > CLAUDE_TABLE.MAX_CELL_LINES) return cards('cellLines');
|
|
196
|
+
|
|
197
|
+
const border = (kind) => {
|
|
198
|
+
const [left, bar, join, right] = {
|
|
199
|
+
top: ['┌', '─', '┬', '┐'],
|
|
200
|
+
middle: ['├', '─', '┼', '┤'],
|
|
201
|
+
bottom: ['└', '─', '┴', '┘'],
|
|
202
|
+
}[kind];
|
|
203
|
+
let line = left;
|
|
204
|
+
D.forEach((width, i) => {
|
|
205
|
+
line += bar.repeat(width + 2);
|
|
206
|
+
line += i < D.length - 1 ? join : right;
|
|
207
|
+
});
|
|
208
|
+
return line;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// One table row -> its bordered lines. Cells are vertically centred with floor((G - n)/2).
|
|
212
|
+
// Header cells are centred; body cells follow `align[c] ?? 'left'` (both Claude's rules).
|
|
213
|
+
const drawRow = (cells, isHeader) => {
|
|
214
|
+
const lines = cells.map((cell, i) => wrapCell(cell || '', D[i], hard));
|
|
215
|
+
const height = Math.max(...lines.map((l) => l.length), 1);
|
|
216
|
+
const off = lines.map((l) => Math.floor((height - l.length) / 2));
|
|
217
|
+
const out = [];
|
|
218
|
+
for (let r = 0; r < height; r += 1) {
|
|
219
|
+
let row = '│';
|
|
220
|
+
for (let c = 0; c < cells.length; c += 1) {
|
|
221
|
+
const idx = r - off[c];
|
|
222
|
+
const text = idx >= 0 && idx < lines[c].length ? lines[c][idx] : '';
|
|
223
|
+
row += ` ${pad(text, D[c], isHeader ? 'center' : ((align && align[c]) || 'left'), strWidth)} │`;
|
|
224
|
+
}
|
|
225
|
+
out.push(row);
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const lines = [border('top'), ...drawRow(headerCells, true), border('middle')];
|
|
231
|
+
bodyRows.forEach((row, i) => {
|
|
232
|
+
lines.push(...drawRow(row, false));
|
|
233
|
+
if (i < bodyRows.length - 1) lines.push(border('middle'));
|
|
234
|
+
});
|
|
235
|
+
lines.push(border('bottom'));
|
|
236
|
+
|
|
237
|
+
let widest = 0;
|
|
238
|
+
for (const line of lines) widest = Math.max(widest, strWidth(stripSgr(line)));
|
|
239
|
+
if (widest > p - CLAUDE_TABLE.MARGIN) return cards('tooWide');
|
|
240
|
+
|
|
241
|
+
if (truncated > 0) lines.push(notShown(truncated));
|
|
242
|
+
return { kind: 'bordered', widths: D, hard, branch, lines };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Claude's `lt(n)`: the 200-row cap's footnote.
|
|
246
|
+
function notShown(count) {
|
|
247
|
+
return `… ${count.toLocaleString()} more ${count === 1 ? 'row' : 'rows'} not shown`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The vertical form, before Ink's box wrap: one `Bold Header: value` line per non-empty cell,
|
|
252
|
+
* continuation lines verbatim, a `─`.repeat(min(cols - 1, 40)) rule BETWEEN cards only (never
|
|
253
|
+
* before the first, never after the last). `style.bold`/`style.boldOff` label the key (Claude
|
|
254
|
+
* paints `\x1b[1m`…`\x1b[22m`).
|
|
255
|
+
*/
|
|
256
|
+
function cardLines(layout, cols, style) {
|
|
257
|
+
const m = Number(cols) || 0;
|
|
258
|
+
const out = [];
|
|
259
|
+
const rule = '─'.repeat(Math.max(0, Math.min(m - 1, CLAUDE_TABLE.RULE_MAX)));
|
|
260
|
+
const headers = (layout && layout.headers) || [];
|
|
261
|
+
for (const row of (layout && layout.rows) || []) {
|
|
262
|
+
const lines = [];
|
|
263
|
+
row.forEach((cell, i) => {
|
|
264
|
+
const label = headers[i] || '';
|
|
265
|
+
// Claude flattens the cell to one line for the FIRST line, then re-wraps the rest.
|
|
266
|
+
const flat = String(cell == null ? '' : cell)
|
|
267
|
+
.trimEnd()
|
|
268
|
+
.replace(/\n+/g, ' ')
|
|
269
|
+
.replace(/\s+/g, ' ')
|
|
270
|
+
.trim();
|
|
271
|
+
if (!label && !flat) return; // an unlabeled empty cell prints nothing at all
|
|
272
|
+
const firstWidth = label ? m - stringCellWidth(label) - 3 : m - 1;
|
|
273
|
+
const contWidth = m - 3;
|
|
274
|
+
const wrapped = wrapCell(flat, Math.max(firstWidth, 10), false);
|
|
275
|
+
const head = wrapped[0] || '';
|
|
276
|
+
const rest = wrapped.length <= 1
|
|
277
|
+
? wrapped
|
|
278
|
+
: [head, ...wrapCell(wrapped.slice(1).map((line) => line.trim()).join(' '), contWidth, false)];
|
|
279
|
+
lines.push(label
|
|
280
|
+
? `${styleSpanText(`${label}:`, style)} ${rest[0] || ''}`
|
|
281
|
+
: (rest[0] || ''));
|
|
282
|
+
for (let d = 1; d < rest.length; d += 1) {
|
|
283
|
+
if (!rest[d].trim()) continue;
|
|
284
|
+
lines.push(rest[d]);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
if (!lines.length) continue;
|
|
288
|
+
if (out.length) out.push(rule);
|
|
289
|
+
out.push(...lines);
|
|
290
|
+
}
|
|
291
|
+
if (layout && layout.truncated > 0) {
|
|
292
|
+
if (out.length) out.push(rule);
|
|
293
|
+
out.push(notShown(layout.truncated));
|
|
294
|
+
}
|
|
295
|
+
return out;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// The card label's own span: open with `style.bold`, close with `style.boldOff` (never a blanket
|
|
299
|
+
// reset, so a caller's surrounding style survives). Kept local so this module stays pure.
|
|
300
|
+
function styleSpanText(text, style) {
|
|
301
|
+
const open = (style && style.bold) || [];
|
|
302
|
+
const close = (style && style.boldOff) || [];
|
|
303
|
+
const openCodes = (Array.isArray(open) ? open : [open]).filter((c) => c !== undefined && c !== null && c !== '');
|
|
304
|
+
if (!openCodes.length) return text;
|
|
305
|
+
const closeCodes = (Array.isArray(close) ? close : [close]).filter((c) => c !== undefined && c !== null && c !== '');
|
|
306
|
+
return `\x1b[${openCodes.join(';')}m${text}${closeCodes.length ? `\x1b[${closeCodes.join(';')}m` : ''}`;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Ink's `<Text wrap="wrap">` inside the 2-column message box: every line is re-wrapped with
|
|
311
|
+
* `wrapAnsi(line, boxWidth, {trim:false, hard:true})` and split on '\n' (D-5 -- observed: the
|
|
312
|
+
* tasks capture's 170-cell card line breaks at 169 into `…rubric` / `and` / `0.60 threshold`).
|
|
313
|
+
*/
|
|
314
|
+
function inkWrapLines(lines, boxWidth) {
|
|
315
|
+
const out = [];
|
|
316
|
+
for (const line of lines || []) {
|
|
317
|
+
out.push(...wrapAnsi(String(line == null ? '' : line), boxWidth, { trim: false, hard: true }).split('\n'));
|
|
318
|
+
}
|
|
319
|
+
return out;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
module.exports = { CLAUDE_TABLE, wrapCell, layoutClaudeTable, cardLines, inkWrapLines };
|
|
@@ -137,6 +137,11 @@ function createClientDiagHandler(deps = {}) {
|
|
|
137
137
|
toCols: nonNegInt(d.toCols),
|
|
138
138
|
widthPx: nonNegInt(d.widthPx),
|
|
139
139
|
reason: typeof d.reason === 'string' ? d.reason.slice(0, 40) : '',
|
|
140
|
+
// WP-2 (docs/codex-terminal-geometry-sticky-cols-2026-10-24.html §5): the two
|
|
141
|
+
// layout facts that make an adoption explainable -- browser viewport width and whether
|
|
142
|
+
// split view was on. Whitelisted here or the beacon's producer fields would be dropped.
|
|
143
|
+
viewportWidthPx: nonNegInt(d.viewportWidthPx),
|
|
144
|
+
split: d.split === true,
|
|
140
145
|
});
|
|
141
146
|
return;
|
|
142
147
|
}
|
|
@@ -105,20 +105,50 @@ function buildCodexTransportOverrideArgs(names, opts = {}) {
|
|
|
105
105
|
return out;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
// Read CODEX_HOME/config.toml
|
|
109
|
-
|
|
108
|
+
// Read CODEX_HOME/config.toml (best-effort: unreadable/missing → null). The one sync read both
|
|
109
|
+
// guards share; it is the ledgered main-thread site (docs/main-thread-sync-baseline.json).
|
|
110
|
+
function readCodexConfigToml(codexHome) {
|
|
110
111
|
let text;
|
|
111
112
|
try {
|
|
112
113
|
text = fs.readFileSync(path.join(codexHome || '', 'config.toml'), 'utf8');
|
|
113
114
|
} catch {
|
|
114
|
-
return
|
|
115
|
+
return null;
|
|
115
116
|
}
|
|
117
|
+
return text;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Return the override args (unreadable/missing config → []).
|
|
121
|
+
function codexMcpTransportGuardArgs(codexHome, opts = {}) {
|
|
122
|
+
const text = readCodexConfigToml(codexHome);
|
|
123
|
+
if (text === null) return [];
|
|
116
124
|
return buildCodexTransportOverrideArgs(findTransportlessMcpServers(text), opts);
|
|
117
125
|
}
|
|
118
126
|
|
|
127
|
+
// WP-1 (codex-routed-fork-cold-restore-guard-2026-10-22.html §5 D-2, §9 S-5): the ids a native
|
|
128
|
+
// `codex` config load resolves through `model_providers.get(id)` — Codex merges its built-in
|
|
129
|
+
// providers with this user table. Only the TABLE HEADERS are needed (the values are irrelevant to
|
|
130
|
+
// servability), so this is a line scan, not a TOML parse: `[model_providers.<id>]` and its
|
|
131
|
+
// sub-tables (`[model_providers.<id>.http_headers]`) both name the provider `<id>`; text before a
|
|
132
|
+
// `[model_providers]` header (or after a different table) is never attributed to it. Best-effort
|
|
133
|
+
// exactly like the transport guard: a missing/unreadable config is an empty set, never a throw.
|
|
134
|
+
// `codexHome` is the CODEX_HOME directory (the one that holds config.toml).
|
|
135
|
+
function readModelProviderKeys(codexHome) {
|
|
136
|
+
const text = readCodexConfigToml(codexHome);
|
|
137
|
+
if (text === null) return [];
|
|
138
|
+
const out = [];
|
|
139
|
+
for (const line of String(text || '').split(/\r?\n/)) {
|
|
140
|
+
const segs = _tableHeaderSegments(line);
|
|
141
|
+
if (!segs || segs.length < 2 || _unquote(segs[0]) !== 'model_providers') continue;
|
|
142
|
+
const key = _unquote(segs[1]);
|
|
143
|
+
if (key) out.push(key);
|
|
144
|
+
}
|
|
145
|
+
return [...new Set(out)];
|
|
146
|
+
}
|
|
147
|
+
|
|
119
148
|
module.exports = {
|
|
120
149
|
INERT_COMMAND,
|
|
121
150
|
findTransportlessMcpServers,
|
|
122
151
|
buildCodexTransportOverrideArgs,
|
|
123
152
|
codexMcpTransportGuardArgs,
|
|
153
|
+
readModelProviderKeys,
|
|
124
154
|
};
|
|
@@ -43,6 +43,17 @@ const CODEX_CONTROL_ADAPTER = 'codex-app-server-q1';
|
|
|
43
43
|
const CODEX_COMPACTION_SCHEMA_RECEIPT = 'codex-model-info-comp-hash-nullable-q1';
|
|
44
44
|
const CODEX_PRE_TURN_COMPACTION_SCHEMA = 'codex-pre-turn-compaction-q1';
|
|
45
45
|
|
|
46
|
+
// Codex's turn_context `cyber_access_program` (protocol/src/turn_input.rs @ rust-v0.163.0) is
|
|
47
|
+
// `standard` when the account's catalog advertises access programs and Daybreak is off
|
|
48
|
+
// (tui/src/daybreak.rs program_for_turn), and core drops any program for a non-OpenAI provider
|
|
49
|
+
// (core/src/cyber_access_program.rs for_provider). Only these values carry no elevated access, so
|
|
50
|
+
// only they may cross to a routed target; daybreak_* and unknown values stay unqualified.
|
|
51
|
+
const NON_ELEVATED_CYBER_ACCESS_PROGRAMS = Object.freeze([null, 'standard']);
|
|
52
|
+
|
|
53
|
+
function isNonElevatedCyberAccessProgram(value) {
|
|
54
|
+
return NON_ELEVATED_CYBER_ACCESS_PROGRAMS.includes(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
// Exact membership (D-4). Never a prefix/range match: '0.162.10' is not '0.162.1'.
|
|
47
58
|
function isQualifiedCodexVersion(version) {
|
|
48
59
|
return typeof version === 'string' && Object.hasOwn(CODEX_QUALIFIED_VERSIONS, version);
|
|
@@ -67,5 +78,6 @@ module.exports = {
|
|
|
67
78
|
CODEX_COMPACTION_SCHEMA_RECEIPT,
|
|
68
79
|
CODEX_PRE_TURN_COMPACTION_SCHEMA,
|
|
69
80
|
isQualifiedCodexVersion,
|
|
81
|
+
isNonElevatedCyberAccessProgram,
|
|
70
82
|
codexQualification,
|
|
71
83
|
};
|