@sideboard-ai/core 0.1.298 → 0.1.299
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-GHZFY65E.js → agents-IVKPCK56.js} +3 -3
- package/dist/{agents-XL67HSZH.js → agents-JCCJJMA7.js} +2 -2
- package/dist/{chunk-RQMLJZ2V.js → chunk-EB3F5AWV.js} +2 -2
- package/dist/{chunk-IL77XODJ.js → chunk-EB7B4D2Z.js} +3 -3
- package/dist/{chunk-JM5P36PM.js → chunk-F3JYJ4UB.js} +2 -2
- package/dist/{chunk-BIMHIHX3.js → chunk-G52HLBQR.js} +21 -1
- package/dist/{chunk-4FWMUMXG.js → chunk-MMIDAD6J.js} +3 -3
- package/dist/{chunk-KRGQWQME.js → chunk-NF3WDI7F.js} +183 -109
- package/dist/{chunk-KMYCNSSI.js → chunk-QB4UQA5L.js} +3 -3
- package/dist/{chunk-5FMQU2RU.js → chunk-UMALFEDS.js} +2 -2
- package/dist/{chunk-2POLTCSC.js → chunk-YAILSKW3.js} +61 -47
- package/dist/{conductor-NGIEDMAB.js → conductor-JLHXMMKR.js} +2 -2
- package/dist/{conductor-HUITLA2M.js → conductor-UQDDDW35.js} +3 -3
- package/dist/{coordinator-prompt-JUN3IITF.js → coordinator-prompt-HKLVS26O.js} +2 -2
- package/dist/{coordinator-prompt-52T5A4SU.js → coordinator-prompt-SSUYZSJO.js} +1 -1
- package/dist/{global-workspace-VVUIFQ72.js → global-workspace-I32EWKX3.js} +2 -2
- package/dist/{global-workspace-Z5YRL67Y.js → global-workspace-MHE6FCUZ.js} +1 -1
- package/dist/index.cjs +336 -224
- package/dist/index.d.cts +44 -26
- package/dist/index.d.ts +44 -26
- package/dist/index.js +11 -11
- package/dist/mcp/run-stdio.cjs +81 -43
- package/dist/mcp/run-stdio.js +7 -7
- package/dist/{orchestrator-S7TKI6DR.js → orchestrator-ESLNXVOX.js} +5 -5
- package/dist/{orchestrator-JY4ZETFX.js → orchestrator-SX4SGZHF.js} +4 -4
- package/dist/{workspaces-OSF56FHS.js → workspaces-ATMIKXLK.js} +2 -2
- package/dist/{workspaces-7FVNGUBV.js → workspaces-O3L32CDO.js} +1 -1
- package/dist/{worktree-LFSBIUCN.js → worktree-RMYXBTJG.js} +1 -1
- package/package.json +1 -1
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
planModeTurnInstruction,
|
|
38
38
|
resolveCursorModelId,
|
|
39
39
|
resolveQuotaFallbackAgent
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-EB7B4D2Z.js";
|
|
41
41
|
import "./chunk-VGNLMGBK.js";
|
|
42
42
|
import "./chunk-F36QRDM4.js";
|
|
43
43
|
import {
|
|
@@ -52,8 +52,8 @@ import {
|
|
|
52
52
|
resolveLoginCommand,
|
|
53
53
|
whichOnPath
|
|
54
54
|
} from "./chunk-B42H6GJR.js";
|
|
55
|
-
import "./chunk-
|
|
56
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-QB4UQA5L.js";
|
|
56
|
+
import "./chunk-G52HLBQR.js";
|
|
57
57
|
import "./chunk-K5EACGG2.js";
|
|
58
58
|
import "./chunk-2P4XKWV2.js";
|
|
59
59
|
import "./chunk-33KDPEK4.js";
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
resolveCursorSdkRoot,
|
|
47
47
|
resolveQuotaFallbackAgent,
|
|
48
48
|
turnCostUsdFromCursorUsage
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-EB3F5AWV.js";
|
|
50
50
|
import {
|
|
51
51
|
getAgentSetupInfo,
|
|
52
52
|
installAgent,
|
|
@@ -63,7 +63,7 @@ import "./chunk-7IAMHN2N.js";
|
|
|
63
63
|
import "./chunk-PXMLMBMI.js";
|
|
64
64
|
import "./chunk-2GPQZZLY.js";
|
|
65
65
|
import "./chunk-5XQ43YZU.js";
|
|
66
|
-
import "./chunk-
|
|
66
|
+
import "./chunk-UMALFEDS.js";
|
|
67
67
|
import "./chunk-3IXGI2FP.js";
|
|
68
68
|
import "./chunk-N2WW62LF.js";
|
|
69
69
|
import "./chunk-DD67JWTN.js";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-5XQ43YZU.js";
|
|
25
25
|
import {
|
|
26
26
|
isOrchestratorThread
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-UMALFEDS.js";
|
|
28
28
|
import {
|
|
29
29
|
codexUnattendedGitConfigArgs,
|
|
30
30
|
mergeAgentGitAuthEnv,
|
|
@@ -2020,7 +2020,7 @@ var claudeAdapter = {
|
|
|
2020
2020
|
);
|
|
2021
2021
|
}
|
|
2022
2022
|
const mode = permissionMode(thread);
|
|
2023
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2023
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-MHE6FCUZ.js");
|
|
2024
2024
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2025
2025
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
2026
2026
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
} from "./chunk-F36QRDM4.js";
|
|
13
13
|
import {
|
|
14
14
|
isOrchestratorThread
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-QB4UQA5L.js";
|
|
16
16
|
import {
|
|
17
17
|
codexUnattendedGitConfigArgs,
|
|
18
18
|
mergeAgentGitAuthEnv,
|
|
19
19
|
resolveAgentGitAuthEnv,
|
|
20
20
|
resolveCodexGitWritableRoots
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-G52HLBQR.js";
|
|
22
22
|
import {
|
|
23
23
|
loadBrightsyConfig
|
|
24
24
|
} from "./chunk-33KDPEK4.js";
|
|
@@ -1757,7 +1757,7 @@ var claudeAdapter = {
|
|
|
1757
1757
|
);
|
|
1758
1758
|
}
|
|
1759
1759
|
const mode = permissionMode(thread);
|
|
1760
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
1760
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-I32EWKX3.js");
|
|
1761
1761
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
1762
1762
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
1763
1763
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
isGlobalThread,
|
|
12
12
|
isOrchestratorThread,
|
|
13
13
|
isSlackCoordinatorThread
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UMALFEDS.js";
|
|
15
15
|
import {
|
|
16
16
|
mergeAgentGitAuthEnv,
|
|
17
17
|
resolveAgentGitAuthEnv
|
|
@@ -1674,7 +1674,7 @@ var PORT_RANGE_SIZE = 10;
|
|
|
1674
1674
|
var RECLAIM_RETRY_DELAY_MS = 40;
|
|
1675
1675
|
var RECLAIM_TRIES = 8;
|
|
1676
1676
|
async function killReclaimable(ports, worktreePath, signal) {
|
|
1677
|
-
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-
|
|
1677
|
+
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-JLHXMMKR.js");
|
|
1678
1678
|
if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
|
|
1679
1679
|
else killListenersOnPorts2(ports);
|
|
1680
1680
|
}
|
|
@@ -750,6 +750,24 @@ function applyCleanLocalMergeTree(gate) {
|
|
|
750
750
|
mergeStateStatus: mergeState === "BEHIND" ? "BEHIND" : mergeState === "UNKNOWN" || !mergeState ? "CLEAN" : gate.mergeStateStatus
|
|
751
751
|
};
|
|
752
752
|
}
|
|
753
|
+
function classifyPrMergeIssue(gate) {
|
|
754
|
+
if (!gate) return null;
|
|
755
|
+
if (prIsInMergeQueue(gate)) return null;
|
|
756
|
+
const mergeable = (gate.mergeable ?? "").toUpperCase();
|
|
757
|
+
const mergeState = (gate.mergeStateStatus ?? "").toUpperCase();
|
|
758
|
+
if (mergeable === "CONFLICTING" || mergeState === "DIRTY") return "conflicts";
|
|
759
|
+
if (mergeState === "BEHIND") return "behind";
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
function mergeStateSuggestsCheckFailure(gate) {
|
|
763
|
+
if (!gate) return false;
|
|
764
|
+
const mergeState = (gate.mergeStateStatus ?? "").toUpperCase();
|
|
765
|
+
if (mergeState === "UNSTABLE") return true;
|
|
766
|
+
if (mergeState === "BLOCKED") {
|
|
767
|
+
return (gate.reviewDecision ?? "").toUpperCase() === "APPROVED";
|
|
768
|
+
}
|
|
769
|
+
return false;
|
|
770
|
+
}
|
|
753
771
|
function ciChecksFailed(checks) {
|
|
754
772
|
if (!checks?.length) return false;
|
|
755
773
|
return checks.some(
|
|
@@ -2584,6 +2602,9 @@ function suggestSlug(source) {
|
|
|
2584
2602
|
}
|
|
2585
2603
|
|
|
2586
2604
|
export {
|
|
2605
|
+
classifyPrMergeIssue,
|
|
2606
|
+
mergeStateSuggestsCheckFailure,
|
|
2607
|
+
ciChecksFailed,
|
|
2587
2608
|
GITHUB_PR_BODY_MAX_CHARS,
|
|
2588
2609
|
GITHUB_PR_BODY_SAFE_CHARS,
|
|
2589
2610
|
isGhRateLimitError,
|
|
@@ -2613,7 +2634,6 @@ export {
|
|
|
2613
2634
|
resolveListPrsOptions,
|
|
2614
2635
|
enqueueByKey,
|
|
2615
2636
|
withRepoGitLock,
|
|
2616
|
-
ciChecksFailed,
|
|
2617
2637
|
detectGhStack,
|
|
2618
2638
|
resetGhStackDetectCache,
|
|
2619
2639
|
parseGhStackViewJson,
|
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
isGlobalThread,
|
|
9
9
|
isOrchestratorThread,
|
|
10
10
|
isSlackCoordinatorThread
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QB4UQA5L.js";
|
|
12
12
|
import {
|
|
13
13
|
mergeAgentGitAuthEnv,
|
|
14
14
|
resolveAgentGitAuthEnv
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G52HLBQR.js";
|
|
16
16
|
import {
|
|
17
17
|
allocateTeamName,
|
|
18
18
|
createEmptyThread,
|
|
@@ -1776,7 +1776,7 @@ var PORT_RANGE_SIZE = 10;
|
|
|
1776
1776
|
var RECLAIM_RETRY_DELAY_MS = 40;
|
|
1777
1777
|
var RECLAIM_TRIES = 8;
|
|
1778
1778
|
async function killReclaimable(ports, worktreePath, signal) {
|
|
1779
|
-
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-
|
|
1779
|
+
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-UQDDDW35.js");
|
|
1780
1780
|
if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
|
|
1781
1781
|
else killListenersOnPorts2(ports);
|
|
1782
1782
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
parseSessionQuotaResetAt,
|
|
15
15
|
planModeTurnInstruction,
|
|
16
16
|
resolveQuotaFallbackAgent
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-EB7B4D2Z.js";
|
|
18
18
|
import {
|
|
19
19
|
REVIEW_TAB_TITLE,
|
|
20
20
|
applyWorktreePkgCacheEnv,
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
worktreeDevProcessKey,
|
|
54
54
|
worktreeRunProcessKey,
|
|
55
55
|
worktreeSetupProcessKey
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-MMIDAD6J.js";
|
|
57
57
|
import {
|
|
58
58
|
applyAgentEvent,
|
|
59
59
|
clipAgentEventForPaint,
|
|
@@ -100,12 +100,13 @@ import {
|
|
|
100
100
|
stageAbsolutePathsAsAttachments,
|
|
101
101
|
stageBuffersAsAttachments,
|
|
102
102
|
syncWorkspacesFromThreads
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-QB4UQA5L.js";
|
|
104
104
|
import {
|
|
105
105
|
addPrStackLayer,
|
|
106
106
|
allocateTeamSlug,
|
|
107
107
|
canonicalizeRepoPath,
|
|
108
108
|
ciChecksFailed,
|
|
109
|
+
classifyPrMergeIssue,
|
|
109
110
|
commitAll,
|
|
110
111
|
connectedPrSelectors,
|
|
111
112
|
createExistingBranchWorktree,
|
|
@@ -132,6 +133,7 @@ import {
|
|
|
132
133
|
markPrReady,
|
|
133
134
|
mergeAgentGitAuthEnv,
|
|
134
135
|
mergePr,
|
|
136
|
+
mergeStateSuggestsCheckFailure,
|
|
135
137
|
pushBranch,
|
|
136
138
|
removeWorktree,
|
|
137
139
|
resolveAgentGitAuthEnv,
|
|
@@ -142,7 +144,7 @@ import {
|
|
|
142
144
|
resolveRepoRoot,
|
|
143
145
|
switchWorktreeBranch,
|
|
144
146
|
withRepoGitLock
|
|
145
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-G52HLBQR.js";
|
|
146
148
|
import {
|
|
147
149
|
agentNicknameFromWorktreePath,
|
|
148
150
|
appendMessage,
|
|
@@ -451,9 +453,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
451
453
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
452
454
|
);
|
|
453
455
|
}
|
|
454
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
456
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-I32EWKX3.js");
|
|
455
457
|
if (isGlobalThread2(thread)) {
|
|
456
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
458
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-HKLVS26O.js");
|
|
457
459
|
ensureGlobalCoordinatorCwd2(
|
|
458
460
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
459
461
|
);
|
|
@@ -2001,20 +2003,7 @@ function threadCardBlockFields(group) {
|
|
|
2001
2003
|
return block ? { blockedReason: block.reason, blockedSource: block.source } : null;
|
|
2002
2004
|
}
|
|
2003
2005
|
|
|
2004
|
-
// src/board/
|
|
2005
|
-
var GLOBAL_WORKSPACE_ID = "__global__";
|
|
2006
|
-
function isHomeBoardThread(thread) {
|
|
2007
|
-
if (thread.sourceType === "orchestration") return false;
|
|
2008
|
-
if (thread.repoPath === GLOBAL_WORKSPACE_ID) return false;
|
|
2009
|
-
return true;
|
|
2010
|
-
}
|
|
2011
|
-
var BOARD_COLUMN_DEFS = [
|
|
2012
|
-
{ id: "new", title: "New" },
|
|
2013
|
-
{ id: "draft", title: "Draft" },
|
|
2014
|
-
{ id: "review", title: "Review" },
|
|
2015
|
-
{ id: "done", title: "Merged" }
|
|
2016
|
-
];
|
|
2017
|
-
var HOME_BOARD_CACHE_TTL_MS = 15 * 60 * 1e3;
|
|
2006
|
+
// src/board/pr-state.ts
|
|
2018
2007
|
function isOpenPrState(prUrl, prState) {
|
|
2019
2008
|
if (!prUrl?.trim()) return false;
|
|
2020
2009
|
const state = (prState ?? "OPEN").trim().toUpperCase();
|
|
@@ -2024,58 +2013,12 @@ function isMergedPrState(prUrl, prState) {
|
|
|
2024
2013
|
if (!prUrl?.trim()) return false;
|
|
2025
2014
|
return (prState ?? "").trim().toUpperCase() === "MERGED";
|
|
2026
2015
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
for (const t of group) {
|
|
2031
|
-
if (t.createdAt && t.createdAt < min) min = t.createdAt;
|
|
2032
|
-
}
|
|
2033
|
-
return min;
|
|
2034
|
-
}
|
|
2035
|
-
function groupUpdatedAt(group) {
|
|
2036
|
-
let max = group[0]?.updatedAt ?? "";
|
|
2037
|
-
for (const t of group) {
|
|
2038
|
-
if (t.updatedAt && t.updatedAt > max) max = t.updatedAt;
|
|
2039
|
-
}
|
|
2040
|
-
return max;
|
|
2041
|
-
}
|
|
2042
|
-
function sortThreadsInWorktree(list) {
|
|
2043
|
-
return [...list].sort((a, b) => {
|
|
2044
|
-
const created = a.createdAt.localeCompare(b.createdAt);
|
|
2045
|
-
if (created !== 0) return created;
|
|
2046
|
-
return a.id.localeCompare(b.id);
|
|
2047
|
-
});
|
|
2048
|
-
}
|
|
2049
|
-
function compareWorktreeGroups(a, b, mode, labelOf) {
|
|
2050
|
-
if (mode === "name") {
|
|
2051
|
-
const named = (labelOf?.(a) ?? a[0]?.id ?? "").localeCompare(
|
|
2052
|
-
labelOf?.(b) ?? b[0]?.id ?? "",
|
|
2053
|
-
void 0,
|
|
2054
|
-
{ sensitivity: "base" }
|
|
2055
|
-
);
|
|
2056
|
-
if (named !== 0) return named;
|
|
2057
|
-
} else if (mode === "activity") {
|
|
2058
|
-
const activity = groupUpdatedAt(b).localeCompare(groupUpdatedAt(a));
|
|
2059
|
-
if (activity !== 0) return activity;
|
|
2060
|
-
} else {
|
|
2061
|
-
const created = groupCreatedAt(b).localeCompare(groupCreatedAt(a));
|
|
2062
|
-
if (created !== 0) return created;
|
|
2063
|
-
}
|
|
2064
|
-
return (a[0]?.id ?? "").localeCompare(b[0]?.id ?? "");
|
|
2065
|
-
}
|
|
2066
|
-
function defaultWorktreeGroupLabel(group) {
|
|
2067
|
-
return worktreeDisplayLabelForGroup(group);
|
|
2068
|
-
}
|
|
2069
|
-
function groupHomeBoardWorktrees(threads, sort = DEFAULT_WORKTREE_SORT, labelOf = defaultWorktreeGroupLabel) {
|
|
2070
|
-
const map = /* @__PURE__ */ new Map();
|
|
2071
|
-
for (const t of threads) {
|
|
2072
|
-
const key = normalizeWorktreePath(t.worktreePath);
|
|
2073
|
-
const list = map.get(key) ?? [];
|
|
2074
|
-
list.push(t);
|
|
2075
|
-
map.set(key, list);
|
|
2076
|
-
}
|
|
2077
|
-
return [...map.values()].map((list) => sortThreadsInWorktree(list)).sort((a, b) => compareWorktreeGroups(a, b, sort, labelOf));
|
|
2016
|
+
function isApprovedOpenPr(thread) {
|
|
2017
|
+
if (!isOpenPrState(thread.prUrl, thread.prState) || thread.prIsDraft) return false;
|
|
2018
|
+
return (thread.prReviewDecision ?? "").trim().toUpperCase() === "APPROVED";
|
|
2078
2019
|
}
|
|
2020
|
+
|
|
2021
|
+
// src/board/worktree-ownership.ts
|
|
2079
2022
|
var DEFAULT_BOARD_OWNERSHIP = "all";
|
|
2080
2023
|
function normalizeViewerLogin(login) {
|
|
2081
2024
|
return (login ?? "").trim().toLowerCase();
|
|
@@ -2106,16 +2049,8 @@ function worktreeMatchesOwnership(group, filter, viewerLogin = "") {
|
|
|
2106
2049
|
if (filter === "all") return true;
|
|
2107
2050
|
return classifyWorktreeOwnership(group, viewerLogin) === filter;
|
|
2108
2051
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
|
|
2112
|
-
return "review";
|
|
2113
|
-
}
|
|
2114
|
-
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && t.prIsDraft)) {
|
|
2115
|
-
return "draft";
|
|
2116
|
-
}
|
|
2117
|
-
return "new";
|
|
2118
|
-
}
|
|
2052
|
+
|
|
2053
|
+
// src/board/worktree-list-badges.ts
|
|
2119
2054
|
function labelsInclude(labels, name) {
|
|
2120
2055
|
const want = name.trim().toLowerCase();
|
|
2121
2056
|
if (!want) return false;
|
|
@@ -2154,34 +2089,169 @@ function groupPrLabels(group) {
|
|
|
2154
2089
|
}
|
|
2155
2090
|
return out;
|
|
2156
2091
|
}
|
|
2092
|
+
function isClosedPrState(prUrl, prState) {
|
|
2093
|
+
if (!prUrl?.trim()) return false;
|
|
2094
|
+
return (prState ?? "").trim().toUpperCase() === "CLOSED";
|
|
2095
|
+
}
|
|
2096
|
+
function listBadge(id, title, conflict = false) {
|
|
2097
|
+
return {
|
|
2098
|
+
id,
|
|
2099
|
+
label: id,
|
|
2100
|
+
title: conflict ? `${title} \xB7 merge conflicts` : title,
|
|
2101
|
+
mod: `is-${id}`,
|
|
2102
|
+
...conflict ? { conflict: true } : {}
|
|
2103
|
+
};
|
|
2104
|
+
}
|
|
2105
|
+
function hasMergeConflict(thread) {
|
|
2106
|
+
if (!isOpenPrState(thread.prUrl, thread.prState)) return false;
|
|
2107
|
+
return classifyPrMergeIssue({
|
|
2108
|
+
mergeable: thread.prMergeable ?? null,
|
|
2109
|
+
mergeStateStatus: thread.prMergeStateStatus ?? null,
|
|
2110
|
+
isInMergeQueue: thread.prIsInMergeQueue
|
|
2111
|
+
}) === "conflicts";
|
|
2112
|
+
}
|
|
2113
|
+
function groupPrError(group) {
|
|
2114
|
+
const open = group.filter(
|
|
2115
|
+
(thread) => isOpenPrState(thread.prUrl, thread.prState) && !thread.prIsInMergeQueue
|
|
2116
|
+
);
|
|
2117
|
+
if (open.some(
|
|
2118
|
+
(thread) => thread.prChecksFailed || mergeStateSuggestsCheckFailure({
|
|
2119
|
+
mergeStateStatus: thread.prMergeStateStatus ?? null,
|
|
2120
|
+
reviewDecision: thread.prReviewDecision ?? null
|
|
2121
|
+
})
|
|
2122
|
+
)) {
|
|
2123
|
+
return { label: "failing", title: "Checks failing" };
|
|
2124
|
+
}
|
|
2125
|
+
if (open.some(
|
|
2126
|
+
(thread) => !thread.prIsDraft && (thread.prReviewDecision ?? "").trim().toUpperCase() === "CHANGES_REQUESTED"
|
|
2127
|
+
)) {
|
|
2128
|
+
return { label: "changes", title: "Changes requested" };
|
|
2129
|
+
}
|
|
2130
|
+
return void 0;
|
|
2131
|
+
}
|
|
2132
|
+
function withPrError(badges, error, conflict) {
|
|
2133
|
+
if (!error) return badges;
|
|
2134
|
+
const [first] = badges;
|
|
2135
|
+
if (!first) {
|
|
2136
|
+
return [
|
|
2137
|
+
{
|
|
2138
|
+
id: "error",
|
|
2139
|
+
label: error.label,
|
|
2140
|
+
title: conflict ? `${error.title} \xB7 merge conflicts` : error.title,
|
|
2141
|
+
mod: "is-error",
|
|
2142
|
+
...conflict ? { conflict: true } : {}
|
|
2143
|
+
}
|
|
2144
|
+
];
|
|
2145
|
+
}
|
|
2146
|
+
return [{ ...first, error }];
|
|
2147
|
+
}
|
|
2157
2148
|
function classifyWorktreeListBadges(group, viewerLogin = "", reviewLabel = "") {
|
|
2158
2149
|
if (group.length === 0 || group.some((t) => t.cowboy)) return [];
|
|
2150
|
+
if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) {
|
|
2151
|
+
return [listBadge("merged", "Merged")];
|
|
2152
|
+
}
|
|
2153
|
+
const conflict = group.some(hasMergeConflict);
|
|
2154
|
+
const error = groupPrError(group);
|
|
2155
|
+
const finish2 = (badges) => withPrError(badges, error, conflict);
|
|
2156
|
+
if (group.some((t) => isApprovedOpenPr(t))) {
|
|
2157
|
+
return finish2([listBadge("approved", "Approved, not merged", conflict)]);
|
|
2158
|
+
}
|
|
2159
2159
|
const open = group.filter((t) => isOpenPrState(t.prUrl, t.prState));
|
|
2160
|
-
if (open.length === 0)
|
|
2160
|
+
if (open.length === 0) {
|
|
2161
|
+
if (group.some((t) => isClosedPrState(t.prUrl, t.prState))) return [];
|
|
2162
|
+
return finish2([listBadge("new", "No pull request")]);
|
|
2163
|
+
}
|
|
2161
2164
|
const ownership = classifyWorktreeOwnership(group, viewerLogin);
|
|
2162
2165
|
if (ownership === "reviewing") {
|
|
2163
|
-
return [
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
mod: "is-review"
|
|
2169
|
-
}
|
|
2170
|
-
];
|
|
2166
|
+
return finish2([listBadge("review", "Someone else's PR", conflict)]);
|
|
2167
|
+
}
|
|
2168
|
+
if (!normalizeViewerLogin(viewerLogin)) return finish2([]);
|
|
2169
|
+
if (!open.some((t) => !t.prIsDraft)) {
|
|
2170
|
+
return finish2([listBadge("draft", "Draft pull request", conflict)]);
|
|
2171
2171
|
}
|
|
2172
|
-
if (!normalizeViewerLogin(viewerLogin)) return [];
|
|
2173
|
-
const draft = open.some((t) => t.prIsDraft);
|
|
2174
2172
|
const readyLabel = reviewLabel.trim();
|
|
2175
|
-
const inReview = readyLabel ? labelsInclude(groupPrLabels(group), readyLabel) :
|
|
2176
|
-
if (!inReview) return [];
|
|
2177
|
-
return [
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2173
|
+
const inReview = readyLabel ? labelsInclude(groupPrLabels(group), readyLabel) : true;
|
|
2174
|
+
if (!inReview) return finish2([]);
|
|
2175
|
+
return finish2([listBadge("pending", "Waiting for review", conflict)]);
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
// src/board/home-board.ts
|
|
2179
|
+
var GLOBAL_WORKSPACE_ID = "__global__";
|
|
2180
|
+
function isHomeBoardThread(thread) {
|
|
2181
|
+
if (thread.sourceType === "orchestration") return false;
|
|
2182
|
+
if (thread.repoPath === GLOBAL_WORKSPACE_ID) return false;
|
|
2183
|
+
return true;
|
|
2184
|
+
}
|
|
2185
|
+
var BOARD_COLUMN_DEFS = [
|
|
2186
|
+
{ id: "new", title: "New" },
|
|
2187
|
+
{ id: "draft", title: "Draft" },
|
|
2188
|
+
{ id: "review", title: "Review" },
|
|
2189
|
+
{ id: "approved", title: "Approved" },
|
|
2190
|
+
{ id: "done", title: "Merged" }
|
|
2191
|
+
];
|
|
2192
|
+
var HOME_BOARD_CACHE_TTL_MS = 15 * 60 * 1e3;
|
|
2193
|
+
var DEFAULT_WORKTREE_SORT = "created";
|
|
2194
|
+
function groupCreatedAt(group) {
|
|
2195
|
+
let min = group[0]?.createdAt ?? "";
|
|
2196
|
+
for (const t of group) {
|
|
2197
|
+
if (t.createdAt && t.createdAt < min) min = t.createdAt;
|
|
2198
|
+
}
|
|
2199
|
+
return min;
|
|
2200
|
+
}
|
|
2201
|
+
function groupUpdatedAt(group) {
|
|
2202
|
+
let max = group[0]?.updatedAt ?? "";
|
|
2203
|
+
for (const t of group) {
|
|
2204
|
+
if (t.updatedAt && t.updatedAt > max) max = t.updatedAt;
|
|
2205
|
+
}
|
|
2206
|
+
return max;
|
|
2207
|
+
}
|
|
2208
|
+
function sortThreadsInWorktree(list) {
|
|
2209
|
+
return [...list].sort((a, b) => {
|
|
2210
|
+
const created = a.createdAt.localeCompare(b.createdAt);
|
|
2211
|
+
if (created !== 0) return created;
|
|
2212
|
+
return a.id.localeCompare(b.id);
|
|
2213
|
+
});
|
|
2214
|
+
}
|
|
2215
|
+
function compareWorktreeGroups(a, b, mode, labelOf) {
|
|
2216
|
+
if (mode === "name") {
|
|
2217
|
+
const named = (labelOf?.(a) ?? a[0]?.id ?? "").localeCompare(
|
|
2218
|
+
labelOf?.(b) ?? b[0]?.id ?? "",
|
|
2219
|
+
void 0,
|
|
2220
|
+
{ sensitivity: "base" }
|
|
2221
|
+
);
|
|
2222
|
+
if (named !== 0) return named;
|
|
2223
|
+
} else if (mode === "activity") {
|
|
2224
|
+
const activity = groupUpdatedAt(b).localeCompare(groupUpdatedAt(a));
|
|
2225
|
+
if (activity !== 0) return activity;
|
|
2226
|
+
} else {
|
|
2227
|
+
const created = groupCreatedAt(b).localeCompare(groupCreatedAt(a));
|
|
2228
|
+
if (created !== 0) return created;
|
|
2229
|
+
}
|
|
2230
|
+
return (a[0]?.id ?? "").localeCompare(b[0]?.id ?? "");
|
|
2231
|
+
}
|
|
2232
|
+
function defaultWorktreeGroupLabel(group) {
|
|
2233
|
+
return worktreeDisplayLabelForGroup(group);
|
|
2234
|
+
}
|
|
2235
|
+
function groupHomeBoardWorktrees(threads, sort = DEFAULT_WORKTREE_SORT, labelOf = defaultWorktreeGroupLabel) {
|
|
2236
|
+
const map = /* @__PURE__ */ new Map();
|
|
2237
|
+
for (const t of threads) {
|
|
2238
|
+
const key = normalizeWorktreePath(t.worktreePath);
|
|
2239
|
+
const list = map.get(key) ?? [];
|
|
2240
|
+
list.push(t);
|
|
2241
|
+
map.set(key, list);
|
|
2242
|
+
}
|
|
2243
|
+
return [...map.values()].map((list) => sortThreadsInWorktree(list)).sort((a, b) => compareWorktreeGroups(a, b, sort, labelOf));
|
|
2244
|
+
}
|
|
2245
|
+
function classifyWorktreeColumn(group) {
|
|
2246
|
+
if (group.some((t) => isMergedPrState(t.prUrl, t.prState))) return "done";
|
|
2247
|
+
if (group.some((t) => isApprovedOpenPr(t))) return "approved";
|
|
2248
|
+
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && !t.prIsDraft)) {
|
|
2249
|
+
return "review";
|
|
2250
|
+
}
|
|
2251
|
+
if (group.some((t) => isOpenPrState(t.prUrl, t.prState) && t.prIsDraft)) {
|
|
2252
|
+
return "draft";
|
|
2253
|
+
}
|
|
2254
|
+
return "new";
|
|
2185
2255
|
}
|
|
2186
2256
|
function normalizeIssueKey(value) {
|
|
2187
2257
|
return value.trim().toLowerCase().replace(/^#/, "");
|
|
@@ -2491,6 +2561,7 @@ function emptyColumns() {
|
|
|
2491
2561
|
new: [],
|
|
2492
2562
|
draft: [],
|
|
2493
2563
|
review: [],
|
|
2564
|
+
approved: [],
|
|
2494
2565
|
done: []
|
|
2495
2566
|
};
|
|
2496
2567
|
}
|
|
@@ -2502,6 +2573,7 @@ function emptyHidden() {
|
|
|
2502
2573
|
new: 0,
|
|
2503
2574
|
draft: 0,
|
|
2504
2575
|
review: 0,
|
|
2576
|
+
approved: 0,
|
|
2505
2577
|
done: 0
|
|
2506
2578
|
};
|
|
2507
2579
|
}
|
|
@@ -2570,6 +2642,7 @@ function assembleHomeBoard(input) {
|
|
|
2570
2642
|
new: 0,
|
|
2571
2643
|
draft: 0,
|
|
2572
2644
|
review: 0,
|
|
2645
|
+
approved: 0,
|
|
2573
2646
|
done: 0,
|
|
2574
2647
|
tickets: 0,
|
|
2575
2648
|
prs: 0,
|
|
@@ -2582,6 +2655,7 @@ function assembleHomeBoard(input) {
|
|
|
2582
2655
|
new: [],
|
|
2583
2656
|
draft: [],
|
|
2584
2657
|
review: [],
|
|
2658
|
+
approved: [],
|
|
2585
2659
|
done: []
|
|
2586
2660
|
};
|
|
2587
2661
|
for (const group of groupHomeBoardWorktrees(live)) {
|
|
@@ -2616,7 +2690,7 @@ function assembleHomeBoard(input) {
|
|
|
2616
2690
|
}
|
|
2617
2691
|
return { columns, hidden, totals };
|
|
2618
2692
|
}
|
|
2619
|
-
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of workspaces (one card per checkout; sibling chats on a card are separate agents). Do not create a second workspace for a ticket, PR, or named branch that already has a live checkout \u2014 create_workspace / start_board_card return that checkout (alreadyStarted) and its chats. Add another agent with fork_chat. Creating from the default branch still opens a new isolated workspace. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. blockedReason means an agent on that card is waiting on a person (the question, plan approval, or a reported block) \u2014 read it and do not send_to_chat a check-in. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2693
|
+
var HOME_BOARD_AGENT_HINT = "Home is a Kanban of workspaces (one card per checkout; sibling chats on a card are separate agents). Do not create a second workspace for a ticket, PR, or named branch that already has a live checkout \u2014 create_workspace / start_board_card return that checkout (alreadyStarted) and its chats. Add another agent with fork_chat. Creating from the default branch still opens a new isolated workspace. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Approved (approved, not merged) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. blockedReason means an agent on that card is waiting on a person (the question, plan approval, or a reported block) \u2014 read it and do not send_to_chat a check-in. Orchestration chats stay in the sidebar. Do not invent status.";
|
|
2620
2694
|
|
|
2621
2695
|
// src/threads/workspace-tags.ts
|
|
2622
2696
|
function workspaceTagTargetRef(opts) {
|
|
@@ -2892,7 +2966,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2892
2966
|
return readThread(thread.id) ?? thread;
|
|
2893
2967
|
}
|
|
2894
2968
|
async function listLinearIssues(agent, repoPath) {
|
|
2895
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2969
|
+
const { getAdapter: getAdapter2 } = await import("./agents-IVKPCK56.js");
|
|
2896
2970
|
await requireAgent(agent, { requireLinear: true });
|
|
2897
2971
|
const adapter = getAdapter2(agent);
|
|
2898
2972
|
if (!adapter.listLinearIssues) {
|
|
@@ -3668,7 +3742,7 @@ async function adoptThread(input) {
|
|
|
3668
3742
|
messages: input.messages ?? []
|
|
3669
3743
|
});
|
|
3670
3744
|
writeThread(thread);
|
|
3671
|
-
const { addWorkspace: addWorkspace2 } = await import("./workspaces-
|
|
3745
|
+
const { addWorkspace: addWorkspace2 } = await import("./workspaces-ATMIKXLK.js");
|
|
3672
3746
|
await addWorkspace2(repoPath);
|
|
3673
3747
|
const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-RXZPTCNH.js");
|
|
3674
3748
|
await ensureWorktreeSideboardIgnored(input.worktreePath);
|
|
@@ -6597,7 +6671,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6597
6671
|
${prompt}`;
|
|
6598
6672
|
}
|
|
6599
6673
|
async function defaultDeps() {
|
|
6600
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6674
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-ESLNXVOX.js");
|
|
6601
6675
|
const orch = getOrchestrator2();
|
|
6602
6676
|
return {
|
|
6603
6677
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -9472,7 +9546,7 @@ async function startOrchestration(opts) {
|
|
|
9472
9546
|
sourceRef: "default",
|
|
9473
9547
|
...createOpts
|
|
9474
9548
|
}).catch(async () => {
|
|
9475
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
9549
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-RMYXBTJG.js");
|
|
9476
9550
|
const repo = await resolveRepoRoot2(repoPath);
|
|
9477
9551
|
const def = await resolveDefaultBranch2(repo);
|
|
9478
9552
|
return orch.createThread({
|
|
@@ -9502,14 +9576,14 @@ export {
|
|
|
9502
9576
|
worktreeBoardStatus,
|
|
9503
9577
|
visibleAgentBlock,
|
|
9504
9578
|
worktreeAgentBlock,
|
|
9579
|
+
reviewLabelForRepo,
|
|
9580
|
+
classifyWorktreeListBadges,
|
|
9505
9581
|
isHomeBoardThread,
|
|
9506
9582
|
BOARD_COLUMN_DEFS,
|
|
9507
9583
|
HOME_BOARD_CACHE_TTL_MS,
|
|
9508
9584
|
DEFAULT_WORKTREE_SORT,
|
|
9509
9585
|
groupHomeBoardWorktrees,
|
|
9510
9586
|
classifyWorktreeColumn,
|
|
9511
|
-
reviewLabelForRepo,
|
|
9512
|
-
classifyWorktreeListBadges,
|
|
9513
9587
|
dedupeBoardIssues,
|
|
9514
9588
|
issueNeedsWorkspacePick,
|
|
9515
9589
|
isAccountWideIssueSource,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ensureGhPreferOrigin,
|
|
4
4
|
resolveGithubRepoSlug,
|
|
5
5
|
resolveRepoRoot
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-G52HLBQR.js";
|
|
7
7
|
import {
|
|
8
8
|
allocateTeamName,
|
|
9
9
|
createEmptyThread,
|
|
@@ -384,7 +384,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
384
384
|
"Sideboard MCP (fleet control \u2014 prefer these for status and orchestration):",
|
|
385
385
|
"Discover:",
|
|
386
386
|
"- list_projects \u2014 registered repos (path + github slug + project context when set). Use account / project context to pick the right repo for tickets or reviews.",
|
|
387
|
-
"- list_board \u2014 Home Kanban of workspaces (New / Draft / Review / Merged; one card per checkout). Sibling chats on a card are separate agents, not one agent. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
|
|
387
|
+
"- list_board \u2014 Home Kanban of workspaces (New / Draft / Review / Approved / Merged; one card per checkout). Sibling chats on a card are separate agents, not one agent. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 approved \u2192 merged. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
|
|
388
388
|
`- list_branches / list_prs / list_issues \u2014 pass repoPath from list_projects. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_workspace sourceType=pr. That is open non-draft PRs labeled with this project's ready-for-review GitHub label (Settings \u2192 Projects; default eng-review) with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Use Settings \u2192 Agents / Projects context (roles, teams, labels \u2014 freeform text; project adds to account) to prefer the right queues. queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).`,
|
|
389
389
|
"- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
|
|
390
390
|
"- Ticket updates: list_issues / linear_search_issues / github_search_issues with updatedSince (yesterday, 2d, or ISO). One call returns new assignments, ticket edits, and new comments \u2014 do not get_issue every ticket just to check for comments. kind=created vs updated distinguishes new tickets from existing ones.",
|
|
@@ -501,7 +501,7 @@ function coordinatorTurnReminder(opts) {
|
|
|
501
501
|
goal ? `- Goal / title: ${goal}` : null,
|
|
502
502
|
accountDefaultsPlaybookLine(),
|
|
503
503
|
accountContextReminderLine() || null,
|
|
504
|
-
"- Status: list_board (worktree Kanban: New \u2192 Draft \u2192 Review \u2192 Merged) or list_chats. Link chats as `[Title](sideboard://chat/<id>)`. Merge only if the user asked. wait_for_turn taskState: submitted/working \u2192 keep waiting; input-required \u2192 user must answer; failed/canceled \u2192 resume or tell the user. blockedReason is why that agent is waiting \u2014 read it; do not send_to_chat a check-in."
|
|
504
|
+
"- Status: list_board (worktree Kanban: New \u2192 Draft \u2192 Review \u2192 Approved \u2192 Merged) or list_chats. Link chats as `[Title](sideboard://chat/<id>)`. Merge only if the user asked. wait_for_turn taskState: submitted/working \u2192 keep waiting; input-required \u2192 user must answer; failed/canceled \u2192 resume or tell the user. blockedReason is why that agent is waiting \u2014 read it; do not send_to_chat a check-in."
|
|
505
505
|
].filter(Boolean).join("\n");
|
|
506
506
|
}
|
|
507
507
|
function ensureGlobalCoordinatorCwd(opts) {
|