@sideboard-ai/core 0.1.245 → 0.1.247
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{abletime-OI6FNSXX.js → abletime-GAPUN2LL.js} +4 -4
- package/dist/{abletime-CWIJ7INC.js → abletime-HTRIHTL5.js} +4 -4
- package/dist/{abletime-oauth-CHVTUZBR.js → abletime-oauth-G6ZPGVAE.js} +3 -3
- package/dist/{abletime-oauth-PUIPZTA4.js → abletime-oauth-ME7ZY2RS.js} +3 -3
- package/dist/{abletime-rest-32NIVXAY.js → abletime-rest-73EKIAZU.js} +3 -3
- package/dist/{abletime-rest-APJUKFKL.js → abletime-rest-M2D2NELV.js} +3 -3
- package/dist/{agents-FTQZFMDS.js → agents-3PQ2BWGB.js} +5 -5
- package/dist/{agents-BOIIFMNG.js → agents-7SCJTTZN.js} +5 -5
- package/dist/{app-settings-VOPXJMGV.js → app-settings-2BHGANQH.js} +7 -1
- package/dist/{app-settings-652J57CX.js → app-settings-NKXH4PKM.js} +7 -1
- package/dist/{chunk-576S3HJ7.js → chunk-64NUGRZ3.js} +4 -4
- package/dist/{chunk-IMO7AZI4.js → chunk-6HIAYIXT.js} +2 -2
- package/dist/{chunk-WURF67ID.js → chunk-BEQE7VOE.js} +5 -5
- package/dist/{chunk-6I5YQTNK.js → chunk-CXTIOJRX.js} +12 -0
- package/dist/{chunk-QRWVKBGP.js → chunk-D3DYMGZS.js} +18 -5
- package/dist/{chunk-J5IZXFLD.js → chunk-ERQYYL4I.js} +74 -23
- package/dist/{chunk-C64YQAA6.js → chunk-GFGSC4Z7.js} +3 -3
- package/dist/{chunk-43F44EKX.js → chunk-GVAR6R6R.js} +2 -2
- package/dist/{chunk-NT6MCFSB.js → chunk-KFXP4KSP.js} +143 -24
- package/dist/{chunk-G45QP2ZD.js → chunk-LPS6D346.js} +3 -3
- package/dist/{chunk-7HOKP4GR.js → chunk-PELMZRDB.js} +12 -0
- package/dist/{chunk-PPJ5JTWA.js → chunk-QVQPIFBV.js} +28 -2
- package/dist/{chunk-QNJXJIWJ.js → chunk-RF46WMSI.js} +5 -5
- package/dist/{chunk-GFRC6JQN.js → chunk-U2ZZMGPV.js} +4 -4
- package/dist/{chunk-3ZEBUVUI.js → chunk-UVWIYSAA.js} +18 -5
- package/dist/{chunk-E6C5NR46.js → chunk-W4F7JKXF.js} +20 -6
- package/dist/{chunk-YLGBQVRK.js → chunk-XEBQRCDW.js} +28 -2
- package/dist/{chunk-5ZFULOTC.js → chunk-XM4UIFQU.js} +20 -6
- package/dist/{chunk-BL2UGKWU.js → chunk-Z7QWXE4W.js} +3 -3
- package/dist/{coordinator-prompt-ZBYRREHD.js → coordinator-prompt-BFO2TAVR.js} +4 -4
- package/dist/{coordinator-prompt-WQIICPT6.js → coordinator-prompt-IG676OSP.js} +4 -4
- package/dist/{global-workspace-3SQU4GL4.js → global-workspace-J6H7X5SM.js} +4 -4
- package/dist/{global-workspace-2N6KISDO.js → global-workspace-RLCICVQE.js} +4 -4
- package/dist/index.cjs +207 -15
- package/dist/index.d.cts +66 -2
- package/dist/index.d.ts +66 -2
- package/dist/index.js +27 -16
- package/dist/mcp/run-stdio.cjs +131 -15
- package/dist/mcp/run-stdio.js +17 -15
- package/dist/{orchestrator-5ROSTGGH.js → orchestrator-2NZUV4LI.js} +6 -6
- package/dist/{orchestrator-7YCQ7V5S.js → orchestrator-JCETTHVV.js} +6 -6
- package/dist/{thread-store-JQB7KZJR.js → thread-store-BEBZMOS7.js} +1 -1
- package/dist/{thread-store-SCV2IZYS.js → thread-store-S6PJADDM.js} +1 -1
- package/dist/{workspaces-QLKWW3O2.js → workspaces-NJF3GG5F.js} +4 -4
- package/dist/{workspaces-CFI7XVAE.js → workspaces-OLBW42V3.js} +4 -4
- package/dist/{worktree-PK3QETXO.js → worktree-2FYRYJTB.js} +3 -3
- package/dist/{worktree-4UAOZUJ4.js → worktree-UKLK7VHH.js} +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1365,6 +1365,7 @@ __export(app_settings_exports, {
|
|
|
1365
1365
|
HARNESS_ENV_KEYS: () => HARNESS_ENV_KEYS,
|
|
1366
1366
|
ISSUE_SOURCE_LABELS: () => ISSUE_SOURCE_LABELS,
|
|
1367
1367
|
PROFILE_NOTES_MAX: () => PROFILE_NOTES_MAX,
|
|
1368
|
+
REVIEW_LABEL_MAX: () => REVIEW_LABEL_MAX,
|
|
1368
1369
|
USAGE_ON_LIMIT_VALUES: () => USAGE_ON_LIMIT_VALUES,
|
|
1369
1370
|
agentDoneSound: () => agentDoneSound,
|
|
1370
1371
|
appSettingsPath: () => appSettingsPath,
|
|
@@ -1421,6 +1422,7 @@ __export(app_settings_exports, {
|
|
|
1421
1422
|
issueSourceLabel: () => issueSourceLabel,
|
|
1422
1423
|
loadAppSettings: () => loadAppSettings,
|
|
1423
1424
|
maxConcurrentAgents: () => maxConcurrentAgents,
|
|
1425
|
+
normalizeReviewLabel: () => normalizeReviewLabel,
|
|
1424
1426
|
orchestrationQuotaFallbackAgent: () => orchestrationQuotaFallbackAgent,
|
|
1425
1427
|
orchestrationQuotaOnLimit: () => orchestrationQuotaOnLimit,
|
|
1426
1428
|
readViewerContext: () => readViewerContext,
|
|
@@ -1432,6 +1434,7 @@ __export(app_settings_exports, {
|
|
|
1432
1434
|
resolveNewOrchestratorOptions: () => resolveNewOrchestratorOptions,
|
|
1433
1435
|
resolveNewThreadOptions: () => resolveNewThreadOptions,
|
|
1434
1436
|
resolveOrchestratorDefaults: () => resolveOrchestratorDefaults,
|
|
1437
|
+
resolveProjectReviewLabel: () => resolveProjectReviewLabel,
|
|
1435
1438
|
resolveThreadDefaults: () => resolveThreadDefaults,
|
|
1436
1439
|
resolveUsageOnLimit: () => resolveUsageOnLimit,
|
|
1437
1440
|
resolveViewerProfile: () => resolveViewerProfile,
|
|
@@ -1764,13 +1767,25 @@ function normalizeDefaults(raw) {
|
|
|
1764
1767
|
function profileRepoKey(path2) {
|
|
1765
1768
|
return path2.trim().replace(/\/+$/, "");
|
|
1766
1769
|
}
|
|
1770
|
+
function normalizeReviewLabel(value) {
|
|
1771
|
+
const label = (value ?? "").trim().replace(/^:+/, "").slice(0, REVIEW_LABEL_MAX);
|
|
1772
|
+
if (!label || /[,|]/.test(label)) return "";
|
|
1773
|
+
return label;
|
|
1774
|
+
}
|
|
1775
|
+
function projectProfileHasFields(profile) {
|
|
1776
|
+
return Boolean(profile.notes || profile.reviewLabel);
|
|
1777
|
+
}
|
|
1767
1778
|
function normalizeProjectProfile(raw) {
|
|
1768
1779
|
if (!raw || typeof raw !== "object") return void 0;
|
|
1769
1780
|
const source = raw;
|
|
1770
1781
|
const out = {};
|
|
1771
1782
|
const notes = foldLegacyRolesIntoNotes(source.roles, source.role, source.notes);
|
|
1772
1783
|
if (notes) out.notes = notes;
|
|
1773
|
-
|
|
1784
|
+
const reviewLabel = normalizeReviewLabel(
|
|
1785
|
+
typeof source.reviewLabel === "string" ? source.reviewLabel : null
|
|
1786
|
+
);
|
|
1787
|
+
if (reviewLabel) out.reviewLabel = reviewLabel;
|
|
1788
|
+
return projectProfileHasFields(out) ? out : void 0;
|
|
1774
1789
|
}
|
|
1775
1790
|
function normalizeProjects(raw) {
|
|
1776
1791
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
@@ -2443,12 +2458,22 @@ function updateProjectProfileSettings(repoPath, patch) {
|
|
|
2443
2458
|
if (!notes) delete next.notes;
|
|
2444
2459
|
else next.notes = notes;
|
|
2445
2460
|
}
|
|
2461
|
+
if ("reviewLabel" in patch) {
|
|
2462
|
+
const reviewLabel = normalizeReviewLabel(patch.reviewLabel);
|
|
2463
|
+
if (!reviewLabel) delete next.reviewLabel;
|
|
2464
|
+
else next.reviewLabel = reviewLabel;
|
|
2465
|
+
}
|
|
2446
2466
|
delete next.roles;
|
|
2447
2467
|
delete next.role;
|
|
2448
|
-
if (!next
|
|
2468
|
+
if (!projectProfileHasFields(next)) delete projects[key];
|
|
2449
2469
|
else projects[key] = next;
|
|
2450
2470
|
return saveAppSettings({ ...current, projects });
|
|
2451
2471
|
}
|
|
2472
|
+
function resolveProjectReviewLabel(settings, repoPath) {
|
|
2473
|
+
const key = findProjectProfileKey(settings.projects, repoPath);
|
|
2474
|
+
if (!key) return "";
|
|
2475
|
+
return settings.projects[key]?.reviewLabel?.trim() || "";
|
|
2476
|
+
}
|
|
2452
2477
|
function getDefaultAgent(settings = loadAppSettings()) {
|
|
2453
2478
|
return settings.defaults.agent ?? "claude";
|
|
2454
2479
|
}
|
|
@@ -2973,7 +2998,7 @@ function childEnvWithAppSettings(extra) {
|
|
|
2973
2998
|
function harnessEnvKey(harness) {
|
|
2974
2999
|
return HARNESS_ENV_KEYS[harness];
|
|
2975
3000
|
}
|
|
2976
|
-
var import_node_crypto2, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, AGENT_DONE_SOUNDS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
|
|
3001
|
+
var import_node_crypto2, import_node_fs8, import_node_os3, import_node_path9, HARNESS_ENV_KEYS, DEFAULT_AGENTS, GITHUB_GIT_AUTH_MODES, FOLLOW_UP_BEHAVIORS, AGENT_DONE_SOUNDS, CLOUD_CONNECT_AGENTS, ISSUE_SOURCES, GIT_AUTH_MODES, REVIEW_LABEL_MAX, EMPTY_SETTINGS, CONFIRM_ACCOUNT, CONFIRM_PROJECT, DEFAULT_CLI_BIN;
|
|
2977
3002
|
var init_app_settings = __esm({
|
|
2978
3003
|
"src/store/app-settings.ts"() {
|
|
2979
3004
|
"use strict";
|
|
@@ -3030,6 +3055,7 @@ var init_app_settings = __esm({
|
|
|
3030
3055
|
]);
|
|
3031
3056
|
ISSUE_SOURCES = /* @__PURE__ */ new Set(["linear", "github", "abletime"]);
|
|
3032
3057
|
GIT_AUTH_MODES = new Set(GITHUB_GIT_AUTH_MODES);
|
|
3058
|
+
REVIEW_LABEL_MAX = 50;
|
|
3033
3059
|
EMPTY_SETTINGS = {
|
|
3034
3060
|
environment: {},
|
|
3035
3061
|
claude: {},
|
|
@@ -3315,6 +3341,12 @@ function normalizeThread(raw) {
|
|
|
3315
3341
|
prTitle: raw.prTitle ?? null,
|
|
3316
3342
|
prState: raw.prState ?? null,
|
|
3317
3343
|
prIsDraft: Boolean(raw.prIsDraft),
|
|
3344
|
+
prReviewDecision: raw.prReviewDecision ?? null,
|
|
3345
|
+
prMergeable: raw.prMergeable ?? null,
|
|
3346
|
+
prMergeStateStatus: raw.prMergeStateStatus ?? null,
|
|
3347
|
+
prIsInMergeQueue: Boolean(raw.prIsInMergeQueue),
|
|
3348
|
+
prLabels: Array.isArray(raw.prLabels) ? raw.prLabels : [],
|
|
3349
|
+
prChecksFailed: typeof raw.prChecksFailed === "boolean" ? raw.prChecksFailed : void 0,
|
|
3318
3350
|
skipAutoArchiveOnMerge: Boolean(raw.skipAutoArchiveOnMerge),
|
|
3319
3351
|
cowboy: Boolean(raw.cowboy),
|
|
3320
3352
|
stackId: raw.stackId ?? null,
|
|
@@ -3350,6 +3382,12 @@ function createEmptyThread(partial) {
|
|
|
3350
3382
|
prIsDraft: Boolean(partial.prIsDraft),
|
|
3351
3383
|
prAuthorLogin: partial.prAuthorLogin?.trim() || null,
|
|
3352
3384
|
prReviewerLogins: partial.prReviewerLogins ?? [],
|
|
3385
|
+
prReviewDecision: partial.prReviewDecision ?? null,
|
|
3386
|
+
prMergeable: partial.prMergeable ?? null,
|
|
3387
|
+
prMergeStateStatus: partial.prMergeStateStatus ?? null,
|
|
3388
|
+
prIsInMergeQueue: Boolean(partial.prIsInMergeQueue),
|
|
3389
|
+
prLabels: partial.prLabels ?? [],
|
|
3390
|
+
prChecksFailed: partial.prChecksFailed,
|
|
3353
3391
|
skipAutoArchiveOnMerge: partial.skipAutoArchiveOnMerge ?? false,
|
|
3354
3392
|
cowboy: Boolean(partial.cowboy),
|
|
3355
3393
|
stackId: partial.stackId ?? null,
|
|
@@ -4449,6 +4487,14 @@ function lastRunningSkillIndex(parts, parentId) {
|
|
|
4449
4487
|
}
|
|
4450
4488
|
return -1;
|
|
4451
4489
|
}
|
|
4490
|
+
function markRunningSkillsDone(parts, parentId) {
|
|
4491
|
+
return parts.map((p) => {
|
|
4492
|
+
if (p.type === "tool" && isSkillToolName(p.name) && p.status === "running" && sameParentId(p.parentId, parentId)) {
|
|
4493
|
+
return withPartTimes({ ...p, status: "done" }, p);
|
|
4494
|
+
}
|
|
4495
|
+
return p;
|
|
4496
|
+
});
|
|
4497
|
+
}
|
|
4452
4498
|
function promoteOrFoldSkillText(parts, textIdx) {
|
|
4453
4499
|
const acc = parts[textIdx];
|
|
4454
4500
|
if (acc?.type !== "text") return parts;
|
|
@@ -4583,7 +4629,10 @@ function applyAgentEvent(parts, event) {
|
|
|
4583
4629
|
{
|
|
4584
4630
|
...prev,
|
|
4585
4631
|
result: clipToolResultForStore(result),
|
|
4586
|
-
|
|
4632
|
+
// Stay running after the YAML `name:` fence so later content_block_delta
|
|
4633
|
+
// tokens of SKILL.md stay on this row. thinking / tool_use / finalizeParts
|
|
4634
|
+
// mark the row done so the real reply can be chat.
|
|
4635
|
+
status: "running"
|
|
4587
4636
|
},
|
|
4588
4637
|
prev
|
|
4589
4638
|
);
|
|
@@ -4625,6 +4674,7 @@ function applyAgentEvent(parts, event) {
|
|
|
4625
4674
|
if (event.type === "thinking") {
|
|
4626
4675
|
const data = event.data;
|
|
4627
4676
|
if (!data) return parts;
|
|
4677
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
4628
4678
|
const next = [...parts];
|
|
4629
4679
|
if (event.replace) {
|
|
4630
4680
|
for (let i = next.length - 1; i >= 0; i--) {
|
|
@@ -4672,6 +4722,7 @@ function applyAgentEvent(parts, event) {
|
|
|
4672
4722
|
return withCompactFinish(next, data, event.parentId);
|
|
4673
4723
|
}
|
|
4674
4724
|
if (event.type === "tool_use") {
|
|
4725
|
+
parts = markRunningSkillsDone(parts, event.parentId);
|
|
4675
4726
|
const input = asRecord(event.input);
|
|
4676
4727
|
const diff = diffFromInput(input);
|
|
4677
4728
|
const existing = parts.findIndex((p) => p.type === "tool" && p.id === event.id);
|
|
@@ -5810,6 +5861,72 @@ function classifyWorktreeColumn(group) {
|
|
|
5810
5861
|
}
|
|
5811
5862
|
return "new";
|
|
5812
5863
|
}
|
|
5864
|
+
function labelsInclude(labels, name) {
|
|
5865
|
+
const want = name.trim().toLowerCase();
|
|
5866
|
+
if (!want) return false;
|
|
5867
|
+
return (labels ?? []).some((label) => label.trim().toLowerCase() === want);
|
|
5868
|
+
}
|
|
5869
|
+
function reviewLabelForRepo(labelsByRepo, repoPath) {
|
|
5870
|
+
const want = repoPath.trim().replace(/\/+$/, "");
|
|
5871
|
+
if (!want || !labelsByRepo) return "";
|
|
5872
|
+
const direct = labelsByRepo[want]?.trim();
|
|
5873
|
+
if (direct) return direct;
|
|
5874
|
+
let best = "";
|
|
5875
|
+
let bestLen = 0;
|
|
5876
|
+
for (const [key, label] of Object.entries(labelsByRepo)) {
|
|
5877
|
+
const stored = key.trim().replace(/\/+$/, "");
|
|
5878
|
+
const value = label.trim();
|
|
5879
|
+
if (!stored || !value) continue;
|
|
5880
|
+
if (stored === want || want.startsWith(`${stored}/`)) {
|
|
5881
|
+
if (stored.length > bestLen) {
|
|
5882
|
+
best = value;
|
|
5883
|
+
bestLen = stored.length;
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
return best;
|
|
5888
|
+
}
|
|
5889
|
+
function groupPrLabels(group) {
|
|
5890
|
+
const out = [];
|
|
5891
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5892
|
+
for (const thread of group) {
|
|
5893
|
+
for (const label of thread.prLabels ?? []) {
|
|
5894
|
+
const key = label.trim().toLowerCase();
|
|
5895
|
+
if (!key || seen.has(key)) continue;
|
|
5896
|
+
seen.add(key);
|
|
5897
|
+
out.push(label.trim());
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
return out;
|
|
5901
|
+
}
|
|
5902
|
+
function classifyWorktreeListBadges(group, viewerLogin = "", reviewLabel = "") {
|
|
5903
|
+
if (group.length === 0 || group.some((t) => t.cowboy)) return [];
|
|
5904
|
+
const open = group.filter((t) => isOpenPrState(t.prUrl, t.prState));
|
|
5905
|
+
if (open.length === 0) return [];
|
|
5906
|
+
const ownership = classifyWorktreeOwnership(group, viewerLogin);
|
|
5907
|
+
if (ownership === "reviewing") {
|
|
5908
|
+
return [
|
|
5909
|
+
{
|
|
5910
|
+
id: "review",
|
|
5911
|
+
label: "review",
|
|
5912
|
+
title: "Someone else's PR",
|
|
5913
|
+
mod: "is-review"
|
|
5914
|
+
}
|
|
5915
|
+
];
|
|
5916
|
+
}
|
|
5917
|
+
const draft = open.some((t) => t.prIsDraft);
|
|
5918
|
+
const readyLabel = reviewLabel.trim();
|
|
5919
|
+
const inReview = readyLabel ? labelsInclude(groupPrLabels(group), readyLabel) : !draft;
|
|
5920
|
+
if (!inReview) return [];
|
|
5921
|
+
return [
|
|
5922
|
+
{
|
|
5923
|
+
id: "pending",
|
|
5924
|
+
label: "pending",
|
|
5925
|
+
title: "Waiting for review",
|
|
5926
|
+
mod: "is-pending"
|
|
5927
|
+
}
|
|
5928
|
+
];
|
|
5929
|
+
}
|
|
5813
5930
|
function worktreeBoardStatus(group) {
|
|
5814
5931
|
const order = ["running", "queued", "error", "broken"];
|
|
5815
5932
|
for (const status of order) {
|
|
@@ -7983,6 +8100,10 @@ function normalizePrListQueue(queue, state) {
|
|
|
7983
8100
|
}
|
|
7984
8101
|
return void 0;
|
|
7985
8102
|
}
|
|
8103
|
+
function reviewQueueLabel(reviewLabel) {
|
|
8104
|
+
const label = (reviewLabel ?? "").trim();
|
|
8105
|
+
return label || QUEUE_DEFAULTS.review.labels[0];
|
|
8106
|
+
}
|
|
7986
8107
|
function ticketRefsFromPrTitle(title) {
|
|
7987
8108
|
const out = [];
|
|
7988
8109
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -8000,10 +8121,12 @@ function resolveListPrsOptions(opts) {
|
|
|
8000
8121
|
const defaults = queue ? QUEUE_DEFAULTS[queue] : void 0;
|
|
8001
8122
|
const stateIsQueueAlias = Boolean(normalizePrListQueue(void 0, opts?.state));
|
|
8002
8123
|
const labels = normalizePrLabels(opts?.labels);
|
|
8124
|
+
const readyLabel = reviewQueueLabel(opts?.reviewLabel);
|
|
8125
|
+
const queueLabels = queue === "review" || queue === "mine" ? [readyLabel] : defaults?.labels ?? [];
|
|
8003
8126
|
return {
|
|
8004
8127
|
...queue ? { queue } : {},
|
|
8005
8128
|
state: normalizePrListState(stateIsQueueAlias ? defaults?.state : opts?.state ?? defaults?.state),
|
|
8006
|
-
labels: labels.length ? labels :
|
|
8129
|
+
labels: labels.length ? labels : queueLabels,
|
|
8007
8130
|
...opts?.reviewer?.trim() ? { reviewer: opts.reviewer.trim() } : defaults?.reviewer ? { reviewer: defaults.reviewer } : {},
|
|
8008
8131
|
...opts?.query?.trim() ? { query: opts.query.trim() } : {},
|
|
8009
8132
|
...opts?.draft !== void 0 ? { draft: opts.draft } : defaults?.draft !== void 0 ? { draft: defaults.draft } : {},
|
|
@@ -8364,6 +8487,12 @@ function prIsInMergeQueue(gate) {
|
|
|
8364
8487
|
if (gate.isInMergeQueue) return true;
|
|
8365
8488
|
return (gate.mergeStateStatus ?? "").toUpperCase() === "QUEUED";
|
|
8366
8489
|
}
|
|
8490
|
+
function ciChecksFailed(checks) {
|
|
8491
|
+
if (!checks?.length) return false;
|
|
8492
|
+
return checks.some(
|
|
8493
|
+
(check) => (!check.kind || check.kind === "ci") && check.bucket === "fail"
|
|
8494
|
+
);
|
|
8495
|
+
}
|
|
8367
8496
|
function buildMergeGateChecks(gate, opts = {}) {
|
|
8368
8497
|
const rows = [];
|
|
8369
8498
|
const base = gate.baseRefName?.trim() || "the base branch";
|
|
@@ -9271,7 +9400,7 @@ async function getPrMeta(cwd, selector) {
|
|
|
9271
9400
|
"view",
|
|
9272
9401
|
selector,
|
|
9273
9402
|
"--json",
|
|
9274
|
-
"number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable,author,reviewRequests"
|
|
9403
|
+
"number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,isInMergeQueue,mergeStateStatus,mergeable,author,reviewRequests,labels"
|
|
9275
9404
|
];
|
|
9276
9405
|
if (slug) viewArgs.push("--repo", slug);
|
|
9277
9406
|
let { stdout, exitCode, stderr } = await gh(viewArgs, cwd, { reject: false });
|
|
@@ -9281,7 +9410,7 @@ async function getPrMeta(cwd, selector) {
|
|
|
9281
9410
|
"view",
|
|
9282
9411
|
selector,
|
|
9283
9412
|
"--json",
|
|
9284
|
-
"number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable,author,reviewRequests"
|
|
9413
|
+
"number,title,url,state,isDraft,reviewDecision,baseRefName,headRefName,mergeStateStatus,mergeable,author,reviewRequests,labels"
|
|
9285
9414
|
];
|
|
9286
9415
|
if (slug) retry.push("--repo", slug);
|
|
9287
9416
|
({ stdout, exitCode, stderr } = await gh(retry, cwd, { reject: false }));
|
|
@@ -9316,7 +9445,8 @@ async function getPrMeta(cwd, selector) {
|
|
|
9316
9445
|
mergeable: resolved.mergeable,
|
|
9317
9446
|
mergeStateStatus: resolved.mergeStateStatus,
|
|
9318
9447
|
authorLogin: author.login?.trim() || null,
|
|
9319
|
-
reviewerLogins: humanReviewerLogins(view.reviewRequests)
|
|
9448
|
+
reviewerLogins: humanReviewerLogins(view.reviewRequests),
|
|
9449
|
+
labels: labelNames(view.labels)
|
|
9320
9450
|
};
|
|
9321
9451
|
} catch {
|
|
9322
9452
|
return null;
|
|
@@ -10549,7 +10679,7 @@ var init_coordinator_prompt = __esm({
|
|
|
10549
10679
|
"Discover:",
|
|
10550
10680
|
"- list_workspaces \u2014 registered repos (path + github slug + project context when set). Use account / project context to pick the right repo for tickets or reviews.",
|
|
10551
10681
|
"- list_board \u2014 Home Kanban of worktrees (New / Draft / Review / Merged; one card per checkout). Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
|
|
10552
|
-
|
|
10682
|
+
`- list_branches / list_prs / list_issues \u2014 pass repoPath from list_workspaces. 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_thread 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).`,
|
|
10553
10683
|
"- 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_thread 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.",
|
|
10554
10684
|
"- 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.",
|
|
10555
10685
|
"- linear_* (when Linear is connected) \u2014 list_teams for team key/states; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
|
|
@@ -16621,11 +16751,41 @@ function threadPrMetaPatch(thread, meta) {
|
|
|
16621
16751
|
if (!sameLoginList(nextReviewers, thread.prReviewerLogins)) {
|
|
16622
16752
|
patch.prReviewerLogins = nextReviewers;
|
|
16623
16753
|
}
|
|
16754
|
+
const nextDecision = meta.reviewDecision ?? null;
|
|
16755
|
+
if ((thread.prReviewDecision ?? null) !== nextDecision) {
|
|
16756
|
+
patch.prReviewDecision = nextDecision;
|
|
16757
|
+
}
|
|
16758
|
+
const nextMergeable = meta.mergeable ?? null;
|
|
16759
|
+
if ((thread.prMergeable ?? null) !== nextMergeable) {
|
|
16760
|
+
patch.prMergeable = nextMergeable;
|
|
16761
|
+
}
|
|
16762
|
+
const nextMergeState = meta.mergeStateStatus ?? null;
|
|
16763
|
+
if ((thread.prMergeStateStatus ?? null) !== nextMergeState) {
|
|
16764
|
+
patch.prMergeStateStatus = nextMergeState;
|
|
16765
|
+
}
|
|
16766
|
+
const nextQueued = Boolean(meta.isInMergeQueue);
|
|
16767
|
+
if (Boolean(thread.prIsInMergeQueue) !== nextQueued) {
|
|
16768
|
+
patch.prIsInMergeQueue = nextQueued;
|
|
16769
|
+
}
|
|
16770
|
+
const nextLabels = meta.labels ?? [];
|
|
16771
|
+
if (!sameLoginList(nextLabels, thread.prLabels)) {
|
|
16772
|
+
patch.prLabels = nextLabels;
|
|
16773
|
+
}
|
|
16774
|
+
const mergeState = (nextMergeState ?? "").toUpperCase();
|
|
16775
|
+
if (mergeState === "CLEAN" && thread.prChecksFailed) {
|
|
16776
|
+
patch.prChecksFailed = false;
|
|
16777
|
+
} else if ((mergeState === "UNSTABLE" || mergeState === "BLOCKED" && (nextDecision ?? "").toUpperCase() === "APPROVED") && !thread.prChecksFailed) {
|
|
16778
|
+
patch.prChecksFailed = true;
|
|
16779
|
+
}
|
|
16624
16780
|
if (thread.skipAutoArchiveOnMerge && nextState && nextState !== "MERGED" && nextState !== "CLOSED") {
|
|
16625
16781
|
patch.skipAutoArchiveOnMerge = false;
|
|
16626
16782
|
}
|
|
16627
16783
|
return patch;
|
|
16628
16784
|
}
|
|
16785
|
+
function threadPrChecksFailedPatch(thread, failed) {
|
|
16786
|
+
if (thread.prChecksFailed === failed) return {};
|
|
16787
|
+
return { prChecksFailed: failed };
|
|
16788
|
+
}
|
|
16629
16789
|
function shouldAutoArchiveOnPrMerge(opts) {
|
|
16630
16790
|
if (!opts.autoArchiveEnabled) return false;
|
|
16631
16791
|
if (opts.isGlobal) return false;
|
|
@@ -17229,6 +17389,12 @@ function worktreeBindingFrom(from) {
|
|
|
17229
17389
|
prIsDraft: from.prIsDraft,
|
|
17230
17390
|
prAuthorLogin: from.prAuthorLogin,
|
|
17231
17391
|
prReviewerLogins: from.prReviewerLogins,
|
|
17392
|
+
prReviewDecision: from.prReviewDecision,
|
|
17393
|
+
prMergeable: from.prMergeable,
|
|
17394
|
+
prMergeStateStatus: from.prMergeStateStatus,
|
|
17395
|
+
prIsInMergeQueue: from.prIsInMergeQueue,
|
|
17396
|
+
prLabels: from.prLabels,
|
|
17397
|
+
prChecksFailed: from.prChecksFailed,
|
|
17232
17398
|
skipAutoArchiveOnMerge: from.skipAutoArchiveOnMerge,
|
|
17233
17399
|
stackId: from.stackId,
|
|
17234
17400
|
stackLayer: from.stackLayer,
|
|
@@ -20712,6 +20878,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
20712
20878
|
let prUrl = null;
|
|
20713
20879
|
let prTitle = null;
|
|
20714
20880
|
let prAuthorLogin2 = null;
|
|
20881
|
+
let prLabels = [];
|
|
20715
20882
|
if (sourceType === "pr") {
|
|
20716
20883
|
const num2 = Number(input.sourceRef.replace(/^#/, ""));
|
|
20717
20884
|
if (!Number.isFinite(num2)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
|
|
@@ -20728,6 +20895,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
20728
20895
|
sourceIsFork = pr.isCrossRepository;
|
|
20729
20896
|
prUrl = pr.url;
|
|
20730
20897
|
prAuthorLogin2 = pr.author?.login?.trim() || null;
|
|
20898
|
+
prLabels = pr.labels ?? [];
|
|
20731
20899
|
const localFetchBranch = `sideboard-pr-${pr.number}`;
|
|
20732
20900
|
await fetchPrHead(repoPath, pr.number, localFetchBranch);
|
|
20733
20901
|
sourceRef = localFetchBranch;
|
|
@@ -20751,6 +20919,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
20751
20919
|
prUrl = existing.url;
|
|
20752
20920
|
prTitle = existing.title;
|
|
20753
20921
|
prAuthorLogin2 = existing.author?.login?.trim() || null;
|
|
20922
|
+
prLabels = existing.labels ?? [];
|
|
20754
20923
|
}
|
|
20755
20924
|
}
|
|
20756
20925
|
}
|
|
@@ -20786,7 +20955,8 @@ async function createThread(input, _onSetupLine) {
|
|
|
20786
20955
|
status: "idle",
|
|
20787
20956
|
prUrl,
|
|
20788
20957
|
prTitle,
|
|
20789
|
-
prAuthorLogin: prAuthorLogin2
|
|
20958
|
+
prAuthorLogin: prAuthorLogin2,
|
|
20959
|
+
prLabels
|
|
20790
20960
|
});
|
|
20791
20961
|
writeThread(thread);
|
|
20792
20962
|
await ensureWorkspace(repoPath);
|
|
@@ -24242,6 +24412,7 @@ var init_orchestrator = __esm({
|
|
|
24242
24412
|
init_stack();
|
|
24243
24413
|
init_agent_git_actions();
|
|
24244
24414
|
init_pr_merge_archive();
|
|
24415
|
+
init_pr_gates();
|
|
24245
24416
|
init_conductor();
|
|
24246
24417
|
init_dev_preview();
|
|
24247
24418
|
init_setup_log();
|
|
@@ -26438,10 +26609,20 @@ var init_orchestrator = __esm({
|
|
|
26438
26609
|
return { thread, selectors: connectedPrSelectors(thread, headUrl), cwd, headUrl };
|
|
26439
26610
|
}
|
|
26440
26611
|
async getPrChecks(threadRef) {
|
|
26441
|
-
const { selectors, cwd } = await this.withPrSelector(threadRef);
|
|
26612
|
+
const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
|
|
26442
26613
|
for (const selector of selectors) {
|
|
26443
26614
|
const checks = await getPrChecks(cwd, selector);
|
|
26444
|
-
if (checks)
|
|
26615
|
+
if (!checks) continue;
|
|
26616
|
+
const live = this.requireThread(thread.id);
|
|
26617
|
+
const failed = ciChecksFailed(checks);
|
|
26618
|
+
const siblings = threadsSharingWorktree(live.worktreePath);
|
|
26619
|
+
const targets = siblings.length > 0 ? siblings : [live];
|
|
26620
|
+
for (const t of targets) {
|
|
26621
|
+
const patch = threadPrChecksFailedPatch(t, failed);
|
|
26622
|
+
if (Object.keys(patch).length === 0) continue;
|
|
26623
|
+
updateThread(t.id, patch);
|
|
26624
|
+
}
|
|
26625
|
+
return checks;
|
|
26445
26626
|
}
|
|
26446
26627
|
return null;
|
|
26447
26628
|
}
|
|
@@ -27114,6 +27295,7 @@ __export(index_exports, {
|
|
|
27114
27295
|
PR_DETAILS_JSON_FIELDS: () => PR_DETAILS_JSON_FIELDS,
|
|
27115
27296
|
REPO_REVIEW_NAME: () => REPO_REVIEW_NAME,
|
|
27116
27297
|
REPO_REVIEW_PATH: () => REPO_REVIEW_PATH,
|
|
27298
|
+
REVIEW_LABEL_MAX: () => REVIEW_LABEL_MAX,
|
|
27117
27299
|
REVIEW_REQUEST_NAME: () => REVIEW_REQUEST_NAME,
|
|
27118
27300
|
REVIEW_REQUEST_PATH: () => REVIEW_REQUEST_PATH,
|
|
27119
27301
|
REVIEW_REQUEST_PREFILL: () => REVIEW_REQUEST_PREFILL,
|
|
@@ -27245,6 +27427,7 @@ __export(index_exports, {
|
|
|
27245
27427
|
clampHistoryMaxDays: () => clampHistoryMaxDays,
|
|
27246
27428
|
classifyRunScriptPreview: () => classifyRunScriptPreview,
|
|
27247
27429
|
classifyWorktreeColumn: () => classifyWorktreeColumn,
|
|
27430
|
+
classifyWorktreeListBadges: () => classifyWorktreeListBadges,
|
|
27248
27431
|
claudeAdapter: () => claudeAdapter,
|
|
27249
27432
|
claudeChromeEnabled: () => claudeChromeEnabled,
|
|
27250
27433
|
claudeUsageOverLimitWindows: () => claudeUsageOverLimitWindows,
|
|
@@ -27685,6 +27868,7 @@ __export(index_exports, {
|
|
|
27685
27868
|
normalizeCodeSelection: () => normalizeCodeSelection,
|
|
27686
27869
|
normalizeLinearRelationType: () => normalizeLinearRelationType,
|
|
27687
27870
|
normalizeParseResult: () => normalizeParseResult,
|
|
27871
|
+
normalizeReviewLabel: () => normalizeReviewLabel,
|
|
27688
27872
|
normalizeServiceOrigin: () => normalizeServiceOrigin,
|
|
27689
27873
|
normalizeThinkingEffort: () => normalizeThinkingEffort,
|
|
27690
27874
|
normalizeThread: () => normalizeThread,
|
|
@@ -27812,6 +27996,7 @@ __export(index_exports, {
|
|
|
27812
27996
|
resolvePlanMarkdown: () => resolvePlanMarkdown,
|
|
27813
27997
|
resolvePrSelector: () => resolvePrSelector,
|
|
27814
27998
|
resolvePrSelectors: () => resolvePrSelectors,
|
|
27999
|
+
resolveProjectReviewLabel: () => resolveProjectReviewLabel,
|
|
27815
28000
|
resolveQuotaFallbackAgent: () => resolveQuotaFallbackAgent,
|
|
27816
28001
|
resolveRepoRoot: () => resolveRepoRoot,
|
|
27817
28002
|
resolveReviewGuidelines: () => resolveReviewGuidelines,
|
|
@@ -27826,6 +28011,7 @@ __export(index_exports, {
|
|
|
27826
28011
|
resolveViewerProfile: () => resolveViewerProfile,
|
|
27827
28012
|
resolveViewerProfileForRepo: () => resolveViewerProfileForRepo,
|
|
27828
28013
|
resolveWorktreeStartPoint: () => resolveWorktreeStartPoint,
|
|
28014
|
+
reviewLabelForRepo: () => reviewLabelForRepo,
|
|
27829
28015
|
rewriteAbleTimeError: () => rewriteAbleTimeError,
|
|
27830
28016
|
rewriteLinearError: () => rewriteLinearError,
|
|
27831
28017
|
run: () => run,
|
|
@@ -34385,12 +34571,12 @@ async function startMcpServer() {
|
|
|
34385
34571
|
);
|
|
34386
34572
|
server.tool(
|
|
34387
34573
|
"list_prs",
|
|
34388
|
-
|
|
34574
|
+
`List GitHub PRs for a registered workspace (the review surface for assigned ticket work \u2014 not the tickets). Pass repoPath from list_workspaces. "Get me N tickets to review" \u2192 queue=review and limit=N: 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. Prefer teams that match Settings \u2192 Agents / Projects roles for this repo. A team like engineering-team is not a claim (you are on that team). Also: state (open|closed|merged|all|review), label, reviewer (me|unassigned|login), query, limit (default 40, max 250). Then create_thread with sourceType=pr.`,
|
|
34389
34575
|
{
|
|
34390
34576
|
repoPath: import_zod9.z.string(),
|
|
34391
34577
|
query: import_zod9.z.string().optional().describe("GitHub search tokens (title, draft:true, \u2026)"),
|
|
34392
34578
|
queue: import_zod9.z.enum(["review", "mine", "approved", "changes"]).optional().describe(
|
|
34393
|
-
|
|
34579
|
+
"review = unclaimed ready-for-review inbox (Settings \u2192 Projects label, default eng-review). mine = review-requested:@me. approved / changes = eng-approved / eng-requested-changes."
|
|
34394
34580
|
),
|
|
34395
34581
|
state: import_zod9.z.enum(["open", "closed", "merged", "all", "review"]).optional().describe("GitHub PR state (default open). review is an alias for queue=review."),
|
|
34396
34582
|
label: import_zod9.z.string().optional().describe(
|
|
@@ -34410,7 +34596,8 @@ async function startMcpServer() {
|
|
|
34410
34596
|
state,
|
|
34411
34597
|
labels: label,
|
|
34412
34598
|
reviewer,
|
|
34413
|
-
limit: page + 1
|
|
34599
|
+
limit: page + 1,
|
|
34600
|
+
reviewLabel: resolveProjectReviewLabel(loadAppSettings(), root)
|
|
34414
34601
|
});
|
|
34415
34602
|
const prs = await listPrs(root, resolved);
|
|
34416
34603
|
const windowed = applyIssueListWindow(prs, page);
|
|
@@ -36944,6 +37131,7 @@ async function startSlackRelayServer(opts) {
|
|
|
36944
37131
|
PR_DETAILS_JSON_FIELDS,
|
|
36945
37132
|
REPO_REVIEW_NAME,
|
|
36946
37133
|
REPO_REVIEW_PATH,
|
|
37134
|
+
REVIEW_LABEL_MAX,
|
|
36947
37135
|
REVIEW_REQUEST_NAME,
|
|
36948
37136
|
REVIEW_REQUEST_PATH,
|
|
36949
37137
|
REVIEW_REQUEST_PREFILL,
|
|
@@ -37075,6 +37263,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37075
37263
|
clampHistoryMaxDays,
|
|
37076
37264
|
classifyRunScriptPreview,
|
|
37077
37265
|
classifyWorktreeColumn,
|
|
37266
|
+
classifyWorktreeListBadges,
|
|
37078
37267
|
claudeAdapter,
|
|
37079
37268
|
claudeChromeEnabled,
|
|
37080
37269
|
claudeUsageOverLimitWindows,
|
|
@@ -37515,6 +37704,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37515
37704
|
normalizeCodeSelection,
|
|
37516
37705
|
normalizeLinearRelationType,
|
|
37517
37706
|
normalizeParseResult,
|
|
37707
|
+
normalizeReviewLabel,
|
|
37518
37708
|
normalizeServiceOrigin,
|
|
37519
37709
|
normalizeThinkingEffort,
|
|
37520
37710
|
normalizeThread,
|
|
@@ -37642,6 +37832,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37642
37832
|
resolvePlanMarkdown,
|
|
37643
37833
|
resolvePrSelector,
|
|
37644
37834
|
resolvePrSelectors,
|
|
37835
|
+
resolveProjectReviewLabel,
|
|
37645
37836
|
resolveQuotaFallbackAgent,
|
|
37646
37837
|
resolveRepoRoot,
|
|
37647
37838
|
resolveReviewGuidelines,
|
|
@@ -37656,6 +37847,7 @@ async function startSlackRelayServer(opts) {
|
|
|
37656
37847
|
resolveViewerProfile,
|
|
37657
37848
|
resolveViewerProfileForRepo,
|
|
37658
37849
|
resolveWorktreeStartPoint,
|
|
37850
|
+
reviewLabelForRepo,
|
|
37659
37851
|
rewriteAbleTimeError,
|
|
37660
37852
|
rewriteLinearError,
|
|
37661
37853
|
run,
|