claude-overnight 1.25.38 → 1.25.39
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/coach.js
CHANGED
|
@@ -5,9 +5,10 @@ import { execSync } from "child_process";
|
|
|
5
5
|
import { homedir } from "os";
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import { runPlannerQuery, attemptJsonParse } from "./planner-query.js";
|
|
8
|
+
import { renderWaitingIndicator } from "./render.js";
|
|
8
9
|
import { createTurn, beginTurn, endTurn } from "./turns.js";
|
|
9
10
|
import { selectKey, ask } from "./cli.js";
|
|
10
|
-
import { envFor } from "./providers.js";
|
|
11
|
+
import { envFor, isCursorProxyProvider, ensureCursorProxyRunning, PROXY_DEFAULT_URL } from "./providers.js";
|
|
11
12
|
// ── URL fetching for plan links in the objective ──
|
|
12
13
|
const URL_REGEX = /https?:\/\/[^\s<>"{}|\\^`\[\]]+/g;
|
|
13
14
|
async function fetchUrlContent(url, timeoutMs = 5_000) {
|
|
@@ -56,7 +57,7 @@ export function saveUserSettings(s) {
|
|
|
56
57
|
}
|
|
57
58
|
// ── Coach model (separate from DEFAULT_MODEL so the coach can stay cheap) ──
|
|
58
59
|
export const COACH_MODEL = "claude-haiku-4-5";
|
|
59
|
-
const COACH_TIMEOUT_MS =
|
|
60
|
+
const COACH_TIMEOUT_MS = 60_000;
|
|
60
61
|
const COACH_SOFT_STATUS_MS = 5_000;
|
|
61
62
|
// ── Raw schema matching the SKILL.md invocation contract ──
|
|
62
63
|
const COACH_SCHEMA = {
|
|
@@ -342,18 +343,31 @@ export async function runSetupCoach(rawObjective, cwd, ctx) {
|
|
|
342
343
|
}
|
|
343
344
|
const userMessage = renderRepoFacts(facts, rawObjective, ctx.providers, ctx.cliFlags, planContent);
|
|
344
345
|
const prompt = `${skill}\n\n---\n\n${userMessage}\n\nRespond with the JSON object defined in "Invocation contract" only.`;
|
|
345
|
-
|
|
346
|
+
// cursor "auto" maps to a slow thinking-class model for large prompts (182s observed).
|
|
347
|
+
// composer-2-fast gives the same quality for structured JSON at ~8s.
|
|
348
|
+
const CURSOR_FAST_MODEL = "composer-2-fast";
|
|
349
|
+
let model = ctx.coachModel ?? COACH_MODEL;
|
|
346
350
|
const startedAt = Date.now();
|
|
347
351
|
const spinner = setInterval(() => {
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
+
const indicator = renderWaitingIndicator("coach", startedAt, { style: "thinking" });
|
|
353
|
+
process.stdout.write(`\x1B[2K\r ${indicator}`);
|
|
354
|
+
}, 120);
|
|
355
|
+
if (ctx.coachProvider && isCursorProxyProvider(ctx.coachProvider)) {
|
|
356
|
+
const proxyUrl = ctx.coachProvider.baseURL || PROXY_DEFAULT_URL;
|
|
357
|
+
const proxyUp = await ensureCursorProxyRunning(proxyUrl);
|
|
358
|
+
if (!proxyUp) {
|
|
359
|
+
clearInterval(spinner);
|
|
360
|
+
process.stdout.write(`\x1B[2K\r`);
|
|
361
|
+
console.log(chalk.dim(" coach skipped: proxy failed to start"));
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
if (model === "auto")
|
|
365
|
+
model = CURSOR_FAST_MODEL;
|
|
366
|
+
}
|
|
352
367
|
let raw;
|
|
353
368
|
const turn = createTurn("coach", "Coach", "coach-0", model);
|
|
354
369
|
beginTurn(turn);
|
|
355
370
|
try {
|
|
356
|
-
const coachEnv = ctx.coachProvider ? envFor(ctx.coachProvider) : undefined;
|
|
357
371
|
const queryPromise = runPlannerQuery(prompt, {
|
|
358
372
|
cwd,
|
|
359
373
|
model,
|
|
@@ -362,7 +376,7 @@ export async function runSetupCoach(rawObjective, cwd, ctx) {
|
|
|
362
376
|
transcriptName: "coach",
|
|
363
377
|
maxTurns: 3,
|
|
364
378
|
tools: [],
|
|
365
|
-
env:
|
|
379
|
+
env: ctx.coachProvider ? envFor(ctx.coachProvider) : undefined,
|
|
366
380
|
turnId: turn.id,
|
|
367
381
|
}, () => { });
|
|
368
382
|
const timeout = new Promise((_, reject) => {
|
package/dist/planner-query.js
CHANGED
|
@@ -81,7 +81,49 @@ async function throttlePlanner(onLog, aborted) {
|
|
|
81
81
|
const NUDGE_MS = 15 * 60 * 1000;
|
|
82
82
|
const HARD_TIMEOUT_MS = 30 * 60 * 1000;
|
|
83
83
|
const WALL_CLOCK_LIMIT_MS = 45 * 60 * 1000;
|
|
84
|
+
// ── Cursor proxy: direct HTTP bypass ──
|
|
85
|
+
//
|
|
86
|
+
// When the env routes to a cursor proxy (CURSOR_API_KEY present, no ANTHROPIC_API_KEY),
|
|
87
|
+
// the claude-agent-sdk wrapper is harmful, not helpful:
|
|
88
|
+
// - The SDK spawns a `claude` subprocess that makes 4+ sequential HTTP calls to the proxy.
|
|
89
|
+
// - Each call spawns a fresh cursor-agent subprocess (~15s overhead each).
|
|
90
|
+
// - Total: 4 × 15s = 60s for what should be a single 10-15s completion.
|
|
91
|
+
// The SDK features (local tool loop, session resume, rate-limit headers) do not apply:
|
|
92
|
+
// - cursor-agent runs its own internal tool loop; local tool_use never fires.
|
|
93
|
+
// - cursor proxy doesn't expose session IDs or rate-limit headers.
|
|
94
|
+
// One direct POST is always correct and 4-10× faster.
|
|
95
|
+
function isCursorProxyEnv(env) {
|
|
96
|
+
return !!env?.CURSOR_API_KEY && !env?.ANTHROPIC_API_KEY;
|
|
97
|
+
}
|
|
98
|
+
async function runViaDirectFetch(prompt, opts, onLog) {
|
|
99
|
+
const env = opts.env ?? _envResolver?.(opts.model);
|
|
100
|
+
const baseUrl = (env?.ANTHROPIC_BASE_URL ?? "http://127.0.0.1:8765").replace(/\/$/, "");
|
|
101
|
+
const authToken = env?.ANTHROPIC_AUTH_TOKEN ?? "";
|
|
102
|
+
const MAX_RETRIES = 3;
|
|
103
|
+
const BACKOFF = [30_000, 60_000, 120_000];
|
|
104
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
105
|
+
const res = await fetch(`${baseUrl}/v1/messages`, {
|
|
106
|
+
method: "POST",
|
|
107
|
+
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${authToken}` },
|
|
108
|
+
body: JSON.stringify({ model: opts.model, max_tokens: 8192, messages: [{ role: "user", content: prompt }] }),
|
|
109
|
+
});
|
|
110
|
+
if (res.status === 429 && attempt < MAX_RETRIES) {
|
|
111
|
+
const waitMs = BACKOFF[attempt];
|
|
112
|
+
onLog(`Cursor proxy rate limited — waiting ${Math.round(waitMs / 1000)}s`, "event");
|
|
113
|
+
await new Promise(r => setTimeout(r, waitMs));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (!res.ok)
|
|
117
|
+
throw new Error(`Cursor proxy ${res.status}: ${(await res.text().catch(() => ""))}`);
|
|
118
|
+
const data = await res.json();
|
|
119
|
+
return data.content?.[0]?.text ?? "";
|
|
120
|
+
}
|
|
121
|
+
throw new Error("Cursor proxy direct fetch failed after retries");
|
|
122
|
+
}
|
|
84
123
|
export async function runPlannerQuery(prompt, opts, onLog) {
|
|
124
|
+
const env = opts.env ?? _envResolver?.(opts.model);
|
|
125
|
+
if (isCursorProxyEnv(env))
|
|
126
|
+
return runViaDirectFetch(prompt, opts, onLog);
|
|
85
127
|
const MAX_RETRIES = 3;
|
|
86
128
|
const BACKOFF = [30_000, 60_000, 120_000];
|
|
87
129
|
let currentPrompt = prompt;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.39",
|
|
4
4
|
"description": "Parallel Claude agents in git worktrees with a usage cap that reserves headroom for your interactive Claude Code. Crash-safe resume. Provider-agnostic model catalog (Anthropic, Cursor, OpenAI, Gemini, DeepSeek, Llama, Qwen) with capability-based task scoping.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-overnight",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.39",
|
|
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"
|