create-walle 0.9.17 → 0.9.19
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 +7 -5
- package/package.json +2 -2
- package/template/README.md +18 -16
- package/template/bin/ctm-dev-cleanup.js +264 -0
- package/template/bin/dev.sh +40 -2
- package/template/claude-task-manager/api-prompts.js +600 -97
- package/template/claude-task-manager/api-reviews.js +56 -3
- package/template/claude-task-manager/approval-agent.js +62 -10
- package/template/claude-task-manager/bin/check-sqlite-driver.js +32 -0
- package/template/claude-task-manager/bin/restart-ctm.sh +8 -0
- package/template/claude-task-manager/db.js +1413 -265
- package/template/claude-task-manager/docs/codex-resume-state-guard-design.md +85 -0
- package/template/claude-task-manager/docs/codex-session-status-time-contract.md +29 -0
- package/template/claude-task-manager/docs/conversation-import-freshness.md +91 -0
- package/template/claude-task-manager/docs/feedback-admin-board-design.md +178 -0
- package/template/claude-task-manager/docs/image-paste-ux.md +22 -0
- package/template/claude-task-manager/docs/large-jsonl-transcript-ingestion.md +128 -0
- package/template/claude-task-manager/docs/light-mode-theme-design.md +129 -0
- package/template/claude-task-manager/docs/microsoft-dev-tunnel-phone-access-design.md +712 -0
- package/template/claude-task-manager/docs/mobile-live-streaming.md +167 -0
- package/template/claude-task-manager/docs/mobile-unified-live-timeline-design.md +184 -0
- package/template/claude-task-manager/docs/mobile-walle-chat-design.md +56 -0
- package/template/claude-task-manager/docs/obsidian-resource-map-design.md +141 -0
- package/template/claude-task-manager/docs/phone-access-design.md +1391 -0
- package/template/claude-task-manager/docs/phone-setup.md +127 -0
- package/template/claude-task-manager/docs/prompt-editing-tree-design.md +586 -0
- package/template/claude-task-manager/docs/session-management-architecture.md +127 -547
- package/template/claude-task-manager/docs/session-render-state-management-design.md +377 -0
- package/template/claude-task-manager/docs/session-search-corpus-architecture.md +121 -0
- package/template/claude-task-manager/docs/session-standup-command-center-design.md +2 -2
- package/template/claude-task-manager/docs/session-timeline-consistency-design.md +107 -0
- package/template/claude-task-manager/docs/smart-session-search-design.md +222 -0
- package/template/claude-task-manager/docs/sqlite-driver-recovery.md +80 -0
- package/template/claude-task-manager/docs/walle-relay-phone-access-design.md +1027 -0
- package/template/claude-task-manager/docs/walle-transcript-display-projection.md +42 -0
- package/template/claude-task-manager/fuzzy-utils.js +3 -2
- package/template/claude-task-manager/git-utils.js +90 -7
- package/template/claude-task-manager/lib/activity-time.js +57 -0
- package/template/claude-task-manager/lib/agent-hooks-installer.js +102 -8
- package/template/claude-task-manager/lib/agent-presets.js +3 -0
- package/template/claude-task-manager/lib/auth-context.js +176 -0
- package/template/claude-task-manager/lib/auth-rate-limit.js +107 -0
- package/template/claude-task-manager/lib/auth-rules.js +242 -0
- package/template/claude-task-manager/lib/background-llm.js +225 -0
- package/template/claude-task-manager/lib/cloudflare-access.js +352 -0
- package/template/claude-task-manager/lib/cloudflare-setup.js +1338 -0
- package/template/claude-task-manager/lib/coding-agent-models.js +4 -0
- package/template/claude-task-manager/lib/conversation-tail-merge.js +127 -0
- package/template/claude-task-manager/lib/document-review.js +250 -0
- package/template/claude-task-manager/lib/feedback-api.js +241 -0
- package/template/claude-task-manager/lib/feedback-store.js +813 -0
- package/template/claude-task-manager/lib/fs-watcher.js +11 -2
- package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +1841 -0
- package/template/claude-task-manager/lib/mobile-auth-api.js +673 -0
- package/template/claude-task-manager/lib/mobile-auth-store.js +807 -0
- package/template/claude-task-manager/lib/mobile-notification-dispatcher.js +275 -0
- package/template/claude-task-manager/lib/mobile-push-api.js +114 -0
- package/template/claude-task-manager/lib/mobile-push-store.js +342 -0
- package/template/claude-task-manager/lib/perf-tracker.js +16 -7
- package/template/claude-task-manager/lib/relink-audit.js +188 -30
- package/template/claude-task-manager/lib/remote-feedback-client.js +74 -0
- package/template/claude-task-manager/lib/remote-relay-protocol.js +205 -0
- package/template/claude-task-manager/lib/remote-relay-store.js +268 -0
- package/template/claude-task-manager/lib/resource-links.js +500 -0
- package/template/claude-task-manager/lib/resume-cwd.js +76 -0
- package/template/claude-task-manager/lib/scheduler.js +11 -1
- package/template/claude-task-manager/lib/server-config.js +6 -1
- package/template/claude-task-manager/lib/server-listeners.js +44 -0
- package/template/claude-task-manager/lib/session-empty.js +89 -0
- package/template/claude-task-manager/lib/session-history.js +714 -53
- package/template/claude-task-manager/lib/session-jobs.js +176 -61
- package/template/claude-task-manager/lib/session-restore.js +207 -0
- package/template/claude-task-manager/lib/session-standup.js +277 -35
- package/template/claude-task-manager/lib/session-state-bus.js +45 -9
- package/template/claude-task-manager/lib/session-stream.js +396 -82
- package/template/claude-task-manager/lib/session-timeline.js +161 -0
- package/template/claude-task-manager/lib/setup-network-config.js +184 -0
- package/template/claude-task-manager/lib/setup-provider-config.js +95 -1
- package/template/claude-task-manager/lib/skill-autocomplete.js +298 -0
- package/template/claude-task-manager/lib/sqlite-driver.js +332 -0
- package/template/claude-task-manager/lib/standup-incremental.js +144 -0
- package/template/claude-task-manager/lib/status-hooks.js +2 -2
- package/template/claude-task-manager/lib/tailscale-setup.js +181 -0
- package/template/claude-task-manager/lib/telemetry-receiver.js +68 -17
- package/template/claude-task-manager/lib/terminal-snapshot-options.js +19 -0
- package/template/claude-task-manager/lib/transcript-store.js +647 -0
- package/template/claude-task-manager/lib/transport-security.js +304 -0
- package/template/claude-task-manager/lib/update-telemetry.js +1 -1
- package/template/claude-task-manager/lib/walle-client.js +41 -11
- package/template/claude-task-manager/lib/walle-ctm-history.js +260 -7
- package/template/claude-task-manager/lib/walle-external-actions.js +276 -0
- package/template/claude-task-manager/lib/walle-mcp-auto-config.js +18 -3
- package/template/claude-task-manager/lib/walle-permission-policy.js +59 -0
- package/template/claude-task-manager/lib/walle-ready-retry.js +113 -0
- package/template/claude-task-manager/lib/walle-session-cache.js +140 -0
- package/template/claude-task-manager/lib/walle-transcript.js +6 -0
- package/template/claude-task-manager/lib/worktree-active-sync.js +86 -0
- package/template/claude-task-manager/package.json +5 -2
- package/template/claude-task-manager/prompt-harvest.js +92 -9
- package/template/claude-task-manager/providers/claude-code.js +6 -1
- package/template/claude-task-manager/public/css/feedback.css +544 -0
- package/template/claude-task-manager/public/css/listening.css +51 -15
- package/template/claude-task-manager/public/css/prompts.css +49 -12
- package/template/claude-task-manager/public/css/reviews.css +124 -0
- package/template/claude-task-manager/public/css/setup.css +1210 -7
- package/template/claude-task-manager/public/css/walle-session.css +806 -18
- package/template/claude-task-manager/public/css/walle.css +204 -3
- package/template/claude-task-manager/public/index.html +12546 -1376
- package/template/claude-task-manager/public/js/feedback.js +724 -0
- package/template/claude-task-manager/public/js/image-normalize.js +163 -0
- package/template/claude-task-manager/public/js/message-renderer.js +778 -25
- package/template/claude-task-manager/public/js/prompts.js +196 -20
- package/template/claude-task-manager/public/js/reviews.js +468 -19
- package/template/claude-task-manager/public/js/session-activity-utils.js +45 -7
- package/template/claude-task-manager/public/js/session-search-utils.js +71 -21
- package/template/claude-task-manager/public/js/session-status-precedence.js +122 -18
- package/template/claude-task-manager/public/js/setup.js +3433 -296
- package/template/claude-task-manager/public/js/stream-view.js +635 -119
- package/template/claude-task-manager/public/js/terminal-restore-state.js +78 -1
- package/template/claude-task-manager/public/js/walle-session.js +2339 -169
- package/template/claude-task-manager/public/js/walle.js +576 -155
- package/template/claude-task-manager/public/m/app.css +2946 -0
- package/template/claude-task-manager/public/m/app.js +5119 -0
- package/template/claude-task-manager/public/m/claim.html +141 -0
- package/template/claude-task-manager/public/m/index.html +213 -0
- package/template/claude-task-manager/public/m/sw.js +125 -0
- package/template/claude-task-manager/public/prompts.html +8 -3
- package/template/claude-task-manager/public/setup.html +6 -1
- package/template/claude-task-manager/queue-engine.js +68 -15
- package/template/claude-task-manager/scripts/repair-claude-session-images.js +177 -0
- package/template/claude-task-manager/server.js +8339 -1649
- package/template/claude-task-manager/session-integrity.js +676 -32
- package/template/claude-task-manager/session-search-ranking.js +79 -0
- package/template/claude-task-manager/session-utils.js +121 -4
- package/template/claude-task-manager/workers/conversation-import-worker.js +22 -2
- package/template/claude-task-manager/workers/harvest-worker.js +27 -2
- package/template/claude-task-manager/workers/headless-term-worker.js +94 -4
- package/template/claude-task-manager/workers/scrollback-worker.js +2 -0
- package/template/claude-task-manager/workers/session-integrity-worker.js +22 -2
- package/template/claude-task-manager/workers/state-detectors/claude-code.js +6 -4
- package/template/claude-task-manager/workers/state-detectors/codex.js +4 -1
- package/template/docs/designs/2026-05-17-portkey-gateway-provider-ux.md +154 -0
- package/template/docs/designs/2026-05-18-walle-external-action-approval.md +57 -0
- package/template/docs/site/api/README.md +18 -4
- package/template/docs/site/src/content/docs/api.md +18 -4
- package/template/package.json +3 -1
- package/template/wall-e/agent-runners/claude-code.js +85 -10
- package/template/wall-e/agent-runners/codex.js +3 -1
- package/template/wall-e/agent-runners/contract.js +1 -0
- package/template/wall-e/agent-runtime/index.js +3 -0
- package/template/wall-e/agent-runtime/recovery-recipes.js +87 -0
- package/template/wall-e/agent-runtime/spawn.js +26 -0
- package/template/wall-e/agent-runtime/task-packet.js +99 -0
- package/template/wall-e/agent-runtime/worker-boot.js +236 -0
- package/template/wall-e/agent.js +48 -3
- package/template/wall-e/api-walle.js +1734 -134
- package/template/wall-e/auth/flow-manager.js +133 -0
- package/template/wall-e/auth/provider-flows.js +114 -0
- package/template/wall-e/bin/walle-mcp-stdio.js +101 -0
- package/template/wall-e/brain.js +548 -32
- package/template/wall-e/channels/message-ledger.js +136 -0
- package/template/wall-e/channels/reply-dispatcher.js +41 -1
- package/template/wall-e/chat/capability-resolver.js +1 -0
- package/template/wall-e/chat.js +1954 -140
- package/template/wall-e/coding/acp-adapter.js +44 -0
- package/template/wall-e/coding/acp-jsonrpc.js +324 -0
- package/template/wall-e/coding/artifact-store.js +157 -0
- package/template/wall-e/coding/capability-broker.js +362 -0
- package/template/wall-e/coding/event-reconciler.js +145 -0
- package/template/wall-e/coding/git-safety.js +168 -0
- package/template/wall-e/coding/hook-bus.js +63 -0
- package/template/wall-e/coding/lane-events.js +223 -0
- package/template/wall-e/coding/mcp-lifecycle.js +242 -0
- package/template/wall-e/coding/model-message.js +3 -2
- package/template/wall-e/coding/parity-harness.js +137 -0
- package/template/wall-e/coding/permission-rules-store.js +21 -3
- package/template/wall-e/coding/permission-service.js +115 -10
- package/template/wall-e/coding/policy-engine.js +103 -0
- package/template/wall-e/coding/prompt-capabilities.js +572 -0
- package/template/wall-e/coding/provider-compat.js +193 -0
- package/template/wall-e/coding/provider-transform.js +21 -8
- package/template/wall-e/coding/session-index.js +204 -0
- package/template/wall-e/coding/side-git-snapshot.js +129 -0
- package/template/wall-e/coding/snapshot-service.js +48 -2
- package/template/wall-e/coding/stream-processor.js +326 -3
- package/template/wall-e/coding/task-tool.js +20 -5
- package/template/wall-e/coding/tool-registry.js +419 -50
- package/template/wall-e/coding/transcript-writer.js +371 -1
- package/template/wall-e/coding/workspace-replay.js +134 -5
- package/template/wall-e/coding-context.js +7 -1
- package/template/wall-e/coding-orchestrator.js +911 -119
- package/template/wall-e/coding-prompts.js +214 -5
- package/template/wall-e/coding-review.js +186 -0
- package/template/wall-e/context/context-builder.js +193 -30
- package/template/wall-e/context/response-language.js +66 -0
- package/template/wall-e/context/topic-matcher.js +14 -3
- package/template/wall-e/core-tasks.js +11 -11
- package/template/wall-e/docs/external-action-controller.md +97 -0
- package/template/wall-e/docs/telemetry-lifecycle.md +88 -0
- package/template/wall-e/eval/agent-runner.js +84 -8
- package/template/wall-e/eval/allowed-test-commands.js +34 -0
- package/template/wall-e/eval/benchmarks/chat-eval.json +2 -2
- package/template/wall-e/eval/benchmarks/memory-retrieval.json +54 -0
- package/template/wall-e/eval/benchmarks.js +7 -0
- package/template/wall-e/eval/chat-eval.js +1 -1
- package/template/wall-e/eval/codex-cli-baseline.js +59 -23
- package/template/wall-e/eval/coding-agent-real.js +2 -0
- package/template/wall-e/eval/eval-orchestrator.js +2 -0
- package/template/wall-e/eval/head-to-head.js +9 -6
- package/template/wall-e/eval/meta-harness/adapters/coding-agent.js +57 -0
- package/template/wall-e/eval/meta-harness/bootstrap-snapshot.js +149 -0
- package/template/wall-e/eval/meta-harness/candidate-store.js +117 -0
- package/template/wall-e/eval/meta-harness/cli.js +86 -0
- package/template/wall-e/eval/meta-harness/domain-spec.js +154 -0
- package/template/wall-e/eval/meta-harness/domains/coding-agent.domain.json +84 -0
- package/template/wall-e/eval/meta-harness/examples/env-bootstrap-candidate.js +29 -0
- package/template/wall-e/eval/meta-harness/experience-store.js +174 -0
- package/template/wall-e/eval/meta-harness/frontier.js +96 -0
- package/template/wall-e/eval/meta-harness/harness-interface.js +90 -0
- package/template/wall-e/eval/meta-harness/leakage-guard.js +80 -0
- package/template/wall-e/eval/meta-harness/optimizer.js +207 -0
- package/template/wall-e/eval/meta-harness/proposer-runner.js +110 -0
- package/template/wall-e/eval/meta-harness/reporting.js +58 -0
- package/template/wall-e/eval/meta-harness/telemetry.js +27 -0
- package/template/wall-e/eval/meta-harness/validation.js +81 -0
- package/template/wall-e/eval/provider-normalizer.js +33 -0
- package/template/wall-e/eval/run-codex-cli-baseline.js +1 -1
- package/template/wall-e/eval/run-coding-agent-real.js +2 -2
- package/template/wall-e/eval/run-eval.js +16 -6
- package/template/wall-e/evaluation/self-critique.js +5 -3
- package/template/wall-e/evaluation/tier-selector.js +4 -3
- package/template/wall-e/external-action-controller.js +419 -0
- package/template/wall-e/hooks/doctor.js +52 -0
- package/template/wall-e/hooks/index.js +1 -0
- package/template/wall-e/hooks/manifest.js +30 -4
- package/template/wall-e/hooks/runtime.js +7 -5
- package/template/wall-e/http/auth.js +2 -0
- package/template/wall-e/http/chat-api.js +120 -17
- package/template/wall-e/http/model-admin.js +29 -6
- package/template/wall-e/lib/mcp-integration.js +373 -53
- package/template/wall-e/llm/anthropic.js +6 -32
- package/template/wall-e/llm/claude-cli.js +67 -19
- package/template/wall-e/llm/client.js +17 -7
- package/template/wall-e/llm/codex-cli.js +24 -12
- package/template/wall-e/llm/codex-cli.plugin.json +1 -1
- package/template/wall-e/llm/coding-availability.js +2 -1
- package/template/wall-e/llm/deepseek.js +47 -32
- package/template/wall-e/llm/google.js +6 -14
- package/template/wall-e/llm/index.js +2 -0
- package/template/wall-e/llm/model-catalog.js +181 -0
- package/template/wall-e/llm/moonshot.js +149 -0
- package/template/wall-e/llm/moonshot.plugin.json +22 -0
- package/template/wall-e/llm/ollama-setup.js +2 -1
- package/template/wall-e/llm/ollama.js +22 -4
- package/template/wall-e/llm/openai.js +16 -40
- package/template/wall-e/llm/openai.plugin.json +1 -1
- package/template/wall-e/llm/portkey.js +124 -0
- package/template/wall-e/llm/provider-detector.js +24 -2
- package/template/wall-e/llm/provider-error.js +14 -4
- package/template/wall-e/llm/retry.js +14 -0
- package/template/wall-e/llm/supported-models.js +216 -0
- package/template/wall-e/llm/text-tool-calls.js +258 -0
- package/template/wall-e/location-awareness.js +168 -0
- package/template/wall-e/location-inference.js +236 -0
- package/template/wall-e/loops/initiative.js +70 -12
- package/template/wall-e/mcp-server.js +493 -76
- package/template/wall-e/memory/ctm-session-context.js +14 -1
- package/template/wall-e/prompts/coding/frontend-design.md +150 -0
- package/template/wall-e/prompts/coding/memory-protocol.md +5 -2
- package/template/wall-e/routing/index.js +5 -0
- package/template/wall-e/routing/resolve-route.js +202 -0
- package/template/wall-e/runtime/agent-run-context.js +196 -0
- package/template/wall-e/runtime/execution-trace.js +17 -2
- package/template/wall-e/runtime/live-capabilities.js +204 -0
- package/template/wall-e/runtime/prompt-envelope.js +116 -0
- package/template/wall-e/runtime/recovery-lanes.js +151 -0
- package/template/wall-e/runtime/run-envelope.js +242 -0
- package/template/wall-e/runtime/run-trace.js +84 -0
- package/template/wall-e/scripts/smoke-coding-agent-jsonl.js +5 -0
- package/template/wall-e/security/doctor.js +36 -0
- package/template/wall-e/security/sandbox-policy.js +85 -0
- package/template/wall-e/server.js +8 -2
- package/template/wall-e/session-files.js +2 -1
- package/template/wall-e/skills/_bundled/coding-agent/run.js +11 -2
- package/template/wall-e/skills/_bundled/email-sync/run.js +58 -10
- package/template/wall-e/skills/_bundled/gws-workspace/run.js +51 -22
- package/template/wall-e/skills/_bundled/gws-workspace/setup.js +769 -134
- package/template/wall-e/skills/_bundled/memory-search/SKILL.md +3 -0
- package/template/wall-e/skills/_bundled/meta-harness-proposer/SKILL.md +70 -0
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +395 -41
- package/template/wall-e/skills/mcp-client.js +46 -4
- package/template/wall-e/skills/skill-fallback.js +20 -12
- package/template/wall-e/skills/skill-loader.js +307 -29
- package/template/wall-e/skills/skill-planner.js +303 -8
- package/template/wall-e/slack/activation.js +34 -0
- package/template/wall-e/slack/socket-mode-listener.js +3 -1
- package/template/wall-e/telemetry.js +42 -3
- package/template/wall-e/tools/builtin-middleware.js +60 -22
- package/template/wall-e/tools/command-registry.js +59 -9
- package/template/wall-e/tools/local-tools.js +2014 -33
- package/template/wall-e/tools/lsp-client.js +32 -3
- package/template/wall-e/tools/permission-checker.js +13 -1
- package/template/wall-e/tools/permission-rules.js +10 -0
- package/template/wall-e/tools/slack-mcp.js +2 -2
- package/template/website/index.html +22 -15
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# create-walle
|
|
2
2
|
|
|
3
|
-
Set up **CTM + Wall-E** in one command — a browser-based
|
|
3
|
+
Set up **CTM + Wall-E** in one command — a browser-based command center for AI coding agents, remote phone access, review workflows, and a personal AI agent that builds a searchable second brain from your work life.
|
|
4
4
|
|
|
5
5
|
## What You Get
|
|
6
6
|
|
|
@@ -12,7 +12,8 @@ A web dashboard for running and managing AI coding sessions across multiple prov
|
|
|
12
12
|
- **Prompt Editor** — Save, version, and organize prompts with folders, tags, chains, templates, and AI search
|
|
13
13
|
- **Task Queue** — Queue prompts for sequential execution with auto-advance when the agent finishes, or step through manually
|
|
14
14
|
- **Approval Workflows** — Auto-approve tool-use requests based on learned rules; uncertain cases escalate to you
|
|
15
|
-
- **
|
|
15
|
+
- **Remote Phone Access** — Pair your phone with a QR code and use a mobile CTM UI over Microsoft Dev Tunnels, Tailscale, Cloudflare Tunnel, or Walle Remote
|
|
16
|
+
- **Code & Doc Review** — Review git diffs and Markdown docs side by side, add anchored comments, and send feedback into an agent session or queue
|
|
16
17
|
- **Model Registry** — Manage providers (Anthropic, OpenAI, Google, DeepSeek, Ollama, LM Studio, MLX, and CLI subscription providers), compare pricing, switch models per session
|
|
17
18
|
- **Session Insights** — Analyze patterns across sessions to optimize prompts and workflows
|
|
18
19
|
|
|
@@ -23,7 +24,7 @@ An always-on AI agent that learns from your Slack, email, calendar, and coding s
|
|
|
23
24
|
- **Second Brain** — Automatically ingests your digital life and coding sessions into a searchable memory store with full-text search, knowledge extraction, and pattern detection
|
|
24
25
|
- **Proactive Intelligence** — Surfaces time-sensitive items, suggests actions, and delivers morning briefings and weekly reflections without being asked
|
|
25
26
|
- **Chat with Tools** — Talk to Wall-E in the browser — it can search memories, recall prior coding sessions, look up people, run skills, and call external tools via MCP
|
|
26
|
-
- **
|
|
27
|
+
- **21 Bundled Skills** — Morning briefing, weekly reflection, proactive alerts, Slack monitoring, email sync, calendar integration, coding agent, memory search, model training, model pricing sync, and more
|
|
27
28
|
- **Multi-Model** — Works with Claude, GPT, Gemini, DeepSeek, and local models via Ollama, LM Studio, or MLX with smart routing
|
|
28
29
|
- **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
30
|
- **Multi-Device** — Share your brain across machines via Dropbox or iCloud
|
|
@@ -34,7 +35,7 @@ An always-on AI agent that learns from your Slack, email, calendar, and coding s
|
|
|
34
35
|
npx create-walle install ./walle
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
This copies the project, installs dependencies, auto-detects your name and timezone, and starts the server. Open **http://localhost:3456** to finish setup in the browser.
|
|
38
|
+
This copies the project, installs dependencies, auto-detects your name and timezone, and starts the server. Open **http://localhost:3456** to finish setup in the browser, then pair your phone from Setup if you want remote access.
|
|
38
39
|
|
|
39
40
|
## Commands
|
|
40
41
|
|
|
@@ -61,6 +62,7 @@ On first launch, the browser setup page guides you through:
|
|
|
61
62
|
1. **Owner name** — auto-detected from `git config`
|
|
62
63
|
2. **API key** — enter manually, or click "Auto-detect" to find it from your shell environment, Claude Code OAuth, or corporate devbox
|
|
63
64
|
3. **Integrations** — connect Slack (OAuth), email and calendar auto-detected on macOS
|
|
65
|
+
4. **Remote phone access** — optional QR pairing with Microsoft Dev Tunnels, Tailscale, Cloudflare Tunnel, or Walle Remote
|
|
64
66
|
|
|
65
67
|
## Custom Port
|
|
66
68
|
|
|
@@ -76,7 +78,7 @@ Everything runs locally. CTM serves the dashboard, Wall-E runs as a background a
|
|
|
76
78
|
|
|
77
79
|
| Component | Default Port | What it does |
|
|
78
80
|
|-----------|-------------|--------------|
|
|
79
|
-
| CTM | 3456 | Dashboard, multi-agent terminal, prompt editor, queue, model registry, code review |
|
|
81
|
+
| CTM | 3456 | Dashboard, multi-agent terminal, prompt editor, queue, model registry, code/doc review, remote phone UI |
|
|
80
82
|
| Wall-E | 3457 | AI agent, brain database, skills engine, multi-model chat API |
|
|
81
83
|
|
|
82
84
|
## Links
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-walle",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "CTM + Wall-E \u2014 AI coding dashboard and personal digital twin agent. Multi-agent terminal for Claude Code, Codex, Gemini, Aider, OpenCode, and more, plus prompt editor, task queue, and an agent that learns from Slack, email & calendar.",
|
|
3
|
+
"version": "0.9.19",
|
|
4
|
+
"description": "CTM + Wall-E \u2014 AI coding dashboard and personal digital twin agent. Multi-agent terminal for Claude Code, Codex, Gemini, Aider, OpenCode, and more, plus prompt editor, task queue, remote phone access, code/doc review, and an agent that learns from Slack, email & calendar.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-walle": "bin/create-walle.js"
|
|
7
7
|
},
|
package/template/README.md
CHANGED
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
**Wall-E** is your personal digital twin — an AI agent that learns from your Slack, email, and calendar to build a searchable second brain, answer questions in your voice, and automate daily workflows.
|
|
4
4
|
|
|
5
|
-
**CTM** (
|
|
5
|
+
**CTM** (Coding Task Manager) is an agent task manager and terminal multiplexer — a web dashboard for running Claude Code, Codex, Gemini, Aider, OpenCode, Cursor Agent, and other AI coding sessions, plus prompts, code review, phone access, and Wall-E control.
|
|
6
6
|
|
|
7
|
-
Together they give you a local-first AI command center: a browser-based workspace where you manage
|
|
7
|
+
Together they give you a local-first AI command center: a browser-based workspace where you manage AI coding sessions, chat with an AI that knows your work context, respond from your phone, and automate the repetitive parts of your day.
|
|
8
8
|
|
|
9
9
|
## What You Get
|
|
10
10
|
|
|
11
11
|
### CTM — Agent Task Manager
|
|
12
|
-
- **Terminal multiplexer** — run multiple
|
|
12
|
+
- **Terminal multiplexer** — run multiple AI coding agents side-by-side in browser tabs, with session history, search, and replay
|
|
13
13
|
- **Prompt library** — rich-text editor with versioning, folders, tags, and one-click send to any active session
|
|
14
14
|
- **Prompt queue** — batch multiple prompts and send them sequentially to a session with idle detection
|
|
15
15
|
- **Shadow Approver** — learns your permission patterns and auto-approves safe operations across sessions
|
|
16
16
|
- **Code review** — AI-assisted diff review across projects with inline comments
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
17
|
+
- **Phone access** — pair a phone with a QR code and use the mobile CTM UI through Microsoft Dev Tunnels, Tailscale, Cloudflare Tunnel, or Walle Remote
|
|
18
|
+
- **Session insights** — AI analysis of your coding-agent usage with actionable recommendations
|
|
19
|
+
- **Permission manager** — fine-grained control over what coding agents can do automatically, with risk tiers and rule consolidation
|
|
19
20
|
|
|
20
21
|
### Wall-E — Personal AI Agent
|
|
21
22
|
- **Second brain** — ingests Slack messages, calendar events, and sent emails into a local SQLite database with full-text search
|
|
@@ -54,12 +55,10 @@ CTM (port 3456) Wall-E Daemon
|
|
|
54
55
|
## Quickstart
|
|
55
56
|
|
|
56
57
|
```bash
|
|
57
|
-
npx create-walle
|
|
58
|
-
cd my-agent
|
|
59
|
-
node claude-task-manager/server.js
|
|
58
|
+
npx create-walle install ./walle
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
Open **http://localhost:3456** — the setup page walks you through adding your API key and
|
|
61
|
+
Open **http://localhost:3456** — the setup page walks you through adding your API key, connecting integrations, and pairing your phone if you want mobile access. Your name and timezone are auto-detected.
|
|
63
62
|
|
|
64
63
|
Or clone manually:
|
|
65
64
|
|
|
@@ -75,7 +74,7 @@ The first run auto-creates `.env`, `wall-e-config.json`, and `~/.walle/data/`. F
|
|
|
75
74
|
## Dashboard Features
|
|
76
75
|
|
|
77
76
|
### Sessions
|
|
78
|
-
Terminal multiplexer for
|
|
77
|
+
Terminal multiplexer for AI coding agents — create, monitor, and manage multiple sessions from a single browser tab. Features include:
|
|
79
78
|
- Live terminal output via WebSocket (xterm.js)
|
|
80
79
|
- Session search and AI-powered search across all session history
|
|
81
80
|
- AI auto-titling for sessions
|
|
@@ -84,7 +83,7 @@ Terminal multiplexer for Claude Code — create, monitor, and manage multiple se
|
|
|
84
83
|
- Session replay and review
|
|
85
84
|
|
|
86
85
|
### Prompts
|
|
87
|
-
Rich-text prompt editor with a full formatting toolbar. Organize prompts into folders, tag them, track usage across sessions, and send to any active
|
|
86
|
+
Rich-text prompt editor with a full formatting toolbar. Organize prompts into folders, tag them, track usage across sessions, and send to any active coding-agent session with one click.
|
|
88
87
|
- **Composite prompts** — parent prompt with sub-prompts that compose into a single message
|
|
89
88
|
- **Prompt queue** — batch multiple prompts, send sequentially with idle detection between items
|
|
90
89
|
- **Power tools** — chains (multi-step sequences), templates, pattern detection, harvest (extract prompts from session history), and AI copilot suggestions
|
|
@@ -101,8 +100,11 @@ Chat directly with Wall-E from the dashboard. Wall-E has access to your full bra
|
|
|
101
100
|
|
|
102
101
|
Sub-tabs: Chat, Tasks (background task manager), Skills (view and run), Brain (knowledge graph), Actions, Timeline, Questions, Status.
|
|
103
102
|
|
|
103
|
+
### Phone Access
|
|
104
|
+
Pair a phone from Setup and open the mobile CTM UI at `/m/`. CTM supports Microsoft Dev Tunnels, Tailscale, Cloudflare Tunnel, and Walle Remote paths so you can monitor sessions and respond while away from the desktop browser.
|
|
105
|
+
|
|
104
106
|
### Shadow Approver
|
|
105
|
-
Learns your permission patterns from
|
|
107
|
+
Learns your permission patterns from coding-agent sessions and auto-approves safe operations. Features:
|
|
106
108
|
- Pattern learning from your approval history
|
|
107
109
|
- AI-driven approval decisions with confidence scoring
|
|
108
110
|
- Domain-specific trust tiers (Observe, Draft, Guarded, Autonomous)
|
|
@@ -114,10 +116,10 @@ AI-assisted code review across projects:
|
|
|
114
116
|
- Inline diff viewer
|
|
115
117
|
- Multi-project support
|
|
116
118
|
- AI review comments with confidence levels
|
|
117
|
-
- Send review to a
|
|
119
|
+
- Send review to a coding-agent session for implementation
|
|
118
120
|
|
|
119
121
|
### Session Insights
|
|
120
|
-
AI analysis of your
|
|
122
|
+
AI analysis of your coding-agent usage patterns:
|
|
121
123
|
- Workflow recommendations (automate repetitive tasks)
|
|
122
124
|
- Prompt effectiveness analysis
|
|
123
125
|
- Skill gap detection
|
|
@@ -125,7 +127,7 @@ AI analysis of your Claude Code usage patterns:
|
|
|
125
127
|
- Session statistics
|
|
126
128
|
|
|
127
129
|
### Permission Manager
|
|
128
|
-
Fine-grained control over what
|
|
130
|
+
Fine-grained control over what coding agents can do automatically:
|
|
129
131
|
- Search and filter across all rules
|
|
130
132
|
- Risk-based categorization (LOW, MEDIUM, HIGH)
|
|
131
133
|
- Per-project or global scope
|
|
@@ -239,7 +241,7 @@ CTM runs on port 3456. Key endpoints:
|
|
|
239
241
|
| GET | `/api/wall-e/tasks` | List background tasks |
|
|
240
242
|
| POST | `/api/wall-e/chat` | Chat with Wall-E (supports SSE streaming) |
|
|
241
243
|
| GET | `/api/prompts` | List prompts |
|
|
242
|
-
| GET | `/api/recent-sessions` | List recent
|
|
244
|
+
| GET | `/api/recent-sessions` | List recent coding-agent sessions |
|
|
243
245
|
|
|
244
246
|
## Tech Stack
|
|
245
247
|
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_MAX_AGE_MIN = 24 * 60;
|
|
7
|
+
const PROTECTED_PORTS = new Set([3456, 3457]);
|
|
8
|
+
|
|
9
|
+
function parseArgs(argv) {
|
|
10
|
+
const opts = {
|
|
11
|
+
kill: false,
|
|
12
|
+
stale: false,
|
|
13
|
+
maxAgeMin: DEFAULT_MAX_AGE_MIN,
|
|
14
|
+
port: null,
|
|
15
|
+
wallePort: null,
|
|
16
|
+
json: false,
|
|
17
|
+
};
|
|
18
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
+
const arg = argv[i];
|
|
20
|
+
if (arg === '--kill') opts.kill = true;
|
|
21
|
+
else if (arg === '--stale') opts.stale = true;
|
|
22
|
+
else if (arg === '--json') opts.json = true;
|
|
23
|
+
else if (arg === '--max-age-min') opts.maxAgeMin = Number(argv[++i] || DEFAULT_MAX_AGE_MIN);
|
|
24
|
+
else if (arg === '--port') opts.port = Number(argv[++i] || 0) || null;
|
|
25
|
+
else if (arg === '--wall-e-port') opts.wallePort = Number(argv[++i] || 0) || null;
|
|
26
|
+
else if (arg === '--help' || arg === '-h') opts.help = true;
|
|
27
|
+
}
|
|
28
|
+
return opts;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseElapsedToSeconds(value) {
|
|
32
|
+
const text = String(value || '').trim();
|
|
33
|
+
if (!text) return 0;
|
|
34
|
+
const daySplit = text.split('-');
|
|
35
|
+
let days = 0;
|
|
36
|
+
let rest = text;
|
|
37
|
+
if (daySplit.length === 2) {
|
|
38
|
+
days = Number(daySplit[0]) || 0;
|
|
39
|
+
rest = daySplit[1];
|
|
40
|
+
}
|
|
41
|
+
const parts = rest.split(':').map(n => Number(n) || 0);
|
|
42
|
+
if (parts.length === 3) return days * 86400 + parts[0] * 3600 + parts[1] * 60 + parts[2];
|
|
43
|
+
if (parts.length === 2) return days * 86400 + parts[0] * 60 + parts[1];
|
|
44
|
+
return days * 86400 + (parts[0] || 0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function findExecutable(candidates) {
|
|
48
|
+
for (const file of candidates) {
|
|
49
|
+
try {
|
|
50
|
+
execFileSync(file, ['-v'], { stdio: 'ignore', timeout: 1000 });
|
|
51
|
+
return file;
|
|
52
|
+
} catch {}
|
|
53
|
+
}
|
|
54
|
+
return candidates[0];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function runText(file, args, timeout = 3000) {
|
|
58
|
+
try {
|
|
59
|
+
return execFileSync(file, args, { encoding: 'utf8', timeout, maxBuffer: 8 * 1024 * 1024 });
|
|
60
|
+
} catch {
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function listProcesses() {
|
|
66
|
+
const output = runText('ps', ['-A', '-o', 'pid=,ppid=,etime=,pcpu=,command=']);
|
|
67
|
+
const rows = [];
|
|
68
|
+
for (const line of output.split(/\r?\n/)) {
|
|
69
|
+
const trimmed = line.trim();
|
|
70
|
+
if (!trimmed) continue;
|
|
71
|
+
const match = trimmed.match(/^(\d+)\s+(\d+)\s+(\S+)\s+([0-9.]+)\s+(.+)$/);
|
|
72
|
+
if (!match) continue;
|
|
73
|
+
rows.push({
|
|
74
|
+
pid: Number(match[1]),
|
|
75
|
+
ppid: Number(match[2]),
|
|
76
|
+
etime: match[3],
|
|
77
|
+
ageSeconds: parseElapsedToSeconds(match[3]),
|
|
78
|
+
cpu: Number(match[4]) || 0,
|
|
79
|
+
command: match[5].trim(),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return rows;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function lsofBinary() {
|
|
86
|
+
return findExecutable(['lsof', '/usr/sbin/lsof', '/usr/bin/lsof']);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function pidsListeningOnPort(port, lsof = lsofBinary()) {
|
|
90
|
+
if (!port || PROTECTED_PORTS.has(Number(port))) return [];
|
|
91
|
+
const output = runText(lsof, [`-tiTCP:${port}`, '-sTCP:LISTEN', '-nP']);
|
|
92
|
+
return [...new Set(output.split(/\s+/).map(n => Number(n)).filter(Number.isInteger))];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function processDetails(pid, lsof = lsofBinary()) {
|
|
96
|
+
const output = runText(lsof, ['-Pan', '-p', String(pid)], 2000);
|
|
97
|
+
const ports = [];
|
|
98
|
+
const paths = [];
|
|
99
|
+
for (const line of output.split(/\r?\n/)) {
|
|
100
|
+
const portMatch = line.match(/TCP\s+\S+:(\d+)\s+\(LISTEN\)/);
|
|
101
|
+
if (portMatch) ports.push(Number(portMatch[1]));
|
|
102
|
+
const pathMatch = line.match(/\s(\/(?:private\/)?tmp\/(?:walle|ctm)-[^ ]+)/);
|
|
103
|
+
if (pathMatch) paths.push(pathMatch[1]);
|
|
104
|
+
}
|
|
105
|
+
return { ports: [...new Set(ports)], paths: [...new Set(paths)] };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function isProtectedProcess(proc, details = {}) {
|
|
109
|
+
if (/^(ctm|walle)-primary\b/.test(proc.command)) return true;
|
|
110
|
+
return (details.ports || []).some(port => PROTECTED_PORTS.has(Number(port)));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function titleKind(command) {
|
|
114
|
+
if (/^ctm-dev-\d+\b/.test(command)) return 'ctm-dev';
|
|
115
|
+
if (/^walle-dev-\d+\b/.test(command)) return 'walle-dev';
|
|
116
|
+
if (/^ctm-(?:badge-test|render-test|e2e|test)(?:[-\w]*)?\b/.test(command)) return 'ctm-test';
|
|
117
|
+
if (/^walle-(?:staging|render-test|e2e|test)(?:[-\w]*)?\b/.test(command)) return 'walle-test';
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function commandMatchesExactPort(command, port, wallePort) {
|
|
122
|
+
if (PROTECTED_PORTS.has(Number(port)) || PROTECTED_PORTS.has(Number(wallePort))) return false;
|
|
123
|
+
if (port && (command === `ctm-dev-${port}` || command === `walle-dev-${port}`)) return true;
|
|
124
|
+
if (wallePort && command === `walle-dev-${Number(wallePort) - 1}`) return true;
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function tempBacked(details) {
|
|
129
|
+
return (details.paths || []).some(p =>
|
|
130
|
+
/\/(?:private\/)?tmp\/(?:walle-dev|walle-staging|walle-e2e|ctm-dev|ctm-worktree|ctm-render-test|ctm-e2e)(?:[-/]|$)/.test(p)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function collectTargets(procs, opts, detailsByPid = new Map()) {
|
|
135
|
+
const maxAgeSeconds = Math.max(0, Number(opts.maxAgeMin || DEFAULT_MAX_AGE_MIN)) * 60;
|
|
136
|
+
const exactPortPids = new Set([
|
|
137
|
+
...pidsListeningOnPort(opts.port).filter(pid => Number.isInteger(pid)),
|
|
138
|
+
...pidsListeningOnPort(opts.wallePort).filter(pid => Number.isInteger(pid)),
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
const targets = [];
|
|
142
|
+
const kept = [];
|
|
143
|
+
|
|
144
|
+
for (const proc of procs) {
|
|
145
|
+
const kind = titleKind(proc.command);
|
|
146
|
+
const maybeExact = exactPortPids.has(proc.pid) || commandMatchesExactPort(proc.command, opts.port, opts.wallePort);
|
|
147
|
+
if (!kind && !maybeExact) continue;
|
|
148
|
+
|
|
149
|
+
const details = detailsByPid.get(proc.pid) || processDetails(proc.pid);
|
|
150
|
+
detailsByPid.set(proc.pid, details);
|
|
151
|
+
|
|
152
|
+
if (isProtectedProcess(proc, details)) {
|
|
153
|
+
kept.push({ ...proc, reason: 'protected primary CTM/Wall-E' });
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (maybeExact) {
|
|
158
|
+
targets.push({ ...proc, reason: 'matching requested dev port', details });
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!opts.stale) {
|
|
163
|
+
kept.push({ ...proc, reason: `${kind} candidate; stale sweep disabled`, details });
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const oldEnough = proc.ageSeconds >= maxAgeSeconds;
|
|
168
|
+
const orphaned = proc.ppid === 1 && tempBacked(details);
|
|
169
|
+
if (oldEnough || orphaned) {
|
|
170
|
+
targets.push({
|
|
171
|
+
...proc,
|
|
172
|
+
reason: oldEnough ? `stale ${kind} older than ${opts.maxAgeMin}m` : `orphaned temp-backed ${kind}`,
|
|
173
|
+
details,
|
|
174
|
+
});
|
|
175
|
+
} else {
|
|
176
|
+
kept.push({ ...proc, reason: `${kind} below stale threshold`, details });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return { targets, kept };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function killTargets(targets) {
|
|
184
|
+
const killedByPid = new Map();
|
|
185
|
+
for (const proc of targets) {
|
|
186
|
+
try {
|
|
187
|
+
process.kill(proc.pid, 'SIGTERM');
|
|
188
|
+
killedByPid.set(proc.pid, { ...proc, signal: 'SIGTERM' });
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
const deadline = Date.now() + 1500;
|
|
192
|
+
while (Date.now() < deadline) {
|
|
193
|
+
const alive = targets.filter(proc => {
|
|
194
|
+
try { process.kill(proc.pid, 0); return true; } catch { return false; }
|
|
195
|
+
});
|
|
196
|
+
if (alive.length === 0) return [...killedByPid.values()];
|
|
197
|
+
}
|
|
198
|
+
for (const proc of targets) {
|
|
199
|
+
try {
|
|
200
|
+
process.kill(proc.pid, 0);
|
|
201
|
+
process.kill(proc.pid, 'SIGKILL');
|
|
202
|
+
const previous = killedByPid.get(proc.pid);
|
|
203
|
+
killedByPid.set(proc.pid, { ...(previous || proc), signal: previous ? 'SIGTERM+SIGKILL' : 'SIGKILL' });
|
|
204
|
+
} catch {}
|
|
205
|
+
}
|
|
206
|
+
return [...killedByPid.values()];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function formatReport(result, opts) {
|
|
210
|
+
if (opts.json) return JSON.stringify(result, null, 2);
|
|
211
|
+
const action = opts.kill ? 'Cleaned' : 'Would clean';
|
|
212
|
+
const lines = [`${action} ${result.killed.length || result.targets.length} CTM/Wall-E dev process(es); kept ${result.kept.length}.`];
|
|
213
|
+
const visibleTargets = opts.kill ? result.killed : result.targets;
|
|
214
|
+
if (visibleTargets.length > 0) {
|
|
215
|
+
lines.push('');
|
|
216
|
+
lines.push(opts.kill ? 'Killed:' : 'Targets:');
|
|
217
|
+
for (const p of visibleTargets) {
|
|
218
|
+
const ports = p.details && p.details.ports && p.details.ports.length ? ` ports=${p.details.ports.join(',')}` : '';
|
|
219
|
+
lines.push(` PID ${p.pid} ${p.command} (${p.cpu}% CPU, age ${p.etime}) - ${p.reason}${ports}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (result.kept.length > 0) {
|
|
223
|
+
lines.push('');
|
|
224
|
+
lines.push('Kept:');
|
|
225
|
+
for (const p of result.kept) {
|
|
226
|
+
lines.push(` PID ${p.pid} ${p.command} - ${p.reason}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return lines.join('\n');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function main(argv = process.argv.slice(2)) {
|
|
233
|
+
const opts = parseArgs(argv);
|
|
234
|
+
if (opts.help) {
|
|
235
|
+
console.log([
|
|
236
|
+
'Usage: node bin/ctm-dev-cleanup.js [--kill] [--stale] [--max-age-min N] [--port N --wall-e-port N] [--json]',
|
|
237
|
+
'',
|
|
238
|
+
'Dry-runs by default. Never targets ctm-primary/walle-primary or ports 3456/3457.',
|
|
239
|
+
].join('\n'));
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
const detailsByPid = new Map();
|
|
243
|
+
const { targets, kept } = collectTargets(listProcesses(), opts, detailsByPid);
|
|
244
|
+
const killed = opts.kill ? killTargets(targets) : [];
|
|
245
|
+
const result = { targets, killed, kept };
|
|
246
|
+
console.log(formatReport(result, opts));
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (require.main === module) {
|
|
251
|
+
process.exitCode = main();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
module.exports = {
|
|
255
|
+
collectTargets,
|
|
256
|
+
commandMatchesExactPort,
|
|
257
|
+
formatReport,
|
|
258
|
+
isProtectedProcess,
|
|
259
|
+
killTargets,
|
|
260
|
+
parseArgs,
|
|
261
|
+
parseElapsedToSeconds,
|
|
262
|
+
tempBacked,
|
|
263
|
+
titleKind,
|
|
264
|
+
};
|
package/template/bin/dev.sh
CHANGED
|
@@ -27,6 +27,15 @@ fi
|
|
|
27
27
|
mkdir -p "$DEV_DIR"
|
|
28
28
|
|
|
29
29
|
cleanup_processes() {
|
|
30
|
+
local stale_args=()
|
|
31
|
+
if [[ "${1:-}" == "--stale" ]]; then
|
|
32
|
+
stale_args=(--stale --max-age-min "${CTM_DEV_STALE_MAX_MIN:-1440}")
|
|
33
|
+
fi
|
|
34
|
+
node "$ROOT/bin/ctm-dev-cleanup.js" \
|
|
35
|
+
--kill \
|
|
36
|
+
--port "$DEV_CTM_PORT" \
|
|
37
|
+
--wall-e-port "$DEV_WALLE_PORT" \
|
|
38
|
+
"${stale_args[@]}" >/dev/null 2>&1 || true
|
|
30
39
|
pkill -f "ctm-dev-$DEV_CTM_PORT" 2>/dev/null || true
|
|
31
40
|
pkill -f "walle-dev-$DEV_CTM_PORT" 2>/dev/null || true
|
|
32
41
|
lsof -ti ":$DEV_CTM_PORT" -sTCP:LISTEN 2>/dev/null | xargs kill 2>/dev/null || true
|
|
@@ -35,6 +44,10 @@ cleanup_processes() {
|
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
cleanup_dev() {
|
|
47
|
+
node "$ROOT/bin/ctm-dev-cleanup.js" \
|
|
48
|
+
--kill \
|
|
49
|
+
--port "$DEV_CTM_PORT" \
|
|
50
|
+
--wall-e-port "$DEV_WALLE_PORT" >/dev/null 2>&1 || true
|
|
38
51
|
cleanup_processes
|
|
39
52
|
# Remove dev data directory to prevent /tmp bloat (each copy is ~2-6 GB)
|
|
40
53
|
if [[ "$DEV_DIR" == /tmp/walle-* && -d "$DEV_DIR" ]]; then
|
|
@@ -43,7 +56,7 @@ cleanup_dev() {
|
|
|
43
56
|
fi
|
|
44
57
|
}
|
|
45
58
|
|
|
46
|
-
cleanup_processes
|
|
59
|
+
cleanup_processes --stale
|
|
47
60
|
|
|
48
61
|
# Handle flags
|
|
49
62
|
if [[ "$1" == "--fresh" || -z "$1" ]]; then
|
|
@@ -81,14 +94,39 @@ export WALL_E_SESSIONS_DIR="$DEV_DIR/sessions"
|
|
|
81
94
|
export CTM_HOST="127.0.0.1"
|
|
82
95
|
export CTM_INSTANCE_TAG="dev-$DEV_CTM_PORT"
|
|
83
96
|
export OAUTH_PROXY_PORT="$DEV_OAUTH_PROXY_PORT"
|
|
97
|
+
export CTM_TLS_CERT=""
|
|
98
|
+
export CTM_TLS_KEY=""
|
|
99
|
+
# Dev instances must not rewrite user-level Codex/Claude MCP config to their
|
|
100
|
+
# temporary Wall-E port. Set WALLE_MCP_AUTO_CONFIG=1 to opt in deliberately.
|
|
101
|
+
export WALLE_MCP_AUTO_CONFIG="${WALLE_MCP_AUTO_CONFIG:-0}"
|
|
84
102
|
|
|
85
103
|
# Source the rest of .env (API keys, owner name, etc.)
|
|
86
104
|
if [[ -f "$ROOT/.env" ]]; then
|
|
87
105
|
set -a
|
|
88
|
-
source <(grep -v '^#' "$ROOT/.env" | grep -vE '^(CTM_PORT|WALL_E_PORT|CTM_DATA_DIR|WALL_E_DATA_DIR|WALLE_SESSIONS_DIR|WALL_E_SESSIONS_DIR|CTM_HOST|CTM_INSTANCE_TAG|OAUTH_PROXY_PORT)=' | grep '=')
|
|
106
|
+
source <(grep -v '^#' "$ROOT/.env" | grep -vE '^(CTM_PORT|WALL_E_PORT|CTM_DATA_DIR|WALL_E_DATA_DIR|WALLE_SESSIONS_DIR|WALL_E_SESSIONS_DIR|CTM_HOST|CTM_INSTANCE_TAG|OAUTH_PROXY_PORT|CTM_TLS_CERT|CTM_TLS_KEY|CTM_API_BASE_URL|CTM_SESSION_MEMORY_API_BASE_URL|WALLE_MCP_AUTO_CONFIG|CTM_SKIP_DOTENV)=' | grep '=')
|
|
89
107
|
set +a
|
|
90
108
|
fi
|
|
91
109
|
|
|
110
|
+
# Reassert the dev isolation boundary after loading production credentials.
|
|
111
|
+
# Some user .env files contain TLS/public-host settings for the primary CTM;
|
|
112
|
+
# the dev instance must stay loopback HTTP so Wall-E's internal CTM API probe,
|
|
113
|
+
# browser tests, and curl checks hit the isolated data dir instead.
|
|
114
|
+
export CTM_PORT="$DEV_CTM_PORT"
|
|
115
|
+
export WALL_E_PORT="$DEV_WALLE_PORT"
|
|
116
|
+
export CTM_DATA_DIR="$DEV_DIR"
|
|
117
|
+
export WALL_E_DATA_DIR="$DEV_DIR"
|
|
118
|
+
export WALLE_SESSIONS_DIR="$DEV_DIR/sessions"
|
|
119
|
+
export WALL_E_SESSIONS_DIR="$DEV_DIR/sessions"
|
|
120
|
+
export CTM_HOST="127.0.0.1"
|
|
121
|
+
export CTM_INSTANCE_TAG="dev-$DEV_CTM_PORT"
|
|
122
|
+
export OAUTH_PROXY_PORT="$DEV_OAUTH_PROXY_PORT"
|
|
123
|
+
export CTM_TLS_CERT=""
|
|
124
|
+
export CTM_TLS_KEY=""
|
|
125
|
+
export CTM_API_BASE_URL="http://127.0.0.1:$DEV_CTM_PORT"
|
|
126
|
+
export CTM_SESSION_MEMORY_API_BASE_URL="http://127.0.0.1:$DEV_CTM_PORT"
|
|
127
|
+
export WALLE_MCP_AUTO_CONFIG="${WALLE_MCP_AUTO_CONFIG:-0}"
|
|
128
|
+
export CTM_SKIP_DOTENV="1"
|
|
129
|
+
|
|
92
130
|
trap cleanup_dev EXIT
|
|
93
131
|
|
|
94
132
|
# Clean up stale dev/e2e data dirs older than 24h (from crashed sessions)
|