create-walle 0.9.8 → 0.9.10
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 +95 -13
- package/bin/mcp-inject.js +60 -0
- package/package.json +11 -3
- package/template/CLAUDE.md +19 -0
- package/template/bin/dev.sh +46 -23
- package/template/bin/install-service.sh +50 -16
- package/template/bin/setup.js +2 -1
- package/template/bin/sqlite-snapshot.js +148 -0
- package/template/claude-code-skill.md +35 -34
- package/template/claude-task-manager/api-prompts.js +1139 -259
- package/template/claude-task-manager/api-reviews.js +12 -0
- package/template/claude-task-manager/approval-agent.js +517 -88
- package/template/claude-task-manager/atomic-write.js +22 -0
- 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 +2146 -108
- 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 +761 -1
- 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 +216 -0
- package/template/claude-task-manager/public/css/walle-session.css +178 -0
- package/template/claude-task-manager/public/css/walle.css +346 -0
- package/template/claude-task-manager/public/index.html +9421 -1256
- 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 +2068 -0
- 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 +447 -72
- package/template/claude-task-manager/public/js/walle.js +7141 -3695
- package/template/claude-task-manager/public/prompts.html +679 -307
- package/template/claude-task-manager/public/setup.html +13 -459
- 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-state.js +8 -1
- package/template/claude-task-manager/server.js +7521 -1643
- package/template/claude-task-manager/session-integrity.js +706 -0
- package/template/claude-task-manager/session-utils.js +116 -5
- 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/harvest-worker.js +36 -0
- package/template/claude-task-manager/workers/headless-term-worker.js +444 -0
- package/template/claude-task-manager/workers/scrollback-worker.js +76 -0
- 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 +3 -1
- 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 +684 -211
- package/template/wall-e/api-walle.js +2493 -245
- 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 +2062 -111
- 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 +1181 -118
- package/template/wall-e/coding-context.js +142 -6
- package/template/wall-e/coding-orchestrator.js +1400 -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 +33 -0
- package/template/wall-e/context/context-builder.js +439 -80
- package/template/wall-e/context/query-sanitizer.js +81 -0
- package/template/wall-e/context/topic-matcher.js +67 -18
- 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/docs/prompt-architecture.md +121 -0
- package/template/wall-e/embeddings.js +840 -0
- 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 +414 -0
- package/template/wall-e/eval/benchmark-generator.js +93 -0
- package/template/wall-e/eval/benchmarks/chat-eval.json +1602 -0
- package/template/wall-e/eval/benchmarks/chat.json +82 -0
- 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/coding.json +122 -0
- package/template/wall-e/eval/benchmarks/memory-retrieval.json +82 -0
- package/template/wall-e/eval/benchmarks/reasoning.json +82 -0
- package/template/wall-e/eval/benchmarks/swebench-lite-30.json +212 -0
- package/template/wall-e/eval/benchmarks.js +578 -0
- package/template/wall-e/eval/cc-replay.js +718 -0
- package/template/wall-e/eval/chat-eval.js +525 -0
- 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/evaluate.js +202 -0
- package/template/wall-e/eval/evaluator.js +373 -0
- package/template/wall-e/eval/exporter.js +212 -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 +628 -0
- package/template/wall-e/eval/head-to-head.js +364 -0
- 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 +228 -0
- package/template/wall-e/eval/replay.js +395 -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 +161 -0
- 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/train.py +320 -0
- package/template/wall-e/eval/trainer.js +232 -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/complexity.js +3 -0
- package/template/wall-e/evaluation/index.js +3 -1
- package/template/wall-e/evaluation/learner.js +15 -2
- package/template/wall-e/evaluation/phase-detector.js +129 -0
- package/template/wall-e/evaluation/quorum-evaluator.js +545 -0
- package/template/wall-e/evaluation/quorum.js +1 -254
- package/template/wall-e/evaluation/router.js +250 -25
- package/template/wall-e/evaluation/scorecard.js +81 -2
- package/template/wall-e/evaluation/self-critique.js +188 -0
- package/template/wall-e/evaluation/tier-selector.js +167 -0
- package/template/wall-e/evaluation/user-signals.js +109 -0
- 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 +61 -17
- package/template/wall-e/extraction/noise-stripper.js +63 -0
- package/template/wall-e/http/api-utils.js +100 -0
- package/template/wall-e/http/auth.js +45 -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 +760 -0
- 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 +131 -21
- 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 +2 -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.js +220 -0
- package/template/wall-e/llm/mlx.plugin.json +24 -0
- package/template/wall-e/llm/ollama-setup.js +234 -0
- 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-availability.js +213 -0
- package/template/wall-e/llm/provider-detector.js +270 -0
- 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 +485 -0
- 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 +77 -3
- 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 +47 -0
- package/template/wall-e/loops/silent-reply-tokens.js +109 -0
- package/template/wall-e/loops/tasks.js +83 -13
- package/template/wall-e/loops/think.js +71 -4
- package/template/wall-e/loops/workspace-prompts.js +210 -0
- package/template/wall-e/mcp-server.js +381 -0
- package/template/wall-e/package.json +11 -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 +308 -0
- package/template/wall-e/scripts/slack-channel-history.js +1 -1
- 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 +55 -6
- package/template/wall-e/skills/_bundled/coding-agent/run.js +50 -33
- package/template/wall-e/skills/_bundled/email-sync/mail-search.swift +237 -0
- package/template/wall-e/skills/_bundled/email-sync/run.js +90 -28
- package/template/wall-e/skills/_bundled/file-ingest/run.js +17 -7
- package/template/wall-e/skills/_bundled/glean-team-sync/run.js +10 -6
- package/template/wall-e/skills/_bundled/google-calendar/run.js +46 -29
- 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/mcp-scan/run.js +9 -4
- package/template/wall-e/skills/_bundled/morning-briefing/run.js +82 -6
- package/template/wall-e/skills/_bundled/proactive-alerts/run.js +28 -7
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +104 -34
- package/template/wall-e/skills/_bundled/training-harvester/SKILL.md +43 -0
- package/template/wall-e/skills/_bundled/training-harvester/run.js +46 -0
- 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 +427 -79
- 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 +60 -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 +998 -137
- 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 +21 -16
- package/template/wall-e/tools/smart-truncation.js +100 -0
- package/template/wall-e/tools/snapshot.js +479 -0
- package/template/wall-e/training/aggregator.js +115 -0
- package/template/wall-e/training/evaluator.js +373 -0
- package/template/wall-e/training/exporter.js +86 -1
- package/template/wall-e/training/harvester.js +476 -0
- package/template/wall-e/training/promoter.js +146 -0
- package/template/wall-e/training/replay.js +381 -0
- package/template/wall-e/training/shadow.js +144 -0
- package/template/wall-e/training/train.py +78 -32
- package/template/wall-e/training/trainer.js +30 -1
- 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/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 -152
- 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 -132
- 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/evaluate.test.js +0 -221
- package/template/wall-e/test/training/exporter.test.js +0 -213
- package/template/wall-e/test/training/trainer.test.js +0 -241
- 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/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 -303
- 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 -215
- package/template/wall-e/tests/contradiction.test.js +0 -217
- 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/proactive-alerts.test.js +0 -140
- package/template/wall-e/tests/reflect.test.js +0 -103
- 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 -435
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
|
@@ -13,6 +13,7 @@ const RED = '\x1b[31m';
|
|
|
13
13
|
const CYAN = '\x1b[36m';
|
|
14
14
|
const RESET = '\x1b[0m';
|
|
15
15
|
|
|
16
|
+
const { injectMcpConfigs } = require('./mcp-inject');
|
|
16
17
|
const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
|
|
17
18
|
const LABEL = 'com.walle.server';
|
|
18
19
|
const INSTALL_PATH_FILE = path.join(process.env.HOME, '.walle', 'install-path');
|
|
@@ -70,6 +71,29 @@ ${BOLD}${CYAN} Wall-E${RESET} — Your personal digital twin
|
|
|
70
71
|
`);
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
function printMcpResults(wallePort) {
|
|
75
|
+
try {
|
|
76
|
+
const results = injectMcpConfigs(wallePort);
|
|
77
|
+
const hasAny = results.some(r => r.action !== 'not_installed');
|
|
78
|
+
if (!hasAny) return;
|
|
79
|
+
|
|
80
|
+
console.log(` ${BOLD}MCP Integrations:${RESET}`);
|
|
81
|
+
for (const r of results) {
|
|
82
|
+
if (r.action === 'not_installed') {
|
|
83
|
+
console.log(` ${DIM}- ${r.tool} -- not installed${RESET}`);
|
|
84
|
+
} else if (r.action === 'already_configured') {
|
|
85
|
+
console.log(` ${DIM}= ${r.tool} -- already configured${RESET}`);
|
|
86
|
+
} else if (r.action === 'updated') {
|
|
87
|
+
console.log(` ${GREEN}~ ${r.tool}${RESET} -- updated port in ${DIM}${r.configPath}${RESET}`);
|
|
88
|
+
} else {
|
|
89
|
+
console.log(` ${GREEN}+ ${r.tool}${RESET} -- added Wall-E to ${DIM}${r.configPath}${RESET}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
console.log(`\n ${DIM}Your AI coding tools can now access Wall-E's memory and knowledge.`);
|
|
93
|
+
console.log(` To undo: remove the "wall-e" entry from the config files above.${RESET}\n`);
|
|
94
|
+
} catch {}
|
|
95
|
+
}
|
|
96
|
+
|
|
73
97
|
function install(targetDir) {
|
|
74
98
|
// If no target dir given, check for existing install
|
|
75
99
|
if (!targetDir) {
|
|
@@ -120,14 +144,20 @@ function install(targetDir) {
|
|
|
120
144
|
console.log(` Installing dependencies...\n`);
|
|
121
145
|
npmInstall(targetDir);
|
|
122
146
|
|
|
147
|
+
compileHotkeyDaemon(targetDir);
|
|
148
|
+
|
|
123
149
|
// .env
|
|
124
150
|
const envLines = [
|
|
125
151
|
`# Wall-E configuration — generated ${new Date().toISOString().split('T')[0]}`,
|
|
126
152
|
`# Finish setup at http://localhost:${port}/setup.html`,
|
|
127
153
|
'',
|
|
128
|
-
`WALLE_OWNER_NAME
|
|
154
|
+
`WALLE_OWNER_NAME="${ownerName.replace(/"/g, '\\"')}"`,
|
|
129
155
|
'# ANTHROPIC_API_KEY=',
|
|
130
156
|
'',
|
|
157
|
+
'# AI Provider: anthropic, openai, google, ollama',
|
|
158
|
+
'# WALLE_PROVIDER=anthropic',
|
|
159
|
+
'# WALLE_MODEL=',
|
|
160
|
+
'',
|
|
131
161
|
`CTM_PORT=${port}`,
|
|
132
162
|
`WALL_E_PORT=${wallePort}`,
|
|
133
163
|
'',
|
|
@@ -172,6 +202,7 @@ function install(targetDir) {
|
|
|
172
202
|
npx create-walle status ${DIM}Check status${RESET}
|
|
173
203
|
npx create-walle logs ${DIM}View logs${RESET}
|
|
174
204
|
`);
|
|
205
|
+
printMcpResults(parseInt(wallePort));
|
|
175
206
|
}
|
|
176
207
|
|
|
177
208
|
function update() {
|
|
@@ -218,7 +249,9 @@ function update() {
|
|
|
218
249
|
console.log(` Installing dependencies...\n`);
|
|
219
250
|
npmInstall(dir);
|
|
220
251
|
|
|
221
|
-
|
|
252
|
+
compileHotkeyDaemon(dir);
|
|
253
|
+
|
|
254
|
+
// 7. Start again
|
|
222
255
|
console.log(`\n Starting Wall-E...`);
|
|
223
256
|
startForegroundOrService(dir, port);
|
|
224
257
|
|
|
@@ -227,6 +260,7 @@ function update() {
|
|
|
227
260
|
|
|
228
261
|
${DIM}Your .env and config were preserved.${RESET}
|
|
229
262
|
`);
|
|
263
|
+
printMcpResults(parseInt(readWallePort(dir)));
|
|
230
264
|
}
|
|
231
265
|
|
|
232
266
|
function start() {
|
|
@@ -235,6 +269,7 @@ function start() {
|
|
|
235
269
|
console.log(`\n Starting Wall-E from ${DIM}${dir}${RESET} on port ${port}...`);
|
|
236
270
|
installService(dir, port);
|
|
237
271
|
console.log(` ${GREEN}Running!${RESET} http://localhost:${port}\n`);
|
|
272
|
+
printMcpResults(parseInt(readWallePort(dir)));
|
|
238
273
|
}
|
|
239
274
|
|
|
240
275
|
function stop() {
|
|
@@ -300,9 +335,8 @@ function stopQuiet(dir, port) {
|
|
|
300
335
|
while (Date.now() < deadline) {
|
|
301
336
|
try {
|
|
302
337
|
execFileSync('curl', ['-s', '--max-time', '1', `http://localhost:${port}/api/services/status`], { encoding: 'utf8', timeout: 2000 });
|
|
303
|
-
// Still running —
|
|
304
|
-
|
|
305
|
-
while (Date.now() < waitUntil) { /* spin */ }
|
|
338
|
+
// Still running — sleep briefly (avoid CPU spin)
|
|
339
|
+
try { execFileSync('sleep', ['0.5'], { timeout: 2000 }); } catch {}
|
|
306
340
|
} catch {
|
|
307
341
|
break; // Port is free
|
|
308
342
|
}
|
|
@@ -339,15 +373,18 @@ function installService(walleDir, port) {
|
|
|
339
373
|
fs.mkdirSync(plistDir, { recursive: true });
|
|
340
374
|
const plistPath = path.join(plistDir, `${LABEL}.plist`);
|
|
341
375
|
|
|
342
|
-
|
|
343
|
-
|
|
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`;
|
|
344
380
|
envDict += ` <key>CTM_PORT</key>\n <string>${port}</string>\n`;
|
|
381
|
+
envDict += ` <key>CTM_MANAGED_BY_LAUNCHD</key>\n <string>1</string>\n`;
|
|
345
382
|
try {
|
|
346
383
|
const envFile = fs.readFileSync(path.join(walleDir, '.env'), 'utf8');
|
|
347
384
|
for (const line of envFile.split('\n')) {
|
|
348
385
|
const m = line.match(/^\s*([^#=\s]+)\s*=\s*(.+?)\s*$/);
|
|
349
386
|
if (m && m[1] !== 'CTM_PORT' && m[1] !== 'PATH' && m[1] !== 'HOME') {
|
|
350
|
-
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`;
|
|
351
388
|
}
|
|
352
389
|
}
|
|
353
390
|
} catch {}
|
|
@@ -371,11 +408,16 @@ ${envDict} </dict>
|
|
|
371
408
|
<key>RunAtLoad</key>
|
|
372
409
|
<true/>
|
|
373
410
|
<key>KeepAlive</key>
|
|
374
|
-
<
|
|
411
|
+
<dict>
|
|
412
|
+
<key>SuccessfulExit</key>
|
|
413
|
+
<false/>
|
|
414
|
+
</dict>
|
|
415
|
+
<key>ThrottleInterval</key>
|
|
416
|
+
<integer>5</integer>
|
|
375
417
|
<key>StandardOutPath</key>
|
|
376
|
-
<string>${logDir}/
|
|
418
|
+
<string>${logDir}/ctm.log</string>
|
|
377
419
|
<key>StandardErrorPath</key>
|
|
378
|
-
<string>${logDir}/
|
|
420
|
+
<string>${logDir}/ctm.err</string>
|
|
379
421
|
</dict>
|
|
380
422
|
</plist>`;
|
|
381
423
|
|
|
@@ -383,10 +425,34 @@ ${envDict} </dict>
|
|
|
383
425
|
try { execFileSync('launchctl', ['unload', plistPath], { stdio: 'ignore' }); } catch {}
|
|
384
426
|
execFileSync('launchctl', ['load', plistPath]);
|
|
385
427
|
} else {
|
|
386
|
-
|
|
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], {
|
|
387
453
|
cwd: walleDir,
|
|
388
454
|
detached: true,
|
|
389
|
-
stdio:
|
|
455
|
+
stdio: 'ignore',
|
|
390
456
|
env: { ...process.env, CTM_PORT: port },
|
|
391
457
|
});
|
|
392
458
|
child.unref();
|
|
@@ -474,6 +540,22 @@ function detectTimezone() {
|
|
|
474
540
|
return 'UTC';
|
|
475
541
|
}
|
|
476
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
|
+
|
|
477
559
|
function copyRecursive(src, dest) {
|
|
478
560
|
const stat = fs.statSync(src);
|
|
479
561
|
if (stat.isDirectory()) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const MCP_TARGETS = [
|
|
6
|
+
{ tool: 'Claude Code', configPath: '.claude/mcp.json', detectDir: '.claude' },
|
|
7
|
+
{ tool: 'Cursor', configPath: '.cursor/mcp.json', detectDir: '.cursor' },
|
|
8
|
+
{ tool: 'Windsurf', configPath: '.codeium/windsurf/mcp_config.json', detectDir: '.codeium/windsurf' },
|
|
9
|
+
{ tool: 'Claude Desktop', configPath: 'Library/Application Support/Claude/claude_desktop_config.json', detectDir: 'Library/Application Support/Claude' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Inject Wall-E MCP server config into detected AI tool config files.
|
|
14
|
+
* @param {number} wallePort - The Wall-E HTTP port
|
|
15
|
+
* @param {string} [homeDir] - Home directory override for testing
|
|
16
|
+
* @returns {Array<{tool: string, action: string, configPath?: string}>}
|
|
17
|
+
*/
|
|
18
|
+
function injectMcpConfigs(wallePort, homeDir) {
|
|
19
|
+
const home = homeDir || process.env.HOME;
|
|
20
|
+
const walleUrl = `http://localhost:${wallePort}/mcp`;
|
|
21
|
+
const results = [];
|
|
22
|
+
|
|
23
|
+
for (const target of MCP_TARGETS) {
|
|
24
|
+
const detectPath = path.join(home, target.detectDir);
|
|
25
|
+
const configPath = path.join(home, target.configPath);
|
|
26
|
+
|
|
27
|
+
if (!fs.existsSync(detectPath)) {
|
|
28
|
+
results.push({ tool: target.tool, action: 'not_installed' });
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let config = {};
|
|
33
|
+
if (fs.existsSync(configPath)) {
|
|
34
|
+
try {
|
|
35
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
36
|
+
} catch {
|
|
37
|
+
config = {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
42
|
+
|
|
43
|
+
const existing = config.mcpServers['wall-e'];
|
|
44
|
+
if (existing && existing.url === walleUrl) {
|
|
45
|
+
results.push({ tool: target.tool, action: 'already_configured', configPath });
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const action = existing ? 'updated' : 'added';
|
|
50
|
+
config.mcpServers['wall-e'] = { type: 'http', url: walleUrl };
|
|
51
|
+
|
|
52
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
53
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
54
|
+
results.push({ tool: target.tool, action, configPath });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return results;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = { injectMcpConfigs, MCP_TARGETS };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-walle",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "CTM + Wall-E
|
|
3
|
+
"version": "0.9.10",
|
|
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"
|
|
7
7
|
},
|
|
@@ -15,5 +15,13 @@
|
|
|
15
15
|
"prepublishOnly": "bash build.sh"
|
|
16
16
|
},
|
|
17
17
|
"license": "MIT",
|
|
18
|
-
"keywords": [
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ctm",
|
|
20
|
+
"task-manager",
|
|
21
|
+
"wall-e",
|
|
22
|
+
"ai",
|
|
23
|
+
"digital-twin",
|
|
24
|
+
"claude",
|
|
25
|
+
"personal-assistant"
|
|
26
|
+
]
|
|
19
27
|
}
|
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"
|
package/template/bin/setup.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const { execFileSync } = require('child_process');
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
|
+
const { atomicWriteFileSync } = require('../claude-task-manager/atomic-write');
|
|
10
11
|
|
|
11
12
|
const ROOT = path.resolve(__dirname, '..');
|
|
12
13
|
const ENV_PATH = path.join(ROOT, '.env');
|
|
@@ -41,7 +42,7 @@ function runIfNeeded() {
|
|
|
41
42
|
`WALLE_OWNER_NAME=${ownerName}`,
|
|
42
43
|
'# ANTHROPIC_API_KEY=sk-ant-...',
|
|
43
44
|
];
|
|
44
|
-
|
|
45
|
+
atomicWriteFileSync(ENV_PATH, envLines.join('\n') + '\n', { mode: 0o600 });
|
|
45
46
|
|
|
46
47
|
// Set in current process
|
|
47
48
|
process.env.WALLE_OWNER_NAME = ownerName;
|