@sideboard-ai/core 0.1.227 → 0.1.229
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/{abletime-D6773P33.js → abletime-BGVOCEOU.js} +4 -4
- package/dist/{abletime-BF253OZT.js → abletime-WZNDTRVL.js} +4 -4
- package/dist/{abletime-oauth-KQPVVBKA.js → abletime-oauth-6M5GWEPX.js} +3 -3
- package/dist/{abletime-oauth-H4672PRH.js → abletime-oauth-ZLU2EYRK.js} +3 -3
- package/dist/{abletime-rest-DAFPXZ7H.js → abletime-rest-F7XG5NGY.js} +3 -3
- package/dist/{abletime-rest-OPEVV3XC.js → abletime-rest-WNHIATB3.js} +3 -3
- package/dist/{agents-DV5UROWB.js → agents-B7G4BQTS.js} +4 -4
- package/dist/{agents-QQ77D7VT.js → agents-ZKP7QNXA.js} +4 -4
- package/dist/{app-settings-5RQMQKSB.js → app-settings-KBL2G7M4.js} +7 -1
- package/dist/{app-settings-V2BBCX2H.js → app-settings-UXWCPDEA.js} +7 -1
- package/dist/{chunk-FUDJ6NFM.js → chunk-6HKGCUDN.js} +117 -62
- package/dist/{chunk-N2VST3NL.js → chunk-7YKXBFQE.js} +2 -2
- package/dist/{chunk-KTZESHYH.js → chunk-AMMRFFB7.js} +1 -1
- package/dist/{chunk-HSYE5ID6.js → chunk-AS4UN7QL.js} +5 -5
- package/dist/{chunk-3NWUHXU3.js → chunk-C774RJJA.js} +3 -3
- package/dist/{chunk-NFWPDEN4.js → chunk-F3GT6DQW.js} +1 -1
- package/dist/{chunk-CLI5DVU4.js → chunk-GHRZNPBK.js} +2 -2
- package/dist/{chunk-EWHJNJHV.js → chunk-I5NC7DWO.js} +38 -0
- package/dist/{chunk-VUW3VKLW.js → chunk-LULHFLPU.js} +17 -4
- package/dist/{chunk-646I442S.js → chunk-MVLXDYN5.js} +5 -5
- package/dist/{chunk-P2EAAM3H.js → chunk-N7UXGM3Y.js} +2 -2
- package/dist/{chunk-RRW2XWAY.js → chunk-P6ZM5QJW.js} +2 -2
- package/dist/{chunk-THLVCXLF.js → chunk-RGNPPRZZ.js} +3 -3
- package/dist/{chunk-Y5JES2VV.js → chunk-RZTRWN2V.js} +38 -0
- package/dist/{chunk-SOGGKYFV.js → chunk-SWNEA5OZ.js} +3 -3
- package/dist/{chunk-SQHRPJ7P.js → chunk-T7Y5ULHM.js} +14 -4
- package/dist/{chunk-I2HOATRJ.js → chunk-UHT6OS7V.js} +129 -62
- package/dist/{coordinator-prompt-JLMQVORO.js → coordinator-prompt-DZMMCDRW.js} +3 -3
- package/dist/{coordinator-prompt-VZ7OSRLD.js → coordinator-prompt-RL3GKIAQ.js} +3 -3
- package/dist/{global-workspace-QPSJEXGR.js → global-workspace-G3QEVRGZ.js} +3 -3
- package/dist/{global-workspace-3FDAUNN2.js → global-workspace-QW4OXCLJ.js} +3 -3
- package/dist/index.cjs +927 -658
- package/dist/index.d.cts +89 -3
- package/dist/index.d.ts +89 -3
- package/dist/index.js +206 -67
- package/dist/mcp/run-stdio.cjs +224 -84
- package/dist/mcp/run-stdio.js +86 -50
- package/dist/{orchestrator-CWOSAYAE.js → orchestrator-GKAHLGXT.js} +5 -5
- package/dist/{orchestrator-VKPHI64Q.js → orchestrator-X4VFA5WW.js} +5 -5
- package/dist/{workspaces-76W7IEKR.js → workspaces-77C5XQEY.js} +3 -3
- package/dist/{workspaces-TDBA64II.js → workspaces-WXRPLT2N.js} +3 -3
- package/dist/{worktree-I573UOPD.js → worktree-L6FJXFUC.js} +2 -2
- package/dist/{worktree-7V67XTEO.js → worktree-P67WAJKH.js} +2 -2
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -3787,12 +3787,14 @@ var init_issue_source_labels = __esm({
|
|
|
3787
3787
|
// src/store/app-settings.ts
|
|
3788
3788
|
var app_settings_exports = {};
|
|
3789
3789
|
__export(app_settings_exports, {
|
|
3790
|
+
AGENT_DONE_SOUNDS: () => AGENT_DONE_SOUNDS,
|
|
3790
3791
|
FOLLOW_UP_BEHAVIORS: () => FOLLOW_UP_BEHAVIORS,
|
|
3791
3792
|
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
3792
3793
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
3793
3794
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
3794
3795
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
3795
3796
|
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
3797
|
+
agentDoneSound: () => agentDoneSound,
|
|
3796
3798
|
appSettingsPath: () => appSettingsPath,
|
|
3797
3799
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
3798
3800
|
autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
|
|
@@ -3840,6 +3842,7 @@ __export(app_settings_exports, {
|
|
|
3840
3842
|
historyMaxCount: () => historyMaxCount,
|
|
3841
3843
|
historyMaxDays: () => historyMaxDays,
|
|
3842
3844
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
3845
|
+
isAgentDoneSound: () => isAgentDoneSound,
|
|
3843
3846
|
isIssueSourceConnected: () => isIssueSourceConnected,
|
|
3844
3847
|
isLinearConnected: () => isLinearConnected,
|
|
3845
3848
|
isUsageOnLimit: () => isUsageOnLimit,
|
|
@@ -3881,6 +3884,9 @@ __export(app_settings_exports, {
|
|
|
3881
3884
|
usageOnLimit: () => usageOnLimit,
|
|
3882
3885
|
writeViewerContext: () => writeViewerContext
|
|
3883
3886
|
});
|
|
3887
|
+
function isAgentDoneSound(value) {
|
|
3888
|
+
return AGENT_DONE_SOUNDS.includes(value);
|
|
3889
|
+
}
|
|
3884
3890
|
function emptyPublicIntegrations() {
|
|
3885
3891
|
return {
|
|
3886
3892
|
hasLinearApiKey: false,
|
|
@@ -4311,6 +4317,13 @@ function normalizeAdvanced(raw) {
|
|
|
4311
4317
|
if (source.followUpBehavior === "queue" || source.followUpBehavior === "steer") {
|
|
4312
4318
|
out.followUpBehavior = source.followUpBehavior;
|
|
4313
4319
|
}
|
|
4320
|
+
if (isAgentDoneSound(source.agentDoneSound)) {
|
|
4321
|
+
out.agentDoneSound = source.agentDoneSound;
|
|
4322
|
+
}
|
|
4323
|
+
if (typeof source.agentDoneCustomSoundName === "string") {
|
|
4324
|
+
const name = source.agentDoneCustomSoundName.trim();
|
|
4325
|
+
if (name) out.agentDoneCustomSoundName = name.slice(0, 200);
|
|
4326
|
+
}
|
|
4314
4327
|
return out;
|
|
4315
4328
|
}
|
|
4316
4329
|
function normalizeSettings(raw) {
|
|
@@ -5221,6 +5234,16 @@ function updateAdvancedSettings(patch) {
|
|
|
5221
5234
|
if (patch.followUpBehavior === "queue" || patch.followUpBehavior === "steer") {
|
|
5222
5235
|
advanced.followUpBehavior = patch.followUpBehavior;
|
|
5223
5236
|
}
|
|
5237
|
+
if (isAgentDoneSound(patch.agentDoneSound)) {
|
|
5238
|
+
advanced.agentDoneSound = patch.agentDoneSound;
|
|
5239
|
+
}
|
|
5240
|
+
if (patch.agentDoneCustomSoundName === null || patch.agentDoneCustomSoundName === "") {
|
|
5241
|
+
delete advanced.agentDoneCustomSoundName;
|
|
5242
|
+
} else if (typeof patch.agentDoneCustomSoundName === "string") {
|
|
5243
|
+
const name = patch.agentDoneCustomSoundName.trim();
|
|
5244
|
+
if (name) advanced.agentDoneCustomSoundName = name.slice(0, 200);
|
|
5245
|
+
else delete advanced.agentDoneCustomSoundName;
|
|
5246
|
+
}
|
|
5224
5247
|
return saveAppSettings({ ...current, advanced });
|
|
5225
5248
|
}
|
|
5226
5249
|
function autoRenameBranchEnabled(settings = loadAppSettings()) {
|
|
@@ -5288,6 +5311,9 @@ function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
|
5288
5311
|
function followUpBehavior(settings = loadAppSettings()) {
|
|
5289
5312
|
return settings.advanced.followUpBehavior === "queue" ? "queue" : "steer";
|
|
5290
5313
|
}
|
|
5314
|
+
function agentDoneSound(settings = loadAppSettings()) {
|
|
5315
|
+
return isAgentDoneSound(settings.advanced.agentDoneSound) ? settings.advanced.agentDoneSound : "none";
|
|
5316
|
+
}
|
|
5291
5317
|
function maxConcurrentAgents(settings = loadAppSettings()) {
|
|
5292
5318
|
const n = settings.advanced.maxConcurrent;
|
|
5293
5319
|
if (typeof n === "number" && Number.isFinite(n)) {
|
|
@@ -5375,7 +5401,7 @@ function childEnvWithAppSettings(extra) {
|
|
|
5375
5401
|
function harnessEnvKey(harness) {
|
|
5376
5402
|
return HARNESS_ENV_KEYS[harness];
|
|
5377
5403
|
}
|
|
5378
|
-
var import_node_crypto3, import_node_fs15, import_node_os5, import_node_path18, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
|
|
5404
|
+
var import_node_crypto3, import_node_fs15, import_node_os5, import_node_path18, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, AGENT_DONE_SOUNDS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
|
|
5379
5405
|
var init_app_settings = __esm({
|
|
5380
5406
|
"src/store/app-settings.ts"() {
|
|
5381
5407
|
"use strict";
|
|
@@ -5412,6 +5438,18 @@ var init_app_settings = __esm({
|
|
|
5412
5438
|
]);
|
|
5413
5439
|
GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
5414
5440
|
FOLLOW_UP_BEHAVIORS = ["steer", "queue"];
|
|
5441
|
+
AGENT_DONE_SOUNDS = [
|
|
5442
|
+
"none",
|
|
5443
|
+
"goal",
|
|
5444
|
+
"bell",
|
|
5445
|
+
"level",
|
|
5446
|
+
"coin",
|
|
5447
|
+
"fanfare",
|
|
5448
|
+
"magic",
|
|
5449
|
+
"rooster",
|
|
5450
|
+
"whistle",
|
|
5451
|
+
"custom"
|
|
5452
|
+
];
|
|
5415
5453
|
CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
|
|
5416
5454
|
"claude",
|
|
5417
5455
|
"codex",
|
|
@@ -10242,6 +10280,9 @@ var init_injected_mcp = __esm({
|
|
|
10242
10280
|
"mcp__sideboard__present_plan",
|
|
10243
10281
|
"mcp__sideboard__wait_for_job",
|
|
10244
10282
|
"mcp__sideboard__stop_job",
|
|
10283
|
+
"mcp__sideboard__list_run_scripts",
|
|
10284
|
+
"mcp__sideboard__run_dev_script",
|
|
10285
|
+
"mcp__sideboard__stop_dev_script",
|
|
10245
10286
|
"mcp__sideboard__get_viewer_context",
|
|
10246
10287
|
"mcp__sideboard__update_viewer_context"
|
|
10247
10288
|
];
|
|
@@ -10451,6 +10492,13 @@ function toolDescription(name, input) {
|
|
|
10451
10492
|
if (/stop_job$/i.test(name)) {
|
|
10452
10493
|
return str2(input?.id) ? `Stop ${str2(input?.id)}` : "Stop job";
|
|
10453
10494
|
}
|
|
10495
|
+
if (/list_run_scripts$/i.test(name)) return "List run scripts";
|
|
10496
|
+
if (/run_dev_script$/i.test(name)) {
|
|
10497
|
+
return str2(input?.name) ? `Start ${str2(input?.name)}` : "Start Dev script";
|
|
10498
|
+
}
|
|
10499
|
+
if (/stop_dev_script$/i.test(name)) {
|
|
10500
|
+
return str2(input?.name) ? `Stop ${str2(input?.name)}` : "Stop Dev script";
|
|
10501
|
+
}
|
|
10454
10502
|
if (isSubagentToolName(name)) {
|
|
10455
10503
|
const desc = str2(input?.description);
|
|
10456
10504
|
const sub = asRecord(input?.subagentType);
|
|
@@ -14630,61 +14678,92 @@ function getRunScript(worktreePath, repoPath, name) {
|
|
|
14630
14678
|
function getRunMode(worktreePath, repoPath) {
|
|
14631
14679
|
return loadWorkspaceSettings(worktreePath, repoPath)?.runMode ?? "concurrent";
|
|
14632
14680
|
}
|
|
14633
|
-
async function
|
|
14681
|
+
async function reservePort() {
|
|
14634
14682
|
return new Promise((resolve, reject) => {
|
|
14635
14683
|
const server = (0, import_node_net.createServer)();
|
|
14684
|
+
let released = false;
|
|
14685
|
+
const release = () => new Promise((res) => {
|
|
14686
|
+
if (released) {
|
|
14687
|
+
res();
|
|
14688
|
+
return;
|
|
14689
|
+
}
|
|
14690
|
+
released = true;
|
|
14691
|
+
server.close(() => res());
|
|
14692
|
+
});
|
|
14636
14693
|
server.listen(0, "127.0.0.1", () => {
|
|
14637
14694
|
const addr = server.address();
|
|
14638
14695
|
if (!addr || typeof addr === "string") {
|
|
14639
|
-
|
|
14640
|
-
reject(new Error("Failed to allocate port"));
|
|
14696
|
+
void release().then(() => reject(new Error("Failed to allocate port")));
|
|
14641
14697
|
return;
|
|
14642
14698
|
}
|
|
14643
|
-
|
|
14644
|
-
server.close((err) => err ? reject(err) : resolve(port));
|
|
14699
|
+
resolve({ port: addr.port, release });
|
|
14645
14700
|
});
|
|
14646
14701
|
server.on("error", reject);
|
|
14647
14702
|
});
|
|
14648
14703
|
}
|
|
14649
|
-
async function
|
|
14650
|
-
|
|
14651
|
-
|
|
14652
|
-
|
|
14653
|
-
const
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14704
|
+
async function tryReservePort(port) {
|
|
14705
|
+
return new Promise((resolve) => {
|
|
14706
|
+
const server = (0, import_node_net.createServer)();
|
|
14707
|
+
let released = false;
|
|
14708
|
+
const release = () => new Promise((res) => {
|
|
14709
|
+
if (released) {
|
|
14710
|
+
res();
|
|
14711
|
+
return;
|
|
14712
|
+
}
|
|
14713
|
+
released = true;
|
|
14714
|
+
server.close(() => res());
|
|
14660
14715
|
});
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14716
|
+
server.once("error", () => resolve(null));
|
|
14717
|
+
server.listen(port, "127.0.0.1", () => {
|
|
14718
|
+
resolve({ port, release });
|
|
14719
|
+
});
|
|
14720
|
+
});
|
|
14721
|
+
}
|
|
14722
|
+
async function reservePortRange(size = PORT_RANGE_SIZE) {
|
|
14723
|
+
const held = [await reservePort()];
|
|
14724
|
+
const base = held[0].port;
|
|
14725
|
+
try {
|
|
14726
|
+
for (let i = 1; i < size; i++) {
|
|
14727
|
+
const candidate = base + i;
|
|
14728
|
+
const next = await tryReservePort(candidate);
|
|
14729
|
+
if (next) {
|
|
14730
|
+
held.push(next);
|
|
14731
|
+
} else {
|
|
14732
|
+
held.push(await reservePort());
|
|
14733
|
+
}
|
|
14665
14734
|
}
|
|
14735
|
+
return held;
|
|
14736
|
+
} catch (err) {
|
|
14737
|
+
await Promise.all(held.map((h) => h.release()));
|
|
14738
|
+
throw err;
|
|
14666
14739
|
}
|
|
14667
|
-
return ports;
|
|
14668
14740
|
}
|
|
14669
14741
|
async function startDevServer(repoPath, worktreePath, onLine, opts) {
|
|
14670
14742
|
const script = getRunScript(worktreePath, repoPath, opts?.scriptName);
|
|
14671
14743
|
if (!script) return null;
|
|
14672
|
-
const
|
|
14673
|
-
const
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
|
|
14680
|
-
|
|
14681
|
-
|
|
14682
|
-
|
|
14683
|
-
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14687
|
-
|
|
14744
|
+
const held = await reservePortRange(PORT_RANGE_SIZE);
|
|
14745
|
+
const ports = held.map((h) => h.port);
|
|
14746
|
+
try {
|
|
14747
|
+
await Promise.all(held.map((h) => h.release()));
|
|
14748
|
+
const handle = await spawnWorkspaceScript(script.command, {
|
|
14749
|
+
worktreePath,
|
|
14750
|
+
repoPath,
|
|
14751
|
+
ports,
|
|
14752
|
+
defaultBranch: opts?.defaultBranch,
|
|
14753
|
+
onLine
|
|
14754
|
+
});
|
|
14755
|
+
return {
|
|
14756
|
+
pid: handle.pid,
|
|
14757
|
+
port: ports[0],
|
|
14758
|
+
ports,
|
|
14759
|
+
scriptName: script.name,
|
|
14760
|
+
kill: handle.kill,
|
|
14761
|
+
done: handle.done
|
|
14762
|
+
};
|
|
14763
|
+
} catch (err) {
|
|
14764
|
+
await Promise.all(held.map((h) => h.release()));
|
|
14765
|
+
throw err;
|
|
14766
|
+
}
|
|
14688
14767
|
}
|
|
14689
14768
|
var import_node_fs37, import_node_child_process4, import_node_net, import_node_path39, import_execa4, import_node_readline3, PORT_RANGE_SIZE, cachedLoginEnv;
|
|
14690
14769
|
var init_conductor = __esm({
|
|
@@ -20498,12 +20577,13 @@ function formatLongRunningDirective(opts) {
|
|
|
20498
20577
|
"- Loop Sideboard MCP `wait_for_job` (returns in ~45s). The desktop opens a `type=log` pane from wait/stop (and shell detached-job JSON) automatically \u2014 you may still `present_artifact` with `artifact_id=<id>` for a custom title. stillRunning \u2192 wait again. Shell fallback: the same helper with `wait <id>`.",
|
|
20499
20578
|
"- Hanging, no useful output, or the wrong thing \u2192 `stop_job` (or the helper with `stop <id>`). Do not stop a pack/test/deploy that is clearly making progress.",
|
|
20500
20579
|
"- Stay in the loop until stillRunning is false (or you stopped it). ok \u2192 finish the task. failed / stopped \u2192 read the log, fix or narrow the command, start once.",
|
|
20501
|
-
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
20580
|
+
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
|
|
20581
|
+
"Project Dev / run scripts (`.sideboard` `[scripts.run.*]`, same as the desktop Dev button): use MCP `list_run_scripts` / `run_dev_script` / `stop_dev_script` \u2014 logs and Stop live in the thread UI. Do not detached-job or shell-spawn that same command."
|
|
20502
20582
|
].join("\n");
|
|
20503
20583
|
}
|
|
20504
20584
|
function formatLongRunningReminder(opts) {
|
|
20505
20585
|
const invoke = formatDetachedJobInvoke(opts?.scriptPath);
|
|
20506
|
-
return `Long jobs: \`${invoke} start <id> -- <cmd>\`, loop wait_for_job (or detached-job wait). The log pane updates from wait JSON; present_artifact type=log is optional. stop_job if hanging or wrong. Do not say you will let the user know later \u2014 stay in the turn.`;
|
|
20586
|
+
return `Long jobs: \`${invoke} start <id> -- <cmd>\`, loop wait_for_job (or detached-job wait). The log pane updates from wait JSON; present_artifact type=log is optional. stop_job if hanging or wrong. Do not say you will let the user know later \u2014 stay in the turn. Project Dev button: list_run_scripts / run_dev_script / stop_dev_script (UI-connected \u2014 not detached-job).`;
|
|
20507
20587
|
}
|
|
20508
20588
|
function formatArtifactDirective() {
|
|
20509
20589
|
return [
|
|
@@ -20515,7 +20595,7 @@ function formatArtifactDirective() {
|
|
|
20515
20595
|
].join("\n");
|
|
20516
20596
|
}
|
|
20517
20597
|
function formatUiReminder() {
|
|
20518
|
-
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
20598
|
+
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. type=log appends (same artifact_id, new lines only). ask_user only for a real multiple-choice (not hellos, \u201Cwhat next?\u201D, or after a review) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable. Dev / preview: run_dev_script (same as the Dev button); stop_dev_script to stop.";
|
|
20519
20599
|
}
|
|
20520
20600
|
var import_node_fs50, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
20521
20601
|
var init_instructions = __esm({
|
|
@@ -21662,6 +21742,8 @@ var init_orchestrator = __esm({
|
|
|
21662
21742
|
/** Auto-continues after a worktree turn ended while a detached job still runs. */
|
|
21663
21743
|
jobContinueCount = /* @__PURE__ */ new Map();
|
|
21664
21744
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
21745
|
+
/** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
|
|
21746
|
+
startingDev = /* @__PURE__ */ new Map();
|
|
21665
21747
|
maxConcurrent;
|
|
21666
21748
|
runningCount = 0;
|
|
21667
21749
|
constructor(opts) {
|
|
@@ -22879,9 +22961,20 @@ var init_orchestrator = __esm({
|
|
|
22879
22961
|
"No run script found for this worktree. Add [scripts.run.*] in the worktree\u2019s .sideboard/settings.toml or .conductor/settings.toml (or settings.local.toml on the main repo)."
|
|
22880
22962
|
);
|
|
22881
22963
|
}
|
|
22964
|
+
const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
|
|
22965
|
+
const inFlight = this.startingDev.get(runKey);
|
|
22966
|
+
if (inFlight) return inFlight;
|
|
22967
|
+
const start = this.startDevUnlocked(thread, resolvedName, scriptName, scripts, runKey);
|
|
22968
|
+
this.startingDev.set(runKey, start);
|
|
22969
|
+
try {
|
|
22970
|
+
return await start;
|
|
22971
|
+
} finally {
|
|
22972
|
+
this.startingDev.delete(runKey);
|
|
22973
|
+
}
|
|
22974
|
+
}
|
|
22975
|
+
async startDevUnlocked(thread, resolvedName, scriptName, scripts, runKey) {
|
|
22882
22976
|
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
22883
22977
|
const shared = mergeWorktreeActiveRuns(siblings);
|
|
22884
|
-
const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
|
|
22885
22978
|
const existing = this.processes.get(runKey) ?? siblings.map((t) => this.processes.get(`${t.id}:run:${resolvedName}`)).find(Boolean);
|
|
22886
22979
|
const active = shared.activeRuns.find((r) => r.scriptName === resolvedName);
|
|
22887
22980
|
if (existing && active) {
|
|
@@ -22893,6 +22986,14 @@ var init_orchestrator = __esm({
|
|
|
22893
22986
|
return { port: shared.devPort, scriptName: resolvedName, ports: [shared.devPort] };
|
|
22894
22987
|
}
|
|
22895
22988
|
}
|
|
22989
|
+
if (active && !existing) {
|
|
22990
|
+
killListenersOnPorts(collectActiveRunPorts([active]));
|
|
22991
|
+
this.syncWorktreeRuns(
|
|
22992
|
+
thread.worktreePath,
|
|
22993
|
+
shared.activeRuns.filter((r) => r.scriptName !== resolvedName),
|
|
22994
|
+
shared.devPort === active.port ? null : shared.devPort
|
|
22995
|
+
);
|
|
22996
|
+
}
|
|
22896
22997
|
const mode = getRunMode(thread.worktreePath, thread.repoPath);
|
|
22897
22998
|
if (mode === "nonconcurrent") {
|
|
22898
22999
|
const here = normalizeWorktreePath(thread.worktreePath);
|
|
@@ -22941,6 +23042,7 @@ var init_orchestrator = __esm({
|
|
|
22941
23042
|
kill: handle.kill
|
|
22942
23043
|
});
|
|
22943
23044
|
}
|
|
23045
|
+
const latestShared = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
|
|
22944
23046
|
const run2 = {
|
|
22945
23047
|
scriptName: resolvedName,
|
|
22946
23048
|
port: handle.port,
|
|
@@ -22948,13 +23050,13 @@ var init_orchestrator = __esm({
|
|
|
22948
23050
|
startedAt
|
|
22949
23051
|
};
|
|
22950
23052
|
const nextRuns = [
|
|
22951
|
-
...
|
|
23053
|
+
...latestShared.activeRuns.filter((r) => r.scriptName !== resolvedName),
|
|
22952
23054
|
run2
|
|
22953
23055
|
];
|
|
22954
23056
|
this.syncWorktreeRuns(
|
|
22955
23057
|
thread.worktreePath,
|
|
22956
23058
|
nextRuns,
|
|
22957
|
-
isDefault ? handle.port :
|
|
23059
|
+
isDefault ? handle.port : latestShared.devPort
|
|
22958
23060
|
);
|
|
22959
23061
|
this.emit({
|
|
22960
23062
|
type: "dev_server_started",
|
|
@@ -25677,6 +25779,23 @@ function mcpArchiveBlockedReason(thread) {
|
|
|
25677
25779
|
|
|
25678
25780
|
// src/mcp/server.ts
|
|
25679
25781
|
init_profile();
|
|
25782
|
+
|
|
25783
|
+
// src/mcp/run-script-ref.ts
|
|
25784
|
+
init_chat_tabs();
|
|
25785
|
+
function resolveRunScriptThreadRef(ref) {
|
|
25786
|
+
const explicit = ref?.trim();
|
|
25787
|
+
if (explicit) return explicit;
|
|
25788
|
+
const siblings = threadsSharingWorktree(process.cwd());
|
|
25789
|
+
const thread = siblings[0];
|
|
25790
|
+
if (!thread) {
|
|
25791
|
+
throw new Error(
|
|
25792
|
+
"No Sideboard thread for this cwd. Pass ref (thread id), or call from a worktree chat."
|
|
25793
|
+
);
|
|
25794
|
+
}
|
|
25795
|
+
return thread.id;
|
|
25796
|
+
}
|
|
25797
|
+
|
|
25798
|
+
// src/mcp/server.ts
|
|
25680
25799
|
init_wait_for_turn();
|
|
25681
25800
|
init_wait_for_job();
|
|
25682
25801
|
init_message_parts();
|
|
@@ -28108,13 +28227,73 @@ async function startMcpServer() {
|
|
|
28108
28227
|
"Stop a detached job you started with detached-job.cjs when it is hanging, producing no useful output, buffering forever, or doing the wrong thing (wrong project, infinite watch, huge dump). Do not stop a pack/test/deploy that is clearly making progress. The type=log pane updates to status=failed with the last delta. Then decide the next step.",
|
|
28109
28228
|
{
|
|
28110
28229
|
id: import_zod9.z.string().describe("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
|
|
28111
|
-
reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the
|
|
28230
|
+
reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the answer)")
|
|
28112
28231
|
},
|
|
28113
28232
|
async ({ id, reason }) => {
|
|
28114
28233
|
const result = await stopDetachedJob(process.cwd(), id, { reason });
|
|
28115
28234
|
return mcpJson(result);
|
|
28116
28235
|
}
|
|
28117
28236
|
);
|
|
28237
|
+
server.tool(
|
|
28238
|
+
"list_run_scripts",
|
|
28239
|
+
"List .sideboard/.conductor run scripts for this thread (same menu as the desktop Dev button) and which are active. Worktree turns may omit ref (uses cwd).",
|
|
28240
|
+
{
|
|
28241
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd).")
|
|
28242
|
+
},
|
|
28243
|
+
async ({ ref }) => {
|
|
28244
|
+
try {
|
|
28245
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28246
|
+
const scripts = orch.listThreadRunScripts(threadRef);
|
|
28247
|
+
const active = orch.getActiveRuns(threadRef);
|
|
28248
|
+
return mcpJson({ scripts, active, ref: threadRef });
|
|
28249
|
+
} catch (err) {
|
|
28250
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28251
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28252
|
+
}
|
|
28253
|
+
}
|
|
28254
|
+
);
|
|
28255
|
+
server.tool(
|
|
28256
|
+
"run_dev_script",
|
|
28257
|
+
"Start a .sideboard/.conductor run script (same as the desktop Dev / play button). Logs and Stop appear in the thread UI \u2014 do not detached-job or shell-spawn the same command. Returns the allocated port. Worktree turns may omit ref (uses cwd). Omit name for the default script.",
|
|
28258
|
+
{
|
|
28259
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
|
|
28260
|
+
name: import_zod9.z.string().optional().describe("Script name from list_run_scripts (default script if omitted).")
|
|
28261
|
+
},
|
|
28262
|
+
async ({ ref, name }) => {
|
|
28263
|
+
try {
|
|
28264
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28265
|
+
const result = await orch.startDev(threadRef, name);
|
|
28266
|
+
return mcpJson({
|
|
28267
|
+
port: result.port,
|
|
28268
|
+
scriptName: result.scriptName,
|
|
28269
|
+
ports: result.ports,
|
|
28270
|
+
url: `http://localhost:${result.port}`,
|
|
28271
|
+
ref: threadRef
|
|
28272
|
+
});
|
|
28273
|
+
} catch (err) {
|
|
28274
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28275
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28276
|
+
}
|
|
28277
|
+
}
|
|
28278
|
+
);
|
|
28279
|
+
server.tool(
|
|
28280
|
+
"stop_dev_script",
|
|
28281
|
+
"Stop a run script started with run_dev_script or the desktop Dev button (same as UI Stop). Omit name to stop all scripts on this worktree. Worktree turns may omit ref (uses cwd).",
|
|
28282
|
+
{
|
|
28283
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
|
|
28284
|
+
name: import_zod9.z.string().optional().describe("Script name to stop; omit to stop all active scripts.")
|
|
28285
|
+
},
|
|
28286
|
+
async ({ ref, name }) => {
|
|
28287
|
+
try {
|
|
28288
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28289
|
+
orch.stopDev(threadRef, name);
|
|
28290
|
+
return mcpJson({ ok: true, ref: threadRef, stopped: name ?? "all" });
|
|
28291
|
+
} catch (err) {
|
|
28292
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28293
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28294
|
+
}
|
|
28295
|
+
}
|
|
28296
|
+
);
|
|
28118
28297
|
if (!worktreeProfile) {
|
|
28119
28298
|
registerSlackTools(server);
|
|
28120
28299
|
registerConnectedIssueVendorTools(server);
|
|
@@ -28593,45 +28772,6 @@ async function startMcpServer() {
|
|
|
28593
28772
|
}
|
|
28594
28773
|
}
|
|
28595
28774
|
);
|
|
28596
|
-
server.tool(
|
|
28597
|
-
"run_dev_script",
|
|
28598
|
-
"Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
|
|
28599
|
-
{
|
|
28600
|
-
ref: import_zod9.z.string(),
|
|
28601
|
-
name: import_zod9.z.string().optional()
|
|
28602
|
-
},
|
|
28603
|
-
async ({ ref, name }) => {
|
|
28604
|
-
const result = await orch.startDev(ref, name);
|
|
28605
|
-
return mcpJson({
|
|
28606
|
-
port: result.port,
|
|
28607
|
-
scriptName: result.scriptName,
|
|
28608
|
-
ports: result.ports,
|
|
28609
|
-
url: `http://localhost:${result.port}`
|
|
28610
|
-
});
|
|
28611
|
-
}
|
|
28612
|
-
);
|
|
28613
|
-
server.tool(
|
|
28614
|
-
"list_run_scripts",
|
|
28615
|
-
"List named run scripts available for a thread",
|
|
28616
|
-
{ ref: import_zod9.z.string() },
|
|
28617
|
-
async ({ ref }) => {
|
|
28618
|
-
const scripts = orch.listThreadRunScripts(ref);
|
|
28619
|
-
const active = orch.getActiveRuns(ref);
|
|
28620
|
-
return mcpJson({ scripts, active });
|
|
28621
|
-
}
|
|
28622
|
-
);
|
|
28623
|
-
server.tool(
|
|
28624
|
-
"stop_dev_script",
|
|
28625
|
-
"Stop a running script for a thread (all scripts if name omitted)",
|
|
28626
|
-
{
|
|
28627
|
-
ref: import_zod9.z.string(),
|
|
28628
|
-
name: import_zod9.z.string().optional()
|
|
28629
|
-
},
|
|
28630
|
-
async ({ ref, name }) => {
|
|
28631
|
-
orch.stopDev(ref, name);
|
|
28632
|
-
return { content: [{ type: "text", text: "ok" }] };
|
|
28633
|
-
}
|
|
28634
|
-
);
|
|
28635
28775
|
server.tool(
|
|
28636
28776
|
"run_setup",
|
|
28637
28777
|
"Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
|