create-walle 0.9.4 → 0.9.5

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 (89) hide show
  1. package/README.md +13 -11
  2. package/package.json +2 -2
  3. package/template/claude-task-manager/approval-agent.js +3 -2
  4. package/template/claude-task-manager/db.js +44 -10
  5. package/template/claude-task-manager/public/css/walle-session.css +538 -0
  6. package/template/claude-task-manager/public/css/walle.css +5 -1
  7. package/template/claude-task-manager/public/index.html +1334 -172
  8. package/template/claude-task-manager/public/js/prompts.js +4 -1
  9. package/template/claude-task-manager/public/js/walle-session.js +691 -0
  10. package/template/claude-task-manager/public/js/walle.js +115 -54
  11. package/template/claude-task-manager/public/setup.html +9 -0
  12. package/template/claude-task-manager/queue-engine.js +6 -0
  13. package/template/claude-task-manager/server.js +1082 -45
  14. package/template/package.json +1 -1
  15. package/template/wall-e/agent.js +28 -0
  16. package/template/wall-e/api-walle.js +196 -2
  17. package/template/wall-e/brain.js +256 -3
  18. package/template/wall-e/chat.js +202 -63
  19. package/template/wall-e/coding-orchestrator.js +284 -12
  20. package/template/wall-e/context/compactor.js +5 -8
  21. package/template/wall-e/context/context-builder.js +52 -2
  22. package/template/wall-e/context/state-snapshot.js +1 -1
  23. package/template/wall-e/context/topic-matcher.js +5 -1
  24. package/template/wall-e/evaluation/complexity.js +141 -0
  25. package/template/wall-e/evaluation/index.js +9 -0
  26. package/template/wall-e/evaluation/learner.js +208 -0
  27. package/template/wall-e/evaluation/quorum.js +256 -0
  28. package/template/wall-e/evaluation/router.js +332 -0
  29. package/template/wall-e/evaluation/scorecard.js +173 -0
  30. package/template/wall-e/extraction/contradiction.js +7 -10
  31. package/template/wall-e/extraction/knowledge-extractor.js +11 -79
  32. package/template/wall-e/fly.toml +2 -1
  33. package/template/wall-e/llm/anthropic.js +213 -0
  34. package/template/wall-e/llm/client.js +62 -0
  35. package/template/wall-e/llm/google.js +163 -0
  36. package/template/wall-e/llm/health.js +256 -0
  37. package/template/wall-e/llm/index.js +10 -0
  38. package/template/wall-e/llm/ollama.js +97 -0
  39. package/template/wall-e/llm/openai.js +138 -0
  40. package/template/wall-e/llm/tool-adapter.js +206 -0
  41. package/template/wall-e/loops/initiative.js +13 -49
  42. package/template/wall-e/package.json +1 -0
  43. package/template/wall-e/scripts/slack-backfill.js +1 -1
  44. package/template/wall-e/scripts/slack-channel-history.js +15 -4
  45. package/template/wall-e/skills/_bundled/model-pricing-sync/SKILL.md +44 -0
  46. package/template/wall-e/skills/_bundled/model-pricing-sync/run.js +251 -0
  47. package/template/wall-e/skills/_bundled/model-trainer/SKILL.md +34 -0
  48. package/template/wall-e/skills/_bundled/model-trainer/index.js +112 -0
  49. package/template/wall-e/skills/_bundled/model-trainer/skill.json +7 -0
  50. package/template/wall-e/skills/_bundled/slack-mentions/run.js +140 -16
  51. package/template/wall-e/skills/claude-code-reader.js +383 -78
  52. package/template/wall-e/skills/skill-executor.js +20 -52
  53. package/template/wall-e/skills/skill-planner.js +28 -3
  54. package/template/wall-e/skills/slack-pull-live.js +2 -2
  55. package/template/wall-e/telemetry.js +130 -0
  56. package/template/wall-e/test/evaluation/complexity.test.js +101 -0
  57. package/template/wall-e/test/evaluation/learner.test.js +271 -0
  58. package/template/wall-e/test/evaluation/quorum.test.js +372 -0
  59. package/template/wall-e/test/evaluation/router.test.js +269 -0
  60. package/template/wall-e/test/evaluation/scorecard.test.js +152 -0
  61. package/template/wall-e/test/llm/anthropic.test.js +172 -0
  62. package/template/wall-e/test/llm/brain-models.test.js +182 -0
  63. package/template/wall-e/test/llm/client.test.js +132 -0
  64. package/template/wall-e/test/llm/google.test.js +37 -0
  65. package/template/wall-e/test/llm/health.test.js +426 -0
  66. package/template/wall-e/test/llm/integration.test.js +285 -0
  67. package/template/wall-e/test/llm/ollama.test.js +50 -0
  68. package/template/wall-e/test/llm/openai.test.js +48 -0
  69. package/template/wall-e/test/llm/tool-adapter.test.js +297 -0
  70. package/template/wall-e/test/training/evaluate.test.js +221 -0
  71. package/template/wall-e/test/training/exporter.test.js +213 -0
  72. package/template/wall-e/test/training/trainer.test.js +241 -0
  73. package/template/wall-e/tests/agent-api.test.js +6 -6
  74. package/template/wall-e/tests/brain.test.js +2 -1
  75. package/template/wall-e/tests/chat.test.js +20 -20
  76. package/template/wall-e/tests/compactor.test.js +13 -15
  77. package/template/wall-e/tests/initiative.test.js +32 -32
  78. package/template/wall-e/tests/session-persistence.test.js +38 -42
  79. package/template/wall-e/tools/local-tools.js +168 -6
  80. package/template/wall-e/tools/permission-checker.js +110 -0
  81. package/template/wall-e/tools/slack-mcp.js +124 -6
  82. package/template/wall-e/training/evaluate.js +202 -0
  83. package/template/wall-e/training/exporter.js +127 -0
  84. package/template/wall-e/training/train.py +269 -0
  85. package/template/wall-e/training/trainer.js +202 -0
  86. package/template/website/Dockerfile +4 -0
  87. package/template/website/fly.toml +15 -0
  88. package/template/website/index.html +436 -0
  89. package/template/website/nginx.conf +21 -0
