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.
Files changed (136) hide show
  1. package/bin/create-walle.js +134 -0
  2. package/package.json +18 -0
  3. package/template/.env.example +40 -0
  4. package/template/CLAUDE.md +12 -0
  5. package/template/LICENSE +21 -0
  6. package/template/README.md +167 -0
  7. package/template/bin/setup.js +100 -0
  8. package/template/claude-code-skill.md +60 -0
  9. package/template/claude-task-manager/api-prompts.js +1841 -0
  10. package/template/claude-task-manager/api-reviews.js +275 -0
  11. package/template/claude-task-manager/approval-agent.js +454 -0
  12. package/template/claude-task-manager/bin/restart-ctm.sh +16 -0
  13. package/template/claude-task-manager/db.js +1721 -0
  14. package/template/claude-task-manager/docs/PROMPT-MANAGEMENT-DESIGN.md +631 -0
  15. package/template/claude-task-manager/git-utils.js +214 -0
  16. package/template/claude-task-manager/package-lock.json +1607 -0
  17. package/template/claude-task-manager/package.json +31 -0
  18. package/template/claude-task-manager/prompt-harvest.js +1148 -0
  19. package/template/claude-task-manager/public/css/prompts.css +880 -0
  20. package/template/claude-task-manager/public/css/reviews.css +430 -0
  21. package/template/claude-task-manager/public/css/walle.css +732 -0
  22. package/template/claude-task-manager/public/favicon.ico +0 -0
  23. package/template/claude-task-manager/public/icon.svg +37 -0
  24. package/template/claude-task-manager/public/index.html +8346 -0
  25. package/template/claude-task-manager/public/js/prompts.js +3159 -0
  26. package/template/claude-task-manager/public/js/reviews.js +1292 -0
  27. package/template/claude-task-manager/public/js/walle.js +3081 -0
  28. package/template/claude-task-manager/public/manifest.json +13 -0
  29. package/template/claude-task-manager/public/prompts.html +4353 -0
  30. package/template/claude-task-manager/public/setup.html +216 -0
  31. package/template/claude-task-manager/queue-engine.js +404 -0
  32. package/template/claude-task-manager/server-state.js +5 -0
  33. package/template/claude-task-manager/server.js +2254 -0
  34. package/template/claude-task-manager/session-utils.js +124 -0
  35. package/template/claude-task-manager/start.sh +17 -0
  36. package/template/claude-task-manager/tests/test-ai-search.js +61 -0
  37. package/template/claude-task-manager/tests/test-editor-ux.js +76 -0
  38. package/template/claude-task-manager/tests/test-editor-ux2.js +51 -0
  39. package/template/claude-task-manager/tests/test-features-v2.js +127 -0
  40. package/template/claude-task-manager/tests/test-insights-cached.js +78 -0
  41. package/template/claude-task-manager/tests/test-insights.js +124 -0
  42. package/template/claude-task-manager/tests/test-permissions-v2.js +127 -0
  43. package/template/claude-task-manager/tests/test-permissions.js +122 -0
  44. package/template/claude-task-manager/tests/test-pin.js +51 -0
  45. package/template/claude-task-manager/tests/test-prompts.js +164 -0
  46. package/template/claude-task-manager/tests/test-recent-sessions.js +96 -0
  47. package/template/claude-task-manager/tests/test-review.js +104 -0
  48. package/template/claude-task-manager/tests/test-send-dropdown.js +76 -0
  49. package/template/claude-task-manager/tests/test-send-final.js +30 -0
  50. package/template/claude-task-manager/tests/test-send-fixes.js +76 -0
  51. package/template/claude-task-manager/tests/test-send-integration.js +107 -0
  52. package/template/claude-task-manager/tests/test-send-visual.js +34 -0
  53. package/template/claude-task-manager/tests/test-session-create.js +147 -0
  54. package/template/claude-task-manager/tests/test-sidebar-ux.js +83 -0
  55. package/template/claude-task-manager/tests/test-url-hash.js +68 -0
  56. package/template/claude-task-manager/tests/test-ux-crop.js +34 -0
  57. package/template/claude-task-manager/tests/test-ux-review.js +130 -0
  58. package/template/claude-task-manager/tests/test-zoom-card.js +76 -0
  59. package/template/claude-task-manager/tests/test-zoom.js +92 -0
  60. package/template/claude-task-manager/tests/test-zoom2.js +67 -0
  61. package/template/docs/site/api/README.md +187 -0
  62. package/template/docs/site/guides/claude-code.md +58 -0
  63. package/template/docs/site/guides/configuration.md +96 -0
  64. package/template/docs/site/guides/quickstart.md +158 -0
  65. package/template/docs/site/index.md +14 -0
  66. package/template/docs/site/skills/README.md +135 -0
  67. package/template/wall-e/.dockerignore +11 -0
  68. package/template/wall-e/Dockerfile +25 -0
  69. package/template/wall-e/adapters/adapter-base.js +37 -0
  70. package/template/wall-e/adapters/ctm.js +193 -0
  71. package/template/wall-e/adapters/slack.js +56 -0
  72. package/template/wall-e/agent.js +319 -0
  73. package/template/wall-e/api-walle.js +1073 -0
  74. package/template/wall-e/brain.js +1235 -0
  75. package/template/wall-e/channels/agent-api.js +172 -0
  76. package/template/wall-e/channels/channel-base.js +14 -0
  77. package/template/wall-e/channels/imessage-channel.js +113 -0
  78. package/template/wall-e/channels/slack-channel.js +118 -0
  79. package/template/wall-e/chat.js +778 -0
  80. package/template/wall-e/decision/confidence.js +93 -0
  81. package/template/wall-e/deploy.sh +35 -0
  82. package/template/wall-e/docs/specs/2026-04-01-publish-plan.md +112 -0
  83. package/template/wall-e/docs/specs/SKILL-FORMAT.md +326 -0
  84. package/template/wall-e/extraction/contradiction.js +168 -0
  85. package/template/wall-e/extraction/knowledge-extractor.js +190 -0
  86. package/template/wall-e/fly.toml +24 -0
  87. package/template/wall-e/loops/ingest.js +34 -0
  88. package/template/wall-e/loops/reflect.js +63 -0
  89. package/template/wall-e/loops/tasks.js +487 -0
  90. package/template/wall-e/loops/think.js +125 -0
  91. package/template/wall-e/package-lock.json +533 -0
  92. package/template/wall-e/package.json +18 -0
  93. package/template/wall-e/scripts/ingest-slack-search.js +85 -0
  94. package/template/wall-e/scripts/pull-slack-via-claude.js +98 -0
  95. package/template/wall-e/scripts/slack-backfill.js +295 -0
  96. package/template/wall-e/scripts/slack-channel-history.js +454 -0
  97. package/template/wall-e/server.js +93 -0
  98. package/template/wall-e/skills/_bundled/email-digest/SKILL.md +95 -0
  99. package/template/wall-e/skills/_bundled/email-sync/SKILL.md +65 -0
  100. package/template/wall-e/skills/_bundled/email-sync/mail-reader.jxa +104 -0
  101. package/template/wall-e/skills/_bundled/email-sync/run.js +213 -0
  102. package/template/wall-e/skills/_bundled/google-calendar/SKILL.md +73 -0
  103. package/template/wall-e/skills/_bundled/google-calendar/cal-reader.swift +81 -0
  104. package/template/wall-e/skills/_bundled/google-calendar/run.js +181 -0
  105. package/template/wall-e/skills/_bundled/memory-search/SKILL.md +92 -0
  106. package/template/wall-e/skills/_bundled/morning-briefing/SKILL.md +131 -0
  107. package/template/wall-e/skills/_bundled/morning-briefing/run.js +264 -0
  108. package/template/wall-e/skills/_bundled/slack-backfill/SKILL.md +60 -0
  109. package/template/wall-e/skills/_bundled/slack-sync/SKILL.md +55 -0
  110. package/template/wall-e/skills/claude-code-reader.js +144 -0
  111. package/template/wall-e/skills/mcp-client.js +407 -0
  112. package/template/wall-e/skills/skill-executor.js +163 -0
  113. package/template/wall-e/skills/skill-loader.js +410 -0
  114. package/template/wall-e/skills/skill-planner.js +88 -0
  115. package/template/wall-e/skills/slack-ingest.js +329 -0
  116. package/template/wall-e/skills/slack-pull-live.js +270 -0
  117. package/template/wall-e/skills/tool-executor.js +188 -0
  118. package/template/wall-e/tests/adapter-base.test.js +20 -0
  119. package/template/wall-e/tests/adapter-ctm.test.js +122 -0
  120. package/template/wall-e/tests/adapter-slack.test.js +98 -0
  121. package/template/wall-e/tests/agent-api.test.js +256 -0
  122. package/template/wall-e/tests/api-walle.test.js +222 -0
  123. package/template/wall-e/tests/brain.test.js +602 -0
  124. package/template/wall-e/tests/channels.test.js +104 -0
  125. package/template/wall-e/tests/chat.test.js +103 -0
  126. package/template/wall-e/tests/confidence.test.js +134 -0
  127. package/template/wall-e/tests/contradiction.test.js +217 -0
  128. package/template/wall-e/tests/ingest.test.js +113 -0
  129. package/template/wall-e/tests/mcp-client.test.js +71 -0
  130. package/template/wall-e/tests/reflect.test.js +103 -0
  131. package/template/wall-e/tests/server.test.js +111 -0
  132. package/template/wall-e/tests/skills.test.js +198 -0
  133. package/template/wall-e/tests/slack-ingest.test.js +103 -0
  134. package/template/wall-e/tests/think.test.js +435 -0
  135. package/template/wall-e/tools/local-tools.js +697 -0
  136. 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 };