@sideboard-ai/core 0.1.151 → 0.1.153
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-223A3LY6.js → abletime-H7LPGIP2.js} +3 -3
- package/dist/{abletime-CLC5UJC2.js → abletime-JSTJLXAW.js} +3 -3
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-JAOMXDXN.js → agents-V24DYZI4.js} +8 -9
- package/dist/{agents-U2JCFXW4.js → agents-YVW75KBO.js} +8 -9
- package/dist/{app-settings-3CHCNIMD.js → app-settings-H3INSR67.js} +38 -4
- package/dist/{app-settings-J3JBCUOT.js → app-settings-VRQI3FIE.js} +38 -4
- package/dist/{caffeinate-hold-NBRUWYXO.js → caffeinate-hold-DBKMRZZO.js} +2 -2
- package/dist/{caffeinate-hold-X3JNPR42.js → caffeinate-hold-SK2QISPE.js} +2 -2
- package/dist/chunk-2F63IMCL.js +959 -0
- package/dist/{chunk-GCWAAPJ5.js → chunk-2NRNP7QP.js} +432 -239
- package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
- package/dist/{chunk-LZAOX76N.js → chunk-4THE3EY7.js} +6 -6
- package/dist/{chunk-TUGKX5BD.js → chunk-7UURXPKD.js} +1 -1
- package/dist/{chunk-DCOZABNT.js → chunk-AO35MGOE.js} +1 -1
- package/dist/{chunk-3JBMACYX.js → chunk-CJQLPPEJ.js} +387 -15
- package/dist/{chunk-CZD4NRDZ.js → chunk-D7EGJ3EI.js} +244 -1
- package/dist/{chunk-QZQEXME2.js → chunk-EFVFB2AH.js} +1 -1
- package/dist/{chunk-B7XK37WZ.js → chunk-FDCFXMDG.js} +1 -1
- package/dist/{chunk-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
- package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
- package/dist/{chunk-6H4TJ5TA.js → chunk-KMNODRWF.js} +481 -212
- package/dist/{chunk-GE7M3QTE.js → chunk-LQMFCS54.js} +387 -15
- package/dist/{chunk-G7SIQFBQ.js → chunk-LZ6QMEQC.js} +1 -1
- package/dist/{chunk-EUXOHTUK.js → chunk-LZQULFIT.js} +1 -1
- package/dist/{chunk-KLBOWJ74.js → chunk-OCQPTUR7.js} +1 -1
- package/dist/{chunk-UIS7BVCX.js → chunk-QZEZXYVV.js} +13 -13
- package/dist/chunk-RNC3GR6L.js +905 -0
- package/dist/{chunk-VHX673DI.js → chunk-WLPXZFRE.js} +1 -1
- package/dist/{chunk-7F4XE6UG.js → chunk-XD2BAANL.js} +5 -5
- package/dist/{connected-teams-XO766HB4.js → connected-teams-DBWAMP7G.js} +2 -2
- package/dist/{connected-teams-I2WZZZFA.js → connected-teams-WGONUQOF.js} +2 -2
- package/dist/{coordinator-prompt-LWYUZAXR.js → coordinator-prompt-7FHKCWXB.js} +5 -5
- package/dist/{coordinator-prompt-ZK5MII7W.js → coordinator-prompt-KX2FVVYT.js} +5 -5
- package/dist/{cursor-recover-NOQYOFRF.js → cursor-recover-L5MD6MBO.js} +1 -1
- package/dist/{cursor-recover-QSLWEZNA.js → cursor-recover-NDMLLNYX.js} +2 -2
- package/dist/{global-workspace-IB2CCEJF.js → global-workspace-2BRRKSDN.js} +5 -6
- package/dist/{global-workspace-T7RL3XEC.js → global-workspace-4LHCZ2DC.js} +5 -6
- package/dist/index.cjs +1961 -786
- package/dist/index.d.cts +228 -30
- package/dist/index.d.ts +228 -30
- package/dist/index.js +322 -110
- package/dist/mcp/run-stdio.cjs +1817 -1264
- package/dist/mcp/run-stdio.js +250 -82
- package/dist/{orchestrator-DPTRBKEH.js → orchestrator-5PSHBLP6.js} +10 -12
- package/dist/{orchestrator-Y5MWUU7C.js → orchestrator-ZSSU3FKW.js} +9 -11
- package/dist/{paths-UMEDHOS5.js → paths-53TLA7VQ.js} +1 -1
- package/dist/{paths-QCI3MTO5.js → paths-RRCLNSJB.js} +1 -1
- package/dist/{thread-store-WGASXXXR.js → thread-store-KBFBHT5G.js} +2 -2
- package/dist/{thread-store-57ZLHR3A.js → thread-store-MVQU6HPJ.js} +2 -2
- package/dist/{workspaces-ZXCUVCZC.js → workspaces-5UNDTN4G.js} +5 -7
- package/dist/{workspaces-VICQYI2N.js → workspaces-MQYNZXUK.js} +5 -7
- package/dist/{worktree-HTUM35NT.js → worktree-PEWDAX5O.js} +4 -4
- package/dist/{worktree-DPIREDFR.js → worktree-T4SWFSTT.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-77MP647F.js +0 -210
- package/dist/chunk-ADCEGG4A.js +0 -592
- package/dist/chunk-HWZWBJWL.js +0 -120
- package/dist/chunk-OXOU2FRS.js +0 -212
- package/dist/chunk-TSCWSAQL.js +0 -122
- package/dist/chunk-Y2FNDKHF.js +0 -538
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-NVXVEGGM.js";
|
|
6
6
|
import {
|
|
7
7
|
listThreads
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LZQULFIT.js";
|
|
9
9
|
import {
|
|
10
10
|
ensureWorktreeSideboardIgnored
|
|
11
11
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -21,11 +21,14 @@ import {
|
|
|
21
21
|
} from "./chunk-FNQNJOHY.js";
|
|
22
22
|
import {
|
|
23
23
|
getGithubGitAuthMode,
|
|
24
|
-
getGithubPat
|
|
25
|
-
|
|
24
|
+
getGithubPat,
|
|
25
|
+
preferTeamsForRole,
|
|
26
|
+
resolveViewerProfile,
|
|
27
|
+
resolveViewerProfileForRepo
|
|
28
|
+
} from "./chunk-D7EGJ3EI.js";
|
|
26
29
|
import {
|
|
27
30
|
worktreesRoot
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-JTJHOYCU.js";
|
|
29
32
|
|
|
30
33
|
// src/git/worktree.ts
|
|
31
34
|
import { randomBytes } from "crypto";
|
|
@@ -1141,6 +1144,361 @@ function formatGitAuthModeDirective(mode) {
|
|
|
1141
1144
|
}
|
|
1142
1145
|
}
|
|
1143
1146
|
|
|
1147
|
+
// src/git/list-prs.ts
|
|
1148
|
+
var PR_LIST_JSON_FIELDS = [
|
|
1149
|
+
"number",
|
|
1150
|
+
"title",
|
|
1151
|
+
"headRefName",
|
|
1152
|
+
"url",
|
|
1153
|
+
"isCrossRepository",
|
|
1154
|
+
"author",
|
|
1155
|
+
"labels",
|
|
1156
|
+
"reviewRequests",
|
|
1157
|
+
"reviewDecision",
|
|
1158
|
+
"state",
|
|
1159
|
+
"isDraft",
|
|
1160
|
+
"assignees"
|
|
1161
|
+
].join(",");
|
|
1162
|
+
var BOT_REVIEWER_LOGINS = /* @__PURE__ */ new Set([
|
|
1163
|
+
"copilot",
|
|
1164
|
+
"copilot-pull-request-reviewer",
|
|
1165
|
+
"github-actions",
|
|
1166
|
+
"github-advanced-security",
|
|
1167
|
+
"dependabot",
|
|
1168
|
+
"renovate",
|
|
1169
|
+
"greptile",
|
|
1170
|
+
"greptile-apps",
|
|
1171
|
+
"coderabbit",
|
|
1172
|
+
"coderabbitai",
|
|
1173
|
+
"cursor",
|
|
1174
|
+
"cursor-agent"
|
|
1175
|
+
]);
|
|
1176
|
+
function normalizePrListState(state) {
|
|
1177
|
+
const key = (state ?? "").trim().toLowerCase();
|
|
1178
|
+
if (key === "closed") return "closed";
|
|
1179
|
+
if (key === "merged") return "merged";
|
|
1180
|
+
if (key === "all" || key === "*") return "all";
|
|
1181
|
+
return "open";
|
|
1182
|
+
}
|
|
1183
|
+
function normalizePrListQueue(queue, state) {
|
|
1184
|
+
const q = (queue ?? "").trim().toLowerCase();
|
|
1185
|
+
if (q === "review" || q === "unclaimed" || q === "inbox") return "review";
|
|
1186
|
+
if (q === "mine" || q === "assigned") return "mine";
|
|
1187
|
+
if (q === "approved" || q === "eng-approved") return "approved";
|
|
1188
|
+
if (q === "changes" || q === "eng-requested-changes" || q === "requested-changes") {
|
|
1189
|
+
return "changes";
|
|
1190
|
+
}
|
|
1191
|
+
const s = (state ?? "").trim().toLowerCase();
|
|
1192
|
+
if (s === "review" || s === "view" || s === "in-review" || s === "in_review") {
|
|
1193
|
+
return "review";
|
|
1194
|
+
}
|
|
1195
|
+
return void 0;
|
|
1196
|
+
}
|
|
1197
|
+
var QUEUE_DEFAULTS = {
|
|
1198
|
+
review: {
|
|
1199
|
+
state: "open",
|
|
1200
|
+
labels: ["eng-review"],
|
|
1201
|
+
reviewer: "unassigned",
|
|
1202
|
+
draft: false
|
|
1203
|
+
},
|
|
1204
|
+
mine: {
|
|
1205
|
+
state: "open",
|
|
1206
|
+
labels: ["eng-review"],
|
|
1207
|
+
reviewer: "me",
|
|
1208
|
+
draft: false
|
|
1209
|
+
},
|
|
1210
|
+
approved: { state: "open", labels: ["eng-approved"] },
|
|
1211
|
+
changes: { state: "open", labels: ["eng-requested-changes"] }
|
|
1212
|
+
};
|
|
1213
|
+
var TICKET_IN_TITLE_RE = /\b[A-Z]{2,8}-\d{1,6}\b|(?:^|[^\w/])#(\d+)\b/g;
|
|
1214
|
+
function ticketRefsFromPrTitle(title) {
|
|
1215
|
+
const out = [];
|
|
1216
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1217
|
+
for (const match of title.matchAll(TICKET_IN_TITLE_RE)) {
|
|
1218
|
+
const id = match[1] ? `#${match[1]}` : match[0];
|
|
1219
|
+
const key = id.toLowerCase();
|
|
1220
|
+
if (seen.has(key)) continue;
|
|
1221
|
+
seen.add(key);
|
|
1222
|
+
out.push(id);
|
|
1223
|
+
}
|
|
1224
|
+
return out;
|
|
1225
|
+
}
|
|
1226
|
+
function resolveListPrsOptions(opts) {
|
|
1227
|
+
const queue = normalizePrListQueue(opts?.queue, opts?.state);
|
|
1228
|
+
const defaults = queue ? QUEUE_DEFAULTS[queue] : void 0;
|
|
1229
|
+
const stateIsQueueAlias = Boolean(normalizePrListQueue(void 0, opts?.state));
|
|
1230
|
+
const labels = normalizePrLabels(opts?.labels);
|
|
1231
|
+
return {
|
|
1232
|
+
...queue ? { queue } : {},
|
|
1233
|
+
state: normalizePrListState(stateIsQueueAlias ? defaults?.state : opts?.state ?? defaults?.state),
|
|
1234
|
+
labels: labels.length ? labels : defaults?.labels ?? [],
|
|
1235
|
+
...opts?.reviewer?.trim() ? { reviewer: opts.reviewer.trim() } : defaults?.reviewer ? { reviewer: defaults.reviewer } : {},
|
|
1236
|
+
...opts?.query?.trim() ? { query: opts.query.trim() } : {},
|
|
1237
|
+
...opts?.draft !== void 0 ? { draft: opts.draft } : defaults?.draft !== void 0 ? { draft: defaults.draft } : {},
|
|
1238
|
+
...opts?.viewerTeams?.length ? { viewerTeams: opts.viewerTeams } : {},
|
|
1239
|
+
...opts?.limit != null ? { limit: opts.limit } : {}
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
function normalizePrLabels(labels) {
|
|
1243
|
+
const raw = (Array.isArray(labels) ? labels : [labels ?? ""]).flatMap((part) => String(part).split(",")).map((part) => part.trim()).filter(Boolean);
|
|
1244
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1245
|
+
const out = [];
|
|
1246
|
+
for (const label of raw) {
|
|
1247
|
+
const name = label.trim();
|
|
1248
|
+
if (!name) continue;
|
|
1249
|
+
const key = name.toLowerCase();
|
|
1250
|
+
if (seen.has(key)) continue;
|
|
1251
|
+
seen.add(key);
|
|
1252
|
+
out.push(name);
|
|
1253
|
+
}
|
|
1254
|
+
return out;
|
|
1255
|
+
}
|
|
1256
|
+
function normalizePrReviewer(reviewer) {
|
|
1257
|
+
return (reviewer ?? "").trim().toLowerCase();
|
|
1258
|
+
}
|
|
1259
|
+
function isBotReviewerLogin(login) {
|
|
1260
|
+
const raw = login.trim();
|
|
1261
|
+
if (!raw) return true;
|
|
1262
|
+
if (/\[[^\]]*bot[^\]]*\]/i.test(raw)) return true;
|
|
1263
|
+
const n = raw.toLowerCase().replace(/\[bot\]$/i, "");
|
|
1264
|
+
if (n.endsWith("-bot") || n.endsWith("_bot")) return true;
|
|
1265
|
+
return BOT_REVIEWER_LOGINS.has(n);
|
|
1266
|
+
}
|
|
1267
|
+
function looksLikeTeamSlug(id) {
|
|
1268
|
+
const n = id.trim().toLowerCase().replace(/\[bot\]$/i, "");
|
|
1269
|
+
if (!n) return false;
|
|
1270
|
+
if (n.includes("/")) return true;
|
|
1271
|
+
return /(^|-)team(-|$)/.test(n) || n.endsWith("-squad");
|
|
1272
|
+
}
|
|
1273
|
+
function parseReviewRequest(raw) {
|
|
1274
|
+
if (typeof raw === "string") {
|
|
1275
|
+
const id2 = raw.trim();
|
|
1276
|
+
if (!id2) return null;
|
|
1277
|
+
if (isBotReviewerLogin(id2)) return { id: id2, kind: "bot" };
|
|
1278
|
+
if (looksLikeTeamSlug(id2)) return { id: id2, kind: "team" };
|
|
1279
|
+
return { id: id2, kind: "user" };
|
|
1280
|
+
}
|
|
1281
|
+
if (!raw || typeof raw !== "object") return null;
|
|
1282
|
+
const row = raw;
|
|
1283
|
+
const typename = String(row.__typename ?? row.type ?? "");
|
|
1284
|
+
const slug = typeof row.slug === "string" ? row.slug.trim() : "";
|
|
1285
|
+
const login = typeof row.login === "string" ? row.login.trim() : "";
|
|
1286
|
+
const name = typeof row.name === "string" ? row.name.trim() : "";
|
|
1287
|
+
const id = login || slug || name;
|
|
1288
|
+
if (!id) return null;
|
|
1289
|
+
if (/team/i.test(typename) || slug && !login || looksLikeTeamSlug(id)) {
|
|
1290
|
+
return { id: slug || name || login, kind: "team" };
|
|
1291
|
+
}
|
|
1292
|
+
if (isBotReviewerLogin(id) || /bot/i.test(typename)) return { id, kind: "bot" };
|
|
1293
|
+
return { id, kind: "user" };
|
|
1294
|
+
}
|
|
1295
|
+
function collectReviewRequests(raw) {
|
|
1296
|
+
if (!Array.isArray(raw)) return { ids: [], users: [], teams: [] };
|
|
1297
|
+
const ids = [];
|
|
1298
|
+
const users = [];
|
|
1299
|
+
const teams = [];
|
|
1300
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1301
|
+
const take = (list, id) => {
|
|
1302
|
+
const key = id.toLowerCase();
|
|
1303
|
+
if (seen.has(`${list === teams ? "t" : list === users ? "u" : "i"}:${key}`)) return;
|
|
1304
|
+
seen.add(`${list === teams ? "t" : list === users ? "u" : "i"}:${key}`);
|
|
1305
|
+
list.push(id);
|
|
1306
|
+
};
|
|
1307
|
+
for (const item of raw) {
|
|
1308
|
+
const parsed = parseReviewRequest(item);
|
|
1309
|
+
if (!parsed) continue;
|
|
1310
|
+
take(ids, parsed.id);
|
|
1311
|
+
if (parsed.kind === "user") take(users, parsed.id);
|
|
1312
|
+
if (parsed.kind === "team") take(teams, parsed.id);
|
|
1313
|
+
}
|
|
1314
|
+
return { ids, users, teams };
|
|
1315
|
+
}
|
|
1316
|
+
function reviewerIdentities(raw) {
|
|
1317
|
+
return collectReviewRequests(raw).ids;
|
|
1318
|
+
}
|
|
1319
|
+
function humanReviewerLogins(raw) {
|
|
1320
|
+
return collectReviewRequests(raw).users;
|
|
1321
|
+
}
|
|
1322
|
+
function teamReviewerSlugs(raw) {
|
|
1323
|
+
return collectReviewRequests(raw).teams;
|
|
1324
|
+
}
|
|
1325
|
+
function labelNames(raw) {
|
|
1326
|
+
if (!Array.isArray(raw)) return [];
|
|
1327
|
+
const out = [];
|
|
1328
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1329
|
+
for (const item of raw) {
|
|
1330
|
+
const name = typeof item === "string" ? item.trim() : item && typeof item === "object" && typeof item.name === "string" ? item.name.trim() : "";
|
|
1331
|
+
if (!name) continue;
|
|
1332
|
+
const key = name.toLowerCase();
|
|
1333
|
+
if (seen.has(key)) continue;
|
|
1334
|
+
seen.add(key);
|
|
1335
|
+
out.push(name);
|
|
1336
|
+
}
|
|
1337
|
+
return out;
|
|
1338
|
+
}
|
|
1339
|
+
function searchLabelToken(label) {
|
|
1340
|
+
return /[\s:]/.test(label) ? `label:"${label.replace(/"/g, "")}"` : `label:${label}`;
|
|
1341
|
+
}
|
|
1342
|
+
function searchStateTokens(state) {
|
|
1343
|
+
if (state === "open") return ["is:open"];
|
|
1344
|
+
if (state === "closed") return ["is:closed", "-is:merged"];
|
|
1345
|
+
if (state === "merged") return ["is:merged"];
|
|
1346
|
+
return [];
|
|
1347
|
+
}
|
|
1348
|
+
function isUnassignedReviewer(reviewer) {
|
|
1349
|
+
const key = normalizePrReviewer(reviewer);
|
|
1350
|
+
return key === "unassigned" || key === "none" || key === "null";
|
|
1351
|
+
}
|
|
1352
|
+
function prListFetchLimit(limit, reviewer) {
|
|
1353
|
+
const n = Math.max(1, Math.min(250, Math.floor(limit)));
|
|
1354
|
+
if (isUnassignedReviewer(reviewer)) {
|
|
1355
|
+
return Math.min(250, Math.max(n * 4, 80));
|
|
1356
|
+
}
|
|
1357
|
+
return n;
|
|
1358
|
+
}
|
|
1359
|
+
function buildGhPrListArgs(opts) {
|
|
1360
|
+
const state = normalizePrListState(opts.state);
|
|
1361
|
+
const labels = normalizePrLabels(opts.labels);
|
|
1362
|
+
const reviewer = normalizePrReviewer(opts.reviewer);
|
|
1363
|
+
const query = opts.query?.trim() ?? "";
|
|
1364
|
+
const namedReviewer = reviewer && reviewer !== "all" && reviewer !== "*" && !isUnassignedReviewer(reviewer) ? reviewer === "me" || reviewer === "@me" ? "@me" : (opts.reviewer ?? "").trim().replace(/^@/, "") : "";
|
|
1365
|
+
const useSearch = Boolean(query || namedReviewer || opts.draft === true || opts.draft === false);
|
|
1366
|
+
const args = [
|
|
1367
|
+
"pr",
|
|
1368
|
+
"list",
|
|
1369
|
+
"--json",
|
|
1370
|
+
PR_LIST_JSON_FIELDS,
|
|
1371
|
+
"--limit",
|
|
1372
|
+
String(Math.max(1, Math.min(250, Math.floor(opts.limit))))
|
|
1373
|
+
];
|
|
1374
|
+
if (useSearch) {
|
|
1375
|
+
const parts = [...searchStateTokens(state)];
|
|
1376
|
+
for (const label of labels) parts.push(searchLabelToken(label));
|
|
1377
|
+
if (namedReviewer) parts.push(`review-requested:${namedReviewer}`);
|
|
1378
|
+
if (opts.draft === true) parts.push("draft:true");
|
|
1379
|
+
if (opts.draft === false) parts.push("draft:false");
|
|
1380
|
+
if (query) parts.push(query);
|
|
1381
|
+
args.push("--search", parts.join(" "));
|
|
1382
|
+
} else {
|
|
1383
|
+
args.push("--state", state);
|
|
1384
|
+
for (const label of labels) args.push("--label", label);
|
|
1385
|
+
}
|
|
1386
|
+
if (opts.slug) args.push("--repo", opts.slug);
|
|
1387
|
+
return args;
|
|
1388
|
+
}
|
|
1389
|
+
function parseGhPrList(stdout) {
|
|
1390
|
+
let parsed;
|
|
1391
|
+
try {
|
|
1392
|
+
parsed = JSON.parse(stdout);
|
|
1393
|
+
} catch {
|
|
1394
|
+
return [];
|
|
1395
|
+
}
|
|
1396
|
+
if (!Array.isArray(parsed)) return [];
|
|
1397
|
+
const out = [];
|
|
1398
|
+
for (const raw of parsed) {
|
|
1399
|
+
if (!raw || typeof raw !== "object") continue;
|
|
1400
|
+
const item = raw;
|
|
1401
|
+
const number = Number(item.number);
|
|
1402
|
+
if (!Number.isFinite(number) || number <= 0) continue;
|
|
1403
|
+
const requested = collectReviewRequests(item.reviewRequests);
|
|
1404
|
+
const reviewRequests = requested.ids;
|
|
1405
|
+
const reviewers = requested.users;
|
|
1406
|
+
const teams = requested.teams;
|
|
1407
|
+
const labels = labelNames(item.labels);
|
|
1408
|
+
const assignees = reviewerIdentities(item.assignees);
|
|
1409
|
+
const authorLogin = item.author?.login?.trim();
|
|
1410
|
+
const title = typeof item.title === "string" ? item.title : "";
|
|
1411
|
+
const tickets = ticketRefsFromPrTitle(title);
|
|
1412
|
+
out.push({
|
|
1413
|
+
number,
|
|
1414
|
+
title,
|
|
1415
|
+
headRefName: typeof item.headRefName === "string" ? item.headRefName : "",
|
|
1416
|
+
url: typeof item.url === "string" ? item.url : "",
|
|
1417
|
+
isCrossRepository: item.isCrossRepository === true,
|
|
1418
|
+
...authorLogin ? { author: { login: authorLogin } } : {},
|
|
1419
|
+
...item.isDraft === true ? { isDraft: true } : {},
|
|
1420
|
+
...typeof item.state === "string" && item.state ? { state: item.state } : {},
|
|
1421
|
+
...labels.length ? { labels } : {},
|
|
1422
|
+
...reviewRequests.length ? { reviewRequests } : {},
|
|
1423
|
+
...reviewers.length ? { reviewers } : {},
|
|
1424
|
+
...teams.length ? { teams } : {},
|
|
1425
|
+
...typeof item.reviewDecision === "string" && item.reviewDecision ? { reviewDecision: item.reviewDecision } : {},
|
|
1426
|
+
...assignees.length ? { assignees } : {},
|
|
1427
|
+
...tickets.length ? { tickets } : {}
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
return out;
|
|
1431
|
+
}
|
|
1432
|
+
function individualReviewers(pr) {
|
|
1433
|
+
if (pr.reviewers?.length) return pr.reviewers;
|
|
1434
|
+
return humanReviewerLogins(pr.reviewRequests);
|
|
1435
|
+
}
|
|
1436
|
+
function teamSlugsOnPr(pr) {
|
|
1437
|
+
if (pr.teams?.length) return pr.teams;
|
|
1438
|
+
return teamReviewerSlugs(pr.reviewRequests);
|
|
1439
|
+
}
|
|
1440
|
+
function requestedOfViewerTeam(pr, viewerTeams) {
|
|
1441
|
+
if (!viewerTeams?.length) return true;
|
|
1442
|
+
const mine = new Set(viewerTeams.map((slug) => slug.trim().toLowerCase()).filter(Boolean));
|
|
1443
|
+
if (mine.size === 0) return true;
|
|
1444
|
+
const teams = teamSlugsOnPr(pr);
|
|
1445
|
+
if (teams.length === 0) return true;
|
|
1446
|
+
return teams.some((slug) => mine.has(slug.toLowerCase()));
|
|
1447
|
+
}
|
|
1448
|
+
function prMatchesReviewer(pr, reviewer, viewerTeams) {
|
|
1449
|
+
const key = normalizePrReviewer(reviewer);
|
|
1450
|
+
if (!key || key === "all" || key === "*") return true;
|
|
1451
|
+
const humans = individualReviewers(pr);
|
|
1452
|
+
if (key === "unassigned" || key === "none" || key === "null") {
|
|
1453
|
+
return humans.length === 0 && requestedOfViewerTeam(pr, viewerTeams);
|
|
1454
|
+
}
|
|
1455
|
+
if (key === "me" || key === "@me") return true;
|
|
1456
|
+
return humans.some((login) => login.toLowerCase() === key);
|
|
1457
|
+
}
|
|
1458
|
+
function filterPrsByReviewer(prs, reviewer, viewerTeams) {
|
|
1459
|
+
return prs.filter((pr) => prMatchesReviewer(pr, reviewer, viewerTeams));
|
|
1460
|
+
}
|
|
1461
|
+
function filterListedPrs(prs, opts) {
|
|
1462
|
+
let out = filterPrsByReviewer(prs, opts?.reviewer, opts?.viewerTeams);
|
|
1463
|
+
if (opts?.draft === false) out = out.filter((pr) => !pr.isDraft);
|
|
1464
|
+
if (opts?.draft === true) out = out.filter((pr) => pr.isDraft);
|
|
1465
|
+
return out;
|
|
1466
|
+
}
|
|
1467
|
+
function applyPrListResponse(stdout, opts) {
|
|
1468
|
+
const resolved = resolveListPrsOptions(opts);
|
|
1469
|
+
const listed = filterListedPrs(parseGhPrList(stdout), resolved);
|
|
1470
|
+
if (resolved.limit == null) return listed;
|
|
1471
|
+
const n = Math.max(1, Math.min(250, Math.floor(resolved.limit)));
|
|
1472
|
+
return listed.slice(0, n);
|
|
1473
|
+
}
|
|
1474
|
+
async function listGithubViewerTeamSlugs(repoPath) {
|
|
1475
|
+
const { stdout, exitCode } = await gh(
|
|
1476
|
+
["api", "user/teams", "--paginate"],
|
|
1477
|
+
repoPath,
|
|
1478
|
+
{ reject: false }
|
|
1479
|
+
);
|
|
1480
|
+
if (exitCode !== 0 || !stdout.trim()) return [];
|
|
1481
|
+
let parsed;
|
|
1482
|
+
try {
|
|
1483
|
+
parsed = JSON.parse(stdout);
|
|
1484
|
+
} catch {
|
|
1485
|
+
return [];
|
|
1486
|
+
}
|
|
1487
|
+
const rows = Array.isArray(parsed) ? parsed : [];
|
|
1488
|
+
const slugs = [];
|
|
1489
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1490
|
+
for (const row of rows) {
|
|
1491
|
+
if (!row || typeof row !== "object") continue;
|
|
1492
|
+
const slug = row.slug;
|
|
1493
|
+
if (typeof slug !== "string" || !slug.trim()) continue;
|
|
1494
|
+
const key = slug.trim().toLowerCase();
|
|
1495
|
+
if (seen.has(key)) continue;
|
|
1496
|
+
seen.add(key);
|
|
1497
|
+
slugs.push(slug.trim());
|
|
1498
|
+
}
|
|
1499
|
+
return slugs;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1144
1502
|
// src/util/enqueue-by-key.ts
|
|
1145
1503
|
var tails = /* @__PURE__ */ new Map();
|
|
1146
1504
|
function enqueueByKey(key, fn) {
|
|
@@ -1659,20 +2017,33 @@ async function listBranches(repoPath, opts) {
|
|
|
1659
2017
|
}
|
|
1660
2018
|
return sorted.filter((b) => keep.has(b.name));
|
|
1661
2019
|
}
|
|
1662
|
-
async function listPrs(repoPath) {
|
|
2020
|
+
async function listPrs(repoPath, opts) {
|
|
1663
2021
|
const slug = await resolveGithubRepoSlug(repoPath);
|
|
1664
|
-
const
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
2022
|
+
const resolved = resolveListPrsOptions(opts);
|
|
2023
|
+
const limit = resolved.limit ?? 200;
|
|
2024
|
+
const reviewerKey = (resolved.reviewer ?? "").trim().toLowerCase();
|
|
2025
|
+
const needsUnclaimed = reviewerKey === "unassigned" || reviewerKey === "none" || reviewerKey === "null";
|
|
2026
|
+
let profile;
|
|
2027
|
+
try {
|
|
2028
|
+
profile = resolveViewerProfileForRepo(repoPath);
|
|
2029
|
+
} catch {
|
|
2030
|
+
profile = resolveViewerProfile();
|
|
2031
|
+
}
|
|
2032
|
+
const fetchedTeams = needsUnclaimed ? await listGithubViewerTeamSlugs(repoPath).catch(() => []) : [];
|
|
2033
|
+
const viewerTeams = resolved.viewerTeams ?? (needsUnclaimed ? preferTeamsForRole(fetchedTeams, profile.reviewTeamHints) : void 0);
|
|
2034
|
+
const fetchLimit = prListFetchLimit(limit, resolved.reviewer);
|
|
2035
|
+
const args = buildGhPrListArgs({
|
|
2036
|
+
slug,
|
|
2037
|
+
state: resolved.state,
|
|
2038
|
+
labels: resolved.labels,
|
|
2039
|
+
reviewer: resolved.reviewer,
|
|
2040
|
+
query: resolved.query,
|
|
2041
|
+
draft: resolved.draft,
|
|
2042
|
+
limit: fetchLimit
|
|
2043
|
+
});
|
|
1673
2044
|
const { stdout, exitCode } = await gh(args, repoPath, { reject: false });
|
|
1674
2045
|
if (exitCode !== 0 || !stdout.trim()) return [];
|
|
1675
|
-
return
|
|
2046
|
+
return applyPrListResponse(stdout, { ...resolved, limit, viewerTeams });
|
|
1676
2047
|
}
|
|
1677
2048
|
async function getPr(repoPath, number) {
|
|
1678
2049
|
const slug = await resolveGithubRepoSlug(repoPath);
|
|
@@ -2808,6 +3179,7 @@ export {
|
|
|
2808
3179
|
resolveCodexGitWritableRoots,
|
|
2809
3180
|
codexUnattendedGitConfigArgs,
|
|
2810
3181
|
formatGitAuthModeDirective,
|
|
3182
|
+
resolveListPrsOptions,
|
|
2811
3183
|
enqueueByKey,
|
|
2812
3184
|
withRepoGitLock,
|
|
2813
3185
|
detectGhStack,
|