claude-overnight 1.24.4 → 1.24.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.
@@ -1 +1 @@
1
- export declare const VERSION = "1.24.4";
1
+ export declare const VERSION = "1.24.5";
package/dist/_version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by build — do not edit manually.
2
- export const VERSION = "1.24.4";
2
+ export const VERSION = "1.24.5";
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 cursor-composer-in-claude`));
226
+ console.warn(chalk.yellow(` Start it: npm exec cursor-composer-in-claude (from this tool's install directory)`));
227
227
  console.warn(chalk.dim(` (Continuing — you can still use Anthropic models)\n`));
228
228
  }
229
229
  }
@@ -776,7 +776,7 @@ async function main() {
776
776
  if (!result.ok) {
777
777
  console.error(chalk.red(` ✗ ${role} preflight failed: ${chalk.dim(result.error)}`));
778
778
  if (isCursorProxyProvider(provider)) {
779
- console.error(chalk.yellow(` The proxy at ${PROXY_DEFAULT_URL} may have crashed. Start it: npx cursor-composer-in-claude`));
779
+ console.error(chalk.yellow(` The proxy at ${PROXY_DEFAULT_URL} may have crashed or timed out (e.g. keychain/UI). Retry, or start the same version as this install: npm exec cursor-composer-in-claude (from the claude-overnight folder, not bare npx — avoids a stale global cache).`));
780
780
  }
781
781
  else {
782
782
  console.error(chalk.red(` Fix the provider at ~/.claude/claude-overnight/providers.json and retry.`));
package/dist/providers.js CHANGED
@@ -9,6 +9,7 @@ import { ask, select, selectKey } from "./cli.js";
9
9
  import { getBearerToken, clearTokenCache } from "./auth.js";
10
10
  import { DEFAULT_MODEL } from "./models.js";
11
11
  import { CURSOR_PRIORITY_MODELS, CURSOR_KNOWN_MODELS, KNOWN_CURSOR_MODEL_IDS, cursorModelHint, } from "./cursor-models.js";
12
+ import { VERSION } from "./_version.js";
12
13
  /** Run the installed package CLI with `node` (avoids npx/npm invoking extra tooling on macOS). */
13
14
  function resolveCursorComposerCli() {
14
15
  try {
@@ -22,6 +23,18 @@ function resolveCursorComposerCli() {
22
23
  return null;
23
24
  }
24
25
  }
26
+ /** Version from the dependency bundled with claude-overnight (not `npx` cache). */
27
+ function getEmbeddedComposerProxyVersion() {
28
+ try {
29
+ const require = createRequire(import.meta.url);
30
+ const pkgJsonPath = require.resolve("cursor-composer-in-claude/package.json");
31
+ const j = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
32
+ return typeof j.version === "string" ? j.version : null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
25
38
  // ── Store ──
26
39
  const STORE_PATH = join(homedir(), ".claude", "claude-overnight", "providers.json");
27
40
  export function getStorePath() { return STORE_PATH; }
@@ -84,6 +97,9 @@ export function envFor(p) {
84
97
  const key = process.env.CURSOR_BRIDGE_API_KEY || p.cursorApiKey;
85
98
  base.ANTHROPIC_AUTH_TOKEN = key || "unused";
86
99
  delete base.ANTHROPIC_API_KEY;
100
+ // SDK replaces env for subprocesses — force these so nothing inherits a bad CI / skip flag.
101
+ base.CI = "true";
102
+ base.CURSOR_SKIP_KEYCHAIN = "1";
87
103
  return base;
88
104
  }
89
105
  const key = resolveKey(p);
@@ -321,6 +337,45 @@ export async function healthCheckCursorProxy(baseUrl = PROXY_DEFAULT_URL) {
321
337
  return false;
322
338
  }
323
339
  }
340
+ /** GET /health JSON — used to detect stale `npx` proxies older than this package's dependency. */
341
+ async function getCursorProxyHealthInfo(baseUrl = PROXY_DEFAULT_URL) {
342
+ try {
343
+ const url = `${baseUrl.replace(/\/$/, "")}/health`;
344
+ const res = await fetch(url, { method: "GET", signal: AbortSignal.timeout(3_000), ...cursorProxyFetchOpts() });
345
+ if (!res.ok)
346
+ return null;
347
+ const json = (await res.json());
348
+ return {
349
+ ok: json.ok,
350
+ version: typeof json.version === "string" ? json.version : undefined,
351
+ };
352
+ }
353
+ catch {
354
+ return null;
355
+ }
356
+ }
357
+ /**
358
+ * If something is listening and reports a different package version than our
359
+ * embedded `cursor-composer-in-claude`, kill the port and start the bundled CLI.
360
+ * Stops `npx` leaving an ancient proxy alive while preflight times out behind keychain/UI.
361
+ */
362
+ async function maybeRestartStaleProxy(baseUrl, url, port) {
363
+ const embedded = getEmbeddedComposerProxyVersion();
364
+ const info = await getCursorProxyHealthInfo(baseUrl);
365
+ const runningV = info?.version;
366
+ if (embedded && runningV && embedded !== runningV) {
367
+ console.log(chalk.yellow(` ⚠ Running proxy is v${runningV} but claude-overnight depends on cursor-composer-in-claude v${embedded} — restarting…`));
368
+ killProcessOnPort(port, url.hostname);
369
+ await new Promise(r => setTimeout(r, 500));
370
+ return startProxyProcess(baseUrl, url, port);
371
+ }
372
+ console.log(chalk.dim(JSON.stringify({
373
+ claudeOvernight: VERSION,
374
+ cursorComposerExpected: embedded,
375
+ cursorComposerRunning: runningV ?? "unknown",
376
+ })));
377
+ return true;
378
+ }
324
379
  /**
325
380
  * Fetch available Cursor models via GET /v1/models on the proxy.
326
381
  * Returns model IDs like ["auto", "composer", "composer-2", "opus-4.6", ...].
@@ -466,14 +521,14 @@ export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, forc
466
521
  const port = parseInt(url.port, 10) || 80;
467
522
  // Already healthy?
468
523
  if (await healthCheckCursorProxy(baseUrl)) {
469
- return true;
524
+ return await maybeRestartStaleProxy(baseUrl, url, port);
470
525
  }
471
526
  // Something bound the port — verify it's actually the cursor proxy
472
527
  if (await isPortInUse(port, url.hostname)) {
473
528
  const isProxy = await verifyCursorProxy(baseUrl);
474
529
  if (isProxy) {
475
530
  console.log(chalk.dim(` Proxy verified at port ${port}`));
476
- return true;
531
+ return await maybeRestartStaleProxy(baseUrl, url, port);
477
532
  }
478
533
  // Stale process on the port — kill it if forceRestart, or try automatically
479
534
  if (!forceRestart) {
@@ -516,41 +571,19 @@ async function startProxyProcess(baseUrl, url, port) {
516
571
  const apiKeyEnv = process.env.CURSOR_BRIDGE_API_KEY;
517
572
  const apiKeyStored = loadProviders().find(p => p.cursorProxy)?.cursorApiKey;
518
573
  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}`));
574
+ const proxyVersion = getEmbeddedComposerProxyVersion() ?? "unknown";
548
575
  const composerCli = resolveCursorComposerCli();
549
576
  if (!composerCli) {
550
577
  console.log(chalk.yellow(` ⚠ cursor-composer-in-claude is not installed (missing from node_modules). Run: npm install`));
551
578
  return false;
552
579
  }
553
- console.log(chalk.dim(` Command: ${process.execPath} ${composerCli}`));
580
+ let cliResolved;
581
+ try {
582
+ cliResolved = realpathSync(composerCli);
583
+ }
584
+ catch {
585
+ cliResolved = composerCli;
586
+ }
554
587
  const proxyEnv = {
555
588
  ...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined)),
556
589
  CI: "true",
@@ -561,6 +594,18 @@ async function startProxyProcess(baseUrl, url, port) {
561
594
  proxyEnv.CURSOR_AGENT_NODE = sysNode;
562
595
  proxyEnv.CURSOR_AGENT_SCRIPT = agentJs;
563
596
  }
597
+ console.log(chalk.dim(JSON.stringify({
598
+ claudeOvernight: VERSION,
599
+ spawnProxy: {
600
+ pkg: "cursor-composer-in-claude",
601
+ version: proxyVersion,
602
+ cliPath: cliResolved,
603
+ nodeExec: process.execPath,
604
+ apiKey: keySource,
605
+ agentPaths: sysNode && agentJs ? { node: sysNode, script: agentJs } : undefined,
606
+ childEnv: { CI: proxyEnv.CI, CURSOR_SKIP_KEYCHAIN: proxyEnv.CURSOR_SKIP_KEYCHAIN },
607
+ },
608
+ })));
564
609
  try {
565
610
  console.log(chalk.dim(` Spawning proxy…`));
566
611
  const child = spawn(process.execPath, [composerCli], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.24.4",
3
+ "version": "1.24.5",
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": {
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "@anthropic-ai/claude-agent-sdk": "^0.2.92",
18
18
  "chalk": "^5.4.1",
19
- "cursor-composer-in-claude": "^0.7.6",
19
+ "cursor-composer-in-claude": "0.7.7",
20
20
  "jsonwebtoken": "^9.0.2"
21
21
  },
22
22
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.24.4",
3
+ "version": "1.24.5",
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"