@sideboard-ai/core 0.1.24 → 0.1.31
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 +33 -3
- package/dist/agents/cursor-runner.js +17 -4
- package/dist/{agents-LJJRPW4Y.js → agents-HWIPJLC3.js} +23 -3
- package/dist/{chunk-WK6AK7NK.js → chunk-4YLTMPEO.js} +319 -2
- package/dist/{chunk-JNMLRJ3D.js → chunk-OY47OEY2.js} +332 -58
- package/dist/index.cjs +692 -65
- package/dist/index.d.cts +152 -3
- package/dist/index.d.ts +152 -3
- package/dist/index.js +35 -2
- package/dist/mcp/run-stdio.cjs +579 -24
- package/dist/mcp/run-stdio.js +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4538,6 +4538,35 @@ var init_claude = __esm({
|
|
|
4538
4538
|
});
|
|
4539
4539
|
|
|
4540
4540
|
// src/agents/codex.ts
|
|
4541
|
+
async function listCodexModels() {
|
|
4542
|
+
const now = Date.now();
|
|
4543
|
+
if (cachedCodexModels && now - cachedCodexModels.at < CODEX_MODEL_CACHE_MS) {
|
|
4544
|
+
return cachedCodexModels.models;
|
|
4545
|
+
}
|
|
4546
|
+
const which = await run("which", ["codex"], { reject: false });
|
|
4547
|
+
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
4548
|
+
const listed = await run("codex", ["debug", "models"], { reject: false });
|
|
4549
|
+
if (listed.exitCode !== 0 || !listed.stdout.trim()) {
|
|
4550
|
+
return cachedCodexModels?.models ?? FALLBACK_CODEX_MODELS;
|
|
4551
|
+
}
|
|
4552
|
+
try {
|
|
4553
|
+
const parsed = JSON.parse(listed.stdout);
|
|
4554
|
+
const rows = Array.isArray(parsed.models) ? parsed.models : [];
|
|
4555
|
+
const preferred = rows.filter((m) => (m.visibility ?? "list") === "list");
|
|
4556
|
+
const source = preferred.length > 0 ? preferred : rows;
|
|
4557
|
+
const models = source.map((m) => ({
|
|
4558
|
+
id: (m.slug || "").trim(),
|
|
4559
|
+
displayName: (m.display_name || m.slug || "").trim(),
|
|
4560
|
+
description: m.description,
|
|
4561
|
+
priority: typeof m.priority === "number" ? m.priority : 999
|
|
4562
|
+
})).filter((m) => m.id).sort((a, b) => a.priority - b.priority).map(({ id, displayName, description }) => ({ id, displayName, description }));
|
|
4563
|
+
if (models.length === 0) return FALLBACK_CODEX_MODELS;
|
|
4564
|
+
cachedCodexModels = { at: now, models };
|
|
4565
|
+
return models;
|
|
4566
|
+
} catch {
|
|
4567
|
+
return cachedCodexModels?.models ?? FALLBACK_CODEX_MODELS;
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4541
4570
|
function usageFromCodex(usage) {
|
|
4542
4571
|
if (!usage) return null;
|
|
4543
4572
|
const inputTokens = Number(usage.input_tokens ?? 0);
|
|
@@ -4561,7 +4590,7 @@ function codexConfigHasNetworkAccess() {
|
|
|
4561
4590
|
}
|
|
4562
4591
|
return false;
|
|
4563
4592
|
}
|
|
4564
|
-
var import_node_fs12, import_node_os7, import_node_path12, CODEX_PROMPT_ARG_MAX, codexAdapter;
|
|
4593
|
+
var import_node_fs12, import_node_os7, import_node_path12, CODEX_PROMPT_ARG_MAX, FALLBACK_CODEX_MODELS, cachedCodexModels, CODEX_MODEL_CACHE_MS, codexAdapter;
|
|
4565
4594
|
var init_codex = __esm({
|
|
4566
4595
|
"src/agents/codex.ts"() {
|
|
4567
4596
|
"use strict";
|
|
@@ -4572,6 +4601,15 @@ var init_codex = __esm({
|
|
|
4572
4601
|
init_turn_input();
|
|
4573
4602
|
init_types();
|
|
4574
4603
|
CODEX_PROMPT_ARG_MAX = 2e5;
|
|
4604
|
+
FALLBACK_CODEX_MODELS = [
|
|
4605
|
+
{ id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
|
|
4606
|
+
{ id: "gpt-5.6-terra", displayName: "GPT-5.6 Terra" },
|
|
4607
|
+
{ id: "gpt-5.6-luna", displayName: "GPT-5.6 Luna" },
|
|
4608
|
+
{ id: "gpt-5.5", displayName: "GPT-5.5" },
|
|
4609
|
+
{ id: "gpt-5.2", displayName: "GPT-5.2" }
|
|
4610
|
+
];
|
|
4611
|
+
cachedCodexModels = null;
|
|
4612
|
+
CODEX_MODEL_CACHE_MS = 5 * 60 * 1e3;
|
|
4575
4613
|
codexAdapter = {
|
|
4576
4614
|
kind: "codex",
|
|
4577
4615
|
async detect() {
|
|
@@ -4617,6 +4655,7 @@ var init_codex = __esm({
|
|
|
4617
4655
|
);
|
|
4618
4656
|
}
|
|
4619
4657
|
const mode = permissionMode(thread);
|
|
4658
|
+
const model = thread.model?.trim();
|
|
4620
4659
|
const args = [
|
|
4621
4660
|
"exec",
|
|
4622
4661
|
...sessionId ? ["resume", sessionId] : [],
|
|
@@ -4627,7 +4666,8 @@ var init_codex = __esm({
|
|
|
4627
4666
|
"--sandbox",
|
|
4628
4667
|
mode.codexSandbox,
|
|
4629
4668
|
"--ask-for-approval",
|
|
4630
|
-
"never"
|
|
4669
|
+
"never",
|
|
4670
|
+
...model ? ["--model", model] : []
|
|
4631
4671
|
];
|
|
4632
4672
|
return {
|
|
4633
4673
|
file: "codex",
|
|
@@ -4808,6 +4848,35 @@ function resolveCursorApiKey() {
|
|
|
4808
4848
|
if (fromEnv) return fromEnv;
|
|
4809
4849
|
return (loadAppSettings().environment.CURSOR_API_KEY || "").trim();
|
|
4810
4850
|
}
|
|
4851
|
+
function isCursorAutoModel(model) {
|
|
4852
|
+
const id = (model ?? "").trim().toLowerCase();
|
|
4853
|
+
return !id || id === "default" || id === "auto";
|
|
4854
|
+
}
|
|
4855
|
+
function resolveCursorModelId(model) {
|
|
4856
|
+
if (isCursorAutoModel(model)) return "default";
|
|
4857
|
+
return model.trim();
|
|
4858
|
+
}
|
|
4859
|
+
async function listCursorModels() {
|
|
4860
|
+
const now = Date.now();
|
|
4861
|
+
if (cachedModels && now - cachedModels.at < MODEL_CACHE_MS) {
|
|
4862
|
+
return cachedModels.models;
|
|
4863
|
+
}
|
|
4864
|
+
const apiKey = resolveCursorApiKey();
|
|
4865
|
+
if (!apiKey) return FALLBACK_CURSOR_MODELS;
|
|
4866
|
+
try {
|
|
4867
|
+
const listed = await import_sdk.Cursor.models.list({ apiKey });
|
|
4868
|
+
const models = listed.map((m) => ({
|
|
4869
|
+
id: m.id,
|
|
4870
|
+
displayName: m.displayName || m.id,
|
|
4871
|
+
description: m.description
|
|
4872
|
+
})).filter((m) => Boolean(m.id));
|
|
4873
|
+
if (models.length === 0) return FALLBACK_CURSOR_MODELS;
|
|
4874
|
+
cachedModels = { at: now, models };
|
|
4875
|
+
return models;
|
|
4876
|
+
} catch {
|
|
4877
|
+
return cachedModels?.models ?? FALLBACK_CURSOR_MODELS;
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4811
4880
|
function entryDir() {
|
|
4812
4881
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
4813
4882
|
if (cjsDir) return cjsDir;
|
|
@@ -4839,7 +4908,7 @@ function cursorRunnerPath() {
|
|
|
4839
4908
|
}
|
|
4840
4909
|
return candidates[0];
|
|
4841
4910
|
}
|
|
4842
|
-
var import_node_fs13, import_node_module2, import_node_path13, import_node_url2, import_sdk, import_meta2, cursorAdapter;
|
|
4911
|
+
var import_node_fs13, import_node_module2, import_node_path13, import_node_url2, import_sdk, import_meta2, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
4843
4912
|
var init_cursor = __esm({
|
|
4844
4913
|
"src/agents/cursor.ts"() {
|
|
4845
4914
|
"use strict";
|
|
@@ -4854,6 +4923,13 @@ var init_cursor = __esm({
|
|
|
4854
4923
|
init_turn_input();
|
|
4855
4924
|
init_cursor_events();
|
|
4856
4925
|
import_meta2 = {};
|
|
4926
|
+
FALLBACK_CURSOR_MODELS = [
|
|
4927
|
+
{ id: "default", displayName: "Auto" },
|
|
4928
|
+
{ id: "composer-2.5", displayName: "Composer 2.5" },
|
|
4929
|
+
{ id: "composer-2", displayName: "Composer 2" }
|
|
4930
|
+
];
|
|
4931
|
+
cachedModels = null;
|
|
4932
|
+
MODEL_CACHE_MS = 5 * 60 * 1e3;
|
|
4857
4933
|
cursorAdapter = {
|
|
4858
4934
|
kind: "cursor",
|
|
4859
4935
|
async detect() {
|
|
@@ -4904,12 +4980,16 @@ var init_cursor = __esm({
|
|
|
4904
4980
|
};
|
|
4905
4981
|
const runner = cursorRunnerPath();
|
|
4906
4982
|
const isTs = runner.endsWith(".ts");
|
|
4983
|
+
const whichNode = await run("which", ["node"], { reject: false });
|
|
4984
|
+
const nodeBin = whichNode.exitCode === 0 && whichNode.stdout.trim() ? whichNode.stdout.trim() : null;
|
|
4985
|
+
const file = nodeBin || process.execPath;
|
|
4907
4986
|
return {
|
|
4908
|
-
file
|
|
4987
|
+
file,
|
|
4909
4988
|
args: isTs ? ["--import", "tsx", runner] : [runner],
|
|
4910
4989
|
cwd: thread.worktreePath,
|
|
4911
4990
|
stdin: JSON.stringify(req),
|
|
4912
4991
|
env: {
|
|
4992
|
+
...nodeBin ? {} : { ELECTRON_RUN_AS_NODE: "1" },
|
|
4913
4993
|
...apiKey ? { CURSOR_API_KEY: apiKey } : {}
|
|
4914
4994
|
}
|
|
4915
4995
|
};
|
|
@@ -4934,6 +5014,46 @@ var init_cursor = __esm({
|
|
|
4934
5014
|
});
|
|
4935
5015
|
|
|
4936
5016
|
// src/agents/opencode.ts
|
|
5017
|
+
function displayNameFromOpencodeId(id) {
|
|
5018
|
+
const slash = id.indexOf("/");
|
|
5019
|
+
if (slash <= 0) return id;
|
|
5020
|
+
const provider = id.slice(0, slash);
|
|
5021
|
+
const name = id.slice(slash + 1);
|
|
5022
|
+
return `${provider} \xB7 ${name}`;
|
|
5023
|
+
}
|
|
5024
|
+
function sortOpencodeModelIds(ids) {
|
|
5025
|
+
return [...ids].sort((a, b) => {
|
|
5026
|
+
const aLatest = /latest|~/.test(a) ? 0 : 1;
|
|
5027
|
+
const bLatest = /latest|~/.test(b) ? 0 : 1;
|
|
5028
|
+
if (aLatest !== bLatest) return aLatest - bLatest;
|
|
5029
|
+
const aOc = a.startsWith("opencode/") ? 0 : 1;
|
|
5030
|
+
const bOc = b.startsWith("opencode/") ? 0 : 1;
|
|
5031
|
+
if (aOc !== bOc) return aOc - bOc;
|
|
5032
|
+
return a.localeCompare(b);
|
|
5033
|
+
});
|
|
5034
|
+
}
|
|
5035
|
+
async function listOpencodeModels() {
|
|
5036
|
+
const now = Date.now();
|
|
5037
|
+
if (cachedOpencodeModels && now - cachedOpencodeModels.at < OPENCODE_MODEL_CACHE_MS) {
|
|
5038
|
+
return cachedOpencodeModels.models;
|
|
5039
|
+
}
|
|
5040
|
+
const which = await run("which", ["opencode"], { reject: false });
|
|
5041
|
+
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
5042
|
+
const listed = await run("opencode", ["models"], { reject: false });
|
|
5043
|
+
if (listed.exitCode !== 0 || !listed.stdout.trim()) {
|
|
5044
|
+
return cachedOpencodeModels?.models ?? FALLBACK_OPENCODE_MODELS;
|
|
5045
|
+
}
|
|
5046
|
+
const ids = listed.stdout.split("\n").map((l) => l.trim()).filter((l) => /^[\w.~@+-]+\/[\w.~@+/-]+$/.test(l));
|
|
5047
|
+
const unique = [...new Set(ids)];
|
|
5048
|
+
if (unique.length === 0) return FALLBACK_OPENCODE_MODELS;
|
|
5049
|
+
const OPENCODE_PICKER_LIMIT = 60;
|
|
5050
|
+
const models = sortOpencodeModelIds(unique).slice(0, OPENCODE_PICKER_LIMIT).map((id) => ({
|
|
5051
|
+
id,
|
|
5052
|
+
displayName: displayNameFromOpencodeId(id)
|
|
5053
|
+
}));
|
|
5054
|
+
cachedOpencodeModels = { at: now, models };
|
|
5055
|
+
return models;
|
|
5056
|
+
}
|
|
4937
5057
|
function usageFromOpencode(tokens) {
|
|
4938
5058
|
if (!tokens) return null;
|
|
4939
5059
|
const inputTokens = Number(tokens.input ?? 0);
|
|
@@ -4946,13 +5066,26 @@ function usageFromOpencode(tokens) {
|
|
|
4946
5066
|
cacheWriteTokens: tokens.cache?.write ? Number(tokens.cache.write) : void 0
|
|
4947
5067
|
};
|
|
4948
5068
|
}
|
|
4949
|
-
var opencodeAdapter;
|
|
5069
|
+
var FALLBACK_OPENCODE_MODELS, cachedOpencodeModels, OPENCODE_MODEL_CACHE_MS, opencodeAdapter;
|
|
4950
5070
|
var init_opencode = __esm({
|
|
4951
5071
|
"src/agents/opencode.ts"() {
|
|
4952
5072
|
"use strict";
|
|
4953
5073
|
init_run();
|
|
4954
5074
|
init_turn_input();
|
|
4955
5075
|
init_types();
|
|
5076
|
+
FALLBACK_OPENCODE_MODELS = [
|
|
5077
|
+
{ id: "opencode/big-pickle", displayName: "opencode \xB7 big-pickle" },
|
|
5078
|
+
{
|
|
5079
|
+
id: "openrouter/~anthropic/claude-sonnet-latest",
|
|
5080
|
+
displayName: "openrouter \xB7 claude-sonnet-latest"
|
|
5081
|
+
},
|
|
5082
|
+
{
|
|
5083
|
+
id: "openrouter/~openai/gpt-latest",
|
|
5084
|
+
displayName: "openrouter \xB7 gpt-latest"
|
|
5085
|
+
}
|
|
5086
|
+
];
|
|
5087
|
+
cachedOpencodeModels = null;
|
|
5088
|
+
OPENCODE_MODEL_CACHE_MS = 5 * 60 * 1e3;
|
|
4956
5089
|
opencodeAdapter = {
|
|
4957
5090
|
kind: "opencode",
|
|
4958
5091
|
async detect() {
|
|
@@ -4984,6 +5117,7 @@ var init_opencode = __esm({
|
|
|
4984
5117
|
const prompt = flattenTurnInput(input);
|
|
4985
5118
|
const sessionId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
4986
5119
|
const mode = permissionMode(thread);
|
|
5120
|
+
const model = thread.model?.trim();
|
|
4987
5121
|
const args = [
|
|
4988
5122
|
"run",
|
|
4989
5123
|
"--dir",
|
|
@@ -4994,6 +5128,9 @@ var init_opencode = __esm({
|
|
|
4994
5128
|
if (sessionId) {
|
|
4995
5129
|
args.push("--session", sessionId);
|
|
4996
5130
|
}
|
|
5131
|
+
if (model) {
|
|
5132
|
+
args.push("--model", model);
|
|
5133
|
+
}
|
|
4997
5134
|
return {
|
|
4998
5135
|
file: "opencode",
|
|
4999
5136
|
args,
|
|
@@ -5121,6 +5258,183 @@ var init_opencode = __esm({
|
|
|
5121
5258
|
}
|
|
5122
5259
|
});
|
|
5123
5260
|
|
|
5261
|
+
// src/agents/install.ts
|
|
5262
|
+
function getAgentSetupInfo(agent) {
|
|
5263
|
+
return SETUP[agent];
|
|
5264
|
+
}
|
|
5265
|
+
function listAgentSetupInfo() {
|
|
5266
|
+
return Object.values(SETUP);
|
|
5267
|
+
}
|
|
5268
|
+
async function openInSystemTerminal(command) {
|
|
5269
|
+
ensureAgentPath();
|
|
5270
|
+
const trimmed = command.trim();
|
|
5271
|
+
if (!trimmed) throw new Error("Command is empty");
|
|
5272
|
+
if (process.platform === "darwin") {
|
|
5273
|
+
const escaped = trimmed.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
5274
|
+
const script = `tell application "Terminal" to do script "${escaped}"`;
|
|
5275
|
+
const result = await run("osascript", ["-e", script], { reject: false });
|
|
5276
|
+
if (result.exitCode !== 0) {
|
|
5277
|
+
throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open Terminal");
|
|
5278
|
+
}
|
|
5279
|
+
await run("osascript", ["-e", 'tell application "Terminal" to activate'], {
|
|
5280
|
+
reject: false
|
|
5281
|
+
});
|
|
5282
|
+
return;
|
|
5283
|
+
}
|
|
5284
|
+
if (process.platform === "win32") {
|
|
5285
|
+
const result = await run(
|
|
5286
|
+
"cmd.exe",
|
|
5287
|
+
["/c", "start", "cmd.exe", "/k", trimmed],
|
|
5288
|
+
{ reject: false }
|
|
5289
|
+
);
|
|
5290
|
+
if (result.exitCode !== 0) {
|
|
5291
|
+
throw new Error(result.stderr.trim() || result.stdout.trim() || "Failed to open cmd");
|
|
5292
|
+
}
|
|
5293
|
+
return;
|
|
5294
|
+
}
|
|
5295
|
+
const candidates = [
|
|
5296
|
+
{ file: "gnome-terminal", args: ["--", "bash", "-lc", `${trimmed}; exec bash`] },
|
|
5297
|
+
{ file: "x-terminal-emulator", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
|
|
5298
|
+
{ file: "konsole", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] },
|
|
5299
|
+
{ file: "xterm", args: ["-e", "bash", "-lc", `${trimmed}; exec bash`] }
|
|
5300
|
+
];
|
|
5301
|
+
for (const c of candidates) {
|
|
5302
|
+
const which = await run("which", [c.file], { reject: false });
|
|
5303
|
+
if (which.exitCode !== 0 || !which.stdout.trim()) continue;
|
|
5304
|
+
const result = await run(c.file, c.args, { reject: false });
|
|
5305
|
+
if (result.exitCode === 0) return;
|
|
5306
|
+
}
|
|
5307
|
+
throw new Error(
|
|
5308
|
+
`No terminal found to run: ${trimmed}. Install gnome-terminal (or similar), or run the command manually.`
|
|
5309
|
+
);
|
|
5310
|
+
}
|
|
5311
|
+
async function installAgent(agent) {
|
|
5312
|
+
const info = getAgentSetupInfo(agent);
|
|
5313
|
+
if (info.kind === "bundled-sdk" || info.kind === "api-key") {
|
|
5314
|
+
return {
|
|
5315
|
+
ok: true,
|
|
5316
|
+
message: info.summary
|
|
5317
|
+
};
|
|
5318
|
+
}
|
|
5319
|
+
if (!info.installCommand) {
|
|
5320
|
+
return { ok: false, message: `No install command for ${agent}` };
|
|
5321
|
+
}
|
|
5322
|
+
if (/curl\s| \|\s*bash/.test(info.installCommand) || !info.npmPackage) {
|
|
5323
|
+
await openInSystemTerminal(info.installCommand);
|
|
5324
|
+
return {
|
|
5325
|
+
ok: true,
|
|
5326
|
+
openedTerminal: true,
|
|
5327
|
+
command: info.installCommand,
|
|
5328
|
+
message: `Opened Terminal to run: ${info.installCommand}`
|
|
5329
|
+
};
|
|
5330
|
+
}
|
|
5331
|
+
ensureAgentPath();
|
|
5332
|
+
const result = await run("npm", ["install", "-g", info.npmPackage], { reject: false });
|
|
5333
|
+
const ok = result.exitCode === 0;
|
|
5334
|
+
if (!ok) {
|
|
5335
|
+
try {
|
|
5336
|
+
await openInSystemTerminal(info.installCommand);
|
|
5337
|
+
return {
|
|
5338
|
+
ok: false,
|
|
5339
|
+
openedTerminal: true,
|
|
5340
|
+
command: info.installCommand,
|
|
5341
|
+
exitCode: result.exitCode,
|
|
5342
|
+
stdout: result.stdout,
|
|
5343
|
+
stderr: result.stderr,
|
|
5344
|
+
message: `npm install failed (exit ${result.exitCode}). Opened Terminal with: ${info.installCommand}`
|
|
5345
|
+
};
|
|
5346
|
+
} catch {
|
|
5347
|
+
return {
|
|
5348
|
+
ok: false,
|
|
5349
|
+
command: info.installCommand,
|
|
5350
|
+
exitCode: result.exitCode,
|
|
5351
|
+
stdout: result.stdout,
|
|
5352
|
+
stderr: result.stderr,
|
|
5353
|
+
message: result.stderr.trim() || result.stdout.trim() || `npm install failed (exit ${result.exitCode})`
|
|
5354
|
+
};
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
return {
|
|
5358
|
+
ok: true,
|
|
5359
|
+
command: info.installCommand,
|
|
5360
|
+
exitCode: 0,
|
|
5361
|
+
stdout: result.stdout,
|
|
5362
|
+
stderr: result.stderr,
|
|
5363
|
+
message: `Installed ${info.npmPackage}`
|
|
5364
|
+
};
|
|
5365
|
+
}
|
|
5366
|
+
async function loginAgent(agent) {
|
|
5367
|
+
const info = getAgentSetupInfo(agent);
|
|
5368
|
+
if (!info.loginCommand) {
|
|
5369
|
+
return {
|
|
5370
|
+
ok: true,
|
|
5371
|
+
message: info.kind === "bundled-sdk" || info.kind === "api-key" ? info.summary : `No login command for ${agent}`
|
|
5372
|
+
};
|
|
5373
|
+
}
|
|
5374
|
+
await openInSystemTerminal(info.loginCommand);
|
|
5375
|
+
return {
|
|
5376
|
+
ok: true,
|
|
5377
|
+
openedTerminal: true,
|
|
5378
|
+
command: info.loginCommand,
|
|
5379
|
+
message: `Opened Terminal to run: ${info.loginCommand}`
|
|
5380
|
+
};
|
|
5381
|
+
}
|
|
5382
|
+
var SETUP;
|
|
5383
|
+
var init_install = __esm({
|
|
5384
|
+
"src/agents/install.ts"() {
|
|
5385
|
+
"use strict";
|
|
5386
|
+
init_run();
|
|
5387
|
+
init_path();
|
|
5388
|
+
SETUP = {
|
|
5389
|
+
claude: {
|
|
5390
|
+
agent: "claude",
|
|
5391
|
+
kind: "cli",
|
|
5392
|
+
summary: "Install the Claude Code CLI, then complete login in a terminal.",
|
|
5393
|
+
docsUrl: "https://code.claude.com/docs/en/install",
|
|
5394
|
+
installCommand: "npm install -g @anthropic-ai/claude-code",
|
|
5395
|
+
loginCommand: "claude auth login",
|
|
5396
|
+
npmPackage: "@anthropic-ai/claude-code"
|
|
5397
|
+
},
|
|
5398
|
+
codex: {
|
|
5399
|
+
agent: "codex",
|
|
5400
|
+
kind: "cli",
|
|
5401
|
+
summary: "Install the Codex CLI, then run login in a terminal.",
|
|
5402
|
+
docsUrl: "https://github.com/openai/codex",
|
|
5403
|
+
installCommand: "npm install -g @openai/codex",
|
|
5404
|
+
loginCommand: "codex login",
|
|
5405
|
+
npmPackage: "@openai/codex"
|
|
5406
|
+
},
|
|
5407
|
+
opencode: {
|
|
5408
|
+
agent: "opencode",
|
|
5409
|
+
kind: "cli",
|
|
5410
|
+
summary: "Install OpenCode (curl installer or npm), then authenticate providers.",
|
|
5411
|
+
docsUrl: "https://opencode.ai/docs",
|
|
5412
|
+
// Prefer the official installer; npm package name is opencode-ai.
|
|
5413
|
+
installCommand: "curl -fsSL https://opencode.ai/install | bash",
|
|
5414
|
+
loginCommand: "opencode auth login",
|
|
5415
|
+
npmPackage: "opencode-ai@latest"
|
|
5416
|
+
},
|
|
5417
|
+
cursor: {
|
|
5418
|
+
agent: "cursor",
|
|
5419
|
+
kind: "bundled-sdk",
|
|
5420
|
+
summary: "No CLI install \u2014 Sideboard ships the Cursor SDK. Add a CURSOR_API_KEY from the Cursor dashboard.",
|
|
5421
|
+
docsUrl: "https://cursor.com/dashboard/integrations",
|
|
5422
|
+
installCommand: null,
|
|
5423
|
+
loginCommand: null
|
|
5424
|
+
},
|
|
5425
|
+
brightsy: {
|
|
5426
|
+
agent: "brightsy",
|
|
5427
|
+
kind: "cli",
|
|
5428
|
+
summary: "Install the Brightsy CLI, then run `brightsy login`.",
|
|
5429
|
+
docsUrl: "https://www.npmjs.com/package/@brightsy/cli",
|
|
5430
|
+
installCommand: "npm install -g @brightsy/cli",
|
|
5431
|
+
loginCommand: "brightsy login",
|
|
5432
|
+
npmPackage: "@brightsy/cli"
|
|
5433
|
+
}
|
|
5434
|
+
};
|
|
5435
|
+
}
|
|
5436
|
+
});
|
|
5437
|
+
|
|
5124
5438
|
// src/agents/index.ts
|
|
5125
5439
|
var agents_exports = {};
|
|
5126
5440
|
__export(agents_exports, {
|
|
@@ -5135,10 +5449,20 @@ __export(agents_exports, {
|
|
|
5135
5449
|
encodeBrightsyTarget: () => encodeBrightsyTarget,
|
|
5136
5450
|
ensureAgentPath: () => ensureAgentPath,
|
|
5137
5451
|
getAdapter: () => getAdapter,
|
|
5452
|
+
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
5453
|
+
installAgent: () => installAgent,
|
|
5454
|
+
isCursorAutoModel: () => isCursorAutoModel,
|
|
5455
|
+
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
5138
5456
|
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
5457
|
+
listCodexModels: () => listCodexModels,
|
|
5458
|
+
listCursorModels: () => listCursorModels,
|
|
5459
|
+
listOpencodeModels: () => listOpencodeModels,
|
|
5460
|
+
loginAgent: () => loginAgent,
|
|
5461
|
+
openInSystemTerminal: () => openInSystemTerminal,
|
|
5139
5462
|
opencodeAdapter: () => opencodeAdapter,
|
|
5140
5463
|
parseCursorRunnerLine: () => parseCursorRunnerLine,
|
|
5141
|
-
permissionMode: () => permissionMode
|
|
5464
|
+
permissionMode: () => permissionMode,
|
|
5465
|
+
resolveCursorModelId: () => resolveCursorModelId
|
|
5142
5466
|
});
|
|
5143
5467
|
function getAdapter(kind) {
|
|
5144
5468
|
return adapters[kind];
|
|
@@ -5162,8 +5486,10 @@ var init_agents = __esm({
|
|
|
5162
5486
|
init_codex();
|
|
5163
5487
|
init_cursor();
|
|
5164
5488
|
init_cursor_events();
|
|
5489
|
+
init_cursor();
|
|
5165
5490
|
init_opencode();
|
|
5166
5491
|
init_path();
|
|
5492
|
+
init_install();
|
|
5167
5493
|
adapters = {
|
|
5168
5494
|
claude: claudeAdapter,
|
|
5169
5495
|
codex: codexAdapter,
|
|
@@ -5241,6 +5567,9 @@ __export(index_exports, {
|
|
|
5241
5567
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
5242
5568
|
applyCompaction: () => applyCompaction,
|
|
5243
5569
|
applyThreadIntoMain: () => applyThreadIntoMain,
|
|
5570
|
+
attachmentFromAbsolutePath: () => attachmentFromAbsolutePath,
|
|
5571
|
+
attachmentsFromBuffers: () => attachmentsFromBuffers,
|
|
5572
|
+
attachmentsFromWorktreePaths: () => attachmentsFromWorktreePaths,
|
|
5244
5573
|
autoCleanupOrphansEnabled: () => autoCleanupOrphansEnabled,
|
|
5245
5574
|
autoRenameBranchEnabled: () => autoRenameBranchEnabled,
|
|
5246
5575
|
autoRunAfterSetupEnabled: () => autoRunAfterSetupEnabled,
|
|
@@ -5326,6 +5655,7 @@ __export(index_exports, {
|
|
|
5326
5655
|
formatWorkspaceInventory: () => formatWorkspaceInventory,
|
|
5327
5656
|
formatWorktreeDirective: () => formatWorktreeDirective,
|
|
5328
5657
|
getAdapter: () => getAdapter,
|
|
5658
|
+
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
5329
5659
|
getBrightsySession: () => getBrightsySession,
|
|
5330
5660
|
getDefaultRunScript: () => getDefaultRunScript,
|
|
5331
5661
|
getDiff: () => getDiff,
|
|
@@ -5356,27 +5686,34 @@ __export(index_exports, {
|
|
|
5356
5686
|
importConductorWorkspaceAsync: () => importConductorWorkspaceAsync,
|
|
5357
5687
|
initializeGitRepository: () => initializeGitRepository,
|
|
5358
5688
|
inspectGitWorktree: () => inspectGitWorktree,
|
|
5689
|
+
installAgent: () => installAgent,
|
|
5359
5690
|
isBrightsyConnected: () => isBrightsyConnected,
|
|
5360
5691
|
isBrightsyNdjsonLine: () => isBrightsyNdjsonLine,
|
|
5361
5692
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
5693
|
+
isCursorAutoModel: () => isCursorAutoModel,
|
|
5362
5694
|
isDirty: () => isDirty,
|
|
5363
5695
|
isGhRateLimitError: () => isGhRateLimitError,
|
|
5364
5696
|
isGlobalRepoPath: () => isGlobalRepoPath,
|
|
5365
5697
|
isGlobalThread: () => isGlobalThread,
|
|
5698
|
+
isImageFilePath: () => isImageFilePath,
|
|
5366
5699
|
isLinearConnected: () => isLinearConnected,
|
|
5367
5700
|
isOrchestratorThread: () => isOrchestratorThread,
|
|
5368
5701
|
isPlaceholderBranch: () => isPlaceholderBranch,
|
|
5702
|
+
listAgentSetupInfo: () => listAgentSetupInfo,
|
|
5369
5703
|
listBranchCommits: () => listBranchCommits,
|
|
5370
5704
|
listBranches: () => listBranches,
|
|
5371
5705
|
listBrightsyAccounts: () => listBrightsyAccounts,
|
|
5372
5706
|
listBrightsyChatTargets: () => listBrightsyChatTargets,
|
|
5707
|
+
listCodexModels: () => listCodexModels,
|
|
5373
5708
|
listConductorWorkspaces: () => listConductorWorkspaces,
|
|
5374
5709
|
listConnectedBrightsyTeams: () => listConnectedBrightsyTeams,
|
|
5710
|
+
listCursorModels: () => listCursorModels,
|
|
5375
5711
|
listGitHubIssues: () => listGitHubIssues,
|
|
5376
5712
|
listGlobalThreads: () => listGlobalThreads,
|
|
5377
5713
|
listIssues: () => listIssues,
|
|
5378
5714
|
listLinearIssues: () => listLinearIssues,
|
|
5379
5715
|
listLinearIssuesDirect: () => listLinearIssuesDirect,
|
|
5716
|
+
listOpencodeModels: () => listOpencodeModels,
|
|
5380
5717
|
listPrs: () => listPrs,
|
|
5381
5718
|
listRunScripts: () => listRunScripts,
|
|
5382
5719
|
listThreads: () => listThreads,
|
|
@@ -5390,6 +5727,7 @@ __export(index_exports, {
|
|
|
5390
5727
|
loadRepoSettings: () => loadRepoSettings,
|
|
5391
5728
|
loadWorkspaceSettings: () => loadWorkspaceSettings,
|
|
5392
5729
|
locksDir: () => locksDir,
|
|
5730
|
+
loginAgent: () => loginAgent,
|
|
5393
5731
|
lookupSoccerTeam: () => lookupSoccerTeam,
|
|
5394
5732
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
5395
5733
|
maybeCompactContext: () => maybeCompactContext,
|
|
@@ -5401,6 +5739,7 @@ __export(index_exports, {
|
|
|
5401
5739
|
normalizeThread: () => normalizeThread,
|
|
5402
5740
|
normalizeTurnInput: () => normalizeTurnInput,
|
|
5403
5741
|
normalizeWorktreePath: () => normalizeWorktreePath,
|
|
5742
|
+
openInSystemTerminal: () => openInSystemTerminal,
|
|
5404
5743
|
opencodeAdapter: () => opencodeAdapter,
|
|
5405
5744
|
orchestrationTitleNeedsSoccerNickname: () => orchestrationTitleNeedsSoccerNickname,
|
|
5406
5745
|
orchestratorSessionPoisonedByBuiltins: () => orchestratorSessionPoisonedByBuiltins,
|
|
@@ -5425,6 +5764,7 @@ __export(index_exports, {
|
|
|
5425
5764
|
requireAgent: () => requireAgent,
|
|
5426
5765
|
resolveClaudeExecutable: () => resolveClaudeExecutable,
|
|
5427
5766
|
resolveConductorCursorAgentId: () => resolveConductorCursorAgentId,
|
|
5767
|
+
resolveCursorModelId: () => resolveCursorModelId,
|
|
5428
5768
|
resolveDefaultBranch: () => resolveDefaultBranch,
|
|
5429
5769
|
resolveDiffBaseRef: () => resolveDiffBaseRef,
|
|
5430
5770
|
resolveEffectiveIssueSource: () => resolveEffectiveIssueSource,
|
|
@@ -5451,6 +5791,8 @@ __export(index_exports, {
|
|
|
5451
5791
|
slugify: () => slugify,
|
|
5452
5792
|
spawnAgentTurn: () => spawnAgentTurn,
|
|
5453
5793
|
splitForCompaction: () => splitForCompaction,
|
|
5794
|
+
stageAbsolutePathsAsAttachments: () => stageAbsolutePathsAsAttachments,
|
|
5795
|
+
stageBuffersAsAttachments: () => stageBuffersAsAttachments,
|
|
5454
5796
|
startDevServer: () => startDevServer,
|
|
5455
5797
|
startMcpServer: () => startMcpServer,
|
|
5456
5798
|
startOrchestration: () => startOrchestration,
|
|
@@ -7257,6 +7599,9 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
7257
7599
|
parts.push("");
|
|
7258
7600
|
parts.push(`## Attachment: ${att.name}`);
|
|
7259
7601
|
parts.push(`Kind: ${att.kind}`);
|
|
7602
|
+
if (att.path) {
|
|
7603
|
+
parts.push(`Path in worktree: \`${att.path}\``);
|
|
7604
|
+
}
|
|
7260
7605
|
parts.push("");
|
|
7261
7606
|
parts.push(att.content);
|
|
7262
7607
|
}
|
|
@@ -7342,10 +7687,239 @@ function buildDiffCommentAttachment(input) {
|
|
|
7342
7687
|
id: input.id ?? `diff-comment-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
7343
7688
|
name,
|
|
7344
7689
|
kind: "diff-comment",
|
|
7690
|
+
path: input.path.trim(),
|
|
7345
7691
|
content
|
|
7346
7692
|
};
|
|
7347
7693
|
}
|
|
7348
7694
|
|
|
7695
|
+
// src/composer/stage-files.ts
|
|
7696
|
+
var import_node_fs19 = require("fs");
|
|
7697
|
+
var import_node_path19 = require("path");
|
|
7698
|
+
var import_node_crypto2 = require("crypto");
|
|
7699
|
+
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
7700
|
+
"png",
|
|
7701
|
+
"jpg",
|
|
7702
|
+
"jpeg",
|
|
7703
|
+
"gif",
|
|
7704
|
+
"webp",
|
|
7705
|
+
"svg",
|
|
7706
|
+
"bmp",
|
|
7707
|
+
"ico"
|
|
7708
|
+
]);
|
|
7709
|
+
var IMAGE_MIME_BY_EXT = {
|
|
7710
|
+
png: "image/png",
|
|
7711
|
+
jpg: "image/jpeg",
|
|
7712
|
+
jpeg: "image/jpeg",
|
|
7713
|
+
gif: "image/gif",
|
|
7714
|
+
webp: "image/webp",
|
|
7715
|
+
svg: "image/svg+xml",
|
|
7716
|
+
bmp: "image/bmp",
|
|
7717
|
+
ico: "image/x-icon"
|
|
7718
|
+
};
|
|
7719
|
+
var ATTACHMENTS_DIR = ".sideboard/attachments";
|
|
7720
|
+
var ATTACHMENTS_GITIGNORE = `# Sideboard review / composer attachments (local only)
|
|
7721
|
+
*
|
|
7722
|
+
!.gitignore
|
|
7723
|
+
`;
|
|
7724
|
+
var MAX_INLINE_BYTES = 4e5;
|
|
7725
|
+
var MAX_PREVIEW_BYTES = 5e6;
|
|
7726
|
+
function fileExtension(filePath) {
|
|
7727
|
+
const base = (0, import_node_path19.basename)(filePath).toLowerCase();
|
|
7728
|
+
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
7729
|
+
}
|
|
7730
|
+
function isImageFilePath(filePath) {
|
|
7731
|
+
return IMAGE_EXTENSIONS2.has(fileExtension(filePath));
|
|
7732
|
+
}
|
|
7733
|
+
function imageMimeType(filePath) {
|
|
7734
|
+
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
7735
|
+
}
|
|
7736
|
+
function ensureAttachmentsDir(worktreePath) {
|
|
7737
|
+
const dir = (0, import_node_path19.join)(worktreePath, ATTACHMENTS_DIR);
|
|
7738
|
+
(0, import_node_fs19.mkdirSync)(dir, { recursive: true });
|
|
7739
|
+
const gi = (0, import_node_path19.join)(dir, ".gitignore");
|
|
7740
|
+
if (!(0, import_node_fs19.existsSync)(gi)) {
|
|
7741
|
+
(0, import_node_fs19.writeFileSync)(gi, ATTACHMENTS_GITIGNORE, "utf8");
|
|
7742
|
+
}
|
|
7743
|
+
return dir;
|
|
7744
|
+
}
|
|
7745
|
+
function uniqueAttachmentName(dir, originalName) {
|
|
7746
|
+
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
7747
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, safe))) return safe;
|
|
7748
|
+
const ext = (0, import_node_path19.extname)(safe);
|
|
7749
|
+
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
7750
|
+
for (let i = 1; i < 1e4; i++) {
|
|
7751
|
+
const candidate = `${stem}-${i}${ext}`;
|
|
7752
|
+
if (!(0, import_node_fs19.existsSync)((0, import_node_path19.join)(dir, candidate))) return candidate;
|
|
7753
|
+
}
|
|
7754
|
+
return `${stem}-${(0, import_node_crypto2.randomUUID)()}${ext}`;
|
|
7755
|
+
}
|
|
7756
|
+
function previewDataUrlFromBuf(filePath, buf) {
|
|
7757
|
+
if (!isImageFilePath(filePath)) return void 0;
|
|
7758
|
+
if (buf.length > MAX_PREVIEW_BYTES) return void 0;
|
|
7759
|
+
return `data:${imageMimeType(filePath)};base64,${buf.toString("base64")}`;
|
|
7760
|
+
}
|
|
7761
|
+
function attachmentFromBuffer(name, buf, opts) {
|
|
7762
|
+
const previewDataUrl = previewDataUrlFromBuf(name, buf);
|
|
7763
|
+
if (isImageFilePath(name)) {
|
|
7764
|
+
const pathHint = opts.path ? `\`${opts.path}\`` : opts.sourceLabel || name;
|
|
7765
|
+
return {
|
|
7766
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7767
|
+
name,
|
|
7768
|
+
kind: "file",
|
|
7769
|
+
path: opts.path,
|
|
7770
|
+
previewDataUrl,
|
|
7771
|
+
content: [
|
|
7772
|
+
`Image attached: ${pathHint}`,
|
|
7773
|
+
opts.path ? `Use the Read tool on \`${opts.path}\` to view this image.` : "The image is shown in the composer; copy it into the worktree if you need to inspect pixels."
|
|
7774
|
+
].join("\n")
|
|
7775
|
+
};
|
|
7776
|
+
}
|
|
7777
|
+
if (buf.length > MAX_INLINE_BYTES) {
|
|
7778
|
+
return {
|
|
7779
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7780
|
+
name,
|
|
7781
|
+
kind: "file",
|
|
7782
|
+
path: opts.path,
|
|
7783
|
+
content: opts.path ? `(file too large to attach inline: \`${opts.path}\`, ${buf.length} bytes \u2014 use the Read tool)` : `(file too large to attach inline: ${opts.sourceLabel || name}, ${buf.length} bytes)`
|
|
7784
|
+
};
|
|
7785
|
+
}
|
|
7786
|
+
if (buf.includes(0)) {
|
|
7787
|
+
return {
|
|
7788
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7789
|
+
name,
|
|
7790
|
+
kind: "file",
|
|
7791
|
+
path: opts.path,
|
|
7792
|
+
content: opts.path ? `(binary file at \`${opts.path}\` \u2014 use tools to inspect)` : `(binary file attached by path only: ${opts.sourceLabel || name})`
|
|
7793
|
+
};
|
|
7794
|
+
}
|
|
7795
|
+
return {
|
|
7796
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7797
|
+
name,
|
|
7798
|
+
kind: "file",
|
|
7799
|
+
path: opts.path,
|
|
7800
|
+
content: buf.toString("utf8")
|
|
7801
|
+
};
|
|
7802
|
+
}
|
|
7803
|
+
function attachmentFromAbsolutePath(absolutePath) {
|
|
7804
|
+
const name = (0, import_node_path19.basename)(absolutePath);
|
|
7805
|
+
try {
|
|
7806
|
+
const st = (0, import_node_fs19.statSync)(absolutePath);
|
|
7807
|
+
if (!st.isFile()) {
|
|
7808
|
+
return {
|
|
7809
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7810
|
+
name,
|
|
7811
|
+
kind: "file",
|
|
7812
|
+
content: `(not a file: ${absolutePath})`
|
|
7813
|
+
};
|
|
7814
|
+
}
|
|
7815
|
+
const buf = (0, import_node_fs19.readFileSync)(absolutePath);
|
|
7816
|
+
return attachmentFromBuffer(name, buf, { sourceLabel: absolutePath });
|
|
7817
|
+
} catch (err) {
|
|
7818
|
+
return {
|
|
7819
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7820
|
+
name,
|
|
7821
|
+
kind: "file",
|
|
7822
|
+
content: `(could not read ${absolutePath}: ${err instanceof Error ? err.message : String(err)})`
|
|
7823
|
+
};
|
|
7824
|
+
}
|
|
7825
|
+
}
|
|
7826
|
+
function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
7827
|
+
if (absolutePaths.length === 0) return [];
|
|
7828
|
+
const dir = ensureAttachmentsDir(worktreePath);
|
|
7829
|
+
const out = [];
|
|
7830
|
+
for (const abs of absolutePaths) {
|
|
7831
|
+
const originalName = (0, import_node_path19.basename)(abs);
|
|
7832
|
+
try {
|
|
7833
|
+
const st = (0, import_node_fs19.statSync)(abs);
|
|
7834
|
+
if (!st.isFile()) continue;
|
|
7835
|
+
const name = uniqueAttachmentName(dir, originalName);
|
|
7836
|
+
const destAbs = (0, import_node_path19.join)(dir, name);
|
|
7837
|
+
(0, import_node_fs19.copyFileSync)(abs, destAbs);
|
|
7838
|
+
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
7839
|
+
const buf = (0, import_node_fs19.readFileSync)(destAbs);
|
|
7840
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
7841
|
+
} catch (err) {
|
|
7842
|
+
out.push({
|
|
7843
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7844
|
+
name: originalName,
|
|
7845
|
+
kind: "file",
|
|
7846
|
+
content: `(could not attach ${abs}: ${err instanceof Error ? err.message : String(err)})`
|
|
7847
|
+
});
|
|
7848
|
+
}
|
|
7849
|
+
}
|
|
7850
|
+
return out;
|
|
7851
|
+
}
|
|
7852
|
+
function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
7853
|
+
if (buffers.length === 0) return [];
|
|
7854
|
+
const dir = ensureAttachmentsDir(worktreePath);
|
|
7855
|
+
const out = [];
|
|
7856
|
+
for (const item of buffers) {
|
|
7857
|
+
const originalName = (item.name || "file").replace(/[/\\]/g, "_") || "file";
|
|
7858
|
+
try {
|
|
7859
|
+
const buf = Buffer.from(item.dataBase64, "base64");
|
|
7860
|
+
const name = uniqueAttachmentName(dir, originalName);
|
|
7861
|
+
const destAbs = (0, import_node_path19.join)(dir, name);
|
|
7862
|
+
(0, import_node_fs19.writeFileSync)(destAbs, buf);
|
|
7863
|
+
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
7864
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
7865
|
+
} catch (err) {
|
|
7866
|
+
out.push({
|
|
7867
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7868
|
+
name: originalName,
|
|
7869
|
+
kind: "file",
|
|
7870
|
+
content: `(could not attach ${originalName}: ${err instanceof Error ? err.message : String(err)})`
|
|
7871
|
+
});
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
return out;
|
|
7875
|
+
}
|
|
7876
|
+
function attachmentsFromBuffers(buffers) {
|
|
7877
|
+
return buffers.map((item) => {
|
|
7878
|
+
const name = (item.name || "file").replace(/[/\\]/g, "_") || "file";
|
|
7879
|
+
try {
|
|
7880
|
+
const buf = Buffer.from(item.dataBase64, "base64");
|
|
7881
|
+
return attachmentFromBuffer(name, buf, { sourceLabel: name });
|
|
7882
|
+
} catch (err) {
|
|
7883
|
+
return {
|
|
7884
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7885
|
+
name,
|
|
7886
|
+
kind: "file",
|
|
7887
|
+
content: `(could not attach ${name}: ${err instanceof Error ? err.message : String(err)})`
|
|
7888
|
+
};
|
|
7889
|
+
}
|
|
7890
|
+
});
|
|
7891
|
+
}
|
|
7892
|
+
function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
7893
|
+
const out = [];
|
|
7894
|
+
for (const rel of relativePaths) {
|
|
7895
|
+
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
7896
|
+
out.push({
|
|
7897
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7898
|
+
name: (0, import_node_path19.basename)(rel) || "file",
|
|
7899
|
+
kind: "file",
|
|
7900
|
+
content: `(invalid path: ${rel})`
|
|
7901
|
+
});
|
|
7902
|
+
continue;
|
|
7903
|
+
}
|
|
7904
|
+
const name = (0, import_node_path19.basename)(rel);
|
|
7905
|
+
try {
|
|
7906
|
+
const abs = (0, import_node_path19.join)(worktreePath, rel);
|
|
7907
|
+
const st = (0, import_node_fs19.statSync)(abs);
|
|
7908
|
+
if (!st.isFile()) continue;
|
|
7909
|
+
const buf = (0, import_node_fs19.readFileSync)(abs);
|
|
7910
|
+
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
7911
|
+
} catch (err) {
|
|
7912
|
+
out.push({
|
|
7913
|
+
id: (0, import_node_crypto2.randomUUID)(),
|
|
7914
|
+
name,
|
|
7915
|
+
kind: "file",
|
|
7916
|
+
content: `(could not read ${rel}: ${err instanceof Error ? err.message : String(err)})`
|
|
7917
|
+
});
|
|
7918
|
+
}
|
|
7919
|
+
}
|
|
7920
|
+
return out;
|
|
7921
|
+
}
|
|
7922
|
+
|
|
7349
7923
|
// src/composer/summarize.ts
|
|
7350
7924
|
init_run();
|
|
7351
7925
|
init_path();
|
|
@@ -7784,14 +8358,14 @@ async function confirmLand(thread, opts) {
|
|
|
7784
8358
|
}
|
|
7785
8359
|
|
|
7786
8360
|
// src/threads/create.ts
|
|
7787
|
-
var
|
|
8361
|
+
var import_node_fs20 = require("fs");
|
|
7788
8362
|
init_worktree();
|
|
7789
8363
|
init_thread_store();
|
|
7790
8364
|
init_workspaces();
|
|
7791
8365
|
async function createThread(input, onSetupLine) {
|
|
7792
8366
|
await requireAgent(input.agent);
|
|
7793
8367
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
7794
|
-
if (!(0,
|
|
8368
|
+
if (!(0, import_node_fs20.existsSync)(repoPath)) {
|
|
7795
8369
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
7796
8370
|
}
|
|
7797
8371
|
let sourceRef = input.sourceRef;
|
|
@@ -7874,7 +8448,7 @@ async function listLinearIssues(agent, repoPath) {
|
|
|
7874
8448
|
}
|
|
7875
8449
|
|
|
7876
8450
|
// src/threads/chat-tabs.ts
|
|
7877
|
-
var
|
|
8451
|
+
var import_node_crypto3 = require("crypto");
|
|
7878
8452
|
init_teams();
|
|
7879
8453
|
init_worktree_labels();
|
|
7880
8454
|
init_global_workspace();
|
|
@@ -7930,7 +8504,7 @@ function forkMessageSlice(from, throughIndex) {
|
|
|
7930
8504
|
function buildForkTranscriptAttachment(baseTitle, messages) {
|
|
7931
8505
|
const title = baseTitle || "Chat";
|
|
7932
8506
|
return {
|
|
7933
|
-
id: (0,
|
|
8507
|
+
id: (0, import_node_crypto3.randomUUID)(),
|
|
7934
8508
|
name: `Transcript of ${title}.md`,
|
|
7935
8509
|
kind: "transcript",
|
|
7936
8510
|
content: formatTranscriptMarkdown(title, messages)
|
|
@@ -7949,10 +8523,10 @@ function createChatTab(input) {
|
|
|
7949
8523
|
userSetTitle: true,
|
|
7950
8524
|
...binding,
|
|
7951
8525
|
agent: input.agent ?? from.agent,
|
|
7952
|
-
model: input.agent && input.agent !== from.agent ? null : from.model,
|
|
8526
|
+
model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
|
|
7953
8527
|
fast: from.fast,
|
|
7954
8528
|
planMode: from.planMode,
|
|
7955
|
-
autonomy: from.autonomy,
|
|
8529
|
+
autonomy: input.autonomy ?? from.autonomy,
|
|
7956
8530
|
attachments: input.attachments ?? [],
|
|
7957
8531
|
status: "idle"
|
|
7958
8532
|
});
|
|
@@ -7989,30 +8563,34 @@ async function forkThreadWorktree(input, onSetupLine) {
|
|
|
7989
8563
|
repoPath: from.repoPath,
|
|
7990
8564
|
agent: input.agent ?? from.agent,
|
|
7991
8565
|
autonomy: from.autonomy,
|
|
8566
|
+
model: from.model,
|
|
8567
|
+
fast: from.fast,
|
|
8568
|
+
planMode: from.planMode,
|
|
7992
8569
|
title: input.title?.trim() || void 0,
|
|
7993
|
-
parentThreadId: from.id
|
|
8570
|
+
parentThreadId: from.id,
|
|
8571
|
+
attachments: [attachment]
|
|
7994
8572
|
},
|
|
7995
8573
|
onSetupLine
|
|
7996
8574
|
);
|
|
7997
|
-
return
|
|
8575
|
+
return thread;
|
|
7998
8576
|
}
|
|
7999
8577
|
|
|
8000
8578
|
// src/threads/adopt.ts
|
|
8001
8579
|
var import_node_child_process = require("child_process");
|
|
8002
|
-
var
|
|
8580
|
+
var import_node_fs21 = require("fs");
|
|
8003
8581
|
var import_node_os9 = require("os");
|
|
8004
|
-
var
|
|
8582
|
+
var import_node_path20 = require("path");
|
|
8005
8583
|
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
8006
8584
|
init_worktree();
|
|
8007
8585
|
init_thread_store();
|
|
8008
|
-
var CONDUCTOR_APP_SUPPORT = (0,
|
|
8586
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path20.join)(
|
|
8009
8587
|
process.env.HOME ?? "",
|
|
8010
8588
|
"Library",
|
|
8011
8589
|
"Application Support",
|
|
8012
8590
|
"com.conductor.app"
|
|
8013
8591
|
);
|
|
8014
|
-
var CONDUCTOR_DB = (0,
|
|
8015
|
-
var CURSOR_SDK_STORE = (0,
|
|
8592
|
+
var CONDUCTOR_DB = (0, import_node_path20.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
8593
|
+
var CURSOR_SDK_STORE = (0, import_node_path20.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
8016
8594
|
function mapAgentType(raw) {
|
|
8017
8595
|
if (!raw) return null;
|
|
8018
8596
|
const v = raw.toLowerCase();
|
|
@@ -8024,21 +8602,21 @@ function mapAgentType(raw) {
|
|
|
8024
8602
|
return null;
|
|
8025
8603
|
}
|
|
8026
8604
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
8027
|
-
if (!workspacePath || !(0,
|
|
8605
|
+
if (!workspacePath || !(0, import_node_fs21.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
8028
8606
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
8029
8607
|
let best = null;
|
|
8030
8608
|
let hashes;
|
|
8031
8609
|
try {
|
|
8032
|
-
hashes = (0,
|
|
8610
|
+
hashes = (0, import_node_fs21.readdirSync)(CURSOR_SDK_STORE);
|
|
8033
8611
|
} catch {
|
|
8034
8612
|
return null;
|
|
8035
8613
|
}
|
|
8036
8614
|
for (const hash of hashes) {
|
|
8037
|
-
const agentsFile = (0,
|
|
8038
|
-
if (!(0,
|
|
8615
|
+
const agentsFile = (0, import_node_path20.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
8616
|
+
if (!(0, import_node_fs21.existsSync)(agentsFile)) continue;
|
|
8039
8617
|
let text;
|
|
8040
8618
|
try {
|
|
8041
|
-
text = (0,
|
|
8619
|
+
text = (0, import_node_fs21.readFileSync)(agentsFile, "utf8");
|
|
8042
8620
|
} catch {
|
|
8043
8621
|
continue;
|
|
8044
8622
|
}
|
|
@@ -8062,7 +8640,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
8062
8640
|
return best?.agentId ?? null;
|
|
8063
8641
|
}
|
|
8064
8642
|
async function adoptThread(input) {
|
|
8065
|
-
if (!(0,
|
|
8643
|
+
if (!(0, import_node_fs21.existsSync)(input.worktreePath)) {
|
|
8066
8644
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
8067
8645
|
}
|
|
8068
8646
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -8089,18 +8667,18 @@ function conductorDbPath() {
|
|
|
8089
8667
|
return CONDUCTOR_DB;
|
|
8090
8668
|
}
|
|
8091
8669
|
function listConductorWorkspaces() {
|
|
8092
|
-
if (!(0,
|
|
8670
|
+
if (!(0, import_node_fs21.existsSync)(CONDUCTOR_DB)) {
|
|
8093
8671
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
8094
8672
|
}
|
|
8095
|
-
const tmp = (0,
|
|
8096
|
-
const snapshot = (0,
|
|
8673
|
+
const tmp = (0, import_node_fs21.mkdtempSync)((0, import_node_path20.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
|
|
8674
|
+
const snapshot = (0, import_node_path20.join)(tmp, "conductor.db");
|
|
8097
8675
|
try {
|
|
8098
|
-
(0,
|
|
8676
|
+
(0, import_node_fs21.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
8099
8677
|
for (const suffix of ["-wal", "-shm"]) {
|
|
8100
8678
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
8101
|
-
if ((0,
|
|
8679
|
+
if ((0, import_node_fs21.existsSync)(src)) {
|
|
8102
8680
|
try {
|
|
8103
|
-
(0,
|
|
8681
|
+
(0, import_node_fs21.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
8104
8682
|
} catch {
|
|
8105
8683
|
}
|
|
8106
8684
|
}
|
|
@@ -8176,22 +8754,22 @@ function listConductorWorkspaces() {
|
|
|
8176
8754
|
db.close();
|
|
8177
8755
|
}
|
|
8178
8756
|
} finally {
|
|
8179
|
-
(0,
|
|
8757
|
+
(0, import_node_fs21.rmSync)(tmp, { recursive: true, force: true });
|
|
8180
8758
|
}
|
|
8181
8759
|
}
|
|
8182
8760
|
function importConductorWorkspace(workspaceId) {
|
|
8183
|
-
if (!(0,
|
|
8761
|
+
if (!(0, import_node_fs21.existsSync)(CONDUCTOR_DB)) {
|
|
8184
8762
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
8185
8763
|
}
|
|
8186
|
-
const tmp = (0,
|
|
8187
|
-
const snapshot = (0,
|
|
8764
|
+
const tmp = (0, import_node_fs21.mkdtempSync)((0, import_node_path20.join)((0, import_node_os9.tmpdir)(), "sideboard-conductor-"));
|
|
8765
|
+
const snapshot = (0, import_node_path20.join)(tmp, "conductor.db");
|
|
8188
8766
|
try {
|
|
8189
|
-
(0,
|
|
8767
|
+
(0, import_node_fs21.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
8190
8768
|
for (const suffix of ["-wal", "-shm"]) {
|
|
8191
8769
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
8192
|
-
if ((0,
|
|
8770
|
+
if ((0, import_node_fs21.existsSync)(src)) {
|
|
8193
8771
|
try {
|
|
8194
|
-
(0,
|
|
8772
|
+
(0, import_node_fs21.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
8195
8773
|
} catch {
|
|
8196
8774
|
}
|
|
8197
8775
|
}
|
|
@@ -8209,7 +8787,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
8209
8787
|
).get(workspaceId);
|
|
8210
8788
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
8211
8789
|
const worktreePath = String(row.workspacePath);
|
|
8212
|
-
if (!(0,
|
|
8790
|
+
if (!(0, import_node_fs21.existsSync)(worktreePath)) {
|
|
8213
8791
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
8214
8792
|
}
|
|
8215
8793
|
let sessionId = null;
|
|
@@ -8272,7 +8850,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
8272
8850
|
db.close();
|
|
8273
8851
|
}
|
|
8274
8852
|
} finally {
|
|
8275
|
-
(0,
|
|
8853
|
+
(0, import_node_fs21.rmSync)(tmp, { recursive: true, force: true });
|
|
8276
8854
|
}
|
|
8277
8855
|
}
|
|
8278
8856
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -8281,13 +8859,13 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
8281
8859
|
|
|
8282
8860
|
// src/orchestrator/orchestrator.ts
|
|
8283
8861
|
var import_node_events = require("events");
|
|
8284
|
-
var
|
|
8862
|
+
var import_node_fs24 = require("fs");
|
|
8285
8863
|
init_agents();
|
|
8286
8864
|
init_worktree();
|
|
8287
8865
|
|
|
8288
8866
|
// src/git/orphan-cleanup.ts
|
|
8289
|
-
var
|
|
8290
|
-
var
|
|
8867
|
+
var import_node_fs22 = require("fs");
|
|
8868
|
+
var import_node_path21 = require("path");
|
|
8291
8869
|
init_worktree();
|
|
8292
8870
|
init_thread_store();
|
|
8293
8871
|
init_paths();
|
|
@@ -8302,9 +8880,9 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
8302
8880
|
repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
|
|
8303
8881
|
);
|
|
8304
8882
|
const homeRoot = sideboardWorkspacesDir();
|
|
8305
|
-
if ((0,
|
|
8883
|
+
if ((0, import_node_fs22.existsSync)(homeRoot)) {
|
|
8306
8884
|
try {
|
|
8307
|
-
for (const entry of (0,
|
|
8885
|
+
for (const entry of (0, import_node_fs22.readdirSync)(homeRoot, { withFileTypes: true })) {
|
|
8308
8886
|
if (!entry.isDirectory()) continue;
|
|
8309
8887
|
void entry;
|
|
8310
8888
|
}
|
|
@@ -8314,7 +8892,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
8314
8892
|
const orphans = [];
|
|
8315
8893
|
const seen = /* @__PURE__ */ new Set();
|
|
8316
8894
|
for (const repoPath of repos) {
|
|
8317
|
-
if (!repoPath || !(0,
|
|
8895
|
+
if (!repoPath || !(0, import_node_fs22.existsSync)(repoPath)) continue;
|
|
8318
8896
|
try {
|
|
8319
8897
|
const wts = await listWorktrees(repoPath);
|
|
8320
8898
|
for (const wt of wts) {
|
|
@@ -8325,7 +8903,7 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
8325
8903
|
seen.add(path);
|
|
8326
8904
|
let mtimeMs = 0;
|
|
8327
8905
|
try {
|
|
8328
|
-
mtimeMs = (0,
|
|
8906
|
+
mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
|
|
8329
8907
|
} catch {
|
|
8330
8908
|
mtimeMs = 0;
|
|
8331
8909
|
}
|
|
@@ -8335,16 +8913,16 @@ async function findOrphanWorktrees(repoPaths) {
|
|
|
8335
8913
|
}
|
|
8336
8914
|
try {
|
|
8337
8915
|
const root = worktreesRoot(repoPath);
|
|
8338
|
-
if ((0,
|
|
8339
|
-
for (const entry of (0,
|
|
8916
|
+
if ((0, import_node_fs22.existsSync)(root)) {
|
|
8917
|
+
for (const entry of (0, import_node_fs22.readdirSync)(root, { withFileTypes: true })) {
|
|
8340
8918
|
if (!entry.isDirectory()) continue;
|
|
8341
|
-
const path = (0,
|
|
8919
|
+
const path = (0, import_node_path21.join)(root, entry.name).replace(/\/$/, "");
|
|
8342
8920
|
if (known.has(path) || seen.has(path)) continue;
|
|
8343
|
-
if (!(0,
|
|
8921
|
+
if (!(0, import_node_fs22.existsSync)((0, import_node_path21.join)(path, ".git"))) continue;
|
|
8344
8922
|
seen.add(path);
|
|
8345
8923
|
let mtimeMs = 0;
|
|
8346
8924
|
try {
|
|
8347
|
-
mtimeMs = (0,
|
|
8925
|
+
mtimeMs = (0, import_node_fs22.statSync)(path).mtimeMs;
|
|
8348
8926
|
} catch {
|
|
8349
8927
|
mtimeMs = Date.now();
|
|
8350
8928
|
}
|
|
@@ -8490,8 +9068,8 @@ async function applyThreadIntoMain(thread, opts) {
|
|
|
8490
9068
|
}
|
|
8491
9069
|
|
|
8492
9070
|
// src/git/clone-repo.ts
|
|
8493
|
-
var
|
|
8494
|
-
var
|
|
9071
|
+
var import_node_fs23 = require("fs");
|
|
9072
|
+
var import_node_path22 = require("path");
|
|
8495
9073
|
var import_execa6 = require("execa");
|
|
8496
9074
|
init_paths();
|
|
8497
9075
|
init_workspaces();
|
|
@@ -8501,12 +9079,12 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
8501
9079
|
if (!url) throw new Error("Clone URL is required");
|
|
8502
9080
|
let name = opts.name?.trim();
|
|
8503
9081
|
if (!name) {
|
|
8504
|
-
const leaf = (0,
|
|
9082
|
+
const leaf = (0, import_node_path22.basename)(url.replace(/\/$/, "").replace(/\.git$/, ""));
|
|
8505
9083
|
name = leaf || "repo";
|
|
8506
9084
|
}
|
|
8507
9085
|
name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
|
|
8508
|
-
const dest = (0,
|
|
8509
|
-
if ((0,
|
|
9086
|
+
const dest = (0, import_node_path22.join)(sideboardReposDir(), name);
|
|
9087
|
+
if ((0, import_node_fs23.existsSync)(dest)) {
|
|
8510
9088
|
const repoPath2 = await resolveRepoRoot(dest);
|
|
8511
9089
|
const workspace2 = await ensureWorkspace(repoPath2);
|
|
8512
9090
|
return { repoPath: repoPath2, workspace: workspace2 };
|
|
@@ -8618,7 +9196,7 @@ var Orchestrator = class {
|
|
|
8618
9196
|
}
|
|
8619
9197
|
continue;
|
|
8620
9198
|
}
|
|
8621
|
-
if (!(0,
|
|
9199
|
+
if (!(0, import_node_fs24.existsSync)(thread.worktreePath)) {
|
|
8622
9200
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
8623
9201
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
8624
9202
|
continue;
|
|
@@ -8871,6 +9449,7 @@ var Orchestrator = class {
|
|
|
8871
9449
|
...fresh.agent === "claude" && fresh.sessionId ? [] : [instructions, seed]
|
|
8872
9450
|
].filter(Boolean).join("\n\n---\n\n");
|
|
8873
9451
|
try {
|
|
9452
|
+
let lastStderr = "";
|
|
8874
9453
|
const handle = await spawnAgentTurn(
|
|
8875
9454
|
fresh,
|
|
8876
9455
|
{ cachedPrefix, prompt: agentPrompt },
|
|
@@ -8879,6 +9458,9 @@ var Orchestrator = class {
|
|
|
8879
9458
|
if (event.type === "session_id") {
|
|
8880
9459
|
updateThread(threadId, { sessionId: event.data });
|
|
8881
9460
|
}
|
|
9461
|
+
if (event.type === "stderr" && typeof event.data === "string" && event.data.trim()) {
|
|
9462
|
+
lastStderr = event.data.trim();
|
|
9463
|
+
}
|
|
8882
9464
|
}
|
|
8883
9465
|
);
|
|
8884
9466
|
this.activeTurns.set(threadId, handle);
|
|
@@ -8924,7 +9506,12 @@ var Orchestrator = class {
|
|
|
8924
9506
|
this.emit({ type: "status_changed", threadId, status: "stopped" });
|
|
8925
9507
|
this.emit({ type: "turn_finished", threadId, exitCode: result.exitCode });
|
|
8926
9508
|
} else {
|
|
8927
|
-
|
|
9509
|
+
const failDetail = lastStderr ? `exit ${result.exitCode}: ${lastStderr.slice(0, 500)}` : `exit ${result.exitCode}`;
|
|
9510
|
+
setStatus(
|
|
9511
|
+
threadId,
|
|
9512
|
+
result.exitCode === 0 ? "idle" : "error",
|
|
9513
|
+
result.exitCode === 0 ? null : failDetail
|
|
9514
|
+
);
|
|
8928
9515
|
this.emit({
|
|
8929
9516
|
type: "status_changed",
|
|
8930
9517
|
threadId,
|
|
@@ -9398,9 +9985,16 @@ var Orchestrator = class {
|
|
|
9398
9985
|
if (patch.planMode !== void 0) next.planMode = patch.planMode;
|
|
9399
9986
|
if (patch.model !== void 0) next.model = patch.model;
|
|
9400
9987
|
if (patch.agent !== void 0) {
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9988
|
+
if (patch.agent !== thread.agent) {
|
|
9989
|
+
if (thread.messages.length > 0) {
|
|
9990
|
+
throw new Error(
|
|
9991
|
+
`Cannot switch agent provider mid-chat (${thread.agent} \u2192 ${patch.agent}). Start a new chat tab instead.`
|
|
9992
|
+
);
|
|
9993
|
+
}
|
|
9994
|
+
next.agent = patch.agent;
|
|
9995
|
+
if (patch.agent !== "claude" && patch.model === void 0) next.model = null;
|
|
9996
|
+
next.sessionId = null;
|
|
9997
|
+
}
|
|
9404
9998
|
}
|
|
9405
9999
|
return updateThread(thread.id, next);
|
|
9406
10000
|
}
|
|
@@ -9430,6 +10024,23 @@ var Orchestrator = class {
|
|
|
9430
10024
|
setAttachments(threadRef, attachments) {
|
|
9431
10025
|
return updateThread(this.requireThread(threadRef).id, { attachments });
|
|
9432
10026
|
}
|
|
10027
|
+
/**
|
|
10028
|
+
* Stage OS / worktree files into composer attachments (copies external files
|
|
10029
|
+
* into `.sideboard/attachments/` so agents can Read images and binaries).
|
|
10030
|
+
*/
|
|
10031
|
+
attachComposerFiles(threadRef, opts) {
|
|
10032
|
+
const thread = this.requireThread(threadRef);
|
|
10033
|
+
const fromAbs = stageAbsolutePathsAsAttachments(
|
|
10034
|
+
thread.worktreePath,
|
|
10035
|
+
opts.absolutePaths ?? []
|
|
10036
|
+
);
|
|
10037
|
+
const fromRel = attachmentsFromWorktreePaths(
|
|
10038
|
+
thread.worktreePath,
|
|
10039
|
+
opts.relativePaths ?? []
|
|
10040
|
+
);
|
|
10041
|
+
const fromBuf = stageBuffersAsAttachments(thread.worktreePath, opts.buffers ?? []);
|
|
10042
|
+
return [...fromAbs, ...fromRel, ...fromBuf];
|
|
10043
|
+
}
|
|
9433
10044
|
listWorktreeChats(threadRef) {
|
|
9434
10045
|
const thread = this.requireThread(threadRef);
|
|
9435
10046
|
return threadsSharingWorktree(thread.worktreePath);
|
|
@@ -9489,7 +10100,7 @@ var Orchestrator = class {
|
|
|
9489
10100
|
updateThread(thread.id, { worktreePath: globalAgentCwd2() });
|
|
9490
10101
|
return setStatus(thread.id, "idle");
|
|
9491
10102
|
}
|
|
9492
|
-
if (!(0,
|
|
10103
|
+
if (!(0, import_node_fs24.existsSync)(thread.worktreePath)) {
|
|
9493
10104
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
9494
10105
|
const { execa: execa7 } = await import("execa");
|
|
9495
10106
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -9591,7 +10202,7 @@ init_coordinator_prompt();
|
|
|
9591
10202
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
9592
10203
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
9593
10204
|
var import_zod = require("zod");
|
|
9594
|
-
var
|
|
10205
|
+
var import_node_path23 = require("path");
|
|
9595
10206
|
init_worktree();
|
|
9596
10207
|
init_global_workspace();
|
|
9597
10208
|
|
|
@@ -9639,7 +10250,7 @@ async function startMcpServer() {
|
|
|
9639
10250
|
async () => {
|
|
9640
10251
|
const threads = orch.getThreads(true);
|
|
9641
10252
|
const lines = threads.map((t) => {
|
|
9642
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
10253
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path23.basename)(t.repoPath) || t.repoPath;
|
|
9643
10254
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
|
|
9644
10255
|
});
|
|
9645
10256
|
return {
|
|
@@ -10535,6 +11146,9 @@ init_injected_mcp();
|
|
|
10535
11146
|
applyAppEnvironment,
|
|
10536
11147
|
applyCompaction,
|
|
10537
11148
|
applyThreadIntoMain,
|
|
11149
|
+
attachmentFromAbsolutePath,
|
|
11150
|
+
attachmentsFromBuffers,
|
|
11151
|
+
attachmentsFromWorktreePaths,
|
|
10538
11152
|
autoCleanupOrphansEnabled,
|
|
10539
11153
|
autoRenameBranchEnabled,
|
|
10540
11154
|
autoRunAfterSetupEnabled,
|
|
@@ -10620,6 +11234,7 @@ init_injected_mcp();
|
|
|
10620
11234
|
formatWorkspaceInventory,
|
|
10621
11235
|
formatWorktreeDirective,
|
|
10622
11236
|
getAdapter,
|
|
11237
|
+
getAgentSetupInfo,
|
|
10623
11238
|
getBrightsySession,
|
|
10624
11239
|
getDefaultRunScript,
|
|
10625
11240
|
getDiff,
|
|
@@ -10650,27 +11265,34 @@ init_injected_mcp();
|
|
|
10650
11265
|
importConductorWorkspaceAsync,
|
|
10651
11266
|
initializeGitRepository,
|
|
10652
11267
|
inspectGitWorktree,
|
|
11268
|
+
installAgent,
|
|
10653
11269
|
isBrightsyConnected,
|
|
10654
11270
|
isBrightsyNdjsonLine,
|
|
10655
11271
|
isCloudCoordinatorThread,
|
|
11272
|
+
isCursorAutoModel,
|
|
10656
11273
|
isDirty,
|
|
10657
11274
|
isGhRateLimitError,
|
|
10658
11275
|
isGlobalRepoPath,
|
|
10659
11276
|
isGlobalThread,
|
|
11277
|
+
isImageFilePath,
|
|
10660
11278
|
isLinearConnected,
|
|
10661
11279
|
isOrchestratorThread,
|
|
10662
11280
|
isPlaceholderBranch,
|
|
11281
|
+
listAgentSetupInfo,
|
|
10663
11282
|
listBranchCommits,
|
|
10664
11283
|
listBranches,
|
|
10665
11284
|
listBrightsyAccounts,
|
|
10666
11285
|
listBrightsyChatTargets,
|
|
11286
|
+
listCodexModels,
|
|
10667
11287
|
listConductorWorkspaces,
|
|
10668
11288
|
listConnectedBrightsyTeams,
|
|
11289
|
+
listCursorModels,
|
|
10669
11290
|
listGitHubIssues,
|
|
10670
11291
|
listGlobalThreads,
|
|
10671
11292
|
listIssues,
|
|
10672
11293
|
listLinearIssues,
|
|
10673
11294
|
listLinearIssuesDirect,
|
|
11295
|
+
listOpencodeModels,
|
|
10674
11296
|
listPrs,
|
|
10675
11297
|
listRunScripts,
|
|
10676
11298
|
listThreads,
|
|
@@ -10684,6 +11306,7 @@ init_injected_mcp();
|
|
|
10684
11306
|
loadRepoSettings,
|
|
10685
11307
|
loadWorkspaceSettings,
|
|
10686
11308
|
locksDir,
|
|
11309
|
+
loginAgent,
|
|
10687
11310
|
lookupSoccerTeam,
|
|
10688
11311
|
maxConcurrentAgents,
|
|
10689
11312
|
maybeCompactContext,
|
|
@@ -10695,6 +11318,7 @@ init_injected_mcp();
|
|
|
10695
11318
|
normalizeThread,
|
|
10696
11319
|
normalizeTurnInput,
|
|
10697
11320
|
normalizeWorktreePath,
|
|
11321
|
+
openInSystemTerminal,
|
|
10698
11322
|
opencodeAdapter,
|
|
10699
11323
|
orchestrationTitleNeedsSoccerNickname,
|
|
10700
11324
|
orchestratorSessionPoisonedByBuiltins,
|
|
@@ -10719,6 +11343,7 @@ init_injected_mcp();
|
|
|
10719
11343
|
requireAgent,
|
|
10720
11344
|
resolveClaudeExecutable,
|
|
10721
11345
|
resolveConductorCursorAgentId,
|
|
11346
|
+
resolveCursorModelId,
|
|
10722
11347
|
resolveDefaultBranch,
|
|
10723
11348
|
resolveDiffBaseRef,
|
|
10724
11349
|
resolveEffectiveIssueSource,
|
|
@@ -10745,6 +11370,8 @@ init_injected_mcp();
|
|
|
10745
11370
|
slugify,
|
|
10746
11371
|
spawnAgentTurn,
|
|
10747
11372
|
splitForCompaction,
|
|
11373
|
+
stageAbsolutePathsAsAttachments,
|
|
11374
|
+
stageBuffersAsAttachments,
|
|
10748
11375
|
startDevServer,
|
|
10749
11376
|
startMcpServer,
|
|
10750
11377
|
startOrchestration,
|