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,214 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { execFile } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// Run a git command in a given project directory
|
|
6
|
+
function git(cwd, args, maxBuffer = 1024 * 1024 * 5) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
execFile('git', args, { cwd, maxBuffer, timeout: 15000 }, (err, stdout, stderr) => {
|
|
9
|
+
if (err && !stdout) return reject(err);
|
|
10
|
+
resolve(stdout);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Get list of recent commits for base-ref picker
|
|
16
|
+
async function getCommits(cwd, count = 30) {
|
|
17
|
+
const out = await git(cwd, ['log', '--oneline', '--no-decorate', `-${count}`]);
|
|
18
|
+
return out.trim().split('\n').filter(Boolean).map(line => {
|
|
19
|
+
const i = line.indexOf(' ');
|
|
20
|
+
return { sha: line.slice(0, i), message: line.slice(i + 1) };
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Get current branch name
|
|
25
|
+
async function getBranch(cwd) {
|
|
26
|
+
const out = await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
27
|
+
return out.trim();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function parseNumstat(out) {
|
|
31
|
+
const files = [];
|
|
32
|
+
for (const line of out.trim().split('\n')) {
|
|
33
|
+
const m = line.match(/^(\d+|-)\t(\d+|-)\t(.+)$/);
|
|
34
|
+
if (m) {
|
|
35
|
+
files.push({
|
|
36
|
+
additions: m[1] === '-' ? 0 : parseInt(m[1]),
|
|
37
|
+
deletions: m[2] === '-' ? 0 : parseInt(m[2]),
|
|
38
|
+
path: m[3],
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Get diff stat (file list with additions/deletions) - lightweight for badge polling
|
|
46
|
+
async function getDiffStat(cwd, baseRef) {
|
|
47
|
+
let args;
|
|
48
|
+
if (!baseRef) {
|
|
49
|
+
args = ['diff', '--relative', '--stat', '--numstat'];
|
|
50
|
+
} else if (/^[0-9a-f]{7,40}$/.test(baseRef)) {
|
|
51
|
+
try {
|
|
52
|
+
const out = await git(cwd, ['diff', '--stat', '--numstat', `${baseRef}^`, baseRef]);
|
|
53
|
+
return parseNumstat(out);
|
|
54
|
+
} catch {
|
|
55
|
+
const out = await git(cwd, ['diff-tree', '--stat', '--numstat', '--root', baseRef]);
|
|
56
|
+
return parseNumstat(out);
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
args = ['diff', '--relative', '--stat', '--numstat', baseRef];
|
|
60
|
+
}
|
|
61
|
+
const out = await git(cwd, args);
|
|
62
|
+
return parseNumstat(out);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Get full unified diff - the source of truth for review
|
|
66
|
+
async function getFullDiff(cwd, baseRef) {
|
|
67
|
+
let args;
|
|
68
|
+
if (!baseRef) {
|
|
69
|
+
// No base: working tree vs HEAD
|
|
70
|
+
args = ['diff', '--relative', '-U5'];
|
|
71
|
+
} else if (/^[0-9a-f]{7,40}$/.test(baseRef)) {
|
|
72
|
+
// Commit SHA: show what that commit introduced (parent..commit)
|
|
73
|
+
// No --relative here: show all files the commit touched regardless of cwd
|
|
74
|
+
try {
|
|
75
|
+
const raw = await git(cwd, ['diff', '-U5', `${baseRef}^`, baseRef]);
|
|
76
|
+
return parseDiff(raw);
|
|
77
|
+
} catch {
|
|
78
|
+
// Root commit — use diff-tree to show all changes
|
|
79
|
+
const raw = await git(cwd, ['diff-tree', '-p', '-U5', '--root', baseRef]);
|
|
80
|
+
return parseDiff(raw);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
// Branch name or other ref: working tree vs ref
|
|
84
|
+
args = ['diff', '--relative', '-U5', baseRef];
|
|
85
|
+
}
|
|
86
|
+
const raw = await git(cwd, args);
|
|
87
|
+
return parseDiff(raw);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Get diff for staged files only
|
|
91
|
+
async function getStagedDiff(cwd) {
|
|
92
|
+
const raw = await git(cwd, ['diff', '--relative', '--staged', '-U5']);
|
|
93
|
+
return parseDiff(raw);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Parse unified diff format into structured data
|
|
97
|
+
function parseDiff(raw) {
|
|
98
|
+
const files = [];
|
|
99
|
+
if (!raw || !raw.trim()) return files;
|
|
100
|
+
|
|
101
|
+
const diffBlocks = raw.split(/^diff --git /m).filter(Boolean);
|
|
102
|
+
|
|
103
|
+
for (const block of diffBlocks) {
|
|
104
|
+
const lines = block.split('\n');
|
|
105
|
+
// First line: a/path b/path
|
|
106
|
+
const pathMatch = lines[0].match(/a\/(.+?) b\/(.+)/);
|
|
107
|
+
if (!pathMatch) continue;
|
|
108
|
+
|
|
109
|
+
const file = {
|
|
110
|
+
oldPath: pathMatch[1],
|
|
111
|
+
path: pathMatch[2],
|
|
112
|
+
language: detectLanguage(pathMatch[2]),
|
|
113
|
+
additions: 0,
|
|
114
|
+
deletions: 0,
|
|
115
|
+
hunks: [],
|
|
116
|
+
isBinary: false,
|
|
117
|
+
isNew: false,
|
|
118
|
+
isDeleted: false,
|
|
119
|
+
isRenamed: pathMatch[1] !== pathMatch[2],
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Check for binary, new file, deleted file markers
|
|
123
|
+
let headerEnd = 1;
|
|
124
|
+
for (let i = 1; i < lines.length; i++) {
|
|
125
|
+
if (lines[i].startsWith('@@')) { headerEnd = i; break; }
|
|
126
|
+
if (lines[i].startsWith('Binary files')) { file.isBinary = true; headerEnd = lines.length; break; }
|
|
127
|
+
if (lines[i].startsWith('new file')) file.isNew = true;
|
|
128
|
+
if (lines[i].startsWith('deleted file')) file.isDeleted = true;
|
|
129
|
+
headerEnd = i + 1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (file.isBinary) { files.push(file); continue; }
|
|
133
|
+
|
|
134
|
+
// Parse hunks
|
|
135
|
+
let currentHunk = null;
|
|
136
|
+
for (let i = headerEnd; i < lines.length; i++) {
|
|
137
|
+
const line = lines[i];
|
|
138
|
+
const hunkMatch = line.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)/);
|
|
139
|
+
if (hunkMatch) {
|
|
140
|
+
currentHunk = {
|
|
141
|
+
oldStart: parseInt(hunkMatch[1]),
|
|
142
|
+
oldLines: parseInt(hunkMatch[2] || '1'),
|
|
143
|
+
newStart: parseInt(hunkMatch[3]),
|
|
144
|
+
newLines: parseInt(hunkMatch[4] || '1'),
|
|
145
|
+
header: hunkMatch[5].trim(),
|
|
146
|
+
lines: [],
|
|
147
|
+
};
|
|
148
|
+
file.hunks.push(currentHunk);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!currentHunk) continue;
|
|
153
|
+
|
|
154
|
+
if (line.startsWith('+')) {
|
|
155
|
+
currentHunk.lines.push({ type: 'add', content: line.slice(1) });
|
|
156
|
+
file.additions++;
|
|
157
|
+
} else if (line.startsWith('-')) {
|
|
158
|
+
currentHunk.lines.push({ type: 'del', content: line.slice(1) });
|
|
159
|
+
file.deletions++;
|
|
160
|
+
} else if (line.startsWith(' ') || line === '') {
|
|
161
|
+
currentHunk.lines.push({ type: 'ctx', content: line.slice(1) });
|
|
162
|
+
} else if (line.startsWith('\\')) {
|
|
163
|
+
// "No newline at end of file" marker - skip
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
files.push(file);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Assign line numbers to each line in each hunk
|
|
171
|
+
for (const file of files) {
|
|
172
|
+
for (const hunk of file.hunks) {
|
|
173
|
+
let oldNum = hunk.oldStart;
|
|
174
|
+
let newNum = hunk.newStart;
|
|
175
|
+
for (const line of hunk.lines) {
|
|
176
|
+
if (line.type === 'ctx') {
|
|
177
|
+
line.oldNum = oldNum++;
|
|
178
|
+
line.newNum = newNum++;
|
|
179
|
+
} else if (line.type === 'add') {
|
|
180
|
+
line.oldNum = null;
|
|
181
|
+
line.newNum = newNum++;
|
|
182
|
+
} else if (line.type === 'del') {
|
|
183
|
+
line.oldNum = oldNum++;
|
|
184
|
+
line.newNum = null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return files;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Detect language from file extension for syntax highlighting class
|
|
194
|
+
function detectLanguage(filePath) {
|
|
195
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
196
|
+
const map = {
|
|
197
|
+
'.js': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
|
|
198
|
+
'.ts': 'typescript', '.tsx': 'typescript',
|
|
199
|
+
'.py': 'python', '.rb': 'ruby', '.go': 'go',
|
|
200
|
+
'.rs': 'rust', '.java': 'java', '.kt': 'kotlin',
|
|
201
|
+
'.c': 'c', '.cpp': 'cpp', '.h': 'c', '.hpp': 'cpp',
|
|
202
|
+
'.css': 'css', '.scss': 'scss', '.less': 'less',
|
|
203
|
+
'.html': 'html', '.htm': 'html', '.xml': 'xml',
|
|
204
|
+
'.json': 'json', '.yaml': 'yaml', '.yml': 'yaml',
|
|
205
|
+
'.md': 'markdown', '.sh': 'bash', '.zsh': 'bash',
|
|
206
|
+
'.sql': 'sql', '.graphql': 'graphql',
|
|
207
|
+
'.toml': 'toml', '.ini': 'ini', '.cfg': 'ini',
|
|
208
|
+
'.dockerfile': 'dockerfile', '.svelte': 'svelte',
|
|
209
|
+
'.vue': 'vue', '.jsx': 'javascript',
|
|
210
|
+
};
|
|
211
|
+
return map[ext] || 'plaintext';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = { git, getCommits, getBranch, getDiffStat, getFullDiff, getStagedDiff, parseDiff };
|