@sideboard-ai/core 0.1.62 → 0.1.67
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-KF3J3C53.js → agents-OTBZVTZO.js} +27 -7
- package/dist/{agents-QLSFIQAO.js → agents-TS3EI2YI.js} +27 -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-UGXSSBFJ.js → chunk-4BUCGNZS.js} +1 -1
- package/dist/chunk-4UIYN56C.js +173 -0
- package/dist/{chunk-NVU7EC2E.js → chunk-57WWNMFP.js} +2 -2
- package/dist/{chunk-A6FOKNOU.js → chunk-5HTTCYWA.js} +2 -2
- package/dist/{chunk-DXTGDXO2.js → chunk-7ZOQY4A7.js} +31 -6
- package/dist/{chunk-ZF5YJCXO.js → chunk-B4PRRKMA.js} +284 -93
- package/dist/{chunk-DDN3UF4R.js → chunk-BPOTVI5J.js} +115 -3
- package/dist/{chunk-MBAL5FE6.js → chunk-DB3I75FI.js} +4 -4
- package/dist/chunk-FGDJOJ2L.js +176 -0
- package/dist/{chunk-2FEA4LDA.js → chunk-JWZNK3CQ.js} +31 -6
- package/dist/{chunk-2MCNURQV.js → chunk-K7LM4CLD.js} +279 -93
- package/dist/{chunk-3KKNTHUC.js → chunk-LW5CMQGZ.js} +1 -1
- package/dist/{chunk-JB2H7E7V.js → chunk-M5V4QIWF.js} +1 -1
- package/dist/{chunk-6CUJQKTJ.js → chunk-MHR4OGZ4.js} +115 -3
- package/dist/{chunk-46KMKHSD.js → chunk-WAFIF22N.js} +2 -2
- package/dist/{chunk-27MAWNKY.js → chunk-ZRFAZVGL.js} +2 -2
- package/dist/{connected-teams-MKIYKOYA.js → connected-teams-OMDHTL6A.js} +2 -2
- package/dist/{connected-teams-RSL4VB3X.js → connected-teams-RUNMOCG5.js} +2 -2
- package/dist/{coordinator-prompt-N2R6FGZK.js → coordinator-prompt-3BSMKZL4.js} +4 -4
- package/dist/{coordinator-prompt-LKG3SHMI.js → coordinator-prompt-6HMTOX4G.js} +4 -4
- package/dist/{global-workspace-LALWQWRJ.js → global-workspace-QS7A23CB.js} +5 -6
- package/dist/{global-workspace-YOAUQCMA.js → global-workspace-YZ2NJVLL.js} +5 -6
- package/dist/index.cjs +1345 -933
- package/dist/index.d.cts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +750 -715
- package/dist/mcp/run-stdio.cjs +1293 -977
- package/dist/mcp/run-stdio.js +691 -748
- package/dist/{run-GPSVV5OH.js → run-JLD2Y52J.js} +1 -1
- package/dist/{run-HZTBWGQR.js → run-Y2MI3EVV.js} +1 -1
- package/dist/{workspaces-E75POJXP.js → workspaces-AIUYUXB7.js} +6 -7
- package/dist/{workspaces-VCAIHVIE.js → workspaces-EBFW7I7S.js} +6 -7
- package/dist/{worktree-MV4WRW6G.js → worktree-7NBPIVFZ.js} +2 -2
- package/dist/{worktree-LZEGVQSN.js → worktree-WMDJW2BL.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-73AT5K4A.js +0 -104
- package/dist/chunk-GI7E5733.js +0 -30
- package/dist/chunk-RIWUU7FO.js +0 -107
- 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-WAFIF22N.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-B4PRRKMA.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-7ZOQY4A7.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-DB3I75FI.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-ZRFAZVGL.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-4BUCGNZS.js";
|
|
225
236
|
import {
|
|
226
237
|
ATTACHMENTS_DIR,
|
|
227
238
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -273,12 +284,18 @@ import {
|
|
|
273
284
|
worktreesRoot
|
|
274
285
|
} from "./chunk-M37RITA6.js";
|
|
275
286
|
import {
|
|
287
|
+
conductorBundledBinDir,
|
|
288
|
+
enrichPathWithNpmGlobalBin,
|
|
276
289
|
ensureAgentPath,
|
|
277
290
|
gh,
|
|
278
291
|
git,
|
|
292
|
+
isConductorBundledCli,
|
|
293
|
+
posixShellSingleQuote,
|
|
294
|
+
resolveCommandBinarySync,
|
|
279
295
|
resolveGhAuthToken,
|
|
280
|
-
run
|
|
281
|
-
|
|
296
|
+
run,
|
|
297
|
+
withExportedPath
|
|
298
|
+
} from "./chunk-4UIYN56C.js";
|
|
282
299
|
|
|
283
300
|
// src/integrations/github.ts
|
|
284
301
|
async function getGitHubStatus() {
|
|
@@ -707,9 +724,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
707
724
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
708
725
|
);
|
|
709
726
|
}
|
|
710
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
727
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-QS7A23CB.js");
|
|
711
728
|
if (isGlobalThread2(thread)) {
|
|
712
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
729
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-3BSMKZL4.js");
|
|
713
730
|
ensureGlobalCoordinatorCwd2(
|
|
714
731
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
715
732
|
);
|
|
@@ -911,6 +928,9 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
911
928
|
);
|
|
912
929
|
return lines.join("\n");
|
|
913
930
|
}
|
|
931
|
+
function formatWorktreeReminder() {
|
|
932
|
+
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.";
|
|
933
|
+
}
|
|
914
934
|
function formatArtifactDirective() {
|
|
915
935
|
return [
|
|
916
936
|
"Sideboard side column (desktop UI):",
|
|
@@ -996,11 +1016,13 @@ ${prompt}`;
|
|
|
996
1016
|
// src/detect/detect.ts
|
|
997
1017
|
async function detectAgents() {
|
|
998
1018
|
ensureAgentPath();
|
|
1019
|
+
enrichPathWithNpmGlobalBin();
|
|
999
1020
|
return Promise.all(allAdapters().map((a) => a.detect()));
|
|
1000
1021
|
}
|
|
1001
1022
|
var REQUIRE_AGENT_TIMEOUT_MS = 8e3;
|
|
1002
1023
|
async function requireAgent(agent, opts) {
|
|
1003
1024
|
ensureAgentPath();
|
|
1025
|
+
enrichPathWithNpmGlobalBin();
|
|
1004
1026
|
const status = await Promise.race([
|
|
1005
1027
|
getAdapter(agent).detect(),
|
|
1006
1028
|
new Promise((_, reject) => {
|
|
@@ -2842,7 +2864,7 @@ async function previewLand(thread) {
|
|
|
2842
2864
|
const target = await resolveDefaultBranch(thread.repoPath);
|
|
2843
2865
|
if (thread.branchName === target || thread.branchName === "main" || thread.branchName === "master") {
|
|
2844
2866
|
}
|
|
2845
|
-
const { stdout: head } = await import("./run-
|
|
2867
|
+
const { stdout: head } = await import("./run-JLD2Y52J.js").then(
|
|
2846
2868
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], thread.worktreePath)
|
|
2847
2869
|
);
|
|
2848
2870
|
const current = head.trim();
|
|
@@ -2881,7 +2903,7 @@ async function confirmLand(thread, opts) {
|
|
|
2881
2903
|
if (preview.dirty) {
|
|
2882
2904
|
committed = await commitAll(thread.worktreePath, meta.commitMessage);
|
|
2883
2905
|
}
|
|
2884
|
-
const { git: git2 } = await import("./run-
|
|
2906
|
+
const { git: git2 } = await import("./run-JLD2Y52J.js");
|
|
2885
2907
|
const { stdout: headOut } = await git2(
|
|
2886
2908
|
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
2887
2909
|
thread.worktreePath,
|
|
@@ -2979,7 +3001,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2979
3001
|
return readThread(thread.id) ?? thread;
|
|
2980
3002
|
}
|
|
2981
3003
|
async function listLinearIssues(agent, repoPath) {
|
|
2982
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
3004
|
+
const { getAdapter: getAdapter2 } = await import("./agents-TS3EI2YI.js");
|
|
2983
3005
|
await requireAgent(agent, { requireLinear: true });
|
|
2984
3006
|
const adapter = getAdapter2(agent);
|
|
2985
3007
|
if (!adapter.listLinearIssues) {
|
|
@@ -3507,7 +3529,7 @@ async function adoptThread(input) {
|
|
|
3507
3529
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
3508
3530
|
}
|
|
3509
3531
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
3510
|
-
const { stdout: branch } = await import("./run-
|
|
3532
|
+
const { stdout: branch } = await import("./run-JLD2Y52J.js").then(
|
|
3511
3533
|
({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
|
|
3512
3534
|
);
|
|
3513
3535
|
const thread = createEmptyThread({
|
|
@@ -3522,7 +3544,7 @@ async function adoptThread(input) {
|
|
|
3522
3544
|
messages: input.messages ?? []
|
|
3523
3545
|
});
|
|
3524
3546
|
writeThread(thread);
|
|
3525
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3547
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-EBFW7I7S.js");
|
|
3526
3548
|
await ensureWorkspace2(repoPath);
|
|
3527
3549
|
return thread;
|
|
3528
3550
|
}
|
|
@@ -4473,7 +4495,7 @@ var Orchestrator = class {
|
|
|
4473
4495
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
4474
4496
|
});
|
|
4475
4497
|
}
|
|
4476
|
-
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-
|
|
4498
|
+
const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4477
4499
|
if (autoCleanupOrphansEnabled2() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
4478
4500
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
4479
4501
|
}
|
|
@@ -4630,7 +4652,7 @@ var Orchestrator = class {
|
|
|
4630
4652
|
}
|
|
4631
4653
|
async finishCreateThread(threadId, prompt) {
|
|
4632
4654
|
await this.runSetupAfterCreate(threadId);
|
|
4633
|
-
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-
|
|
4655
|
+
const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4634
4656
|
if (autoRunAfterSetupEnabled2()) {
|
|
4635
4657
|
try {
|
|
4636
4658
|
await this.startDev(threadId);
|
|
@@ -4871,13 +4893,14 @@ var Orchestrator = class {
|
|
|
4871
4893
|
"Files column: MCP present_files (brightsy account storage or memory).",
|
|
4872
4894
|
"Do not say artifacts/CMS UI are unavailable."
|
|
4873
4895
|
].join(" ") : null;
|
|
4896
|
+
const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
|
|
4874
4897
|
const agentPrompt = [
|
|
4875
4898
|
thread.planMode ? PLAN_MODE_INSTRUCTION : null,
|
|
4876
4899
|
orchestrationReminder,
|
|
4900
|
+
worktreeReminder,
|
|
4877
4901
|
artifactReminder,
|
|
4878
4902
|
expandedPrompt
|
|
4879
4903
|
].filter(Boolean).join("\n\n");
|
|
4880
|
-
const instructionFiles = loadAgentInstructions(thread.worktreePath, thread.agent);
|
|
4881
4904
|
if (thread.attachments.length > 0) {
|
|
4882
4905
|
updateThread(threadId, { attachments: [] });
|
|
4883
4906
|
}
|
|
@@ -4901,11 +4924,10 @@ var Orchestrator = class {
|
|
|
4901
4924
|
});
|
|
4902
4925
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
4903
4926
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
4904
|
-
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-
|
|
4927
|
+
const { autoRenameBranchEnabled: autoRenameBranchEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
4905
4928
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled2() ? formatRenameBranchDirective(fresh, {
|
|
4906
4929
|
customPrompt: settings?.prompts?.renameBranch
|
|
4907
4930
|
}) : null;
|
|
4908
|
-
const instructions = fresh.agent === "claude" || isBrightsy ? null : formatAgentInstructions(instructionFiles);
|
|
4909
4931
|
let seed = null;
|
|
4910
4932
|
if (!fresh.sessionId) {
|
|
4911
4933
|
const prior = fresh.messages.slice(0, -1);
|
|
@@ -4926,12 +4948,12 @@ var Orchestrator = class {
|
|
|
4926
4948
|
});
|
|
4927
4949
|
}
|
|
4928
4950
|
}
|
|
4929
|
-
const cachedPrefix = [
|
|
4951
|
+
const cachedPrefix = fresh.sessionId ? "" : [
|
|
4930
4952
|
coordinatorDirective,
|
|
4931
4953
|
worktreeDirective,
|
|
4932
4954
|
artifactDirective,
|
|
4933
4955
|
renameBranchDirective,
|
|
4934
|
-
|
|
4956
|
+
seed
|
|
4935
4957
|
].filter(Boolean).join("\n\n---\n\n");
|
|
4936
4958
|
try {
|
|
4937
4959
|
const stderrTail = [];
|
|
@@ -5018,15 +5040,11 @@ var Orchestrator = class {
|
|
|
5018
5040
|
const retryThread = this.requireThread(threadId);
|
|
5019
5041
|
const prior = retryThread.messages.slice(0, -1);
|
|
5020
5042
|
const retrySeed = buildSessionSeed(prior);
|
|
5021
|
-
const retryInstructions = retryThread.agent === "claude" ? null : formatAgentInstructions(
|
|
5022
|
-
loadAgentInstructions(retryThread.worktreePath, retryThread.agent)
|
|
5023
|
-
);
|
|
5024
5043
|
const retryPrefix = [
|
|
5025
5044
|
coordinatorDirective,
|
|
5026
5045
|
worktreeDirective,
|
|
5027
5046
|
artifactDirective,
|
|
5028
5047
|
renameBranchDirective,
|
|
5029
|
-
retryInstructions,
|
|
5030
5048
|
retrySeed
|
|
5031
5049
|
].filter(Boolean).join("\n\n---\n\n");
|
|
5032
5050
|
const retryHandle = await spawnAgentTurn(
|
|
@@ -5596,7 +5614,7 @@ var Orchestrator = class {
|
|
|
5596
5614
|
updateThread(thread.id, { title: meta.title });
|
|
5597
5615
|
}
|
|
5598
5616
|
}
|
|
5599
|
-
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-
|
|
5617
|
+
const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
5600
5618
|
const latest = this.requireThread(thread.id);
|
|
5601
5619
|
if (!shouldAutoArchiveOnPrMerge({
|
|
5602
5620
|
previousPrState: prevState || null,
|
|
@@ -5820,7 +5838,7 @@ var Orchestrator = class {
|
|
|
5820
5838
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
5821
5839
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
5822
5840
|
try {
|
|
5823
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
5841
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-EBFW7I7S.js");
|
|
5824
5842
|
await ensureWorkspace2(thread.repoPath);
|
|
5825
5843
|
} catch {
|
|
5826
5844
|
}
|
|
@@ -5841,7 +5859,7 @@ var Orchestrator = class {
|
|
|
5841
5859
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
5842
5860
|
} catch {
|
|
5843
5861
|
}
|
|
5844
|
-
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-
|
|
5862
|
+
const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
5845
5863
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
|
|
5846
5864
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
5847
5865
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -5862,7 +5880,7 @@ var Orchestrator = class {
|
|
|
5862
5880
|
return restored2;
|
|
5863
5881
|
}
|
|
5864
5882
|
if (!existsSync13(thread.worktreePath)) {
|
|
5865
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
5883
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7NBPIVFZ.js");
|
|
5866
5884
|
const { execa: execa6 } = await import("execa");
|
|
5867
5885
|
const slug = thread.worktreePath.split("/").pop();
|
|
5868
5886
|
const dest = thread.worktreePath;
|
|
@@ -5971,7 +5989,7 @@ async function startOrchestration(opts) {
|
|
|
5971
5989
|
sourceRef: "default",
|
|
5972
5990
|
...createOpts
|
|
5973
5991
|
}).catch(async () => {
|
|
5974
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
5992
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7NBPIVFZ.js");
|
|
5975
5993
|
const repo = await resolveRepoRoot2(repoPath);
|
|
5976
5994
|
const def = await resolveDefaultBranch2(repo);
|
|
5977
5995
|
return createThread({
|
|
@@ -6127,7 +6145,7 @@ function withTimeout(promise, ms, label) {
|
|
|
6127
6145
|
async function startMcpServer() {
|
|
6128
6146
|
const orch = getOrchestrator();
|
|
6129
6147
|
try {
|
|
6130
|
-
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-
|
|
6148
|
+
const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
6131
6149
|
orch.setMaxConcurrent(maxConcurrentAgents2());
|
|
6132
6150
|
} catch {
|
|
6133
6151
|
}
|
|
@@ -6218,14 +6236,13 @@ async function startMcpServer() {
|
|
|
6218
6236
|
),
|
|
6219
6237
|
artifact_id: z.string().optional().describe("Stable id when updating the same artifact across turns")
|
|
6220
6238
|
},
|
|
6221
|
-
async ({ title, type,
|
|
6239
|
+
async ({ title, type, artifact_id }) => {
|
|
6222
6240
|
const id = artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
6223
6241
|
const payload = {
|
|
6224
6242
|
ok: true,
|
|
6225
6243
|
artifact_id: id,
|
|
6226
6244
|
title,
|
|
6227
6245
|
type,
|
|
6228
|
-
content,
|
|
6229
6246
|
message: "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
|
|
6230
6247
|
};
|
|
6231
6248
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6278,7 +6295,6 @@ async function startMcpServer() {
|
|
|
6278
6295
|
ok: true,
|
|
6279
6296
|
path,
|
|
6280
6297
|
title: title?.trim() || "Plan",
|
|
6281
|
-
content,
|
|
6282
6298
|
message: "Plan saved to .context/attachments/plan.md and shown in Sideboard chat for approval."
|
|
6283
6299
|
};
|
|
6284
6300
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6308,9 +6324,6 @@ async function startMcpServer() {
|
|
|
6308
6324
|
datasource: args.datasource ?? (args.resource ? "inline" : "brightsy"),
|
|
6309
6325
|
resource_id: args.resource_id,
|
|
6310
6326
|
record_id: args.record_id,
|
|
6311
|
-
resource: args.resource,
|
|
6312
|
-
record: args.record,
|
|
6313
|
-
records: args.records,
|
|
6314
6327
|
message: "Schema pane accepted. Sideboard desktop opens the CMS column beside chat."
|
|
6315
6328
|
};
|
|
6316
6329
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
@@ -6338,739 +6351,741 @@ async function startMcpServer() {
|
|
|
6338
6351
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
6339
6352
|
}
|
|
6340
6353
|
);
|
|
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
|
-
|
|
6354
|
+
if (sideboardMcpProfile() !== "worktree") {
|
|
6355
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-ONKMFSEJ.js");
|
|
6356
|
+
const accountDefaults = resolveThreadDefaults2();
|
|
6357
|
+
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
6358
|
+
server.tool(
|
|
6359
|
+
"create_thread",
|
|
6360
|
+
`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.`,
|
|
6361
|
+
{
|
|
6362
|
+
sourceType: z.enum(["branch", "pr", "ticket"]),
|
|
6363
|
+
sourceRef: z.string(),
|
|
6364
|
+
agent: z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]).optional().describe(`Omit to use Account default agent (${accountDefaults.agent})`),
|
|
6365
|
+
model: z.string().nullable().optional().describe(
|
|
6366
|
+
`Usually omit to use Account default model (${accountDefaults.model?.trim() || "Auto"}). Pass null only to force Auto / agent-default.`
|
|
6367
|
+
),
|
|
6368
|
+
repoPath: z.string(),
|
|
6369
|
+
title: z.string().optional(),
|
|
6370
|
+
parentThreadId: z.string().optional().describe(
|
|
6371
|
+
"Orchestration: omit (preferred) or pass YOUR chat id from the turn reminder / AGENTS.md. Do not invent uuids."
|
|
6372
|
+
)
|
|
6373
|
+
},
|
|
6374
|
+
async (args) => {
|
|
6375
|
+
const envParentId = process.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || "";
|
|
6376
|
+
let parentId = args.parentThreadId?.trim() || "";
|
|
6377
|
+
let parent = parentId ? orch.getThread(parentId) : null;
|
|
6378
|
+
let parentCorrectedFrom;
|
|
6379
|
+
if (envParentId) {
|
|
6380
|
+
const envParent = orch.getThread(envParentId);
|
|
6381
|
+
if (envParent) {
|
|
6382
|
+
if (parentId && parentId !== envParentId) parentCorrectedFrom = parentId;
|
|
6383
|
+
else if (!parentId) parentCorrectedFrom = void 0;
|
|
6384
|
+
parentId = envParentId;
|
|
6385
|
+
parent = envParent;
|
|
6386
|
+
}
|
|
6372
6387
|
}
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6388
|
+
if (parentId && !parent) {
|
|
6389
|
+
parentCorrectedFrom = parentId;
|
|
6390
|
+
parentId = "";
|
|
6391
|
+
parent = null;
|
|
6392
|
+
}
|
|
6393
|
+
if (parentId) {
|
|
6394
|
+
const children = orch.getThreads(false).filter((t) => t.parentThreadId === parentId);
|
|
6395
|
+
if (children.length >= MAX_ORCH_THREADS) {
|
|
6396
|
+
return {
|
|
6397
|
+
content: [
|
|
6398
|
+
{
|
|
6399
|
+
type: "text",
|
|
6400
|
+
text: `Thread-creation cap (${MAX_ORCH_THREADS}) reached for this orchestration session`
|
|
6401
|
+
}
|
|
6402
|
+
],
|
|
6403
|
+
isError: true
|
|
6404
|
+
};
|
|
6405
|
+
}
|
|
6406
|
+
}
|
|
6407
|
+
let agentArg = args.agent;
|
|
6408
|
+
let agentCoercedFrom;
|
|
6409
|
+
const resolvedProbe = resolveNewThreadOptions2({ agent: agentArg }).agent;
|
|
6410
|
+
if (resolvedProbe === "codex") {
|
|
6411
|
+
agentCoercedFrom = agentArg ?? "codex";
|
|
6412
|
+
const accountAgent = resolveNewThreadOptions2({}).agent;
|
|
6413
|
+
agentArg = accountAgent !== "codex" ? accountAgent : "cursor";
|
|
6414
|
+
}
|
|
6415
|
+
const opts = resolveNewThreadOptions2({
|
|
6416
|
+
agent: agentArg,
|
|
6417
|
+
model: args.model
|
|
6418
|
+
});
|
|
6419
|
+
try {
|
|
6420
|
+
const thread = await withTimeout(
|
|
6421
|
+
orch.createThread({
|
|
6422
|
+
sourceType: args.sourceType,
|
|
6423
|
+
sourceRef: args.sourceRef,
|
|
6424
|
+
agent: opts.agent,
|
|
6425
|
+
model: opts.model,
|
|
6426
|
+
effort: opts.effort,
|
|
6427
|
+
fast: opts.fast,
|
|
6428
|
+
repoPath: args.repoPath,
|
|
6429
|
+
title: args.title,
|
|
6430
|
+
parentThreadId: parentId || null
|
|
6431
|
+
}),
|
|
6432
|
+
CREATE_THREAD_TIMEOUT_MS,
|
|
6433
|
+
"create_thread"
|
|
6434
|
+
);
|
|
6435
|
+
const parentNote = parentCorrectedFrom ? parentId ? `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; nested under ${parentId}` : `Ignored unknown/stale parentThreadId ${parentCorrectedFrom}; created without parent` : void 0;
|
|
6382
6436
|
return {
|
|
6383
6437
|
content: [
|
|
6384
6438
|
{
|
|
6385
6439
|
type: "text",
|
|
6386
|
-
text:
|
|
6440
|
+
text: JSON.stringify({
|
|
6441
|
+
id: thread.id,
|
|
6442
|
+
title: thread.title,
|
|
6443
|
+
branchName: thread.branchName,
|
|
6444
|
+
worktreePath: thread.worktreePath,
|
|
6445
|
+
agent: thread.agent,
|
|
6446
|
+
model: thread.model,
|
|
6447
|
+
status: thread.status,
|
|
6448
|
+
link: `sideboard://thread/${thread.id}`,
|
|
6449
|
+
parentThreadId: thread.parentThreadId,
|
|
6450
|
+
...agentCoercedFrom ? {
|
|
6451
|
+
agentCoercedFrom,
|
|
6452
|
+
note: `Avoid nested Codex under a Codex orchestrator \u2014 used Account default agent=${thread.agent}`
|
|
6453
|
+
} : {},
|
|
6454
|
+
...parentCorrectedFrom ? { parentCorrectedFrom, parentNote } : {}
|
|
6455
|
+
})
|
|
6456
|
+
}
|
|
6457
|
+
]
|
|
6458
|
+
};
|
|
6459
|
+
} catch (err) {
|
|
6460
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6461
|
+
return {
|
|
6462
|
+
content: [
|
|
6463
|
+
{
|
|
6464
|
+
type: "text",
|
|
6465
|
+
text: `create_thread failed: ${message}`
|
|
6387
6466
|
}
|
|
6388
6467
|
],
|
|
6389
6468
|
isError: true
|
|
6390
6469
|
};
|
|
6391
6470
|
}
|
|
6392
6471
|
}
|
|
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;
|
|
6472
|
+
);
|
|
6473
|
+
server.tool(
|
|
6474
|
+
"send_to_thread",
|
|
6475
|
+
"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.",
|
|
6476
|
+
{
|
|
6477
|
+
ref: z.string(),
|
|
6478
|
+
prompt: z.string(),
|
|
6479
|
+
force_stop: z.boolean().optional()
|
|
6480
|
+
},
|
|
6481
|
+
async ({ ref, prompt, force_stop }) => {
|
|
6482
|
+
if (force_stop) {
|
|
6483
|
+
const existing = orch.getThread(ref);
|
|
6484
|
+
if (existing) {
|
|
6485
|
+
orch.stop(ref, { clearQueue: true });
|
|
6486
|
+
}
|
|
6487
|
+
}
|
|
6488
|
+
const thread = await orch.send(ref, prompt);
|
|
6422
6489
|
return {
|
|
6423
6490
|
content: [
|
|
6424
6491
|
{
|
|
6425
6492
|
type: "text",
|
|
6426
6493
|
text: JSON.stringify({
|
|
6427
6494
|
id: thread.id,
|
|
6428
|
-
title: thread.title,
|
|
6429
|
-
branchName: thread.branchName,
|
|
6430
|
-
worktreePath: thread.worktreePath,
|
|
6431
|
-
agent: thread.agent,
|
|
6432
|
-
model: thread.model,
|
|
6433
6495
|
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 } : {}
|
|
6496
|
+
queueLength: thread.queue.length,
|
|
6497
|
+
forceStopped: Boolean(force_stop)
|
|
6441
6498
|
})
|
|
6442
6499
|
}
|
|
6443
6500
|
]
|
|
6444
6501
|
};
|
|
6445
|
-
}
|
|
6446
|
-
|
|
6502
|
+
}
|
|
6503
|
+
);
|
|
6504
|
+
server.tool(
|
|
6505
|
+
"wait_for_turn",
|
|
6506
|
+
"Block until the thread finishes its current/queued turn (avoids polling). Use after send_to_thread to read the agent reply.",
|
|
6507
|
+
{
|
|
6508
|
+
ref: z.string(),
|
|
6509
|
+
timeoutMs: z.number().optional()
|
|
6510
|
+
},
|
|
6511
|
+
async ({ ref, timeoutMs }) => {
|
|
6512
|
+
const thread = await orch.waitForTurn(ref, timeoutMs ?? 6e5);
|
|
6513
|
+
const result = orch.getTurnResult(thread.id);
|
|
6447
6514
|
return {
|
|
6448
6515
|
content: [
|
|
6449
6516
|
{
|
|
6450
6517
|
type: "text",
|
|
6451
|
-
text:
|
|
6518
|
+
text: JSON.stringify({
|
|
6519
|
+
id: thread.id,
|
|
6520
|
+
status: result.status,
|
|
6521
|
+
text: result.text
|
|
6522
|
+
})
|
|
6452
6523
|
}
|
|
6453
|
-
]
|
|
6454
|
-
isError: true
|
|
6524
|
+
]
|
|
6455
6525
|
};
|
|
6456
6526
|
}
|
|
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
|
-
}
|
|
6527
|
+
);
|
|
6528
|
+
server.tool(
|
|
6529
|
+
"get_turn_result",
|
|
6530
|
+
"Final assistant message only (not full transcript)",
|
|
6531
|
+
{ ref: z.string() },
|
|
6532
|
+
async ({ ref }) => {
|
|
6533
|
+
const result = orch.getTurnResult(ref);
|
|
6534
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
6473
6535
|
}
|
|
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) {
|
|
6536
|
+
);
|
|
6537
|
+
server.tool(
|
|
6538
|
+
"stop_thread",
|
|
6539
|
+
"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.",
|
|
6540
|
+
{
|
|
6541
|
+
ref: z.string(),
|
|
6542
|
+
force: z.boolean().optional()
|
|
6543
|
+
},
|
|
6544
|
+
async ({ ref, force }) => {
|
|
6545
|
+
const t = orch.getThread(ref);
|
|
6546
|
+
if (!t) {
|
|
6547
|
+
return {
|
|
6548
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6549
|
+
isError: true
|
|
6550
|
+
};
|
|
6551
|
+
}
|
|
6552
|
+
const clearQueue = force !== false;
|
|
6553
|
+
const hadQueued = t.queue.length > 0;
|
|
6554
|
+
const stopped = orch.stop(ref, { clearQueue });
|
|
6533
6555
|
return {
|
|
6534
|
-
content: [
|
|
6535
|
-
|
|
6556
|
+
content: [
|
|
6557
|
+
{
|
|
6558
|
+
type: "text",
|
|
6559
|
+
text: JSON.stringify({
|
|
6560
|
+
id: stopped.id,
|
|
6561
|
+
status: stopped.status,
|
|
6562
|
+
clearedQueue: clearQueue && hadQueued
|
|
6563
|
+
})
|
|
6564
|
+
}
|
|
6565
|
+
]
|
|
6536
6566
|
};
|
|
6537
6567
|
}
|
|
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) {
|
|
6568
|
+
);
|
|
6569
|
+
server.tool(
|
|
6570
|
+
"archive_thread",
|
|
6571
|
+
"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.",
|
|
6572
|
+
{ ref: z.string() },
|
|
6573
|
+
async ({ ref }) => {
|
|
6574
|
+
const t = orch.getThread(ref);
|
|
6575
|
+
if (!t) {
|
|
6576
|
+
return {
|
|
6577
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6578
|
+
isError: true
|
|
6579
|
+
};
|
|
6580
|
+
}
|
|
6581
|
+
const blocked = mcpArchiveBlockedReason(t);
|
|
6582
|
+
if (blocked) {
|
|
6583
|
+
return {
|
|
6584
|
+
content: [{ type: "text", text: blocked }],
|
|
6585
|
+
isError: true
|
|
6586
|
+
};
|
|
6587
|
+
}
|
|
6588
|
+
const archived = await orch.archive(ref);
|
|
6562
6589
|
return {
|
|
6563
|
-
content: [
|
|
6564
|
-
|
|
6590
|
+
content: [
|
|
6591
|
+
{
|
|
6592
|
+
type: "text",
|
|
6593
|
+
text: JSON.stringify({
|
|
6594
|
+
id: archived.id,
|
|
6595
|
+
status: archived.status
|
|
6596
|
+
})
|
|
6597
|
+
}
|
|
6598
|
+
]
|
|
6565
6599
|
};
|
|
6566
6600
|
}
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6601
|
+
);
|
|
6602
|
+
server.tool(
|
|
6603
|
+
"restore_thread",
|
|
6604
|
+
"Restore an archived thread (recreates worktree from branch when needed)",
|
|
6605
|
+
{ ref: z.string() },
|
|
6606
|
+
async ({ ref }) => {
|
|
6607
|
+
try {
|
|
6608
|
+
const restored = await orch.restore(ref);
|
|
6609
|
+
return {
|
|
6610
|
+
content: [
|
|
6611
|
+
{
|
|
6612
|
+
type: "text",
|
|
6613
|
+
text: JSON.stringify({
|
|
6614
|
+
id: restored.id,
|
|
6615
|
+
status: restored.status,
|
|
6616
|
+
worktreePath: restored.worktreePath
|
|
6617
|
+
})
|
|
6618
|
+
}
|
|
6619
|
+
]
|
|
6620
|
+
};
|
|
6621
|
+
} catch (err) {
|
|
6622
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6623
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6624
|
+
}
|
|
6573
6625
|
}
|
|
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);
|
|
6626
|
+
);
|
|
6627
|
+
server.tool(
|
|
6628
|
+
"get_diff",
|
|
6629
|
+
"Compact diff summary (capped hunks, paginated)",
|
|
6630
|
+
{
|
|
6631
|
+
ref: z.string(),
|
|
6632
|
+
maxFiles: z.number().optional()
|
|
6633
|
+
},
|
|
6634
|
+
async ({ ref, maxFiles }) => {
|
|
6635
|
+
const summary = await orch.diffSummary(ref);
|
|
6595
6636
|
return {
|
|
6596
6637
|
content: [
|
|
6597
6638
|
{
|
|
6598
6639
|
type: "text",
|
|
6599
6640
|
text: JSON.stringify({
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
worktreePath: restored.worktreePath
|
|
6641
|
+
...summary,
|
|
6642
|
+
files: summary.files.slice(0, maxFiles ?? 10)
|
|
6603
6643
|
})
|
|
6604
6644
|
}
|
|
6605
6645
|
]
|
|
6606
6646
|
};
|
|
6607
|
-
} catch (err) {
|
|
6608
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6609
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6610
6647
|
}
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6648
|
+
);
|
|
6649
|
+
server.tool(
|
|
6650
|
+
"request_review",
|
|
6651
|
+
'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.',
|
|
6652
|
+
{ ref: z.string().describe("Worktree thread id/ref to review") },
|
|
6653
|
+
async ({ ref }) => {
|
|
6654
|
+
try {
|
|
6655
|
+
const tab = await orch.requestReview(ref);
|
|
6656
|
+
const from = orch.getThread(ref);
|
|
6657
|
+
return {
|
|
6658
|
+
content: [
|
|
6659
|
+
{
|
|
6660
|
+
type: "text",
|
|
6661
|
+
text: JSON.stringify({
|
|
6662
|
+
id: tab.id,
|
|
6663
|
+
title: tab.title,
|
|
6664
|
+
status: tab.status,
|
|
6665
|
+
fromThreadId: from?.id ?? ref,
|
|
6666
|
+
link: `sideboard://thread/${tab.id}`
|
|
6667
|
+
})
|
|
6668
|
+
}
|
|
6669
|
+
]
|
|
6670
|
+
};
|
|
6671
|
+
} catch (err) {
|
|
6672
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6673
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6674
|
+
}
|
|
6675
|
+
}
|
|
6676
|
+
);
|
|
6677
|
+
const agentEnum = z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]);
|
|
6678
|
+
server.tool(
|
|
6679
|
+
"list_models",
|
|
6680
|
+
"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.",
|
|
6681
|
+
{
|
|
6682
|
+
agent: agentEnum.optional().describe("Limit to one agent; omit for all")
|
|
6683
|
+
},
|
|
6684
|
+
async ({ agent }) => {
|
|
6685
|
+
try {
|
|
6686
|
+
const catalogs = await listModelsForAgent(agent);
|
|
6687
|
+
return {
|
|
6688
|
+
content: [{ type: "text", text: JSON.stringify(catalogs, null, 2) }]
|
|
6689
|
+
};
|
|
6690
|
+
} catch (err) {
|
|
6691
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6692
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6693
|
+
}
|
|
6694
|
+
}
|
|
6695
|
+
);
|
|
6696
|
+
server.tool(
|
|
6697
|
+
"fork_worktree",
|
|
6698
|
+
"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.",
|
|
6699
|
+
{
|
|
6700
|
+
ref: z.string().describe("Worktree thread id/ref to fork"),
|
|
6701
|
+
through_index: z.number().optional().describe("Inclusive message index to include in the transcript (default: all)"),
|
|
6702
|
+
agent: agentEnum.optional().describe("Agent for the forked chat (default: same as source)"),
|
|
6703
|
+
model: z.string().nullable().optional().describe("Usually omit (Auto). Only set from list_models when you need a specific model"),
|
|
6704
|
+
title: z.string().optional()
|
|
6705
|
+
},
|
|
6706
|
+
async ({ ref, through_index, agent, model, title }) => {
|
|
6707
|
+
try {
|
|
6708
|
+
const source = orch.getThread(ref);
|
|
6709
|
+
if (source) await orch.reconcile(source.repoPath, { drainQueues: false });
|
|
6710
|
+
const thread = await orch.forkThreadWorktree({
|
|
6711
|
+
threadId: ref,
|
|
6712
|
+
throughIndex: through_index,
|
|
6713
|
+
agent,
|
|
6714
|
+
model,
|
|
6715
|
+
title
|
|
6716
|
+
});
|
|
6717
|
+
return {
|
|
6718
|
+
content: [
|
|
6719
|
+
{
|
|
6720
|
+
type: "text",
|
|
6721
|
+
text: JSON.stringify({
|
|
6722
|
+
id: thread.id,
|
|
6723
|
+
title: thread.title,
|
|
6724
|
+
status: thread.status,
|
|
6725
|
+
agent: thread.agent,
|
|
6726
|
+
model: thread.model,
|
|
6727
|
+
branchName: thread.branchName,
|
|
6728
|
+
worktreePath: thread.worktreePath,
|
|
6729
|
+
fromThreadId: source?.id ?? ref,
|
|
6730
|
+
link: `sideboard://thread/${thread.id}`
|
|
6731
|
+
})
|
|
6732
|
+
}
|
|
6733
|
+
]
|
|
6734
|
+
};
|
|
6735
|
+
} catch (err) {
|
|
6736
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6737
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
);
|
|
6741
|
+
server.tool(
|
|
6742
|
+
"fork_chat",
|
|
6743
|
+
"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.",
|
|
6744
|
+
{
|
|
6745
|
+
ref: z.string().describe("Thread id/ref to fork (worktree agent or orchestration chat)"),
|
|
6746
|
+
through_index: z.number().optional().describe("Inclusive message index to include in the transcript (default: all)"),
|
|
6747
|
+
agent: agentEnum.optional().describe("Agent for the forked chat (default: same as source)"),
|
|
6748
|
+
model: z.string().nullable().optional().describe("Usually omit (Auto). Only set from list_models when you need a specific model"),
|
|
6749
|
+
title: z.string().optional()
|
|
6750
|
+
},
|
|
6751
|
+
async ({ ref, through_index, agent, model, title }) => {
|
|
6752
|
+
try {
|
|
6753
|
+
const source = orch.getThread(ref);
|
|
6754
|
+
if (!source) {
|
|
6755
|
+
return {
|
|
6756
|
+
content: [{ type: "text", text: `Thread not found: ${ref}` }],
|
|
6757
|
+
isError: true
|
|
6758
|
+
};
|
|
6630
6759
|
}
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6640
|
-
|
|
6641
|
-
|
|
6642
|
-
|
|
6760
|
+
const tab = orch.forkChatTab({
|
|
6761
|
+
threadId: source.id,
|
|
6762
|
+
throughIndex: through_index,
|
|
6763
|
+
agent,
|
|
6764
|
+
model,
|
|
6765
|
+
title
|
|
6766
|
+
});
|
|
6767
|
+
return {
|
|
6768
|
+
content: [
|
|
6769
|
+
{
|
|
6770
|
+
type: "text",
|
|
6771
|
+
text: JSON.stringify({
|
|
6772
|
+
id: tab.id,
|
|
6773
|
+
title: tab.title,
|
|
6774
|
+
status: tab.status,
|
|
6775
|
+
agent: tab.agent,
|
|
6776
|
+
model: tab.model,
|
|
6777
|
+
sourceType: tab.sourceType,
|
|
6778
|
+
worktreePath: tab.worktreePath,
|
|
6779
|
+
fromThreadId: source.id,
|
|
6780
|
+
link: `sideboard://thread/${tab.id}`
|
|
6781
|
+
})
|
|
6782
|
+
}
|
|
6783
|
+
]
|
|
6784
|
+
};
|
|
6785
|
+
} catch (err) {
|
|
6786
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6787
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
6788
|
+
}
|
|
6789
|
+
}
|
|
6790
|
+
);
|
|
6791
|
+
server.tool(
|
|
6792
|
+
"run_dev_script",
|
|
6793
|
+
"Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
|
|
6794
|
+
{
|
|
6795
|
+
ref: z.string(),
|
|
6796
|
+
name: z.string().optional()
|
|
6797
|
+
},
|
|
6798
|
+
async ({ ref, name }) => {
|
|
6799
|
+
const result = await orch.startDev(ref, name);
|
|
6643
6800
|
return {
|
|
6644
6801
|
content: [
|
|
6645
6802
|
{
|
|
6646
6803
|
type: "text",
|
|
6647
6804
|
text: JSON.stringify({
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
link: `sideboard://thread/${tab.id}`
|
|
6805
|
+
port: result.port,
|
|
6806
|
+
scriptName: result.scriptName,
|
|
6807
|
+
ports: result.ports,
|
|
6808
|
+
url: `http://localhost:${result.port}`
|
|
6653
6809
|
})
|
|
6654
6810
|
}
|
|
6655
6811
|
]
|
|
6656
6812
|
};
|
|
6657
|
-
} catch (err) {
|
|
6658
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6659
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6660
6813
|
}
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
},
|
|
6670
|
-
async ({ agent }) => {
|
|
6671
|
-
try {
|
|
6672
|
-
const catalogs = await listModelsForAgent(agent);
|
|
6814
|
+
);
|
|
6815
|
+
server.tool(
|
|
6816
|
+
"list_run_scripts",
|
|
6817
|
+
"List named run scripts available for a thread",
|
|
6818
|
+
{ ref: z.string() },
|
|
6819
|
+
async ({ ref }) => {
|
|
6820
|
+
const scripts = orch.listThreadRunScripts(ref);
|
|
6821
|
+
const active = orch.getActiveRuns(ref);
|
|
6673
6822
|
return {
|
|
6674
|
-
content: [
|
|
6823
|
+
content: [
|
|
6824
|
+
{
|
|
6825
|
+
type: "text",
|
|
6826
|
+
text: JSON.stringify({ scripts, active }, null, 2)
|
|
6827
|
+
}
|
|
6828
|
+
]
|
|
6675
6829
|
};
|
|
6676
|
-
} catch (err) {
|
|
6677
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6678
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6679
6830
|
}
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6831
|
+
);
|
|
6832
|
+
server.tool(
|
|
6833
|
+
"stop_dev_script",
|
|
6834
|
+
"Stop a running script for a thread (all scripts if name omitted)",
|
|
6835
|
+
{
|
|
6836
|
+
ref: z.string(),
|
|
6837
|
+
name: z.string().optional()
|
|
6838
|
+
},
|
|
6839
|
+
async ({ ref, name }) => {
|
|
6840
|
+
orch.stopDev(ref, name);
|
|
6841
|
+
return { content: [{ type: "text", text: "ok" }] };
|
|
6842
|
+
}
|
|
6843
|
+
);
|
|
6844
|
+
server.tool(
|
|
6845
|
+
"run_setup",
|
|
6846
|
+
"Re-run workspace setup (Sideboard/Conductor settings or .cursor/worktrees.json)",
|
|
6847
|
+
{ ref: z.string() },
|
|
6848
|
+
async ({ ref }) => {
|
|
6849
|
+
const result = await orch.runSetup(ref);
|
|
6850
|
+
return {
|
|
6851
|
+
content: [{ type: "text", text: JSON.stringify(result) }]
|
|
6852
|
+
};
|
|
6853
|
+
}
|
|
6854
|
+
);
|
|
6855
|
+
server.tool(
|
|
6856
|
+
"add_workspace",
|
|
6857
|
+
"Register a git repo as a Sideboard workspace",
|
|
6858
|
+
{ repoPath: z.string() },
|
|
6859
|
+
async ({ repoPath }) => {
|
|
6860
|
+
const ws = await orch.addWorkspace(repoPath);
|
|
6861
|
+
return { content: [{ type: "text", text: JSON.stringify(ws) }] };
|
|
6862
|
+
}
|
|
6863
|
+
);
|
|
6864
|
+
server.tool(
|
|
6865
|
+
"remove_workspace",
|
|
6866
|
+
"Unregister a Sideboard workspace (does not archive threads)",
|
|
6867
|
+
{ repoPath: z.string() },
|
|
6868
|
+
async ({ repoPath }) => {
|
|
6869
|
+
orch.removeWorkspace(repoPath);
|
|
6870
|
+
return { content: [{ type: "text", text: "ok" }] };
|
|
6871
|
+
}
|
|
6872
|
+
);
|
|
6873
|
+
server.tool(
|
|
6874
|
+
"fanout",
|
|
6875
|
+
"Best-of-n: create one thread per agent with the same prompt (parallel attempts)",
|
|
6876
|
+
{
|
|
6877
|
+
prompt: z.string(),
|
|
6878
|
+
agents: z.array(z.enum(["claude", "codex", "opencode", "brightsy", "cursor"])),
|
|
6879
|
+
repoPath: z.string(),
|
|
6880
|
+
sourceType: z.enum(["branch", "pr", "ticket"]).optional(),
|
|
6881
|
+
sourceRef: z.string().optional(),
|
|
6882
|
+
title: z.string().optional()
|
|
6883
|
+
},
|
|
6884
|
+
async (args) => {
|
|
6885
|
+
const threads = await orch.bestOfN(args);
|
|
6886
|
+
return {
|
|
6887
|
+
content: [
|
|
6888
|
+
{
|
|
6889
|
+
type: "text",
|
|
6890
|
+
text: JSON.stringify(
|
|
6891
|
+
threads.map((t) => ({
|
|
6892
|
+
id: t.id,
|
|
6893
|
+
agent: t.agent,
|
|
6894
|
+
branchName: t.branchName,
|
|
6895
|
+
worktreePath: t.worktreePath
|
|
6896
|
+
})),
|
|
6897
|
+
null,
|
|
6898
|
+
2
|
|
6899
|
+
)
|
|
6900
|
+
}
|
|
6901
|
+
]
|
|
6902
|
+
};
|
|
6903
|
+
}
|
|
6904
|
+
);
|
|
6905
|
+
server.tool(
|
|
6906
|
+
"list_branches",
|
|
6907
|
+
"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).",
|
|
6908
|
+
{
|
|
6909
|
+
repoPath: z.string(),
|
|
6910
|
+
unmergedOnly: z.boolean().optional()
|
|
6911
|
+
},
|
|
6912
|
+
async ({ repoPath, unmergedOnly }) => {
|
|
6913
|
+
const root = await resolveRepoRoot(repoPath);
|
|
6914
|
+
const branches = await listBranches(root, {
|
|
6915
|
+
unmergedOnly: unmergedOnly !== false
|
|
6702
6916
|
});
|
|
6703
6917
|
return {
|
|
6704
6918
|
content: [
|
|
6705
6919
|
{
|
|
6706
6920
|
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
|
-
})
|
|
6921
|
+
text: branches.map((b) => `${b.current ? "*" : " "} ${b.name}`).join("\n")
|
|
6718
6922
|
}
|
|
6719
6923
|
]
|
|
6720
6924
|
};
|
|
6721
|
-
} catch (err) {
|
|
6722
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6723
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6724
6925
|
}
|
|
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
|
-
|
|
6926
|
+
);
|
|
6927
|
+
server.tool(
|
|
6928
|
+
"list_prs",
|
|
6929
|
+
"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.",
|
|
6930
|
+
{ repoPath: z.string() },
|
|
6931
|
+
async ({ repoPath }) => {
|
|
6932
|
+
const root = await resolveRepoRoot(repoPath);
|
|
6933
|
+
const prs = await listPrs(root);
|
|
6934
|
+
return {
|
|
6935
|
+
content: [
|
|
6936
|
+
{
|
|
6937
|
+
type: "text",
|
|
6938
|
+
text: prs.map(
|
|
6939
|
+
(p) => `#${p.number} ${p.title} (${p.headRefName})${p.isCrossRepository ? " [fork]" : ""}`
|
|
6940
|
+
).join("\n")
|
|
6941
|
+
}
|
|
6942
|
+
]
|
|
6943
|
+
};
|
|
6944
|
+
}
|
|
6945
|
+
);
|
|
6946
|
+
server.tool(
|
|
6947
|
+
"get_pr_stack",
|
|
6948
|
+
"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.",
|
|
6949
|
+
{ ref: z.string() },
|
|
6950
|
+
async ({ ref }) => {
|
|
6951
|
+
const stack = await orch.getPrStack(ref);
|
|
6952
|
+
return {
|
|
6953
|
+
content: [{ type: "text", text: JSON.stringify(stack, null, 2) }]
|
|
6954
|
+
};
|
|
6955
|
+
}
|
|
6956
|
+
);
|
|
6957
|
+
server.tool(
|
|
6958
|
+
"open_pr_stack_layers",
|
|
6959
|
+
"Materialize one worktree+thread per stack layer (or a single 1-based layer). Pass a thread ref already on the stack.",
|
|
6960
|
+
{
|
|
6961
|
+
ref: z.string(),
|
|
6962
|
+
layer: z.number().int().positive().optional()
|
|
6963
|
+
},
|
|
6964
|
+
async ({ ref, layer }) => {
|
|
6965
|
+
const result = await orch.openPrStackLayers(ref, { layer });
|
|
6966
|
+
return {
|
|
6967
|
+
content: [
|
|
6968
|
+
{
|
|
6969
|
+
type: "text",
|
|
6970
|
+
text: JSON.stringify(
|
|
6971
|
+
{
|
|
6972
|
+
stackNumber: result.stack.stackNumber,
|
|
6973
|
+
trunk: result.stack.trunk,
|
|
6974
|
+
threads: result.threads.map((t) => ({
|
|
6975
|
+
id: t.id,
|
|
6976
|
+
title: t.title,
|
|
6977
|
+
branchName: t.branchName,
|
|
6978
|
+
stackLayer: t.stackLayer,
|
|
6979
|
+
worktreePath: t.worktreePath,
|
|
6980
|
+
prUrl: t.prUrl,
|
|
6981
|
+
link: `sideboard://thread/${t.id}`
|
|
6982
|
+
}))
|
|
6983
|
+
},
|
|
6984
|
+
null,
|
|
6985
|
+
2
|
|
6986
|
+
)
|
|
6987
|
+
}
|
|
6988
|
+
]
|
|
6989
|
+
};
|
|
6990
|
+
}
|
|
6991
|
+
);
|
|
6992
|
+
server.tool(
|
|
6993
|
+
"add_stack_layer",
|
|
6994
|
+
"Add a branch on top of the current stack (`gh stack add`) and open a worktree+thread for it.",
|
|
6995
|
+
{
|
|
6996
|
+
ref: z.string(),
|
|
6997
|
+
branchName: z.string(),
|
|
6998
|
+
title: z.string().optional()
|
|
6999
|
+
},
|
|
7000
|
+
async ({ ref, branchName, title }) => {
|
|
7001
|
+
const result = await orch.addStackLayer(ref, branchName, { title });
|
|
7002
|
+
return {
|
|
7003
|
+
content: [
|
|
7004
|
+
{
|
|
7005
|
+
type: "text",
|
|
7006
|
+
text: JSON.stringify(
|
|
7007
|
+
{
|
|
7008
|
+
id: result.thread.id,
|
|
7009
|
+
title: result.thread.title,
|
|
7010
|
+
branchName: result.thread.branchName,
|
|
7011
|
+
stackLayer: result.thread.stackLayer,
|
|
7012
|
+
worktreePath: result.thread.worktreePath,
|
|
7013
|
+
link: `sideboard://thread/${result.thread.id}`
|
|
7014
|
+
},
|
|
7015
|
+
null,
|
|
7016
|
+
2
|
|
7017
|
+
)
|
|
7018
|
+
}
|
|
7019
|
+
]
|
|
7020
|
+
};
|
|
7021
|
+
}
|
|
7022
|
+
);
|
|
7023
|
+
server.tool(
|
|
7024
|
+
"create_pr_stack",
|
|
7025
|
+
"Create a new GitHub PR stack with one Sideboard worktree per layer (bottom\u2192top branch names). Requires `gh extension install github/gh-stack`.",
|
|
7026
|
+
{
|
|
7027
|
+
repoPath: z.string(),
|
|
7028
|
+
branches: z.array(z.string()).min(1),
|
|
7029
|
+
agent: z.enum(["claude", "codex", "opencode", "brightsy", "cursor"]),
|
|
7030
|
+
base: z.string().optional(),
|
|
7031
|
+
title: z.string().optional()
|
|
7032
|
+
},
|
|
7033
|
+
async (args) => {
|
|
7034
|
+
const result = await orch.createPrStack({
|
|
7035
|
+
repoPath: args.repoPath,
|
|
7036
|
+
branches: args.branches,
|
|
7037
|
+
agent: args.agent,
|
|
7038
|
+
base: args.base,
|
|
7039
|
+
title: args.title
|
|
6752
7040
|
});
|
|
6753
7041
|
return {
|
|
6754
7042
|
content: [
|
|
6755
7043
|
{
|
|
6756
7044
|
type: "text",
|
|
6757
|
-
text: JSON.stringify(
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
7045
|
+
text: JSON.stringify(
|
|
7046
|
+
{
|
|
7047
|
+
stackNumber: result.stack.stackNumber,
|
|
7048
|
+
trunk: result.stack.trunk,
|
|
7049
|
+
threads: result.threads.map((t) => ({
|
|
7050
|
+
id: t.id,
|
|
7051
|
+
title: t.title,
|
|
7052
|
+
branchName: t.branchName,
|
|
7053
|
+
stackLayer: t.stackLayer,
|
|
7054
|
+
worktreePath: t.worktreePath,
|
|
7055
|
+
link: `sideboard://thread/${t.id}`
|
|
7056
|
+
}))
|
|
7057
|
+
},
|
|
7058
|
+
null,
|
|
7059
|
+
2
|
|
7060
|
+
)
|
|
6768
7061
|
}
|
|
6769
7062
|
]
|
|
6770
7063
|
};
|
|
6771
|
-
} catch (err) {
|
|
6772
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
6773
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
6774
7064
|
}
|
|
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
|
-
);
|
|
7065
|
+
);
|
|
7066
|
+
server.tool(
|
|
7067
|
+
"list_issues",
|
|
7068
|
+
"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.",
|
|
7069
|
+
{ repoPath: z.string() },
|
|
7070
|
+
async ({ repoPath }) => {
|
|
7071
|
+
const root = await resolveRepoRoot(repoPath);
|
|
7072
|
+
const result = await listIssues(root);
|
|
7073
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
7074
|
+
}
|
|
7075
|
+
);
|
|
7076
|
+
server.tool(
|
|
7077
|
+
"list_linear_issues",
|
|
7078
|
+
"Deprecated: prefer list_issues. Lists assigned Linear issues via the chosen agent MCP connector",
|
|
7079
|
+
{
|
|
7080
|
+
agent: z.enum(["claude", "codex", "opencode"]),
|
|
7081
|
+
repoPath: z.string()
|
|
7082
|
+
},
|
|
7083
|
+
async ({ agent, repoPath }) => {
|
|
7084
|
+
const issues = await listLinearIssues(agent, repoPath);
|
|
7085
|
+
return { content: [{ type: "text", text: JSON.stringify(issues, null, 2) }] };
|
|
7086
|
+
}
|
|
7087
|
+
);
|
|
7088
|
+
}
|
|
7074
7089
|
const transport = new StdioServerTransport();
|
|
7075
7090
|
await server.connect(transport);
|
|
7076
7091
|
}
|
|
@@ -7436,6 +7451,7 @@ export {
|
|
|
7436
7451
|
REVIEW_REQUEST_PREFILL,
|
|
7437
7452
|
SIDEBOARD_FORCE_STOP,
|
|
7438
7453
|
SIDEBOARD_MCP_ALLOWED_TOOLS,
|
|
7454
|
+
SIDEBOARD_MCP_PROFILE_ENV,
|
|
7439
7455
|
THINKING_EFFORTS,
|
|
7440
7456
|
addPrStackLayer,
|
|
7441
7457
|
addStackLayerFromThread,
|
|
@@ -7467,6 +7483,7 @@ export {
|
|
|
7467
7483
|
brightsyCloudConnectAgent,
|
|
7468
7484
|
brightsyCloudConnectEnabled,
|
|
7469
7485
|
brightsyConfigPath,
|
|
7486
|
+
brightsyInjectWorktreeMcpEnabled,
|
|
7470
7487
|
brightsyMcpAllowedTools,
|
|
7471
7488
|
brightsyMcpServerName,
|
|
7472
7489
|
buildCachedUserContent,
|
|
@@ -7492,6 +7509,7 @@ export {
|
|
|
7492
7509
|
coerceOrchestratorAgent,
|
|
7493
7510
|
collectTakenTeamSlugs,
|
|
7494
7511
|
commitAll,
|
|
7512
|
+
conductorBundledBinDir,
|
|
7495
7513
|
conductorDbPath,
|
|
7496
7514
|
confirmLand,
|
|
7497
7515
|
connectBrightsyTeam,
|
|
@@ -7518,7 +7536,9 @@ export {
|
|
|
7518
7536
|
detectLocalMergeConflicts,
|
|
7519
7537
|
disconnectBrightsyTeam,
|
|
7520
7538
|
discoverSkills,
|
|
7539
|
+
dropCachedPrefixOnResume,
|
|
7521
7540
|
encodeBrightsyTarget,
|
|
7541
|
+
enrichPathWithNpmGlobalBin,
|
|
7522
7542
|
enrichWorkspacesWithGithub,
|
|
7523
7543
|
ensureAgentPath,
|
|
7524
7544
|
ensureCloudCoordinator,
|
|
@@ -7556,6 +7576,7 @@ export {
|
|
|
7556
7576
|
formatTranscriptMarkdown,
|
|
7557
7577
|
formatWorkspaceInventory,
|
|
7558
7578
|
formatWorktreeDirective,
|
|
7579
|
+
formatWorktreeReminder,
|
|
7559
7580
|
getAdapter,
|
|
7560
7581
|
getAgentSetupInfo,
|
|
7561
7582
|
getBrightsySession,
|
|
@@ -7600,6 +7621,7 @@ export {
|
|
|
7600
7621
|
isBrightsyConnected,
|
|
7601
7622
|
isBrightsyNdjsonLine,
|
|
7602
7623
|
isCloudCoordinatorThread,
|
|
7624
|
+
isConductorBundledCli,
|
|
7603
7625
|
isCursorAutoModel,
|
|
7604
7626
|
isDirty,
|
|
7605
7627
|
isGhRateLimitError,
|
|
@@ -7682,7 +7704,10 @@ export {
|
|
|
7682
7704
|
pastedTextStats,
|
|
7683
7705
|
permissionMode,
|
|
7684
7706
|
planFileAbs,
|
|
7707
|
+
posixShellSingleQuote,
|
|
7708
|
+
prepareTerminalCommand,
|
|
7685
7709
|
previewLand,
|
|
7710
|
+
promptMentionsBrightsy,
|
|
7686
7711
|
pushBranch,
|
|
7687
7712
|
readExistingReviewRequestFile,
|
|
7688
7713
|
readPlanFile,
|
|
@@ -7698,7 +7723,9 @@ export {
|
|
|
7698
7723
|
requestReview,
|
|
7699
7724
|
requireAgent,
|
|
7700
7725
|
resetGhStackDetectCache,
|
|
7726
|
+
resolveAgentExecutable,
|
|
7701
7727
|
resolveClaudeExecutable,
|
|
7728
|
+
resolveCommandBinarySync,
|
|
7702
7729
|
resolveConductorCursorAgentId,
|
|
7703
7730
|
resolveCursorModelId,
|
|
7704
7731
|
resolveDefaultBranch,
|
|
@@ -7707,6 +7734,7 @@ export {
|
|
|
7707
7734
|
resolveFilesToCopy,
|
|
7708
7735
|
resolveGhAuthToken,
|
|
7709
7736
|
resolveGithubRepoSlug,
|
|
7737
|
+
resolveLoginCommand,
|
|
7710
7738
|
resolveNewThreadOptions,
|
|
7711
7739
|
resolvePlanMarkdown,
|
|
7712
7740
|
resolvePrSelector,
|
|
@@ -7728,9 +7756,11 @@ export {
|
|
|
7728
7756
|
settingsSourceLabel,
|
|
7729
7757
|
shouldAttachPastedText,
|
|
7730
7758
|
shouldCompactContext,
|
|
7759
|
+
shouldInjectBrightsyMcp,
|
|
7731
7760
|
shouldRefreshReviewRequestTemplate,
|
|
7732
7761
|
shouldRunWorktreeCleanup,
|
|
7733
7762
|
sideboardHomeDir,
|
|
7763
|
+
sideboardMcpProfile,
|
|
7734
7764
|
sideboardReposDir,
|
|
7735
7765
|
sideboardWorkspacesDir,
|
|
7736
7766
|
slugify,
|
|
@@ -7758,6 +7788,7 @@ export {
|
|
|
7758
7788
|
threadDisplayLabel,
|
|
7759
7789
|
threadFilePath,
|
|
7760
7790
|
threadLockPath,
|
|
7791
|
+
threadRequestsBrightsyMcp,
|
|
7761
7792
|
threadsDir,
|
|
7762
7793
|
threadsSharingWorktree,
|
|
7763
7794
|
toolDescription,
|
|
@@ -7765,14 +7796,18 @@ export {
|
|
|
7765
7796
|
toolFilePath,
|
|
7766
7797
|
totalTokens,
|
|
7767
7798
|
updateAdvancedSettings,
|
|
7799
|
+
updateAgentExecutable,
|
|
7768
7800
|
updateAppEnvironment,
|
|
7769
7801
|
updateBrightsySettings,
|
|
7770
7802
|
updateClaudeSettings,
|
|
7803
|
+
updateCodexSettings,
|
|
7771
7804
|
updateDefaultsSettings,
|
|
7772
7805
|
updateIntegrationsSettings,
|
|
7806
|
+
updateOpencodeSettings,
|
|
7773
7807
|
updateThread,
|
|
7774
7808
|
validateLinearApiKey,
|
|
7775
7809
|
withAgentInstructions,
|
|
7810
|
+
withExportedPath,
|
|
7776
7811
|
withThreadLock,
|
|
7777
7812
|
workspaceSettingsSourceLabel,
|
|
7778
7813
|
worktreeCleanupSettings,
|