create-walle 0.1.0
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/bin/create-walle.js +134 -0
- package/package.json +18 -0
- package/template/.env.example +40 -0
- package/template/CLAUDE.md +12 -0
- package/template/LICENSE +21 -0
- package/template/README.md +167 -0
- package/template/bin/setup.js +100 -0
- package/template/claude-code-skill.md +60 -0
- package/template/claude-task-manager/api-prompts.js +1841 -0
- package/template/claude-task-manager/api-reviews.js +275 -0
- package/template/claude-task-manager/approval-agent.js +454 -0
- package/template/claude-task-manager/bin/restart-ctm.sh +16 -0
- package/template/claude-task-manager/db.js +1721 -0
- package/template/claude-task-manager/docs/PROMPT-MANAGEMENT-DESIGN.md +631 -0
- package/template/claude-task-manager/git-utils.js +214 -0
- package/template/claude-task-manager/package-lock.json +1607 -0
- package/template/claude-task-manager/package.json +31 -0
- package/template/claude-task-manager/prompt-harvest.js +1148 -0
- package/template/claude-task-manager/public/css/prompts.css +880 -0
- package/template/claude-task-manager/public/css/reviews.css +430 -0
- package/template/claude-task-manager/public/css/walle.css +732 -0
- package/template/claude-task-manager/public/favicon.ico +0 -0
- package/template/claude-task-manager/public/icon.svg +37 -0
- package/template/claude-task-manager/public/index.html +8346 -0
- package/template/claude-task-manager/public/js/prompts.js +3159 -0
- package/template/claude-task-manager/public/js/reviews.js +1292 -0
- package/template/claude-task-manager/public/js/walle.js +3081 -0
- package/template/claude-task-manager/public/manifest.json +13 -0
- package/template/claude-task-manager/public/prompts.html +4353 -0
- package/template/claude-task-manager/public/setup.html +216 -0
- package/template/claude-task-manager/queue-engine.js +404 -0
- package/template/claude-task-manager/server-state.js +5 -0
- package/template/claude-task-manager/server.js +2254 -0
- package/template/claude-task-manager/session-utils.js +124 -0
- package/template/claude-task-manager/start.sh +17 -0
- package/template/claude-task-manager/tests/test-ai-search.js +61 -0
- package/template/claude-task-manager/tests/test-editor-ux.js +76 -0
- package/template/claude-task-manager/tests/test-editor-ux2.js +51 -0
- package/template/claude-task-manager/tests/test-features-v2.js +127 -0
- package/template/claude-task-manager/tests/test-insights-cached.js +78 -0
- package/template/claude-task-manager/tests/test-insights.js +124 -0
- package/template/claude-task-manager/tests/test-permissions-v2.js +127 -0
- package/template/claude-task-manager/tests/test-permissions.js +122 -0
- package/template/claude-task-manager/tests/test-pin.js +51 -0
- package/template/claude-task-manager/tests/test-prompts.js +164 -0
- package/template/claude-task-manager/tests/test-recent-sessions.js +96 -0
- package/template/claude-task-manager/tests/test-review.js +104 -0
- package/template/claude-task-manager/tests/test-send-dropdown.js +76 -0
- package/template/claude-task-manager/tests/test-send-final.js +30 -0
- package/template/claude-task-manager/tests/test-send-fixes.js +76 -0
- package/template/claude-task-manager/tests/test-send-integration.js +107 -0
- package/template/claude-task-manager/tests/test-send-visual.js +34 -0
- package/template/claude-task-manager/tests/test-session-create.js +147 -0
- package/template/claude-task-manager/tests/test-sidebar-ux.js +83 -0
- package/template/claude-task-manager/tests/test-url-hash.js +68 -0
- package/template/claude-task-manager/tests/test-ux-crop.js +34 -0
- package/template/claude-task-manager/tests/test-ux-review.js +130 -0
- package/template/claude-task-manager/tests/test-zoom-card.js +76 -0
- package/template/claude-task-manager/tests/test-zoom.js +92 -0
- package/template/claude-task-manager/tests/test-zoom2.js +67 -0
- package/template/docs/site/api/README.md +187 -0
- package/template/docs/site/guides/claude-code.md +58 -0
- package/template/docs/site/guides/configuration.md +96 -0
- package/template/docs/site/guides/quickstart.md +158 -0
- package/template/docs/site/index.md +14 -0
- package/template/docs/site/skills/README.md +135 -0
- package/template/wall-e/.dockerignore +11 -0
- package/template/wall-e/Dockerfile +25 -0
- package/template/wall-e/adapters/adapter-base.js +37 -0
- package/template/wall-e/adapters/ctm.js +193 -0
- package/template/wall-e/adapters/slack.js +56 -0
- package/template/wall-e/agent.js +319 -0
- package/template/wall-e/api-walle.js +1073 -0
- package/template/wall-e/brain.js +1235 -0
- package/template/wall-e/channels/agent-api.js +172 -0
- package/template/wall-e/channels/channel-base.js +14 -0
- package/template/wall-e/channels/imessage-channel.js +113 -0
- package/template/wall-e/channels/slack-channel.js +118 -0
- package/template/wall-e/chat.js +778 -0
- package/template/wall-e/decision/confidence.js +93 -0
- package/template/wall-e/deploy.sh +35 -0
- package/template/wall-e/docs/specs/2026-04-01-publish-plan.md +112 -0
- package/template/wall-e/docs/specs/SKILL-FORMAT.md +326 -0
- package/template/wall-e/extraction/contradiction.js +168 -0
- package/template/wall-e/extraction/knowledge-extractor.js +190 -0
- package/template/wall-e/fly.toml +24 -0
- package/template/wall-e/loops/ingest.js +34 -0
- package/template/wall-e/loops/reflect.js +63 -0
- package/template/wall-e/loops/tasks.js +487 -0
- package/template/wall-e/loops/think.js +125 -0
- package/template/wall-e/package-lock.json +533 -0
- package/template/wall-e/package.json +18 -0
- package/template/wall-e/scripts/ingest-slack-search.js +85 -0
- package/template/wall-e/scripts/pull-slack-via-claude.js +98 -0
- package/template/wall-e/scripts/slack-backfill.js +295 -0
- package/template/wall-e/scripts/slack-channel-history.js +454 -0
- package/template/wall-e/server.js +93 -0
- package/template/wall-e/skills/_bundled/email-digest/SKILL.md +95 -0
- package/template/wall-e/skills/_bundled/email-sync/SKILL.md +65 -0
- package/template/wall-e/skills/_bundled/email-sync/mail-reader.jxa +104 -0
- package/template/wall-e/skills/_bundled/email-sync/run.js +213 -0
- package/template/wall-e/skills/_bundled/google-calendar/SKILL.md +73 -0
- package/template/wall-e/skills/_bundled/google-calendar/cal-reader.swift +81 -0
- package/template/wall-e/skills/_bundled/google-calendar/run.js +181 -0
- package/template/wall-e/skills/_bundled/memory-search/SKILL.md +92 -0
- package/template/wall-e/skills/_bundled/morning-briefing/SKILL.md +131 -0
- package/template/wall-e/skills/_bundled/morning-briefing/run.js +264 -0
- package/template/wall-e/skills/_bundled/slack-backfill/SKILL.md +60 -0
- package/template/wall-e/skills/_bundled/slack-sync/SKILL.md +55 -0
- package/template/wall-e/skills/claude-code-reader.js +144 -0
- package/template/wall-e/skills/mcp-client.js +407 -0
- package/template/wall-e/skills/skill-executor.js +163 -0
- package/template/wall-e/skills/skill-loader.js +410 -0
- package/template/wall-e/skills/skill-planner.js +88 -0
- package/template/wall-e/skills/slack-ingest.js +329 -0
- package/template/wall-e/skills/slack-pull-live.js +270 -0
- package/template/wall-e/skills/tool-executor.js +188 -0
- package/template/wall-e/tests/adapter-base.test.js +20 -0
- package/template/wall-e/tests/adapter-ctm.test.js +122 -0
- package/template/wall-e/tests/adapter-slack.test.js +98 -0
- package/template/wall-e/tests/agent-api.test.js +256 -0
- package/template/wall-e/tests/api-walle.test.js +222 -0
- package/template/wall-e/tests/brain.test.js +602 -0
- package/template/wall-e/tests/channels.test.js +104 -0
- package/template/wall-e/tests/chat.test.js +103 -0
- package/template/wall-e/tests/confidence.test.js +134 -0
- package/template/wall-e/tests/contradiction.test.js +217 -0
- package/template/wall-e/tests/ingest.test.js +113 -0
- package/template/wall-e/tests/mcp-client.test.js +71 -0
- package/template/wall-e/tests/reflect.test.js +103 -0
- package/template/wall-e/tests/server.test.js +111 -0
- package/template/wall-e/tests/skills.test.js +198 -0
- package/template/wall-e/tests/slack-ingest.test.js +103 -0
- package/template/wall-e/tests/think.test.js +435 -0
- package/template/wall-e/tools/local-tools.js +697 -0
- package/template/wall-e/tools/slack-mcp.js +290 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require('child_process');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const BOLD = '\x1b[1m';
|
|
9
|
+
const DIM = '\x1b[2m';
|
|
10
|
+
const GREEN = '\x1b[32m';
|
|
11
|
+
const CYAN = '\x1b[36m';
|
|
12
|
+
const RESET = '\x1b[0m';
|
|
13
|
+
|
|
14
|
+
// Template directory bundled inside this npm package
|
|
15
|
+
const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
|
|
16
|
+
|
|
17
|
+
function detectName() {
|
|
18
|
+
try { return execFileSync('git', ['config', 'user.name'], { encoding: 'utf8' }).trim(); } catch {}
|
|
19
|
+
try { return execFileSync('id', ['-F'], { encoding: 'utf8' }).trim(); } catch {} // macOS full name
|
|
20
|
+
return process.env.USER || 'Owner';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function detectTimezone() {
|
|
24
|
+
try { return Intl.DateTimeFormat().resolvedOptions().timeZone; } catch {}
|
|
25
|
+
return 'UTC';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function copyRecursive(src, dest) {
|
|
29
|
+
const stat = fs.statSync(src);
|
|
30
|
+
if (stat.isDirectory()) {
|
|
31
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
32
|
+
for (const entry of fs.readdirSync(src)) {
|
|
33
|
+
if (entry === 'node_modules' || entry === '.git') continue;
|
|
34
|
+
copyRecursive(path.join(src, entry), path.join(dest, entry));
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
fs.copyFileSync(src, dest);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function main() {
|
|
42
|
+
const targetDir = process.argv[2] || 'walle';
|
|
43
|
+
|
|
44
|
+
console.log(`\n${BOLD}${CYAN} Wall-E${RESET} — Your personal digital twin\n`);
|
|
45
|
+
|
|
46
|
+
if (fs.existsSync(targetDir)) {
|
|
47
|
+
console.log(` Directory "${targetDir}" already exists. Choose a different name:\n npx create-walle my-agent\n`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!fs.existsSync(TEMPLATE_DIR)) {
|
|
52
|
+
console.error(' Template directory not found. Try: npm cache clean --force && npx create-walle@latest');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Auto-detect owner info (strip chars that would break .env)
|
|
57
|
+
const ownerName = detectName().replace(/[\r\n=]/g, '').trim().slice(0, 200);
|
|
58
|
+
const timezone = detectTimezone();
|
|
59
|
+
const nameParts = ownerName.split(/\s+/);
|
|
60
|
+
|
|
61
|
+
console.log(` ${DIM}Owner: ${ownerName}${RESET}`);
|
|
62
|
+
console.log(` ${DIM}Timezone: ${timezone}${RESET}`);
|
|
63
|
+
|
|
64
|
+
// Copy template
|
|
65
|
+
console.log(`\n Copying files...`);
|
|
66
|
+
copyRecursive(TEMPLATE_DIR, targetDir);
|
|
67
|
+
|
|
68
|
+
// Install dependencies
|
|
69
|
+
console.log(` Installing dependencies...\n`);
|
|
70
|
+
try {
|
|
71
|
+
execFileSync('npm', ['install', '--loglevel=warn'], { cwd: path.join(targetDir, 'claude-task-manager'), stdio: 'inherit' });
|
|
72
|
+
execFileSync('npm', ['install', '--loglevel=warn'], { cwd: path.join(targetDir, 'wall-e'), stdio: 'inherit' });
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error(`\n Failed to install dependencies. Make sure npm is installed and try:\n cd ${targetDir}/claude-task-manager && npm install\n cd ${targetDir}/wall-e && npm install\n`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Create .env (API key left as placeholder — configured via web UI)
|
|
79
|
+
const envLines = [
|
|
80
|
+
`# Wall-E configuration — generated ${new Date().toISOString().split('T')[0]}`,
|
|
81
|
+
`# Add your API key below, or configure it at http://localhost:3456/setup`,
|
|
82
|
+
'',
|
|
83
|
+
`WALLE_OWNER_NAME=${ownerName}`,
|
|
84
|
+
'# ANTHROPIC_API_KEY=sk-ant-...',
|
|
85
|
+
'',
|
|
86
|
+
'# Slack (connect via http://localhost:3456/#walle → Settings)',
|
|
87
|
+
'# SLACK_TOKEN=',
|
|
88
|
+
'# SLACK_OWNER_USER_ID=',
|
|
89
|
+
'# SLACK_OWNER_HANDLE=',
|
|
90
|
+
];
|
|
91
|
+
fs.writeFileSync(path.join(targetDir, '.env'), envLines.join('\n') + '\n', { mode: 0o600 });
|
|
92
|
+
|
|
93
|
+
// Create wall-e-config.json
|
|
94
|
+
const walleConfig = {
|
|
95
|
+
owner: {
|
|
96
|
+
name: ownerName,
|
|
97
|
+
first_name: nameParts[0],
|
|
98
|
+
last_name: nameParts.slice(1).join(' '),
|
|
99
|
+
timezone,
|
|
100
|
+
},
|
|
101
|
+
adapters: { ctm: { enabled: true }, slack: { enabled: false } },
|
|
102
|
+
intervals: { ingest_ms: 60000, think_ms: 120000 },
|
|
103
|
+
};
|
|
104
|
+
fs.writeFileSync(
|
|
105
|
+
path.join(targetDir, 'wall-e', 'wall-e-config.json'),
|
|
106
|
+
JSON.stringify(walleConfig, null, 2) + '\n',
|
|
107
|
+
{ mode: 0o600 }
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Create data directory
|
|
111
|
+
const dataDir = path.join(process.env.HOME, '.walle', 'data');
|
|
112
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
113
|
+
|
|
114
|
+
// Init git repo
|
|
115
|
+
execFileSync('git', ['init', '-q'], { cwd: targetDir, stdio: 'ignore' });
|
|
116
|
+
|
|
117
|
+
console.log(`
|
|
118
|
+
${GREEN}${BOLD}Done!${RESET}
|
|
119
|
+
|
|
120
|
+
${BOLD}1. Start:${RESET}
|
|
121
|
+
cd ${targetDir} && node claude-task-manager/server.js
|
|
122
|
+
|
|
123
|
+
${BOLD}2. Open:${RESET}
|
|
124
|
+
http://localhost:3456
|
|
125
|
+
|
|
126
|
+
${BOLD}3. Finish setup in the browser:${RESET}
|
|
127
|
+
Add your Anthropic API key and connect integrations.
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
main().catch(err => {
|
|
132
|
+
console.error(` Error: ${err.message}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-walle",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Set up Wall-E — your personal digital twin",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-walle": "bin/create-walle.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"template/"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "bash build.sh",
|
|
14
|
+
"prepublishOnly": "bash build.sh"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"keywords": ["wall-e", "ai", "digital-twin", "claude", "personal-assistant"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Wall-E & CTM Configuration
|
|
2
|
+
# Copy this to .env and fill in your values
|
|
3
|
+
|
|
4
|
+
# === Required ===
|
|
5
|
+
|
|
6
|
+
# Anthropic API key (for Wall-E chat, skills, and agent loops)
|
|
7
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
8
|
+
|
|
9
|
+
# Owner name (used in system prompts, memory attribution)
|
|
10
|
+
WALLE_OWNER_NAME=Your Name
|
|
11
|
+
|
|
12
|
+
# === Data Storage ===
|
|
13
|
+
|
|
14
|
+
# Where to store databases and backups (default: ~/.walle/data)
|
|
15
|
+
# CTM_DATA_DIR=~/.walle/data
|
|
16
|
+
# WALL_E_DATA_DIR=~/.walle/data
|
|
17
|
+
|
|
18
|
+
# === Optional: Slack Integration ===
|
|
19
|
+
|
|
20
|
+
# Slack bot/user token (for Slack sync skills)
|
|
21
|
+
# SLACK_TOKEN=xoxb-...
|
|
22
|
+
# SLACK_BOT_TOKEN=xoxb-...
|
|
23
|
+
|
|
24
|
+
# Your Slack user ID (for filtering your own messages)
|
|
25
|
+
# SLACK_OWNER_USER_ID=U0XXXXXXXX
|
|
26
|
+
|
|
27
|
+
# Your Slack handle/username (for search queries)
|
|
28
|
+
# SLACK_OWNER_HANDLE=your.name
|
|
29
|
+
|
|
30
|
+
# === Optional: API Gateway ===
|
|
31
|
+
|
|
32
|
+
# If using Portkey or another gateway instead of direct Anthropic API
|
|
33
|
+
# ANTHROPIC_BASE_URL=https://api.portkey.ai/v1
|
|
34
|
+
# ANTHROPIC_CUSTOM_HEADERS_B64=<base64-encoded JSON headers>
|
|
35
|
+
|
|
36
|
+
# === Optional: Server Config ===
|
|
37
|
+
|
|
38
|
+
# CTM_PORT=3456
|
|
39
|
+
# CTM_HOST=127.0.0.1
|
|
40
|
+
# WALL_E_PORT=3457
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Project: Tools (CTM + Wall-E)
|
|
2
|
+
|
|
3
|
+
## Service Management
|
|
4
|
+
|
|
5
|
+
NEVER kill CTM or Wall-E processes directly (e.g. `kill`, `lsof | xargs kill`, `pkill`).
|
|
6
|
+
Always use the restart API or helper script — they handle graceful shutdown and auto-respawn.
|
|
7
|
+
|
|
8
|
+
- **Restart CTM**: `bash claude-task-manager/bin/restart-ctm.sh` or `curl -sX POST http://localhost:3456/api/restart/ctm`
|
|
9
|
+
- **Restart Wall-E**: `curl -sX POST http://localhost:3456/api/restart/walle`
|
|
10
|
+
- **Stop Wall-E**: `curl -sX POST http://localhost:3456/api/stop/walle`
|
|
11
|
+
- **Start Wall-E**: `curl -sX POST http://localhost:3456/api/start/walle`
|
|
12
|
+
- **Check status**: `curl -s http://localhost:3456/api/services/status`
|
package/template/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Juncao Li
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Wall-E
|
|
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.
|
|
4
|
+
|
|
5
|
+
Wall-E runs locally alongside **CTM** (Claude Task Manager), a terminal multiplexer and task dashboard for Claude Code sessions.
|
|
6
|
+
|
|
7
|
+
## What It Does
|
|
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
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
CTM (port 3456) Wall-E
|
|
19
|
+
+-----------------------+ +------------------------+
|
|
20
|
+
| Web Dashboard | | Agent Daemon |
|
|
21
|
+
| - Sessions (pty) | <---> | - Ingest loop (60s) |
|
|
22
|
+
| - 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)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx create-walle my-agent
|
|
38
|
+
cd my-agent
|
|
39
|
+
node claude-task-manager/server.js
|
|
40
|
+
```
|
|
41
|
+
|
|
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.
|
|
43
|
+
|
|
44
|
+
Or clone manually:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone <repo-url> walle && cd walle
|
|
48
|
+
cd claude-task-manager && npm install && cd ..
|
|
49
|
+
cd wall-e && npm install && cd ..
|
|
50
|
+
node claude-task-manager/server.js
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The first run auto-creates `.env`, `wall-e-config.json`, and `~/.walle/data/`. Finish setup at http://localhost:3456/setup.html.
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
All configuration lives in `.env` (auto-generated on first run). Edit directly or use the browser setup page.
|
|
58
|
+
|
|
59
|
+
| Variable | Required | Description |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `ANTHROPIC_API_KEY` | Yes | Your Anthropic API key (set via browser setup) |
|
|
62
|
+
| `WALLE_OWNER_NAME` | Auto | Your name (auto-detected from `git config`) |
|
|
63
|
+
| `WALL_E_DATA_DIR` | No | Data directory (default: `~/.walle/data`) |
|
|
64
|
+
| `CTM_DATA_DIR` | No | CTM data directory (default: `~/.walle/data`) |
|
|
65
|
+
| `SLACK_TOKEN` | No | Slack token (set via OAuth — click "Connect" in setup) |
|
|
66
|
+
| `SLACK_OWNER_USER_ID` | No | Your Slack user ID |
|
|
67
|
+
| `SLACK_OWNER_HANDLE` | No | Your Slack handle |
|
|
68
|
+
|
|
69
|
+
## Bundled Skills
|
|
70
|
+
|
|
71
|
+
Wall-E ships with skills that run on a schedule to keep your brain up to date:
|
|
72
|
+
|
|
73
|
+
| Skill | Schedule | Description |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `google-calendar` | every 30m | Syncs macOS Calendar events (Google, iCloud, Outlook) via EventKit |
|
|
76
|
+
| `slack-sync` | every 15m | Incremental Slack message sync via MCP |
|
|
77
|
+
| `slack-backfill` | manual | Full Slack history backfill (2022-present) |
|
|
78
|
+
| `email-sync` | every 30m | Syncs sent emails from macOS Mail via JXA |
|
|
79
|
+
| `email-digest` | daily 7am | Summarizes recent email activity |
|
|
80
|
+
| `morning-briefing` | daily 7am | AI-generated daily briefing from all sources |
|
|
81
|
+
| `memory-search` | on-demand | Full-text search across all memories |
|
|
82
|
+
|
|
83
|
+
### Creating Custom Skills
|
|
84
|
+
|
|
85
|
+
Skills are defined as `SKILL.md` files with YAML frontmatter:
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
---
|
|
89
|
+
name: my-skill
|
|
90
|
+
description: What this skill does
|
|
91
|
+
version: 1.0.0
|
|
92
|
+
execution: script # or "agent" for LLM-driven skills
|
|
93
|
+
entry: run.js
|
|
94
|
+
trigger:
|
|
95
|
+
type: interval
|
|
96
|
+
schedule: "every 30m"
|
|
97
|
+
tags: [sync, data]
|
|
98
|
+
---
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Place skills in `wall-e/skills/_bundled/your-skill/SKILL.md` or load from a custom directory.
|
|
102
|
+
|
|
103
|
+
## Dashboard Features
|
|
104
|
+
|
|
105
|
+
### Sessions Tab
|
|
106
|
+
Terminal multiplexer for Claude Code — create, monitor, and manage multiple sessions from a single browser tab.
|
|
107
|
+
|
|
108
|
+
### Prompts Tab
|
|
109
|
+
Rich-text prompt editor with versioning, tagging, folders, and one-click send to any active Claude session. Supports composite prompts (parent + sub-prompts).
|
|
110
|
+
|
|
111
|
+
### Tasks Tab
|
|
112
|
+
Task dashboard with recurring task support, skill execution, checkpoint/resume, and live logs.
|
|
113
|
+
|
|
114
|
+
### Wall-E Tab
|
|
115
|
+
Chat directly with Wall-E — ask about your schedule, search your memories, run skills, and get AI-powered answers grounded in your actual data.
|
|
116
|
+
|
|
117
|
+
### Code Review Tab
|
|
118
|
+
Review code changes across projects with inline diffs and AI-assisted review.
|
|
119
|
+
|
|
120
|
+
## API
|
|
121
|
+
|
|
122
|
+
CTM runs on port 3456. Key endpoints:
|
|
123
|
+
|
|
124
|
+
| Method | Path | Description |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| GET | `/api/services/status` | CTM and Wall-E process status |
|
|
127
|
+
| POST | `/api/restart/walle` | Restart Wall-E daemon |
|
|
128
|
+
| POST | `/api/start/walle` | Start Wall-E daemon |
|
|
129
|
+
| POST | `/api/stop/walle` | Stop Wall-E daemon |
|
|
130
|
+
| GET | `/api/wall-e/status` | Wall-E brain stats and owner info |
|
|
131
|
+
| GET | `/api/wall-e/memories` | List memories (filterable by source, since, limit) |
|
|
132
|
+
| GET | `/api/wall-e/knowledge` | List knowledge entries |
|
|
133
|
+
| GET | `/api/wall-e/people` | List known people |
|
|
134
|
+
| GET | `/api/wall-e/timeline` | Memory timeline |
|
|
135
|
+
| POST | `/api/wall-e/chat` | Chat with Wall-E |
|
|
136
|
+
| GET | `/api/prompts` | List prompts |
|
|
137
|
+
| GET | `/api/sessions` | List active terminal sessions |
|
|
138
|
+
|
|
139
|
+
## Tech Stack
|
|
140
|
+
|
|
141
|
+
- **Runtime**: Node.js (no framework — raw `http.createServer`)
|
|
142
|
+
- **Database**: SQLite via better-sqlite3 (WAL mode, FTS5 full-text search)
|
|
143
|
+
- **AI**: Claude API via Anthropic SDK (supports Portkey gateway)
|
|
144
|
+
- **Frontend**: Vanilla HTML/CSS/JS (no build step, no React)
|
|
145
|
+
- **macOS integration**: EventKit (calendar), JXA (email/AppleScript), Spotlight (file search)
|
|
146
|
+
- **Terminal**: node-pty for session management
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Run Wall-E tests
|
|
152
|
+
cd wall-e && npm test
|
|
153
|
+
|
|
154
|
+
# Run a single test file
|
|
155
|
+
node --test tests/brain.test.js
|
|
156
|
+
|
|
157
|
+
# Run Slack backfill manually
|
|
158
|
+
node scripts/slack-backfill.js 2024-01 # single month
|
|
159
|
+
node scripts/slack-backfill.js incremental # new messages only
|
|
160
|
+
|
|
161
|
+
# Run calendar sync manually
|
|
162
|
+
node skills/_bundled/google-calendar/run.js
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// First-run setup — auto-detects owner info and creates .env + config.
|
|
5
|
+
// No interactive prompts. API key and integrations are configured via the web UI.
|
|
6
|
+
|
|
7
|
+
const { execFileSync } = require('child_process');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
12
|
+
const ENV_PATH = path.join(ROOT, '.env');
|
|
13
|
+
const WALLE_CONFIG = path.join(ROOT, 'wall-e', 'wall-e-config.json');
|
|
14
|
+
|
|
15
|
+
function detectName() {
|
|
16
|
+
try { return execFileSync('git', ['config', 'user.name'], { encoding: 'utf8' }).trim(); } catch {}
|
|
17
|
+
try { return execFileSync('id', ['-F'], { encoding: 'utf8' }).trim(); } catch {}
|
|
18
|
+
return process.env.USER || 'Owner';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function detectTimezone() {
|
|
22
|
+
try { return Intl.DateTimeFormat().resolvedOptions().timeZone; } catch {}
|
|
23
|
+
return 'UTC';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Returns true if setup was performed, false if already configured.
|
|
28
|
+
*/
|
|
29
|
+
function runIfNeeded() {
|
|
30
|
+
if (fs.existsSync(ENV_PATH)) return false;
|
|
31
|
+
|
|
32
|
+
const ownerName = detectName().replace(/[\r\n=]/g, '').trim().slice(0, 200);
|
|
33
|
+
const timezone = detectTimezone();
|
|
34
|
+
const nameParts = ownerName.split(/\s+/);
|
|
35
|
+
|
|
36
|
+
// Write .env
|
|
37
|
+
const envLines = [
|
|
38
|
+
`# Wall-E configuration — generated ${new Date().toISOString().split('T')[0]}`,
|
|
39
|
+
`# Configure API key and integrations at http://localhost:3456/setup`,
|
|
40
|
+
'',
|
|
41
|
+
`WALLE_OWNER_NAME=${ownerName}`,
|
|
42
|
+
'# ANTHROPIC_API_KEY=sk-ant-...',
|
|
43
|
+
];
|
|
44
|
+
fs.writeFileSync(ENV_PATH, envLines.join('\n') + '\n', { mode: 0o600 });
|
|
45
|
+
|
|
46
|
+
// Set in current process
|
|
47
|
+
process.env.WALLE_OWNER_NAME = ownerName;
|
|
48
|
+
|
|
49
|
+
// Write wall-e-config.json if missing
|
|
50
|
+
if (!fs.existsSync(WALLE_CONFIG)) {
|
|
51
|
+
const config = {
|
|
52
|
+
owner: {
|
|
53
|
+
name: ownerName,
|
|
54
|
+
first_name: nameParts[0],
|
|
55
|
+
last_name: nameParts.slice(1).join(' '),
|
|
56
|
+
timezone,
|
|
57
|
+
},
|
|
58
|
+
adapters: { ctm: { enabled: true }, slack: { enabled: false } },
|
|
59
|
+
intervals: { ingest_ms: 60000, think_ms: 120000 },
|
|
60
|
+
};
|
|
61
|
+
fs.mkdirSync(path.dirname(WALLE_CONFIG), { recursive: true });
|
|
62
|
+
fs.writeFileSync(WALLE_CONFIG, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create data directory
|
|
66
|
+
const dataDir = process.env.WALL_E_DATA_DIR || path.join(process.env.HOME, '.walle', 'data');
|
|
67
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
68
|
+
|
|
69
|
+
console.log(`[setup] First-run setup complete. Owner: ${ownerName}`);
|
|
70
|
+
console.log(`[setup] Finish setup at http://localhost:3456/setup`);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Returns true if setup is needed (no API key configured anywhere). Cached after first check. */
|
|
75
|
+
let _needsSetupCache = undefined;
|
|
76
|
+
function needsSetup() {
|
|
77
|
+
if (_needsSetupCache !== undefined) return _needsSetupCache;
|
|
78
|
+
// Check process.env first (may be set via Portkey, environment, etc.)
|
|
79
|
+
if (process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_BASE_URL) {
|
|
80
|
+
_needsSetupCache = false;
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
if (!fs.existsSync(ENV_PATH)) {
|
|
84
|
+
_needsSetupCache = true;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
const content = fs.readFileSync(ENV_PATH, 'utf8');
|
|
88
|
+
_needsSetupCache = !content.match(/^ANTHROPIC_API_KEY=\S+/m);
|
|
89
|
+
return _needsSetupCache;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Call after saving API key to clear the needsSetup cache. */
|
|
93
|
+
function clearSetupCache() { _needsSetupCache = undefined; }
|
|
94
|
+
|
|
95
|
+
module.exports = { runIfNeeded, needsSetup, clearSetupCache };
|
|
96
|
+
|
|
97
|
+
if (require.main === module) {
|
|
98
|
+
const ran = runIfNeeded();
|
|
99
|
+
if (!ran) console.log('Already configured.');
|
|
100
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Wall-E — Claude Code Skill
|
|
2
|
+
|
|
3
|
+
Wall-E can be used as an MCP server from Claude Code, giving Claude access to your personal knowledge base, calendar, and memory search.
|
|
4
|
+
|
|
5
|
+
## Install as MCP Server
|
|
6
|
+
|
|
7
|
+
Add to your Claude Code MCP config (`~/.claude/mcp.json`):
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"mcpServers": {
|
|
12
|
+
"wall-e": {
|
|
13
|
+
"type": "http",
|
|
14
|
+
"url": "http://localhost:3457/mcp"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Then start Wall-E's standalone HTTP server:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd wall-e
|
|
24
|
+
WALL_E_PORT=3457 node agent.js
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Available Tools
|
|
28
|
+
|
|
29
|
+
Once connected, Claude Code gains access to:
|
|
30
|
+
|
|
31
|
+
| Tool | Description |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `search_memories` | Full-text search across all ingested memories (Slack, email, calendar) |
|
|
34
|
+
| `calendar_events` | Get upcoming calendar events with attendees, location, notes |
|
|
35
|
+
| `remember_fact` | Store new knowledge in the brain |
|
|
36
|
+
| `run_skill` | Execute any bundled or custom skill |
|
|
37
|
+
| `list_mcp_tools` | Discover tools from Wall-E's own MCP connections |
|
|
38
|
+
|
|
39
|
+
## Use Cases in Claude Code
|
|
40
|
+
|
|
41
|
+
Once Wall-E is connected as an MCP server, you can ask Claude Code:
|
|
42
|
+
|
|
43
|
+
- "What meetings do I have tomorrow?" — searches calendar memories
|
|
44
|
+
- "What did I discuss with Alice last week?" — searches Slack memories
|
|
45
|
+
- "Remember that I prefer Tailwind over Bootstrap" — stores knowledge
|
|
46
|
+
- "Run the morning briefing skill" — generates a daily summary
|
|
47
|
+
- "Search my memories for the database migration discussion" — full-text search
|
|
48
|
+
|
|
49
|
+
## CLAUDE.md Integration
|
|
50
|
+
|
|
51
|
+
Add to your project's `CLAUDE.md` to give Claude Code context about Wall-E:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Wall-E (Personal Digital Twin)
|
|
55
|
+
|
|
56
|
+
This project has Wall-E connected as an MCP server. Use it to:
|
|
57
|
+
- Search the owner's memories and knowledge base
|
|
58
|
+
- Check calendar events and meeting schedules
|
|
59
|
+
- Look up past Slack conversations for context
|
|
60
|
+
```
|