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.
- package/README.md +13 -11
- package/package.json +2 -2
- package/template/claude-task-manager/approval-agent.js +3 -2
- package/template/claude-task-manager/db.js +44 -10
- package/template/claude-task-manager/public/css/walle-session.css +538 -0
- package/template/claude-task-manager/public/css/walle.css +5 -1
- package/template/claude-task-manager/public/index.html +1334 -172
- package/template/claude-task-manager/public/js/prompts.js +4 -1
- package/template/claude-task-manager/public/js/walle-session.js +691 -0
- package/template/claude-task-manager/public/js/walle.js +115 -54
- package/template/claude-task-manager/public/setup.html +9 -0
- package/template/claude-task-manager/queue-engine.js +6 -0
- package/template/claude-task-manager/server.js +1082 -45
- package/template/package.json +1 -1
- package/template/wall-e/agent.js +28 -0
- package/template/wall-e/api-walle.js +196 -2
- package/template/wall-e/brain.js +256 -3
- package/template/wall-e/chat.js +202 -63
- package/template/wall-e/coding-orchestrator.js +284 -12
- package/template/wall-e/context/compactor.js +5 -8
- package/template/wall-e/context/context-builder.js +52 -2
- package/template/wall-e/context/state-snapshot.js +1 -1
- package/template/wall-e/context/topic-matcher.js +5 -1
- package/template/wall-e/evaluation/complexity.js +141 -0
- package/template/wall-e/evaluation/index.js +9 -0
- package/template/wall-e/evaluation/learner.js +208 -0
- package/template/wall-e/evaluation/quorum.js +256 -0
- package/template/wall-e/evaluation/router.js +332 -0
- package/template/wall-e/evaluation/scorecard.js +173 -0
- package/template/wall-e/extraction/contradiction.js +7 -10
- package/template/wall-e/extraction/knowledge-extractor.js +11 -79
- package/template/wall-e/fly.toml +2 -1
- package/template/wall-e/llm/anthropic.js +213 -0
- package/template/wall-e/llm/client.js +62 -0
- package/template/wall-e/llm/google.js +163 -0
- package/template/wall-e/llm/health.js +256 -0
- package/template/wall-e/llm/index.js +10 -0
- package/template/wall-e/llm/ollama.js +97 -0
- package/template/wall-e/llm/openai.js +138 -0
- package/template/wall-e/llm/tool-adapter.js +206 -0
- package/template/wall-e/loops/initiative.js +13 -49
- package/template/wall-e/package.json +1 -0
- package/template/wall-e/scripts/slack-backfill.js +1 -1
- package/template/wall-e/scripts/slack-channel-history.js +15 -4
- package/template/wall-e/skills/_bundled/model-pricing-sync/SKILL.md +44 -0
- package/template/wall-e/skills/_bundled/model-pricing-sync/run.js +251 -0
- package/template/wall-e/skills/_bundled/model-trainer/SKILL.md +34 -0
- package/template/wall-e/skills/_bundled/model-trainer/index.js +112 -0
- package/template/wall-e/skills/_bundled/model-trainer/skill.json +7 -0
- package/template/wall-e/skills/_bundled/slack-mentions/run.js +140 -16
- package/template/wall-e/skills/claude-code-reader.js +383 -78
- package/template/wall-e/skills/skill-executor.js +20 -52
- package/template/wall-e/skills/skill-planner.js +28 -3
- package/template/wall-e/skills/slack-pull-live.js +2 -2
- package/template/wall-e/telemetry.js +130 -0
- package/template/wall-e/test/evaluation/complexity.test.js +101 -0
- package/template/wall-e/test/evaluation/learner.test.js +271 -0
- package/template/wall-e/test/evaluation/quorum.test.js +372 -0
- package/template/wall-e/test/evaluation/router.test.js +269 -0
- package/template/wall-e/test/evaluation/scorecard.test.js +152 -0
- package/template/wall-e/test/llm/anthropic.test.js +172 -0
- package/template/wall-e/test/llm/brain-models.test.js +182 -0
- package/template/wall-e/test/llm/client.test.js +132 -0
- package/template/wall-e/test/llm/google.test.js +37 -0
- package/template/wall-e/test/llm/health.test.js +426 -0
- package/template/wall-e/test/llm/integration.test.js +285 -0
- package/template/wall-e/test/llm/ollama.test.js +50 -0
- package/template/wall-e/test/llm/openai.test.js +48 -0
- package/template/wall-e/test/llm/tool-adapter.test.js +297 -0
- package/template/wall-e/test/training/evaluate.test.js +221 -0
- package/template/wall-e/test/training/exporter.test.js +213 -0
- package/template/wall-e/test/training/trainer.test.js +241 -0
- package/template/wall-e/tests/agent-api.test.js +6 -6
- package/template/wall-e/tests/brain.test.js +2 -1
- package/template/wall-e/tests/chat.test.js +20 -20
- package/template/wall-e/tests/compactor.test.js +13 -15
- package/template/wall-e/tests/initiative.test.js +32 -32
- package/template/wall-e/tests/session-persistence.test.js +38 -42
- package/template/wall-e/tools/local-tools.js +168 -6
- package/template/wall-e/tools/permission-checker.js +110 -0
- package/template/wall-e/tools/slack-mcp.js +124 -6
- package/template/wall-e/training/evaluate.js +202 -0
- package/template/wall-e/training/exporter.js +127 -0
- package/template/wall-e/training/train.py +269 -0
- package/template/wall-e/training/trainer.js +202 -0
- package/template/website/Dockerfile +4 -0
- package/template/website/fly.toml +15 -0
- package/template/website/index.html +436 -0
- 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
|
|
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 (
|
|
7
|
+
### CTM (Coding Task Manager)
|
|
8
8
|
|
|
9
|
-
A web dashboard for running and managing
|
|
9
|
+
A web dashboard for running and managing AI coding sessions across multiple providers.
|
|
10
10
|
|
|
11
|
-
- **Terminal Multiplexer** — Run
|
|
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
|
|
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
|
-
- **
|
|
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
|
|
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
|
-
- **
|
|
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
|
|
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
|
|
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
|
-
"description": "CTM + Wall-E —
|
|
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
|
-
|
|
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(
|
|
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,
|