create-walle 0.8.0 → 0.9.1

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.
Files changed (50) hide show
  1. package/README.md +23 -7
  2. package/package.json +3 -3
  3. package/template/CLAUDE.md +14 -1
  4. package/template/README.md +123 -43
  5. package/template/claude-task-manager/bin/restart-ctm.sh +3 -2
  6. package/template/claude-task-manager/db.js +40 -2
  7. package/template/claude-task-manager/public/css/walle.css +123 -0
  8. package/template/claude-task-manager/public/index.html +1003 -75
  9. package/template/claude-task-manager/public/js/walle.js +562 -131
  10. package/template/claude-task-manager/public/prompts.html +84 -26
  11. package/template/claude-task-manager/public/walle-icon.svg +45 -0
  12. package/template/claude-task-manager/server.js +69 -4
  13. package/template/docs/openclaw-vs-walle-comparison.md +103 -0
  14. package/template/package.json +1 -1
  15. package/template/wall-e/agent.js +63 -3
  16. package/template/wall-e/api-walle.js +158 -0
  17. package/template/wall-e/brain.js +182 -5
  18. package/template/wall-e/channels/imessage-channel.js +4 -1
  19. package/template/wall-e/channels/slack-channel.js +3 -1
  20. package/template/wall-e/chat.js +115 -213
  21. package/template/wall-e/context/compactor.js +163 -0
  22. package/template/wall-e/context/context-builder.js +355 -0
  23. package/template/wall-e/context/state-snapshot.js +209 -0
  24. package/template/wall-e/context/token-counter.js +55 -0
  25. package/template/wall-e/context/topic-matcher.js +79 -0
  26. package/template/wall-e/core-tasks.js +25 -1
  27. package/template/wall-e/events/event-bus.js +23 -0
  28. package/template/wall-e/loops/ingest.js +4 -0
  29. package/template/wall-e/loops/initiative.js +316 -0
  30. package/template/wall-e/loops/tasks.js +55 -5
  31. package/template/wall-e/skills/_bundled/email-sync/run.js +3 -1
  32. package/template/wall-e/skills/_bundled/mcp-scan/SKILL.md +14 -0
  33. package/template/wall-e/skills/_bundled/mcp-scan/run.js +86 -0
  34. package/template/wall-e/skills/_bundled/morning-briefing/run.js +41 -0
  35. package/template/wall-e/skills/_bundled/proactive-alerts/SKILL.md +20 -0
  36. package/template/wall-e/skills/_bundled/proactive-alerts/run.js +144 -0
  37. package/template/wall-e/skills/_bundled/slack-mentions/.watched-threads.json +18 -0
  38. package/template/wall-e/skills/_bundled/slack-mentions/.watermark.json +4 -0
  39. package/template/wall-e/skills/_bundled/slack-mentions/SKILL.md +52 -0
  40. package/template/wall-e/skills/_bundled/slack-mentions/run.js +470 -0
  41. package/template/wall-e/skills/_bundled/weekly-reflection/SKILL.md +69 -0
  42. package/template/wall-e/skills/mcp-client.js +241 -13
  43. package/template/wall-e/tests/brain.test.js +4 -4
  44. package/template/wall-e/tests/compactor.test.js +323 -0
  45. package/template/wall-e/tests/context-builder.test.js +215 -0
  46. package/template/wall-e/tests/event-bus.test.js +74 -0
  47. package/template/wall-e/tests/initiative.test.js +354 -0
  48. package/template/wall-e/tests/proactive-alerts.test.js +140 -0
  49. package/template/wall-e/tests/session-persistence.test.js +335 -0
  50. package/template/wall-e/tools/local-tools.js +65 -0
package/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # create-walle
2
2
 
3
- Set up **Wall-E** your personal digital twin. An AI agent that learns from your Slack, email, and calendar to build a searchable second brain.
3
+ Set up **CTM + Wall-E** in one command.
4
+
5
+ **CTM** (Claude Task Manager) is a web-based dashboard for running and managing Claude Code sessions. It includes a terminal multiplexer, prompt editor, task queue, and code review panel — all in the browser.
6
+
7
+ **Wall-E** is your personal digital twin. An AI agent that learns from your Slack, email, and calendar to build a searchable second brain. It comes with bundled skills (morning briefing, weekly reflection, proactive alerts, and more) and a chat interface with tool-use.
8
+
9
+ Together they run as a single server: CTM on the main port, Wall-E on port+1.
4
10
 
5
11
  ## Install
6
12
 
@@ -13,11 +19,11 @@ This copies the project, installs dependencies, auto-detects your name and timez
13
19
  ## Commands
14
20
 
