@sideboard-ai/core 0.1.62 → 0.1.66
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-QLSFIQAO.js → agents-EWFD765A.js} +23 -7
- package/dist/{agents-KF3J3C53.js → agents-MD7SCFYX.js} +23 -7
- package/dist/{app-settings-LTSFG7QJ.js → app-settings-GJVZGU3M.js} +13 -3
- package/dist/{app-settings-HK4KAM4R.js → app-settings-ONKMFSEJ.js} +13 -3
- package/dist/{chunk-RIWUU7FO.js → chunk-5AG5BUQN.js} +61 -3
- package/dist/{chunk-27MAWNKY.js → chunk-AKPEXIKK.js} +2 -2
- package/dist/{chunk-2MCNURQV.js → chunk-BBEH2CJE.js} +264 -93
- package/dist/{chunk-DDN3UF4R.js → chunk-BPOTVI5J.js} +115 -3
- package/dist/{chunk-2FEA4LDA.js → chunk-DNPP7QMK.js} +31 -6
- package/dist/{chunk-MBAL5FE6.js → chunk-DZYMNW2A.js} +4 -4
- package/dist/{chunk-JB2H7E7V.js → chunk-EVD4KNKR.js} +1 -1
- package/dist/{chunk-A6FOKNOU.js → chunk-HTOTTJJX.js} +2 -2
- package/dist/{chunk-3KKNTHUC.js → chunk-I2KGRAXC.js} +1 -1
- package/dist/{chunk-ZF5YJCXO.js → chunk-IFAU2DEY.js} +269 -93
- package/dist/{chunk-NVU7EC2E.js → chunk-LRBRQFBU.js} +2 -2
- package/dist/{chunk-6CUJQKTJ.js → chunk-MHR4OGZ4.js} +115 -3
- package/dist/{chunk-46KMKHSD.js → chunk-PESJDZTB.js} +2 -2
- package/dist/{chunk-UGXSSBFJ.js → chunk-R7GUDEPY.js} +1 -1
- package/dist/{chunk-73AT5K4A.js → chunk-TXQ6K2GR.js} +61 -3
- package/dist/{chunk-DXTGDXO2.js → chunk-YTNLOJPK.js} +31 -6
- package/dist/{connected-teams-RSL4VB3X.js → connected-teams-CHXO5FFA.js} +2 -2
- package/dist/{connected-teams-MKIYKOYA.js → connected-teams-GJTESSTX.js} +2 -2
- package/dist/{coordinator-prompt-LKG3SHMI.js → coordinator-prompt-E5UGSJES.js} +4 -4
- package/dist/{coordinator-prompt-N2R6FGZK.js → coordinator-prompt-ILSULI7C.js} +4 -4
- package/dist/{global-workspace-LALWQWRJ.js → global-workspace-44UG64NA.js} +5 -6
- package/dist/{global-workspace-YOAUQCMA.js → global-workspace-5PM5LA6E.js} +5 -6
- package/dist/index.cjs +1308 -925
- package/dist/index.d.cts +92 -1
- package/dist/index.d.ts +92 -1
- package/dist/index.js +746 -715
- package/dist/mcp/run-stdio.cjs +1267 -976
- package/dist/mcp/run-stdio.js +691 -748
- package/dist/{run-HZTBWGQR.js → run-74S2NZWB.js} +1 -1
- package/dist/{run-GPSVV5OH.js → run-JLN5JK7Q.js} +1 -1
- package/dist/{workspaces-VCAIHVIE.js → workspaces-OVBCSS5Y.js} +6 -7
- package/dist/{workspaces-E75POJXP.js → workspaces-RXFXQRRF.js} +6 -7
- package/dist/{worktree-MV4WRW6G.js → worktree-K2JB53R5.js} +2 -2
- package/dist/{worktree-LZEGVQSN.js → worktree-S2N63FLV.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-GI7E5733.js +0 -30
- package/dist/chunk-S2LL5HA4.js +0 -33
package/dist/index.js
CHANGED
|
@@ -4,33 +4,14 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
10
|
-
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
11
|
-
CLOUD_COORDINATOR_TIMEOUT_REPLY,
|
|
12
|
-
CLOUD_ORCHESTRATOR_GOAL,
|
|
13
|
-
GLOBAL_WORKSPACE_ID,
|
|
14
|
-
SIDEBOARD_FORCE_STOP,
|
|
15
|
-
createGlobalChat,
|
|
16
|
-
ensureCloudCoordinator,
|
|
17
|
-
healOrchestrationSoccerTitles,
|
|
18
|
-
isCloudCoordinatorThread,
|
|
19
|
-
isGlobalRepoPath,
|
|
20
|
-
isGlobalThread,
|
|
21
|
-
isOrchestratorThread,
|
|
22
|
-
listGlobalThreads,
|
|
23
|
-
orchestrationTitleNeedsSoccerNickname,
|
|
24
|
-
orchestratorSessionPoisonedByBuiltins,
|
|
25
|
-
parseForceStopMessage,
|
|
26
|
-
takenTeamSlugsForOrchestration
|
|
27
|
-
} from "./chunk-DXTGDXO2.js";
|
|
7
|
+
} from "./chunk-PESJDZTB.js";
|
|
28
8
|
import {
|
|
29
9
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
30
10
|
CLAUDE_MODEL_CATALOG,
|
|
31
11
|
MAX_ANTHROPIC_CACHE_CONTROL_BLOCKS,
|
|
32
12
|
PLAN_MODE_INSTRUCTION,
|
|
33
13
|
SIDEBOARD_MCP_ALLOWED_TOOLS,
|
|
14
|
+
SIDEBOARD_MCP_PROFILE_ENV,
|
|
34
15
|
allAdapters,
|
|
35
16
|
brightsyAdapter,
|
|
36
17
|
brightsyMcpAllowedTools,
|
|
@@ -41,6 +22,7 @@ import {
|
|
|
41
22
|
countCacheControlBlocks,
|
|
42
23
|
cursorAdapter,
|
|
43
24
|
decodeBrightsyTarget,
|
|
25
|
+
dropCachedPrefixOnResume,
|
|
44
26
|
encodeBrightsyTarget,
|
|
45
27
|
findInvalidCacheControlTtlOrder,
|
|
46
28
|
flattenTurnInput,
|
|
@@ -66,17 +48,41 @@ import {
|
|
|
66
48
|
parseMcpList,
|
|
67
49
|
parseSessionQuotaResetAt,
|
|
68
50
|
permissionMode,
|
|
51
|
+
prepareTerminalCommand,
|
|
52
|
+
promptMentionsBrightsy,
|
|
69
53
|
resolveCursorModelId,
|
|
54
|
+
resolveLoginCommand,
|
|
70
55
|
resolveQuotaFallbackAgent,
|
|
71
56
|
sanitizeMcpServerName,
|
|
57
|
+
shouldInjectBrightsyMcp,
|
|
58
|
+
sideboardMcpProfile,
|
|
59
|
+
threadRequestsBrightsyMcp,
|
|
72
60
|
writeInjectedMcpConfig
|
|
73
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-IFAU2DEY.js";
|
|
74
62
|
import {
|
|
63
|
+
CLOUD_COORDINATOR_BUSY_REPLY,
|
|
64
|
+
CLOUD_COORDINATOR_STOPPED_REPLY,
|
|
65
|
+
CLOUD_COORDINATOR_TIMEOUT_REPLY,
|
|
66
|
+
CLOUD_ORCHESTRATOR_GOAL,
|
|
67
|
+
GLOBAL_WORKSPACE_ID,
|
|
75
68
|
ORCHESTRATOR_AGENT_KINDS,
|
|
69
|
+
SIDEBOARD_FORCE_STOP,
|
|
76
70
|
assertOrchestratorCapableAgent,
|
|
77
71
|
coerceOrchestratorAgent,
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
createGlobalChat,
|
|
73
|
+
ensureCloudCoordinator,
|
|
74
|
+
healOrchestrationSoccerTitles,
|
|
75
|
+
isCloudCoordinatorThread,
|
|
76
|
+
isGlobalRepoPath,
|
|
77
|
+
isGlobalThread,
|
|
78
|
+
isOrchestratorCapableAgent,
|
|
79
|
+
isOrchestratorThread,
|
|
80
|
+
listGlobalThreads,
|
|
81
|
+
orchestrationTitleNeedsSoccerNickname,
|
|
82
|
+
orchestratorSessionPoisonedByBuiltins,
|
|
83
|
+
parseForceStopMessage,
|
|
84
|
+
takenTeamSlugsForOrchestration
|
|
85
|
+
} from "./chunk-YTNLOJPK.js";
|
|
80
86
|
import {
|
|
81
87
|
brightsyConfigPath,
|
|
82
88
|
brightsyMcpServerName,
|
|
@@ -88,7 +94,7 @@ import {
|
|
|
88
94
|
loadBrightsyConfig,
|
|
89
95
|
saveBrightsyConfig,
|
|
90
96
|
switchBrightsyAccount
|
|
91
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-DZYMNW2A.js";
|
|
92
98
|
import {
|
|
93
99
|
LEGACY_PLAN_FILE_REL,
|
|
94
100
|
PLAN_FILE_NAME,
|
|
@@ -118,7 +124,7 @@ import {
|
|
|
118
124
|
enrichWorkspacesWithGithub,
|
|
119
125
|
ensureGlobalCoordinatorCwd,
|
|
120
126
|
formatWorkspaceInventory
|
|
121
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-AKPEXIKK.js";
|
|
122
128
|
import {
|
|
123
129
|
HARNESS_ENV_KEYS,
|
|
124
130
|
appSettingsPath,
|
|
@@ -129,6 +135,7 @@ import {
|
|
|
129
135
|
autoRunAfterSetupEnabled,
|
|
130
136
|
brightsyCloudConnectAgent,
|
|
131
137
|
brightsyCloudConnectEnabled,
|
|
138
|
+
brightsyInjectWorktreeMcpEnabled,
|
|
132
139
|
caffeinateWhileCloudConnectEnabled,
|
|
133
140
|
caffeinateWhileRunningEnabled,
|
|
134
141
|
childEnvWithAppSettings,
|
|
@@ -147,18 +154,22 @@ import {
|
|
|
147
154
|
maxConcurrentAgents,
|
|
148
155
|
orchestrationQuotaFallbackAgent,
|
|
149
156
|
orchestrationQuotaOnLimit,
|
|
157
|
+
resolveAgentExecutable,
|
|
150
158
|
resolveClaudeExecutable,
|
|
151
159
|
resolveEffectiveIssueSource,
|
|
152
160
|
resolveNewThreadOptions,
|
|
153
161
|
resolveThreadDefaults,
|
|
154
162
|
saveAppSettings,
|
|
155
163
|
updateAdvancedSettings,
|
|
164
|
+
updateAgentExecutable,
|
|
156
165
|
updateAppEnvironment,
|
|
157
166
|
updateBrightsySettings,
|
|
158
167
|
updateClaudeSettings,
|
|
168
|
+
updateCodexSettings,
|
|
159
169
|
updateDefaultsSettings,
|
|
160
|
-
updateIntegrationsSettings
|
|
161
|
-
|
|
170
|
+
updateIntegrationsSettings,
|
|
171
|
+
updateOpencodeSettings
|
|
172
|
+
} from "./chunk-MHR4OGZ4.js";
|
|
162
173
|
import {
|
|
163
174
|
FAMOUS_SOCCER_TEAMS,
|
|
164
175
|
addPrStackLayer,
|
|
@@ -221,7 +232,7 @@ import {
|
|
|
221
232
|
worktreeDisplayLabel,
|
|
222
233
|
worktreeDisplayLabelForGroup,
|
|
223
234
|
worktreeNameFromPath
|
|
224
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-R7GUDEPY.js";
|
|
225
236
|
import {
|
|
226
237
|
ATTACHMENTS_DIR,
|
|
227
238
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -273,12 +284,16 @@ import {
|
|
|
273
284
|
worktreesRoot
|
|
274
285
|
} from "./chunk-M37RITA6.js";
|
|
275
286
|
import {
|
|
287
|
+
enrichPathWithNpmGlobalBin,
|
|
276
288
|
ensureAgentPath,
|
|
277
289
|
gh,
|
|
278
290
|
git,
|
|
291
|
+
posixShellSingleQuote,
|
|
292
|
+
resolveCommandBinarySync,
|
|
279
293
|
resolveGhAuthToken,
|
|
280
|
-
run
|
|
281
|
-
|
|
294
|
+
run,
|
|
295
|
+
withExportedPath
|
|
296
|
+
} from "./chunk-TXQ6K2GR.js";
|
|
282
297
|
|
|
283
298
|
// src/integrations/github.ts
|
|
284
299
|
async function getGitHubStatus() {
|
|
@@ -707,9 +722,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
707
722
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
708
723
|
);
|
|
709
724
|
}
|
|
710
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
725
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-44UG64NA.js");
|
|
711
726
|
if (isGlobalThread2(thread)) {
|
|
712
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
727
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-ILSULI7C.js");
|
|
713
728
|
ensureGlobalCoordinatorCwd2(
|
|
714
729
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
715
730
|
);
|
|
@@ -911,6 +926,9 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
911
926
|
);
|
|
912
927
|
return lines.join("\n");
|
|
913
928
|
}
|
|
929
|
+
function formatWorktreeReminder() {
|
|
930
|
+
return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout.";
|
|
931
|
+
}
|
|
914
932
|
function formatArtifactDirective() {
|
|
915
933
|
return [
|
|
916
934
|
"Sideboard side column (desktop UI):",
|
|
@@ -996,11 +1014,13 @@ ${prompt}`;
|
|
|
996
1014
|
// src/detect/detect.ts
|
|
997
1015
|
async function detectAgents() {
|
|
998
1016
|
ensureAgentPath();
|
|
1017
|
+
enrichPathWithNpmGlobalBin();
|
|
999
1018
|
return Promise.all(allAdapters().map((a) => a.detect()));
|
|
1000
1019
|
}
|
|
1001
1020
|
var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
|
|
1002
1021
|
async function requireAgent(agent, opts) {
|
|
1003
1022
|
ensureAgentPath();
|
|
1023
|
+
enrichPathWithNpmGlobalBin();
|
|
1004
1024
|
const status = await Promise.race([
|
|
1005
1025
|
getAdapter(agent).detect(),
|
|
1006
1026
|
new Promise((_, reject) => {
|
|
@@ -2842,7 +2862,7 @@ async function previewLand(thread) {
|
|
|
2842
2862
|
const target = await resolveDefaultBranch(thread.repoPath);
|
|
2843
2863
|
if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
|
|
2844
2864
|
}
|
|
2845
|
-
const { stdout: head } = await import("./run-
|
|
2865
|
+
const { stdout: head } = await import("./run-JLN5JK7Q.js").then(
|
|
2846
2866
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
|
|
2847
2867
|
);
|
|
2848
2868
|
const current = head.trim();
|
|
@@ -2881,7 +2901,7 @@ async function confirmLand(thread, opts) {
|
|
|
2881
2901
|
if (preview.dirty) {
|
|
2882
2902
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
2883
2903
|
}
|
|
2884
|
-
const { git: git2 } = await import("./run-
|
|
2904
|
+
const { git: git2 } = await import("./run-JLN5JK7Q.js");
|
|
2885
2905
|
const { stdout: headOut } = await git2(
|
|
2886
2906
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
2887
2907
|
thread.worktreePath,
|
|
@@ -2979,7 +2999,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2979
2999
|
return readThread(thread.id) ?? thread;
|
|
2980
3000
|
}
|
|
2981
3001
|
async function listLinearIssues(agent, repoPath) {
|
|
2982
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3002
|
+
const { getAdapter: getAdapter2 } = await import("./agents-EWFD765A.js");
|
|
2983
3003
|
await requireAgent(agent, { requireLinear: true });
|
|
2984
3004
|
const adapter = getAdapter2(agent);
|
|
2985
3005
|
if (!adapter.listLinearIssues) {
|
|
@@ -3507,7 +3527,7 @@ async function adoptThread(input) {
|
|
|
3507
3527
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3508
3528
|
}
|
|
3509
3529
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
3510
|
-
const { stdout: branch } = await import("./run-
|
|
3530
|
+
const { stdout: branch } = await import("./run-JLN5JK7Q.js").then(
|
|
3511
3531
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
3512
3532
|
);
|
|
3513
3533
|
const thread = createEmptyThread({
|
|
@@ -3522,7 +3542,7 @@ async function adoptThread(input) {
|
|
|
3522
3542
|
messages: input.messages ?? []
|
|
3523
3543
|
});
|
|
3524
3544
|
writeThread(thread);
|
|
3525
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3545
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OVBCSS5Y.js");
|
|
3526
3546
|
await ensureWorkspace2(repoPath);
|
|
3527
3547
|
return thread;
|
|
3528
3548
|
}
|
|
@@ -4473,7 +4493,7 @@ var Orchestrator = class {
|
|
|
4473
4493
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
4474
4494
|
});
|
|
4475
4495
|
}
|
|
4476
|
-
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-
|
|
4496
|
+
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4477
4497
|
if (autoCleanupOrphansEnabled2() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
4478
4498
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
4479
4499
|
}
|
|
@@ -4630,7 +4650,7 @@ var Orchestrator = class {
|
|
|
4630
4650
|
}
|
|
4631
4651
|
async finishCreateThread(threadId, prompt) {
|
|
4632
4652
|
await this.runSetupAfterCreate(threadId);
|
|
4633
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-
|
|
4653
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4634
4654
|
if (autoRunAfterSetupEnabled2()) {
|
|
4635
4655
|
try {
|
|
4636
4656
|
await this.startDev(threadId);
|
|
@@ -4871,13 +4891,14 @@ var Orchestrator = class {
|
|
|
4871
4891
|
"Files column: MCP present_files (brightsy account storage or memory).",
|
|
4872
4892
|
"Do not say artifacts/CMS UI are unavailable."
|
|
4873
4893
|
].join(" ") : null;
|
|
4894
|
+
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
4874
4895
|
const agentPrompt = [
|
|
4875
4896
|
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
4876
4897
|
orchestrationReminder,
|
|
4898
|
+
worktreeReminder,
|
|
4877
4899
|
artifactReminder,
|
|
4878
4900
|
expandedPrompt
|
|
4879
4901
|
].filter(Boolean).join("\n\n");
|
|
4880
|
-
const instructionFiles = loadAgentInstructions(thread.worktreePath, thread.agent);
|
|
4881
4902
|
if (thread.attachments.length > 0) {
|
|
4882
4903
|
updateThread(threadId, { attachments: [] });
|
|
4883
4904
|
}
|
|
@@ -4901,11 +4922,10 @@ var Orchestrator = class {
|
|
|
4901
4922
|
});
|
|
4902
4923
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
4903
4924
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
4904
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-
|
|
4925
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4905
4926
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
|
|
4906
4927
|
customPrompt: settings?.prompts?.renameBranch
|
|
4907
4928
|
}) : null;
|
|
4908
|
-
const instructions = fresh.agent === "claude" || isBrightsy ? null : formatAgentInstructions(instructionFiles);
|
|
4909
4929
|
let seed = null;
|
|
4910
4930
|
if (!fresh.sessionId) {
|
|
4911
4931
|
const prior = fresh.messages.slice(0, -1);
|
|
@@ -4926,12 +4946,12 @@ var Orchestrator = class {
|
|
|
4926
4946
|
});
|
|
4927
4947
|
}
|
|
4928
4948
|
}
|
|
4929
|
-
const cachedPrefix = [
|
|
4949
|
+
const cachedPrefix = fresh.sessionId ? "" : [
|
|
4930
4950
|
coordinatorDirective,
|
|
4931
4951
|
worktreeDirective,
|
|
4932
4952
|
artifactDirective,
|
|
4933
4953
|
renameBranchDirective,
|
|
4934
|
-
|
|
4954
|
+
seed
|
|
4935
4955
|
].filter(Boolean).join("\n\n---\n\n");
|
|
4936
4956
|
try {
|
|
4937
4957
|
const stderrTail = [];
|
|
@@ -5018,15 +5038,11 @@ var Orchestrator = class {
|
|
|
5018
5038
|
const retryThread = this.requireThread(threadId);
|
|
5019
5039
|
const prior = retryThread.messages.slice(0, -1);
|
|
5020
5040
|
const retrySeed = buildSessionSeed(prior);
|
|
5021
|
-
const retryInstructions = retryThread.agent === "claude" ? null : formatAgentInstructions(
|
|
5022
|
-
loadAgentInstructions(retryThread.worktreePath, retryThread.agent)
|
|
5023
|
-
);
|
|
5024
5041
|
const retryPrefix = [
|
|
5025
5042
|
coordinatorDirective,
|
|
5026
5043
|
worktreeDirective,
|
|
5027
5044
|
artifactDirective,
|
|
5028
5045
|
renameBranchDirective,
|
|
5029
|
-
retryInstructions,
|
|
5030
5046
|
retrySeed
|
|
5031
5047
|
].filter(Boolean).join("\n\n---\n\n");
|
|
5032
5048
|
const retryHandle = await spawnAgentTurn(
|
|
@@ -5596,7 +5612,7 @@ var Orchestrator = class {
|
|
|
5596
5612
|
updateThread(thread.id, { title: meta.title });
|
|
5597
5613
|
}
|
|
5598
5614
|
}
|
|
5599
|
-
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-
|
|
5615
|
+
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
5600
5616
|
const latest = this.requireThread(thread.id);
|
|
5601
5617
|
if (!shouldAutoArchiveOnPrMerge({
|
|
5602
5618
|
previousPrState: prevState || null,
|
|
@@ -5820,7 +5836,7 @@ var Orchestrator = class {
|
|
|
5820
5836
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
5821
5837
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
5822
5838
|
try {
|
|
5823
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
5839
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OVBCSS5Y.js");
|
|
5824
5840
|
await ensureWorkspace2(thread.repoPath);
|
|
5825
5841
|
} catch {
|
|
5826
5842
|
}
|
|
@@ -5841,7 +5857,7 @@ var Orchestrator = class {
|
|
|
5841
5857
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
5842
5858
|
} catch {
|
|
5843
5859
|
}
|
|
5844
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-
|
|
5860
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
5845
5861
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
5846
5862
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
5847
5863
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -5862,7 +5878,7 @@ var Orchestrator = class {
|
|
|
5862
5878
|
return restored2;
|
|
5863
5879
|
}
|
|
5864
5880
|
if (!existsSync13(thread.worktreePath)) {
|
|
5865
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
5881
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-K2JB53R5.js");
|
|
5866
5882
|
const { execa: execa6 } = await import("execa");
|
|
5867
5883
|
const slug = thread.worktreePath.split("/").pop();
|
|
5868
5884
|
const dest = thread.worktreePath;
|
|
@@ -5971,7 +5987,7 @@ async function startOrchestration(opts) {
|
|
|
5971
5987
|
sourceRef: "default",
|
|
5972
5988
|
...createOpts
|
|
5973
5989
|
}).catch(async () => {
|
|
5974
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
5990
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-K2JB53R5.js");
|
|
5975
5991
|
const repo = await resolveRepoRoot2(repoPath);
|
|
5976
5992
|
const def = await resolveDefaultBranch2(repo);
|
|
5977
5993
|
return createThread({
|
|
@@ -6127,7 +6143,7 @@ function withTimeout(promise, ms, label) {
|
|
|
6127
6143
|
async function startMcpServer() {
|
|
6128
6144
|
const orch = getOrchestrator();
|
|
6129
6145
|
try {
|
|
6130
|
-
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-
|
|
6146
|
+
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
6131
6147
|
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
6132
6148
|
} catch {
|
|
6133
6149
|
}
|
|
@@ -6218,14 +6234,13 @@ async function startMcpServer() {
|
|
|
6218
6234
|
),
|
|
6219
6235
|
artifact_id: z.string().optional().describe("Stable id when updating the same artifact across turns")
|
|
6220
6236
|
},
|
|
6221
|
-
async ({ title, type,
|
|
6237
|
+
async ({ title, type, artifact_id }) => {
|
|
6222
6238
|
const id = artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
6223
6239
|
const payload = {
|
|
6224
6240
|
ok: true,
|
|
6225
6241
|
artifact_id: id,
|
|
6226
6242
|
title,
|
|
6227
6243
|
type,
|
|
6228
|
-
content,
|
|
6229
6244
|
message: "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
|
|
6230
6245
|
};
|
|
6231
6246
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6278,7 +6293,6 @@ async function startMcpServer() {
|
|
|
6278
6293
|
ok: true,
|
|
6279
6294
|
path,
|
|
6280
6295
|
title: title?.trim() || "Plan",
|
|
6281
|
-
content,
|
|
6282
6296
|
message: "Plan saved to .context/attachments/plan.md and shown in Sideboard chat for approval."
|
|
6283
6297
|
};
|
|
6284
6298
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6308,9 +6322,6 @@ async function startMcpServer() {
|
|
|
6308
6322
|
datasource: args.datasource ?? (args.resource ? "inline" : "brightsy"),
|
|
6309
6323
|
resource_id: args.resource_id,
|
|
6310
6324
|
record_id: args.record_id,
|
|
6311
|
-
resource: args.resource,
|
|
6312
|
-
record: args.record,
|
|
6313
|
-
records: args.records,
|
|
6314
6325
|
message: "Schema pane accepted. Sideboard desktop opens the CMS column beside chat."
|
|
6315
6326
|
};
|
|
6316
6327
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6338,739 +6349,741 @@ async function startMcpServer() {
|
|
|
6338
6349
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
6339
6350
|
}
|
|
6340
6351
|
);
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
if (
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6352
|
+
if (sideboardMcpProfile() !== "worktree") {
|
|
6353
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
6354
|
+
const accountDefaults = resolveThreadDefaults2();
|
|
6355
|
+
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
6356
|
+
server.tool(
|
|
6357
|
+
"create_thread",
|
|
6358
|
+
`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.`,
|
|
6359
|
+
{
|
|
6360
|
+
sourceType: z.enum(["branch", "pr", "ticket"]),
|
|
6361
|
+
sourceRef: z.string(),
|
|
6362
|
+
agent: z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(`Omit to use Account default agent (${accountDefaults.agent})`),
|
|
6363
|
+
model: z.string().nullable().optional().describe(
|
|
6364
|
+
`Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
|
|
6365
|
+
),
|
|
6366
|
+
repoPath: z.string(),
|
|
6367
|
+
title: z.string().optional(),
|
|
6368
|
+
parentThreadId: z.string().optional().describe(
|
|
6369
|
+
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
6370
|
+
)
|
|
6371
|
+
},
|
|
6372
|
+
async (args) => {
|
|
6373
|
+
const envParentId = process.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || "";
|
|
6374
|
+
let parentId = args.parentThreadId?.trim() || "";
|
|
6375
|
+
let parent = parentId ? orch.getThread(parentId) : null;
|
|
6376
|
+
let parentCorrectedFrom;
|
|
6377
|
+
if (envParentId) {
|
|
6378
|
+
const envParent = orch.getThread(envParentId);
|
|
6379
|
+
if (envParent) {
|
|
6380
|
+
if (parentId && parentId !== envParentId) parentCorrectedFrom = parentId;
|
|
6381
|
+
else if (!parentId) parentCorrectedFrom = void 0;
|
|
6382
|
+
parentId = envParentId;
|
|
6383
|
+
parent = envParent;
|
|
6384
|
+
}
|
|
6372
6385
|
}
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6386
|
+
if (parentId && !parent) {
|
|
6387
|
+
parentCorrectedFrom = parentId;
|
|
6388
|
+
parentId = "";
|
|
6389
|
+
parent = null;
|
|
6390
|
+
}
|
|
6391
|
+
if (parentId) {
|
|
6392
|
+
const children = orch.getThreads(false).filter((t) => t.parentThreadId === parentId);
|
|
6393
|
+
if (children.length >= MAX_ORCH_THREADS) {
|
|
6394
|
+
return {
|
|
6395
|
+
content: [
|
|
6396
|
+
{
|
|
6397
|
+
type: "text",
|
|
6398
|
+
text: `Thread-creation cap (${MAX_ORCH_THREADS}) reached for this orchestration session`
|
|
6399
|
+
}
|
|
6400
|
+
],
|
|
6401
|
+
isError: true
|
|
6402
|
+
};
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
let agentArg = args.agent;
|
|
6406
|
+
let agentCoercedFrom;
|
|
6407
|
+
const resolvedProbe = resolveNewThreadOptions2({ agent: agentArg }).agent;
|
|
6408
|
+
if (resolvedProbe === "codex") {
|
|
6409
|
+
agentCoercedFrom = agentArg ?? "codex";
|
|
6410
|
+
const accountAgent = resolveNewThreadOptions2({}).agent;
|
|
6411
|
+
agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
|
|
6412
|
+
}
|
|
6413
|
+
const opts = resolveNewThreadOptions2({
|
|
6414
|
+
agent: agentArg,
|
|
6415
|
+
model: args.model
|
|
6416
|
+
});
|
|
6417
|
+
try {
|
|
6418
|
+
const thread = await withTimeout(
|
|
6419
|
+
orch.createThread({
|
|
6420
|
+
sourceType: args.sourceType,
|
|
6421
|
+
sourceRef: args.sourceRef,
|
|
6422
|
+
agent: opts.agent,
|
|
6423
|
+
model: opts.model,
|
|
6424
|
+
effort: opts.effort,
|
|
6425
|
+
fast: opts.fast,
|
|
6426
|
+
repoPath: args.repoPath,
|
|
6427
|
+
title: args.title,
|
|
6428
|
+
parentThreadId: parentId || null
|
|
6429
|
+
}),
|
|
6430
|
+
CREATE_THREAD_TIMEOUT_MS,
|
|
6431
|
+
"create_thread"
|
|
6432
|
+
);
|
|
6433
|
+
const parentNote = parentCorrectedFrom ? parentId ? `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; nested under ${parentId}` : `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; created without parent` : void 0;
|
|
6382
6434
|
return {
|
|
6383
6435
|
content: [
|
|
6384
6436
|
{
|
|
6385
6437
|
type: "text",
|
|
6386
|
-
text:
|
|
6438
|
+
text: JSON.stringify({
|
|
6439
|
+
id: thread.id,
|
|
6440
|
+
title: thread.title,
|
|
6441
|
+
branchName: thread.branchName,
|
|
6442
|
+
worktreePath: thread.worktreePath,
|
|
6443
|
+
agent: thread.agent,
|
|
6444
|
+
model: thread.model,
|
|
6445
|
+
status: thread.status,
|
|
6446
|
+
link: `sideboard://thread/${thread.id}`,
|
|
6447
|
+
parentThreadId: thread.parentThreadId,
|
|
6448
|
+
...agentCoercedFrom ? {
|
|
6449
|
+
agentCoercedFrom,
|
|
6450
|
+
note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
|
|
6451
|
+
} : {},
|
|
6452
|
+
...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
|
|
6453
|
+
})
|
|
6454
|
+
}
|
|
6455
|
+
]
|
|
6456
|
+
};
|
|
6457
|
+
} catch (err) {
|
|
6458
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6459
|
+
return {
|
|
6460
|
+
content: [
|
|
6461
|
+
{
|
|
6462
|
+
type: "text",
|
|
6463
|
+
text: `create_thread failed: ${message}`
|
|
6387
6464
|
}
|
|
6388
6465
|
],
|
|
6389
6466
|
isError: true
|
|
6390
6467
|
};
|
|
6391
6468
|
}
|
|
6392
6469
|
}
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
agent: opts.agent,
|
|
6411
|
-
model: opts.model,
|
|
6412
|
-
effort: opts.effort,
|
|
6413
|
-
fast: opts.fast,
|
|
6414
|
-
repoPath: args.repoPath,
|
|
6415
|
-
title: args.title,
|
|
6416
|
-
parentThreadId: parentId || null
|
|
6417
|
-
}),
|
|
6418
|
-
CREATE_THREAD_TIMEOUT_MS,
|
|
6419
|
-
"create_thread"
|
|
6420
|
-
);
|
|
6421
|
-
const parentNote = parentCorrectedFrom ? parentId ? `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; nested under ${parentId}` : `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; created without parent` : void 0;
|
|
6470
|
+
);
|
|
6471
|
+
server.tool(
|
|
6472
|
+
"send_to_thread",
|
|
6473
|
+
"Queue a prompt on a worktree thread chat (runs under concurrency cap). Use after create_thread to start or continue a conversation. Set force_stop=true to interrupt an in-flight/queued turn (kill + clear queue) before queueing this prompt \u2014 use when the thread is mid-turn or has stale queued prompts you need to replace.",
|
|
6474
|
+
{
|
|
6475
|
+
ref: z.string(),
|
|
6476
|
+
prompt: z.string(),
|
|
6477
|
+
force_stop: z.boolean().optional()
|
|
6478
|
+
},
|
|
6479
|
+
async ({ ref, prompt, force_stop }) => {
|
|
6480
|
+
if (force_stop) {
|
|
6481
|
+
const existing = orch.getThread(ref);
|
|
6482
|
+
if (existing) {
|
|
6483
|
+
orch.stop(ref, { clearQueue: true });
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
const thread = await orch.send(ref, prompt);
|
|
6422
6487
|
return {
|
|
6423
6488
|
content: [
|
|
6424
6489
|
{
|
|
6425
6490
|
type: "text",
|
|
6426
6491
|
text: JSON.stringify({
|
|
6427
6492
|
id: thread.id,
|
|
6428
|
-
title: thread.title,
|
|
6429
|
-
branchName: thread.branchName,
|
|
6430
|
-
worktreePath: thread.worktreePath,
|
|
6431
|
-
agent: thread.agent,
|
|
6432
|
-
model: thread.model,
|
|
6433
6493
|
status: thread.status,
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
...agentCoercedFrom ? {
|
|
6437
|
-
agentCoercedFrom,
|
|
6438
|
-
note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
|
|
6439
|
-
} : {},
|
|
6440
|
-
...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
|
|
6494
|
+
queueLength: thread.queue.length,
|
|
6495
|
+
forceStopped: Boolean(force_stop)
|
|
6441
6496
|
})
|
|
6442
6497
|
}
|
|
6443
6498
|
]
|
|
6444
6499
|
};
|
|
6445
|
-
}
|
|
6446
|
-
|
|
6500
|
+
}
|
|
6501
|
+
);
|
|
6502
|
+
server.tool(
|
|
6503
|
+
"wait_for_turn",
|
|
6504
|
+
"Block until the thread finishes its current/queued turn (avoids polling). Use after send_to_thread to read the agent reply.",
|
|
6505
|
+
{
|
|
6506
|
+
ref: z.string(),
|
|
6507
|
+
timeoutMs: z.number().optional()
|
|
6508
|
+
},
|
|
6509
|
+
async ({ ref, timeoutMs }) => {
|
|
6510
|
+
const thread = await orch.waitForTurn(ref, timeoutMs ?? 6e5);
|
|
6511
|
+
const result = orch.getTurnResult(thread.id);
|
|
6447
6512
|
return {
|
|
6448
6513
|
content: [
|
|
6449
6514
|
{
|
|
6450
6515
|
type: "text",
|
|
6451
|
-
text:
|
|
6516
|
+
text: JSON.stringify({
|
|
6517
|
+
id: thread.id,
|
|
6518
|
+
status: result.status,
|
|
6519
|
+
text: result.text
|
|
6520
|
+
})
|
|
6452
6521
|
}
|
|
6453
|
-
]
|
|
6454
|
-
isError: true
|
|
6522
|
+
]
|
|
6455
6523
|
};
|
|
6456
6524
|
}
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
force_stop: z.boolean().optional()
|
|
6466
|
-
},
|
|
6467
|
-
async ({ ref, prompt, force_stop }) => {
|
|
6468
|
-
if (force_stop) {
|
|
6469
|
-
const existing = orch.getThread(ref);
|
|
6470
|
-
if (existing) {
|
|
6471
|
-
orch.stop(ref, { clearQueue: true });
|
|
6472
|
-
}
|
|
6525
|
+
);
|
|
6526
|
+
server.tool(
|
|
6527
|
+
"get_turn_result",
|
|
6528
|
+
"Final assistant message only (not full transcript)",
|
|
6529
|
+
{ ref: z.string() },
|
|
6530
|
+
async ({ ref }) => {
|
|
6531
|
+
const result = orch.getTurnResult(ref);
|
|
6532
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
6473
6533
|
}
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
{
|
|
6494
|
-
ref: z.string(),
|
|
6495
|
-
timeoutMs: z.number().optional()
|
|
6496
|
-
},
|
|
6497
|
-
async ({ ref, timeoutMs }) => {
|
|
6498
|
-
const thread = await orch.waitForTurn(ref, timeoutMs ?? 6e5);
|
|
6499
|
-
const result = orch.getTurnResult(thread.id);
|
|
6500
|
-
return {
|
|
6501
|
-
content: [
|
|
6502
|
-
{
|
|
6503
|
-
type: "text",
|
|
6504
|
-
text: JSON.stringify({
|
|
6505
|
-
id: thread.id,
|
|
6506
|
-
status: result.status,
|
|
6507
|
-
text: result.text
|
|
6508
|
-
})
|
|
6509
|
-
}
|
|
6510
|
-
]
|
|
6511
|
-
};
|
|
6512
|
-
}
|
|
6513
|
-
);
|
|
6514
|
-
server.tool(
|
|
6515
|
-
"get_turn_result",
|
|
6516
|
-
"Final assistant message only (not full transcript)",
|
|
6517
|
-
{ ref: z.string() },
|
|
6518
|
-
async ({ ref }) => {
|
|
6519
|
-
const result = orch.getTurnResult(ref);
|
|
6520
|
-
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
6521
|
-
}
|
|
6522
|
-
);
|
|
6523
|
-
server.tool(
|
|
6524
|
-
"stop_thread",
|
|
6525
|
-
"Force-stop a thread: kill any in-flight agent turn AND clear queued prompts so drainQueue cannot continue. Does not archive the worktree. Optional force defaults to true.",
|
|
6526
|
-
{
|
|
6527
|
-
ref: z.string(),
|
|
6528
|
-
force: z.boolean().optional()
|
|
6529
|
-
},
|
|
6530
|
-
async ({ ref, force }) => {
|
|
6531
|
-
const t = orch.getThread(ref);
|
|
6532
|
-
if (!t) {
|
|
6534
|
+
);
|
|
6535
|
+
server.tool(
|
|
6536
|
+
"stop_thread",
|
|
6537
|
+
"Force-stop a thread: kill any in-flight agent turn AND clear queued prompts so drainQueue cannot continue. Does not archive the worktree. Optional force defaults to true.",
|
|
6538
|
+
{
|
|
6539
|
+
ref: z.string(),
|
|
6540
|
+
force: z.boolean().optional()
|
|
6541
|
+
},
|
|
6542
|
+
async ({ ref, force }) => {
|
|
6543
|
+
const t = orch.getThread(ref);
|
|
6544
|
+
if (!t) {
|
|
6545
|
+
return {
|
|
6546
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6547
|
+
isError: true
|
|
6548
|
+
};
|
|
6549
|
+
}
|
|
6550
|
+
const clearQueue = force !== false;
|
|
6551
|
+
const hadQueued = t.queue.length > 0;
|
|
6552
|
+
const stopped = orch.stop(ref, { clearQueue });
|
|
6533
6553
|
return {
|
|
6534
|
-
content: [
|
|
6535
|
-
|
|
6554
|
+
content: [
|
|
6555
|
+
{
|
|
6556
|
+
type: "text",
|
|
6557
|
+
text: JSON.stringify({
|
|
6558
|
+
id: stopped.id,
|
|
6559
|
+
status: stopped.status,
|
|
6560
|
+
clearedQueue: clearQueue && hadQueued
|
|
6561
|
+
})
|
|
6562
|
+
}
|
|
6563
|
+
]
|
|
6536
6564
|
};
|
|
6537
6565
|
}
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
async ({ ref }) => {
|
|
6560
|
-
const t = orch.getThread(ref);
|
|
6561
|
-
if (!t) {
|
|
6566
|
+
);
|
|
6567
|
+
server.tool(
|
|
6568
|
+
"archive_thread",
|
|
6569
|
+
"Archive a thread (stops agent/dev, runs archive script, removes worktree when last chat tab). Cannot archive the cloud coordinator \u2014 use the Sideboard UI for that.",
|
|
6570
|
+
{ ref: z.string() },
|
|
6571
|
+
async ({ ref }) => {
|
|
6572
|
+
const t = orch.getThread(ref);
|
|
6573
|
+
if (!t) {
|
|
6574
|
+
return {
|
|
6575
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6576
|
+
isError: true
|
|
6577
|
+
};
|
|
6578
|
+
}
|
|
6579
|
+
const blocked = mcpArchiveBlockedReason(t);
|
|
6580
|
+
if (blocked) {
|
|
6581
|
+
return {
|
|
6582
|
+
content: [{ type: "text", text: blocked }],
|
|
6583
|
+
isError: true
|
|
6584
|
+
};
|
|
6585
|
+
}
|
|
6586
|
+
const archived = await orch.archive(ref);
|
|
6562
6587
|
return {
|
|
6563
|
-
content: [
|
|
6564
|
-
|
|
6588
|
+
content: [
|
|
6589
|
+
{
|
|
6590
|
+
type: "text",
|
|
6591
|
+
text: JSON.stringify({
|
|
6592
|
+
id: archived.id,
|
|
6593
|
+
status: archived.status
|
|
6594
|
+
})
|
|
6595
|
+
}
|
|
6596
|
+
]
|
|
6565
6597
|
};
|
|
6566
6598
|
}
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6599
|
+
);
|
|
6600
|
+
server.tool(
|
|
6601
|
+
"restore_thread",
|
|
6602
|
+
"Restore an archived thread (recreates worktree from branch when needed)",
|
|
6603
|
+
{ ref: z.string() },
|
|
6604
|
+
async ({ ref }) => {
|
|
6605
|
+
try {
|
|
6606
|
+
const restored = await orch.restore(ref);
|
|
6607
|
+
return {
|
|
6608
|
+
content: [
|
|
6609
|
+
{
|
|
6610
|
+
type: "text",
|
|
6611
|
+
text: JSON.stringify({
|
|
6612
|
+
id: restored.id,
|
|
6613
|
+
status: restored.status,
|
|
6614
|
+
worktreePath: restored.worktreePath
|
|
6615
|
+
})
|
|
6616
|
+
}
|
|
6617
|
+
]
|
|
6618
|
+
};
|
|
6619
|
+
} catch (err) {
|
|
6620
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6621
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6622
|
+
}
|
|
6573
6623
|
}
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
]
|
|
6585
|
-
};
|
|
6586
|
-
}
|
|
6587
|
-
);
|
|
6588
|
-
server.tool(
|
|
6589
|
-
"restore_thread",
|
|
6590
|
-
"Restore an archived thread (recreates worktree from branch when needed)",
|
|
6591
|
-
{ ref: z.string() },
|
|
6592
|
-
async ({ ref }) => {
|
|
6593
|
-
try {
|
|
6594
|
-
const restored = await orch.restore(ref);
|
|
6624
|
+
);
|
|
6625
|
+
server.tool(
|
|
6626
|
+
"get_diff",
|
|
6627
|
+
"Compact diff summary (capped hunks, paginated)",
|
|
6628
|
+
{
|
|
6629
|
+
ref: z.string(),
|
|
6630
|
+
maxFiles: z.number().optional()
|
|
6631
|
+
},
|
|
6632
|
+
async ({ ref, maxFiles }) => {
|
|
6633
|
+
const summary = await orch.diffSummary(ref);
|
|
6595
6634
|
return {
|
|
6596
6635
|
content: [
|
|
6597
6636
|
{
|
|
6598
6637
|
type: "text",
|
|
6599
6638
|
text: JSON.stringify({
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
worktreePath: restored.worktreePath
|
|
6639
|
+
...summary,
|
|
6640
|
+
files: summary.files.slice(0, maxFiles ?? 10)
|
|
6603
6641
|
})
|
|
6604
6642
|
}
|
|
6605
6643
|
]
|
|
6606
6644
|
};
|
|
6607
|
-
} catch (err) {
|
|
6608
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6609
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6610
6645
|
}
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6646
|
+
);
|
|
6647
|
+
server.tool(
|
|
6648
|
+
"request_review",
|
|
6649
|
+
'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.',
|
|
6650
|
+
{ ref: z.string().describe("Worktree thread id/ref to review") },
|
|
6651
|
+
async ({ ref }) => {
|
|
6652
|
+
try {
|
|
6653
|
+
const tab = await orch.requestReview(ref);
|
|
6654
|
+
const from = orch.getThread(ref);
|
|
6655
|
+
return {
|
|
6656
|
+
content: [
|
|
6657
|
+
{
|
|
6658
|
+
type: "text",
|
|
6659
|
+
text: JSON.stringify({
|
|
6660
|
+
id: tab.id,
|
|
6661
|
+
title: tab.title,
|
|
6662
|
+
status: tab.status,
|
|
6663
|
+
fromThreadId: from?.id ?? ref,
|
|
6664
|
+
link: `sideboard://thread/${tab.id}`
|
|
6665
|
+
})
|
|
6666
|
+
}
|
|
6667
|
+
]
|
|
6668
|
+
};
|
|
6669
|
+
} catch (err) {
|
|
6670
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6671
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6672
|
+
}
|
|
6673
|
+
}
|
|
6674
|
+
);
|
|
6675
|
+
const agentEnum = z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]);
|
|
6676
|
+
server.tool(
|
|
6677
|
+
"list_models",
|
|
6678
|
+
"List models for an agent. Prefer Auto: do not call this unless you have a reason to pin a specific model (user request, cost/latency, capability). Omit agent to list all.",
|
|
6679
|
+
{
|
|
6680
|
+
agent: agentEnum.optional().describe("Limit to one agent; omit for all")
|
|
6681
|
+
},
|
|
6682
|
+
async ({ agent }) => {
|
|
6683
|
+
try {
|
|
6684
|
+
const catalogs = await listModelsForAgent(agent);
|
|
6685
|
+
return {
|
|
6686
|
+
content: [{ type: "text", text: JSON.stringify(catalogs, null, 2) }]
|
|
6687
|
+
};
|
|
6688
|
+
} catch (err) {
|
|
6689
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6690
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6691
|
+
}
|
|
6692
|
+
}
|
|
6693
|
+
);
|
|
6694
|
+
server.tool(
|
|
6695
|
+
"fork_worktree",
|
|
6696
|
+
"Fork a worktree agent chat into a NEW git worktree + chat (desktop \u201CFork to new workspace\u201D). Seeds a transcript (through through_index, default all). Optional agent override. Leave model unset for Auto (default) \u2014 only pass model when you have a reason. Not for the orchestrator. Then send_to_thread / wait_for_turn on the returned id.",
|
|
6697
|
+
{
|
|
6698
|
+
ref: z.string().describe("Worktree thread id/ref to fork"),
|
|
6699
|
+
through_index: z.number().optional().describe("Inclusive message index to include in the transcript (default: all)"),
|
|
6700
|
+
agent: agentEnum.optional().describe("Agent for the forked chat (default: same as source)"),
|
|
6701
|
+
model: z.string().nullable().optional().describe("Usually omit (Auto). Only set from list_models when you need a specific model"),
|
|
6702
|
+
title: z.string().optional()
|
|
6703
|
+
},
|
|
6704
|
+
async ({ ref, through_index, agent, model, title }) => {
|
|
6705
|
+
try {
|
|
6706
|
+
const source = orch.getThread(ref);
|
|
6707
|
+
if (source) await orch.reconcile(source.repoPath, { drainQueues: false });
|
|
6708
|
+
const thread = await orch.forkThreadWorktree({
|
|
6709
|
+
threadId: ref,
|
|
6710
|
+
throughIndex: through_index,
|
|
6711
|
+
agent,
|
|
6712
|
+
model,
|
|
6713
|
+
title
|
|
6714
|
+
});
|
|
6715
|
+
return {
|
|
6716
|
+
content: [
|
|
6717
|
+
{
|
|
6718
|
+
type: "text",
|
|
6719
|
+
text: JSON.stringify({
|
|
6720
|
+
id: thread.id,
|
|
6721
|
+
title: thread.title,
|
|
6722
|
+
status: thread.status,
|
|
6723
|
+
agent: thread.agent,
|
|
6724
|
+
model: thread.model,
|
|
6725
|
+
branchName: thread.branchName,
|
|
6726
|
+
worktreePath: thread.worktreePath,
|
|
6727
|
+
fromThreadId: source?.id ?? ref,
|
|
6728
|
+
link: `sideboard://thread/${thread.id}`
|
|
6729
|
+
})
|
|
6730
|
+
}
|
|
6731
|
+
]
|
|
6732
|
+
};
|
|
6733
|
+
} catch (err) {
|
|
6734
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6735
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6736
|
+
}
|
|
6737
|
+
}
|
|
6738
|
+
);
|
|
6739
|
+
server.tool(
|
|
6740
|
+
"fork_chat",
|
|
6741
|
+
"Fork a chat into a NEW tab on the SAME workspace: worktree agent \u2192 same worktree tab; Global orchestration chat \u2192 new orchestration chat (same synthetic home). Seeds a transcript; optional agent override. Leave model unset for Auto unless you have a reason. Orchestration forks require an MCP-capable agent (claude, cursor, codex, opencode \u2014 not brightsy). Remote coordinators use this to continue an orchestration chat on another agent after session limits. Then send_to_thread / wait_for_turn on the returned id. Use fork_worktree only for worktree agents that need a new git worktree.",
|
|
6742
|
+
{
|
|
6743
|
+
ref: z.string().describe("Thread id/ref to fork (worktree agent or orchestration chat)"),
|
|
6744
|
+
through_index: z.number().optional().describe("Inclusive message index to include in the transcript (default: all)"),
|
|
6745
|
+
agent: agentEnum.optional().describe("Agent for the forked chat (default: same as source)"),
|
|
6746
|
+
model: z.string().nullable().optional().describe("Usually omit (Auto). Only set from list_models when you need a specific model"),
|
|
6747
|
+
title: z.string().optional()
|
|
6748
|
+
},
|
|
6749
|
+
async ({ ref, through_index, agent, model, title }) => {
|
|
6750
|
+
try {
|
|
6751
|
+
const source = orch.getThread(ref);
|
|
6752
|
+
if (!source) {
|
|
6753
|
+
return {
|
|
6754
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6755
|
+
isError: true
|
|
6756
|
+
};
|
|
6630
6757
|
}
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6758
|
+
const tab = orch.forkChatTab({
|
|
6759
|
+
threadId: source.id,
|
|
6760
|
+
throughIndex: through_index,
|
|
6761
|
+
agent,
|
|
6762
|
+
model,
|
|
6763
|
+
title
|
|
6764
|
+
});
|
|
6765
|
+
return {
|
|
6766
|
+
content: [
|
|
6767
|
+
{
|
|
6768
|
+
type: "text",
|
|
6769
|
+
text: JSON.stringify({
|
|
6770
|
+
id: tab.id,
|
|
6771
|
+
title: tab.title,
|
|
6772
|
+
status: tab.status,
|
|
6773
|
+
agent: tab.agent,
|
|
6774
|
+
model: tab.model,
|
|
6775
|
+
sourceType: tab.sourceType,
|
|
6776
|
+
worktreePath: tab.worktreePath,
|
|
6777
|
+
fromThreadId: source.id,
|
|
6778
|
+
link: `sideboard://thread/${tab.id}`
|
|
6779
|
+
})
|
|
6780
|
+
}
|
|
6781
|
+
]
|
|
6782
|
+
};
|
|
6783
|
+
} catch (err) {
|
|
6784
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6785
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
);
|
|
6789
|
+
server.tool(
|
|
6790
|
+
"run_dev_script",
|
|
6791
|
+
"Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
|
|
6792
|
+
{
|
|
6793
|
+
ref: z.string(),
|
|
6794
|
+
name: z.string().optional()
|
|
6795
|
+
},
|
|
6796
|
+
async ({ ref, name }) => {
|
|
6797
|
+
const result = await orch.startDev(ref, name);
|
|
6643
6798
|
return {
|
|
6644
6799
|
content: [
|
|
6645
6800
|
{
|
|
6646
6801
|
type: "text",
|
|
6647
6802
|
text: JSON.stringify({
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
link: `sideboard://thread/${tab.id}`
|
|
6803
|
+
port: result.port,
|
|
6804
|
+
scriptName: result.scriptName,
|
|
6805
|
+
ports: result.ports,
|
|
6806
|
+
url: `http://localhost:${result.port}`
|
|
6653
6807
|
})
|
|
6654
6808
|
}
|
|
6655
6809
|
]
|
|
6656
6810
|
};
|
|
6657
|
-
} catch (err) {
|
|
6658
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6659
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6660
6811
|
}
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
},
|
|
6670
|
-
async ({ agent }) => {
|
|
6671
|
-
try {
|
|
6672
|
-
const catalogs = await listModelsForAgent(agent);
|
|
6812
|
+
);
|
|
6813
|
+
server.tool(
|
|
6814
|
+
"list_run_scripts",
|
|
6815
|
+
"List named run scripts available for a thread",
|
|
6816
|
+
{ ref: z.string() },
|
|
6817
|
+
async ({ ref }) => {
|
|
6818
|
+
const scripts = orch.listThreadRunScripts(ref);
|
|
6819
|
+
const active = orch.getActiveRuns(ref);
|
|
6673
6820
|
return {
|
|
6674
|
-
content: [
|
|
6821
|
+
content: [
|
|
6822
|
+
{
|
|
6823
|
+
type: "text",
|
|
6824
|
+
text: JSON.stringify({ scripts, active }, null, 2)
|
|
6825
|
+
}
|
|
6826
|
+
]
|
|
6675
6827
|
};
|
|
6676
|
-
} catch (err) {
|
|
6677
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6678
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6679
6828
|
}
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6829
|
+
);
|
|
6830
|
+
server.tool(
|
|
6831
|
+
"stop_dev_script",
|
|
6832
|
+
"Stop a running script for a thread (all scripts if name omitted)",
|
|
6833
|
+
{
|
|
6834
|
+
ref: z.string(),
|
|
6835
|
+
name: z.string().optional()
|
|
6836
|
+
},
|
|
6837
|
+
async ({ ref, name }) => {
|
|
6838
|
+
orch.stopDev(ref, name);
|
|
6839
|
+
return { content: [{ type: "text", text: "ok" }] };
|
|
6840
|
+
}
|
|
6841
|
+
);
|
|
6842
|
+
server.tool(
|
|
6843
|
+
"run_setup",
|
|
6844
|
+
"Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
|
|
6845
|
+
{ ref: z.string() },
|
|
6846
|
+
async ({ ref }) => {
|
|
6847
|
+
const result = await orch.runSetup(ref);
|
|
6848
|
+
return {
|
|
6849
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
6850
|
+
};
|
|
6851
|
+
}
|
|
6852
|
+
);
|
|
6853
|
+
server.tool(
|
|
6854
|
+
"add_workspace",
|
|
6855
|
+
"Register a git repo as a Sideboard workspace",
|
|
6856
|
+
{ repoPath: z.string() },
|
|
6857
|
+
async ({ repoPath }) => {
|
|
6858
|
+
const ws = await orch.addWorkspace(repoPath);
|
|
6859
|
+
return { content: [{ type: "text", text: JSON.stringify(ws) }] };
|
|
6860
|
+
}
|
|
6861
|
+
);
|
|
6862
|
+
server.tool(
|
|
6863
|
+
"remove_workspace",
|
|
6864
|
+
"Unregister a Sideboard workspace (does not archive threads)",
|
|
6865
|
+
{ repoPath: z.string() },
|
|
6866
|
+
async ({ repoPath }) => {
|
|
6867
|
+
orch.removeWorkspace(repoPath);
|
|
6868
|
+
return { content: [{ type: "text", text: "ok" }] };
|
|
6869
|
+
}
|
|
6870
|
+
);
|
|
6871
|
+
server.tool(
|
|
6872
|
+
"fanout",
|
|
6873
|
+
"Best-of-n: create one thread per agent with the same prompt (parallel attempts)",
|
|
6874
|
+
{
|
|
6875
|
+
prompt: z.string(),
|
|
6876
|
+
agents: z.array(z.enum(["claude", "codex", "opencode", "brightsy", "cursor"])),
|
|
6877
|
+
repoPath: z.string(),
|
|
6878
|
+
sourceType: z.enum(["branch", "pr", "ticket"]).optional(),
|
|
6879
|
+
sourceRef: z.string().optional(),
|
|
6880
|
+
title: z.string().optional()
|
|
6881
|
+
},
|
|
6882
|
+
async (args) => {
|
|
6883
|
+
const threads = await orch.bestOfN(args);
|
|
6884
|
+
return {
|
|
6885
|
+
content: [
|
|
6886
|
+
{
|
|
6887
|
+
type: "text",
|
|
6888
|
+
text: JSON.stringify(
|
|
6889
|
+
threads.map((t) => ({
|
|
6890
|
+
id: t.id,
|
|
6891
|
+
agent: t.agent,
|
|
6892
|
+
branchName: t.branchName,
|
|
6893
|
+
worktreePath: t.worktreePath
|
|
6894
|
+
})),
|
|
6895
|
+
null,
|
|
6896
|
+
2
|
|
6897
|
+
)
|
|
6898
|
+
}
|
|
6899
|
+
]
|
|
6900
|
+
};
|
|
6901
|
+
}
|
|
6902
|
+
);
|
|
6903
|
+
server.tool(
|
|
6904
|
+
"list_branches",
|
|
6905
|
+
"List git branches in a registered workspace. Pass repoPath from list_workspaces (unmerged into the default branch by default \u2014 for create_thread sourceType=branch).",
|
|
6906
|
+
{
|
|
6907
|
+
repoPath: z.string(),
|
|
6908
|
+
unmergedOnly: z.boolean().optional()
|
|
6909
|
+
},
|
|
6910
|
+
async ({ repoPath, unmergedOnly }) => {
|
|
6911
|
+
const root = await resolveRepoRoot(repoPath);
|
|
6912
|
+
const branches = await listBranches(root, {
|
|
6913
|
+
unmergedOnly: unmergedOnly !== false
|
|
6702
6914
|
});
|
|
6703
6915
|
return {
|
|
6704
6916
|
content: [
|
|
6705
6917
|
{
|
|
6706
6918
|
type: "text",
|
|
6707
|
-
text:
|
|
6708
|
-
id: thread.id,
|
|
6709
|
-
title: thread.title,
|
|
6710
|
-
status: thread.status,
|
|
6711
|
-
agent: thread.agent,
|
|
6712
|
-
model: thread.model,
|
|
6713
|
-
branchName: thread.branchName,
|
|
6714
|
-
worktreePath: thread.worktreePath,
|
|
6715
|
-
fromThreadId: source?.id ?? ref,
|
|
6716
|
-
link: `sideboard://thread/${thread.id}`
|
|
6717
|
-
})
|
|
6919
|
+
text: branches.map((b) => `${b.current ? "*" : " "} ${b.name}`).join("\n")
|
|
6718
6920
|
}
|
|
6719
6921
|
]
|
|
6720
6922
|
};
|
|
6721
|
-
} catch (err) {
|
|
6722
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6723
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6724
6923
|
}
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6924
|
+
);
|
|
6925
|
+
server.tool(
|
|
6926
|
+
"list_prs",
|
|
6927
|
+
"List open GitHub PRs for a registered workspace. Pass repoPath from list_workspaces (uses gh against that repo remote). Then create_thread with sourceType=pr.",
|
|
6928
|
+
{ repoPath: z.string() },
|
|
6929
|
+
async ({ repoPath }) => {
|
|
6930
|
+
const root = await resolveRepoRoot(repoPath);
|
|
6931
|
+
const prs = await listPrs(root);
|
|
6932
|
+
return {
|
|
6933
|
+
content: [
|
|
6934
|
+
{
|
|
6935
|
+
type: "text",
|
|
6936
|
+
text: prs.map(
|
|
6937
|
+
(p) => `#${p.number} ${p.title} (${p.headRefName})${p.isCrossRepository ? " [fork]" : ""}`
|
|
6938
|
+
).join("\n")
|
|
6939
|
+
}
|
|
6940
|
+
]
|
|
6941
|
+
};
|
|
6942
|
+
}
|
|
6943
|
+
);
|
|
6944
|
+
server.tool(
|
|
6945
|
+
"get_pr_stack",
|
|
6946
|
+
"Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before mergePr on stacked PRs.",
|
|
6947
|
+
{ ref: z.string() },
|
|
6948
|
+
async ({ ref }) => {
|
|
6949
|
+
const stack = await orch.getPrStack(ref);
|
|
6950
|
+
return {
|
|
6951
|
+
content: [{ type: "text", text: JSON.stringify(stack, null, 2) }]
|
|
6952
|
+
};
|
|
6953
|
+
}
|
|
6954
|
+
);
|
|
6955
|
+
server.tool(
|
|
6956
|
+
"open_pr_stack_layers",
|
|
6957
|
+
"Materialize one worktree+thread per stack layer (or a single 1-based layer). Pass a thread ref already on the stack.",
|
|
6958
|
+
{
|
|
6959
|
+
ref: z.string(),
|
|
6960
|
+
layer: z.number().int().positive().optional()
|
|
6961
|
+
},
|
|
6962
|
+
async ({ ref, layer }) => {
|
|
6963
|
+
const result = await orch.openPrStackLayers(ref, { layer });
|
|
6964
|
+
return {
|
|
6965
|
+
content: [
|
|
6966
|
+
{
|
|
6967
|
+
type: "text",
|
|
6968
|
+
text: JSON.stringify(
|
|
6969
|
+
{
|
|
6970
|
+
stackNumber: result.stack.stackNumber,
|
|
6971
|
+
trunk: result.stack.trunk,
|
|
6972
|
+
threads: result.threads.map((t) => ({
|
|
6973
|
+
id: t.id,
|
|
6974
|
+
title: t.title,
|
|
6975
|
+
branchName: t.branchName,
|
|
6976
|
+
stackLayer: t.stackLayer,
|
|
6977
|
+
worktreePath: t.worktreePath,
|
|
6978
|
+
prUrl: t.prUrl,
|
|
6979
|
+
link: `sideboard://thread/${t.id}`
|
|
6980
|
+
}))
|
|
6981
|
+
},
|
|
6982
|
+
null,
|
|
6983
|
+
2
|
|
6984
|
+
)
|
|
6985
|
+
}
|
|
6986
|
+
]
|
|
6987
|
+
};
|
|
6988
|
+
}
|
|
6989
|
+
);
|
|
6990
|
+
server.tool(
|
|
6991
|
+
"add_stack_layer",
|
|
6992
|
+
"Add a branch on top of the current stack (`gh stack add`) and open a worktree+thread for it.",
|
|
6993
|
+
{
|
|
6994
|
+
ref: z.string(),
|
|
6995
|
+
branchName: z.string(),
|
|
6996
|
+
title: z.string().optional()
|
|
6997
|
+
},
|
|
6998
|
+
async ({ ref, branchName, title }) => {
|
|
6999
|
+
const result = await orch.addStackLayer(ref, branchName, { title });
|
|
7000
|
+
return {
|
|
7001
|
+
content: [
|
|
7002
|
+
{
|
|
7003
|
+
type: "text",
|
|
7004
|
+
text: JSON.stringify(
|
|
7005
|
+
{
|
|
7006
|
+
id: result.thread.id,
|
|
7007
|
+
title: result.thread.title,
|
|
7008
|
+
branchName: result.thread.branchName,
|
|
7009
|
+
stackLayer: result.thread.stackLayer,
|
|
7010
|
+
worktreePath: result.thread.worktreePath,
|
|
7011
|
+
link: `sideboard://thread/${result.thread.id}`
|
|
7012
|
+
},
|
|
7013
|
+
null,
|
|
7014
|
+
2
|
|
7015
|
+
)
|
|
7016
|
+
}
|
|
7017
|
+
]
|
|
7018
|
+
};
|
|
7019
|
+
}
|
|
7020
|
+
);
|
|
7021
|
+
server.tool(
|
|
7022
|
+
"create_pr_stack",
|
|
7023
|
+
"Create a new GitHub PR stack with one Sideboard worktree per layer (bottom\u2192top branch names). Requires `gh extension install github/gh-stack`.",
|
|
7024
|
+
{
|
|
7025
|
+
repoPath: z.string(),
|
|
7026
|
+
branches: z.array(z.string()).min(1),
|
|
7027
|
+
agent: z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]),
|
|
7028
|
+
base: z.string().optional(),
|
|
7029
|
+
title: z.string().optional()
|
|
7030
|
+
},
|
|
7031
|
+
async (args) => {
|
|
7032
|
+
const result = await orch.createPrStack({
|
|
7033
|
+
repoPath: args.repoPath,
|
|
7034
|
+
branches: args.branches,
|
|
7035
|
+
agent: args.agent,
|
|
7036
|
+
base: args.base,
|
|
7037
|
+
title: args.title
|
|
6752
7038
|
});
|
|
6753
7039
|
return {
|
|
6754
7040
|
content: [
|
|
6755
7041
|
{
|
|
6756
7042
|
type: "text",
|
|
6757
|
-
text: JSON.stringify(
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
7043
|
+
text: JSON.stringify(
|
|
7044
|
+
{
|
|
7045
|
+
stackNumber: result.stack.stackNumber,
|
|
7046
|
+
trunk: result.stack.trunk,
|
|
7047
|
+
threads: result.threads.map((t) => ({
|
|
7048
|
+
id: t.id,
|
|
7049
|
+
title: t.title,
|
|
7050
|
+
branchName: t.branchName,
|
|
7051
|
+
stackLayer: t.stackLayer,
|
|
7052
|
+
worktreePath: t.worktreePath,
|
|
7053
|
+
link: `sideboard://thread/${t.id}`
|
|
7054
|
+
}))
|
|
7055
|
+
},
|
|
7056
|
+
null,
|
|
7057
|
+
2
|
|
7058
|
+
)
|
|
6768
7059
|
}
|
|
6769
7060
|
]
|
|
6770
7061
|
};
|
|
6771
|
-
} catch (err) {
|
|
6772
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6773
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6774
7062
|
}
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
}
|
|
6800
|
-
);
|
|
6801
|
-
server.tool(
|
|
6802
|
-
"list_run_scripts",
|
|
6803
|
-
"List named run scripts available for a thread",
|
|
6804
|
-
{ ref: z.string() },
|
|
6805
|
-
async ({ ref }) => {
|
|
6806
|
-
const scripts = orch.listThreadRunScripts(ref);
|
|
6807
|
-
const active = orch.getActiveRuns(ref);
|
|
6808
|
-
return {
|
|
6809
|
-
content: [
|
|
6810
|
-
{
|
|
6811
|
-
type: "text",
|
|
6812
|
-
text: JSON.stringify({ scripts, active }, null, 2)
|
|
6813
|
-
}
|
|
6814
|
-
]
|
|
6815
|
-
};
|
|
6816
|
-
}
|
|
6817
|
-
);
|
|
6818
|
-
server.tool(
|
|
6819
|
-
"stop_dev_script",
|
|
6820
|
-
"Stop a running script for a thread (all scripts if name omitted)",
|
|
6821
|
-
{
|
|
6822
|
-
ref: z.string(),
|
|
6823
|
-
name: z.string().optional()
|
|
6824
|
-
},
|
|
6825
|
-
async ({ ref, name }) => {
|
|
6826
|
-
orch.stopDev(ref, name);
|
|
6827
|
-
return { content: [{ type: "text", text: "ok" }] };
|
|
6828
|
-
}
|
|
6829
|
-
);
|
|
6830
|
-
server.tool(
|
|
6831
|
-
"run_setup",
|
|
6832
|
-
"Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
|
|
6833
|
-
{ ref: z.string() },
|
|
6834
|
-
async ({ ref }) => {
|
|
6835
|
-
const result = await orch.runSetup(ref);
|
|
6836
|
-
return {
|
|
6837
|
-
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
6838
|
-
};
|
|
6839
|
-
}
|
|
6840
|
-
);
|
|
6841
|
-
server.tool(
|
|
6842
|
-
"add_workspace",
|
|
6843
|
-
"Register a git repo as a Sideboard workspace",
|
|
6844
|
-
{ repoPath: z.string() },
|
|
6845
|
-
async ({ repoPath }) => {
|
|
6846
|
-
const ws = await orch.addWorkspace(repoPath);
|
|
6847
|
-
return { content: [{ type: "text", text: JSON.stringify(ws) }] };
|
|
6848
|
-
}
|
|
6849
|
-
);
|
|
6850
|
-
server.tool(
|
|
6851
|
-
"remove_workspace",
|
|
6852
|
-
"Unregister a Sideboard workspace (does not archive threads)",
|
|
6853
|
-
{ repoPath: z.string() },
|
|
6854
|
-
async ({ repoPath }) => {
|
|
6855
|
-
orch.removeWorkspace(repoPath);
|
|
6856
|
-
return { content: [{ type: "text", text: "ok" }] };
|
|
6857
|
-
}
|
|
6858
|
-
);
|
|
6859
|
-
server.tool(
|
|
6860
|
-
"fanout",
|
|
6861
|
-
"Best-of-n: create one thread per agent with the same prompt (parallel attempts)",
|
|
6862
|
-
{
|
|
6863
|
-
prompt: z.string(),
|
|
6864
|
-
agents: z.array(z.enum(["claude", "codex", "opencode", "brightsy", "cursor"])),
|
|
6865
|
-
repoPath: z.string(),
|
|
6866
|
-
sourceType: z.enum(["branch", "pr", "ticket"]).optional(),
|
|
6867
|
-
sourceRef: z.string().optional(),
|
|
6868
|
-
title: z.string().optional()
|
|
6869
|
-
},
|
|
6870
|
-
async (args) => {
|
|
6871
|
-
const threads = await orch.bestOfN(args);
|
|
6872
|
-
return {
|
|
6873
|
-
content: [
|
|
6874
|
-
{
|
|
6875
|
-
type: "text",
|
|
6876
|
-
text: JSON.stringify(
|
|
6877
|
-
threads.map((t) => ({
|
|
6878
|
-
id: t.id,
|
|
6879
|
-
agent: t.agent,
|
|
6880
|
-
branchName: t.branchName,
|
|
6881
|
-
worktreePath: t.worktreePath
|
|
6882
|
-
})),
|
|
6883
|
-
null,
|
|
6884
|
-
2
|
|
6885
|
-
)
|
|
6886
|
-
}
|
|
6887
|
-
]
|
|
6888
|
-
};
|
|
6889
|
-
}
|
|
6890
|
-
);
|
|
6891
|
-
server.tool(
|
|
6892
|
-
"list_branches",
|
|
6893
|
-
"List git branches in a registered workspace. Pass repoPath from list_workspaces (unmerged into the default branch by default \u2014 for create_thread sourceType=branch).",
|
|
6894
|
-
{
|
|
6895
|
-
repoPath: z.string(),
|
|
6896
|
-
unmergedOnly: z.boolean().optional()
|
|
6897
|
-
},
|
|
6898
|
-
async ({ repoPath, unmergedOnly }) => {
|
|
6899
|
-
const root = await resolveRepoRoot(repoPath);
|
|
6900
|
-
const branches = await listBranches(root, {
|
|
6901
|
-
unmergedOnly: unmergedOnly !== false
|
|
6902
|
-
});
|
|
6903
|
-
return {
|
|
6904
|
-
content: [
|
|
6905
|
-
{
|
|
6906
|
-
type: "text",
|
|
6907
|
-
text: branches.map((b) => `${b.current ? "*" : " "} ${b.name}`).join("\n")
|
|
6908
|
-
}
|
|
6909
|
-
]
|
|
6910
|
-
};
|
|
6911
|
-
}
|
|
6912
|
-
);
|
|
6913
|
-
server.tool(
|
|
6914
|
-
"list_prs",
|
|
6915
|
-
"List open GitHub PRs for a registered workspace. Pass repoPath from list_workspaces (uses gh against that repo remote). Then create_thread with sourceType=pr.",
|
|
6916
|
-
{ repoPath: z.string() },
|
|
6917
|
-
async ({ repoPath }) => {
|
|
6918
|
-
const root = await resolveRepoRoot(repoPath);
|
|
6919
|
-
const prs = await listPrs(root);
|
|
6920
|
-
return {
|
|
6921
|
-
content: [
|
|
6922
|
-
{
|
|
6923
|
-
type: "text",
|
|
6924
|
-
text: prs.map(
|
|
6925
|
-
(p) => `#${p.number} ${p.title} (${p.headRefName})${p.isCrossRepository ? " [fork]" : ""}`
|
|
6926
|
-
).join("\n")
|
|
6927
|
-
}
|
|
6928
|
-
]
|
|
6929
|
-
};
|
|
6930
|
-
}
|
|
6931
|
-
);
|
|
6932
|
-
server.tool(
|
|
6933
|
-
"get_pr_stack",
|
|
6934
|
-
"Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before mergePr on stacked PRs.",
|
|
6935
|
-
{ ref: z.string() },
|
|
6936
|
-
async ({ ref }) => {
|
|
6937
|
-
const stack = await orch.getPrStack(ref);
|
|
6938
|
-
return {
|
|
6939
|
-
content: [{ type: "text", text: JSON.stringify(stack, null, 2) }]
|
|
6940
|
-
};
|
|
6941
|
-
}
|
|
6942
|
-
);
|
|
6943
|
-
server.tool(
|
|
6944
|
-
"open_pr_stack_layers",
|
|
6945
|
-
"Materialize one worktree+thread per stack layer (or a single 1-based layer). Pass a thread ref already on the stack.",
|
|
6946
|
-
{
|
|
6947
|
-
ref: z.string(),
|
|
6948
|
-
layer: z.number().int().positive().optional()
|
|
6949
|
-
},
|
|
6950
|
-
async ({ ref, layer }) => {
|
|
6951
|
-
const result = await orch.openPrStackLayers(ref, { layer });
|
|
6952
|
-
return {
|
|
6953
|
-
content: [
|
|
6954
|
-
{
|
|
6955
|
-
type: "text",
|
|
6956
|
-
text: JSON.stringify(
|
|
6957
|
-
{
|
|
6958
|
-
stackNumber: result.stack.stackNumber,
|
|
6959
|
-
trunk: result.stack.trunk,
|
|
6960
|
-
threads: result.threads.map((t) => ({
|
|
6961
|
-
id: t.id,
|
|
6962
|
-
title: t.title,
|
|
6963
|
-
branchName: t.branchName,
|
|
6964
|
-
stackLayer: t.stackLayer,
|
|
6965
|
-
worktreePath: t.worktreePath,
|
|
6966
|
-
prUrl: t.prUrl,
|
|
6967
|
-
link: `sideboard://thread/${t.id}`
|
|
6968
|
-
}))
|
|
6969
|
-
},
|
|
6970
|
-
null,
|
|
6971
|
-
2
|
|
6972
|
-
)
|
|
6973
|
-
}
|
|
6974
|
-
]
|
|
6975
|
-
};
|
|
6976
|
-
}
|
|
6977
|
-
);
|
|
6978
|
-
server.tool(
|
|
6979
|
-
"add_stack_layer",
|
|
6980
|
-
"Add a branch on top of the current stack (`gh stack add`) and open a worktree+thread for it.",
|
|
6981
|
-
{
|
|
6982
|
-
ref: z.string(),
|
|
6983
|
-
branchName: z.string(),
|
|
6984
|
-
title: z.string().optional()
|
|
6985
|
-
},
|
|
6986
|
-
async ({ ref, branchName, title }) => {
|
|
6987
|
-
const result = await orch.addStackLayer(ref, branchName, { title });
|
|
6988
|
-
return {
|
|
6989
|
-
content: [
|
|
6990
|
-
{
|
|
6991
|
-
type: "text",
|
|
6992
|
-
text: JSON.stringify(
|
|
6993
|
-
{
|
|
6994
|
-
id: result.thread.id,
|
|
6995
|
-
title: result.thread.title,
|
|
6996
|
-
branchName: result.thread.branchName,
|
|
6997
|
-
stackLayer: result.thread.stackLayer,
|
|
6998
|
-
worktreePath: result.thread.worktreePath,
|
|
6999
|
-
link: `sideboard://thread/${result.thread.id}`
|
|
7000
|
-
},
|
|
7001
|
-
null,
|
|
7002
|
-
2
|
|
7003
|
-
)
|
|
7004
|
-
}
|
|
7005
|
-
]
|
|
7006
|
-
};
|
|
7007
|
-
}
|
|
7008
|
-
);
|
|
7009
|
-
server.tool(
|
|
7010
|
-
"create_pr_stack",
|
|
7011
|
-
"Create a new GitHub PR stack with one Sideboard worktree per layer (bottom\u2192top branch names). Requires `gh extension install github/gh-stack`.",
|
|
7012
|
-
{
|
|
7013
|
-
repoPath: z.string(),
|
|
7014
|
-
branches: z.array(z.string()).min(1),
|
|
7015
|
-
agent: z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]),
|
|
7016
|
-
base: z.string().optional(),
|
|
7017
|
-
title: z.string().optional()
|
|
7018
|
-
},
|
|
7019
|
-
async (args) => {
|
|
7020
|
-
const result = await orch.createPrStack({
|
|
7021
|
-
repoPath: args.repoPath,
|
|
7022
|
-
branches: args.branches,
|
|
7023
|
-
agent: args.agent,
|
|
7024
|
-
base: args.base,
|
|
7025
|
-
title: args.title
|
|
7026
|
-
});
|
|
7027
|
-
return {
|
|
7028
|
-
content: [
|
|
7029
|
-
{
|
|
7030
|
-
type: "text",
|
|
7031
|
-
text: JSON.stringify(
|
|
7032
|
-
{
|
|
7033
|
-
stackNumber: result.stack.stackNumber,
|
|
7034
|
-
trunk: result.stack.trunk,
|
|
7035
|
-
threads: result.threads.map((t) => ({
|
|
7036
|
-
id: t.id,
|
|
7037
|
-
title: t.title,
|
|
7038
|
-
branchName: t.branchName,
|
|
7039
|
-
stackLayer: t.stackLayer,
|
|
7040
|
-
worktreePath: t.worktreePath,
|
|
7041
|
-
link: `sideboard://thread/${t.id}`
|
|
7042
|
-
}))
|
|
7043
|
-
},
|
|
7044
|
-
null,
|
|
7045
|
-
2
|
|
7046
|
-
)
|
|
7047
|
-
}
|
|
7048
|
-
]
|
|
7049
|
-
};
|
|
7050
|
-
}
|
|
7051
|
-
);
|
|
7052
|
-
server.tool(
|
|
7053
|
-
"list_issues",
|
|
7054
|
-
"List issues from Sideboard Account connections (Linear API or GitHub Issues; Linear\u2192GitHub fallback when Linear is not connected). Pass repoPath from list_workspaces \u2014 GitHub Issues are scoped to that repo. Then create_thread with sourceType=ticket.",
|
|
7055
|
-
{ repoPath: z.string() },
|
|
7056
|
-
async ({ repoPath }) => {
|
|
7057
|
-
const root = await resolveRepoRoot(repoPath);
|
|
7058
|
-
const result = await listIssues(root);
|
|
7059
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
7060
|
-
}
|
|
7061
|
-
);
|
|
7062
|
-
server.tool(
|
|
7063
|
-
"list_linear_issues",
|
|
7064
|
-
"Deprecated: prefer list_issues. Lists assigned Linear issues via the chosen agent MCP connector",
|
|
7065
|
-
{
|
|
7066
|
-
agent: z.enum(["claude", "codex", "opencode"]),
|
|
7067
|
-
repoPath: z.string()
|
|
7068
|
-
},
|
|
7069
|
-
async ({ agent, repoPath }) => {
|
|
7070
|
-
const issues = await listLinearIssues(agent, repoPath);
|
|
7071
|
-
return { content: [{ type: "text", text: JSON.stringify(issues, null, 2) }] };
|
|
7072
|
-
}
|
|
7073
|
-
);
|
|
7063
|
+
);
|
|
7064
|
+
server.tool(
|
|
7065
|
+
"list_issues",
|
|
7066
|
+
"List issues from Sideboard Account connections (Linear API or GitHub Issues; Linear\u2192GitHub fallback when Linear is not connected). Pass repoPath from list_workspaces \u2014 GitHub Issues are scoped to that repo. Then create_thread with sourceType=ticket.",
|
|
7067
|
+
{ repoPath: z.string() },
|
|
7068
|
+
async ({ repoPath }) => {
|
|
7069
|
+
const root = await resolveRepoRoot(repoPath);
|
|
7070
|
+
const result = await listIssues(root);
|
|
7071
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
7072
|
+
}
|
|
7073
|
+
);
|
|
7074
|
+
server.tool(
|
|
7075
|
+
"list_linear_issues",
|
|
7076
|
+
"Deprecated: prefer list_issues. Lists assigned Linear issues via the chosen agent MCP connector",
|
|
7077
|
+
{
|
|
7078
|
+
agent: z.enum(["claude", "codex", "opencode"]),
|
|
7079
|
+
repoPath: z.string()
|
|
7080
|
+
},
|
|
7081
|
+
async ({ agent, repoPath }) => {
|
|
7082
|
+
const issues = await listLinearIssues(agent, repoPath);
|
|
7083
|
+
return { content: [{ type: "text", text: JSON.stringify(issues, null, 2) }] };
|
|
7084
|
+
}
|
|
7085
|
+
);
|
|
7086
|
+
}
|
|
7074
7087
|
const transport = new StdioServerTransport();
|
|
7075
7088
|
await server.connect(transport);
|
|
7076
7089
|
}
|
|
@@ -7436,6 +7449,7 @@ export {
|
|
|
7436
7449
|
REVIEW_REQUEST_PREFILL,
|
|
7437
7450
|
SIDEBOARD_FORCE_STOP,
|
|
7438
7451
|
SIDEBOARD_MCP_ALLOWED_TOOLS,
|
|
7452
|
+
SIDEBOARD_MCP_PROFILE_ENV,
|
|
7439
7453
|
THINKING_EFFORTS,
|
|
7440
7454
|
addPrStackLayer,
|
|
7441
7455
|
addStackLayerFromThread,
|
|
@@ -7467,6 +7481,7 @@ export {
|
|
|
7467
7481
|
brightsyCloudConnectAgent,
|
|
7468
7482
|
brightsyCloudConnectEnabled,
|
|
7469
7483
|
brightsyConfigPath,
|
|
7484
|
+
brightsyInjectWorktreeMcpEnabled,
|
|
7470
7485
|
brightsyMcpAllowedTools,
|
|
7471
7486
|
brightsyMcpServerName,
|
|
7472
7487
|
buildCachedUserContent,
|
|
@@ -7518,7 +7533,9 @@ export {
|
|
|
7518
7533
|
detectLocalMergeConflicts,
|
|
7519
7534
|
disconnectBrightsyTeam,
|
|
7520
7535
|
discoverSkills,
|
|
7536
|
+
dropCachedPrefixOnResume,
|
|
7521
7537
|
encodeBrightsyTarget,
|
|
7538
|
+
enrichPathWithNpmGlobalBin,
|
|
7522
7539
|
enrichWorkspacesWithGithub,
|
|
7523
7540
|
ensureAgentPath,
|
|
7524
7541
|
ensureCloudCoordinator,
|
|
@@ -7556,6 +7573,7 @@ export {
|
|
|
7556
7573
|
formatTranscriptMarkdown,
|
|
7557
7574
|
formatWorkspaceInventory,
|
|
7558
7575
|
formatWorktreeDirective,
|
|
7576
|
+
formatWorktreeReminder,
|
|
7559
7577
|
getAdapter,
|
|
7560
7578
|
getAgentSetupInfo,
|
|
7561
7579
|
getBrightsySession,
|
|
@@ -7682,7 +7700,10 @@ export {
|
|
|
7682
7700
|
pastedTextStats,
|
|
7683
7701
|
permissionMode,
|
|
7684
7702
|
planFileAbs,
|
|
7703
|
+
posixShellSingleQuote,
|
|
7704
|
+
prepareTerminalCommand,
|
|
7685
7705
|
previewLand,
|
|
7706
|
+
promptMentionsBrightsy,
|
|
7686
7707
|
pushBranch,
|
|
7687
7708
|
readExistingReviewRequestFile,
|
|
7688
7709
|
readPlanFile,
|
|
@@ -7698,7 +7719,9 @@ export {
|
|
|
7698
7719
|
requestReview,
|
|
7699
7720
|
requireAgent,
|
|
7700
7721
|
resetGhStackDetectCache,
|
|
7722
|
+
resolveAgentExecutable,
|
|
7701
7723
|
resolveClaudeExecutable,
|
|
7724
|
+
resolveCommandBinarySync,
|
|
7702
7725
|
resolveConductorCursorAgentId,
|
|
7703
7726
|
resolveCursorModelId,
|
|
7704
7727
|
resolveDefaultBranch,
|
|
@@ -7707,6 +7730,7 @@ export {
|
|
|
7707
7730
|
resolveFilesToCopy,
|
|
7708
7731
|
resolveGhAuthToken,
|
|
7709
7732
|
resolveGithubRepoSlug,
|
|
7733
|
+
resolveLoginCommand,
|
|
7710
7734
|
resolveNewThreadOptions,
|
|
7711
7735
|
resolvePlanMarkdown,
|
|
7712
7736
|
resolvePrSelector,
|
|
@@ -7728,9 +7752,11 @@ export {
|
|
|
7728
7752
|
settingsSourceLabel,
|
|
7729
7753
|
shouldAttachPastedText,
|
|
7730
7754
|
shouldCompactContext,
|
|
7755
|
+
shouldInjectBrightsyMcp,
|
|
7731
7756
|
shouldRefreshReviewRequestTemplate,
|
|
7732
7757
|
shouldRunWorktreeCleanup,
|
|
7733
7758
|
sideboardHomeDir,
|
|
7759
|
+
sideboardMcpProfile,
|
|
7734
7760
|
sideboardReposDir,
|
|
7735
7761
|
sideboardWorkspacesDir,
|
|
7736
7762
|
slugify,
|
|
@@ -7758,6 +7784,7 @@ export {
|
|
|
7758
7784
|
threadDisplayLabel,
|
|
7759
7785
|
threadFilePath,
|
|
7760
7786
|
threadLockPath,
|
|
7787
|
+
threadRequestsBrightsyMcp,
|
|
7761
7788
|
threadsDir,
|
|
7762
7789
|
threadsSharingWorktree,
|
|
7763
7790
|
toolDescription,
|
|
@@ -7765,14 +7792,18 @@ export {
|
|
|
7765
7792
|
toolFilePath,
|
|
7766
7793
|
totalTokens,
|
|
7767
7794
|
updateAdvancedSettings,
|
|
7795
|
+
updateAgentExecutable,
|
|
7768
7796
|
updateAppEnvironment,
|
|
7769
7797
|
updateBrightsySettings,
|
|
7770
7798
|
updateClaudeSettings,
|
|
7799
|
+
updateCodexSettings,
|
|
7771
7800
|
updateDefaultsSettings,
|
|
7772
7801
|
updateIntegrationsSettings,
|
|
7802
|
+
updateOpencodeSettings,
|
|
7773
7803
|
updateThread,
|
|
7774
7804
|
validateLinearApiKey,
|
|
7775
7805
|
withAgentInstructions,
|
|
7806
|
+
withExportedPath,
|
|
7776
7807
|
withThreadLock,
|
|
7777
7808
|
workspaceSettingsSourceLabel,
|
|
7778
7809
|
worktreeCleanupSettings,
|