package/README.md CHANGED
@@ -1,28 +1,30 @@
1
1
  # create-walle
2
2
 
3
- Set up **CTM + Wall-E** in one command — a browser-based Claude Code dashboard paired with a personal AI agent that builds a searchable second brain from your work life.
3
+ Set up **CTM + Wall-E** in one command — a browser-based dashboard for AI coding agents paired with a personal AI agent that builds a searchable second brain from your work life.
4
4
 
5
5
  ## What You Get
6
6
 
7
- ### CTM (Claude Task Manager)
7
+ ### CTM (Coding Task Manager)
8
8
 
9
- A web dashboard for running and managing Claude Code sessions, prompts, and workflows.
9
+ A web dashboard for running and managing AI coding sessions across multiple providers.
10
10
 
11
- - **Terminal Multiplexer** — Run multiple Claude Code sessions side by side with live status, persistent scrollback, and AI-generated titles
11
+ - **Terminal Multiplexer** — Run Claude Code, Codex, Gemini CLI, and Aider sessions side by side with live status, persistent scrollback, model switching, and AI-generated titles
12
12
  - **Prompt Editor** — Save, version, and organize prompts with folders, tags, chains, templates, and AI search
13
- - **Task Queue** — Queue prompts for sequential execution with auto-advance when Claude finishes, or step through manually
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
  - **Code Review** — View git diffs from any project, staged or unstaged, with line-level detail
16
- - **Session Insights** — Analyze patterns across sessions using Claude
16
+ - **Model Registry** — Manage providers (Anthropic, OpenAI, Google, Ollama), compare pricing, switch models per session
17
+ - **Session Insights** — Analyze patterns across sessions to optimize prompts and workflows
17
18
 
18
19
  ### Wall-E (Personal Digital Twin)
19
20
 
20
- An always-on AI agent that learns from your Slack, email, calendar, and Claude Code sessions.
21
+ An always-on AI agent that learns from your Slack, email, calendar, and coding sessions.
21
22
 
22
23
  - **Second Brain** — Automatically ingests your digital life into a searchable memory store with full-text search, knowledge extraction, and pattern detection
23
24
  - **Proactive Intelligence** — Surfaces time-sensitive items, suggests actions, and delivers morning briefings and weekly reflections without being asked
24
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.)
25
- - **14 Bundled Skills** — Morning briefing, weekly reflection, proactive alerts, Slack mentions, email sync, calendar integration, coding agent, and more
26
+ - **16 Bundled Skills** — Morning briefing, weekly reflection, proactive alerts, Slack monitoring, email sync, calendar integration, coding agent, model training, and more
27
+ - **Multi-Model** — Works with Claude, GPT, Gemini, and local models via Ollama with smart routing
26
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
27
29
  - **Multi-Device** — Share your brain across machines via Dropbox or iCloud
28
30
 
@@ -65,12 +67,12 @@ Wall-E runs on `CTM_PORT + 1` (e.g., 5001).
65
67
 
66
68
  ## Architecture
67
69
 
68
- Everything runs locally. CTM serves the dashboard, Wall-E runs as a background agent. Both use SQLite — no external databases, no cloud dependency beyond the Claude API.
70
+ Everything runs locally. CTM serves the dashboard, Wall-E runs as a background agent. Both use SQLite — no external databases, no cloud dependency beyond your LLM API keys.
69
71
 