15
21
  ```bash
16
- npx create-walle install <dir> # Install Wall-E (or update if already installed)
22
+ npx create-walle install <dir> # Install CTM + Wall-E (or update if already installed)
17
23
  npx create-walle update # Update to latest version, keep your config
18
24
  npx create-walle start # Start as background service (auto-restarts on reboot)
19
25
  npx create-walle stop # Stop the service
20
- npx create-walle status # Check if Wall-E is running
26
+ npx create-walle status # Check if running
21
27
  npx create-walle logs # Tail the service logs
22
28
  npx create-walle uninstall # Remove the auto-start service
23
29
  npx create-walle -v # Show version
@@ -62,10 +68,20 @@ Wall-E API runs on `CTM_PORT + 1` (e.g., 5001).
62
68
 
63
69
  ## What's Included
64
70
 
65
- - **CTM Dashboard** — terminal multiplexer, prompt editor, task manager, code review
66
- - **Wall-E Agent**ingest/think/reflect loops, 7 bundled skills, chat with tool-use
67
- - **Brain DB**SQLite with full-text search across Slack, email, calendar
68
- - **Multi-device**share data via Dropbox/iCloud, sessions tagged by hostname
71
+ **CTM Dashboard:**
72
+ - Terminal multiplexerrun multiple Claude Code sessions side by side
73
+ - Prompt editorsave, organize, and queue prompts to Claude
74
+ - Task queue automated prompt execution with auto/manual modes
75
+ - Code review panel — session insights and review workflows
76
+ - Live session status — Running/Waiting/Idle indicators with scroll-up support during active output
77
+
78
+ **Wall-E Agent:**
79
+ - Ingest/think/reflect loops that continuously learn from your data
80
+ - 12 bundled skills (morning briefing, weekly reflection, proactive alerts, slack mentions, email sync, and more)
81
+ - Chat with tool-use — search memories, run skills, call MCP servers
82
+ - Brain DB — SQLite with full-text search across Slack, email, calendar
83
+ - Intelligence engine — context-aware compaction, initiative scoring, proactive briefings
84
+ - Multi-device — share data via Dropbox/iCloud, sessions tagged by hostname
69
85
 
70
86
  ## Links
71
87
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.8.0",
4
- "description": "Wall-E — your personal digital twin. AI agent that learns from Slack, email & calendar. Includes dashboard, chat, and 7 bundled skills.",
3
+ "version": "0.9.1",
4
+ "description": "CTM + Wall-E — Claude Task Manager dashboard and your personal digital twin AI agent. Terminal multiplexer, 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,5 @@
15
15
  "prepublishOnly": "bash build.sh"
16
16
  },
17
17
  "license": "MIT",
18
- "keywords": ["wall-e", "ai", "digital-twin", "claude", "personal-assistant"]
18
+ "keywords": ["ctm", "task-manager", "wall-e", "ai", "digital-twin", "claude", "personal-assistant"]
19
19
  }
@@ -5,8 +5,21 @@
5
5
  NEVER kill CTM or Wall-E processes directly (e.g. `kill`, `lsof | xargs kill`, `pkill`).
6
6
  Always use the restart API or helper script — they handle graceful shutdown and auto-respawn.
7
7
 
8
- - **Restart CTM**: `bash claude-task-manager/bin/restart-ctm.sh` or `curl -sX POST http://localhost:3456/api/restart/ctm`
8
+ - **Restart CTM**: `bash claude-task-manager/bin/restart-ctm.sh` or `curl -sX POST http://localhost:3456/api/restart/ctm?force=true`
9
9
  - **Restart Wall-E**: `curl -sX POST http://localhost:3456/api/restart/walle`
10
10
  - **Stop Wall-E**: `curl -sX POST http://localhost:3456/api/stop/walle`
11
11
  - **Start Wall-E**: `curl -sX POST http://localhost:3456/api/start/walle`
12
12
  - **Check status**: `curl -s http://localhost:3456/api/services/status`
13
+
14
+ ## CTM Development — CRITICAL SAFETY RULE
15
+
16
+ **NEVER test code changes against the primary instance (port 3456/3457).**
17
+ The primary instance is the user's live workbench — restarting or testing against it
18
+ kills all active sessions. This applies to ALL operations: curl, fetch, restart, etc.
19
+
20
+ When developing CTM or Wall-E code:
21
+ 1. Use the `/ctm-dev` skill (or run it manually)
22
+ 2. Pick a random port pair: `DEV_CTM_PORT=$((4100 + RANDOM % 900))`
23
+ 3. Start a dev instance: `DEV_CTM_PORT=$port DEV_WALLE_PORT=$((port+1)) bash bin/dev.sh`
24
+ 4. Test ONLY against your dev port, never 3456
25
+ 5. Only restart primary when the user explicitly asks — and ask for confirmation first
@@ -1,34 +1,54 @@
1
- # Wall-E
1
+ # Wall-E + CTM
2
2
 
