claude-overnight 1.11.2 → 1.11.3

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/render.js CHANGED
@@ -62,7 +62,7 @@ function renderHeader(out, w, p) {
62
62
  function renderUsageBars(out, w, swarm) {
63
63
  const windows = Array.from(swarm.rateLimitWindows.values());
64
64
  const rlPct = swarm.rateLimitUtilization;
65
- if (rlPct <= 0 && !swarm.rateLimitResetsAt && !swarm.cappedOut && windows.length === 0)
65
+ if (rlPct <= 0 && !swarm.rateLimitResetsAt && !swarm.cappedOut && swarm.rateLimitPaused <= 0 && windows.length === 0)
66
66
  return;
67
67
  const barW = Math.min(30, w - 40);
68
68
  const capFrac = swarm.usageCap;
@@ -85,6 +85,9 @@ function renderUsageBars(out, w, swarm) {
85
85
  else
86
86
  label = chalk.yellow(`Capped at ${capFrac != null ? Math.round(capFrac * 100) : 100}% \u2014 finishing active`);
87
87
  }
88
+ else if (swarm.rateLimitPaused > 0) {
89
+ label = chalk.yellow(`Cooling down \u2014 ${swarm.rateLimitPaused} worker(s) waiting`);
90
+ }
88
91
  else if (swarm.rateLimitResetsAt && swarm.rateLimitResetsAt > Date.now()) {
89
92
  const waitSec = Math.ceil((swarm.rateLimitResetsAt - Date.now()) / 1000);
90
93
  const mm = Math.floor(waitSec / 60), ss = waitSec % 60;
@@ -128,7 +131,8 @@ export function renderFrame(swarm, showHotkeys, runInfo) {
128
131
  const out = [];
129
132
  const stoppingTag = swarm.aborted ? chalk.yellow("STOPPING") : "";
130
133
  const phaseLabel = swarm.phase === "planning" ? chalk.magenta("PLANNING")
131
- : swarm.phase === "merging" ? chalk.yellow("MERGING") : "";
134
+ : swarm.phase === "merging" ? chalk.yellow("MERGING")
135
+ : swarm.rateLimitPaused > 0 ? chalk.yellow("COOLING") : "";
132
136
  const phase = [phaseLabel, stoppingTag].filter(Boolean).join(" ");
133
137
  const waveUsed = swarm.completed + swarm.failed;
134
138
  renderHeader(out, w, {
package/dist/swarm.d.ts CHANGED
@@ -38,6 +38,7 @@ export declare class Swarm {
38
38
  rateLimitUtilization: number;
39
39
  rateLimitResetsAt?: number;
40
40
  rateLimitWindows: Map<string, RateLimitWindow>;
41
+ rateLimitPaused: number;
41
42
  isUsingOverage: boolean;
42
43
  overageDisabledReason?: string;
43
44
  overageCostUsd: number;
package/dist/swarm.js CHANGED
@@ -31,6 +31,7 @@ export class Swarm {
31
31
  rateLimitUtilization = 0;
32
32
  rateLimitResetsAt;
33
33
  rateLimitWindows = new Map();
34
+ rateLimitPaused = 0;
34
35
  isUsingOverage = false;
35
36
  overageDisabledReason;
36
37
  overageCostUsd = 0;
@@ -179,12 +180,6 @@ export class Swarm {
179
180
  async throttle() {
180
181
  if (this.cappedOut)
181
182
  return;
182
- const cap = this.usageCap;
183
- if (cap != null && cap < 1 && this.rateLimitUtilization >= cap) {
184
- this.cappedOut = true;
185
- this.log(-1, `Usage cap ${Math.round(cap * 100)}% reached (at ${Math.round(this.rateLimitUtilization * 100)}%) — finishing active agents, no new tasks`);
186
- return;
187
- }
188
183
  if (this.isUsingOverage && !this.allowExtraUsage) {
189
184
  this.capForOverage(`Extra usage detected but not allowed — stopping dispatch`);
190
185
  return;
@@ -193,12 +188,27 @@ export class Swarm {
193
188
  this.capForOverage(`Extra usage budget $${this.extraUsageBudget} reached ($${this.overageCostUsd.toFixed(2)} spent) — stopping dispatch`);
194
189
  return;
195
190
  }
191
+ const cap = this.usageCap;
192
+ if (cap != null && cap < 1 && this.rateLimitUtilization >= cap) {
193
+ const waitMs = this.rateLimitResetsAt
194
+ ? Math.max(5000, this.rateLimitResetsAt - Date.now())
195
+ : 60_000;
196
+ this.log(-1, `Usage at ${Math.round(this.rateLimitUtilization * 100)}% (cap ${Math.round(cap * 100)}%), waiting ${Math.ceil(waitMs / 1000)}s for cooldown`);
197
+ this.rateLimitPaused++;
198
+ await sleep(waitMs);
199
+ this.rateLimitPaused--;
200
+ this.rateLimitUtilization = 0;
201
+ this.rateLimitResetsAt = undefined;
202
+ return;
203
+ }
196
204
  if (this.rateLimitResetsAt) {
197
205
  const resetTarget = this.rateLimitResetsAt;
198
206
  const waitMs = resetTarget - Date.now();
199
207
  if (waitMs > 0) {
200
208
  this.log(-1, `Rate limited, pausing ${Math.ceil(waitMs / 1000)}s`);
209
+ this.rateLimitPaused++;
201
210
  await sleep(waitMs);
211
+ this.rateLimitPaused--;
202
212
  }
203
213
  if (this.rateLimitResetsAt === resetTarget)
204
214
  this.rateLimitResetsAt = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.11.2",
3
+ "version": "1.11.3",
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": {