paperclip-github-plugin 0.8.3 → 0.8.4
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 +4 -3
- package/dist/manifest.js +2 -1
- package/dist/worker.js +33 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -159,8 +159,8 @@ When the local Paperclip API is available, the plugin also syncs labels by name,
|
|
|
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
161
|
| Open issue with a linked pull request and unfinished CI | `in_progress` |
|
|
162
|
-
| Open issue with failing CI, a non-mergeable linked pull request,
|
|
163
|
-
| Open issue with green CI, a merge-ready linked pull request,
|
|
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
|
+
| 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` |
|
|
165
165
|
| Closed issue closed as `not_planned` or `duplicate` | `cancelled` |
|
|
166
166
|
|
|
@@ -170,7 +170,8 @@ 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
|
|
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.
|
|
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.
|
|
174
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.
|
|
175
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.
|
|
176
177
|
- Sync-driven handoffs to agent assignees best-effort enqueue an explicit wakeup so the next reviewer, approver, or executor can pick the issue up even when their agent is not running heartbeats.
|
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.4"?.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,
|
|
@@ -559,6 +559,7 @@ var manifest = {
|
|
|
559
559
|
"issues.create",
|
|
560
560
|
"issues.update",
|
|
561
561
|
"issues.wakeup",
|
|
562
|
+
"issue.relations.read",
|
|
562
563
|
"issue.comments.read",
|
|
563
564
|
"issue.comments.create",
|
|
564
565
|
"agents.read",
|
package/dist/worker.js
CHANGED
|
@@ -5021,6 +5021,29 @@ function getPaperclipIssueSyncContext(issue) {
|
|
|
5021
5021
|
executionState: normalizePaperclipIssueExecutionState(record.executionState)
|
|
5022
5022
|
};
|
|
5023
5023
|
}
|
|
5024
|
+
function hasUnresolvedPaperclipIssueBlockerSummary(blockers) {
|
|
5025
|
+
if (!Array.isArray(blockers)) {
|
|
5026
|
+
return false;
|
|
5027
|
+
}
|
|
5028
|
+
return blockers.some((blocker) => {
|
|
5029
|
+
if (!blocker || typeof blocker !== "object") {
|
|
5030
|
+
return true;
|
|
5031
|
+
}
|
|
5032
|
+
const status = blocker.status;
|
|
5033
|
+
return status !== "done" && status !== "cancelled";
|
|
5034
|
+
});
|
|
5035
|
+
}
|
|
5036
|
+
async function hasUnresolvedPaperclipIssueBlocker(ctx, issue, companyId) {
|
|
5037
|
+
const record = issue;
|
|
5038
|
+
if (hasUnresolvedPaperclipIssueBlockerSummary(record.blockedBy)) {
|
|
5039
|
+
return true;
|
|
5040
|
+
}
|
|
5041
|
+
if (typeof ctx.issues.relations?.get !== "function") {
|
|
5042
|
+
return false;
|
|
5043
|
+
}
|
|
5044
|
+
const relations = await ctx.issues.relations.get(issue.id, companyId);
|
|
5045
|
+
return hasUnresolvedPaperclipIssueBlockerSummary(relations.blockedBy);
|
|
5046
|
+
}
|
|
5024
5047
|
function isSamePaperclipIssueAssigneePrincipal(left, right) {
|
|
5025
5048
|
if (!left || !right) {
|
|
5026
5049
|
return !left && !right;
|
|
@@ -5556,10 +5579,10 @@ function normalizeGitHubPullRequestReviewDecision(value) {
|
|
|
5556
5579
|
}
|
|
5557
5580
|
}
|
|
5558
5581
|
function isGitHubPullRequestActionRequiredForSync(pullRequest) {
|
|
5559
|
-
return pullRequest.
|
|
5582
|
+
return pullRequest.mergeability === "conflicting" || ACTION_REQUIRED_GITHUB_PULL_REQUEST_MERGE_STATE_STATUSES.has(pullRequest.mergeStateStatus);
|
|
5560
5583
|
}
|
|
5561
5584
|
function isGitHubPullRequestReviewReadyForSync(pullRequest) {
|
|
5562
|
-
if (pullRequest.ciState !== "green" || pullRequest.hasUnresolvedReviewThreads
|
|
5585
|
+
if (pullRequest.ciState !== "green" || pullRequest.hasUnresolvedReviewThreads) {
|
|
5563
5586
|
return false;
|
|
5564
5587
|
}
|
|
5565
5588
|
return REVIEW_READY_GITHUB_PULL_REQUEST_MERGE_STATE_STATUSES.has(pullRequest.mergeStateStatus);
|
|
@@ -5592,9 +5615,6 @@ function listGitHubPullRequestSyncBlockingConditions(pullRequest) {
|
|
|
5592
5615
|
if (pullRequest.hasUnresolvedReviewThreads) {
|
|
5593
5616
|
conditions.push("unresolved review threads");
|
|
5594
5617
|
}
|
|
5595
|
-
if (pullRequest.reviewDecision === "changes_requested") {
|
|
5596
|
-
conditions.push("requested changes");
|
|
5597
|
-
}
|
|
5598
5618
|
return conditions;
|
|
5599
5619
|
}
|
|
5600
5620
|
function tryBuildGitHubPullRequestStatusSnapshotFromBatchNode(node, repository) {
|
|
@@ -9025,7 +9045,7 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9025
9045
|
paperclipIssueSyncContext,
|
|
9026
9046
|
advancedSettings
|
|
9027
9047
|
);
|
|
9028
|
-
|
|
9048
|
+
let nextStatus = resolvePaperclipIssueStatus({
|
|
9029
9049
|
currentStatus: paperclipIssue.status,
|
|
9030
9050
|
snapshot,
|
|
9031
9051
|
hasTrustedNewComment,
|
|
@@ -9034,6 +9054,9 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
|
|
|
9034
9054
|
maintainerAuthoredImportedIssue,
|
|
9035
9055
|
hasExecutorHandoffTarget: Boolean(executorTransitionAssignee)
|
|
9036
9056
|
});
|
|
9057
|
+
if (paperclipIssue.status === "blocked" && nextStatus !== "blocked" && await hasUnresolvedPaperclipIssueBlocker(ctx, paperclipIssue, mapping.companyId)) {
|
|
9058
|
+
nextStatus = "blocked";
|
|
9059
|
+
}
|
|
9037
9060
|
const shouldPreserveMaintainerWaitRouting = isHealthyMaintainerWaitTransition({
|
|
9038
9061
|
currentStatus: paperclipIssue.status,
|
|
9039
9062
|
nextStatus,
|
|
@@ -9236,11 +9259,14 @@ async function synchronizePaperclipPullRequestIssueStatuses(ctx, octokit, mappin
|
|
|
9236
9259
|
paperclipIssueSyncContext,
|
|
9237
9260
|
advancedSettings
|
|
9238
9261
|
);
|
|
9239
|
-
|
|
9262
|
+
let nextStatus = resolvePaperclipPullRequestIssueStatus({
|
|
9240
9263
|
currentStatus: paperclipIssue.status,
|
|
9241
9264
|
pullRequest,
|
|
9242
9265
|
hasExecutorHandoffTarget: Boolean(executorTransitionAssignee)
|
|
9243
9266
|
});
|
|
9267
|
+
if (paperclipIssue.status === "blocked" && nextStatus !== "blocked" && await hasUnresolvedPaperclipIssueBlocker(ctx, paperclipIssue, mapping.companyId)) {
|
|
9268
|
+
nextStatus = "blocked";
|
|
9269
|
+
}
|
|
9244
9270
|
const shouldPreserveMaintainerWaitRouting = isHealthyMaintainerWaitTransition({
|
|
9245
9271
|
currentStatus: paperclipIssue.status,
|
|
9246
9272
|
nextStatus,
|