3
- **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.
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
- Wall-E runs locally alongside **CTM** (Claude Task Manager), a terminal multiplexer and task dashboard for Claude Code sessions.
5
+ **CTM** (Claude Task Manager) is an agent task manager and terminal multiplexer a web dashboard for running Claude Code sessions, managing prompts, reviewing code, and controlling Wall-E.
6
6
 
7
- ## What It Does
7
+ Together they give you a local-first AI command center: a browser-based workspace where you manage Claude Code sessions, chat with an AI that knows your work context, and automate the repetitive parts of your day.
8
8
 
9
- - **Ingests** your Slack messages, calendar events, and sent emails into a local SQLite brain
10
- - **Learns** your preferences, relationships, communication style, and knowledge over time
11
- - **Answers** questions about your work, meetings, and conversations — with citations
12
- - **Runs skills** on a schedule: morning briefings, Slack sync, calendar sync, and more
13
- - **Manages tasks** and Claude Code sessions through a web dashboard
9
+ ## What You Get
10
+
11
+ ### CTM Agent Task Manager
12
+ - **Terminal multiplexer** run multiple Claude Code sessions side-by-side in browser tabs, with session history, search, and replay
13
+ - **Prompt library** — rich-text editor with versioning, folders, tags, and one-click send to any active session
14
+ - **Prompt queue** — batch multiple prompts and send them sequentially to a session with idle detection
15
+ - **Shadow Approver** — learns your permission patterns and auto-approves safe operations across sessions
16
+ - **Code review** — AI-assisted diff review across projects with inline comments
17
+ - **Session insights** — AI analysis of your Claude Code usage with actionable recommendations
18
+ - **Permission manager** — fine-grained control over what Claude Code can do automatically, with risk tiers and rule consolidation
19
+
20
+ ### Wall-E — Personal AI Agent
21
+ - **Second brain** — ingests Slack messages, calendar events, and sent emails into a local SQLite database with full-text search
22
+ - **Chat** — ask questions about your work, meetings, and conversations — grounded in your actual data with citations
23
+ - **Scheduled skills** — morning briefings, Slack sync, calendar sync, email digest, and custom skills on configurable schedules
24
+ - **Background tasks** — recurring or one-shot tasks with live logs, skill execution, and checkpoint/resume
25
+ - **Knowledge graph** — automatically extracts facts, relationships, and patterns from your data over time
26
+ - **People intelligence** — tracks relationships, communication patterns, trust levels, and personas
27
+ - **MCP integration** — calls tools on Slack, GitHub, and custom MCP servers directly from chat
28
+ - **macOS native** — calendar via EventKit, email via AppleScript, Spotlight file search, desktop notifications, clipboard access
14
29
 
15
30
  ## Architecture
16
31
 
17
32
  ```
18
- CTM (port 3456) Wall-E
33
+ CTM (port 3456) Wall-E Daemon
19
34
  +-----------------------+ +------------------------+
20
35
  | Web Dashboard | | Agent Daemon |
21
36
  | - Sessions (pty) | <---> | - Ingest loop (60s) |
22
37
  | - Prompts editor | | - Think loop (120s) |
23
- | - Task manager | | - Reflect loop (1hr) |
24
- | - Code review | | - Skills loop (5min) |
25
- | - Wall-E chat tab | | - Tasks loop (30s) |
26
- +-----------------------+ +------------------------+
27
- | |
28
- v v
29
- task-manager.db wall-e-brain.db
30
- (sessions, prompts, (memories, knowledge,
31
- tasks, reviews) people, skills, tasks)
38
+ | - Prompt queue | | - Reflect loop (1hr) |
39
+ | - Shadow Approver | | - Skills loop (5min) |
40
+ | - Code review | | - Tasks loop (30s) |
41
+ | - Session insights | | |
42
+ | - Permission manager | | Chat Engine |
43
+ | - Wall-E chat tab | | - Tool use (local+MCP)|
44
+ +-----------------------+ | - Memory search |
45
+ | | - Skill execution |
46
+ v +------------------------+
47
+ task-manager.db |
48
+ (sessions, prompts, v
49
+ rules, reviews) wall-e-brain.db
50
+ (memories, knowledge,
51
+ people, skills, tasks)
32
52
  ```
33
53
 
34
54
  ## Quickstart
@@ -39,7 +59,7 @@ cd my-agent
39
59
  node claude-task-manager/server.js
