claude-overnight 1.2.0 → 1.2.2
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/README.md +8 -6
- package/dist/index.js +2 -12
- package/dist/planner.d.ts +1 -1
- package/dist/planner.js +2 -18
- package/dist/swarm.js +10 -2
- package/dist/ui.js +8 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,15 +43,16 @@ claude-overnight
|
|
|
43
43
|
│ sonnet · budget 200 · 5× · flex · cap 90% · no extra │
|
|
44
44
|
╰──────────────────────────────────────────────────╯
|
|
45
45
|
|
|
46
|
+
⠹ 8s · $0.04 · 12% · identifying themes ← every phase shows cost + usage
|
|
46
47
|
✓ 5 themes → review, press Run, walk away
|
|
47
48
|
|
|
48
|
-
◆ Thinking: 5 agents exploring...
|
|
49
|
-
◆ Orchestrating plan...
|
|
50
|
-
◆ Wave 1 · 50 tasks
|
|
49
|
+
◆ Thinking: 5 agents exploring... ← architects analyze your codebase
|
|
50
|
+
◆ Orchestrating plan... ← synthesizes 50 concrete tasks
|
|
51
|
+
◆ Wave 1 · 50 tasks · $4.20 spent ← fully autonomous from here
|
|
51
52
|
◆ Assessing... how close to amazing?
|
|
52
|
-
◆ Wave 2 · 30 tasks
|
|
53
|
-
◆ Reflection: 2 agents reviewing
|
|
54
|
-
◆ Wave 3 · 20 tasks
|
|
53
|
+
◆ Wave 2 · 30 tasks · $18.50 spent ← improvements from assessment
|
|
54
|
+
◆ Reflection: 2 agents reviewing ← deep quality audit
|
|
55
|
+
◆ Wave 3 · 20 tasks · $31.00 spent ← fixes from review findings
|
|
55
56
|
◆ Assessing... ✓ Vision met
|
|
56
57
|
```
|
|
57
58
|
|
|
@@ -224,6 +225,7 @@ The usage bar cycles through all rate limit windows (5h, 7d, etc.) every 3 secon
|
|
|
224
225
|
|
|
225
226
|
Built for unattended runs lasting hours or days.
|
|
226
227
|
|
|
228
|
+
- **Smooth overage transition**: when extra usage is allowed, plan limit rejection is seamless — no dispatch blocking, agents continue into overage
|
|
227
229
|
- **Hard block**: pauses until the rate limit window resets, then resumes
|
|
228
230
|
- **Soft throttle**: slows dispatch at >75% utilization
|
|
229
231
|
- **Extra usage guard**: detects overage billing and stops unless explicitly allowed
|
package/dist/index.js
CHANGED
|
@@ -852,18 +852,8 @@ async function main() {
|
|
|
852
852
|
try {
|
|
853
853
|
if (useThinking) {
|
|
854
854
|
// Phase 1: Quick theme identification → review → then autonomous
|
|
855
|
-
let themeFrame = 0;
|
|
856
|
-
const themeSpinner = setInterval(() => {
|
|
857
|
-
const spin = chalk.cyan(BRAILLE[themeFrame++ % BRAILLE.length]);
|
|
858
|
-
process.stdout.write(`\x1B[2K\r ${spin} ${chalk.dim("identifying themes...")}`);
|
|
859
|
-
}, 120);
|
|
860
855
|
let themes;
|
|
861
|
-
|
|
862
|
-
themes = await identifyThemes(objective, thinkingCount, plannerModel, permissionMode);
|
|
863
|
-
}
|
|
864
|
-
finally {
|
|
865
|
-
clearInterval(themeSpinner);
|
|
866
|
-
}
|
|
856
|
+
themes = await identifyThemes(objective, thinkingCount, plannerModel, permissionMode, makeProgressLog());
|
|
867
857
|
process.stdout.write(`\x1B[2K\r ${chalk.green(`\u2713 ${themes.length} themes`)}\n\n`);
|
|
868
858
|
// Show themes for review — this is the LAST user interaction
|
|
869
859
|
planRestore();
|
|
@@ -888,7 +878,7 @@ async function main() {
|
|
|
888
878
|
break;
|
|
889
879
|
process.stdout.write("\x1B[?25l");
|
|
890
880
|
try {
|
|
891
|
-
themes = await identifyThemes(`${objective}\n\nUser feedback: ${feedback}`, thinkingCount, plannerModel, permissionMode);
|
|
881
|
+
themes = await identifyThemes(`${objective}\n\nUser feedback: ${feedback}`, thinkingCount, plannerModel, permissionMode, makeProgressLog());
|
|
892
882
|
process.stdout.write(`\x1B[2K\r ${chalk.green(`\u2713 ${themes.length} themes`)}\n\n`);
|
|
893
883
|
}
|
|
894
884
|
catch (err) {
|
package/dist/planner.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export type ModelTier = "opus" | "sonnet" | "haiku" | "unknown";
|
|
|
38
38
|
export declare function detectModelTier(model: string): ModelTier;
|
|
39
39
|
export declare function getPlannerRateLimitInfo(): PlannerRateLimitInfo;
|
|
40
40
|
export declare function planTasks(objective: string, cwd: string, plannerModel: string, workerModel: string, permissionMode: PermMode, budget: number | undefined, concurrency: number, onLog: (text: string) => void, flexNote?: string, outFile?: string): Promise<Task[]>;
|
|
41
|
-
export declare function identifyThemes(objective: string, count: number, model: string, permissionMode: PermMode): Promise<string[]>;
|
|
41
|
+
export declare function identifyThemes(objective: string, count: number, model: string, permissionMode: PermMode, onLog?: (text: string) => void): Promise<string[]>;
|
|
42
42
|
export declare function buildThinkingTasks(objective: string, themes: string[], designDir: string, plannerModel: string, previousKnowledge?: string): Task[];
|
|
43
43
|
export declare function buildReflectionTasks(objective: string, goal: string, reflectionDir: string, waveNum: number, plannerModel: string): Task[];
|
|
44
44
|
export declare function orchestrate(objective: string, designDocs: string, cwd: string, plannerModel: string, workerModel: string, permissionMode: PermMode, budget: number, concurrency: number, onLog: (text: string) => void, flexNote?: string, outFile?: string): Promise<Task[]>;
|
package/dist/planner.js
CHANGED
|
@@ -366,24 +366,8 @@ export async function planTasks(objective, cwd, plannerModel, workerModel, permi
|
|
|
366
366
|
return tasks;
|
|
367
367
|
}
|
|
368
368
|
// ── Thinking wave ──
|
|
369
|
-
export async function identifyThemes(objective, count, model, permissionMode) {
|
|
370
|
-
|
|
371
|
-
for await (const msg of query({
|
|
372
|
-
prompt: `Split this objective into exactly ${count} independent research angles for architects exploring a codebase. Each angle should cover a distinct aspect.
|
|
373
|
-
|
|
374
|
-
Objective: ${objective}
|
|
375
|
-
|
|
376
|
-
Return ONLY a JSON object: {"themes": ["angle description", ...]}`,
|
|
377
|
-
options: {
|
|
378
|
-
model,
|
|
379
|
-
permissionMode,
|
|
380
|
-
...(permissionMode === "bypassPermissions" && { allowDangerouslySkipPermissions: true }),
|
|
381
|
-
persistSession: false,
|
|
382
|
-
},
|
|
383
|
-
})) {
|
|
384
|
-
if (msg.type === "result" && msg.subtype === "success")
|
|
385
|
-
resultText = msg.result || "";
|
|
386
|
-
}
|
|
369
|
+
export async function identifyThemes(objective, count, model, permissionMode, onLog = () => { }) {
|
|
370
|
+
const resultText = await runPlannerQuery(`Split this objective into exactly ${count} independent research angles for architects exploring a codebase. Each angle should cover a distinct aspect.\n\nObjective: ${objective}\n\nReturn ONLY a JSON object: {"themes": ["angle description", ...]}`, { cwd: process.cwd(), model, permissionMode }, onLog);
|
|
387
371
|
const parsed = attemptJsonParse(resultText);
|
|
388
372
|
if (parsed?.themes && Array.isArray(parsed.themes))
|
|
389
373
|
return parsed.themes.slice(0, count);
|
package/dist/swarm.js
CHANGED
|
@@ -659,9 +659,14 @@ export class Swarm {
|
|
|
659
659
|
const info = rl.rate_limit_info;
|
|
660
660
|
this.rateLimitUtilization = info.utilization ?? 0;
|
|
661
661
|
this.rateLimitStatus = info.status;
|
|
662
|
-
if (info.status === "rejected" && info.resetsAt) {
|
|
662
|
+
if (info.status === "rejected" && info.resetsAt && !this.allowExtraUsage) {
|
|
663
|
+
// Only block dispatch on rejection if extra usage is NOT allowed.
|
|
664
|
+
// When extra usage is allowed, rejection is just the plan→overage transition.
|
|
663
665
|
this.rateLimitResetsAt = info.resetsAt;
|
|
664
666
|
}
|
|
667
|
+
else if (info.status !== "rejected") {
|
|
668
|
+
this.rateLimitResetsAt = undefined;
|
|
669
|
+
}
|
|
665
670
|
// Track per-window state
|
|
666
671
|
const windowType = info.rateLimitType;
|
|
667
672
|
if (windowType) {
|
|
@@ -684,7 +689,10 @@ export class Swarm {
|
|
|
684
689
|
}
|
|
685
690
|
const pct = info.utilization != null ? `${Math.round(info.utilization * 100)}%` : "";
|
|
686
691
|
const overageTag = this.isUsingOverage ? " [EXTRA]" : "";
|
|
687
|
-
|
|
692
|
+
const statusLabel = info.status === "rejected" && this.allowExtraUsage
|
|
693
|
+
? "switching to extra usage"
|
|
694
|
+
: info.status;
|
|
695
|
+
this.log(agent.id, `Rate: ${statusLabel} ${pct}${overageTag}${windowType ? ` (${windowType})` : ""}`);
|
|
688
696
|
break;
|
|
689
697
|
}
|
|
690
698
|
}
|
package/dist/ui.js
CHANGED
|
@@ -75,14 +75,18 @@ export function renderFrame(swarm, showHotkeys = false) {
|
|
|
75
75
|
label = chalk.yellow(`Capped at ${capFrac != null ? Math.round(capFrac * 100) : 100}% — finishing active`);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
else if (swarm.rateLimitResetsAt) {
|
|
79
|
-
const waitSec = Math.
|
|
78
|
+
else if (swarm.rateLimitResetsAt && swarm.rateLimitResetsAt > Date.now()) {
|
|
79
|
+
const waitSec = Math.ceil((swarm.rateLimitResetsAt - Date.now()) / 1000);
|
|
80
80
|
const mm = Math.floor(waitSec / 60);
|
|
81
81
|
const ss = waitSec % 60;
|
|
82
82
|
label = chalk.red(`Waiting for reset ${mm > 0 ? `${mm}m ${ss}s` : `${ss}s`}`);
|
|
83
83
|
}
|
|
84
|
-
if (swarm.isUsingOverage && !swarm.cappedOut)
|
|
85
|
-
|
|
84
|
+
if (swarm.isUsingOverage && !swarm.cappedOut) {
|
|
85
|
+
const budgetInfo = swarm.extraUsageBudget != null
|
|
86
|
+
? ` $${swarm.overageCostUsd.toFixed(2)}/$${swarm.extraUsageBudget}`
|
|
87
|
+
: "";
|
|
88
|
+
label += chalk.red(` [EXTRA USAGE${budgetInfo}]`);
|
|
89
|
+
}
|
|
86
90
|
const prefix = windowLabel ? chalk.dim(windowLabel.padEnd(6)) : chalk.dim("Usage ");
|
|
87
91
|
out.push(` ${prefix}${barStr} ${label}`);
|
|
88
92
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Run 10, 100, or 1000 Claude agents overnight. Parallel autonomous AI coding with thinking waves, iterative quality steering, crash recovery, and rate limit handling. Built on the Claude Agent SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|