create-claude-workspace 2.3.33 → 2.3.34
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/dist/scheduler/index.mjs +2 -1
- package/dist/scheduler/ui/tui.mjs +61 -35
- package/package.json +1 -1
package/dist/scheduler/index.mjs
CHANGED
|
@@ -434,13 +434,14 @@ export async function runScheduler(opts) {
|
|
|
434
434
|
if (!workDone) {
|
|
435
435
|
if (state.taskMode === 'interactive') {
|
|
436
436
|
// Interactive mode: wait for user input (no external polling)
|
|
437
|
-
|
|
437
|
+
tui.setIdle(true);
|
|
438
438
|
while (!stopping) {
|
|
439
439
|
const pending = readInbox(opts.projectDir);
|
|
440
440
|
if (pending.length > 0 || discoveredIssueStore.peek().length > 0)
|
|
441
441
|
break;
|
|
442
442
|
await sleep(500, stoppingRef);
|
|
443
443
|
}
|
|
444
|
+
tui.setIdle(false);
|
|
444
445
|
}
|
|
445
446
|
else {
|
|
446
447
|
// No work → idle polling (platform/local)
|
|
@@ -52,7 +52,7 @@ export class TUI {
|
|
|
52
52
|
this.state = {
|
|
53
53
|
iteration: 0, maxIter: 0, loopStart: Date.now(), iterStart: 0,
|
|
54
54
|
tools: 0, tokensIn: 0, tokensOut: 0, agents: [], taskName: '',
|
|
55
|
-
tasksDone: 0, tasksTotal: 0, paused: false, inputBuf: '',
|
|
55
|
+
tasksDone: 0, tasksTotal: 0, paused: false, idle: false, inputBuf: '',
|
|
56
56
|
pendingInputs: [],
|
|
57
57
|
};
|
|
58
58
|
if (this.interactive) {
|
|
@@ -157,13 +157,13 @@ export class TUI {
|
|
|
157
157
|
isPaused() { return this.state.paused; }
|
|
158
158
|
addPendingInput(text) {
|
|
159
159
|
this.state.pendingInputs.push(text);
|
|
160
|
-
this.log(` ${ANSI_COLORS.gray}${ts()}${RESET} ${ANSI_COLORS.magenta}
|
|
160
|
+
this.log(` ${ANSI_COLORS.gray}${ts()}${RESET} ${ANSI_COLORS.magenta}${BOLD}▶ USER${RESET} ${ANSI_COLORS.white}${text}${RESET} ${ANSI_COLORS.gray}[queued #${this.state.pendingInputs.length}]${RESET}`, ` ${ts()} ▶ USER ${text} [queued #${this.state.pendingInputs.length}]`);
|
|
161
161
|
this.renderStatusBar();
|
|
162
162
|
}
|
|
163
163
|
consumePendingInput() {
|
|
164
164
|
const item = this.state.pendingInputs.shift();
|
|
165
165
|
if (item) {
|
|
166
|
-
this.log(` ${ANSI_COLORS.gray}${ts()}${RESET} ${ANSI_COLORS.green}
|
|
166
|
+
this.log(` ${ANSI_COLORS.gray}${ts()}${RESET} ${ANSI_COLORS.green}${BOLD}▶ START${RESET} ${ANSI_COLORS.white}${item}${RESET}`, ` ${ts()} ▶ START ${item}`);
|
|
167
167
|
this.renderStatusBar();
|
|
168
168
|
}
|
|
169
169
|
return item;
|
|
@@ -194,24 +194,36 @@ export class TUI {
|
|
|
194
194
|
lines.push(` ${ANSI_COLORS.gray}› type to send input${RESET}`);
|
|
195
195
|
}
|
|
196
196
|
// Line 3: Status bar (stats)
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
197
|
+
if (s.idle) {
|
|
198
|
+
// Idle: static bar, no running timers
|
|
199
|
+
let stats = `\x1b[7m ${ANSI_COLORS.gray}IDLE${RESET}\x1b[7m — waiting for input`;
|
|
200
|
+
if (s.pendingInputs.length > 0)
|
|
201
|
+
stats += ` | ${ANSI_COLORS.magenta}${s.pendingInputs.length} queued${RESET}\x1b[7m`;
|
|
202
|
+
if (s.paused)
|
|
203
|
+
stats += ` | ${ANSI_COLORS.yellow}⏸ PAUSED${RESET}\x1b[7m`;
|
|
204
|
+
stats += ` ${RESET}`;
|
|
205
|
+
lines.push(stats);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
const elapsed = fmtDur(Date.now() - s.loopStart);
|
|
209
|
+
const iterTime = s.iterStart ? fmtDur(Date.now() - s.iterStart) : '—';
|
|
210
|
+
const pct = s.maxIter > 0 ? Math.round((s.iteration / s.maxIter) * 100) : 0;
|
|
211
|
+
const filled = Math.round((pct / 100) * 8);
|
|
212
|
+
const bar = `${ANSI_COLORS.green}${'\u2588'.repeat(filled)}${ANSI_COLORS.gray}${'\u2591'.repeat(8 - filled)}${RESET}`;
|
|
213
|
+
const tok = fmtTok(s.tokensIn + s.tokensOut);
|
|
214
|
+
const cur = s.agents.length > 0 ? s.agents[s.agents.length - 1] : '';
|
|
215
|
+
let stats = `\x1b[7m ${elapsed} | Iter ${s.iteration}/${s.maxIter} \x1b[27m ${bar} \x1b[7m ${iterTime} | ${ANSI_COLORS.cyan}${s.tools}${RESET}\x1b[7m tools | ${ANSI_COLORS.yellow}${tok}${RESET}\x1b[7m tok`;
|
|
216
|
+
if (cur) {
|
|
217
|
+
const col = ANSI_COLORS[agentColor(cur)] || '';
|
|
218
|
+
stats += ` | ${col}${BOLD}${cur}${RESET}\x1b[7m`;
|
|
219
|
+
}
|
|
220
|
+
if (s.taskName)
|
|
221
|
+
stats += ` | ${ANSI_COLORS.cyan}${statusTrunc(s.taskName, 30)}${RESET}\x1b[7m`;
|
|
222
|
+
if (s.paused)
|
|
223
|
+
stats += ` | ${ANSI_COLORS.yellow}⏸ PAUSED${RESET}\x1b[7m`;
|
|
224
|
+
stats += ` ${RESET}`;
|
|
225
|
+
lines.push(stats);
|
|
208
226
|
}
|
|
209
|
-
if (s.taskName)
|
|
210
|
-
stats += ` | ${ANSI_COLORS.cyan}${statusTrunc(s.taskName, 30)}${RESET}\x1b[7m`;
|
|
211
|
-
if (s.paused)
|
|
212
|
-
stats += ` | ${ANSI_COLORS.yellow}⏸ PAUSED${RESET}\x1b[7m`;
|
|
213
|
-
stats += ` ${RESET}`;
|
|
214
|
-
lines.push(stats);
|
|
215
227
|
return lines;
|
|
216
228
|
}
|
|
217
229
|
/** Plain-text version for testing / non-ANSI contexts. */
|
|
@@ -224,21 +236,31 @@ export class TUI {
|
|
|
224
236
|
lines.push(` [${s.pendingInputs.length} queued] ${items}${more}`);
|
|
225
237
|
}
|
|
226
238
|
lines.push(s.inputBuf ? ` › ${s.inputBuf}` : ' › type to send input');
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
if (s.idle) {
|
|
240
|
+
let stats = ' IDLE — waiting for input';
|
|
241
|
+
if (s.pendingInputs.length > 0)
|
|
242
|
+
stats += ` | ${s.pendingInputs.length} queued`;
|
|
243
|
+
if (s.paused)
|
|
244
|
+
stats += ' | PAUSED';
|
|
245
|
+
lines.push(stats);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const elapsed = fmtDur(Date.now() - s.loopStart);
|
|
249
|
+
const iterTime = s.iterStart ? fmtDur(Date.now() - s.iterStart) : '—';
|
|
250
|
+
const pct = s.maxIter > 0 ? Math.round((s.iteration / s.maxIter) * 100) : 0;
|
|
251
|
+
const filled = Math.round((pct / 100) * 8);
|
|
252
|
+
const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(8 - filled);
|
|
253
|
+
const tok = fmtTok(s.tokensIn + s.tokensOut);
|
|
254
|
+
const cur = s.agents.length > 0 ? s.agents[s.agents.length - 1] : '';
|
|
255
|
+
let stats = ` ${elapsed} | Iter ${s.iteration}/${s.maxIter} ${bar} | ${iterTime} | ${s.tools} tools | ${tok} tok`;
|
|
256
|
+
if (cur)
|
|
257
|
+
stats += ` | ${cur}`;
|
|
258
|
+
if (s.taskName)
|
|
259
|
+
stats += ` | ${statusTrunc(s.taskName, 30)}`;
|
|
260
|
+
if (s.paused)
|
|
261
|
+
stats += ' | PAUSED';
|
|
262
|
+
lines.push(stats);
|
|
263
|
+
}
|
|
242
264
|
return lines;
|
|
243
265
|
}
|
|
244
266
|
clearStatusArea() {
|
|
@@ -321,6 +343,10 @@ export class TUI {
|
|
|
321
343
|
this.log(` ${BOLD}━━━ Iteration ${i}/${max} ${pct}% │ ${elapsed} elapsed ━━━${RESET}`);
|
|
322
344
|
this.log('');
|
|
323
345
|
}
|
|
346
|
+
setIdle(idle) {
|
|
347
|
+
this.state.idle = idle;
|
|
348
|
+
this.renderStatusBar();
|
|
349
|
+
}
|
|
324
350
|
setTask(name, done, total) {
|
|
325
351
|
this.state.taskName = name;
|
|
326
352
|
this.state.tasksDone = done;
|