paperclip-github-plugin 0.8.5 → 0.8.7
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 +3 -3
- package/dist/manifest.js +1 -1
- package/dist/worker.js +156 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ If a company already has a Paperclip project bound to a GitHub repository worksp
|
|
|
62
62
|
|
|
63
63
|
### Status sync with delivery context
|
|
64
64
|
|
|
65
|
-
The plugin does more than mirror issue text. It looks at linked pull requests, mergeability, CI, review decisions, review threads, and trusted new GitHub comments so imported Paperclip issues can reflect where the work actually is. When GitHub links an issue to a pull request in another repository, GitHub Sync now follows that pull request's actual repository for status checks, review state, and deep links instead of assuming the issue repository. When sync closes an imported issue as `done` or `cancelled`, it also clears any pending Paperclip review or approval execution state so the host accepts the terminal transition cleanly.
|
|
65
|
+
The plugin does more than mirror issue text. It looks at linked pull requests, mergeability, CI, review decisions, review threads, and trusted new GitHub comments so imported Paperclip issues can reflect where the work actually is. When GitHub links an issue to a pull request in another repository, GitHub Sync now follows that pull request's actual repository for status checks, review state, and deep links instead of assuming the issue repository. When sync closes an imported issue as `done` or `cancelled`, it also clears any pending Paperclip review or approval execution policy/state so the host accepts the terminal transition cleanly and does not keep waking stale review participants.
|
|
66
66
|
|
|
67
67
|
### Company KPI dashboard
|
|
68
68
|
|
|
@@ -158,7 +158,7 @@ When the local Paperclip API is available, the plugin also syncs labels by name,
|
|
|
158
158
|
| --- | --- |
|
|
159
159
|
| Open issue with no linked pull request, created by a repository maintainer | `todo` on first import |
|
|
160
160
|
| Open issue with no linked pull request | Configured default status, which defaults to `backlog` |
|
|
161
|
-
| Open issue with a linked pull request and unfinished CI | `in_progress` |
|
|
161
|
+
| Open issue with a linked pull request and unfinished CI | `in_progress`; already-blocked pending-only PR waits remain `blocked` |
|
|
162
162
|
| Open issue with failing CI, a non-mergeable linked pull request, or unresolved review threads | `todo`, or `in_progress` when GitHub Sync can hand the work back to an executor |
|
|
163
163
|
| Open issue with green CI, a merge-ready linked pull request, and all review threads resolved | `in_review` |
|
|
164
164
|
| Closed issue completed as finished work | `done` |
|
|
@@ -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. 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.
|
|
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. If an issue is already `blocked` and GitHub reports only pending external merge requirements while CI is unfinished, sync preserves the external wait instead of waking an executor. 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.7"?.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
|
@@ -1498,6 +1498,88 @@ function getErrorResponseDataMessage(error) {
|
|
|
1498
1498
|
const message = data.message;
|
|
1499
1499
|
return typeof message === "string" && message.trim() ? message.trim() : void 0;
|
|
1500
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
|
+
}
|
|
1501
1583
|
function getErrorResponseDataErrors(error) {
|
|
1502
1584
|
if (!error || typeof error !== "object" || !("response" in error)) {
|
|
1503
1585
|
return [];
|
|
@@ -5247,6 +5329,9 @@ function isHealthyMaintainerWaitTransition(params) {
|
|
|
5247
5329
|
const { currentStatus, nextStatus, syncContext } = params;
|
|
5248
5330
|
return nextStatus === "in_review" && (currentStatus === "done" || currentStatus === "in_review") && syncContext.executionState === null && syncContext.executionPolicy !== null;
|
|
5249
5331
|
}
|
|
5332
|
+
function shouldClearCompletedSyncExecutionPolicy(params) {
|
|
5333
|
+
return (params.nextStatus === "done" || params.nextStatus === "cancelled") && (params.syncContext.executionPolicy !== null || params.syncContext.executionState !== null);
|
|
5334
|
+
}
|
|
5250
5335
|
function shouldPreserveImportedTriageAssignee(params) {
|
|
5251
5336
|
return params.wasImportedThisRun && params.maintainerAuthoredImportedIssue === true && params.currentStatus === "backlog" && params.nextStatus === "todo";
|
|
5252
5337
|
}
|
|
@@ -5436,6 +5521,12 @@ function resolvePaperclipIssueStatus(params) {
|
|
|
5436
5521
|
return hasExecutorHandoffTarget ? "in_progress" : "todo";
|
|
5437
5522
|
}
|
|
5438
5523
|
if (snapshot.linkedPullRequests.length > 0) {
|
|
5524
|
+
if (shouldPreserveBlockedExternalPullRequestWait({
|
|
5525
|
+
currentStatus,
|
|
5526
|
+
linkedPullRequests: snapshot.linkedPullRequests
|
|
5527
|
+
})) {
|
|
5528
|
+
return "blocked";
|
|
5529
|
+
}
|
|
5439
5530
|
return resolvePaperclipStatusFromLinkedPullRequests(snapshot.linkedPullRequests, {
|
|
5440
5531
|
preferInProgress: hasExecutorHandoffTarget,
|
|
5441
5532
|
preserveTransientUnknownMergeabilityWait: currentStatus === "done" || currentStatus === "in_review"
|
|
@@ -5454,6 +5545,12 @@ function resolvePaperclipPullRequestIssueStatus(params) {
|
|
|
5454
5545
|
if (currentStatus === "done" || currentStatus === "cancelled") {
|
|
5455
5546
|
return currentStatus;
|
|
5456
5547
|
}
|
|
5548
|
+
if (shouldPreserveBlockedExternalPullRequestWait({
|
|
5549
|
+
currentStatus,
|
|
5550
|
+
linkedPullRequests: [pullRequest]
|
|
5551
|
+
})) {
|
|
5552
|
+
return "blocked";
|
|
5553
|
+
}
|
|
5457
5554
|
return resolvePaperclipStatusFromLinkedPullRequests([pullRequest], {
|
|
5458
5555
|
preferInProgress: hasExecutorHandoffTarget,
|
|
5459
5556
|
preserveTransientUnknownMergeabilityWait: currentStatus === "in_review"
|
|
@@ -5605,6 +5702,12 @@ function normalizeGitHubPullRequestReviewDecision(value) {
|
|
|
5605
5702
|
function isGitHubPullRequestActionRequiredForSync(pullRequest) {
|
|
5606
5703
|
return pullRequest.mergeability === "conflicting" || ACTION_REQUIRED_GITHUB_PULL_REQUEST_MERGE_STATE_STATUSES.has(pullRequest.mergeStateStatus);
|
|
5607
5704
|
}
|
|
5705
|
+
function isGitHubPullRequestPendingExternalWaitForSync(pullRequest) {
|
|
5706
|
+
return pullRequest.ciState === "unfinished" && !pullRequest.hasUnresolvedReviewThreads && pullRequest.mergeability !== "conflicting" && (pullRequest.mergeStateStatus === "blocked" || pullRequest.mergeStateStatus === "unstable");
|
|
5707
|
+
}
|
|
5708
|
+
function shouldPreserveBlockedExternalPullRequestWait(params) {
|
|
5709
|
+
return params.currentStatus === "blocked" && params.linkedPullRequests.length > 0 && params.linkedPullRequests.every((pullRequest) => isGitHubPullRequestPendingExternalWaitForSync(pullRequest));
|
|
5710
|
+
}
|
|
5608
5711
|
function isGitHubPullRequestTransientUnknownMergeabilityWait(pullRequest) {
|
|
5609
5712
|
return pullRequest.ciState === "green" && !pullRequest.hasUnresolvedReviewThreads && pullRequest.mergeability !== "conflicting" && pullRequest.mergeStateStatus === "unknown";
|
|
5610
5713
|
}
|
|
@@ -9089,6 +9192,10 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9089
9192
|
nextStatus,
|
|
9090
9193
|
syncContext: paperclipIssueSyncContext
|
|
9091
9194
|
});
|
|
9195
|
+
const shouldClearCompletedExecutionPolicy = shouldClearCompletedSyncExecutionPolicy({
|
|
9196
|
+
nextStatus,
|
|
9197
|
+
syncContext: paperclipIssueSyncContext
|
|
9198
|
+
});
|
|
9092
9199
|
const shouldPreserveImportedTriageRouting = shouldPreserveImportedTriageAssignee({
|
|
9093
9200
|
currentStatus: paperclipIssue.status,
|
|
9094
9201
|
nextStatus,
|
|
@@ -9110,7 +9217,7 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9110
9217
|
importedIssue.lastSeenGitHubState = snapshot.state;
|
|
9111
9218
|
importedIssue.linkedPullRequestCommentCounts = currentLinkedPullRequestCommentCounts;
|
|
9112
9219
|
if (paperclipIssue.status === nextStatus) {
|
|
9113
|
-
if (shouldClearTransitionAssignee) {
|
|
9220
|
+
if (shouldClearTransitionAssignee || shouldClearCompletedExecutionPolicy) {
|
|
9114
9221
|
updateSyncFailureContext(syncFailureContext, {
|
|
9115
9222
|
phase: "updating_paperclip_status",
|
|
9116
9223
|
repositoryUrl: repository.url,
|
|
@@ -9122,8 +9229,8 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9122
9229
|
currentStatus: paperclipIssue.status,
|
|
9123
9230
|
syncContext: paperclipIssueSyncContext,
|
|
9124
9231
|
nextStatus,
|
|
9125
|
-
clearAssignee: true,
|
|
9126
|
-
...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
|
|
9232
|
+
...shouldClearTransitionAssignee ? { clearAssignee: true } : {},
|
|
9233
|
+
...shouldPreserveMaintainerWaitRouting || shouldClearCompletedExecutionPolicy ? { clearExecutionPolicy: true } : {},
|
|
9127
9234
|
transitionComment: "",
|
|
9128
9235
|
paperclipApiBaseUrl
|
|
9129
9236
|
});
|
|
@@ -9159,7 +9266,7 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9159
9266
|
nextStatus,
|
|
9160
9267
|
...nextTransitionAssignee ? { nextAssignee: nextTransitionAssignee.principal } : {},
|
|
9161
9268
|
...shouldClearTransitionAssignee ? { clearAssignee: true } : {},
|
|
9162
|
-
...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
|
|
9269
|
+
...shouldPreserveMaintainerWaitRouting || shouldClearCompletedExecutionPolicy ? { clearExecutionPolicy: true } : {},
|
|
9163
9270
|
transitionComment: transitionComment.body,
|
|
9164
9271
|
transitionCommentAnnotation: transitionComment.annotation,
|
|
9165
9272
|
paperclipApiBaseUrl
|
|
@@ -9778,12 +9885,16 @@ async function handleCompanyMetricApiRoute(ctx, input) {
|
|
|
9778
9885
|
}
|
|
9779
9886
|
};
|
|
9780
9887
|
}
|
|
9781
|
-
async function createGitHubToolOctokit(ctx, companyId) {
|
|
9888
|
+
async function createGitHubToolOctokit(ctx, companyId, context = {}) {
|
|
9782
9889
|
const token = (await resolveGithubToken(ctx, { companyId })).trim();
|
|
9783
9890
|
if (!token) {
|
|
9784
9891
|
throw new Error(MISSING_GITHUB_TOKEN_SYNC_MESSAGE);
|
|
9785
9892
|
}
|
|
9786
|
-
return
|
|
9893
|
+
return createGitHubOctokit(ctx, token, {
|
|
9894
|
+
companyId,
|
|
9895
|
+
operation: "github-api",
|
|
9896
|
+
...context
|
|
9897
|
+
});
|
|
9787
9898
|
}
|
|
9788
9899
|
async function listGitHubRepositoryOpenPullRequestNumbers(octokit, repository) {
|
|
9789
9900
|
const response = await octokit.rest.pulls.list({
|
|
@@ -12684,8 +12795,11 @@ function mergeNamedValues(currentValues, params) {
|
|
|
12684
12795
|
}
|
|
12685
12796
|
return [...values.values()];
|
|
12686
12797
|
}
|
|
12687
|
-
async function validateGithubToken(token) {
|
|
12688
|
-
const octokit =
|
|
12798
|
+
async function validateGithubToken(ctx, token) {
|
|
12799
|
+
const octokit = createGitHubOctokit(ctx, token.trim(), {
|
|
12800
|
+
logFailures: false,
|
|
12801
|
+
operation: "settings.validateToken"
|
|
12802
|
+
});
|
|
12689
12803
|
try {
|
|
12690
12804
|
const response = await octokit.rest.users.getAuthenticated();
|
|
12691
12805
|
return {
|
|
@@ -12797,7 +12911,12 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
12797
12911
|
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
12798
12912
|
}
|
|
12799
12913
|
activePaperclipApiAuthTokensByCompanyId = await resolvePaperclipApiAuthTokens(ctx, settings, config, mappings);
|
|
12800
|
-
const
|
|
12914
|
+
const octokitLogContext = {
|
|
12915
|
+
companyId: targetCompanyId,
|
|
12916
|
+
operation: "sync.github-issues",
|
|
12917
|
+
syncTrigger: trigger
|
|
12918
|
+
};
|
|
12919
|
+
const octokit = createGitHubOctokit(ctx, token, octokitLogContext);
|
|
12801
12920
|
let syncedIssuesCount = 0;
|
|
12802
12921
|
let createdIssuesCount = 0;
|
|
12803
12922
|
let skippedIssuesCount = 0;
|
|
@@ -12947,6 +13066,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
12947
13066
|
await throwIfSyncCancelled();
|
|
12948
13067
|
try {
|
|
12949
13068
|
const repository = requireRepositoryReference(mapping.repositoryUrl);
|
|
13069
|
+
octokitLogContext.repositoryUrl = repository.url;
|
|
12950
13070
|
const importedIssueRecords = nextRegistry.filter((entry) => doesImportedIssueRecordMatchMapping(entry, mapping)).filter((entry) => doesImportedIssueMatchTarget(entry, options.target));
|
|
12951
13071
|
const shouldLoadClosedIssues = options.target?.kind === "issue" || importedIssueRecords.length > 0;
|
|
12952
13072
|
currentProgress = {
|
|
@@ -13068,6 +13188,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
13068
13188
|
await throwIfSyncCancelled();
|
|
13069
13189
|
try {
|
|
13070
13190
|
const { mapping, advancedSettings, repository, repositoryIndex, allIssuesById, issues, pullRequestLinks } = plan;
|
|
13191
|
+
octokitLogContext.repositoryUrl = repository.url;
|
|
13071
13192
|
const companyId = mapping.companyId;
|
|
13072
13193
|
let availableLabels = companyId ? companyLabelDirectoryCache.get(companyId) : void 0;
|
|
13073
13194
|
if (!availableLabels) {
|
|
@@ -13509,13 +13630,19 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
13509
13630
|
}
|
|
13510
13631
|
}
|
|
13511
13632
|
function registerGitHubAgentTools(ctx) {
|
|
13633
|
+
async function createAgentToolOctokit(runCtx, toolName, repository) {
|
|
13634
|
+
return createGitHubToolOctokit(ctx, runCtx.companyId, {
|
|
13635
|
+
toolName,
|
|
13636
|
+
...repository ? { repositoryUrl: repository.url } : {}
|
|
13637
|
+
});
|
|
13638
|
+
}
|
|
13512
13639
|
ctx.tools.register(
|
|
13513
13640
|
"search_repository_items",
|
|
13514
13641
|
getGitHubAgentToolDeclaration("search_repository_items"),
|
|
13515
13642
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13516
13643
|
const input = getToolInputRecord(params);
|
|
13517
|
-
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
13518
13644
|
const repository = await resolveGitHubToolRepository(ctx, runCtx, input);
|
|
13645
|
+
const octokit = await createAgentToolOctokit(runCtx, "search_repository_items", repository);
|
|
13519
13646
|
const rawQuery = normalizeOptionalToolString(input.query);
|
|
13520
13647
|
if (!rawQuery) {
|
|
13521
13648
|
throw new Error("query is required.");
|
|
@@ -13583,7 +13710,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13583
13710
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13584
13711
|
const input = getToolInputRecord(params);
|
|
13585
13712
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13586
|
-
const octokit = await
|
|
13713
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_issue", target.repository);
|
|
13587
13714
|
const response = await octokit.rest.issues.get({
|
|
13588
13715
|
owner: target.repository.owner,
|
|
13589
13716
|
repo: target.repository.repo,
|
|
@@ -13630,7 +13757,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13630
13757
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13631
13758
|
const input = getToolInputRecord(params);
|
|
13632
13759
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13633
|
-
const octokit = await
|
|
13760
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_issue_comments", target.repository);
|
|
13634
13761
|
const comments = await listAllGitHubIssueComments(octokit, target.repository, target.issueNumber);
|
|
13635
13762
|
return buildToolSuccessResult(
|
|
13636
13763
|
`Loaded ${comments.length} GitHub ${comments.length === 1 ? "comment" : "comments"} from issue #${target.issueNumber}.`,
|
|
@@ -13648,7 +13775,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13648
13775
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13649
13776
|
const input = getToolInputRecord(params);
|
|
13650
13777
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13651
|
-
const octokit = await
|
|
13778
|
+
const octokit = await createAgentToolOctokit(runCtx, "update_issue", target.repository);
|
|
13652
13779
|
const currentResponse = await octokit.rest.issues.get({
|
|
13653
13780
|
owner: target.repository.owner,
|
|
13654
13781
|
repo: target.repository.repo,
|
|
@@ -13721,7 +13848,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13721
13848
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13722
13849
|
const input = getToolInputRecord(params);
|
|
13723
13850
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13724
|
-
const octokit = await
|
|
13851
|
+
const octokit = await createAgentToolOctokit(runCtx, "assign_to_current_user", target.repository);
|
|
13725
13852
|
const [currentResponse, authenticatedUserResponse] = await Promise.all([
|
|
13726
13853
|
octokit.rest.issues.get({
|
|
13727
13854
|
owner: target.repository.owner,
|
|
@@ -13781,7 +13908,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13781
13908
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13782
13909
|
const input = getToolInputRecord(params);
|
|
13783
13910
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
13784
|
-
const octokit = await
|
|
13911
|
+
const octokit = await createAgentToolOctokit(runCtx, "add_issue_comment", target.repository);
|
|
13785
13912
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), "comment", normalizeOptionalToolString(input.llmModel));
|
|
13786
13913
|
const response = await octokit.rest.issues.createComment({
|
|
13787
13914
|
owner: target.repository.owner,
|
|
@@ -13831,7 +13958,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13831
13958
|
"pull request description",
|
|
13832
13959
|
normalizeOptionalToolString(input.llmModel)
|
|
13833
13960
|
) : void 0;
|
|
13834
|
-
const octokit = await
|
|
13961
|
+
const octokit = await createAgentToolOctokit(runCtx, "create_pull_request", repository);
|
|
13835
13962
|
const response = await octokit.rest.pulls.create({
|
|
13836
13963
|
owner: repository.owner,
|
|
13837
13964
|
repo: repository.repo,
|
|
@@ -13907,7 +14034,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13907
14034
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13908
14035
|
const input = getToolInputRecord(params);
|
|
13909
14036
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
13910
|
-
const octokit = await
|
|
14037
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_pull_request", target.repository);
|
|
13911
14038
|
const response = await octokit.rest.pulls.get({
|
|
13912
14039
|
owner: target.repository.owner,
|
|
13913
14040
|
repo: target.repository.repo,
|
|
@@ -13955,7 +14082,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
13955
14082
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
13956
14083
|
const input = getToolInputRecord(params);
|
|
13957
14084
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
13958
|
-
const octokit = await
|
|
14085
|
+
const octokit = await createAgentToolOctokit(runCtx, "update_pull_request", target.repository);
|
|
13959
14086
|
let currentResponse = await octokit.rest.pulls.get({
|
|
13960
14087
|
owner: target.repository.owner,
|
|
13961
14088
|
repo: target.repository.repo,
|
|
@@ -14021,7 +14148,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14021
14148
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14022
14149
|
const input = getToolInputRecord(params);
|
|
14023
14150
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14024
|
-
const octokit = await
|
|
14151
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_pull_request_files", target.repository);
|
|
14025
14152
|
const files = await listAllPullRequestFiles(octokit, target.repository, target.pullRequestNumber);
|
|
14026
14153
|
return buildToolSuccessResult(
|
|
14027
14154
|
`Loaded ${files.length} changed ${files.length === 1 ? "file" : "files"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -14039,7 +14166,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14039
14166
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14040
14167
|
const input = getToolInputRecord(params);
|
|
14041
14168
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14042
|
-
const octokit = await
|
|
14169
|
+
const octokit = await createAgentToolOctokit(runCtx, "get_pull_request_checks", target.repository);
|
|
14043
14170
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
14044
14171
|
owner: target.repository.owner,
|
|
14045
14172
|
repo: target.repository.repo,
|
|
@@ -14138,7 +14265,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14138
14265
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14139
14266
|
const input = getToolInputRecord(params);
|
|
14140
14267
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14141
|
-
const octokit = await
|
|
14268
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_pull_request_review_threads", target.repository);
|
|
14142
14269
|
const threads = await listDetailedPullRequestReviewThreads(octokit, target.repository, target.pullRequestNumber);
|
|
14143
14270
|
return buildToolSuccessResult(
|
|
14144
14271
|
`Loaded ${threads.length} review ${threads.length === 1 ? "thread" : "threads"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -14160,7 +14287,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14160
14287
|
throw new Error("threadId is required.");
|
|
14161
14288
|
}
|
|
14162
14289
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), "comment", normalizeOptionalToolString(input.llmModel));
|
|
14163
|
-
const octokit = await
|
|
14290
|
+
const octokit = await createAgentToolOctokit(runCtx, "reply_to_review_thread");
|
|
14164
14291
|
const response = await octokit.graphql(
|
|
14165
14292
|
GITHUB_ADD_PULL_REQUEST_REVIEW_THREAD_REPLY_MUTATION,
|
|
14166
14293
|
{
|
|
@@ -14195,7 +14322,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14195
14322
|
if (!threadId) {
|
|
14196
14323
|
throw new Error("threadId is required.");
|
|
14197
14324
|
}
|
|
14198
|
-
const octokit = await
|
|
14325
|
+
const octokit = await createAgentToolOctokit(runCtx, "resolve_review_thread");
|
|
14199
14326
|
const response = await octokit.graphql(
|
|
14200
14327
|
GITHUB_RESOLVE_REVIEW_THREAD_MUTATION,
|
|
14201
14328
|
{
|
|
@@ -14226,7 +14353,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14226
14353
|
if (!threadId) {
|
|
14227
14354
|
throw new Error("threadId is required.");
|
|
14228
14355
|
}
|
|
14229
|
-
const octokit = await
|
|
14356
|
+
const octokit = await createAgentToolOctokit(runCtx, "unresolve_review_thread");
|
|
14230
14357
|
const response = await octokit.graphql(
|
|
14231
14358
|
GITHUB_UNRESOLVE_REVIEW_THREAD_MUTATION,
|
|
14232
14359
|
{
|
|
@@ -14259,7 +14386,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14259
14386
|
if (userReviewers.length === 0 && teamReviewers.length === 0) {
|
|
14260
14387
|
throw new Error("Provide at least one user reviewer or team reviewer.");
|
|
14261
14388
|
}
|
|
14262
|
-
const octokit = await
|
|
14389
|
+
const octokit = await createAgentToolOctokit(runCtx, "request_pull_request_reviewers", target.repository);
|
|
14263
14390
|
const response = await octokit.rest.pulls.requestReviewers({
|
|
14264
14391
|
owner: target.repository.owner,
|
|
14265
14392
|
repo: target.repository.repo,
|
|
@@ -14290,7 +14417,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14290
14417
|
if (!organization) {
|
|
14291
14418
|
throw new Error("organization is required.");
|
|
14292
14419
|
}
|
|
14293
|
-
const octokit = await
|
|
14420
|
+
const octokit = await createAgentToolOctokit(runCtx, "list_organization_projects");
|
|
14294
14421
|
const projects = await listGitHubOrganizationProjects(octokit, organization, {
|
|
14295
14422
|
includeClosed: input.includeClosed === true,
|
|
14296
14423
|
query: normalizeOptionalToolString(input.query),
|
|
@@ -14311,7 +14438,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
14311
14438
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
14312
14439
|
const input = getToolInputRecord(params);
|
|
14313
14440
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
14314
|
-
const octokit = await
|
|
14441
|
+
const octokit = await createAgentToolOctokit(runCtx, "add_pull_request_to_project", target.repository);
|
|
14315
14442
|
const projectTarget = await resolveGitHubProjectToolTarget(octokit, input);
|
|
14316
14443
|
const pullRequest = await getGitHubPullRequestProjectItems(
|
|
14317
14444
|
octokit,
|
|
@@ -14380,6 +14507,7 @@ function shouldStartWorkerHost(moduleUrl, entry = process.argv[1]) {
|
|
|
14380
14507
|
}
|
|
14381
14508
|
var __testing = {
|
|
14382
14509
|
buildSyncFallbackExecutionStatePatch,
|
|
14510
|
+
createGitHubToolOctokit,
|
|
14383
14511
|
hasUnresolvedPaperclipIssueBlocker,
|
|
14384
14512
|
isHealthyMaintainerWaitTransition,
|
|
14385
14513
|
resolveSyncTransitionAssignee
|
|
@@ -14681,7 +14809,7 @@ var plugin = definePlugin({
|
|
|
14681
14809
|
if (!trimmedToken) {
|
|
14682
14810
|
throw new Error("Enter a GitHub token.");
|
|
14683
14811
|
}
|
|
14684
|
-
return validateGithubToken(trimmedToken);
|
|
14812
|
+
return validateGithubToken(ctx, trimmedToken);
|
|
14685
14813
|
});
|
|
14686
14814
|
ctx.actions.register("project.pullRequests.createIssue", async (input) => {
|
|
14687
14815
|
const record = input && typeof input === "object" ? input : {};
|