claude-overnight 1.23.0 → 1.23.1
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/dist/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.23.
|
|
1
|
+
export declare const VERSION = "1.23.1";
|
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.
|
|
2
|
+
export const VERSION = "1.23.1";
|
package/dist/providers.d.ts
CHANGED
|
@@ -69,18 +69,14 @@ export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
|
|
|
69
69
|
/**
|
|
70
70
|
* Auto-start the cursor-api-proxy as a detached background process.
|
|
71
71
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* segfaults with --list-models on macOS (exit 139), so we resolve the
|
|
75
|
-
* system `node` binary and the agent's index.js, patch the proxy's env.js
|
|
76
|
-
* to respect CURSOR_AGENT_NODE/SCRIPT on Unix, and pass those env vars.
|
|
72
|
+
* Passes CURSOR_AGENT_NODE/SCRIPT so the fork uses system Node.js for the
|
|
73
|
+
* agent subprocess (avoids segfaults with --list-models on macOS).
|
|
77
74
|
*
|
|
78
75
|
* Handles:
|
|
79
76
|
* - Proxy already running and verified → returns true immediately
|
|
80
|
-
* - Something on the port but not our proxy → warns,
|
|
81
|
-
* -
|
|
82
|
-
* -
|
|
83
|
-
* - Spawn fails (not installed) → returns false, caller falls back to manual instructions
|
|
77
|
+
* - Something on the port but not our proxy → warns, kills, restarts
|
|
78
|
+
* - Proxy not running → spawns detached, waits for health
|
|
79
|
+
* - Spawn fails → returns false, caller falls back to manual instructions
|
|
84
80
|
*
|
|
85
81
|
* When `forceRestart` is true and a stale process is on the port, it will be
|
|
86
82
|
* killed and the proxy restarted.
|
package/dist/providers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, realpathSync
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, realpathSync } from "fs";
|
|
2
2
|
import { homedir } from "os";
|
|
3
3
|
import { join, dirname } from "path";
|
|
4
4
|
import { execSync, spawn } from "child_process";
|
|
@@ -413,148 +413,17 @@ async function isPortInUse(port, host = "127.0.0.1") {
|
|
|
413
413
|
return false;
|
|
414
414
|
}
|
|
415
415
|
}
|
|
416
|
-
/**
|
|
417
|
-
* Find the system `node` binary path. Uses `which` to bypass any bundled node.
|
|
418
|
-
*/
|
|
419
|
-
function resolveSystemNode() {
|
|
420
|
-
try {
|
|
421
|
-
return execSync("which node 2>/dev/null", {
|
|
422
|
-
timeout: 3_000, encoding: "utf-8", shell: "bash",
|
|
423
|
-
}).trim() || null;
|
|
424
|
-
}
|
|
425
|
-
catch {
|
|
426
|
-
return null;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Find the cursor-agent's index.js. Mirrors the logic in fetchLiveCursorModels:
|
|
431
|
-
* resolves the `agent` symlink to find the version directory containing index.js.
|
|
432
|
-
*/
|
|
433
|
-
function resolveAgentIndexJs() {
|
|
434
|
-
try {
|
|
435
|
-
const agentPath = execSync("command -v agent 2>/dev/null || command -v cursor-agent 2>/dev/null", {
|
|
436
|
-
timeout: 3_000, encoding: "utf-8", shell: "bash",
|
|
437
|
-
}).trim();
|
|
438
|
-
if (!agentPath)
|
|
439
|
-
return null;
|
|
440
|
-
const dir = dirname(realpathSync(agentPath));
|
|
441
|
-
const indexPath = `${dir}/index.js`;
|
|
442
|
-
return existsSync(indexPath) ? indexPath : null;
|
|
443
|
-
}
|
|
444
|
-
catch {
|
|
445
|
-
return null;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Patch the proxy's env.js to use CURSOR_AGENT_NODE + CURSOR_AGENT_SCRIPT on Unix.
|
|
450
|
-
*
|
|
451
|
-
* The proxy already reads these env vars (lines 152-153 of env.js) but only uses
|
|
452
|
-
* them on Windows in resolveAgentCommand(). We inject a Unix code path before the
|
|
453
|
-
* final `return { command: cmd, args, env }` so that when these vars are set,
|
|
454
|
-
* the proxy spawns system node with the agent script instead of the bundled node
|
|
455
|
-
* (which segfaults with --list-models on macOS).
|
|
456
|
-
*
|
|
457
|
-
* Safe to call repeatedly — the patch is idempotent.
|
|
458
|
-
*/
|
|
459
|
-
function patchProxyEnvJs(proxyDir) {
|
|
460
|
-
const envJs = join(proxyDir, "dist", "lib", "env.js");
|
|
461
|
-
if (!existsSync(envJs))
|
|
462
|
-
return false;
|
|
463
|
-
const src = readFileSync(envJs, "utf-8");
|
|
464
|
-
// Check if already patched
|
|
465
|
-
if (src.includes("/* claude-overnight patch */"))
|
|
466
|
-
return true;
|
|
467
|
-
const patch = `\n/* claude-overnight patch: use CURSOR_AGENT_NODE+SCRIPT on unix */\n` +
|
|
468
|
-
`if (platform !== "win32" && loaded.agentNode && loaded.agentScript) {\n` +
|
|
469
|
-
` return { command: loaded.agentNode, args: [loaded.agentScript, ...args], env: { ...env, CURSOR_INVOKED_AS: "agent" }, agentScriptPath: loaded.agentScript };\n` +
|
|
470
|
-
`}`;
|
|
471
|
-
// Insert before the final return in resolveAgentCommand
|
|
472
|
-
const target = " return { command: cmd, args, env };\n}";
|
|
473
|
-
if (!src.includes(target)) {
|
|
474
|
-
// Try minified variant
|
|
475
|
-
const target2 = "return{command:cmd,args,env}}";
|
|
476
|
-
if (!src.includes(target2))
|
|
477
|
-
return false;
|
|
478
|
-
writeFileSync(envJs, src.replace(target2, patch + "\n" + target2), "utf-8");
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
writeFileSync(envJs, src.replace(target, patch + "\n" + target), "utf-8");
|
|
482
|
-
}
|
|
483
|
-
return true;
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Patch the proxy's token-cache.js to skip the macOS keychain read.
|
|
487
|
-
*
|
|
488
|
-
* The proxy calls `security find-generic-password -s "cursor-access-token" -w`
|
|
489
|
-
* after every agent run to cache tokens for its multi-account pool feature.
|
|
490
|
-
* This triggers a macOS keychain popup even though the key is not needed for
|
|
491
|
-
* auth (the cursor-agent subprocess handles its own auth). We neutralize it.
|
|
492
|
-
*
|
|
493
|
-
* Safe to call repeatedly — the patch is idempotent.
|
|
494
|
-
*/
|
|
495
|
-
function patchProxyTokenCacheJs(proxyDir) {
|
|
496
|
-
const tcJs = join(proxyDir, "dist", "lib", "token-cache.js");
|
|
497
|
-
if (!existsSync(tcJs))
|
|
498
|
-
return false;
|
|
499
|
-
const src = readFileSync(tcJs, "utf-8");
|
|
500
|
-
// Check if already patched
|
|
501
|
-
if (src.includes("/* claude-overnight patch: skip keychain */"))
|
|
502
|
-
return true;
|
|
503
|
-
const patch = `\n/* claude-overnight patch: skip keychain */\n` +
|
|
504
|
-
`return undefined;`;
|
|
505
|
-
// Replace the entire execSync chain inside readKeychainToken (multi-line)
|
|
506
|
-
const target = `const t = execSync('security find-generic-password -s "cursor-access-token" -w', { stdio: ["pipe", "pipe", "pipe"], timeout: 5000 })
|
|
507
|
-
.toString()
|
|
508
|
-
.trim();`;
|
|
509
|
-
if (!src.includes(target))
|
|
510
|
-
return false;
|
|
511
|
-
writeFileSync(tcJs, src.replace(target, patch + "\n// " + target.replace(/\n/g, "\n// ")), "utf-8");
|
|
512
|
-
return true;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Find the cursor-api-proxy package directory (npx cache or global install).
|
|
516
|
-
*/
|
|
517
|
-
function findProxyPackageDir() {
|
|
518
|
-
try {
|
|
519
|
-
// Try npx cache first
|
|
520
|
-
const npmCacheRoot = join(homedir(), ".npm", "_npx");
|
|
521
|
-
if (existsSync(npmCacheRoot)) {
|
|
522
|
-
const dirs = readdirSync(npmCacheRoot);
|
|
523
|
-
for (const d of dirs) {
|
|
524
|
-
const candidate = join(npmCacheRoot, d, "node_modules", "cursor-api-proxy");
|
|
525
|
-
if (existsSync(join(candidate, "dist", "lib", "env.js")))
|
|
526
|
-
return candidate;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
catch { }
|
|
531
|
-
// Try global install
|
|
532
|
-
try {
|
|
533
|
-
const globalDir = execSync("npm root -g 2>/dev/null", {
|
|
534
|
-
timeout: 5_000, encoding: "utf-8", shell: "bash",
|
|
535
|
-
}).trim();
|
|
536
|
-
if (globalDir && existsSync(join(globalDir, "cursor-api-proxy", "dist", "lib", "env.js"))) {
|
|
537
|
-
return join(globalDir, "cursor-api-proxy");
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
catch { }
|
|
541
|
-
return null;
|
|
542
|
-
}
|
|
543
416
|
/**
|
|
544
417
|
* Auto-start the cursor-api-proxy as a detached background process.
|
|
545
418
|
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
* segfaults with --list-models on macOS (exit 139), so we resolve the
|
|
549
|
-
* system `node` binary and the agent's index.js, patch the proxy's env.js
|
|
550
|
-
* to respect CURSOR_AGENT_NODE/SCRIPT on Unix, and pass those env vars.
|
|
419
|
+
* Passes CURSOR_AGENT_NODE/SCRIPT so the fork uses system Node.js for the
|
|
420
|
+
* agent subprocess (avoids segfaults with --list-models on macOS).
|
|
551
421
|
*
|
|
552
422
|
* Handles:
|
|
553
423
|
* - Proxy already running and verified → returns true immediately
|
|
554
|
-
* - Something on the port but not our proxy → warns,
|
|
555
|
-
* -
|
|
556
|
-
* -
|
|
557
|
-
* - Spawn fails (not installed) → returns false, caller falls back to manual instructions
|
|
424
|
+
* - Something on the port but not our proxy → warns, kills, restarts
|
|
425
|
+
* - Proxy not running → spawns detached, waits for health
|
|
426
|
+
* - Spawn fails → returns false, caller falls back to manual instructions
|
|
558
427
|
*
|
|
559
428
|
* When `forceRestart` is true and a stale process is on the port, it will be
|
|
560
429
|
* killed and the proxy restarted.
|
|
@@ -564,20 +433,8 @@ function findProxyPackageDir() {
|
|
|
564
433
|
export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, forceRestart = false) {
|
|
565
434
|
const url = new URL(baseUrl);
|
|
566
435
|
const port = parseInt(url.port, 10) || 80;
|
|
567
|
-
// Always patch the npx cache on startup so proxy skips keychain reads.
|
|
568
|
-
// Idempotent — safe to call on every run.
|
|
569
|
-
const proxyDir = findProxyPackageDir();
|
|
570
|
-
if (proxyDir)
|
|
571
|
-
patchProxyTokenCacheJs(proxyDir);
|
|
572
436
|
// Already healthy?
|
|
573
437
|
if (await healthCheckCursorProxy(baseUrl)) {
|
|
574
|
-
// Proxy was running before the patch — restart it to load the patched token-cache.js.
|
|
575
|
-
console.log(chalk.dim(` Proxy already running — restarting to pick up keychain patch…`));
|
|
576
|
-
const killedPid = killProcessOnPort(port, url.hostname);
|
|
577
|
-
if (killedPid) {
|
|
578
|
-
await new Promise(r => setTimeout(r, 500));
|
|
579
|
-
return startProxyProcess(baseUrl, url, port);
|
|
580
|
-
}
|
|
581
438
|
return true;
|
|
582
439
|
}
|
|
583
440
|
// Something bound the port — verify it's actually the cursor proxy
|
|
@@ -607,32 +464,33 @@ export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, forc
|
|
|
607
464
|
/** Spawn the proxy process and wait for it to become healthy. */
|
|
608
465
|
async function startProxyProcess(baseUrl, url, port) {
|
|
609
466
|
console.log(chalk.yellow(`\n Proxy not running at ${baseUrl} — starting it for you…`));
|
|
610
|
-
// Resolve system node and agent index.js so the proxy
|
|
611
|
-
// agent
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}
|
|
467
|
+
// Resolve system node and agent index.js so the proxy uses system Node.js
|
|
468
|
+
// for the agent subprocess (avoids segfaults with --list-models on macOS).
|
|
469
|
+
let sysNode = null;
|
|
470
|
+
let agentJs = null;
|
|
471
|
+
try {
|
|
472
|
+
sysNode = execSync("which node 2>/dev/null", { timeout: 3_000, encoding: "utf-8", shell: "bash" }).trim() || null;
|
|
473
|
+
const agentPath = execSync("command -v agent 2>/dev/null || command -v cursor-agent 2>/dev/null", {
|
|
474
|
+
timeout: 3_000, encoding: "utf-8", shell: "bash",
|
|
475
|
+
}).trim();
|
|
476
|
+
if (agentPath) {
|
|
477
|
+
const agentDir = dirname(realpathSync(agentPath));
|
|
478
|
+
const indexPath = `${agentDir}/index.js`;
|
|
479
|
+
if (existsSync(indexPath))
|
|
480
|
+
agentJs = indexPath;
|
|
625
481
|
}
|
|
626
482
|
}
|
|
483
|
+
catch { }
|
|
627
484
|
const proxyEnv = {
|
|
628
485
|
...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined)),
|
|
629
486
|
CURSOR_BRIDGE_API_KEY: process.env.CURSOR_BRIDGE_API_KEY
|
|
630
487
|
|| loadProviders().find(p => p.cursorProxy)?.cursorApiKey
|
|
631
488
|
|| "unused",
|
|
632
489
|
};
|
|
633
|
-
if (
|
|
490
|
+
if (sysNode && agentJs) {
|
|
634
491
|
proxyEnv.CURSOR_AGENT_NODE = sysNode;
|
|
635
492
|
proxyEnv.CURSOR_AGENT_SCRIPT = agentJs;
|
|
493
|
+
console.log(chalk.dim(` Using system node for agent subprocess: ${sysNode}`));
|
|
636
494
|
}
|
|
637
495
|
try {
|
|
638
496
|
const child = spawn("npx", ["cursor-api-proxy"], {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.1",
|
|
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,6 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@anthropic-ai/claude-agent-sdk": "^0.2.92",
|
|
18
|
+
"@claude-overnight/cursor-api-proxy": "file:../cursor-api-proxy",
|
|
18
19
|
"chalk": "^5.4.1",
|
|
19
20
|
"jsonwebtoken": "^9.0.2"
|
|
20
21
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.1",
|
|
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"
|