@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.js
CHANGED
|
@@ -17,14 +17,14 @@ import {
|
|
|
17
17
|
resolveQuotaFallbackAgent,
|
|
18
18
|
sideboardMcpProfile,
|
|
19
19
|
summarizeTurnStderr
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-FYS2BULQ.js";
|
|
21
21
|
import "../chunk-DKHGWYWR.js";
|
|
22
22
|
import {
|
|
23
23
|
addWorkspace,
|
|
24
24
|
ensureWorkspace,
|
|
25
25
|
removeWorkspace,
|
|
26
26
|
syncWorkspacesFromThreads
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-OANJQTVG.js";
|
|
28
28
|
import {
|
|
29
29
|
extractPresentedPlan,
|
|
30
30
|
readPlanFile,
|
|
@@ -41,8 +41,9 @@ import {
|
|
|
41
41
|
isGlobalRepoPath,
|
|
42
42
|
isGlobalThread,
|
|
43
43
|
isOrchestratorThread,
|
|
44
|
+
isSlackCoordinatorThread,
|
|
44
45
|
orchestratorSessionPoisonedByBuiltins
|
|
45
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-HI2OTFFR.js";
|
|
46
47
|
import {
|
|
47
48
|
SLACK_REPLY_FORMATTING,
|
|
48
49
|
coordinatorSystemPrompt,
|
|
@@ -943,7 +944,7 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
943
944
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
944
945
|
);
|
|
945
946
|
}
|
|
946
|
-
const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-
|
|
947
|
+
const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-WMF3BJP5.js");
|
|
947
948
|
if (isGlobalThread2(thread)) {
|
|
948
949
|
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("../coordinator-prompt-OQOOD5ET.js");
|
|
949
950
|
ensureGlobalCoordinatorCwd2(
|
|
@@ -1744,6 +1745,41 @@ async function cloneRepoIntoSideboard(opts) {
|
|
|
1744
1745
|
return { repoPath, workspace };
|
|
1745
1746
|
}
|
|
1746
1747
|
|
|
1748
|
+
// src/store/desktop-host.ts
|
|
1749
|
+
import { readFileSync as readFileSync4, unlinkSync, writeFileSync } from "fs";
|
|
1750
|
+
import { join as join7 } from "path";
|
|
1751
|
+
function desktopHostPidPath() {
|
|
1752
|
+
return join7(appDataDir(), "desktop-host.pid");
|
|
1753
|
+
}
|
|
1754
|
+
function readDesktopHostPid() {
|
|
1755
|
+
try {
|
|
1756
|
+
const pid = Number.parseInt(readFileSync4(desktopHostPidPath(), "utf8").trim(), 10);
|
|
1757
|
+
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
1758
|
+
return pid;
|
|
1759
|
+
} catch {
|
|
1760
|
+
return null;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
function pidAlive(pid) {
|
|
1764
|
+
try {
|
|
1765
|
+
process.kill(pid, 0);
|
|
1766
|
+
return true;
|
|
1767
|
+
} catch {
|
|
1768
|
+
return false;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function isDesktopHostAlive() {
|
|
1772
|
+
const pid = readDesktopHostPid();
|
|
1773
|
+
return pid != null && pidAlive(pid);
|
|
1774
|
+
}
|
|
1775
|
+
function isThisProcessDesktopHost() {
|
|
1776
|
+
return readDesktopHostPid() === process.pid && pidAlive(process.pid);
|
|
1777
|
+
}
|
|
1778
|
+
function thisProcessShouldDrainAgentQueues() {
|
|
1779
|
+
if (isThisProcessDesktopHost()) return true;
|
|
1780
|
+
return !isDesktopHostAlive();
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1747
1783
|
// src/threads/create.ts
|
|
1748
1784
|
import { existsSync as existsSync6 } from "fs";
|
|
1749
1785
|
|
|
@@ -1851,7 +1887,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
1851
1887
|
return readThread(thread.id) ?? thread;
|
|
1852
1888
|
}
|
|
1853
1889
|
async function listLinearIssues(agent, repoPath) {
|
|
1854
|
-
const { getAdapter: getAdapter2 } = await import("../agents-
|
|
1890
|
+
const { getAdapter: getAdapter2 } = await import("../agents-ESJKIQQA.js");
|
|
1855
1891
|
await requireAgent(agent, { requireLinear: true });
|
|
1856
1892
|
const adapter = getAdapter2(agent);
|
|
1857
1893
|
if (!adapter.listLinearIssues) {
|
|
@@ -2205,6 +2241,7 @@ function createChatTab(input) {
|
|
|
2205
2241
|
if (isOrchestratorThread(from) || binding.sourceType === "orchestration") {
|
|
2206
2242
|
assertOrchestratorCapableAgent(nextAgent);
|
|
2207
2243
|
}
|
|
2244
|
+
const singletonInbox = isSlackCoordinatorThread(from) || isCloudCoordinatorThread(from);
|
|
2208
2245
|
const thread = createEmptyThread({
|
|
2209
2246
|
title,
|
|
2210
2247
|
// Chat-tab nicknames (soccer team or explicit) must stick. Post-turn
|
|
@@ -2212,6 +2249,10 @@ function createChatTab(input) {
|
|
|
2212
2249
|
// shared worktree folder name (e.g. fork "Arsenal" → "Monaco").
|
|
2213
2250
|
userSetTitle: true,
|
|
2214
2251
|
...binding,
|
|
2252
|
+
// Slack / Brightsy cloud identity stays on the original chat. A + tab
|
|
2253
|
+
// that copies `slack:team:user` would steal inbound DMs after you close
|
|
2254
|
+
// the connected chat.
|
|
2255
|
+
sourceRef: singletonInbox ? title : binding.sourceRef,
|
|
2215
2256
|
agent: nextAgent,
|
|
2216
2257
|
model: input.model !== void 0 ? input.model : input.agent && input.agent !== from.agent ? null : from.model,
|
|
2217
2258
|
effort: input.effort !== void 0 ? input.effort : from.effort,
|
|
@@ -2245,8 +2286,8 @@ function forkChatTab(input) {
|
|
|
2245
2286
|
|
|
2246
2287
|
// src/review/request-review.ts
|
|
2247
2288
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2248
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as
|
|
2249
|
-
import { dirname as dirname2, join as
|
|
2289
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
2290
|
+
import { dirname as dirname2, join as join8 } from "path";
|
|
2250
2291
|
|
|
2251
2292
|
// src/review/review-request-template.ts
|
|
2252
2293
|
var REVIEW_REQUEST_TEMPLATE = `# Review guidelines:
|
|
@@ -2393,20 +2434,20 @@ function shouldRefreshReviewRequestTemplate(content) {
|
|
|
2393
2434
|
function readTextIfPresent(abs) {
|
|
2394
2435
|
if (!existsSync7(abs)) return null;
|
|
2395
2436
|
try {
|
|
2396
|
-
const content =
|
|
2437
|
+
const content = readFileSync5(abs, "utf8");
|
|
2397
2438
|
return content.trim() ? content : null;
|
|
2398
2439
|
} catch {
|
|
2399
2440
|
return null;
|
|
2400
2441
|
}
|
|
2401
2442
|
}
|
|
2402
2443
|
function ensureAttachmentsGitignore(worktreePath) {
|
|
2403
|
-
const gitignoreAbs =
|
|
2444
|
+
const gitignoreAbs = join8(worktreePath, ATTACHMENTS_DIR, ".gitignore");
|
|
2404
2445
|
if (existsSync7(gitignoreAbs)) return;
|
|
2405
2446
|
mkdirSync2(dirname2(gitignoreAbs), { recursive: true });
|
|
2406
|
-
|
|
2447
|
+
writeFileSync2(gitignoreAbs, attachmentsGitignoreBody(), "utf8");
|
|
2407
2448
|
}
|
|
2408
2449
|
function resolveReviewGuidelines(worktreePath) {
|
|
2409
|
-
const repoAbs =
|
|
2450
|
+
const repoAbs = join8(worktreePath, REPO_REVIEW_PATH);
|
|
2410
2451
|
const repoContent = readTextIfPresent(repoAbs);
|
|
2411
2452
|
if (repoContent) {
|
|
2412
2453
|
return {
|
|
@@ -2416,7 +2457,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
2416
2457
|
source: "repo"
|
|
2417
2458
|
};
|
|
2418
2459
|
}
|
|
2419
|
-
const localAbs =
|
|
2460
|
+
const localAbs = join8(worktreePath, REVIEW_REQUEST_PATH);
|
|
2420
2461
|
const localContent = readTextIfPresent(localAbs);
|
|
2421
2462
|
if (localContent && !shouldRefreshReviewRequestTemplate(localContent)) {
|
|
2422
2463
|
return {
|
|
@@ -2426,7 +2467,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
2426
2467
|
source: "local"
|
|
2427
2468
|
};
|
|
2428
2469
|
}
|
|
2429
|
-
const legacyAbs =
|
|
2470
|
+
const legacyAbs = join8(worktreePath, LEGACY_REVIEW_REQUEST_PATH);
|
|
2430
2471
|
const legacyContent = readTextIfPresent(legacyAbs);
|
|
2431
2472
|
if (legacyContent && !shouldRefreshReviewRequestTemplate(legacyContent)) {
|
|
2432
2473
|
return {
|
|
@@ -2438,7 +2479,7 @@ function resolveReviewGuidelines(worktreePath) {
|
|
|
2438
2479
|
}
|
|
2439
2480
|
ensureAttachmentsGitignore(worktreePath);
|
|
2440
2481
|
mkdirSync2(dirname2(localAbs), { recursive: true });
|
|
2441
|
-
|
|
2482
|
+
writeFileSync2(localAbs, REVIEW_REQUEST_TEMPLATE, "utf8");
|
|
2442
2483
|
return {
|
|
2443
2484
|
path: REVIEW_REQUEST_PATH,
|
|
2444
2485
|
name: REVIEW_REQUEST_NAME,
|
|
@@ -2637,20 +2678,20 @@ import {
|
|
|
2637
2678
|
existsSync as existsSync8,
|
|
2638
2679
|
mkdtempSync,
|
|
2639
2680
|
readdirSync as readdirSync3,
|
|
2640
|
-
readFileSync as
|
|
2681
|
+
readFileSync as readFileSync6,
|
|
2641
2682
|
rmSync
|
|
2642
2683
|
} from "fs";
|
|
2643
2684
|
import { tmpdir } from "os";
|
|
2644
|
-
import { join as
|
|
2685
|
+
import { join as join9 } from "path";
|
|
2645
2686
|
import { createRequire } from "module";
|
|
2646
|
-
var CONDUCTOR_APP_SUPPORT =
|
|
2687
|
+
var CONDUCTOR_APP_SUPPORT = join9(
|
|
2647
2688
|
process.env.HOME ?? "",
|
|
2648
2689
|
"Library",
|
|
2649
2690
|
"Application Support",
|
|
2650
2691
|
"com.conductor.app"
|
|
2651
2692
|
);
|
|
2652
|
-
var CONDUCTOR_DB =
|
|
2653
|
-
var CURSOR_SDK_STORE =
|
|
2693
|
+
var CONDUCTOR_DB = join9(CONDUCTOR_APP_SUPPORT, "conductor.db");
|
|
2694
|
+
var CURSOR_SDK_STORE = join9(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
|
|
2654
2695
|
function openReadonlySqlite(file) {
|
|
2655
2696
|
const req = createRequire(import.meta.url);
|
|
2656
2697
|
const Database = req("better-sqlite3");
|
|
@@ -2677,11 +2718,11 @@ function resolveConductorCursorAgentId(workspacePath) {
|
|
|
2677
2718
|
return null;
|
|
2678
2719
|
}
|
|
2679
2720
|
for (const hash of hashes) {
|
|
2680
|
-
const agentsFile =
|
|
2721
|
+
const agentsFile = join9(CURSOR_SDK_STORE, hash, "agents.ndjson");
|
|
2681
2722
|
if (!existsSync8(agentsFile)) continue;
|
|
2682
2723
|
let text3;
|
|
2683
2724
|
try {
|
|
2684
|
-
text3 =
|
|
2725
|
+
text3 = readFileSync6(agentsFile, "utf8");
|
|
2685
2726
|
} catch {
|
|
2686
2727
|
continue;
|
|
2687
2728
|
}
|
|
@@ -2724,7 +2765,7 @@ async function adoptThread(input) {
|
|
|
2724
2765
|
messages: input.messages ?? []
|
|
2725
2766
|
});
|
|
2726
2767
|
writeThread(thread);
|
|
2727
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-
|
|
2768
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-MZVQHRSJ.js");
|
|
2728
2769
|
await ensureWorkspace2(repoPath);
|
|
2729
2770
|
return thread;
|
|
2730
2771
|
}
|
|
@@ -2732,8 +2773,8 @@ function listConductorWorkspaces() {
|
|
|
2732
2773
|
if (!existsSync8(CONDUCTOR_DB)) {
|
|
2733
2774
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
2734
2775
|
}
|
|
2735
|
-
const tmp = mkdtempSync(
|
|
2736
|
-
const snapshot =
|
|
2776
|
+
const tmp = mkdtempSync(join9(tmpdir(), "sideboard-conductor-"));
|
|
2777
|
+
const snapshot = join9(tmp, "conductor.db");
|
|
2737
2778
|
try {
|
|
2738
2779
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
2739
2780
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -2823,8 +2864,8 @@ function importConductorWorkspace(workspaceId) {
|
|
|
2823
2864
|
if (!existsSync8(CONDUCTOR_DB)) {
|
|
2824
2865
|
throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
|
|
2825
2866
|
}
|
|
2826
|
-
const tmp = mkdtempSync(
|
|
2827
|
-
const snapshot =
|
|
2867
|
+
const tmp = mkdtempSync(join9(tmpdir(), "sideboard-conductor-"));
|
|
2868
|
+
const snapshot = join9(tmp, "conductor.db");
|
|
2828
2869
|
try {
|
|
2829
2870
|
copyFileSync2(CONDUCTOR_DB, snapshot);
|
|
2830
2871
|
for (const suffix of ["-wal", "-shm"]) {
|
|
@@ -3204,8 +3245,8 @@ async function createPrStack(input, onSetupLine) {
|
|
|
3204
3245
|
}
|
|
3205
3246
|
|
|
3206
3247
|
// src/diff/diff.ts
|
|
3207
|
-
import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as
|
|
3208
|
-
import { dirname as dirname3, join as
|
|
3248
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync7, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
3249
|
+
import { dirname as dirname3, join as join10 } from "path";
|
|
3209
3250
|
async function inspectGitWorktree(worktreePath) {
|
|
3210
3251
|
if (!worktreePath || !existsSync10(worktreePath)) return "missing_worktree";
|
|
3211
3252
|
const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
|
|
@@ -3351,11 +3392,11 @@ new file mode 100644
|
|
|
3351
3392
|
};
|
|
3352
3393
|
}
|
|
3353
3394
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
3354
|
-
const abs =
|
|
3395
|
+
const abs = join10(worktreePath, path);
|
|
3355
3396
|
try {
|
|
3356
3397
|
const st = statSync2(abs);
|
|
3357
3398
|
if (st.isFile() && st.size > maxHunk) {
|
|
3358
|
-
const buf =
|
|
3399
|
+
const buf = readFileSync7(abs).subarray(0, maxHunk);
|
|
3359
3400
|
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
3360
3401
|
}
|
|
3361
3402
|
} catch {
|
|
@@ -3856,7 +3897,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
|
|
|
3856
3897
|
function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
3857
3898
|
assertSafeRelativePath(relativePath);
|
|
3858
3899
|
const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
|
|
3859
|
-
const abs =
|
|
3900
|
+
const abs = join10(worktreePath, relativePath);
|
|
3860
3901
|
const st = statSync2(abs);
|
|
3861
3902
|
if (!st.isFile()) {
|
|
3862
3903
|
throw new Error(`Not a file: ${relativePath}`);
|
|
@@ -3866,7 +3907,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
3866
3907
|
`File too large to upload (${st.size} bytes; max ${maxBytes})`
|
|
3867
3908
|
);
|
|
3868
3909
|
}
|
|
3869
|
-
const buf =
|
|
3910
|
+
const buf = readFileSync7(abs);
|
|
3870
3911
|
return {
|
|
3871
3912
|
path: relativePath,
|
|
3872
3913
|
contentBase64: buf.toString("base64"),
|
|
@@ -3876,12 +3917,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
|
|
|
3876
3917
|
function readWorktreeFile(worktreePath, relativePath, opts) {
|
|
3877
3918
|
assertSafeRelativePath(relativePath);
|
|
3878
3919
|
const maxBytes = opts?.maxBytes ?? 2e5;
|
|
3879
|
-
const abs =
|
|
3920
|
+
const abs = join10(worktreePath, relativePath);
|
|
3880
3921
|
const st = statSync2(abs);
|
|
3881
3922
|
if (!st.isFile()) {
|
|
3882
3923
|
throw new Error(`Not a file: ${relativePath}`);
|
|
3883
3924
|
}
|
|
3884
|
-
const buf =
|
|
3925
|
+
const buf = readFileSync7(abs);
|
|
3885
3926
|
if (isImageRelativePath(relativePath)) {
|
|
3886
3927
|
const maxImageBytes = Math.max(maxBytes, 15e6);
|
|
3887
3928
|
const truncated2 = buf.length > maxImageBytes;
|
|
@@ -3924,9 +3965,9 @@ function assertSafeRelativePath(relativePath) {
|
|
|
3924
3965
|
}
|
|
3925
3966
|
function writeWorktreeFile(worktreePath, relativePath, content) {
|
|
3926
3967
|
assertSafeRelativePath(relativePath);
|
|
3927
|
-
const abs =
|
|
3968
|
+
const abs = join10(worktreePath, relativePath);
|
|
3928
3969
|
mkdirSync3(dirname3(abs), { recursive: true });
|
|
3929
|
-
|
|
3970
|
+
writeFileSync3(abs, content, "utf8");
|
|
3930
3971
|
return { path: relativePath };
|
|
3931
3972
|
}
|
|
3932
3973
|
async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
@@ -4029,9 +4070,9 @@ async function confirmLand(thread, opts) {
|
|
|
4029
4070
|
}
|
|
4030
4071
|
|
|
4031
4072
|
// src/skills/discover.ts
|
|
4032
|
-
import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as
|
|
4073
|
+
import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync3 } from "fs";
|
|
4033
4074
|
import { homedir } from "os";
|
|
4034
|
-
import { join as
|
|
4075
|
+
import { join as join11 } from "path";
|
|
4035
4076
|
function toCommand(name) {
|
|
4036
4077
|
return name.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
4037
4078
|
}
|
|
@@ -4063,7 +4104,7 @@ function parseFrontmatter(content) {
|
|
|
4063
4104
|
}
|
|
4064
4105
|
function readSkill(skillMd, source) {
|
|
4065
4106
|
try {
|
|
4066
|
-
const content =
|
|
4107
|
+
const content = readFileSync8(skillMd, "utf8");
|
|
4067
4108
|
const { name: fmName, description } = parseFrontmatter(content);
|
|
4068
4109
|
const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
|
|
4069
4110
|
const name = fmName || dirName;
|
|
@@ -4091,7 +4132,7 @@ function scanSkillsDir(dir, source, out) {
|
|
|
4091
4132
|
}
|
|
4092
4133
|
for (const entry of entries) {
|
|
4093
4134
|
if (entry.startsWith(".")) continue;
|
|
4094
|
-
const skillMd =
|
|
4135
|
+
const skillMd = join11(dir, entry, "SKILL.md");
|
|
4095
4136
|
if (!existsSync11(skillMd)) continue;
|
|
4096
4137
|
try {
|
|
4097
4138
|
if (!statSync3(skillMd).isFile()) continue;
|
|
@@ -4113,12 +4154,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
|
|
|
4113
4154
|
return;
|
|
4114
4155
|
}
|
|
4115
4156
|
if (lookingForSkillsDir && entries.includes("SKILL.md")) {
|
|
4116
|
-
const skill = readSkill(
|
|
4157
|
+
const skill = readSkill(join11(dir, "SKILL.md"), "cli");
|
|
4117
4158
|
if (skill) out.push(skill);
|
|
4118
4159
|
}
|
|
4119
4160
|
for (const entry of entries) {
|
|
4120
4161
|
if (entry === "node_modules" || entry === ".git") continue;
|
|
4121
|
-
const full =
|
|
4162
|
+
const full = join11(dir, entry);
|
|
4122
4163
|
try {
|
|
4123
4164
|
if (!statSync3(full).isDirectory()) continue;
|
|
4124
4165
|
} catch {
|
|
@@ -4138,17 +4179,17 @@ function discoverSkills(worktreePath) {
|
|
|
4138
4179
|
const home = homedir();
|
|
4139
4180
|
const collected = [];
|
|
4140
4181
|
for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
|
|
4141
|
-
scanSkillsDir(
|
|
4182
|
+
scanSkillsDir(join11(worktreePath, rel), "workspace", collected);
|
|
4142
4183
|
}
|
|
4143
4184
|
for (const abs of [
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4185
|
+
join11(home, ".claude/skills"),
|
|
4186
|
+
join11(home, ".cursor/skills"),
|
|
4187
|
+
join11(home, ".sideboard/skills"),
|
|
4188
|
+
join11(home, ".brightsy/skills")
|
|
4148
4189
|
]) {
|
|
4149
4190
|
scanSkillsDir(abs, "user", collected);
|
|
4150
4191
|
}
|
|
4151
|
-
scanClaudePluginSkills(
|
|
4192
|
+
scanClaudePluginSkills(join11(home, ".claude/plugins"), collected);
|
|
4152
4193
|
const rank = { workspace: 0, user: 1, cli: 2 };
|
|
4153
4194
|
const byCommand = /* @__PURE__ */ new Map();
|
|
4154
4195
|
for (const skill of collected) {
|
|
@@ -4160,7 +4201,7 @@ function discoverSkills(worktreePath) {
|
|
|
4160
4201
|
return [...byCommand.values()].sort((a, b) => a.command.localeCompare(b.command));
|
|
4161
4202
|
}
|
|
4162
4203
|
function readSkillBody(skillPath, maxChars = 12e3) {
|
|
4163
|
-
const raw =
|
|
4204
|
+
const raw = readFileSync8(skillPath, "utf8");
|
|
4164
4205
|
if (raw.startsWith("---")) {
|
|
4165
4206
|
const end = raw.indexOf("\n---", 3);
|
|
4166
4207
|
if (end >= 0) {
|
|
@@ -4253,8 +4294,8 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
|
|
|
4253
4294
|
}
|
|
4254
4295
|
|
|
4255
4296
|
// src/composer/stage-files.ts
|
|
4256
|
-
import { copyFileSync as copyFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as
|
|
4257
|
-
import { basename as basename3, extname, join as
|
|
4297
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
4298
|
+
import { basename as basename3, extname, join as join12 } from "path";
|
|
4258
4299
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
4259
4300
|
var IMAGE_EXTENSIONS2 = /* @__PURE__ */ new Set([
|
|
4260
4301
|
"png",
|
|
@@ -4289,22 +4330,22 @@ function imageMimeType(filePath) {
|
|
|
4289
4330
|
return IMAGE_MIME_BY_EXT[fileExtension(filePath)] || "image/png";
|
|
4290
4331
|
}
|
|
4291
4332
|
function ensureAttachmentsDir(worktreePath) {
|
|
4292
|
-
const dir =
|
|
4333
|
+
const dir = join12(worktreePath, ATTACHMENTS_DIR);
|
|
4293
4334
|
mkdirSync4(dir, { recursive: true });
|
|
4294
|
-
const gi =
|
|
4335
|
+
const gi = join12(dir, ".gitignore");
|
|
4295
4336
|
if (!existsSync12(gi)) {
|
|
4296
|
-
|
|
4337
|
+
writeFileSync4(gi, attachmentsGitignoreBody(), "utf8");
|
|
4297
4338
|
}
|
|
4298
4339
|
return dir;
|
|
4299
4340
|
}
|
|
4300
4341
|
function uniqueAttachmentName(dir, originalName) {
|
|
4301
4342
|
const safe = originalName.replace(/[/\\]/g, "_") || "file";
|
|
4302
|
-
if (!existsSync12(
|
|
4343
|
+
if (!existsSync12(join12(dir, safe))) return safe;
|
|
4303
4344
|
const ext = extname(safe);
|
|
4304
4345
|
const stem = ext ? safe.slice(0, -ext.length) : safe;
|
|
4305
4346
|
for (let i = 1; i < 1e4; i++) {
|
|
4306
4347
|
const candidate = `${stem}-${i}${ext}`;
|
|
4307
|
-
if (!existsSync12(
|
|
4348
|
+
if (!existsSync12(join12(dir, candidate))) return candidate;
|
|
4308
4349
|
}
|
|
4309
4350
|
return `${stem}-${randomUUID4()}${ext}`;
|
|
4310
4351
|
}
|
|
@@ -4365,10 +4406,10 @@ function stageAbsolutePathsAsAttachments(worktreePath, absolutePaths) {
|
|
|
4365
4406
|
const st = statSync4(abs);
|
|
4366
4407
|
if (!st.isFile()) continue;
|
|
4367
4408
|
const name = uniqueAttachmentName(dir, originalName);
|
|
4368
|
-
const destAbs =
|
|
4409
|
+
const destAbs = join12(dir, name);
|
|
4369
4410
|
copyFileSync3(abs, destAbs);
|
|
4370
4411
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
4371
|
-
const buf =
|
|
4412
|
+
const buf = readFileSync9(destAbs);
|
|
4372
4413
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
4373
4414
|
} catch (err) {
|
|
4374
4415
|
out.push({
|
|
@@ -4390,8 +4431,8 @@ function stageBuffersAsAttachments(worktreePath, buffers) {
|
|
|
4390
4431
|
try {
|
|
4391
4432
|
const buf = Buffer.from(item.dataBase64, "base64");
|
|
4392
4433
|
const name = uniqueAttachmentName(dir, originalName);
|
|
4393
|
-
const destAbs =
|
|
4394
|
-
|
|
4434
|
+
const destAbs = join12(dir, name);
|
|
4435
|
+
writeFileSync4(destAbs, buf);
|
|
4395
4436
|
const rel = `${ATTACHMENTS_DIR}/${name}`;
|
|
4396
4437
|
out.push(attachmentFromBuffer(name, buf, { path: rel }));
|
|
4397
4438
|
} catch (err) {
|
|
@@ -4419,10 +4460,10 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
4419
4460
|
}
|
|
4420
4461
|
const name = basename3(rel);
|
|
4421
4462
|
try {
|
|
4422
|
-
const abs =
|
|
4463
|
+
const abs = join12(worktreePath, rel);
|
|
4423
4464
|
const st = statSync4(abs);
|
|
4424
4465
|
if (!st.isFile()) continue;
|
|
4425
|
-
const buf =
|
|
4466
|
+
const buf = readFileSync9(abs);
|
|
4426
4467
|
out.push(attachmentFromBuffer(name, buf, { path: rel, sourceLabel: abs }));
|
|
4427
4468
|
} catch (err) {
|
|
4428
4469
|
out.push({
|
|
@@ -4437,8 +4478,8 @@ function attachmentsFromWorktreePaths(worktreePath, relativePaths) {
|
|
|
4437
4478
|
}
|
|
4438
4479
|
|
|
4439
4480
|
// src/agents/instructions.ts
|
|
4440
|
-
import { existsSync as existsSync13, readFileSync as
|
|
4441
|
-
import { join as
|
|
4481
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
|
|
4482
|
+
import { join as join13 } from "path";
|
|
4442
4483
|
function normPath(p) {
|
|
4443
4484
|
return p.replace(/\/+$/, "");
|
|
4444
4485
|
}
|
|
@@ -4942,6 +4983,9 @@ var Orchestrator = class {
|
|
|
4942
4983
|
}
|
|
4943
4984
|
return withThreadLock(thread.id, async () => {
|
|
4944
4985
|
const current = this.requireThread(thread.id);
|
|
4986
|
+
if (current.status === "archived") {
|
|
4987
|
+
throw new Error(`Thread is archived: ${thread.id}`);
|
|
4988
|
+
}
|
|
4945
4989
|
const queue = [...current.queue, prompt];
|
|
4946
4990
|
this.haltDrain.delete(thread.id);
|
|
4947
4991
|
const patch = { queue, status: "queued" };
|
|
@@ -4952,7 +4996,9 @@ var Orchestrator = class {
|
|
|
4952
4996
|
updateThread(thread.id, patch);
|
|
4953
4997
|
this.emit({ type: "queue_changed", threadId: thread.id, queue });
|
|
4954
4998
|
this.emit({ type: "status_changed", threadId: thread.id, status: "queued" });
|
|
4955
|
-
|
|
4999
|
+
if (thisProcessShouldDrainAgentQueues()) {
|
|
5000
|
+
void this.drainQueue(thread.id);
|
|
5001
|
+
}
|
|
4956
5002
|
return this.requireThread(thread.id);
|
|
4957
5003
|
});
|
|
4958
5004
|
}
|
|
@@ -5005,10 +5051,10 @@ var Orchestrator = class {
|
|
|
5005
5051
|
async sendQueuedMessageNow(threadRef, index) {
|
|
5006
5052
|
const thread = this.requireThread(threadRef);
|
|
5007
5053
|
const promoted = await withThreadLock(thread.id, async () => {
|
|
5008
|
-
const
|
|
5009
|
-
if (index < 0 || index >=
|
|
5010
|
-
const item =
|
|
5011
|
-
const rest =
|
|
5054
|
+
const current2 = this.requireThread(thread.id);
|
|
5055
|
+
if (index < 0 || index >= current2.queue.length) return false;
|
|
5056
|
+
const item = current2.queue[index];
|
|
5057
|
+
const rest = current2.queue.filter((_, i) => i !== index);
|
|
5012
5058
|
const queue = [item, ...rest];
|
|
5013
5059
|
this.haltDrain.delete(thread.id);
|
|
5014
5060
|
updateThread(thread.id, { queue });
|
|
@@ -5016,10 +5062,16 @@ var Orchestrator = class {
|
|
|
5016
5062
|
return true;
|
|
5017
5063
|
});
|
|
5018
5064
|
if (!promoted) return this.requireThread(thread.id);
|
|
5065
|
+
const current = this.requireThread(thread.id);
|
|
5019
5066
|
const inFlight = this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id);
|
|
5067
|
+
const livePid = current.agentPid;
|
|
5068
|
+
const foreignLive = !inFlight && typeof livePid === "number" && livePid > 0 && isPidAlive(livePid);
|
|
5020
5069
|
if (inFlight) {
|
|
5021
5070
|
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
5022
5071
|
} else {
|
|
5072
|
+
if (foreignLive) {
|
|
5073
|
+
this.stop(thread.id, { clearQueue: false, continueQueue: true });
|
|
5074
|
+
}
|
|
5023
5075
|
void this.drainQueue(thread.id);
|
|
5024
5076
|
}
|
|
5025
5077
|
return this.requireThread(thread.id);
|
|
@@ -5454,6 +5506,13 @@ var Orchestrator = class {
|
|
|
5454
5506
|
if (handle) handle.kill();
|
|
5455
5507
|
const proc = this.processes.get(`${thread.id}:agent`);
|
|
5456
5508
|
if (proc) proc.kill();
|
|
5509
|
+
const pid = thread.agentPid;
|
|
5510
|
+
if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) {
|
|
5511
|
+
try {
|
|
5512
|
+
process.kill(pid, "SIGTERM");
|
|
5513
|
+
} catch {
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
5457
5516
|
const stopped = writeLiveStatus(thread.id, "stopped") ?? readThread(thread.id) ?? thread;
|
|
5458
5517
|
if (stopped.status === "stopped") {
|
|
5459
5518
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
@@ -6192,7 +6251,7 @@ var Orchestrator = class {
|
|
|
6192
6251
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
6193
6252
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
6194
6253
|
try {
|
|
6195
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-
|
|
6254
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-MZVQHRSJ.js");
|
|
6196
6255
|
await ensureWorkspace2(thread.repoPath);
|
|
6197
6256
|
} catch {
|
|
6198
6257
|
}
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-UYQYK2RY.js";
|
|
8
|
+
import "./chunk-FO67IJTY.js";
|
|
9
9
|
import "./chunk-XUWDLRAE.js";
|
|
10
10
|
import "./chunk-CIRXAYWS.js";
|
|
11
11
|
import "./chunk-FKOIHGKV.js";
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
listWorkspaces,
|
|
7
7
|
removeWorkspace,
|
|
8
8
|
syncWorkspacesFromThreads
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-OANJQTVG.js";
|
|
10
|
+
import "./chunk-HI2OTFFR.js";
|
|
11
11
|
import "./chunk-XH2GS2LO.js";
|
|
12
12
|
import "./chunk-R7BQBSDT.js";
|
|
13
13
|
import "./chunk-B3SJXYIJ.js";
|