paperclip-github-plugin 0.7.0 → 0.7.2

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 CHANGED
@@ -89,7 +89,7 @@ Paperclip agents can search GitHub for duplicates, read and update issues, post
89
89
  ## Requirements
90
90
 
91
91
  - Node.js 20+
92
- - a Paperclip host on `2026.427.0` or newer with plugin installation enabled
92
+ - a Paperclip host with plugin installation enabled. GitHub Sync is built and tested against Paperclip `2026.427.0`; the manifest relies on explicit capabilities instead of a strict host-version gate because current latest/development hosts can report `0.0.0` during plugin upgrade.
93
93
  - a GitHub token with API access to the repositories you want to sync
94
94
 
95
95
  ## Install from npm
@@ -248,6 +248,7 @@ Because the KPI attribution endpoint is a native plugin JSON route rather than a
248
248
 
249
249
  ## Troubleshooting
250
250
 
251
+ - If an older GitHub Sync build fails upgrade with `requires host version 2026.427.0 or newer, but this server is running 0.0.0`, upgrade to a build that removes the strict manifest host-version gate. The host is reporting a development-version sentinel, so the plugin now relies on declared capabilities and runtime fallbacks instead.
251
252
  - If setup is reported as incomplete, confirm that a GitHub token has been saved or that `${PAPERCLIP_HOME:-~/.paperclip}/plugins/github-sync/config.json` contains `githubToken`, and make sure at least one mapping has a created Paperclip project.
252
253
  - If Paperclip says board access is required, open plugin settings inside the affected company and complete the Paperclip board access flow before retrying sync.
253
254
  - If GitHub Sync agent tools fail with `403 {"error":"Board access required"}` on `/api/plugins/tools` or `/api/plugins/tools/execute`, the current Paperclip host rejected the request before the plugin worker ran. Re-run from a board-authenticated session or agent run that has board access to the target company.
package/dist/manifest.js CHANGED
@@ -516,12 +516,11 @@ var COMPANY_METRIC_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_ID}/a
516
516
  var require2 = createRequire(import.meta.url);
517
517
  var packageJson = require2("../package.json");
518
518
  var SCHEDULE_TICK_CRON = "* * * * *";
