create-walle 0.9.9 → 0.9.11
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 +1 -1
- package/bin/create-walle.js +63 -12
- package/package.json +1 -1
- package/template/CLAUDE.md +19 -0
- package/template/bin/dev.sh +46 -23
- package/template/bin/install-service.sh +50 -16
- package/template/bin/sqlite-snapshot.js +148 -0
- package/template/claude-task-manager/api-prompts.js +1057 -220
- package/template/claude-task-manager/api-reviews.js +12 -0
- package/template/claude-task-manager/approval-agent.js +406 -82
- package/template/claude-task-manager/bin/capture-pty.js +92 -0
- package/template/claude-task-manager/bin/claude-hook.js +42 -0
- package/template/claude-task-manager/bin/codex-notify.js +44 -0
- package/template/claude-task-manager/bin/ctm-hotkey.swift +118 -0
- package/template/claude-task-manager/bin/extract-fixture.js +142 -0
- package/template/claude-task-manager/bin/gemini-hook.js +41 -0
- package/template/claude-task-manager/bin/install-hotkey.sh +120 -0
- package/template/claude-task-manager/bin/restart-ctm.sh +25 -6
- package/template/claude-task-manager/db.js +1681 -130
- package/template/claude-task-manager/docs/session-management-architecture.md +554 -0
- package/template/claude-task-manager/fuzzy-utils.js +455 -0
- package/template/claude-task-manager/git-utils.js +680 -31
- package/template/claude-task-manager/lib/agent-capabilities.js +108 -0
- package/template/claude-task-manager/lib/agent-cli-cache.js +224 -0
- package/template/claude-task-manager/lib/agent-hooks-installer.js +416 -0
- package/template/claude-task-manager/lib/agent-presets.js +129 -0
- package/template/claude-task-manager/lib/auto-approval-verifier.js +199 -0
- package/template/claude-task-manager/lib/coding-agent-models.js +219 -0
- package/template/claude-task-manager/lib/compact-stitch.js +140 -0
- package/template/claude-task-manager/lib/devcontainer-wrapper.js +93 -0
- package/template/claude-task-manager/lib/fs-watcher.js +305 -0
- package/template/claude-task-manager/lib/git-status.js +130 -0
- package/template/claude-task-manager/lib/hook-executor.js +111 -0
- package/template/claude-task-manager/lib/launch-presets.js +103 -0
- package/template/claude-task-manager/lib/message-export.js +146 -0
- package/template/claude-task-manager/lib/message-pagination.js +47 -0
- package/template/claude-task-manager/lib/oauth-proxy-supervisor.js +133 -0
- package/template/claude-task-manager/lib/perf-tracker.js +58 -0
- package/template/claude-task-manager/lib/permission-sync.js +162 -0
- package/template/claude-task-manager/lib/project-config.js +122 -0
- package/template/claude-task-manager/lib/relink-audit.js +234 -0
- package/template/claude-task-manager/lib/sanitize-anthropic-auth.js +46 -0
- package/template/claude-task-manager/lib/scheduler.js +408 -0
- package/template/claude-task-manager/lib/server-config.js +73 -0
- package/template/claude-task-manager/lib/session-history.js +434 -0
- package/template/claude-task-manager/lib/session-jobs.js +582 -0
- package/template/claude-task-manager/lib/session-lineage.js +291 -0
- package/template/claude-task-manager/lib/session-state-bus.js +143 -0
- package/template/claude-task-manager/lib/session-stream.js +1189 -0
- package/template/claude-task-manager/lib/session-verify.js +215 -0
- package/template/claude-task-manager/lib/status-hooks-config.js +101 -0
- package/template/claude-task-manager/lib/status-hooks.js +101 -0
- package/template/claude-task-manager/lib/telemetry-receiver.js +403 -0
- package/template/claude-task-manager/lib/walle-client.js +176 -0
- package/template/claude-task-manager/lib/walle-supervisor.js +343 -0
- package/template/claude-task-manager/oauth-proxy.js +236 -0
- package/template/claude-task-manager/package.json +12 -2
- package/template/claude-task-manager/prompt-harvest.js +515 -48
- package/template/claude-task-manager/providers/aider.js +63 -0
- package/template/claude-task-manager/providers/amazon-q.js +56 -0
- package/template/claude-task-manager/providers/claude-code.js +115 -0
- package/template/claude-task-manager/providers/cline.js +52 -0
- package/template/claude-task-manager/providers/codex.js +186 -0
- package/template/claude-task-manager/providers/copilot.js +51 -0
- package/template/claude-task-manager/providers/cursor.js +67 -0
- package/template/claude-task-manager/providers/gemini.js +58 -0
- package/template/claude-task-manager/providers/index.js +65 -0
- package/template/claude-task-manager/providers/kimi.js +57 -0
- package/template/claude-task-manager/providers/opencode.js +61 -0
- package/template/claude-task-manager/public/css/listening.css +1481 -0
- package/template/claude-task-manager/public/css/prompts.css +143 -19
- package/template/claude-task-manager/public/css/reviews.css +212 -1
- package/template/claude-task-manager/public/css/setup.css +25 -0
- package/template/claude-task-manager/public/css/walle-session.css +175 -0
- package/template/claude-task-manager/public/css/walle.css +43 -2
- package/template/claude-task-manager/public/index.html +6928 -1568
- package/template/claude-task-manager/public/js/listening.js +1740 -0
- package/template/claude-task-manager/public/js/message-renderer.js +780 -0
- package/template/claude-task-manager/public/js/prompts.js +1451 -565
- package/template/claude-task-manager/public/js/reviewchat.js +498 -0
- package/template/claude-task-manager/public/js/reviews.js +152 -11
- package/template/claude-task-manager/public/js/session-activity-utils.js +111 -0
- package/template/claude-task-manager/public/js/session-search-utils.js +114 -0
- package/template/claude-task-manager/public/js/setup.js +1398 -28
- package/template/claude-task-manager/public/js/stream-view.js +1066 -0
- package/template/claude-task-manager/public/js/walle-core.js +177 -0
- package/template/claude-task-manager/public/js/walle-mcp.js +144 -0
- package/template/claude-task-manager/public/js/walle-session.js +428 -71
- package/template/claude-task-manager/public/js/walle.js +2454 -386
- package/template/claude-task-manager/public/prompts.html +679 -307
- package/template/claude-task-manager/public/setup.html +13 -1048
- package/template/claude-task-manager/public/sr-diagnostic.html +314 -0
- package/template/claude-task-manager/queue-engine.js +14 -0
- package/template/claude-task-manager/scripts/audit-relink.js +109 -0
- package/template/claude-task-manager/scripts/audit-sessions-db.js +294 -0
- package/template/claude-task-manager/scripts/repair-crosslinks.js +221 -0
- package/template/claude-task-manager/server.js +6095 -2131
- package/template/claude-task-manager/session-integrity.js +706 -0
- package/template/claude-task-manager/session-utils.js +66 -2
- package/template/claude-task-manager/workers/approval-blocklist.js +138 -0
- package/template/claude-task-manager/workers/approval-patterns.js +20 -0
- package/template/claude-task-manager/workers/approval-widget-validator.js +176 -0
- package/template/claude-task-manager/workers/conversation-import-worker.js +35 -0
- package/template/claude-task-manager/workers/headless-term-worker.js +444 -0
- package/template/claude-task-manager/workers/scrollback-worker.js +22 -6
- package/template/claude-task-manager/workers/session-integrity-worker.js +40 -0
- package/template/claude-task-manager/workers/state-detectors/base.js +54 -0
- package/template/claude-task-manager/workers/state-detectors/claude-code.js +39 -0
- package/template/claude-task-manager/workers/state-detectors/codex.js +62 -0
- package/template/claude-task-manager/workers/state-detectors/gemini.js +36 -0
- package/template/claude-task-manager/workers/state-detectors/index.js +46 -0
- package/template/claude-task-manager/workers/terminal-counters.js +75 -0
- package/template/docs/designs/2026-04-18-dictation-focus-redesign.md +358 -0
- package/template/package.json +4 -2
- package/template/wall-e/_workspace-templates/AGENTS.md +52 -0
- package/template/wall-e/_workspace-templates/BOOT.md +34 -0
- package/template/wall-e/_workspace-templates/HEARTBEAT.md +42 -0
- package/template/wall-e/_workspace-templates/IDENTITY.md +27 -0
- package/template/wall-e/_workspace-templates/SOUL.md +53 -0
- package/template/wall-e/_workspace-templates/TOOLS.md +34 -0
- package/template/wall-e/_workspace-templates/USER.md +37 -0
- package/template/wall-e/adapters/chatgpt.js +120 -0
- package/template/wall-e/adapters/chatgpt.plugin.json +17 -0
- package/template/wall-e/adapters/claude-web.js +75 -0
- package/template/wall-e/adapters/claude-web.plugin.json +17 -0
- package/template/wall-e/adapters/ctm.plugin.json +19 -0
- package/template/wall-e/adapters/plaintext.js +80 -0
- package/template/wall-e/adapters/plaintext.plugin.json +17 -0
- package/template/wall-e/adapters/registry.js +229 -0
- package/template/wall-e/adapters/slack.plugin.json +19 -0
- package/template/wall-e/agent-runners/claude-code.js +86 -0
- package/template/wall-e/agent-runners/codex.js +116 -0
- package/template/wall-e/agent-runners/contract.js +60 -0
- package/template/wall-e/agent-runners/gemini.js +96 -0
- package/template/wall-e/agent-runners/index.js +62 -0
- package/template/wall-e/agent-runners/multi-agent.js +202 -0
- package/template/wall-e/agent-runners/utils.js +165 -0
- package/template/wall-e/agent.js +407 -69
- package/template/wall-e/api-walle.js +1906 -238
- package/template/wall-e/auth/cooldown.js +166 -0
- package/template/wall-e/auth/key-rotation.js +231 -0
- package/template/wall-e/auth/profiles.js +144 -0
- package/template/wall-e/brain.js +1518 -122
- package/template/wall-e/channels/channel-retry.js +154 -0
- package/template/wall-e/channels/idle-poll-backoff.js +141 -0
- package/template/wall-e/channels/imessage-channel.plugin.json +21 -0
- package/template/wall-e/channels/registry.js +233 -0
- package/template/wall-e/channels/slack-channel.plugin.json +20 -0
- package/template/wall-e/channels/telegram-channel.plugin.json +20 -0
- package/template/wall-e/chat/attachment-storage.js +123 -0
- package/template/wall-e/chat/attachments.js +192 -0
- package/template/wall-e/chat/capability-resolver.js +92 -0
- package/template/wall-e/chat/code-review-context.js +192 -0
- package/template/wall-e/chat-fallback.js +174 -0
- package/template/wall-e/chat.js +915 -91
- package/template/wall-e/coding-context.js +142 -6
- package/template/wall-e/coding-orchestrator.js +1369 -224
- package/template/wall-e/coding-prompts.js +223 -0
- package/template/wall-e/coding-review.js +95 -51
- package/template/wall-e/compat.js +113 -0
- package/template/wall-e/context/compaction-hooks.js +117 -0
- package/template/wall-e/context/compactor.js +12 -0
- package/template/wall-e/context/context-builder.js +229 -22
- package/template/wall-e/context/query-sanitizer.js +81 -0
- package/template/wall-e/context/topic-matcher.js +36 -16
- package/template/wall-e/core-tasks.js +15 -3
- package/template/wall-e/db/write-audit.js +81 -0
- package/template/wall-e/dispatch/collapse-policy.js +91 -0
- package/template/wall-e/dispatch/source-registry.js +154 -0
- package/template/wall-e/docs/architecture.md +460 -0
- package/template/wall-e/embeddings.js +33 -3
- package/template/wall-e/eval/ab-test.js +203 -0
- package/template/wall-e/eval/agent-runner.js +629 -0
- package/template/wall-e/eval/agent-scorer.js +461 -0
- package/template/wall-e/eval/aggregator.js +310 -11
- package/template/wall-e/eval/benchmark-generator.js +93 -0
- package/template/wall-e/eval/benchmarks/chat-eval.json +586 -25
- package/template/wall-e/eval/benchmarks/coding-agent-real.json +1 -0
- package/template/wall-e/eval/benchmarks/coding-agent.json +2177 -0
- package/template/wall-e/eval/benchmarks/swebench-lite-30.json +212 -0
- package/template/wall-e/eval/benchmarks.js +119 -5
- package/template/wall-e/eval/cc-replay.js +718 -0
- package/template/wall-e/eval/chat-eval.js +18 -2
- package/template/wall-e/eval/check-keys.js +15 -0
- package/template/wall-e/eval/check-providers.js +42 -0
- package/template/wall-e/eval/coding-agent-real.js +568 -0
- package/template/wall-e/eval/context-compactor.js +251 -0
- package/template/wall-e/eval/debug-agent003.js +67 -0
- package/template/wall-e/eval/diagnostics.js +216 -0
- package/template/wall-e/eval/eval-orchestrator.js +430 -0
- package/template/wall-e/eval/fixtures/express-basic/package.json +9 -0
- package/template/wall-e/eval/fixtures/express-basic/server.js +115 -0
- package/template/wall-e/eval/fixtures/express-basic/test.js +83 -0
- package/template/wall-e/eval/fixtures/express-buggy/package.json +9 -0
- package/template/wall-e/eval/fixtures/express-buggy/server.js +113 -0
- package/template/wall-e/eval/fixtures/express-buggy/test.js +83 -0
- package/template/wall-e/eval/fixtures/express-buggy-items/package.json +9 -0
- package/template/wall-e/eval/fixtures/express-buggy-items/server.js +112 -0
- package/template/wall-e/eval/fixtures/express-buggy-items/test.js +83 -0
- package/template/wall-e/eval/fixtures/express-buggy-search/package.json +9 -0
- package/template/wall-e/eval/fixtures/express-buggy-search/server.js +121 -0
- package/template/wall-e/eval/fixtures/express-buggy-search/test.js +83 -0
- package/template/wall-e/eval/fixtures/express-rename-data/data.js +34 -0
- package/template/wall-e/eval/fixtures/express-rename-data/package.json +9 -0
- package/template/wall-e/eval/fixtures/express-rename-data/server.js +97 -0
- package/template/wall-e/eval/fixtures/express-rename-data/test.js +88 -0
- package/template/wall-e/eval/fixtures/express-xss/package.json +12 -0
- package/template/wall-e/eval/fixtures/express-xss/server.js +90 -0
- package/template/wall-e/eval/fixtures/express-xss/test.js +67 -0
- package/template/wall-e/eval/fixtures/express-xss/views/profile.ejs +9 -0
- package/template/wall-e/eval/fixtures/fullstack-app/config/default.js +9 -0
- package/template/wall-e/eval/fixtures/fullstack-app/config/test.js +13 -0
- package/template/wall-e/eval/fixtures/fullstack-app/package.json +11 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/css/style.css +137 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/index.html +46 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/app.js +121 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/auth.js +71 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/items.js +80 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/js/users.js +46 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/login.html +45 -0
- package/template/wall-e/eval/fixtures/fullstack-app/public/register.html +38 -0
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/migrate.js +23 -0
- package/template/wall-e/eval/fixtures/fullstack-app/scripts/seed.js +46 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/db.js +99 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/index.js +94 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/auth.js +19 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/middleware/logger.js +19 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/router.js +50 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/auth.js +69 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/health.js +23 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/items.js +88 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/routes/users.js +75 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/test.js +198 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/response.js +34 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server/utils/validate.js +26 -0
- package/template/wall-e/eval/fixtures/fullstack-app/server.js +8 -0
- package/template/wall-e/eval/fixtures/fullstack-app/test.js +12 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/package.json +8 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/data.js +58 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/middleware.js +46 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/package.json +8 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/routes.js +64 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/server.js +56 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/api/test.js +116 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/commands.js +61 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/index.js +62 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/output.js +43 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/package.json +11 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/cli/test.js +44 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/formatters.js +43 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/index.js +12 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/package.json +5 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/test.js +55 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/packages/shared/validators.js +29 -0
- package/template/wall-e/eval/fixtures/monorepo-basic/test.js +46 -0
- package/template/wall-e/eval/fixtures/node-cli/index.js +78 -0
- package/template/wall-e/eval/fixtures/node-cli/package.json +10 -0
- package/template/wall-e/eval/fixtures/node-cli/test.js +57 -0
- package/template/wall-e/eval/fixtures/node-typed/package.json +8 -0
- package/template/wall-e/eval/fixtures/node-typed/src/handlers.js +31 -0
- package/template/wall-e/eval/fixtures/node-typed/src/utils.js +33 -0
- package/template/wall-e/eval/fixtures/node-typed/test.js +36 -0
- package/template/wall-e/eval/fixtures/python-flask/app.py +14 -0
- package/template/wall-e/eval/fixtures/python-flask/requirements.txt +2 -0
- package/template/wall-e/eval/fixtures/python-flask/test_app.py +25 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/brain.js +105 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/aggregator.js +101 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/chat.json +20 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks/coding.json +32 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/benchmarks.js +64 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/package.json +6 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/server.js +31 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/test.js +18 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/fixtures/simple-project/utils.js +34 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/runner.js +104 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/scorer.js +73 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/eval/test.js +134 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/client.js +99 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/providers.js +63 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/llm/test.js +70 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/package.json +10 -0
- package/template/wall-e/eval/fixtures/wall-e-subset/test.js +86 -0
- package/template/wall-e/eval/harvester.js +177 -21
- package/template/wall-e/eval/head-to-head.js +38 -11
- package/template/wall-e/eval/humaneval-adapter.js +296 -0
- package/template/wall-e/eval/list-models.js +31 -0
- package/template/wall-e/eval/livecodebench-adapter.js +267 -0
- package/template/wall-e/eval/mail-integration.js +443 -0
- package/template/wall-e/eval/promoter.js +82 -0
- package/template/wall-e/eval/replay.js +14 -0
- package/template/wall-e/eval/run-agent-benchmarks.js +314 -0
- package/template/wall-e/eval/run-coding-agent-real.js +187 -0
- package/template/wall-e/eval/run-eval.js +425 -0
- package/template/wall-e/eval/run-model-comparison.js +141 -0
- package/template/wall-e/eval/session-evaluator.js +187 -0
- package/template/wall-e/eval/session-miner.js +207 -0
- package/template/wall-e/eval/session-transcripts.js +456 -0
- package/template/wall-e/eval/shadow.js +19 -2
- package/template/wall-e/eval/swebench-adapter.js +238 -0
- package/template/wall-e/eval/swebench-docker.js +192 -0
- package/template/wall-e/eval/weekly-eval-loop.js +241 -0
- package/template/wall-e/evaluation/agent-router.js +76 -0
- package/template/wall-e/evaluation/coding-quorum.js +325 -0
- package/template/wall-e/evaluation/index.js +2 -0
- package/template/wall-e/evaluation/learner.js +2 -1
- package/template/wall-e/evaluation/phase-detector.js +129 -0
- package/template/wall-e/evaluation/quorum-evaluator.js +1 -0
- package/template/wall-e/evaluation/quorum.js +3 -0
- package/template/wall-e/evaluation/router.js +26 -9
- package/template/wall-e/evaluation/scorecard.js +7 -0
- package/template/wall-e/evaluation/tier-selector.js +2 -1
- package/template/wall-e/extraction/contradiction.js +148 -4
- package/template/wall-e/extraction/entity-normalizer.js +488 -0
- package/template/wall-e/extraction/exchange-chunker.js +83 -0
- package/template/wall-e/extraction/heuristic-extractor.js +184 -0
- package/template/wall-e/extraction/i18n/en.json +18 -0
- package/template/wall-e/extraction/i18n/zh.json +17 -0
- package/template/wall-e/extraction/indexer.js +171 -0
- package/template/wall-e/extraction/knowledge-extractor.js +1 -0
- package/template/wall-e/extraction/noise-stripper.js +63 -0
- package/template/wall-e/fly.toml +1 -0
- package/template/wall-e/http/api-utils.js +100 -0
- package/template/wall-e/http/auth.js +46 -0
- package/template/wall-e/http/chat-api.js +377 -0
- package/template/wall-e/http/listening-api.js +441 -0
- package/template/wall-e/http/model-admin.js +586 -0
- package/template/wall-e/http/scheduler-api.js +49 -0
- package/template/wall-e/lib/activity-log.js +99 -0
- package/template/wall-e/lib/coalescer.js +46 -0
- package/template/wall-e/lib/config-watcher.js +95 -0
- package/template/wall-e/lib/recovery-logger.js +226 -0
- package/template/wall-e/lib/scheduler-failure-alert.js +127 -0
- package/template/wall-e/lib/scheduler.js +393 -22
- package/template/wall-e/listening/calendar.js +282 -0
- package/template/wall-e/listening/diarize.js +209 -0
- package/template/wall-e/listening/engine.js +299 -0
- package/template/wall-e/listening/notes.js +293 -0
- package/template/wall-e/listening/refine.js +65 -0
- package/template/wall-e/listening/storage.js +80 -0
- package/template/wall-e/listening/stt.js +251 -0
- package/template/wall-e/llm/anthropic.js +139 -18
- package/template/wall-e/llm/anthropic.plugin.json +23 -0
- package/template/wall-e/llm/claude-cli.js +208 -0
- package/template/wall-e/llm/claude-cli.plugin.json +23 -0
- package/template/wall-e/llm/client.js +72 -30
- package/template/wall-e/llm/codex-cli.js +210 -0
- package/template/wall-e/llm/codex-cli.plugin.json +23 -0
- package/template/wall-e/llm/deepseek.js +182 -0
- package/template/wall-e/llm/deepseek.plugin.json +22 -0
- package/template/wall-e/llm/google.js +104 -4
- package/template/wall-e/llm/google.plugin.json +22 -0
- package/template/wall-e/llm/index.js +1 -0
- package/template/wall-e/llm/lmstudio.js +40 -0
- package/template/wall-e/llm/lmstudio.plugin.json +23 -0
- package/template/wall-e/llm/mlx.plugin.json +24 -0
- package/template/wall-e/llm/ollama-setup.js +7 -1
- package/template/wall-e/llm/ollama.js +66 -8
- package/template/wall-e/llm/ollama.plugin.json +23 -0
- package/template/wall-e/llm/openai.js +30 -15
- package/template/wall-e/llm/openai.plugin.json +22 -0
- package/template/wall-e/llm/provider-detector.js +3 -6
- package/template/wall-e/llm/registry.js +248 -0
- package/template/wall-e/llm/retry.js +163 -0
- package/template/wall-e/llm/tool-adapter.js +50 -3
- package/template/wall-e/loops/backfill.js +149 -2
- package/template/wall-e/loops/boot.js +124 -0
- package/template/wall-e/loops/conversation-composer.js +129 -0
- package/template/wall-e/loops/deterministic-ordering.js +140 -0
- package/template/wall-e/loops/ingest.js +37 -0
- package/template/wall-e/loops/initiative.js +68 -7
- package/template/wall-e/loops/loop-directives.js +128 -0
- package/template/wall-e/loops/loop-precheck.js +96 -0
- package/template/wall-e/loops/loop-prompt-discipline.js +82 -0
- package/template/wall-e/loops/reflect.js +38 -4
- package/template/wall-e/loops/silent-reply-tokens.js +109 -0
- package/template/wall-e/loops/tasks.js +27 -2
- package/template/wall-e/loops/think.js +20 -4
- package/template/wall-e/loops/workspace-prompts.js +210 -0
- package/template/wall-e/mcp-server.js +146 -0
- package/template/wall-e/package.json +10 -2
- package/template/wall-e/plugins/activation-planner.js +161 -0
- package/template/wall-e/plugins/diagnostics.js +138 -0
- package/template/wall-e/plugins/manifest-loader.js +215 -0
- package/template/wall-e/plugins/manifest-types.js +66 -0
- package/template/wall-e/plugins/manifest-validator.js +241 -0
- package/template/wall-e/plugins/npm-scanner.js +191 -0
- package/template/wall-e/plugins/registry-base.js +81 -0
- package/template/wall-e/prompts/tool-workflows.md +51 -0
- package/template/wall-e/qa/README.md +59 -0
- package/template/wall-e/qa/scenario-format.md +75 -0
- package/template/wall-e/qa/scenarios/agents/instruction-followthrough.md +63 -0
- package/template/wall-e/qa/scenarios/channels/handoff-context-preservation.md +74 -0
- package/template/wall-e/qa/scenarios/character/persona-consistency.md +61 -0
- package/template/wall-e/runtime/devbox-gateway.js +38 -0
- package/template/wall-e/scripts/eval-embeddings.js +2 -5
- package/template/wall-e/scripts/smoke-coding-agent-jsonl.js +254 -0
- package/template/wall-e/search/bm25.js +97 -0
- package/template/wall-e/server.js +48 -8
- package/template/wall-e/skills/_bundled/coding-agent/run.js +42 -33
- package/template/wall-e/skills/_bundled/email-sync/mail-search.swift +237 -0
- package/template/wall-e/skills/_bundled/email-sync/run.js +81 -27
- package/template/wall-e/skills/_bundled/file-ingest/run.js +13 -8
- package/template/wall-e/skills/_bundled/glean-team-sync/run.js +1 -2
- package/template/wall-e/skills/_bundled/google-calendar/run.js +6 -23
- package/template/wall-e/skills/_bundled/gws-workspace/SKILL.md +76 -0
- package/template/wall-e/skills/_bundled/gws-workspace/run.js +401 -0
- package/template/wall-e/skills/_bundled/gws-workspace/setup.js +574 -0
- package/template/wall-e/skills/_bundled/listening/SKILL.md +26 -0
- package/template/wall-e/skills/_bundled/listening/run.js +80 -0
- package/template/wall-e/skills/_bundled/proactive-alerts/run.js +19 -3
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +82 -19
- package/template/wall-e/skills/internal-skill-registry.js +229 -0
- package/template/wall-e/skills/routing-reason-codes.js +82 -0
- package/template/wall-e/skills/sandbox-registry.js +104 -0
- package/template/wall-e/skills/skill-dispatch-decision.js +192 -0
- package/template/wall-e/skills/skill-executor.js +49 -6
- package/template/wall-e/skills/skill-fallback.js +146 -0
- package/template/wall-e/skills/skill-harness-registry.js +173 -0
- package/template/wall-e/skills/skill-loader.js +151 -220
- package/template/wall-e/skills/skill-planner.js +382 -62
- package/template/wall-e/skills/skill-snapshot.js +134 -0
- package/template/wall-e/skills/skill-validator.js +103 -1
- package/template/wall-e/skills/slack-ingest.js +26 -2
- package/template/wall-e/skills/trigger-registry.js +120 -0
- package/template/wall-e/telemetry.js +17 -1
- package/template/wall-e/tools/builtin-middleware.js +167 -0
- package/template/wall-e/tools/coding-events.js +68 -0
- package/template/wall-e/tools/coding-middleware.js +169 -0
- package/template/wall-e/tools/command-registry.js +237 -0
- package/template/wall-e/tools/edit-replacers.js +485 -0
- package/template/wall-e/tools/env-service.js +148 -0
- package/template/wall-e/tools/event-log.js +207 -0
- package/template/wall-e/tools/file-tracker.js +72 -0
- package/template/wall-e/tools/formatter.js +397 -0
- package/template/wall-e/tools/local-tools.js +929 -195
- package/template/wall-e/tools/lsp-client.js +701 -0
- package/template/wall-e/tools/lsp-language.js +137 -0
- package/template/wall-e/tools/lsp-servers.js +869 -0
- package/template/wall-e/tools/npm-service.js +180 -0
- package/template/wall-e/tools/patch.js +503 -0
- package/template/wall-e/tools/permission-checker.js +137 -34
- package/template/wall-e/tools/permission-rules.js +476 -0
- package/template/wall-e/tools/port-detector.js +81 -0
- package/template/wall-e/tools/project-detector.js +290 -0
- package/template/wall-e/tools/question-manager.js +213 -0
- package/template/wall-e/tools/session-sharing.js +231 -0
- package/template/wall-e/tools/shell-analyzer.js +524 -0
- package/template/wall-e/tools/slack-mcp.js +1 -0
- package/template/wall-e/tools/smart-truncation.js +100 -0
- package/template/wall-e/tools/snapshot.js +479 -0
- package/template/wall-e/utils/dedup.js +165 -0
- package/template/wall-e/utils/exporter.js +163 -0
- package/template/wall-e/utils/heartbeat-content.js +78 -0
- package/template/wall-e/utils/repair.js +145 -0
- package/template/website/index.html +2 -3
- package/template/claude-task-manager/workers/vterm-worker.js +0 -179
- package/template/wall-e/test/eval/aggregator.test.js +0 -180
- package/template/wall-e/test/eval/benchmarks.test.js +0 -373
- package/template/wall-e/test/eval/brain-shadow.test.js +0 -359
- package/template/wall-e/test/eval/evaluate.test.js +0 -221
- package/template/wall-e/test/eval/evaluator.test.js +0 -340
- package/template/wall-e/test/eval/exporter.test.js +0 -353
- package/template/wall-e/test/eval/harvester.test.js +0 -718
- package/template/wall-e/test/eval/head-to-head.test.js +0 -485
- package/template/wall-e/test/eval/promoter.test.js +0 -175
- package/template/wall-e/test/eval/shadow.test.js +0 -156
- package/template/wall-e/test/eval/trainer.test.js +0 -314
- package/template/wall-e/test/evaluation/complexity.test.js +0 -101
- package/template/wall-e/test/evaluation/learner.test.js +0 -271
- package/template/wall-e/test/evaluation/quorum.test.js +0 -372
- package/template/wall-e/test/evaluation/router.test.js +0 -269
- package/template/wall-e/test/evaluation/scorecard.test.js +0 -185
- package/template/wall-e/test/llm/anthropic.test.js +0 -172
- package/template/wall-e/test/llm/brain-models.test.js +0 -182
- package/template/wall-e/test/llm/client.test.js +0 -200
- package/template/wall-e/test/llm/google.test.js +0 -37
- package/template/wall-e/test/llm/health.test.js +0 -426
- package/template/wall-e/test/llm/integration.test.js +0 -285
- package/template/wall-e/test/llm/ollama.test.js +0 -50
- package/template/wall-e/test/llm/openai.test.js +0 -48
- package/template/wall-e/test/llm/tool-adapter.test.js +0 -297
- package/template/wall-e/test/training/aggregator.test.js +0 -180
- package/template/wall-e/test/training/brain-shadow.test.js +0 -359
- package/template/wall-e/test/training/evaluate.test.js +0 -221
- package/template/wall-e/test/training/evaluator.test.js +0 -340
- package/template/wall-e/test/training/exporter.test.js +0 -353
- package/template/wall-e/test/training/harvester.test.js +0 -718
- package/template/wall-e/test/training/promoter.test.js +0 -175
- package/template/wall-e/test/training/shadow.test.js +0 -156
- package/template/wall-e/test/training/trainer.test.js +0 -314
- package/template/wall-e/tests/adapter-base.test.js +0 -20
- package/template/wall-e/tests/adapter-ctm.test.js +0 -122
- package/template/wall-e/tests/adapter-slack.test.js +0 -98
- package/template/wall-e/tests/agent-api.test.js +0 -256
- package/template/wall-e/tests/api-walle.test.js +0 -222
- package/template/wall-e/tests/backfill.test.js +0 -126
- package/template/wall-e/tests/brain.test.js +0 -603
- package/template/wall-e/tests/channels.test.js +0 -104
- package/template/wall-e/tests/chat.test.js +0 -103
- package/template/wall-e/tests/coding-agent-integration.test.js +0 -240
- package/template/wall-e/tests/coding-context.test.js +0 -212
- package/template/wall-e/tests/coding-orchestrator.test.js +0 -298
- package/template/wall-e/tests/coding-review.test.js +0 -141
- package/template/wall-e/tests/compactor.test.js +0 -321
- package/template/wall-e/tests/confidence.test.js +0 -134
- package/template/wall-e/tests/context-builder.test.js +0 -222
- package/template/wall-e/tests/contradiction.test.js +0 -217
- package/template/wall-e/tests/embeddings.test.js +0 -378
- package/template/wall-e/tests/event-bus.test.js +0 -74
- package/template/wall-e/tests/ingest.test.js +0 -113
- package/template/wall-e/tests/initiative.test.js +0 -354
- package/template/wall-e/tests/mcp-client.test.js +0 -71
- package/template/wall-e/tests/mcp-inject.test.js +0 -68
- package/template/wall-e/tests/mcp-server.test.js +0 -219
- package/template/wall-e/tests/ollama-setup.test.js +0 -81
- package/template/wall-e/tests/proactive-alerts.test.js +0 -140
- package/template/wall-e/tests/provider-availability.test.js +0 -231
- package/template/wall-e/tests/provider-detector.test.js +0 -127
- package/template/wall-e/tests/quorum-evaluator.test.js +0 -277
- package/template/wall-e/tests/reflect.test.js +0 -103
- package/template/wall-e/tests/scheduler.test.js +0 -546
- package/template/wall-e/tests/scorecard-evolution.test.js +0 -96
- package/template/wall-e/tests/self-critique.test.js +0 -162
- package/template/wall-e/tests/server.test.js +0 -111
- package/template/wall-e/tests/session-persistence.test.js +0 -331
- package/template/wall-e/tests/skills.test.js +0 -198
- package/template/wall-e/tests/slack-ingest.test.js +0 -103
- package/template/wall-e/tests/think.test.js +0 -454
- package/template/wall-e/tests/tier-selector.test.js +0 -109
- package/template/wall-e/tests/user-signals.test.js +0 -73
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ An always-on AI agent that learns from your Slack, email, calendar, and coding s
|
|
|
23
23
|
- **Second Brain** — Automatically ingests your digital life into a searchable memory store with full-text search, knowledge extraction, and pattern detection
|
|
24
24
|
- **Proactive Intelligence** — Surfaces time-sensitive items, suggests actions, and delivers morning briefings and weekly reflections without being asked
|
|
25
25
|
- **Chat with Tools** — Talk to Wall-E in the browser — it can search your memories, look up people, run skills, and call external tools via MCP (Slack, Glean, etc.)
|
|
26
|
-
- **
|
|
26
|
+
- **19 Bundled Skills** — Morning briefing, weekly reflection, proactive alerts, Slack monitoring, email sync, calendar integration, coding agent, model training, model pricing sync, and more
|
|
27
27
|
- **Multi-Model** — Works with Claude, GPT, Gemini, and local models via Ollama with smart routing
|
|
28
28
|
- **Skill Management GUI** — Search, filter, create, edit, and monitor skills from the browser with rich cards, config forms, execution history, export/import, and pre-flight validation
|
|
29
29
|
- **Multi-Device** — Share your brain across machines via Dropbox or iCloud
|
package/bin/create-walle.js
CHANGED
|
@@ -144,12 +144,14 @@ function install(targetDir) {
|
|
|
144
144
|
console.log(` Installing dependencies...\n`);
|
|
145
145
|
npmInstall(targetDir);
|
|
146
146
|
|
|
147
|
+
compileHotkeyDaemon(targetDir);
|
|
148
|
+
|
|
147
149
|
// .env
|
|
148
150
|
const envLines = [
|
|
149
151
|
`# Wall-E configuration — generated ${new Date().toISOString().split('T')[0]}`,
|
|
150
152
|
`# Finish setup at http://localhost:${port}/setup.html`,
|
|
151
153
|
'',
|
|
152
|
-
`WALLE_OWNER_NAME
|
|
154
|
+
`WALLE_OWNER_NAME="${ownerName.replace(/"/g, '\\"')}"`,
|
|
153
155
|
'# ANTHROPIC_API_KEY=',
|
|
154
156
|
'',
|
|
155
157
|
'# AI Provider: anthropic, openai, google, ollama',
|
|
@@ -247,6 +249,8 @@ function update() {
|
|
|
247
249
|
console.log(` Installing dependencies...\n`);
|
|
248
250
|
npmInstall(dir);
|
|
249
251
|
|
|
252
|
+
compileHotkeyDaemon(dir);
|
|
253
|
+
|
|
250
254
|
// 7. Start again
|
|
251
255
|
console.log(`\n Starting Wall-E...`);
|
|
252
256
|
startForegroundOrService(dir, port);
|
|
@@ -331,9 +335,8 @@ function stopQuiet(dir, port) {
|
|
|
331
335
|
while (Date.now() < deadline) {
|
|
332
336
|
try {
|
|
333
337
|
execFileSync('curl', ['-s', '--max-time', '1', `http://localhost:${port}/api/services/status`], { encoding: 'utf8', timeout: 2000 });
|
|
334
|
-
// Still running —
|
|
335
|
-
|
|
336
|
-
while (Date.now() < waitUntil) { /* spin */ }
|
|
338
|
+
// Still running — sleep briefly (avoid CPU spin)
|
|
339
|
+
try { execFileSync('sleep', ['0.5'], { timeout: 2000 }); } catch {}
|
|
337
340
|
} catch {
|
|
338
341
|
break; // Port is free
|
|
339
342
|
}
|
|
@@ -370,15 +373,18 @@ function installService(walleDir, port) {
|
|
|
370
373
|
fs.mkdirSync(plistDir, { recursive: true });
|
|
371
374
|
const plistPath = path.join(plistDir, `${LABEL}.plist`);
|
|
372
375
|
|
|
373
|
-
|
|
374
|
-
|
|
376
|
+
const xmlEsc = (s) => String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
377
|
+
const nodeBinDir = path.dirname(nodePath);
|
|
378
|
+
let envDict = ` <key>PATH</key>\n <string>${xmlEsc(nodeBinDir)}:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>\n`;
|
|
379
|
+
envDict += ` <key>HOME</key>\n <string>${xmlEsc(process.env.HOME)}</string>\n`;
|
|
375
380
|
envDict += ` <key>CTM_PORT</key>\n <string>${port}</string>\n`;
|
|
381
|
+
envDict += ` <key>CTM_MANAGED_BY_LAUNCHD</key>\n <string>1</string>\n`;
|
|
376
382
|
try {
|
|
377
383
|
const envFile = fs.readFileSync(path.join(walleDir, '.env'), 'utf8');
|
|
378
384
|
for (const line of envFile.split('\n')) {
|
|
379
385
|
const m = line.match(/^\s*([^#=\s]+)\s*=\s*(.+?)\s*$/);
|
|
380
386
|
if (m && m[1] !== 'CTM_PORT' && m[1] !== 'PATH' && m[1] !== 'HOME') {
|
|
381
|
-
envDict += ` <key>${m[1]}</key>\n <string>${m[2]}</string>\n`;
|
|
387
|
+
envDict += ` <key>${xmlEsc(m[1])}</key>\n <string>${xmlEsc(m[2])}</string>\n`;
|
|
382
388
|
}
|
|
383
389
|
}
|
|
384
390
|
} catch {}
|
|
@@ -402,11 +408,16 @@ ${envDict} </dict>
|
|
|
402
408
|
<key>RunAtLoad</key>
|
|
403
409
|
<true/>
|
|
404
410
|
<key>KeepAlive</key>
|
|
405
|
-
<
|
|
411
|
+
<dict>
|
|
412
|
+
<key>SuccessfulExit</key>
|
|
413
|
+
<false/>
|
|
414
|
+
</dict>
|
|
415
|
+
<key>ThrottleInterval</key>
|
|
416
|
+
<integer>5</integer>
|
|
406
417
|
<key>StandardOutPath</key>
|
|
407
|
-
<string>${logDir}/
|
|
418
|
+
<string>${logDir}/ctm.log</string>
|
|
408
419
|
<key>StandardErrorPath</key>
|
|
409
|
-
<string>${logDir}/
|
|
420
|
+
<string>${logDir}/ctm.err</string>
|
|
410
421
|
</dict>
|
|
411
422
|
</plist>`;
|
|
412
423
|
|
|
@@ -414,10 +425,34 @@ ${envDict} </dict>
|
|
|
414
425
|
try { execFileSync('launchctl', ['unload', plistPath], { stdio: 'ignore' }); } catch {}
|
|
415
426
|
execFileSync('launchctl', ['load', plistPath]);
|
|
416
427
|
} else {
|
|
417
|
-
|
|
428
|
+
// Linux/other: spawn with a restart-on-crash wrapper shell script
|
|
429
|
+
const watchdogScript = path.join(walleDir, 'bin', 'watchdog.sh');
|
|
430
|
+
const watchdogContent = `#!/bin/bash
|
|
431
|
+
# Auto-restart CTM on crash. Clean exit (code 0) stops the watchdog.
|
|
432
|
+
CRASHES=0
|
|
433
|
+
while true; do
|
|
434
|
+
"${process.execPath}" claude-task-manager/server.js >> "${logDir}/ctm.log" 2>> "${logDir}/ctm.err"
|
|
435
|
+
EXIT_CODE=$?
|
|
436
|
+
if [ $EXIT_CODE -eq 0 ]; then
|
|
437
|
+
echo "[watchdog] Clean exit (code 0), stopping." >> "${logDir}/ctm.log"
|
|
438
|
+
break
|
|
439
|
+
fi
|
|
440
|
+
CRASHES=$((CRASHES + 1))
|
|
441
|
+
echo "[watchdog] CTM exited with code $EXIT_CODE (crash #$CRASHES), restarting in 5s..." >> "${logDir}/ctm.log"
|
|
442
|
+
if [ $CRASHES -ge 5 ]; then
|
|
443
|
+
echo "[watchdog] Too many crashes ($CRASHES), giving up." >> "${logDir}/ctm.log"
|
|
444
|
+
break
|
|
445
|
+
fi
|
|
446
|
+
sleep 5
|
|
447
|
+
done
|
|
448
|
+
`;
|
|
449
|
+
fs.mkdirSync(path.join(walleDir, 'bin'), { recursive: true });
|
|
450
|
+
fs.writeFileSync(watchdogScript, watchdogContent, { mode: 0o755 });
|
|
451
|
+
|
|
452
|
+
const child = spawn('bash', [watchdogScript], {
|
|
418
453
|
cwd: walleDir,
|
|
419
454
|
detached: true,
|
|
420
|
-
stdio:
|
|
455
|
+
stdio: 'ignore',
|
|
421
456
|
env: { ...process.env, CTM_PORT: port },
|
|
422
457
|
});
|
|
423
458
|
child.unref();
|
|
@@ -505,6 +540,22 @@ function detectTimezone() {
|
|
|
505
540
|
return 'UTC';
|
|
506
541
|
}
|
|
507
542
|
|
|
543
|
+
function compileHotkeyDaemon(walleDir) {
|
|
544
|
+
if (process.platform !== 'darwin') return; // macOS only
|
|
545
|
+
const swiftSource = path.join(walleDir, 'claude-task-manager', 'bin', 'ctm-hotkey.swift');
|
|
546
|
+
if (!fs.existsSync(swiftSource)) return;
|
|
547
|
+
const binary = path.join(process.env.HOME, '.local', 'bin', 'ctm-hotkey');
|
|
548
|
+
try {
|
|
549
|
+
fs.mkdirSync(path.dirname(binary), { recursive: true });
|
|
550
|
+
execFileSync('swiftc', ['-O', '-o', binary, swiftSource, '-framework', 'Cocoa'], { timeout: 120000, stdio: 'pipe' });
|
|
551
|
+
fs.chmodSync(binary, 0o755);
|
|
552
|
+
console.log(` ${GREEN}Compiled hotkey daemon${RESET} ${DIM}(${binary})${RESET}`);
|
|
553
|
+
} catch {
|
|
554
|
+
// swiftc not available or compilation failed — non-fatal
|
|
555
|
+
console.log(` ${DIM}Skipped hotkey daemon (Swift compiler not available)${RESET}`);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
508
559
|
function copyRecursive(src, dest) {
|
|
509
560
|
const stat = fs.statSync(src);
|
|
510
561
|
if (stat.isDirectory()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-walle",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.11",
|
|
4
4
|
"description": "CTM + Wall-E \u2014 AI coding dashboard and personal digital twin agent. Multi-agent terminal for Claude Code, Codex, Gemini & Aider, plus prompt editor, task queue, and an agent that learns from Slack, email & calendar.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-walle": "bin/create-walle.js"
|
package/template/CLAUDE.md
CHANGED
|
@@ -24,6 +24,18 @@ When developing CTM or Wall-E code:
|
|
|
24
24
|
4. Test ONLY against your dev port, never 3456
|
|
25
25
|
5. Only restart primary when the user explicitly asks — and ask for confirmation first
|
|
26
26
|
|
|
27
|
+
## Testing
|
|
28
|
+
|
|
29
|
+
Both projects use Node.js built-in test runner with `--test-force-exit` to prevent hangs:
|
|
30
|
+
- **Wall-E**: `cd wall-e && npm test`
|
|
31
|
+
- **CTM**: `cd claude-task-manager && npm test`
|
|
32
|
+
|
|
33
|
+
When writing new tests, follow these rules to avoid handle leaks and cross-test contamination:
|
|
34
|
+
- **Never set `process.env` at module top level** — set in `before()`, restore in `after()`
|
|
35
|
+
- **Close every DB connection you open** — store `readDb` handles in module scope, close in `after()`/teardown
|
|
36
|
+
- **Call `brain.closeDb()` before `brain.initDb()`** in tests that reinitialize the brain singleton
|
|
37
|
+
- **Don't change `journal_mode`** on readonly connections (causes SQLITE_BUSY against WAL dbs)
|
|
38
|
+
|
|
27
39
|
## Publishing to npm (create-walle)
|
|
28
40
|
|
|
29
41
|
When publishing with `/publish`:
|
|
@@ -32,3 +44,10 @@ When publishing with `/publish`:
|
|
|
32
44
|
3. Bump version in both `create-walle/package.json` AND root `package.json`
|
|
33
45
|
4. Run `bash build.sh` and verify file count
|
|
34
46
|
5. Ask for confirmation before `npm publish`
|
|
47
|
+
|
|
48
|
+
## Architecture reference
|
|
49
|
+
|
|
50
|
+
For Wall-E architecture (loops, brain DB, scheduler, skills, channels, anti-patterns):
|
|
51
|
+
read `wall-e/docs/architecture.md` before making non-trivial changes. The
|
|
52
|
+
"Non-goals" section is a guardrail — coordinate via data, not via
|
|
53
|
+
manager-of-managers.
|
package/template/bin/dev.sh
CHANGED
|
@@ -3,50 +3,64 @@
|
|
|
3
3
|
# Primary instance stays untouched. Ctrl+C to stop.
|
|
4
4
|
#
|
|
5
5
|
# Usage:
|
|
6
|
-
# bash bin/dev.sh # Start dev instance
|
|
7
|
-
# bash bin/dev.sh --refresh #
|
|
8
|
-
# bash bin/dev.sh --fresh #
|
|
6
|
+
# bash bin/dev.sh # Start dev instance with fresh empty DBs
|
|
7
|
+
# bash bin/dev.sh --refresh # Explicitly copy production DBs before starting
|
|
8
|
+
# bash bin/dev.sh --fresh # Reset to empty DBs before starting
|
|
9
9
|
|
|
10
10
|
set -e
|
|
11
11
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
12
12
|
DEV_DIR="${WALLE_DEV_DIR:-/tmp/walle-dev}"
|
|
13
13
|
DEV_CTM_PORT="${DEV_CTM_PORT:-4000}"
|
|
14
14
|
DEV_WALLE_PORT="${DEV_WALLE_PORT:-4001}"
|
|
15
|
+
DEV_OAUTH_PROXY_PORT="${DEV_OAUTH_PROXY_PORT:-$((DEV_CTM_PORT + 2))}"
|
|
15
16
|
|
|
16
|
-
# Source production .env to find DB paths
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
# Source production .env to find DB paths. DEV_SOURCE_* lets worktrees without
|
|
18
|
+
# their own .env refresh from the primary repo's configured data directory.
|
|
19
|
+
PROD_CTM_DIR="${DEV_SOURCE_CTM_DATA_DIR:-$HOME/.walle/data}"
|
|
20
|
+
PROD_WALLE_DIR="${DEV_SOURCE_WALL_E_DATA_DIR:-$HOME/.walle/data}"
|
|
19
21
|
if [[ -f "$ROOT/.env" ]]; then
|
|
20
22
|
eval "$(grep -E '^(CTM_DATA_DIR|WALL_E_DATA_DIR)=' "$ROOT/.env" 2>/dev/null)" || true
|
|
21
|
-
[[ -n "$CTM_DATA_DIR" ]] && PROD_CTM_DIR="$CTM_DATA_DIR"
|
|
22
|
-
[[ -n "$WALL_E_DATA_DIR" ]] && PROD_WALLE_DIR="$WALL_E_DATA_DIR"
|
|
23
|
+
[[ -z "$DEV_SOURCE_CTM_DATA_DIR" && -n "$CTM_DATA_DIR" ]] && PROD_CTM_DIR="$CTM_DATA_DIR"
|
|
24
|
+
[[ -z "$DEV_SOURCE_WALL_E_DATA_DIR" && -n "$WALL_E_DATA_DIR" ]] && PROD_WALLE_DIR="$WALL_E_DATA_DIR"
|
|
23
25
|
fi
|
|
24
26
|
|
|
25
27
|
mkdir -p "$DEV_DIR"
|
|
26
28
|
|
|
29
|
+
cleanup_processes() {
|
|
30
|
+
pkill -f "ctm-dev-$DEV_CTM_PORT" 2>/dev/null || true
|
|
31
|
+
pkill -f "walle-dev-$DEV_CTM_PORT" 2>/dev/null || true
|
|
32
|
+
lsof -ti ":$DEV_CTM_PORT" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true
|
|
33
|
+
lsof -ti ":$DEV_WALLE_PORT" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true
|
|
34
|
+
lsof -ti ":$DEV_OAUTH_PROXY_PORT" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
cleanup_dev() {
|
|
38
|
+
cleanup_processes
|
|
39
|
+
# Remove dev data directory to prevent /tmp bloat (each copy is ~2-6 GB)
|
|
40
|
+
if [[ "$DEV_DIR" == /tmp/walle-* && -d "$DEV_DIR" ]]; then
|
|
41
|
+
echo "[dev] Cleaning up $DEV_DIR ..."
|
|
42
|
+
rm -rf "$DEV_DIR"
|
|
43
|
+
fi
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
cleanup_processes
|
|
47
|
+
|
|
27
48
|
# Handle flags
|
|
28
|
-
if [[ "$1" == "--fresh" ]]; then
|
|
49
|
+
if [[ "$1" == "--fresh" || -z "$1" ]]; then
|
|
29
50
|
echo "[dev] Starting with fresh (empty) databases"
|
|
30
51
|
rm -f "$DEV_DIR"/*.db "$DEV_DIR"/*.db-wal "$DEV_DIR"/*.db-shm
|
|
31
|
-
elif [[ "$1" == "--refresh"
|
|
32
|
-
echo "[dev]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
echo " CTM: $PROD_CTM_DIR/task-manager.db → $DEV_DIR/"
|
|
37
|
-
fi
|
|
38
|
-
# Copy Wall-E brain
|
|
39
|
-
if [[ -f "$PROD_WALLE_DIR/wall-e-brain.db" ]]; then
|
|
40
|
-
cp "$PROD_WALLE_DIR/wall-e-brain.db" "$DEV_DIR/wall-e-brain.db"
|
|
41
|
-
echo " Brain: $PROD_WALLE_DIR/wall-e-brain.db → $DEV_DIR/"
|
|
42
|
-
fi
|
|
43
|
-
# Clean WAL files (they're specific to the source process)
|
|
52
|
+
elif [[ "$1" == "--refresh" ]]; then
|
|
53
|
+
echo "[dev] Snapshotting production databases to $DEV_DIR ..."
|
|
54
|
+
node "$ROOT/bin/sqlite-snapshot.js" "$PROD_CTM_DIR/task-manager.db" "$DEV_DIR/task-manager.db" "CTM"
|
|
55
|
+
node "$ROOT/bin/sqlite-snapshot.js" "$PROD_WALLE_DIR/wall-e-brain.db" "$DEV_DIR/wall-e-brain.db" "Brain"
|
|
56
|
+
# Ensure the dev instance owns its WAL files from first open.
|
|
44
57
|
rm -f "$DEV_DIR"/*.db-wal "$DEV_DIR"/*.db-shm
|
|
45
58
|
fi
|
|
46
59
|
|
|
47
60
|
echo ""
|
|
48
61
|
echo " Dev CTM: http://localhost:$DEV_CTM_PORT"
|
|
49
62
|
echo " Dev Wall-E: port $DEV_WALLE_PORT"
|
|
63
|
+
echo " Dev OAuth: port $DEV_OAUTH_PROXY_PORT"
|
|
50
64
|
echo " Dev data: $DEV_DIR"
|
|
51
65
|
echo " Source: $ROOT"
|
|
52
66
|
echo ""
|
|
@@ -59,14 +73,23 @@ export WALL_E_PORT="$DEV_WALLE_PORT"
|
|
|
59
73
|
export CTM_DATA_DIR="$DEV_DIR"
|
|
60
74
|
export WALL_E_DATA_DIR="$DEV_DIR"
|
|
61
75
|
export CTM_HOST="127.0.0.1"
|
|
76
|
+
export CTM_INSTANCE_TAG="dev-$DEV_CTM_PORT"
|
|
77
|
+
export OAUTH_PROXY_PORT="$DEV_OAUTH_PROXY_PORT"
|
|
62
78
|
|
|
63
79
|
# Source the rest of .env (API keys, owner name, etc.)
|
|
64
80
|
if [[ -f "$ROOT/.env" ]]; then
|
|
65
81
|
set -a
|
|
66
|
-
source <(grep -v '^#' "$ROOT/.env" | grep -vE '^(CTM_PORT|WALL_E_PORT|CTM_DATA_DIR|WALL_E_DATA_DIR|CTM_HOST)=' | grep '=')
|
|
82
|
+
source <(grep -v '^#' "$ROOT/.env" | grep -vE '^(CTM_PORT|WALL_E_PORT|CTM_DATA_DIR|WALL_E_DATA_DIR|CTM_HOST|CTM_INSTANCE_TAG|OAUTH_PROXY_PORT)=' | grep '=')
|
|
67
83
|
set +a
|
|
68
84
|
fi
|
|
69
85
|
|
|
86
|
+
trap cleanup_dev EXIT
|
|
87
|
+
|
|
88
|
+
# Clean up stale dev/e2e data dirs older than 24h (from crashed sessions)
|
|
89
|
+
find /tmp -maxdepth 1 -name "walle-dev-*" -type d -mmin +1440 -exec rm -rf {} + 2>/dev/null || true
|
|
90
|
+
find /tmp -maxdepth 1 -name "walle-e2e-*" -type d -mmin +1440 -exec rm -rf {} + 2>/dev/null || true
|
|
91
|
+
find /tmp -maxdepth 1 -name "ctm-dev-*" -type d -mmin +1440 -exec rm -rf {} + 2>/dev/null || true
|
|
92
|
+
|
|
70
93
|
# Run in foreground so Ctrl+C stops it cleanly
|
|
71
94
|
cd "$ROOT"
|
|
72
95
|
exec node claude-task-manager/server.js
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Install Wall-E as a macOS Launch Agent so it starts automatically on login
|
|
2
|
+
# Install CTM + Wall-E as a macOS Launch Agent so it starts automatically on login
|
|
3
|
+
# and auto-restarts on crash (but NOT on clean exit).
|
|
3
4
|
# Usage: bash bin/install-service.sh [--uninstall]
|
|
4
5
|
|
|
5
6
|
set -e
|
|
@@ -7,22 +8,40 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
7
8
|
ROOT="$(dirname "$SCRIPT_DIR")"
|
|
8
9
|
LABEL="com.walle.server"
|
|
9
10
|
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
|
|
10
|
-
PORT="${CTM_PORT:-
|
|
11
|
+
PORT="${CTM_PORT:-3456}"
|
|
11
12
|
|
|
12
13
|
if [[ "$1" == "--uninstall" ]]; then
|
|
13
|
-
launchctl
|
|
14
|
+
launchctl bootout "gui/$(id -u)/$LABEL" 2>/dev/null || \
|
|
15
|
+
launchctl unload "$PLIST" 2>/dev/null || true
|
|
14
16
|
rm -f "$PLIST"
|
|
15
|
-
echo "
|
|
17
|
+
echo "CTM service uninstalled."
|
|
16
18
|
exit 0
|
|
17
19
|
fi
|
|
18
20
|
|
|
19
|
-
# Source .env
|
|
21
|
+
# Source .env for port and data dir overrides
|
|
22
|
+
ENV_VARS=""
|
|
20
23
|
if [[ -f "$ROOT/.env" ]]; then
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
while IFS='' read -r line || [[ -n "$line" ]]; do
|
|
25
|
+
[[ -z "$line" || "$line" == \#* ]] && continue
|
|
26
|
+
key="${line%%=*}"
|
|
27
|
+
value="${line#*=}"
|
|
28
|
+
key=$(echo "$key" | xargs)
|
|
29
|
+
value=$(echo "$value" | xargs | sed 's/^["'"'"']//;s/["'"'"']$//')
|
|
30
|
+
[[ -z "$key" ]] && continue
|
|
31
|
+
case "$key" in
|
|
32
|
+
CTM_PORT) PORT="$value" ;;
|
|
33
|
+
esac
|
|
34
|
+
# XML-escape for plist safety
|
|
35
|
+
esc_key=$(echo "$key" | sed 's/&/\&/g;s/</\</g;s/>/\>/g')
|
|
36
|
+
esc_val=$(echo "$value" | sed 's/&/\&/g;s/</\</g;s/>/\>/g')
|
|
37
|
+
ENV_VARS="$ENV_VARS
|
|
38
|
+
<key>$esc_key</key>
|
|
39
|
+
<string>$esc_val</string>"
|
|
40
|
+
done < "$ROOT/.env"
|
|
23
41
|
fi
|
|
24
42
|
|
|
25
43
|
NODE=$(which node)
|
|
44
|
+
NODE_BIN_DIR=$(dirname "$NODE")
|
|
26
45
|
LOG_DIR="$HOME/.walle/logs"
|
|
27
46
|
mkdir -p "$LOG_DIR"
|
|
28
47
|
|
|
@@ -43,30 +62,45 @@ cat > "$PLIST" << EOF
|
|
|
43
62
|
<key>EnvironmentVariables</key>
|
|
44
63
|
<dict>
|
|
45
64
|
<key>PATH</key>
|
|
46
|
-
<string
|
|
65
|
+
<string>$NODE_BIN_DIR:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
|
|
47
66
|
<key>HOME</key>
|
|
48
67
|
<string>$HOME</string>
|
|
49
68
|
<key>CTM_PORT</key>
|
|
50
69
|
<string>$PORT</string>
|
|
70
|
+
<key>CTM_MANAGED_BY_LAUNCHD</key>
|
|
71
|
+
<string>1</string>$ENV_VARS
|
|
51
72
|
</dict>
|
|
52
73
|
<key>RunAtLoad</key>
|
|
53
74
|
<true/>
|
|
54
75
|
<key>KeepAlive</key>
|
|
55
|
-
<
|
|
76
|
+
<dict>
|
|
77
|
+
<key>SuccessfulExit</key>
|
|
78
|
+
<false/>
|
|
79
|
+
</dict>
|
|
80
|
+
<key>ThrottleInterval</key>
|
|
81
|
+
<integer>5</integer>
|
|
56
82
|
<key>StandardOutPath</key>
|
|
57
|
-
<string>$LOG_DIR/
|
|
83
|
+
<string>$LOG_DIR/ctm.log</string>
|
|
58
84
|
<key>StandardErrorPath</key>
|
|
59
|
-
<string>$LOG_DIR/
|
|
85
|
+
<string>$LOG_DIR/ctm.err</string>
|
|
60
86
|
</dict>
|
|
61
87
|
</plist>
|
|
62
88
|
EOF
|
|
63
89
|
|
|
64
|
-
|
|
65
|
-
launchctl
|
|
90
|
+
# Load the service (unload first if previously loaded, wait for clean exit)
|
|
91
|
+
launchctl bootout "gui/$(id -u)/$LABEL" 2>/dev/null || \
|
|
92
|
+
launchctl unload "$PLIST" 2>/dev/null || true
|
|
93
|
+
sleep 1 # Let old process release port before bootstrapping new one
|
|
94
|
+
launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || \
|
|
95
|
+
launchctl load "$PLIST"
|
|
66
96
|
|
|
67
|
-
echo "
|
|
97
|
+
echo "CTM installed as a macOS Launch Agent."
|
|
68
98
|
echo ""
|
|
69
|
-
echo " Status: launchctl list
|
|
70
|
-
echo " Logs: tail -f ~/.walle/logs/
|
|
99
|
+
echo " Status: launchctl list $LABEL"
|
|
100
|
+
echo " Logs: tail -f ~/.walle/logs/ctm.log"
|
|
101
|
+
echo " Errors: tail -f ~/.walle/logs/ctm.err"
|
|
71
102
|
echo " Dashboard: http://localhost:$PORT"
|
|
72
103
|
echo " Uninstall: bash bin/install-service.sh --uninstall"
|
|
104
|
+
echo ""
|
|
105
|
+
echo " Auto-restarts on crash. Clean exit (SIGTERM/SIGINT) stops the service."
|
|
106
|
+
echo " To manually stop: launchctl kill SIGTERM gui/$(id -u)/$LABEL"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { spawn } = require('child_process');
|
|
7
|
+
|
|
8
|
+
function loadBetterSqlite() {
|
|
9
|
+
try { return require('../claude-task-manager/node_modules/better-sqlite3'); } catch {}
|
|
10
|
+
try { return require('../wall-e/node_modules/better-sqlite3'); } catch {}
|
|
11
|
+
return require('better-sqlite3');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const Database = loadBetterSqlite();
|
|
15
|
+
|
|
16
|
+
function removeFile(file) {
|
|
17
|
+
try { fs.rmSync(file, { force: true }); } catch {}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function removeDbFamily(file) {
|
|
21
|
+
removeFile(file);
|
|
22
|
+
removeFile(file + '-wal');
|
|
23
|
+
removeFile(file + '-shm');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function loadOptionalVec(db) {
|
|
27
|
+
try {
|
|
28
|
+
const sqliteVec = require('../wall-e/node_modules/sqlite-vec');
|
|
29
|
+
sqliteVec.load(db);
|
|
30
|
+
} catch {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function logDebug(label, message) {
|
|
34
|
+
if (process.env.SQLITE_SNAPSHOT_DEBUG === '1') {
|
|
35
|
+
console.warn(` ${label}: ${message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function quickCheck(dbPath) {
|
|
40
|
+
let db;
|
|
41
|
+
try {
|
|
42
|
+
db = new Database(dbPath, { readonly: true, fileMustExist: true });
|
|
43
|
+
loadOptionalVec(db);
|
|
44
|
+
const rows = db.pragma('quick_check');
|
|
45
|
+
const value = rows?.[0] ? Object.values(rows[0])[0] : '';
|
|
46
|
+
return value === 'ok' ? { ok: true } : { ok: false, error: String(value || 'quick_check failed') };
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return { ok: false, error: err.message };
|
|
49
|
+
} finally {
|
|
50
|
+
try { if (db) db.close(); } catch {}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function sqliteBackup(src, dest) {
|
|
55
|
+
const db = new Database(src, { readonly: true, fileMustExist: true });
|
|
56
|
+
try {
|
|
57
|
+
loadOptionalVec(db);
|
|
58
|
+
await db.backup(dest);
|
|
59
|
+
} finally {
|
|
60
|
+
db.close();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function pipeRecover(input, output) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
removeFile(output);
|
|
67
|
+
const sqlite = process.env.SQLITE3_BIN || '/usr/bin/sqlite3';
|
|
68
|
+
const recover = spawn(sqlite, [input, '.recover'], { stdio: ['ignore', 'pipe', 'inherit'] });
|
|
69
|
+
const apply = spawn(sqlite, [output], { stdio: ['pipe', 'ignore', 'inherit'] });
|
|
70
|
+
let recoverCode = null;
|
|
71
|
+
let applyCode = null;
|
|
72
|
+
let settled = false;
|
|
73
|
+
const fail = (err) => {
|
|
74
|
+
if (settled) return;
|
|
75
|
+
settled = true;
|
|
76
|
+
reject(err);
|
|
77
|
+
};
|
|
78
|
+
const maybeDone = () => {
|
|
79
|
+
if (settled || recoverCode === null || applyCode === null) return;
|
|
80
|
+
if (recoverCode !== 0) return fail(new Error(`sqlite3 .recover exited ${recoverCode}`));
|
|
81
|
+
if (applyCode !== 0) return fail(new Error(`sqlite3 restore exited ${applyCode}`));
|
|
82
|
+
settled = true;
|
|
83
|
+
resolve();
|
|
84
|
+
};
|
|
85
|
+
recover.stdout.pipe(apply.stdin);
|
|
86
|
+
recover.on('error', fail);
|
|
87
|
+
apply.on('error', fail);
|
|
88
|
+
recover.on('close', (code) => {
|
|
89
|
+
recoverCode = code;
|
|
90
|
+
if (code !== 0) try { apply.stdin.destroy(); } catch {}
|
|
91
|
+
maybeDone();
|
|
92
|
+
});
|
|
93
|
+
apply.on('close', (code) => {
|
|
94
|
+
applyCode = code;
|
|
95
|
+
maybeDone();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function main() {
|
|
101
|
+
const [src, dest, label = 'SQLite'] = process.argv.slice(2);
|
|
102
|
+
if (!src || !dest) {
|
|
103
|
+
console.error('Usage: sqlite-snapshot.js <source.db> <dest.db> [label]');
|
|
104
|
+
process.exit(2);
|
|
105
|
+
}
|
|
106
|
+
if (!fs.existsSync(src)) {
|
|
107
|
+
console.log(` ${label}: source missing (${src}) - starting fresh`);
|
|
108
|
+
removeDbFamily(dest);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
113
|
+
removeDbFamily(dest);
|
|
114
|
+
const tmp = `${dest}.tmp-${process.pid}`;
|
|
115
|
+
const recovered = `${dest}.recovered-${process.pid}`;
|
|
116
|
+
removeDbFamily(tmp);
|
|
117
|
+
removeDbFamily(recovered);
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await sqliteBackup(src, tmp);
|
|
121
|
+
const check = quickCheck(tmp);
|
|
122
|
+
if (check.ok) {
|
|
123
|
+
fs.renameSync(tmp, dest);
|
|
124
|
+
console.log(` ${label}: snapshotted ${src} -> ${dest}`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
logDebug(label, `snapshot quick_check failed: ${check.error.slice(0, 160)}`);
|
|
129
|
+
console.log(` ${label}: snapshot required recovery - attempting sqlite .recover`);
|
|
130
|
+
await pipeRecover(tmp, recovered);
|
|
131
|
+
const recoveredCheck = quickCheck(recovered);
|
|
132
|
+
if (!recoveredCheck.ok) throw new Error(`recovered DB failed quick_check: ${recoveredCheck.error.slice(0, 160)}`);
|
|
133
|
+
fs.renameSync(recovered, dest);
|
|
134
|
+
console.log(` ${label}: recovered snapshot written to ${dest}`);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
logDebug(label, `unable to create healthy snapshot: ${err.message}`);
|
|
137
|
+
console.warn(` ${label}: unable to create healthy snapshot - starting fresh`);
|
|
138
|
+
removeDbFamily(dest);
|
|
139
|
+
} finally {
|
|
140
|
+
removeDbFamily(tmp);
|
|
141
|
+
removeDbFamily(recovered);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main().catch((err) => {
|
|
146
|
+
console.error(`sqlite snapshot failed: ${err.stack || err.message}`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
});
|