claude-overnight 1.24.4 → 1.24.6
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 +1 -1
- package/dist/_version.js +1 -1
- package/dist/index.js +9 -3
- package/dist/providers.d.ts +7 -3
- package/dist/providers.js +163 -78
- package/package.json +2 -2
- package/plugins/claude-overnight/.claude-plugin/plugin.json +1 -1
package/dist/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.24.
|
|
1
|
+
export declare const VERSION = "1.24.6";
|
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.
|
|
2
|
+
export const VERSION = "1.24.6";
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Swarm } from "./swarm.js";
|
|
|
9
9
|
import { planTasks, refinePlan, identifyThemes, buildThinkingTasks, orchestrate, salvageFromFile } from "./planner.js";
|
|
10
10
|
import { modelDisplayName, formatContextWindow, DEFAULT_MODEL } from "./models.js";
|
|
11
11
|
import { setPlannerEnvResolver } from "./planner-query.js";
|
|
12
|
-
import { pickModel, loadProviders, preflightProvider, buildEnvResolver, healthCheckCursorProxy, PROXY_DEFAULT_URL, isCursorProxyProvider, ensureCursorProxyRunning } from "./providers.js";
|
|
12
|
+
import { pickModel, loadProviders, preflightProvider, buildEnvResolver, healthCheckCursorProxy, PROXY_DEFAULT_URL, isCursorProxyProvider, ensureCursorProxyRunning, bundledComposerProxyShellCommand, } from "./providers.js";
|
|
13
13
|
import { RunDisplay } from "./ui.js";
|
|
14
14
|
import { renderSummary } from "./render.js";
|
|
15
15
|
import { executeRun } from "./run.js";
|
|
@@ -223,7 +223,10 @@ 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
|
-
|
|
226
|
+
{
|
|
227
|
+
const cmd = bundledComposerProxyShellCommand();
|
|
228
|
+
console.warn(chalk.yellow(cmd ? ` Start bundled proxy: ${cmd}` : ` Run npm install where claude-overnight is installed, then retry`));
|
|
229
|
+
}
|
|
227
230
|
console.warn(chalk.dim(` (Continuing — you can still use Anthropic models)\n`));
|
|
228
231
|
}
|
|
229
232
|
}
|
|
@@ -776,7 +779,10 @@ async function main() {
|
|
|
776
779
|
if (!result.ok) {
|
|
777
780
|
console.error(chalk.red(` ✗ ${role} preflight failed: ${chalk.dim(result.error)}`));
|
|
778
781
|
if (isCursorProxyProvider(provider)) {
|
|
779
|
-
|
|
782
|
+
{
|
|
783
|
+
const cmd = bundledComposerProxyShellCommand();
|
|
784
|
+
console.error(chalk.yellow(` The proxy at ${PROXY_DEFAULT_URL} may have crashed or timed out (e.g. keychain/UI). Retry, or start the bundled proxy: ${cmd ?? "npm install in the claude-overnight package, then re-run"}`));
|
|
785
|
+
}
|
|
780
786
|
}
|
|
781
787
|
else {
|
|
782
788
|
console.error(chalk.red(` Fix the provider at ~/.claude/claude-overnight/providers.json and retry.`));
|
package/dist/providers.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ModelInfo } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Shell command to run the same bundled proxy CLI we spawn in-process (never `npx`/global).
|
|
4
|
+
*/
|
|
5
|
+
export declare function bundledComposerProxyShellCommand(): string | null;
|
|
2
6
|
/**
|
|
3
7
|
* A non-Anthropic model provider reachable via an Anthropic-compatible endpoint
|
|
4
8
|
* (e.g. DashScope for Qwen, OpenRouter, a local proxy). Stored user-level so a
|
|
@@ -80,8 +84,8 @@ export declare function fetchCursorModels(baseUrl?: string): Promise<string[]>;
|
|
|
80
84
|
* - Proxy not running → spawns detached, waits for health
|
|
81
85
|
* - Spawn fails → returns false, caller falls back to manual instructions
|
|
82
86
|
*
|
|
83
|
-
* When `forceRestart` is true
|
|
84
|
-
*
|
|
87
|
+
* When `forceRestart` is true, any listener on the port is killed and the
|
|
88
|
+
* bundled proxy is spawned (same as a version mismatch).
|
|
85
89
|
*
|
|
86
90
|
* Returns true when the proxy is reachable at PROXY_DEFAULT_URL.
|
|
87
91
|
*/
|
|
@@ -90,7 +94,7 @@ export declare function ensureCursorProxyRunning(baseUrl?: string, forceRestart?
|
|
|
90
94
|
* Full install + configure flow for cursor-composer-in-claude.
|
|
91
95
|
* Walks through CLI install, API key config, and proxy start.
|
|
92
96
|
* Only needed when the quick auto-start (`ensureCursorProxyRunning`) fails —
|
|
93
|
-
* e.g.
|
|
97
|
+
* e.g. dependencies not installed or the user has no API key yet.
|
|
94
98
|
* Returns true when proxy is running and healthy.
|
|
95
99
|
*/
|
|
96
100
|
export declare function setupCursorProxy(): Promise<boolean>;
|
package/dist/providers.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, realpath
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { join, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { execSync, spawn } from "child_process";
|
|
6
7
|
import chalk from "chalk";
|
|
7
8
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
@@ -9,6 +10,7 @@ import { ask, select, selectKey } from "./cli.js";
|
|
|
9
10
|
import { getBearerToken, clearTokenCache } from "./auth.js";
|
|
10
11
|
import { DEFAULT_MODEL } from "./models.js";
|
|
11
12
|
import { CURSOR_PRIORITY_MODELS, CURSOR_KNOWN_MODELS, KNOWN_CURSOR_MODEL_IDS, cursorModelHint, } from "./cursor-models.js";
|
|
13
|
+
import { VERSION } from "./_version.js";
|
|
12
14
|
/** Run the installed package CLI with `node` (avoids npx/npm invoking extra tooling on macOS). */
|
|
13
15
|
function resolveCursorComposerCli() {
|
|
14
16
|
try {
|
|
@@ -22,6 +24,31 @@ function resolveCursorComposerCli() {
|
|
|
22
24
|
return null;
|
|
23
25
|
}
|
|
24
26
|
}
|
|
27
|
+
/** Version from the dependency bundled with claude-overnight (not `npx` cache). */
|
|
28
|
+
function getEmbeddedComposerProxyVersion() {
|
|
29
|
+
try {
|
|
30
|
+
const require = createRequire(import.meta.url);
|
|
31
|
+
const pkgJsonPath = require.resolve("cursor-composer-in-claude/package.json");
|
|
32
|
+
const j = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
33
|
+
return typeof j.version === "string" ? j.version : null;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Directory containing this package's `package.json` (works for global and local installs). */
|
|
40
|
+
function getClaudeOvernightInstallRoot() {
|
|
41
|
+
return dirname(dirname(fileURLToPath(import.meta.url)));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Shell command to run the same bundled proxy CLI we spawn in-process (never `npx`/global).
|
|
45
|
+
*/
|
|
46
|
+
export function bundledComposerProxyShellCommand() {
|
|
47
|
+
const cli = resolveCursorComposerCli();
|
|
48
|
+
if (!cli)
|
|
49
|
+
return null;
|
|
50
|
+
return `node "${cli}"`;
|
|
51
|
+
}
|
|
25
52
|
// ── Store ──
|
|
26
53
|
const STORE_PATH = join(homedir(), ".claude", "claude-overnight", "providers.json");
|
|
27
54
|
export function getStorePath() { return STORE_PATH; }
|
|
@@ -84,6 +111,9 @@ export function envFor(p) {
|
|
|
84
111
|
const key = process.env.CURSOR_BRIDGE_API_KEY || p.cursorApiKey;
|
|
85
112
|
base.ANTHROPIC_AUTH_TOKEN = key || "unused";
|
|
86
113
|
delete base.ANTHROPIC_API_KEY;
|
|
114
|
+
// SDK replaces env for subprocesses — force these so nothing inherits a bad CI / skip flag.
|
|
115
|
+
base.CI = "true";
|
|
116
|
+
base.CURSOR_SKIP_KEYCHAIN = "1";
|
|
87
117
|
return base;
|
|
88
118
|
}
|
|
89
119
|
const key = resolveKey(p);
|
|
@@ -321,6 +351,57 @@ export async function healthCheckCursorProxy(baseUrl = PROXY_DEFAULT_URL) {
|
|
|
321
351
|
return false;
|
|
322
352
|
}
|
|
323
353
|
}
|
|
354
|
+
/** GET /health JSON — used to detect stale `npx` proxies older than this package's dependency. */
|
|
355
|
+
async function getCursorProxyHealthInfo(baseUrl = PROXY_DEFAULT_URL) {
|
|
356
|
+
try {
|
|
357
|
+
const url = `${baseUrl.replace(/\/$/, "")}/health`;
|
|
358
|
+
const res = await fetch(url, { method: "GET", signal: AbortSignal.timeout(3_000), ...cursorProxyFetchOpts() });
|
|
359
|
+
if (!res.ok)
|
|
360
|
+
return null;
|
|
361
|
+
const json = (await res.json());
|
|
362
|
+
return {
|
|
363
|
+
ok: json.ok,
|
|
364
|
+
version: typeof json.version === "string" ? json.version : undefined,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* If something is listening and we cannot prove it is this install's bundled
|
|
373
|
+
* `cursor-composer-in-claude` (version mismatch or missing `/health.version`),
|
|
374
|
+
* kill the listener and start the bundled CLI. Avoids stale global/`npx` proxies.
|
|
375
|
+
*/
|
|
376
|
+
async function maybeRestartStaleProxy(baseUrl, url, port) {
|
|
377
|
+
const embedded = getEmbeddedComposerProxyVersion();
|
|
378
|
+
const info = await getCursorProxyHealthInfo(baseUrl);
|
|
379
|
+
const runningV = info?.version;
|
|
380
|
+
if (!embedded) {
|
|
381
|
+
console.log(chalk.dim(JSON.stringify({
|
|
382
|
+
claudeOvernight: VERSION,
|
|
383
|
+
cursorComposerExpected: null,
|
|
384
|
+
cursorComposerRunning: runningV ?? "unknown",
|
|
385
|
+
})));
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
const trusted = Boolean(runningV && runningV === embedded);
|
|
389
|
+
if (trusted) {
|
|
390
|
+
console.log(chalk.dim(JSON.stringify({
|
|
391
|
+
claudeOvernight: VERSION,
|
|
392
|
+
cursorComposerExpected: embedded,
|
|
393
|
+
cursorComposerRunning: runningV,
|
|
394
|
+
})));
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
const reason = !runningV
|
|
398
|
+
? `proxy does not report a version in /health — replacing with bundled v${embedded}`
|
|
399
|
+
: `running proxy is v${runningV} but this install bundles cursor-composer-in-claude v${embedded}`;
|
|
400
|
+
console.log(chalk.yellow(` ⚠ ${reason} — restarting…`));
|
|
401
|
+
killProcessOnPort(port, url.hostname);
|
|
402
|
+
await new Promise(r => setTimeout(r, 500));
|
|
403
|
+
return startProxyProcess(baseUrl, url, port);
|
|
404
|
+
}
|
|
324
405
|
/**
|
|
325
406
|
* Fetch available Cursor models via GET /v1/models on the proxy.
|
|
326
407
|
* Returns model IDs like ["auto", "composer", "composer-2", "opus-4.6", ...].
|
|
@@ -401,22 +482,23 @@ async function verifyCursorProxy(baseUrl = PROXY_DEFAULT_URL) {
|
|
|
401
482
|
const res = await fetch(`${url}/v1/models`, { method: "GET", signal: AbortSignal.timeout(3_000), ...opts });
|
|
402
483
|
if (!res.ok)
|
|
403
484
|
return false;
|
|
404
|
-
const json = await res.json();
|
|
405
|
-
return Array.isArray(json
|
|
485
|
+
const json = (await res.json());
|
|
486
|
+
return Array.isArray(json["data"]);
|
|
406
487
|
}
|
|
407
488
|
catch {
|
|
408
489
|
return false;
|
|
409
490
|
}
|
|
410
491
|
}
|
|
411
492
|
/**
|
|
412
|
-
* Kill whatever process is
|
|
413
|
-
* `
|
|
414
|
-
*
|
|
493
|
+
* Kill whatever process is listening on the given port.
|
|
494
|
+
* Uses `lsof` with TCP LISTEN only — plain `lsof -ti :PORT` also matches
|
|
495
|
+
* *clients* whose remote peer is that port, so the first PID can be the
|
|
496
|
+
* caller (e.g. claude-overnight) and `kill -9` would suicide the CLI.
|
|
415
497
|
*/
|
|
416
498
|
function killProcessOnPort(port, host = "127.0.0.1") {
|
|
417
499
|
try {
|
|
418
|
-
//
|
|
419
|
-
const pid = execSync(`lsof -
|
|
500
|
+
// `-sTCP:LISTEN` is required: `lsof -ti :PORT` includes ESTABLISHED clients to localhost:PORT.
|
|
501
|
+
const pid = execSync(`lsof -nP -iTCP:${port} -sTCP:LISTEN -t 2>/dev/null`, {
|
|
420
502
|
timeout: 5_000, encoding: "utf-8",
|
|
421
503
|
}).trim().split("\n")[0];
|
|
422
504
|
if (!pid || !/^\d+$/.test(pid))
|
|
@@ -456,24 +538,30 @@ async function isPortInUse(port, host = "127.0.0.1") {
|
|
|
456
538
|
* - Proxy not running → spawns detached, waits for health
|
|
457
539
|
* - Spawn fails → returns false, caller falls back to manual instructions
|
|
458
540
|
*
|
|
459
|
-
* When `forceRestart` is true
|
|
460
|
-
*
|
|
541
|
+
* When `forceRestart` is true, any listener on the port is killed and the
|
|
542
|
+
* bundled proxy is spawned (same as a version mismatch).
|
|
461
543
|
*
|
|
462
544
|
* Returns true when the proxy is reachable at PROXY_DEFAULT_URL.
|
|
463
545
|
*/
|
|
464
546
|
export async function ensureCursorProxyRunning(baseUrl = PROXY_DEFAULT_URL, forceRestart = false) {
|
|
465
547
|
const url = new URL(baseUrl);
|
|
466
548
|
const port = parseInt(url.port, 10) || 80;
|
|
549
|
+
if (forceRestart && resolveCursorComposerCli()) {
|
|
550
|
+
console.log(chalk.dim(` Replacing listener on port ${port} with bundled cursor-composer-in-claude…`));
|
|
551
|
+
killProcessOnPort(port, url.hostname);
|
|
552
|
+
await new Promise(r => setTimeout(r, 500));
|
|
553
|
+
return startProxyProcess(baseUrl, url, port);
|
|
554
|
+
}
|
|
467
555
|
// Already healthy?
|
|
468
556
|
if (await healthCheckCursorProxy(baseUrl)) {
|
|
469
|
-
return
|
|
557
|
+
return await maybeRestartStaleProxy(baseUrl, url, port);
|
|
470
558
|
}
|
|
471
559
|
// Something bound the port — verify it's actually the cursor proxy
|
|
472
560
|
if (await isPortInUse(port, url.hostname)) {
|
|
473
561
|
const isProxy = await verifyCursorProxy(baseUrl);
|
|
474
562
|
if (isProxy) {
|
|
475
563
|
console.log(chalk.dim(` Proxy verified at port ${port}`));
|
|
476
|
-
return
|
|
564
|
+
return await maybeRestartStaleProxy(baseUrl, url, port);
|
|
477
565
|
}
|
|
478
566
|
// Stale process on the port — kill it if forceRestart, or try automatically
|
|
479
567
|
if (!forceRestart) {
|
|
@@ -516,41 +604,19 @@ async function startProxyProcess(baseUrl, url, port) {
|
|
|
516
604
|
const apiKeyEnv = process.env.CURSOR_BRIDGE_API_KEY;
|
|
517
605
|
const apiKeyStored = loadProviders().find(p => p.cursorProxy)?.cursorApiKey;
|
|
518
606
|
const keySource = apiKeyEnv ? "env CURSOR_BRIDGE_API_KEY" : (apiKeyStored ? "providers.json (stored)" : "none — using 'unused'");
|
|
519
|
-
|
|
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}`));
|
|
607
|
+
const proxyVersion = getEmbeddedComposerProxyVersion() ?? "unknown";
|
|
548
608
|
const composerCli = resolveCursorComposerCli();
|
|
549
609
|
if (!composerCli) {
|
|
550
610
|
console.log(chalk.yellow(` ⚠ cursor-composer-in-claude is not installed (missing from node_modules). Run: npm install`));
|
|
551
611
|
return false;
|
|
552
612
|
}
|
|
553
|
-
|
|
613
|
+
let cliResolved;
|
|
614
|
+
try {
|
|
615
|
+
cliResolved = realpathSync(composerCli);
|
|
616
|
+
}
|
|
617
|
+
catch {
|
|
618
|
+
cliResolved = composerCli;
|
|
619
|
+
}
|
|
554
620
|
const proxyEnv = {
|
|
555
621
|
...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== undefined)),
|
|
556
622
|
CI: "true",
|
|
@@ -561,6 +627,18 @@ async function startProxyProcess(baseUrl, url, port) {
|
|
|
561
627
|
proxyEnv.CURSOR_AGENT_NODE = sysNode;
|
|
562
628
|
proxyEnv.CURSOR_AGENT_SCRIPT = agentJs;
|
|
563
629
|
}
|
|
630
|
+
console.log(chalk.dim(JSON.stringify({
|
|
631
|
+
claudeOvernight: VERSION,
|
|
632
|
+
spawnProxy: {
|
|
633
|
+
pkg: "cursor-composer-in-claude",
|
|
634
|
+
version: proxyVersion,
|
|
635
|
+
cliPath: cliResolved,
|
|
636
|
+
nodeExec: process.execPath,
|
|
637
|
+
apiKey: keySource,
|
|
638
|
+
agentPaths: sysNode && agentJs ? { node: sysNode, script: agentJs } : undefined,
|
|
639
|
+
childEnv: { CI: proxyEnv.CI, CURSOR_SKIP_KEYCHAIN: proxyEnv.CURSOR_SKIP_KEYCHAIN },
|
|
640
|
+
},
|
|
641
|
+
})));
|
|
564
642
|
try {
|
|
565
643
|
console.log(chalk.dim(` Spawning proxy…`));
|
|
566
644
|
const child = spawn(process.execPath, [composerCli], {
|
|
@@ -593,6 +671,18 @@ async function startProxyProcess(baseUrl, url, port) {
|
|
|
593
671
|
return false;
|
|
594
672
|
}
|
|
595
673
|
}
|
|
674
|
+
function tryBundledComposerHelp() {
|
|
675
|
+
const cli = resolveCursorComposerCli();
|
|
676
|
+
if (!cli)
|
|
677
|
+
return false;
|
|
678
|
+
try {
|
|
679
|
+
execSync(`node "${cli}" --help`, { stdio: "pipe", timeout: 10_000 });
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
catch {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
596
686
|
function setupSteps() {
|
|
597
687
|
return [
|
|
598
688
|
{
|
|
@@ -621,19 +711,11 @@ function setupSteps() {
|
|
|
621
711
|
successMsg: "Cursor API key configured",
|
|
622
712
|
},
|
|
623
713
|
{
|
|
624
|
-
label: "cursor-composer-in-claude
|
|
625
|
-
check: () =>
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
catch {
|
|
631
|
-
return false;
|
|
632
|
-
}
|
|
633
|
-
},
|
|
634
|
-
autoCmd: "npx cursor-composer-in-claude",
|
|
635
|
-
manualCmd: "npx cursor-composer-in-claude",
|
|
636
|
-
successMsg: "cursor-composer-in-claude available",
|
|
714
|
+
label: "cursor-composer-in-claude (bundled dependency)",
|
|
715
|
+
check: () => tryBundledComposerHelp(),
|
|
716
|
+
autoCmd: "npm install",
|
|
717
|
+
manualCmd: "npm install",
|
|
718
|
+
successMsg: "Bundled proxy package installed",
|
|
637
719
|
},
|
|
638
720
|
];
|
|
639
721
|
}
|
|
@@ -677,7 +759,7 @@ async function promptAndSaveCursorKey() {
|
|
|
677
759
|
* Full install + configure flow for cursor-composer-in-claude.
|
|
678
760
|
* Walks through CLI install, API key config, and proxy start.
|
|
679
761
|
* Only needed when the quick auto-start (`ensureCursorProxyRunning`) fails —
|
|
680
|
-
* e.g.
|
|
762
|
+
* e.g. dependencies not installed or the user has no API key yet.
|
|
681
763
|
* Returns true when proxy is running and healthy.
|
|
682
764
|
*/
|
|
683
765
|
export async function setupCursorProxy() {
|
|
@@ -732,40 +814,41 @@ export async function setupCursorProxy() {
|
|
|
732
814
|
console.log(chalk.yellow(" No API key — the proxy won't authenticate without one."));
|
|
733
815
|
}
|
|
734
816
|
}
|
|
735
|
-
// ── Step 3:
|
|
817
|
+
// ── Step 3: Bundled proxy dependency ──
|
|
736
818
|
const proxyStep = steps[2];
|
|
819
|
+
const installRoot = getClaudeOvernightInstallRoot();
|
|
737
820
|
if (proxyStep.check()) {
|
|
738
821
|
console.log(chalk.green(` ✓ ${proxyStep.successMsg}`));
|
|
739
822
|
}
|
|
740
823
|
else {
|
|
741
|
-
console.log(chalk.yellow(`\n ${proxyStep.label}
|
|
742
|
-
const choice = await selectKey(`
|
|
743
|
-
{ key: "a", desc: "uto (install
|
|
824
|
+
console.log(chalk.yellow(`\n ${proxyStep.label} missing under node_modules`));
|
|
825
|
+
const choice = await selectKey(` Run npm install in this claude-overnight install?`, [
|
|
826
|
+
{ key: "a", desc: "uto (npm install)" },
|
|
744
827
|
{ key: "m", desc: "anual (show commands)" },
|
|
745
828
|
{ key: "s", desc: "kip (I'll handle it)" },
|
|
746
829
|
]);
|
|
747
830
|
if (choice === "a") {
|
|
748
|
-
console.log(chalk.dim(`
|
|
831
|
+
console.log(chalk.dim(` Running: npm install in ${installRoot}`));
|
|
749
832
|
try {
|
|
750
|
-
execSync("
|
|
751
|
-
console.log(chalk.green(` ✓ cursor-composer-in-claude is installed`));
|
|
833
|
+
execSync("npm install", { cwd: installRoot, stdio: "inherit", timeout: 180_000 });
|
|
752
834
|
}
|
|
753
835
|
catch {
|
|
754
|
-
console.log(chalk.
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
console.log(chalk.yellow(" Install failed — try manual: npm install -g cursor-composer-in-claude"));
|
|
761
|
-
return false;
|
|
762
|
-
}
|
|
836
|
+
console.log(chalk.yellow(" npm install failed."));
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
if (!tryBundledComposerHelp()) {
|
|
840
|
+
console.log(chalk.yellow(" cursor-composer-in-claude still missing after npm install."));
|
|
841
|
+
return false;
|
|
763
842
|
}
|
|
843
|
+
console.log(chalk.green(` ✓ ${proxyStep.successMsg}`));
|
|
764
844
|
}
|
|
765
845
|
else if (choice === "m") {
|
|
766
|
-
console.log(chalk.cyan(`\n
|
|
767
|
-
console.log(chalk.
|
|
768
|
-
const
|
|
846
|
+
console.log(chalk.cyan(`\n From ${chalk.bold(installRoot)}:`));
|
|
847
|
+
console.log(chalk.white(` ${chalk.bold("npm install")}`));
|
|
848
|
+
const cmd = bundledComposerProxyShellCommand();
|
|
849
|
+
if (cmd)
|
|
850
|
+
console.log(chalk.white(` ${chalk.bold(cmd)}\n`));
|
|
851
|
+
const ok = await selectKey(` Done?`, [
|
|
769
852
|
{ key: "r", desc: "eady" },
|
|
770
853
|
{ key: "c", desc: "ancel" },
|
|
771
854
|
]);
|
|
@@ -777,12 +860,14 @@ export async function setupCursorProxy() {
|
|
|
777
860
|
return false;
|
|
778
861
|
}
|
|
779
862
|
}
|
|
780
|
-
// Auto-start the proxy (detached
|
|
863
|
+
// Auto-start the proxy (detached — only the bundled CLI)
|
|
781
864
|
if (await ensureCursorProxyRunning())
|
|
782
865
|
return true;
|
|
783
|
-
|
|
784
|
-
console.log(chalk.yellow(`\n Couldn't start the proxy automatically
|
|
785
|
-
console.log(chalk.
|
|
866
|
+
const manual = bundledComposerProxyShellCommand();
|
|
867
|
+
console.log(chalk.yellow(`\n Couldn't start the proxy automatically.`));
|
|
868
|
+
console.log(chalk.cyan(` Ensure dependencies: ${chalk.bold(`cd "${installRoot}" && npm install`)}`));
|
|
869
|
+
if (manual)
|
|
870
|
+
console.log(chalk.cyan(` Start bundled proxy: ${chalk.bold(manual)}`));
|
|
786
871
|
for (;;) {
|
|
787
872
|
const choice = await selectKey(` Proxy started?`, [
|
|
788
873
|
{ key: "r", desc: "etry (re-attempt auto-start + kill stale)" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.6",
|
|
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": "
|
|
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.
|
|
3
|
+
"version": "1.24.6",
|
|
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"
|