@sideboard-ai/core 0.1.97 → 0.1.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/cursor-runner.cjs +47 -2
- package/dist/agents/cursor-runner.js +47 -2
- package/dist/{agents-WS5QV6LE.js → agents-3MWWWSMF.js} +2 -2
- package/dist/{agents-HBLA6FEV.js → agents-ESJKIQQA.js} +2 -2
- package/dist/{chunk-CLGO7TLO.js → chunk-FO67IJTY.js} +24 -25
- package/dist/{chunk-WBX46OPD.js → chunk-FYS2BULQ.js} +2 -2
- package/dist/{chunk-NR6APJLD.js → chunk-HI2OTFFR.js} +24 -25
- package/dist/{chunk-KWNUZ4LR.js → chunk-MBP3XG57.js} +2 -2
- package/dist/{chunk-6XBXVXX2.js → chunk-OANJQTVG.js} +1 -1
- package/dist/{chunk-QKYO6BHB.js → chunk-UYQYK2RY.js} +1 -1
- package/dist/{global-workspace-M3OMVDDH.js → global-workspace-RSQXRLT7.js} +3 -1
- package/dist/{global-workspace-3GNPQCLE.js → global-workspace-WMF3BJP5.js} +3 -1
- package/dist/index.cjs +541 -420
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +241 -128
- package/dist/mcp/run-stdio.cjs +225 -167
- package/dist/mcp/run-stdio.js +129 -70
- package/dist/{workspaces-ERZC7ULY.js → workspaces-4ZY4QPWQ.js} +2 -2
- package/dist/{workspaces-J4WG6UFR.js → workspaces-MZVQHRSJ.js} +2 -2
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -5167,6 +5167,7 @@ __export(global_workspace_exports, {
|
|
|
5167
5167
|
createGlobalChat: () => createGlobalChat,
|
|
5168
5168
|
ensureCloudCoordinator: () => ensureCloudCoordinator,
|
|
5169
5169
|
ensureSlackCoordinator: () => ensureSlackCoordinator,
|
|
5170
|
+
findSlackCoordinator: () => findSlackCoordinator,
|
|
5170
5171
|
globalAgentCwd: () => globalAgentCwd,
|
|
5171
5172
|
healOrchestrationSoccerTitles: () => healOrchestrationSoccerTitles,
|
|
5172
5173
|
isCloudCoordinatorThread: () => isCloudCoordinatorThread,
|
|
@@ -5313,42 +5314,40 @@ function findSlackCoordinator(teamId, userId) {
|
|
|
5313
5314
|
(t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
|
|
5314
5315
|
);
|
|
5315
5316
|
}
|
|
5316
|
-
function ensureSlackCoordinator(teamId, userId, agent) {
|
|
5317
|
+
function ensureSlackCoordinator(teamId, userId, agent, opts) {
|
|
5317
5318
|
const defaults = resolveThreadDefaults();
|
|
5318
5319
|
const desired = assertOrchestratorCapableAgent(agent);
|
|
5319
5320
|
const ref = slackCoordinatorSourceRef(teamId, userId);
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
if (
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5321
|
+
if (!opts?.forceNew) {
|
|
5322
|
+
const existing = findSlackCoordinator(teamId, userId);
|
|
5323
|
+
if (existing) {
|
|
5324
|
+
const patch = {};
|
|
5325
|
+
if (existing.repoPath !== GLOBAL_WORKSPACE_ID) {
|
|
5326
|
+
patch.repoPath = GLOBAL_WORKSPACE_ID;
|
|
5327
|
+
patch.worktreePath = globalAgentCwd();
|
|
5328
|
+
patch.branchName = "global";
|
|
5329
|
+
}
|
|
5330
|
+
const hasAgentTurns = existing.messages.some((m) => m.role === "agent");
|
|
5331
|
+
const canRetarget = !existing.sessionId && !hasAgentTurns && existing.status !== "running" && existing.status !== "queued";
|
|
5332
|
+
if (canRetarget) {
|
|
5333
|
+
if (existing.agent !== desired) patch.agent = desired;
|
|
5334
|
+
if (existing.model !== defaults.model) patch.model = defaults.model;
|
|
5335
|
+
if (existing.effort !== defaults.effort) patch.effort = defaults.effort;
|
|
5336
|
+
if (existing.fast !== defaults.fast) patch.fast = defaults.fast;
|
|
5337
|
+
}
|
|
5338
|
+
if (Object.keys(patch).length > 0) {
|
|
5339
|
+
return updateThread(existing.id, patch);
|
|
5340
|
+
}
|
|
5341
|
+
return existing;
|
|
5338
5342
|
}
|
|
5339
|
-
return existing;
|
|
5340
5343
|
}
|
|
5341
|
-
|
|
5344
|
+
return createGlobalChat({
|
|
5342
5345
|
sourceRef: ref,
|
|
5343
5346
|
agent: desired,
|
|
5344
5347
|
model: defaults.model,
|
|
5345
5348
|
effort: defaults.effort,
|
|
5346
5349
|
fast: defaults.fast
|
|
5347
5350
|
});
|
|
5348
|
-
const all = listThreads({ includeArchived: true }).filter(
|
|
5349
|
-
(t) => t.status !== "archived" && t.sourceRef === ref && isSlackCoordinatorThread(t)
|
|
5350
|
-
).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
5351
|
-
return all[0] ?? created;
|
|
5352
5351
|
}
|
|
5353
5352
|
function ensureCloudCoordinator(agent) {
|
|
5354
5353
|
const defaults = resolveThreadDefaults();
|
|
@@ -8645,40 +8644,40 @@ __export(plan_file_exports, {
|
|
|
8645
8644
|
writePlanFile: () => writePlanFile
|
|
8646
8645
|
});
|
|
8647
8646
|
function ensureAttachmentsGitignore2(worktreePath) {
|
|
8648
|
-
const gitignoreAbs = (0,
|
|
8649
|
-
if ((0,
|
|
8650
|
-
(0,
|
|
8651
|
-
(0,
|
|
8647
|
+
const gitignoreAbs = (0, import_node_path36.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
8648
|
+
if ((0, import_node_fs39.existsSync)(gitignoreAbs)) return;
|
|
8649
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(gitignoreAbs), { recursive: true });
|
|
8650
|
+
(0, import_node_fs39.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
8652
8651
|
}
|
|
8653
8652
|
function planFileAbs(worktreePath) {
|
|
8654
|
-
return (0,
|
|
8653
|
+
return (0, import_node_path36.join)(worktreePath, PLAN_FILE_REL);
|
|
8655
8654
|
}
|
|
8656
8655
|
function readTextIfPresent2(abs) {
|
|
8657
|
-
if (!(0,
|
|
8656
|
+
if (!(0, import_node_fs39.existsSync)(abs)) return null;
|
|
8658
8657
|
try {
|
|
8659
|
-
const content = (0,
|
|
8658
|
+
const content = (0, import_node_fs39.readFileSync)(abs, "utf8");
|
|
8660
8659
|
return content.trim() ? content : null;
|
|
8661
8660
|
} catch {
|
|
8662
8661
|
return null;
|
|
8663
8662
|
}
|
|
8664
8663
|
}
|
|
8665
8664
|
function readPlanFile(worktreePath) {
|
|
8666
|
-
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0,
|
|
8665
|
+
return readTextIfPresent2(planFileAbs(worktreePath)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, `${LEGACY_ATTACHMENTS_DIR}/plan.md`)) ?? readTextIfPresent2((0, import_node_path36.join)(worktreePath, LEGACY_PLAN_FILE_REL));
|
|
8667
8666
|
}
|
|
8668
8667
|
function writePlanFile(worktreePath, content) {
|
|
8669
8668
|
ensureAttachmentsGitignore2(worktreePath);
|
|
8670
8669
|
const abs = planFileAbs(worktreePath);
|
|
8671
|
-
(0,
|
|
8670
|
+
(0, import_node_fs39.mkdirSync)((0, import_node_path36.dirname)(abs), { recursive: true });
|
|
8672
8671
|
const body = content.trimEnd() + (content.endsWith("\n") ? "" : "\n");
|
|
8673
|
-
(0,
|
|
8672
|
+
(0, import_node_fs39.writeFileSync)(abs, body, "utf8");
|
|
8674
8673
|
return PLAN_FILE_REL;
|
|
8675
8674
|
}
|
|
8676
|
-
var
|
|
8675
|
+
var import_node_fs39, import_node_path36;
|
|
8677
8676
|
var init_plan_file = __esm({
|
|
8678
8677
|
"src/plan/plan-file.ts"() {
|
|
8679
8678
|
"use strict";
|
|
8680
|
-
|
|
8681
|
-
|
|
8679
|
+
import_node_fs39 = require("fs");
|
|
8680
|
+
import_node_path36 = require("path");
|
|
8682
8681
|
init_workspace_scratch();
|
|
8683
8682
|
init_plan_present();
|
|
8684
8683
|
init_plan_present();
|
|
@@ -8699,7 +8698,7 @@ function setCaffeinateHoldHooks(next) {
|
|
|
8699
8698
|
hooks = next;
|
|
8700
8699
|
}
|
|
8701
8700
|
function caffeinateHoldPath() {
|
|
8702
|
-
return (0,
|
|
8701
|
+
return (0, import_node_path37.join)(appDataDir(), "caffeinate-hold.json");
|
|
8703
8702
|
}
|
|
8704
8703
|
function processAlive(pid) {
|
|
8705
8704
|
if (hooks.processAlive) return hooks.processAlive(pid);
|
|
@@ -8733,9 +8732,9 @@ function uniqueIds(ids) {
|
|
|
8733
8732
|
}
|
|
8734
8733
|
function readHold() {
|
|
8735
8734
|
const path = caffeinateHoldPath();
|
|
8736
|
-
if (!(0,
|
|
8735
|
+
if (!(0, import_node_fs40.existsSync)(path)) return null;
|
|
8737
8736
|
try {
|
|
8738
|
-
const parsed = JSON.parse((0,
|
|
8737
|
+
const parsed = JSON.parse((0, import_node_fs40.readFileSync)(path, "utf8"));
|
|
8739
8738
|
if (typeof parsed?.pid === "number" && parsed.pid > 0) {
|
|
8740
8739
|
return {
|
|
8741
8740
|
pid: parsed.pid,
|
|
@@ -8757,7 +8756,7 @@ function writeHold(pid, threadIds) {
|
|
|
8757
8756
|
}
|
|
8758
8757
|
function clearHold() {
|
|
8759
8758
|
try {
|
|
8760
|
-
(0,
|
|
8759
|
+
(0, import_node_fs40.unlinkSync)(caffeinateHoldPath());
|
|
8761
8760
|
} catch {
|
|
8762
8761
|
}
|
|
8763
8762
|
}
|
|
@@ -8842,13 +8841,13 @@ function releaseCaffeinateHoldForThread(threadId) {
|
|
|
8842
8841
|
}
|
|
8843
8842
|
return setCaffeinateHold(false, { threadId: id });
|
|
8844
8843
|
}
|
|
8845
|
-
var import_node_child_process4,
|
|
8844
|
+
var import_node_child_process4, import_node_fs40, import_node_path37, hooks;
|
|
8846
8845
|
var init_caffeinate_hold = __esm({
|
|
8847
8846
|
"src/store/caffeinate-hold.ts"() {
|
|
8848
8847
|
"use strict";
|
|
8849
8848
|
import_node_child_process4 = require("child_process");
|
|
8850
|
-
|
|
8851
|
-
|
|
8849
|
+
import_node_fs40 = require("fs");
|
|
8850
|
+
import_node_path37 = require("path");
|
|
8852
8851
|
init_paths();
|
|
8853
8852
|
init_private_file();
|
|
8854
8853
|
hooks = {};
|
|
@@ -8863,10 +8862,10 @@ __export(cursor_recover_exports, {
|
|
|
8863
8862
|
function recoverFinishedCursorRun(opts) {
|
|
8864
8863
|
const agentId = opts.agentId.trim();
|
|
8865
8864
|
if (!agentId) return null;
|
|
8866
|
-
const runsPath = (0,
|
|
8867
|
-
if (!(0,
|
|
8865
|
+
const runsPath = (0, import_node_path38.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
8866
|
+
if (!(0, import_node_fs41.existsSync)(runsPath)) return null;
|
|
8868
8867
|
try {
|
|
8869
|
-
const lines = (0,
|
|
8868
|
+
const lines = (0, import_node_fs41.readFileSync)(runsPath, "utf8").split("\n");
|
|
8870
8869
|
let best = null;
|
|
8871
8870
|
for (const line of lines) {
|
|
8872
8871
|
const trimmed = line.trim();
|
|
@@ -8892,12 +8891,12 @@ function recoverFinishedCursorRun(opts) {
|
|
|
8892
8891
|
return null;
|
|
8893
8892
|
}
|
|
8894
8893
|
}
|
|
8895
|
-
var
|
|
8894
|
+
var import_node_fs41, import_node_path38;
|
|
8896
8895
|
var init_cursor_recover = __esm({
|
|
8897
8896
|
"src/agents/cursor-recover.ts"() {
|
|
8898
8897
|
"use strict";
|
|
8899
|
-
|
|
8900
|
-
|
|
8898
|
+
import_node_fs41 = require("fs");
|
|
8899
|
+
import_node_path38 = require("path");
|
|
8901
8900
|
init_paths();
|
|
8902
8901
|
}
|
|
8903
8902
|
});
|
|
@@ -8909,7 +8908,7 @@ init_nested_electron_env();
|
|
|
8909
8908
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
8910
8909
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
8911
8910
|
var import_zod3 = require("zod");
|
|
8912
|
-
var
|
|
8911
|
+
var import_node_path39 = require("path");
|
|
8913
8912
|
|
|
8914
8913
|
// src/orchestrator/orchestrator.ts
|
|
8915
8914
|
var import_node_events = require("events");
|
|
@@ -9420,7 +9419,7 @@ async function refreshSlackReplyBadges(opts) {
|
|
|
9420
9419
|
}
|
|
9421
9420
|
|
|
9422
9421
|
// src/orchestrator/orchestrator.ts
|
|
9423
|
-
var
|
|
9422
|
+
var import_node_fs42 = require("fs");
|
|
9424
9423
|
init_error_detail();
|
|
9425
9424
|
|
|
9426
9425
|
// src/agents/spawn.ts
|
|
@@ -10537,8 +10536,44 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
10537
10536
|
// src/orchestrator/orchestrator.ts
|
|
10538
10537
|
init_thread_store();
|
|
10539
10538
|
|
|
10540
|
-
// src/
|
|
10539
|
+
// src/store/desktop-host.ts
|
|
10541
10540
|
var import_node_fs30 = require("fs");
|
|
10541
|
+
var import_node_path29 = require("path");
|
|
10542
|
+
init_paths();
|
|
10543
|
+
function desktopHostPidPath() {
|
|
10544
|
+
return (0, import_node_path29.join)(appDataDir(), "desktop-host.pid");
|
|
10545
|
+
}
|
|
10546
|
+
function readDesktopHostPid() {
|
|
10547
|
+
try {
|
|
10548
|
+
const pid = Number.parseInt((0, import_node_fs30.readFileSync)(desktopHostPidPath(), "utf8").trim(), 10);
|
|
10549
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
10550
|
+
return pid;
|
|
10551
|
+
} catch {
|
|
10552
|
+
return null;
|
|
10553
|
+
}
|
|
10554
|
+
}
|
|
10555
|
+
function pidAlive(pid) {
|
|
10556
|
+
try {
|
|
10557
|
+
process.kill(pid, 0);
|
|
10558
|
+
return true;
|
|
10559
|
+
} catch {
|
|
10560
|
+
return false;
|
|
10561
|
+
}
|
|
10562
|
+
}
|
|
10563
|
+
function isDesktopHostAlive() {
|
|
10564
|
+
const pid = readDesktopHostPid();
|
|
10565
|
+
return pid != null && pidAlive(pid);
|
|
10566
|
+
}
|
|
10567
|
+
function isThisProcessDesktopHost() {
|
|
10568
|
+
return readDesktopHostPid() === process.pid && pidAlive(process.pid);
|
|
10569
|
+
}
|
|
10570
|
+
function thisProcessShouldDrainAgentQueues() {
|
|
10571
|
+
if (isThisProcessDesktopHost()) return true;
|
|
10572
|
+
return !isDesktopHostAlive();
|
|
10573
|
+
}
|
|
10574
|
+
|
|
10575
|
+
// src/threads/create.ts
|
|
10576
|
+
var import_node_fs31 = require("fs");
|
|
10542
10577
|
|
|
10543
10578
|
// src/detect/detect.ts
|
|
10544
10579
|
init_agents();
|
|
@@ -10583,7 +10618,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
10583
10618
|
});
|
|
10584
10619
|
await requireAgent(resolved.agent);
|
|
10585
10620
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
10586
|
-
if (!(0,
|
|
10621
|
+
if (!(0, import_node_fs31.existsSync)(repoPath)) {
|
|
10587
10622
|
throw new Error(`Repo not found: ${repoPath}`);
|
|
10588
10623
|
}
|
|
10589
10624
|
let sourceRef = input.sourceRef;
|
|
@@ -11014,6 +11049,7 @@ function createChatTab(input) {
|
|
|
11014
11049
|
if (isOrchestratorThread(from) || binding.sourceType === "orchestration") {
|
|
11015
11050
|
assertOrchestratorCapableAgent(nextAgent);
|
|
11016
11051
|
}
|
|
11052
|
+
const singletonInbox = isSlackCoordinatorThread(from) || isCloudCoordinatorThread(from);
|
|
11017
11053
|
const thread = createEmptyThread({
|
|
11018
11054
|
title,
|
|
11019
11055
|
// Chat-tab nicknames (soccer team or explicit) must stick. Post-turn
|
|
@@ -11021,6 +11057,10 @@ function createChatTab(input) {
|
|
|
11021
11057
|
// shared worktree folder name (e.g. fork "Arsenal" → "Monaco").
|
|
11022
11058
|
userSetTitle: true,
|
|
11023
11059
|
...binding,
|
|
11060
|
+
// Slack / Brightsy cloud identity stays on the original chat. A + tab
|
|
11061
|
+
// that copies `slack:team:user` would steal inbound DMs after you close
|
|
11062
|
+
// the connected chat.
|
|
11063
|
+
sourceRef: singletonInbox ? title : binding.sourceRef,
|
|
11024
11064
|
agent: nextAgent,
|
|
11025
11065
|
model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
|
|
11026
11066
|
effort: input.effort !== void 0 ? input.effort : from.effort,
|
|
@@ -11054,8 +11094,8 @@ function forkChatTab(input) {
|
|
|
11054
11094
|
|
|
11055
11095
|
// src/review/request-review.ts
|
|
11056
11096
|
var import_node_crypto5 = require("crypto");
|
|
11057
|
-
var
|
|
11058
|
-
var
|
|
11097
|
+
var import_node_fs32 = require("fs");
|
|
11098
|
+
var import_node_path30 = require("path");
|
|
11059
11099
|
init_global_workspace();
|
|
11060
11100
|
init_thread_store();
|
|
11061
11101
|
|
|
@@ -11203,22 +11243,22 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
11203
11243
|
return LEGACY_REVIEW_TEMPLATE_MARKERS.every((m) => trimmed.includes(m));
|
|
11204
11244
|
}
|
|
11205
11245
|
function readTextIfPresent(abs) {
|
|
11206
|
-
if (!(0,
|
|
11246
|
+
if (!(0, import_node_fs32.existsSync)(abs)) return null;
|
|
11207
11247
|
try {
|
|
11208
|
-
const content = (0,
|
|
11248
|
+
const content = (0, import_node_fs32.readFileSync)(abs, "utf8");
|
|
11209
11249
|
return content.trim() ? content : null;
|
|
11210
11250
|
} catch {
|
|
11211
11251
|
return null;
|
|
11212
11252
|
}
|
|
11213
11253
|
}
|
|
11214
11254
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
11215
|
-
const gitignoreAbs = (0,
|
|
11216
|
-
if ((0,
|
|
11217
|
-
(0,
|
|
11218
|
-
(0,
|
|
11255
|
+
const gitignoreAbs = (0, import_node_path30.join)(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
11256
|
+
if ((0, import_node_fs32.existsSync)(gitignoreAbs)) return;
|
|
11257
|
+
(0, import_node_fs32.mkdirSync)((0, import_node_path30.dirname)(gitignoreAbs), { recursive: true });
|
|
11258
|
+
(0, import_node_fs32.writeFileSync)(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
11219
11259
|
}
|
|
11220
11260
|
function resolveReviewGuidelines(worktreePath) {
|
|
11221
|
-
const repoAbs = (0,
|
|
11261
|
+
const repoAbs = (0, import_node_path30.join)(worktreePath, REPO_REVIEW_PATH);
|
|
11222
11262
|
const repoContent = readTextIfPresent(repoAbs);
|
|
11223
11263
|
if (repoContent) {
|
|
11224
11264
|
return {
|
|
@@ -11228,7 +11268,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
11228
11268
|
source: "repo"
|
|
11229
11269
|
};
|
|
11230
11270
|
}
|
|
11231
|
-
const localAbs = (0,
|
|
11271
|
+
const localAbs = (0, import_node_path30.join)(worktreePath, REVIEW_REQUEST_PATH);
|
|
11232
11272
|
const localContent = readTextIfPresent(localAbs);
|
|
11233
11273
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
11234
11274
|
return {
|
|
@@ -11238,7 +11278,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
11238
11278
|
source: "local"
|
|
11239
11279
|
};
|
|
11240
11280
|
}
|
|
11241
|
-
const legacyAbs = (0,
|
|
11281
|
+
const legacyAbs = (0, import_node_path30.join)(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
11242
11282
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
11243
11283
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
11244
11284
|
return {
|
|
@@ -11249,8 +11289,8 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
11249
11289
|
};
|
|
11250
11290
|
}
|
|
11251
11291
|
ensureAttachmentsGitignore(worktreePath);
|
|
11252
|
-
(0,
|
|
11253
|
-
(0,
|
|
11292
|
+
(0, import_node_fs32.mkdirSync)((0, import_node_path30.dirname)(localAbs), { recursive: true });
|
|
11293
|
+
(0, import_node_fs32.writeFileSync)(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
11254
11294
|
return {
|
|
11255
11295
|
path: REVIEW_REQUEST_PATH,
|
|
11256
11296
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -11450,21 +11490,21 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
|
11450
11490
|
|
|
11451
11491
|
// src/threads/adopt.ts
|
|
11452
11492
|
var import_node_child_process3 = require("child_process");
|
|
11453
|
-
var
|
|
11493
|
+
var import_node_fs33 = require("fs");
|
|
11454
11494
|
var import_node_os10 = require("os");
|
|
11455
|
-
var
|
|
11495
|
+
var import_node_path31 = require("path");
|
|
11456
11496
|
var import_node_module4 = require("module");
|
|
11457
11497
|
init_worktree();
|
|
11458
11498
|
init_thread_store();
|
|
11459
11499
|
var import_meta4 = {};
|
|
11460
|
-
var CONDUCTOR_APP_SUPPORT = (0,
|
|
11500
|
+
var CONDUCTOR_APP_SUPPORT = (0, import_node_path31.join)(
|
|
11461
11501
|
process.env.HOME ?? "",
|
|
11462
11502
|
"Library",
|
|
11463
11503
|
"Application Support",
|
|
11464
11504
|
"com.conductor.app"
|
|
11465
11505
|
);
|
|
11466
|
-
var CONDUCTOR_DB = (0,
|
|
11467
|
-
var CURSOR_SDK_STORE = (0,
|
|
11506
|
+
var CONDUCTOR_DB = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
11507
|
+
var CURSOR_SDK_STORE = (0, import_node_path31.join)(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
11468
11508
|
function openReadonlySqlite(file) {
|
|
11469
11509
|
const req = (0, import_node_module4.createRequire)(import_meta4.url);
|
|
11470
11510
|
const Database = req("better-sqlite3");
|
|
@@ -11481,21 +11521,21 @@ function mapAgentType(raw) {
|
|
|
11481
11521
|
return null;
|
|
11482
11522
|
}
|
|
11483
11523
|
function resolveConductorCursorAgentId(workspacePath) {
|
|
11484
|
-
if (!workspacePath || !(0,
|
|
11524
|
+
if (!workspacePath || !(0, import_node_fs33.existsSync)(CURSOR_SDK_STORE)) return null;
|
|
11485
11525
|
const normalized = workspacePath.replace(/\/$/, "");
|
|
11486
11526
|
let best = null;
|
|
11487
11527
|
let hashes;
|
|
11488
11528
|
try {
|
|
11489
|
-
hashes = (0,
|
|
11529
|
+
hashes = (0, import_node_fs33.readdirSync)(CURSOR_SDK_STORE);
|
|
11490
11530
|
} catch {
|
|
11491
11531
|
return null;
|
|
11492
11532
|
}
|
|
11493
11533
|
for (const hash of hashes) {
|
|
11494
|
-
const agentsFile = (0,
|
|
11495
|
-
if (!(0,
|
|
11534
|
+
const agentsFile = (0, import_node_path31.join)(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
11535
|
+
if (!(0, import_node_fs33.existsSync)(agentsFile)) continue;
|
|
11496
11536
|
let text3;
|
|
11497
11537
|
try {
|
|
11498
|
-
text3 = (0,
|
|
11538
|
+
text3 = (0, import_node_fs33.readFileSync)(agentsFile, "utf8");
|
|
11499
11539
|
} catch {
|
|
11500
11540
|
continue;
|
|
11501
11541
|
}
|
|
@@ -11519,7 +11559,7 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
11519
11559
|
return best?.agentId ?? null;
|
|
11520
11560
|
}
|
|
11521
11561
|
async function adoptThread(input) {
|
|
11522
|
-
if (!(0,
|
|
11562
|
+
if (!(0, import_node_fs33.existsSync)(input.worktreePath)) {
|
|
11523
11563
|
throw new Error(`Worktree not found: ${input.worktreePath}`);
|
|
11524
11564
|
}
|
|
11525
11565
|
const repoPath = await resolveRepoRoot(input.worktreePath);
|
|
@@ -11543,18 +11583,18 @@ async function adoptThread(input) {
|
|
|
11543
11583
|
return thread;
|
|
11544
11584
|
}
|
|
11545
11585
|
function listConductorWorkspaces() {
|
|
11546
|
-
if (!(0,
|
|
11586
|
+
if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
|
|
11547
11587
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
11548
11588
|
}
|
|
11549
|
-
const tmp = (0,
|
|
11550
|
-
const snapshot = (0,
|
|
11589
|
+
const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
11590
|
+
const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
|
|
11551
11591
|
try {
|
|
11552
|
-
(0,
|
|
11592
|
+
(0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
11553
11593
|
for (const suffix of ["-wal", "-shm"]) {
|
|
11554
11594
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
11555
|
-
if ((0,
|
|
11595
|
+
if ((0, import_node_fs33.existsSync)(src)) {
|
|
11556
11596
|
try {
|
|
11557
|
-
(0,
|
|
11597
|
+
(0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
11558
11598
|
} catch {
|
|
11559
11599
|
}
|
|
11560
11600
|
}
|
|
@@ -11630,22 +11670,22 @@ function listConductorWorkspaces() {
|
|
|
11630
11670
|
db.close();
|
|
11631
11671
|
}
|
|
11632
11672
|
} finally {
|
|
11633
|
-
(0,
|
|
11673
|
+
(0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
|
|
11634
11674
|
}
|
|
11635
11675
|
}
|
|
11636
11676
|
function importConductorWorkspace(workspaceId) {
|
|
11637
|
-
if (!(0,
|
|
11677
|
+
if (!(0, import_node_fs33.existsSync)(CONDUCTOR_DB)) {
|
|
11638
11678
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
11639
11679
|
}
|
|
11640
|
-
const tmp = (0,
|
|
11641
|
-
const snapshot = (0,
|
|
11680
|
+
const tmp = (0, import_node_fs33.mkdtempSync)((0, import_node_path31.join)((0, import_node_os10.tmpdir)(), "sideboard-conductor-"));
|
|
11681
|
+
const snapshot = (0, import_node_path31.join)(tmp, "conductor.db");
|
|
11642
11682
|
try {
|
|
11643
|
-
(0,
|
|
11683
|
+
(0, import_node_fs33.copyFileSync)(CONDUCTOR_DB, snapshot);
|
|
11644
11684
|
for (const suffix of ["-wal", "-shm"]) {
|
|
11645
11685
|
const src = `${CONDUCTOR_DB}${suffix}`;
|
|
11646
|
-
if ((0,
|
|
11686
|
+
if ((0, import_node_fs33.existsSync)(src)) {
|
|
11647
11687
|
try {
|
|
11648
|
-
(0,
|
|
11688
|
+
(0, import_node_fs33.copyFileSync)(src, `${snapshot}${suffix}`);
|
|
11649
11689
|
} catch {
|
|
11650
11690
|
}
|
|
11651
11691
|
}
|
|
@@ -11663,7 +11703,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
11663
11703
|
).get(workspaceId);
|
|
11664
11704
|
if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
|
|
11665
11705
|
const worktreePath = String(row.workspacePath);
|
|
11666
|
-
if (!(0,
|
|
11706
|
+
if (!(0, import_node_fs33.existsSync)(worktreePath)) {
|
|
11667
11707
|
throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
|
|
11668
11708
|
}
|
|
11669
11709
|
let sessionId = null;
|
|
@@ -11726,7 +11766,7 @@ function importConductorWorkspace(workspaceId) {
|
|
|
11726
11766
|
db.close();
|
|
11727
11767
|
}
|
|
11728
11768
|
} finally {
|
|
11729
|
-
(0,
|
|
11769
|
+
(0, import_node_fs33.rmSync)(tmp, { recursive: true, force: true });
|
|
11730
11770
|
}
|
|
11731
11771
|
}
|
|
11732
11772
|
async function importConductorWorkspaceAsync(workspaceId) {
|
|
@@ -11734,7 +11774,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
|
|
|
11734
11774
|
}
|
|
11735
11775
|
|
|
11736
11776
|
// src/threads/stack-layers.ts
|
|
11737
|
-
var
|
|
11777
|
+
var import_node_fs34 = require("fs");
|
|
11738
11778
|
init_run();
|
|
11739
11779
|
init_stack();
|
|
11740
11780
|
init_worktree();
|
|
@@ -11802,7 +11842,7 @@ async function openStackLayer(input, _onSetupLine) {
|
|
|
11802
11842
|
let createdWorktree = false;
|
|
11803
11843
|
const trees = await listWorktrees(repoPath);
|
|
11804
11844
|
const checkedOut = trees.find((w) => w.branch === branchName);
|
|
11805
|
-
if (checkedOut?.path && (0,
|
|
11845
|
+
if (checkedOut?.path && (0, import_node_fs34.existsSync)(checkedOut.path)) {
|
|
11806
11846
|
if (input.reuseExistingWorktree !== false) {
|
|
11807
11847
|
worktreePath = checkedOut.path;
|
|
11808
11848
|
} else {
|
|
@@ -11944,7 +11984,7 @@ async function initStackFromThread(input, onSetupLine) {
|
|
|
11944
11984
|
async function createPrStack(input, onSetupLine) {
|
|
11945
11985
|
await requireAgent(input.agent);
|
|
11946
11986
|
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
11947
|
-
if (!(0,
|
|
11987
|
+
if (!(0, import_node_fs34.existsSync)(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
|
|
11948
11988
|
if (!input.branches.length) throw new Error("At least one branch name required");
|
|
11949
11989
|
const status = await detectGhStack(repoPath);
|
|
11950
11990
|
if (!status.available) throw new Error(status.reason);
|
|
@@ -12011,7 +12051,7 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12011
12051
|
}
|
|
12012
12052
|
}
|
|
12013
12053
|
const claimed = new Set(threads.map((t) => t.worktreePath));
|
|
12014
|
-
if (!claimed.has(bootstrap.worktreePath) && (0,
|
|
12054
|
+
if (!claimed.has(bootstrap.worktreePath) && (0, import_node_fs34.existsSync)(bootstrap.worktreePath)) {
|
|
12015
12055
|
try {
|
|
12016
12056
|
await removeWorktree(repoPath, bootstrap.worktreePath, {
|
|
12017
12057
|
deleteBranch: bootstrap.branchName
|
|
@@ -12026,12 +12066,12 @@ async function createPrStack(input, onSetupLine) {
|
|
|
12026
12066
|
init_worktree();
|
|
12027
12067
|
|
|
12028
12068
|
// src/diff/diff.ts
|
|
12029
|
-
var
|
|
12030
|
-
var
|
|
12069
|
+
var import_node_fs35 = require("fs");
|
|
12070
|
+
var import_node_path32 = require("path");
|
|
12031
12071
|
init_run();
|
|
12032
12072
|
init_worktree();
|
|
12033
12073
|
async function inspectGitWorktree(worktreePath) {
|
|
12034
|
-
if (!worktreePath || !(0,
|
|
12074
|
+
if (!worktreePath || !(0, import_node_fs35.existsSync)(worktreePath)) return "missing_worktree";
|
|
12035
12075
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
12036
12076
|
reject: false
|
|
12037
12077
|
});
|
|
@@ -12039,7 +12079,7 @@ async function inspectGitWorktree(worktreePath) {
|
|
|
12039
12079
|
return "ok";
|
|
12040
12080
|
}
|
|
12041
12081
|
async function initializeGitRepository(worktreePath) {
|
|
12042
|
-
if (!worktreePath || !(0,
|
|
12082
|
+
if (!worktreePath || !(0, import_node_fs35.existsSync)(worktreePath)) {
|
|
12043
12083
|
throw new Error("Worktree not found");
|
|
12044
12084
|
}
|
|
12045
12085
|
const status = await inspectGitWorktree(worktreePath);
|
|
@@ -12175,11 +12215,11 @@ new file mode 100644
|
|
|
12175
12215
|
};
|
|
12176
12216
|
}
|
|
12177
12217
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
12178
|
-
const abs = (0,
|
|
12218
|
+
const abs = (0, import_node_path32.join)(worktreePath, path);
|
|
12179
12219
|
try {
|
|
12180
|
-
const st = (0,
|
|
12220
|
+
const st = (0, import_node_fs35.statSync)(abs);
|
|
12181
12221
|
if (st.isFile() && st.size > maxHunk) {
|
|
12182
|
-
const buf = (0,
|
|
12222
|
+
const buf = (0, import_node_fs35.readFileSync)(abs).subarray(0, maxHunk);
|
|
12183
12223
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
12184
12224
|
}
|
|
12185
12225
|
} catch {
|
|
@@ -12680,8 +12720,8 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
12680
12720
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
12681
12721
|
assertSafeRelativePath(relativePath);
|
|
12682
12722
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
12683
|
-
const abs = (0,
|
|
12684
|
-
const st = (0,
|
|
12723
|
+
const abs = (0, import_node_path32.join)(worktreePath, relativePath);
|
|
12724
|
+
const st = (0, import_node_fs35.statSync)(abs);
|
|
12685
12725
|
if (!st.isFile()) {
|
|
12686
12726
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12687
12727
|
}
|
|
@@ -12690,7 +12730,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12690
12730
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
12691
12731
|
);
|
|
12692
12732
|
}
|
|
12693
|
-
const buf = (0,
|
|
12733
|
+
const buf = (0, import_node_fs35.readFileSync)(abs);
|
|
12694
12734
|
return {
|
|
12695
12735
|
path: relativePath,
|
|
12696
12736
|
contentBase64: buf.toString("base64"),
|
|
@@ -12700,12 +12740,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
12700
12740
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
12701
12741
|
assertSafeRelativePath(relativePath);
|
|
12702
12742
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
12703
|
-
const abs = (0,
|
|
12704
|
-
const st = (0,
|
|
12743
|
+
const abs = (0, import_node_path32.join)(worktreePath, relativePath);
|
|
12744
|
+
const st = (0, import_node_fs35.statSync)(abs);
|
|
12705
12745
|
if (!st.isFile()) {
|
|
12706
12746
|
throw new Error(`Not a file: ${relativePath}`);
|
|
12707
12747
|
}
|
|
12708
|
-
const buf = (0,
|
|
12748
|
+
const buf = (0, import_node_fs35.readFileSync)(abs);
|
|
12709
12749
|
if (isImageRelativePath(relativePath)) {
|
|
12710
12750
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
12711
12751
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -12748,9 +12788,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
12748
12788
|
}
|
|
12749
12789
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
12750
12790
|
assertSafeRelativePath(relativePath);
|
|
12751
|
-
const abs = (0,
|
|
12752
|
-
(0,
|
|
12753
|
-
(0,
|
|
12791
|
+
const abs = (0, import_node_path32.join)(worktreePath, relativePath);
|
|
12792
|
+
(0, import_node_fs35.mkdirSync)((0, import_node_path32.dirname)(abs), { recursive: true });
|
|
12793
|
+
(0, import_node_fs35.writeFileSync)(abs, content, "utf8");
|
|
12754
12794
|
return { path: relativePath };
|
|
12755
12795
|
}
|
|
12756
12796
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -12854,9 +12894,9 @@ async function confirmLand(thread, opts) {
|
|
|
12854
12894
|
}
|
|
12855
12895
|
|
|
12856
12896
|
// src/skills/discover.ts
|
|
12857
|
-
var
|
|
12897
|
+
var import_node_fs36 = require("fs");
|
|
12858
12898
|
var import_node_os11 = require("os");
|
|
12859
|
-
var
|
|
12899
|
+
var import_node_path33 = require("path");
|
|
12860
12900
|
function toCommand(name) {
|
|
12861
12901
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
12862
12902
|
}
|
|
@@ -12888,7 +12928,7 @@ function parseFrontmatter(content) {
|
|
|
12888
12928
|
}
|
|
12889
12929
|
function readSkill(skillMd, source) {
|
|
12890
12930
|
try {
|
|
12891
|
-
const content = (0,
|
|
12931
|
+
const content = (0, import_node_fs36.readFileSync)(skillMd, "utf8");
|
|
12892
12932
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
12893
12933
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
12894
12934
|
const name = fmName || dirName;
|
|
@@ -12907,19 +12947,19 @@ function readSkill(skillMd, source) {
|
|
|
12907
12947
|
}
|
|
12908
12948
|
}
|
|
12909
12949
|
function scanSkillsDir(dir, source, out) {
|
|
12910
|
-
if (!(0,
|
|
12950
|
+
if (!(0, import_node_fs36.existsSync)(dir)) return;
|
|
12911
12951
|
let entries;
|
|
12912
12952
|
try {
|
|
12913
|
-
entries = (0,
|
|
12953
|
+
entries = (0, import_node_fs36.readdirSync)(dir);
|
|
12914
12954
|
} catch {
|
|
12915
12955
|
return;
|
|
12916
12956
|
}
|
|
12917
12957
|
for (const entry of entries) {
|
|
12918
12958
|
if (entry.startsWith(".")) continue;
|
|
12919
|
-
const skillMd = (0,
|
|
12920
|
-
if (!(0,
|
|
12959
|
+
const skillMd = (0, import_node_path33.join)(dir, entry, "SKILL.md");
|
|
12960
|
+
if (!(0, import_node_fs36.existsSync)(skillMd)) continue;
|
|
12921
12961
|
try {
|
|
12922
|
-
if (!(0,
|
|
12962
|
+
if (!(0, import_node_fs36.statSync)(skillMd).isFile()) continue;
|
|
12923
12963
|
} catch {
|
|
12924
12964
|
continue;
|
|
12925
12965
|
}
|
|
@@ -12928,24 +12968,24 @@ function scanSkillsDir(dir, source, out) {
|
|
|
12928
12968
|
}
|
|
12929
12969
|
}
|
|
12930
12970
|
function scanClaudePluginSkills(pluginsRoot, out) {
|
|
12931
|
-
if (!(0,
|
|
12971
|
+
if (!(0, import_node_fs36.existsSync)(pluginsRoot)) return;
|
|
12932
12972
|
const walk = (dir, depth, lookingForSkillsDir) => {
|
|
12933
12973
|
if (depth > 7) return;
|
|
12934
12974
|
let entries;
|
|
12935
12975
|
try {
|
|
12936
|
-
entries = (0,
|
|
12976
|
+
entries = (0, import_node_fs36.readdirSync)(dir);
|
|
12937
12977
|
} catch {
|
|
12938
12978
|
return;
|
|
12939
12979
|
}
|
|
12940
12980
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
12941
|
-
const skill = readSkill((0,
|
|
12981
|
+
const skill = readSkill((0, import_node_path33.join)(dir, "SKILL.md"), "cli");
|
|
12942
12982
|
if (skill) out.push(skill);
|
|
12943
12983
|
}
|
|
12944
12984
|
for (const entry of entries) {
|
|
12945
12985
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
12946
|
-
const full = (0,
|
|
12986
|
+
const full = (0, import_node_path33.join)(dir, entry);
|
|
12947
12987
|
try {
|
|
12948
|
-
if (!(0,
|
|
12988
|
+
if (!(0, import_node_fs36.statSync)(full).isDirectory()) continue;
|
|
12949
12989
|
} catch {
|
|
12950
12990
|
continue;
|
|
12951
12991
|
}
|
|
@@ -12963,17 +13003,17 @@ function discoverSkills(worktreePath) {
|
|
|
12963
13003
|
const home = (0, import_node_os11.homedir)();
|
|
12964
13004
|
const collected = [];
|
|
12965
13005
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
12966
|
-
scanSkillsDir((0,
|
|
13006
|
+
scanSkillsDir((0, import_node_path33.join)(worktreePath, rel), "workspace", collected);
|
|
12967
13007
|
}
|
|
12968
13008
|
for (const abs of [
|
|
12969
|
-
(0,
|
|
12970
|
-
(0,
|
|
12971
|
-
(0,
|
|
12972
|
-
(0,
|
|
13009
|
+
(0, import_node_path33.join)(home, ".claude/skills"),
|
|
13010
|
+
(0, import_node_path33.join)(home, ".cursor/skills"),
|
|
13011
|
+
(0, import_node_path33.join)(home, ".sideboard/skills"),
|
|
13012
|
+
(0, import_node_path33.join)(home, ".brightsy/skills")
|
|
12973
13013
|
]) {
|
|
12974
13014
|
scanSkillsDir(abs, "user", collected);
|
|
12975
13015
|
}
|
|
12976
|
-
scanClaudePluginSkills((0,
|
|
13016
|
+
scanClaudePluginSkills((0, import_node_path33.join)(home, ".claude/plugins"), collected);
|
|
12977
13017
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
12978
13018
|
const byCommand = /* @__PURE__ */ new Map();
|
|
12979
13019
|
for (const skill of collected) {
|
|
@@ -12985,7 +13025,7 @@ function discoverSkills(worktreePath) {
|
|
|
12985
13025
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
12986
13026
|
}
|
|
12987
13027
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
12988
|
-
const raw = (0,
|
|
13028
|
+
const raw = (0, import_node_fs36.readFileSync)(skillPath, "utf8");
|
|
12989
13029
|
if (raw.startsWith("---")) {
|
|
12990
13030
|
const end = raw.indexOf("\n---", 3);
|
|
12991
13031
|
if (end >= 0) {
|
|
@@ -13078,8 +13118,8 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
13078
13118
|
}
|
|
13079
13119
|
|
|
13080
13120
|
// src/composer/stage-files.ts
|
|
13081
|
-
var
|
|
13082
|
-
var
|
|
13121
|
+
var import_node_fs37 = require("fs");
|
|
13122
|
+
var import_node_path34 = require("path");
|
|
13083
13123
|
var import_node_crypto7 = require("crypto");
|
|
13084
13124
|
init_workspace_scratch();
|
|
13085
13125
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
@@ -13105,7 +13145,7 @@ var IMAGE_MIME_BY_EXT = {
|
|
|
13105
13145
|
var MAX_INLINE_BYTES = 4e5;
|
|
13106
13146
|
var MAX_PREVIEW_BYTES = 5e6;
|
|
13107
13147
|
function fileExtension(filePath) {
|
|
13108
|
-
const base = (0,
|
|
13148
|
+
const base = (0, import_node_path34.basename)(filePath).toLowerCase();
|
|
13109
13149
|
return base.includes(".") ? base.split(".").pop() || "" : "";
|
|
13110
13150
|
}
|
|
13111
13151
|
function isImageFilePath(filePath) {
|
|
@@ -13115,22 +13155,22 @@ function imageMimeType(filePath) {
|
|
|
13115
13155
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
13116
13156
|
}
|
|
13117
13157
|
function ensureAttachmentsDir(worktreePath) {
|
|
13118
|
-
const dir = (0,
|
|
13119
|
-
(0,
|
|
13120
|
-
const gi = (0,
|
|
13121
|
-
if (!(0,
|
|
13122
|
-
(0,
|
|
13158
|
+
const dir = (0, import_node_path34.join)(worktreePath, ATTACHMENTS_DIR);
|
|
13159
|
+
(0, import_node_fs37.mkdirSync)(dir, { recursive: true });
|
|
13160
|
+
const gi = (0, import_node_path34.join)(dir, ".gitignore");
|
|
13161
|
+
if (!(0, import_node_fs37.existsSync)(gi)) {
|
|
13162
|
+
(0, import_node_fs37.writeFileSync)(gi, attachmentsGitignoreBody(), "utf8");
|
|
13123
13163
|
}
|
|
13124
13164
|
return dir;
|
|
13125
13165
|
}
|
|
13126
13166
|
function uniqueAttachmentName(dir, originalName) {
|
|
13127
13167
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
13128
|
-
if (!(0,
|
|
13129
|
-
const ext = (0,
|
|
13168
|
+
if (!(0, import_node_fs37.existsSync)((0, import_node_path34.join)(dir, safe))) return safe;
|
|
13169
|
+
const ext = (0, import_node_path34.extname)(safe);
|
|
13130
13170
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
13131
13171
|
for (let i = 1; i < 1e4; i++) {
|
|
13132
13172
|
const candidate = `${stem}-${i}${ext}`;
|
|
13133
|
-
if (!(0,
|
|
13173
|
+
if (!(0, import_node_fs37.existsSync)((0, import_node_path34.join)(dir, candidate))) return candidate;
|
|
13134
13174
|
}
|
|
13135
13175
|
return `${stem}-${(0, import_node_crypto7.randomUUID)()}${ext}`;
|
|
13136
13176
|
}
|
|
@@ -13186,15 +13226,15 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
13186
13226
|
const dir = ensureAttachmentsDir(worktreePath);
|
|
13187
13227
|
const out = [];
|
|
13188
13228
|
for (const abs of absolutePaths) {
|
|
13189
|
-
const originalName = (0,
|
|
13229
|
+
const originalName = (0, import_node_path34.basename)(abs);
|
|
13190
13230
|
try {
|
|
13191
|
-
const st = (0,
|
|
13231
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13192
13232
|
if (!st.isFile()) continue;
|
|
13193
13233
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13194
|
-
const destAbs = (0,
|
|
13195
|
-
(0,
|
|
13234
|
+
const destAbs = (0, import_node_path34.join)(dir, name);
|
|
13235
|
+
(0, import_node_fs37.copyFileSync)(abs, destAbs);
|
|
13196
13236
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13197
|
-
const buf = (0,
|
|
13237
|
+
const buf = (0, import_node_fs37.readFileSync)(destAbs);
|
|
13198
13238
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13199
13239
|
} catch (err) {
|
|
13200
13240
|
out.push({
|
|
@@ -13216,8 +13256,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
13216
13256
|
try {
|
|
13217
13257
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
13218
13258
|
const name = uniqueAttachmentName(dir, originalName);
|
|
13219
|
-
const destAbs = (0,
|
|
13220
|
-
(0,
|
|
13259
|
+
const destAbs = (0, import_node_path34.join)(dir, name);
|
|
13260
|
+
(0, import_node_fs37.writeFileSync)(destAbs, buf);
|
|
13221
13261
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
13222
13262
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
13223
13263
|
} catch (err) {
|
|
@@ -13237,18 +13277,18 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13237
13277
|
if (!rel || rel.includes("..") || rel.startsWith("/")) {
|
|
13238
13278
|
out.push({
|
|
13239
13279
|
id: (0, import_node_crypto7.randomUUID)(),
|
|
13240
|
-
name: (0,
|
|
13280
|
+
name: (0, import_node_path34.basename)(rel) || "file",
|
|
13241
13281
|
kind: "file",
|
|
13242
13282
|
content: `(invalid path: ${rel})`
|
|
13243
13283
|
});
|
|
13244
13284
|
continue;
|
|
13245
13285
|
}
|
|
13246
|
-
const name = (0,
|
|
13286
|
+
const name = (0, import_node_path34.basename)(rel);
|
|
13247
13287
|
try {
|
|
13248
|
-
const abs = (0,
|
|
13249
|
-
const st = (0,
|
|
13288
|
+
const abs = (0, import_node_path34.join)(worktreePath, rel);
|
|
13289
|
+
const st = (0, import_node_fs37.statSync)(abs);
|
|
13250
13290
|
if (!st.isFile()) continue;
|
|
13251
|
-
const buf = (0,
|
|
13291
|
+
const buf = (0, import_node_fs37.readFileSync)(abs);
|
|
13252
13292
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
13253
13293
|
} catch (err) {
|
|
13254
13294
|
out.push({
|
|
@@ -13263,8 +13303,8 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
13263
13303
|
}
|
|
13264
13304
|
|
|
13265
13305
|
// src/agents/instructions.ts
|
|
13266
|
-
var
|
|
13267
|
-
var
|
|
13306
|
+
var import_node_fs38 = require("fs");
|
|
13307
|
+
var import_node_path35 = require("path");
|
|
13268
13308
|
init_git_auth_mode();
|
|
13269
13309
|
init_worktree_labels();
|
|
13270
13310
|
function normPath3(p) {
|
|
@@ -13544,7 +13584,7 @@ var Orchestrator = class {
|
|
|
13544
13584
|
}
|
|
13545
13585
|
continue;
|
|
13546
13586
|
}
|
|
13547
|
-
if (!(0,
|
|
13587
|
+
if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
|
|
13548
13588
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
13549
13589
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
13550
13590
|
continue;
|
|
@@ -13782,6 +13822,9 @@ var Orchestrator = class {
|
|
|
13782
13822
|
}
|
|
13783
13823
|
return withThreadLock(thread.id, async () => {
|
|
13784
13824
|
const current = this.requireThread(thread.id);
|
|
13825
|
+
if (current.status === "archived") {
|
|
13826
|
+
throw new Error(`Thread is archived: ${thread.id}`);
|
|
13827
|
+
}
|
|
13785
13828
|
const queue = [...current.queue, prompt];
|
|
13786
13829
|
this.haltDrain.delete(thread.id);
|
|
13787
13830
|
const patch = { queue, status: "queued" };
|
|
@@ -13792,7 +13835,9 @@ var Orchestrator = class {
|
|
|
13792
13835
|
updateThread(thread.id, patch);
|
|
13793
13836
|
this.emit({ type: "queue_changed", threadId: thread.id, queue });
|
|
13794
13837
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
13795
|
-
|
|
13838
|
+
if (thisProcessShouldDrainAgentQueues()) {
|
|
13839
|
+
void this.drainQueue(thread.id);
|
|
13840
|
+
}
|
|
13796
13841
|
return this.requireThread(thread.id);
|
|
13797
13842
|
});
|
|
13798
13843
|
}
|
|
@@ -13845,10 +13890,10 @@ var Orchestrator = class {
|
|
|
13845
13890
|
async sendQueuedMessageNow(threadRef, index) {
|
|
13846
13891
|
const thread = this.requireThread(threadRef);
|
|
13847
13892
|
const promoted = await withThreadLock(thread.id, async () => {
|
|
13848
|
-
const
|
|
13849
|
-
if (index < 0 || index >=
|
|
13850
|
-
const item =
|
|
13851
|
-
const rest =
|
|
13893
|
+
const current2 = this.requireThread(thread.id);
|
|
13894
|
+
if (index < 0 || index >= current2.queue.length) return false;
|
|
13895
|
+
const item = current2.queue[index];
|
|
13896
|
+
const rest = current2.queue.filter((_, i) => i !== index);
|
|
13852
13897
|
const queue = [item, ...rest];
|
|
13853
13898
|
this.haltDrain.delete(thread.id);
|
|
13854
13899
|
updateThread(thread.id, { queue });
|
|
@@ -13856,10 +13901,16 @@ var Orchestrator = class {
|
|
|
13856
13901
|
return true;
|
|
13857
13902
|
});
|
|
13858
13903
|
if (!promoted) return this.requireThread(thread.id);
|
|
13904
|
+
const current = this.requireThread(thread.id);
|
|
13859
13905
|
const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
|
|
13906
|
+
const livePid = current.agentPid;
|
|
13907
|
+
const foreignLive = !inFlight && typeof livePid === "number" && livePid > 0 && isPidAlive(livePid);
|
|
13860
13908
|
if (inFlight) {
|
|
13861
13909
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
13862
13910
|
} else {
|
|
13911
|
+
if (foreignLive) {
|
|
13912
|
+
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
13913
|
+
}
|
|
13863
13914
|
void this.drainQueue(thread.id);
|
|
13864
13915
|
}
|
|
13865
13916
|
return this.requireThread(thread.id);
|
|
@@ -14294,6 +14345,13 @@ var Orchestrator = class {
|
|
|
14294
14345
|
if (handle) handle.kill();
|
|
14295
14346
|
const proc = this.processes.get(`${thread.id}:agent`);
|
|
14296
14347
|
if (proc) proc.kill();
|
|
14348
|
+
const pid = thread.agentPid;
|
|
14349
|
+
if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) {
|
|
14350
|
+
try {
|
|
14351
|
+
process.kill(pid, "SIGTERM");
|
|
14352
|
+
} catch {
|
|
14353
|
+
}
|
|
14354
|
+
}
|
|
14297
14355
|
const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
|
|
14298
14356
|
if (stopped.status === "stopped") {
|
|
14299
14357
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
@@ -15074,7 +15132,7 @@ var Orchestrator = class {
|
|
|
15074
15132
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
15075
15133
|
return restored2;
|
|
15076
15134
|
}
|
|
15077
|
-
if (!(0,
|
|
15135
|
+
if (!(0, import_node_fs42.existsSync)(thread.worktreePath)) {
|
|
15078
15136
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
15079
15137
|
const { execa: execa7 } = await import("execa");
|
|
15080
15138
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -16314,7 +16372,7 @@ async function startMcpServer() {
|
|
|
16314
16372
|
async () => {
|
|
16315
16373
|
const threads = orch.getThreads(true);
|
|
16316
16374
|
const lines = threads.map((t) => {
|
|
16317
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
16375
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path39.basename)(t.repoPath) || t.repoPath;
|
|
16318
16376
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
|
|
16319
16377
|
});
|
|
16320
16378
|
return {
|