claude-overnight 1.23.4 → 1.24.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.
@@ -1 +1 @@
1
- export declare const VERSION = "1.23.4";
1
+ export declare const VERSION = "1.24.3";
package/dist/_version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by build — do not edit manually.
2
- export const VERSION = "1.23.4";
2
+ export const VERSION = "1.24.3";
package/dist/index.js CHANGED
@@ -223,7 +223,7 @@ async function main() {
223
223
  const proxyUp = await healthCheckCursorProxy();
224
224
  if (!proxyUp) {
225
225
  console.warn(chalk.yellow(`\n ⚠ ${savedCursorProviders.length} Cursor provider(s) saved but proxy is not running at ${PROXY_DEFAULT_URL}`));
226
- console.warn(chalk.yellow(` Start it: npx @claude-overnight/cursor-api-proxy`));
226
+ console.warn(chalk.yellow(` Start it: npx cursor-composer-in-claude`));
227
227
  console.warn(chalk.dim(` (Continuing — you can still use Anthropic models)\n`));
228
228
  }
229
229
  }
@@ -764,13 +764,19 @@ async function main() {
764
764
  if (cursorProxies.length > 0) {
765
765
  await ensureCursorProxyRunning();
766
766
  }
767
- process.stdout.write(` ${chalk.dim(`◆ Pinging ${pending.map(([r, p]) => `${r} (${p.displayName})`).join(", ")}...`)}\n`);
768
- const results = await Promise.all(pending.map(async ([role, p]) => ({ role, provider: p, result: await preflightProvider(p, cwd) })));
767
+ process.stdout.write(` ${chalk.dim(`◆ Pinging ${pending.map(([r, p]) => `${r} (${p.displayName})`).join(", ")}…`)}\n`);
768
+ const results = await Promise.all(pending.map(async ([role, p]) => ({
769
+ role,
770
+ provider: p,
771
+ result: await preflightProvider(p, cwd, 20_000, {
772
+ onProgress: (msg) => process.stdout.write(chalk.dim(` ${msg}\n`)),
773
+ }),
774
+ })));
769
775
  for (const { role, provider, result } of results) {
770
776
  if (!result.ok) {
771
777
  console.error(chalk.red(` ✗ ${role} preflight failed: ${chalk.dim(result.error)}`));
772
778
  if (isCursorProxyProvider(provider)) {
773
- console.error(chalk.yellow(` The proxy at ${PROXY_DEFAULT_URL} may have crashed. Start it: npx @claude-overnight/cursor-api-proxy`));
779
+ console.error(chalk.yellow(` The proxy at ${PROXY_DEFAULT_URL} may have crashed. Start it: npx cursor-composer-in-claude`));
774
780
  }
775
781
  else {
776
782
  console.error(chalk.red(` Fix the provider at ~/.claude/claude-overnight/providers.json and retry.`));
@@ -15,9 +15,9 @@ export interface ProviderConfig {
15
15
  key?: string;
16
16
  /** When true, use JWT token auth instead of raw API keys. The bearer token is embedded in a short-lived JWT. */
17
17
  useJWT?: boolean;
18
- /** When true, this provider routes through cursor-api-proxy (special env/health-check handling). */
18
+ /** When true, this provider routes through cursor-composer-in-claude (special env/health-check handling). */
19
19
  cursorProxy?: boolean;
20
- /** API key for cursor-api-proxy. Stored in providers.json (0600), used as fallback when CURSOR_BRIDGE_API_KEY env is not set. */
20
+ /** API key for cursor-composer-in-claude. Stored in providers.json (0600), used as fallback when CURSOR_BRIDGE_API_KEY env is not set. */
21
21
  cursorApiKey?: string;
22
22
  }
23
23
  export declare function getStorePath(): string;
@@ -47,14 +47,16 @@ export declare function pickModel(label: string, anthropicModels: ModelInfo[], c
47
47
  * if the key is wrong or the endpoint is unreachable. Timeout is aggressive
48
48
  * so misconfig doesn't delay the main run.
49
49
  */
50
- export declare function preflightProvider(p: ProviderConfig, cwd: string, timeoutMs?: number): Promise<{
50
+ export declare function preflightProvider(p: ProviderConfig, cwd: string, timeoutMs?: number, opts?: {
51
+ onProgress?: (msg: string) => void;
52
+ }): Promise<{
51
53
  ok: true;
52
54
  } | {
53
55
  ok: false;
54
56
  error: string;
55
57
  }>;
56
58
  export declare const PROXY_DEFAULT_URL = "http://127.0.0.1:8765";
57
- /** Check if a provider routes through cursor-api-proxy. */
59
+ /** Check if a provider routes through cursor-composer-in-claude. */
58
60
  export declare function isCursorProxyProvider(p: ProviderConfig): boolean;
59
61
  /**
60
62
  * Health check: GET /health on the proxy. Returns true if proxy is reachable.
@@ -67,7 +69,7 @@ export declare function healthCheckCursorProxy(baseUrl?: string): Promise<boolea
67
69
  */
68
70
  export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
69
71
  /**
70
- * Auto-start the cursor-api-proxy as a detached background process.
72
+ * Auto-start the cursor-composer-in-claude as a detached background process.
71
73
  *
72
74
  * Passes CURSOR_AGENT_NODE/SCRIPT so the fork uses system Node.js for the
73
75
  * agent subprocess (avoids segfaults with --list-models on macOS).
@@ -85,7 +87,7 @@ export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
85
87
  */
86
88
  export declare function ensureCursorProxyRunning(baseUrl?: string, forceRestart?: boolean): Promise<boolean>;
87
89
  /**
88
- * Full install + configure flow for cursor-api-proxy.
90
+ * Full install + configure flow for cursor-composer-in-claude.
89
91
  * Walks through CLI install, API key config, and proxy start.
90
92
  * Only needed when the quick auto-start (`ensureCursorProxyRunning`) fails —
91
93
  * e.g. npx can't find the package or the user has no API key yet.
package/dist/providers.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, realpathSync } from "fs";
2
+ import { createRequire } from "node:module";
2
3
  import { homedir } from "os";
3
4
  import { join, dirname } from "path";
4
5
  import { execSync, spawn } from "child_process";
@@ -8,6 +9,19 @@ import { ask, select, selectKey } from "./cli.js";
8
9
  import { getBearerToken, clearTokenCache } from "./auth.js";
9
10
  import { DEFAULT_MODEL } from "./models.js";
10
11
  import { CURSOR_PRIORITY_MODELS, CURSOR_KNOWN_MODELS, KNOWN_CURSOR_MODEL_IDS, cursorModelHint, } from "./cursor-models.js";
12
+ /** Run the installed package CLI with `node` (avoids npx/npm invoking extra tooling on macOS). */
13
+ function resolveCursorComposerCli() {
14
+ try {
15
+ const require = createRequire(import.meta.url);
16
+ const pkgJson = require.resolve("cursor-composer-in-claude/package.json");
17
+ const root = dirname(pkgJson);
18
+ const cli = join(root, "dist", "cli.js");
19
+ return existsSync(cli) ? cli : null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
11
25
  // ── Store ──
12
26
  const STORE_PATH = join(homedir(), ".claude", "claude-overnight", "providers.json");
13
27
  export function getStorePath() { return STORE_PATH; }
@@ -201,7 +215,7 @@ function normalizeBaseURL(raw) {
201
215
  * if the key is wrong or the endpoint is unreachable. Timeout is aggressive
202
216
  * so misconfig doesn't delay the main run.
203
217
  */
204
- export async function preflightProvider(p, cwd, timeoutMs = 20_000) {
218
+ export async function preflightProvider(p, cwd, timeoutMs = 20_000, opts) {
205
219
  let env;
206
220
  try {
207
221
  env = envFor(p);
@@ -209,6 +223,13 @@ export async function preflightProvider(p, cwd, timeoutMs = 20_000) {
209
223
  catch (err) {
210
224
  return { ok: false, error: err.message };
211
225
  }
226
+ // Show what we're checking
227
+ const keyInfo = p.cursorProxy
228
+ ? `proxy auth`
229
+ : p.keyEnv
230
+ ? `env ${p.keyEnv}`
231
+ : "stored key";
232
+ opts?.onProgress?.(`checking ${p.model} (${keyInfo})…`);
212
233
  let pq;
213
234
  try {
214
235
  pq = query({
@@ -224,19 +245,29 @@ export async function preflightProvider(p, cwd, timeoutMs = 20_000) {
224
245
  },
225
246
  });
226
247
  const stream = pq;
248
+ // Progress ticker during the wait
249
+ let elapsed = 0;
250
+ const PROGRESS_INTERVAL_MS = 3_000;
251
+ const progressTimer = setInterval(() => {
252
+ elapsed += PROGRESS_INTERVAL_MS;
253
+ opts?.onProgress?.(`still waiting… (${(elapsed / 1000).toFixed(1)}s)`);
254
+ }, PROGRESS_INTERVAL_MS);
227
255
  const consume = (async () => {
228
256
  for await (const msg of stream) {
229
257
  if (msg.type === "result") {
258
+ clearInterval(progressTimer);
230
259
  if (msg.subtype !== "success") {
231
260
  return { ok: false, error: String(msg.result || msg.subtype || "unknown error").slice(0, 200) };
232
261
  }
233
262
  return { ok: true };
234
263
  }
235
264
  }
265
+ clearInterval(progressTimer);
236
266
  return { ok: false, error: "no result received" };
237
267
  })();
238
268
  const timeout = new Promise((resolve) => {
239
269
  setTimeout(() => {
270
+ clearInterval(progressTimer);
240
271
  try {
241
272
  stream.interrupt().catch(() => stream.close());
242
273
  }
@@ -258,11 +289,11 @@ export async function preflightProvider(p, cwd, timeoutMs = 20_000) {
258
289
  }
259
290
  // ── Cursor API Proxy ──
260
291
  export const PROXY_DEFAULT_URL = "http://127.0.0.1:8765";
261
- /** Check if a provider routes through cursor-api-proxy. */
292
+ /** Check if a provider routes through cursor-composer-in-claude. */
262
293
  export function isCursorProxyProvider(p) {
263
294
  return p.cursorProxy === true || p.baseURL === PROXY_DEFAULT_URL;
264
295
  }
265
- /** Resolve the cursor-api-proxy API key from env or providers.json. */
296
+ /** Resolve the cursor-composer-in-claude API key from env or providers.json. */
266
297
  function resolveCursorProxyKey() {
267
298
  if (process.env.CURSOR_BRIDGE_API_KEY?.trim())
268
299
  return process.env.CURSOR_BRIDGE_API_KEY.trim();
@@ -350,7 +381,7 @@ async function fetchLiveCursorModels() {
350
381
  return [];
351
382
  }
352
383
  /**
353
- * Verify something is actually cursor-api-proxy (not just any HTTP service on the port).
384
+ * Verify something is actually cursor-composer-in-claude (not just any HTTP service on the port).
354
385
  * Tries /health first (proxy identity), then falls back to /v1/models shape check.
355
386
  * Returns true if it looks like the proxy.
356
387
  */
@@ -414,7 +445,7 @@ async function isPortInUse(port, host = "127.0.0.1") {
414
445
  }
415
446
  }
416
447
  /**
417
- * Auto-start the cursor-api-proxy as a detached background process.
448
+ * Auto-start the cursor-composer-in-claude as a detached background process.
418
449
  *
419
450
  * Passes CURSOR_AGENT_NODE/SCRIPT so the fork uses system Node.js for the
420
451
  * agent subprocess (avoids segfaults with --list-models on macOS).
@@ -446,7 +477,7 @@ export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, forc
446
477
  }
447
478
  // Stale process on the port — kill it if forceRestart, or try automatically
448
479
  if (!forceRestart) {
449
- console.log(chalk.yellow(` ⚠ Something is on port ${port} but it's not cursor-api-proxy — killing stale process…`));
480
+ console.log(chalk.yellow(` ⚠ Something is on port ${port} but it's not cursor-composer-in-claude — killing stale process…`));
450
481
  }
451
482
  const killedPid = killProcessOnPort(port, url.hostname);
452
483
  if (killedPid) {
@@ -481,34 +512,79 @@ async function startProxyProcess(baseUrl, url, port) {
481
512
  }
482
513
  }
483
514
  catch { }
515
+ // Resolve the API key source for logging
516
+ const apiKeyEnv = process.env.CURSOR_BRIDGE_API_KEY;
517
+ const apiKeyStored = loadProviders().find(p => p.cursorProxy)?.cursorApiKey;
518
+ const keySource = apiKeyEnv ? "env CURSOR_BRIDGE_API_KEY" : (apiKeyStored ? "providers.json (stored)" : "none — using 'unused'");
519
+ // Log the installed proxy version
520
+ let proxyVersion = "unknown";
521
+ try {
522
+ const pkgPath = execSync("node -e \"try{console.log(require('cursor-composer-in-claude/package.json').version)}catch(e){}\" 2>/dev/null", {
523
+ timeout: 3_000, encoding: "utf-8", shell: "bash",
524
+ }).trim();
525
+ if (pkgPath)
526
+ proxyVersion = pkgPath;
527
+ }
528
+ catch {
529
+ // Fallback: try resolving from npx cache location
530
+ try {
531
+ const out = execSync("npm ls cursor-composer-in-claude --depth=0 2>/dev/null | grep cursor-composer", {
532
+ timeout: 5_000, encoding: "utf-8", shell: "bash",
533
+ }).trim();
534
+ const verMatch = out.match(/@(\d+\.\d+\.\d+)/);
535
+ if (verMatch)
536
+ proxyVersion = verMatch[1];
537
+ }
538
+ catch { }
539
+ }
540
+ console.log(chalk.dim(` cursor-composer-in-claude v${proxyVersion}`));
541
+ console.log(chalk.dim(` API key: ${keySource}`));
542
+ console.log(chalk.dim(` CI=true (skips Cursor agent keychain probe on startup)`));
543
+ console.log(chalk.dim(` CURSOR_SKIP_KEYCHAIN=1 (proxy-side keychain access disabled)`));
544
+ if (sysNode)
545
+ console.log(chalk.dim(` System node: ${sysNode}`));
546
+ if (agentJs)
547
+ console.log(chalk.dim(` Agent script: ${agentJs}`));
548
+ const composerCli = resolveCursorComposerCli();
549
+ if (!composerCli) {
550
+ console.log(chalk.yellow(` ⚠ cursor-composer-in-claude is not installed (missing from node_modules). Run: npm install`));
551
+ return false;
552
+ }
553
+ console.log(chalk.dim(` Command: ${process.execPath} ${composerCli}`));
484
554
  const proxyEnv = {
485
555
  ...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined)),
486
- CURSOR_BRIDGE_API_KEY: process.env.CURSOR_BRIDGE_API_KEY
487
- || loadProviders().find(p => p.cursorProxy)?.cursorApiKey
488
- || "unused",
556
+ CI: "true",
557
+ CURSOR_BRIDGE_API_KEY: apiKeyEnv || apiKeyStored || "unused",
489
558
  CURSOR_SKIP_KEYCHAIN: "1",
490
559
  };
491
560
  if (sysNode && agentJs) {
492
561
  proxyEnv.CURSOR_AGENT_NODE = sysNode;
493
562
  proxyEnv.CURSOR_AGENT_SCRIPT = agentJs;
494
- console.log(chalk.dim(` Using system node for agent subprocess: ${sysNode}`));
495
563
  }
496
564
  try {
497
- const child = spawn("npx", ["@claude-overnight/cursor-api-proxy"], {
565
+ console.log(chalk.dim(` Spawning proxy…`));
566
+ const child = spawn(process.execPath, [composerCli], {
498
567
  detached: true,
499
568
  stdio: "ignore",
500
569
  env: proxyEnv,
501
570
  });
502
571
  child.unref(); // let it outlive this process
503
- // Wait up to 15s for the proxy to become healthy
504
- for (let i = 0; i < 30; i++) {
505
- await new Promise(r => setTimeout(r, 500));
572
+ // Wait up to 15s for the proxy to become healthy, showing progress
573
+ const HEALTH_POLL_MS = 500;
574
+ const HEALTH_MAX_POLLS = 30;
575
+ for (let i = 0; i < HEALTH_MAX_POLLS; i++) {
576
+ await new Promise(r => setTimeout(r, HEALTH_POLL_MS));
577
+ const elapsed = ((i + 1) * HEALTH_POLL_MS / 1000).toFixed(1);
506
578
  if (await healthCheckCursorProxy(baseUrl)) {
507
- console.log(chalk.green(` ✓ Proxy started (PID ${child.pid}) and healthy`));
579
+ console.log(chalk.green(` ✓ Proxy started (PID ${child.pid}) and healthy after ${elapsed}s`));
508
580
  return true;
509
581
  }
582
+ // Show a dot every 2s to indicate we're still waiting
583
+ if ((i + 1) % 4 === 0) {
584
+ process.stdout.write(chalk.dim(` · still waiting… (${elapsed}s)\n`));
585
+ }
510
586
  }
511
- console.log(chalk.yellow(` ⚠ Proxy process spawned but not responding after 15s`));
587
+ console.log(chalk.yellow(` ⚠ Proxy process spawned (PID ${child.pid}) but not responding after 15s`));
512
588
  console.log(chalk.dim(` It may still be initializing. You can check with: curl ${baseUrl}/health`));
513
589
  return false;
514
590
  }
@@ -545,19 +621,19 @@ function setupSteps() {
545
621
  successMsg: "Cursor API key configured",
546
622
  },
547
623
  {
548
- label: "cursor-api-proxy server",
624
+ label: "cursor-composer-in-claude server",
549
625
  check: () => {
550
626
  try {
551
- execSync("npx @claude-overnight/cursor-api-proxy --help", { stdio: "pipe", timeout: 10_000 });
627
+ execSync("npx cursor-composer-in-claude --help", { stdio: "pipe", timeout: 10_000 });
552
628
  return true;
553
629
  }
554
630
  catch {
555
631
  return false;
556
632
  }
557
633
  },
558
- autoCmd: "npx @claude-overnight/cursor-api-proxy",
559
- manualCmd: "npx @claude-overnight/cursor-api-proxy",
560
- successMsg: "cursor-api-proxy available",
634
+ autoCmd: "npx cursor-composer-in-claude",
635
+ manualCmd: "npx cursor-composer-in-claude",
636
+ successMsg: "cursor-composer-in-claude available",
561
637
  },
562
638
  ];
563
639
  }
@@ -598,14 +674,14 @@ async function promptAndSaveCursorKey() {
598
674
  return false;
599
675
  }
600
676
  /**
601
- * Full install + configure flow for cursor-api-proxy.
677
+ * Full install + configure flow for cursor-composer-in-claude.
602
678
  * Walks through CLI install, API key config, and proxy start.
603
679
  * Only needed when the quick auto-start (`ensureCursorProxyRunning`) fails —
604
680
  * e.g. npx can't find the package or the user has no API key yet.
605
681
  * Returns true when proxy is running and healthy.
606
682
  */
607
683
  export async function setupCursorProxy() {
608
- console.log(chalk.dim("\n Configure cursor-api-proxy"));
684
+ console.log(chalk.dim("\n Configure cursor-composer-in-claude"));
609
685
  console.log(chalk.dim(" " + "─".repeat(40)));
610
686
  console.log(chalk.dim(" We need three things: Cursor CLI, an API key, and the proxy server.\n"));
611
687
  const steps = setupSteps();
@@ -671,24 +747,24 @@ export async function setupCursorProxy() {
671
747
  if (choice === "a") {
672
748
  console.log(chalk.dim(` Checking install…`));
673
749
  try {
674
- execSync("npx @claude-overnight/cursor-api-proxy --help", { stdio: "pipe", timeout: 15_000 });
675
- console.log(chalk.green(` ✓ cursor-api-proxy is installed`));
750
+ execSync("npx cursor-composer-in-claude --help", { stdio: "pipe", timeout: 15_000 });
751
+ console.log(chalk.green(` ✓ cursor-composer-in-claude is installed`));
676
752
  }
677
753
  catch {
678
754
  console.log(chalk.dim(` Installing…`));
679
755
  try {
680
- execSync("npm install -g @claude-overnight/cursor-api-proxy", { stdio: "inherit", timeout: 120_000 });
756
+ execSync("npm install -g cursor-composer-in-claude", { stdio: "inherit", timeout: 120_000 });
681
757
  console.log(chalk.green(` ✓ Installed`));
682
758
  }
683
759
  catch {
684
- console.log(chalk.yellow(" Install failed — try manual: npm install -g @claude-overnight/cursor-api-proxy"));
760
+ console.log(chalk.yellow(" Install failed — try manual: npm install -g cursor-composer-in-claude"));
685
761
  return false;
686
762
  }
687
763
  }
688
764
  }
689
765
  else if (choice === "m") {
690
- console.log(chalk.cyan(`\n Install: ${chalk.bold("npm install -g @claude-overnight/cursor-api-proxy")}`));
691
- console.log(chalk.cyan(` Start: ${chalk.bold("npx @claude-overnight/cursor-api-proxy")}\n`));
766
+ console.log(chalk.cyan(`\n Install: ${chalk.bold("npm install -g cursor-composer-in-claude")}`));
767
+ console.log(chalk.cyan(` Start: ${chalk.bold("npx cursor-composer-in-claude")}\n`));
692
768
  const ok = await selectKey(` Started it?`, [
693
769
  { key: "r", desc: "eady" },
694
770
  { key: "c", desc: "ancel" },
@@ -706,7 +782,7 @@ export async function setupCursorProxy() {
706
782
  return true;
707
783
  // Auto-start failed or not responding — offer manual fallback
708
784
  console.log(chalk.yellow(`\n Couldn't start the proxy automatically. Start it manually:`));
709
- console.log(chalk.white(` ${chalk.bold("npx @claude-overnight/cursor-api-proxy")}`));
785
+ console.log(chalk.white(` ${chalk.bold("npx cursor-composer-in-claude")}`));
710
786
  for (;;) {
711
787
  const choice = await selectKey(` Proxy started?`, [
712
788
  { key: "r", desc: "etry (re-attempt auto-start + kill stale)" },
package/dist/swarm.d.ts CHANGED
@@ -17,7 +17,7 @@ export interface SwarmConfig {
17
17
  baseCostUsd?: number;
18
18
  /** Per-task env overrides: given a model id, return the env to pass to `query()` (or undefined for Anthropic default). */
19
19
  envForModel?: (model?: string) => Record<string, string> | undefined;
20
- /** When true, the run uses cursor-api-proxy. The swarm will attempt to restart it if it crashes mid-run. */
20
+ /** When true, the run uses cursor-composer-in-claude. The swarm will attempt to restart it if it crashes mid-run. */
21
21
  cursorProxy?: boolean;
22
22
  }
23
23
  export declare class Swarm {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.23.4",
3
+ "version": "1.24.3",
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. Provider-agnostic model catalog with capability-based planning.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,16 +15,16 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@anthropic-ai/claude-agent-sdk": "^0.2.92",
18
- "@claude-overnight/cursor-api-proxy": "github:Fornace/cursor-api-proxy",
19
18
  "chalk": "^5.4.1",
19
+ "cursor-composer-in-claude": "^0.7.5",
20
20
  "jsonwebtoken": "^9.0.2"
21
21
  },
22
22
  "devDependencies": {
23
+ "@types/jsonwebtoken": "^9.0.7",
23
24
  "@types/node": "^22.0.0",
24
25
  "node-pty": "^1.1.0",
25
26
  "strip-ansi": "^7.1.0",
26
- "typescript": "^5.7.0",
27
- "@types/jsonwebtoken": "^9.0.7"
27
+ "typescript": "^5.7.0"
28
28
  },
29
29
  "license": "MIT",
30
30
  "author": "Francesco Fornace",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.23.4",
3
+ "version": "1.24.3",
4
4
  "description": "Claude Code skill for understanding, installing, and inspecting claude-overnight runs -- parallel Claude agents in git worktrees with thinking waves, multi-wave steering, and crash-safe resume. Supports Cursor API Proxy, Qwen, OpenRouter.",
5
5
  "author": {
6
6
  "name": "Francesco Fornace"