@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
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
resolveQuotaFallbackAgent,
|
|
25
25
|
stripBrightsyNdjsonNoise,
|
|
26
26
|
toolDescription
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-FA4CPYCY.js";
|
|
28
28
|
import {
|
|
29
29
|
SLACK_REPLY_FORMATTING,
|
|
30
30
|
addWorkspace,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
stageAbsolutePathsAsAttachments,
|
|
48
48
|
stageBuffersAsAttachments,
|
|
49
49
|
syncWorkspacesFromThreads
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-HZFLKVGC.js";
|
|
51
51
|
import {
|
|
52
52
|
addPrStackLayer,
|
|
53
53
|
allocateTeamName,
|
|
@@ -96,7 +96,7 @@ import {
|
|
|
96
96
|
worktreeDisplayLabelForGroup,
|
|
97
97
|
worktreeNameFromPath,
|
|
98
98
|
worktreeSlugForTicket
|
|
99
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-N5TX66CD.js";
|
|
100
100
|
import {
|
|
101
101
|
ATTACHMENTS_DIR,
|
|
102
102
|
DETACHED_JOBS_DIR,
|
|
@@ -163,7 +163,7 @@ import {
|
|
|
163
163
|
updateAdvancedSettings,
|
|
164
164
|
usageOnLimit,
|
|
165
165
|
writeSecureJson
|
|
166
|
-
} from "./chunk-
|
|
166
|
+
} from "./chunk-I5NC7DWO.js";
|
|
167
167
|
import {
|
|
168
168
|
examplePrefixedBranch,
|
|
169
169
|
sanitizeGitBranchPrefix
|
|
@@ -185,7 +185,7 @@ import {
|
|
|
185
185
|
updateThread,
|
|
186
186
|
withThreadLock,
|
|
187
187
|
writeThread
|
|
188
|
-
} from "./chunk-
|
|
188
|
+
} from "./chunk-4VGCG2HV.js";
|
|
189
189
|
import {
|
|
190
190
|
appDataDir,
|
|
191
191
|
findConventionSetup,
|
|
@@ -482,7 +482,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
482
482
|
await continueOnReply(threadId, prompt);
|
|
483
483
|
return;
|
|
484
484
|
}
|
|
485
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
485
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-ZT3SJVKF.js");
|
|
486
486
|
await getOrchestrator2().send(threadId, prompt);
|
|
487
487
|
} catch {
|
|
488
488
|
}
|
|
@@ -742,6 +742,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
742
742
|
}
|
|
743
743
|
|
|
744
744
|
// src/orchestrator/orchestrator.ts
|
|
745
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
745
746
|
import { existsSync as existsSync19 } from "fs";
|
|
746
747
|
|
|
747
748
|
// src/agents/spawn.ts
|
|
@@ -900,9 +901,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
900
901
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
901
902
|
);
|
|
902
903
|
}
|
|
903
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
904
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4SPANNJT.js");
|
|
904
905
|
if (isGlobalThread2(thread)) {
|
|
905
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
906
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-DFXYTM6D.js");
|
|
906
907
|
ensureGlobalCoordinatorCwd2(
|
|
907
908
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
908
909
|
);
|
|
@@ -2981,6 +2982,11 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
2981
2982
|
return { repoPath, workspace };
|
|
2982
2983
|
}
|
|
2983
2984
|
|
|
2985
|
+
// src/types/thread.ts
|
|
2986
|
+
function isUnclaimedRunScriptRequest(req) {
|
|
2987
|
+
return Boolean(req && !req.claimedAt && !req.fulfilledAt && !req.error);
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2984
2990
|
// src/store/desktop-host.ts
|
|
2985
2991
|
import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
2986
2992
|
import { join as join11 } from "path";
|
|
@@ -4086,7 +4092,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4086
4092
|
});
|
|
4087
4093
|
await requireAgent(resolved.agent);
|
|
4088
4094
|
if (input.cowboy) {
|
|
4089
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
4095
|
+
const { cowboyModeEnabled } = await import("./app-settings-UXWCPDEA.js");
|
|
4090
4096
|
if (!cowboyModeEnabled()) {
|
|
4091
4097
|
throw new Error(
|
|
4092
4098
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -4144,7 +4150,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4144
4150
|
let sourceIsFork = false;
|
|
4145
4151
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
4146
4152
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
4147
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
4153
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-BGVOCEOU.js");
|
|
4148
4154
|
const task = await ensureAbleTimeTask({
|
|
4149
4155
|
title: title?.trim() || "Untitled work",
|
|
4150
4156
|
description: input.prompt?.trim() || void 0
|
|
@@ -4246,7 +4252,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
4246
4252
|
return readThread(thread.id) ?? thread;
|
|
4247
4253
|
}
|
|
4248
4254
|
async function listLinearIssues(agent, repoPath) {
|
|
4249
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
4255
|
+
const { getAdapter: getAdapter2 } = await import("./agents-TCTEAK6M.js");
|
|
4250
4256
|
await requireAgent(agent, { requireLinear: true });
|
|
4251
4257
|
const adapter = getAdapter2(agent);
|
|
4252
4258
|
if (!adapter.listLinearIssues) {
|
|
@@ -4719,7 +4725,7 @@ async function adoptThread(input) {
|
|
|
4719
4725
|
messages: input.messages ?? []
|
|
4720
4726
|
});
|
|
4721
4727
|
writeThread(thread);
|
|
4722
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4728
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-73Y7IJY2.js");
|
|
4723
4729
|
await ensureWorkspace2(repoPath);
|
|
4724
4730
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-L32WEBX6.js");
|
|
4725
4731
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -6812,12 +6818,13 @@ function formatLongRunningDirective(opts) {
|
|
|
6812
6818
|
"- 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>`.",
|
|
6813
6819
|
"- 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.",
|
|
6814
6820
|
"- 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.",
|
|
6815
|
-
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
|
|
6821
|
+
"State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available).",
|
|
6822
|
+
"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."
|
|
6816
6823
|
].join("\n");
|
|
6817
6824
|
}
|
|
6818
6825
|
function formatLongRunningReminder(opts) {
|
|
6819
6826
|
const invoke = formatDetachedJobInvoke(opts?.scriptPath);
|
|
6820
|
-
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.`;
|
|
6827
|
+
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).`;
|
|
6821
6828
|
}
|
|
6822
6829
|
function formatArtifactDirective() {
|
|
6823
6830
|
return [
|
|
@@ -6829,7 +6836,7 @@ function formatArtifactDirective() {
|
|
|
6829
6836
|
].join("\n");
|
|
6830
6837
|
}
|
|
6831
6838
|
function formatUiReminder() {
|
|
6832
|
-
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.";
|
|
6839
|
+
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.";
|
|
6833
6840
|
}
|
|
6834
6841
|
|
|
6835
6842
|
// src/review/review-write-gate.ts
|
|
@@ -7400,7 +7407,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
7400
7407
|
${prompt}`;
|
|
7401
7408
|
}
|
|
7402
7409
|
async function defaultDeps() {
|
|
7403
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
7410
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ZT3SJVKF.js");
|
|
7404
7411
|
const orch = getOrchestrator2();
|
|
7405
7412
|
return {
|
|
7406
7413
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -7505,6 +7512,7 @@ function armSchedules() {
|
|
|
7505
7512
|
|
|
7506
7513
|
// src/orchestrator/orchestrator.ts
|
|
7507
7514
|
var LIVE_TURN_SPAWN_GRACE_MS = 15e3;
|
|
7515
|
+
var RUN_SCRIPT_DESKTOP_ADOPT_MS = 2e4;
|
|
7508
7516
|
function isPidAlive(pid) {
|
|
7509
7517
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
7510
7518
|
try {
|
|
@@ -7583,6 +7591,11 @@ var Orchestrator = class {
|
|
|
7583
7591
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
7584
7592
|
/** In-flight startDev per worktree run key — agent MCP + UI Start must not double-spawn. */
|
|
7585
7593
|
startingDev = /* @__PURE__ */ new Map();
|
|
7594
|
+
/**
|
|
7595
|
+
* MCP/CLI poll budget while Electron main adopts `runScriptRequest`.
|
|
7596
|
+
* Tests shorten this so a missing desktop does not wait 20s.
|
|
7597
|
+
*/
|
|
7598
|
+
runScriptAdoptTimeoutMs = RUN_SCRIPT_DESKTOP_ADOPT_MS;
|
|
7586
7599
|
maxConcurrent;
|
|
7587
7600
|
runningCount = 0;
|
|
7588
7601
|
constructor(opts) {
|
|
@@ -7717,7 +7730,7 @@ var Orchestrator = class {
|
|
|
7717
7730
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
7718
7731
|
});
|
|
7719
7732
|
}
|
|
7720
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
7733
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-UXWCPDEA.js");
|
|
7721
7734
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
7722
7735
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
7723
7736
|
}
|
|
@@ -7752,6 +7765,58 @@ var Orchestrator = class {
|
|
|
7752
7765
|
this.armDrain(thread.id);
|
|
7753
7766
|
}
|
|
7754
7767
|
}
|
|
7768
|
+
this.adoptPersistedRunScripts();
|
|
7769
|
+
}
|
|
7770
|
+
/**
|
|
7771
|
+
* Adopt run-script start/stop persisted by MCP/CLI while this process owns
|
|
7772
|
+
* live children (desktop host). Spawning in stdio leaves the Run tab on
|
|
7773
|
+
* "Starting…" with no logs — `run_output` never reaches the renderer.
|
|
7774
|
+
*/
|
|
7775
|
+
adoptPersistedRunScripts() {
|
|
7776
|
+
if (!this.shouldOwnRunScripts()) return;
|
|
7777
|
+
for (const thread of listThreads()) {
|
|
7778
|
+
if (thread.status === "archived") continue;
|
|
7779
|
+
const req = thread.runScriptRequest;
|
|
7780
|
+
if (!isUnclaimedRunScriptRequest(req) || !req) continue;
|
|
7781
|
+
const claimedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7782
|
+
const claimed = { ...req, claimedAt };
|
|
7783
|
+
updateThread(thread.id, { runScriptRequest: claimed });
|
|
7784
|
+
void this.applyRunScriptRequest(thread.id, claimed);
|
|
7785
|
+
}
|
|
7786
|
+
}
|
|
7787
|
+
async applyRunScriptRequest(threadId, req) {
|
|
7788
|
+
try {
|
|
7789
|
+
if (req.op === "start") {
|
|
7790
|
+
await this.startDev(threadId, req.scriptName ?? void 0);
|
|
7791
|
+
} else {
|
|
7792
|
+
await this.stopDev(threadId, req.scriptName ?? void 0);
|
|
7793
|
+
}
|
|
7794
|
+
const latest = readThread(threadId);
|
|
7795
|
+
const current = latest?.runScriptRequest;
|
|
7796
|
+
if (current?.requestId === req.requestId && !current.error) {
|
|
7797
|
+
updateThread(threadId, {
|
|
7798
|
+
runScriptRequest: {
|
|
7799
|
+
...current,
|
|
7800
|
+
fulfilledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7801
|
+
}
|
|
7802
|
+
});
|
|
7803
|
+
}
|
|
7804
|
+
} catch (err) {
|
|
7805
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7806
|
+
const latest = readThread(threadId);
|
|
7807
|
+
const current = latest?.runScriptRequest;
|
|
7808
|
+
if (!current || current.requestId !== req.requestId) return;
|
|
7809
|
+
updateThread(threadId, {
|
|
7810
|
+
runScriptRequest: { ...current, error: message }
|
|
7811
|
+
});
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
7814
|
+
/**
|
|
7815
|
+
* Same rule as agent-queue drain: MCP stdio must not own Electron children
|
|
7816
|
+
* while Sideboard.app is alive.
|
|
7817
|
+
*/
|
|
7818
|
+
shouldOwnRunScripts() {
|
|
7819
|
+
return thisProcessShouldDrainAgentQueues();
|
|
7755
7820
|
}
|
|
7756
7821
|
/**
|
|
7757
7822
|
* Mid-session: a worktree can sit at `running` after the agent process dies
|
|
@@ -8004,7 +8069,7 @@ var Orchestrator = class {
|
|
|
8004
8069
|
}
|
|
8005
8070
|
await setup;
|
|
8006
8071
|
if (skipSetup) return;
|
|
8007
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
8072
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-UXWCPDEA.js");
|
|
8008
8073
|
if (autoRunAfterSetupEnabled()) {
|
|
8009
8074
|
try {
|
|
8010
8075
|
await this.startDev(threadId);
|
|
@@ -8360,7 +8425,7 @@ var Orchestrator = class {
|
|
|
8360
8425
|
}
|
|
8361
8426
|
const isBrightsy = fresh.agent === "brightsy";
|
|
8362
8427
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
8363
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-
|
|
8428
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-UXWCPDEA.js");
|
|
8364
8429
|
const gitAuthMode = getGithubGitAuthMode();
|
|
8365
8430
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
8366
8431
|
githubSlug: await withTimeout(
|
|
@@ -8800,6 +8865,13 @@ var Orchestrator = class {
|
|
|
8800
8865
|
"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)."
|
|
8801
8866
|
);
|
|
8802
8867
|
}
|
|
8868
|
+
if (!this.shouldOwnRunScripts()) {
|
|
8869
|
+
const result = await this.requestDesktopRunScript(thread, "start", resolvedName);
|
|
8870
|
+
if (!result) {
|
|
8871
|
+
throw new Error("Desktop did not return a run script port.");
|
|
8872
|
+
}
|
|
8873
|
+
return result;
|
|
8874
|
+
}
|
|
8803
8875
|
const runKey = worktreeRunProcessKey(thread.worktreePath, resolvedName);
|
|
8804
8876
|
const inFlight = this.startingDev.get(runKey);
|
|
8805
8877
|
if (inFlight) return inFlight;
|
|
@@ -8922,8 +8994,65 @@ var Orchestrator = class {
|
|
|
8922
8994
|
});
|
|
8923
8995
|
return { port: handle.port, scriptName: resolvedName, ports: handle.ports };
|
|
8924
8996
|
}
|
|
8925
|
-
|
|
8997
|
+
/**
|
|
8998
|
+
* Persist a run-script intent for the desktop host (MCP/CLI while the board
|
|
8999
|
+
* is alive). Polls until Electron main adopts and fulfills it.
|
|
9000
|
+
*/
|
|
9001
|
+
async requestDesktopRunScript(thread, op, scriptName) {
|
|
9002
|
+
const latest = readThread(thread.id) ?? thread;
|
|
9003
|
+
const pending = latest.runScriptRequest;
|
|
9004
|
+
const claimedAt = pending?.claimedAt;
|
|
9005
|
+
const staleClaim = typeof claimedAt === "string" && Date.now() - Date.parse(claimedAt) > this.runScriptAdoptTimeoutMs;
|
|
9006
|
+
const sameIntent = pending && pending.op === op && (pending.scriptName ?? null) === (scriptName ?? null) && !pending.error && !pending.fulfilledAt && !staleClaim;
|
|
9007
|
+
const request = sameIntent ? pending : {
|
|
9008
|
+
op,
|
|
9009
|
+
scriptName: scriptName ?? null,
|
|
9010
|
+
requestId: randomUUID5(),
|
|
9011
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9012
|
+
};
|
|
9013
|
+
if (!sameIntent) {
|
|
9014
|
+
updateThread(thread.id, { runScriptRequest: request });
|
|
9015
|
+
}
|
|
9016
|
+
return this.waitForDesktopRunScript(thread.id, request, op, scriptName);
|
|
9017
|
+
}
|
|
9018
|
+
async waitForDesktopRunScript(threadId, request, op, scriptName) {
|
|
9019
|
+
const deadline = Date.now() + this.runScriptAdoptTimeoutMs;
|
|
9020
|
+
while (Date.now() < deadline) {
|
|
9021
|
+
const latest = readThread(threadId);
|
|
9022
|
+
if (!latest) {
|
|
9023
|
+
throw new Error("Thread disappeared while waiting for the desktop run script.");
|
|
9024
|
+
}
|
|
9025
|
+
const req = latest.runScriptRequest;
|
|
9026
|
+
if (req?.requestId === request.requestId && req.error) {
|
|
9027
|
+
throw new Error(req.error);
|
|
9028
|
+
}
|
|
9029
|
+
const shared = mergeWorktreeActiveRuns(threadsSharingWorktree(latest.worktreePath));
|
|
9030
|
+
const run2 = scriptName ? shared.activeRuns.find((r) => r.scriptName === scriptName) : shared.activeRuns[0];
|
|
9031
|
+
const fulfilled = req?.requestId === request.requestId && Boolean(req.fulfilledAt);
|
|
9032
|
+
const requestGone = !req || req.requestId !== request.requestId;
|
|
9033
|
+
if (op === "start") {
|
|
9034
|
+
if (run2 && (fulfilled || requestGone || run2.startedAt >= request.requestedAt)) {
|
|
9035
|
+
return { port: run2.port, scriptName: run2.scriptName, ports: run2.ports };
|
|
9036
|
+
}
|
|
9037
|
+
if (fulfilled && !run2) {
|
|
9038
|
+
throw new Error("Desktop reported the run script started, but it is not active.");
|
|
9039
|
+
}
|
|
9040
|
+
} else {
|
|
9041
|
+
const gone = scriptName ? !run2 : shared.activeRuns.length === 0;
|
|
9042
|
+
if (fulfilled || gone) return null;
|
|
9043
|
+
}
|
|
9044
|
+
await new Promise((r) => setTimeout(r, 40));
|
|
9045
|
+
}
|
|
9046
|
+
throw new Error(
|
|
9047
|
+
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."
|
|
9048
|
+
);
|
|
9049
|
+
}
|
|
9050
|
+
async stopDev(threadRef, scriptName) {
|
|
8926
9051
|
const thread = this.requireThread(threadRef);
|
|
9052
|
+
if (!this.shouldOwnRunScripts()) {
|
|
9053
|
+
await this.requestDesktopRunScript(thread, "stop", scriptName);
|
|
9054
|
+
return;
|
|
9055
|
+
}
|
|
8927
9056
|
const siblings = threadsSharingWorktree(thread.worktreePath);
|
|
8928
9057
|
const shared = mergeWorktreeActiveRuns(siblings);
|
|
8929
9058
|
if (scriptName) {
|
|
@@ -9504,7 +9633,7 @@ var Orchestrator = class {
|
|
|
9504
9633
|
if (!titled.userSetTitle && meta.title && titled.title !== meta.title) {
|
|
9505
9634
|
updateThread(thread.id, { title: meta.title });
|
|
9506
9635
|
}
|
|
9507
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
9636
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-UXWCPDEA.js");
|
|
9508
9637
|
const latest = this.requireThread(thread.id);
|
|
9509
9638
|
if (!shouldAutoArchiveOnPrMerge({
|
|
9510
9639
|
previousPrState: prevState || null,
|
|
@@ -9786,7 +9915,7 @@ var Orchestrator = class {
|
|
|
9786
9915
|
this.enforceHistoryRetention();
|
|
9787
9916
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
9788
9917
|
try {
|
|
9789
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
9918
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-73Y7IJY2.js");
|
|
9790
9919
|
await ensureWorkspace2(thread.repoPath);
|
|
9791
9920
|
} catch {
|
|
9792
9921
|
}
|
|
@@ -9813,7 +9942,7 @@ var Orchestrator = class {
|
|
|
9813
9942
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
9814
9943
|
} catch {
|
|
9815
9944
|
}
|
|
9816
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
9945
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-UXWCPDEA.js");
|
|
9817
9946
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
9818
9947
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
9819
9948
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -9840,7 +9969,7 @@ var Orchestrator = class {
|
|
|
9840
9969
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
9841
9970
|
);
|
|
9842
9971
|
}
|
|
9843
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
9972
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-36VEFUJN.js");
|
|
9844
9973
|
const slug = thread.worktreePath.split("/").pop();
|
|
9845
9974
|
const dest = thread.worktreePath;
|
|
9846
9975
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -9950,7 +10079,7 @@ async function startOrchestration(opts) {
|
|
|
9950
10079
|
sourceRef: "default",
|
|
9951
10080
|
...createOpts
|
|
9952
10081
|
}).catch(async () => {
|
|
9953
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
10082
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-36VEFUJN.js");
|
|
9954
10083
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9955
10084
|
const def = await resolveDefaultBranch2(repo);
|
|
9956
10085
|
return orch.createThread({
|
|
@@ -9960,7 +10089,7 @@ async function startOrchestration(opts) {
|
|
|
9960
10089
|
repoPath: repo
|
|
9961
10090
|
});
|
|
9962
10091
|
});
|
|
9963
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
10092
|
+
const { updateThread: upd } = await import("./thread-store-IKJD4EOK.js");
|
|
9964
10093
|
const updated = upd(thread.id, {
|
|
9965
10094
|
sourceType: "orchestration",
|
|
9966
10095
|
sourceRef: goal
|
|
@@ -9972,6 +10101,7 @@ async function startOrchestration(opts) {
|
|
|
9972
10101
|
}
|
|
9973
10102
|
|
|
9974
10103
|
export {
|
|
10104
|
+
isUnclaimedRunScriptRequest,
|
|
9975
10105
|
isHomeBoardThread,
|
|
9976
10106
|
BOARD_COLUMN_DEFS,
|
|
9977
10107
|
HOME_BOARD_CACHE_TTL_MS,
|
|
@@ -10220,6 +10350,7 @@ export {
|
|
|
10220
10350
|
formatOptionalServicesDirective,
|
|
10221
10351
|
formatOptionalServicesReminder,
|
|
10222
10352
|
LIVE_TURN_SPAWN_GRACE_MS,
|
|
10353
|
+
RUN_SCRIPT_DESKTOP_ADOPT_MS,
|
|
10223
10354
|
isPidAlive,
|
|
10224
10355
|
waitForPidExit,
|
|
10225
10356
|
resolveSendFollowUp,
|
|
@@ -568,6 +568,21 @@ var DEFAULT_AGENTS = /* @__PURE__ */ new Set([
|
|
|
568
568
|
]);
|
|
569
569
|
var GITHUB_GIT_AUTH_MODES = ["auto", "gh", "ssh", "token"];
|
|
570
570
|
var FOLLOW_UP_BEHAVIORS = ["steer", "queue"];
|
|
571
|
+
var AGENT_DONE_SOUNDS = [
|
|
572
|
+
"none",
|
|
573
|
+
"goal",
|
|
574
|
+
"bell",
|
|
575
|
+
"level",
|
|
576
|
+
"coin",
|
|
577
|
+
"fanfare",
|
|
578
|
+
"magic",
|
|
579
|
+
"rooster",
|
|
580
|
+
"whistle",
|
|
581
|
+
"custom"
|
|
582
|
+
];
|
|
583
|
+
function isAgentDoneSound(value) {
|
|
584
|
+
return AGENT_DONE_SOUNDS.includes(value);
|
|
585
|
+
}
|
|
571
586
|
function emptyPublicIntegrations() {
|
|
572
587
|
return {
|
|
573
588
|
hasLinearApiKey: false,
|
|
@@ -1006,6 +1021,13 @@ function normalizeAdvanced(raw) {
|
|
|
1006
1021
|
if (source.followUpBehavior === "queue" || source.followUpBehavior === "steer") {
|
|
1007
1022
|
out.followUpBehavior = source.followUpBehavior;
|
|
1008
1023
|
}
|
|
1024
|
+
if (isAgentDoneSound(source.agentDoneSound)) {
|
|
1025
|
+
out.agentDoneSound = source.agentDoneSound;
|
|
1026
|
+
}
|
|
1027
|
+
if (typeof source.agentDoneCustomSoundName === "string") {
|
|
1028
|
+
const name = source.agentDoneCustomSoundName.trim();
|
|
1029
|
+
if (name) out.agentDoneCustomSoundName = name.slice(0, 200);
|
|
1030
|
+
}
|
|
1009
1031
|
return out;
|
|
1010
1032
|
}
|
|
1011
1033
|
function normalizeSettings(raw) {
|
|
@@ -1929,6 +1951,16 @@ function updateAdvancedSettings(patch) {
|
|
|
1929
1951
|
if (patch.followUpBehavior === "queue" || patch.followUpBehavior === "steer") {
|
|
1930
1952
|
advanced.followUpBehavior = patch.followUpBehavior;
|
|
1931
1953
|
}
|
|
1954
|
+
if (isAgentDoneSound(patch.agentDoneSound)) {
|
|
1955
|
+
advanced.agentDoneSound = patch.agentDoneSound;
|
|
1956
|
+
}
|
|
1957
|
+
if (patch.agentDoneCustomSoundName === null || patch.agentDoneCustomSoundName === "") {
|
|
1958
|
+
delete advanced.agentDoneCustomSoundName;
|
|
1959
|
+
} else if (typeof patch.agentDoneCustomSoundName === "string") {
|
|
1960
|
+
const name = patch.agentDoneCustomSoundName.trim();
|
|
1961
|
+
if (name) advanced.agentDoneCustomSoundName = name.slice(0, 200);
|
|
1962
|
+
else delete advanced.agentDoneCustomSoundName;
|
|
1963
|
+
}
|
|
1932
1964
|
return saveAppSettings({ ...current, advanced });
|
|
1933
1965
|
}
|
|
1934
1966
|
function autoRenameBranchEnabled(settings = loadAppSettings()) {
|
|
@@ -1996,6 +2028,9 @@ function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
|
|
|
1996
2028
|
function followUpBehavior(settings = loadAppSettings()) {
|
|
1997
2029
|
return settings.advanced.followUpBehavior === "queue" ? "queue" : "steer";
|
|
1998
2030
|
}
|
|
2031
|
+
function agentDoneSound(settings = loadAppSettings()) {
|
|
2032
|
+
return isAgentDoneSound(settings.advanced.agentDoneSound) ? settings.advanced.agentDoneSound : "none";
|
|
2033
|
+
}
|
|
1999
2034
|
function maxConcurrentAgents(settings = loadAppSettings()) {
|
|
2000
2035
|
const n = settings.advanced.maxConcurrent;
|
|
2001
2036
|
if (typeof n === "number" && Number.isFinite(n)) {
|
|
@@ -2140,6 +2175,8 @@ export {
|
|
|
2140
2175
|
HARNESS_ENV_KEYS,
|
|
2141
2176
|
GITHUB_GIT_AUTH_MODES,
|
|
2142
2177
|
FOLLOW_UP_BEHAVIORS,
|
|
2178
|
+
AGENT_DONE_SOUNDS,
|
|
2179
|
+
isAgentDoneSound,
|
|
2143
2180
|
emptyPublicIntegrations,
|
|
2144
2181
|
toPublicAppSettings,
|
|
2145
2182
|
appSettingsPath,
|
|
@@ -2208,6 +2245,7 @@ export {
|
|
|
2208
2245
|
orchestrationQuotaOnLimit,
|
|
2209
2246
|
orchestrationQuotaFallbackAgent,
|
|
2210
2247
|
followUpBehavior,
|
|
2248
|
+
agentDoneSound,
|
|
2211
2249
|
maxConcurrentAgents,
|
|
2212
2250
|
resolveClaudeExecutable,
|
|
2213
2251
|
resolveAgentExecutable,
|