claude-overnight 1.9.0 → 1.9.1

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/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { execSync } from "child_process";
1
2
  import { readFileSync } from "fs";
2
3
  import { resolve } from "path";
3
4
  import { createInterface } from "readline";
@@ -233,7 +234,6 @@ export function validateConcurrency(value) {
233
234
  }
234
235
  }
235
236
  export function isGitRepo(cwd) {
236
- const { execSync } = require("child_process");
237
237
  try {
238
238
  execSync("git rev-parse --git-dir", { cwd, encoding: "utf-8", stdio: "pipe" });
239
239
  return true;
package/dist/index.js CHANGED
@@ -408,7 +408,7 @@ async function main() {
408
408
  const thinkingCount = useThinking ? Math.min(Math.max(concurrency, Math.ceil((budget ?? 10) * 0.005)), 10) : 0;
409
409
  try {
410
410
  if (useThinking) {
411
- let themes = await identifyThemes(objective, thinkingCount, plannerModel, permissionMode, makeProgressLog());
411
+ let themes = await identifyThemes(objective, thinkingCount, cwd, plannerModel, permissionMode, makeProgressLog());
412
412
  process.stdout.write(`\x1B[2K\r ${chalk.green(`✓ ${themes.length} themes`)}\n\n`);
413
413
  planRestore();
414
414
  let reviewing = true;
@@ -427,7 +427,7 @@ async function main() {
427
427
  continue;
428
428
  process.stdout.write("\x1B[?25l");
429
429
  try {
430
- themes = await identifyThemes(`${objective}\n\nUser feedback: ${feedback}`, thinkingCount, plannerModel, permissionMode, makeProgressLog());
430
+ themes = await identifyThemes(`${objective}\n\nUser feedback: ${feedback}`, thinkingCount, cwd, plannerModel, permissionMode, makeProgressLog());
431
431
  process.stdout.write(`\x1B[2K\r ${chalk.green(`✓ ${themes.length} themes`)}\n\n`);
432
432
  }
433
433
  catch (err) {
package/dist/planner.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Task, PermMode } from "./types.js";
2
2
  export declare const DESIGN_THINKING = "\nHOW TO THINK ABOUT EVERY TASK:\n\nStart from the user's job. What is someone hiring this product to do? \"I need to send money abroad cheaply\" \u2014 not \"I need a currency conversion API.\" Every decision \u2014 what to build, how fast it responds, what happens on error \u2014 flows from the job.\n\nThe experience IS the product. A 200ms server response is not a \"performance metric\" \u2014 it's the difference between an app that feels alive and one that feels broken. A loading state is not \"polish\" \u2014 it's the user knowing the app heard them. An error message is not \"error handling\" \u2014 it's the app being honest. There is no line between backend and UX. The server, the API, the database query, the render \u2014 they're all one experience the user either trusts or doesn't.\n\nBuild the core, verify it works, learn, iterate. Don't plan 20 features and build them all. Build the ONE thing that matters most, run it, see if it actually works from a user's chair. What you learn from seeing it run will change what you build next. Each wave should make what exists better before adding what doesn't exist yet.\n\nConsistency is what makes complex things feel simple. One design system, rigid rules, no exceptions. This is how Revolut ships a super-app with 30+ features that doesn't feel like chaos.\n";
3
3
  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[]>;
4
- export declare function identifyThemes(objective: string, count: number, model: string, permissionMode: PermMode, onLog?: (text: string) => void): Promise<string[]>;
4
+ export declare function identifyThemes(objective: string, count: number, cwd: string, model: string, permissionMode: PermMode, onLog?: (text: string) => void): Promise<string[]>;
5
5
  export declare function buildThinkingTasks(objective: string, themes: string[], designDir: string, plannerModel: string, previousKnowledge?: string): Task[];
6
6
  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[]>;
7
7
  export declare function refinePlan(objective: string, previousTasks: Task[], feedback: string, cwd: string, plannerModel: string, workerModel: string, permissionMode: PermMode, budget: number | undefined, concurrency: number, onLog: (text: string) => void): Promise<Task[]>;
package/dist/planner.js CHANGED
@@ -1,4 +1,4 @@
1
- import { runPlannerQuery, extractTaskJson, postProcess, detectModelTier, modelCapabilityBlock } from "./planner-query.js";
1
+ import { runPlannerQuery, extractTaskJson, attemptJsonParse, postProcess, detectModelTier, modelCapabilityBlock } from "./planner-query.js";
2
2
  // The core framing for all planning. Not a checklist — a way of thinking.
3
3
  export const DESIGN_THINKING = `
4
4
  HOW TO THINK ABOUT EVERY TASK:
@@ -166,9 +166,9 @@ export async function planTasks(objective, cwd, plannerModel, workerModel, permi
166
166
  onLog(`${tasks.length} tasks`);
167
167
  return tasks;
168
168
  }
169
- export async function identifyThemes(objective, count, model, permissionMode, onLog = () => { }) {
170
- 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, outputFormat: THEMES_SCHEMA }, onLog);
171
- const parsed = (await import("./planner-query.js")).attemptJsonParse(resultText);
169
+ export async function identifyThemes(objective, count, cwd, model, permissionMode, onLog = () => { }) {
170
+ 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, model, permissionMode, outputFormat: THEMES_SCHEMA }, onLog);
171
+ const parsed = attemptJsonParse(resultText);
172
172
  if (parsed?.themes && Array.isArray(parsed.themes))
173
173
  return parsed.themes.slice(0, count);
174
174
  const fallback = ["architecture, patterns, and conventions", "data models, state, and persistence", "user-facing flows, components, and UX", "APIs, integrations, and services", "testing, quality, and error handling", "security, performance, and infrastructure", "build, deployment, and configuration", "documentation and developer experience"];
package/dist/run.js CHANGED
@@ -34,7 +34,7 @@ export async function executeRun(cfg) {
34
34
  const branches = [];
35
35
  if (cfg.resuming && cfg.resumeState) {
36
36
  const rs = cfg.resumeState;
37
- remaining = Math.max(1, (rs.budget ?? 0) - rs.accCompleted);
37
+ remaining = Math.max(1, rs.remaining);
38
38
  currentTasks = rs.currentTasks;
39
39
  waveNum = rs.waveNum;
40
40
  accCost = rs.accCost;
@@ -215,7 +215,8 @@ export async function executeRun(cfg) {
215
215
  accFailed += swarm.failed;
216
216
  accTools += swarm.agents.reduce((sum, a) => sum + a.toolCalls, 0);
217
217
  remaining = Math.max(0, remaining - swarm.completed - swarm.failed);
218
- const expectedFloor = Math.max(0, cfg.budget - accCompleted - accFailed);
218
+ const totalConsumed = accCompleted + accFailed + cfg.thinkingUsed;
219
+ const expectedFloor = Math.max(0, cfg.budget - totalConsumed);
219
220
  if (remaining < expectedFloor)
220
221
  remaining = expectedFloor;
221
222
  if (liveConfig.dirty) {
package/dist/state.js CHANGED
@@ -98,6 +98,8 @@ export function findOrphanedDesigns(rootDir) {
98
98
  // ── History display ──
99
99
  export function formatTimeAgo(isoStr) {
100
100
  const ms = Date.now() - new Date(isoStr).getTime();
101
+ if (!isFinite(ms))
102
+ return "unknown";
101
103
  const mins = Math.floor(ms / 60000);
102
104
  if (mins < 1)
103
105
  return "just now";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
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": {