claude-overnight 1.16.10 → 1.16.12

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
@@ -8,13 +8,38 @@ Isolated by default. Every agent runs in its own git worktree on its own branch,
8
8
 
9
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.
10
10
 
11
+ ## Run on Qwen 3.6 Plus
12
+
13
+ Hit your Claude Max plan limits? Running on a tight budget? Qwen 3.6 Plus via Alibaba Cloud's DashScope gateway is a drop-in executor that speaks the Anthropic Messages API — same client, same flow, pennies per run.
14
+
15
+ 1. **Get an API key.** Sign up at [Alibaba Cloud](https://account.alibabacloud.com/login/login.htm?oauth_callback=https%3A%2F%2Fmodelstudio.console.alibabacloud.com%2Fap-southeast-1%3Ftab%3Ddashboard%23%2Fapi-key&clearRedirectCookie=1) — the link takes you straight to the API key dashboard.
16
+ 2. **Configure the provider.** Run `claude-overnight`, choose `Other…` on the executor step, and fill in:
17
+
18
+ | Field | Value |
19
+ |---|---|
20
+ | Name | `Qwen 3.6 Plus` |
21
+ | Base URL | `https://dashscope-intl.aliyuncs.com/apps/anthropic` |
22
+ | Model id | `qwen3.6-plus` |
23
+ | API key | your DashScope key |
24
+
25
+ 3. That's it. Planner runs on Sonnet (or Opus), executor runs on Qwen.
26
+
27
+ Or set it via env directly:
28
+
29
+ ```bash
30
+ export ANTHROPIC_BASE_URL="https://dashscope-intl.aliyuncs.com/apps/anthropic"
31
+ export ANTHROPIC_API_KEY="sk-..."
32
+ export ANTHROPIC_MODEL="qwen3.6-plus"
33
+ claude-overnight
34
+ ```
35
+
11
36
  ## Install
12
37
 
13
38
  ```bash
14
39
  npm install -g claude-overnight
15
40
  ```
16
41
 
17
- Requires Node.js ≥ 20 and Claude authentication (`claude auth login` or `ANTHROPIC_API_KEY`).
42
+ Requires Node.js ≥ 20 and Claude authentication (`claude auth login` or `ANTHROPIC_API_KEY`). No Anthropic plan or key? See **Run on Qwen 3.6 Plus** above — a cheap, drop-in alternative.
18
43
 
19
44
  ## Quick start
20
45
 
@@ -35,7 +60,7 @@ claude-overnight
35
60
  ● Opus — Opus 4.6 · Most capable
36
61
  ○ Sonnet — Sonnet 4.6 · Best for everyday tasks
37
62
 
38
- ⑤ Executor model (what runs the tasks — Qwen/OpenRouter/etc via Other…):
63
+ ⑤ Executor model (what runs the tasks — Qwen 3.6 Plus / OpenRouter / etc via Other…):
39
64
  ● Sonnet — Sonnet 4.6 · Best for everyday tasks
40
65
  ○ Opus — Opus 4.6 · Most capable
41
66
  ○ Other… · custom OpenAI/Anthropic-compatible endpoint
@@ -232,14 +257,14 @@ Planner and executor are picked separately — pair Opus-on-Anthropic for the pl
232
257
  From the interactive picker, choose `Other…` on the planner or executor step:
233
258
 
234
259
  ```
235
- ⑤ Executor model (what runs the tasks — Qwen/OpenRouter/etc via Other…):
260
+ ⑤ Executor model (what runs the tasks — Qwen 3.6 Plus / OpenRouter / etc via Other…):
236
261
  ○ Sonnet
237
262
  ○ Opus
238
263
  ● Other…
239
264
 
240
- Name: Qwen Coder
241
- Base URL: https://dashscope-intl.aliyuncs.com/api/v2/apps/claude-code-proxy
242
- Model id: qwen3-coder-plus
265
+ Name: Qwen 3.6 Plus
266
+ Base URL: https://dashscope-intl.aliyuncs.com/apps/anthropic
267
+ Model id: qwen3.6-plus
243
268
  API key source:
244
269
  ● Paste key now · stored plaintext in ~/.claude/claude-overnight/providers.json (0600)
245
270
  ○ Read from env var · nothing written to disk
@@ -253,7 +278,7 @@ Saved providers live user-level at `~/.claude/claude-overnight/providers.json` (
253
278
 
254
279
  **Resume.** Provider ids are persisted in `run.json` and rehydrated on resume. If you deleted a provider between runs, resume refuses to start and tells you exactly which id is missing.
255
280
 
256
- **Non-interactive / CI.** `claude-overnight --model=qwen3-coder-plus` auto-resolves the model id to a saved provider — no separate `--provider` flag.
281
+ **Non-interactive / CI.** `claude-overnight --model=qwen3.6-plus` auto-resolves the model id to a saved provider — no separate `--provider` flag.
257
282
 
258
283
  ## Spend caps and usage controls
259
284
 
package/dist/cli.js CHANGED
@@ -264,7 +264,18 @@ export async function select(label, items, defaultIdx = 0) {
264
264
  };
265
265
  const handler = (buf) => {
266
266
  const s = buf.toString();
267
- // Ignore ANSI escape sequences (arrow keys etc.)
267
+ // Arrow keys: \x1B[A = up, \x1B[B = down
268
+ if (s === "\x1B[A") {
269
+ idx = (idx - 1 + items.length) % items.length;
270
+ draw();
271
+ return;
272
+ }
273
+ if (s === "\x1B[B") {
274
+ idx = (idx + 1) % items.length;
275
+ draw();
276
+ return;
277
+ }
278
+ // Ignore any other ANSI escape sequences
268
279
  if (s[0] === "\x1B")
269
280
  return;
270
281
  if (s === "\r")
package/dist/index.js CHANGED
@@ -2,7 +2,10 @@
2
2
  import { readFileSync, existsSync, readdirSync, mkdirSync } from "fs";
3
3
  import { resolve, dirname, join } from "path";
4
4
  import { fileURLToPath } from "url";
5
+ import { createRequire } from "module";
5
6
  import chalk from "chalk";
7
+ const pkg = createRequire(import.meta.url)("../package.json");
8
+ const VERSION = pkg.version;
6
9
  import { query } from "@anthropic-ai/claude-agent-sdk";
7
10
  import { Swarm } from "./swarm.js";
8
11
  import { planTasks, refinePlan, identifyThemes, buildThinkingTasks, orchestrate, salvageFromFile } from "./planner.js";
@@ -166,7 +169,7 @@ async function main() {
166
169
  }
167
170
  if (argv.includes("-h") || argv.includes("--help")) {
168
171
  console.log(`
169
- ${chalk.bold("🌙 claude-overnight")} ${chalk.dim("— background lane for your Claude Max plan")}
172
+ ${chalk.bold("🌙 claude-overnight")} ${chalk.dim("v" + VERSION + " — background lane for your Claude Max plan")}
170
173
  ${chalk.dim("─".repeat(60))}
171
174
 
172
175
  ${chalk.cyan("Usage")}
@@ -245,7 +248,7 @@ async function main() {
245
248
  // ── Mode detection ──
246
249
  // Stop the bin.ts startup splash (if any) before printing our header.
247
250
  globalThis.__coStopSplash?.();
248
- console.log(` ${chalk.bold("🌙 claude-overnight")}`);
251
+ console.log(` ${chalk.bold("🌙 claude-overnight")} ${chalk.dim("v" + VERSION)}`);
249
252
  console.log(chalk.dim(` ${"─".repeat(36)}`));
250
253
  const noTTY = !process.stdin.isTTY;
251
254
  const nonInteractive = noTTY || fileCfg !== undefined || tasks.length > 0;
package/dist/ui.js CHANGED
@@ -328,18 +328,6 @@ export class RunDisplay {
328
328
  /** Handle a typed (non-pasted) chunk. Returns true if the frame needs a redraw. */
329
329
  handleTyped(s) {
330
330
  const lc = this.liveConfig;
331
- // Enter in hotkey mode reveals truncated ask answer in Finder
332
- if (this.inputMode === "none" && this.askTempFile) {
333
- for (const ch of s) {
334
- if (ch === "\r" || ch === "\n") {
335
- try {
336
- execSync(`open -R ${JSON.stringify(this.askTempFile)}`);
337
- }
338
- catch { }
339
- return true;
340
- }
341
- }
342
- }
343
331
  if (this.inputMode === "budget" || this.inputMode === "threshold" || this.inputMode === "concurrency" || this.inputMode === "extra") {
344
332
  let dirty = false;
345
333
  for (const ch of s) {
@@ -457,13 +445,24 @@ export class RunDisplay {
457
445
  return false;
458
446
  const key = s[0];
459
447
  const code = key.charCodeAt(0);
460
- if (code < 0x20 || code > 0x7E)
461
- return false;
448
+ // Allow \r / \n through for Enter-to-reveal
449
+ if (code === 0x0D || code === 0x0A) {
450
+ if (this.askTempFile) {
451
+ try {
452
+ execSync(`open -R ${JSON.stringify(this.askTempFile)}`);
453
+ }
454
+ catch { }
455
+ }
456
+ return true;
457
+ }
458
+ // ESC clears ask answer panel when in hotkey mode (check before the control-char filter below)
462
459
  if (key === "\x1B" && this.askState && !this.askState.streaming) {
463
460
  this.askState = undefined;
464
461
  this.clearAskTempFile();
465
462
  return false;
466
463
  }
464
+ if (code < 0x20 || code > 0x7E)
465
+ return false;
467
466
  if (key === "b" || key === "B") {
468
467
  this.inputMode = "budget";
469
468
  this.inputSegs = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.16.10",
3
+ "version": "1.16.12",
4
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": {