@sideboard-ai/core 0.1.228 → 0.1.230
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-ENAQHQRZ.js} +5 -5
- package/dist/{agents-QQ77D7VT.js → agents-TCTEAK6M.js} +5 -5
- 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-NFWPDEN4.js → chunk-4CZ25DO2.js} +2 -2
- package/dist/{chunk-3IMSQNTS.js → chunk-4VGCG2HV.js} +17 -0
- package/dist/{chunk-SQHRPJ7P.js → chunk-6L25K7BE.js} +14 -4
- package/dist/{chunk-HSYE5ID6.js → chunk-AS4UN7QL.js} +5 -5
- package/dist/{chunk-3NWUHXU3.js → chunk-C774RJJA.js} +3 -3
- package/dist/{chunk-VUW3VKLW.js → chunk-FA4CPYCY.js} +17 -4
- package/dist/{chunk-CLI5DVU4.js → chunk-GHRZNPBK.js} +2 -2
- package/dist/{chunk-N2VST3NL.js → chunk-HZFLKVGC.js} +3 -3
- package/dist/{chunk-72XUASTH.js → chunk-HZLZ34FK.js} +157 -26
- package/dist/{chunk-EWHJNJHV.js → chunk-I5NC7DWO.js} +38 -0
- package/dist/{chunk-WHYJL7CP.js → chunk-JJRRLCCS.js} +156 -25
- package/dist/{chunk-646I442S.js → chunk-MVLXDYN5.js} +5 -5
- package/dist/{chunk-KTZESHYH.js → chunk-N5TX66CD.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-P2EAAM3H.js → chunk-UNTOZA3C.js} +3 -3
- package/dist/{chunk-HY2GFZ5S.js → chunk-XJETIO4K.js} +17 -0
- package/dist/{coordinator-prompt-JLMQVORO.js → coordinator-prompt-DFXYTM6D.js} +4 -4
- package/dist/{coordinator-prompt-VZ7OSRLD.js → coordinator-prompt-YKLXQTWH.js} +4 -4
- package/dist/{global-workspace-3FDAUNN2.js → global-workspace-4SPANNJT.js} +4 -4
- package/dist/{global-workspace-QPSJEXGR.js → global-workspace-EYZKYHAO.js} +4 -4
- package/dist/index.cjs +992 -634
- package/dist/index.d.cts +120 -6
- package/dist/index.d.ts +120 -6
- package/dist/index.js +207 -68
- package/dist/mcp/run-stdio.cjs +289 -50
- package/dist/mcp/run-stdio.js +87 -51
- package/dist/{orchestrator-6XEWQWSM.js → orchestrator-HMJPNUN5.js} +8 -6
- package/dist/{orchestrator-QUJORSTA.js → orchestrator-ZT3SJVKF.js} +8 -6
- package/dist/{thread-store-KDPPXJJ3.js → thread-store-FBK5SZ5P.js} +1 -1
- package/dist/{thread-store-N6WQIWZ4.js → thread-store-IKJD4EOK.js} +1 -1
- package/dist/{workspaces-76W7IEKR.js → workspaces-73Y7IJY2.js} +4 -4
- package/dist/{workspaces-TDBA64II.js → workspaces-FQCSCTNH.js} +4 -4
- package/dist/{worktree-7V67XTEO.js → worktree-36VEFUJN.js} +3 -3
- package/dist/{worktree-I573UOPD.js → worktree-DOPRKG7K.js} +3 -3
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -861,6 +861,22 @@ function resolveThreadEffort(raw) {
|
|
|
861
861
|
if (raw.fast) return "low";
|
|
862
862
|
return "high";
|
|
863
863
|
}
|
|
864
|
+
function normalizeRunScriptRequest(raw) {
|
|
865
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
866
|
+
const req = raw;
|
|
867
|
+
if (req.op !== "start" && req.op !== "stop") return void 0;
|
|
868
|
+
if (typeof req.requestId !== "string" || !req.requestId.trim()) return void 0;
|
|
869
|
+
if (typeof req.requestedAt !== "string" || !req.requestedAt.trim()) return void 0;
|
|
870
|
+
return {
|
|
871
|
+
op: req.op,
|
|
872
|
+
scriptName: req.scriptName ?? null,
|
|
873
|
+
requestId: req.requestId,
|
|
874
|
+
requestedAt: req.requestedAt,
|
|
875
|
+
claimedAt: req.claimedAt ?? null,
|
|
876
|
+
fulfilledAt: req.fulfilledAt ?? null,
|
|
877
|
+
error: req.error ?? null
|
|
878
|
+
};
|
|
879
|
+
}
|
|
864
880
|
function normalizeThread(raw) {
|
|
865
881
|
return {
|
|
866
882
|
...raw,
|
|
@@ -884,6 +900,7 @@ function normalizeThread(raw) {
|
|
|
884
900
|
stackLayer: raw.stackLayer ?? null,
|
|
885
901
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
886
902
|
activeRuns: Array.isArray(raw.activeRuns) ? raw.activeRuns : [],
|
|
903
|
+
runScriptRequest: normalizeRunScriptRequest(raw.runScriptRequest),
|
|
887
904
|
quotaResumeAt: raw.quotaResumeAt ?? null,
|
|
888
905
|
quotaContinuedFromId: raw.quotaContinuedFromId ?? null,
|
|
889
906
|
archivedAt: typeof raw.archivedAt === "string" && raw.archivedAt.trim() ? raw.archivedAt.trim() : void 0
|
|
@@ -3787,12 +3804,14 @@ var init_issue_source_labels = __esm({
|
|
|
3787
3804
|
// src/store/app-settings.ts
|
|
3788
3805
|
var app_settings_exports = {};
|
|
3789
3806
|
__export(app_settings_exports, {
|
|
3807
|
+
AGENT_DONE_SOUNDS: () => AGENT_DONE_SOUNDS,
|
|
3790
3808
|
FOLLOW_UP_BEHAVIORS: () => FOLLOW_UP_BEHAVIORS,
|
|
3791
3809
|
GITHUB_GIT_AUTH_MODES: () => GITHUB_GIT_AUTH_MODES,
|
|
3792
3810
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
3793
3811
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
3794
3812
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
3795
3813
|
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
3814
|
+
agentDoneSound: () => agentDoneSound,
|
|
3796
3815
|
appSettingsPath: () => appSettingsPath,
|
|
3797
3816
|
applyAppEnvironment: () => applyAppEnvironment,
|
|
3798
3817
|
autoArchiveOnMergeEnabled: () => autoArchiveOnMergeEnabled,
|
|
@@ -3840,6 +3859,7 @@ __export(app_settings_exports, {
|
|
|
3840
3859
|
historyMaxCount: () => historyMaxCount,
|
|
3841
3860
|
historyMaxDays: () => historyMaxDays,
|
|
3842
3861
|
isAbleTimeConnected: () => isAbleTimeConnected,
|
|
3862
|
+
isAgentDoneSound: () => isAgentDoneSound,
|
|
3843
3863
|
isIssueSourceConnected: () => isIssueSourceConnected,
|
|
3844
3864
|
isLinearConnected: () => isLinearConnected,
|
|
3845
3865
|
isUsageOnLimit: () => isUsageOnLimit,
|
|
@@ -3881,6 +3901,9 @@ __export(app_settings_exports, {
|
|
|
3881
3901
|
usageOnLimit: () => usageOnLimit,
|
|
3882
3902
|
writeViewerContext: () => writeViewerContext
|
|
3883
3903
|
});
|
|
3904
|
+
function isAgentDoneSound(value) {
|
|
3905
|
+
return AGENT_DONE_SOUNDS.includes(value);
|
|
3906
|
+
}
|
|
3884
3907
|
function emptyPublicIntegrations() {
|
|
3885
3908
|
return {
|
|
3886
3909
|
hasLinearApiKey: false,
|
|
@@ -4311,6 +4334,13 @@ function normalizeAdvanced(raw) {
|
|
|
4311
4334
|
if (source.followUpBehavior === "queue" || source.followUpBehavior === "steer") {
|
|
4312
4335
|
out.followUpBehavior = source.followUpBehavior;
|
|
4313
4336
|
}
|
|
4337
|
+
if (isAgentDoneSound(source.agentDoneSound)) {
|
|
4338
|
+
out.agentDoneSound = source.agentDoneSound;
|
|
4339
|
+
}
|
|
4340
|
+
if (typeof source.agentDoneCustomSoundName === "string") {
|
|
4341
|
+
const name = source.agentDoneCustomSoundName.trim();
|
|
4342
|
+
if (name) out.agentDoneCustomSoundName = name.slice(0, 200);
|
|
4343
|
+
}
|
|
4314
4344
|
return out;
|
|
4315
4345
|
}
|
|
4316
4346
|
function normalizeSettings(raw) {
|
|
@@ -5221,6 +5251,16 @@ function updateAdvancedSettings(patch) {
|
|
|
5221
5251
|
if (patch.followUpBehavior === "queue" || patch.followUpBehavior === "steer") {
|
|
5222
5252
|
advanced.followUpBehavior = patch.followUpBehavior;
|
|
5223
5253
|
}
|
|
5254
|
+
if (isAgentDoneSound(patch.agentDoneSound)) {
|
|
5255
|
+
advanced.agentDoneSound = patch.agentDoneSound;
|
|
5256
|
+
}
|
|
5257
|
+
if (patch.agentDoneCustomSoundName === null || patch.agentDoneCustomSoundName === "") {
|
|
5258
|
+
delete advanced.agentDoneCustomSoundName;
|
|
5259
|
+
} else if (typeof patch.agentDoneCustomSoundName === "string") {
|
|
5260
|
+
const name = patch.agentDoneCustomSoundName.trim();
|
|
5261
|
+
if (name) advanced.agentDoneCustomSoundName = name.slice(0, 200);
|
|
5262
|
+
else delete advanced.agentDoneCustomSoundName;
|
|
5263
|
+
}
|
|
5224
5264
|
return saveAppSettings({ ...current, advanced });
|
|
5225
5265
|
}
|
|
5226
5266
|
function autoRenameBranchEnabled(settings = loadAppSettings()) {
|
|
@@ -5288,6 +5328,9 @@ function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
|
5288
5328
|
function followUpBehavior(settings = loadAppSettings()) {
|
|
5289
5329
|
return settings.advanced.followUpBehavior === "queue" ? "queue" : "steer";
|
|
5290
5330
|
}
|
|
5331
|
+
function agentDoneSound(settings = loadAppSettings()) {
|
|
5332
|
+
return isAgentDoneSound(settings.advanced.agentDoneSound) ? settings.advanced.agentDoneSound : "none";
|
|
5333
|
+
}
|
|
5291
5334
|
function maxConcurrentAgents(settings = loadAppSettings()) {
|
|
5292
5335
|
const n = settings.advanced.maxConcurrent;
|
|
5293
5336
|
if (typeof n === "number" && Number.isFinite(n)) {
|
|
@@ -5375,7 +5418,7 @@ function childEnvWithAppSettings(extra) {
|
|
|
5375
5418
|
function harnessEnvKey(harness) {
|
|
5376
5419
|
return HARNESS_ENV_KEYS[harness];
|
|
5377
5420
|
}
|
|
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;
|
|
5421
|
+
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
5422
|
var init_app_settings = __esm({
|
|
5380
5423
|
"src/store/app-settings.ts"() {
|
|
5381
5424
|
"use strict";
|
|
@@ -5412,6 +5455,18 @@ var init_app_settings = __esm({
|
|
|
5412
5455
|
]);
|
|
5413
5456
|
GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
5414
5457
|
FOLLOW_UP_BEHAVIORS = ["steer", "queue"];
|
|
5458
|
+
AGENT_DONE_SOUNDS = [
|
|
5459
|
+
"none",
|
|
5460
|
+
"goal",
|
|
5461
|
+
"bell",
|
|
5462
|
+
"level",
|
|
5463
|
+
"coin",
|
|
5464
|
+
"fanfare",
|
|
5465
|
+
"magic",
|
|
5466
|
+
"rooster",
|
|
5467
|
+
"whistle",
|
|
5468
|
+
"custom"
|
|
5469
|
+
];
|
|
5415
5470
|
CLOUD_CONNECT_AGENTS = /* @__PURE__ */ new Set([
|
|
5416
5471
|
"claude",
|
|
5417
5472
|
"codex",
|
|
@@ -10242,6 +10297,9 @@ var init_injected_mcp = __esm({
|
|
|
10242
10297
|
"mcp__sideboard__present_plan",
|
|
10243
10298
|
"mcp__sideboard__wait_for_job",
|
|
10244
10299
|
"mcp__sideboard__stop_job",
|
|
10300
|
+
"mcp__sideboard__list_run_scripts",
|
|
10301
|
+
"mcp__sideboard__run_dev_script",
|
|
10302
|
+
"mcp__sideboard__stop_dev_script",
|
|
10245
10303
|
"mcp__sideboard__get_viewer_context",
|
|
10246
10304
|
"mcp__sideboard__update_viewer_context"
|
|
10247
10305
|
];
|
|
@@ -10451,6 +10509,13 @@ function toolDescription(name, input) {
|
|
|
10451
10509
|
if (/stop_job$/i.test(name)) {
|
|
10452
10510
|
return str2(input?.id) ? `Stop ${str2(input?.id)}` : "Stop job";
|
|
10453
10511
|
}
|
|
10512
|
+
if (/list_run_scripts$/i.test(name)) return "List run scripts";
|
|
10513
|
+
if (/run_dev_script$/i.test(name)) {
|
|
10514
|
+
return str2(input?.name) ? `Start ${str2(input?.name)}` : "Start Dev script";
|
|
10515
|
+
}
|
|
10516
|
+
if (/stop_dev_script$/i.test(name)) {
|
|
10517
|
+
return str2(input?.name) ? `Stop ${str2(input?.name)}` : "Stop Dev script";
|
|
10518
|
+
}
|
|
10454
10519
|
if (isSubagentToolName(name)) {
|
|
10455
10520
|
const desc = str2(input?.description);
|
|
10456
10521
|
const sub = asRecord(input?.subagentType);
|
|
@@ -15211,6 +15276,16 @@ var init_clone_repo = __esm({
|
|
|
15211
15276
|
}
|
|
15212
15277
|
});
|
|
15213
15278
|
|
|
15279
|
+
// src/types/thread.ts
|
|
15280
|
+
function isUnclaimedRunScriptRequest(req) {
|
|
15281
|
+
return Boolean(req && !req.claimedAt && !req.fulfilledAt && !req.error);
|
|
15282
|
+
}
|
|
15283
|
+
var init_thread = __esm({
|
|
15284
|
+
"src/types/thread.ts"() {
|
|
15285
|
+
"use strict";
|
|
15286
|
+
}
|
|
15287
|
+
});
|
|
15288
|
+
|
|
15214
15289
|
// src/store/desktop-host.ts
|
|
15215
15290
|
function desktopHostPidPath() {
|
|
15216
15291
|
return (0, import_node_path43.join)(appDataDir(), "desktop-host.pid");
|
|
@@ -20529,12 +20604,13 @@ function formatLongRunningDirective(opts) {
|
|
|
20529
20604
|
"- 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>`.",
|
|
20530
20605
|
"- 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.",
|
|
20531
20606
|
"- 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.",
|
|
20532
|
-
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
20607
|
+
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
|
|
20608
|
+
"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."
|
|
20533
20609
|
].join("\n");
|
|
20534
20610
|
}
|
|
20535
20611
|
function formatLongRunningReminder(opts) {
|
|
20536
20612
|
const invoke = formatDetachedJobInvoke(opts?.scriptPath);
|
|
20537
|
-
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.`;
|
|
20613
|
+
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).`;
|
|
20538
20614
|
}
|
|
20539
20615
|
function formatArtifactDirective() {
|
|
20540
20616
|
return [
|
|
@@ -20546,7 +20622,7 @@ function formatArtifactDirective() {
|
|
|
20546
20622
|
].join("\n");
|
|
20547
20623
|
}
|
|
20548
20624
|
function formatUiReminder() {
|
|
20549
|
-
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.";
|
|
20625
|
+
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.";
|
|
20550
20626
|
}
|
|
20551
20627
|
var import_node_fs50, import_node_path49, PR_GOAL_RE, GITHUB_TICKET_REF, KEYED_TICKET_REF;
|
|
20552
20628
|
var init_instructions = __esm({
|
|
@@ -21478,6 +21554,7 @@ __export(orchestrator_exports, {
|
|
|
21478
21554
|
LIGHT_RECONCILE_THROTTLE_MS: () => LIGHT_RECONCILE_THROTTLE_MS,
|
|
21479
21555
|
LIVE_TURN_SPAWN_GRACE_MS: () => LIVE_TURN_SPAWN_GRACE_MS,
|
|
21480
21556
|
Orchestrator: () => Orchestrator,
|
|
21557
|
+
RUN_SCRIPT_DESKTOP_ADOPT_MS: () => RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
21481
21558
|
getOrchestrator: () => getOrchestrator,
|
|
21482
21559
|
isPidAlive: () => isPidAlive,
|
|
21483
21560
|
resolveOrchChildFollowUp: () => resolveOrchChildFollowUp,
|
|
@@ -21589,12 +21666,13 @@ async function startOrchestration(opts) {
|
|
|
21589
21666
|
}
|
|
21590
21667
|
return updated;
|
|
21591
21668
|
}
|
|
21592
|
-
var import_node_events, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
21669
|
+
var import_node_events, import_node_crypto12, import_node_fs55, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
|
|
21593
21670
|
var init_orchestrator = __esm({
|
|
21594
21671
|
"src/orchestrator/orchestrator.ts"() {
|
|
21595
21672
|
"use strict";
|
|
21596
21673
|
import_node_events = require("events");
|
|
21597
21674
|
init_outbound_watch();
|
|
21675
|
+
import_node_crypto12 = require("crypto");
|
|
21598
21676
|
import_node_fs55 = require("fs");
|
|
21599
21677
|
init_error_detail();
|
|
21600
21678
|
init_run();
|
|
@@ -21612,6 +21690,7 @@ var init_orchestrator = __esm({
|
|
|
21612
21690
|
init_history_cleanup();
|
|
21613
21691
|
init_apply_into_main();
|
|
21614
21692
|
init_clone_repo();
|
|
21693
|
+
init_thread();
|
|
21615
21694
|
init_message_parts();
|
|
21616
21695
|
init_usage();
|
|
21617
21696
|
init_thread_store();
|
|
@@ -21657,6 +21736,7 @@ var init_orchestrator = __esm({
|
|
|
21657
21736
|
init_schedule_runner();
|
|
21658
21737
|
init_coordinator_prompt();
|
|
21659
21738
|
LIVE_TURN_SPAWN_GRACE_MS = 15e3;
|
|
21739
|
+
RUN_SCRIPT_DESKTOP_ADOPT_MS = 2e4;
|
|
21660
21740
|
STALE_AGENT_PID_WAIT_MS = 2500;
|
|
21661
21741
|
LIGHT_RECONCILE_THROTTLE_MS = 1e4;
|
|
21662
21742
|
Orchestrator = class {
|
|
@@ -21695,6 +21775,11 @@ var init_orchestrator = __esm({
|
|
|
21695
21775
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
21696
21776
|
/** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
|
|
21697
21777
|
startingDev = /* @__PURE__ */ new Map();
|
|
21778
|
+
/**
|
|
21779
|
+
* MCP/CLI poll budget while Electron main adopts `runScriptRequest`.
|
|
21780
|
+
* Tests shorten this so a missing desktop does not wait 20s.
|
|
21781
|
+
*/
|
|
21782
|
+
runScriptAdoptTimeoutMs = RUN_SCRIPT_DESKTOP_ADOPT_MS;
|
|
21698
21783
|
maxConcurrent;
|
|
21699
21784
|
runningCount = 0;
|
|
21700
21785
|
constructor(opts) {
|
|
@@ -21864,6 +21949,58 @@ var init_orchestrator = __esm({
|
|
|
21864
21949
|
this.armDrain(thread.id);
|
|
21865
21950
|
}
|
|
21866
21951
|
}
|
|
21952
|
+
this.adoptPersistedRunScripts();
|
|
21953
|
+
}
|
|
21954
|
+
/**
|
|
21955
|
+
* Adopt run-script start/stop persisted by MCP/CLI while this process owns
|
|
21956
|
+
* live children (desktop host). Spawning in stdio leaves the Run tab on
|
|
21957
|
+
* "Starting…" with no logs — `run_output` never reaches the renderer.
|
|
21958
|
+
*/
|
|
21959
|
+
adoptPersistedRunScripts() {
|
|
21960
|
+
if (!this.shouldOwnRunScripts()) return;
|
|
21961
|
+
for (const thread of listThreads()) {
|
|
21962
|
+
if (thread.status === "archived") continue;
|
|
21963
|
+
const req = thread.runScriptRequest;
|
|
21964
|
+
if (!isUnclaimedRunScriptRequest(req) || !req) continue;
|
|
21965
|
+
const claimedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
21966
|
+
const claimed = { ...req, claimedAt };
|
|
21967
|
+
updateThread(thread.id, { runScriptRequest: claimed });
|
|
21968
|
+
void this.applyRunScriptRequest(thread.id, claimed);
|
|
21969
|
+
}
|
|
21970
|
+
}
|
|
21971
|
+
async applyRunScriptRequest(threadId, req) {
|
|
21972
|
+
try {
|
|
21973
|
+
if (req.op === "start") {
|
|
21974
|
+
await this.startDev(threadId, req.scriptName ?? void 0);
|
|
21975
|
+
} else {
|
|
21976
|
+
await this.stopDev(threadId, req.scriptName ?? void 0);
|
|
21977
|
+
}
|
|
21978
|
+
const latest = readThread(threadId);
|
|
21979
|
+
const current = latest?.runScriptRequest;
|
|
21980
|
+
if (current?.requestId === req.requestId && !current.error) {
|
|
21981
|
+
updateThread(threadId, {
|
|
21982
|
+
runScriptRequest: {
|
|
21983
|
+
...current,
|
|
21984
|
+
fulfilledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
21985
|
+
}
|
|
21986
|
+
});
|
|
21987
|
+
}
|
|
21988
|
+
} catch (err) {
|
|
21989
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21990
|
+
const latest = readThread(threadId);
|
|
21991
|
+
const current = latest?.runScriptRequest;
|
|
21992
|
+
if (!current || current.requestId !== req.requestId) return;
|
|
21993
|
+
updateThread(threadId, {
|
|
21994
|
+
runScriptRequest: { ...current, error: message }
|
|
21995
|
+
});
|
|
21996
|
+
}
|
|
21997
|
+
}
|
|
21998
|
+
/**
|
|
21999
|
+
* Same rule as agent-queue drain: MCP stdio must not own Electron children
|
|
22000
|
+
* while Sideboard.app is alive.
|
|
22001
|
+
*/
|
|
22002
|
+
shouldOwnRunScripts() {
|
|
22003
|
+
return thisProcessShouldDrainAgentQueues();
|
|
21867
22004
|
}
|
|
21868
22005
|
/**
|
|
21869
22006
|
* Mid-session: a worktree can sit at `running` after the agent process dies
|
|
@@ -22912,6 +23049,13 @@ var init_orchestrator = __esm({
|
|
|
22912
23049
|
"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)."
|
|
22913
23050
|
);
|
|
22914
23051
|
}
|
|
23052
|
+
if (!this.shouldOwnRunScripts()) {
|
|
23053
|
+
const result = await this.requestDesktopRunScript(thread, "start", resolvedName);
|
|
23054
|
+
if (!result) {
|
|
23055
|
+
throw new Error("Desktop did not return a run script port.");
|
|
23056
|
+
}
|
|
23057
|
+
return result;
|
|
23058
|
+
}
|
|
22915
23059
|
const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
|
|
22916
23060
|
const inFlight = this.startingDev.get(runKey);
|
|
22917
23061
|
if (inFlight) return inFlight;
|
|
@@ -23034,8 +23178,65 @@ var init_orchestrator = __esm({
|
|
|
23034
23178
|
});
|
|
23035
23179
|
return { port: handle.port, scriptName: resolvedName, ports: handle.ports };
|
|
23036
23180
|
}
|
|
23037
|
-
|
|
23181
|
+
/**
|
|
23182
|
+
* Persist a run-script intent for the desktop host (MCP/CLI while the board
|
|
23183
|
+
* is alive). Polls until Electron main adopts and fulfills it.
|
|
23184
|
+
*/
|
|
23185
|
+
async requestDesktopRunScript(thread, op, scriptName) {
|
|
23186
|
+
const latest = readThread(thread.id) ?? thread;
|
|
23187
|
+
const pending = latest.runScriptRequest;
|
|
23188
|
+
const claimedAt = pending?.claimedAt;
|
|
23189
|
+
const staleClaim = typeof claimedAt === "string" && Date.now() - Date.parse(claimedAt) > this.runScriptAdoptTimeoutMs;
|
|
23190
|
+
const sameIntent = pending && pending.op === op && (pending.scriptName ?? null) === (scriptName ?? null) && !pending.error && !pending.fulfilledAt && !staleClaim;
|
|
23191
|
+
const request = sameIntent ? pending : {
|
|
23192
|
+
op,
|
|
23193
|
+
scriptName: scriptName ?? null,
|
|
23194
|
+
requestId: (0, import_node_crypto12.randomUUID)(),
|
|
23195
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23196
|
+
};
|
|
23197
|
+
if (!sameIntent) {
|
|
23198
|
+
updateThread(thread.id, { runScriptRequest: request });
|
|
23199
|
+
}
|
|
23200
|
+
return this.waitForDesktopRunScript(thread.id, request, op, scriptName);
|
|
23201
|
+
}
|
|
23202
|
+
async waitForDesktopRunScript(threadId, request, op, scriptName) {
|
|
23203
|
+
const deadline = Date.now() + this.runScriptAdoptTimeoutMs;
|
|
23204
|
+
while (Date.now() < deadline) {
|
|
23205
|
+
const latest = readThread(threadId);
|
|
23206
|
+
if (!latest) {
|
|
23207
|
+
throw new Error("Thread disappeared while waiting for the desktop run script.");
|
|
23208
|
+
}
|
|
23209
|
+
const req = latest.runScriptRequest;
|
|
23210
|
+
if (req?.requestId === request.requestId && req.error) {
|
|
23211
|
+
throw new Error(req.error);
|
|
23212
|
+
}
|
|
23213
|
+
const shared = mergeWorktreeActiveRuns(threadsSharingWorktree(latest.worktreePath));
|
|
23214
|
+
const run2 = scriptName ? shared.activeRuns.find((r) => r.scriptName === scriptName) : shared.activeRuns[0];
|
|
23215
|
+
const fulfilled = req?.requestId === request.requestId && Boolean(req.fulfilledAt);
|
|
23216
|
+
const requestGone = !req || req.requestId !== request.requestId;
|
|
23217
|
+
if (op === "start") {
|
|
23218
|
+
if (run2 && (fulfilled || requestGone || run2.startedAt >= request.requestedAt)) {
|
|
23219
|
+
return { port: run2.port, scriptName: run2.scriptName, ports: run2.ports };
|
|
23220
|
+
}
|
|
23221
|
+
if (fulfilled && !run2) {
|
|
23222
|
+
throw new Error("Desktop reported the run script started, but it is not active.");
|
|
23223
|
+
}
|
|
23224
|
+
} else {
|
|
23225
|
+
const gone = scriptName ? !run2 : shared.activeRuns.length === 0;
|
|
23226
|
+
if (fulfilled || gone) return null;
|
|
23227
|
+
}
|
|
23228
|
+
await new Promise((r) => setTimeout(r, 40));
|
|
23229
|
+
}
|
|
23230
|
+
throw new Error(
|
|
23231
|
+
op === "start" ? "Desktop did not start the run script in time. Is Sideboard.app running this worktree?" : "Desktop did not stop the run script in time."
|
|
23232
|
+
);
|
|
23233
|
+
}
|
|
23234
|
+
async stopDev(threadRef, scriptName) {
|
|
23038
23235
|
const thread = this.requireThread(threadRef);
|
|
23236
|
+
if (!this.shouldOwnRunScripts()) {
|
|
23237
|
+
await this.requestDesktopRunScript(thread, "stop", scriptName);
|
|
23238
|
+
return;
|
|
23239
|
+
}
|
|
23039
23240
|
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
23040
23241
|
const shared = mergeWorktreeActiveRuns(siblings);
|
|
23041
23242
|
if (scriptName) {
|
|
@@ -24029,7 +24230,7 @@ init_system_ca();
|
|
|
24029
24230
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
24030
24231
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
24031
24232
|
var import_zod9 = require("zod");
|
|
24032
|
-
var
|
|
24233
|
+
var import_node_crypto15 = require("crypto");
|
|
24033
24234
|
var import_node_path55 = require("path");
|
|
24034
24235
|
init_orchestrator();
|
|
24035
24236
|
init_worktree();
|
|
@@ -24456,7 +24657,7 @@ async function createGitHubIssue(input, opts) {
|
|
|
24456
24657
|
init_fetch();
|
|
24457
24658
|
|
|
24458
24659
|
// src/integrations/linear-oauth.ts
|
|
24459
|
-
var
|
|
24660
|
+
var import_node_crypto13 = require("crypto");
|
|
24460
24661
|
var import_node_http2 = require("http");
|
|
24461
24662
|
init_app_settings();
|
|
24462
24663
|
init_fetch();
|
|
@@ -25730,6 +25931,23 @@ function mcpArchiveBlockedReason(thread) {
|
|
|
25730
25931
|
|
|
25731
25932
|
// src/mcp/server.ts
|
|
25732
25933
|
init_profile();
|
|
25934
|
+
|
|
25935
|
+
// src/mcp/run-script-ref.ts
|
|
25936
|
+
init_chat_tabs();
|
|
25937
|
+
function resolveRunScriptThreadRef(ref) {
|
|
25938
|
+
const explicit = ref?.trim();
|
|
25939
|
+
if (explicit) return explicit;
|
|
25940
|
+
const siblings = threadsSharingWorktree(process.cwd());
|
|
25941
|
+
const thread = siblings[0];
|
|
25942
|
+
if (!thread) {
|
|
25943
|
+
throw new Error(
|
|
25944
|
+
"No Sideboard thread for this cwd. Pass ref (thread id), or call from a worktree chat."
|
|
25945
|
+
);
|
|
25946
|
+
}
|
|
25947
|
+
return thread.id;
|
|
25948
|
+
}
|
|
25949
|
+
|
|
25950
|
+
// src/mcp/server.ts
|
|
25733
25951
|
init_wait_for_turn();
|
|
25734
25952
|
init_wait_for_job();
|
|
25735
25953
|
init_message_parts();
|
|
@@ -27439,7 +27657,7 @@ init_worktree();
|
|
|
27439
27657
|
init_paths();
|
|
27440
27658
|
|
|
27441
27659
|
// src/board/board-pins.ts
|
|
27442
|
-
var
|
|
27660
|
+
var import_node_crypto14 = require("crypto");
|
|
27443
27661
|
var import_node_fs56 = require("fs");
|
|
27444
27662
|
var import_node_path53 = require("path");
|
|
27445
27663
|
init_paths();
|
|
@@ -28161,13 +28379,73 @@ async function startMcpServer() {
|
|
|
28161
28379
|
"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.",
|
|
28162
28380
|
{
|
|
28163
28381
|
id: import_zod9.z.string().describe("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
|
|
28164
|
-
reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the
|
|
28382
|
+
reason: import_zod9.z.string().optional().describe("Why you are stopping (hanging, no progress, wrong output, already have the answer)")
|
|
28165
28383
|
},
|
|
28166
28384
|
async ({ id, reason }) => {
|
|
28167
28385
|
const result = await stopDetachedJob(process.cwd(), id, { reason });
|
|
28168
28386
|
return mcpJson(result);
|
|
28169
28387
|
}
|
|
28170
28388
|
);
|
|
28389
|
+
server.tool(
|
|
28390
|
+
"list_run_scripts",
|
|
28391
|
+
"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).",
|
|
28392
|
+
{
|
|
28393
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd).")
|
|
28394
|
+
},
|
|
28395
|
+
async ({ ref }) => {
|
|
28396
|
+
try {
|
|
28397
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28398
|
+
const scripts = orch.listThreadRunScripts(threadRef);
|
|
28399
|
+
const active = orch.getActiveRuns(threadRef);
|
|
28400
|
+
return mcpJson({ scripts, active, ref: threadRef });
|
|
28401
|
+
} catch (err) {
|
|
28402
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28403
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28404
|
+
}
|
|
28405
|
+
}
|
|
28406
|
+
);
|
|
28407
|
+
server.tool(
|
|
28408
|
+
"run_dev_script",
|
|
28409
|
+
"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.",
|
|
28410
|
+
{
|
|
28411
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
|
|
28412
|
+
name: import_zod9.z.string().optional().describe("Script name from list_run_scripts (default script if omitted).")
|
|
28413
|
+
},
|
|
28414
|
+
async ({ ref, name }) => {
|
|
28415
|
+
try {
|
|
28416
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28417
|
+
const result = await orch.startDev(threadRef, name);
|
|
28418
|
+
return mcpJson({
|
|
28419
|
+
port: result.port,
|
|
28420
|
+
scriptName: result.scriptName,
|
|
28421
|
+
ports: result.ports,
|
|
28422
|
+
url: `http://localhost:${result.port}`,
|
|
28423
|
+
ref: threadRef
|
|
28424
|
+
});
|
|
28425
|
+
} catch (err) {
|
|
28426
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28427
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28428
|
+
}
|
|
28429
|
+
}
|
|
28430
|
+
);
|
|
28431
|
+
server.tool(
|
|
28432
|
+
"stop_dev_script",
|
|
28433
|
+
"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).",
|
|
28434
|
+
{
|
|
28435
|
+
ref: import_zod9.z.string().optional().describe("Thread id. Omit on a worktree turn (uses cwd)."),
|
|
28436
|
+
name: import_zod9.z.string().optional().describe("Script name to stop; omit to stop all active scripts.")
|
|
28437
|
+
},
|
|
28438
|
+
async ({ ref, name }) => {
|
|
28439
|
+
try {
|
|
28440
|
+
const threadRef = resolveRunScriptThreadRef(ref);
|
|
28441
|
+
await orch.stopDev(threadRef, name);
|
|
28442
|
+
return mcpJson({ ok: true, ref: threadRef, stopped: name ?? "all" });
|
|
28443
|
+
} catch (err) {
|
|
28444
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
28445
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
28446
|
+
}
|
|
28447
|
+
}
|
|
28448
|
+
);
|
|
28171
28449
|
if (!worktreeProfile) {
|
|
28172
28450
|
registerSlackTools(server);
|
|
28173
28451
|
registerConnectedIssueVendorTools(server);
|
|
@@ -28288,7 +28566,7 @@ async function startMcpServer() {
|
|
|
28288
28566
|
const ident = issue?.identifier ?? ref.trim();
|
|
28289
28567
|
const attachments = issue ? [
|
|
28290
28568
|
{
|
|
28291
|
-
id: (0,
|
|
28569
|
+
id: (0, import_node_crypto15.randomUUID)(),
|
|
28292
28570
|
name: issue.identifier,
|
|
28293
28571
|
kind: "issue",
|
|
28294
28572
|
content: [
|
|
@@ -28646,45 +28924,6 @@ async function startMcpServer() {
|
|
|
28646
28924
|
}
|
|
28647
28925
|
}
|
|
28648
28926
|
);
|
|
28649
|
-
server.tool(
|
|
28650
|
-
"run_dev_script",
|
|
28651
|
-
"Start a .sideboard/.conductor run script for a thread (default script if name omitted); returns port",
|
|
28652
|
-
{
|
|
28653
|
-
ref: import_zod9.z.string(),
|
|
28654
|
-
name: import_zod9.z.string().optional()
|
|
28655
|
-
},
|
|
28656
|
-
async ({ ref, name }) => {
|
|
28657
|
-
const result = await orch.startDev(ref, name);
|
|
28658
|
-
return mcpJson({
|
|
28659
|
-
port: result.port,
|
|
28660
|
-
scriptName: result.scriptName,
|
|
28661
|
-
ports: result.ports,
|
|
28662
|
-
url: `http://localhost:${result.port}`
|
|
28663
|
-
});
|
|
28664
|
-
}
|
|
28665
|
-
);
|
|
28666
|
-
server.tool(
|
|
28667
|
-
"list_run_scripts",
|
|
28668
|
-
"List named run scripts available for a thread",
|
|
28669
|
-
{ ref: import_zod9.z.string() },
|
|
28670
|
-
async ({ ref }) => {
|
|
28671
|
-
const scripts = orch.listThreadRunScripts(ref);
|
|
28672
|
-
const active = orch.getActiveRuns(ref);
|
|
28673
|
-
return mcpJson({ scripts, active });
|
|
28674
|
-
}
|
|
28675
|
-
);
|
|
28676
|
-
server.tool(
|
|
28677
|
-
"stop_dev_script",
|
|
28678
|
-
"Stop a running script for a thread (all scripts if name omitted)",
|
|
28679
|
-
{
|
|
28680
|
-
ref: import_zod9.z.string(),
|
|
28681
|
-
name: import_zod9.z.string().optional()
|
|
28682
|
-
},
|
|
28683
|
-
async ({ ref, name }) => {
|
|
28684
|
-
orch.stopDev(ref, name);
|
|
28685
|
-
return { content: [{ type: "text", text: "ok" }] };
|
|
28686
|
-
}
|
|
28687
|
-
);
|
|
28688
28927
|
server.tool(
|
|
28689
28928
|
"run_setup",
|
|
28690
28929
|
"Re-run workspace setup (Sideboard/Conductor settings, .cursor/worktrees.json, or script/setup). New worktrees already run this automatically.",
|