paperclip-github-plugin 0.8.4 → 0.8.6
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/README.md +1 -1
- package/dist/manifest.js +1 -1
- package/dist/worker.js +161 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -170,7 +170,7 @@ Additional behavior:
|
|
|
170
170
|
- If the Paperclip host initially creates that imported maintainer issue in `backlog`, GitHub Sync promotes it to `todo` without replacing the configured default assignee with the executor handoff assignee, so triage ownership stays intact.
|
|
171
171
|
- When Paperclip board access is connected for a company, the advanced assignee dropdowns list both company agents and `Me` for the connected board user.
|
|
172
172
|
- Newly imported issues that finish sync in `todo` and are assigned to an agent enqueue an assignee wakeup so the agent can pick them up promptly.
|
|
173
|
-
- For linked pull requests, GitHub Sync treats merge-conflict, behind-branch, blocked, draft, unstable merge states, and unresolved review threads as executor work, while merge-ready states such as `CLEAN` and `HAS_HOOKS` can move work into `in_review` when CI is green and review threads are resolved. A stale aggregate `CHANGES_REQUESTED` review decision alone does not move that maintainer wait back to active execution.
|
|
173
|
+
- For linked pull requests, GitHub Sync treats merge-conflict, behind-branch, blocked, draft, unstable merge states, and unresolved review threads as executor work, while merge-ready states such as `CLEAN` and `HAS_HOOKS` can move work into `in_review` when CI is green and review threads are resolved. A stale aggregate `CHANGES_REQUESTED` review decision alone does not move that maintainer wait back to active execution. Transient `UNKNOWN` mergeability also does not move an already `in_review` maintainer wait back to active execution when CI is green and review threads are resolved.
|
|
174
174
|
- Imported issues that are already `blocked` stay `blocked` while any first-class `blockedBy` issue is still non-terminal, even if the linked GitHub pull request is otherwise green and review-ready.
|
|
175
175
|
- When sync moves work into `in_review`, GitHub Sync first follows the Paperclip issue execution policy's current reviewer or approver when that stage is visible on the issue. If Paperclip exposes an internal review or approval stage but not yet the participant, the plugin falls back to the configured reviewer or approver handoff assignee. If the transition is only a healthy linked-PR wait with no visible internal review or approval stage, GitHub Sync leaves the issue unassigned so it can wait on normal maintainer review without waking an internal owner.
|
|
176
176
|
- When sync moves work back into active execution, GitHub Sync first follows the Paperclip issue execution policy `returnAssignee` when it is available. Otherwise it falls back to the configured executor handoff assignee and then to the default imported assignee.
|
package/dist/manifest.js
CHANGED
|
@@ -535,7 +535,7 @@ var COMPANY_METRIC_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_ID}/a
|
|
|
535
535
|
var require2 = createRequire(import.meta.url);
|
|
536
536
|
var packageJson = require2("../package.json");
|
|
537
537
|
var SCHEDULE_TICK_CRON = "* * * * *";
|
|
538
|
-
var MANIFEST_VERSION = "0.8.
|
|
538
|
+
var MANIFEST_VERSION = "0.8.6"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
|
|
539
539
|
var manifest = {
|
|
540
540
|
id: GITHUB_SYNC_PLUGIN_ID,
|
|
541
541
|
apiVersion: 1,
|
package/dist/worker.js
CHANGED
|
@@ -1447,7 +1447,16 @@ function formatGitHubIssueCountLabel(count) {
|
|
|
1447
1447
|
return `${normalizedCount} GitHub ${normalizedCount === 1 ? "issue" : "issues"}`;
|
|
1448
1448
|
}
|
|
1449
1449
|
function getErrorMessage(error) {
|
|
1450
|
-
|
|
1450
|
+
if (error instanceof Error) {
|
|
1451
|
+
return error.message;
|
|
1452
|
+
}
|
|
1453
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
1454
|
+
const message = error.message;
|
|
1455
|
+
if (typeof message === "string") {
|
|
1456
|
+
return message;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
return String(error);
|
|
1451
1460
|
}
|
|
1452
1461
|
function isPaperclipLabelSyncError(error) {
|
|
1453
1462
|
return error instanceof PaperclipLabelSyncError;
|
|
@@ -1489,6 +1498,88 @@ function getErrorResponseDataMessage(error) {
|
|
|
1489
1498
|
const message = data.message;
|
|
1490
1499
|
return typeof message === "string" && message.trim() ? message.trim() : void 0;
|
|
1491
1500
|
}
|
|
1501
|
+
function getGitHubRequestId(error) {
|
|
1502
|
+
const requestId = getErrorResponseHeaders(error)["x-github-request-id"]?.trim();
|
|
1503
|
+
return requestId || void 0;
|
|
1504
|
+
}
|
|
1505
|
+
function buildGitHubOctokitLogMetadata(context) {
|
|
1506
|
+
const metadata = {};
|
|
1507
|
+
const companyId = normalizeCompanyId(context.companyId);
|
|
1508
|
+
const operation = normalizeOptionalString2(context.operation);
|
|
1509
|
+
const repositoryUrl = normalizeOptionalString2(context.repositoryUrl);
|
|
1510
|
+
const toolName = normalizeOptionalString2(context.toolName);
|
|
1511
|
+
if (companyId) {
|
|
1512
|
+
metadata.companyId = companyId;
|
|
1513
|
+
}
|
|
1514
|
+
if (operation) {
|
|
1515
|
+
metadata.operation = operation;
|
|
1516
|
+
}
|
|
1517
|
+
if (repositoryUrl) {
|
|
1518
|
+
metadata.repositoryUrl = repositoryUrl;
|
|
1519
|
+
}
|
|
1520
|
+
if (context.syncTrigger) {
|
|
1521
|
+
metadata.syncTrigger = context.syncTrigger;
|
|
1522
|
+
}
|
|
1523
|
+
if (toolName) {
|
|
1524
|
+
metadata.toolName = toolName;
|
|
1525
|
+
}
|
|
1526
|
+
return metadata;
|
|
1527
|
+
}
|
|
1528
|
+
function getGitHubOctokitRequestPath(url, baseUrl) {
|
|
1529
|
+
if (typeof url !== "string" || !url.trim()) {
|
|
1530
|
+
return void 0;
|
|
1531
|
+
}
|
|
1532
|
+
const trimmedUrl = url.trim();
|
|
1533
|
+
if (typeof baseUrl === "string" && baseUrl.trim() && trimmedUrl.startsWith(baseUrl.trim())) {
|
|
1534
|
+
return trimmedUrl.slice(baseUrl.trim().length) || "/";
|
|
1535
|
+
}
|
|
1536
|
+
try {
|
|
1537
|
+
const parsed = new URL(trimmedUrl);
|
|
1538
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
1539
|
+
} catch {
|
|
1540
|
+
return trimmedUrl;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
function createGitHubOctokit(ctx, token, context = {}) {
|
|
1544
|
+
const octokit = new Octokit({
|
|
1545
|
+
auth: token,
|
|
1546
|
+
log: {
|
|
1547
|
+
debug: () => void 0,
|
|
1548
|
+
info: () => void 0,
|
|
1549
|
+
warn: (message) => {
|
|
1550
|
+
ctx.logger.warn("GitHub Octokit warning.", {
|
|
1551
|
+
...buildGitHubOctokitLogMetadata(context),
|
|
1552
|
+
message
|
|
1553
|
+
});
|
|
1554
|
+
},
|
|
1555
|
+
error: () => void 0
|
|
1556
|
+
}
|
|
1557
|
+
});
|
|
1558
|
+
if (context.logFailures === false) {
|
|
1559
|
+
return octokit;
|
|
1560
|
+
}
|
|
1561
|
+
octokit.hook.wrap("request", async (request, options) => {
|
|
1562
|
+
const start = Date.now();
|
|
1563
|
+
const requestOptions = octokit.request.endpoint.parse(options);
|
|
1564
|
+
try {
|
|
1565
|
+
return await request(options);
|
|
1566
|
+
} catch (error) {
|
|
1567
|
+
const responseMessage = getErrorResponseDataMessage(error);
|
|
1568
|
+
ctx.logger.warn("GitHub API request failed.", {
|
|
1569
|
+
...buildGitHubOctokitLogMetadata(context),
|
|
1570
|
+
method: requestOptions.method,
|
|
1571
|
+
path: getGitHubOctokitRequestPath(requestOptions.url, options.baseUrl),
|
|
1572
|
+
status: getErrorStatus(error) ?? null,
|
|
1573
|
+
requestId: getGitHubRequestId(error) ?? null,
|
|
1574
|
+
durationMs: Date.now() - start,
|
|
1575
|
+
error: getErrorMessage(error),
|
|
1576
|
+
...responseMessage ? { responseMessage } : {}
|
|
1577
|
+
});
|
|
1578
|
+
throw error;
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1581
|
+
return octokit;
|
|
1582
|
+
}
|
|
1492
1583
|
function getErrorResponseDataErrors(error) {
|
|
1493
1584
|
if (!error || typeof error !== "object" || !("response" in error)) {
|
|
1494
1585
|
return [];
|
|
@@ -4889,7 +4980,9 @@ function resolvePaperclipStatusFromLinkedPullRequests(linkedPullRequests, option
|
|
|
4889
4980
|
)) {
|
|
4890
4981
|
return options?.preferInProgress ? "in_progress" : "todo";
|
|
4891
4982
|
}
|
|
4892
|
-
if (linkedPullRequests.length > 0 && linkedPullRequests.every(
|
|
4983
|
+
if (linkedPullRequests.length > 0 && linkedPullRequests.every(
|
|
4984
|
+
(pullRequest) => isGitHubPullRequestReviewReadyForSync(pullRequest) || options?.preserveTransientUnknownMergeabilityWait === true && isGitHubPullRequestTransientUnknownMergeabilityWait(pullRequest)
|
|
4985
|
+
)) {
|
|
4893
4986
|
return "in_review";
|
|
4894
4987
|
}
|
|
4895
4988
|
return "in_progress";
|
|
@@ -5033,6 +5126,10 @@ function hasUnresolvedPaperclipIssueBlockerSummary(blockers) {
|
|
|
5033
5126
|
return status !== "done" && status !== "cancelled";
|
|
5034
5127
|
});
|
|
5035
5128
|
}
|
|
5129
|
+
function isMissingIssueRelationsReadCapabilityError(error) {
|
|
5130
|
+
const message = getErrorMessage(error);
|
|
5131
|
+
return /missing required capability/i.test(message) && /issue\.relations\.read/i.test(message) && /issues\.relations\.get/i.test(message);
|
|
5132
|
+
}
|
|
5036
5133
|
async function hasUnresolvedPaperclipIssueBlocker(ctx, issue, companyId) {
|
|
5037
5134
|
const record = issue;
|
|
5038
5135
|
if (hasUnresolvedPaperclipIssueBlockerSummary(record.blockedBy)) {
|
|
@@ -5041,8 +5138,15 @@ async function hasUnresolvedPaperclipIssueBlocker(ctx, issue, companyId) {
|
|
|
5041
5138
|
if (typeof ctx.issues.relations?.get !== "function") {
|
|
5042
5139
|
return false;
|
|
5043
5140
|
}
|
|
5044
|
-
|
|
5045
|
-
|
|
5141
|
+
try {
|
|
5142
|
+
const relations = await ctx.issues.relations.get(issue.id, companyId);
|
|
5143
|
+
return hasUnresolvedPaperclipIssueBlockerSummary(relations.blockedBy);
|
|
5144
|
+
} catch (error) {
|
|
5145
|
+
if (isMissingIssueRelationsReadCapabilityError(error)) {
|
|
5146
|
+
return false;
|
|
5147
|
+
}
|
|
5148
|
+
throw error;
|
|
5149
|
+
}
|
|
5046
5150
|
}
|
|
5047
5151
|
function isSamePaperclipIssueAssigneePrincipal(left, right) {
|
|
5048
5152
|
if (!left || !right) {
|
|
@@ -5415,7 +5519,8 @@ function resolvePaperclipIssueStatus(params) {
|
|
|
5415
5519
|
}
|
|
5416
5520
|
if (snapshot.linkedPullRequests.length > 0) {
|
|
5417
5521
|
return resolvePaperclipStatusFromLinkedPullRequests(snapshot.linkedPullRequests, {
|
|
5418
|
-
preferInProgress: hasExecutorHandoffTarget
|
|
5522
|
+
preferInProgress: hasExecutorHandoffTarget,
|
|
5523
|
+
preserveTransientUnknownMergeabilityWait: currentStatus === "done" || currentStatus === "in_review"
|
|
5419
5524
|
});
|
|
5420
5525
|
}
|
|
5421
5526
|
if (wasImportedThisRun) {
|
|
@@ -5432,7 +5537,8 @@ function resolvePaperclipPullRequestIssueStatus(params) {
|
|
|
5432
5537
|
return currentStatus;
|
|
5433
5538
|
}
|
|
5434
5539
|
return resolvePaperclipStatusFromLinkedPullRequests([pullRequest], {
|
|
5435
|
-
preferInProgress: hasExecutorHandoffTarget
|
|
5540
|
+
preferInProgress: hasExecutorHandoffTarget,
|
|
5541
|
+
preserveTransientUnknownMergeabilityWait: currentStatus === "in_review"
|
|
5436
5542
|
});
|
|
5437
5543
|
}
|
|
5438
5544
|
async function listLinkedPullRequestsForIssue(octokit, repository, issueNumber) {
|
|
@@ -5581,6 +5687,9 @@ function normalizeGitHubPullRequestReviewDecision(value) {
|
|
|
5581
5687
|
function isGitHubPullRequestActionRequiredForSync(pullRequest) {
|
|
5582
5688
|
return pullRequest.mergeability === "conflicting" || ACTION_REQUIRED_GITHUB_PULL_REQUEST_MERGE_STATE_STATUSES.has(pullRequest.mergeStateStatus);
|
|
5583
5689
|
}
|
|
5690
|
+
function isGitHubPullRequestTransientUnknownMergeabilityWait(pullRequest) {
|
|
5691
|
+
return pullRequest.ciState === "green" && !pullRequest.hasUnresolvedReviewThreads && pullRequest.mergeability !== "conflicting" && pullRequest.mergeStateStatus === "unknown";
|
|
5692
|
+
}
|
|
5584
5693
|
function isGitHubPullRequestReviewReadyForSync(pullRequest) {
|
|
5585
5694
|
if (pullRequest.ciState !== "green" || pullRequest.hasUnresolvedReviewThreads) {
|
|
5586
5695
|
return false;
|
|
@@ -9751,12 +9860,16 @@ async function handleCompanyMetricApiRoute(ctx, input) {
|
|
|
9751
9860
|
}
|
|
9752
9861
|
};
|
|
9753
9862
|
}
|
|
9754
|
-
async function createGitHubToolOctokit(ctx, companyId) {
|
|
9863
|
+
async function createGitHubToolOctokit(ctx, companyId, context = {}) {
|
|
9755
9864
|
const token = (await resolveGithubToken(ctx, { companyId })).trim();
|
|
9756
9865
|
if (!token) {
|
|
9757
9866
|
throw new Error(MISSING_GITHUB_TOKEN_SYNC_MESSAGE);
|
|
9758
9867
|
}
|
|
9759
|
-
return
|
|
9868
|
+
return createGitHubOctokit(ctx, token, {
|
|
9869
|
+
companyId,
|
|
9870
|
+
operation: "github-api",
|
|
9871
|
+
...context
|
|
9872
|
+
});
|
|
9760
9873
|
}
|
|
9761
9874
|
async function listGitHubRepositoryOpenPullRequestNumbers(octokit, repository) {
|
|
9762
9875
|
const response = await octokit.rest.pulls.list({
|
|
@@ -12657,8 +12770,11 @@ function mergeNamedValues(currentValues, params) {
|
|
|
12657
12770
|
}
|
|
12658
12771
|
return [...values.values()];
|
|
12659
12772
|
}
|
|
12660
|
-
async function validateGithubToken(token) {
|
|
12661
|
-
const octokit =
|
|
12773
|
+
async function validateGithubToken(ctx, token) {
|
|
12774
|
+
const octokit = createGitHubOctokit(ctx, token.trim(), {
|
|
12775
|
+
logFailures: false,
|
|
12776
|
+
operation: "settings.validateToken"
|
|
12777
|
+
});
|
|
12662
12778
|
try {
|
|
12663
12779
|
const response = await octokit.rest.users.getAuthenticated();
|
|
12664
12780
|
return {
|
|
@@ -12770,7 +12886,12 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
12770
12886
|
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
12771
12887
|
}
|
|
12772
12888
|
activePaperclipApiAuthTokensByCompanyId = await resolvePaperclipApiAuthTokens(ctx, settings, config, mappings);
|
|
12773
|
-
const
|
|
12889
|
+
const octokitLogContext = {
|
|
12890
|
+
companyId: targetCompanyId,
|
|
12891
|
+
operation: "sync.github-issues",
|
|
12892
|
+
syncTrigger: trigger
|
|
12893
|
+
};
|
|
12894
|
+
const octokit = createGitHubOctokit(ctx, token, octokitLogContext);
|
|
12774
12895
|
let syncedIssuesCount = 0;
|
|
12775
12896
|
let createdIssuesCount = 0;
|
|
12776
12897
|
let skippedIssuesCount = 0;
|
|
@@ -12920,6 +13041,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
12920
13041
|
await throwIfSyncCancelled();
|
|
12921
13042
|
try {
|
|
12922
13043
|
const repository = requireRepositoryReference(mapping.repositoryUrl);
|
|
13044
|
+
octokitLogContext.repositoryUrl = repository.url;
|
|
12923
13045
|
const importedIssueRecords = nextRegistry.filter((entry) => doesImportedIssueRecordMatchMapping(entry, mapping)).filter((entry) => doesImportedIssueMatchTarget(entry, options.target));
|
|
12924
13046
|
const shouldLoadClosedIssues = options.target?.kind === "issue" || importedIssueRecords.length > 0;
|
|
12925
13047
|
currentProgress = {
|
|
@@ -13041,6 +13163,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
13041
13163
|
await throwIfSyncCancelled();
|
|
13042
13164
|
try {
|
|
13043
13165
|
const { mapping, advancedSettings, repository, repositoryIndex, allIssuesById, issues, pullRequestLinks } = plan;
|
|
13166
|
+
octokitLogContext.repositoryUrl = repository.url;
|
|
13044
13167
|
const companyId = mapping.companyId;
|
|
13045
13168
|
let availableLabels = companyId ? companyLabelDirectoryCache.get(companyId) : void 0;
|
|
13046
13169
|
if (!availableLabels) {
|
|
@@ -13482,13 +13605,19 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
13482
13605
|
}
|
|
13483
13606
|
}
|
|
13484
13607
|
function registerGitHubAgentTools(ctx) {
|
|
13608
|
+
async function createAgentToolOctokit(runCtx, toolName, repository) {
|
|
13609
|
+
return createGitHubToolOctokit(ctx, runCtx.companyId, {
|
|
13610
|
+
toolName,
|
|
13611
|
+
...repository ? { repositoryUrl: repository.url } : {}
|
|
13612
|
+
});
|
|
13613
|
+
}
|
|
13485
13614
|
ctx.tools.register(
|
|
13486
13615
|
"search_repository_items",
|
|
13487
13616
|
getGitHubAgentToolDeclaration("search_repository_items"),
|
|
13488
13617
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13489
13618
|
const input = getToolInputRecord(params);
|
|
13490
|
-
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
13491
13619
|
const repository = await resolveGitHubToolRepository(ctx, runCtx, input);
|
|
13620
|
+
const octokit = await createAgentToolOctokit(runCtx, "search_repository_items", repository);
|
|
13492
13621
|
const rawQuery = normalizeOptionalToolString(input.query);
|
|
13493
13622
|
if (!rawQuery) {
|
|
13494
13623
|
throw new Error("query is required.");
|
|
@@ -13556,7 +13685,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13556
13685
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13557
13686
|
const input = getToolInputRecord(params);
|
|
13558
13687
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13559
|
-
const octokit = await
|
|
13688
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_issue", target.repository);
|
|
13560
13689
|
const response = await octokit.rest.issues.get({
|
|
13561
13690
|
owner: target.repository.owner,
|
|
13562
13691
|
repo: target.repository.repo,
|
|
@@ -13603,7 +13732,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13603
13732
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13604
13733
|
const input = getToolInputRecord(params);
|
|
13605
13734
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13606
|
-
const octokit = await
|
|
13735
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_issue_comments", target.repository);
|
|
13607
13736
|
const comments = await listAllGitHubIssueComments(octokit, target.repository, target.issueNumber);
|
|
13608
13737
|
return buildToolSuccessResult(
|
|
13609
13738
|
`Loaded ${comments.length} GitHub ${comments.length === 1 ? "comment" : "comments"} from issue #${target.issueNumber}.`,
|
|
@@ -13621,7 +13750,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13621
13750
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13622
13751
|
const input = getToolInputRecord(params);
|
|
13623
13752
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13624
|
-
const octokit = await
|
|
13753
|
+
const octokit = await createAgentToolOctokit(runCtx, "update_issue", target.repository);
|
|
13625
13754
|
const currentResponse = await octokit.rest.issues.get({
|
|
13626
13755
|
owner: target.repository.owner,
|
|
13627
13756
|
repo: target.repository.repo,
|
|
@@ -13694,7 +13823,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13694
13823
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13695
13824
|
const input = getToolInputRecord(params);
|
|
13696
13825
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13697
|
-
const octokit = await
|
|
13826
|
+
const octokit = await createAgentToolOctokit(runCtx, "assign_to_current_user", target.repository);
|
|
13698
13827
|
const [currentResponse, authenticatedUserResponse] = await Promise.all([
|
|
13699
13828
|
octokit.rest.issues.get({
|
|
13700
13829
|
owner: target.repository.owner,
|
|
@@ -13754,7 +13883,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13754
13883
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13755
13884
|
const input = getToolInputRecord(params);
|
|
13756
13885
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13757
|
-
const octokit = await
|
|
13886
|
+
const octokit = await createAgentToolOctokit(runCtx, "add_issue_comment", target.repository);
|
|
13758
13887
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), "comment", normalizeOptionalToolString(input.llmModel));
|
|
13759
13888
|
const response = await octokit.rest.issues.createComment({
|
|
13760
13889
|
owner: target.repository.owner,
|
|
@@ -13804,7 +13933,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13804
13933
|
"pull request description",
|
|
13805
13934
|
normalizeOptionalToolString(input.llmModel)
|
|
13806
13935
|
) : void 0;
|
|
13807
|
-
const octokit = await
|
|
13936
|
+
const octokit = await createAgentToolOctokit(runCtx, "create_pull_request", repository);
|
|
13808
13937
|
const response = await octokit.rest.pulls.create({
|
|
13809
13938
|
owner: repository.owner,
|
|
13810
13939
|
repo: repository.repo,
|
|
@@ -13880,7 +14009,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13880
14009
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13881
14010
|
const input = getToolInputRecord(params);
|
|
13882
14011
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
13883
|
-
const octokit = await
|
|
14012
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_pull_request", target.repository);
|
|
13884
14013
|
const response = await octokit.rest.pulls.get({
|
|
13885
14014
|
owner: target.repository.owner,
|
|
13886
14015
|
repo: target.repository.repo,
|
|
@@ -13928,7 +14057,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13928
14057
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13929
14058
|
const input = getToolInputRecord(params);
|
|
13930
14059
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
13931
|
-
const octokit = await
|
|
14060
|
+
const octokit = await createAgentToolOctokit(runCtx, "update_pull_request", target.repository);
|
|
13932
14061
|
let currentResponse = await octokit.rest.pulls.get({
|
|
13933
14062
|
owner: target.repository.owner,
|
|
13934
14063
|
repo: target.repository.repo,
|
|
@@ -13994,7 +14123,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13994
14123
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13995
14124
|
const input = getToolInputRecord(params);
|
|
13996
14125
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
13997
|
-
const octokit = await
|
|
14126
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_pull_request_files", target.repository);
|
|
13998
14127
|
const files = await listAllPullRequestFiles(octokit, target.repository, target.pullRequestNumber);
|
|
13999
14128
|
return buildToolSuccessResult(
|
|
14000
14129
|
`Loaded ${files.length} changed ${files.length === 1 ? "file" : "files"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -14012,7 +14141,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14012
14141
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14013
14142
|
const input = getToolInputRecord(params);
|
|
14014
14143
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14015
|
-
const octokit = await
|
|
14144
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_pull_request_checks", target.repository);
|
|
14016
14145
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
14017
14146
|
owner: target.repository.owner,
|
|
14018
14147
|
repo: target.repository.repo,
|
|
@@ -14111,7 +14240,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14111
14240
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14112
14241
|
const input = getToolInputRecord(params);
|
|
14113
14242
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14114
|
-
const octokit = await
|
|
14243
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_pull_request_review_threads", target.repository);
|
|
14115
14244
|
const threads = await listDetailedPullRequestReviewThreads(octokit, target.repository, target.pullRequestNumber);
|
|
14116
14245
|
return buildToolSuccessResult(
|
|
14117
14246
|
`Loaded ${threads.length} review ${threads.length === 1 ? "thread" : "threads"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -14133,7 +14262,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14133
14262
|
throw new Error("threadId is required.");
|
|
14134
14263
|
}
|
|
14135
14264
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), "comment", normalizeOptionalToolString(input.llmModel));
|
|
14136
|
-
const octokit = await
|
|
14265
|
+
const octokit = await createAgentToolOctokit(runCtx, "reply_to_review_thread");
|
|
14137
14266
|
const response = await octokit.graphql(
|
|
14138
14267
|
GITHUB_ADD_PULL_REQUEST_REVIEW_THREAD_REPLY_MUTATION,
|
|
14139
14268
|
{
|
|
@@ -14168,7 +14297,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14168
14297
|
if (!threadId) {
|
|
14169
14298
|
throw new Error("threadId is required.");
|
|
14170
14299
|
}
|
|
14171
|
-
const octokit = await
|
|
14300
|
+
const octokit = await createAgentToolOctokit(runCtx, "resolve_review_thread");
|
|
14172
14301
|
const response = await octokit.graphql(
|
|
14173
14302
|
GITHUB_RESOLVE_REVIEW_THREAD_MUTATION,
|
|
14174
14303
|
{
|
|
@@ -14199,7 +14328,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14199
14328
|
if (!threadId) {
|
|
14200
14329
|
throw new Error("threadId is required.");
|
|
14201
14330
|
}
|
|
14202
|
-
const octokit = await
|
|
14331
|
+
const octokit = await createAgentToolOctokit(runCtx, "unresolve_review_thread");
|
|
14203
14332
|
const response = await octokit.graphql(
|
|
14204
14333
|
GITHUB_UNRESOLVE_REVIEW_THREAD_MUTATION,
|
|
14205
14334
|
{
|
|
@@ -14232,7 +14361,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14232
14361
|
if (userReviewers.length === 0 && teamReviewers.length === 0) {
|
|
14233
14362
|
throw new Error("Provide at least one user reviewer or team reviewer.");
|
|
14234
14363
|
}
|
|
14235
|
-
const octokit = await
|
|
14364
|
+
const octokit = await createAgentToolOctokit(runCtx, "request_pull_request_reviewers", target.repository);
|
|
14236
14365
|
const response = await octokit.rest.pulls.requestReviewers({
|
|
14237
14366
|
owner: target.repository.owner,
|
|
14238
14367
|
repo: target.repository.repo,
|
|
@@ -14263,7 +14392,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14263
14392
|
if (!organization) {
|
|
14264
14393
|
throw new Error("organization is required.");
|
|
14265
14394
|
}
|
|
14266
|
-
const octokit = await
|
|
14395
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_organization_projects");
|
|
14267
14396
|
const projects = await listGitHubOrganizationProjects(octokit, organization, {
|
|
14268
14397
|
includeClosed: input.includeClosed === true,
|
|
14269
14398
|
query: normalizeOptionalToolString(input.query),
|
|
@@ -14284,7 +14413,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14284
14413
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14285
14414
|
const input = getToolInputRecord(params);
|
|
14286
14415
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14287
|
-
const octokit = await
|
|
14416
|
+
const octokit = await createAgentToolOctokit(runCtx, "add_pull_request_to_project", target.repository);
|
|
14288
14417
|
const projectTarget = await resolveGitHubProjectToolTarget(octokit, input);
|
|
14289
14418
|
const pullRequest = await getGitHubPullRequestProjectItems(
|
|
14290
14419
|
octokit,
|
|
@@ -14353,6 +14482,8 @@ function shouldStartWorkerHost(moduleUrl, entry = process.argv[1]) {
|
|
|
14353
14482
|
}
|
|
14354
14483
|
var __testing = {
|
|
14355
14484
|
buildSyncFallbackExecutionStatePatch,
|
|
14485
|
+
createGitHubToolOctokit,
|
|
14486
|
+
hasUnresolvedPaperclipIssueBlocker,
|
|
14356
14487
|
isHealthyMaintainerWaitTransition,
|
|
14357
14488
|
resolveSyncTransitionAssignee
|
|
14358
14489
|
};
|
|
@@ -14653,7 +14784,7 @@ var plugin = definePlugin({
|
|
|
14653
14784
|
if (!trimmedToken) {
|
|
14654
14785
|
throw new Error("Enter a GitHub token.");
|
|
14655
14786
|
}
|
|
14656
|
-
return validateGithubToken(trimmedToken);
|
|
14787
|
+
return validateGithubToken(ctx, trimmedToken);
|
|
14657
14788
|
});
|
|
14658
14789
|
ctx.actions.register("project.pullRequests.createIssue", async (input) => {
|
|
14659
14790
|
const record = input && typeof input === "object" ? input : {};
|