claude-overnight 1.25.27 → 1.25.30
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 +27 -8
- package/dist/interactive-panel.d.ts +2 -0
- package/dist/interactive-panel.js +6 -0
- package/dist/providers.d.ts +11 -2
- package/dist/providers.js +19 -8
- package/dist/proxy-port.d.ts +4 -0
- package/dist/proxy-port.js +28 -0
- package/dist/render.d.ts +4 -0
- package/dist/render.js +36 -14
- package/dist/steering.js +3 -3
- package/dist/swarm.js +2 -2
- 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.30";
|
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.30";
|
package/dist/index.js
CHANGED
|
@@ -10,9 +10,10 @@ import { planTasks, refinePlan, identifyThemes, buildThinkingTasks, orchestrate,
|
|
|
10
10
|
import { modelDisplayName, formatContextWindow, DEFAULT_MODEL } from "./models.js";
|
|
11
11
|
import { setPlannerEnvResolver } from "./planner-query.js";
|
|
12
12
|
import { setTranscriptRunDir } from "./transcripts.js";
|
|
13
|
+
import { getProxyPort, buildProxyUrl } from "./proxy-port.js";
|
|
13
14
|
import { pickModel, loadProviders, preflightProvider, buildEnvResolver, healthCheckCursorProxy, PROXY_DEFAULT_URL, isCursorProxyProvider, readCursorProxyLogTail, ensureCursorProxyRunning, bundledComposerProxyShellCommand, warnMacCursorAgentShellPatchIfNeeded, hasCursorAgentToken, } from "./providers.js";
|
|
14
15
|
import { RunDisplay } from "./ui.js";
|
|
15
|
-
import { renderSummary } from "./render.js";
|
|
16
|
+
import { renderSummary, wrap } from "./render.js";
|
|
16
17
|
import { executeRun } from "./run.js";
|
|
17
18
|
import { parseCliFlags, isAuthError, fetchModels, ask, select, selectKey, loadTaskFile, validateConcurrency, isGitRepo, validateGitRepo, showPlan, BRAILLE, makeProgressLog, } from "./cli.js";
|
|
18
19
|
import { loadRunState, findIncompleteRuns, findOrphanedDesigns, backfillOrphanedPlans, formatTimeAgo, showRunHistory, readPreviousRunKnowledge, createRunDir, updateLatestSymlink, readMdDir, saveRunState, autoMergeBranches, } from "./state.js";
|
|
@@ -366,11 +367,13 @@ async function main() {
|
|
|
366
367
|
const ago = formatTimeAgo(prev.startedAt);
|
|
367
368
|
let lastStatus = "";
|
|
368
369
|
try {
|
|
369
|
-
lastStatus = readFileSync(join(run.dir, "status.md"), "utf-8").trim().slice(0,
|
|
370
|
+
lastStatus = readFileSync(join(run.dir, "status.md"), "utf-8").trim().slice(0, 200);
|
|
370
371
|
}
|
|
371
372
|
catch { }
|
|
372
373
|
const planTaskCount = prev.phase === "planning" ? countTasksInFile(join(run.dir, "tasks.json")) : 0;
|
|
373
374
|
console.log(chalk.yellow(`\n ⚠ Unfinished run`) + chalk.dim(` · ${ago}`));
|
|
375
|
+
const termW = Math.max(process.stdout.columns ?? 80, 60);
|
|
376
|
+
const statusMaxW = Math.min(termW - 8, 80);
|
|
374
377
|
const boxLines = prev.phase === "planning" ? [
|
|
375
378
|
`${obj}${obj.length >= 50 ? "…" : ""}`,
|
|
376
379
|
`Plan ready · ${planTaskCount} tasks · budget ${prev.budget} · ${prev.concurrency}× concurrent`,
|
|
@@ -380,8 +383,10 @@ async function main() {
|
|
|
380
383
|
`${prev.accCompleted}/${prev.budget} sessions · ${Math.max(1, (prev.budget ?? 0) - prev.accCompleted)} remaining · $${prev.accCost.toFixed(2)}`,
|
|
381
384
|
`Wave ${prev.waveNum + 1} · ${prev.phase}`,
|
|
382
385
|
];
|
|
383
|
-
if (lastStatus)
|
|
384
|
-
|
|
386
|
+
if (lastStatus) {
|
|
387
|
+
for (const wl of wrap(lastStatus, statusMaxW))
|
|
388
|
+
boxLines.push(wl);
|
|
389
|
+
}
|
|
385
390
|
if (merged + unmerged + failed > 0)
|
|
386
391
|
boxLines.push(`${merged} merged · ${unmerged} unmerged · ${failed} failed`);
|
|
387
392
|
const boxW = Math.max(...boxLines.map(l => l.length)) + 4;
|
|
@@ -415,7 +420,7 @@ async function main() {
|
|
|
415
420
|
const merged = s.branches.filter(b => b.status === "merged").length;
|
|
416
421
|
let lastStatus = "";
|
|
417
422
|
try {
|
|
418
|
-
lastStatus = readFileSync(join(shown[i].dir, "status.md"), "utf-8").trim().split("\n")[0].slice(0,
|
|
423
|
+
lastStatus = readFileSync(join(shown[i].dir, "status.md"), "utf-8").trim().split("\n")[0].slice(0, 120);
|
|
419
424
|
}
|
|
420
425
|
catch { }
|
|
421
426
|
console.log(chalk.cyan(` ${i + 1}`) + ` ${obj}${obj.length >= 50 ? "…" : ""}`);
|
|
@@ -426,8 +431,11 @@ async function main() {
|
|
|
426
431
|
else {
|
|
427
432
|
console.log(chalk.dim(` ${s.accCompleted}/${s.budget} · $${s.accCost.toFixed(2)} · ${ago} · ${s.phase} at wave ${s.waveNum + 1}${merged ? ` · ${merged} merged` : ""}`));
|
|
428
433
|
}
|
|
429
|
-
if (lastStatus)
|
|
430
|
-
|
|
434
|
+
if (lastStatus) {
|
|
435
|
+
const termW = Math.max(process.stdout.columns ?? 80, 60);
|
|
436
|
+
for (const wl of wrap(lastStatus, termW - 6))
|
|
437
|
+
console.log(chalk.dim(` ${wl}`));
|
|
438
|
+
}
|
|
431
439
|
console.log("");
|
|
432
440
|
}
|
|
433
441
|
const action = await selectKey(` ${chalk.dim(`[1-${shown.length}] resume`)}`, [
|
|
@@ -882,7 +890,18 @@ async function main() {
|
|
|
882
890
|
}
|
|
883
891
|
// Auto-start cursor proxy before pinging (restarts when a token exists so stale listeners get CURSOR_API_KEY).
|
|
884
892
|
if (cursorProxies.length > 0) {
|
|
885
|
-
|
|
893
|
+
const resolvedPort = getProxyPort(cwd);
|
|
894
|
+
const resolvedUrl = buildProxyUrl(resolvedPort);
|
|
895
|
+
await ensureCursorProxyRunning(resolvedUrl);
|
|
896
|
+
// Sync providers to the resolved port (may differ from default if per-project port was picked)
|
|
897
|
+
for (const p of cursorProxies) {
|
|
898
|
+
if (!p.baseURL || p.baseURL === PROXY_DEFAULT_URL) {
|
|
899
|
+
p.baseURL = resolvedUrl;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
if (resolvedUrl !== PROXY_DEFAULT_URL) {
|
|
903
|
+
console.log(chalk.dim(` Proxy port: ${resolvedPort}`));
|
|
904
|
+
}
|
|
886
905
|
if (!hasCursorAgentToken()) {
|
|
887
906
|
console.error(chalk.red(` ✗ Cursor models require a User API key — add it via ${chalk.bold("Cursor…")} setup, or set ` +
|
|
888
907
|
`${chalk.bold("CURSOR_API_KEY")} / ${chalk.bold("CURSOR_BRIDGE_API_KEY")}, or ${chalk.bold("cursorApiKey")} in providers.json.`));
|
|
@@ -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/providers.d.ts
CHANGED
|
@@ -108,6 +108,11 @@ export declare function healthCheckCursorProxy(baseUrl?: string): Promise<boolea
|
|
|
108
108
|
* Returns model IDs like ["auto", "composer", "composer-2", "opus-4.6", ...].
|
|
109
109
|
*/
|
|
110
110
|
export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
|
|
111
|
+
/** Options for {@link ensureCursorProxyRunning}. */
|
|
112
|
+
export interface EnsureProxyOptions {
|
|
113
|
+
forceRestart?: boolean;
|
|
114
|
+
projectRoot?: string;
|
|
115
|
+
}
|
|
111
116
|
/**
|
|
112
117
|
* Auto-start the cursor-composer-in-claude as a detached background process.
|
|
113
118
|
*
|
|
@@ -123,9 +128,13 @@ export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
|
|
|
123
128
|
* When `forceRestart` is true, any listener on the port is killed and the
|
|
124
129
|
* bundled proxy is spawned (same as a version mismatch).
|
|
125
130
|
*
|
|
126
|
-
*
|
|
131
|
+
* When `projectRoot` is provided and `baseUrl` is the default, a per-project
|
|
132
|
+
* port is resolved from `.claude-overnight/config.json` so concurrent runs
|
|
133
|
+
* in different repos don't collide on port 8765.
|
|
134
|
+
*
|
|
135
|
+
* Returns true when the proxy is reachable.
|
|
127
136
|
*/
|
|
128
|
-
export declare function ensureCursorProxyRunning(baseUrl?: string,
|
|
137
|
+
export declare function ensureCursorProxyRunning(baseUrl?: string, opts?: EnsureProxyOptions): Promise<boolean>;
|
|
129
138
|
/**
|
|
130
139
|
* Full install + configure flow for cursor-composer-in-claude.
|
|
131
140
|
* Walks through CLI install, API key config, and proxy start.
|
package/dist/providers.js
CHANGED
|
@@ -11,6 +11,7 @@ import { getBearerToken, clearTokenCache } from "./auth.js";
|
|
|
11
11
|
import { DEFAULT_MODEL } from "./models.js";
|
|
12
12
|
import { CURSOR_PRIORITY_MODELS, CURSOR_KNOWN_MODELS, KNOWN_CURSOR_MODEL_IDS, cursorModelHint, } from "./cursor-models.js";
|
|
13
13
|
import { VERSION } from "./_version.js";
|
|
14
|
+
import { getProxyPort, buildProxyUrl } from "./proxy-port.js";
|
|
14
15
|
/** Cached system Node.js and agent script paths — resolved once, reused across envFor calls. */
|
|
15
16
|
let _cachedAgentNode = null;
|
|
16
17
|
let _cachedAgentScript = null;
|
|
@@ -812,13 +813,23 @@ async function isPortInUse(port, host = "127.0.0.1") {
|
|
|
812
813
|
* When `forceRestart` is true, any listener on the port is killed and the
|
|
813
814
|
* bundled proxy is spawned (same as a version mismatch).
|
|
814
815
|
*
|
|
815
|
-
*
|
|
816
|
+
* When `projectRoot` is provided and `baseUrl` is the default, a per-project
|
|
817
|
+
* port is resolved from `.claude-overnight/config.json` so concurrent runs
|
|
818
|
+
* in different repos don't collide on port 8765.
|
|
819
|
+
*
|
|
820
|
+
* Returns true when the proxy is reachable.
|
|
816
821
|
*/
|
|
817
|
-
export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL,
|
|
822
|
+
export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, opts) {
|
|
818
823
|
warnMacCursorAgentShellPatchIfNeeded();
|
|
819
|
-
|
|
820
|
-
const
|
|
821
|
-
|
|
824
|
+
// Resolve per-project port if no explicit base URL was given and projectRoot is available
|
|
825
|
+
const resolvedPort = opts?.projectRoot && baseUrl === PROXY_DEFAULT_URL
|
|
826
|
+
? getProxyPort(opts.projectRoot)
|
|
827
|
+
: null;
|
|
828
|
+
const effectiveBaseUrl = resolvedPort != null ? buildProxyUrl(resolvedPort) : baseUrl;
|
|
829
|
+
const url = new URL(effectiveBaseUrl);
|
|
830
|
+
const port = resolvedPort ?? (parseInt(url.port, 10) || 80);
|
|
831
|
+
const forceRestart = opts?.forceRestart ?? false;
|
|
832
|
+
// Stale listener may have been started without CURSOR_API_KEY for the agent child.
|
|
822
833
|
// When we have a token, replace the listener by default so the bundled proxy always inherits it.
|
|
823
834
|
// Opt out: CURSOR_OVERNIGHT_NO_PROXY_RESTART=1 (e.g. shared port / external proxy).
|
|
824
835
|
const token = resolveCursorAgentToken();
|
|
@@ -961,7 +972,7 @@ async function startProxyProcess(baseUrl, url, port) {
|
|
|
961
972
|
catch { }
|
|
962
973
|
const logFd = openSync(logPath, "a");
|
|
963
974
|
console.log(chalk.dim(` Spawning proxy… ${chalk.dim(`(logs: ${logPath})`)}`));
|
|
964
|
-
const child = spawn(process.execPath, [composerCli], {
|
|
975
|
+
const child = spawn(process.execPath, [composerCli, "--port", String(port)], {
|
|
965
976
|
detached: true,
|
|
966
977
|
stdio: ["ignore", logFd, logFd],
|
|
967
978
|
env: proxyEnv,
|
|
@@ -1196,7 +1207,7 @@ export async function setupCursorProxy() {
|
|
|
1196
1207
|
{ key: "c", desc: "ancel" },
|
|
1197
1208
|
]);
|
|
1198
1209
|
if (choice === "r") {
|
|
1199
|
-
if (await ensureCursorProxyRunning(PROXY_DEFAULT_URL, true)) {
|
|
1210
|
+
if (await ensureCursorProxyRunning(PROXY_DEFAULT_URL, { forceRestart: true })) {
|
|
1200
1211
|
console.log(chalk.green("\n ✓ Proxy is running and healthy"));
|
|
1201
1212
|
return true;
|
|
1202
1213
|
}
|
|
@@ -1262,7 +1273,7 @@ async function pickCursorModel() {
|
|
|
1262
1273
|
{ key: "c", desc: "ancel" },
|
|
1263
1274
|
]);
|
|
1264
1275
|
if (choice === "r") {
|
|
1265
|
-
if (await ensureCursorProxyRunning(PROXY_DEFAULT_URL, true)) {
|
|
1276
|
+
if (await ensureCursorProxyRunning(PROXY_DEFAULT_URL, { forceRestart: true })) {
|
|
1266
1277
|
console.log(chalk.green(" ✓ Proxy started"));
|
|
1267
1278
|
break;
|
|
1268
1279
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
const CONFIG_FILE = "config.json";
|
|
4
|
+
/** Resolve proxy port (reads from config, or allocates and persists a new one). */
|
|
5
|
+
export function getProxyPort(projectRoot) {
|
|
6
|
+
const dir = join(projectRoot, ".claude-overnight");
|
|
7
|
+
const file = join(dir, CONFIG_FILE);
|
|
8
|
+
try {
|
|
9
|
+
const cfg = JSON.parse(readFileSync(file, "utf-8"));
|
|
10
|
+
if (typeof cfg.proxyPort === "number" && cfg.proxyPort >= 1024 && cfg.proxyPort <= 65535) {
|
|
11
|
+
return cfg.proxyPort;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch { /* not found or malformed */ }
|
|
15
|
+
const port = 61000 + Math.floor(Math.random() * 4536);
|
|
16
|
+
try {
|
|
17
|
+
if (!existsSync(dir))
|
|
18
|
+
mkdirSync(dir, { recursive: true });
|
|
19
|
+
const existing = existsSync(file) ? JSON.parse(readFileSync(file, "utf-8")) : {};
|
|
20
|
+
writeFileSync(file, JSON.stringify({ ...existing, proxyPort: port }, null, 2));
|
|
21
|
+
}
|
|
22
|
+
catch { /* best effort */ }
|
|
23
|
+
return port;
|
|
24
|
+
}
|
|
25
|
+
/** Build the full proxy URL for a per-project port. */
|
|
26
|
+
export function buildProxyUrl(port) {
|
|
27
|
+
return `http://127.0.0.1:${port}`;
|
|
28
|
+
}
|
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/swarm.js
CHANGED
|
@@ -5,7 +5,7 @@ import chalk from "chalk";
|
|
|
5
5
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
6
6
|
import { NudgeError, RATE_LIMIT_WINDOW_SHORT, extractToolTarget, sumUsageTokens } from "./types.js";
|
|
7
7
|
import { gitExec, autoCommit, mergeAllBranches, warnDirtyTree, cleanStaleWorktrees, writeSwarmLog } from "./merge.js";
|
|
8
|
-
import { ensureCursorProxyRunning } from "./providers.js";
|
|
8
|
+
import { ensureCursorProxyRunning, PROXY_DEFAULT_URL } from "./providers.js";
|
|
9
9
|
import { getModelCapability } from "./models.js";
|
|
10
10
|
import { createTurn, beginTurn, endTurn, updateTurn } from "./turns.js";
|
|
11
11
|
const SIMPLIFY_PROMPT = `You just finished your task. Now review and simplify your changes.
|
|
@@ -330,7 +330,7 @@ export class Swarm {
|
|
|
330
330
|
// attempt to restart it before the next task.
|
|
331
331
|
if (this.config.cursorProxy) {
|
|
332
332
|
this.log(-1, " Checking cursor proxy health…");
|
|
333
|
-
const restarted = await ensureCursorProxyRunning();
|
|
333
|
+
const restarted = await ensureCursorProxyRunning(PROXY_DEFAULT_URL, { projectRoot: this.config.cwd });
|
|
334
334
|
if (!restarted) {
|
|
335
335
|
this.log(-1, chalk.yellow(" ⚠ Proxy still down — remaining tasks may fail"));
|
|
336
336
|
}
|
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.30",
|
|
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.30",
|
|
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"
|