40
60
  ```
41
61
 
42
- Open **http://localhost:3456** — the browser setup page walks you through adding your API key and connecting integrations. Your name and timezone are auto-detected.
62
+ Open **http://localhost:3456** — the setup page walks you through adding your API key and connecting integrations. Your name and timezone are auto-detected.
43
63
 
44
64
  Or clone manually:
45
65
 
@@ -52,6 +72,66 @@ node claude-task-manager/server.js
52
72
 
53
73
  The first run auto-creates `.env`, `wall-e-config.json`, and `~/.walle/data/`. Finish setup at http://localhost:3456/setup.html.
54
74
 
75
+ ## Dashboard Features
76
+
77
+ ### Sessions
78
+ Terminal multiplexer for Claude Code — create, monitor, and manage multiple sessions from a single browser tab. Features include:
79
+ - Live terminal output via WebSocket (xterm.js)
80
+ - Session search and AI-powered search across all session history
81
+ - AI auto-titling for sessions
82
+ - Project grouping and filtering
83
+ - Copy session command (with working directory)
84
+ - Session replay and review
85
+
86
+ ### 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 Claude Code session with one click.
88
+ - **Composite prompts** — parent prompt with sub-prompts that compose into a single message
89
+ - **Prompt queue** — batch multiple prompts, send sequentially with idle detection between items
90
+ - **Power tools** — chains (multi-step sequences), templates, pattern detection, harvest (extract prompts from session history), and AI copilot suggestions
91
+ - **Usage tracking** — see which sessions used which prompts and how often
92
+
93
+ ### Wall-E Chat
94
+ Chat directly with Wall-E from the dashboard. Wall-E has access to your full brain (memories, knowledge, people) and can:
95
+ - Search your Slack messages, emails, and calendar
96
+ - Run skills on demand (morning briefing, Slack sync, etc.)
97
+ - Call MCP tools (Slack, GitHub, etc.)
98
+ - Create and manage background tasks
99
+ - Execute shell commands, read files, take screenshots
100
+ - Answer questions grounded in your actual data
101
+
102
+ Sub-tabs: Chat, Tasks (background task manager), Skills (view and run), Brain (knowledge graph), Actions, Timeline, Questions, Status.
103
+
104
+ ### Shadow Approver
105
+ Learns your permission patterns from Claude Code sessions and auto-approves safe operations. Features:
106
+ - Pattern learning from your approval history
107
+ - AI-driven approval decisions with confidence scoring
108
+ - Domain-specific trust tiers (Observe, Draft, Guarded, Autonomous)
109
+ - Rule consolidation (merges similar Bash rules)
110
+ - Decision history and audit trail
111
+
112
+ ### Code Review
113
+ AI-assisted code review across projects:
114
+ - Inline diff viewer
115
+ - Multi-project support
116
+ - AI review comments with confidence levels
117
+ - Send review to a Claude Code session for implementation
118
+
119
+ ### Session Insights
120
+ AI analysis of your Claude Code usage patterns:
121
+ - Workflow recommendations (automate repetitive tasks)
122
+ - Prompt effectiveness analysis
123
+ - Skill gap detection
124
+ - Cost-saving suggestions
125
+ - Session statistics
126
+
127
+ ### Permission Manager
128
+ Fine-grained control over what Claude Code can do automatically:
129
+ - Search and filter across all rules
130
+ - Risk-based categorization (LOW, MEDIUM, HIGH)
131
+ - Per-project or global scope
132
+ - Rule consolidation for similar patterns
133
+ - Import/export with Claude Code's settings files
134
+
55
135
  ## Configuration
56
136
 
57
137
  All configuration lives in `.env` (auto-generated on first run). Edit directly or use the browser setup page.
@@ -84,6 +164,7 @@ If you use `devbox ai -c claude`, Wall-E auto-reads your gateway credentials fro
84
164
  | `ANTHROPIC_AUTH_TOKEN` | No | Auth token when using a gateway |
85
165
  | `ANTHROPIC_CUSTOM_HEADERS_B64` | No | Base64-encoded custom headers (Portkey virtual keys, metadata) |
86
166
  | `WALLE_OWNER_NAME` | Auto | Your name (auto-detected from `git config`) |
167
+ | `WALLE_MODEL` | Auto | Model selection (probed on setup: claude-sonnet-4-6, haiku-4-5, etc.) |
87
168
  | `CTM_PORT` | No | Dashboard port (default: `3456`) |
88
169
  | `WALL_E_PORT` | No | Wall-E API port (default: `CTM_PORT + 1`) |
89
170
  | `WALL_E_DATA_DIR` | No | Data directory (default: `~/.walle/data`) |
@@ -105,8 +186,9 @@ Wall-E ships with skills that run on a schedule to keep your brain up to date:
105
186
  | `slack-backfill` | manual | Full Slack history backfill (2022-present) |
106
187
  | `email-sync` | every 30m | Syncs sent emails from macOS Mail via JXA |
107
188
  | `email-digest` | daily 7am | Summarizes recent email activity |
108
- | `morning-briefing` | daily 7am | AI-generated daily briefing from all sources |
189
+ | `morning-briefing` | daily 7am | AI-generated daily briefing: calendar, Slack activity, tasks, questions |
109
190
  | `memory-search` | on-demand | Full-text search across all memories |
191
+ | `file-ingest` | manual | Read a folder of files into the brain with glob filtering |
110
192
 
111
193
  ### Creating Custom Skills
112
194
 
@@ -128,22 +210,15 @@ tags: [sync, data]
128
210
 
129
211
  Place skills in `wall-e/skills/_bundled/your-skill/SKILL.md` or load from a custom directory.
130
212
 
131
- ## Dashboard Features
132
-
133
- ### Sessions Tab
134
- Terminal multiplexer for Claude Code — create, monitor, and manage multiple sessions from a single browser tab.
213
+ ## Integrations
135
214
 
136
- ### Prompts Tab
137
- Rich-text prompt editor with versioning, tagging, folders, and one-click send to any active Claude session. Supports composite prompts (parent + sub-prompts).
138
-
139
- ### Tasks Tab
140
- Task dashboard with recurring task support, skill execution, checkpoint/resume, and live logs.
141
-
142
- ### Wall-E Tab
143
- Chat directly with Wall-E — ask about your schedule, search your memories, run skills, and get AI-powered answers grounded in your actual data.
144
-
145
- ### Code Review Tab
146
- Review code changes across projects with inline diffs and AI-assisted review.
215
+ | Integration | How it works | Setup |
216
+ |---|---|---|
217
+ | **Slack** | OAuth + MCP protocol for search, read, send | Click "Connect" in setup page |
218
+ | **Google Calendar** | macOS EventKit (reads all calendars: Google, iCloud, Outlook) | Automatic on macOS |
219
+ | **Email** | macOS Mail via JXA/AppleScript | Automatic on macOS |
220
+ | **GitHub** | MCP server (if configured in Claude Code) | Via MCP config |
221
+ | **Custom MCP servers** | Any MCP-compatible server | Add to MCP config |
147
222
 
148
223
  ## API
149
224
 
@@ -152,17 +227,19 @@ CTM runs on port 3456. Key endpoints:
152
227
  | Method | Path | Description |
153
228
  |---|---|---|
154
229
  | GET | `/api/services/status` | CTM and Wall-E process status |
230
+ | POST | `/api/restart/ctm` | Restart CTM server |
155
231
  | POST | `/api/restart/walle` | Restart Wall-E daemon |
156
232
  | POST | `/api/start/walle` | Start Wall-E daemon |
157
233
  | POST | `/api/stop/walle` | Stop Wall-E daemon |
158
- | GET | `/api/wall-e/status` | Wall-E brain stats and owner info |
234
+ | GET | `/api/wall-e/status` | Brain stats, loop health, owner info |
159
235
  | GET | `/api/wall-e/memories` | List memories (filterable by source, since, limit) |
160
236
  | GET | `/api/wall-e/knowledge` | List knowledge entries |
161
237
  | GET | `/api/wall-e/people` | List known people |
162
238
  | GET | `/api/wall-e/timeline` | Memory timeline |
163
- | POST | `/api/wall-e/chat` | Chat with Wall-E |
239
+ | GET | `/api/wall-e/tasks` | List background tasks |
240
+ | POST | `/api/wall-e/chat` | Chat with Wall-E (supports SSE streaming) |
164
241
  | GET | `/api/prompts` | List prompts |
165
- | GET | `/api/sessions` | List active terminal sessions |
242
+ | GET | `/api/recent-sessions` | List recent Claude Code sessions |
166
243
 
167
244
  ## Tech Stack
168
245
 
@@ -170,24 +247,27 @@ CTM runs on port 3456. Key endpoints:
170
247
  - **Database**: SQLite via better-sqlite3 (WAL mode, FTS5 full-text search)
171
248
  - **AI**: Claude API via Anthropic SDK (supports Portkey gateway)
172
249
  - **Frontend**: Vanilla HTML/CSS/JS (no build step, no React)
250
+ - **Terminal**: xterm.js (frontend) + node-pty (backend)
173
251
  - **macOS integration**: EventKit (calendar), JXA (email/AppleScript), Spotlight (file search)
174
- - **Terminal**: node-pty for session management
175
252
 
176
253
  ## Development
177
254
 
178
255
  ```bash
