@ycodium-ai/plugin-pull-requests 0.2.2998 → 0.2.3002
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/assets/ui.js +11 -11
- package/dist/index.js +219 -196
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { definePlugin } from "@ycodium-ai/plugin-api";
|
|
2
|
+
import { definePlugin, projectOrNull } from "@ycodium-ai/plugin-api";
|
|
3
|
+
|
|
4
|
+
// src/hostProject.ts
|
|
5
|
+
var providerOf = (provider) => provider === "github" || provider === "gitlab" ? provider : "unknown";
|
|
6
|
+
var workspaceShellOf = (project) => {
|
|
7
|
+
const identity = project.repositoryIdentity;
|
|
8
|
+
return {
|
|
9
|
+
projectId: project.id,
|
|
10
|
+
title: project.title,
|
|
11
|
+
workspaceRoot: project.workspaceRoot,
|
|
12
|
+
repositoryIdentity: identity == null ? null : {
|
|
13
|
+
provider: providerOf(identity.provider),
|
|
14
|
+
canonicalKey: identity.canonicalKey,
|
|
15
|
+
remoteName: identity.locator.remoteName,
|
|
16
|
+
remoteUrl: identity.locator.remoteUrl,
|
|
17
|
+
...identity.displayName === void 0 ? {} : { displayName: identity.displayName },
|
|
18
|
+
...identity.owner === void 0 ? {} : { owner: identity.owner },
|
|
19
|
+
...identity.name === void 0 ? {} : { name: identity.name },
|
|
20
|
+
...identity.rootPath === void 0 ? {} : { rootPath: identity.rootPath }
|
|
21
|
+
},
|
|
22
|
+
...project.archivedAt == null ? {} : { archivedAt: project.archivedAt }
|
|
23
|
+
};
|
|
24
|
+
};
|
|
3
25
|
|
|
4
26
|
// src/service/backoff.ts
|
|
5
27
|
var FALLBACK_COOLDOWN_MS = 3e4;
|
|
@@ -1398,58 +1420,7 @@ var decodeReviewerCandidates = (value) => {
|
|
|
1398
1420
|
};
|
|
1399
1421
|
};
|
|
1400
1422
|
|
|
1401
|
-
// src/
|
|
1402
|
-
var CAPABILITIES = {
|
|
1403
|
-
diff: true,
|
|
1404
|
-
comment: true,
|
|
1405
|
-
actions: [
|
|
1406
|
-
"merge",
|
|
1407
|
-
"ready",
|
|
1408
|
-
"draft",
|
|
1409
|
-
"close",
|
|
1410
|
-
"reopen",
|
|
1411
|
-
"update-branch",
|
|
1412
|
-
"enable-auto-merge",
|
|
1413
|
-
"disable-auto-merge"
|
|
1414
|
-
],
|
|
1415
|
-
mergeMethods: ["merge", "squash", "rebase"],
|
|
1416
|
-
updateMethods: ["merge", "rebase"],
|
|
1417
|
-
search: true,
|
|
1418
|
-
reactions: true,
|
|
1419
|
-
review: {
|
|
1420
|
-
inlineComment: true,
|
|
1421
|
-
reply: true,
|
|
1422
|
-
resolve: true,
|
|
1423
|
-
verdicts: ["comment", "approve", "request-changes"]
|
|
1424
|
-
},
|
|
1425
|
-
reviewers: { request: true, listCandidates: true },
|
|
1426
|
-
edit: { changeRequest: true, comment: true }
|
|
1427
|
-
};
|
|
1428
|
-
var DIFF_MAX_BYTES = 8 * 1024 * 1024;
|
|
1429
|
-
var DIFF_TIMEOUT_MS = 6e4;
|
|
1430
|
-
var DIFF_FILE_MAX_BYTES = 1024 * 1024;
|
|
1431
|
-
var DIFF_FILES_PAGE_SIZE = 100;
|
|
1432
|
-
var REVIEW_THREAD_PAGES = 10;
|
|
1433
|
-
var FALLBACK_MAX_ROWS = 1e3;
|
|
1434
|
-
var REST_PAGE_SIZE = 100;
|
|
1435
|
-
var STAT_ALIASES_PER_REQUEST = 25;
|
|
1436
|
-
var STAT_REQUEST_CONCURRENCY = 4;
|
|
1437
|
-
var gitHubViewerPermissions = (access) => ({
|
|
1438
|
-
actions: [
|
|
1439
|
-
// 布置自动合并与撤销布置就是延后的合并:这里不能合的人,也不该留下一条以后合的指令。
|
|
1440
|
-
...access.canWrite ? ["merge", "enable-auto-merge", "disable-auto-merge"] : [],
|
|
1441
|
-
...access.canUpdate ? ["ready", "draft", "close", "reopen"] : [],
|
|
1442
|
-
// 能不能更新分支是 GitHub 自己的答案;答不上来就谁都不给,而不是谁都给。
|
|
1443
|
-
...access.canUpdateBranch ? ["update-branch"] : []
|
|
1444
|
-
],
|
|
1445
|
-
comment: true,
|
|
1446
|
-
resolve: access.canWrite || access.didAuthor,
|
|
1447
|
-
// 谁都能评审自己看得见的合并请求,除了自己那条:GitHub 拒绝作者的批准与要求修改
|
|
1448
|
-
// ("Can not approve your own pull request"),只留下评论——那也正是作者对自己改动能说的。
|
|
1449
|
-
verdicts: access.didAuthor ? ["comment"] : CAPABILITIES.review.verdicts,
|
|
1450
|
-
requestReviewers: access.canWrite,
|
|
1451
|
-
...access.canUpdateBranch ? { updateMethods: CAPABILITIES.updateMethods } : {}
|
|
1452
|
-
});
|
|
1423
|
+
// src/githubRepository.ts
|
|
1453
1424
|
var failed = (operation, detail) => new GitHubError({ code: "failed", operation, detail });
|
|
1454
1425
|
var parseRepositorySelector = (value) => {
|
|
1455
1426
|
const parts = value.trim().split("/").filter(Boolean);
|
|
@@ -1462,13 +1433,145 @@ var selector = (input, operation) => {
|
|
|
1462
1433
|
}
|
|
1463
1434
|
return parsed;
|
|
1464
1435
|
};
|
|
1465
|
-
var path = (value) => value.split("/").map(encodeURIComponent).join("/");
|
|
1466
1436
|
var repositoryPath = (input, operation) => {
|
|
1467
1437
|
const { owner, name } = selector(input, operation);
|
|
1468
1438
|
return `repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`;
|
|
1469
1439
|
};
|
|
1440
|
+
|
|
1441
|
+
// src/githubDiff.ts
|
|
1442
|
+
var DIFF_MAX_BYTES = 8 * 1024 * 1024;
|
|
1443
|
+
var DIFF_TIMEOUT_MS = 6e4;
|
|
1444
|
+
var DIFF_FILE_MAX_BYTES = 1024 * 1024;
|
|
1445
|
+
var DIFF_FILES_PAGE_SIZE = 100;
|
|
1446
|
+
var path = (value) => value.split("/").map(encodeURIComponent).join("/");
|
|
1470
1447
|
var diffCursorPage = (cursor) => /^[1-9][0-9]{0,6}$/.test(cursor) ? Number(cursor) : null;
|
|
1471
1448
|
var isCommitSha = (value) => /^[0-9a-f]{7,64}$/i.test(value);
|
|
1449
|
+
var diffFilesPage = async (ctx, input) => {
|
|
1450
|
+
const repository = repositoryPath(input, "getDiff");
|
|
1451
|
+
const paging = `per_page=${DIFF_FILES_PAGE_SIZE}&page=${input.page}`;
|
|
1452
|
+
const result = await callGitHubApi(ctx, {
|
|
1453
|
+
operation: "getDiff",
|
|
1454
|
+
host: input.host,
|
|
1455
|
+
path: input.commit === void 0 ? `${repository}/pulls/${input.number}/files?${paging}` : `${repository}/commits/${input.commit}?${paging}`,
|
|
1456
|
+
maxBytes: DIFF_MAX_BYTES,
|
|
1457
|
+
timeoutMs: DIFF_TIMEOUT_MS
|
|
1458
|
+
});
|
|
1459
|
+
if (result.truncated) {
|
|
1460
|
+
throw failed("getDiff", `Page ${input.page} of the changed files was too large to read.`);
|
|
1461
|
+
}
|
|
1462
|
+
let body;
|
|
1463
|
+
try {
|
|
1464
|
+
body = JSON.parse(result.body.trim());
|
|
1465
|
+
} catch {
|
|
1466
|
+
throw readError("getDiff", "changed files");
|
|
1467
|
+
}
|
|
1468
|
+
const files = input.commit === void 0 ? body : body?.files ?? [];
|
|
1469
|
+
const decoded = decodeFiles(files);
|
|
1470
|
+
if (decoded === null) throw readError("getDiff", "changed files");
|
|
1471
|
+
const morePages = decoded.rawCount >= DIFF_FILES_PAGE_SIZE;
|
|
1472
|
+
return {
|
|
1473
|
+
patch: decoded.patch,
|
|
1474
|
+
truncated: decoded.truncated,
|
|
1475
|
+
nextCursor: morePages ? String(input.page + 1) : null,
|
|
1476
|
+
...decoded.omittedFileStats.length === 0 ? {} : { omittedFileStats: decoded.omittedFileStats }
|
|
1477
|
+
};
|
|
1478
|
+
};
|
|
1479
|
+
var getDiff = async (ctx, input) => {
|
|
1480
|
+
if (input.commit !== void 0 && !isCommitSha(input.commit)) {
|
|
1481
|
+
throw failed("getDiff", "The named commit was not a commit sha.");
|
|
1482
|
+
}
|
|
1483
|
+
const target = {
|
|
1484
|
+
cwd: input.cwd,
|
|
1485
|
+
repository: input.repository,
|
|
1486
|
+
host: input.host,
|
|
1487
|
+
number: input.number,
|
|
1488
|
+
...input.commit === void 0 ? {} : { commit: input.commit }
|
|
1489
|
+
};
|
|
1490
|
+
if (input.cursor !== void 0) {
|
|
1491
|
+
const page = diffCursorPage(input.cursor);
|
|
1492
|
+
if (page === null) {
|
|
1493
|
+
throw failed("getDiff", "The diff cursor was not one this pull request handed out.");
|
|
1494
|
+
}
|
|
1495
|
+
return diffFilesPage(ctx, { ...target, page });
|
|
1496
|
+
}
|
|
1497
|
+
if (input.commit !== void 0) return diffFilesPage(ctx, { ...target, page: 1 });
|
|
1498
|
+
const whole = async () => {
|
|
1499
|
+
const result = await callGitHubApi(ctx, {
|
|
1500
|
+
operation: "getDiff",
|
|
1501
|
+
host: input.host,
|
|
1502
|
+
path: `${repositoryPath(input, "getDiff")}/pulls/${input.number}`,
|
|
1503
|
+
accept: "application/vnd.github.diff",
|
|
1504
|
+
maxBytes: DIFF_MAX_BYTES,
|
|
1505
|
+
timeoutMs: DIFF_TIMEOUT_MS
|
|
1506
|
+
});
|
|
1507
|
+
return result.truncated ? null : { patch: result.body, truncated: false, nextCursor: null };
|
|
1508
|
+
};
|
|
1509
|
+
try {
|
|
1510
|
+
const slice = await whole();
|
|
1511
|
+
return slice ?? await diffFilesPage(ctx, { ...target, page: 1 });
|
|
1512
|
+
} catch (error) {
|
|
1513
|
+
if (error instanceof GitHubError && error.code !== "failed") throw error;
|
|
1514
|
+
try {
|
|
1515
|
+
return await diffFilesPage(ctx, { ...target, page: 1 });
|
|
1516
|
+
} catch {
|
|
1517
|
+
throw error;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
var getDiffFileContents = async (ctx, input) => {
|
|
1522
|
+
const operation = "getDiffFileContents";
|
|
1523
|
+
if (input.commit !== void 0 && !isCommitSha(input.commit)) {
|
|
1524
|
+
throw failed(operation, "The named commit was not a commit sha.");
|
|
1525
|
+
}
|
|
1526
|
+
const repository = repositoryPath(input, operation);
|
|
1527
|
+
const revisions = decodeRevisions(
|
|
1528
|
+
await callGitHubJson(ctx, {
|
|
1529
|
+
operation,
|
|
1530
|
+
host: input.host,
|
|
1531
|
+
path: input.commit === void 0 ? `${repository}/pulls/${input.number}` : `${repository}/commits/${input.commit}`,
|
|
1532
|
+
maxBytes: DIFF_MAX_BYTES,
|
|
1533
|
+
timeoutMs: DIFF_TIMEOUT_MS
|
|
1534
|
+
}),
|
|
1535
|
+
input.commit === void 0 ? "pull-request" : "commit"
|
|
1536
|
+
);
|
|
1537
|
+
const rootCommitNewFile = input.commit !== void 0 && input.changeType === "new" && revisions?.baseRef === null;
|
|
1538
|
+
const baseRef = revisions?.baseRef ?? null;
|
|
1539
|
+
const headRef = revisions?.headRef ?? null;
|
|
1540
|
+
if (headRef === null || !isCommitSha(headRef) || !rootCommitNewFile && (baseRef === null || !isCommitSha(baseRef))) {
|
|
1541
|
+
throw failed(
|
|
1542
|
+
operation,
|
|
1543
|
+
input.commit === void 0 ? `Pull request #${input.number} reported no usable base and head revisions.` : `Commit ${input.commit} reported no usable revisions for this file.`
|
|
1544
|
+
);
|
|
1545
|
+
}
|
|
1546
|
+
const readFile = async (revision, filePath) => {
|
|
1547
|
+
const result = await callGitHubApi(ctx, {
|
|
1548
|
+
operation,
|
|
1549
|
+
host: input.host,
|
|
1550
|
+
path: `${repository}/contents/${path(filePath)}?ref=${encodeURIComponent(revision)}`,
|
|
1551
|
+
accept: "application/vnd.github.raw",
|
|
1552
|
+
maxBytes: DIFF_FILE_MAX_BYTES,
|
|
1553
|
+
timeoutMs: DIFF_TIMEOUT_MS
|
|
1554
|
+
});
|
|
1555
|
+
if (result.truncated) {
|
|
1556
|
+
throw failed(operation, `The diff file '${filePath}' exceeds the 1 MB expansion limit.`);
|
|
1557
|
+
}
|
|
1558
|
+
if (result.body.includes("\0")) {
|
|
1559
|
+
throw failed(operation, `The diff file '${filePath}' is binary.`);
|
|
1560
|
+
}
|
|
1561
|
+
return result.body;
|
|
1562
|
+
};
|
|
1563
|
+
const [oldContents, newContents] = await Promise.all([
|
|
1564
|
+
input.changeType === "new" ? Promise.resolve("") : readFile(baseRef, input.oldPath),
|
|
1565
|
+
input.changeType === "deleted" ? Promise.resolve("") : readFile(headRef, input.newPath)
|
|
1566
|
+
]);
|
|
1567
|
+
return { oldContents, newContents };
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
// src/githubSearch.ts
|
|
1571
|
+
var FALLBACK_MAX_ROWS = 1e3;
|
|
1572
|
+
var REST_PAGE_SIZE = 100;
|
|
1573
|
+
var STAT_ALIASES_PER_REQUEST = 25;
|
|
1574
|
+
var STAT_REQUEST_CONCURRENCY = 4;
|
|
1472
1575
|
var searchPhrase = (query2) => `"${query2.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
1473
1576
|
var REVIEW_QUALIFIERS = {
|
|
1474
1577
|
approved: "approved",
|
|
@@ -1531,15 +1634,6 @@ var matchesFallback = (item, input) => {
|
|
|
1531
1634
|
const holds = (label) => labels.has(label.trim().toLowerCase());
|
|
1532
1635
|
return (filters.draft === void 0 || item.isDraft === (filters.draft === "only")) && (filters.labels === void 0 || filters.labels.every((group) => group.some(holds))) && (filters.excludedLabels === void 0 || !filters.excludedLabels.some(holds)) && (filters.author === void 0 || item.author?.login.toLowerCase() === resolveAuthor(filters.author, input.viewer).toLowerCase());
|
|
1533
1636
|
};
|
|
1534
|
-
var getViewer = async (ctx) => {
|
|
1535
|
-
const login = decodeViewerLogin(
|
|
1536
|
-
await callGitHubJson(ctx, { operation: "getViewer", path: "user" })
|
|
1537
|
-
);
|
|
1538
|
-
if (login === null) {
|
|
1539
|
-
throw failed("getViewer", "GitHub returned no login for the authenticated account.");
|
|
1540
|
-
}
|
|
1541
|
-
return login;
|
|
1542
|
-
};
|
|
1543
1637
|
var searchRows = (limit) => Math.min(limit + 1, SEARCH_MAX_ROWS);
|
|
1544
1638
|
var listFallback = async (ctx, input) => {
|
|
1545
1639
|
const repository = repositoryPath(input, "listChangeRequests");
|
|
@@ -1648,6 +1742,60 @@ var listChangeRequestStats = async (ctx, input) => {
|
|
|
1648
1742
|
}
|
|
1649
1743
|
return results;
|
|
1650
1744
|
};
|
|
1745
|
+
|
|
1746
|
+
// src/githubCommands.ts
|
|
1747
|
+
var CAPABILITIES = {
|
|
1748
|
+
diff: true,
|
|
1749
|
+
comment: true,
|
|
1750
|
+
actions: [
|
|
1751
|
+
"merge",
|
|
1752
|
+
"ready",
|
|
1753
|
+
"draft",
|
|
1754
|
+
"close",
|
|
1755
|
+
"reopen",
|
|
1756
|
+
"update-branch",
|
|
1757
|
+
"enable-auto-merge",
|
|
1758
|
+
"disable-auto-merge"
|
|
1759
|
+
],
|
|
1760
|
+
mergeMethods: ["merge", "squash", "rebase"],
|
|
1761
|
+
updateMethods: ["merge", "rebase"],
|
|
1762
|
+
search: true,
|
|
1763
|
+
reactions: true,
|
|
1764
|
+
review: {
|
|
1765
|
+
inlineComment: true,
|
|
1766
|
+
reply: true,
|
|
1767
|
+
resolve: true,
|
|
1768
|
+
verdicts: ["comment", "approve", "request-changes"]
|
|
1769
|
+
},
|
|
1770
|
+
reviewers: { request: true, listCandidates: true },
|
|
1771
|
+
edit: { changeRequest: true, comment: true }
|
|
1772
|
+
};
|
|
1773
|
+
var REVIEW_THREAD_PAGES = 10;
|
|
1774
|
+
var gitHubViewerPermissions = (access) => ({
|
|
1775
|
+
actions: [
|
|
1776
|
+
// 布置自动合并与撤销布置就是延后的合并:这里不能合的人,也不该留下一条以后合的指令。
|
|
1777
|
+
...access.canWrite ? ["merge", "enable-auto-merge", "disable-auto-merge"] : [],
|
|
1778
|
+
...access.canUpdate ? ["ready", "draft", "close", "reopen"] : [],
|
|
1779
|
+
// 能不能更新分支是 GitHub 自己的答案;答不上来就谁都不给,而不是谁都给。
|
|
1780
|
+
...access.canUpdateBranch ? ["update-branch"] : []
|
|
1781
|
+
],
|
|
1782
|
+
comment: true,
|
|
1783
|
+
resolve: access.canWrite || access.didAuthor,
|
|
1784
|
+
// 谁都能评审自己看得见的合并请求,除了自己那条:GitHub 拒绝作者的批准与要求修改
|
|
1785
|
+
// ("Can not approve your own pull request"),只留下评论——那也正是作者对自己改动能说的。
|
|
1786
|
+
verdicts: access.didAuthor ? ["comment"] : CAPABILITIES.review.verdicts,
|
|
1787
|
+
requestReviewers: access.canWrite,
|
|
1788
|
+
...access.canUpdateBranch ? { updateMethods: CAPABILITIES.updateMethods } : {}
|
|
1789
|
+
});
|
|
1790
|
+
var getViewer = async (ctx) => {
|
|
1791
|
+
const login = decodeViewerLogin(
|
|
1792
|
+
await callGitHubJson(ctx, { operation: "getViewer", path: "user" })
|
|
1793
|
+
);
|
|
1794
|
+
if (login === null) {
|
|
1795
|
+
throw failed("getViewer", "GitHub returned no login for the authenticated account.");
|
|
1796
|
+
}
|
|
1797
|
+
return login;
|
|
1798
|
+
};
|
|
1651
1799
|
var detailOf = async (ctx, input, operation) => {
|
|
1652
1800
|
const { owner, name } = selector(input, operation);
|
|
1653
1801
|
const decoded = decodeDetail(
|
|
@@ -1760,126 +1908,6 @@ var getViewerPermissions = async (ctx, input) => {
|
|
|
1760
1908
|
if (access === null) throw readError("getViewerPermissions", "viewer permissions");
|
|
1761
1909
|
return gitHubViewerPermissions(access);
|
|
1762
1910
|
};
|
|
1763
|
-
var diffFilesPage = async (ctx, input) => {
|
|
1764
|
-
const repository = repositoryPath(input, "getDiff");
|
|
1765
|
-
const paging = `per_page=${DIFF_FILES_PAGE_SIZE}&page=${input.page}`;
|
|
1766
|
-
const result = await callGitHubApi(ctx, {
|
|
1767
|
-
operation: "getDiff",
|
|
1768
|
-
host: input.host,
|
|
1769
|
-
path: input.commit === void 0 ? `${repository}/pulls/${input.number}/files?${paging}` : `${repository}/commits/${input.commit}?${paging}`,
|
|
1770
|
-
maxBytes: DIFF_MAX_BYTES,
|
|
1771
|
-
timeoutMs: DIFF_TIMEOUT_MS
|
|
1772
|
-
});
|
|
1773
|
-
if (result.truncated) {
|
|
1774
|
-
throw failed("getDiff", `Page ${input.page} of the changed files was too large to read.`);
|
|
1775
|
-
}
|
|
1776
|
-
let body;
|
|
1777
|
-
try {
|
|
1778
|
-
body = JSON.parse(result.body.trim());
|
|
1779
|
-
} catch {
|
|
1780
|
-
throw readError("getDiff", "changed files");
|
|
1781
|
-
}
|
|
1782
|
-
const files = input.commit === void 0 ? body : body?.files ?? [];
|
|
1783
|
-
const decoded = decodeFiles(files);
|
|
1784
|
-
if (decoded === null) throw readError("getDiff", "changed files");
|
|
1785
|
-
const morePages = decoded.rawCount >= DIFF_FILES_PAGE_SIZE;
|
|
1786
|
-
return {
|
|
1787
|
-
patch: decoded.patch,
|
|
1788
|
-
truncated: decoded.truncated,
|
|
1789
|
-
nextCursor: morePages ? String(input.page + 1) : null,
|
|
1790
|
-
...decoded.omittedFileStats.length === 0 ? {} : { omittedFileStats: decoded.omittedFileStats }
|
|
1791
|
-
};
|
|
1792
|
-
};
|
|
1793
|
-
var getDiff = async (ctx, input) => {
|
|
1794
|
-
if (input.commit !== void 0 && !isCommitSha(input.commit)) {
|
|
1795
|
-
throw failed("getDiff", "The named commit was not a commit sha.");
|
|
1796
|
-
}
|
|
1797
|
-
const target = {
|
|
1798
|
-
cwd: input.cwd,
|
|
1799
|
-
repository: input.repository,
|
|
1800
|
-
host: input.host,
|
|
1801
|
-
number: input.number,
|
|
1802
|
-
...input.commit === void 0 ? {} : { commit: input.commit }
|
|
1803
|
-
};
|
|
1804
|
-
if (input.cursor !== void 0) {
|
|
1805
|
-
const page = diffCursorPage(input.cursor);
|
|
1806
|
-
if (page === null) {
|
|
1807
|
-
throw failed("getDiff", "The diff cursor was not one this pull request handed out.");
|
|
1808
|
-
}
|
|
1809
|
-
return diffFilesPage(ctx, { ...target, page });
|
|
1810
|
-
}
|
|
1811
|
-
if (input.commit !== void 0) return diffFilesPage(ctx, { ...target, page: 1 });
|
|
1812
|
-
const whole = async () => {
|
|
1813
|
-
const result = await callGitHubApi(ctx, {
|
|
1814
|
-
operation: "getDiff",
|
|
1815
|
-
host: input.host,
|
|
1816
|
-
path: `${repositoryPath(input, "getDiff")}/pulls/${input.number}`,
|
|
1817
|
-
accept: "application/vnd.github.diff",
|
|
1818
|
-
maxBytes: DIFF_MAX_BYTES,
|
|
1819
|
-
timeoutMs: DIFF_TIMEOUT_MS
|
|
1820
|
-
});
|
|
1821
|
-
return result.truncated ? null : { patch: result.body, truncated: false, nextCursor: null };
|
|
1822
|
-
};
|
|
1823
|
-
try {
|
|
1824
|
-
const slice = await whole();
|
|
1825
|
-
return slice ?? await diffFilesPage(ctx, { ...target, page: 1 });
|
|
1826
|
-
} catch (error) {
|
|
1827
|
-
if (error instanceof GitHubError && error.code !== "failed") throw error;
|
|
1828
|
-
try {
|
|
1829
|
-
return await diffFilesPage(ctx, { ...target, page: 1 });
|
|
1830
|
-
} catch {
|
|
1831
|
-
throw error;
|
|
1832
|
-
}
|
|
1833
|
-
}
|
|
1834
|
-
};
|
|
1835
|
-
var getDiffFileContents = async (ctx, input) => {
|
|
1836
|
-
const operation = "getDiffFileContents";
|
|
1837
|
-
if (input.commit !== void 0 && !isCommitSha(input.commit)) {
|
|
1838
|
-
throw failed(operation, "The named commit was not a commit sha.");
|
|
1839
|
-
}
|
|
1840
|
-
const repository = repositoryPath(input, operation);
|
|
1841
|
-
const revisions = decodeRevisions(
|
|
1842
|
-
await callGitHubJson(ctx, {
|
|
1843
|
-
operation,
|
|
1844
|
-
host: input.host,
|
|
1845
|
-
path: input.commit === void 0 ? `${repository}/pulls/${input.number}` : `${repository}/commits/${input.commit}`,
|
|
1846
|
-
maxBytes: DIFF_MAX_BYTES,
|
|
1847
|
-
timeoutMs: DIFF_TIMEOUT_MS
|
|
1848
|
-
}),
|
|
1849
|
-
input.commit === void 0 ? "pull-request" : "commit"
|
|
1850
|
-
);
|
|
1851
|
-
const rootCommitNewFile = input.commit !== void 0 && input.changeType === "new" && revisions?.baseRef === null;
|
|
1852
|
-
const baseRef = revisions?.baseRef ?? null;
|
|
1853
|
-
const headRef = revisions?.headRef ?? null;
|
|
1854
|
-
if (headRef === null || !isCommitSha(headRef) || !rootCommitNewFile && (baseRef === null || !isCommitSha(baseRef))) {
|
|
1855
|
-
throw failed(
|
|
1856
|
-
operation,
|
|
1857
|
-
input.commit === void 0 ? `Pull request #${input.number} reported no usable base and head revisions.` : `Commit ${input.commit} reported no usable revisions for this file.`
|
|
1858
|
-
);
|
|
1859
|
-
}
|
|
1860
|
-
const readFile = async (revision, filePath) => {
|
|
1861
|
-
const result = await callGitHubApi(ctx, {
|
|
1862
|
-
operation,
|
|
1863
|
-
host: input.host,
|
|
1864
|
-
path: `${repository}/contents/${path(filePath)}?ref=${encodeURIComponent(revision)}`,
|
|
1865
|
-
accept: "application/vnd.github.raw",
|
|
1866
|
-
maxBytes: DIFF_FILE_MAX_BYTES,
|
|
1867
|
-
timeoutMs: DIFF_TIMEOUT_MS
|
|
1868
|
-
});
|
|
1869
|
-
if (result.truncated) {
|
|
1870
|
-
throw failed(operation, `The diff file '${filePath}' exceeds the 1 MB expansion limit.`);
|
|
1871
|
-
}
|
|
1872
|
-
if (result.body.includes("\0")) {
|
|
1873
|
-
throw failed(operation, `The diff file '${filePath}' is binary.`);
|
|
1874
|
-
}
|
|
1875
|
-
return result.body;
|
|
1876
|
-
};
|
|
1877
|
-
const [oldContents, newContents] = await Promise.all([
|
|
1878
|
-
input.changeType === "new" ? Promise.resolve("") : readFile(baseRef, input.oldPath),
|
|
1879
|
-
input.changeType === "deleted" ? Promise.resolve("") : readFile(headRef, input.newPath)
|
|
1880
|
-
]);
|
|
1881
|
-
return { oldContents, newContents };
|
|
1882
|
-
};
|
|
1883
1911
|
var listReviewerCandidates = async (ctx, input) => {
|
|
1884
1912
|
const { owner, name } = selector(input, "listReviewerCandidates");
|
|
1885
1913
|
const decoded = decodeReviewerCandidates(
|
|
@@ -4456,13 +4484,6 @@ var WORKSPACE_PROJECT_SCHEMA = {
|
|
|
4456
4484
|
}
|
|
4457
4485
|
}
|
|
4458
4486
|
};
|
|
4459
|
-
var workspaceProjectOf = (project) => ({
|
|
4460
|
-
projectId: project.projectId,
|
|
4461
|
-
title: project.title,
|
|
4462
|
-
workspaceRoot: project.workspaceRoot,
|
|
4463
|
-
repositoryIdentity: project.repositoryIdentity,
|
|
4464
|
-
...project.archivedAt == null ? {} : { archivedAt: project.archivedAt }
|
|
4465
|
-
});
|
|
4466
4487
|
var DIFF_STREAM_ITEM_SCHEMA = {
|
|
4467
4488
|
oneOf: [
|
|
4468
4489
|
{
|
|
@@ -4498,10 +4519,11 @@ var DIFF_STREAM_ITEM_SCHEMA = {
|
|
|
4498
4519
|
};
|
|
4499
4520
|
var index_default = definePlugin({
|
|
4500
4521
|
id: "pull-requests",
|
|
4501
|
-
apiVersion:
|
|
4522
|
+
apiVersion: 6,
|
|
4502
4523
|
activate: (ctx) => {
|
|
4503
4524
|
const service = createPullRequestService({
|
|
4504
|
-
|
|
4525
|
+
// 要全部(含已归档,按号点名时用)并解析仓库身份:项目选择器与认领都靠它。
|
|
4526
|
+
listProjects: async () => (await ctx.projects.list({})).map(workspaceShellOf),
|
|
4505
4527
|
apis: [gitlabApi(ctx), githubApi(ctx)],
|
|
4506
4528
|
onRefreshFailure: (error) => ctx.log.warn("stale diff refresh failed", { detail: String(error) }),
|
|
4507
4529
|
// 编排事件流里没有「合并了」这个转移,所以这条触发事件只能从这里报。不 await:
|
|
@@ -4651,9 +4673,9 @@ var index_default = definePlugin({
|
|
|
4651
4673
|
properties: { projects: { type: "array", items: WORKSPACE_PROJECT_SCHEMA } }
|
|
4652
4674
|
},
|
|
4653
4675
|
handle: async () => {
|
|
4654
|
-
const projects = await ctx.
|
|
4676
|
+
const projects = (await ctx.projects.list({})).map(workspaceShellOf);
|
|
4655
4677
|
return {
|
|
4656
|
-
projects: projects.filter((project) => !isArchivedWorkspaceProject(project))
|
|
4678
|
+
projects: projects.filter((project) => !isArchivedWorkspaceProject(project))
|
|
4657
4679
|
};
|
|
4658
4680
|
}
|
|
4659
4681
|
});
|
|
@@ -4674,10 +4696,11 @@ var index_default = definePlugin({
|
|
|
4674
4696
|
properties: { project: { oneOf: [WORKSPACE_PROJECT_SCHEMA, { type: "null" }] } }
|
|
4675
4697
|
},
|
|
4676
4698
|
handle: async (payload) => {
|
|
4677
|
-
const project = await
|
|
4699
|
+
const project = await projectOrNull(
|
|
4700
|
+
ctx.projects,
|
|
4678
4701
|
as(payload).projectId
|
|
4679
4702
|
);
|
|
4680
|
-
return { project: project === null ? null :
|
|
4703
|
+
return { project: project === null ? null : workspaceShellOf(project) };
|
|
4681
4704
|
}
|
|
4682
4705
|
});
|
|
4683
4706
|
ctx.settingsCard({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/plugin-pull-requests",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3002",
|
|
4
4
|
"description": "The pull request page, for GitHub and GitLab.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pull-requests",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"tailwindcss": "^4.0.0",
|
|
31
31
|
"typescript": "~6.0.3",
|
|
32
32
|
"vite-plus": "0.2.2",
|
|
33
|
-
"@ycodium-ai/plugin-api": "0.2.
|
|
33
|
+
"@ycodium-ai/plugin-api": "0.2.3002",
|
|
34
34
|
"ycodium-markdown-fence": "0.0.0"
|
|
35
35
|
},
|
|
36
36
|
"ycodium": {
|