claude-overnight 1.16.2 → 1.16.5

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 CHANGED
@@ -1,10 +1,12 @@
1
1
  # claude-overnight
2
2
 
3
- Run 10, 100, or 1000 Claude agents overnight. Come back to shipped work.
3
+ **A background lane for your Claude Max plan.** Runs a capped swarm of Claude Agent SDK sessions in isolated git worktrees — stops at a usage cap you set, so your interactive Claude Code always has headroom. Rate-limited? It waits. Crash? It resumes with full context.
4
4
 
5
- Local-first, git-native, budget-first. Describe what to build, set a spend cap, press Run. The tool plans, explores your codebase, breaks the objective into tasks, launches parallel agents in isolated git worktrees, iterates toward quality, handles rate limits automatically, and resumes cleanly across crashes and laptop sleeps. You wake up to merged commits.
5
+ Your Max plan rate limits eat interactive coding time. One deep refactor and the 5-hour window is gone before lunch. `claude-overnight` runs background agent sessions up to the percentage cap you pick (90% is typical), leaving the rest free for your own Claude Code session. Hand it an objective and a session budget, walk away, review the diff when the run ends.
6
6
 
7
- Different shape from hosted single-session runtimes like [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview): this runs on your machine, against your real repo, as a parallel swarm with spend caps, git worktree choreography, and multi-day crash-safe resume. Built on the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk). Works with Claude Opus, Sonnet, and Haiku or route executors to Qwen / OpenRouter / any Anthropic-compatible endpoint via the `Other…` picker.
7
+ Isolated by default. Every agent runs in its own git worktree on its own branch, so a misbehaving agent can't trash your working tree. You choose what agents can do before the run starts no surprise escalation mid-flight. Unmerged branches are preserved for manual review, never discarded. Built on the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) not a Claude Code replacement, but a background lane that runs alongside it.
8
+
9
+ Different shape from hosted agent harnesses like [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview): instead of one agent in one cloud container billed separately, you get many parallel sessions on your own machine, in your real repo, against your own Max plan (or API key). Works with Claude Opus, Sonnet, and Haiku — or pair an Anthropic planner with a cheaper executor on Qwen, OpenRouter, or any Anthropic-compatible endpoint.
8
10
 
9
11
  ## Install
10
12
 
@@ -12,16 +14,7 @@ Different shape from hosted single-session runtimes like [Claude Managed Agents]
12
14
  npm install -g claude-overnight
13
15
  ```
14
16
 
15
- Requires Node.js >= 20 and Claude authentication (`claude auth login`, or set `ANTHROPIC_API_KEY`).
16
-
17
- ### Claude Code plugin
18
-
19
- This repo also ships a Claude Code plugin so any Claude instance (inside this repo or any other) knows how to use, inspect, and resume `claude-overnight` runs:
20
-
21
- ```
22
- /plugin marketplace add Fornace/claude-overnight
23
- /plugin install claude-overnight
24
- ```
17
+ Requires Node.js 20 and Claude authentication (`claude auth login` or `ANTHROPIC_API_KEY`).
25
18
 
26
19
  ## Quick start
27
20
 
@@ -62,50 +55,69 @@ claude-overnight
62
55
 
63
56
  ◆ Thinking: 5 agents exploring... ← architects analyze your codebase
64
57
  ◆ Orchestrating plan... ← synthesizes 50 concrete tasks
65
- ◆ Wave 1 · 50 tasks · $4.20 spent ← fully autonomous from here
58
+ ◆ Wave 1 · 50 tasks · $4.20 spent ← runs unattended from here
66
59
  ↑ 1.2M in ↓ 340K out $4.20 / $4.24 total
67
60
  ◆ Assessing... how close to amazing?
68
61
  ◆ Wave 2 · 30 tasks · $18.50 spent ← improvements from assessment
69
62
  ◆ Reflection: 2 agents reviewing ← deep quality audit
70
63
  ◆ Wave 3 · 20 tasks · $31.00 spent ← fixes from review findings
71
- ◆ Assessing... ✓ Vision met
64
+ ◆ Assessing... ✓ Done
72
65
  ```
73
66
 
