@sideboard-ai/core 0.1.125 → 0.1.130
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-DPR2TDNF.js → agents-7BUQY2WX.js} +6 -6
- package/dist/{agents-DCXXLTXF.js → agents-X2I3RNCY.js} +6 -6
- package/dist/{app-settings-YFWV7MOG.js → app-settings-6RPALX4J.js} +7 -1
- package/dist/{app-settings-IKFWZDUK.js → app-settings-E7NEQY7D.js} +7 -1
- package/dist/{chunk-GKY2GR2J.js → chunk-FMBLOOAO.js} +484 -37
- package/dist/{chunk-RG737OWT.js → chunk-G6X6UFJO.js} +2 -0
- package/dist/{chunk-HPAWHIZ3.js → chunk-HLJUNJBF.js} +2 -0
- package/dist/{chunk-OHEFHIG3.js → chunk-HRSBZIXS.js} +14 -6
- package/dist/{chunk-KWGP6RZM.js → chunk-HULESWLI.js} +4 -4
- package/dist/{chunk-FXQPY2KU.js → chunk-HUYEU4GS.js} +26 -4
- package/dist/{chunk-2X7I6MDW.js → chunk-HZPO3SSZ.js} +11 -8
- package/dist/{chunk-O43IRQ2Y.js → chunk-MNL4FSKY.js} +4 -4
- package/dist/{chunk-7Y3AYQWT.js → chunk-NV73AO7Q.js} +4 -4
- package/dist/{chunk-TRTWH6C2.js → chunk-RSFCB23A.js} +11 -8
- package/dist/{chunk-RBVVWBVB.js → chunk-SYLTXDRF.js} +2 -2
- package/dist/{chunk-UAVZ2JSO.js → chunk-UDQI3N47.js} +14 -6
- package/dist/{chunk-HZLE6LJJ.js → chunk-VE22NWBD.js} +2 -2
- package/dist/{chunk-ED27HCPV.js → chunk-YALVX3UE.js} +496 -37
- package/dist/{chunk-JNAIKICO.js → chunk-ZMUOPTKZ.js} +4 -4
- package/dist/{chunk-BMIRX64H.js → chunk-ZND6XV6J.js} +26 -4
- package/dist/{coordinator-prompt-AZ3WRDNC.js → coordinator-prompt-MEEUOEF2.js} +4 -4
- package/dist/{coordinator-prompt-LEU62W25.js → coordinator-prompt-SPJSGAQS.js} +4 -4
- package/dist/{global-workspace-U5UOVXKQ.js → global-workspace-BMWP7YZC.js} +5 -5
- package/dist/{global-workspace-4YNYDMLQ.js → global-workspace-KNESLWKG.js} +5 -5
- package/dist/index.cjs +1233 -170
- package/dist/index.d.cts +233 -10
- package/dist/index.d.ts +233 -10
- package/dist/index.js +695 -131
- package/dist/mcp/run-stdio.cjs +1081 -149
- package/dist/mcp/run-stdio.js +579 -123
- package/dist/{orchestrator-FZYM7I42.js → orchestrator-3ZSFTG72.js} +8 -8
- package/dist/{orchestrator-HN3LYHFN.js → orchestrator-G6DU3AF3.js} +8 -8
- package/dist/{thread-store-JR235AWK.js → thread-store-5MLYY35S.js} +1 -1
- package/dist/{thread-store-PMH3BMB6.js → thread-store-F6BCARQG.js} +1 -1
- package/dist/{workspaces-ICK433ZV.js → workspaces-HSYRYJYV.js} +6 -6
- package/dist/{workspaces-POWKTH2D.js → workspaces-O4QZOASB.js} +6 -6
- package/dist/{worktree-CMGBTVN4.js → worktree-ERHC7Q4F.js} +5 -3
- package/dist/{worktree-T57RD7BQ.js → worktree-JVGSLSLJ.js} +5 -3
- package/package.json +1 -1
|
@@ -18,13 +18,13 @@ import {
|
|
|
18
18
|
stripBrightsyNdjsonNoise,
|
|
19
19
|
sumUsageList,
|
|
20
20
|
toolDescription
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-NV73AO7Q.js";
|
|
22
22
|
import {
|
|
23
23
|
addWorkspace,
|
|
24
24
|
ensureWorkspace,
|
|
25
25
|
removeWorkspace,
|
|
26
26
|
syncWorkspacesFromThreads
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-VE22NWBD.js";
|
|
28
28
|
import {
|
|
29
29
|
assertOrchestratorCapableAgent,
|
|
30
30
|
coerceOrchestratorAgent,
|
|
@@ -37,14 +37,14 @@ import {
|
|
|
37
37
|
isOrchestratorThread,
|
|
38
38
|
isSlackCoordinatorThread,
|
|
39
39
|
orchestratorSessionPoisonedByBuiltins
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-HULESWLI.js";
|
|
41
41
|
import {
|
|
42
42
|
SLACK_REPLY_FORMATTING,
|
|
43
43
|
coordinatorSystemPrompt,
|
|
44
44
|
coordinatorTurnReminder,
|
|
45
45
|
enrichWorkspacesWithGithub,
|
|
46
46
|
ensureGlobalCoordinatorCwd
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-HZPO3SSZ.js";
|
|
48
48
|
import {
|
|
49
49
|
extractPresentedPlan,
|
|
50
50
|
readPlanFile,
|
|
@@ -72,6 +72,7 @@ import {
|
|
|
72
72
|
addPrStackLayer,
|
|
73
73
|
allocateTeamName,
|
|
74
74
|
allocateTeamSlug,
|
|
75
|
+
canonicalizeRepoPath,
|
|
75
76
|
commitAll,
|
|
76
77
|
createExistingBranchWorktree,
|
|
77
78
|
createOrUpdatePr,
|
|
@@ -109,8 +110,9 @@ import {
|
|
|
109
110
|
takenSlugsFromThread,
|
|
110
111
|
threadDisplayLabel,
|
|
111
112
|
withRepoGitLock,
|
|
113
|
+
worktreeDisplayLabelForGroup,
|
|
112
114
|
worktreeNameFromPath
|
|
113
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-UDQI3N47.js";
|
|
114
116
|
import {
|
|
115
117
|
ATTACHMENTS_DIR,
|
|
116
118
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -128,7 +130,7 @@ import {
|
|
|
128
130
|
resolveVaultKey,
|
|
129
131
|
updateAdvancedSettings,
|
|
130
132
|
writeSecureJson
|
|
131
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-HUYEU4GS.js";
|
|
132
134
|
import {
|
|
133
135
|
stripNestedElectronEnv
|
|
134
136
|
} from "./chunk-4TR3HZFT.js";
|
|
@@ -146,7 +148,7 @@ import {
|
|
|
146
148
|
updateThread,
|
|
147
149
|
withThreadLock,
|
|
148
150
|
writeThread
|
|
149
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-HLJUNJBF.js";
|
|
150
152
|
import {
|
|
151
153
|
appDataDir,
|
|
152
154
|
findConventionSetup,
|
|
@@ -439,7 +441,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
439
441
|
await continueOnReply(threadId, prompt);
|
|
440
442
|
return;
|
|
441
443
|
}
|
|
442
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
444
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-G6DU3AF3.js");
|
|
443
445
|
await getOrchestrator2().send(threadId, prompt);
|
|
444
446
|
} catch {
|
|
445
447
|
}
|
|
@@ -719,9 +721,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
719
721
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
720
722
|
);
|
|
721
723
|
}
|
|
722
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
724
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-BMWP7YZC.js");
|
|
723
725
|
if (isGlobalThread2(thread)) {
|
|
724
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
726
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-MEEUOEF2.js");
|
|
725
727
|
ensureGlobalCoordinatorCwd2(
|
|
726
728
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
727
729
|
);
|
|
@@ -1287,6 +1289,7 @@ function worktreeBindingFrom(from) {
|
|
|
1287
1289
|
prUrl: from.prUrl,
|
|
1288
1290
|
prTitle: from.prTitle,
|
|
1289
1291
|
prState: from.prState,
|
|
1292
|
+
prIsDraft: from.prIsDraft,
|
|
1290
1293
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
1291
1294
|
stackId: from.stackId,
|
|
1292
1295
|
stackLayer: from.stackLayer,
|
|
@@ -2294,8 +2297,425 @@ async function requireAgent(agent, opts) {
|
|
|
2294
2297
|
return status;
|
|
2295
2298
|
}
|
|
2296
2299
|
|
|
2300
|
+
// src/board/home-board.ts
|
|
2301
|
+
var GLOBAL_WORKSPACE_ID = "__global__";
|
|
2302
|
+
function isHomeBoardThread(thread) {
|
|
2303
|
+
if (thread.sourceType === "orchestration") return false;
|
|
2304
|
+
if (thread.repoPath === GLOBAL_WORKSPACE_ID) return false;
|
|
2305
|
+
return true;
|
|
2306
|
+
}
|
|
2307
|
+
var BOARD_COLUMN_DEFS = [
|
|
2308
|
+
{ id: "new", title: "New" },
|
|
2309
|
+
{ id: "draft", title: "Draft" },
|
|
2310
|
+
{ id: "review", title: "Review" },
|
|
2311
|
+
{ id: "done", title: "Merged" }
|
|
2312
|
+
];
|
|
2313
|
+
var HOME_BOARD_CACHE_TTL_MS = 15 * 60 * 1e3;
|
|
2314
|
+
function isOpenPrState(prUrl, prState) {
|
|
2315
|
+
if (!prUrl?.trim()) return false;
|
|
2316
|
+
const state = (prState ?? "OPEN").trim().toUpperCase();
|
|
2317
|
+
return state !== "MERGED" && state !== "CLOSED";
|
|
2318
|
+
}
|
|
2319
|
+
function isMergedPrState(prUrl, prState) {
|
|
2320
|
+
if (!prUrl?.trim()) return false;
|
|
2321
|
+
return (prState ?? "").trim().toUpperCase() === "MERGED";
|
|
2322
|
+
}
|
|
2323
|
+
function groupHomeBoardWorktrees(threads) {
|
|
2324
|
+
const map = /* @__PURE__ */ new Map();
|
|
2325
|
+
for (const t of threads) {
|
|
2326
|
+
const key = normalizeWorktreePath(t.worktreePath);
|
|
2327
|
+
const list = map.get(key) ?? [];
|
|
2328
|
+
list.push(t);
|
|
2329
|
+
map.set(key, list);
|
|
2330
|
+
}
|
|
2331
|
+
return [...map.values()].map((list) => list.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))).sort((a, b) => (b[0]?.updatedAt ?? "").localeCompare(a[0]?.updatedAt ?? ""));
|
|
2332
|
+
}
|
|
2333
|
+
function classifyWorktreeColumn(group) {
|
|
2334
|
+
if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) return "done";
|
|
2335
|
+
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
|
|
2336
|
+
return "review";
|
|
2337
|
+
}
|
|
2338
|
+
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && t.prIsDraft)) {
|
|
2339
|
+
return "draft";
|
|
2340
|
+
}
|
|
2341
|
+
return "new";
|
|
2342
|
+
}
|
|
2343
|
+
function worktreeBoardStatus(group) {
|
|
2344
|
+
const order = ["running", "queued", "error", "broken"];
|
|
2345
|
+
for (const status of order) {
|
|
2346
|
+
if (group.some((t) => t.status === status)) return status;
|
|
2347
|
+
}
|
|
2348
|
+
return group[0]?.status ?? "idle";
|
|
2349
|
+
}
|
|
2350
|
+
function normalizeIssueKey(value) {
|
|
2351
|
+
return value.trim().toLowerCase().replace(/^#/, "");
|
|
2352
|
+
}
|
|
2353
|
+
function threadMatchesIssue(thread, issue) {
|
|
2354
|
+
const identRaw = issue.identifier.trim().toLowerCase();
|
|
2355
|
+
const identKey = normalizeIssueKey(issue.identifier);
|
|
2356
|
+
const title = issue.title.trim().toLowerCase();
|
|
2357
|
+
const refRaw = (thread.sourceRef ?? "").trim().toLowerCase();
|
|
2358
|
+
const refKey = normalizeIssueKey(thread.sourceRef ?? "");
|
|
2359
|
+
const threadTitle = (thread.title ?? "").trim().toLowerCase();
|
|
2360
|
+
if (thread.sourceType === "ticket" && identKey && refKey === identKey) return true;
|
|
2361
|
+
if (identRaw && (refRaw === identRaw || threadTitle.includes(identRaw))) return true;
|
|
2362
|
+
if (title && threadTitle === title) return true;
|
|
2363
|
+
return false;
|
|
2364
|
+
}
|
|
2365
|
+
function dedupeBoardIssues(issues) {
|
|
2366
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2367
|
+
const out = [];
|
|
2368
|
+
for (const issue of issues) {
|
|
2369
|
+
const key = [
|
|
2370
|
+
issue.repoPath,
|
|
2371
|
+
issue.provider ?? "",
|
|
2372
|
+
issue.id || issue.identifier
|
|
2373
|
+
].join(":");
|
|
2374
|
+
if (seen.has(key)) continue;
|
|
2375
|
+
seen.add(key);
|
|
2376
|
+
out.push(issue);
|
|
2377
|
+
}
|
|
2378
|
+
return out;
|
|
2379
|
+
}
|
|
2380
|
+
function issueNeedsWorkspacePick(provider, workspaceCount) {
|
|
2381
|
+
if (workspaceCount <= 1) return false;
|
|
2382
|
+
return provider !== "github";
|
|
2383
|
+
}
|
|
2384
|
+
function boardPrKey(pr) {
|
|
2385
|
+
return pr.url?.trim() || `${pr.repoPath}::${pr.number}`;
|
|
2386
|
+
}
|
|
2387
|
+
function urlsMatch(a, b) {
|
|
2388
|
+
const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
|
|
2389
|
+
return Boolean(a && b && norm(a) === norm(b));
|
|
2390
|
+
}
|
|
2391
|
+
function threadMatchesPr(thread, pr) {
|
|
2392
|
+
const num = String(pr.number);
|
|
2393
|
+
if (thread.sourceType === "pr" && normalizeIssueKey(thread.sourceRef ?? "") === num) {
|
|
2394
|
+
return true;
|
|
2395
|
+
}
|
|
2396
|
+
if (thread.prUrl && pr.url && urlsMatch(thread.prUrl, pr.url)) return true;
|
|
2397
|
+
const head = pr.headRefName.trim().toLowerCase();
|
|
2398
|
+
if (!head) return false;
|
|
2399
|
+
const branch = (thread.branchName ?? "").trim().toLowerCase();
|
|
2400
|
+
const ref = (thread.sourceRef ?? "").trim().replace(/^refs\/heads\//, "").replace(/^origin\//, "").toLowerCase();
|
|
2401
|
+
if (branch === head) return true;
|
|
2402
|
+
if (!ref || /^(main|master|develop|development|trunk|default|head)$/.test(ref)) {
|
|
2403
|
+
return false;
|
|
2404
|
+
}
|
|
2405
|
+
return ref === head;
|
|
2406
|
+
}
|
|
2407
|
+
function normalizeBranchRef(value) {
|
|
2408
|
+
return value.trim().replace(/^refs\/heads\//, "").replace(/^origin\//, "").toLowerCase();
|
|
2409
|
+
}
|
|
2410
|
+
function threadMatchesBranch(thread, pin) {
|
|
2411
|
+
if (pin.repoPath && thread.repoPath && pin.repoPath !== thread.repoPath) return false;
|
|
2412
|
+
const head = normalizeBranchRef(pin.ref === "default" ? "" : pin.ref);
|
|
2413
|
+
if (!head) {
|
|
2414
|
+
return thread.sourceType === "branch" && pin.repoPath === thread.repoPath;
|
|
2415
|
+
}
|
|
2416
|
+
const branch = normalizeBranchRef(thread.branchName ?? "");
|
|
2417
|
+
const ref = normalizeBranchRef(thread.sourceRef ?? "");
|
|
2418
|
+
return branch === head || ref === head;
|
|
2419
|
+
}
|
|
2420
|
+
function sameRepoPath(a, b) {
|
|
2421
|
+
return a.replace(/\/+$/, "") === b.replace(/\/+$/, "");
|
|
2422
|
+
}
|
|
2423
|
+
var DEFAULTISH_BRANCH = /^(main|master|develop|development|trunk|default|head)$/;
|
|
2424
|
+
function isDefaultBranchCreateRef(ref) {
|
|
2425
|
+
const head = normalizeBranchRef(ref);
|
|
2426
|
+
return !head || DEFAULTISH_BRANCH.test(head);
|
|
2427
|
+
}
|
|
2428
|
+
function findLiveThreadForCreate(input, threads) {
|
|
2429
|
+
const live = threads.filter(
|
|
2430
|
+
(t) => t.status !== "archived" && sameRepoPath(t.repoPath, input.repoPath)
|
|
2431
|
+
);
|
|
2432
|
+
if (input.cowboy) {
|
|
2433
|
+
return live.find((t) => t.cowboy);
|
|
2434
|
+
}
|
|
2435
|
+
if (input.sourceType === "ticket") {
|
|
2436
|
+
return live.find(
|
|
2437
|
+
(t) => threadMatchesIssue(t, {
|
|
2438
|
+
identifier: input.sourceRef,
|
|
2439
|
+
title: input.title ?? ""
|
|
2440
|
+
})
|
|
2441
|
+
);
|
|
2442
|
+
}
|
|
2443
|
+
if (input.sourceType === "pr") {
|
|
2444
|
+
const number = Number(normalizeIssueKey(input.sourceRef));
|
|
2445
|
+
return live.find(
|
|
2446
|
+
(t) => threadMatchesPr(t, {
|
|
2447
|
+
number: Number.isFinite(number) ? number : -1,
|
|
2448
|
+
title: input.title ?? "",
|
|
2449
|
+
url: "",
|
|
2450
|
+
headRefName: ""
|
|
2451
|
+
})
|
|
2452
|
+
);
|
|
2453
|
+
}
|
|
2454
|
+
if (input.sourceType === "branch") {
|
|
2455
|
+
if (isDefaultBranchCreateRef(input.sourceRef)) return void 0;
|
|
2456
|
+
return live.find(
|
|
2457
|
+
(t) => threadMatchesBranch(t, {
|
|
2458
|
+
ref: input.sourceRef,
|
|
2459
|
+
repoPath: input.repoPath
|
|
2460
|
+
})
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
return void 0;
|
|
2464
|
+
}
|
|
2465
|
+
function boardPinIdentity(pin) {
|
|
2466
|
+
const ref = normalizeIssueKey(pin.ref);
|
|
2467
|
+
if (pin.kind === "ticket" && (pin.provider === "linear" || !pin.repoPath)) {
|
|
2468
|
+
return `ticket:account:${ref}`;
|
|
2469
|
+
}
|
|
2470
|
+
return `${pin.kind}:${pin.repoPath}:${ref}`;
|
|
2471
|
+
}
|
|
2472
|
+
function findBoardPin(pins, kind, ref, repoPath = "") {
|
|
2473
|
+
const key = normalizeIssueKey(ref);
|
|
2474
|
+
const matches = pins.filter(
|
|
2475
|
+
(pin) => pin.kind === kind && normalizeIssueKey(pin.ref) === key
|
|
2476
|
+
);
|
|
2477
|
+
if (repoPath) {
|
|
2478
|
+
const scoped = matches.filter((pin) => pin.repoPath === repoPath);
|
|
2479
|
+
if (scoped[0]) return scoped[0];
|
|
2480
|
+
}
|
|
2481
|
+
return matches[0];
|
|
2482
|
+
}
|
|
2483
|
+
function syncBoardPins(pins, issues, prs) {
|
|
2484
|
+
return pins.map((pin) => {
|
|
2485
|
+
if (pin.kind === "ticket") {
|
|
2486
|
+
const issue = findBoardIssue(issues, pin.ref, pin.repoPath);
|
|
2487
|
+
if (!issue) {
|
|
2488
|
+
return { ...pin, remoteState: pin.remoteState || "stale" };
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
...pin,
|
|
2492
|
+
title: issue.title || pin.title,
|
|
2493
|
+
url: issue.url || pin.url,
|
|
2494
|
+
labels: issue.labels,
|
|
2495
|
+
provider: issue.provider ?? pin.provider,
|
|
2496
|
+
assignee: issue.assignee ?? pin.assignee,
|
|
2497
|
+
cycle: issue.cycle?.name ?? pin.cycle,
|
|
2498
|
+
teamKey: issue.teamKey ?? pin.teamKey,
|
|
2499
|
+
remoteState: "open",
|
|
2500
|
+
needsWorkspacePick: issue.needsWorkspacePick
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
if (pin.kind === "pr") {
|
|
2504
|
+
const pr = findBoardPr(prs, pin.ref, pin.repoPath);
|
|
2505
|
+
if (!pr) {
|
|
2506
|
+
return { ...pin, remoteState: pin.remoteState === "open" ? "stale" : pin.remoteState || "stale" };
|
|
2507
|
+
}
|
|
2508
|
+
return {
|
|
2509
|
+
...pin,
|
|
2510
|
+
title: pr.title || pin.title,
|
|
2511
|
+
url: pr.url || pin.url,
|
|
2512
|
+
headRefName: pr.headRefName || pin.headRefName,
|
|
2513
|
+
author: prAuthorLogin(pr) || pin.author,
|
|
2514
|
+
remoteState: "open"
|
|
2515
|
+
};
|
|
2516
|
+
}
|
|
2517
|
+
return pin;
|
|
2518
|
+
});
|
|
2519
|
+
}
|
|
2520
|
+
function dedupeBoardPrs(prs) {
|
|
2521
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2522
|
+
const out = [];
|
|
2523
|
+
for (const pr of prs) {
|
|
2524
|
+
const key = boardPrKey(pr);
|
|
2525
|
+
if (seen.has(key)) continue;
|
|
2526
|
+
seen.add(key);
|
|
2527
|
+
out.push(pr);
|
|
2528
|
+
}
|
|
2529
|
+
return out.sort((a, b) => b.number - a.number);
|
|
2530
|
+
}
|
|
2531
|
+
var BOARD_PAGE_SIZE = 40;
|
|
2532
|
+
function tokenizeQuery(query) {
|
|
2533
|
+
return query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
2534
|
+
}
|
|
2535
|
+
function haystackMatches(haystack, tokens) {
|
|
2536
|
+
if (tokens.length === 0) return true;
|
|
2537
|
+
const h = haystack.toLowerCase();
|
|
2538
|
+
return tokens.every((token) => h.includes(token));
|
|
2539
|
+
}
|
|
2540
|
+
function prAuthorLogin(pr) {
|
|
2541
|
+
return pr.author?.login?.trim() ?? "";
|
|
2542
|
+
}
|
|
2543
|
+
function threadSearchText(thread, workspaceName = "") {
|
|
2544
|
+
return [
|
|
2545
|
+
thread.title,
|
|
2546
|
+
thread.sourceRef,
|
|
2547
|
+
thread.sourceType,
|
|
2548
|
+
thread.agent,
|
|
2549
|
+
thread.status,
|
|
2550
|
+
thread.branchName,
|
|
2551
|
+
thread.prUrl ?? "",
|
|
2552
|
+
workspaceName,
|
|
2553
|
+
thread.repoPath
|
|
2554
|
+
].join(" ");
|
|
2555
|
+
}
|
|
2556
|
+
function inWorkspace(repoPath, filterRepoPath) {
|
|
2557
|
+
if (!filterRepoPath) return true;
|
|
2558
|
+
return repoPath === filterRepoPath;
|
|
2559
|
+
}
|
|
2560
|
+
function visiblePage(items, shown) {
|
|
2561
|
+
const n = Math.max(0, shown);
|
|
2562
|
+
return {
|
|
2563
|
+
visible: items.slice(0, n),
|
|
2564
|
+
hidden: Math.max(0, items.length - n)
|
|
2565
|
+
};
|
|
2566
|
+
}
|
|
2567
|
+
function emptyColumns() {
|
|
2568
|
+
return {
|
|
2569
|
+
backlog: [],
|
|
2570
|
+
queued: [],
|
|
2571
|
+
running: [],
|
|
2572
|
+
new: [],
|
|
2573
|
+
draft: [],
|
|
2574
|
+
review: [],
|
|
2575
|
+
done: []
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
function emptyHidden() {
|
|
2579
|
+
return {
|
|
2580
|
+
backlog: 0,
|
|
2581
|
+
queued: 0,
|
|
2582
|
+
running: 0,
|
|
2583
|
+
new: 0,
|
|
2584
|
+
draft: 0,
|
|
2585
|
+
review: 0,
|
|
2586
|
+
done: 0
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
function findBoardIssue(issues, ref, repoPath = "") {
|
|
2590
|
+
const key = normalizeIssueKey(ref);
|
|
2591
|
+
if (!key) return void 0;
|
|
2592
|
+
const matches = issues.filter((issue) => normalizeIssueKey(issue.identifier) === key);
|
|
2593
|
+
if (repoPath) {
|
|
2594
|
+
const scoped = matches.filter((issue) => issue.repoPath === repoPath);
|
|
2595
|
+
if (scoped[0]) return scoped[0];
|
|
2596
|
+
}
|
|
2597
|
+
return matches[0];
|
|
2598
|
+
}
|
|
2599
|
+
function findBoardPr(prs, ref, repoPath = "") {
|
|
2600
|
+
const num = Number(normalizeIssueKey(ref));
|
|
2601
|
+
if (!Number.isFinite(num)) return void 0;
|
|
2602
|
+
const matches = prs.filter((pr) => pr.number === num);
|
|
2603
|
+
if (repoPath) {
|
|
2604
|
+
const scoped = matches.filter((pr) => pr.repoPath === repoPath);
|
|
2605
|
+
if (scoped[0]) return scoped[0];
|
|
2606
|
+
}
|
|
2607
|
+
return matches[0];
|
|
2608
|
+
}
|
|
2609
|
+
function toThreadCard(group) {
|
|
2610
|
+
const thread = group[0];
|
|
2611
|
+
const withPr = group.find((t) => t.prUrl?.trim()) ?? thread;
|
|
2612
|
+
return {
|
|
2613
|
+
kind: "thread",
|
|
2614
|
+
id: thread.id,
|
|
2615
|
+
title: worktreeDisplayLabelForGroup(group),
|
|
2616
|
+
status: worktreeBoardStatus(group),
|
|
2617
|
+
agent: thread.agent,
|
|
2618
|
+
sourceType: thread.sourceType,
|
|
2619
|
+
sourceRef: thread.sourceRef,
|
|
2620
|
+
repoPath: thread.repoPath,
|
|
2621
|
+
prUrl: withPr.prUrl,
|
|
2622
|
+
link: `sideboard://thread/${thread.id}`,
|
|
2623
|
+
...group.length > 1 ? { chatCount: group.length } : {}
|
|
2624
|
+
};
|
|
2625
|
+
}
|
|
2626
|
+
function threadMatchesKind(thread, kind) {
|
|
2627
|
+
if (kind === "all" || kind === "threads") return true;
|
|
2628
|
+
if (kind === "tickets") return thread.sourceType === "ticket";
|
|
2629
|
+
if (kind === "prs") return thread.sourceType === "pr";
|
|
2630
|
+
if (kind === "branches") return thread.sourceType === "branch" || thread.sourceType === "adopt";
|
|
2631
|
+
return true;
|
|
2632
|
+
}
|
|
2633
|
+
function assembleHomeBoard(input) {
|
|
2634
|
+
const tokens = tokenizeQuery(input.query ?? "");
|
|
2635
|
+
const repo = input.repoPath?.trim() ?? "";
|
|
2636
|
+
const kind = input.kind ?? "all";
|
|
2637
|
+
const limit = Math.max(1, input.limit ?? BOARD_PAGE_SIZE);
|
|
2638
|
+
const wsName = input.workspaceName ?? (() => "");
|
|
2639
|
+
const byUpdated = (a, b) => b.updatedAt.localeCompare(a.updatedAt);
|
|
2640
|
+
const live = input.threads.filter((t) => t.status !== "archived" && isHomeBoardThread(t)).sort(byUpdated);
|
|
2641
|
+
const columns = emptyColumns();
|
|
2642
|
+
const hidden = emptyHidden();
|
|
2643
|
+
const totals = {
|
|
2644
|
+
backlog: 0,
|
|
2645
|
+
queued: 0,
|
|
2646
|
+
running: 0,
|
|
2647
|
+
new: 0,
|
|
2648
|
+
draft: 0,
|
|
2649
|
+
review: 0,
|
|
2650
|
+
done: 0,
|
|
2651
|
+
tickets: 0,
|
|
2652
|
+
prs: 0,
|
|
2653
|
+
branches: 0,
|
|
2654
|
+
threads: 0
|
|
2655
|
+
};
|
|
2656
|
+
const byCol = {
|
|
2657
|
+
queued: [],
|
|
2658
|
+
running: [],
|
|
2659
|
+
new: [],
|
|
2660
|
+
draft: [],
|
|
2661
|
+
review: [],
|
|
2662
|
+
done: []
|
|
2663
|
+
};
|
|
2664
|
+
for (const group of groupHomeBoardWorktrees(live)) {
|
|
2665
|
+
if (!group.some((t) => threadMatchesKind(t, kind))) continue;
|
|
2666
|
+
const col = classifyWorktreeColumn(group);
|
|
2667
|
+
if (col === "backlog") continue;
|
|
2668
|
+
const primary = group[0];
|
|
2669
|
+
if (!inWorkspace(primary.repoPath, repo)) continue;
|
|
2670
|
+
const hay = group.map((t) => threadSearchText(t, wsName(t.repoPath))).join(" ");
|
|
2671
|
+
if (!haystackMatches(hay, tokens)) continue;
|
|
2672
|
+
byCol[col].push(group);
|
|
2673
|
+
}
|
|
2674
|
+
const flat = [...Object.values(byCol)].flatMap((groups) => groups.map((g) => g[0]));
|
|
2675
|
+
totals.tickets = flat.filter((t) => t.sourceType === "ticket").length;
|
|
2676
|
+
totals.prs = flat.filter((t) => t.sourceType === "pr").length;
|
|
2677
|
+
totals.branches = flat.filter((t) => t.sourceType === "branch" || t.sourceType === "adopt").length;
|
|
2678
|
+
totals.threads = Object.values(byCol).reduce((n, list) => n + list.length, 0);
|
|
2679
|
+
for (const col of Object.keys(byCol)) {
|
|
2680
|
+
const cards = byCol[col].map(toThreadCard);
|
|
2681
|
+
totals[col] = cards.length;
|
|
2682
|
+
const page = visiblePage(cards, limit);
|
|
2683
|
+
columns[col] = page.visible;
|
|
2684
|
+
hidden[col] = page.hidden;
|
|
2685
|
+
}
|
|
2686
|
+
if (input.column) {
|
|
2687
|
+
for (const col of Object.keys(columns)) {
|
|
2688
|
+
if (col === input.column) continue;
|
|
2689
|
+
columns[col] = [];
|
|
2690
|
+
hidden[col] = 0;
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
return { columns, hidden, totals };
|
|
2694
|
+
}
|
|
2695
|
+
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). create_thread reuses a live worktree for the same ticket, PR, or named branch \u2014 do not recreate it. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2696
|
+
|
|
2297
2697
|
// src/threads/create.ts
|
|
2298
2698
|
async function createThread(input, _onSetupLine) {
|
|
2699
|
+
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2700
|
+
if (!existsSync7(repoPath)) {
|
|
2701
|
+
throw new Error(`Repo not found: ${repoPath}`);
|
|
2702
|
+
}
|
|
2703
|
+
if (input.reuseExisting !== false) {
|
|
2704
|
+
const existing = findLiveThreadForCreate(
|
|
2705
|
+
{
|
|
2706
|
+
sourceType: input.sourceType,
|
|
2707
|
+
sourceRef: input.sourceRef,
|
|
2708
|
+
repoPath,
|
|
2709
|
+
title: input.title,
|
|
2710
|
+
cowboy: input.cowboy
|
|
2711
|
+
},
|
|
2712
|
+
listThreads({ includeArchived: false }).map((t) => ({
|
|
2713
|
+
...t,
|
|
2714
|
+
repoPath: canonicalizeRepoPath(t.repoPath)
|
|
2715
|
+
}))
|
|
2716
|
+
);
|
|
2717
|
+
if (existing) return readThread(existing.id) ?? existing;
|
|
2718
|
+
}
|
|
2299
2719
|
const resolved = resolveNewThreadOptions({
|
|
2300
2720
|
agent: input.agent,
|
|
2301
2721
|
model: input.model,
|
|
@@ -2303,12 +2723,8 @@ async function createThread(input, _onSetupLine) {
|
|
|
2303
2723
|
fast: input.fast
|
|
2304
2724
|
});
|
|
2305
2725
|
await requireAgent(resolved.agent);
|
|
2306
|
-
const repoPath = await resolveRepoRoot(input.repoPath);
|
|
2307
|
-
if (!existsSync7(repoPath)) {
|
|
2308
|
-
throw new Error(`Repo not found: ${repoPath}`);
|
|
2309
|
-
}
|
|
2310
2726
|
if (input.cowboy) {
|
|
2311
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
2727
|
+
const { cowboyModeEnabled } = await import("./app-settings-6RPALX4J.js");
|
|
2312
2728
|
if (!cowboyModeEnabled()) {
|
|
2313
2729
|
throw new Error(
|
|
2314
2730
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -2419,7 +2835,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2419
2835
|
return readThread(thread.id) ?? thread;
|
|
2420
2836
|
}
|
|
2421
2837
|
async function listLinearIssues(agent, repoPath) {
|
|
2422
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2838
|
+
const { getAdapter: getAdapter2 } = await import("./agents-X2I3RNCY.js");
|
|
2423
2839
|
await requireAgent(agent, { requireLinear: true });
|
|
2424
2840
|
const adapter = getAdapter2(agent);
|
|
2425
2841
|
if (!adapter.listLinearIssues) {
|
|
@@ -2605,7 +3021,8 @@ async function forkThreadWorktree(input, onSetupLine) {
|
|
|
2605
3021
|
planMode: from.planMode,
|
|
2606
3022
|
title: input.title?.trim() || void 0,
|
|
2607
3023
|
parentThreadId: from.id,
|
|
2608
|
-
attachments: [attachment]
|
|
3024
|
+
attachments: [attachment],
|
|
3025
|
+
reuseExisting: false
|
|
2609
3026
|
},
|
|
2610
3027
|
onSetupLine
|
|
2611
3028
|
);
|
|
@@ -2685,7 +3102,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
2685
3102
|
"",
|
|
2686
3103
|
`## Instructions`,
|
|
2687
3104
|
`- Continue fleet orchestration from this handoff.`,
|
|
2688
|
-
`- Prefer Sideboard MCP (list_threads, get_thread, send_to_thread, \u2026) for live status.`,
|
|
3105
|
+
`- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.`,
|
|
2689
3106
|
`- Leave model Auto unless there is a specific reason to pin one.`,
|
|
2690
3107
|
`- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
|
|
2691
3108
|
].join("\n");
|
|
@@ -2698,9 +3115,9 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
2698
3115
|
}
|
|
2699
3116
|
var QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
|
|
2700
3117
|
`${fromAgent} hit a session/usage limit. Continue this orchestration on ${fallback} using the attached handoff.`,
|
|
2701
|
-
"Call list_threads for live fleet status, then proceed with the goal. Leave model Auto unless needed."
|
|
3118
|
+
"Call list_board or list_threads for live fleet status, then proceed with the goal. Leave model Auto unless needed."
|
|
2702
3119
|
].join(" ");
|
|
2703
|
-
var QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue the orchestration from where you left off. Use list_threads for fleet status.";
|
|
3120
|
+
var QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue the orchestration from where you left off. Use list_board or list_threads for fleet status.";
|
|
2704
3121
|
function createQuotaFailoverChat(from, fallbackAgent, limitText) {
|
|
2705
3122
|
const handoff = buildQuotaHandoffAttachment(from, limitText, fallbackAgent);
|
|
2706
3123
|
const tab = createChatTab({
|
|
@@ -2815,7 +3232,7 @@ async function adoptThread(input) {
|
|
|
2815
3232
|
messages: input.messages ?? []
|
|
2816
3233
|
});
|
|
2817
3234
|
writeThread(thread);
|
|
2818
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
3235
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-O4QZOASB.js");
|
|
2819
3236
|
await ensureWorkspace2(repoPath);
|
|
2820
3237
|
return thread;
|
|
2821
3238
|
}
|
|
@@ -4728,7 +5145,8 @@ function formatArtifactDirective() {
|
|
|
4728
5145
|
"```html",
|
|
4729
5146
|
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
4730
5147
|
"```",
|
|
4731
|
-
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
|
|
5148
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown|react|log), and content \u2014 not both a fence and this tool for the same body.",
|
|
5149
|
+
" type=log is append-only: same `artifact_id`, `content` = new lines only (plus optional status/phase). Do not resend the full log or wrap it in HTML.",
|
|
4732
5150
|
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
4733
5151
|
"3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
|
|
4734
5152
|
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
@@ -4743,7 +5161,7 @@ function formatArtifactDirective() {
|
|
|
4743
5161
|
].join("\n");
|
|
4744
5162
|
}
|
|
4745
5163
|
function formatUiReminder() {
|
|
4746
|
-
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. ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
5164
|
+
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 or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
4747
5165
|
}
|
|
4748
5166
|
var FILES_BY_AGENT = {
|
|
4749
5167
|
claude: [
|
|
@@ -5088,7 +5506,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5088
5506
|
${prompt}`;
|
|
5089
5507
|
}
|
|
5090
5508
|
async function defaultDeps() {
|
|
5091
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5509
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-G6DU3AF3.js");
|
|
5092
5510
|
const orch = getOrchestrator2();
|
|
5093
5511
|
return {
|
|
5094
5512
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5242,7 +5660,7 @@ var Orchestrator = class {
|
|
|
5242
5660
|
maxConcurrent;
|
|
5243
5661
|
runningCount = 0;
|
|
5244
5662
|
constructor(opts) {
|
|
5245
|
-
this.maxConcurrent = opts?.maxConcurrent ??
|
|
5663
|
+
this.maxConcurrent = opts?.maxConcurrent ?? 5;
|
|
5246
5664
|
}
|
|
5247
5665
|
on(listener) {
|
|
5248
5666
|
this.events.on("event", listener);
|
|
@@ -5308,7 +5726,7 @@ var Orchestrator = class {
|
|
|
5308
5726
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
5309
5727
|
});
|
|
5310
5728
|
}
|
|
5311
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
5729
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-6RPALX4J.js");
|
|
5312
5730
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
5313
5731
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
5314
5732
|
}
|
|
@@ -5459,7 +5877,23 @@ var Orchestrator = class {
|
|
|
5459
5877
|
return findThreadByRef(idOrRef) ?? readThread(idOrRef);
|
|
5460
5878
|
}
|
|
5461
5879
|
async createThread(input) {
|
|
5880
|
+
const prior = new Set(
|
|
5881
|
+
listThreads({ includeArchived: false }).map((t) => t.id)
|
|
5882
|
+
);
|
|
5462
5883
|
const thread = await createThread(input);
|
|
5884
|
+
if (prior.has(thread.id)) {
|
|
5885
|
+
if (input.prompt?.trim()) {
|
|
5886
|
+
try {
|
|
5887
|
+
await this.send(thread.id, input.prompt.trim());
|
|
5888
|
+
} catch (err) {
|
|
5889
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
5890
|
+
updateThread(thread.id, {
|
|
5891
|
+
lastError: `First prompt failed: ${message}`
|
|
5892
|
+
});
|
|
5893
|
+
}
|
|
5894
|
+
}
|
|
5895
|
+
return thread;
|
|
5896
|
+
}
|
|
5463
5897
|
this.emit({ type: "status_changed", threadId: thread.id, status: thread.status });
|
|
5464
5898
|
void this.finishCreateThread(thread.id, input.prompt?.trim() || void 0);
|
|
5465
5899
|
return thread;
|
|
@@ -5480,7 +5914,7 @@ var Orchestrator = class {
|
|
|
5480
5914
|
}
|
|
5481
5915
|
await setup;
|
|
5482
5916
|
if (skipSetup) return;
|
|
5483
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
5917
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-6RPALX4J.js");
|
|
5484
5918
|
if (autoRunAfterSetupEnabled()) {
|
|
5485
5919
|
try {
|
|
5486
5920
|
await this.startDev(threadId);
|
|
@@ -5765,7 +6199,7 @@ var Orchestrator = class {
|
|
|
5765
6199
|
}
|
|
5766
6200
|
const isBrightsy = fresh.agent === "brightsy";
|
|
5767
6201
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
5768
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
6202
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-6RPALX4J.js");
|
|
5769
6203
|
const gitAuthMode = getGithubGitAuthMode();
|
|
5770
6204
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
5771
6205
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -6302,7 +6736,8 @@ var Orchestrator = class {
|
|
|
6302
6736
|
agent,
|
|
6303
6737
|
repoPath: opts.repoPath,
|
|
6304
6738
|
title: opts.title ? `${opts.title} (${agent})` : `best-of-n: ${opts.prompt.slice(0, 48)} (${agent})`,
|
|
6305
|
-
prompt: opts.prompt
|
|
6739
|
+
prompt: opts.prompt,
|
|
6740
|
+
reuseExisting: false
|
|
6306
6741
|
});
|
|
6307
6742
|
created.push(thread);
|
|
6308
6743
|
}
|
|
@@ -6539,6 +6974,8 @@ var Orchestrator = class {
|
|
|
6539
6974
|
if (meta.url && meta.url !== thread.prUrl) patch.prUrl = meta.url;
|
|
6540
6975
|
if (meta.title && meta.title !== thread.prTitle) patch.prTitle = meta.title;
|
|
6541
6976
|
if (nextState && nextState !== prevState) patch.prState = nextState;
|
|
6977
|
+
const nextDraft = Boolean(meta.isDraft) && nextState !== "MERGED" && nextState !== "CLOSED";
|
|
6978
|
+
if (nextDraft !== Boolean(thread.prIsDraft)) patch.prIsDraft = nextDraft;
|
|
6542
6979
|
if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
|
|
6543
6980
|
patch.skipAutoArchiveOnMerge = false;
|
|
6544
6981
|
}
|
|
@@ -6549,7 +6986,7 @@ var Orchestrator = class {
|
|
|
6549
6986
|
updateThread(thread.id, { title: meta.title });
|
|
6550
6987
|
}
|
|
6551
6988
|
}
|
|
6552
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
6989
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-6RPALX4J.js");
|
|
6553
6990
|
const latest = this.requireThread(thread.id);
|
|
6554
6991
|
if (!shouldAutoArchiveOnPrMerge({
|
|
6555
6992
|
previousPrState: prevState || null,
|
|
@@ -6563,7 +7000,7 @@ var Orchestrator = class {
|
|
|
6563
7000
|
}
|
|
6564
7001
|
const siblings = threadsSharingWorktree(latest.worktreePath);
|
|
6565
7002
|
for (const t of siblings) {
|
|
6566
|
-
const sibPatch = { prState: "MERGED" };
|
|
7003
|
+
const sibPatch = { prState: "MERGED", prIsDraft: false };
|
|
6567
7004
|
if (meta.url && meta.url !== t.prUrl) sibPatch.prUrl = meta.url;
|
|
6568
7005
|
if (meta.title && meta.title !== t.prTitle) sibPatch.prTitle = meta.title;
|
|
6569
7006
|
if (Object.keys(sibPatch).length > 0) updateThread(t.id, sibPatch);
|
|
@@ -6737,10 +7174,15 @@ var Orchestrator = class {
|
|
|
6737
7174
|
web: action === "create-web"
|
|
6738
7175
|
});
|
|
6739
7176
|
if (!url) return;
|
|
6740
|
-
const patch = {
|
|
7177
|
+
const patch = {
|
|
7178
|
+
prUrl: url,
|
|
7179
|
+
prTitle: meta.title,
|
|
7180
|
+
prIsDraft: action === "create-draft"
|
|
7181
|
+
};
|
|
6741
7182
|
try {
|
|
6742
7183
|
const fetched = await getPrMeta(cwd, url);
|
|
6743
7184
|
if (fetched?.title) patch.prTitle = fetched.title;
|
|
7185
|
+
if (fetched) patch.prIsDraft = Boolean(fetched.isDraft);
|
|
6744
7186
|
} catch {
|
|
6745
7187
|
}
|
|
6746
7188
|
updateThread(thread.id, patch);
|
|
@@ -6854,7 +7296,7 @@ var Orchestrator = class {
|
|
|
6854
7296
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
6855
7297
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
6856
7298
|
try {
|
|
6857
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
7299
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-O4QZOASB.js");
|
|
6858
7300
|
await ensureWorkspace2(thread.repoPath);
|
|
6859
7301
|
} catch {
|
|
6860
7302
|
}
|
|
@@ -6881,7 +7323,7 @@ var Orchestrator = class {
|
|
|
6881
7323
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
6882
7324
|
} catch {
|
|
6883
7325
|
}
|
|
6884
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
7326
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-6RPALX4J.js");
|
|
6885
7327
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
6886
7328
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
6887
7329
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -6908,7 +7350,7 @@ var Orchestrator = class {
|
|
|
6908
7350
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
6909
7351
|
);
|
|
6910
7352
|
}
|
|
6911
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
7353
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-JVGSLSLJ.js");
|
|
6912
7354
|
const slug = thread.worktreePath.split("/").pop();
|
|
6913
7355
|
const dest = thread.worktreePath;
|
|
6914
7356
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7016,7 +7458,7 @@ async function startOrchestration(opts) {
|
|
|
7016
7458
|
sourceRef: "default",
|
|
7017
7459
|
...createOpts
|
|
7018
7460
|
}).catch(async () => {
|
|
7019
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7461
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-JVGSLSLJ.js");
|
|
7020
7462
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7021
7463
|
const def = await resolveDefaultBranch2(repo);
|
|
7022
7464
|
return orch.createThread({
|
|
@@ -7026,7 +7468,7 @@ async function startOrchestration(opts) {
|
|
|
7026
7468
|
repoPath: repo
|
|
7027
7469
|
});
|
|
7028
7470
|
});
|
|
7029
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7471
|
+
const { updateThread: upd } = await import("./thread-store-5MLYY35S.js");
|
|
7030
7472
|
const updated = upd(thread.id, {
|
|
7031
7473
|
sourceType: "orchestration",
|
|
7032
7474
|
sourceRef: goal
|
|
@@ -7148,6 +7590,23 @@ export {
|
|
|
7148
7590
|
cloneRepoIntoSideboard,
|
|
7149
7591
|
detectAgents,
|
|
7150
7592
|
requireAgent,
|
|
7593
|
+
isHomeBoardThread,
|
|
7594
|
+
BOARD_COLUMN_DEFS,
|
|
7595
|
+
HOME_BOARD_CACHE_TTL_MS,
|
|
7596
|
+
groupHomeBoardWorktrees,
|
|
7597
|
+
classifyWorktreeColumn,
|
|
7598
|
+
worktreeBoardStatus,
|
|
7599
|
+
dedupeBoardIssues,
|
|
7600
|
+
issueNeedsWorkspacePick,
|
|
7601
|
+
findLiveThreadForCreate,
|
|
7602
|
+
boardPinIdentity,
|
|
7603
|
+
findBoardPin,
|
|
7604
|
+
syncBoardPins,
|
|
7605
|
+
dedupeBoardPrs,
|
|
7606
|
+
findBoardIssue,
|
|
7607
|
+
findBoardPr,
|
|
7608
|
+
assembleHomeBoard,
|
|
7609
|
+
HOME_BOARD_AGENT_HINT,
|
|
7151
7610
|
createThread,
|
|
7152
7611
|
listLinearIssues,
|
|
7153
7612
|
isCowboyThread,
|