256
+ # Start dev instance (doesn't affect primary on :3456)
257
+ bash bin/dev.sh
258
+
179
259
  # Run Wall-E tests
180
260
  cd wall-e && npm test
181
261
 
182
- # Run a single test file
183
- node --test tests/brain.test.js
184
-
185
262
  # Run Slack backfill manually
186
263
  node scripts/slack-backfill.js 2024-01 # single month
187
264
  node scripts/slack-backfill.js incremental # new messages only
188
265
 
189
266
  # Run calendar sync manually
190
267
  node skills/_bundled/google-calendar/run.js
268
+
269
+ # Run morning briefing manually
270
+ node skills/_bundled/morning-briefing/run.js
191
271
  ```
192
272
 
193
273
  ## License
@@ -1,12 +1,13 @@
1
1
  #!/bin/bash
2
2
  # Graceful CTM restart — spawns a watcher process, then exits cleanly.
3
3
  # Use this instead of killing the process directly.
4
- curl -s -X POST "http://localhost:3456/api/restart/ctm" | cat
4
+ CTM_PORT="${CTM_PORT:-3456}"
5
+ curl -s -X POST "http://localhost:${CTM_PORT}/api/restart/ctm?force=true" | cat
5
6
  echo ""
6
7
  echo "CTM server restarting... waiting for it to come back."
7
8
  sleep 2
8
9
  for i in $(seq 1 15); do
9
- if curl -sf "http://localhost:3456/api/services/status" > /dev/null 2>&1; then
10
+ if curl -sf "http://localhost:${CTM_PORT}/api/services/status" > /dev/null 2>&1; then
10
11
  echo "CTM server is back up."
11
12
  exit 0
12
13
  fi
@@ -594,6 +594,21 @@ function runMigrations() {
594
594
  if (!scCols2.find(c => c.name === 'hostname')) {
595
595
  getDb().prepare("ALTER TABLE session_conversations ADD COLUMN hostname TEXT DEFAULT ''").run();
596
596
  }
597
+
598
+ // startup_tasks: tracks active sessions for crash-safe restore on restart
599
+ const hasStartupTasks = getDb().prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='startup_tasks'").get();
600
+ if (!hasStartupTasks) {
601
+ getDb().exec(`
602
+ CREATE TABLE startup_tasks (
603
+ session_id TEXT PRIMARY KEY,
604
+ label TEXT NOT NULL DEFAULT '',
605
+ cmd TEXT NOT NULL DEFAULT '',
606
+ args TEXT NOT NULL DEFAULT '[]',
607
+ cwd TEXT NOT NULL DEFAULT '',
608
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
609
+ )
610
+ `);
611
+ }
597
612
  }
598
613
 
599
614
  // --- Settings CRUD ---
@@ -1115,9 +1130,9 @@ function listSessionConversations({ search, limit, offset, hostname, allDevices
1115
1130
  params.push(hostname);
1116
1131
  }
1117
1132
  if (search) {
1118
- sql += ' AND (title LIKE ? OR first_message LIKE ? OR project_path LIKE ?)';
1133
+ sql += ' AND (title LIKE ? OR first_message LIKE ? OR project_path LIKE ? OR messages LIKE ?)';
1119
1134
  const q = `%${search}%`;
1120
- params.push(q, q, q);
1135
+ params.push(q, q, q, q);
1121
1136
  }
1122
1137
  sql += ' ORDER BY imported_at DESC';
1123
1138
  if (limit) { sql += ' LIMIT ?'; params.push(limit); }
@@ -1699,6 +1714,28 @@ function getInsightsData(includeInternal) {
1699
1714
  };
1700
1715
  }
1701
1716
 
1717
+ // --- Startup Tasks (crash-safe session restore) ---
1718
+ function addStartupTask(sessionId, label, cmd, args, cwd) {
1719
+ getDb().prepare(
1720
+ 'INSERT OR REPLACE INTO startup_tasks (session_id, label, cmd, args, cwd) VALUES (?, ?, ?, ?, ?)'
1721
+ ).run(sessionId, label || '', cmd || '', JSON.stringify(args || []), cwd || '');
1722
+ }
1723
+
1724
+ function removeStartupTask(sessionId) {
1725
+ getDb().prepare('DELETE FROM startup_tasks WHERE session_id = ?').run(sessionId);
1726
+ }
1727
+
1728
+ function listStartupTasks() {
1729
+ return getDb().prepare('SELECT * FROM startup_tasks ORDER BY created_at').all().map(row => ({
1730
+ ...row,
1731
+ args: JSON.parse(row.args || '[]'),
1732
+ }));
1733
+ }
1734
+
1735
+ function clearStartupTasks() {
1736
+ getDb().prepare('DELETE FROM startup_tasks').run();
1737
+ }
1738
+
1702
1739
  module.exports = {
1703
1740
  initDb, getDb, closeDb, getDbPath: () => currentDbPath,
1704
1741
  getSetting, getSettingsByPrefix, setSetting,
@@ -1729,5 +1766,6 @@ module.exports = {
1729
1766
  replaceInsightRecommendations, listInsightRecommendations,
1730
1767
  startAnalysisRun, completeAnalysisRun, getLastAnalysisRun,
1731
1768
  getInsightsData,
1769
+ addStartupTask, removeStartupTask, listStartupTasks, clearStartupTasks,
1732
1770
  DEFAULT_IMAGES_DIR, BACKUP_DIR,
1733
1771
  };
@@ -7,6 +7,7 @@
7
7
  border-bottom: 1px solid var(--border); flex-shrink: 0;
8
8
  }
9
9
  .walle-header-title { font-size: 15px; font-weight: 700; color: var(--fg); }
10
+ .walle-avatar { vertical-align: middle; margin-right: 2px; position: relative; top: -1px; }
10
11
 
11
12
  .walle-subnav { display: flex; gap: 4px; margin-left: auto; }
12
13
  .walle-subnav-btn {
@@ -541,6 +542,25 @@
541
542
  .we-task-group[open] > .we-task-group-header::before { transform: rotate(90deg); }
542
543
  .we-task-group-header:hover { background: rgba(255,255,255,0.03); }
543
544
 
545
+ /* View tabs */
546
+ .we-view-tabs {
547
+ display: flex; align-items: center; gap: 2px;
548
+ padding: 4px 10px 0; border-bottom: 1px solid var(--border, #2a2a3e);
549
+ }
550
+ .we-view-tab {
551
+ padding: 6px 14px; border: none; background: transparent;
552
+ color: var(--fg-muted, #888); font-size: 12px; font-weight: 500;
553
+ cursor: pointer; border-bottom: 2px solid transparent;
554
+ border-radius: 4px 4px 0 0; transition: all 0.15s;
555
+ }
556
+ .we-view-tab:hover { color: var(--fg, #e0e0e0); background: rgba(255,255,255,0.04); }
557
+ .we-view-tab.active { color: var(--accent, #60a5fa); border-bottom-color: var(--accent, #60a5fa); font-weight: 600; }
558
+ .we-view-tab-badge {
559
+ display: inline-block; min-width: 16px; height: 16px; line-height: 16px;
560
+ text-align: center; font-size: 10px; font-weight: 700; border-radius: 8px;
561
+ background: #e03131; color: #fff; margin-left: 4px; padding: 0 4px;
562
+ }
563
+
544
564
  /* Task card */
545
565
  .we-task-card {
546
566
  background: var(--bg-lighter, #1e1e2e);
@@ -549,7 +569,10 @@
549
569
  border-radius: 6px;
550
570
  padding: 10px 14px;
551
571
  margin: 6px 10px;
572
+ transition: padding 0.15s;
552
573
  }
574
+ .we-task-card.compact { padding: 6px 14px; }
575
+ .we-task-card.compact .we-task-card-header { margin-bottom: 0; }
553
576
  .we-task-card-header {
554
577
  display: flex; justify-content: space-between; align-items: center;
555
578
  margin-bottom: 4px;
@@ -575,6 +598,106 @@
575
598
  .we-task-meta-extra { display: none; }
576
599
  .we-task-meta.we-meta-expanded .we-task-meta-extra { display: contents; }
577
600
 
601
+ /* Compact metadata line */
602
+ .we-task-meta-compact {
603
+ display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
604
+ font-size: 11px; color: #777; margin-top: 2px;
605
+ }
606
+ .we-task-meta-compact span { white-space: nowrap; }
607
+
608
+ /* Source icons */
609
+ .we-src-icon {
610
+ display: inline-block; padding: 1px 5px; border-radius: 3px;
611
+ font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px;
612
+ }
613
+ .we-src-icon.slack { background: #1a2e1a; color: #4ade80; }
614
+ .we-src-icon.chat { background: #1a1a3e; color: #60a5fa; }
615
+ .we-src-icon.init { background: #2e1a2e; color: #c084fc; }
616
+ .we-src-link {
617
+ color: #60a5fa; text-decoration: none; font-size: 11px;
618
+ }
619
+ .we-src-link:hover { text-decoration: underline; }
620
+
621
+ /* Slack thread info panel */
622
+ .we-slack-info { margin: 8px 0 4px; }
623
+ .we-slack-thread-status {
624
+ display: flex; align-items: center; gap: 8px;
625
+ padding: 6px 10px; margin-top: 6px;
626
+ background: rgba(255,255,255,0.03); border-radius: 6px;
627
+ font-size: 12px;
628
+ }
629
+ .we-thread-badge {
630
+ font-weight: 600; font-size: 11px;
631
+ padding: 2px 8px; border-radius: 10px;
632
+ }
633
+ .we-thread-badge.active { background: #1a2e1a; color: #4ade80; }
634
+ .we-thread-badge.expired { background: #2a2a2a; color: #888; }
635
+ .we-thread-expires { color: #888; font-size: 11px; }
636
+
637
+ /* Compact inline action buttons */
638
+ .we-compact-actions { display: inline-flex; gap: 4px; margin-left: auto; }
639
+ .we-compact-btn {
640
+ width: 22px; height: 22px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.1);
641
+ background: transparent; color: #888; font-size: 11px; cursor: pointer;
642
+ display: inline-flex; align-items: center; justify-content: center;
643
+ transition: all 0.15s;
644
+ }
645
+ .we-compact-btn:hover { background: rgba(255,255,255,0.08); color: #ccc; }
646
+ .we-compact-btn.run:hover { color: #4ade80; border-color: #4ade80; }
647
+ .we-compact-btn.stop:hover { color: #e03131; border-color: #e03131; }
648
+
649
+ /* Task context menu */
650
+ .we-task-menu {
651
+ background: #1e1e2e; border: 1px solid rgba(255,255,255,0.15); border-radius: 6px;
652
+ min-width: 140px; padding: 4px 0; z-index: 1000;
653
+ box-shadow: 0 4px 16px rgba(0,0,0,0.5);
654
+ }
655
+ .we-task-menu-item {
656
+ padding: 6px 12px; font-size: 12px; color: #ccc; cursor: pointer;
657
+ white-space: nowrap;
658
+ }
659
+ .we-task-menu-item:hover { background: rgba(255,255,255,0.08); color: #fff; }
660
+ .we-task-menu-item.danger { color: #e03131; }
661
+ .we-task-menu-item.danger:hover { background: rgba(224,49,49,0.15); }
662
+
663
+ /* Automation table view */
664
+ .we-auto-health {
665
+ display: flex; gap: 12px; padding: 8px 10px; margin-bottom: 4px;
666
+ font-size: 12px; font-weight: 500;
667
+ }
668
+ .we-auto-health-item.ok { color: #5c940d; }
669
+ .we-auto-health-item.paused { color: #888; }
670
+ .we-auto-health-item.failed { color: #e03131; }
671
+
672
+ .we-auto-table {
673
+ width: 100%; border-collapse: collapse; font-size: 12px;
674
+ }
675
+ .we-auto-table th {
676
+ text-align: left; padding: 6px 10px; color: #666; font-weight: 500;
677
+ font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
678
+ border-bottom: 1px solid var(--border, #2a2a3e);
679
+ }
680
+ .we-auto-row {
681
+ cursor: pointer; transition: background 0.1s;
682
+ }
683
+ .we-auto-row:hover { background: rgba(255,255,255,0.03); }
684
+ .we-auto-row.expanded { background: rgba(59,130,246,0.05); }
685
+ .we-auto-row td { padding: 8px 10px; border-bottom: 1px solid rgba(255,255,255,0.03); }
686
+ .we-auto-title { color: var(--fg, #e0e0e0); font-weight: 500; }
687
+ .we-auto-sched { color: #888; }
688
+ .we-auto-last { color: #777; }
689
+ .we-auto-actions { text-align: right; }
690
+ .we-auto-btn {
691
+ padding: 2px 8px; font-size: 10px; border-radius: 3px; cursor: pointer;
692
+ border: 1px solid rgba(255,255,255,0.1); background: transparent; color: #888;
693
+ }
694
+ .we-auto-btn:hover { background: rgba(255,255,255,0.08); color: #ccc; }
695
+ .we-auto-detail td {
696
+ padding: 0 10px 12px 10px;
697
+ background: rgba(59,130,246,0.03);
698
+ border-bottom: 1px solid var(--border, #2a2a3e);
699
+ }
700
+
578
701
  /* Chat date separator */
579
702
  .we-chat-date-sep { text-align: center; color: var(--fg-dim, #666); font-size: 11px; padding: 12px 0 4px; position: relative; }
580
703
  .we-chat-date-sep::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid rgba(255,255,255,0.06); }