paperclip-github-plugin 0.9.0 → 0.9.1
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 +6 -2
- package/dist/manifest.js +1 -1
- package/dist/ui/index.js +100 -2
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +150 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -205,7 +205,10 @@ If Paperclip-managed secrets are not available, the worker can read a local fall
|
|
|
205
205
|
|
|
206
206
|
```json
|
|
207
207
|
{
|
|
208
|
-
"githubToken": "ghp_your_token_here"
|
|
208
|
+
"githubToken": "ghp_your_token_here",
|
|
209
|
+
"githubTokensByCompanyId": {
|
|
210
|
+
"company-uuid": "ghp_company_specific_token_here"
|
|
211
|
+
}
|
|
209
212
|
}
|
|
210
213
|
```
|
|
211
214
|
|
|
@@ -213,7 +216,8 @@ Notes:
|
|
|
213
216
|
|
|
214
217
|
- This file is read by the worker only.
|
|
215
218
|
- The raw token is never persisted back into plugin state or plugin config.
|
|
216
|
-
- A GitHub token secret saved through the settings UI
|
|
219
|
+
- A GitHub token secret saved through the settings UI is the primary source. If the current Paperclip host rejects plugin secret-ref resolution while company-scoped plugin config is unavailable, GitHub Sync stores the validated token in `githubTokensByCompanyId` as a worker-local compatibility fallback.
|
|
220
|
+
- On authenticated deployments, selected agents receive `GITHUB_TOKEN` as a latest-version secret-ref env binding, and the settings UI patches agent adapter config with `replaceAdapterConfig: true` so newer Paperclip hosts persist the merged env map.
|
|
217
221
|
|
|
218
222
|
### Worker-facing Paperclip API URL
|
|
219
223
|
|
package/dist/manifest.js
CHANGED
|
@@ -642,7 +642,7 @@ var PULL_REQUEST_ASSET_API_ROUTE_URL_PATH = `/api/plugins/${GITHUB_SYNC_PLUGIN_I
|
|
|
642
642
|
var require2 = createRequire(import.meta.url);
|
|
643
643
|
var packageJson = require2("../package.json");
|
|
644
644
|
var SCHEDULE_TICK_CRON = "* * * * *";
|
|
645
|
-
var MANIFEST_VERSION = "0.9.
|
|
645
|
+
var MANIFEST_VERSION = "0.9.1"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
|
|
646
646
|
var manifest = {
|
|
647
647
|
id: GITHUB_SYNC_PLUGIN_ID,
|
|
648
648
|
apiVersion: 1,
|
package/dist/ui/index.js
CHANGED
|
@@ -23165,6 +23165,9 @@ function resolveToolbarButtonState(params) {
|
|
|
23165
23165
|
syncStartPending
|
|
23166
23166
|
};
|
|
23167
23167
|
}
|
|
23168
|
+
function clearGitHubTokenConfigSyncAttemptOnFailure(currentAttemptKey, failedAttemptKey) {
|
|
23169
|
+
return currentAttemptKey === failedAttemptKey ? null : currentAttemptKey;
|
|
23170
|
+
}
|
|
23168
23171
|
function getSyncToastTitle(syncState) {
|
|
23169
23172
|
if (getActiveRateLimitPause(syncState)) {
|
|
23170
23173
|
return "GitHub sync is paused";
|
|
@@ -28430,7 +28433,8 @@ function getAgentPropagationPatch(params) {
|
|
|
28430
28433
|
...currentEnv,
|
|
28431
28434
|
GITHUB_TOKEN: {
|
|
28432
28435
|
type: "secret_ref",
|
|
28433
|
-
secretId: params.githubTokenSecretRef
|
|
28436
|
+
secretId: params.githubTokenSecretRef,
|
|
28437
|
+
version: "latest"
|
|
28434
28438
|
}
|
|
28435
28439
|
};
|
|
28436
28440
|
if (JSON.stringify(nextEnv2) === JSON.stringify(currentEnv)) {
|
|
@@ -28485,7 +28489,8 @@ async function applyGitHubTokenPropagationUpdate(params) {
|
|
|
28485
28489
|
await fetchJson(`/api/agents/${params.agentId}`, {
|
|
28486
28490
|
method: "PATCH",
|
|
28487
28491
|
body: JSON.stringify({
|
|
28488
|
-
adapterConfig: nextAdapterConfig
|
|
28492
|
+
adapterConfig: nextAdapterConfig,
|
|
28493
|
+
replaceAdapterConfig: true
|
|
28489
28494
|
})
|
|
28490
28495
|
});
|
|
28491
28496
|
}
|
|
@@ -31968,6 +31973,7 @@ function GitHubSyncSettingsPage() {
|
|
|
31968
31973
|
const saveRegistration = usePluginAction("settings.saveRegistration");
|
|
31969
31974
|
const updateBoardAccess = usePluginAction("settings.updateBoardAccess");
|
|
31970
31975
|
const validateToken = usePluginAction("settings.validateToken");
|
|
31976
|
+
const ensureGitHubTokenAvailable = usePluginAction("settings.ensureGitHubTokenAvailable");
|
|
31971
31977
|
const runSyncNow = usePluginAction("sync.runNow");
|
|
31972
31978
|
const cancelSync = usePluginAction("sync.cancel");
|
|
31973
31979
|
const [form, setForm] = useState2(EMPTY_SETTINGS);
|
|
@@ -31995,6 +32001,7 @@ function GitHubSyncSettingsPage() {
|
|
|
31995
32001
|
const themeMode = useResolvedThemeMode();
|
|
31996
32002
|
const boardAccessRequirement = usePaperclipBoardAccessRequirement();
|
|
31997
32003
|
const armSyncCompletionToast = useSyncCompletionToast(form.syncState, toast);
|
|
32004
|
+
const githubTokenConfigSyncAttemptRef = useRef(null);
|
|
31998
32005
|
const boardAccessConfigSyncAttemptRef = useRef(null);
|
|
31999
32006
|
const assigneeFallbackAttemptRef = useRef(null);
|
|
32000
32007
|
const currentSettings = settings.data ?? cachedSettings;
|
|
@@ -32111,6 +32118,76 @@ function GitHubSyncSettingsPage() {
|
|
|
32111
32118
|
cancelled = true;
|
|
32112
32119
|
};
|
|
32113
32120
|
}, [currentSettings?.availableAssignees?.length, currentSettings?.updatedAt, hostContext.companyId]);
|
|
32121
|
+
useEffect2(() => {
|
|
32122
|
+
const companyId = hostContext.companyId;
|
|
32123
|
+
const secretRef = settings.data?.githubTokenNeedsConfigSync ? settings.data.githubTokenConfigSyncRef : void 0;
|
|
32124
|
+
if (!companyId || !secretRef) {
|
|
32125
|
+
return;
|
|
32126
|
+
}
|
|
32127
|
+
const attemptKey = `${companyId}:${secretRef}`;
|
|
32128
|
+
if (githubTokenConfigSyncAttemptRef.current === attemptKey) {
|
|
32129
|
+
return;
|
|
32130
|
+
}
|
|
32131
|
+
githubTokenConfigSyncAttemptRef.current = attemptKey;
|
|
32132
|
+
let cancelled = false;
|
|
32133
|
+
void (async () => {
|
|
32134
|
+
try {
|
|
32135
|
+
const pluginId = await resolveCurrentPluginId(pluginIdFromLocation);
|
|
32136
|
+
if (!pluginId) {
|
|
32137
|
+
throw new Error("Plugin id is required to finish syncing the GitHub token into plugin config.");
|
|
32138
|
+
}
|
|
32139
|
+
await patchPluginConfig(pluginId, {
|
|
32140
|
+
githubTokenRefs: {
|
|
32141
|
+
[companyId]: secretRef
|
|
32142
|
+
}
|
|
32143
|
+
});
|
|
32144
|
+
const selectedAgentIds = normalizeAgentIds(settings.data?.advancedSettings?.githubTokenPropagationAgentIds);
|
|
32145
|
+
if (selectedAgentIds.length > 0) {
|
|
32146
|
+
await propagateGitHubTokenToSelectedAgents({
|
|
32147
|
+
selectedAgentIds,
|
|
32148
|
+
previousAgentIds: selectedAgentIds,
|
|
32149
|
+
githubTokenSecretRef: secretRef
|
|
32150
|
+
});
|
|
32151
|
+
}
|
|
32152
|
+
if (cancelled) {
|
|
32153
|
+
return;
|
|
32154
|
+
}
|
|
32155
|
+
notifyGitHubSyncSettingsChanged();
|
|
32156
|
+
try {
|
|
32157
|
+
await settings.refresh();
|
|
32158
|
+
} catch {
|
|
32159
|
+
return;
|
|
32160
|
+
}
|
|
32161
|
+
} catch (error) {
|
|
32162
|
+
githubTokenConfigSyncAttemptRef.current = clearGitHubTokenConfigSyncAttemptOnFailure(
|
|
32163
|
+
githubTokenConfigSyncAttemptRef.current,
|
|
32164
|
+
attemptKey
|
|
32165
|
+
);
|
|
32166
|
+
if (cancelled) {
|
|
32167
|
+
return;
|
|
32168
|
+
}
|
|
32169
|
+
toast({
|
|
32170
|
+
title: "GitHub token needs reconnection",
|
|
32171
|
+
body: getActionErrorMessage(
|
|
32172
|
+
error,
|
|
32173
|
+
"GitHub Sync could not finish migrating the saved GitHub token into plugin config."
|
|
32174
|
+
),
|
|
32175
|
+
tone: "error"
|
|
32176
|
+
});
|
|
32177
|
+
}
|
|
32178
|
+
})();
|
|
32179
|
+
return () => {
|
|
32180
|
+
cancelled = true;
|
|
32181
|
+
};
|
|
32182
|
+
}, [
|
|
32183
|
+
hostContext.companyId,
|
|
32184
|
+
pluginIdFromLocation,
|
|
32185
|
+
settings.data?.advancedSettings?.githubTokenPropagationAgentIds,
|
|
32186
|
+
settings.data?.githubTokenNeedsConfigSync,
|
|
32187
|
+
settings.data?.githubTokenConfigSyncRef,
|
|
32188
|
+
settings.refresh,
|
|
32189
|
+
toast
|
|
32190
|
+
]);
|
|
32114
32191
|
useEffect2(() => {
|
|
32115
32192
|
const companyId = hostContext.companyId;
|
|
32116
32193
|
const secretRef = settings.data?.paperclipBoardAccessNeedsConfigSync ? settings.data.paperclipBoardAccessConfigSyncRef : void 0;
|
|
@@ -32581,6 +32658,16 @@ function GitHubSyncSettingsPage() {
|
|
|
32581
32658
|
},
|
|
32582
32659
|
githubTokenLogin: validation.login
|
|
32583
32660
|
});
|
|
32661
|
+
let availabilityWarning = null;
|
|
32662
|
+
try {
|
|
32663
|
+
await ensureGitHubTokenAvailable({
|
|
32664
|
+
companyId,
|
|
32665
|
+
githubTokenRef: secret.id,
|
|
32666
|
+
token: trimmedToken
|
|
32667
|
+
});
|
|
32668
|
+
} catch (error) {
|
|
32669
|
+
availabilityWarning = error;
|
|
32670
|
+
}
|
|
32584
32671
|
const selectedAgentIds = normalizeAgentIds(currentSettings?.advancedSettings?.githubTokenPropagationAgentIds);
|
|
32585
32672
|
let propagationError = null;
|
|
32586
32673
|
try {
|
|
@@ -32616,6 +32703,16 @@ function GitHubSyncSettingsPage() {
|
|
|
32616
32703
|
tone: "error"
|
|
32617
32704
|
});
|
|
32618
32705
|
}
|
|
32706
|
+
if (availabilityWarning) {
|
|
32707
|
+
toast({
|
|
32708
|
+
title: "GitHub token saved, but worker token access needs attention",
|
|
32709
|
+
body: getActionErrorMessage(
|
|
32710
|
+
availabilityWarning,
|
|
32711
|
+
"GitHub Sync could not verify worker access to the saved token."
|
|
32712
|
+
),
|
|
32713
|
+
tone: "error"
|
|
32714
|
+
});
|
|
32715
|
+
}
|
|
32619
32716
|
notifyGitHubSyncSettingsChanged();
|
|
32620
32717
|
try {
|
|
32621
32718
|
await settings.refresh();
|
|
@@ -35133,6 +35230,7 @@ export {
|
|
|
35133
35230
|
GitHubSyncProjectPullRequestsPage,
|
|
35134
35231
|
GitHubSyncProjectPullRequestsSidebarItem,
|
|
35135
35232
|
GitHubSyncSettingsPage,
|
|
35233
|
+
clearGitHubTokenConfigSyncAttemptOnFailure,
|
|
35136
35234
|
index_default as default,
|
|
35137
35235
|
resolveGitHubIssueDetailTabState,
|
|
35138
35236
|
resolveOrCreateProject,
|