74
- You interact once (objective, budget, model, review themes), then everything runs autonomously — thinking, planning, executing, reflecting, steering. Rate-limited? It waits and retries. Crash? Resume where you left off. Capped at usage limit? Pick up next time with full context preserved.
67
+ You interact once (objective, budget, model, review themes), then the rest runs unattended — thinking, planning, executing, reflecting, steering. Rate-limited? It waits and retries. Crash? Resume where you left off. Capped at usage limit? Pick up next time with full context preserved.
68
+
69
+ ## How it differs
70
+
71
+ - vs **Claude Code**: many agents, no driver, capped so your Claude Code session keeps its headroom
72
+ - vs **[Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview)**: on your machine, against your Max plan, in your real git history — not a cloud container billed separately
73
+ - vs **Cursor / Copilot / Cline**: asynchronous, off the keyboard
74
+
75
+ ## Use cases
76
+
77
+ - **Overnight refactors** — "Modernize the auth system" at budget 200.
78
+ - **Batch feature implementation** — dozens of features from a task file, parallelized.
79
+ - **Codebase-wide cleanups** — deduplicate, simplify, rename, normalize.
80
+ - **Test generation at scale** — integration tests for every route or module.
81
+ - **Documentation sprints** — API docs, READMEs, inline comments, changelogs.
82
+ - **Framework migrations** — version upgrades, type annotations, config format swaps.
83
+ - **Quality audits** — reflection waves surface architectural issues and code smells.
84
+ - **Long research runs** — architect sessions explore a large codebase before any code lands.
85
+
86
+ Typical shape: one objective + a $20–$200 spend cap + walk away.
75
87
 
76
88
  ## How it works
77
89
 
78
- ### 1. Thinking wave
90
+ ### 1. Thinking phase — parallel architect sessions
79
91
 
80
92
  For budgets > 15, the tool launches **architect agents** that explore your codebase before any code is written. Each one gets a different research angle (architecture, data models, APIs, testing, etc.) and writes a structured design document. The number scales with budget: 5 for budget=50, 10 for budget=2000.
81
93
 
82
- ### 2. Orchestration
94
+ ### 2. Task orchestration
83
95
 
84
- An orchestrator agent reads all design documents and synthesizes concrete execution tasks — grounded in real files and patterns the architects found. No guesswork. The task plan is also written to a file for resilience — if orchestration is interrupted, partial results survive.
96
+ An orchestrator session reads all design documents and synthesizes concrete execution tasks — grounded in real files and patterns the architects found. The task plan is also written to a file for resilience — if orchestration is interrupted, partial results survive.
85
97
 
86
- ### 3. Iterative execution
98
+ ### 3. Parallel execution waves
87
99
 
88
- Tasks run in parallel (each agent in its own git worktree). After completing its task, each agent automatically runs a **simplify pass** — reviewing its own `git diff` for code reuse opportunities, quality issues, and inefficiencies, then fixing them before the framework commits.
100
+ Tasks run in parallel agent sessions (each in its own git worktree). After completing its task, each session automatically runs a **simplify pass** — reviewing its own `git diff` for code reuse opportunities, quality issues, and inefficiencies, then fixing them before the framework commits.
89
101
 
90
102
  After each wave, steering assesses: "how good is this?" — not "what's missing?" It can:
91
103
 
92
104
  - **Execute** more tasks to build features, fix bugs, polish UX
93
- - **Reflect** by spinning up 1-2 review agents for deep quality/architecture audits
105
+ - **Reflect** by spinning up 1-2 review sessions for deep quality/architecture audits
94
106
  - **Declare done** when the vision is met at high quality
95
107
 
96
- ### 4. Goal refinement
108
+ ### 4. Goal refinement and steering
97
109
 
98
- The tool starts with your broad objective but evolves its definition of "amazing" as it learns your codebase. Steering refines the goal after each wave. Late waves are informed by early discoveries.
110
+ The tool starts with your broad objective but refines its definition of quality as it learns your codebase. Steering updates the goal after each wave. Late waves are informed by early discoveries.
99
111
 
100
- ### 5. Three-layer context
112
+ ### 5. Three-layer context memory
101
113
 
102
114
  Long runs stay sharp because steering maintains three layers of memory:
103
115
 
104
116
  - **Status** — a living project snapshot, updated every wave. Compressed, never truncated.
