claude-overnight 1.25.27 → 1.25.29
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/_version.d.ts +1 -1
- package/dist/_version.js +1 -1
- package/dist/index.js +14 -7
- package/dist/interactive-panel.d.ts +2 -0
- package/dist/interactive-panel.js +6 -0
- package/dist/render.d.ts +4 -0
- package/dist/render.js +36 -14
- package/dist/steering.js +3 -3
- package/dist/ui.js +7 -2
- package/package.json +1 -1
- package/plugins/claude-overnight/.claude-plugin/plugin.json +1 -1
package/dist/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.25.
|
|
1
|
+
export declare const VERSION = "1.25.29";
|
package/dist/_version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by build — do not edit manually.
|
|
2
|
-
export const VERSION = "1.25.
|
|
2
|
+
export const VERSION = "1.25.29";
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { setPlannerEnvResolver } from "./planner-query.js";
|
|
|
12
12
|
import { setTranscriptRunDir } from "./transcripts.js";
|
|
13
13
|
import { pickModel, loadProviders, preflightProvider, buildEnvResolver, healthCheckCursorProxy, PROXY_DEFAULT_URL, isCursorProxyProvider, readCursorProxyLogTail, ensureCursorProxyRunning, bundledComposerProxyShellCommand, warnMacCursorAgentShellPatchIfNeeded, hasCursorAgentToken, } from "./providers.js";
|
|
14
14
|
import { RunDisplay } from "./ui.js";
|
|
15
|
-
import { renderSummary } from "./render.js";
|
|
15
|
+
import { renderSummary, wrap } from "./render.js";
|
|
16
16
|
import { executeRun } from "./run.js";
|
|
17
17
|
import { parseCliFlags, isAuthError, fetchModels, ask, select, selectKey, loadTaskFile, validateConcurrency, isGitRepo, validateGitRepo, showPlan, BRAILLE, makeProgressLog, } from "./cli.js";
|
|
18
18
|
import { loadRunState, findIncompleteRuns, findOrphanedDesigns, backfillOrphanedPlans, formatTimeAgo, showRunHistory, readPreviousRunKnowledge, createRunDir, updateLatestSymlink, readMdDir, saveRunState, autoMergeBranches, } from "./state.js";
|
|
@@ -366,11 +366,13 @@ async function main() {
|
|
|
366
366
|
const ago = formatTimeAgo(prev.startedAt);
|
|
367
367
|
let lastStatus = "";
|
|
368
368
|
try {
|
|
369
|
-
lastStatus = readFileSync(join(run.dir, "status.md"), "utf-8").trim().slice(0,
|
|
369
|
+
lastStatus = readFileSync(join(run.dir, "status.md"), "utf-8").trim().slice(0, 200);
|
|
370
370
|
}
|
|
371
371
|
catch { }
|
|
372
372
|
const planTaskCount = prev.phase === "planning" ? countTasksInFile(join(run.dir, "tasks.json")) : 0;
|
|
373
373
|
console.log(chalk.yellow(`\n ⚠ Unfinished run`) + chalk.dim(` · ${ago}`));
|
|
374
|
+
const termW = Math.max(process.stdout.columns ?? 80, 60);
|
|
375
|
+
const statusMaxW = Math.min(termW - 8, 80);
|
|
374
376
|
const boxLines = prev.phase === "planning" ? [
|
|
375
377
|
`${obj}${obj.length >= 50 ? "…" : ""}`,
|
|
376
378
|
`Plan ready · ${planTaskCount} tasks · budget ${prev.budget} · ${prev.concurrency}× concurrent`,
|
|
@@ -380,8 +382,10 @@ async function main() {
|
|
|
380
382
|
`${prev.accCompleted}/${prev.budget} sessions · ${Math.max(1, (prev.budget ?? 0) - prev.accCompleted)} remaining · $${prev.accCost.toFixed(2)}`,
|
|
381
383
|
`Wave ${prev.waveNum + 1} · ${prev.phase}`,
|
|
382
384
|
];
|
|
383
|
-
if (lastStatus)
|
|
384
|
-
|
|
385
|
+
if (lastStatus) {
|
|
386
|
+
for (const wl of wrap(lastStatus, statusMaxW))
|
|
387
|
+
boxLines.push(wl);
|
|
388
|
+
}
|
|
385
389
|
if (merged + unmerged + failed > 0)
|
|
386
390
|
boxLines.push(`${merged} merged · ${unmerged} unmerged · ${failed} failed`);
|
|
387
391
|
const boxW = Math.max(...boxLines.map(l => l.length)) + 4;
|
|
@@ -415,7 +419,7 @@ async function main() {
|
|
|
415
419
|
const merged = s.branches.filter(b => b.status === "merged").length;
|
|
416
420
|
let lastStatus = "";
|
|
417
421
|
try {
|
|
418
|
-
lastStatus = readFileSync(join(shown[i].dir, "status.md"), "utf-8").trim().split("\n")[0].slice(0,
|
|
422
|
+
lastStatus = readFileSync(join(shown[i].dir, "status.md"), "utf-8").trim().split("\n")[0].slice(0, 120);
|
|
419
423
|
}
|
|
420
424
|
catch { }
|
|
421
425
|
console.log(chalk.cyan(` ${i + 1}`) + ` ${obj}${obj.length >= 50 ? "…" : ""}`);
|
|
@@ -426,8 +430,11 @@ async function main() {
|
|
|
426
430
|
else {
|
|
427
431
|
console.log(chalk.dim(` ${s.accCompleted}/${s.budget} · $${s.accCost.toFixed(2)} · ${ago} · ${s.phase} at wave ${s.waveNum + 1}${merged ? ` · ${merged} merged` : ""}`));
|
|
428
432
|
}
|
|
429
|
-
if (lastStatus)
|
|
430
|
-
|
|
433
|
+
if (lastStatus) {
|
|
434
|
+
const termW = Math.max(process.stdout.columns ?? 80, 60);
|
|
435
|
+
for (const wl of wrap(lastStatus, termW - 6))
|
|
436
|
+
console.log(chalk.dim(` ${wl}`));
|
|
437
|
+
}
|
|
431
438
|
console.log("");
|
|
432
439
|
}
|
|
433
440
|
const action = await selectKey(` ${chalk.dim(`[1-${shown.length}] resume`)}`, [
|
|
@@ -17,6 +17,8 @@ export declare class InteractivePanel {
|
|
|
17
17
|
preview: string;
|
|
18
18
|
body: string;
|
|
19
19
|
}): void;
|
|
20
|
+
/** Close the panel entirely (set mode to "none"). */
|
|
21
|
+
close(): void;
|
|
20
22
|
collapse(): void;
|
|
21
23
|
toggle(): void;
|
|
22
24
|
scroll(direction: "up" | "down", visibleRows: number): void;
|
|
@@ -35,6 +35,12 @@ export class InteractivePanel {
|
|
|
35
35
|
this._bodyLines = params.body.split("\n").filter(l => l.length > 0);
|
|
36
36
|
this.state.scrollOffset = 0;
|
|
37
37
|
}
|
|
38
|
+
/** Close the panel entirely (set mode to "none"). */
|
|
39
|
+
close() {
|
|
40
|
+
this.state.mode = "none";
|
|
41
|
+
this.state.expanded = false;
|
|
42
|
+
this.state.scrollOffset = 0;
|
|
43
|
+
}
|
|
38
44
|
collapse() {
|
|
39
45
|
this.state.expanded = false;
|
|
40
46
|
this.state.scrollOffset = 0;
|
package/dist/render.d.ts
CHANGED
|
@@ -31,6 +31,10 @@ export declare function renderWaitingIndicator(label: string, startedAt: number
|
|
|
31
31
|
style?: "info" | "warn" | "wait" | "thinking";
|
|
32
32
|
}): string;
|
|
33
33
|
export declare function truncate(s: string, max: number): string;
|
|
34
|
+
/** Word-wrap text into lines of at most `max` chars.
|
|
35
|
+
* Splits on spaces; if a single word exceeds `max` it is hard-broken.
|
|
36
|
+
* Ignores ANSI escape codes for length calculation. */
|
|
37
|
+
export declare function wrap(s: string, max: number): string[];
|
|
34
38
|
export declare function fmtTokens(n: number): string;
|
|
35
39
|
export declare function fmtDur(ms: number): string;
|
|
36
40
|
/** Context-fill percentage and color function for a token count vs safe limit. */
|
package/dist/render.js
CHANGED
|
@@ -41,6 +41,36 @@ export function renderWaitingIndicator(label, startedAt, opts = {}) {
|
|
|
41
41
|
export function truncate(s, max) {
|
|
42
42
|
return s.length <= max ? s : s.slice(0, max - 1) + "\u2026";
|
|
43
43
|
}
|
|
44
|
+
/** Word-wrap text into lines of at most `max` chars.
|
|
45
|
+
* Splits on spaces; if a single word exceeds `max` it is hard-broken.
|
|
46
|
+
* Ignores ANSI escape codes for length calculation. */
|
|
47
|
+
export function wrap(s, max) {
|
|
48
|
+
if (s.length <= max)
|
|
49
|
+
return [s];
|
|
50
|
+
// Strip ANSI for length calculation
|
|
51
|
+
const stripped = s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
52
|
+
if (stripped.length <= max)
|
|
53
|
+
return [s];
|
|
54
|
+
const lines = [];
|
|
55
|
+
const words = stripped.split(/\s+/);
|
|
56
|
+
let cur = "";
|
|
57
|
+
for (const w of words) {
|
|
58
|
+
if (cur.length === 0) {
|
|
59
|
+
cur = w;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (cur.length + 1 + w.length <= max) {
|
|
63
|
+
cur += " " + w;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push(cur);
|
|
67
|
+
cur = w;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (cur)
|
|
71
|
+
lines.push(cur);
|
|
72
|
+
return lines;
|
|
73
|
+
}
|
|
44
74
|
export function fmtTokens(n) {
|
|
45
75
|
if (n >= 1_000_000)
|
|
46
76
|
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
@@ -412,12 +442,6 @@ export function renderFrame(swarm, showHotkeys, runInfo, selectedAgentId, maxRow
|
|
|
412
442
|
// Build footer
|
|
413
443
|
let hotkeyRow;
|
|
414
444
|
const extraFooterRows = [];
|
|
415
|
-
// Collapsed panel bar shown in footer area
|
|
416
|
-
if (panel?.visible && !panel.state.expanded) {
|
|
417
|
-
const bar = panel.renderCollapsed(Math.max((process.stdout.columns ?? 80) || 80, 60));
|
|
418
|
-
if (bar)
|
|
419
|
-
extraFooterRows.push(bar);
|
|
420
|
-
}
|
|
421
445
|
if (showHotkeys) {
|
|
422
446
|
const pending = runInfo?.pendingSteer ?? 0;
|
|
423
447
|
const chip = pending > 0 ? chalk.cyan(` \u270E ${pending} steer queued`) : "";
|
|
@@ -530,8 +554,12 @@ function renderStatusBlock(out, w, status) {
|
|
|
530
554
|
if (lines.length === 0)
|
|
531
555
|
return;
|
|
532
556
|
section(out, w, "Status");
|
|
533
|
-
|
|
534
|
-
|
|
557
|
+
const indent = " ";
|
|
558
|
+
const maxW = w - indent.length;
|
|
559
|
+
for (const ln of lines) {
|
|
560
|
+
for (const wl of wrap(ln.trim(), maxW))
|
|
561
|
+
out.push(`${indent}${chalk.dim(wl)}`);
|
|
562
|
+
}
|
|
535
563
|
}
|
|
536
564
|
export function renderSteeringFrame(runInfo, data, showHotkeys, rlGetter, maxRows, panel) {
|
|
537
565
|
const totalUsed = runInfo.accCompleted + runInfo.accFailed;
|
|
@@ -609,12 +637,6 @@ export function renderSteeringFrame(runInfo, data, showHotkeys, rlGetter, maxRow
|
|
|
609
637
|
// Footer
|
|
610
638
|
let hotkeyRow;
|
|
611
639
|
const extraFooterRows = [];
|
|
612
|
-
// Collapsed panel bar shown in footer area
|
|
613
|
-
if (panel?.visible && !panel.state.expanded) {
|
|
614
|
-
const bar = panel.renderCollapsed(Math.max((process.stdout.columns ?? 80) || 80, 60));
|
|
615
|
-
if (bar)
|
|
616
|
-
extraFooterRows.push(bar);
|
|
617
|
-
}
|
|
618
640
|
if (showHotkeys) {
|
|
619
641
|
const pending = runInfo?.pendingSteer ?? 0;
|
|
620
642
|
const chip = pending > 0 ? chalk.cyan(` \u270E ${pending} steer queued`) : "";
|
package/dist/steering.js
CHANGED
|
@@ -104,14 +104,14 @@ Respond with ONLY a JSON object (no markdown fences):
|
|
|
104
104
|
"estimatedSessionsRemaining": 15,
|
|
105
105
|
"tasks": [
|
|
106
106
|
{"prompt": "task instruction...", "model": "worker"},
|
|
107
|
-
{"prompt": "
|
|
108
|
-
{"prompt": "verify the app end-to-end...", "model": "
|
|
107
|
+
{"prompt": "quick icon fix, verified by worker next wave...", "model": "fast"},
|
|
108
|
+
{"prompt": "verify the app end-to-end...", "model": "worker", "noWorktree": true}
|
|
109
109
|
]
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
"estimatedSessionsRemaining" is REQUIRED. Your best honest estimate of how many MORE agent sessions (beyond the wave you just composed above) are needed to reach 'amazing' -- include follow-up fixes, polish, verification, and anything else you'd want before shipping. Be realistic, not optimistic. Use 0 only if truly done.
|
|
113
113
|
|
|
114
|
-
The "model" field on each task: use "worker" (${workerModel}) for
|
|
114
|
+
The "model" field on each task: use "worker" (${workerModel}) for all tasks. Use "fast" (${fastModel ?? "not set"}) for small, single-file changes that will be checked by the worker in the next wave.
|
|
115
115
|
Set "noWorktree": true for verify/user-test tasks -- they need the real project directory with env files, dependencies, and local config.
|
|
116
116
|
|
|
117
117
|
If done: {"done": true, "reasoning": "...", "statusUpdate": "...", "estimatedSessionsRemaining": 0, "tasks": []}`;
|
package/dist/ui.js
CHANGED
|
@@ -550,9 +550,14 @@ export class RunDisplay {
|
|
|
550
550
|
}
|
|
551
551
|
return false; // swallow other CSIs silently
|
|
552
552
|
}
|
|
553
|
-
// Bare ESC: collapse
|
|
553
|
+
// Bare ESC: collapse if expanded, close if collapsed
|
|
554
554
|
if (s === "\x1B") {
|
|
555
|
-
this.panel.
|
|
555
|
+
if (this.panel.state.expanded) {
|
|
556
|
+
this.panel.collapse();
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
this.panel.close();
|
|
560
|
+
}
|
|
556
561
|
return true;
|
|
557
562
|
}
|
|
558
563
|
// Ctrl-O: toggle (collapse)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.29",
|
|
4
4
|
"description": "Parallel Claude agents in git worktrees with a usage cap that reserves headroom for your interactive Claude Code. Crash-safe resume. Provider-agnostic model catalog (Anthropic, Cursor, OpenAI, Gemini, DeepSeek, Llama, Qwen) with capability-based task scoping.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.29",
|
|
4
4
|
"description": "Claude Code skill for understanding, installing, and inspecting claude-overnight runs -- parallel Claude agents in git worktrees with thinking waves, multi-wave steering, and crash-safe resume. Supports Cursor API Proxy, Qwen, OpenRouter.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Francesco Fornace"
|