@sideboard-ai/core 0.1.153 → 0.1.156
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/agents/cursor-runner.cjs +6 -1
- package/dist/agents/cursor-runner.js +6 -1
- package/dist/{agents-V24DYZI4.js → agents-2FTZAXO3.js} +4 -2
- package/dist/{agents-YVW75KBO.js → agents-IY4CSPWV.js} +4 -2
- package/dist/{chunk-KMNODRWF.js → chunk-7EIPEPAH.js} +22 -24
- package/dist/{chunk-2F63IMCL.js → chunk-MSFPM5VK.js} +3 -3
- package/dist/{chunk-2NRNP7QP.js → chunk-OLE2BLIX.js} +15 -23
- package/dist/{chunk-RNC3GR6L.js → chunk-TI6UMRWK.js} +3 -3
- package/dist/{chunk-4THE3EY7.js → chunk-UA3YZKRX.js} +197 -38
- package/dist/{chunk-QZEZXYVV.js → chunk-XLU7DXHH.js} +260 -32
- package/dist/{coordinator-prompt-7FHKCWXB.js → coordinator-prompt-D2FHU5IZ.js} +1 -1
- package/dist/{coordinator-prompt-KX2FVVYT.js → coordinator-prompt-UZDNIVP7.js} +1 -1
- package/dist/{global-workspace-2BRRKSDN.js → global-workspace-5WZVSWNT.js} +1 -1
- package/dist/{global-workspace-4LHCZ2DC.js → global-workspace-MR75BDBY.js} +1 -1
- package/dist/index.cjs +510 -337
- package/dist/index.d.cts +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +19 -73
- package/dist/mcp/run-stdio.cjs +437 -274
- package/dist/mcp/run-stdio.js +3 -3
- package/dist/{orchestrator-5PSHBLP6.js → orchestrator-G4WKJG5Y.js} +3 -3
- package/dist/{orchestrator-ZSSU3FKW.js → orchestrator-LXO2CDOG.js} +3 -3
- package/dist/{workspaces-MQYNZXUK.js → workspaces-HO4EQNNM.js} +1 -1
- package/dist/{workspaces-5UNDTN4G.js → workspaces-RP32AW6X.js} +1 -1
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -7511,7 +7511,7 @@ function ensureGlobalCoordinatorCwd(opts) {
|
|
|
7511
7511
|
"Never pass `agent=codex` when you yourself are Codex \u2014 nested Codex deadlocks on shared ~/.codex locks. Omit agent (Account default) or use cursor/claude.",
|
|
7512
7512
|
"Typical flow (Home board): list_board \u2192 create_thread (sourceType=ticket|pr|branch) \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft \u2192 wait_for_turn. Merge only if the user explicitly asked (`ask_git` merge).",
|
|
7513
7513
|
"Typical flow (branch / explicit source): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
7514
|
-
"Typical flow (find work): list_workspaces \u2192 pick repo(s) matching viewer roles/notes \u2192 list_issues (tickets) or list_prs(queue=review) (reviews) \u2192 show the options. Only create_thread + send_to_thread when they asked to start (e.g. \u201Cfind me work and start it\u201D) \u2014 then wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
7514
|
+
"Typical flow (find work): list_workspaces \u2192 pick repo(s) matching viewer roles/notes \u2192 Sideboard list_issues / linear_* (tickets) or list_prs(queue=review) (reviews) \u2192 show the options. Never wait on Claude Linear MCP. Only create_thread + send_to_thread when they asked to start (e.g. \u201Cfind me work and start it\u201D) \u2014 then wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
7515
7515
|
'Typical flow (review inbox): list_workspaces \u2192 list_prs(queue=review, limit=N) \u2192 show those PRs (ticket ids in the title when present). create_thread sourceType=pr only when they asked to start / do the work. Do not list_issues for "tickets to review".',
|
|
7516
7516
|
"Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
|
|
7517
7517
|
"Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
|
|
@@ -7568,8 +7568,8 @@ var init_coordinator_prompt = __esm({
|
|
|
7568
7568
|
"- list_workspaces \u2014 registered repos (path + github slug + roles/notes when set). Use that profile to pick the right repo for tickets or reviews.",
|
|
7569
7569
|
"- list_board \u2014 Home Kanban of worktrees (New / Draft / Review / Merged; one card per checkout). Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
|
|
7570
7570
|
'- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_thread sourceType=pr. That is open non-draft PRs labeled eng-review with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Prefer teams that match Settings \u2192 Agents / Projects roles (check one or more of Engineering, Design, Product, or extras they added \u2014 never a combined both value; project roles override account for that repo). queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, use their notes (assignee=me or unassigned as the notes say) and prefer ones that match their roles.',
|
|
7571
|
-
"- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) roles and notes. Tickets \u2192 list_issues. Reviews \u2192 list_prs(queue=review). Show the options \u2014 do not create_thread or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted.",
|
|
7572
|
-
"- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Scope errors: reconnect Linear in Account settings.",
|
|
7571
|
+
"- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) roles and notes. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_thread or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted.",
|
|
7572
|
+
"- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
|
|
7573
7573
|
"- abletime_* (when AbleTime is connected) \u2014 orientation first; ensure_task when work has no ticket (or create_thread from the default branch auto-creates one).",
|
|
7574
7574
|
"- list_teams / slack_list_channels / slack_list_users / slack_search / slack_read / slack_post / slack_replies \u2014 Slack workspaces from Settings \u2192 Remote; pass team_id from list_teams",
|
|
7575
7575
|
"- Optional connectors (Vercel, Supabase, PostHog, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`) with those env vars. PostHog has no first-class CLI \u2014 use the HTTP API (`POSTHOG_PERSONAL_API_KEY`). If a CLI is missing, the user can Install CLI on that row (not auto-installed on Connect). Do not add vendor MCPs or ask the user to paste tokens again. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues; Slack stays Settings \u2192 Remote (Sideboard MCP).",
|
|
@@ -9593,7 +9593,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
9593
9593
|
}
|
|
9594
9594
|
return args;
|
|
9595
9595
|
}
|
|
9596
|
-
function toOpencodeMcpConfigContent(servers) {
|
|
9596
|
+
function toOpencodeMcpConfigContent(servers, opts) {
|
|
9597
9597
|
const mcp = {};
|
|
9598
9598
|
for (const s of servers) {
|
|
9599
9599
|
const env = mcpSpawnEnv(s.env);
|
|
@@ -9604,6 +9604,11 @@ function toOpencodeMcpConfigContent(servers) {
|
|
|
9604
9604
|
...env ? { environment: env } : {}
|
|
9605
9605
|
};
|
|
9606
9606
|
}
|
|
9607
|
+
for (const name of opts?.disableNames ?? []) {
|
|
9608
|
+
const key = name.trim();
|
|
9609
|
+
if (!key || mcp[key]?.enabled === true) continue;
|
|
9610
|
+
mcp[key] = { ...mcp[key], enabled: false };
|
|
9611
|
+
}
|
|
9607
9612
|
return JSON.stringify({ mcp });
|
|
9608
9613
|
}
|
|
9609
9614
|
function writeMcpServersConfig(servers) {
|
|
@@ -9834,13 +9839,50 @@ function claudeString(obj, key) {
|
|
|
9834
9839
|
const v = obj[key];
|
|
9835
9840
|
return typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
9836
9841
|
}
|
|
9842
|
+
function mcpStatusThinkingFromClaudeInit(obj) {
|
|
9843
|
+
const raw = obj.mcp_servers ?? obj.mcpServers;
|
|
9844
|
+
const servers = [];
|
|
9845
|
+
if (Array.isArray(raw)) {
|
|
9846
|
+
for (const item of raw) {
|
|
9847
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
9848
|
+
const rec = item;
|
|
9849
|
+
const name = typeof rec.name === "string" && rec.name.trim() || typeof rec.server === "string" && rec.server.trim() || "";
|
|
9850
|
+
const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "";
|
|
9851
|
+
if (name) servers.push({ name, status: status || "unknown" });
|
|
9852
|
+
}
|
|
9853
|
+
} else if (raw && typeof raw === "object") {
|
|
9854
|
+
for (const [name, value] of Object.entries(raw)) {
|
|
9855
|
+
if (!name.trim()) continue;
|
|
9856
|
+
if (typeof value === "string" && value.trim()) {
|
|
9857
|
+
servers.push({ name, status: value.trim() });
|
|
9858
|
+
continue;
|
|
9859
|
+
}
|
|
9860
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
9861
|
+
const rec = value;
|
|
9862
|
+
const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "unknown";
|
|
9863
|
+
servers.push({ name, status });
|
|
9864
|
+
}
|
|
9865
|
+
}
|
|
9866
|
+
}
|
|
9867
|
+
const notable = servers.filter((s) => !isCleanMcpConnect(s.status));
|
|
9868
|
+
if (notable.length === 0) return null;
|
|
9869
|
+
return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
|
|
9870
|
+
}
|
|
9871
|
+
function isCleanMcpConnect(status) {
|
|
9872
|
+
return /^(connected|ok|ready|success)$/i.test(status.trim());
|
|
9873
|
+
}
|
|
9837
9874
|
function eventsFromClaudeSystem(obj) {
|
|
9838
9875
|
const subtype = claudeString(obj, "subtype") ?? "";
|
|
9839
9876
|
const parentId = claudeParentToolUseId(obj);
|
|
9840
9877
|
if (subtype === "init") {
|
|
9841
9878
|
if (parentId) return null;
|
|
9842
9879
|
const sid = claudeString(obj, "session_id");
|
|
9843
|
-
|
|
9880
|
+
const mcpNote = mcpStatusThinkingFromClaudeInit(obj);
|
|
9881
|
+
const events = [];
|
|
9882
|
+
if (sid) events.push({ type: "session_id", data: sid });
|
|
9883
|
+
if (mcpNote) events.push({ type: "thinking", data: mcpNote, replace: true });
|
|
9884
|
+
if (events.length === 0) return null;
|
|
9885
|
+
return events.length === 1 ? events[0] : events;
|
|
9844
9886
|
}
|
|
9845
9887
|
if (subtype === "task_started") {
|
|
9846
9888
|
const id = claudeString(obj, "tool_use_id") ?? claudeString(obj, "task_id");
|
|
@@ -10104,6 +10146,9 @@ var init_claude = __esm({
|
|
|
10104
10146
|
const mcpConfigPath = writeMcpServersConfig(injectedServers);
|
|
10105
10147
|
if (mcpConfigPath) {
|
|
10106
10148
|
args.push("--mcp-config", mcpConfigPath);
|
|
10149
|
+
if (isOrchestrator) {
|
|
10150
|
+
args.push("--strict-mcp-config");
|
|
10151
|
+
}
|
|
10107
10152
|
}
|
|
10108
10153
|
if (chromeOn) {
|
|
10109
10154
|
args.push("--chrome");
|
|
@@ -10133,7 +10178,10 @@ var init_claude = __esm({
|
|
|
10133
10178
|
// abandoned at Claude Code’s 10-minute default.
|
|
10134
10179
|
env: {
|
|
10135
10180
|
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
10136
|
-
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS)
|
|
10181
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? String(CLAUDE_PRINT_BG_WAIT_CEILING_MS),
|
|
10182
|
+
// `--strict-mcp-config` still fetches claude.ai connectors on some CLI
|
|
10183
|
+
// builds (anthropics/claude-code#60252). Coordinators do not need them.
|
|
10184
|
+
...isOrchestrator ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
|
|
10137
10185
|
}
|
|
10138
10186
|
};
|
|
10139
10187
|
},
|
|
@@ -10257,6 +10305,114 @@ var init_claude = __esm({
|
|
|
10257
10305
|
}
|
|
10258
10306
|
});
|
|
10259
10307
|
|
|
10308
|
+
// src/agents/user-mcp-config.ts
|
|
10309
|
+
var import_node_fs26, import_node_os10, import_node_path27;
|
|
10310
|
+
var init_user_mcp_config = __esm({
|
|
10311
|
+
"src/agents/user-mcp-config.ts"() {
|
|
10312
|
+
"use strict";
|
|
10313
|
+
import_node_fs26 = require("fs");
|
|
10314
|
+
import_node_os10 = require("os");
|
|
10315
|
+
import_node_path27 = require("path");
|
|
10316
|
+
init_paths();
|
|
10317
|
+
init_injected_mcp();
|
|
10318
|
+
}
|
|
10319
|
+
});
|
|
10320
|
+
|
|
10321
|
+
// src/agents/orch-mcp-isolation.ts
|
|
10322
|
+
function isInjectedOrchMcpName(name) {
|
|
10323
|
+
const n = name.trim().toLowerCase();
|
|
10324
|
+
return n === "sideboard" || n === "brightsy" || n.startsWith("brightsy_");
|
|
10325
|
+
}
|
|
10326
|
+
function asObject(value) {
|
|
10327
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
10328
|
+
return value;
|
|
10329
|
+
}
|
|
10330
|
+
function listMcpNamesFromJsonMap(raw, key) {
|
|
10331
|
+
return Object.keys(asObject(asObject(raw)[key])).filter((n) => n.trim());
|
|
10332
|
+
}
|
|
10333
|
+
function listMcpNamesFromCodexToml(text5) {
|
|
10334
|
+
try {
|
|
10335
|
+
const parsed = (0, import_smol_toml2.parse)(text5);
|
|
10336
|
+
return Object.keys(asObject(parsed.mcp_servers)).filter((n) => n.trim());
|
|
10337
|
+
} catch {
|
|
10338
|
+
return [];
|
|
10339
|
+
}
|
|
10340
|
+
}
|
|
10341
|
+
function readJsonObject(path) {
|
|
10342
|
+
try {
|
|
10343
|
+
return JSON.parse((0, import_node_fs27.readFileSync)(path, "utf8"));
|
|
10344
|
+
} catch {
|
|
10345
|
+
return {};
|
|
10346
|
+
}
|
|
10347
|
+
}
|
|
10348
|
+
function readText(path) {
|
|
10349
|
+
try {
|
|
10350
|
+
return (0, import_node_fs27.readFileSync)(path, "utf8");
|
|
10351
|
+
} catch {
|
|
10352
|
+
return "";
|
|
10353
|
+
}
|
|
10354
|
+
}
|
|
10355
|
+
function userCodexConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
10356
|
+
return [(0, import_node_path28.join)(home, ".codex", "config.toml"), (0, import_node_path28.join)(home, ".config", "codex", "config.toml")];
|
|
10357
|
+
}
|
|
10358
|
+
function userOpencodeConfigPaths(home = (0, import_node_os11.homedir)()) {
|
|
10359
|
+
return [
|
|
10360
|
+
(0, import_node_path28.join)(home, ".config", "opencode", "opencode.json"),
|
|
10361
|
+
(0, import_node_path28.join)(home, ".config", "opencode", "opencode.jsonc")
|
|
10362
|
+
];
|
|
10363
|
+
}
|
|
10364
|
+
function userMcpNamesToDisable(opts) {
|
|
10365
|
+
const keep = new Set(
|
|
10366
|
+
[...opts.injectedNames ?? []].map((n) => n.trim().toLowerCase()).filter(Boolean)
|
|
10367
|
+
);
|
|
10368
|
+
const out = [];
|
|
10369
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10370
|
+
for (const raw of opts.names) {
|
|
10371
|
+
const name = raw.trim();
|
|
10372
|
+
if (!name) continue;
|
|
10373
|
+
const key = name.toLowerCase();
|
|
10374
|
+
if (seen.has(key) || keep.has(key) || isInjectedOrchMcpName(name)) continue;
|
|
10375
|
+
seen.add(key);
|
|
10376
|
+
out.push(name);
|
|
10377
|
+
}
|
|
10378
|
+
return out;
|
|
10379
|
+
}
|
|
10380
|
+
function listUserCodexMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
10381
|
+
const names = [];
|
|
10382
|
+
for (const path of userCodexConfigPaths(home)) {
|
|
10383
|
+
if (!(0, import_node_fs27.existsSync)(path)) continue;
|
|
10384
|
+
names.push(...listMcpNamesFromCodexToml(readText(path)));
|
|
10385
|
+
}
|
|
10386
|
+
return names;
|
|
10387
|
+
}
|
|
10388
|
+
function listUserOpencodeMcpNames(home = (0, import_node_os11.homedir)()) {
|
|
10389
|
+
const names = [];
|
|
10390
|
+
for (const path of userOpencodeConfigPaths(home)) {
|
|
10391
|
+
if (!(0, import_node_fs27.existsSync)(path)) continue;
|
|
10392
|
+
names.push(...listMcpNamesFromJsonMap(readJsonObject(path), "mcp"));
|
|
10393
|
+
}
|
|
10394
|
+
return names;
|
|
10395
|
+
}
|
|
10396
|
+
function toCodexDisableUserMcpArgs(names) {
|
|
10397
|
+
const args = [];
|
|
10398
|
+
for (const name of names) {
|
|
10399
|
+
if (!/^[A-Za-z0-9_-]+$/.test(name)) continue;
|
|
10400
|
+
args.push("-c", `mcp_servers.${name}.enabled=false`);
|
|
10401
|
+
}
|
|
10402
|
+
return args;
|
|
10403
|
+
}
|
|
10404
|
+
var import_node_fs27, import_node_os11, import_node_path28, import_smol_toml2;
|
|
10405
|
+
var init_orch_mcp_isolation = __esm({
|
|
10406
|
+
"src/agents/orch-mcp-isolation.ts"() {
|
|
10407
|
+
"use strict";
|
|
10408
|
+
import_node_fs27 = require("fs");
|
|
10409
|
+
import_node_os11 = require("os");
|
|
10410
|
+
import_node_path28 = require("path");
|
|
10411
|
+
import_smol_toml2 = require("smol-toml");
|
|
10412
|
+
init_user_mcp_config();
|
|
10413
|
+
}
|
|
10414
|
+
});
|
|
10415
|
+
|
|
10260
10416
|
// src/agents/codex.ts
|
|
10261
10417
|
async function listCodexModels() {
|
|
10262
10418
|
const now = Date.now();
|
|
@@ -10267,7 +10423,7 @@ async function listCodexModels() {
|
|
|
10267
10423
|
if (codex === "codex") {
|
|
10268
10424
|
const which = await run("which", ["codex"], { reject: false });
|
|
10269
10425
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
10270
|
-
} else if (!(0,
|
|
10426
|
+
} else if (!(0, import_node_fs28.existsSync)(codex)) {
|
|
10271
10427
|
return FALLBACK_CODEX_MODELS;
|
|
10272
10428
|
}
|
|
10273
10429
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -10302,12 +10458,12 @@ function usageFromCodex(usage) {
|
|
|
10302
10458
|
}
|
|
10303
10459
|
function codexConfigHasNetworkAccess() {
|
|
10304
10460
|
const candidates = [
|
|
10305
|
-
(0,
|
|
10306
|
-
(0,
|
|
10461
|
+
(0, import_node_path29.join)((0, import_node_os12.homedir)(), ".codex", "config.toml"),
|
|
10462
|
+
(0, import_node_path29.join)((0, import_node_os12.homedir)(), ".config", "codex", "config.toml")
|
|
10307
10463
|
];
|
|
10308
10464
|
for (const path of candidates) {
|
|
10309
|
-
if (!(0,
|
|
10310
|
-
const text5 = (0,
|
|
10465
|
+
if (!(0, import_node_fs28.existsSync)(path)) continue;
|
|
10466
|
+
const text5 = (0, import_node_fs28.readFileSync)(path, "utf8");
|
|
10311
10467
|
if (/network_access\s*=\s*true/.test(text5)) return true;
|
|
10312
10468
|
}
|
|
10313
10469
|
return false;
|
|
@@ -10339,21 +10495,21 @@ function asRecord2(value) {
|
|
|
10339
10495
|
return void 0;
|
|
10340
10496
|
}
|
|
10341
10497
|
function codexLooksAuthenticated() {
|
|
10342
|
-
const authPath = (0,
|
|
10343
|
-
if (!(0,
|
|
10498
|
+
const authPath = (0, import_node_path29.join)((0, import_node_os12.homedir)(), ".codex", "auth.json");
|
|
10499
|
+
if (!(0, import_node_fs28.existsSync)(authPath)) return false;
|
|
10344
10500
|
try {
|
|
10345
|
-
return (0,
|
|
10501
|
+
return (0, import_node_fs28.statSync)(authPath).size > 2;
|
|
10346
10502
|
} catch {
|
|
10347
10503
|
return false;
|
|
10348
10504
|
}
|
|
10349
10505
|
}
|
|
10350
|
-
var
|
|
10506
|
+
var import_node_fs28, import_node_os12, import_node_path29, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
10351
10507
|
var init_codex = __esm({
|
|
10352
10508
|
"src/agents/codex.ts"() {
|
|
10353
10509
|
"use strict";
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10510
|
+
import_node_fs28 = require("fs");
|
|
10511
|
+
import_node_os12 = require("os");
|
|
10512
|
+
import_node_path29 = require("path");
|
|
10357
10513
|
init_run();
|
|
10358
10514
|
init_app_settings();
|
|
10359
10515
|
init_global_workspace();
|
|
@@ -10361,6 +10517,7 @@ var init_codex = __esm({
|
|
|
10361
10517
|
init_usage();
|
|
10362
10518
|
init_git_auth_mode();
|
|
10363
10519
|
init_injected_mcp();
|
|
10520
|
+
init_orch_mcp_isolation();
|
|
10364
10521
|
init_turn_input();
|
|
10365
10522
|
init_types();
|
|
10366
10523
|
CODEX_PROMPT_ARG_MAX = 2e5;
|
|
@@ -10378,7 +10535,7 @@ var init_codex = __esm({
|
|
|
10378
10535
|
async detect() {
|
|
10379
10536
|
const codex = resolveAgentExecutable("codex");
|
|
10380
10537
|
if (codex !== "codex") {
|
|
10381
|
-
if (!(0,
|
|
10538
|
+
if (!(0, import_node_fs28.existsSync)(codex)) {
|
|
10382
10539
|
return {
|
|
10383
10540
|
agent: "codex",
|
|
10384
10541
|
installed: false,
|
|
@@ -10438,7 +10595,15 @@ var init_codex = __esm({
|
|
|
10438
10595
|
}),
|
|
10439
10596
|
orchestratorThreadId: isOrchestrator ? thread.id : null
|
|
10440
10597
|
});
|
|
10441
|
-
const mcpOverrides =
|
|
10598
|
+
const mcpOverrides = [
|
|
10599
|
+
...toCodexMcpConfigArgs(injected2),
|
|
10600
|
+
...isOrchestrator ? toCodexDisableUserMcpArgs(
|
|
10601
|
+
userMcpNamesToDisable({
|
|
10602
|
+
injectedNames: injected2.map((s) => s.name),
|
|
10603
|
+
names: listUserCodexMcpNames()
|
|
10604
|
+
})
|
|
10605
|
+
) : []
|
|
10606
|
+
];
|
|
10442
10607
|
const execOpts = [
|
|
10443
10608
|
// Global orchestration cwd is not a git repo; without this Codex ≥0.147
|
|
10444
10609
|
// refuses to start ("Not inside a trusted directory").
|
|
@@ -10673,21 +10838,21 @@ function platformRipgrepPackage() {
|
|
|
10673
10838
|
}
|
|
10674
10839
|
function usableRipgrepPath(candidate) {
|
|
10675
10840
|
const raw = candidate?.trim();
|
|
10676
|
-
if (!raw || !(0,
|
|
10841
|
+
if (!raw || !(0, import_node_path30.isAbsolute)(raw)) return null;
|
|
10677
10842
|
const readable = nodeReadableScriptPath(raw);
|
|
10678
|
-
if (!(0,
|
|
10843
|
+
if (!(0, import_node_fs29.existsSync)(readable) || isAsarPath(readable)) return null;
|
|
10679
10844
|
return readable;
|
|
10680
10845
|
}
|
|
10681
10846
|
function walkForBundledRipgrep(startFile) {
|
|
10682
10847
|
if (!startFile) return null;
|
|
10683
10848
|
const pkg = platformRipgrepPackage();
|
|
10684
10849
|
const name = rgBinaryName();
|
|
10685
|
-
let dir = (0,
|
|
10686
|
-
const root = (0,
|
|
10850
|
+
let dir = (0, import_node_path30.dirname)((0, import_node_path30.resolve)(startFile));
|
|
10851
|
+
const root = (0, import_node_path30.parse)(dir).root;
|
|
10687
10852
|
while (dir !== root) {
|
|
10688
|
-
const hit = usableRipgrepPath((0,
|
|
10853
|
+
const hit = usableRipgrepPath((0, import_node_path30.join)(dir, "node_modules", pkg, "bin", name));
|
|
10689
10854
|
if (hit) return hit;
|
|
10690
|
-
const next = (0,
|
|
10855
|
+
const next = (0, import_node_path30.dirname)(dir);
|
|
10691
10856
|
if (next === dir) break;
|
|
10692
10857
|
dir = next;
|
|
10693
10858
|
}
|
|
@@ -10697,7 +10862,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
10697
10862
|
try {
|
|
10698
10863
|
const req = (0, import_node_module2.createRequire)(fromFile);
|
|
10699
10864
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
10700
|
-
return usableRipgrepPath((0,
|
|
10865
|
+
return usableRipgrepPath((0, import_node_path30.join)((0, import_node_path30.dirname)(pkgJson), "bin", rgBinaryName()));
|
|
10701
10866
|
} catch {
|
|
10702
10867
|
return null;
|
|
10703
10868
|
}
|
|
@@ -10719,13 +10884,13 @@ function cursorRipgrepEnv(opts) {
|
|
|
10719
10884
|
const path = resolveCursorRipgrepPath(opts);
|
|
10720
10885
|
return path ? { [RIPGREP_ENV]: path } : {};
|
|
10721
10886
|
}
|
|
10722
|
-
var
|
|
10887
|
+
var import_node_fs29, import_node_module2, import_node_path30, RIPGREP_ENV;
|
|
10723
10888
|
var init_cursor_ripgrep = __esm({
|
|
10724
10889
|
"src/agents/cursor-ripgrep.ts"() {
|
|
10725
10890
|
"use strict";
|
|
10726
|
-
|
|
10891
|
+
import_node_fs29 = require("fs");
|
|
10727
10892
|
import_node_module2 = require("module");
|
|
10728
|
-
|
|
10893
|
+
import_node_path30 = require("path");
|
|
10729
10894
|
init_node_launch();
|
|
10730
10895
|
init_packaged_runtime();
|
|
10731
10896
|
RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
@@ -10763,11 +10928,11 @@ function entryDir() {
|
|
|
10763
10928
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
10764
10929
|
if (cjsDir) return cjsDir;
|
|
10765
10930
|
try {
|
|
10766
|
-
return (0,
|
|
10931
|
+
return (0, import_node_path31.dirname)((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
10767
10932
|
} catch {
|
|
10768
10933
|
try {
|
|
10769
10934
|
const req = (0, import_node_module3.createRequire)(process.cwd() + "/");
|
|
10770
|
-
return (0,
|
|
10935
|
+
return (0, import_node_path31.dirname)(req.resolve("@sideboard-ai/core"));
|
|
10771
10936
|
} catch {
|
|
10772
10937
|
return process.cwd();
|
|
10773
10938
|
}
|
|
@@ -10778,27 +10943,27 @@ function cursorRunnerPath() {
|
|
|
10778
10943
|
if (packaged) return packaged;
|
|
10779
10944
|
const root = entryDir();
|
|
10780
10945
|
const candidates = [
|
|
10781
|
-
(0,
|
|
10782
|
-
(0,
|
|
10946
|
+
(0, import_node_path31.join)(root, "agents", "cursor-runner.js"),
|
|
10947
|
+
(0, import_node_path31.join)(root, "agents", "cursor-runner.cjs"),
|
|
10783
10948
|
// If somehow resolved from package root instead of dist/
|
|
10784
|
-
(0,
|
|
10785
|
-
(0,
|
|
10949
|
+
(0, import_node_path31.join)(root, "dist", "agents", "cursor-runner.js"),
|
|
10950
|
+
(0, import_node_path31.join)(root, "dist", "agents", "cursor-runner.cjs"),
|
|
10786
10951
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
10787
|
-
(0,
|
|
10788
|
-
(0,
|
|
10952
|
+
(0, import_node_path31.join)(root, "cursor-runner.ts"),
|
|
10953
|
+
(0, import_node_path31.join)(root, "src", "agents", "cursor-runner.ts")
|
|
10789
10954
|
];
|
|
10790
10955
|
for (const candidate of candidates) {
|
|
10791
|
-
if ((0,
|
|
10956
|
+
if ((0, import_node_fs30.existsSync)(candidate)) return candidate;
|
|
10792
10957
|
}
|
|
10793
10958
|
return candidates[0];
|
|
10794
10959
|
}
|
|
10795
|
-
var
|
|
10960
|
+
var import_node_fs30, import_node_module3, import_node_path31, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
10796
10961
|
var init_cursor = __esm({
|
|
10797
10962
|
"src/agents/cursor.ts"() {
|
|
10798
10963
|
"use strict";
|
|
10799
|
-
|
|
10964
|
+
import_node_fs30 = require("fs");
|
|
10800
10965
|
import_node_module3 = require("module");
|
|
10801
|
-
|
|
10966
|
+
import_node_path31 = require("path");
|
|
10802
10967
|
import_node_url2 = require("url");
|
|
10803
10968
|
import_sdk = require("@cursor/sdk");
|
|
10804
10969
|
init_run();
|
|
@@ -10864,6 +11029,7 @@ var init_cursor = __esm({
|
|
|
10864
11029
|
fast: thread.fast,
|
|
10865
11030
|
planMode: thread.planMode,
|
|
10866
11031
|
apiKey,
|
|
11032
|
+
...isOrchestrator ? { isolateAmbientMcp: true } : {},
|
|
10867
11033
|
...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
|
|
10868
11034
|
};
|
|
10869
11035
|
const runner = cursorRunnerPath();
|
|
@@ -10949,7 +11115,7 @@ async function listOpencodeModels() {
|
|
|
10949
11115
|
if (opencode === "opencode") {
|
|
10950
11116
|
const which = await run("which", ["opencode"], { reject: false });
|
|
10951
11117
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
10952
|
-
} else if (!(0,
|
|
11118
|
+
} else if (!(0, import_node_fs31.existsSync)(opencode)) {
|
|
10953
11119
|
return FALLBACK_OPENCODE_MODELS;
|
|
10954
11120
|
}
|
|
10955
11121
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -10979,17 +11145,18 @@ function usageFromOpencode(tokens) {
|
|
|
10979
11145
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
10980
11146
|
};
|
|
10981
11147
|
}
|
|
10982
|
-
var
|
|
11148
|
+
var import_node_fs31, FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
10983
11149
|
var init_opencode = __esm({
|
|
10984
11150
|
"src/agents/opencode.ts"() {
|
|
10985
11151
|
"use strict";
|
|
10986
|
-
|
|
11152
|
+
import_node_fs31 = require("fs");
|
|
10987
11153
|
init_run();
|
|
10988
11154
|
init_app_settings();
|
|
10989
11155
|
init_global_workspace();
|
|
10990
11156
|
init_error_detail();
|
|
10991
11157
|
init_message_parts();
|
|
10992
11158
|
init_injected_mcp();
|
|
11159
|
+
init_orch_mcp_isolation();
|
|
10993
11160
|
init_turn_input();
|
|
10994
11161
|
init_types();
|
|
10995
11162
|
FALLBACK_OPENCODE_MODELS = [
|
|
@@ -11010,7 +11177,7 @@ var init_opencode = __esm({
|
|
|
11010
11177
|
async detect() {
|
|
11011
11178
|
const opencode = resolveAgentExecutable("opencode");
|
|
11012
11179
|
if (opencode !== "opencode") {
|
|
11013
|
-
if (!(0,
|
|
11180
|
+
if (!(0, import_node_fs31.existsSync)(opencode)) {
|
|
11014
11181
|
return {
|
|
11015
11182
|
agent: "opencode",
|
|
11016
11183
|
installed: false,
|
|
@@ -11072,7 +11239,11 @@ var init_opencode = __esm({
|
|
|
11072
11239
|
}),
|
|
11073
11240
|
orchestratorThreadId: isOrchestrator ? thread.id : null
|
|
11074
11241
|
});
|
|
11075
|
-
const
|
|
11242
|
+
const disableNames = isOrchestrator ? userMcpNamesToDisable({
|
|
11243
|
+
injectedNames: injected2.map((s) => s.name),
|
|
11244
|
+
names: listUserOpencodeMcpNames()
|
|
11245
|
+
}) : [];
|
|
11246
|
+
const mcpContent = injected2.length > 0 || disableNames.length > 0 ? toOpencodeMcpConfigContent(injected2, { disableNames }) : null;
|
|
11076
11247
|
return {
|
|
11077
11248
|
file: resolveAgentExecutable("opencode"),
|
|
11078
11249
|
args,
|
|
@@ -12544,21 +12715,21 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
12544
12715
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
12545
12716
|
}
|
|
12546
12717
|
function readTextIfPresent(abs) {
|
|
12547
|
-
if (!(0,
|
|
12718
|
+
if (!(0, import_node_fs32.existsSync)(abs)) return null;
|
|
12548
12719
|
try {
|
|
12549
|
-
const content = (0,
|
|
12720
|
+
const content = (0, import_node_fs32.readFileSync)(abs, "utf8");
|
|
12550
12721
|
return content.trim() ? content : null;
|
|
12551
12722
|
} catch {
|
|
12552
12723
|
return null;
|
|
12553
12724
|
}
|
|
12554
12725
|
}
|
|
12555
12726
|
function readLocalGuidelines(worktreePath) {
|
|
12556
|
-
const localAbs = (0,
|
|
12727
|
+
const localAbs = (0, import_node_path32.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
12557
12728
|
const localContent = readTextIfPresent(localAbs);
|
|
12558
12729
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
12559
12730
|
return { path: REVIEW_REQUEST_PATH, content: localContent };
|
|
12560
12731
|
}
|
|
12561
|
-
const legacyAbs = (0,
|
|
12732
|
+
const legacyAbs = (0, import_node_path32.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
12562
12733
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
12563
12734
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
12564
12735
|
return { path: LEGACY_REVIEW_REQUEST_PATH, content: legacyContent };
|
|
@@ -12582,27 +12753,27 @@ function contextGuidelines(content, source) {
|
|
|
12582
12753
|
};
|
|
12583
12754
|
}
|
|
12584
12755
|
function writeContextGuidelines(worktreePath, content) {
|
|
12585
|
-
const abs = (0,
|
|
12586
|
-
(0,
|
|
12756
|
+
const abs = (0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH);
|
|
12757
|
+
(0, import_node_fs32.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
|
|
12587
12758
|
const body = content.endsWith("\n") ? content : `${content}
|
|
12588
12759
|
`;
|
|
12589
|
-
(0,
|
|
12760
|
+
(0, import_node_fs32.writeFileSync)(abs, body, "utf8");
|
|
12590
12761
|
return body;
|
|
12591
12762
|
}
|
|
12592
12763
|
function readSideboardReview(worktreePath, repoPath) {
|
|
12593
|
-
const fromWorktree = readTextIfPresent((0,
|
|
12764
|
+
const fromWorktree = readTextIfPresent((0, import_node_path32.join)(worktreePath, REPO_REVIEW_PATH));
|
|
12594
12765
|
if (fromWorktree) return fromWorktree;
|
|
12595
12766
|
const repo = repoPath?.replace(/\/+$/, "");
|
|
12596
12767
|
const wt = worktreePath.replace(/\/+$/, "");
|
|
12597
12768
|
if (!repo || repo === wt) return null;
|
|
12598
|
-
return readTextIfPresent((0,
|
|
12769
|
+
return readTextIfPresent((0, import_node_path32.join)(repo, REPO_REVIEW_PATH));
|
|
12599
12770
|
}
|
|
12600
12771
|
function ensureReviewGuidelinesFile(worktreePath, repoPath) {
|
|
12601
|
-
const skillContent = readTextIfPresent((0,
|
|
12772
|
+
const skillContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, REVIEW_SKILL_PATH));
|
|
12602
12773
|
if (skillContent) {
|
|
12603
12774
|
return { ...skillGuidelines(skillContent, "skill"), wrote: false };
|
|
12604
12775
|
}
|
|
12605
|
-
const contextContent = readTextIfPresent((0,
|
|
12776
|
+
const contextContent = readTextIfPresent((0, import_node_path32.join)(worktreePath, CONTEXT_REVIEW_PATH));
|
|
12606
12777
|
if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
|
|
12607
12778
|
return { ...contextGuidelines(contextContent, "local"), wrote: false };
|
|
12608
12779
|
}
|
|
@@ -12657,13 +12828,13 @@ async function requestReview(threadRef, send) {
|
|
|
12657
12828
|
const started = await send(tab.id, REVIEW_REQUEST_PREFILL);
|
|
12658
12829
|
return { tab: started, from };
|
|
12659
12830
|
}
|
|
12660
|
-
var import_node_crypto7,
|
|
12831
|
+
var import_node_crypto7, import_node_fs32, import_node_path32, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
12661
12832
|
var init_request_review = __esm({
|
|
12662
12833
|
"src/review/request-review.ts"() {
|
|
12663
12834
|
"use strict";
|
|
12664
12835
|
import_node_crypto7 = require("crypto");
|
|
12665
|
-
|
|
12666
|
-
|
|
12836
|
+
import_node_fs32 = require("fs");
|
|
12837
|
+
import_node_path32 = require("path");
|
|
12667
12838
|
init_global_workspace();
|
|
12668
12839
|
init_chat_tabs();
|
|
12669
12840
|
init_thread_store();
|
|
@@ -12689,9 +12860,9 @@ function matchSimpleGlob(pattern, name) {
|
|
|
12689
12860
|
return new RegExp(`^${escaped}$`).test(name);
|
|
12690
12861
|
}
|
|
12691
12862
|
function readWorktreeInclude(repoPath) {
|
|
12692
|
-
const path = (0,
|
|
12693
|
-
if (!(0,
|
|
12694
|
-
return (0,
|
|
12863
|
+
const path = (0, import_node_path33.join)(repoPath, ".worktreeinclude");
|
|
12864
|
+
if (!(0, import_node_fs33.existsSync)(path)) return [];
|
|
12865
|
+
return (0, import_node_fs33.readFileSync)(path, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
12695
12866
|
}
|
|
12696
12867
|
function resolveFilesToCopy(repoPath) {
|
|
12697
12868
|
const fromInclude = readWorktreeInclude(repoPath);
|
|
@@ -12701,10 +12872,10 @@ function resolveFilesToCopy(repoPath) {
|
|
|
12701
12872
|
if (settings?.fileIncludeGlobs?.length) {
|
|
12702
12873
|
const matched = [];
|
|
12703
12874
|
try {
|
|
12704
|
-
for (const entry of (0,
|
|
12875
|
+
for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
12705
12876
|
if (!entry.isFile()) continue;
|
|
12706
12877
|
for (const glob of settings.fileIncludeGlobs) {
|
|
12707
|
-
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0,
|
|
12878
|
+
if (matchSimpleGlob(glob, entry.name) || matchSimpleGlob((0, import_node_path33.basename)(glob), entry.name)) {
|
|
12708
12879
|
matched.push(entry.name);
|
|
12709
12880
|
break;
|
|
12710
12881
|
}
|
|
@@ -12716,7 +12887,7 @@ function resolveFilesToCopy(repoPath) {
|
|
|
12716
12887
|
}
|
|
12717
12888
|
const defaults = [];
|
|
12718
12889
|
try {
|
|
12719
|
-
for (const entry of (0,
|
|
12890
|
+
for (const entry of (0, import_node_fs33.readdirSync)(repoPath, { withFileTypes: true })) {
|
|
12720
12891
|
if (entry.isFile() && entry.name.startsWith(".env")) {
|
|
12721
12892
|
defaults.push(entry.name);
|
|
12722
12893
|
}
|
|
@@ -12730,11 +12901,11 @@ function copyConfiguredFiles(repoPath, worktreePath) {
|
|
|
12730
12901
|
const patterns = resolveFilesToCopy(repoPath);
|
|
12731
12902
|
const copied = [];
|
|
12732
12903
|
for (const rel of patterns) {
|
|
12733
|
-
const src = (0,
|
|
12734
|
-
if (!(0,
|
|
12735
|
-
const dest = (0,
|
|
12736
|
-
(0,
|
|
12737
|
-
(0,
|
|
12904
|
+
const src = (0, import_node_path33.join)(repoPath, rel);
|
|
12905
|
+
if (!(0, import_node_fs33.existsSync)(src)) continue;
|
|
12906
|
+
const dest = (0, import_node_path33.join)(worktreePath, rel);
|
|
12907
|
+
(0, import_node_fs33.mkdirSync)((0, import_node_path33.dirname)(dest), { recursive: true });
|
|
12908
|
+
(0, import_node_fs33.copyFileSync)(src, dest);
|
|
12738
12909
|
copied.push(rel);
|
|
12739
12910
|
}
|
|
12740
12911
|
return copied;
|
|
@@ -12769,7 +12940,7 @@ function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
|
12769
12940
|
const env = stripNestedElectronEnv({
|
|
12770
12941
|
...baseEnv ?? process.env
|
|
12771
12942
|
});
|
|
12772
|
-
const name = opts.workspaceName ?? (0,
|
|
12943
|
+
const name = opts.workspaceName ?? (0, import_node_path33.basename)(opts.worktreePath);
|
|
12773
12944
|
const ports = opts.ports ?? [];
|
|
12774
12945
|
const primary = ports[0];
|
|
12775
12946
|
env.SIDEBOARD_WORKSPACE_NAME = name;
|
|
@@ -13031,13 +13202,13 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
|
13031
13202
|
done: handle.done
|
|
13032
13203
|
};
|
|
13033
13204
|
}
|
|
13034
|
-
var
|
|
13205
|
+
var import_node_fs33, import_node_net, import_node_path33, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
13035
13206
|
var init_conductor = __esm({
|
|
13036
13207
|
"src/hook/conductor.ts"() {
|
|
13037
13208
|
"use strict";
|
|
13038
|
-
|
|
13209
|
+
import_node_fs33 = require("fs");
|
|
13039
13210
|
import_node_net = require("net");
|
|
13040
|
-
|
|
13211
|
+
import_node_path33 = require("path");
|
|
13041
13212
|
import_execa4 = require("execa");
|
|
13042
13213
|
import_node_readline3 = require("readline");
|
|
13043
13214
|
init_settings();
|
|
@@ -13055,7 +13226,7 @@ var init_conductor = __esm({
|
|
|
13055
13226
|
|
|
13056
13227
|
// src/store/setup-log.ts
|
|
13057
13228
|
function setupLogPath(threadId) {
|
|
13058
|
-
return (0,
|
|
13229
|
+
return (0, import_node_path34.join)(threadsDir(), `${threadId}.setup.log.json`);
|
|
13059
13230
|
}
|
|
13060
13231
|
function emptySetupLog() {
|
|
13061
13232
|
return { ...EMPTY };
|
|
@@ -13072,7 +13243,7 @@ function persistNow(threadId) {
|
|
|
13072
13243
|
const snap = memory.get(threadId);
|
|
13073
13244
|
if (!snap) return;
|
|
13074
13245
|
try {
|
|
13075
|
-
(0,
|
|
13246
|
+
(0, import_node_fs34.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
|
|
13076
13247
|
`, "utf8");
|
|
13077
13248
|
} catch {
|
|
13078
13249
|
}
|
|
@@ -13089,9 +13260,9 @@ function schedulePersist(threadId) {
|
|
|
13089
13260
|
}
|
|
13090
13261
|
function loadFromDisk(threadId) {
|
|
13091
13262
|
const path = setupLogPath(threadId);
|
|
13092
|
-
if (!(0,
|
|
13263
|
+
if (!(0, import_node_fs34.existsSync)(path)) return null;
|
|
13093
13264
|
try {
|
|
13094
|
-
const raw = JSON.parse((0,
|
|
13265
|
+
const raw = JSON.parse((0, import_node_fs34.readFileSync)(path, "utf8"));
|
|
13095
13266
|
return {
|
|
13096
13267
|
output: typeof raw.output === "string" ? raw.output : "",
|
|
13097
13268
|
running: Boolean(raw.running),
|
|
@@ -13147,12 +13318,12 @@ function finishSetupLog(threadId, exitCode, source) {
|
|
|
13147
13318
|
persistNow(threadId);
|
|
13148
13319
|
return clone(snap);
|
|
13149
13320
|
}
|
|
13150
|
-
var
|
|
13321
|
+
var import_node_fs34, import_node_path34, EMPTY, memory, persistTimers;
|
|
13151
13322
|
var init_setup_log = __esm({
|
|
13152
13323
|
"src/store/setup-log.ts"() {
|
|
13153
13324
|
"use strict";
|
|
13154
|
-
|
|
13155
|
-
|
|
13325
|
+
import_node_fs34 = require("fs");
|
|
13326
|
+
import_node_path34 = require("path");
|
|
13156
13327
|
init_paths();
|
|
13157
13328
|
EMPTY = {
|
|
13158
13329
|
output: "",
|
|
@@ -13176,9 +13347,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13176
13347
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
13177
13348
|
);
|
|
13178
13349
|
const homeRoot = sideboardWorkspacesDir();
|
|
13179
|
-
if ((0,
|
|
13350
|
+
if ((0, import_node_fs35.existsSync)(homeRoot)) {
|
|
13180
13351
|
try {
|
|
13181
|
-
for (const entry of (0,
|
|
13352
|
+
for (const entry of (0, import_node_fs35.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
13182
13353
|
if (!entry.isDirectory()) continue;
|
|
13183
13354
|
void entry;
|
|
13184
13355
|
}
|
|
@@ -13188,7 +13359,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13188
13359
|
const orphans = [];
|
|
13189
13360
|
const seen = /* @__PURE__ */ new Set();
|
|
13190
13361
|
for (const repoPath of repos) {
|
|
13191
|
-
if (!repoPath || !(0,
|
|
13362
|
+
if (!repoPath || !(0, import_node_fs35.existsSync)(repoPath)) continue;
|
|
13192
13363
|
try {
|
|
13193
13364
|
const wts = await listWorktrees(repoPath);
|
|
13194
13365
|
for (const wt of wts) {
|
|
@@ -13199,7 +13370,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13199
13370
|
seen.add(path);
|
|
13200
13371
|
let mtimeMs = 0;
|
|
13201
13372
|
try {
|
|
13202
|
-
mtimeMs = (0,
|
|
13373
|
+
mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
|
|
13203
13374
|
} catch {
|
|
13204
13375
|
mtimeMs = 0;
|
|
13205
13376
|
}
|
|
@@ -13209,16 +13380,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
13209
13380
|
}
|
|
13210
13381
|
try {
|
|
13211
13382
|
const root = worktreesRoot(repoPath);
|
|
13212
|
-
if ((0,
|
|
13213
|
-
for (const entry of (0,
|
|
13383
|
+
if ((0, import_node_fs35.existsSync)(root)) {
|
|
13384
|
+
for (const entry of (0, import_node_fs35.readdirSync)(root, { withFileTypes: true })) {
|
|
13214
13385
|
if (!entry.isDirectory()) continue;
|
|
13215
|
-
const path = (0,
|
|
13386
|
+
const path = (0, import_node_path35.join)(root, entry.name).replace(/\/$/, "");
|
|
13216
13387
|
if (known.has(path) || seen.has(path)) continue;
|
|
13217
|
-
if (!(0,
|
|
13388
|
+
if (!(0, import_node_fs35.existsSync)((0, import_node_path35.join)(path, ".git"))) continue;
|
|
13218
13389
|
seen.add(path);
|
|
13219
13390
|
let mtimeMs = 0;
|
|
13220
13391
|
try {
|
|
13221
|
-
mtimeMs = (0,
|
|
13392
|
+
mtimeMs = (0, import_node_fs35.statSync)(path).mtimeMs;
|
|
13222
13393
|
} catch {
|
|
13223
13394
|
mtimeMs = Date.now();
|
|
13224
13395
|
}
|
|
@@ -13270,12 +13441,12 @@ function shouldRunWorktreeCleanup(settings = loadAppSettings()) {
|
|
|
13270
13441
|
const elapsed = Date.now() - Date.parse(last);
|
|
13271
13442
|
return elapsed >= intervalHours * 36e5;
|
|
13272
13443
|
}
|
|
13273
|
-
var
|
|
13444
|
+
var import_node_fs35, import_node_path35;
|
|
13274
13445
|
var init_orphan_cleanup = __esm({
|
|
13275
13446
|
"src/git/orphan-cleanup.ts"() {
|
|
13276
13447
|
"use strict";
|
|
13277
|
-
|
|
13278
|
-
|
|
13448
|
+
import_node_fs35 = require("fs");
|
|
13449
|
+
import_node_path35 = require("path");
|
|
13279
13450
|
init_worktree();
|
|
13280
13451
|
init_thread_store();
|
|
13281
13452
|
init_paths();
|
|
@@ -13378,12 +13549,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
13378
13549
|
if (!url) throw new Error("Clone URL is required");
|
|
13379
13550
|
let name = opts.name?.trim();
|
|
13380
13551
|
if (!name) {
|
|
13381
|
-
const leaf = (0,
|
|
13552
|
+
const leaf = (0, import_node_path36.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
13382
13553
|
name = leaf || "repo";
|
|
13383
13554
|
}
|
|
13384
13555
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
13385
|
-
const dest = (0,
|
|
13386
|
-
if ((0,
|
|
13556
|
+
const dest = (0, import_node_path36.join)(sideboardReposDir(), name);
|
|
13557
|
+
if ((0, import_node_fs36.existsSync)(dest)) {
|
|
13387
13558
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
13388
13559
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
13389
13560
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -13398,12 +13569,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
13398
13569
|
const workspace = await ensureWorkspace(repoPath);
|
|
13399
13570
|
return { repoPath, workspace };
|
|
13400
13571
|
}
|
|
13401
|
-
var
|
|
13572
|
+
var import_node_fs36, import_node_path36, import_execa6;
|
|
13402
13573
|
var init_clone_repo = __esm({
|
|
13403
13574
|
"src/git/clone-repo.ts"() {
|
|
13404
13575
|
"use strict";
|
|
13405
|
-
|
|
13406
|
-
|
|
13576
|
+
import_node_fs36 = require("fs");
|
|
13577
|
+
import_node_path36 = require("path");
|
|
13407
13578
|
import_execa6 = require("execa");
|
|
13408
13579
|
init_paths();
|
|
13409
13580
|
init_workspaces2();
|
|
@@ -13413,11 +13584,11 @@ var init_clone_repo = __esm({
|
|
|
13413
13584
|
|
|
13414
13585
|
// src/store/desktop-host.ts
|
|
13415
13586
|
function desktopHostPidPath() {
|
|
13416
|
-
return (0,
|
|
13587
|
+
return (0, import_node_path37.join)(appDataDir(), "desktop-host.pid");
|
|
13417
13588
|
}
|
|
13418
13589
|
function readDesktopHostPid() {
|
|
13419
13590
|
try {
|
|
13420
|
-
const pid = Number.parseInt((0,
|
|
13591
|
+
const pid = Number.parseInt((0, import_node_fs37.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
13421
13592
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
13422
13593
|
return pid;
|
|
13423
13594
|
} catch {
|
|
@@ -13443,12 +13614,12 @@ function thisProcessShouldDrainAgentQueues() {
|
|
|
13443
13614
|
if (isThisProcessDesktopHost()) return true;
|
|
13444
13615
|
return !isDesktopHostAlive();
|
|
13445
13616
|
}
|
|
13446
|
-
var
|
|
13617
|
+
var import_node_fs37, import_node_path37;
|
|
13447
13618
|
var init_desktop_host = __esm({
|
|
13448
13619
|
"src/store/desktop-host.ts"() {
|
|
13449
13620
|
"use strict";
|
|
13450
|
-
|
|
13451
|
-
|
|
13621
|
+
import_node_fs37 = require("fs");
|
|
13622
|
+
import_node_path37 = require("path");
|
|
13452
13623
|
init_paths();
|
|
13453
13624
|
}
|
|
13454
13625
|
});
|
|
@@ -14500,7 +14671,7 @@ function reuseLiveThread(input, repoPath, match) {
|
|
|
14500
14671
|
}
|
|
14501
14672
|
async function createThread(input, _onSetupLine) {
|
|
14502
14673
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
14503
|
-
if (!(0,
|
|
14674
|
+
if (!(0, import_node_fs38.existsSync)(repoPath)) {
|
|
14504
14675
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
14505
14676
|
}
|
|
14506
14677
|
const reused = reuseLiveThread(input, repoPath, {
|
|
@@ -14671,11 +14842,11 @@ async function createThread(input, _onSetupLine) {
|
|
|
14671
14842
|
await ensureWorkspace(repoPath);
|
|
14672
14843
|
return readThread(thread.id) ?? thread;
|
|
14673
14844
|
}
|
|
14674
|
-
var
|
|
14845
|
+
var import_node_fs38;
|
|
14675
14846
|
var init_create = __esm({
|
|
14676
14847
|
"src/threads/create.ts"() {
|
|
14677
14848
|
"use strict";
|
|
14678
|
-
|
|
14849
|
+
import_node_fs38 = require("fs");
|
|
14679
14850
|
init_detect();
|
|
14680
14851
|
init_worktree();
|
|
14681
14852
|
init_home_board();
|
|
@@ -14778,20 +14949,20 @@ function writeTurnLive(threadId, progress) {
|
|
|
14778
14949
|
const path = threadLivePath(threadId);
|
|
14779
14950
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
14780
14951
|
try {
|
|
14781
|
-
(0,
|
|
14782
|
-
(0,
|
|
14952
|
+
(0, import_node_fs39.writeFileSync)(tmp, JSON.stringify(progress), "utf8");
|
|
14953
|
+
(0, import_node_fs39.renameSync)(tmp, path);
|
|
14783
14954
|
} catch {
|
|
14784
14955
|
try {
|
|
14785
|
-
(0,
|
|
14956
|
+
(0, import_node_fs39.unlinkSync)(tmp);
|
|
14786
14957
|
} catch {
|
|
14787
14958
|
}
|
|
14788
14959
|
}
|
|
14789
14960
|
}
|
|
14790
14961
|
function readTurnLive(threadId) {
|
|
14791
14962
|
const path = threadLivePath(threadId);
|
|
14792
|
-
if (!(0,
|
|
14963
|
+
if (!(0, import_node_fs39.existsSync)(path)) return null;
|
|
14793
14964
|
try {
|
|
14794
|
-
const raw = JSON.parse((0,
|
|
14965
|
+
const raw = JSON.parse((0, import_node_fs39.readFileSync)(path, "utf8"));
|
|
14795
14966
|
if (!raw || typeof raw.summary !== "string") return null;
|
|
14796
14967
|
return raw;
|
|
14797
14968
|
} catch {
|
|
@@ -14803,17 +14974,17 @@ function clearTurnLive(threadId) {
|
|
|
14803
14974
|
if (buf?.timer) clearTimeout(buf.timer);
|
|
14804
14975
|
buffers.delete(threadId);
|
|
14805
14976
|
const path = threadLivePath(threadId);
|
|
14806
|
-
if (!(0,
|
|
14977
|
+
if (!(0, import_node_fs39.existsSync)(path)) return;
|
|
14807
14978
|
try {
|
|
14808
|
-
(0,
|
|
14979
|
+
(0, import_node_fs39.unlinkSync)(path);
|
|
14809
14980
|
} catch {
|
|
14810
14981
|
}
|
|
14811
14982
|
}
|
|
14812
|
-
var
|
|
14983
|
+
var import_node_fs39, buffers, FLUSH_MS, MAX_PARTS;
|
|
14813
14984
|
var init_turn_live = __esm({
|
|
14814
14985
|
"src/store/turn-live.ts"() {
|
|
14815
14986
|
"use strict";
|
|
14816
|
-
|
|
14987
|
+
import_node_fs39 = require("fs");
|
|
14817
14988
|
init_message_parts();
|
|
14818
14989
|
init_paths();
|
|
14819
14990
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -14846,7 +15017,8 @@ var init_reconcile_heal = __esm({
|
|
|
14846
15017
|
// src/orchestrator/setup-last-error.ts
|
|
14847
15018
|
function shouldStampSetupLastError(opts) {
|
|
14848
15019
|
if (opts.turnInFlight) return false;
|
|
14849
|
-
if (opts.status === "running") return false;
|
|
15020
|
+
if (opts.status === "running" || opts.status === "queued") return false;
|
|
15021
|
+
if (opts.hasQueuedPrompt) return false;
|
|
14850
15022
|
return true;
|
|
14851
15023
|
}
|
|
14852
15024
|
function isStaleLastErrorDuringTurn(err) {
|
|
@@ -15029,7 +15201,7 @@ var init_quota_failover = __esm({
|
|
|
15029
15201
|
// src/threads/adopt.ts
|
|
15030
15202
|
function thisModuleFile() {
|
|
15031
15203
|
const cjsFile = typeof __filename !== "undefined" ? __filename : "";
|
|
15032
|
-
return cjsFile || process.argv[1] || (0,
|
|
15204
|
+
return cjsFile || process.argv[1] || (0, import_node_path38.join)(process.cwd(), "package.json");
|
|
15033
15205
|
}
|
|
15034
15206
|
function openReadonlySqlite(file) {
|
|
15035
15207
|
const req = (0, import_node_module4.createRequire)(thisModuleFile());
|
|
@@ -15047,21 +15219,21 @@ function mapAgentType(raw) {
|
|
|
15047
15219
|
return null;
|
|
15048
15220
|
}
|
|
15049
15221
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
15050
|
-
if (!workspacePath || !(0,
|
|
15222
|
+
if (!workspacePath || !(0, import_node_fs40.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
15051
15223
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
15052
15224
|
let best = null;
|
|
15053
15225
|
let hashes;
|
|
15054
15226
|
try {
|
|
15055
|
-
hashes = (0,
|
|
15227
|
+
hashes = (0, import_node_fs40.readdirSync)(CURSOR_SDK_STORE);
|
|
15056
15228
|
} catch {
|
|
15057
15229
|
return null;
|
|
15058
15230
|
}
|
|
15059
15231
|
for (const hash of hashes) {
|
|
15060
|
-
const agentsFile = (0,
|
|
15061
|
-
if (!(0,
|
|
15232
|
+
const agentsFile = (0, import_node_path38.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
15233
|
+
if (!(0, import_node_fs40.existsSync)(agentsFile)) continue;
|
|
15062
15234
|
let text5;
|
|
15063
15235
|
try {
|
|
15064
|
-
text5 = (0,
|
|
15236
|
+
text5 = (0, import_node_fs40.readFileSync)(agentsFile, "utf8");
|
|
15065
15237
|
} catch {
|
|
15066
15238
|
continue;
|
|
15067
15239
|
}
|
|
@@ -15085,7 +15257,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
15085
15257
|
return best?.agentId ?? null;
|
|
15086
15258
|
}
|
|
15087
15259
|
async function adoptThread(input) {
|
|
15088
|
-
if (!(0,
|
|
15260
|
+
if (!(0, import_node_fs40.existsSync)(input.worktreePath)) {
|
|
15089
15261
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
15090
15262
|
}
|
|
15091
15263
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -15111,18 +15283,18 @@ async function adoptThread(input) {
|
|
|
15111
15283
|
return thread;
|
|
15112
15284
|
}
|
|
15113
15285
|
function listConductorWorkspaces() {
|
|
15114
|
-
if (!(0,
|
|
15286
|
+
if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
|
|
15115
15287
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
15116
15288
|
}
|
|
15117
|
-
const tmp = (0,
|
|
15118
|
-
const snapshot = (0,
|
|
15289
|
+
const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
|
|
15290
|
+
const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
|
|
15119
15291
|
try {
|
|
15120
|
-
(0,
|
|
15292
|
+
(0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
15121
15293
|
for (const suffix of ["-wal", "-shm"]) {
|
|
15122
15294
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
15123
|
-
if ((0,
|
|
15295
|
+
if ((0, import_node_fs40.existsSync)(src)) {
|
|
15124
15296
|
try {
|
|
15125
|
-
(0,
|
|
15297
|
+
(0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
15126
15298
|
} catch {
|
|
15127
15299
|
}
|
|
15128
15300
|
}
|
|
@@ -15198,22 +15370,22 @@ function listConductorWorkspaces() {
|
|
|
15198
15370
|
db.close();
|
|
15199
15371
|
}
|
|
15200
15372
|
} finally {
|
|
15201
|
-
(0,
|
|
15373
|
+
(0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
|
|
15202
15374
|
}
|
|
15203
15375
|
}
|
|
15204
15376
|
function importConductorWorkspace(workspaceId) {
|
|
15205
|
-
if (!(0,
|
|
15377
|
+
if (!(0, import_node_fs40.existsSync)(CONDUCTOR_DB)) {
|
|
15206
15378
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
15207
15379
|
}
|
|
15208
|
-
const tmp = (0,
|
|
15209
|
-
const snapshot = (0,
|
|
15380
|
+
const tmp = (0, import_node_fs40.mkdtempSync)((0, import_node_path38.join)((0, import_node_os13.tmpdir)(), "sideboard-conductor-"));
|
|
15381
|
+
const snapshot = (0, import_node_path38.join)(tmp, "conductor.db");
|
|
15210
15382
|
try {
|
|
15211
|
-
(0,
|
|
15383
|
+
(0, import_node_fs40.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
15212
15384
|
for (const suffix of ["-wal", "-shm"]) {
|
|
15213
15385
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
15214
|
-
if ((0,
|
|
15386
|
+
if ((0, import_node_fs40.existsSync)(src)) {
|
|
15215
15387
|
try {
|
|
15216
|
-
(0,
|
|
15388
|
+
(0, import_node_fs40.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
15217
15389
|
} catch {
|
|
15218
15390
|
}
|
|
15219
15391
|
}
|
|
@@ -15231,7 +15403,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
15231
15403
|
).get(workspaceId);
|
|
15232
15404
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
15233
15405
|
const worktreePath = String(row.workspacePath);
|
|
15234
|
-
if (!(0,
|
|
15406
|
+
if (!(0, import_node_fs40.existsSync)(worktreePath)) {
|
|
15235
15407
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
15236
15408
|
}
|
|
15237
15409
|
let sessionId = null;
|
|
@@ -15294,31 +15466,31 @@ function importConductorWorkspace(workspaceId) {
|
|
|
15294
15466
|
db.close();
|
|
15295
15467
|
}
|
|
15296
15468
|
} finally {
|
|
15297
|
-
(0,
|
|
15469
|
+
(0, import_node_fs40.rmSync)(tmp, { recursive: true, force: true });
|
|
15298
15470
|
}
|
|
15299
15471
|
}
|
|
15300
15472
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
15301
15473
|
return importConductorWorkspace(workspaceId);
|
|
15302
15474
|
}
|
|
15303
|
-
var import_node_child_process3,
|
|
15475
|
+
var import_node_child_process3, import_node_fs40, import_node_os13, import_node_path38, import_node_module4, CONDUCTOR_APP_SUPPORT, CONDUCTOR_DB, CURSOR_SDK_STORE;
|
|
15304
15476
|
var init_adopt = __esm({
|
|
15305
15477
|
"src/threads/adopt.ts"() {
|
|
15306
15478
|
"use strict";
|
|
15307
15479
|
import_node_child_process3 = require("child_process");
|
|
15308
|
-
|
|
15309
|
-
|
|
15310
|
-
|
|
15480
|
+
import_node_fs40 = require("fs");
|
|
15481
|
+
import_node_os13 = require("os");
|
|
15482
|
+
import_node_path38 = require("path");
|
|
15311
15483
|
import_node_module4 = require("module");
|
|
15312
15484
|
init_worktree();
|
|
15313
15485
|
init_thread_store();
|
|
15314
|
-
CONDUCTOR_APP_SUPPORT = (0,
|
|
15486
|
+
CONDUCTOR_APP_SUPPORT = (0, import_node_path38.join)(
|
|
15315
15487
|
process.env.HOME ?? "",
|
|
15316
15488
|
"Library",
|
|
15317
15489
|
"Application Support",
|
|
15318
15490
|
"com.conductor.app"
|
|
15319
15491
|
);
|
|
15320
|
-
CONDUCTOR_DB = (0,
|
|
15321
|
-
CURSOR_SDK_STORE = (0,
|
|
15492
|
+
CONDUCTOR_DB = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
15493
|
+
CURSOR_SDK_STORE = (0, import_node_path38.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
15322
15494
|
}
|
|
15323
15495
|
});
|
|
15324
15496
|
|
|
@@ -15385,7 +15557,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
15385
15557
|
let createdWorktree = false;
|
|
15386
15558
|
const trees = await listWorktrees(repoPath);
|
|
15387
15559
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
15388
|
-
if (checkedOut?.path && (0,
|
|
15560
|
+
if (checkedOut?.path && (0, import_node_fs41.existsSync)(checkedOut.path)) {
|
|
15389
15561
|
if (input.reuseExistingWorktree !== false) {
|
|
15390
15562
|
worktreePath = checkedOut.path;
|
|
15391
15563
|
} else {
|
|
@@ -15527,7 +15699,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
15527
15699
|
async function createPrStack(input, onSetupLine) {
|
|
15528
15700
|
await requireAgent(input.agent);
|
|
15529
15701
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
15530
|
-
if (!(0,
|
|
15702
|
+
if (!(0, import_node_fs41.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
15531
15703
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
15532
15704
|
const status = await detectGhStack(repoPath);
|
|
15533
15705
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -15594,7 +15766,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
15594
15766
|
}
|
|
15595
15767
|
}
|
|
15596
15768
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
15597
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
15769
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs41.existsSync)(bootstrap.worktreePath)) {
|
|
15598
15770
|
try {
|
|
15599
15771
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
15600
15772
|
deleteBranch: bootstrap.branchName
|
|
@@ -15604,11 +15776,11 @@ async function createPrStack(input, onSetupLine) {
|
|
|
15604
15776
|
}
|
|
15605
15777
|
return { stack, threads, createdThreadIds };
|
|
15606
15778
|
}
|
|
15607
|
-
var
|
|
15779
|
+
var import_node_fs41;
|
|
15608
15780
|
var init_stack_layers = __esm({
|
|
15609
15781
|
"src/threads/stack-layers.ts"() {
|
|
15610
15782
|
"use strict";
|
|
15611
|
-
|
|
15783
|
+
import_node_fs41 = require("fs");
|
|
15612
15784
|
init_detect();
|
|
15613
15785
|
init_run();
|
|
15614
15786
|
init_stack();
|
|
@@ -15621,7 +15793,7 @@ var init_stack_layers = __esm({
|
|
|
15621
15793
|
|
|
15622
15794
|
// src/diff/diff.ts
|
|
15623
15795
|
async function inspectGitWorktree(worktreePath) {
|
|
15624
|
-
if (!worktreePath || !(0,
|
|
15796
|
+
if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) return "missing_worktree";
|
|
15625
15797
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
15626
15798
|
reject: false
|
|
15627
15799
|
});
|
|
@@ -15629,7 +15801,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
15629
15801
|
return "ok";
|
|
15630
15802
|
}
|
|
15631
15803
|
async function initializeGitRepository(worktreePath) {
|
|
15632
|
-
if (!worktreePath || !(0,
|
|
15804
|
+
if (!worktreePath || !(0, import_node_fs42.existsSync)(worktreePath)) {
|
|
15633
15805
|
throw new Error("Worktree not found");
|
|
15634
15806
|
}
|
|
15635
15807
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -15763,11 +15935,11 @@ new file mode 100644
|
|
|
15763
15935
|
};
|
|
15764
15936
|
}
|
|
15765
15937
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
15766
|
-
const abs = (0,
|
|
15938
|
+
const abs = (0, import_node_path39.join)(worktreePath, path);
|
|
15767
15939
|
try {
|
|
15768
|
-
const st = (0,
|
|
15940
|
+
const st = (0, import_node_fs42.statSync)(abs);
|
|
15769
15941
|
if (st.isFile() && st.size > maxHunk) {
|
|
15770
|
-
const buf = (0,
|
|
15942
|
+
const buf = (0, import_node_fs42.readFileSync)(abs).subarray(0, maxHunk);
|
|
15771
15943
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
15772
15944
|
}
|
|
15773
15945
|
} catch {
|
|
@@ -16256,8 +16428,8 @@ function isImageRelativePath(relativePath) {
|
|
|
16256
16428
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
16257
16429
|
assertSafeRelativePath(relativePath);
|
|
16258
16430
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
16259
|
-
const abs = (0,
|
|
16260
|
-
const st = (0,
|
|
16431
|
+
const abs = (0, import_node_path39.join)(worktreePath, relativePath);
|
|
16432
|
+
const st = (0, import_node_fs42.statSync)(abs);
|
|
16261
16433
|
if (!st.isFile()) {
|
|
16262
16434
|
throw new Error(`Not a file: ${relativePath}`);
|
|
16263
16435
|
}
|
|
@@ -16266,7 +16438,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
16266
16438
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
16267
16439
|
);
|
|
16268
16440
|
}
|
|
16269
|
-
const buf = (0,
|
|
16441
|
+
const buf = (0, import_node_fs42.readFileSync)(abs);
|
|
16270
16442
|
return {
|
|
16271
16443
|
path: relativePath,
|
|
16272
16444
|
contentBase64: buf.toString("base64"),
|
|
@@ -16276,12 +16448,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
16276
16448
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
16277
16449
|
assertSafeRelativePath(relativePath);
|
|
16278
16450
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
16279
|
-
const abs = (0,
|
|
16280
|
-
const st = (0,
|
|
16451
|
+
const abs = (0, import_node_path39.join)(worktreePath, relativePath);
|
|
16452
|
+
const st = (0, import_node_fs42.statSync)(abs);
|
|
16281
16453
|
if (!st.isFile()) {
|
|
16282
16454
|
throw new Error(`Not a file: ${relativePath}`);
|
|
16283
16455
|
}
|
|
16284
|
-
const buf = (0,
|
|
16456
|
+
const buf = (0, import_node_fs42.readFileSync)(abs);
|
|
16285
16457
|
if (isImageRelativePath(relativePath)) {
|
|
16286
16458
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
16287
16459
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -16324,9 +16496,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
16324
16496
|
}
|
|
16325
16497
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
16326
16498
|
assertSafeRelativePath(relativePath);
|
|
16327
|
-
const abs = (0,
|
|
16328
|
-
(0,
|
|
16329
|
-
(0,
|
|
16499
|
+
const abs = (0, import_node_path39.join)(worktreePath, relativePath);
|
|
16500
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path39.dirname)(abs), { recursive: true });
|
|
16501
|
+
(0, import_node_fs42.writeFileSync)(abs, content, "utf8");
|
|
16330
16502
|
return { path: relativePath };
|
|
16331
16503
|
}
|
|
16332
16504
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -16343,12 +16515,12 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
16343
16515
|
truncated: full.files.length > maxFiles
|
|
16344
16516
|
};
|
|
16345
16517
|
}
|
|
16346
|
-
var
|
|
16518
|
+
var import_node_fs42, import_node_path39, mergeBaseCache, MERGE_BASE_TTL_MS, SHA_RE, IMAGE_EXTENSIONS2, DEFAULT_UPLOAD_MAX_BYTES;
|
|
16347
16519
|
var init_diff = __esm({
|
|
16348
16520
|
"src/diff/diff.ts"() {
|
|
16349
16521
|
"use strict";
|
|
16350
|
-
|
|
16351
|
-
|
|
16522
|
+
import_node_fs42 = require("fs");
|
|
16523
|
+
import_node_path39 = require("path");
|
|
16352
16524
|
init_run();
|
|
16353
16525
|
init_worktree();
|
|
16354
16526
|
mergeBaseCache = /* @__PURE__ */ new Map();
|
|
@@ -16616,7 +16788,7 @@ function parseFrontmatter(content) {
|
|
|
16616
16788
|
}
|
|
16617
16789
|
function readSkill(skillMd, source) {
|
|
16618
16790
|
try {
|
|
16619
|
-
const content = (0,
|
|
16791
|
+
const content = (0, import_node_fs43.readFileSync)(skillMd, "utf8");
|
|
16620
16792
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
16621
16793
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
16622
16794
|
const name = fmName || dirName;
|
|
@@ -16635,19 +16807,19 @@ function readSkill(skillMd, source) {
|
|
|
16635
16807
|
}
|
|
16636
16808
|
}
|
|
16637
16809
|
function scanSkillsDir(dir, source, out) {
|
|
16638
|
-
if (!(0,
|
|
16810
|
+
if (!(0, import_node_fs43.existsSync)(dir)) return;
|
|
16639
16811
|
let entries;
|
|
16640
16812
|
try {
|
|
16641
|
-
entries = (0,
|
|
16813
|
+
entries = (0, import_node_fs43.readdirSync)(dir);
|
|
16642
16814
|
} catch {
|
|
16643
16815
|
return;
|
|
16644
16816
|
}
|
|
16645
16817
|
for (const entry of entries) {
|
|
16646
16818
|
if (entry.startsWith(".")) continue;
|
|
16647
|
-
const skillMd = (0,
|
|
16648
|
-
if (!(0,
|
|
16819
|
+
const skillMd = (0, import_node_path40.join)(dir, entry, "SKILL.md");
|
|
16820
|
+
if (!(0, import_node_fs43.existsSync)(skillMd)) continue;
|
|
16649
16821
|
try {
|
|
16650
|
-
if (!(0,
|
|
16822
|
+
if (!(0, import_node_fs43.statSync)(skillMd).isFile()) continue;
|
|
16651
16823
|
} catch {
|
|
16652
16824
|
continue;
|
|
16653
16825
|
}
|
|
@@ -16656,24 +16828,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
16656
16828
|
}
|
|
16657
16829
|
}
|
|
16658
16830
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
16659
|
-
if (!(0,
|
|
16831
|
+
if (!(0, import_node_fs43.existsSync)(pluginsRoot)) return;
|
|
16660
16832
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
16661
16833
|
if (depth > 7) return;
|
|
16662
16834
|
let entries;
|
|
16663
16835
|
try {
|
|
16664
|
-
entries = (0,
|
|
16836
|
+
entries = (0, import_node_fs43.readdirSync)(dir);
|
|
16665
16837
|
} catch {
|
|
16666
16838
|
return;
|
|
16667
16839
|
}
|
|
16668
16840
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
16669
|
-
const skill = readSkill((0,
|
|
16841
|
+
const skill = readSkill((0, import_node_path40.join)(dir, "SKILL.md"), "cli");
|
|
16670
16842
|
if (skill) out.push(skill);
|
|
16671
16843
|
}
|
|
16672
16844
|
for (const entry of entries) {
|
|
16673
16845
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
16674
|
-
const full = (0,
|
|
16846
|
+
const full = (0, import_node_path40.join)(dir, entry);
|
|
16675
16847
|
try {
|
|
16676
|
-
if (!(0,
|
|
16848
|
+
if (!(0, import_node_fs43.statSync)(full).isDirectory()) continue;
|
|
16677
16849
|
} catch {
|
|
16678
16850
|
continue;
|
|
16679
16851
|
}
|
|
@@ -16688,20 +16860,20 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
16688
16860
|
walk(pluginsRoot, 0, false);
|
|
16689
16861
|
}
|
|
16690
16862
|
function discoverSkills(worktreePath) {
|
|
16691
|
-
const home = (0,
|
|
16863
|
+
const home = (0, import_node_os14.homedir)();
|
|
16692
16864
|
const collected = [];
|
|
16693
16865
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
16694
|
-
scanSkillsDir((0,
|
|
16866
|
+
scanSkillsDir((0, import_node_path40.join)(worktreePath, rel), "workspace", collected);
|
|
16695
16867
|
}
|
|
16696
16868
|
for (const abs of [
|
|
16697
|
-
(0,
|
|
16698
|
-
(0,
|
|
16699
|
-
(0,
|
|
16700
|
-
(0,
|
|
16869
|
+
(0, import_node_path40.join)(home, ".claude/skills"),
|
|
16870
|
+
(0, import_node_path40.join)(home, ".cursor/skills"),
|
|
16871
|
+
(0, import_node_path40.join)(home, ".sideboard/skills"),
|
|
16872
|
+
(0, import_node_path40.join)(home, ".brightsy/skills")
|
|
16701
16873
|
]) {
|
|
16702
16874
|
scanSkillsDir(abs, "user", collected);
|
|
16703
16875
|
}
|
|
16704
|
-
scanClaudePluginSkills((0,
|
|
16876
|
+
scanClaudePluginSkills((0, import_node_path40.join)(home, ".claude/plugins"), collected);
|
|
16705
16877
|
collected.push(...bundledSkills());
|
|
16706
16878
|
const rank = {
|
|
16707
16879
|
workspace: 0,
|
|
@@ -16727,7 +16899,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
16727
16899
|
\u2026(truncated)` : body;
|
|
16728
16900
|
}
|
|
16729
16901
|
}
|
|
16730
|
-
const raw = (0,
|
|
16902
|
+
const raw = (0, import_node_fs43.readFileSync)(skillPath, "utf8");
|
|
16731
16903
|
if (raw.startsWith("---")) {
|
|
16732
16904
|
const end = raw.indexOf("\n---", 3);
|
|
16733
16905
|
if (end >= 0) {
|
|
@@ -16741,13 +16913,13 @@ function readSkillBody(skillPath, maxChars = 12e3) {
|
|
|
16741
16913
|
|
|
16742
16914
|
\u2026(truncated)` : raw;
|
|
16743
16915
|
}
|
|
16744
|
-
var
|
|
16916
|
+
var import_node_fs43, import_node_os14, import_node_path40, BUNDLED_SKILL_PREFIX;
|
|
16745
16917
|
var init_discover = __esm({
|
|
16746
16918
|
"src/skills/discover.ts"() {
|
|
16747
16919
|
"use strict";
|
|
16748
|
-
|
|
16749
|
-
|
|
16750
|
-
|
|
16920
|
+
import_node_fs43 = require("fs");
|
|
16921
|
+
import_node_os14 = require("os");
|
|
16922
|
+
import_node_path40 = require("path");
|
|
16751
16923
|
init_long_running();
|
|
16752
16924
|
BUNDLED_SKILL_PREFIX = "bundled:";
|
|
16753
16925
|
}
|
|
@@ -16842,17 +17014,17 @@ var init_expand = __esm({
|
|
|
16842
17014
|
function packagedDetachedJobPath() {
|
|
16843
17015
|
const dir = packagedMcpDir();
|
|
16844
17016
|
if (!dir) return null;
|
|
16845
|
-
const script = (0,
|
|
16846
|
-
return (0,
|
|
17017
|
+
const script = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
|
|
17018
|
+
return (0, import_node_fs44.existsSync)(script) ? script : null;
|
|
16847
17019
|
}
|
|
16848
17020
|
function resolveDetachedJobScript() {
|
|
16849
17021
|
const packaged = packagedDetachedJobPath();
|
|
16850
17022
|
if (packaged) return packaged;
|
|
16851
|
-
let dir = (0,
|
|
17023
|
+
let dir = (0, import_node_path41.dirname)((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
16852
17024
|
for (let i = 0; i < 8; i++) {
|
|
16853
|
-
const candidate = (0,
|
|
16854
|
-
if ((0,
|
|
16855
|
-
const parent = (0,
|
|
17025
|
+
const candidate = (0, import_node_path41.join)(dir, "scripts", "detached-job.js");
|
|
17026
|
+
if ((0, import_node_fs44.existsSync)(candidate)) return candidate;
|
|
17027
|
+
const parent = (0, import_node_path41.dirname)(dir);
|
|
16856
17028
|
if (parent === dir) break;
|
|
16857
17029
|
dir = parent;
|
|
16858
17030
|
}
|
|
@@ -16863,12 +17035,12 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
16863
17035
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
16864
17036
|
return "node scripts/detached-job.js";
|
|
16865
17037
|
}
|
|
16866
|
-
var
|
|
17038
|
+
var import_node_fs44, import_node_path41, import_node_url3, import_meta3;
|
|
16867
17039
|
var init_detached_job_path = __esm({
|
|
16868
17040
|
"src/skills/detached-job-path.ts"() {
|
|
16869
17041
|
"use strict";
|
|
16870
|
-
|
|
16871
|
-
|
|
17042
|
+
import_node_fs44 = require("fs");
|
|
17043
|
+
import_node_path41 = require("path");
|
|
16872
17044
|
import_node_url3 = require("url");
|
|
16873
17045
|
init_packaged_runtime();
|
|
16874
17046
|
import_meta3 = {};
|
|
@@ -17046,12 +17218,12 @@ function formatArtifactDirective() {
|
|
|
17046
17218
|
function formatUiReminder() {
|
|
17047
17219
|
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
17048
17220
|
}
|
|
17049
|
-
var
|
|
17221
|
+
var import_node_fs45, import_node_path42;
|
|
17050
17222
|
var init_instructions = __esm({
|
|
17051
17223
|
"src/agents/instructions.ts"() {
|
|
17052
17224
|
"use strict";
|
|
17053
|
-
|
|
17054
|
-
|
|
17225
|
+
import_node_fs45 = require("fs");
|
|
17226
|
+
import_node_path42 = require("path");
|
|
17055
17227
|
init_git_auth_mode();
|
|
17056
17228
|
init_worktree_labels();
|
|
17057
17229
|
init_detached_job_path();
|
|
@@ -17221,40 +17393,40 @@ __export(plan_file_exports, {
|
|
|
17221
17393
|
writePlanFile: () => writePlanFile
|
|
17222
17394
|
});
|
|
17223
17395
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
17224
|
-
const gitignoreAbs = (0,
|
|
17225
|
-
if ((0,
|
|
17226
|
-
(0,
|
|
17227
|
-
(0,
|
|
17396
|
+
const gitignoreAbs = (0, import_node_path43.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
17397
|
+
if ((0, import_node_fs46.existsSync)(gitignoreAbs)) return;
|
|
17398
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(gitignoreAbs), { recursive: true });
|
|
17399
|
+
(0, import_node_fs46.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
17228
17400
|
}
|
|
17229
17401
|
function planFileAbs(worktreePath) {
|
|
17230
|
-
return (0,
|
|
17402
|
+
return (0, import_node_path43.join)(worktreePath, PLAN_FILE_REL);
|
|
17231
17403
|
}
|
|
17232
17404
|
function readTextIfPresent2(abs) {
|
|
17233
|
-
if (!(0,
|
|
17405
|
+
if (!(0, import_node_fs46.existsSync)(abs)) return null;
|
|
17234
17406
|
try {
|
|
17235
|
-
const content = (0,
|
|
17407
|
+
const content = (0, import_node_fs46.readFileSync)(abs, "utf8");
|
|
17236
17408
|
return content.trim() ? content : null;
|
|
17237
17409
|
} catch {
|
|
17238
17410
|
return null;
|
|
17239
17411
|
}
|
|
17240
17412
|
}
|
|
17241
17413
|
function readPlanFile(worktreePath) {
|
|
17242
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
17414
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path43.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path43.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
17243
17415
|
}
|
|
17244
17416
|
function writePlanFile(worktreePath, content) {
|
|
17245
17417
|
ensureAttachmentsGitignore(worktreePath);
|
|
17246
17418
|
const abs = planFileAbs(worktreePath);
|
|
17247
|
-
(0,
|
|
17419
|
+
(0, import_node_fs46.mkdirSync)((0, import_node_path43.dirname)(abs), { recursive: true });
|
|
17248
17420
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
17249
|
-
(0,
|
|
17421
|
+
(0, import_node_fs46.writeFileSync)(abs, body, "utf8");
|
|
17250
17422
|
return PLAN_FILE_REL;
|
|
17251
17423
|
}
|
|
17252
|
-
var
|
|
17424
|
+
var import_node_fs46, import_node_path43;
|
|
17253
17425
|
var init_plan_file = __esm({
|
|
17254
17426
|
"src/plan/plan-file.ts"() {
|
|
17255
17427
|
"use strict";
|
|
17256
|
-
|
|
17257
|
-
|
|
17428
|
+
import_node_fs46 = require("fs");
|
|
17429
|
+
import_node_path43 = require("path");
|
|
17258
17430
|
init_workspace_scratch();
|
|
17259
17431
|
init_plan_present();
|
|
17260
17432
|
init_plan_present();
|
|
@@ -17314,7 +17486,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
17314
17486
|
hooks = next;
|
|
17315
17487
|
}
|
|
17316
17488
|
function caffeinateHoldPath() {
|
|
17317
|
-
return (0,
|
|
17489
|
+
return (0, import_node_path44.join)(appDataDir(), "caffeinate-hold.json");
|
|
17318
17490
|
}
|
|
17319
17491
|
function processAlive(pid) {
|
|
17320
17492
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -17348,9 +17520,9 @@ function uniqueIds(ids) {
|
|
|
17348
17520
|
}
|
|
17349
17521
|
function readHold() {
|
|
17350
17522
|
const path = caffeinateHoldPath();
|
|
17351
|
-
if (!(0,
|
|
17523
|
+
if (!(0, import_node_fs47.existsSync)(path)) return null;
|
|
17352
17524
|
try {
|
|
17353
|
-
const parsed = JSON.parse((0,
|
|
17525
|
+
const parsed = JSON.parse((0, import_node_fs47.readFileSync)(path, "utf8"));
|
|
17354
17526
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
17355
17527
|
return {
|
|
17356
17528
|
pid: parsed.pid,
|
|
@@ -17372,7 +17544,7 @@ function writeHold(pid, threadIds) {
|
|
|
17372
17544
|
}
|
|
17373
17545
|
function clearHold() {
|
|
17374
17546
|
try {
|
|
17375
|
-
(0,
|
|
17547
|
+
(0, import_node_fs47.unlinkSync)(caffeinateHoldPath());
|
|
17376
17548
|
} catch {
|
|
17377
17549
|
}
|
|
17378
17550
|
}
|
|
@@ -17457,13 +17629,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
17457
17629
|
}
|
|
17458
17630
|
return setCaffeinateHold(false, { threadId: id });
|
|
17459
17631
|
}
|
|
17460
|
-
var import_node_child_process4,
|
|
17632
|
+
var import_node_child_process4, import_node_fs47, import_node_path44, hooks;
|
|
17461
17633
|
var init_caffeinate_hold = __esm({
|
|
17462
17634
|
"src/store/caffeinate-hold.ts"() {
|
|
17463
17635
|
"use strict";
|
|
17464
17636
|
import_node_child_process4 = require("child_process");
|
|
17465
|
-
|
|
17466
|
-
|
|
17637
|
+
import_node_fs47 = require("fs");
|
|
17638
|
+
import_node_path44 = require("path");
|
|
17467
17639
|
init_paths();
|
|
17468
17640
|
init_private_file();
|
|
17469
17641
|
hooks = {};
|
|
@@ -17472,7 +17644,7 @@ var init_caffeinate_hold = __esm({
|
|
|
17472
17644
|
|
|
17473
17645
|
// src/store/schedules.ts
|
|
17474
17646
|
function schedulesPath() {
|
|
17475
|
-
return (0,
|
|
17647
|
+
return (0, import_node_path45.join)(appDataDir(), "schedules.json");
|
|
17476
17648
|
}
|
|
17477
17649
|
function parseDurationMs(every) {
|
|
17478
17650
|
const m = every.trim().match(DURATION_RE);
|
|
@@ -17572,9 +17744,9 @@ function normalizeTask(raw) {
|
|
|
17572
17744
|
}
|
|
17573
17745
|
function readAll2() {
|
|
17574
17746
|
const path = schedulesPath();
|
|
17575
|
-
if (!(0,
|
|
17747
|
+
if (!(0, import_node_fs48.existsSync)(path)) return [];
|
|
17576
17748
|
try {
|
|
17577
|
-
const parsed = JSON.parse((0,
|
|
17749
|
+
const parsed = JSON.parse((0, import_node_fs48.readFileSync)(path, "utf8"));
|
|
17578
17750
|
if (!Array.isArray(parsed)) return [];
|
|
17579
17751
|
return parsed.map((row) => {
|
|
17580
17752
|
try {
|
|
@@ -17686,13 +17858,13 @@ function recordScheduleRun(id, result) {
|
|
|
17686
17858
|
writeAll2(rows);
|
|
17687
17859
|
return next;
|
|
17688
17860
|
}
|
|
17689
|
-
var import_node_crypto9,
|
|
17861
|
+
var import_node_crypto9, import_node_fs48, import_node_path45, import_croner, DURATION_RE, UNIT_MS;
|
|
17690
17862
|
var init_schedules = __esm({
|
|
17691
17863
|
"src/store/schedules.ts"() {
|
|
17692
17864
|
"use strict";
|
|
17693
17865
|
import_node_crypto9 = require("crypto");
|
|
17694
|
-
|
|
17695
|
-
|
|
17866
|
+
import_node_fs48 = require("fs");
|
|
17867
|
+
import_node_path45 = require("path");
|
|
17696
17868
|
import_croner = require("croner");
|
|
17697
17869
|
init_orchestrator_capable();
|
|
17698
17870
|
init_paths();
|
|
@@ -17834,13 +18006,13 @@ var init_schedule_runner = __esm({
|
|
|
17834
18006
|
|
|
17835
18007
|
// src/agents/cursor-store.ts
|
|
17836
18008
|
function cursorSdkStoreDir(threadId) {
|
|
17837
|
-
const root = (0,
|
|
18009
|
+
const root = (0, import_node_path46.join)(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
17838
18010
|
const id = sanitizeCursorStoreSegment(threadId);
|
|
17839
18011
|
if (!id) return root;
|
|
17840
|
-
return (0,
|
|
18012
|
+
return (0, import_node_path46.join)(root, "threads", id);
|
|
17841
18013
|
}
|
|
17842
18014
|
function cursorSdkRunsNdjsonPath(threadId) {
|
|
17843
|
-
return (0,
|
|
18015
|
+
return (0, import_node_path46.join)(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
17844
18016
|
}
|
|
17845
18017
|
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
17846
18018
|
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
@@ -17853,11 +18025,11 @@ function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
|
17853
18025
|
function sanitizeCursorStoreSegment(threadId) {
|
|
17854
18026
|
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
17855
18027
|
}
|
|
17856
|
-
var
|
|
18028
|
+
var import_node_path46, CURSOR_SDK_STORE_DIR;
|
|
17857
18029
|
var init_cursor_store = __esm({
|
|
17858
18030
|
"src/agents/cursor-store.ts"() {
|
|
17859
18031
|
"use strict";
|
|
17860
|
-
|
|
18032
|
+
import_node_path46 = require("path");
|
|
17861
18033
|
init_paths();
|
|
17862
18034
|
CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
17863
18035
|
}
|
|
@@ -17879,9 +18051,9 @@ function recoverFinishedCursorRun(opts) {
|
|
|
17879
18051
|
return best;
|
|
17880
18052
|
}
|
|
17881
18053
|
function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
17882
|
-
if (!(0,
|
|
18054
|
+
if (!(0, import_node_fs49.existsSync)(runsPath)) return null;
|
|
17883
18055
|
try {
|
|
17884
|
-
const lines = (0,
|
|
18056
|
+
const lines = (0, import_node_fs49.readFileSync)(runsPath, "utf8").split("\n");
|
|
17885
18057
|
let best = null;
|
|
17886
18058
|
for (const line of lines) {
|
|
17887
18059
|
const trimmed = line.trim();
|
|
@@ -17907,11 +18079,11 @@ function scanFinishedCursorRuns(runsPath, agentId, startedAfterMs) {
|
|
|
17907
18079
|
return null;
|
|
17908
18080
|
}
|
|
17909
18081
|
}
|
|
17910
|
-
var
|
|
18082
|
+
var import_node_fs49;
|
|
17911
18083
|
var init_cursor_recover = __esm({
|
|
17912
18084
|
"src/agents/cursor-recover.ts"() {
|
|
17913
18085
|
"use strict";
|
|
17914
|
-
|
|
18086
|
+
import_node_fs49 = require("fs");
|
|
17915
18087
|
init_cursor_store();
|
|
17916
18088
|
}
|
|
17917
18089
|
});
|
|
@@ -18043,13 +18215,13 @@ async function startOrchestration(opts) {
|
|
|
18043
18215
|
}
|
|
18044
18216
|
return updated;
|
|
18045
18217
|
}
|
|
18046
|
-
var import_node_events,
|
|
18218
|
+
var import_node_events, import_node_fs50, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
|
|
18047
18219
|
var init_orchestrator = __esm({
|
|
18048
18220
|
"src/orchestrator/orchestrator.ts"() {
|
|
18049
18221
|
"use strict";
|
|
18050
18222
|
import_node_events = require("events");
|
|
18051
18223
|
init_outbound_watch();
|
|
18052
|
-
|
|
18224
|
+
import_node_fs50 = require("fs");
|
|
18053
18225
|
init_error_detail();
|
|
18054
18226
|
init_run();
|
|
18055
18227
|
init_stale_lock();
|
|
@@ -18217,7 +18389,7 @@ var init_orchestrator = __esm({
|
|
|
18217
18389
|
}
|
|
18218
18390
|
continue;
|
|
18219
18391
|
}
|
|
18220
|
-
if (!(0,
|
|
18392
|
+
if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
|
|
18221
18393
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
18222
18394
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
18223
18395
|
continue;
|
|
@@ -18487,21 +18659,11 @@ var init_orchestrator = __esm({
|
|
|
18487
18659
|
/** Run workspace setup after a new worktree is created (no-op if none configured). */
|
|
18488
18660
|
async runSetupAfterCreate(threadId) {
|
|
18489
18661
|
try {
|
|
18490
|
-
await this.runSetup(threadId);
|
|
18662
|
+
await this.runSetup(threadId, { stampLastError: false });
|
|
18491
18663
|
} catch (err) {
|
|
18492
18664
|
const message = err instanceof Error ? err.message : String(err);
|
|
18493
18665
|
if (/no setup script/i.test(message)) return;
|
|
18494
18666
|
if (/already running/i.test(message)) return;
|
|
18495
|
-
const live = readThread(threadId);
|
|
18496
|
-
if (!shouldStampSetupLastError({
|
|
18497
|
-
turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
|
|
18498
|
-
status: live?.status
|
|
18499
|
-
})) {
|
|
18500
|
-
return;
|
|
18501
|
-
}
|
|
18502
|
-
updateThread(threadId, {
|
|
18503
|
-
lastError: `Setup failed: ${message}`
|
|
18504
|
-
});
|
|
18505
18667
|
}
|
|
18506
18668
|
}
|
|
18507
18669
|
listWorkspaces() {
|
|
@@ -19289,7 +19451,7 @@ var init_orchestrator = __esm({
|
|
|
19289
19451
|
}
|
|
19290
19452
|
return snap;
|
|
19291
19453
|
}
|
|
19292
|
-
async runSetup(threadRef) {
|
|
19454
|
+
async runSetup(threadRef, opts) {
|
|
19293
19455
|
const thread = this.requireThread(threadRef);
|
|
19294
19456
|
this.assertNotGlobal(thread, "Setup");
|
|
19295
19457
|
const key = `${thread.id}:setup`;
|
|
@@ -19330,9 +19492,10 @@ var init_orchestrator = __esm({
|
|
|
19330
19492
|
}
|
|
19331
19493
|
if (setup.exitCode !== 0 && setup.exitCode !== null) {
|
|
19332
19494
|
const live = readThread(thread.id);
|
|
19333
|
-
if (shouldStampSetupLastError({
|
|
19495
|
+
if ((opts?.stampLastError ?? true) && shouldStampSetupLastError({
|
|
19334
19496
|
turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
|
|
19335
|
-
status: live?.status
|
|
19497
|
+
status: live?.status,
|
|
19498
|
+
hasQueuedPrompt: Boolean(live?.queue?.length)
|
|
19336
19499
|
})) {
|
|
19337
19500
|
updateThread(thread.id, {
|
|
19338
19501
|
lastError: `Setup exited ${setup.exitCode}`
|
|
@@ -20035,7 +20198,7 @@ var init_orchestrator = __esm({
|
|
|
20035
20198
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
20036
20199
|
return restored2;
|
|
20037
20200
|
}
|
|
20038
|
-
if (!(0,
|
|
20201
|
+
if (!(0, import_node_fs50.existsSync)(thread.worktreePath)) {
|
|
20039
20202
|
if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
|
|
20040
20203
|
throw new Error(
|
|
20041
20204
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
@@ -20118,7 +20281,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
20118
20281
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
20119
20282
|
var import_zod5 = require("zod");
|
|
20120
20283
|
var import_node_crypto12 = require("crypto");
|
|
20121
|
-
var
|
|
20284
|
+
var import_node_path49 = require("path");
|
|
20122
20285
|
init_orchestrator();
|
|
20123
20286
|
init_worktree();
|
|
20124
20287
|
|
|
@@ -22019,27 +22182,27 @@ init_gh_errors();
|
|
|
22019
22182
|
init_git_auth_mode();
|
|
22020
22183
|
|
|
22021
22184
|
// src/board/load-home-board.ts
|
|
22022
|
-
var
|
|
22023
|
-
var
|
|
22185
|
+
var import_node_fs52 = require("fs");
|
|
22186
|
+
var import_node_path48 = require("path");
|
|
22024
22187
|
init_worktree();
|
|
22025
22188
|
init_paths();
|
|
22026
22189
|
|
|
22027
22190
|
// src/board/board-pins.ts
|
|
22028
22191
|
var import_node_crypto11 = require("crypto");
|
|
22029
|
-
var
|
|
22030
|
-
var
|
|
22192
|
+
var import_node_fs51 = require("fs");
|
|
22193
|
+
var import_node_path47 = require("path");
|
|
22031
22194
|
init_paths();
|
|
22032
22195
|
init_home_board();
|
|
22033
22196
|
var FILE = "home-board-pins.json";
|
|
22034
22197
|
var VERSION = 1;
|
|
22035
22198
|
function pinsFile() {
|
|
22036
|
-
return (0,
|
|
22199
|
+
return (0, import_node_path47.join)(appDataDir(), FILE);
|
|
22037
22200
|
}
|
|
22038
22201
|
function readDisk() {
|
|
22039
22202
|
const path = pinsFile();
|
|
22040
|
-
if (!(0,
|
|
22203
|
+
if (!(0, import_node_fs51.existsSync)(path)) return [];
|
|
22041
22204
|
try {
|
|
22042
|
-
const raw = JSON.parse((0,
|
|
22205
|
+
const raw = JSON.parse((0, import_node_fs51.readFileSync)(path, "utf8"));
|
|
22043
22206
|
if (raw?.version !== VERSION || !Array.isArray(raw.items)) return [];
|
|
22044
22207
|
return raw.items.filter((item) => item?.id && item.kind && item.ref);
|
|
22045
22208
|
} catch {
|
|
@@ -22047,8 +22210,8 @@ function readDisk() {
|
|
|
22047
22210
|
}
|
|
22048
22211
|
}
|
|
22049
22212
|
function writeDisk(items) {
|
|
22050
|
-
(0,
|
|
22051
|
-
(0,
|
|
22213
|
+
(0, import_node_fs51.mkdirSync)(appDataDir(), { recursive: true });
|
|
22214
|
+
(0, import_node_fs51.writeFileSync)(pinsFile(), JSON.stringify({ version: VERSION, items }, null, 2), "utf8");
|
|
22052
22215
|
}
|
|
22053
22216
|
function listBoardPins() {
|
|
22054
22217
|
return readDisk();
|
|
@@ -22069,7 +22232,7 @@ function homeBoardWorkspaceKey(workspaces) {
|
|
|
22069
22232
|
return workspaces.map((w) => w.path).filter(Boolean).sort().join("\n");
|
|
22070
22233
|
}
|
|
22071
22234
|
function cacheFile() {
|
|
22072
|
-
return (0,
|
|
22235
|
+
return (0, import_node_path48.join)(appDataDir(), "home-board-cache.json");
|
|
22073
22236
|
}
|
|
22074
22237
|
function emptyInputs() {
|
|
22075
22238
|
return {
|
|
@@ -22095,9 +22258,9 @@ function shouldCacheHomeBoardInputs(inputs) {
|
|
|
22095
22258
|
}
|
|
22096
22259
|
function readDiskCache() {
|
|
22097
22260
|
const path = cacheFile();
|
|
22098
|
-
if (!(0,
|
|
22261
|
+
if (!(0, import_node_fs52.existsSync)(path)) return null;
|
|
22099
22262
|
try {
|
|
22100
|
-
const raw = JSON.parse((0,
|
|
22263
|
+
const raw = JSON.parse((0, import_node_fs52.readFileSync)(path, "utf8"));
|
|
22101
22264
|
if (raw?.version !== CACHE_VERSION || typeof raw.fetchedAt !== "number") {
|
|
22102
22265
|
return null;
|
|
22103
22266
|
}
|
|
@@ -22111,8 +22274,8 @@ function readDiskCache() {
|
|
|
22111
22274
|
}
|
|
22112
22275
|
function writeDiskCache(entry) {
|
|
22113
22276
|
try {
|
|
22114
|
-
(0,
|
|
22115
|
-
(0,
|
|
22277
|
+
(0, import_node_fs52.mkdirSync)(appDataDir(), { recursive: true });
|
|
22278
|
+
(0, import_node_fs52.writeFileSync)(cacheFile(), JSON.stringify(entry), "utf8");
|
|
22116
22279
|
} catch {
|
|
22117
22280
|
}
|
|
22118
22281
|
}
|
|
@@ -22408,7 +22571,7 @@ async function startMcpServer() {
|
|
|
22408
22571
|
async () => {
|
|
22409
22572
|
const threads = orch.getThreads(true);
|
|
22410
22573
|
const lines = threads.map((t) => {
|
|
22411
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
22574
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path49.basename)(t.repoPath) || t.repoPath;
|
|
22412
22575
|
const live = orch.threadLooksLive(t) ? readTurnLive(t.id) : null;
|
|
22413
22576
|
const parent = t.parentThreadId ? ` parent:${t.parentThreadId.slice(0, 8)}` : "";
|
|
22414
22577
|
const preview = lastMessagePreview(t.messages, 80);
|