105
117
  - **Milestones** — strategic snapshots archived every ~5 waves. Long-term memory.
106
- - **Goal** — the evolving north star. What "amazing" means for this codebase.
118
+ - **Goal** — the evolving north star. What quality means for this codebase.
107
119
 
108
- ## Run history and resume
120
+ ## Run history, resume, and knowledge carryforward
109
121
 
110
122
  Every run gets its own folder in `.claude-overnight/runs/`. Nothing is ever overwritten.
111
123
 
@@ -133,7 +145,7 @@ Any run that stops before the steering system declares the objective complete
133
145
 
134
146
  On resume: unmerged branches auto-merge, the wave loop continues, all context is preserved. Designs and reflections stay on disk until the objective is truly complete.
135
147
 
136
- If the thinking phase succeeds but orchestration crashes, the next run detects the orphaned design docs and reuses them — no re-running $9 worth of architect agents:
148
+ If the thinking phase succeeds but orchestration crashes, the next run detects the orphaned design docs and reuses them — no re-running $9 worth of architect sessions:
137
149
 
138
150
  ```
139
151
  ✓ Reusing 5 design docs (from prior attempt)
@@ -143,15 +155,13 @@ If the thinking phase succeeds but orchestration crashes, the next run detects t
143
155
  ...
144
156
  ```
145
157
 
146
- **Knowledge carries forward** — new runs inherit knowledge from completed previous runs. Thinking agents and steering see what past runs built. Run 2 knows run 1 already built the auth system.
158
+ **Knowledge carries forward** — new runs inherit knowledge from completed previous runs. Thinking sessions and steering see what past runs built. Run 2 knows run 1 already built the auth system.
147
159
 
148
160
  Add `.claude-overnight/` to your `.gitignore` (with the trailing slash — see below).
149
161
 
150
162
  A separate, tiny `claude-overnight.log.md` is also written at the repo root on every run. It's human-readable, append-only, one block per run (objective, start/finish, cost, outcome, branch), and is designed to be **committed** — so even after `.claude-overnight/` is cleaned up you can still recover which prompt produced which commits. Use `.claude-overnight/` (with trailing slash) in your gitignore so this file isn't matched by accident.
151
163
 
152
- ## Other usage modes
153
-
154
- ### Task file
164
+ ## Task file and inline modes
155
165
 
156
166
  ```bash
157
167
  claude-overnight tasks.json
@@ -181,7 +191,7 @@ For multi-wave runs, add `objective` and `flexiblePlan`:
181
191
  }
182
192
  ```
183
193
 
184
- ### Inline
194
+ Inline:
185
195
 