70
72
  | Component | Default Port | What it does |
71
73
  |-----------|-------------|--------------|
72
- | CTM | 3456 | Dashboard, terminal multiplexer, prompt editor, queue, code review |
73
- | Wall-E | 3457 | AI agent, brain database, skills engine, chat API |
74
+ | CTM | 3456 | Dashboard, multi-agent terminal, prompt editor, queue, model registry, code review |
75
+ | Wall-E | 3457 | AI agent, brain database, skills engine, multi-model chat API |
74
76
 
75
77
  ## Links
76
78
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-walle",
3
- "version": "0.9.4",
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.",
3
+ "version": "0.9.5",
4
+ "description": "CTM + Wall-E — 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
  },
@@ -10,7 +10,8 @@ const dbModule = require('./db');
10
10
  // - "Do you want to proceed?" (Bash commands)
11
11
  // - "Do you want to make this edit to <file>?" (Edit tool)
12
12
  // - "Do you want to create <file>?" (Write tool)
13
- const PROCEED_PATTERN = /Do you want to (proceed|make this edit to .+|create .+)\??/;
13
+ // - "Do you want to overwrite <file>?" (Write tool, file exists)
14
+ const PROCEED_PATTERN = /Do you want to (proceed|make this edit to .+|create .+|overwrite .+)\??/;
14
15
  const YES_NO_PATTERN = /[>❯]\s*1\.\s*Yes/;
15
16
 
16
17
  // Parse the terminal buffer to extract the approval context
@@ -133,7 +134,7 @@ function reviewWithHeuristics(context) {
133
134
 
134
135
  // High-risk patterns — always escalate
135
136
  const highRisk = [
136
- /rm\s+-rf?\s+[\/~]/, /force.?push/, /--force/, /drop\s+table/i,
137
+ /rm\s+-rf?\s+(?!\/tmp\/)[\/~]/, /force.?push/, /--force/, /drop\s+table/i,
137
138
  /delete.*production/i, /sudo\s/, /chmod\s+777/, /curl.*\|\s*sh/,
138
139
  />\s*\/etc\//, />\s*\/usr\//, />\s*\/var\//, /mkfs/, /dd\s+if=/,
139
140
  ];
@@ -609,6 +609,32 @@ function runMigrations() {
609
609
  )
610
610
  `);
611
611
  }
612
+
613
+ // Add model_id to startup_tasks for crash-safe model restore
614
+ try {
615
+ const stCols = getDb().prepare("PRAGMA table_info(startup_tasks)").all();
616
+ if (!stCols.find(c => c.name === 'model_id')) {
617
+ getDb().exec("ALTER TABLE startup_tasks ADD COLUMN model_id TEXT DEFAULT NULL");
618
+ }
619
+ } catch {}
620
+
621
+ // Add type and chat_session_id to startup_tasks for Wall-E sessions
622
+ try {
623
+ const stCols2 = getDb().prepare("PRAGMA table_info(startup_tasks)").all();
624
+ if (!stCols2.find(c => c.name === 'type')) {
625
+ getDb().exec("ALTER TABLE startup_tasks ADD COLUMN type TEXT DEFAULT 'pty'");
626
+ }
627
+ if (!stCols2.find(c => c.name === 'chat_session_id')) {
628
+ getDb().exec("ALTER TABLE startup_tasks ADD COLUMN chat_session_id TEXT DEFAULT NULL");
629
+ }
630
+ } catch {}
631
+
632
+ // Add model tracking to session_conversations
633
+ const sessCols = getDb().prepare("PRAGMA table_info(session_conversations)").all();
634
+ if (!sessCols.find(c => c.name === 'model_provider')) {
635
+ getDb().exec("ALTER TABLE session_conversations ADD COLUMN model_provider TEXT");
636
+ getDb().exec("ALTER TABLE session_conversations ADD COLUMN model_id TEXT");
637
+ }
612
638
  }
613
639
 
614
640
  // --- Settings CRUD ---
@@ -1104,26 +1130,28 @@ function setAlwaysAsk(toolName, alwaysAsk) {
1104
1130
  }
1105
1131
 
1106
1132
  // --- Session Conversations ---
1107
- function importSessionConversation({ session_id, project_path, messages, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, hostname }) {
1133
+ function importSessionConversation({ session_id, project_path, messages, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, hostname, model_provider, model_id }) {
1108
1134
  getDb().prepare(
1109
- `INSERT INTO session_conversations (session_id, project_path, messages, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, hostname)
1110
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1135
+ `INSERT INTO session_conversations (session_id, project_path, messages, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, hostname, model_provider, model_id)
1136
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1111
1137
  ON CONFLICT(session_id) DO UPDATE SET
1112
1138
  messages=excluded.messages, user_msg_count=excluded.user_msg_count,
1113
1139
  assistant_msg_count=excluded.assistant_msg_count, title=excluded.title,
1114
1140
  first_message=excluded.first_message, git_branch=excluded.git_branch,
1115
1141
  file_size=excluded.file_size, hostname=COALESCE(NULLIF(excluded.hostname,''), session_conversations.hostname),
1142
+ model_provider=COALESCE(NULLIF(excluded.model_provider,''), session_conversations.model_provider),
1143
+ model_id=COALESCE(NULLIF(excluded.model_id,''), session_conversations.model_id),
1116
1144
  imported_at=datetime('now')`
1117
1145
  ).run(
1118
1146
  session_id, project_path || '', JSON.stringify(messages || []),
1119
1147
  user_msg_count || 0, assistant_msg_count || 0, title || '',
1120
1148
  first_message || '', git_branch || '', file_size || 0, session_created_at || '',
1121
- hostname || require('os').hostname()
1149
+ hostname || require('os').hostname(), model_provider || '', model_id || ''
1122
1150
  );
