create-walle 0.9.30 → 0.9.32
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/package.json +1 -1
- package/template/claude-task-manager/api-prompts.js +410 -5
- package/template/claude-task-manager/api-reviews.js +251 -3
- package/template/claude-task-manager/approval-agent.js +322 -24
- package/template/claude-task-manager/db.js +77 -13
- package/template/claude-task-manager/docs/codex-app-server-approvals.md +35 -1
- package/template/claude-task-manager/docs/postgres-concurrency-dgx-spark.html +407 -0
- package/template/claude-task-manager/docs/prompt-manager-redesign-proposal.html +667 -0
- package/template/claude-task-manager/docs/resume-ux-redesign.html +493 -0
- package/template/claude-task-manager/docs/review-redesign-proposal.html +892 -0
- package/template/claude-task-manager/docs/unified-auto-approver-proposal.html +520 -0
- package/template/claude-task-manager/git-utils.js +164 -26
- package/template/claude-task-manager/lib/agent-capabilities.js +26 -5
- package/template/claude-task-manager/lib/agent-cli-cache.js +1 -1
- package/template/claude-task-manager/lib/agent-presets.js +12 -0
- package/template/claude-task-manager/lib/agent-version-service.js +650 -0
- package/template/claude-task-manager/lib/approval-drift.js +57 -0
- package/template/claude-task-manager/lib/approval-hook.js +13 -0
- package/template/claude-task-manager/lib/auth-rules.js +6 -0
- package/template/claude-task-manager/lib/broadcast-payload-memo.js +109 -0
- package/template/claude-task-manager/lib/coding-agent-models.js +89 -8
- package/template/claude-task-manager/lib/db-owner-cooperative-scheduler.js +10 -1
- package/template/claude-task-manager/lib/document-review.js +75 -1
- package/template/claude-task-manager/lib/escalation-review.js +33 -3
- package/template/claude-task-manager/lib/headless-term-service.js +54 -9
- package/template/claude-task-manager/lib/mcp-risk.js +128 -0
- package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +51 -2
- package/template/claude-task-manager/lib/native-agent-model-args.js +149 -0
- package/template/claude-task-manager/lib/opencode-conversation-store.js +269 -0
- package/template/claude-task-manager/lib/permission-match.js +77 -5
- package/template/claude-task-manager/lib/read-pool-client.js +15 -6
- package/template/claude-task-manager/lib/restore-backoff.js +82 -0
- package/template/claude-task-manager/lib/runtime-registry.js +1 -0
- package/template/claude-task-manager/lib/scheduled-wake.js +42 -0
- package/template/claude-task-manager/lib/session-capture.js +33 -6
- package/template/claude-task-manager/lib/session-history.js +60 -3
- package/template/claude-task-manager/lib/session-jobs.js +19 -0
- package/template/claude-task-manager/lib/session-restore.js +5 -4
- package/template/claude-task-manager/lib/session-standup.js +2 -0
- package/template/claude-task-manager/lib/session-stream.js +9 -0
- package/template/claude-task-manager/lib/state-sync/cell-diff.js +31 -4
- package/template/claude-task-manager/lib/state-sync/restore-frame-hold.js +39 -0
- package/template/claude-task-manager/lib/tui-input-modes.js +40 -0
- package/template/claude-task-manager/lib/walle-ctm-history.js +103 -36
- package/template/claude-task-manager/lib/walle-session-model-catalog.js +7 -1
- package/template/claude-task-manager/lib/walle-token-chip.js +65 -0
- package/template/claude-task-manager/package.json +1 -1
- package/template/claude-task-manager/providers/claude-code.js +20 -1
- package/template/claude-task-manager/providers/codex-mcp-extract.js +33 -0
- package/template/claude-task-manager/providers/codex-mcp.js +23 -20
- package/template/claude-task-manager/providers/codex.js +65 -1
- package/template/claude-task-manager/public/css/prompts.css +345 -0
- package/template/claude-task-manager/public/css/reviews.css +248 -40
- package/template/claude-task-manager/public/css/walle-session.css +90 -26
- package/template/claude-task-manager/public/index.html +2031 -428
- package/template/claude-task-manager/public/js/document-review-links.js +255 -13
- package/template/claude-task-manager/public/js/file-context-menu.js +185 -0
- package/template/claude-task-manager/public/js/message-renderer.js +46 -1
- package/template/claude-task-manager/public/js/mobile-review-core.js +54 -0
- package/template/claude-task-manager/public/js/prompt-diff.js +55 -0
- package/template/claude-task-manager/public/js/prompt-editor-chrome.js +108 -0
- package/template/claude-task-manager/public/js/prompt-editor-modes.js +87 -0
- package/template/claude-task-manager/public/js/prompt-organize.js +179 -0
- package/template/claude-task-manager/public/js/prompt-reuse.js +77 -0
- package/template/claude-task-manager/public/js/prompts.js +683 -215
- package/template/claude-task-manager/public/js/resume-state.js +186 -0
- package/template/claude-task-manager/public/js/reviews.js +402 -121
- package/template/claude-task-manager/public/js/screenshot-router.js +91 -0
- package/template/claude-task-manager/public/js/session-search-utils.js +81 -0
- package/template/claude-task-manager/public/js/state-sync-client.js +134 -17
- package/template/claude-task-manager/public/js/stream-view.js +93 -20
- package/template/claude-task-manager/public/js/walle-session.js +183 -32
- package/template/claude-task-manager/public/js/walle.js +21 -9
- package/template/claude-task-manager/public/m/app.css +117 -0
- package/template/claude-task-manager/public/m/app.js +309 -3
- package/template/claude-task-manager/public/m/index.html +56 -1
- package/template/claude-task-manager/server.js +724 -305
- package/template/claude-task-manager/workers/db-owner-worker.js +8 -0
- package/template/claude-task-manager/workers/read-pool-worker.js +4 -0
- package/template/claude-task-manager/workers/state-detectors/claude-code.js +10 -1
- package/template/docs/proposals/2026-06-23-local-model-right-path.html +340 -0
- package/template/docs/proposals/2026-06-24-qlora-done-right.md +255 -0
- package/template/package.json +1 -1
- package/template/wall-e/api-walle.js +21 -3
- package/template/wall-e/bin/train-gemma-e4b-tooluse.js +27 -4
- package/template/wall-e/brain.js +50 -5
- package/template/wall-e/chat/force-compact.js +73 -0
- package/template/wall-e/chat.js +137 -9
- package/template/wall-e/coding/action-memory-policy.js +120 -1
- package/template/wall-e/coding/compaction-service.js +10 -3
- package/template/wall-e/coding/model-router.js +116 -0
- package/template/wall-e/coding-orchestrator.js +303 -11
- package/template/wall-e/coding-prompts.js +1 -1
- package/template/wall-e/docs/skill-self-heal-design.html +429 -0
- package/template/wall-e/llm/client.js +115 -6
- package/template/wall-e/llm/codex-cli.js +71 -23
- package/template/wall-e/llm/codex-cli.plugin.json +1 -0
- package/template/wall-e/llm/default-fallback.js +71 -11
- package/template/wall-e/llm/mlx-worker.js +0 -0
- package/template/wall-e/llm/mlx.js +46 -12
- package/template/wall-e/llm/provider-error.js +9 -3
- package/template/wall-e/llm/provider-health-state.js +561 -11
- package/template/wall-e/llm/registry.js +6 -0
- package/template/wall-e/llm/routing-policy.js +255 -25
- package/template/wall-e/llm/tool-call-validator.js +156 -0
- package/template/wall-e/skills/skill-dispatch-decision.js +82 -2
- package/template/wall-e/skills/skill-planner.js +72 -5
- package/template/wall-e/tools/command-registry.js +34 -0
- package/template/wall-e/training/gemma-e4b-qlora.js +197 -1
- package/template/wall-e/training/mlx_lora_launch.py +196 -0
- package/template/wall-e/training/training-coexistence.sh +87 -0
- package/template/wall-e/training/training-mem-guard.sh +76 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* resume-state.js — the single source of truth for "what should the user see
|
|
5
|
+
* while a session is resuming?"
|
|
6
|
+
*
|
|
7
|
+
* Redesign goal (see docs/resume-ux-redesign.html): replace the scattered web of
|
|
8
|
+
* 4 client flags (+ s.meta mirrors), a server flag, a client timestamp, and a
|
|
9
|
+
* cluster of Codex-only heuristics spread across ~10 functions and two overlays
|
|
10
|
+
* with ONE pure reducer. Every consumer — the loading overlay, the skeleton
|
|
11
|
+
* preview, the sidebar tag, the input-enable gate — reads from this.
|
|
12
|
+
*
|
|
13
|
+
* Two design rules encode the operator's guidance:
|
|
14
|
+
* - "Content-wait, not spinner-wait." → when the prior conversation is already
|
|
15
|
+
* composed (it usually is), surface it as a dimmed read-only skeleton instead
|
|
16
|
+
* of a spinner over a blank buffer.
|
|
17
|
+
* - "Eliminate the race, don't guard it." → the reducer is the SOLE owner of
|
|
18
|
+
* dismissal. A blank snapshot simply fails to advance to `live`, so it can
|
|
19
|
+
* never wipe the skeleton. The blank-page race becomes structurally
|
|
20
|
+
* impossible rather than defended in three fragile places.
|
|
21
|
+
*
|
|
22
|
+
* Isomorphic: same dual node/browser export as session-phase.js, so the server
|
|
23
|
+
* and the client derive resume state from identical code, and node can unit-test it.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
(function initResumeState(root, factory) {
|
|
27
|
+
if (typeof module === 'object' && module.exports) {
|
|
28
|
+
module.exports = factory();
|
|
29
|
+
} else {
|
|
30
|
+
root.ResumeState = factory();
|
|
31
|
+
}
|
|
32
|
+
})(typeof globalThis !== 'undefined' ? globalThis : this, function buildResumeState() {
|
|
33
|
+
// ---- states ------------------------------------------------------------
|
|
34
|
+
const STATES = {
|
|
35
|
+
IDLE: 'idle', // no resume underway
|
|
36
|
+
SPAWNING: 'spawning', // PTY requested, no history yet (≤100ms window)
|
|
37
|
+
PREVIEW: 'preview', // prior conversation available → skeleton
|
|
38
|
+
LIVE_PENDING: 'live-pending', // live frames arriving, not yet settled
|
|
39
|
+
LIVE: 'live', // first settled meaningful paint → done
|
|
40
|
+
SLOW: 'slow', // genuine large silent-load (server still loading)
|
|
41
|
+
ERROR: 'error', // preflight/spawn failed
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// ---- timing ------------------------------------------------------------
|
|
45
|
+
// Only enter the `slow` state once a server-side load has genuinely run long,
|
|
46
|
+
// so fast resumes never flash the "this can take a few minutes" copy. This is
|
|
47
|
+
// the lone resume timing constant the UI needs; the old 600ms/700ms×8/250–2500ms
|
|
48
|
+
// chain is an implementation detail the skeleton now hides.
|
|
49
|
+
const SLOW_ELAPSED_MS = 3000;
|
|
50
|
+
|
|
51
|
+
// ---- copy (one home for every resume string) ---------------------------
|
|
52
|
+
const STRINGS = {
|
|
53
|
+
spawning: 'Resuming…',
|
|
54
|
+
resuming: 'Resuming',
|
|
55
|
+
error: "Couldn't resume this session",
|
|
56
|
+
footerReconnecting: 'reconnecting live session…',
|
|
57
|
+
skeletonHeader: 'Resuming where you left off',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// ---- helpers -----------------------------------------------------------
|
|
61
|
+
function formatBytes(bytes) {
|
|
62
|
+
const n = Number(bytes) || 0;
|
|
63
|
+
if (n <= 0) return '';
|
|
64
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
65
|
+
let i = 0;
|
|
66
|
+
let v = n;
|
|
67
|
+
while (v >= 1024 && i < units.length - 1) { v /= 1024; i += 1; }
|
|
68
|
+
const rounded = v >= 100 || i === 0 ? Math.round(v) : Math.round(v * 10) / 10;
|
|
69
|
+
return `${rounded} ${units[i]}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function formatElapsed(ms) {
|
|
73
|
+
const total = Math.max(0, Math.floor((Number(ms) || 0) / 1000));
|
|
74
|
+
const m = Math.floor(total / 60);
|
|
75
|
+
const s = total % 60;
|
|
76
|
+
return `${m}:${String(s).padStart(2, '0')}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function slowProgressText(signals) {
|
|
80
|
+
const size = formatBytes(signals.fileSize);
|
|
81
|
+
const sizePart = size ? `${size} ` : '';
|
|
82
|
+
const elapsed = signals.elapsedMs ? ` (elapsed ${formatElapsed(signals.elapsedMs)})` : '';
|
|
83
|
+
return `Loading ${sizePart}session into memory — this can take a few minutes.${elapsed}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Build the dimmed skeleton lines from the prior user prompts (s.promptPreviews — already
|
|
87
|
+
// maintained client-side, so the preview is decoupled from the live xterm buffer: no seeding,
|
|
88
|
+
// no scatter/ghost/blank-on-seed risk). Newest-last, capped, whitespace-collapsed, truncated.
|
|
89
|
+
const PREVIEW_MARKER = '› ';
|
|
90
|
+
function previewLines(prompts, opts) {
|
|
91
|
+
if (!Array.isArray(prompts) || !prompts.length) return [];
|
|
92
|
+
const max = Math.max(1, (opts && opts.max) || 6);
|
|
93
|
+
const width = Math.max(8, (opts && opts.width) || 64);
|
|
94
|
+
return prompts
|
|
95
|
+
.filter((p) => p != null && String(p).trim())
|
|
96
|
+
.slice(-max)
|
|
97
|
+
.map((p) => {
|
|
98
|
+
const text = String(p).replace(/\s+/g, ' ').trim();
|
|
99
|
+
const clipped = text.length > width ? text.slice(0, width - 1).trimEnd() + '…' : text;
|
|
100
|
+
return PREVIEW_MARKER + clipped;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function headerFor(state, title) {
|
|
105
|
+
const named = title ? `${STRINGS.resuming}: ${title}` : STRINGS.resuming;
|
|
106
|
+
switch (state) {
|
|
107
|
+
case STATES.SPAWNING: return title ? named : STRINGS.spawning;
|
|
108
|
+
case STATES.PREVIEW:
|
|
109
|
+
case STATES.LIVE_PENDING:
|
|
110
|
+
case STATES.SLOW: return named;
|
|
111
|
+
case STATES.ERROR: return STRINGS.error;
|
|
112
|
+
default: return ''; // idle / live → no resume header
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ------------------------------------------------------------------------
|
|
117
|
+
// deriveResumeState — the ONLY place the resume state is decided.
|
|
118
|
+
//
|
|
119
|
+
// Signals (all optional):
|
|
120
|
+
// resuming bool a resume is underway (set at handleCreate, cleared on live)
|
|
121
|
+
// agentType string 'codex' | 'claude' | …
|
|
122
|
+
// hasHistorySnapshot bool the prior conversation has been composed/cached
|
|
123
|
+
// serverResumeLoading bool the server reports it is still loading the session
|
|
124
|
+
// firstLiveByteAt number ts of the first live PTY frame (truthy ⇒ painting)
|
|
125
|
+
// meaningfulContent bool a settled, non-blank live paint has landed
|
|
126
|
+
// fileSize number bytes of the session being loaded (for slow copy)
|
|
127
|
+
// elapsedMs number ms since the resume began
|
|
128
|
+
// preflightError string non-empty ⇒ resume cannot proceed
|
|
129
|
+
// title string session title for the skeleton header
|
|
130
|
+
// ------------------------------------------------------------------------
|
|
131
|
+
function deriveResumeState(signals = {}) {
|
|
132
|
+
const resuming = !!signals.resuming;
|
|
133
|
+
const hasHistory = !!signals.hasHistorySnapshot;
|
|
134
|
+
const live = !!signals.firstLiveByteAt;
|
|
135
|
+
const elapsedMs = Number(signals.elapsedMs) || 0;
|
|
136
|
+
const isSlow = !!signals.serverResumeLoading && elapsedMs >= SLOW_ELAPSED_MS;
|
|
137
|
+
|
|
138
|
+
let state;
|
|
139
|
+
if (signals.preflightError) {
|
|
140
|
+
state = STATES.ERROR;
|
|
141
|
+
} else if (signals.meaningfulContent) {
|
|
142
|
+
state = STATES.LIVE; // settled → resume complete
|
|
143
|
+
} else if (!resuming) {
|
|
144
|
+
state = STATES.IDLE;
|
|
145
|
+
} else if (live) {
|
|
146
|
+
state = STATES.LIVE_PENDING; // painting beats "silently loading"
|
|
147
|
+
} else if (isSlow) {
|
|
148
|
+
state = STATES.SLOW;
|
|
149
|
+
} else if (hasHistory) {
|
|
150
|
+
state = STATES.PREVIEW;
|
|
151
|
+
} else {
|
|
152
|
+
state = STATES.SPAWNING;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const inResumeFlow = state === STATES.SPAWNING || state === STATES.PREVIEW
|
|
156
|
+
|| state === STATES.LIVE_PENDING || state === STATES.SLOW;
|
|
157
|
+
const showSkeleton = hasHistory
|
|
158
|
+
&& (state === STATES.PREVIEW || state === STATES.LIVE_PENDING || state === STATES.SLOW);
|
|
159
|
+
const showSlowProgress = state === STATES.SLOW;
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
state,
|
|
163
|
+
showSkeleton,
|
|
164
|
+
showSlowProgress,
|
|
165
|
+
headerText: headerFor(state, signals.title),
|
|
166
|
+
footerText: inResumeFlow ? STRINGS.footerReconnecting : '',
|
|
167
|
+
progressText: showSlowProgress ? slowProgressText(signals) : '',
|
|
168
|
+
// dismissal is owned solely here: only the non-terminal resume states block
|
|
169
|
+
// the skeleton from being torn down. A blank snapshot can never reach `live`,
|
|
170
|
+
// so it can never unblock — the blank-page race is impossible by construction.
|
|
171
|
+
dismissBlocked: inResumeFlow,
|
|
172
|
+
inputEnabled: state === STATES.IDLE || state === STATES.LIVE,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
STATES,
|
|
178
|
+
STRINGS,
|
|
179
|
+
SLOW_ELAPSED_MS,
|
|
180
|
+
formatBytes,
|
|
181
|
+
formatElapsed,
|
|
182
|
+
slowProgressText,
|
|
183
|
+
previewLines,
|
|
184
|
+
deriveResumeState,
|
|
185
|
+
};
|
|
186
|
+
});
|