paperclip-github-plugin 0.4.0 → 0.4.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 +4 -4
- package/dist/manifest.js +10 -7
- package/dist/ui/index.js +65 -20
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +475 -153
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -630,11 +630,13 @@ var COMMENT_ANNOTATION_ENTITY_TYPE = "paperclip-github-plugin.comment-annotation
|
|
|
630
630
|
var AI_AUTHORED_COMMENT_FOOTER_PREFIX = "Created by a Paperclip AI agent using ";
|
|
631
631
|
var HIDDEN_GITHUB_IMPORT_MARKER_PREFIX = "<!-- paperclip-github-plugin-imported-from: ";
|
|
632
632
|
var HIDDEN_GITHUB_IMPORT_MARKER_SUFFIX = " -->";
|
|
633
|
+
var EMPTY_GITHUB_ISSUE_DESCRIPTION_PLACEHOLDER = "_No description provided on GitHub._";
|
|
633
634
|
function normalizeCompanyId(value) {
|
|
634
635
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
635
636
|
}
|
|
636
637
|
var activeSyncPromise = null;
|
|
637
638
|
var activeRunningSyncState = null;
|
|
639
|
+
var activeRunningSyncCompanyId;
|
|
638
640
|
var activePaperclipApiAuthTokensByCompanyId = null;
|
|
639
641
|
var activeExternalConfigWarningKey = null;
|
|
640
642
|
var activeProjectPullRequestPageCache = /* @__PURE__ */ new Map();
|
|
@@ -710,6 +712,7 @@ var FAILED_STATUS_CONTEXT_STATES = /* @__PURE__ */ new Set(["ERROR", "FAILURE"])
|
|
|
710
712
|
var PENDING_STATUS_CONTEXT_STATES = /* @__PURE__ */ new Set(["EXPECTED", "PENDING"]);
|
|
711
713
|
var GITHUB_REPOSITORY_MAINTAINER_WARMUP_CONCURRENCY = 4;
|
|
712
714
|
var GITHUB_REPOSITORY_MAINTAINER_ROLE_NAMES = /* @__PURE__ */ new Set(["admin", "maintain"]);
|
|
715
|
+
var GITHUB_REPOSITORY_TRUSTED_AUTHOR_ASSOCIATIONS = /* @__PURE__ */ new Set(["collaborator", "member", "owner"]);
|
|
713
716
|
var GITHUB_ISSUE_STATUS_SNAPSHOT_QUERY = `
|
|
714
717
|
query GitHubIssueStatusSnapshot($owner: String!, $repo: String!, $issueNumber: Int!, $after: String) {
|
|
715
718
|
repository(owner: $owner, name: $repo) {
|
|
@@ -1613,6 +1616,20 @@ function normalizeGitHubUserLogin(value) {
|
|
|
1613
1616
|
function normalizeGitHubTokenRef(value) {
|
|
1614
1617
|
return normalizeSecretRef(value);
|
|
1615
1618
|
}
|
|
1619
|
+
function normalizeGitHubTokenRefs(value) {
|
|
1620
|
+
if (!value || typeof value !== "object") {
|
|
1621
|
+
return void 0;
|
|
1622
|
+
}
|
|
1623
|
+
const entries = Object.entries(value).map(([companyId, secretRef]) => {
|
|
1624
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
1625
|
+
const normalizedSecretRef = normalizeGitHubTokenRef(secretRef);
|
|
1626
|
+
return normalizedCompanyId && normalizedSecretRef ? [normalizedCompanyId, normalizedSecretRef] : null;
|
|
1627
|
+
}).filter((entry) => entry !== null);
|
|
1628
|
+
if (entries.length === 0) {
|
|
1629
|
+
return void 0;
|
|
1630
|
+
}
|
|
1631
|
+
return Object.fromEntries(entries);
|
|
1632
|
+
}
|
|
1616
1633
|
function formatUtcTimestamp(value) {
|
|
1617
1634
|
const parsed = new Date(value);
|
|
1618
1635
|
if (Number.isNaN(parsed.getTime())) {
|
|
@@ -2237,7 +2254,7 @@ async function hydrateRecoveredPaperclipIssueGitHubLink(ctx, issueId, fallbackLi
|
|
|
2237
2254
|
}
|
|
2238
2255
|
let octokit;
|
|
2239
2256
|
try {
|
|
2240
|
-
octokit = await createGitHubToolOctokit(ctx);
|
|
2257
|
+
octokit = await createGitHubToolOctokit(ctx, fallbackLink.companyId);
|
|
2241
2258
|
} catch {
|
|
2242
2259
|
return null;
|
|
2243
2260
|
}
|
|
@@ -2410,10 +2427,10 @@ function extractGitHubLinksFromCommentBody(body) {
|
|
|
2410
2427
|
return [...links.values()];
|
|
2411
2428
|
}
|
|
2412
2429
|
async function buildToolbarSyncState(ctx, input) {
|
|
2413
|
-
const settings = await getActiveOrCurrentSyncState(ctx);
|
|
2414
|
-
const config = await getResolvedConfig(ctx);
|
|
2415
|
-
const githubTokenConfigured = hasConfiguredGithubToken(settings, config);
|
|
2416
2430
|
const companyId = typeof input.companyId === "string" && input.companyId.trim() ? input.companyId.trim() : void 0;
|
|
2431
|
+
const settings = await getActiveOrCurrentSyncState(ctx, companyId);
|
|
2432
|
+
const config = await getResolvedConfig(ctx);
|
|
2433
|
+
const githubTokenConfigured = hasConfiguredGithubToken(settings, config, companyId);
|
|
2417
2434
|
const entityId = typeof input.entityId === "string" && input.entityId.trim() ? input.entityId.trim() : void 0;
|
|
2418
2435
|
const entityType = typeof input.entityType === "string" && input.entityType.trim() ? input.entityType.trim() : void 0;
|
|
2419
2436
|
const savedMappingCount = companyId ? getSyncableMappingsForTarget(settings.mappings, {
|
|
@@ -2454,7 +2471,7 @@ async function buildToolbarSyncState(ctx, input) {
|
|
|
2454
2471
|
}) : [];
|
|
2455
2472
|
return {
|
|
2456
2473
|
kind: "issue",
|
|
2457
|
-
visible:
|
|
2474
|
+
visible: false,
|
|
2458
2475
|
canRun: githubTokenConfigured && mappings.length > 0,
|
|
2459
2476
|
label: link?.githubIssueNumber ? `Sync #${link.githubIssueNumber}` : "Sync issue",
|
|
2460
2477
|
message: link ? `Sync ${link.repositoryUrl.replace(/^https:\/\/github\.com\//, "")} issue #${link.githubIssueNumber}.` : "This Paperclip issue is not linked to GitHub yet.",
|
|
@@ -2625,14 +2642,26 @@ function sanitizeSettingsForCurrentSetup(settings, setup) {
|
|
|
2625
2642
|
}
|
|
2626
2643
|
function getPublicSettings(settings) {
|
|
2627
2644
|
const {
|
|
2645
|
+
githubTokenRefs: _githubTokenRefs,
|
|
2646
|
+
githubTokenLoginByCompanyId: _githubTokenLoginByCompanyId,
|
|
2628
2647
|
githubTokenRef: _githubTokenRef,
|
|
2629
2648
|
paperclipBoardApiTokenRefs: _paperclipBoardApiTokenRefs,
|
|
2630
2649
|
paperclipBoardAccessIdentityByCompanyId: _paperclipBoardAccessIdentityByCompanyId,
|
|
2631
2650
|
companyAdvancedSettingsByCompanyId: _companyAdvancedSettingsByCompanyId,
|
|
2651
|
+
syncStateByCompanyId: _syncStateByCompanyId,
|
|
2652
|
+
scheduleFrequencyMinutesByCompanyId: _scheduleFrequencyMinutesByCompanyId,
|
|
2653
|
+
paperclipApiBaseUrlByCompanyId: _paperclipApiBaseUrlByCompanyId,
|
|
2632
2654
|
...publicSettings
|
|
2633
2655
|
} = settings;
|
|
2634
2656
|
return publicSettings;
|
|
2635
2657
|
}
|
|
2658
|
+
function getGitHubTokenLogin(settings, companyId) {
|
|
2659
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2660
|
+
if (!normalizedCompanyId) {
|
|
2661
|
+
return void 0;
|
|
2662
|
+
}
|
|
2663
|
+
return normalizeOptionalString2(settings.githubTokenLoginByCompanyId?.[normalizedCompanyId]) ?? normalizeOptionalString2(settings.githubTokenLogin);
|
|
2664
|
+
}
|
|
2636
2665
|
function getPaperclipBoardAccessIdentity(settings, companyId) {
|
|
2637
2666
|
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2638
2667
|
if (!normalizedCompanyId) {
|
|
@@ -2642,11 +2671,13 @@ function getPaperclipBoardAccessIdentity(settings, companyId) {
|
|
|
2642
2671
|
}
|
|
2643
2672
|
function getPublicSettingsForScope(settings, companyId) {
|
|
2644
2673
|
const publicSettings = getPublicSettings(settings);
|
|
2674
|
+
const githubTokenLogin = getGitHubTokenLogin(settings, companyId);
|
|
2645
2675
|
const paperclipBoardAccessIdentity = getPaperclipBoardAccessIdentity(settings, companyId);
|
|
2646
2676
|
return {
|
|
2647
2677
|
...publicSettings,
|
|
2648
2678
|
mappings: filterMappingsByCompany(publicSettings.mappings, companyId),
|
|
2649
2679
|
advancedSettings: getCompanyAdvancedSettings(settings, companyId),
|
|
2680
|
+
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
2650
2681
|
...paperclipBoardAccessIdentity ? { paperclipBoardAccessIdentity } : {}
|
|
2651
2682
|
};
|
|
2652
2683
|
}
|
|
@@ -2830,14 +2861,11 @@ function createSetupConfigurationErrorSyncState(issue, trigger) {
|
|
|
2830
2861
|
});
|
|
2831
2862
|
}
|
|
2832
2863
|
}
|
|
2833
|
-
async function saveSettingsSyncState(ctx, settings, syncState) {
|
|
2834
|
-
const next =
|
|
2835
|
-
...settings,
|
|
2836
|
-
syncState
|
|
2837
|
-
};
|
|
2864
|
+
async function saveSettingsSyncState(ctx, settings, syncState, companyId) {
|
|
2865
|
+
const next = upsertScopedSyncState(normalizeSettings(settings), syncState, companyId);
|
|
2838
2866
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
2839
|
-
await ctx.state.set(SYNC_STATE_SCOPE,
|
|
2840
|
-
return next;
|
|
2867
|
+
await ctx.state.set(SYNC_STATE_SCOPE, syncState);
|
|
2868
|
+
return materializeScopedSettings(next, null, companyId);
|
|
2841
2869
|
}
|
|
2842
2870
|
async function setSyncCancellationRequest(ctx, request) {
|
|
2843
2871
|
if (request) {
|
|
@@ -2862,8 +2890,8 @@ function buildCancelledSyncMessage(target, progress) {
|
|
|
2862
2890
|
const completionSummary = completedIssueCount !== void 0 && totalIssueCount !== void 0 ? ` Completed ${Math.min(completedIssueCount, totalIssueCount)} of ${totalIssueCount} issues before stopping.` : "";
|
|
2863
2891
|
return `${scopeLabel} was cancelled before it finished.${completionSummary}`;
|
|
2864
2892
|
}
|
|
2865
|
-
async function createUnexpectedSyncErrorResult(ctx, trigger, error) {
|
|
2866
|
-
const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
2893
|
+
async function createUnexpectedSyncErrorResult(ctx, trigger, error, companyId) {
|
|
2894
|
+
const settings = materializeScopedSettings(normalizeSettings(await ctx.state.get(SETTINGS_SCOPE)), null, companyId);
|
|
2867
2895
|
const errorDetails = buildSyncErrorDetails(error, {
|
|
2868
2896
|
phase: "configuration"
|
|
2869
2897
|
});
|
|
@@ -2888,7 +2916,8 @@ async function createUnexpectedSyncErrorResult(ctx, trigger, error) {
|
|
|
2888
2916
|
errorDetails
|
|
2889
2917
|
})
|
|
2890
2918
|
)
|
|
2891
|
-
})
|
|
2919
|
+
}),
|
|
2920
|
+
companyId
|
|
2892
2921
|
);
|
|
2893
2922
|
}
|
|
2894
2923
|
async function waitForSyncResultWithinGracePeriod(promise, timeoutMs) {
|
|
@@ -2906,15 +2935,13 @@ async function waitForSyncResultWithinGracePeriod(promise, timeoutMs) {
|
|
|
2906
2935
|
}
|
|
2907
2936
|
}
|
|
2908
2937
|
}
|
|
2909
|
-
async function getActiveOrCurrentSyncState(ctx) {
|
|
2910
|
-
|
|
2911
|
-
|
|
2938
|
+
async function getActiveOrCurrentSyncState(ctx, companyId) {
|
|
2939
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
2940
|
+
if (activeRunningSyncState?.syncState.status === "running" && activeRunningSyncCompanyId === normalizedCompanyId) {
|
|
2941
|
+
return materializeScopedSettings(activeRunningSyncState, null, normalizedCompanyId);
|
|
2912
2942
|
}
|
|
2913
2943
|
const current = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
2914
|
-
|
|
2915
|
-
return current;
|
|
2916
|
-
}
|
|
2917
|
-
return current;
|
|
2944
|
+
return materializeScopedSettings(current, null, normalizedCompanyId);
|
|
2918
2945
|
}
|
|
2919
2946
|
function updateSyncFailureContext(current, next) {
|
|
2920
2947
|
if ("phase" in next) {
|
|
@@ -2953,11 +2980,13 @@ function normalizeConfig(value) {
|
|
|
2953
2980
|
return {};
|
|
2954
2981
|
}
|
|
2955
2982
|
const record = value;
|
|
2983
|
+
const githubTokenRefs = normalizeGitHubTokenRefs(record.githubTokenRefs);
|
|
2956
2984
|
const githubTokenRef = normalizeGitHubTokenRef(record.githubTokenRef);
|
|
2957
2985
|
const githubToken = normalizeGitHubToken(record.githubToken);
|
|
2958
2986
|
const paperclipBoardApiTokenRefs = normalizePaperclipBoardApiTokenRefs(record.paperclipBoardApiTokenRefs);
|
|
2959
2987
|
const paperclipApiBaseUrl = normalizePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
|
|
2960
2988
|
return {
|
|
2989
|
+
...githubTokenRefs ? { githubTokenRefs } : {},
|
|
2961
2990
|
...githubTokenRef ? { githubTokenRef } : {},
|
|
2962
2991
|
...githubToken ? { githubToken } : {},
|
|
2963
2992
|
...paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs } : {},
|
|
@@ -3049,6 +3078,20 @@ function normalizePaperclipBoardApiTokenRefs(value) {
|
|
|
3049
3078
|
}
|
|
3050
3079
|
return Object.fromEntries(entries);
|
|
3051
3080
|
}
|
|
3081
|
+
function normalizeGitHubTokenLoginByCompanyId(value) {
|
|
3082
|
+
if (!value || typeof value !== "object") {
|
|
3083
|
+
return void 0;
|
|
3084
|
+
}
|
|
3085
|
+
const entries = Object.entries(value).map(([companyId, login]) => {
|
|
3086
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3087
|
+
const normalizedLogin = normalizeOptionalString2(login);
|
|
3088
|
+
return normalizedCompanyId && normalizedLogin ? [normalizedCompanyId, normalizedLogin] : null;
|
|
3089
|
+
}).filter((entry) => entry !== null);
|
|
3090
|
+
if (entries.length === 0) {
|
|
3091
|
+
return void 0;
|
|
3092
|
+
}
|
|
3093
|
+
return Object.fromEntries(entries);
|
|
3094
|
+
}
|
|
3052
3095
|
function normalizePaperclipBoardAccessIdentityByCompanyId(value) {
|
|
3053
3096
|
if (!value || typeof value !== "object") {
|
|
3054
3097
|
return void 0;
|
|
@@ -3082,14 +3125,14 @@ function normalizeSyncState(value) {
|
|
|
3082
3125
|
const recentFailures = normalizeSyncFailureLogEntries(record.recentFailures);
|
|
3083
3126
|
return {
|
|
3084
3127
|
status: status === "running" || status === "success" || status === "error" || status === "cancelled" ? status : "idle",
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
lastRunTrigger
|
|
3092
|
-
|
|
3128
|
+
...typeof record.message === "string" ? { message: record.message } : {},
|
|
3129
|
+
...typeof record.checkedAt === "string" ? { checkedAt: record.checkedAt } : {},
|
|
3130
|
+
...typeof record.syncedIssuesCount === "number" ? { syncedIssuesCount: record.syncedIssuesCount } : {},
|
|
3131
|
+
...typeof record.createdIssuesCount === "number" ? { createdIssuesCount: record.createdIssuesCount } : {},
|
|
3132
|
+
...typeof record.skippedIssuesCount === "number" ? { skippedIssuesCount: record.skippedIssuesCount } : {},
|
|
3133
|
+
...typeof record.erroredIssuesCount === "number" ? { erroredIssuesCount: record.erroredIssuesCount } : {},
|
|
3134
|
+
...lastRunTrigger === "manual" || lastRunTrigger === "schedule" || lastRunTrigger === "retry" ? { lastRunTrigger } : {},
|
|
3135
|
+
...typeof record.cancelRequestedAt === "string" ? { cancelRequestedAt: record.cancelRequestedAt } : {},
|
|
3093
3136
|
...progress ? { progress } : {},
|
|
3094
3137
|
...errorDetails ? { errorDetails } : {},
|
|
3095
3138
|
...recentFailures ? { recentFailures } : {}
|
|
@@ -3199,6 +3242,26 @@ function normalizeScheduleFrequencyMinutes(value) {
|
|
|
3199
3242
|
}
|
|
3200
3243
|
return Math.floor(numericValue);
|
|
3201
3244
|
}
|
|
3245
|
+
function normalizeSyncStateByCompanyId(value) {
|
|
3246
|
+
if (!value || typeof value !== "object") {
|
|
3247
|
+
return void 0;
|
|
3248
|
+
}
|
|
3249
|
+
const entries = Object.entries(value).map(([companyId, syncState]) => {
|
|
3250
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3251
|
+
return normalizedCompanyId ? [normalizedCompanyId, normalizeSyncState(syncState)] : null;
|
|
3252
|
+
}).filter((entry) => entry !== null);
|
|
3253
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3254
|
+
}
|
|
3255
|
+
function normalizeScheduleFrequencyMinutesByCompanyId(value) {
|
|
3256
|
+
if (!value || typeof value !== "object") {
|
|
3257
|
+
return void 0;
|
|
3258
|
+
}
|
|
3259
|
+
const entries = Object.entries(value).map(([companyId, scheduleFrequencyMinutes]) => {
|
|
3260
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3261
|
+
return normalizedCompanyId ? [normalizedCompanyId, normalizeScheduleFrequencyMinutes(scheduleFrequencyMinutes)] : null;
|
|
3262
|
+
}).filter((entry) => entry !== null);
|
|
3263
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3264
|
+
}
|
|
3202
3265
|
function normalizePaperclipApiBaseUrl(value) {
|
|
3203
3266
|
if (typeof value !== "string") {
|
|
3204
3267
|
return void 0;
|
|
@@ -3213,6 +3276,17 @@ function normalizePaperclipApiBaseUrl(value) {
|
|
|
3213
3276
|
return void 0;
|
|
3214
3277
|
}
|
|
3215
3278
|
}
|
|
3279
|
+
function normalizePaperclipApiBaseUrlByCompanyId(value) {
|
|
3280
|
+
if (!value || typeof value !== "object") {
|
|
3281
|
+
return void 0;
|
|
3282
|
+
}
|
|
3283
|
+
const entries = Object.entries(value).map(([companyId, paperclipApiBaseUrl]) => {
|
|
3284
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3285
|
+
const normalizedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(paperclipApiBaseUrl);
|
|
3286
|
+
return normalizedCompanyId && normalizedPaperclipApiBaseUrl ? [normalizedCompanyId, normalizedPaperclipApiBaseUrl] : null;
|
|
3287
|
+
}).filter((entry) => entry !== null);
|
|
3288
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
3289
|
+
}
|
|
3216
3290
|
function getRuntimePaperclipApiBaseUrl() {
|
|
3217
3291
|
if (typeof process === "undefined" || !process?.env) {
|
|
3218
3292
|
return void 0;
|
|
@@ -3232,19 +3306,26 @@ function resolvePaperclipApiBaseUrl(...values) {
|
|
|
3232
3306
|
}
|
|
3233
3307
|
return void 0;
|
|
3234
3308
|
}
|
|
3235
|
-
function getConfiguredPaperclipApiBaseUrl(settings, config) {
|
|
3236
|
-
|
|
3309
|
+
function getConfiguredPaperclipApiBaseUrl(settings, config, companyId) {
|
|
3310
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3311
|
+
return normalizedCompanyId ? resolvePaperclipApiBaseUrl(
|
|
3312
|
+
config?.paperclipApiBaseUrl,
|
|
3313
|
+
settings?.paperclipApiBaseUrlByCompanyId?.[normalizedCompanyId],
|
|
3314
|
+
settings?.paperclipApiBaseUrl
|
|
3315
|
+
) : resolvePaperclipApiBaseUrl(config?.paperclipApiBaseUrl, settings?.paperclipApiBaseUrl);
|
|
3237
3316
|
}
|
|
3238
|
-
function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config) {
|
|
3317
|
+
function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config, companyId) {
|
|
3239
3318
|
const runtimePaperclipApiBaseUrl = getRuntimePaperclipApiBaseUrl();
|
|
3240
3319
|
if (runtimePaperclipApiBaseUrl) {
|
|
3241
3320
|
return runtimePaperclipApiBaseUrl;
|
|
3242
3321
|
}
|
|
3243
3322
|
const requestedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(value);
|
|
3244
3323
|
const configuredPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(config?.paperclipApiBaseUrl);
|
|
3324
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3325
|
+
const savedCompanyPaperclipApiBaseUrl = normalizedCompanyId ? normalizePaperclipApiBaseUrl(settings?.paperclipApiBaseUrlByCompanyId?.[normalizedCompanyId]) : void 0;
|
|
3245
3326
|
const savedPaperclipApiBaseUrl = normalizePaperclipApiBaseUrl(settings?.paperclipApiBaseUrl);
|
|
3246
3327
|
if (!requestedPaperclipApiBaseUrl) {
|
|
3247
|
-
return configuredPaperclipApiBaseUrl ?? savedPaperclipApiBaseUrl;
|
|
3328
|
+
return configuredPaperclipApiBaseUrl ?? savedCompanyPaperclipApiBaseUrl ?? savedPaperclipApiBaseUrl;
|
|
3248
3329
|
}
|
|
3249
3330
|
if (configuredPaperclipApiBaseUrl) {
|
|
3250
3331
|
if (requestedPaperclipApiBaseUrl !== configuredPaperclipApiBaseUrl) {
|
|
@@ -3254,6 +3335,9 @@ function resolveTrustedPaperclipApiBaseUrlInput(value, settings, config) {
|
|
|
3254
3335
|
}
|
|
3255
3336
|
return configuredPaperclipApiBaseUrl;
|
|
3256
3337
|
}
|
|
3338
|
+
if (savedCompanyPaperclipApiBaseUrl && requestedPaperclipApiBaseUrl === savedCompanyPaperclipApiBaseUrl) {
|
|
3339
|
+
return savedCompanyPaperclipApiBaseUrl;
|
|
3340
|
+
}
|
|
3257
3341
|
if (savedPaperclipApiBaseUrl && requestedPaperclipApiBaseUrl === savedPaperclipApiBaseUrl) {
|
|
3258
3342
|
return savedPaperclipApiBaseUrl;
|
|
3259
3343
|
}
|
|
@@ -3266,7 +3350,14 @@ function normalizeSettings(value) {
|
|
|
3266
3350
|
return DEFAULT_SETTINGS;
|
|
3267
3351
|
}
|
|
3268
3352
|
const record = value;
|
|
3353
|
+
const syncStateByCompanyId = normalizeSyncStateByCompanyId(record.syncStateByCompanyId);
|
|
3354
|
+
const scheduleFrequencyMinutesByCompanyId = normalizeScheduleFrequencyMinutesByCompanyId(
|
|
3355
|
+
record.scheduleFrequencyMinutesByCompanyId
|
|
3356
|
+
);
|
|
3269
3357
|
const paperclipApiBaseUrl = resolvePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
|
|
3358
|
+
const paperclipApiBaseUrlByCompanyId = normalizePaperclipApiBaseUrlByCompanyId(record.paperclipApiBaseUrlByCompanyId);
|
|
3359
|
+
const githubTokenRefs = normalizeGitHubTokenRefs(record.githubTokenRefs);
|
|
3360
|
+
const githubTokenLoginByCompanyId = normalizeGitHubTokenLoginByCompanyId(record.githubTokenLoginByCompanyId);
|
|
3270
3361
|
const githubTokenRef = normalizeGitHubTokenRef(record.githubTokenRef);
|
|
3271
3362
|
const githubTokenLogin = normalizeOptionalString2(record.githubTokenLogin);
|
|
3272
3363
|
const paperclipBoardApiTokenRefs = normalizePaperclipBoardApiTokenRefs(record.paperclipBoardApiTokenRefs);
|
|
@@ -3277,8 +3368,13 @@ function normalizeSettings(value) {
|
|
|
3277
3368
|
return {
|
|
3278
3369
|
mappings: normalizeMappings(record.mappings),
|
|
3279
3370
|
syncState: normalizeSyncState(record.syncState),
|
|
3371
|
+
...syncStateByCompanyId ? { syncStateByCompanyId } : {},
|
|
3280
3372
|
scheduleFrequencyMinutes: normalizeScheduleFrequencyMinutes(record.scheduleFrequencyMinutes),
|
|
3373
|
+
...scheduleFrequencyMinutesByCompanyId ? { scheduleFrequencyMinutesByCompanyId } : {},
|
|
3281
3374
|
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {},
|
|
3375
|
+
...paperclipApiBaseUrlByCompanyId ? { paperclipApiBaseUrlByCompanyId } : {},
|
|
3376
|
+
...githubTokenRefs ? { githubTokenRefs } : {},
|
|
3377
|
+
...githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId } : {},
|
|
3282
3378
|
...githubTokenRef ? { githubTokenRef } : {},
|
|
3283
3379
|
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
3284
3380
|
...paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs } : {},
|
|
@@ -3287,6 +3383,103 @@ function normalizeSettings(value) {
|
|
|
3287
3383
|
updatedAt: typeof record.updatedAt === "string" ? record.updatedAt : void 0
|
|
3288
3384
|
};
|
|
3289
3385
|
}
|
|
3386
|
+
function getScopedSyncState(settings, companyId) {
|
|
3387
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3388
|
+
if (!normalizedCompanyId) {
|
|
3389
|
+
return normalizeSyncState(settings.syncState);
|
|
3390
|
+
}
|
|
3391
|
+
const scopedSyncState = settings.syncStateByCompanyId?.[normalizedCompanyId];
|
|
3392
|
+
return scopedSyncState ? normalizeSyncState(scopedSyncState) : normalizeSyncState(settings.syncState);
|
|
3393
|
+
}
|
|
3394
|
+
function getScopedScheduleFrequencyMinutes(settings, companyId) {
|
|
3395
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3396
|
+
if (!normalizedCompanyId) {
|
|
3397
|
+
return normalizeScheduleFrequencyMinutes(settings.scheduleFrequencyMinutes);
|
|
3398
|
+
}
|
|
3399
|
+
const scopedScheduleFrequencyMinutes = settings.scheduleFrequencyMinutesByCompanyId?.[normalizedCompanyId];
|
|
3400
|
+
return scopedScheduleFrequencyMinutes !== void 0 ? normalizeScheduleFrequencyMinutes(scopedScheduleFrequencyMinutes) : normalizeScheduleFrequencyMinutes(settings.scheduleFrequencyMinutes);
|
|
3401
|
+
}
|
|
3402
|
+
function materializeScopedSettings(settings, config, companyId) {
|
|
3403
|
+
const syncState = getScopedSyncState(settings, companyId);
|
|
3404
|
+
const scheduleFrequencyMinutes = getScopedScheduleFrequencyMinutes(settings, companyId);
|
|
3405
|
+
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(settings, config, companyId);
|
|
3406
|
+
return {
|
|
3407
|
+
...settings,
|
|
3408
|
+
syncState,
|
|
3409
|
+
scheduleFrequencyMinutes,
|
|
3410
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
|
|
3411
|
+
};
|
|
3412
|
+
}
|
|
3413
|
+
function upsertScopedSyncState(settings, syncState, companyId) {
|
|
3414
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3415
|
+
if (!normalizedCompanyId) {
|
|
3416
|
+
return {
|
|
3417
|
+
...settings,
|
|
3418
|
+
syncState
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
return {
|
|
3422
|
+
...settings,
|
|
3423
|
+
syncState,
|
|
3424
|
+
syncStateByCompanyId: {
|
|
3425
|
+
...settings.syncStateByCompanyId ?? {},
|
|
3426
|
+
[normalizedCompanyId]: syncState
|
|
3427
|
+
}
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
function upsertScopedScheduleFrequencyMinutes(settings, scheduleFrequencyMinutes, companyId) {
|
|
3431
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3432
|
+
if (!normalizedCompanyId) {
|
|
3433
|
+
return {
|
|
3434
|
+
...settings,
|
|
3435
|
+
scheduleFrequencyMinutes
|
|
3436
|
+
};
|
|
3437
|
+
}
|
|
3438
|
+
return {
|
|
3439
|
+
...settings,
|
|
3440
|
+
scheduleFrequencyMinutes,
|
|
3441
|
+
scheduleFrequencyMinutesByCompanyId: {
|
|
3442
|
+
...settings.scheduleFrequencyMinutesByCompanyId ?? {},
|
|
3443
|
+
[normalizedCompanyId]: scheduleFrequencyMinutes
|
|
3444
|
+
}
|
|
3445
|
+
};
|
|
3446
|
+
}
|
|
3447
|
+
function upsertScopedPaperclipApiBaseUrl(settings, paperclipApiBaseUrl, companyId) {
|
|
3448
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3449
|
+
if (!normalizedCompanyId) {
|
|
3450
|
+
return {
|
|
3451
|
+
...settings,
|
|
3452
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
|
|
3453
|
+
};
|
|
3454
|
+
}
|
|
3455
|
+
const nextPaperclipApiBaseUrlByCompanyId = {
|
|
3456
|
+
...settings.paperclipApiBaseUrlByCompanyId ?? {}
|
|
3457
|
+
};
|
|
3458
|
+
if (paperclipApiBaseUrl) {
|
|
3459
|
+
nextPaperclipApiBaseUrlByCompanyId[normalizedCompanyId] = paperclipApiBaseUrl;
|
|
3460
|
+
} else {
|
|
3461
|
+
delete nextPaperclipApiBaseUrlByCompanyId[normalizedCompanyId];
|
|
3462
|
+
}
|
|
3463
|
+
return {
|
|
3464
|
+
...settings,
|
|
3465
|
+
...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {},
|
|
3466
|
+
...Object.keys(nextPaperclipApiBaseUrlByCompanyId).length > 0 ? { paperclipApiBaseUrlByCompanyId: nextPaperclipApiBaseUrlByCompanyId } : {}
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3469
|
+
function getScopedSyncTarget(companyId) {
|
|
3470
|
+
return {
|
|
3471
|
+
kind: "company",
|
|
3472
|
+
companyId,
|
|
3473
|
+
displayLabel: "this company"
|
|
3474
|
+
};
|
|
3475
|
+
}
|
|
3476
|
+
function getSyncableMappingsForScope(mappings, companyId) {
|
|
3477
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
3478
|
+
return normalizedCompanyId ? getSyncableMappingsForTarget(mappings, getScopedSyncTarget(normalizedCompanyId)) : getSyncableMappings(mappings);
|
|
3479
|
+
}
|
|
3480
|
+
function hasAnyScopedValue(valueByCompanyId) {
|
|
3481
|
+
return Boolean(valueByCompanyId && Object.keys(valueByCompanyId).length > 0);
|
|
3482
|
+
}
|
|
3290
3483
|
function normalizeImportRegistry(value) {
|
|
3291
3484
|
if (!Array.isArray(value)) {
|
|
3292
3485
|
return [];
|
|
@@ -3446,6 +3639,7 @@ function normalizeGitHubIssueRecord(issue) {
|
|
|
3446
3639
|
body: typeof issue.body === "string" ? stripNullBytes(issue.body) : null,
|
|
3447
3640
|
htmlUrl: issue.html_url,
|
|
3448
3641
|
...normalizeGitHubUsername(issue.user?.login) ? { authorLogin: normalizeGitHubUsername(issue.user?.login) } : {},
|
|
3642
|
+
...normalizeGitHubLowercaseString(issue.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(issue.author_association) } : {},
|
|
3449
3643
|
labels: normalizeGitHubIssueLabels(issue.labels),
|
|
3450
3644
|
state: issue.state === "closed" ? "closed" : "open",
|
|
3451
3645
|
stateReason: normalizeGitHubIssueStateReason(issue.state_reason),
|
|
@@ -4226,6 +4420,22 @@ async function getGitHubIssueStatusSnapshot(octokit, repository, issueNumber, gi
|
|
|
4226
4420
|
function buildGitHubRepositoryActorCacheKey(repository, login) {
|
|
4227
4421
|
return `${repository.owner.toLowerCase()}/${repository.repo.toLowerCase()}:${login}`;
|
|
4228
4422
|
}
|
|
4423
|
+
function getGitHubRepositoryTrustedAuthorStatusFromAssociation(authorAssociation) {
|
|
4424
|
+
const normalizedAssociation = normalizeGitHubLowercaseString(authorAssociation);
|
|
4425
|
+
if (!normalizedAssociation) {
|
|
4426
|
+
return void 0;
|
|
4427
|
+
}
|
|
4428
|
+
return GITHUB_REPOSITORY_TRUSTED_AUTHOR_ASSOCIATIONS.has(normalizedAssociation);
|
|
4429
|
+
}
|
|
4430
|
+
function cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(repository, login, authorAssociation, cache) {
|
|
4431
|
+
const normalizedLogin = normalizeGitHubUserLogin(login);
|
|
4432
|
+
const trustedAuthorStatus = getGitHubRepositoryTrustedAuthorStatusFromAssociation(authorAssociation);
|
|
4433
|
+
if (!normalizedLogin || trustedAuthorStatus === void 0) {
|
|
4434
|
+
return trustedAuthorStatus;
|
|
4435
|
+
}
|
|
4436
|
+
cache.set(buildGitHubRepositoryActorCacheKey(repository, normalizedLogin), trustedAuthorStatus);
|
|
4437
|
+
return trustedAuthorStatus;
|
|
4438
|
+
}
|
|
4229
4439
|
async function isGitHubUserRepositoryMaintainer(octokit, repository, login, cache) {
|
|
4230
4440
|
const normalizedLogin = normalizeGitHubUserLogin(login);
|
|
4231
4441
|
if (!normalizedLogin) {
|
|
@@ -4291,6 +4501,7 @@ async function listNewGitHubIssueCommentsSinceCount(octokit, repository, issueNu
|
|
|
4291
4501
|
body: typeof comment.body === "string" ? stripNullBytes(comment.body) : "",
|
|
4292
4502
|
url: comment.html_url ?? void 0,
|
|
4293
4503
|
authorLogin: normalizeGitHubUserLogin(comment.user?.login),
|
|
4504
|
+
...normalizeGitHubLowercaseString(comment.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(comment.author_association) } : {},
|
|
4294
4505
|
createdAt: comment.created_at ?? void 0,
|
|
4295
4506
|
updatedAt: comment.updated_at ?? void 0
|
|
4296
4507
|
});
|
|
@@ -4332,6 +4543,18 @@ async function hasTrustedNewGitHubIssueComment(params) {
|
|
|
4332
4543
|
if (originalPosterLogin && authorLogin === originalPosterLogin) {
|
|
4333
4544
|
return true;
|
|
4334
4545
|
}
|
|
4546
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4547
|
+
params.repository,
|
|
4548
|
+
authorLogin,
|
|
4549
|
+
comment.authorAssociation,
|
|
4550
|
+
params.maintainerCache
|
|
4551
|
+
);
|
|
4552
|
+
if (trustedAuthorStatus === true) {
|
|
4553
|
+
return true;
|
|
4554
|
+
}
|
|
4555
|
+
if (trustedAuthorStatus === false) {
|
|
4556
|
+
continue;
|
|
4557
|
+
}
|
|
4335
4558
|
unseenAuthors.add(authorLogin);
|
|
4336
4559
|
}
|
|
4337
4560
|
for (const authorLogin of unseenAuthors) {
|
|
@@ -4351,6 +4574,15 @@ async function isMaintainerAuthoredGitHubIssue(params) {
|
|
|
4351
4574
|
if (!authorLogin) {
|
|
4352
4575
|
return false;
|
|
4353
4576
|
}
|
|
4577
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4578
|
+
params.repository,
|
|
4579
|
+
authorLogin,
|
|
4580
|
+
params.githubIssue.authorAssociation,
|
|
4581
|
+
params.maintainerCache
|
|
4582
|
+
);
|
|
4583
|
+
if (trustedAuthorStatus !== void 0) {
|
|
4584
|
+
return trustedAuthorStatus;
|
|
4585
|
+
}
|
|
4354
4586
|
return isGitHubUserRepositoryMaintainer(
|
|
4355
4587
|
params.octokit,
|
|
4356
4588
|
params.repository,
|
|
@@ -4360,7 +4592,19 @@ async function isMaintainerAuthoredGitHubIssue(params) {
|
|
|
4360
4592
|
}
|
|
4361
4593
|
async function warmGitHubRepositoryMaintainerCache(params) {
|
|
4362
4594
|
const uniqueAuthorLogins = [...new Set(
|
|
4363
|
-
params.githubIssues.
|
|
4595
|
+
params.githubIssues.flatMap((issue) => {
|
|
4596
|
+
const authorLogin = normalizeGitHubUserLogin(issue.authorLogin);
|
|
4597
|
+
if (!authorLogin) {
|
|
4598
|
+
return [];
|
|
4599
|
+
}
|
|
4600
|
+
const trustedAuthorStatus = cacheGitHubRepositoryTrustedAuthorStatusFromAssociation(
|
|
4601
|
+
params.repository,
|
|
4602
|
+
authorLogin,
|
|
4603
|
+
issue.authorAssociation,
|
|
4604
|
+
params.maintainerCache
|
|
4605
|
+
);
|
|
4606
|
+
return trustedAuthorStatus === void 0 ? [authorLogin] : [];
|
|
4607
|
+
})
|
|
4364
4608
|
)].filter((authorLogin) => !params.maintainerCache.has(buildGitHubRepositoryActorCacheKey(params.repository, authorLogin)));
|
|
4365
4609
|
if (uniqueAuthorLogins.length === 0) {
|
|
4366
4610
|
return;
|
|
@@ -4575,7 +4819,9 @@ function buildPaperclipIssueDescription(issue, linkedPullRequestNumbers = []) {
|
|
|
4575
4819
|
return normalizedBody ?? "";
|
|
4576
4820
|
}
|
|
4577
4821
|
if (!normalizedBody) {
|
|
4578
|
-
return
|
|
4822
|
+
return `${EMPTY_GITHUB_ISSUE_DESCRIPTION_PLACEHOLDER}
|
|
4823
|
+
|
|
4824
|
+
${hiddenImportMarker}`;
|
|
4579
4825
|
}
|
|
4580
4826
|
return `${normalizedBody}
|
|
4581
4827
|
|
|
@@ -6173,20 +6419,34 @@ async function getResolvedConfig(ctx) {
|
|
|
6173
6419
|
...normalizeConfig(savedConfig)
|
|
6174
6420
|
};
|
|
6175
6421
|
}
|
|
6176
|
-
function getConfiguredGithubTokenSource(settings, config) {
|
|
6177
|
-
const
|
|
6422
|
+
function getConfiguredGithubTokenSource(settings, config, companyId) {
|
|
6423
|
+
const normalizedCompanyId = normalizeCompanyId(companyId);
|
|
6424
|
+
const hasScopedGitHubTokenRefs = hasAnyScopedValue(settings?.githubTokenRefs) || hasAnyScopedValue(config.githubTokenRefs);
|
|
6425
|
+
const secretRef = normalizedCompanyId ? normalizeSecretRef(config.githubTokenRefs?.[normalizedCompanyId]) ?? normalizeSecretRef(settings?.githubTokenRefs?.[normalizedCompanyId]) ?? (!hasScopedGitHubTokenRefs ? normalizeGitHubTokenRef(config.githubTokenRef) ?? normalizeGitHubTokenRef(settings?.githubTokenRef) : void 0) : normalizeGitHubTokenRef(config.githubTokenRef) ?? normalizeGitHubTokenRef(settings?.githubTokenRef) ?? (() => {
|
|
6426
|
+
const configuredRefs = [
|
|
6427
|
+
...Object.values(config.githubTokenRefs ?? {}),
|
|
6428
|
+
...Object.values(settings?.githubTokenRefs ?? {})
|
|
6429
|
+
].map((value) => normalizeGitHubTokenRef(value)).filter((value) => Boolean(value));
|
|
6430
|
+
const uniqueRefs = [...new Set(configuredRefs)];
|
|
6431
|
+
return uniqueRefs.length === 1 ? uniqueRefs[0] : void 0;
|
|
6432
|
+
})();
|
|
6178
6433
|
if (secretRef) {
|
|
6179
6434
|
return { secretRef };
|
|
6180
6435
|
}
|
|
6181
|
-
const token = normalizeGitHubToken(config.githubToken);
|
|
6436
|
+
const token = !normalizedCompanyId || !hasScopedGitHubTokenRefs ? normalizeGitHubToken(config.githubToken) : void 0;
|
|
6182
6437
|
return token ? { token } : {};
|
|
6183
6438
|
}
|
|
6184
|
-
function
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6439
|
+
function hasConfiguredGithubToken(settings, config, companyId) {
|
|
6440
|
+
const configuredTokenSource = getConfiguredGithubTokenSource(settings, config, companyId);
|
|
6441
|
+
if (configuredTokenSource.secretRef ?? configuredTokenSource.token) {
|
|
6442
|
+
return true;
|
|
6443
|
+
}
|
|
6444
|
+
if (normalizeCompanyId(companyId)) {
|
|
6445
|
+
return false;
|
|
6446
|
+
}
|
|
6447
|
+
return Boolean(
|
|
6448
|
+
settings?.githubTokenRefs && Object.keys(settings.githubTokenRefs).length > 0 || config.githubTokenRefs && Object.keys(config.githubTokenRefs).length > 0
|
|
6449
|
+
);
|
|
6190
6450
|
}
|
|
6191
6451
|
function getSavedPaperclipBoardApiTokenRef(settings, companyId) {
|
|
6192
6452
|
if (!companyId) {
|
|
@@ -6269,7 +6529,7 @@ async function resolvePaperclipApiAuthTokens(ctx, settings, config, mappings) {
|
|
|
6269
6529
|
async function resolveGithubToken(ctx, options = {}) {
|
|
6270
6530
|
const settings = options.settings ?? normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
6271
6531
|
const config = options.config ?? await getResolvedConfig(ctx);
|
|
6272
|
-
const configuredTokenSource = getConfiguredGithubTokenSource(settings, config);
|
|
6532
|
+
const configuredTokenSource = getConfiguredGithubTokenSource(settings, config, options.companyId);
|
|
6273
6533
|
if (configuredTokenSource.secretRef) {
|
|
6274
6534
|
return ctx.secrets.resolve(configuredTokenSource.secretRef);
|
|
6275
6535
|
}
|
|
@@ -6347,8 +6607,8 @@ async function executeGitHubTool(fn) {
|
|
|
6347
6607
|
return buildToolErrorResult(error);
|
|
6348
6608
|
}
|
|
6349
6609
|
}
|
|
6350
|
-
async function createGitHubToolOctokit(ctx) {
|
|
6351
|
-
const token = (await resolveGithubToken(ctx)).trim();
|
|
6610
|
+
async function createGitHubToolOctokit(ctx, companyId) {
|
|
6611
|
+
const token = (await resolveGithubToken(ctx, { companyId })).trim();
|
|
6352
6612
|
if (!token) {
|
|
6353
6613
|
throw new Error(MISSING_GITHUB_TOKEN_SYNC_MESSAGE);
|
|
6354
6614
|
}
|
|
@@ -6888,6 +7148,7 @@ async function listAllGitHubIssueComments(octokit, repository, issueNumber) {
|
|
|
6888
7148
|
body: typeof comment.body === "string" ? stripNullBytes(comment.body) : "",
|
|
6889
7149
|
url: comment.html_url ?? void 0,
|
|
6890
7150
|
authorLogin: normalizeGitHubUserLogin(comment.user?.login),
|
|
7151
|
+
...normalizeGitHubLowercaseString(comment.author_association) ? { authorAssociation: normalizeGitHubLowercaseString(comment.author_association) } : {},
|
|
6891
7152
|
authorUrl: comment.user?.html_url ?? void 0,
|
|
6892
7153
|
authorAvatarUrl: comment.user?.avatar_url ?? void 0,
|
|
6893
7154
|
createdAt: comment.created_at ?? void 0,
|
|
@@ -7770,7 +8031,7 @@ async function getOrLoadCachedProjectPullRequestMetricsEntry(ctx, scope, octokit
|
|
|
7770
8031
|
return inFlightMetrics;
|
|
7771
8032
|
}
|
|
7772
8033
|
const loadMetricsPromise = (async () => {
|
|
7773
|
-
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
|
|
8034
|
+
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
|
|
7774
8035
|
const metrics = await listProjectPullRequestMetrics(resolvedOctokit, scope);
|
|
7775
8036
|
return cacheProjectPullRequestMetricsEntry(scope, metrics);
|
|
7776
8037
|
})();
|
|
@@ -7808,7 +8069,7 @@ async function getOrLoadCachedProjectPullRequestCount(ctx, scope, octokit) {
|
|
|
7808
8069
|
return inFlightCount;
|
|
7809
8070
|
}
|
|
7810
8071
|
const loadCountPromise = (async () => {
|
|
7811
|
-
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
|
|
8072
|
+
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
|
|
7812
8073
|
const totalOpenPullRequests = await listProjectPullRequestCount(resolvedOctokit, scope);
|
|
7813
8074
|
return setCacheValue(
|
|
7814
8075
|
activeProjectPullRequestCountCache,
|
|
@@ -7920,7 +8181,7 @@ async function getOrLoadProjectPullRequestSummaryRecordsForNumbers(ctx, scope, p
|
|
|
7920
8181
|
}
|
|
7921
8182
|
const missingPullRequestNumbers = normalizedPullRequestNumbers.filter((pullRequestNumber) => !recordsByNumber.has(pullRequestNumber));
|
|
7922
8183
|
if (missingPullRequestNumbers.length > 0) {
|
|
7923
|
-
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
|
|
8184
|
+
const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
|
|
7924
8185
|
const loadedRecords = await listProjectPullRequestSummaryRecordsByNumbers(
|
|
7925
8186
|
ctx,
|
|
7926
8187
|
resolvedOctokit,
|
|
@@ -8030,7 +8291,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
|
|
|
8030
8291
|
}
|
|
8031
8292
|
const scope = await requireProjectPullRequestScope(ctx, input, projectMappings);
|
|
8032
8293
|
const config = await getResolvedConfig(ctx);
|
|
8033
|
-
if (!hasConfiguredGithubToken(settings, config)) {
|
|
8294
|
+
if (!hasConfiguredGithubToken(settings, config, scope.companyId)) {
|
|
8034
8295
|
return {
|
|
8035
8296
|
status: "missing_token",
|
|
8036
8297
|
projectId,
|
|
@@ -8049,7 +8310,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
|
|
|
8049
8310
|
};
|
|
8050
8311
|
}
|
|
8051
8312
|
try {
|
|
8052
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8313
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8053
8314
|
const pageCacheKey = buildProjectPullRequestPageCacheKey(scope, filter, pageIndex, cursor);
|
|
8054
8315
|
const cachedPage = getFreshCacheValue(activeProjectPullRequestPageCache, pageCacheKey);
|
|
8055
8316
|
if (cachedPage) {
|
|
@@ -8221,7 +8482,7 @@ async function buildProjectPullRequestMetricsData(ctx, input) {
|
|
|
8221
8482
|
};
|
|
8222
8483
|
}
|
|
8223
8484
|
const config = await getResolvedConfig(ctx);
|
|
8224
|
-
if (!hasConfiguredGithubToken(settings, config)) {
|
|
8485
|
+
if (!hasConfiguredGithubToken(settings, config, companyId)) {
|
|
8225
8486
|
return {
|
|
8226
8487
|
status: "missing_token",
|
|
8227
8488
|
projectId,
|
|
@@ -8270,7 +8531,7 @@ async function buildProjectPullRequestCountData(ctx, input) {
|
|
|
8270
8531
|
};
|
|
8271
8532
|
}
|
|
8272
8533
|
const config = await getResolvedConfig(ctx);
|
|
8273
|
-
if (!hasConfiguredGithubToken(settings, config)) {
|
|
8534
|
+
if (!hasConfiguredGithubToken(settings, config, companyId)) {
|
|
8274
8535
|
return {
|
|
8275
8536
|
status: "missing_token",
|
|
8276
8537
|
projectId,
|
|
@@ -8307,7 +8568,7 @@ async function buildSettingsTokenPermissionAuditData(ctx, input) {
|
|
|
8307
8568
|
}
|
|
8308
8569
|
const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
8309
8570
|
const config = await getResolvedConfig(ctx);
|
|
8310
|
-
if (!hasConfiguredGithubToken(settings, config)) {
|
|
8571
|
+
if (!hasConfiguredGithubToken(settings, config, requestedCompanyId)) {
|
|
8311
8572
|
return {
|
|
8312
8573
|
status: "missing_token",
|
|
8313
8574
|
allRequiredPermissionsGranted: false,
|
|
@@ -8328,7 +8589,7 @@ async function buildSettingsTokenPermissionAuditData(ctx, input) {
|
|
|
8328
8589
|
};
|
|
8329
8590
|
}
|
|
8330
8591
|
try {
|
|
8331
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8592
|
+
const octokit = await createGitHubToolOctokit(ctx, requestedCompanyId);
|
|
8332
8593
|
const repositories = await Promise.all(
|
|
8333
8594
|
[
|
|
8334
8595
|
...new Map(
|
|
@@ -8397,7 +8658,7 @@ async function buildProjectPullRequestDetailData(ctx, input) {
|
|
|
8397
8658
|
buildProjectPullRequestSummaryRecordCacheKey(scope, pullRequestNumber)
|
|
8398
8659
|
);
|
|
8399
8660
|
const cachedLinkedIssue = cachedSummaryRecord ? getLinkedPaperclipIssueFromProjectPullRequestRecord(cachedSummaryRecord) : void 0;
|
|
8400
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8661
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8401
8662
|
const response = await octokit.rest.pulls.get({
|
|
8402
8663
|
owner: scope.repository.owner,
|
|
8403
8664
|
repo: scope.repository.repo,
|
|
@@ -8528,7 +8789,7 @@ async function createProjectPullRequestPaperclipIssue(ctx, input) {
|
|
|
8528
8789
|
throw new Error("This Paperclip runtime does not expose plugin issue creation yet.");
|
|
8529
8790
|
}
|
|
8530
8791
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8531
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8792
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8532
8793
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
8533
8794
|
owner: scope.repository.owner,
|
|
8534
8795
|
repo: scope.repository.repo,
|
|
@@ -8602,7 +8863,7 @@ async function updateProjectPullRequestBranch(ctx, input) {
|
|
|
8602
8863
|
throw new Error("pullRequestNumber is required.");
|
|
8603
8864
|
}
|
|
8604
8865
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8605
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8866
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8606
8867
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
8607
8868
|
owner: scope.repository.owner,
|
|
8608
8869
|
repo: scope.repository.repo,
|
|
@@ -8665,7 +8926,7 @@ async function mergeProjectPullRequest(ctx, input) {
|
|
|
8665
8926
|
throw new Error("pullRequestNumber is required.");
|
|
8666
8927
|
}
|
|
8667
8928
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8668
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8929
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8669
8930
|
const response = await octokit.rest.pulls.merge({
|
|
8670
8931
|
owner: scope.repository.owner,
|
|
8671
8932
|
repo: scope.repository.repo,
|
|
@@ -8689,7 +8950,7 @@ async function closeProjectPullRequest(ctx, input) {
|
|
|
8689
8950
|
throw new Error("pullRequestNumber is required.");
|
|
8690
8951
|
}
|
|
8691
8952
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8692
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8953
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8693
8954
|
const response = await octokit.rest.pulls.update({
|
|
8694
8955
|
owner: scope.repository.owner,
|
|
8695
8956
|
repo: scope.repository.repo,
|
|
@@ -8718,7 +8979,7 @@ async function addProjectPullRequestComment(ctx, input) {
|
|
|
8718
8979
|
throw new Error("Comment body cannot be empty.");
|
|
8719
8980
|
}
|
|
8720
8981
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8721
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
8982
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8722
8983
|
const response = await createProjectPullRequestGitHubComment(octokit, scope, pullRequestNumber, body);
|
|
8723
8984
|
invalidateProjectPullRequestCaches(scope);
|
|
8724
8985
|
return {
|
|
@@ -8775,7 +9036,7 @@ async function requestProjectPullRequestCopilotAction(ctx, input) {
|
|
|
8775
9036
|
throw new Error('action must be one of "fix_ci", "rebase", "address_review_feedback", or "review".');
|
|
8776
9037
|
}
|
|
8777
9038
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8778
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
9039
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8779
9040
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
8780
9041
|
owner: scope.repository.owner,
|
|
8781
9042
|
repo: scope.repository.repo,
|
|
@@ -8889,7 +9150,7 @@ async function reviewProjectPullRequest(ctx, input) {
|
|
|
8889
9150
|
}
|
|
8890
9151
|
const body = typeof input.body === "string" ? input.body.trim() : "";
|
|
8891
9152
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8892
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
9153
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8893
9154
|
let response;
|
|
8894
9155
|
try {
|
|
8895
9156
|
response = await octokit.rest.pulls.createReview({
|
|
@@ -8936,7 +9197,7 @@ async function rerunProjectPullRequestCi(ctx, input) {
|
|
|
8936
9197
|
throw new Error("pullRequestNumber is required.");
|
|
8937
9198
|
}
|
|
8938
9199
|
const scope = await requireProjectPullRequestScope(ctx, input);
|
|
8939
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
9200
|
+
const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
|
|
8940
9201
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
8941
9202
|
owner: scope.repository.owner,
|
|
8942
9203
|
repo: scope.repository.repo,
|
|
@@ -9122,12 +9383,25 @@ function shouldRunScheduledSync(settings, scheduledAt) {
|
|
|
9122
9383
|
}
|
|
9123
9384
|
return now - lastCheckedAt >= settings.scheduleFrequencyMinutes * 6e4;
|
|
9124
9385
|
}
|
|
9386
|
+
function listScheduledSyncTargets(settings) {
|
|
9387
|
+
const companyIds = [
|
|
9388
|
+
...new Set(
|
|
9389
|
+
settings.mappings.map((mapping) => normalizeCompanyId(mapping.companyId)).filter((companyId) => Boolean(companyId))
|
|
9390
|
+
)
|
|
9391
|
+
];
|
|
9392
|
+
if (companyIds.length === 0) {
|
|
9393
|
+
return settings.mappings.length > 0 ? [void 0] : [];
|
|
9394
|
+
}
|
|
9395
|
+
return companyIds.map((companyId) => getScopedSyncTarget(companyId));
|
|
9396
|
+
}
|
|
9125
9397
|
async function performSync(ctx, trigger, options = {}) {
|
|
9126
|
-
const
|
|
9398
|
+
const targetCompanyId = normalizeCompanyId(options.target?.companyId);
|
|
9399
|
+
const baseSettings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
9127
9400
|
const config = await getResolvedConfig(ctx);
|
|
9401
|
+
const settings = materializeScopedSettings(baseSettings, config, targetCompanyId);
|
|
9128
9402
|
const importRegistry = normalizeImportRegistry(await ctx.state.get(IMPORT_REGISTRY_SCOPE));
|
|
9129
|
-
const token = typeof options.resolvedToken === "string" ? options.resolvedToken : await resolveGithubToken(ctx);
|
|
9130
|
-
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(
|
|
9403
|
+
const token = typeof options.resolvedToken === "string" ? options.resolvedToken : await resolveGithubToken(ctx, { companyId: targetCompanyId });
|
|
9404
|
+
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(baseSettings, config, targetCompanyId);
|
|
9131
9405
|
const mappings = getSyncableMappingsForTarget(settings.mappings, options.target);
|
|
9132
9406
|
activePaperclipApiAuthTokensByCompanyId = null;
|
|
9133
9407
|
const failureContext = {
|
|
@@ -9138,18 +9412,14 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9138
9412
|
...settings,
|
|
9139
9413
|
syncState: createSetupConfigurationErrorSyncState("missing_token", trigger)
|
|
9140
9414
|
};
|
|
9141
|
-
|
|
9142
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9143
|
-
return next;
|
|
9415
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9144
9416
|
}
|
|
9145
9417
|
if (mappings.length === 0) {
|
|
9146
9418
|
const next = {
|
|
9147
9419
|
...settings,
|
|
9148
9420
|
syncState: createSetupConfigurationErrorSyncState("missing_mapping", trigger)
|
|
9149
9421
|
};
|
|
9150
|
-
|
|
9151
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9152
|
-
return next;
|
|
9422
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9153
9423
|
}
|
|
9154
9424
|
const mappingsMissingBoardAccess = getMappingsMissingPaperclipBoardAccess(settings, config, mappings);
|
|
9155
9425
|
if (mappingsMissingBoardAccess.length > 0 && await detectPaperclipBoardAccessRequirement(paperclipApiBaseUrl)) {
|
|
@@ -9157,9 +9427,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9157
9427
|
...settings,
|
|
9158
9428
|
syncState: createSetupConfigurationErrorSyncState("missing_board_access", trigger)
|
|
9159
9429
|
};
|
|
9160
|
-
|
|
9161
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9162
|
-
return next;
|
|
9430
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9163
9431
|
}
|
|
9164
9432
|
if (!ctx.issues || typeof ctx.issues.create !== "function") {
|
|
9165
9433
|
const errorDetails = {
|
|
@@ -9185,9 +9453,7 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9185
9453
|
)
|
|
9186
9454
|
})
|
|
9187
9455
|
};
|
|
9188
|
-
|
|
9189
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9190
|
-
return next;
|
|
9456
|
+
return saveSettingsSyncState(ctx, settings, next.syncState, targetCompanyId);
|
|
9191
9457
|
}
|
|
9192
9458
|
activePaperclipApiAuthTokensByCompanyId = await resolvePaperclipApiAuthTokens(ctx, settings, config, mappings);
|
|
9193
9459
|
const octokit = new Octokit({ auth: token });
|
|
@@ -9255,7 +9521,8 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9255
9521
|
erroredIssuesCount: recoverableFailures.length,
|
|
9256
9522
|
progress,
|
|
9257
9523
|
recentFailures
|
|
9258
|
-
})
|
|
9524
|
+
}),
|
|
9525
|
+
targetCompanyId
|
|
9259
9526
|
);
|
|
9260
9527
|
activeRunningSyncState = currentSettings;
|
|
9261
9528
|
lastProgressPersistedAt = now;
|
|
@@ -9592,10 +9859,9 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9592
9859
|
recentFailures: buildRecentSyncFailureLogEntries(recoverableFailures)
|
|
9593
9860
|
})
|
|
9594
9861
|
};
|
|
9595
|
-
await ctx.
|
|
9596
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next2.syncState);
|
|
9862
|
+
await saveSettingsSyncState(ctx, currentSettings, next2.syncState, targetCompanyId);
|
|
9597
9863
|
await ctx.state.set(IMPORT_REGISTRY_SCOPE, nextRegistry);
|
|
9598
|
-
return next2;
|
|
9864
|
+
return materializeScopedSettings(next2, config, targetCompanyId);
|
|
9599
9865
|
}
|
|
9600
9866
|
const next = {
|
|
9601
9867
|
...currentSettings,
|
|
@@ -9651,10 +9917,9 @@ async function performSync(ctx, trigger, options = {}) {
|
|
|
9651
9917
|
)
|
|
9652
9918
|
})
|
|
9653
9919
|
};
|
|
9654
|
-
await ctx.
|
|
9655
|
-
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
9920
|
+
await saveSettingsSyncState(ctx, currentSettings, next.syncState, targetCompanyId);
|
|
9656
9921
|
await ctx.state.set(IMPORT_REGISTRY_SCOPE, nextRegistry);
|
|
9657
|
-
return next;
|
|
9922
|
+
return materializeScopedSettings(next, config, targetCompanyId);
|
|
9658
9923
|
}
|
|
9659
9924
|
}
|
|
9660
9925
|
async function startSync(ctx, trigger, options = {}) {
|
|
@@ -9672,26 +9937,32 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9672
9937
|
getResolvedConfig(ctx),
|
|
9673
9938
|
ctx.state.get(SETTINGS_SCOPE).then((value) => normalizeSettings(value))
|
|
9674
9939
|
]);
|
|
9940
|
+
const targetCompanyId = normalizeCompanyId(options.target?.companyId);
|
|
9675
9941
|
const token = await resolveGithubToken(ctx, {
|
|
9942
|
+
companyId: targetCompanyId,
|
|
9676
9943
|
config,
|
|
9677
9944
|
settings: persistedSettings
|
|
9678
9945
|
}).catch(() => "");
|
|
9679
|
-
let currentSettings = sanitizeSettingsForCurrentSetup(persistedSettings, {
|
|
9946
|
+
let currentSettings = sanitizeSettingsForCurrentSetup(materializeScopedSettings(persistedSettings, config, targetCompanyId), {
|
|
9680
9947
|
hasToken: Boolean(token.trim()),
|
|
9681
|
-
hasMappings:
|
|
9948
|
+
hasMappings: getSyncableMappingsForScope(persistedSettings.mappings, targetCompanyId).length > 0
|
|
9682
9949
|
});
|
|
9683
|
-
const nextPaperclipApiBaseUrl = trigger === "manual" ? resolveTrustedPaperclipApiBaseUrlInput(options.paperclipApiBaseUrl,
|
|
9950
|
+
const nextPaperclipApiBaseUrl = trigger === "manual" ? resolveTrustedPaperclipApiBaseUrlInput(options.paperclipApiBaseUrl, persistedSettings, config, targetCompanyId) : getConfiguredPaperclipApiBaseUrl(persistedSettings, config, targetCompanyId);
|
|
9684
9951
|
if (nextPaperclipApiBaseUrl !== currentSettings.paperclipApiBaseUrl) {
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9952
|
+
const nextPersistedSettings = upsertScopedPaperclipApiBaseUrl(
|
|
9953
|
+
{
|
|
9954
|
+
...persistedSettings,
|
|
9955
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9956
|
+
},
|
|
9957
|
+
nextPaperclipApiBaseUrl,
|
|
9958
|
+
targetCompanyId
|
|
9959
|
+
);
|
|
9960
|
+
await ctx.state.set(SETTINGS_SCOPE, nextPersistedSettings);
|
|
9691
9961
|
await ctx.state.set(SYNC_STATE_SCOPE, currentSettings.syncState);
|
|
9962
|
+
currentSettings = materializeScopedSettings(nextPersistedSettings, config, targetCompanyId);
|
|
9692
9963
|
}
|
|
9693
|
-
if (currentSettings !== persistedSettings) {
|
|
9694
|
-
await saveSettingsSyncState(ctx,
|
|
9964
|
+
if (JSON.stringify(currentSettings.syncState) !== JSON.stringify(getScopedSyncState(persistedSettings, targetCompanyId))) {
|
|
9965
|
+
await saveSettingsSyncState(ctx, persistedSettings, currentSettings.syncState, targetCompanyId);
|
|
9695
9966
|
}
|
|
9696
9967
|
if (getActiveGitHubRateLimitPause(currentSettings.syncState)) {
|
|
9697
9968
|
return currentSettings;
|
|
@@ -9720,7 +9991,8 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9720
9991
|
...currentSettings,
|
|
9721
9992
|
syncState
|
|
9722
9993
|
};
|
|
9723
|
-
|
|
9994
|
+
activeRunningSyncCompanyId = targetCompanyId;
|
|
9995
|
+
return saveSettingsSyncState(ctx, currentSettings, syncState, targetCompanyId);
|
|
9724
9996
|
})();
|
|
9725
9997
|
activeSyncPromise = (async () => {
|
|
9726
9998
|
try {
|
|
@@ -9730,11 +10002,12 @@ async function startSync(ctx, trigger, options = {}) {
|
|
|
9730
10002
|
target: options.target
|
|
9731
10003
|
});
|
|
9732
10004
|
} catch (error) {
|
|
9733
|
-
return await createUnexpectedSyncErrorResult(ctx, trigger, error);
|
|
10005
|
+
return await createUnexpectedSyncErrorResult(ctx, trigger, error, targetCompanyId);
|
|
9734
10006
|
} finally {
|
|
9735
10007
|
await setSyncCancellationRequest(ctx, null);
|
|
9736
10008
|
activePaperclipApiAuthTokensByCompanyId = null;
|
|
9737
10009
|
activeRunningSyncState = null;
|
|
10010
|
+
activeRunningSyncCompanyId = void 0;
|
|
9738
10011
|
activeSyncPromise = null;
|
|
9739
10012
|
}
|
|
9740
10013
|
})();
|
|
@@ -9763,7 +10036,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
9763
10036
|
getGitHubAgentToolDeclaration("search_repository_items"),
|
|
9764
10037
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
9765
10038
|
const input = getToolInputRecord(params);
|
|
9766
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10039
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
9767
10040
|
const repository = await resolveGitHubToolRepository(ctx, runCtx, input);
|
|
9768
10041
|
const rawQuery = normalizeOptionalToolString(input.query);
|
|
9769
10042
|
if (!rawQuery) {
|
|
@@ -9832,7 +10105,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
9832
10105
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
9833
10106
|
const input = getToolInputRecord(params);
|
|
9834
10107
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
9835
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10108
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
9836
10109
|
const response = await octokit.rest.issues.get({
|
|
9837
10110
|
owner: target.repository.owner,
|
|
9838
10111
|
repo: target.repository.repo,
|
|
@@ -9879,7 +10152,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
9879
10152
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
9880
10153
|
const input = getToolInputRecord(params);
|
|
9881
10154
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
9882
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10155
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
9883
10156
|
const comments = await listAllGitHubIssueComments(octokit, target.repository, target.issueNumber);
|
|
9884
10157
|
return buildToolSuccessResult(
|
|
9885
10158
|
`Loaded ${comments.length} GitHub ${comments.length === 1 ? "comment" : "comments"} from issue #${target.issueNumber}.`,
|
|
@@ -9897,7 +10170,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
9897
10170
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
9898
10171
|
const input = getToolInputRecord(params);
|
|
9899
10172
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
9900
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10173
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
9901
10174
|
const currentResponse = await octokit.rest.issues.get({
|
|
9902
10175
|
owner: target.repository.owner,
|
|
9903
10176
|
repo: target.repository.repo,
|
|
@@ -9969,7 +10242,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
9969
10242
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
9970
10243
|
const input = getToolInputRecord(params);
|
|
9971
10244
|
const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
|
|
9972
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10245
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
9973
10246
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), normalizeOptionalToolString(input.llmModel) ?? "");
|
|
9974
10247
|
const response = await octokit.rest.issues.createComment({
|
|
9975
10248
|
owner: target.repository.owner,
|
|
@@ -10008,7 +10281,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10008
10281
|
if (!head || !base || !title) {
|
|
10009
10282
|
throw new Error("head, base, and title are required.");
|
|
10010
10283
|
}
|
|
10011
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10284
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10012
10285
|
const response = await octokit.rest.pulls.create({
|
|
10013
10286
|
owner: repository.owner,
|
|
10014
10287
|
repo: repository.repo,
|
|
@@ -10045,7 +10318,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10045
10318
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10046
10319
|
const input = getToolInputRecord(params);
|
|
10047
10320
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10048
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10321
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10049
10322
|
const response = await octokit.rest.pulls.get({
|
|
10050
10323
|
owner: target.repository.owner,
|
|
10051
10324
|
repo: target.repository.repo,
|
|
@@ -10093,7 +10366,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10093
10366
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10094
10367
|
const input = getToolInputRecord(params);
|
|
10095
10368
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10096
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10369
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10097
10370
|
let currentResponse = await octokit.rest.pulls.get({
|
|
10098
10371
|
owner: target.repository.owner,
|
|
10099
10372
|
repo: target.repository.repo,
|
|
@@ -10158,7 +10431,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10158
10431
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10159
10432
|
const input = getToolInputRecord(params);
|
|
10160
10433
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10161
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10434
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10162
10435
|
const files = await listAllPullRequestFiles(octokit, target.repository, target.pullRequestNumber);
|
|
10163
10436
|
return buildToolSuccessResult(
|
|
10164
10437
|
`Loaded ${files.length} changed ${files.length === 1 ? "file" : "files"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -10176,7 +10449,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10176
10449
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10177
10450
|
const input = getToolInputRecord(params);
|
|
10178
10451
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10179
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10452
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10180
10453
|
const pullRequestResponse = await octokit.rest.pulls.get({
|
|
10181
10454
|
owner: target.repository.owner,
|
|
10182
10455
|
repo: target.repository.repo,
|
|
@@ -10274,7 +10547,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10274
10547
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10275
10548
|
const input = getToolInputRecord(params);
|
|
10276
10549
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10277
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10550
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10278
10551
|
const threads = await listDetailedPullRequestReviewThreads(octokit, target.repository, target.pullRequestNumber);
|
|
10279
10552
|
return buildToolSuccessResult(
|
|
10280
10553
|
`Loaded ${threads.length} review ${threads.length === 1 ? "thread" : "threads"} from pull request #${target.pullRequestNumber}.`,
|
|
@@ -10289,14 +10562,14 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10289
10562
|
ctx.tools.register(
|
|
10290
10563
|
"reply_to_review_thread",
|
|
10291
10564
|
getGitHubAgentToolDeclaration("reply_to_review_thread"),
|
|
10292
|
-
async (params) => executeGitHubTool(async () => {
|
|
10565
|
+
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10293
10566
|
const input = getToolInputRecord(params);
|
|
10294
10567
|
const threadId = normalizeOptionalToolString(input.threadId);
|
|
10295
10568
|
if (!threadId) {
|
|
10296
10569
|
throw new Error("threadId is required.");
|
|
10297
10570
|
}
|
|
10298
10571
|
const body = appendAiAuthorshipFooter(String(input.body ?? ""), normalizeOptionalToolString(input.llmModel) ?? "");
|
|
10299
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10572
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10300
10573
|
const response = await octokit.graphql(
|
|
10301
10574
|
GITHUB_ADD_PULL_REQUEST_REVIEW_THREAD_REPLY_MUTATION,
|
|
10302
10575
|
{
|
|
@@ -10325,13 +10598,13 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10325
10598
|
ctx.tools.register(
|
|
10326
10599
|
"resolve_review_thread",
|
|
10327
10600
|
getGitHubAgentToolDeclaration("resolve_review_thread"),
|
|
10328
|
-
async (params) => executeGitHubTool(async () => {
|
|
10601
|
+
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10329
10602
|
const input = getToolInputRecord(params);
|
|
10330
10603
|
const threadId = normalizeOptionalToolString(input.threadId);
|
|
10331
10604
|
if (!threadId) {
|
|
10332
10605
|
throw new Error("threadId is required.");
|
|
10333
10606
|
}
|
|
10334
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10607
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10335
10608
|
const response = await octokit.graphql(
|
|
10336
10609
|
GITHUB_RESOLVE_REVIEW_THREAD_MUTATION,
|
|
10337
10610
|
{
|
|
@@ -10356,13 +10629,13 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10356
10629
|
ctx.tools.register(
|
|
10357
10630
|
"unresolve_review_thread",
|
|
10358
10631
|
getGitHubAgentToolDeclaration("unresolve_review_thread"),
|
|
10359
|
-
async (params) => executeGitHubTool(async () => {
|
|
10632
|
+
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10360
10633
|
const input = getToolInputRecord(params);
|
|
10361
10634
|
const threadId = normalizeOptionalToolString(input.threadId);
|
|
10362
10635
|
if (!threadId) {
|
|
10363
10636
|
throw new Error("threadId is required.");
|
|
10364
10637
|
}
|
|
10365
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10638
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10366
10639
|
const response = await octokit.graphql(
|
|
10367
10640
|
GITHUB_UNRESOLVE_REVIEW_THREAD_MUTATION,
|
|
10368
10641
|
{
|
|
@@ -10395,7 +10668,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10395
10668
|
if (userReviewers.length === 0 && teamReviewers.length === 0) {
|
|
10396
10669
|
throw new Error("Provide at least one user reviewer or team reviewer.");
|
|
10397
10670
|
}
|
|
10398
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10671
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10399
10672
|
const response = await octokit.rest.pulls.requestReviewers({
|
|
10400
10673
|
owner: target.repository.owner,
|
|
10401
10674
|
repo: target.repository.repo,
|
|
@@ -10420,13 +10693,13 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10420
10693
|
ctx.tools.register(
|
|
10421
10694
|
"list_organization_projects",
|
|
10422
10695
|
getGitHubAgentToolDeclaration("list_organization_projects"),
|
|
10423
|
-
async (params) => executeGitHubTool(async () => {
|
|
10696
|
+
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10424
10697
|
const input = getToolInputRecord(params);
|
|
10425
10698
|
const organization = normalizeOptionalToolString(input.organization);
|
|
10426
10699
|
if (!organization) {
|
|
10427
10700
|
throw new Error("organization is required.");
|
|
10428
10701
|
}
|
|
10429
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10702
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10430
10703
|
const projects = await listGitHubOrganizationProjects(octokit, organization, {
|
|
10431
10704
|
includeClosed: input.includeClosed === true,
|
|
10432
10705
|
query: normalizeOptionalToolString(input.query),
|
|
@@ -10447,7 +10720,7 @@ function registerGitHubAgentTools(ctx) {
|
|
|
10447
10720
|
async (params, runCtx) => executeGitHubTool(async () => {
|
|
10448
10721
|
const input = getToolInputRecord(params);
|
|
10449
10722
|
const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
|
|
10450
|
-
const octokit = await createGitHubToolOctokit(ctx);
|
|
10723
|
+
const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
|
|
10451
10724
|
const projectTarget = await resolveGitHubProjectToolTarget(octokit, input);
|
|
10452
10725
|
const pullRequest = await getGitHubPullRequestProjectItems(
|
|
10453
10726
|
octokit,
|
|
@@ -10524,22 +10797,18 @@ var plugin = definePlugin({
|
|
|
10524
10797
|
const importRegistry = normalizeImportRegistry(await ctx.state.get(IMPORT_REGISTRY_SCOPE));
|
|
10525
10798
|
const normalizedSettings = normalizeSettings(saved);
|
|
10526
10799
|
const config = await getResolvedConfig(ctx);
|
|
10527
|
-
const
|
|
10528
|
-
const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(normalizedSettings, config);
|
|
10529
|
-
const githubTokenConfigured = hasConfiguredGithubToken(normalizedSettings, config);
|
|
10800
|
+
const githubTokenConfigured = hasConfiguredGithubToken(normalizedSettings, config, requestedCompanyId);
|
|
10530
10801
|
const configuredBoardTokenRef = getConfiguredPaperclipBoardApiTokenRef(config, requestedCompanyId);
|
|
10531
10802
|
const savedBoardTokenRef = getSavedPaperclipBoardApiTokenRef(normalizedSettings, requestedCompanyId);
|
|
10532
|
-
const
|
|
10533
|
-
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
if (settingsForResponse !== normalizedSettings) {
|
|
10542
|
-
await saveSettingsSyncState(ctx, settingsForResponse, settingsForResponse.syncState);
|
|
10803
|
+
const settingsForResponse = sanitizeSettingsForCurrentSetup(
|
|
10804
|
+
materializeScopedSettings(normalizedSettings, config, requestedCompanyId),
|
|
10805
|
+
{
|
|
10806
|
+
hasToken: githubTokenConfigured,
|
|
10807
|
+
hasMappings: getSyncableMappingsForScope(normalizedSettings.mappings, requestedCompanyId).length > 0
|
|
10808
|
+
}
|
|
10809
|
+
);
|
|
10810
|
+
if (JSON.stringify(settingsForResponse.syncState) !== JSON.stringify(getScopedSyncState(normalizedSettings, requestedCompanyId))) {
|
|
10811
|
+
await saveSettingsSyncState(ctx, normalizedSettings, settingsForResponse.syncState, requestedCompanyId);
|
|
10543
10812
|
}
|
|
10544
10813
|
const scopedMappings = filterMappingsByCompany(settingsForResponse.mappings, requestedCompanyId);
|
|
10545
10814
|
const availableAssignees = includeAssignees && requestedCompanyId ? await listAvailableAssignees(ctx, requestedCompanyId) : [];
|
|
@@ -10598,10 +10867,34 @@ var plugin = definePlugin({
|
|
|
10598
10867
|
const config = await getResolvedConfig(ctx);
|
|
10599
10868
|
const record = input && typeof input === "object" ? input : {};
|
|
10600
10869
|
const requestedCompanyId = normalizeCompanyId(record.companyId);
|
|
10870
|
+
const requestedGitHubTokenLogin = "githubTokenLogin" in record ? normalizeOptionalString2(record.githubTokenLogin) : void 0;
|
|
10601
10871
|
const hasMappingsPatch = "mappings" in record;
|
|
10602
10872
|
const hasAdvancedSettingsPatch = "advancedSettings" in record;
|
|
10603
|
-
const
|
|
10604
|
-
const
|
|
10873
|
+
const previousScopedSettings = materializeScopedSettings(previous, config, requestedCompanyId);
|
|
10874
|
+
const nextGitHubTokenRefs = {
|
|
10875
|
+
...previous.githubTokenRefs ?? {}
|
|
10876
|
+
};
|
|
10877
|
+
if (requestedCompanyId) {
|
|
10878
|
+
const companyScopedGitHubTokenRef = normalizeGitHubTokenRefs(record.githubTokenRefs)?.[requestedCompanyId] ?? ("githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : void 0);
|
|
10879
|
+
if (companyScopedGitHubTokenRef) {
|
|
10880
|
+
nextGitHubTokenRefs[requestedCompanyId] = companyScopedGitHubTokenRef;
|
|
10881
|
+
}
|
|
10882
|
+
}
|
|
10883
|
+
const githubTokenRefs = Object.keys(nextGitHubTokenRefs).length > 0 ? nextGitHubTokenRefs : void 0;
|
|
10884
|
+
const githubTokenRef = !requestedCompanyId && "githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : normalizeGitHubTokenRef(previous.githubTokenRef) ?? normalizeGitHubTokenRef(config.githubTokenRef);
|
|
10885
|
+
const nextGitHubTokenLoginByCompanyId = {
|
|
10886
|
+
...previous.githubTokenLoginByCompanyId ?? {}
|
|
10887
|
+
};
|
|
10888
|
+
if (requestedCompanyId && "githubTokenLogin" in record) {
|
|
10889
|
+
const companyScopedGitHubTokenLogin = requestedGitHubTokenLogin;
|
|
10890
|
+
if (companyScopedGitHubTokenLogin) {
|
|
10891
|
+
nextGitHubTokenLoginByCompanyId[requestedCompanyId] = companyScopedGitHubTokenLogin;
|
|
10892
|
+
} else {
|
|
10893
|
+
delete nextGitHubTokenLoginByCompanyId[requestedCompanyId];
|
|
10894
|
+
}
|
|
10895
|
+
}
|
|
10896
|
+
const githubTokenLoginByCompanyId = Object.keys(nextGitHubTokenLoginByCompanyId).length > 0 ? nextGitHubTokenLoginByCompanyId : void 0;
|
|
10897
|
+
const githubTokenLogin = !requestedCompanyId && "githubTokenLogin" in record ? requestedGitHubTokenLogin : previous.githubTokenLogin;
|
|
10605
10898
|
const inputMappings = hasMappingsPatch ? normalizeMappings(record.mappings) : previous.mappings;
|
|
10606
10899
|
const nextCompanyAdvancedSettingsByCompanyId = {
|
|
10607
10900
|
...previous.companyAdvancedSettingsByCompanyId ?? {}
|
|
@@ -10616,17 +10909,26 @@ var plugin = definePlugin({
|
|
|
10616
10909
|
companyId: requestedCompanyId
|
|
10617
10910
|
}))
|
|
10618
10911
|
] : inputMappings;
|
|
10619
|
-
|
|
10912
|
+
let current = normalizeSettings({
|
|
10620
10913
|
mappings: mergedMappings,
|
|
10621
10914
|
syncState: previous.syncState,
|
|
10622
|
-
|
|
10623
|
-
|
|
10915
|
+
...previous.syncStateByCompanyId ? { syncStateByCompanyId: previous.syncStateByCompanyId } : {},
|
|
10916
|
+
scheduleFrequencyMinutes: previous.scheduleFrequencyMinutes,
|
|
10917
|
+
...previous.scheduleFrequencyMinutesByCompanyId ? { scheduleFrequencyMinutesByCompanyId: previous.scheduleFrequencyMinutesByCompanyId } : {},
|
|
10918
|
+
...previous.paperclipApiBaseUrl ? { paperclipApiBaseUrl: previous.paperclipApiBaseUrl } : {},
|
|
10919
|
+
...previous.paperclipApiBaseUrlByCompanyId ? { paperclipApiBaseUrlByCompanyId: previous.paperclipApiBaseUrlByCompanyId } : {},
|
|
10920
|
+
...githubTokenRefs ? { githubTokenRefs } : {},
|
|
10921
|
+
...githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId } : {},
|
|
10624
10922
|
...githubTokenLogin ? { githubTokenLogin } : {},
|
|
10625
10923
|
paperclipBoardApiTokenRefs: previous.paperclipBoardApiTokenRefs,
|
|
10626
10924
|
paperclipBoardAccessIdentityByCompanyId: previous.paperclipBoardAccessIdentityByCompanyId,
|
|
10627
10925
|
...Object.keys(nextCompanyAdvancedSettingsByCompanyId).length > 0 ? { companyAdvancedSettingsByCompanyId: nextCompanyAdvancedSettingsByCompanyId } : {},
|
|
10628
10926
|
...githubTokenRef ? { githubTokenRef } : {}
|
|
10629
10927
|
});
|
|
10928
|
+
const nextScheduleFrequencyMinutes = "scheduleFrequencyMinutes" in record ? normalizeScheduleFrequencyMinutes(record.scheduleFrequencyMinutes) : getScopedScheduleFrequencyMinutes(previous, requestedCompanyId);
|
|
10929
|
+
current = upsertScopedScheduleFrequencyMinutes(current, nextScheduleFrequencyMinutes, requestedCompanyId);
|
|
10930
|
+
const nextPaperclipApiBaseUrl = "paperclipApiBaseUrl" in record ? resolveTrustedPaperclipApiBaseUrlInput(record.paperclipApiBaseUrl, previous, config, requestedCompanyId) : getConfiguredPaperclipApiBaseUrl(previous, config, requestedCompanyId);
|
|
10931
|
+
current = upsertScopedPaperclipApiBaseUrl(current, nextPaperclipApiBaseUrl, requestedCompanyId);
|
|
10630
10932
|
const nextMappings = current.mappings.map((mapping, index) => ({
|
|
10631
10933
|
id: mapping.id.trim() || createMappingId(index),
|
|
10632
10934
|
repositoryUrl: parseRepositoryReference(mapping.repositoryUrl)?.url ?? mapping.repositoryUrl.trim(),
|
|
@@ -10634,11 +10936,15 @@ var plugin = definePlugin({
|
|
|
10634
10936
|
paperclipProjectId: mapping.paperclipProjectId,
|
|
10635
10937
|
companyId: mapping.companyId
|
|
10636
10938
|
}));
|
|
10939
|
+
const materializedCurrent = materializeScopedSettings(current, config, requestedCompanyId);
|
|
10637
10940
|
const next = sanitizeSettingsForCurrentSetup({
|
|
10941
|
+
...current,
|
|
10638
10942
|
mappings: nextMappings,
|
|
10639
|
-
syncState:
|
|
10640
|
-
scheduleFrequencyMinutes:
|
|
10641
|
-
...
|
|
10943
|
+
syncState: materializedCurrent.syncState,
|
|
10944
|
+
scheduleFrequencyMinutes: materializedCurrent.scheduleFrequencyMinutes,
|
|
10945
|
+
...materializedCurrent.paperclipApiBaseUrl ? { paperclipApiBaseUrl: materializedCurrent.paperclipApiBaseUrl } : {},
|
|
10946
|
+
...current.githubTokenRefs ? { githubTokenRefs: current.githubTokenRefs } : {},
|
|
10947
|
+
...current.githubTokenLoginByCompanyId ? { githubTokenLoginByCompanyId: current.githubTokenLoginByCompanyId } : {},
|
|
10642
10948
|
...current.githubTokenLogin ? { githubTokenLogin: current.githubTokenLogin } : {},
|
|
10643
10949
|
...current.paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs: current.paperclipBoardApiTokenRefs } : {},
|
|
10644
10950
|
...current.paperclipBoardAccessIdentityByCompanyId ? { paperclipBoardAccessIdentityByCompanyId: current.paperclipBoardAccessIdentityByCompanyId } : {},
|
|
@@ -10646,14 +10952,16 @@ var plugin = definePlugin({
|
|
|
10646
10952
|
...githubTokenRef ? { githubTokenRef } : {},
|
|
10647
10953
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10648
10954
|
}, {
|
|
10649
|
-
hasToken: hasConfiguredGithubToken(
|
|
10650
|
-
hasMappings:
|
|
10955
|
+
hasToken: hasConfiguredGithubToken(current, config, requestedCompanyId),
|
|
10956
|
+
hasMappings: getSyncableMappingsForScope(nextMappings, requestedCompanyId).length > 0
|
|
10651
10957
|
});
|
|
10652
10958
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
10653
10959
|
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
10654
10960
|
clearGitHubRepositoryTokenCapabilityAudits();
|
|
10961
|
+
const scopedGitHubTokenLogin = (requestedCompanyId && "githubTokenLogin" in record ? requestedGitHubTokenLogin : void 0) ?? getGitHubTokenLogin(next, requestedCompanyId);
|
|
10655
10962
|
return {
|
|
10656
10963
|
...getPublicSettingsForScope(next, requestedCompanyId),
|
|
10964
|
+
...scopedGitHubTokenLogin ? { githubTokenLogin: scopedGitHubTokenLogin } : {},
|
|
10657
10965
|
availableAssignees: requestedCompanyId ? await listAvailableAssignees(ctx, requestedCompanyId) : []
|
|
10658
10966
|
};
|
|
10659
10967
|
});
|
|
@@ -10691,15 +10999,16 @@ var plugin = definePlugin({
|
|
|
10691
10999
|
paperclipBoardAccessIdentityByCompanyId: _previousPaperclipBoardAccessIdentityByCompanyId,
|
|
10692
11000
|
...previousWithoutBoardAccess
|
|
10693
11001
|
} = previous;
|
|
10694
|
-
const
|
|
11002
|
+
const nextBase = sanitizeSettingsForCurrentSetup({
|
|
10695
11003
|
...previousWithoutBoardAccess,
|
|
10696
11004
|
...Object.keys(nextPaperclipBoardApiTokenRefs).length > 0 ? { paperclipBoardApiTokenRefs: nextPaperclipBoardApiTokenRefs } : {},
|
|
10697
11005
|
...Object.keys(nextPaperclipBoardAccessIdentityByCompanyId).length > 0 ? { paperclipBoardAccessIdentityByCompanyId: nextPaperclipBoardAccessIdentityByCompanyId } : {},
|
|
10698
11006
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10699
11007
|
}, {
|
|
10700
|
-
hasToken: hasConfiguredGithubToken(previous, config),
|
|
10701
|
-
hasMappings:
|
|
11008
|
+
hasToken: hasConfiguredGithubToken(previous, config, companyId),
|
|
11009
|
+
hasMappings: getSyncableMappingsForScope(previous.mappings, companyId).length > 0
|
|
10702
11010
|
});
|
|
11011
|
+
const next = materializeScopedSettings(nextBase, config, companyId);
|
|
10703
11012
|
await ctx.state.set(SETTINGS_SCOPE, next);
|
|
10704
11013
|
await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
|
|
10705
11014
|
return {
|
|
@@ -10770,7 +11079,7 @@ var plugin = definePlugin({
|
|
|
10770
11079
|
});
|
|
10771
11080
|
});
|
|
10772
11081
|
ctx.actions.register("sync.cancel", async () => {
|
|
10773
|
-
const currentSettings = await getActiveOrCurrentSyncState(ctx);
|
|
11082
|
+
const currentSettings = await getActiveOrCurrentSyncState(ctx, activeRunningSyncCompanyId);
|
|
10774
11083
|
if (currentSettings.syncState.status !== "running") {
|
|
10775
11084
|
return currentSettings;
|
|
10776
11085
|
}
|
|
@@ -10790,7 +11099,8 @@ var plugin = definePlugin({
|
|
|
10790
11099
|
progress: currentSettings.syncState.progress,
|
|
10791
11100
|
message: CANCELLING_SYNC_MESSAGE,
|
|
10792
11101
|
cancelRequestedAt: cancellationRequest.requestedAt
|
|
10793
|
-
})
|
|
11102
|
+
}),
|
|
11103
|
+
activeRunningSyncCompanyId
|
|
10794
11104
|
);
|
|
10795
11105
|
activeRunningSyncState = next;
|
|
10796
11106
|
return next;
|
|
@@ -10798,10 +11108,22 @@ var plugin = definePlugin({
|
|
|
10798
11108
|
registerGitHubAgentTools(ctx);
|
|
10799
11109
|
ctx.jobs.register("sync.github-issues", async (job) => {
|
|
10800
11110
|
const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
|
|
10801
|
-
|
|
11111
|
+
const trigger = job.trigger === "retry" ? "retry" : "schedule";
|
|
11112
|
+
const scheduledTargets = listScheduledSyncTargets(settings);
|
|
11113
|
+
if (scheduledTargets.length === 0) {
|
|
11114
|
+
if (job.trigger === "schedule" && !shouldRunScheduledSync(settings, job.scheduledAt)) {
|
|
11115
|
+
return;
|
|
11116
|
+
}
|
|
11117
|
+
await startSync(ctx, trigger);
|
|
10802
11118
|
return;
|
|
10803
11119
|
}
|
|
10804
|
-
|
|
11120
|
+
for (const target of scheduledTargets) {
|
|
11121
|
+
const scopedSettings = materializeScopedSettings(settings, null, target?.companyId);
|
|
11122
|
+
if (job.trigger === "schedule" && !shouldRunScheduledSync(scopedSettings, job.scheduledAt)) {
|
|
11123
|
+
continue;
|
|
11124
|
+
}
|
|
11125
|
+
await startSync(ctx, trigger, target ? { target } : {});
|
|
11126
|
+
}
|
|
10805
11127
|
});
|
|
10806
11128
|
}
|
|
10807
11129
|
});
|