create-walle 0.9.13 → 0.9.15

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 (98) hide show
  1. package/README.md +8 -3
  2. package/bin/create-walle.js +232 -32
  3. package/bin/mcp-inject.js +18 -53
  4. package/package.json +3 -1
  5. package/template/claude-task-manager/api-prompts.js +11 -2
  6. package/template/claude-task-manager/approval-agent.js +7 -0
  7. package/template/claude-task-manager/db.js +94 -75
  8. package/template/claude-task-manager/docs/session-standup-command-center-design.md +242 -0
  9. package/template/claude-task-manager/docs/session-tooltip-freshness-design.md +224 -0
  10. package/template/claude-task-manager/docs/session-ux-issue-review-2026-05-01.md +369 -0
  11. package/template/claude-task-manager/fuzzy-utils.js +10 -2
  12. package/template/claude-task-manager/git-utils.js +140 -10
  13. package/template/claude-task-manager/lib/agent-capabilities.js +1 -1
  14. package/template/claude-task-manager/lib/agent-presets.js +38 -5
  15. package/template/claude-task-manager/lib/codex-terminal-final.js +53 -0
  16. package/template/claude-task-manager/lib/ctm-session-context-api.js +222 -0
  17. package/template/claude-task-manager/lib/session-diagnostics.js +56 -0
  18. package/template/claude-task-manager/lib/session-history.js +309 -16
  19. package/template/claude-task-manager/lib/session-standup.js +409 -0
  20. package/template/claude-task-manager/lib/session-stream.js +253 -20
  21. package/template/claude-task-manager/lib/standup-attention.js +200 -0
  22. package/template/claude-task-manager/lib/status-hooks.js +8 -2
  23. package/template/claude-task-manager/lib/update-telemetry.js +114 -0
  24. package/template/claude-task-manager/lib/walle-ctm-history.js +49 -6
  25. package/template/claude-task-manager/lib/walle-default-model.js +55 -0
  26. package/template/claude-task-manager/lib/walle-mcp-auto-config.js +66 -0
  27. package/template/claude-task-manager/lib/walle-supervisor.js +86 -19
  28. package/template/claude-task-manager/lib/walle-transcript.js +1 -3
  29. package/template/claude-task-manager/lib/worktree-cwd.js +82 -0
  30. package/template/claude-task-manager/package.json +1 -0
  31. package/template/claude-task-manager/providers/codex-mcp.js +104 -0
  32. package/template/claude-task-manager/providers/index.js +2 -0
  33. package/template/claude-task-manager/public/css/setup.css +2 -1
  34. package/template/claude-task-manager/public/css/walle.css +71 -0
  35. package/template/claude-task-manager/public/index.html +2388 -429
  36. package/template/claude-task-manager/public/js/message-renderer.js +314 -35
  37. package/template/claude-task-manager/public/js/session-search-utils.js +185 -3
  38. package/template/claude-task-manager/public/js/session-status-precedence.js +125 -0
  39. package/template/claude-task-manager/public/js/setup.js +62 -19
  40. package/template/claude-task-manager/public/js/stream-view.js +396 -55
  41. package/template/claude-task-manager/public/js/terminal-restore-state.js +57 -0
  42. package/template/claude-task-manager/public/js/walle-session.js +234 -26
  43. package/template/claude-task-manager/public/js/walle.js +143 -2
  44. package/template/claude-task-manager/server.js +1402 -433
  45. package/template/claude-task-manager/session-integrity.js +77 -28
  46. package/template/claude-task-manager/workers/approval-widget-validator.js +15 -5
  47. package/template/claude-task-manager/workers/scrollback-worker.js +5 -6
  48. package/template/claude-task-manager/workers/state-detectors/codex.js +6 -0
  49. package/template/package.json +1 -1
  50. package/template/wall-e/agent-runners/claude-code.js +2 -0
  51. package/template/wall-e/agent.js +63 -8
  52. package/template/wall-e/api-walle.js +330 -52
  53. package/template/wall-e/brain.js +291 -42
  54. package/template/wall-e/chat.js +172 -15
  55. package/template/wall-e/coding/compaction-service.js +19 -5
  56. package/template/wall-e/coding/stream-processor.js +22 -2
  57. package/template/wall-e/coding/workspace-replay.js +1 -4
  58. package/template/wall-e/coding-orchestrator.js +250 -80
  59. package/template/wall-e/compat.js +0 -28
  60. package/template/wall-e/context/context-builder.js +3 -1
  61. package/template/wall-e/embeddings.js +2 -7
  62. package/template/wall-e/eval/agent-runner.js +30 -9
  63. package/template/wall-e/eval/benchmark-generator.js +21 -1
  64. package/template/wall-e/eval/benchmarks/chat-eval.json +66 -6
  65. package/template/wall-e/eval/benchmarks/coding-agent.json +0 -596
  66. package/template/wall-e/eval/cc-replay.js +1 -0
  67. package/template/wall-e/eval/codex-cli-baseline.js +633 -0
  68. package/template/wall-e/eval/debug-agent003.js +1 -0
  69. package/template/wall-e/eval/eval-orchestrator.js +3 -3
  70. package/template/wall-e/eval/run-agent-benchmarks.js +11 -3
  71. package/template/wall-e/eval/run-codex-cli-baseline.js +177 -0
  72. package/template/wall-e/eval/run-model-comparison.js +1 -0
  73. package/template/wall-e/eval/swebench-adapter.js +1 -0
  74. package/template/wall-e/evaluation/quorum-evaluator.js +0 -1
  75. package/template/wall-e/extraction/knowledge-extractor.js +1 -2
  76. package/template/wall-e/lib/mcp-integration.js +336 -0
  77. package/template/wall-e/llm/ollama.js +47 -8
  78. package/template/wall-e/llm/ollama.plugin.json +1 -1
  79. package/template/wall-e/llm/tool-adapter.js +1 -0
  80. package/template/wall-e/loops/ingest.js +42 -8
  81. package/template/wall-e/loops/initiative.js +87 -2
  82. package/template/wall-e/mcp-server.js +872 -19
  83. package/template/wall-e/memory/ctm-context-client.js +230 -0
  84. package/template/wall-e/memory/ctm-session-context.js +1376 -0
  85. package/template/wall-e/prompts/coding/memory-protocol.md +6 -0
  86. package/template/wall-e/server.js +30 -1
  87. package/template/wall-e/skills/_bundled/memory-search/SKILL.md +8 -0
  88. package/template/wall-e/skills/_bundled/scan-ctm-sessions/SKILL.md +20 -0
  89. package/template/wall-e/skills/_bundled/scan-ctm-sessions/run.js +43 -0
  90. package/template/wall-e/skills/_bundled/slack-mentions/run.js +471 -188
  91. package/template/wall-e/skills/skill-planner.js +86 -4
  92. package/template/wall-e/slack/socket-mode-listener.js +276 -0
  93. package/template/wall-e/telemetry.js +70 -2
  94. package/template/wall-e/tools/builtin-middleware.js +55 -2
  95. package/template/wall-e/tools/shell-policy.js +1 -1
  96. package/template/wall-e/tools/slack-owner.js +104 -0
  97. package/template/website/index.html +4 -4
  98. package/template/builder-journal.md +0 -17