1123
1151
  }
1124
1152
 
1125
1153
  function listSessionConversations({ search, limit, offset, hostname, allDevices } = {}) {
1126
- let sql = 'SELECT id, session_id, project_path, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, imported_at, hostname FROM session_conversations WHERE 1=1';
1154
+ let sql = 'SELECT id, session_id, project_path, user_msg_count, assistant_msg_count, title, first_message, git_branch, file_size, session_created_at, imported_at, hostname, model_provider, model_id FROM session_conversations WHERE 1=1';
1127
1155
  const params = [];
1128
1156
  if (!allDevices && hostname) {
1129
1157
  sql += ' AND (hostname = ? OR hostname = \'\' OR hostname IS NULL)';
@@ -1144,6 +1172,12 @@ function getSessionConversation(sessionId) {
1144
1172
  return getDb().prepare('SELECT * FROM session_conversations WHERE session_id = ?').get(sessionId);
1145
1173
  }
1146
1174
 
1175
+ function updateSessionModel(sessionId, modelProvider, modelId) {
1176
+ getDb().prepare(
1177
+ 'UPDATE session_conversations SET model_provider = ?, model_id = ? WHERE session_id = ?'
1178
+ ).run(modelProvider, modelId, sessionId);
1179
+ }
1180
+
1147
1181
  // --- Templates ---
1148
1182
  function createTemplate({ name, description, content, content_html, variables, category }) {
1149
1183
  const result = getDb().prepare(
@@ -1447,7 +1481,7 @@ function deleteApprovalRule(id) {
1447
1481
  }
1448
1482
 
1449
1483
  function incrementApprovalRuleMatch(id) {
1450
- getDb().prepare('UPDATE approval_rules SET times_matched = times_matched + 1, updated_at = datetime("now") WHERE id = ?').run(id);
1484
+ getDb().prepare("UPDATE approval_rules SET times_matched = times_matched + 1, updated_at = datetime('now') WHERE id = ?").run(id);
1451
1485
  }
1452
1486
 
1453
1487
  // --- Approval Decisions (audit log) ---
@@ -1715,10 +1749,10 @@ function getInsightsData(includeInternal) {
1715
1749
  }
1716
1750
 
1717
1751
  // --- Startup Tasks (crash-safe session restore) ---
1718
- function addStartupTask(sessionId, label, cmd, args, cwd) {
1752
+ function addStartupTask(sessionId, label, cmd, args, cwd, model_id, type, chatSessionId) {
1719
1753
  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 || '');
1754
+ 'INSERT OR REPLACE INTO startup_tasks (session_id, label, cmd, args, cwd, model_id, type, chat_session_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
1755
+ ).run(sessionId, label || '', cmd || '', JSON.stringify(args || []), cwd || '', model_id || null, type || 'pty', chatSessionId || null);
1722
1756
  }
1723
1757
 
1724
1758
  function updateStartupTaskLabel(sessionId, label) {
@@ -1751,7 +1785,7 @@ module.exports = {
1751
1785
  listPermissionRules, upsertPermissionRule, deletePermissionRule,
1752
1786
  listPermissionLog, addPermissionLog,
1753
1787
  getAlwaysAskTools, setAlwaysAsk,
1754
- importSessionConversation, listSessionConversations, getSessionConversation,
1788
+ importSessionConversation, listSessionConversations, getSessionConversation, updateSessionModel,
1755
1789
  getSessionTitle, setSessionTitle, isSessionUserRenamed, getAllSessionTitles,
1756
1790
  createTemplate, listTemplates, getTemplate, deleteTemplate,
1757
1791
  trackPromptUsage, getPromptUsageStats,