@sideboard-ai/core 0.1.56 → 0.1.59
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-2YYWW723.js → agents-B2723EOF.js} +4 -4
- package/dist/{agents-AQFEFKBL.js → agents-EADRAAPG.js} +4 -4
- package/dist/{app-settings-2LQNRTBE.js → app-settings-TBHTJWLQ.js} +1 -1
- package/dist/{app-settings-73DI4B6T.js → app-settings-YBNZ4XSR.js} +1 -1
- package/dist/{chunk-5DMYULLC.js → chunk-2P2UK7E7.js} +2 -2
- package/dist/{chunk-7LNGIP3X.js → chunk-73AT5K4A.js} +15 -3
- package/dist/{chunk-DIOF73S2.js → chunk-75QR74KM.js} +7 -2
- package/dist/{chunk-EBWEKG52.js → chunk-CHGOMFTA.js} +3 -3
- package/dist/{chunk-C4BCC5X5.js → chunk-FGNBTFRD.js} +7 -2
- package/dist/{chunk-H6GGDLYS.js → chunk-JB2H7E7V.js} +1 -1
- package/dist/{chunk-BXJ76RHF.js → chunk-MBAL5FE6.js} +4 -4
- package/dist/{chunk-XOU6HNQJ.js → chunk-MFGGIRUA.js} +39 -13
- package/dist/{chunk-S42XDFKF.js → chunk-MLAST5BB.js} +3 -3
- package/dist/{chunk-C3J4GDW4.js → chunk-MX7UH5AT.js} +76 -60
- package/dist/{chunk-DQJ5D42H.js → chunk-NTYRBRE7.js} +44 -13
- package/dist/{chunk-DZFH2KLT.js → chunk-P7EQUFB6.js} +39 -13
- package/dist/{chunk-V2DUTUNC.js → chunk-QJBC4BRK.js} +2 -2
- package/dist/{chunk-ZNM4MAN4.js → chunk-RIWUU7FO.js} +15 -3
- package/dist/{chunk-UA5NDAHL.js → chunk-XWPKLRB3.js} +44 -13
- package/dist/{chunk-7F454EE2.js → chunk-ZXDOI6IH.js} +76 -53
- package/dist/{connected-teams-ONC4666A.js → connected-teams-MKIYKOYA.js} +2 -2
- package/dist/{connected-teams-2ANNZCP5.js → connected-teams-RSL4VB3X.js} +2 -2
- package/dist/{coordinator-prompt-RBKUNRPR.js → coordinator-prompt-4P23VVFC.js} +4 -4
- package/dist/{coordinator-prompt-ICF36NUQ.js → coordinator-prompt-LNWHZ64D.js} +4 -4
- package/dist/{global-workspace-667XLBW6.js → global-workspace-BHT4XUAA.js} +5 -5
- package/dist/{global-workspace-S7VLWPWG.js → global-workspace-TMMAVRVW.js} +5 -5
- package/dist/index.cjs +342 -119
- package/dist/index.d.cts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +195 -67
- package/dist/mcp/run-stdio.cjs +342 -130
- package/dist/mcp/run-stdio.js +194 -71
- package/dist/{run-ZJKYHXGN.js → run-GPSVV5OH.js} +1 -1
- package/dist/{run-H3IMNOYN.js → run-HZTBWGQR.js} +1 -1
- package/dist/{workspaces-FPJJXXAE.js → workspaces-3GO3EDQG.js} +6 -6
- package/dist/{workspaces-LYIDE2VR.js → workspaces-GFPGDGCS.js} +6 -6
- package/dist/{worktree-5KEQWSAF.js → worktree-3L2G6PCM.js} +2 -2
- package/dist/{worktree-RWGL7FUV.js → worktree-GBLHEFHR.js} +2 -2
- 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-2P2UK7E7.js";
|
|
8
8
|
import {
|
|
9
9
|
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
10
10
|
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
orchestratorSessionPoisonedByBuiltins,
|
|
25
25
|
parseForceStopMessage,
|
|
26
26
|
takenTeamSlugsForOrchestration
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-MLAST5BB.js";
|
|
28
28
|
import {
|
|
29
29
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
30
30
|
CLAUDE_MODEL_CATALOG,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
resolveQuotaFallbackAgent,
|
|
71
71
|
sanitizeMcpServerName,
|
|
72
72
|
writeInjectedMcpConfig
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-ZXDOI6IH.js";
|
|
74
74
|
import {
|
|
75
75
|
ORCHESTRATOR_AGENT_KINDS,
|
|
76
76
|
assertOrchestratorCapableAgent,
|
|
@@ -88,7 +88,7 @@ import {
|
|
|
88
88
|
loadBrightsyConfig,
|
|
89
89
|
saveBrightsyConfig,
|
|
90
90
|
switchBrightsyAccount
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-MBAL5FE6.js";
|
|
92
92
|
import {
|
|
93
93
|
LEGACY_PLAN_FILE_REL,
|
|
94
94
|
PLAN_FILE_NAME,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
enrichWorkspacesWithGithub,
|
|
119
119
|
ensureGlobalCoordinatorCwd,
|
|
120
120
|
formatWorkspaceInventory
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-XWPKLRB3.js";
|
|
122
122
|
import {
|
|
123
123
|
HARNESS_ENV_KEYS,
|
|
124
124
|
appSettingsPath,
|
|
@@ -157,7 +157,7 @@ import {
|
|
|
157
157
|
updateClaudeSettings,
|
|
158
158
|
updateDefaultsSettings,
|
|
159
159
|
updateIntegrationsSettings
|
|
160
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-75QR74KM.js";
|
|
161
161
|
import {
|
|
162
162
|
FAMOUS_SOCCER_TEAMS,
|
|
163
163
|
addPrStackLayer,
|
|
@@ -220,7 +220,7 @@ import {
|
|
|
220
220
|
worktreeDisplayLabel,
|
|
221
221
|
worktreeDisplayLabelForGroup,
|
|
222
222
|
worktreeNameFromPath
|
|
223
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-P7EQUFB6.js";
|
|
224
224
|
import {
|
|
225
225
|
ATTACHMENTS_DIR,
|
|
226
226
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -277,7 +277,7 @@ import {
|
|
|
277
277
|
git,
|
|
278
278
|
resolveGhAuthToken,
|
|
279
279
|
run
|
|
280
|
-
} from "./chunk-
|
|
280
|
+
} from "./chunk-73AT5K4A.js";
|
|
281
281
|
|
|
282
282
|
// src/integrations/github.ts
|
|
283
283
|
async function getGitHubStatus() {
|
|
@@ -706,10 +706,12 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
706
706
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
707
707
|
);
|
|
708
708
|
}
|
|
709
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
709
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-TMMAVRVW.js");
|
|
710
710
|
if (isGlobalThread2(thread)) {
|
|
711
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
712
|
-
ensureGlobalCoordinatorCwd2(
|
|
711
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-LNWHZ64D.js");
|
|
712
|
+
ensureGlobalCoordinatorCwd2(
|
|
713
|
+
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
714
|
+
);
|
|
713
715
|
}
|
|
714
716
|
if (isOrchestratorThread(thread)) {
|
|
715
717
|
assertOrchestratorCapableAgent(thread.agent);
|
|
@@ -995,9 +997,21 @@ async function detectAgents() {
|
|
|
995
997
|
ensureAgentPath();
|
|
996
998
|
return Promise.all(allAdapters().map((a) => a.detect()));
|
|
997
999
|
}
|
|
1000
|
+
var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
|
|
998
1001
|
async function requireAgent(agent, opts) {
|
|
999
|
-
|
|
1000
|
-
|
|
1002
|
+
ensureAgentPath();
|
|
1003
|
+
const status = await Promise.race([
|
|
1004
|
+
getAdapter(agent).detect(),
|
|
1005
|
+
new Promise((_, reject) => {
|
|
1006
|
+
setTimeout(() => {
|
|
1007
|
+
reject(
|
|
1008
|
+
new Error(
|
|
1009
|
+
`${agent} detect timed out after ${REQUIRE_AGENT_TIMEOUT_MS / 1e3}s`
|
|
1010
|
+
)
|
|
1011
|
+
);
|
|
1012
|
+
}, REQUIRE_AGENT_TIMEOUT_MS);
|
|
1013
|
+
})
|
|
1014
|
+
]);
|
|
1001
1015
|
if (!status.installed || !status.authenticated) {
|
|
1002
1016
|
throw new Error(status.reason ?? `${agent} is not available`);
|
|
1003
1017
|
}
|
|
@@ -2827,7 +2841,7 @@ async function previewLand(thread) {
|
|
|
2827
2841
|
const target = await resolveDefaultBranch(thread.repoPath);
|
|
2828
2842
|
if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
|
|
2829
2843
|
}
|
|
2830
|
-
const { stdout: head } = await import("./run-
|
|
2844
|
+
const { stdout: head } = await import("./run-GPSVV5OH.js").then(
|
|
2831
2845
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
|
|
2832
2846
|
);
|
|
2833
2847
|
const current = head.trim();
|
|
@@ -2866,7 +2880,7 @@ async function confirmLand(thread, opts) {
|
|
|
2866
2880
|
if (preview.dirty) {
|
|
2867
2881
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
2868
2882
|
}
|
|
2869
|
-
const { git: git2 } = await import("./run-
|
|
2883
|
+
const { git: git2 } = await import("./run-GPSVV5OH.js");
|
|
2870
2884
|
const { stdout: headOut } = await git2(
|
|
2871
2885
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
2872
2886
|
thread.worktreePath,
|
|
@@ -2964,7 +2978,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2964
2978
|
return readThread(thread.id) ?? thread;
|
|
2965
2979
|
}
|
|
2966
2980
|
async function listLinearIssues(agent, repoPath) {
|
|
2967
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2981
|
+
const { getAdapter: getAdapter2 } = await import("./agents-B2723EOF.js");
|
|
2968
2982
|
await requireAgent(agent, { requireLinear: true });
|
|
2969
2983
|
const adapter = getAdapter2(agent);
|
|
2970
2984
|
if (!adapter.listLinearIssues) {
|
|
@@ -3490,7 +3504,7 @@ async function adoptThread(input) {
|
|
|
3490
3504
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3491
3505
|
}
|
|
3492
3506
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
3493
|
-
const { stdout: branch } = await import("./run-
|
|
3507
|
+
const { stdout: branch } = await import("./run-GPSVV5OH.js").then(
|
|
3494
3508
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
3495
3509
|
);
|
|
3496
3510
|
const thread = createEmptyThread({
|
|
@@ -3505,7 +3519,7 @@ async function adoptThread(input) {
|
|
|
3505
3519
|
messages: input.messages ?? []
|
|
3506
3520
|
});
|
|
3507
3521
|
writeThread(thread);
|
|
3508
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3522
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-3GO3EDQG.js");
|
|
3509
3523
|
await ensureWorkspace2(repoPath);
|
|
3510
3524
|
return thread;
|
|
3511
3525
|
}
|
|
@@ -4066,7 +4080,7 @@ var REPO_REVIEW_NAME = "review.md";
|
|
|
4066
4080
|
var REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
|
|
4067
4081
|
var LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
|
|
4068
4082
|
var REVIEW_REQUEST_NAME = "Review request.md";
|
|
4069
|
-
var REVIEW_REQUEST_PREFILL = "Review.";
|
|
4083
|
+
var REVIEW_REQUEST_PREFILL = "Review changes in this workspace.";
|
|
4070
4084
|
var LEGACY_REVIEW_TEMPLATE_MARKERS = [
|
|
4071
4085
|
"You are acting as a reviewer for a proposed code change made by another engineer.",
|
|
4072
4086
|
"HOW MANY FINDINGS TO RETURN:"
|
|
@@ -4401,6 +4415,7 @@ var Orchestrator = class {
|
|
|
4401
4415
|
}
|
|
4402
4416
|
async reconcile(repoPath, opts) {
|
|
4403
4417
|
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
4418
|
+
const drainQueues = opts?.drainQueues !== false;
|
|
4404
4419
|
healOrchestrationSoccerTitles();
|
|
4405
4420
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
4406
4421
|
if (thread.status === "archived") continue;
|
|
@@ -4441,18 +4456,42 @@ var Orchestrator = class {
|
|
|
4441
4456
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
4442
4457
|
});
|
|
4443
4458
|
}
|
|
4444
|
-
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-
|
|
4459
|
+
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
4445
4460
|
if (autoCleanupOrphansEnabled2() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
4446
4461
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
4447
4462
|
}
|
|
4448
4463
|
} catch {
|
|
4449
4464
|
}
|
|
4465
|
+
if (drainQueues) {
|
|
4466
|
+
this.adoptPersistedQueues();
|
|
4467
|
+
}
|
|
4468
|
+
this.schedulePendingQuotaResumes();
|
|
4469
|
+
}
|
|
4470
|
+
/**
|
|
4471
|
+
* Adopt queues persisted by another process (MCP stdio / CLI) into this
|
|
4472
|
+
* orchestrator's drain loops. Desktop calls this on thread-store changes so
|
|
4473
|
+
* MCP-created review threads don't stay `queued` after the MCP child exits.
|
|
4474
|
+
*/
|
|
4475
|
+
adoptPersistedQueues() {
|
|
4450
4476
|
for (const thread of listThreads()) {
|
|
4451
|
-
if (thread.
|
|
4477
|
+
if (thread.status === "stopped" || thread.status === "archived") continue;
|
|
4478
|
+
const pid = thread.agentPid;
|
|
4479
|
+
const deadPid = typeof pid === "number" && pid > 0 && !isPidAlive(pid) ? true : false;
|
|
4480
|
+
if (deadPid) {
|
|
4481
|
+
updateThread(thread.id, { agentPid: null });
|
|
4482
|
+
}
|
|
4483
|
+
if (thread.status === "queued" && thread.queue.length === 0) {
|
|
4484
|
+
if (!this.activeTurns.has(thread.id) && !this.startingTurns.has(thread.id)) {
|
|
4485
|
+
setStatus(thread.id, "idle");
|
|
4486
|
+
this.emit({ type: "status_changed", threadId: thread.id, status: "idle" });
|
|
4487
|
+
}
|
|
4488
|
+
continue;
|
|
4489
|
+
}
|
|
4490
|
+
if (thread.queue.length > 0) {
|
|
4491
|
+
this.haltDrain.delete(thread.id);
|
|
4452
4492
|
void this.drainQueue(thread.id);
|
|
4453
4493
|
}
|
|
4454
4494
|
}
|
|
4455
|
-
this.schedulePendingQuotaResumes();
|
|
4456
4495
|
}
|
|
4457
4496
|
clearQuotaResumeTimer(threadId) {
|
|
4458
4497
|
const timer = this.quotaResumeTimers.get(threadId);
|
|
@@ -4574,7 +4613,7 @@ var Orchestrator = class {
|
|
|
4574
4613
|
}
|
|
4575
4614
|
async finishCreateThread(threadId, prompt) {
|
|
4576
4615
|
await this.runSetupAfterCreate(threadId);
|
|
4577
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-
|
|
4616
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
4578
4617
|
if (autoRunAfterSetupEnabled2()) {
|
|
4579
4618
|
try {
|
|
4580
4619
|
await this.startDev(threadId);
|
|
@@ -4634,7 +4673,12 @@ var Orchestrator = class {
|
|
|
4634
4673
|
const current = this.requireThread(thread.id);
|
|
4635
4674
|
const queue = [...current.queue, prompt];
|
|
4636
4675
|
this.haltDrain.delete(thread.id);
|
|
4637
|
-
|
|
4676
|
+
const patch = { queue, status: "queued" };
|
|
4677
|
+
const pid = current.agentPid;
|
|
4678
|
+
if (typeof pid === "number" && pid > 0 && !isPidAlive(pid)) {
|
|
4679
|
+
patch.agentPid = null;
|
|
4680
|
+
}
|
|
4681
|
+
updateThread(thread.id, patch);
|
|
4638
4682
|
this.emit({ type: "queue_changed", threadId: thread.id, queue });
|
|
4639
4683
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
4640
4684
|
void this.drainQueue(thread.id);
|
|
@@ -4840,7 +4884,7 @@ var Orchestrator = class {
|
|
|
4840
4884
|
});
|
|
4841
4885
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
4842
4886
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
4843
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-
|
|
4887
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
4844
4888
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
|
|
4845
4889
|
customPrompt: settings?.prompts?.renameBranch
|
|
4846
4890
|
}) : null;
|
|
@@ -4852,7 +4896,9 @@ var Orchestrator = class {
|
|
|
4852
4896
|
}
|
|
4853
4897
|
let coordinatorDirective = null;
|
|
4854
4898
|
if (isOrchestration) {
|
|
4855
|
-
if (isGlobalThread(fresh))
|
|
4899
|
+
if (isGlobalThread(fresh)) {
|
|
4900
|
+
ensureGlobalCoordinatorCwd({ orchestratorThreadId: fresh.id });
|
|
4901
|
+
}
|
|
4856
4902
|
if (!fresh.sessionId) {
|
|
4857
4903
|
const inventory = await enrichWorkspacesWithGithub(this.listWorkspaces());
|
|
4858
4904
|
coordinatorDirective = coordinatorSystemPrompt({
|
|
@@ -5709,7 +5755,7 @@ var Orchestrator = class {
|
|
|
5709
5755
|
const archived = setStatus(thread.id, "archived");
|
|
5710
5756
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
5711
5757
|
try {
|
|
5712
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
5758
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-3GO3EDQG.js");
|
|
5713
5759
|
await ensureWorkspace2(thread.repoPath);
|
|
5714
5760
|
} catch {
|
|
5715
5761
|
}
|
|
@@ -5730,7 +5776,7 @@ var Orchestrator = class {
|
|
|
5730
5776
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
5731
5777
|
} catch {
|
|
5732
5778
|
}
|
|
5733
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-
|
|
5779
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
5734
5780
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
5735
5781
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
5736
5782
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -5749,7 +5795,7 @@ var Orchestrator = class {
|
|
|
5749
5795
|
return setStatus(thread.id, "idle");
|
|
5750
5796
|
}
|
|
5751
5797
|
if (!existsSync13(thread.worktreePath)) {
|
|
5752
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
5798
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-GBLHEFHR.js");
|
|
5753
5799
|
const { execa: execa6 } = await import("execa");
|
|
5754
5800
|
const slug = thread.worktreePath.split("/").pop();
|
|
5755
5801
|
const dest = thread.worktreePath;
|
|
@@ -5834,7 +5880,7 @@ async function startOrchestration(opts) {
|
|
|
5834
5880
|
sourceRef: "default",
|
|
5835
5881
|
...createOpts
|
|
5836
5882
|
}).catch(async () => {
|
|
5837
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
5883
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-GBLHEFHR.js");
|
|
5838
5884
|
const repo = await resolveRepoRoot2(repoPath);
|
|
5839
5885
|
const def = await resolveDefaultBranch2(repo);
|
|
5840
5886
|
return createThread({
|
|
@@ -5969,9 +6015,39 @@ function mcpArchiveBlockedReason(thread) {
|
|
|
5969
6015
|
|
|
5970
6016
|
// src/mcp/server.ts
|
|
5971
6017
|
var MAX_ORCH_THREADS = 5;
|
|
6018
|
+
var CREATE_THREAD_TIMEOUT_MS = 9e4;
|
|
6019
|
+
function withTimeout(promise, ms, label) {
|
|
6020
|
+
return new Promise((resolve, reject) => {
|
|
6021
|
+
const timer = setTimeout(() => {
|
|
6022
|
+
reject(new Error(`${label} timed out after ${Math.round(ms / 1e3)}s`));
|
|
6023
|
+
}, ms);
|
|
6024
|
+
promise.then(
|
|
6025
|
+
(value) => {
|
|
6026
|
+
clearTimeout(timer);
|
|
6027
|
+
resolve(value);
|
|
6028
|
+
},
|
|
6029
|
+
(err) => {
|
|
6030
|
+
clearTimeout(timer);
|
|
6031
|
+
reject(err);
|
|
6032
|
+
}
|
|
6033
|
+
);
|
|
6034
|
+
});
|
|
6035
|
+
}
|
|
5972
6036
|
async function startMcpServer() {
|
|
5973
6037
|
const orch = getOrchestrator();
|
|
5974
|
-
|
|
6038
|
+
try {
|
|
6039
|
+
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
6040
|
+
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
6041
|
+
} catch {
|
|
6042
|
+
}
|
|
6043
|
+
try {
|
|
6044
|
+
await orch.reconcile(void 0, { reclaimStaleTurns: false, drainQueues: false });
|
|
6045
|
+
} catch (err) {
|
|
6046
|
+
console.error(
|
|
6047
|
+
"[sideboard-mcp] reconcile on boot failed (continuing):",
|
|
6048
|
+
err instanceof Error ? err.message : err
|
|
6049
|
+
);
|
|
6050
|
+
}
|
|
5975
6051
|
const server = new McpServer({
|
|
5976
6052
|
name: "sideboard",
|
|
5977
6053
|
version: "0.1.0"
|
|
@@ -6171,12 +6247,12 @@ async function startMcpServer() {
|
|
|
6171
6247
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
6172
6248
|
}
|
|
6173
6249
|
);
|
|
6174
|
-
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-
|
|
6250
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-TBHTJWLQ.js");
|
|
6175
6251
|
const accountDefaults = resolveThreadDefaults2();
|
|
6176
6252
|
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
6177
6253
|
server.tool(
|
|
6178
6254
|
"create_thread",
|
|
6179
|
-
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces
|
|
6255
|
+
`Create a new worktree thread (chat) from branch, pr, or ticket. Pass repoPath from list_workspaces. From an orchestration chat, omit parentThreadId (Sideboard binds the child to this chat) or pass the exact id from the turn reminder \u2014 never invent a uuid. Prefer omitting agent/model so Sideboard applies ${accountDefaultsHint}. Then use send_to_thread to chat.`,
|
|
6180
6256
|
{
|
|
6181
6257
|
sourceType: z.enum(["branch", "pr", "ticket"]),
|
|
6182
6258
|
sourceRef: z.string(),
|
|
@@ -6186,11 +6262,31 @@ async function startMcpServer() {
|
|
|
6186
6262
|
),
|
|
6187
6263
|
repoPath: z.string(),
|
|
6188
6264
|
title: z.string().optional(),
|
|
6189
|
-
parentThreadId: z.string().optional()
|
|
6265
|
+
parentThreadId: z.string().optional().describe(
|
|
6266
|
+
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
6267
|
+
)
|
|
6190
6268
|
},
|
|
6191
6269
|
async (args) => {
|
|
6192
|
-
|
|
6193
|
-
|
|
6270
|
+
const envParentId = process.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || "";
|
|
6271
|
+
let parentId = args.parentThreadId?.trim() || "";
|
|
6272
|
+
let parent = parentId ? orch.getThread(parentId) : null;
|
|
6273
|
+
let parentCorrectedFrom;
|
|
6274
|
+
if (envParentId) {
|
|
6275
|
+
const envParent = orch.getThread(envParentId);
|
|
6276
|
+
if (envParent) {
|
|
6277
|
+
if (parentId && parentId !== envParentId) parentCorrectedFrom = parentId;
|
|
6278
|
+
else if (!parentId) parentCorrectedFrom = void 0;
|
|
6279
|
+
parentId = envParentId;
|
|
6280
|
+
parent = envParent;
|
|
6281
|
+
}
|
|
6282
|
+
}
|
|
6283
|
+
if (parentId && !parent) {
|
|
6284
|
+
parentCorrectedFrom = parentId;
|
|
6285
|
+
parentId = "";
|
|
6286
|
+
parent = null;
|
|
6287
|
+
}
|
|
6288
|
+
if (parentId) {
|
|
6289
|
+
const children = orch.getThreads(true).filter((t) => t.parentThreadId === parentId);
|
|
6194
6290
|
if (children.length >= MAX_ORCH_THREADS) {
|
|
6195
6291
|
return {
|
|
6196
6292
|
content: [
|
|
@@ -6203,38 +6299,70 @@ async function startMcpServer() {
|
|
|
6203
6299
|
};
|
|
6204
6300
|
}
|
|
6205
6301
|
}
|
|
6302
|
+
let agentArg = args.agent;
|
|
6303
|
+
let agentCoercedFrom;
|
|
6304
|
+
const resolvedProbe = resolveNewThreadOptions2({ agent: agentArg }).agent;
|
|
6305
|
+
if (resolvedProbe === "codex") {
|
|
6306
|
+
agentCoercedFrom = agentArg ?? "codex";
|
|
6307
|
+
const accountAgent = resolveNewThreadOptions2({}).agent;
|
|
6308
|
+
agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
|
|
6309
|
+
}
|
|
6206
6310
|
const opts = resolveNewThreadOptions2({
|
|
6207
|
-
agent:
|
|
6311
|
+
agent: agentArg,
|
|
6208
6312
|
model: args.model
|
|
6209
6313
|
});
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6314
|
+
try {
|
|
6315
|
+
const thread = await withTimeout(
|
|
6316
|
+
orch.createThread({
|
|
6317
|
+
sourceType: args.sourceType,
|
|
6318
|
+
sourceRef: args.sourceRef,
|
|
6319
|
+
agent: opts.agent,
|
|
6320
|
+
model: opts.model,
|
|
6321
|
+
effort: opts.effort,
|
|
6322
|
+
fast: opts.fast,
|
|
6323
|
+
repoPath: args.repoPath,
|
|
6324
|
+
title: args.title,
|
|
6325
|
+
parentThreadId: parentId || null
|
|
6326
|
+
}),
|
|
6327
|
+
CREATE_THREAD_TIMEOUT_MS,
|
|
6328
|
+
"create_thread"
|
|
6329
|
+
);
|
|
6330
|
+
const parentNote = parentCorrectedFrom ? parentId ? `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; nested under ${parentId}` : `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; created without parent` : void 0;
|
|
6331
|
+
return {
|
|
6332
|
+
content: [
|
|
6333
|
+
{
|
|
6334
|
+
type: "text",
|
|
6335
|
+
text: JSON.stringify({
|
|
6336
|
+
id: thread.id,
|
|
6337
|
+
title: thread.title,
|
|
6338
|
+
branchName: thread.branchName,
|
|
6339
|
+
worktreePath: thread.worktreePath,
|
|
6340
|
+
agent: thread.agent,
|
|
6341
|
+
model: thread.model,
|
|
6342
|
+
status: thread.status,
|
|
6343
|
+
link: `sideboard://thread/${thread.id}`,
|
|
6344
|
+
parentThreadId: thread.parentThreadId,
|
|
6345
|
+
...agentCoercedFrom ? {
|
|
6346
|
+
agentCoercedFrom,
|
|
6347
|
+
note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
|
|
6348
|
+
} : {},
|
|
6349
|
+
...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
|
|
6350
|
+
})
|
|
6351
|
+
}
|
|
6352
|
+
]
|
|
6353
|
+
};
|
|
6354
|
+
} catch (err) {
|
|
6355
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6356
|
+
return {
|
|
6357
|
+
content: [
|
|
6358
|
+
{
|
|
6359
|
+
type: "text",
|
|
6360
|
+
text: `create_thread failed: ${message}`
|
|
6361
|
+
}
|
|
6362
|
+
],
|
|
6363
|
+
isError: true
|
|
6364
|
+
};
|
|
6365
|
+
}
|
|
6238
6366
|
}
|
|
6239
6367
|
);
|
|
6240
6368
|
server.tool(
|
|
@@ -6415,7 +6543,7 @@ async function startMcpServer() {
|
|
|
6415
6543
|
);
|
|
6416
6544
|
server.tool(
|
|
6417
6545
|
"request_review",
|
|
6418
|
-
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .sideboard/review.md when present (else local Review request.md / stock template), and sends "Review." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn / get_turn_result on the returned review tab id.',
|
|
6546
|
+
'Start a merge-readiness Review on a worktree agent thread (same as the desktop Review button). Opens a new Review chat tab, attaches .sideboard/review.md when present (else local Review request.md / stock template), and sends "Review changes in this workspace." Expect Approve / Approve with nits / Request changes / Needs more information. Pass a worktree thread ref \u2014 not the orchestrator. Then wait_for_turn / get_turn_result on the returned review tab id.',
|
|
6419
6547
|
{ ref: z.string().describe("Worktree thread id/ref to review") },
|
|
6420
6548
|
async ({ ref }) => {
|
|
6421
6549
|
try {
|
|
@@ -6473,7 +6601,7 @@ async function startMcpServer() {
|
|
|
6473
6601
|
async ({ ref, through_index, agent, model, title }) => {
|
|
6474
6602
|
try {
|
|
6475
6603
|
const source = orch.getThread(ref);
|
|
6476
|
-
if (source) await orch.reconcile(source.repoPath);
|
|
6604
|
+
if (source) await orch.reconcile(source.repoPath, { drainQueues: false });
|
|
6477
6605
|
const thread = await orch.forkThreadWorktree({
|
|
6478
6606
|
threadId: ref,
|
|
6479
6607
|
throughIndex: through_index,
|