519
- var MANIFEST_VERSION = "0.7.0"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
519
+ var MANIFEST_VERSION = "0.7.2"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
520
520
  var manifest = {
521
521
  id: GITHUB_SYNC_PLUGIN_ID,
522
522
  apiVersion: 1,
523
523
  version: MANIFEST_VERSION,
524
- minimumHostVersion: "2026.427.0",
525
524
  displayName: "GitHub Sync",
526
525
  description: "Synchronize GitHub issues into Paperclip projects.",
527
526
  author: "\xC1lvaro S\xE1nchez-Mariscal",
package/dist/worker.js CHANGED
@@ -5026,7 +5026,10 @@ function resolvePaperclipIssueExecutorAssignee(syncContext, advancedSettings) {
5026
5026
  return null;
5027
5027
  }
5028
5028
  function resolveSyncTransitionAssignee(params) {
5029
- const { nextStatus, syncContext, advancedSettings } = params;
5029
+ const { currentStatus, nextStatus, syncContext, advancedSettings } = params;
5030
+ if (isHealthyMaintainerWaitTransition({ currentStatus, nextStatus, syncContext })) {
5031
+ return null;
5032
+ }
5030
5033
  if (nextStatus === "in_review") {
5031
5034
  return resolvePaperclipIssueReviewAssignee(syncContext, advancedSettings);
5032
5035
  }
@@ -5035,6 +5038,10 @@ function resolveSyncTransitionAssignee(params) {
5035
5038
  }
5036
5039
  return null;
5037
5040
  }
5041
+ function isHealthyMaintainerWaitTransition(params) {
5042
+ const { currentStatus, nextStatus, syncContext } = params;
5043
+ return nextStatus === "in_review" && (currentStatus === "done" || currentStatus === "in_review") && syncContext.executionState === null && syncContext.executionPolicy !== null;
5044
+ }
5038
5045
  function doesPaperclipIssueAssigneeMatch(currentAssignee, nextAssignee) {
5039
5046
  return isSamePaperclipIssueAssigneePrincipal(currentAssignee, nextAssignee);
5040
5047
  }
@@ -7599,6 +7606,7 @@ async function updatePaperclipIssueState(ctx, params) {
7599
7606
  nextStatus,
7600
7607
  nextAssignee,
7601
7608
  clearAssignee,
7609
+ clearExecutionPolicy,
7602
7610
  transitionComment,
7603
7611
  transitionCommentAnnotation,
7604
7612
  paperclipApiBaseUrl
@@ -7613,7 +7621,8 @@ async function updatePaperclipIssueState(ctx, params) {
7613
7621
  });
7614
7622
  const issuePatch = {
7615
7623
  status: nextStatus,
7616
- ...syncExecutionStatePatch === null ? { executionState: null } : {}
7624
+ ...syncExecutionStatePatch === null ? { executionState: null } : {},
7625
+ ...clearExecutionPolicy ? { executionPolicy: null, executionState: null } : {}
7617
7626
  };
7618
7627
  if (nextAssignee) {
7619
7628
  if (nextAssignee.kind === "agent") {
@@ -8125,12 +8134,18 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
8125
8134
  maintainerAuthoredImportedIssue,
8126
8135
  hasExecutorHandoffTarget: Boolean(executorTransitionAssignee)
8127
8136
  });
8137
+ const shouldPreserveMaintainerWaitRouting = isHealthyMaintainerWaitTransition({
8138
+ currentStatus: paperclipIssue.status,
8139
+ nextStatus,
8140
+ syncContext: paperclipIssueSyncContext
8141
+ });
8128
8142
  const nextTransitionAssignee = resolveSyncTransitionAssignee({
8143
+ currentStatus: paperclipIssue.status,
8129
8144
  nextStatus,
8130
8145
  syncContext: paperclipIssueSyncContext,
8131
8146
  advancedSettings
8132
8147
  });
8133
- const shouldClearTransitionAssignee = nextStatus === "in_review" && nextTransitionAssignee === null && paperclipIssueSyncContext.assignee !== null;
8148
+ const shouldClearTransitionAssignee = nextStatus === "in_review" && (nextTransitionAssignee === null || shouldPreserveMaintainerWaitRouting) && paperclipIssueSyncContext.assignee !== null;
8134
8149
  const nextAssigneeChanged = nextTransitionAssignee ? !doesPaperclipIssueAssigneeMatch(paperclipIssueSyncContext.assignee, nextTransitionAssignee.principal) : false;
8135
8150
  const shouldWakeImportedAssignee = wasImportedThisRun && paperclipIssue.status === nextStatus && nextStatus === "todo" && paperclipIssueSyncContext.assignee?.kind === "agent";
8136
8151
  const shouldWakeTransitionAssignee = paperclipIssue.status !== nextStatus && nextTransitionAssignee?.principal.kind === "agent" && isActionablePaperclipIssueStatus(nextStatus) && (nextAssigneeChanged || paperclipIssue.status !== nextStatus);
@@ -8152,6 +8167,7 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
8152
8167
  syncContext: paperclipIssueSyncContext,
8153
8168
  nextStatus,
8154
8169
  clearAssignee: true,
8170
+ ...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
8155
8171
  transitionComment: "",
8156
8172
  paperclipApiBaseUrl
8157
8173
  });
@@ -8187,6 +8203,7 @@ async function synchronizePaperclipIssueStatuses(ctx, octokit, repository, mappi
8187
8203
  nextStatus,
8188
8204
  ...nextTransitionAssignee ? { nextAssignee: nextTransitionAssignee.principal } : {},
8189
8205
  ...shouldClearTransitionAssignee ? { clearAssignee: true } : {},
8206
+ ...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
8190
8207
  transitionComment: transitionComment.body,
8191
8208
  transitionCommentAnnotation: transitionComment.annotation,
8192
8209
  paperclipApiBaseUrl
@@ -8310,12 +8327,18 @@ async function synchronizePaperclipPullRequestIssueStatuses(ctx, octokit, mappin
8310
8327
  pullRequest,
8311
8328
  hasExecutorHandoffTarget: Boolean(executorTransitionAssignee)
8312
8329
  });