186
196
  ```bash
187
197
  claude-overnight "fix auth bug in src/auth.ts" "add tests for user model"
@@ -215,7 +225,7 @@ claude-overnight "fix auth bug in src/auth.ts" "add tests for user model"
215
225
  | `mergeStrategy` | `"yolo" \| "branch"` | `"yolo"` | Merge into HEAD or new branch |
216
226
  | `usageCap` | `number (0-100)` | unlimited | Stop at N% utilization |
217
227
 
218
- ## Custom providers (Qwen, OpenRouter, anything Anthropic-compatible)
228
+ ## Custom providers (Qwen, OpenRouter, any Anthropic-compatible endpoint)
219
229
 
220
230
  Planner and executor are picked separately — pair Opus-on-Anthropic for the planner/thinker with a cheaper model on another provider for the bulk of execution.
221
231
 
@@ -245,7 +255,7 @@ Saved providers live user-level at `~/.claude/claude-overnight/providers.json` (
245
255
 
246
256
  **Non-interactive / CI.** `claude-overnight --model=qwen3-coder-plus` auto-resolves the model id to a saved provider — no separate `--provider` flag.
247
257
 
248
- ## Usage controls
258
+ ## Spend caps and usage controls
249
259
 
250
260
  ### Extra usage protection
251
261
 
@@ -272,7 +282,7 @@ The usage bar cycles through all rate limit windows (5h, 7d, etc.) every 3 secon
272
282
 
273
283
  When using extra usage with a budget, a dedicated progress bar shows spend vs limit with color-coded fill (magenta → yellow → red).
274
284
 
275
- ## Rate limits
285
+ ## Rate-limit handling and crash-safe recovery
276
286
 
277
287
  Built for unattended runs lasting hours or days.
278
288
 
@@ -286,15 +296,24 @@ Built for unattended runs lasting hours or days.
286
296
  - **Usage cap**: set a ceiling, active agents finish, no new ones start — run is resumable
287
297
  - **Planner retries**: steering and orchestration retry on rate limits (30s/60s/120s backoff) with full context
288
298
 
289
- ## Worktrees and merging
299
+ ## Git worktrees and branch merging
290
300
 
291
- Each agent gets an isolated git worktree (`swarm/task-N` branch). Changes auto-commit. After all agents complete, branches merge back.
301
+ Each agent session gets an isolated git worktree (`swarm/task-N` branch). Changes auto-commit. After all sessions complete, branches merge back.
292
302
 
293
303
  - `"yolo"` (default): merges into your current branch
294
304
  - `"branch"`: creates a new `swarm/run-{timestamp}` branch
295
305
 
296
306
  Conflicts retry with `-X theirs`. Unresolved branches are preserved for manual merge.
297
307
 
308
+ ## Claude Code plugin
309
+
310
+ This repo also ships a Claude Code plugin so any Claude instance (inside this repo or any other) knows how to use, inspect, and resume `claude-overnight` runs:
311
+
312
+ ```
313
+ /plugin marketplace add Fornace/claude-overnight
314
+ /plugin install claude-overnight
315
+ ```
316
+
298
317
  ## Exit codes
299
318
 
300
319
  | Code | Meaning |
package/dist/cli.js CHANGED
@@ -158,10 +158,12 @@ export function ask(question) {
158
158
  }
159
159
  return new Promise((resolve) => {
160
160
  const segs = [];
161
- const lastLine = question.split("\n").pop() ?? "";
161
+ // DEC save/restore cursor + clear-to-end-of-screen so redraws don't pile
162
+ // up when the input wraps past the terminal width onto additional rows.
162
163
  const redraw = () => {
163
- stdout.write("\r\x1B[K" + lastLine + renderSegments(segs));
164
+ stdout.write("\x1B8\x1B[J" + question + renderSegments(segs));
164
165
  };
166
+ stdout.write("\x1B7");
165
167
  stdout.write(question);
166
168
  stdout.write("\x1B[?2004h");
167
169
  try {
package/dist/merge.d.ts CHANGED
@@ -17,6 +17,15 @@ export declare function mergeAllBranches(agents: {
17
17
  branch: string;
18
18
  filesChanged: number;
19
19
  }[], cwd: string, strategy: MergeStrategy, log: (id: number, msg: string) => void): MergeAllResult;
20
+ /**
21
+ * Last-resort merge: overlay the branch's file state onto HEAD without a real
22
+ * 3-way merge. Walks `git diff --name-status base..branch` and for each entry
23
+ * either checks out the branch's version (add/modify/rename) or removes the
24
+ * file (delete). Always succeeds unless the branch itself is broken. Trades
25
+ * merge-graph fidelity for "your changes actually land" — the right call for
26
+ * an autonomous swarm.
27
+ */
28
+ export declare function forceMergeOverlay(branch: string, cwd: string): boolean;
20
29
  export declare function warnDirtyTree(cwd: string, log: (id: number, msg: string) => void): void;
21
30
  export declare function cleanStaleWorktrees(cwd: string, log: (id: number, msg: string) => void): void;
22
31
  export declare function writeSwarmLog(opts: {
package/dist/merge.js CHANGED
@@ -5,20 +5,45 @@ import { tmpdir } from "os";
5
5
  export function gitExec(cmd, cwd) {
6
6
  return execSync(cmd, { cwd, encoding: "utf-8", stdio: "pipe" });
7
7
  }
8
+ /** Total files the agent touched vs base — tracked changes + untracked. */
9
+ function measureWork(worktreeCwd, baseRef) {
10
+ const seen = new Set();
11
+ try {
12
+ // Tracked: committed + staged + unstaged, all vs the worktree's base.
13
+ const diff = gitExec(`git diff --name-only ${baseRef} --`, worktreeCwd);
14
+ for (const p of diff.split("\n"))
15
+ if (p)
16
+ seen.add(p);
17
+ }
18
+ catch { }
19
+ try {
20
+ // Untracked files don't show in `git diff`; count them separately.
21
+ const untracked = gitExec("git ls-files --others --exclude-standard", worktreeCwd);
22
+ for (const p of untracked.split("\n"))
23
+ if (p)
24
+ seen.add(p);
25
+ }
26
+ catch { }
27
+ return seen.size;
28
+ }
8
29
  export function autoCommit(agentId, taskPrompt, worktreeCwd, baseRef, log) {
9
30
  if (!existsSync(worktreeCwd)) {
10
31
  log(agentId, "Worktree directory gone, skipping commit");
11
32
  return 0;
12
33
  }
13
- // Step 1: commit any uncommitted changes. Agents *may* commit their own work;
14
- // we pick up whatever is still dirty.
34
+ if (!baseRef)
35
+ return 0;
36
+ // Measure actual work BEFORE committing. This captures reality even if a
37
+ // pre-commit hook rejects the commit: we used to silently return 0 in that
38
+ // case and the worktree cleanup would destroy the changes.
39
+ const preCount = measureWork(worktreeCwd, baseRef);
15
40
  let status;
16
41
  try {
17
42
  status = gitExec("git status --porcelain", worktreeCwd);
18
43
  }
19
44
  catch (err) {
20
45
  log(agentId, `git status failed: ${String(err.message || err).slice(0, 120)}`);
21
- return 0;
46
+ return preCount;
22
47
  }
23
48
  if (status.trim()) {
24
49
  try {
@@ -27,33 +52,49 @@ export function autoCommit(agentId, taskPrompt, worktreeCwd, baseRef, log) {
27
52
  catch (err) {
28
53
  log(agentId, `git add failed: ${String(err.message || err).slice(0, 120)}`);
29
54
  }
55
+ const msg = taskPrompt.slice(0, 72).replace(/'/g, "'\\''");
30
56
  try {
31
- const msg = taskPrompt.slice(0, 72).replace(/'/g, "'\\''");
32
57
  gitExec(`git commit -m 'swarm: ${msg}'`, worktreeCwd);
33
58
  }
34
59
  catch (err) {
35
60
  const m = String(err.message || err);
36
- if (!m.includes("nothing to commit"))
37
- log(agentId, `git commit failed: ${m.slice(0, 120)}`);
61
+ if (!m.includes("nothing to commit")) {
62
+ // Hook-gated project: the user's pre-commit hooks rejected a
63
+ // potentially work-in-progress commit (lint errors, type errors,
64
+ // whatever). Retry bypassing hooks — this is swarm scaffolding,
65
+ // not a user-facing commit. Without this the branch stays empty,
66
+ // the merge gate drops it, and the work is destroyed when the
67
+ // worktree is cleaned up.
68
+ try {
69
+ gitExec(`git commit --no-verify -m 'swarm: ${msg}'`, worktreeCwd);
70
+ log(agentId, `Commit hooks bypassed (rejected swarm WIP commit)`);
71
+ }
72
+ catch (err2) {
73
+ log(agentId, `git commit failed even with --no-verify: ${String(err2.message || err2).slice(0, 120)}`);
74
+ }
75
+ }
38
76
  }
39
77
  }
40
- // Step 2: measure against the worktree's origin commit — true regardless of
41
- // who made the commits (agent or autoCommit). Pre-1.11.10 this counted
42
- // `git status --porcelain` lines, which was zero whenever the agent committed
43
- // its own work → filesChanged=0 → branch skipped by the merge gate → orphaned.
44
- if (!baseRef)
45
- return 0;
78
+ // Authoritative post-commit count: this is what `mergeAllBranches` will
79
+ // actually see on the branch.
80
+ let landed = 0;
46
81
  try {
47
82
  const diff = gitExec(`git diff --name-only ${baseRef}..HEAD`, worktreeCwd);
48
- const count = diff.trim().split("\n").filter(Boolean).length;
49
- if (count > 0)
50
- log(agentId, `${count} file(s) changed`);
51
- return count;
83
+ landed = diff.trim().split("\n").filter(Boolean).length;
52
84
  }
53
85
  catch (err) {
54
86
  log(agentId, `diff vs base failed: ${String(err.message || err).slice(0, 120)}`);
55
- return 0;
56
87
  }
88
+ // Red-flag: work existed before the commit attempt but didn't land on the
89
+ // branch. Surfaces silent data loss (stuck hooks, writes outside the
90
+ // worktree, gitignored targets) that used to look like "agent did 0 work".
91
+ if (landed === 0 && preCount > 0) {
92
+ log(agentId, `${preCount} file(s) touched but did NOT land on branch — check hooks / gitignore / absolute paths`);
93
+ return preCount;
94
+ }
95
+ if (landed > 0)
96
+ log(agentId, `${landed} file(s) changed`);
97
+ return landed;
57
98
  }
58
99
  export function mergeAllBranches(agents, cwd, strategy, log) {
59
100
  const mergeResults = [];
@@ -121,8 +162,17 @@ export function mergeAllBranches(agents, cwd, strategy, log) {
121
162
  gitExec("git merge --abort", cwd);
122
163
  }
123
164
  catch { }
124
- result.error = e.message?.slice(0, 80);
125
- log(agent.id, `Merge conflict: ${agent.branch}`);
165
+ // 3rd tier: brute-force overlay. Handles rename/rename, rename/delete
166
+ // and other tree-level conflicts that `-X theirs` can't resolve.
167
+ if (forceMergeOverlay(agent.branch, cwd)) {
168
+ result.ok = true;
169
+ result.autoResolved = true;
170
+ log(agent.id, `Force-merged ${agent.branch} (overlay)`);
171
+ }
172
+ else {
173
+ result.error = e.message?.slice(0, 80);
174
+ log(agent.id, `Merge conflict: ${agent.branch}`);
175
+ }
126
176
  }
127
177
  }
128
178
  mergeResults.push(result);
@@ -165,6 +215,70 @@ export function mergeAllBranches(agents, cwd, strategy, log) {
165
215
  }
166
216
  return { mergeResults, mergeBranch };
167
217
  }
218
+ /**
219
+ * Last-resort merge: overlay the branch's file state onto HEAD without a real
220
+ * 3-way merge. Walks `git diff --name-status base..branch` and for each entry
221
+ * either checks out the branch's version (add/modify/rename) or removes the
222
+ * file (delete). Always succeeds unless the branch itself is broken. Trades
223
+ * merge-graph fidelity for "your changes actually land" — the right call for
224
+ * an autonomous swarm.
225
+ */
226
+ export function forceMergeOverlay(branch, cwd) {
227
+ try {
228
+ const base = gitExec(`git merge-base HEAD "${branch}"`, cwd).trim();
229
+ const diff = gitExec(`git diff --name-status ${base} "${branch}"`, cwd);
230
+ for (const line of diff.split("\n")) {
231
+ if (!line)
232
+ continue;
233
+ const fields = line.split("\t");
234
+ const status = fields[0];
235
+ if (status.startsWith("R") || status.startsWith("C")) {
236
+ const from = fields[1];
237
+ const to = fields[2];
238
+ if (status.startsWith("R")) {
239
+ try {
240
+ gitExec(`git rm -f -- "${from}"`, cwd);
241
+ }
242
+ catch { }
243
+ }
244
+ try {
245
+ gitExec(`git checkout "${branch}" -- "${to}"`, cwd);
246
+ gitExec(`git add -- "${to}"`, cwd);
247
+ }
248
+ catch { }
249
+ }
250
+ else if (status.startsWith("D")) {
251
+ try {
252
+ gitExec(`git rm -f -- "${fields[1]}"`, cwd);
253
+ }
254
+ catch { }
255
+ }
256
+ else {
257
+ try {
258
+ gitExec(`git checkout "${branch}" -- "${fields[1]}"`, cwd);
259
+ gitExec(`git add -- "${fields[1]}"`, cwd);
260
+ }
261
+ catch { }
262
+ }
263
+ }
264
+ const dirty = gitExec("git status --porcelain", cwd).trim();
265
+ if (!dirty)
266
+ return true;
267
+ gitExec(`git commit -m 'swarm: force-merge ${branch}'`, cwd);
268
+ return true;
269
+ }
270
+ catch {
271
+ try {
272
+ gitExec("git merge --abort", cwd);
273
+ }
274
+ catch { }
275
+ try {
276
+ gitExec("git reset --hard HEAD", cwd);
277
+ }
278
+ catch { }
279
+ return false;
280
+ }
281
+ }
168
282
  export function warnDirtyTree(cwd, log) {
169
283
  try {
170
284
  const status = gitExec("git status --porcelain", cwd);
@@ -219,6 +219,19 @@ export function postProcess(raw, budget, onLog) {
219
219
  tasks = tasks.filter((t) => t.prompt && t.prompt.trim().split(/\s+/).length >= 3);
220
220
  if (tasks.length < before)
221
221
  onLog(`Filtered ${before - tasks.length} task(s) with fewer than 3 words`);
222
+ // Read-only tasks (verify/audit/user-test) shouldn't get a worktree: they
223
+ // don't change files, so they'd just create empty swarm branches that show
224
+ // up as "0 files changed" noise. Run them in the real project directory so
225
+ // env files, dependencies, and local config are available.
226
+ let readOnly = 0;
227
+ for (const t of tasks) {
228
+ if (!t.noWorktree && /^\s*(verify|audit|user[- ]?test)\b/i.test(t.prompt)) {
229
+ t.noWorktree = true;
230
+ readOnly++;
231
+ }
232
+ }
233
+ if (readOnly > 0)
234
+ onLog(`${readOnly} read-only task(s) marked noWorktree`);
222
235
  const dominated = new Set();
223
236
  for (let i = 0; i < tasks.length; i++) {
224
237
  if (dominated.has(i))
package/dist/state.js CHANGED
@@ -2,6 +2,7 @@ import { readFileSync, existsSync, mkdirSync, readdirSync, writeFileSync, symlin
2
2
  import { execSync } from "child_process";
3
3
  import { join } from "path";
4
4
  import chalk from "chalk";
5
+ import { forceMergeOverlay } from "./merge.js";
5
6
  // ── File I/O helpers ──
6
7
  export function readMdDir(dir) {
7
8
  try {
@@ -472,8 +473,14 @@ export function autoMergeBranches(cwd, branches, onLog) {
472
473
  execSync("git merge --abort", { cwd, encoding: "utf-8", stdio: "pipe" });
473
474
  }
474
475
  catch { }
475
- br.status = "merge-failed";
476
- onLog(` ✗ ${br.branch} (conflict — preserved for manual merge)`);
476
+ if (forceMergeOverlay(br.branch, cwd)) {
477
+ br.status = "merged";
478
+ onLog(` ✓ ${br.branch} (force-merged)`);
479
+ }
480
+ else {
481
+ br.status = "merge-failed";
482
+ onLog(` ✗ ${br.branch} (conflict — preserved for manual merge)`);
483
+ }
477
484
  }
478
485
  }
479
486
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.16.2",
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.",
3
+ "version": "1.16.5",
4
+ "description": "Background lane for your Claude Max plan. Parallel Claude Agent SDK sessions in git worktrees with a usage cap that reserves headroom for your interactive Claude Code. Crash-safe resume. Opus/Sonnet/Haiku + Qwen/OpenRouter.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "claude-overnight": "dist/bin.js"
@@ -29,19 +29,34 @@
29
29
  },
30
30
  "keywords": [
31
31
  "claude",
32
+ "claude-code",
32
33
  "claude-agent-sdk",
34
+ "agent-sdk",
35
+ "managed-agents",
36
+ "anthropic",
33
37
  "ai-agents",
34
38
  "ai-coding",
35
- "parallel-agents",
36
39
  "autonomous-coding",
40
+ "autonomous-agent",
41
+ "coding-agent",
42
+ "background-agent",
43
+ "async-coding",
44
+ "parallel-agents",
45
+ "multi-agent",
37
46
  "swarm",
38
47
  "overnight",
39
- "cli",
48
+ "overnight-coding",
40
49
  "orchestration",
41
- "multi-agent",
42
- "code-generation",
43
- "anthropic",
50
+ "orchestrator",
51
+ "cli",
44
52
  "worktrees",
53
+ "git-worktree",
54
+ "code-generation",
55
+ "code-automation",
56
+ "refactoring",
57
+ "migration",
58
+ "qwen",
59
+ "openrouter",
45
60
  "iterative"
46
61
  ],
47
62
  "engines": {