create-walle 0.9.21 → 0.9.23
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 +27 -5
- package/package.json +2 -2
- package/template/CLAUDE.md +2 -2
- package/template/LICENSE +1 -1
- package/template/bin/ctm-dev-cleanup.js +24 -3
- package/template/bin/ctm-launch.sh +13 -0
- package/template/bin/dev.sh +156 -18
- package/template/bin/node-bin.sh +84 -0
- package/template/bin/pin-node.sh +51 -0
- package/template/claude-task-manager/api-prompts.js +1203 -182
- package/template/claude-task-manager/api-reviews.js +109 -15
- package/template/claude-task-manager/approval-agent.js +1360 -280
- package/template/claude-task-manager/bin/restart-ctm.sh +64 -23
- package/template/claude-task-manager/bin/storage-migration-supervisor.js +338 -0
- package/template/claude-task-manager/db.js +4417 -295
- package/template/claude-task-manager/docs/app-update-refresh-protocol.md +69 -0
- package/template/claude-task-manager/docs/approval-ai-refinement.md +138 -0
- package/template/claude-task-manager/docs/approval-rescue-loop.md +74 -0
- package/template/claude-task-manager/docs/codex-operational-warning-health.md +107 -0
- package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +17 -12
- package/template/claude-task-manager/docs/codex-terminal-render-controller-handoff.md +311 -0
- package/template/claude-task-manager/docs/coding-agent-hooks-architecture.md +418 -0
- package/template/claude-task-manager/docs/conversation-import-freshness.md +20 -0
- package/template/claude-task-manager/docs/google-workspace-auth-health.md +77 -0
- package/template/claude-task-manager/docs/image-paste-ux.md +13 -0
- package/template/claude-task-manager/docs/ipad-web-preview.md +88 -0
- package/template/claude-task-manager/docs/main-loop-offload-architecture.md +66 -0
- package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +274 -519
- package/template/claude-task-manager/docs/mobile-live-streaming.md +27 -5
- package/template/claude-task-manager/docs/mobile-remote-submission-lifecycle.md +69 -0
- package/template/claude-task-manager/docs/phone-access-design.md +53 -15
- package/template/claude-task-manager/docs/phone-passkey-identity.md +122 -0
- package/template/claude-task-manager/docs/phone-setup.md +3 -0
- package/template/claude-task-manager/docs/prompt-editing-tree-design.md +25 -1
- package/template/claude-task-manager/docs/remote-desktop-access-design.md +268 -0
- package/template/claude-task-manager/docs/restart-lifecycle-architecture.md +95 -0
- package/template/claude-task-manager/docs/runtime-work-control-plane.md +53 -0
- package/template/claude-task-manager/docs/session-interactive-wait-surfaces.md +38 -0
- package/template/claude-task-manager/docs/session-needs-you-dismissal.md +84 -0
- package/template/claude-task-manager/docs/session-render-state-management-design.md +91 -3
- package/template/claude-task-manager/docs/session-standup-command-center-design.md +25 -1
- package/template/claude-task-manager/docs/session-title-authority.md +32 -0
- package/template/claude-task-manager/docs/session-workspace-binding.md +33 -0
- package/template/claude-task-manager/docs/skill-intent-resolution-design.md +72 -0
- package/template/claude-task-manager/docs/walle-mcp-supervisor-health.md +86 -0
- package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +24 -15
- package/template/claude-task-manager/docs/walle-session-history-hydration.md +114 -0
- package/template/claude-task-manager/docs/walle-session-input-queue.md +104 -0
- package/template/claude-task-manager/docs/walle-session-model-catalog.md +90 -0
- package/template/claude-task-manager/docs/walle-session-model-preferences.md +15 -6
- package/template/claude-task-manager/git-utils.js +897 -27
- package/template/claude-task-manager/lib/agent-capabilities.js +33 -0
- package/template/claude-task-manager/lib/agent-cli-cache.js +37 -7
- package/template/claude-task-manager/lib/agent-hooks-installer.js +26 -2
- package/template/claude-task-manager/lib/agent-presets.js +17 -1
- package/template/claude-task-manager/lib/all-sessions-query.js +108 -0
- package/template/claude-task-manager/lib/approval-ai-refinement.js +488 -0
- package/template/claude-task-manager/lib/approval-self-adapt.js +168 -0
- package/template/claude-task-manager/lib/async-semaphore.js +44 -0
- package/template/claude-task-manager/lib/auth-context.js +5 -0
- package/template/claude-task-manager/lib/auth-rate-limit.js +47 -4
- package/template/claude-task-manager/lib/auth-rules.js +29 -2
- package/template/claude-task-manager/lib/auto-approval-verifier.js +129 -16
- package/template/claude-task-manager/lib/background-llm.js +144 -17
- package/template/claude-task-manager/lib/branch-inventory.js +212 -0
- package/template/claude-task-manager/lib/claude-desktop-sessions.js +15 -3
- package/template/claude-task-manager/lib/coalesce-sync-frames.js +151 -0
- package/template/claude-task-manager/lib/codex-launch-health.js +762 -0
- package/template/claude-task-manager/lib/codex-transcript-pager.js +51 -0
- package/template/claude-task-manager/lib/codex-zst.js +124 -0
- package/template/claude-task-manager/lib/coding-agent-models.js +233 -30
- package/template/claude-task-manager/lib/connection-health.js +232 -0
- package/template/claude-task-manager/lib/conversation-blob-parser.js +42 -0
- package/template/claude-task-manager/lib/conversation-tail-merge.js +89 -26
- package/template/claude-task-manager/lib/ctm-session-context-api.js +39 -10
- package/template/claude-task-manager/lib/cursor-conversation-store.js +354 -0
- package/template/claude-task-manager/lib/db-owner-worker-client.js +315 -0
- package/template/claude-task-manager/lib/document-review.js +141 -6
- package/template/claude-task-manager/lib/escalation-review.js +152 -0
- package/template/claude-task-manager/lib/graceful-shutdown.js +159 -0
- package/template/claude-task-manager/lib/headless-term-service.js +678 -0
- package/template/claude-task-manager/lib/heavy-worker-fallback.js +38 -0
- package/template/claude-task-manager/lib/jsonl-conversation-parser.js +542 -0
- package/template/claude-task-manager/lib/jsonl-range-reader.js +112 -0
- package/template/claude-task-manager/lib/main-db-census.js +216 -0
- package/template/claude-task-manager/lib/message-pagination.js +106 -4
- package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +750 -26
- package/template/claude-task-manager/lib/mobile-auth-api.js +274 -7
- package/template/claude-task-manager/lib/mobile-auth-store.js +592 -10
- package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +15 -0
- package/template/claude-task-manager/lib/model-overview-brain-fallback.js +311 -0
- package/template/claude-task-manager/lib/model-overview-cache.js +141 -0
- package/template/claude-task-manager/lib/models-health-routing-notice.js +126 -0
- package/template/claude-task-manager/lib/node-pin-guard.js +93 -0
- package/template/claude-task-manager/lib/perf-tracker.js +242 -6
- package/template/claude-task-manager/lib/permission-match.js +76 -0
- package/template/claude-task-manager/lib/permission-sync.js +133 -20
- package/template/claude-task-manager/lib/process-title.js +35 -0
- package/template/claude-task-manager/lib/prompt-executions-query.js +25 -0
- package/template/claude-task-manager/lib/prompt-index-disk-cache.js +44 -0
- package/template/claude-task-manager/lib/prompt-intent.js +132 -0
- package/template/claude-task-manager/lib/provider-user-context.js +34 -0
- package/template/claude-task-manager/lib/read-pool-client.js +313 -0
- package/template/claude-task-manager/lib/readpool-breaker.js +31 -0
- package/template/claude-task-manager/lib/recent-sessions-breaker.js +12 -0
- package/template/claude-task-manager/lib/remote-feedback-client.js +72 -0
- package/template/claude-task-manager/lib/remote-relay-protocol.js +37 -4
- package/template/claude-task-manager/lib/remote-relay-store.js +159 -0
- package/template/claude-task-manager/lib/remote-submission-observer.js +278 -0
- package/template/claude-task-manager/lib/restart-guard.js +109 -0
- package/template/claude-task-manager/lib/restore-interruption-detector.js +439 -0
- package/template/claude-task-manager/lib/restore-policy.js +13 -0
- package/template/claude-task-manager/lib/restore-resume-batch.js +74 -0
- package/template/claude-task-manager/lib/restore-runtime.js +68 -0
- package/template/claude-task-manager/lib/restore-storm.js +34 -0
- package/template/claude-task-manager/lib/resume-cwd.js +36 -0
- package/template/claude-task-manager/lib/resume-preflight.js +313 -0
- package/template/claude-task-manager/lib/runtime-work-registry.js +444 -0
- package/template/claude-task-manager/lib/sanitize-openai-auth.js +31 -0
- package/template/claude-task-manager/lib/scheduler.js +21 -1
- package/template/claude-task-manager/lib/scrollback-snapshot-store.js +159 -0
- package/template/claude-task-manager/lib/serial-task-queue.js +64 -0
- package/template/claude-task-manager/lib/server-listeners.js +239 -0
- package/template/claude-task-manager/lib/session-capture.js +42 -7
- package/template/claude-task-manager/lib/session-content-backfill.js +131 -0
- package/template/claude-task-manager/lib/session-history.js +388 -43
- package/template/claude-task-manager/lib/session-host-manager.js +287 -0
- package/template/claude-task-manager/lib/session-image-refs.js +209 -0
- package/template/claude-task-manager/lib/session-jobs.js +399 -59
- package/template/claude-task-manager/lib/session-prompt-index.js +137 -0
- package/template/claude-task-manager/lib/session-restore.js +53 -0
- package/template/claude-task-manager/lib/session-standup.js +123 -23
- package/template/claude-task-manager/lib/session-state-bus.js +14 -0
- package/template/claude-task-manager/lib/session-stream.js +64 -16
- package/template/claude-task-manager/lib/session-timeline-summary.js +260 -0
- package/template/claude-task-manager/lib/session-token-usage.js +494 -0
- package/template/claude-task-manager/lib/session-workspace-binding.js +356 -0
- package/template/claude-task-manager/lib/setup-network-config.js +9 -0
- package/template/claude-task-manager/lib/size-cap.js +45 -0
- package/template/claude-task-manager/lib/size-cap.test.js +62 -0
- package/template/claude-task-manager/lib/skill-autocomplete.js +180 -1
- package/template/claude-task-manager/lib/skill-intent-resolver.js +304 -0
- package/template/claude-task-manager/lib/sqlite-driver.js +19 -3
- package/template/claude-task-manager/lib/standup-attention.js +7 -3
- package/template/claude-task-manager/lib/status-authority.js +39 -0
- package/template/claude-task-manager/lib/status-hooks.js +4 -0
- package/template/claude-task-manager/lib/storage-migration.js +235 -0
- package/template/claude-task-manager/lib/structured-capture.js +298 -0
- package/template/claude-task-manager/lib/sync-io-census.js +163 -0
- package/template/claude-task-manager/lib/tailscale-setup.js +6 -0
- package/template/claude-task-manager/lib/terminal-activity-evidence.js +33 -0
- package/template/claude-task-manager/lib/terminal-choice.js +364 -0
- package/template/claude-task-manager/lib/terminal-control-sanitize.js +17 -0
- package/template/claude-task-manager/lib/terminal-fingerprint.js +48 -0
- package/template/claude-task-manager/lib/terminal-output-flush.js +84 -0
- package/template/claude-task-manager/lib/timeline-order.js +122 -0
- package/template/claude-task-manager/lib/transcript-store.js +348 -43
- package/template/claude-task-manager/lib/transport-security.js +84 -1
- package/template/claude-task-manager/lib/wait-state.js +184 -0
- package/template/claude-task-manager/lib/walle-client.js +47 -5
- package/template/claude-task-manager/lib/walle-ctm-history.js +564 -4
- package/template/claude-task-manager/lib/walle-external-actions.js +135 -16
- package/template/claude-task-manager/lib/walle-history-hydration.js +46 -0
- package/template/claude-task-manager/lib/walle-native-health.js +403 -0
- package/template/claude-task-manager/lib/walle-repair.js +701 -0
- package/template/claude-task-manager/lib/walle-session-cache.js +109 -0
- package/template/claude-task-manager/lib/walle-session-context.js +57 -21
- package/template/claude-task-manager/lib/walle-session-model-catalog.js +34 -0
- package/template/claude-task-manager/lib/walle-supervisor.js +539 -63
- package/template/claude-task-manager/lib/walle-transcript.js +52 -0
- package/template/claude-task-manager/lib/worktree-active-sync.js +11 -7
- package/template/claude-task-manager/lib/worktree-cwd.js +32 -1
- package/template/claude-task-manager/package.json +1 -1
- package/template/claude-task-manager/prompt-harvest.js +89 -66
- package/template/claude-task-manager/providers/claude-code.js +51 -3
- package/template/claude-task-manager/providers/cursor.js +140 -45
- package/template/claude-task-manager/public/css/reviews.css +551 -61
- package/template/claude-task-manager/public/css/setup.css +191 -0
- package/template/claude-task-manager/public/css/walle-session.css +865 -10
- package/template/claude-task-manager/public/css/walle.css +154 -0
- package/template/claude-task-manager/public/designs/ai-providers-consolidation-v2.html +830 -0
- package/template/claude-task-manager/public/index.html +18516 -2058
- package/template/claude-task-manager/public/ipad.html +363 -0
- package/template/claude-task-manager/public/js/document-review-links.js +301 -0
- package/template/claude-task-manager/public/js/image-normalize.js +69 -36
- package/template/claude-task-manager/public/js/message-renderer.js +1265 -77
- package/template/claude-task-manager/public/js/prompts.js +66 -29
- package/template/claude-task-manager/public/js/reviews.js +901 -133
- package/template/claude-task-manager/public/js/session-activity-utils.js +11 -1
- package/template/claude-task-manager/public/js/session-search-utils.js +94 -10
- package/template/claude-task-manager/public/js/session-status-precedence.js +23 -5
- package/template/claude-task-manager/public/js/setup.js +1273 -176
- package/template/claude-task-manager/public/js/stream-view.js +691 -73
- package/template/claude-task-manager/public/js/terminal-reconciler.js +210 -0
- package/template/claude-task-manager/public/js/walle-session.js +2455 -158
- package/template/claude-task-manager/public/js/walle.js +455 -28
- package/template/claude-task-manager/public/m/app.css +2909 -262
- package/template/claude-task-manager/public/m/app.js +6601 -398
- package/template/claude-task-manager/public/m/claim.html +224 -17
- package/template/claude-task-manager/public/m/index.html +117 -21
- package/template/claude-task-manager/public/m/sw.js +3 -1
- package/template/claude-task-manager/public/manifest.json +2 -2
- package/template/claude-task-manager/public/prompts.html +30 -14
- package/template/claude-task-manager/queue-engine.js +507 -28
- package/template/claude-task-manager/scripts/repair-claude-session-images.js +27 -8
- package/template/claude-task-manager/server.js +14341 -2197
- package/template/claude-task-manager/session-integrity.js +160 -18
- package/template/claude-task-manager/session-search-ranking.js +1 -0
- package/template/claude-task-manager/session-utils.js +25 -5
- package/template/claude-task-manager/workers/approval-blocklist.js +96 -6
- package/template/claude-task-manager/workers/approval-widget-validator.js +14 -8
- package/template/claude-task-manager/workers/conversation-import-worker.js +11 -50
- package/template/claude-task-manager/workers/db-owner-worker.js +386 -0
- package/template/claude-task-manager/workers/harvest-worker.js +9 -55
- package/template/claude-task-manager/workers/headless-term-worker.js +9 -530
- package/template/claude-task-manager/workers/read-pool-worker.js +387 -0
- package/template/claude-task-manager/workers/scrollback-worker.js +11 -72
- package/template/claude-task-manager/workers/session-host-process.js +146 -0
- package/template/claude-task-manager/workers/session-integrity-worker.js +10 -54
- package/template/claude-task-manager/workers/state-detectors/base.js +18 -1
- package/template/claude-task-manager/workers/state-detectors/claude-code.js +182 -9
- package/template/claude-task-manager/workers/state-detectors/codex.js +150 -2
- package/template/claude-task-manager/workers/state-detectors/cursor.js +127 -0
- package/template/claude-task-manager/workers/state-detectors/gemini.js +21 -0
- package/template/claude-task-manager/workers/state-detectors/index.js +29 -0
- package/template/claude-task-manager/workers/state-detectors/opencode.js +103 -0
- package/template/docs/design/markdown-review-pane.md +206 -0
- package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +129 -38
- package/template/docs/designs/2026-05-20-mobile-worktree-finish-command.md +27 -0
- package/template/docs/designs/2026-05-22-ai-configuration-consolidation.md +248 -0
- package/template/docs/designs/ai-configuration-consolidation-mock.html +812 -0
- package/template/docs/private-memory-and-pii-policy.md +69 -0
- package/template/package.json +2 -1
- package/template/scripts/check-private-data.js +201 -0
- package/template/shared/sqlite-owner-guard.js +30 -0
- package/template/shared/sqlite-owner-write-queue.js +225 -0
- package/template/shared/sqlite-storage-policy.js +111 -0
- package/template/shared/sqlite-write-lock.js +428 -0
- package/template/wall-e/agent-runners/claude-code.js +5 -0
- package/template/wall-e/agent.js +166 -22
- package/template/wall-e/api-walle.js +524 -70
- package/template/wall-e/auth/provider-flows.js +11 -1
- package/template/wall-e/bin/walle-mcp-stdio.js +341 -17
- package/template/wall-e/brain.js +1614 -141
- package/template/wall-e/chat/attachment-blocks.js +96 -0
- package/template/wall-e/chat/attachments.js +2 -1
- package/template/wall-e/chat/capability-resolver.js +7 -7
- package/template/wall-e/chat/context-messages.js +28 -0
- package/template/wall-e/chat/conversation-frame.js +630 -0
- package/template/wall-e/chat/provider-messages.js +125 -0
- package/template/wall-e/chat.js +1002 -233
- package/template/wall-e/coding/acceptance-contract.js +170 -0
- package/template/wall-e/coding/acp-adapter.js +1 -1
- package/template/wall-e/coding/agent-catalog.js +3 -0
- package/template/wall-e/coding/artifact-store.js +93 -0
- package/template/wall-e/coding/capability-router.js +120 -0
- package/template/wall-e/coding/coding-run-controller.js +423 -0
- package/template/wall-e/coding/compaction-service.js +157 -12
- package/template/wall-e/coding/frontend-verification.js +258 -0
- package/template/wall-e/coding/lifecycle-hooks.js +75 -0
- package/template/wall-e/coding/local-preview-contract.js +157 -0
- package/template/wall-e/coding/permission-service.js +57 -13
- package/template/wall-e/coding/prompt-bundle.js +19 -1
- package/template/wall-e/coding/prompt-section-registry.js +227 -0
- package/template/wall-e/coding/provider-compat.js +15 -0
- package/template/wall-e/coding/runtime-events.js +224 -0
- package/template/wall-e/coding/runtime-mode.js +3 -0
- package/template/wall-e/coding/side-git-snapshot.js +160 -4
- package/template/wall-e/coding/snapshot-service.js +143 -1
- package/template/wall-e/coding/stream-processor.js +388 -34
- package/template/wall-e/coding/task-tool.js +141 -4
- package/template/wall-e/coding/tool-execution-controller.js +365 -0
- package/template/wall-e/coding/tool-registry.js +43 -5
- package/template/wall-e/coding/user-hooks.js +217 -0
- package/template/wall-e/coding-orchestrator.js +1330 -221
- package/template/wall-e/coding-prompts.js +20 -4
- package/template/wall-e/context/context-builder.js +15 -2
- package/template/wall-e/decision/confidence.js +1 -1
- package/template/wall-e/docs/coding-acceptance-contract.md +41 -0
- package/template/wall-e/docs/external-action-controller.md +26 -6
- package/template/wall-e/docs/telemetry-lifecycle.md +8 -2
- package/template/wall-e/embeddings.js +591 -53
- package/template/wall-e/external-action-controller.js +12 -0
- package/template/wall-e/http/auth.js +1 -0
- package/template/wall-e/http/chat-api.js +46 -11
- package/template/wall-e/http/model-admin.js +836 -34
- package/template/wall-e/lib/boot-profile.js +88 -0
- package/template/wall-e/lib/event-loop-monitor.js +93 -0
- package/template/wall-e/lib/service-health.js +194 -0
- package/template/wall-e/llm/anthropic.js +130 -5
- package/template/wall-e/llm/client.js +266 -63
- package/template/wall-e/llm/default-fallback.js +382 -0
- package/template/wall-e/llm/health.js +19 -0
- package/template/wall-e/llm/message-guard.js +78 -0
- package/template/wall-e/llm/model-catalog.js +252 -1
- package/template/wall-e/llm/openai.js +26 -4
- package/template/wall-e/llm/portkey-sync.js +654 -0
- package/template/wall-e/llm/provider-error.js +30 -2
- package/template/wall-e/llm/registry.js +5 -1
- package/template/wall-e/llm/request-compat.js +67 -0
- package/template/wall-e/loops/backfill.js +79 -23
- package/template/wall-e/loops/brain-optimize.js +67 -0
- package/template/wall-e/loops/ingest.js +25 -10
- package/template/wall-e/loops/question-digest.js +160 -0
- package/template/wall-e/loops/reflect.js +6 -4
- package/template/wall-e/loops/think.js +39 -12
- package/template/wall-e/mcp-server.js +318 -36
- package/template/wall-e/memory/ctm-context-client.js +52 -14
- package/template/wall-e/memory/ctm-operational-context.js +237 -0
- package/template/wall-e/memory/ctm-prompt-executions-client.js +128 -0
- package/template/wall-e/memory/ctm-session-context.js +111 -63
- package/template/wall-e/prompts/coding/deepseek.txt +3 -0
- package/template/wall-e/prompts/coding/gemini.txt +6 -0
- package/template/wall-e/prompts/coding/gpt.txt +6 -0
- package/template/wall-e/prompts/coding/local.txt +7 -0
- package/template/wall-e/runtime/decision-hooks.js +115 -0
- package/template/wall-e/runtime/devbox-gateway.js +82 -8
- package/template/wall-e/runtime/prompt-manifest.js +86 -0
- package/template/wall-e/runtime/tool-executor.js +269 -0
- package/template/wall-e/runtime/tool-result-envelope.js +138 -0
- package/template/wall-e/runtime/transcript-projection.js +60 -0
- package/template/wall-e/runtime/walle-runtime.js +224 -0
- package/template/wall-e/scripts/db-optimize/migrate.js +162 -0
- package/template/wall-e/scripts/db-optimize/recall-eval.js +117 -0
- package/template/wall-e/server.js +15 -0
- package/template/wall-e/session-files.js +9 -0
- package/template/wall-e/skills/_bundled/google-calendar/run.js +1 -1
- package/template/wall-e/skills/_bundled/gws-workspace/run.js +1 -1
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +76 -6
- package/template/wall-e/skills/claude-code-reader.js +7 -3
- package/template/wall-e/skills/script-skill-runner.js +10 -0
- package/template/wall-e/skills/skill-planner.js +38 -0
- package/template/wall-e/tools/builtin-middleware.js +19 -9
- package/template/wall-e/tools/local-tools.js +1428 -16
- package/template/wall-e/tools/permission-checker.js +73 -5
- package/template/wall-e/tools/question-manager.js +117 -7
- package/template/wall-e/training/harvester.js +12 -28
- package/template/wall-e/training/replay.js +25 -80
- package/template/website/index.html +10 -10
- package/template/wall-e/eval/ab-test.js +0 -203
- package/template/wall-e/eval/agent-runner.js +0 -772
- package/template/wall-e/eval/agent-scorer.js +0 -461
- package/template/wall-e/eval/aggregator.js +0 -414
- package/template/wall-e/eval/allowed-test-commands.js +0 -34
- package/template/wall-e/eval/benchmark-generator.js +0 -113
- package/template/wall-e/eval/benchmarks/chat-eval.json +0 -1662
- package/template/wall-e/eval/benchmarks/chat.json +0 -82
- package/template/wall-e/eval/benchmarks/coding-agent-real.json +0 -1
- package/template/wall-e/eval/benchmarks/coding-agent.json +0 -1581
- package/template/wall-e/eval/benchmarks/coding.json +0 -122
- package/template/wall-e/eval/benchmarks/memory-retrieval.json +0 -234
- package/template/wall-e/eval/benchmarks/reasoning.json +0 -82
- package/template/wall-e/eval/benchmarks/swebench-lite-30.json +0 -212
- package/template/wall-e/eval/benchmarks.js +0 -669
- package/template/wall-e/eval/cc-replay.js +0 -719
- package/template/wall-e/eval/chat-eval.js +0 -525
- package/template/wall-e/eval/check-keys.js +0 -15
- package/template/wall-e/eval/check-providers.js +0 -42
- package/template/wall-e/eval/codex-cli-baseline.js +0 -669
- package/template/wall-e/eval/coding-agent-real.js +0 -570
- package/template/wall-e/eval/context-compactor.js +0 -251
- package/template/wall-e/eval/debug-agent003.js +0 -68
- package/template/wall-e/eval/diagnostics.js +0 -216
- package/template/wall-e/eval/eval-orchestrator.js +0 -642
- package/template/wall-e/eval/evaluate.js +0 -202
- package/template/wall-e/eval/evaluator.js +0 -373
- package/template/wall-e/eval/exporter.js +0 -212
- package/template/wall-e/eval/fixtures/express-basic/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-basic/server.js +0 -115
- package/template/wall-e/eval/fixtures/express-basic/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy/server.js +0 -113
- package/template/wall-e/eval/fixtures/express-buggy/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy-items/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy-items/server.js +0 -112
- package/template/wall-e/eval/fixtures/express-buggy-items/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-buggy-search/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-buggy-search/server.js +0 -121
- package/template/wall-e/eval/fixtures/express-buggy-search/test.js +0 -83
- package/template/wall-e/eval/fixtures/express-rename-data/data.js +0 -34
- package/template/wall-e/eval/fixtures/express-rename-data/package.json +0 -9
- package/template/wall-e/eval/fixtures/express-rename-data/server.js +0 -97
- package/template/wall-e/eval/fixtures/express-rename-data/test.js +0 -88
- package/template/wall-e/eval/fixtures/express-xss/package.json +0 -12
- package/template/wall-e/eval/fixtures/express-xss/server.js +0 -90
- package/template/wall-e/eval/fixtures/express-xss/test.js +0 -67
- package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +0 -9
- package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +0 -9
- package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +0 -13
- package/template/wall-e/eval/fixtures/fullstack-app/package.json +0 -11
- package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +0 -137
- package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +0 -121
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +0 -71
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +0 -80
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +0 -45
- package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +0 -38
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +0 -23
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +0 -46
- package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +0 -99
- package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +0 -94
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +0 -19
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +0 -19
- package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +0 -50
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +0 -69
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +0 -23
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +0 -88
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +0 -75
- package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +0 -198
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +0 -34
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +0 -26
- package/template/wall-e/eval/fixtures/fullstack-app/server.js +0 -8
- package/template/wall-e/eval/fixtures/fullstack-app/test.js +0 -12
- package/template/wall-e/eval/fixtures/monorepo-basic/package.json +0 -8
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +0 -58
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +0 -46
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +0 -8
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +0 -64
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +0 -56
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +0 -116
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +0 -61
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +0 -62
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +0 -43
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +0 -11
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +0 -44
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +0 -43
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +0 -12
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +0 -5
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +0 -55
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +0 -29
- package/template/wall-e/eval/fixtures/monorepo-basic/test.js +0 -46
- package/template/wall-e/eval/fixtures/node-cli/index.js +0 -78
- package/template/wall-e/eval/fixtures/node-cli/package.json +0 -10
- package/template/wall-e/eval/fixtures/node-cli/test.js +0 -57
- package/template/wall-e/eval/fixtures/node-typed/package.json +0 -8
- package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +0 -31
- package/template/wall-e/eval/fixtures/node-typed/src/utils.js +0 -33
- package/template/wall-e/eval/fixtures/node-typed/test.js +0 -36
- package/template/wall-e/eval/fixtures/python-flask/app.py +0 -14
- package/template/wall-e/eval/fixtures/python-flask/requirements.txt +0 -2
- package/template/wall-e/eval/fixtures/python-flask/test_app.py +0 -25
- package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +0 -105
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +0 -101
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +0 -20
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +0 -32
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +0 -64
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +0 -6
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +0 -31
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +0 -18
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +0 -34
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +0 -104
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +0 -73
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +0 -134
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +0 -99
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +0 -63
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +0 -70
- package/template/wall-e/eval/fixtures/wall-e-subset/package.json +0 -10
- package/template/wall-e/eval/fixtures/wall-e-subset/test.js +0 -86
- package/template/wall-e/eval/harvester.js +0 -685
- package/template/wall-e/eval/head-to-head.js +0 -388
- package/template/wall-e/eval/humaneval-adapter.js +0 -321
- package/template/wall-e/eval/list-models.js +0 -31
- package/template/wall-e/eval/livecodebench-adapter.js +0 -291
- package/template/wall-e/eval/mail-integration.js +0 -443
- package/template/wall-e/eval/manifest.js +0 -186
- package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +0 -57
- package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +0 -149
- package/template/wall-e/eval/meta-harness/candidate-store.js +0 -117
- package/template/wall-e/eval/meta-harness/cli.js +0 -86
- package/template/wall-e/eval/meta-harness/domain-spec.js +0 -154
- package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +0 -84
- package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +0 -29
- package/template/wall-e/eval/meta-harness/experience-store.js +0 -174
- package/template/wall-e/eval/meta-harness/frontier.js +0 -96
- package/template/wall-e/eval/meta-harness/harness-interface.js +0 -90
- package/template/wall-e/eval/meta-harness/leakage-guard.js +0 -80
- package/template/wall-e/eval/meta-harness/optimizer.js +0 -207
- package/template/wall-e/eval/meta-harness/proposer-runner.js +0 -110
- package/template/wall-e/eval/meta-harness/reporting.js +0 -58
- package/template/wall-e/eval/meta-harness/telemetry.js +0 -27
- package/template/wall-e/eval/meta-harness/validation.js +0 -81
- package/template/wall-e/eval/promoter.js +0 -228
- package/template/wall-e/eval/provider-normalizer.js +0 -33
- package/template/wall-e/eval/replay.js +0 -395
- package/template/wall-e/eval/run-agent-benchmarks.js +0 -386
- package/template/wall-e/eval/run-codex-cli-baseline.js +0 -177
- package/template/wall-e/eval/run-coding-agent-real.js +0 -187
- package/template/wall-e/eval/run-eval.js +0 -435
- package/template/wall-e/eval/run-model-comparison.js +0 -142
- package/template/wall-e/eval/session-evaluator.js +0 -187
- package/template/wall-e/eval/session-miner.js +0 -207
- package/template/wall-e/eval/session-retrieval-benchmark.js +0 -150
- package/template/wall-e/eval/session-transcripts.js +0 -509
- package/template/wall-e/eval/shadow.js +0 -161
- package/template/wall-e/eval/swebench-adapter.js +0 -345
- package/template/wall-e/eval/swebench-docker.js +0 -192
- package/template/wall-e/eval/train.py +0 -320
- package/template/wall-e/eval/trainer.js +0 -232
- package/template/wall-e/eval/weekly-eval-loop.js +0 -241
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Read/parse pool worker.
|
|
4
|
+
//
|
|
5
|
+
// One of N identical workers managed by lib/read-pool-client.js. Its job is to
|
|
6
|
+
// take the CPU/IO-heavy *read* work off the main event loop: parsing JSONL
|
|
7
|
+
// conversation transcripts (often 1–10MB `JSON.parse`) and batch `fs.stat`
|
|
8
|
+
// scans. These block the main thread for seconds and stall keystroke echo when
|
|
9
|
+
// many sessions are open (see lib/perf-tracker.js + the [perf-lag] log).
|
|
10
|
+
//
|
|
11
|
+
// Deliberately DB-free: the main thread resolves file paths via fast indexed
|
|
12
|
+
// SQLite lookups and passes them in as payload, so a pool worker never opens a
|
|
13
|
+
// SQLite connection. That keeps the pool simple (no read-only WAL connection to
|
|
14
|
+
// manage) and side-effect-free — it only reads files and returns plain data.
|
|
15
|
+
//
|
|
16
|
+
// Speaks the same message protocol as workers/db-owner-worker.js (ready /
|
|
17
|
+
// request / response / status / close) so it can share the client transport.
|
|
18
|
+
|
|
19
|
+
const { parentPort } = require('node:worker_threads');
|
|
20
|
+
const fs = require('node:fs');
|
|
21
|
+
|
|
22
|
+
let ready = false;
|
|
23
|
+
let closing = false;
|
|
24
|
+
let active = null;
|
|
25
|
+
let enqueued = 0;
|
|
26
|
+
let completed = 0;
|
|
27
|
+
let failed = 0;
|
|
28
|
+
const queue = [];
|
|
29
|
+
|
|
30
|
+
// Lazy so the worker boots instantly and a parser require error surfaces per
|
|
31
|
+
// request (as a normal op failure) instead of crashing the whole pool at boot.
|
|
32
|
+
let parser = null;
|
|
33
|
+
function _parser() {
|
|
34
|
+
if (!parser) parser = require('../lib/jsonl-conversation-parser');
|
|
35
|
+
return parser;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Lazy require of the coding-agent model helpers (used by the resolveAgentModels op). DB-free
|
|
39
|
+
// except the Codex state DB it opens read-only — fine in a worker thread.
|
|
40
|
+
let _codingModels = null;
|
|
41
|
+
function _codingModelsMod() {
|
|
42
|
+
if (!_codingModels) _codingModels = require('../lib/coding-agent-models');
|
|
43
|
+
return _codingModels;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Opportunity A follow-up: a READ-ONLY connection used only for the recent-sessions
|
|
47
|
+
// rebuild (getAllSessionsData — a ~700ms window-function query). Running it here keeps
|
|
48
|
+
// it off the main event loop. Read-only + lazy: opened on first use, cached per dbPath,
|
|
49
|
+
// never writes, never changes journal_mode (WAL readers don't need to). This is the one
|
|
50
|
+
// DB touch the otherwise DB-free pool makes, scoped to a pure read.
|
|
51
|
+
let _roDb = null;
|
|
52
|
+
let _roDbPath = null;
|
|
53
|
+
function _readonlyDb(dbPath) {
|
|
54
|
+
if (!dbPath) throw new Error('getAllSessionsData requires a dbPath');
|
|
55
|
+
if (_roDb && _roDbPath === dbPath) return _roDb;
|
|
56
|
+
if (_roDb) { try { _roDb.close(); } catch {} _roDb = null; _roDbPath = null; }
|
|
57
|
+
const { loadSqliteDriver } = require('../lib/sqlite-driver');
|
|
58
|
+
const Database = loadSqliteDriver({ source: 'read-pool-worker' });
|
|
59
|
+
const d = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
60
|
+
d.pragma('busy_timeout = 5000');
|
|
61
|
+
_roDb = d;
|
|
62
|
+
_roDbPath = dbPath;
|
|
63
|
+
return _roDb;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _serializeError(err) {
|
|
67
|
+
return {
|
|
68
|
+
message: err && err.message ? err.message : String(err || 'unknown error'),
|
|
69
|
+
code: err && err.code ? err.code : undefined,
|
|
70
|
+
stack: err && err.stack ? String(err.stack) : undefined,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function _status() {
|
|
75
|
+
return { ready, active, running: !!active, pending: queue.length, enqueued, completed, failed };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function _postStatus() {
|
|
79
|
+
try { parentPort.postMessage({ type: 'status', status: _status() }); } catch {}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function _runOp(op, payload = {}) {
|
|
83
|
+
switch (op) {
|
|
84
|
+
case 'ping': {
|
|
85
|
+
// Test hook: an optional bounded delay lets tests hold a worker busy to
|
|
86
|
+
// exercise pool concurrency/admission control deterministically.
|
|
87
|
+
const sleepMs = Math.min(5000, Math.max(0, Number(payload.sleepMs) || 0));
|
|
88
|
+
if (sleepMs > 0) await new Promise((r) => setTimeout(r, sleepMs));
|
|
89
|
+
return { pong: true, ts: Number(payload.ts) || 0 };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
case 'statFiles': {
|
|
93
|
+
// Batch fs.stat off the main thread. apiSessionMessages and the scan jobs
|
|
94
|
+
// sum per-file sizes with synchronous statSync loops on the hot path.
|
|
95
|
+
const paths = Array.isArray(payload.paths) ? payload.paths : [];
|
|
96
|
+
let totalSize = 0;
|
|
97
|
+
const stats = paths.map((p) => {
|
|
98
|
+
try {
|
|
99
|
+
const st = fs.statSync(p);
|
|
100
|
+
totalSize += st.size;
|
|
101
|
+
return { path: p, exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
102
|
+
} catch {
|
|
103
|
+
return { path: p, exists: false, size: 0, mtimeMs: 0 };
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return { stats, totalSize };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
case 'resolveAgentModels': {
|
|
110
|
+
// Resolve agent model ids (+ optional Codex titles) off the main loop. The claude path
|
|
111
|
+
// reads/scans the transcript JSONL (statSync + tail read + JSON.parse); the codex path
|
|
112
|
+
// opens the Codex state DB read-only — both blocked the main event loop in
|
|
113
|
+
// syncCodingSessionModels. Returns RAW model names; the main thread maps them to the model
|
|
114
|
+
// registry (cheap, no fs/DB) so the registry cache stays single-sourced on main.
|
|
115
|
+
const mod = _codingModelsMod();
|
|
116
|
+
const homeDir = payload.homeDir || process.env.HOME;
|
|
117
|
+
const items = Array.isArray(payload.items) ? payload.items : [];
|
|
118
|
+
const results = items.map((it) => {
|
|
119
|
+
const out = { id: it.id };
|
|
120
|
+
try {
|
|
121
|
+
if (it.agentType === 'claude') {
|
|
122
|
+
out.modelName = mod.getClaudeSessionModelName({
|
|
123
|
+
jsonlPath: it.claudeJsonlPath,
|
|
124
|
+
homeDir,
|
|
125
|
+
sessionActivityMs: it.sessionActivityMs || 0,
|
|
126
|
+
}) || null;
|
|
127
|
+
} else if (it.agentType === 'codex') {
|
|
128
|
+
out.modelName = it.codexThreadId
|
|
129
|
+
? mod.getCodexThreadModel(it.codexThreadId, homeDir)
|
|
130
|
+
: mod.getCodexLatestModel(homeDir);
|
|
131
|
+
if (it.wantCodexTitle && it.codexThreadId) {
|
|
132
|
+
out.codexTitle = mod.getCodexThreadTitleById(it.codexThreadId, homeDir) || null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
out.error = e && e.message ? e.message : String(e);
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
});
|
|
140
|
+
return { results };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'parseSessionFiles': {
|
|
144
|
+
// Phase 2b consumer: read + parse a session's JSONL file set into the
|
|
145
|
+
// combined, chronologically-sorted message list the Conversation tab
|
|
146
|
+
// renders. The heavy fs.readFileSync + JSON.parse (up to 10MB) runs here,
|
|
147
|
+
// not on the main event loop. Returns the exact shape parseSessionFiles()
|
|
148
|
+
// returns on the main thread — parity is by construction (same function).
|
|
149
|
+
const files = Array.isArray(payload.files) ? payload.files : [];
|
|
150
|
+
return _parser().parseSessionFiles(files, payload.options || {});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'getAllSessionsData': {
|
|
154
|
+
// Opportunity A: run the recent-sessions rebuild query (~700ms) off the main
|
|
155
|
+
// event loop, on this worker's read-only connection. Same logic as
|
|
156
|
+
// db.getAllSessionsData() (shared lib/all-sessions-query). Returns plain rows.
|
|
157
|
+
const { queryAllSessionsData } = require('../lib/all-sessions-query');
|
|
158
|
+
return { rows: queryAllSessionsData(_readonlyDb(payload.dbPath)) };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
case 'listPromptExecutions': {
|
|
162
|
+
// Move the /api/prompt-executions list query OFF the main event loop. It is
|
|
163
|
+
// `SELECT * FROM prompt_executions ... LIMIT ?` where LIMIT can be up to 10000
|
|
164
|
+
// and each row carries large message_text — a CPU profile of the live primary
|
|
165
|
+
// showed a single .all() blocking ~3.9s on the request path. Same SQL as the
|
|
166
|
+
// main-thread handler (shared lib → parity by construction); the heavy read
|
|
167
|
+
// runs here on this worker's read-only connection.
|
|
168
|
+
const { queryPromptExecutions } = require('../lib/prompt-executions-query');
|
|
169
|
+
return { executions: queryPromptExecutions(_readonlyDb(payload.dbPath), payload) };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
case 'listRichWorktrees': {
|
|
173
|
+
// Move the worktree git fan-out OFF the main event loop. listRichWorktrees spawns
|
|
174
|
+
// ~4 git processes PER worktree (rev-list/status/log/unmerged); on a 37-worktree repo
|
|
175
|
+
// that's ~150 fork/execs whose synchronous spawn setup blocked the main loop for
|
|
176
|
+
// seconds every refresh (the dominant `(unknown)` freeze in the CPU profile). Running
|
|
177
|
+
// it here puts the spawn storm on a worker thread. Read-only fan-out only — the
|
|
178
|
+
// side-effecting autoRecover path stays on main.
|
|
179
|
+
const gitw = require('../git-utils');
|
|
180
|
+
const worktrees = await gitw.listRichWorktrees(payload.cwd, payload.opts || {});
|
|
181
|
+
return { worktrees: Array.isArray(worktrees) ? worktrees : [] };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
case 'loadCursorConversation': {
|
|
185
|
+
// Phase 3: run the cursor blob-graph enumeration + reconstruction OFF the main event
|
|
186
|
+
// loop (the cold cache-miss path; steady state is served from session_conversations).
|
|
187
|
+
// Worker-safe: cursor-conversation-store uses only better-sqlite3 (readonly) + fs/path.
|
|
188
|
+
const cs = require('../lib/cursor-conversation-store');
|
|
189
|
+
const store = cs.loadCursorConversationForSession(payload.options || {});
|
|
190
|
+
if (!store || !Array.isArray(store.messages)) return { store: null };
|
|
191
|
+
return {
|
|
192
|
+
store: {
|
|
193
|
+
messages: store.messages,
|
|
194
|
+
agentId: store.agentId || '',
|
|
195
|
+
name: store.name || '',
|
|
196
|
+
workspacePath: store.workspacePath || '',
|
|
197
|
+
lastUsedModel: store.lastUsedModel || '',
|
|
198
|
+
createdAtMs: store.createdAtMs || 0,
|
|
199
|
+
storeDbPath: store.storeDbPath || '',
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
case 'parseConversationBlob': {
|
|
205
|
+
// Move the session_conversations cache-blob parse OFF the main event loop. The
|
|
206
|
+
// JSON.parse (0.5–2MB, deeply nested) + codex-synthetic scan + timeline sort is
|
|
207
|
+
// 150–360ms on main per the [freeze-probe]; growing/active sessions re-parse it on
|
|
208
|
+
// every poll. Same function as the main-thread fallback (shared module) → parity by
|
|
209
|
+
// construction. Clone-in (string) + clone-out (array) is ~3ms even at 1.7MB.
|
|
210
|
+
const { parseConversationBlob } = require('../lib/conversation-blob-parser');
|
|
211
|
+
return { messages: parseConversationBlob(payload.messages) };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
case 'computeUserPromptIndex': {
|
|
215
|
+
// Phase 1: run the Queue Builder prompt-index compute (SELECT all user rows + sort
|
|
216
|
+
// + exclusions + sha1-per-prompt summary, ~460ms on a 328-prompt session) off the
|
|
217
|
+
// main event loop. Same logic as the main-thread fallback (shared module). Inputs
|
|
218
|
+
// (sourceIds, exclusion rows, codex-synthetic flag) are resolved on main.
|
|
219
|
+
const { computeUserPromptIndex } = require('../lib/session-prompt-index');
|
|
220
|
+
return computeUserPromptIndex(_readonlyDb(payload.dbPath), {
|
|
221
|
+
sourceIds: payload.sourceIds || [],
|
|
222
|
+
exclusionRows: payload.exclusionRows || [],
|
|
223
|
+
filterCodexSynthetic: payload.filterCodexSynthetic === true,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
case 'autoTitleCandidates': {
|
|
228
|
+
// Run auto-title's candidate SELECT OFF the main event loop. The query
|
|
229
|
+
// (ORDER BY imported_at DESC LIMIT 20, LEFT JOIN ctm_sessions to find
|
|
230
|
+
// untitled ones) full-scans + sorts the session_conversations table whose
|
|
231
|
+
// rows carry large `messages` blobs — synchronously on the main loop it was
|
|
232
|
+
// measured freezing it up to ~25s on cold Dropbox pages every 5 min (the
|
|
233
|
+
// dominant auto-title freeze). Off-thread the cold cost is invisible to the
|
|
234
|
+
// loop. (An imported_at index was measured: it removes the sort but trades
|
|
235
|
+
// sequential scan for random row fetches that page in MORE on cold Dropbox —
|
|
236
|
+
// net slower cold, negligible warm — so we offload instead of indexing.)
|
|
237
|
+
// Read-only WAL connection → side-effect-free; same SQL as the main fallback.
|
|
238
|
+
const conn = _readonlyDb(payload.dbPath);
|
|
239
|
+
const rows = conn.prepare(`
|
|
240
|
+
SELECT sc.ctm_session_id as session_id, sc.first_message, sc.user_msg_count
|
|
241
|
+
FROM session_conversations sc
|
|
242
|
+
LEFT JOIN ctm_sessions cs ON sc.ctm_session_id = cs.id
|
|
243
|
+
WHERE (cs.title IS NULL OR cs.title = '')
|
|
244
|
+
AND sc.user_msg_count >= 2
|
|
245
|
+
AND sc.first_message != ''
|
|
246
|
+
ORDER BY sc.imported_at DESC
|
|
247
|
+
LIMIT 20
|
|
248
|
+
`).all();
|
|
249
|
+
return { rows };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
case 'sessionIntegrityDetect': {
|
|
253
|
+
// Run session-integrity's READ-ONLY detection (the full-corpus mismatch scan +
|
|
254
|
+
// relink audit) OFF the db-owner worker. On cold Dropbox this scan takes ~60s;
|
|
255
|
+
// run on the single serial db-owner worker it MONOPOLIZES it, starving
|
|
256
|
+
// interactive writes onto the main thread where they stall on Dropbox I/O — the
|
|
257
|
+
// 30-min steady-state freeze. detectMismatches and auditRelink are both
|
|
258
|
+
// read-only, so they run safely on this worker's read-only connection. Only the
|
|
259
|
+
// rare recovery WRITES stay on the db-owner worker (applied by main when issues
|
|
260
|
+
// exist). Mirrors the read-only portions of session-integrity.runIntegrityCheck.
|
|
261
|
+
const roDb = _readonlyDb(payload.dbPath);
|
|
262
|
+
const integ = require('../session-integrity');
|
|
263
|
+
const { getAllSessionFiles } = require('../session-utils');
|
|
264
|
+
const issues = integ.detectMismatches(roDb, getAllSessionFiles);
|
|
265
|
+
let crossLinks = [];
|
|
266
|
+
try {
|
|
267
|
+
const { auditRelink } = require('../lib/relink-audit');
|
|
268
|
+
const audit = auditRelink({ db: roDb });
|
|
269
|
+
crossLinks = (audit.tabs || [])
|
|
270
|
+
.filter((t) => t.verdict === 'cross_linked')
|
|
271
|
+
.map((t) => ({
|
|
272
|
+
ctm_session_id: t.ctm_session_id,
|
|
273
|
+
label: t.label,
|
|
274
|
+
startup_target: t.startup_agent_id,
|
|
275
|
+
reason: t.details?.reason || 'cross_linked',
|
|
276
|
+
suggested_fix: t.details?.suggested_fix || null,
|
|
277
|
+
}));
|
|
278
|
+
} catch (e) {
|
|
279
|
+
// Relink audit is best-effort; detection issues are still returned.
|
|
280
|
+
}
|
|
281
|
+
return { issues, crossLinks };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
case 'auditRelink': {
|
|
285
|
+
// Run the relink audit (full agent_sessions + session_conversations scan + a
|
|
286
|
+
// per-agent cold-JSONL header/first-message read) OFF the main event loop. It runs
|
|
287
|
+
// synchronously at the TOP of restore (repairSafeRelinkSwaps) where, on cold Dropbox,
|
|
288
|
+
// the N×M fs reads froze the loop for tens of seconds. auditRelink is fully read-only,
|
|
289
|
+
// so it runs on this worker's read-only connection; the rare repair WRITES stay on the
|
|
290
|
+
// main thread (repairSafeRelinkSwaps consumes this result). Returns the full audit.
|
|
291
|
+
const { auditRelink } = require('../lib/relink-audit');
|
|
292
|
+
return auditRelink({ db: _readonlyDb(payload.dbPath) });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
case 'ctmSessionMemorySearch':
|
|
296
|
+
case 'ctmSessionMemoryContext':
|
|
297
|
+
case 'ctmSessionMemoryContextPack': {
|
|
298
|
+
// Run the Wall-E session-memory reads OFF the main event loop. These power the
|
|
299
|
+
// /api/ctm/session-memory/* endpoint that Wall-E MCP routing (walle_context_hint /
|
|
300
|
+
// lookup_context / context_pack / search_sessions) calls from EVERY active agent
|
|
301
|
+
// session. The work is brutal on the main thread: searchCtmSessions runs an FTS scan
|
|
302
|
+
// PLUS a `content LIKE '%q%'` scan over session_messages (220k+ rows) PLUS a
|
|
303
|
+
// `messages LIKE '%q%'` scan over the session_conversations blob column (tens of MB of
|
|
304
|
+
// JSON) PLUS a full JSON.parse of every matched conversation. A single search was
|
|
305
|
+
// measured blocking the CTM main loop 7.74s. Same shared wall-e module as the
|
|
306
|
+
// main-thread fallback → result parity by construction; the worker's read-only WAL
|
|
307
|
+
// connection makes it side-effect-free (better-sqlite3 readonly + fs only).
|
|
308
|
+
const ctx = require('../../wall-e/memory/ctm-session-context');
|
|
309
|
+
const args = (payload && payload.args) || {};
|
|
310
|
+
const conn = _readonlyDb(payload.dbPath);
|
|
311
|
+
if (op === 'ctmSessionMemorySearch') return ctx.searchCtmSessions({ ...args, db: conn });
|
|
312
|
+
if (op === 'ctmSessionMemoryContext') return ctx.getCtmSessionContext({ ...args, db: conn });
|
|
313
|
+
return ctx.buildContextPack({ ...args, db: conn });
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
case 'drain':
|
|
317
|
+
return { ok: true, ..._status() };
|
|
318
|
+
|
|
319
|
+
default: {
|
|
320
|
+
const err = new Error(`Unsupported read-pool op: ${op}`);
|
|
321
|
+
err.code = 'CTM_READ_POOL_UNSUPPORTED_OP';
|
|
322
|
+
throw err;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function _pump() {
|
|
328
|
+
if (active || closing) return;
|
|
329
|
+
const task = queue.shift();
|
|
330
|
+
if (!task) {
|
|
331
|
+
_postStatus();
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
active = task.op;
|
|
335
|
+
_postStatus();
|
|
336
|
+
Promise.resolve()
|
|
337
|
+
.then(() => _runOp(task.op, task.payload))
|
|
338
|
+
.then((result) => {
|
|
339
|
+
completed += 1;
|
|
340
|
+
parentPort.postMessage({ type: 'response', requestId: task.requestId, result });
|
|
341
|
+
}, (err) => {
|
|
342
|
+
failed += 1;
|
|
343
|
+
parentPort.postMessage({ type: 'response', requestId: task.requestId, error: _serializeError(err) });
|
|
344
|
+
})
|
|
345
|
+
.finally(() => {
|
|
346
|
+
active = null;
|
|
347
|
+
_pump();
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function _enqueue(msg) {
|
|
352
|
+
enqueued += 1;
|
|
353
|
+
queue.push({ requestId: msg.requestId, op: msg.op, payload: msg.payload || {} });
|
|
354
|
+
_pump();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function _close() {
|
|
358
|
+
closing = true;
|
|
359
|
+
queue.length = 0;
|
|
360
|
+
ready = false;
|
|
361
|
+
try { parentPort.postMessage({ type: 'closed' }); } catch {}
|
|
362
|
+
setImmediate(() => {
|
|
363
|
+
try { parentPort.close(); } catch {}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
parentPort.on('message', (msg) => {
|
|
368
|
+
if (!msg || typeof msg !== 'object') return;
|
|
369
|
+
if (msg.type === 'request') { _enqueue(msg); return; }
|
|
370
|
+
if (msg.type === 'status') { _postStatus(); return; }
|
|
371
|
+
if (msg.type === 'close') {
|
|
372
|
+
if (active) {
|
|
373
|
+
const interval = setInterval(() => {
|
|
374
|
+
if (active) return;
|
|
375
|
+
clearInterval(interval);
|
|
376
|
+
_close();
|
|
377
|
+
}, 10);
|
|
378
|
+
if (typeof interval.unref === 'function') interval.unref();
|
|
379
|
+
} else {
|
|
380
|
+
_close();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// No DB to open — signal ready immediately.
|
|
386
|
+
ready = true;
|
|
387
|
+
try { parentPort.postMessage({ type: 'ready', status: _status() }); } catch {}
|
|
@@ -1,77 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
// Handles SQLite scrollback writes off the main event loop.
|
|
3
|
-
// Opens its own better-sqlite3 connection (WAL mode supports concurrent access).
|
|
1
|
+
'use strict';
|
|
4
2
|
|
|
5
|
-
const { parentPort
|
|
6
|
-
const Database = require('better-sqlite3');
|
|
7
|
-
|
|
8
|
-
const SCROLLBACK_MAX_CHUNKS = 5000;
|
|
9
|
-
|
|
10
|
-
let db = null;
|
|
11
|
-
|
|
12
|
-
function getDb() {
|
|
13
|
-
if (db) return db;
|
|
14
|
-
db = new Database(workerData.dbPath);
|
|
15
|
-
db.pragma('journal_mode = WAL');
|
|
16
|
-
db.pragma('busy_timeout = 5000');
|
|
17
|
-
// Ensure scrollback_log table exists (may already exist from main thread)
|
|
18
|
-
db.prepare(`CREATE TABLE IF NOT EXISTS scrollback_log (
|
|
19
|
-
ctm_session_id TEXT NOT NULL,
|
|
20
|
-
chunk_seq INTEGER NOT NULL,
|
|
21
|
-
data TEXT NOT NULL,
|
|
22
|
-
PRIMARY KEY (ctm_session_id, chunk_seq)
|
|
23
|
-
)`).run();
|
|
24
|
-
const cols = db.prepare('PRAGMA table_info(scrollback_log)').all().map(c => c.name);
|
|
25
|
-
if (cols.includes('session_id') && !cols.includes('ctm_session_id')) {
|
|
26
|
-
db.exec('ALTER TABLE scrollback_log RENAME COLUMN session_id TO ctm_session_id');
|
|
27
|
-
}
|
|
28
|
-
return db;
|
|
29
|
-
}
|
|
3
|
+
const { parentPort } = require('node:worker_threads');
|
|
30
4
|
|
|
31
5
|
parentPort.on('message', (msg) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const d = getDb();
|
|
36
|
-
const insert = d.prepare('INSERT OR REPLACE INTO scrollback_log (ctm_session_id, chunk_seq, data) VALUES (?, ?, ?)');
|
|
37
|
-
const txn = d.transaction((items) => {
|
|
38
|
-
for (const c of items) insert.run(msg.sessionId, c.seq, c.data);
|
|
39
|
-
const maxSeq = items[items.length - 1]?.seq || 0;
|
|
40
|
-
if (maxSeq > SCROLLBACK_MAX_CHUNKS) {
|
|
41
|
-
const cutoff = maxSeq - SCROLLBACK_MAX_CHUNKS;
|
|
42
|
-
d.prepare('DELETE FROM scrollback_log WHERE ctm_session_id = ? AND chunk_seq < ?').run(msg.sessionId, cutoff);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
txn(msg.chunks);
|
|
46
|
-
if (msg.requestId) parentPort.postMessage({ type: 'appended', requestId: msg.requestId });
|
|
47
|
-
} catch (e) {
|
|
48
|
-
// Non-fatal — scrollback is best-effort
|
|
49
|
-
parentPort.postMessage({ type: 'error', op: 'append', error: e.message, requestId: msg.requestId });
|
|
50
|
-
}
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
case 'clear': {
|
|
54
|
-
try {
|
|
55
|
-
getDb().prepare('DELETE FROM scrollback_log WHERE ctm_session_id = ?').run(msg.sessionId);
|
|
56
|
-
if (msg.requestId) parentPort.postMessage({ type: 'cleared', requestId: msg.requestId });
|
|
57
|
-
} catch (e) {
|
|
58
|
-
parentPort.postMessage({ type: 'error', op: 'clear', error: e.message, requestId: msg.requestId });
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
case 'close': {
|
|
63
|
-
// Gracefully close DB connection before terminate() kills the thread.
|
|
64
|
-
// This ensures any in-flight WAL writes are completed and the connection
|
|
65
|
-
// is properly closed, preventing WAL corruption during shutdown.
|
|
66
|
-
if (db) { try { db.close(); } catch {} db = null; }
|
|
67
|
-
parentPort.postMessage({ type: 'closed' });
|
|
68
|
-
setImmediate(() => process.exit(0));
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
6
|
+
if (msg?.type === 'close') {
|
|
7
|
+
parentPort.postMessage({ type: 'closed' });
|
|
8
|
+
return;
|
|
71
9
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
10
|
+
parentPort.postMessage({
|
|
11
|
+
type: 'error',
|
|
12
|
+
op: msg?.type || 'unknown',
|
|
13
|
+
requestId: msg?.requestId,
|
|
14
|
+
error: 'scrollback DB writes are owned by the CTM DB owner worker',
|
|
15
|
+
});
|
|
77
16
|
});
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Per-session PTY host process. This owns node-pty for exactly one CTM
|
|
4
|
+
// terminal session and embeds the shared headless terminal service for the same
|
|
5
|
+
// session. The primary CTM process stays as the control plane; this process owns
|
|
6
|
+
// the native PTY resource so node-pty never crosses worker_threads boundaries.
|
|
7
|
+
|
|
8
|
+
process.env.CTM_PROCESS_ROLE = process.env.CTM_PROCESS_ROLE || 'ctm-session-host';
|
|
9
|
+
|
|
10
|
+
const pty = require('node-pty');
|
|
11
|
+
const { bindHeadlessTerminalService } = require('../lib/headless-term-service');
|
|
12
|
+
|
|
13
|
+
let sessionId = '';
|
|
14
|
+
let ptyProcess = null;
|
|
15
|
+
let ptyClosed = false;
|
|
16
|
+
let postExitShutdownTimer = null;
|
|
17
|
+
const POST_EXIT_HEADLESS_TTL_MS = 60000;
|
|
18
|
+
|
|
19
|
+
function send(msg) {
|
|
20
|
+
if (typeof process.send !== 'function') return;
|
|
21
|
+
try { process.send(msg); } catch {}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const headless = bindHeadlessTerminalService({
|
|
25
|
+
postMessage: (message) => send({ type: 'headless-message', sessionId: message.sessionId || sessionId, message }),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function hostError(message, details = {}) {
|
|
29
|
+
send({
|
|
30
|
+
type: 'host-error',
|
|
31
|
+
sessionId,
|
|
32
|
+
message: message && message.message ? message.message : String(message || 'session host error'),
|
|
33
|
+
...details,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function schedulePostExitShutdown() {
|
|
38
|
+
if (postExitShutdownTimer) return;
|
|
39
|
+
postExitShutdownTimer = setTimeout(() => {
|
|
40
|
+
headless.close();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}, POST_EXIT_HEADLESS_TTL_MS);
|
|
43
|
+
postExitShutdownTimer.unref?.();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function finishHostProcess() {
|
|
47
|
+
if (postExitShutdownTimer) {
|
|
48
|
+
clearTimeout(postExitShutdownTimer);
|
|
49
|
+
postExitShutdownTimer = null;
|
|
50
|
+
}
|
|
51
|
+
headless.close();
|
|
52
|
+
setTimeout(() => process.exit(0), 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handleHeadlessMessage(message) {
|
|
56
|
+
const payload = message || {};
|
|
57
|
+
try {
|
|
58
|
+
headless.handleMessage(payload);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
hostError(err, { code: 'headless_message_failed' });
|
|
61
|
+
}
|
|
62
|
+
if (ptyClosed && payload.type === 'destroy') {
|
|
63
|
+
finishHostProcess();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function startSession(msg) {
|
|
68
|
+
if (ptyProcess) return;
|
|
69
|
+
sessionId = String(msg.sessionId || '');
|
|
70
|
+
const cols = Number(msg.cols || 120) || 120;
|
|
71
|
+
const rows = Number(msg.rows || 30) || 30;
|
|
72
|
+
try {
|
|
73
|
+
headless.handleMessage({ type: 'create', sessionId, cols, rows });
|
|
74
|
+
ptyProcess = pty.spawn(msg.cmd, Array.isArray(msg.args) ? msg.args : [], {
|
|
75
|
+
name: msg.name || 'xterm-256color',
|
|
76
|
+
cols,
|
|
77
|
+
rows,
|
|
78
|
+
cwd: msg.cwd || process.cwd(),
|
|
79
|
+
env: msg.env || process.env,
|
|
80
|
+
});
|
|
81
|
+
send({ type: 'started', sessionId, pid: ptyProcess.pid, cols, rows });
|
|
82
|
+
ptyProcess.onData((data) => {
|
|
83
|
+
const text = String(data || '');
|
|
84
|
+
Promise.resolve(headless.handleMessage({ type: 'feed', sessionId, data: text }))
|
|
85
|
+
.catch((err) => hostError(err, { code: 'headless_feed_failed' }));
|
|
86
|
+
send({ type: 'data', sessionId, data: text });
|
|
87
|
+
});
|
|
88
|
+
ptyProcess.onExit(({ exitCode, signal }) => {
|
|
89
|
+
ptyClosed = true;
|
|
90
|
+
send({ type: 'exit', sessionId, exitCode, signal });
|
|
91
|
+
// Keep the embedded headless terminal alive after PTY exit. The parent
|
|
92
|
+
// process still needs one final serialize pass to persist/restore the
|
|
93
|
+
// complete terminal screen before it sends the destroy message.
|
|
94
|
+
schedulePostExitShutdown();
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
hostError(err, { code: 'spawn_failed' });
|
|
98
|
+
send({ type: 'exit', sessionId, exitCode: 1, signal: null, spawnFailed: true });
|
|
99
|
+
headless.close();
|
|
100
|
+
setTimeout(() => process.exit(1), 0);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function handleMessage(msg) {
|
|
105
|
+
if (!msg || typeof msg !== 'object') return;
|
|
106
|
+
switch (msg.type) {
|
|
107
|
+
case 'start':
|
|
108
|
+
startSession(msg);
|
|
109
|
+
break;
|
|
110
|
+
case 'input':
|
|
111
|
+
if (ptyProcess && !ptyClosed) ptyProcess.write(String(msg.data || ''));
|
|
112
|
+
break;
|
|
113
|
+
case 'resize': {
|
|
114
|
+
if (ptyProcess && !ptyClosed) {
|
|
115
|
+
const cols = Number(msg.cols || 0);
|
|
116
|
+
const rows = Number(msg.rows || 0);
|
|
117
|
+
if (cols > 0 && rows > 0) ptyProcess.resize(cols, rows);
|
|
118
|
+
}
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case 'kill':
|
|
122
|
+
if (ptyProcess && !ptyClosed) ptyProcess.kill();
|
|
123
|
+
else finishHostProcess();
|
|
124
|
+
break;
|
|
125
|
+
case 'headless':
|
|
126
|
+
handleHeadlessMessage(msg.message || {});
|
|
127
|
+
break;
|
|
128
|
+
case 'shutdown':
|
|
129
|
+
try { if (ptyProcess && !ptyClosed) ptyProcess.kill(); } catch {}
|
|
130
|
+
finishHostProcess();
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
process.on('message', handleMessage);
|
|
136
|
+
process.on('disconnect', finishHostProcess);
|
|
137
|
+
process.on('uncaughtException', (err) => {
|
|
138
|
+
hostError(err, { code: 'uncaught_exception' });
|
|
139
|
+
process.exit(1);
|
|
140
|
+
});
|
|
141
|
+
process.on('unhandledRejection', (err) => {
|
|
142
|
+
hostError(err, { code: 'unhandled_rejection' });
|
|
143
|
+
process.exit(1);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
send({ type: 'ready' });
|