8330
+ const shouldPreserveMaintainerWaitRouting = isHealthyMaintainerWaitTransition({
8331
+ currentStatus: paperclipIssue.status,
8332
+ nextStatus,
8333
+ syncContext: paperclipIssueSyncContext
8334
+ });
8313
8335
  const nextTransitionAssignee = resolveSyncTransitionAssignee({
8336
+ currentStatus: paperclipIssue.status,
8314
8337
  nextStatus,
8315
8338
  syncContext: paperclipIssueSyncContext,
8316
8339
  advancedSettings
8317
8340
  });
8318
- const shouldClearTransitionAssignee = nextStatus === "in_review" && nextTransitionAssignee === null && paperclipIssueSyncContext.assignee !== null;
8341
+ const shouldClearTransitionAssignee = nextStatus === "in_review" && (nextTransitionAssignee === null || shouldPreserveMaintainerWaitRouting) && paperclipIssueSyncContext.assignee !== null;
8319
8342
  const nextAssigneeChanged = nextTransitionAssignee ? !doesPaperclipIssueAssigneeMatch(paperclipIssueSyncContext.assignee, nextTransitionAssignee.principal) : false;
8320
8343
  const shouldWakeTransitionAssignee = paperclipIssue.status !== nextStatus && nextTransitionAssignee?.principal.kind === "agent" && isActionablePaperclipIssueStatus(nextStatus) && (nextAssigneeChanged || paperclipIssue.status !== nextStatus);
8321
8344
  if (paperclipIssue.status === nextStatus) {
@@ -8332,6 +8355,7 @@ async function synchronizePaperclipPullRequestIssueStatuses(ctx, octokit, mappin
8332
8355
  syncContext: paperclipIssueSyncContext,
8333
8356
  nextStatus,
8334
8357
  clearAssignee: true,
8358
+ ...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
8335
8359
  transitionComment: "",
8336
8360
  paperclipApiBaseUrl
8337
8361
  });
@@ -8356,6 +8380,7 @@ async function synchronizePaperclipPullRequestIssueStatuses(ctx, octokit, mappin
8356
8380
  nextStatus,
8357
8381
  ...nextTransitionAssignee ? { nextAssignee: nextTransitionAssignee.principal } : {},
8358
8382
  ...shouldClearTransitionAssignee ? { clearAssignee: true } : {},
8383
+ ...shouldPreserveMaintainerWaitRouting ? { clearExecutionPolicy: true } : {},
8359
8384
  transitionComment,
8360
8385
  paperclipApiBaseUrl
8361
8386
  });
@@ -13235,6 +13260,11 @@ function shouldStartWorkerHost(moduleUrl, entry = process.argv[1]) {
13235
13260
  return resolve(entry) === resolve(modulePath);
13236
13261
  }
13237
13262
  }
13263
+ var __testing = {
13264
+ buildSyncFallbackExecutionStatePatch,
13265
+ isHealthyMaintainerWaitTransition,
13266
+ resolveSyncTransitionAssignee
13267
+ };
13238
13268
  var plugin = definePlugin({
13239
13269
  async setup(ctx) {
13240
13270
  pluginRuntimeContext = ctx;
@@ -13617,6 +13647,7 @@ if (shouldStartWorkerHost(import.meta.url)) {
13617
13647
  startWorkerRpcHost({ plugin });
13618
13648
  }
13619
13649
  export {
13650
+ __testing,
13620
13651
  worker_default as default,
13621
13652
  shouldStartWorkerHost
13622
13653
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paperclip-github-plugin",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Paperclip plugin for synchronizing GitHub issues into Paperclip projects.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",