@sideboard-ai/core 0.1.88 → 0.1.92
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 +176 -15
- package/dist/agents/cursor-runner.js +11 -2
- package/dist/{agents-LMUFTGKF.js → agents-JXQ5QHDU.js} +4 -4
- package/dist/{agents-ODBP7J6E.js → agents-TUV4NH7S.js} +5 -5
- package/dist/{chunk-RJLBSYUO.js → chunk-35LKGGOC.js} +45 -77
- package/dist/{chunk-WANQFU3S.js → chunk-6XBXVXX2.js} +2 -2
- package/dist/{chunk-7D27DD2X.js → chunk-CIRXAYWS.js} +260 -61
- package/dist/{chunk-B2KIO2SD.js → chunk-CLGO7TLO.js} +2 -2
- package/dist/{chunk-JE75QW2I.js → chunk-GJ2HJQIU.js} +236 -96
- package/dist/{chunk-CBJSPTBG.js → chunk-GXSYI7FH.js} +206 -5
- package/dist/chunk-MMI4RJ5I.js +46 -0
- package/dist/{chunk-UHTNJKZX.js → chunk-NR6APJLD.js} +2 -2
- package/dist/{chunk-6EZRSCIT.js → chunk-QKYO6BHB.js} +2 -2
- package/dist/{chunk-ZXYWWSHZ.js → chunk-R7BQBSDT.js} +254 -61
- package/dist/{chunk-OB6IRIFV.js → chunk-XH2GS2LO.js} +2 -2
- package/dist/{chunk-VZ2L4AEJ.js → chunk-XUWDLRAE.js} +2 -2
- package/dist/{coordinator-prompt-UK5LYFN5.js → coordinator-prompt-AKEY4WSO.js} +2 -2
- package/dist/{coordinator-prompt-CI5SHONJ.js → coordinator-prompt-OQOOD5ET.js} +2 -2
- package/dist/{global-workspace-2YZ2V4I5.js → global-workspace-3GNPQCLE.js} +3 -3
- package/dist/{global-workspace-JQQLPJM5.js → global-workspace-M3OMVDDH.js} +3 -3
- package/dist/index.cjs +998 -463
- package/dist/index.d.cts +77 -19
- package/dist/index.d.ts +77 -19
- package/dist/index.js +181 -50
- package/dist/mcp/run-stdio.cjs +872 -436
- package/dist/mcp/run-stdio.js +132 -48
- package/dist/{workspaces-YWCC3WV4.js → workspaces-ERZC7ULY.js} +4 -4
- package/dist/{workspaces-FDO5L4NI.js → workspaces-J4WG6UFR.js} +4 -4
- package/dist/{worktree-7YNSJ224.js → worktree-DA4BOV7G.js} +7 -1
- package/dist/{worktree-4555QBQ7.js → worktree-EO5QAGJU.js} +7 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QKYO6BHB.js";
|
|
8
8
|
import {
|
|
9
9
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
10
10
|
CLAUDE_MODEL_CATALOG,
|
|
@@ -58,13 +58,14 @@ import {
|
|
|
58
58
|
resolveCursorModelId,
|
|
59
59
|
resolveLoginCommand,
|
|
60
60
|
resolveQuotaFallbackAgent,
|
|
61
|
+
resolveSideboardMcpServer,
|
|
61
62
|
sanitizeMcpServerName,
|
|
62
63
|
shouldInjectBrightsyMcp,
|
|
63
64
|
sideboardMcpProfile,
|
|
64
65
|
threadRequestsBrightsyMcp,
|
|
65
66
|
totalTokens,
|
|
66
67
|
writeInjectedMcpConfig
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-35LKGGOC.js";
|
|
68
69
|
import {
|
|
69
70
|
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
70
71
|
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
@@ -91,7 +92,7 @@ import {
|
|
|
91
92
|
parseForceStopMessage,
|
|
92
93
|
slackCoordinatorSourceRef,
|
|
93
94
|
takenTeamSlugsForOrchestration
|
|
94
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-CLGO7TLO.js";
|
|
95
96
|
import {
|
|
96
97
|
COORDINATOR_TOOL_PLAYBOOK,
|
|
97
98
|
SLACK_REPLY_FORMATTING,
|
|
@@ -100,7 +101,7 @@ import {
|
|
|
100
101
|
enrichWorkspacesWithGithub,
|
|
101
102
|
ensureGlobalCoordinatorCwd,
|
|
102
103
|
formatWorkspaceInventory
|
|
103
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-XUWDLRAE.js";
|
|
104
105
|
import {
|
|
105
106
|
brightsyConfigPath,
|
|
106
107
|
brightsyMcpServerName,
|
|
@@ -124,6 +125,9 @@ import {
|
|
|
124
125
|
resolvePlanMarkdown,
|
|
125
126
|
writePlanFile
|
|
126
127
|
} from "./chunk-QTUESPAW.js";
|
|
128
|
+
import {
|
|
129
|
+
createAgentStreamCoalescer
|
|
130
|
+
} from "./chunk-MMI4RJ5I.js";
|
|
127
131
|
import {
|
|
128
132
|
cursorSdkMessageToEvents,
|
|
129
133
|
fallbackTurnFailDetail,
|
|
@@ -134,7 +138,7 @@ import {
|
|
|
134
138
|
parseCursorRunnerLine,
|
|
135
139
|
pushTurnStderr,
|
|
136
140
|
summarizeTurnStderr
|
|
137
|
-
} from "./chunk-
|
|
141
|
+
} from "./chunk-GXSYI7FH.js";
|
|
138
142
|
import {
|
|
139
143
|
caffeinateHoldPath,
|
|
140
144
|
getCaffeinateHold,
|
|
@@ -151,6 +155,7 @@ import {
|
|
|
151
155
|
applyGithubGitAuthEnv,
|
|
152
156
|
branchDisplayLabel,
|
|
153
157
|
checkoutPrStackLayer,
|
|
158
|
+
codexSandboxWritableRootsArgs,
|
|
154
159
|
codexUnattendedGitConfigArgs,
|
|
155
160
|
collectTakenTeamSlugs,
|
|
156
161
|
commitAll,
|
|
@@ -171,12 +176,14 @@ import {
|
|
|
171
176
|
getPr,
|
|
172
177
|
getPrChecks,
|
|
173
178
|
getPrDetails,
|
|
179
|
+
getPrForHeadBranch,
|
|
174
180
|
getPrMeta,
|
|
175
181
|
getPrStack,
|
|
176
182
|
ghHeadRef,
|
|
177
183
|
ghRepoSelectArgs,
|
|
178
184
|
githubAgentGitEnv,
|
|
179
185
|
initPrStack,
|
|
186
|
+
isDefaultishSourceRef,
|
|
180
187
|
isDirty,
|
|
181
188
|
isGhRateLimitError,
|
|
182
189
|
isInPrStack,
|
|
@@ -187,6 +194,7 @@ import {
|
|
|
187
194
|
listPrs,
|
|
188
195
|
listWorktrees,
|
|
189
196
|
lookupSoccerTeam,
|
|
197
|
+
mergeAgentGitAuthEnv,
|
|
190
198
|
mergePr,
|
|
191
199
|
mergePrStack,
|
|
192
200
|
nonInteractiveGitProcessEnv,
|
|
@@ -197,24 +205,29 @@ import {
|
|
|
197
205
|
pushBranch,
|
|
198
206
|
removeWorktree,
|
|
199
207
|
resetGhStackDetectCache,
|
|
208
|
+
resetGithubAgentTokenMemo,
|
|
200
209
|
resolveAgentGitAuthEnv,
|
|
210
|
+
resolveCodexGitWritableRoots,
|
|
201
211
|
resolveDefaultBranch,
|
|
202
212
|
resolveDiffBaseRef,
|
|
203
213
|
resolveGithubAgentToken,
|
|
204
214
|
resolveGithubRepoSlug,
|
|
205
215
|
resolvePrSelector,
|
|
216
|
+
resolvePrSelectors,
|
|
206
217
|
resolveRepoRoot,
|
|
207
218
|
resolveWorktreeStartPoint,
|
|
219
|
+
scrubGithubTokensFromChildEnv,
|
|
208
220
|
slugify,
|
|
209
221
|
stackMergeReadiness,
|
|
210
222
|
submitPrStack,
|
|
211
223
|
suggestSlug,
|
|
212
224
|
takenSlugsFromThread,
|
|
213
225
|
threadDisplayLabel,
|
|
226
|
+
warmGithubAgentAuth,
|
|
214
227
|
worktreeDisplayLabel,
|
|
215
228
|
worktreeDisplayLabelForGroup,
|
|
216
229
|
worktreeNameFromPath
|
|
217
|
-
} from "./chunk-
|
|
230
|
+
} from "./chunk-CIRXAYWS.js";
|
|
218
231
|
import {
|
|
219
232
|
ATTACHMENTS_DIR,
|
|
220
233
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -1325,9 +1338,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1325
1338
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
1326
1339
|
);
|
|
1327
1340
|
}
|
|
1328
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
1341
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-M3OMVDDH.js");
|
|
1329
1342
|
if (isGlobalThread2(thread)) {
|
|
1330
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
1343
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-AKEY4WSO.js");
|
|
1331
1344
|
ensureGlobalCoordinatorCwd2(
|
|
1332
1345
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
1333
1346
|
);
|
|
@@ -1345,10 +1358,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1345
1358
|
const env = childEnvWithAppSettings(cmd.env);
|
|
1346
1359
|
try {
|
|
1347
1360
|
if (isOrchestratorThread(thread)) {
|
|
1348
|
-
|
|
1361
|
+
mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
|
|
1349
1362
|
} else {
|
|
1350
|
-
|
|
1351
|
-
Object.assign(env, originEnv);
|
|
1363
|
+
mergeAgentGitAuthEnv(env, await originGhRepoEnv(thread.worktreePath, { env }));
|
|
1352
1364
|
}
|
|
1353
1365
|
} catch (err) {
|
|
1354
1366
|
const detail = err instanceof Error ? err.message : String(err);
|
|
@@ -1372,12 +1384,13 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1372
1384
|
let assistantText = "";
|
|
1373
1385
|
let parts = [];
|
|
1374
1386
|
let usage = null;
|
|
1387
|
+
const outbound = createAgentStreamCoalescer(onEvent);
|
|
1375
1388
|
const consume = (stream, kind) => {
|
|
1376
1389
|
if (!stream) return;
|
|
1377
1390
|
const rl = createInterface({ input: stream, crlfDelay: Infinity });
|
|
1378
1391
|
rl.on("line", (line) => {
|
|
1379
1392
|
if (kind === "stderr") {
|
|
1380
|
-
|
|
1393
|
+
outbound.push({ type: "stderr", data: line });
|
|
1381
1394
|
return;
|
|
1382
1395
|
}
|
|
1383
1396
|
let events = normalizeParseResult(adapter.parseEvent(line));
|
|
@@ -1392,12 +1405,12 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1392
1405
|
for (const parsed of events) {
|
|
1393
1406
|
if (parsed.type === "session_id") {
|
|
1394
1407
|
sessionId = parsed.data;
|
|
1395
|
-
|
|
1408
|
+
outbound.push(parsed);
|
|
1396
1409
|
continue;
|
|
1397
1410
|
}
|
|
1398
1411
|
if (parsed.type === "usage") {
|
|
1399
1412
|
usage = applyTurnUsage(usage, parsed.data, parsed.scope ?? "request");
|
|
1400
|
-
|
|
1413
|
+
outbound.push(parsed);
|
|
1401
1414
|
continue;
|
|
1402
1415
|
}
|
|
1403
1416
|
if (parsed.type === "stdout") {
|
|
@@ -1410,13 +1423,14 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1410
1423
|
assistantText += parsed.data;
|
|
1411
1424
|
}
|
|
1412
1425
|
parts = applyAgentEvent(parts, parsed);
|
|
1413
|
-
|
|
1426
|
+
outbound.push(parsed);
|
|
1414
1427
|
}
|
|
1415
1428
|
});
|
|
1416
1429
|
};
|
|
1417
1430
|
consume(child.stdout, "stdout");
|
|
1418
1431
|
consume(child.stderr, "stderr");
|
|
1419
1432
|
const done = child.then((result) => {
|
|
1433
|
+
outbound.flush();
|
|
1420
1434
|
const exitCode = result.exitCode ?? null;
|
|
1421
1435
|
onEvent({ type: "exit", data: exitCode });
|
|
1422
1436
|
const finalized = finalizeParts(parts);
|
|
@@ -1569,9 +1583,10 @@ function formatArtifactDirective() {
|
|
|
1569
1583
|
"Files / media browser (CMS file manager column):",
|
|
1570
1584
|
"4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
|
|
1571
1585
|
" Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
|
|
1572
|
-
"Multiple-choice questions
|
|
1573
|
-
"5) Call Sideboard MCP `ask_user` when
|
|
1574
|
-
"
|
|
1586
|
+
"Multiple-choice questions:",
|
|
1587
|
+
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
1588
|
+
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
1589
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
1575
1590
|
].join("\n");
|
|
1576
1591
|
}
|
|
1577
1592
|
function formatUiReminder() {
|
|
@@ -1582,7 +1597,7 @@ function formatUiReminder() {
|
|
|
1582
1597
|
"CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
|
|
1583
1598
|
"Files column: MCP present_files (brightsy account storage or memory).",
|
|
1584
1599
|
"Do not say artifacts/CMS UI are unavailable.",
|
|
1585
|
-
"
|
|
1600
|
+
"ask_user: only when blocked on a real multiple-choice (approach fork, which API). Never for hellos, check-ins, or \u201Cwhat next?\u201D menus \u2014 reply in chat."
|
|
1586
1601
|
].join(" ");
|
|
1587
1602
|
}
|
|
1588
1603
|
var FILES_BY_AGENT = {
|
|
@@ -1869,7 +1884,10 @@ async function spawnWorkspaceScript(command, opts) {
|
|
|
1869
1884
|
loginEnv
|
|
1870
1885
|
);
|
|
1871
1886
|
try {
|
|
1872
|
-
|
|
1887
|
+
mergeAgentGitAuthEnv(
|
|
1888
|
+
env,
|
|
1889
|
+
await resolveAgentGitAuthEnv(env, { cwd: opts.worktreePath })
|
|
1890
|
+
);
|
|
1873
1891
|
} catch {
|
|
1874
1892
|
}
|
|
1875
1893
|
const shell = process.platform === "darwin" ? "zsh" : "bash";
|
|
@@ -3754,6 +3772,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3754
3772
|
let sourceRef = input.sourceRef;
|
|
3755
3773
|
let sourceIsFork = false;
|
|
3756
3774
|
let prUrl = null;
|
|
3775
|
+
let prTitle = null;
|
|
3757
3776
|
if (input.sourceType === "pr") {
|
|
3758
3777
|
const num = Number(input.sourceRef.replace(/^#/, ""));
|
|
3759
3778
|
if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
@@ -3769,6 +3788,12 @@ async function createThread(input, _onSetupLine) {
|
|
|
3769
3788
|
} else if (input.sourceType === "branch") {
|
|
3770
3789
|
if (!sourceRef || sourceRef === "HEAD" || sourceRef === "default") {
|
|
3771
3790
|
sourceRef = await resolveDefaultBranch(repoPath);
|
|
3791
|
+
} else {
|
|
3792
|
+
const existing = await getPrForHeadBranch(repoPath, sourceRef);
|
|
3793
|
+
if (existing?.url) {
|
|
3794
|
+
prUrl = existing.url;
|
|
3795
|
+
prTitle = existing.title;
|
|
3796
|
+
}
|
|
3772
3797
|
}
|
|
3773
3798
|
} else if (input.sourceType === "adopt") {
|
|
3774
3799
|
throw new Error("Use adoptThread() for adopt sources");
|
|
@@ -3799,14 +3824,15 @@ async function createThread(input, _onSetupLine) {
|
|
|
3799
3824
|
sourceIsFork,
|
|
3800
3825
|
parentThreadId: input.parentThreadId ?? null,
|
|
3801
3826
|
status: "idle",
|
|
3802
|
-
prUrl
|
|
3827
|
+
prUrl,
|
|
3828
|
+
prTitle
|
|
3803
3829
|
});
|
|
3804
3830
|
writeThread(thread);
|
|
3805
3831
|
await ensureWorkspace(repoPath);
|
|
3806
3832
|
return readThread(thread.id) ?? thread;
|
|
3807
3833
|
}
|
|
3808
3834
|
async function listLinearIssues(agent, repoPath) {
|
|
3809
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3835
|
+
const { getAdapter: getAdapter2 } = await import("./agents-TUV4NH7S.js");
|
|
3810
3836
|
await requireAgent(agent, { requireLinear: true });
|
|
3811
3837
|
const adapter = getAdapter2(agent);
|
|
3812
3838
|
if (!adapter.listLinearIssues) {
|
|
@@ -4272,7 +4298,7 @@ import {
|
|
|
4272
4298
|
} from "fs";
|
|
4273
4299
|
import { tmpdir } from "os";
|
|
4274
4300
|
import { join as join6 } from "path";
|
|
4275
|
-
import
|
|
4301
|
+
import { createRequire } from "module";
|
|
4276
4302
|
var CONDUCTOR_APP_SUPPORT = join6(
|
|
4277
4303
|
process.env.HOME ?? "",
|
|
4278
4304
|
"Library",
|
|
@@ -4281,6 +4307,11 @@ var CONDUCTOR_APP_SUPPORT = join6(
|
|
|
4281
4307
|
);
|
|
4282
4308
|
var CONDUCTOR_DB = join6(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
4283
4309
|
var CURSOR_SDK_STORE = join6(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
4310
|
+
function openReadonlySqlite(file) {
|
|
4311
|
+
const req = createRequire(import.meta.url);
|
|
4312
|
+
const Database = req("better-sqlite3");
|
|
4313
|
+
return new Database(file, { readonly: true, fileMustExist: true });
|
|
4314
|
+
}
|
|
4284
4315
|
function mapAgentType(raw) {
|
|
4285
4316
|
if (!raw) return null;
|
|
4286
4317
|
const v = raw.toLowerCase();
|
|
@@ -4349,7 +4380,7 @@ async function adoptThread(input) {
|
|
|
4349
4380
|
messages: input.messages ?? []
|
|
4350
4381
|
});
|
|
4351
4382
|
writeThread(thread);
|
|
4352
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4383
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ERZC7ULY.js");
|
|
4353
4384
|
await ensureWorkspace2(repoPath);
|
|
4354
4385
|
return thread;
|
|
4355
4386
|
}
|
|
@@ -4373,7 +4404,7 @@ function listConductorWorkspaces() {
|
|
|
4373
4404
|
}
|
|
4374
4405
|
}
|
|
4375
4406
|
}
|
|
4376
|
-
const db =
|
|
4407
|
+
const db = openReadonlySqlite(snapshot);
|
|
4377
4408
|
try {
|
|
4378
4409
|
const tables = db.prepare(`SELECT name FROM sqlite_master WHERE type='table'`).all();
|
|
4379
4410
|
const names = new Set(tables.map((t) => t.name));
|
|
@@ -4464,7 +4495,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
4464
4495
|
}
|
|
4465
4496
|
}
|
|
4466
4497
|
}
|
|
4467
|
-
const db =
|
|
4498
|
+
const db = openReadonlySqlite(snapshot);
|
|
4468
4499
|
try {
|
|
4469
4500
|
const row = db.prepare(
|
|
4470
4501
|
`SELECT
|
|
@@ -6354,10 +6385,12 @@ var Orchestrator = class {
|
|
|
6354
6385
|
if (event.type === "stderr" && typeof event.data === "string") {
|
|
6355
6386
|
pushTurnStderr(stderrTail, event.data);
|
|
6356
6387
|
}
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6388
|
+
if (event.type !== "stdout" && event.type !== "thinking") {
|
|
6389
|
+
const live = readThread(threadId);
|
|
6390
|
+
if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
|
|
6391
|
+
setStatus(threadId, "running");
|
|
6392
|
+
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
6393
|
+
}
|
|
6361
6394
|
}
|
|
6362
6395
|
}
|
|
6363
6396
|
);
|
|
@@ -6941,8 +6974,9 @@ var Orchestrator = class {
|
|
|
6941
6974
|
return result;
|
|
6942
6975
|
}
|
|
6943
6976
|
async mergePr(threadRef) {
|
|
6944
|
-
const { thread,
|
|
6977
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
6945
6978
|
this.assertNotGlobal(thread, "Merge PR");
|
|
6979
|
+
const selector = selectors[0];
|
|
6946
6980
|
if (!selector) throw new Error("No pull request linked to this thread");
|
|
6947
6981
|
const result = await mergePr(cwd, selector);
|
|
6948
6982
|
const state = normalizePrState(result.state) || "MERGED";
|
|
@@ -6962,29 +6996,34 @@ var Orchestrator = class {
|
|
|
6962
6996
|
await this.persistPrMetaAndMaybeArchive(thread, metaLike);
|
|
6963
6997
|
return { url: metaLike.url, state };
|
|
6964
6998
|
}
|
|
6965
|
-
/** Resolve PR
|
|
6999
|
+
/** Resolve PR selectors and optionally persist `prUrl` when found. */
|
|
6966
7000
|
async withPrSelector(threadRef) {
|
|
6967
7001
|
const thread = this.requireThread(threadRef);
|
|
6968
|
-
const
|
|
7002
|
+
const selectors = resolvePrSelectors(thread);
|
|
6969
7003
|
const cwd = thread.worktreePath;
|
|
6970
7004
|
if (!cwd?.trim()) {
|
|
6971
7005
|
throw new Error(`Thread ${threadRef} has no worktreePath`);
|
|
6972
7006
|
}
|
|
6973
|
-
return { thread,
|
|
7007
|
+
return { thread, selectors, cwd };
|
|
6974
7008
|
}
|
|
6975
7009
|
async getPrChecks(threadRef) {
|
|
6976
|
-
const {
|
|
6977
|
-
|
|
6978
|
-
|
|
7010
|
+
const { selectors, cwd } = await this.withPrSelector(threadRef);
|
|
7011
|
+
for (const selector of selectors) {
|
|
7012
|
+
const checks = await getPrChecks(cwd, selector);
|
|
7013
|
+
if (checks) return checks;
|
|
7014
|
+
}
|
|
7015
|
+
return null;
|
|
6979
7016
|
}
|
|
6980
7017
|
async getPrMeta(threadRef) {
|
|
6981
|
-
const { thread,
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
7018
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
7019
|
+
for (const selector of selectors) {
|
|
7020
|
+
const meta = await getPrMeta(cwd, selector);
|
|
7021
|
+
if (meta) {
|
|
7022
|
+
await this.persistPrMetaAndMaybeArchive(thread, meta);
|
|
7023
|
+
return meta;
|
|
7024
|
+
}
|
|
6986
7025
|
}
|
|
6987
|
-
return
|
|
7026
|
+
return null;
|
|
6988
7027
|
}
|
|
6989
7028
|
/**
|
|
6990
7029
|
* Persist PR URL/title/state and Conductor-style auto-archive when the PR
|
|
@@ -7108,9 +7147,12 @@ var Orchestrator = class {
|
|
|
7108
7147
|
return { stack: result.stack, threads: result.threads };
|
|
7109
7148
|
}
|
|
7110
7149
|
async getPrDetails(threadRef) {
|
|
7111
|
-
const { thread,
|
|
7112
|
-
|
|
7113
|
-
const
|
|
7150
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
7151
|
+
let details = null;
|
|
7152
|
+
for (const selector of selectors) {
|
|
7153
|
+
details = await getPrDetails(cwd, selector);
|
|
7154
|
+
if (details) break;
|
|
7155
|
+
}
|
|
7114
7156
|
if (details) {
|
|
7115
7157
|
const patch = {};
|
|
7116
7158
|
if (details.url && details.url !== thread.prUrl) patch.prUrl = details.url;
|
|
@@ -7295,7 +7337,7 @@ var Orchestrator = class {
|
|
|
7295
7337
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
7296
7338
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
7297
7339
|
try {
|
|
7298
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7340
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ERZC7ULY.js");
|
|
7299
7341
|
await ensureWorkspace2(thread.repoPath);
|
|
7300
7342
|
} catch {
|
|
7301
7343
|
}
|
|
@@ -7338,7 +7380,7 @@ var Orchestrator = class {
|
|
|
7338
7380
|
return restored2;
|
|
7339
7381
|
}
|
|
7340
7382
|
if (!existsSync14(thread.worktreePath)) {
|
|
7341
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7383
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-DA4BOV7G.js");
|
|
7342
7384
|
const { execa: execa5 } = await import("execa");
|
|
7343
7385
|
const slug = thread.worktreePath.split("/").pop();
|
|
7344
7386
|
const dest = thread.worktreePath;
|
|
@@ -7447,7 +7489,7 @@ async function startOrchestration(opts) {
|
|
|
7447
7489
|
sourceRef: "default",
|
|
7448
7490
|
...createOpts
|
|
7449
7491
|
}).catch(async () => {
|
|
7450
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7492
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-DA4BOV7G.js");
|
|
7451
7493
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7452
7494
|
const def = await resolveDefaultBranch2(repo);
|
|
7453
7495
|
return orch.createThread({
|
|
@@ -8198,6 +8240,14 @@ function withTimeout(promise, ms, label) {
|
|
|
8198
8240
|
}
|
|
8199
8241
|
async function startMcpServer() {
|
|
8200
8242
|
const orch = getOrchestrator();
|
|
8243
|
+
try {
|
|
8244
|
+
await warmGithubAgentAuth();
|
|
8245
|
+
} catch (err) {
|
|
8246
|
+
console.error(
|
|
8247
|
+
"[sideboard-mcp] GitHub agent auth warm skipped:",
|
|
8248
|
+
err instanceof Error ? err.message : err
|
|
8249
|
+
);
|
|
8250
|
+
}
|
|
8201
8251
|
try {
|
|
8202
8252
|
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-BRF7VKTQ.js");
|
|
8203
8253
|
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
@@ -8304,7 +8354,7 @@ async function startMcpServer() {
|
|
|
8304
8354
|
);
|
|
8305
8355
|
server.tool(
|
|
8306
8356
|
"ask_user",
|
|
8307
|
-
"Ask the user clarifying multiple-choice
|
|
8357
|
+
"Ask the user a clarifying multiple-choice question in Sideboard\u2019s composer. Call only when work is blocked on choosing among a few concrete options (approach fork, which API, auth vs cookies). Do not call for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat instead. If one option is the obvious default, proceed without asking. Before calling, write a short chat message explaining the decision and what each option means. Include a description on every option. After calling, stop and wait for answers. Not for \u201Cis the plan ready?\u201D.",
|
|
8308
8358
|
{
|
|
8309
8359
|
questions: z3.array(
|
|
8310
8360
|
z3.object({
|
|
@@ -9533,6 +9583,74 @@ async function runCloudConnect(opts) {
|
|
|
9533
9583
|
}
|
|
9534
9584
|
}
|
|
9535
9585
|
|
|
9586
|
+
// src/agents/user-mcp-config.ts
|
|
9587
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
|
|
9588
|
+
import { homedir as homedir2 } from "os";
|
|
9589
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
9590
|
+
function userCursorMcpConfigPath() {
|
|
9591
|
+
return join13(homedir2(), ".cursor", "mcp.json");
|
|
9592
|
+
}
|
|
9593
|
+
function userClaudeMcpConfigPath() {
|
|
9594
|
+
return join13(homedir2(), ".claude.json");
|
|
9595
|
+
}
|
|
9596
|
+
function asObject(value) {
|
|
9597
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
9598
|
+
return { ...value };
|
|
9599
|
+
}
|
|
9600
|
+
function stripElectronSpawnEnv(env) {
|
|
9601
|
+
if (!env) return void 0;
|
|
9602
|
+
const next = { ...env };
|
|
9603
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
9604
|
+
delete next.ELECTRON_RUN_AS_NODE;
|
|
9605
|
+
return Object.keys(next).length > 0 ? next : void 0;
|
|
9606
|
+
}
|
|
9607
|
+
function mergeSideboardIntoMcpServersJson(existing, sideboard) {
|
|
9608
|
+
const root = asObject(existing);
|
|
9609
|
+
const servers = asObject(root.mcpServers);
|
|
9610
|
+
const env = stripElectronSpawnEnv(sideboard.env);
|
|
9611
|
+
servers.sideboard = {
|
|
9612
|
+
command: sideboard.command,
|
|
9613
|
+
...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
|
|
9614
|
+
...env ? { env } : {}
|
|
9615
|
+
};
|
|
9616
|
+
return { ...root, mcpServers: servers };
|
|
9617
|
+
}
|
|
9618
|
+
function writeMergedMcpServersJson(configPath, sideboard) {
|
|
9619
|
+
let existing = {};
|
|
9620
|
+
if (existsSync15(configPath)) {
|
|
9621
|
+
try {
|
|
9622
|
+
existing = JSON.parse(readFileSync10(configPath, "utf8"));
|
|
9623
|
+
} catch {
|
|
9624
|
+
existing = {};
|
|
9625
|
+
}
|
|
9626
|
+
}
|
|
9627
|
+
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
9628
|
+
mkdirSync5(dirname4(configPath), { recursive: true });
|
|
9629
|
+
writeFileSync4(configPath, `${JSON.stringify(next, null, 2)}
|
|
9630
|
+
`);
|
|
9631
|
+
}
|
|
9632
|
+
function launchFromResolved(server) {
|
|
9633
|
+
return {
|
|
9634
|
+
command: server.command,
|
|
9635
|
+
args: server.args,
|
|
9636
|
+
env: {
|
|
9637
|
+
...server.env ?? {},
|
|
9638
|
+
SIDEBOARD_APP_DATA: appDataDir()
|
|
9639
|
+
}
|
|
9640
|
+
};
|
|
9641
|
+
}
|
|
9642
|
+
async function registerPackagedUserMcpClients() {
|
|
9643
|
+
const launch = launchFromResolved(await resolveSideboardMcpServer());
|
|
9644
|
+
const cursor = userCursorMcpConfigPath();
|
|
9645
|
+
writeMergedMcpServersJson(cursor, launch);
|
|
9646
|
+
const claude = userClaudeMcpConfigPath();
|
|
9647
|
+
if (existsSync15(claude)) {
|
|
9648
|
+
writeMergedMcpServersJson(claude, launch);
|
|
9649
|
+
return { cursor, claude };
|
|
9650
|
+
}
|
|
9651
|
+
return { cursor };
|
|
9652
|
+
}
|
|
9653
|
+
|
|
9536
9654
|
// src/slack/oauth.ts
|
|
9537
9655
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
9538
9656
|
|
|
@@ -11231,6 +11349,7 @@ export {
|
|
|
11231
11349
|
cleanupOrphanWorktrees,
|
|
11232
11350
|
cloneRepoIntoSideboard,
|
|
11233
11351
|
codexAdapter,
|
|
11352
|
+
codexSandboxWritableRootsArgs,
|
|
11234
11353
|
codexUnattendedGitConfigArgs,
|
|
11235
11354
|
coerceOrchestratorAgent,
|
|
11236
11355
|
collectTakenTeamSlugs,
|
|
@@ -11347,6 +11466,7 @@ export {
|
|
|
11347
11466
|
getPr,
|
|
11348
11467
|
getPrChecks,
|
|
11349
11468
|
getPrDetails,
|
|
11469
|
+
getPrForHeadBranch,
|
|
11350
11470
|
getPrMeta,
|
|
11351
11471
|
getPrStack,
|
|
11352
11472
|
getRepoSetupInfo,
|
|
@@ -11383,6 +11503,7 @@ export {
|
|
|
11383
11503
|
isCloudCoordinatorThread,
|
|
11384
11504
|
isConductorBundledCli,
|
|
11385
11505
|
isCursorAutoModel,
|
|
11506
|
+
isDefaultishSourceRef,
|
|
11386
11507
|
isDirty,
|
|
11387
11508
|
isGhRateLimitError,
|
|
11388
11509
|
isGlobalRepoPath,
|
|
@@ -11449,8 +11570,10 @@ export {
|
|
|
11449
11570
|
maybeCompactContext,
|
|
11450
11571
|
mcpAllowTools,
|
|
11451
11572
|
mcpAuthWarnings,
|
|
11573
|
+
mergeAgentGitAuthEnv,
|
|
11452
11574
|
mergePr,
|
|
11453
11575
|
mergePrStack,
|
|
11576
|
+
mergeSideboardIntoMcpServersJson,
|
|
11454
11577
|
mergeUsage,
|
|
11455
11578
|
nextPastedTextName,
|
|
11456
11579
|
nextThinkingEffort,
|
|
@@ -11501,6 +11624,7 @@ export {
|
|
|
11501
11624
|
recordSlackOutboundWatch,
|
|
11502
11625
|
refreshGitHubAuth,
|
|
11503
11626
|
refreshSlackReplyBadges,
|
|
11627
|
+
registerPackagedUserMcpClients,
|
|
11504
11628
|
releaseCaffeinateHoldForThread,
|
|
11505
11629
|
removeWorkspace,
|
|
11506
11630
|
removeWorktree,
|
|
@@ -11509,9 +11633,11 @@ export {
|
|
|
11509
11633
|
requestReview,
|
|
11510
11634
|
requireAgent,
|
|
11511
11635
|
resetGhStackDetectCache,
|
|
11636
|
+
resetGithubAgentTokenMemo,
|
|
11512
11637
|
resolveAgentExecutable,
|
|
11513
11638
|
resolveAgentGitAuthEnv,
|
|
11514
11639
|
resolveClaudeExecutable,
|
|
11640
|
+
resolveCodexGitWritableRoots,
|
|
11515
11641
|
resolveCommandBinarySync,
|
|
11516
11642
|
resolveConductorCursorAgentId,
|
|
11517
11643
|
resolveCursorModelId,
|
|
@@ -11528,6 +11654,7 @@ export {
|
|
|
11528
11654
|
resolveNewThreadOptions,
|
|
11529
11655
|
resolvePlanMarkdown,
|
|
11530
11656
|
resolvePrSelector,
|
|
11657
|
+
resolvePrSelectors,
|
|
11531
11658
|
resolveQuotaFallbackAgent,
|
|
11532
11659
|
resolveRepoRoot,
|
|
11533
11660
|
resolveReviewGuidelines,
|
|
@@ -11550,6 +11677,7 @@ export {
|
|
|
11550
11677
|
sanitizeMcpServerName,
|
|
11551
11678
|
saveAppSettings,
|
|
11552
11679
|
saveLinearOAuth,
|
|
11680
|
+
scrubGithubTokensFromChildEnv,
|
|
11553
11681
|
secureFileUnlocksWith,
|
|
11554
11682
|
setCaffeinateHold,
|
|
11555
11683
|
setHttpFetchImpl,
|
|
@@ -11620,7 +11748,10 @@ export {
|
|
|
11620
11748
|
updateLinearIssue,
|
|
11621
11749
|
updateOpencodeSettings,
|
|
11622
11750
|
updateThread,
|
|
11751
|
+
userClaudeMcpConfigPath,
|
|
11752
|
+
userCursorMcpConfigPath,
|
|
11623
11753
|
validateLinearApiKey,
|
|
11754
|
+
warmGithubAgentAuth,
|
|
11624
11755
|
withAgentInstructions,
|
|
11625
11756
|
withExportedPath,
|
|
11626
11757
|
withThreadLock,
|