@@ -0,0 +1,230 @@
1
+ 'use strict';
2
+
3
+ const ctmSessionContext = require('./ctm-session-context');
4
+
5
+ const DEFAULT_TIMEOUT_MS = 700;
6
+ const DEFAULT_COOLDOWN_MS = 15000;
7
+
8
+ let apiFailureUntil = 0;
9
+ let lastApiFailure = null;
10
+
11
+ function resolveApiBaseUrl(env = process.env) {
12
+ const explicit = env.CTM_SESSION_MEMORY_API_BASE_URL || env.CTM_API_BASE_URL || env.CTM_BASE_URL;
13
+ if (explicit) return explicit.replace(/\/+$/, '');
14
+ if (env.WALLE_CTM_API === '1' && (env.CTM_PORT || env.DEV_CTM_PORT)) {
15
+ return `http://127.0.0.1:${env.CTM_PORT || env.DEV_CTM_PORT}`;
16
+ }
17
+ return '';
18
+ }
19
+
20
+ function apiDisabled(env = process.env) {
21
+ return env.WALLE_CTM_API_DISABLED === '1' || env.CTM_SESSION_MEMORY_API === '0';
22
+ }
23
+
24
+ async function getHealth(options = {}) {
25
+ return apiFirst({
26
+ path: '/api/ctm/session-memory/health',
27
+ fallback: () => ctmSessionContext.getCtmDbHealth(directOptions(options)),
28
+ options,
29
+ });
30
+ }
31
+
32
+ async function searchSessions(args = {}, options = {}) {
33
+ const params = new URLSearchParams();
34
+ if (args.query !== undefined) params.set('q', String(args.query || ''));
35
+ if (args.limit !== undefined) params.set('limit', String(args.limit));
36
+ return apiFirst({
37
+ path: `/api/ctm/session-memory/search?${params.toString()}`,
38
+ fallback: () => ctmSessionContext.searchCtmSessions({ ...args, ...directOptions(options) }),
39
+ options: { ...options, preferApi: args.prefer_api !== false && options.preferApi !== false },
40
+ });
41
+ }
42
+
43
+ async function getSessionContext(args = {}, options = {}) {
44
+ const params = new URLSearchParams();
45
+ for (const id of normalizeIds(args.session_ids || args.ids)) params.append('session_id', id);
46
+ if (args.session_id || args.source_id) params.append('session_id', args.session_id || args.source_id);
47
+ for (const [key, value] of Object.entries({
48
+ limit: args.limit,
49
+ cursor: args.cursor,
50
+ format: args.format,
51
+ })) {
52
+ if (value !== undefined && value !== null) params.set(key, String(value));
53
+ }
54
+ if (args.include_raw) params.set('include_raw', '1');
55
+ if (args.dedupe === false) params.set('no_dedupe', '1');
56
+
57
+ return apiFirst({
58
+ path: `/api/ctm/session-memory/context?${params.toString()}`,
59
+ fallback: () => ctmSessionContext.getCtmSessionContext({ ...args, ...directOptions(options) }),
60
+ options: { ...options, preferApi: args.prefer_api !== false && options.preferApi !== false },
61
+ });
62
+ }
63
+
64
+ async function buildContextPack(args = {}, options = {}) {
65
+ return apiFirst({
66
+ path: '/api/ctm/session-memory/context-pack',
67
+ method: 'POST',
68
+ body: {
69
+ task: args.task || '',
70
+ query: args.query || '',
71
+ session_ids: args.session_ids || args.ids,
72
+ limit: args.limit,
73
+ token_budget: args.token_budget,
74
+ include_raw: Boolean(args.include_raw),
75
+ mode: args.mode || 'auto',
76
+ },
77
+ fallback: () => ctmSessionContext.buildContextPack({ ...args, ...directOptions(options) }),
78
+ options: { ...options, preferApi: args.prefer_api !== false && options.preferApi !== false },
79
+ });
80
+ }
81
+
82
+ async function backfillMessageIndex(args = {}, options = {}) {
83
+ const dryRun = Boolean(args.dry_run);
84
+ return apiFirst({
85
+ path: '/api/ctm/session-memory/message-index/backfill',
86
+ method: 'POST',
87
+ body: {
88
+ limit: args.limit,
89
+ chunk_size: args.chunk_size || args.chunkSize,
90
+ dry_run: dryRun,
91
+ },
92
+ fallback: () => {
93
+ if (dryRun) {
94
+ return ctmSessionContext.backfillCtmSessionMessages({
95
+ ...directOptions(options),
96
+ limit: args.limit,
97
+ dry_run: true,
98
+ });
99
+ }
100
+ return {
101
+ ok: false,
102
+ source: 'ctm-api',
103
+ authority: 'ctm',
104
+ reason: 'ctm_api_required_for_writes',
105
+ dry_run: false,
106
+ };
107
+ },
108
+ options: { ...options, preferApi: args.prefer_api !== false && options.preferApi !== false },
109
+ });
110
+ }
111
+
112
+ async function apiFirst({ path, method = 'GET', body, fallback, options = {} }) {
113
+ const env = options.env || process.env;
114
+ const preferApi = options.preferApi !== false;
115
+ const fallbackResult = () => annotateFallback(fallback(), {
116
+ attempted: false,
117
+ skipped: true,
118
+ reason: apiDisabled(env) ? 'api_disabled' : 'api_base_url_missing',
119
+ });
120
+
121
+ if (!preferApi || apiDisabled(env)) return fallbackResult();
122
+
123
+ const baseUrl = resolveApiBaseUrl(env);
124
+ if (!baseUrl) return fallbackResult();
125
+
126
+ const now = Date.now();
127
+ const cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;
128
+ if (cooldownMs > 0 && apiFailureUntil > now) {
129
+ return annotateFallback(fallback(), {
130
+ attempted: false,
131
+ skipped: true,
132
+ reason: 'api_cooldown',
133
+ last_error: lastApiFailure,
134
+ });
135
+ }
136
+
137
+ try {
138
+ const result = await requestJson(`${baseUrl}${path}`, {
139
+ method,
140
+ body,
141
+ timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
142
+ token: env.CTM_TOKEN || env.WALLE_CTM_TOKEN || env.CTM_API_TOKEN,
143
+ });
144
+ apiFailureUntil = 0;
145
+ lastApiFailure = null;
146
+ return {
147
+ ...result,
148
+ api_transport: {
149
+ attempted: true,
150
+ ok: true,
151
+ base_url: baseUrl,
152
+ },
153
+ };
154
+ } catch (err) {
155
+ lastApiFailure = err.message;
156
+ apiFailureUntil = Date.now() + cooldownMs;
157
+ return annotateFallback(fallback(), {
158
+ attempted: true,
159
+ ok: false,
160
+ base_url: baseUrl,
161
+ reason: 'api_request_failed',
162
+ error: err.message,
163
+ });
164
+ }
165
+ }
166
+
167
+ async function requestJson(url, { method, body, timeoutMs, token }) {
168
+ const controller = new AbortController();
169
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
170
+ try {
171
+ const headers = { Accept: 'application/json' };
172
+ let payload;
173
+ if (body !== undefined) {
174
+ headers['Content-Type'] = 'application/json';
175
+ payload = JSON.stringify(body);
176
+ }
177
+ if (token) headers.Authorization = `Bearer ${token}`;
178
+
179
+ const response = await fetch(url, {
180
+ method,
181
+ headers,
182
+ body: payload,
183
+ signal: controller.signal,
184
+ });
185
+ const text = await response.text();
186
+ const json = text ? JSON.parse(text) : {};
187
+ if (!response.ok) {
188
+ throw new Error(`ctm_api_http_${response.status}:${json?.reason || json?.error || response.statusText}`);
189
+ }
190
+ return json;
191
+ } finally {
192
+ clearTimeout(timer);
193
+ }
194
+ }
195
+
196
+ function annotateFallback(result, apiTransport) {
197
+ return {
198
+ ...(result || {}),
199
+ api_transport: apiTransport,
200
+ };
201
+ }
202
+
203
+ function directOptions(options = {}) {
204
+ const out = {};
205
+ if (options.db) out.db = options.db;
206
+ if (options.dbPath) out.dbPath = options.dbPath;
207
+ if (options.env) out.env = options.env;
208
+ return out;
209
+ }
210
+
211
+ function normalizeIds(value) {
212
+ if (!value) return [];
213
+ const raw = Array.isArray(value) ? value : String(value).split(',');
214
+ return raw.map((item) => String(item || '').trim()).filter(Boolean);
215
+ }
216
+
217
+ function resetApiState() {
218
+ apiFailureUntil = 0;
219
+ lastApiFailure = null;
220
+ }
221
+
222
+ module.exports = {
223
+ resolveApiBaseUrl,
224
+ getHealth,
225
+ searchSessions,
226
+ getSessionContext,
227
+ buildContextPack,
228
+ backfillMessageIndex,
229
+ resetApiState,
230
+ };