claude-overnight 1.24.1 → 1.24.4

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.1";
1
+ export declare const VERSION = "1.24.4";
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.1";
2
+ export const VERSION = "1.24.4";
package/dist/index.js CHANGED
@@ -764,8 +764,14 @@ 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)}`));
@@ -47,7 +47,9 @@ 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;
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
  }
@@ -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", ["cursor-composer-in-claude"], {
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-overnight",
3
- "version": "1.24.1",
3
+ "version": "1.24.4",
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
- "cursor-composer-in-claude": "^0.7.3",
19
18
  "chalk": "^5.4.1",
19
+ "cursor-composer-in-claude": "^0.7.6",
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.24.1",
3
+ "version": "1.24.4",
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"