paperclip-github-plugin 0.3.6 → 0.4.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/dist/worker.js CHANGED
@@ -1600,13 +1600,16 @@ function buildGitHubRepositoryTokenCapabilityAudit(params) {
1600
1600
  function normalizeSecretRef(value) {
1601
1601
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
1602
1602
  }
1603
- function normalizeGitHubUserLogin(value) {
1603
+ function normalizeGitHubLowercaseString(value) {
1604
1604
  if (typeof value !== "string") {
1605
1605
  return void 0;
1606
1606
  }
1607
1607
  const trimmed = stripNullBytes(value).trim();
1608
1608
  return trimmed ? trimmed.toLowerCase() : void 0;
1609
1609
  }
1610
+ function normalizeGitHubUserLogin(value) {
1611
+ return normalizeGitHubLowercaseString(value);
1612
+ }
1610
1613
  function normalizeGitHubTokenRef(value) {
1611
1614
  return normalizeSecretRef(value);
1612
1615
  }
@@ -2234,7 +2237,7 @@ async function hydrateRecoveredPaperclipIssueGitHubLink(ctx, issueId, fallbackLi
2234
2237
  }
2235
2238
  let octokit;
2236
2239
  try {
2237
- octokit = await createGitHubToolOctokit(ctx);
2240
+ octokit = await createGitHubToolOctokit(ctx, fallbackLink.companyId);
2238
2241
  } catch {
2239
2242
  return null;
2240
2243
  }
@@ -2409,8 +2412,8 @@ function extractGitHubLinksFromCommentBody(body) {
2409
2412
  async function buildToolbarSyncState(ctx, input) {
2410
2413
  const settings = await getActiveOrCurrentSyncState(ctx);
2411
2414
  const config = await getResolvedConfig(ctx);
2412
- const githubTokenConfigured = hasConfiguredGithubToken(settings, config);
2413
2415
  const companyId = typeof input.companyId === "string" && input.companyId.trim() ? input.companyId.trim() : void 0;
2416
+ const githubTokenConfigured = hasConfiguredGithubToken(settings, config, companyId);
2414
2417
  const entityId = typeof input.entityId === "string" && input.entityId.trim() ? input.entityId.trim() : void 0;
2415
2418
  const entityType = typeof input.entityType === "string" && input.entityType.trim() ? input.entityType.trim() : void 0;
2416
2419
  const savedMappingCount = companyId ? getSyncableMappingsForTarget(settings.mappings, {
@@ -2622,21 +2625,53 @@ function sanitizeSettingsForCurrentSetup(settings, setup) {
2622
2625
  }
2623
2626
  function getPublicSettings(settings) {
2624
2627
  const {
2628
+ githubTokenRefs: _githubTokenRefs,
2629
+ githubTokenLoginsByCompanyId: _githubTokenLoginsByCompanyId,
2625
2630
  githubTokenRef: _githubTokenRef,
2626
2631
  paperclipBoardApiTokenRefs: _paperclipBoardApiTokenRefs,
2632
+ paperclipBoardAccessIdentityByCompanyId: _paperclipBoardAccessIdentityByCompanyId,
2627
2633
  companyAdvancedSettingsByCompanyId: _companyAdvancedSettingsByCompanyId,
2628
2634
  ...publicSettings
2629
2635
  } = settings;
2630
2636
  return publicSettings;
2631
2637
  }
2638
+ function getPaperclipBoardAccessIdentity(settings, companyId) {
2639
+ const normalizedCompanyId = normalizeCompanyId(companyId);
2640
+ if (!normalizedCompanyId) {
2641
+ return void 0;
2642
+ }
2643
+ return normalizeOptionalString2(settings.paperclipBoardAccessIdentityByCompanyId?.[normalizedCompanyId]);
2644
+ }
2632
2645
  function getPublicSettingsForScope(settings, companyId) {
2633
2646
  const publicSettings = getPublicSettings(settings);
2647
+ const paperclipBoardAccessIdentity = getPaperclipBoardAccessIdentity(settings, companyId);
2634
2648
  return {
2635
2649
  ...publicSettings,
2636
2650
  mappings: filterMappingsByCompany(publicSettings.mappings, companyId),
2637
- advancedSettings: getCompanyAdvancedSettings(settings, companyId)
2651
+ advancedSettings: getCompanyAdvancedSettings(settings, companyId),
2652
+ ...paperclipBoardAccessIdentity ? { paperclipBoardAccessIdentity } : {}
2638
2653
  };
2639
2654
  }
2655
+ function getSavedGitHubTokenRef(settings, companyId) {
2656
+ const normalizedCompanyId = normalizeCompanyId(companyId);
2657
+ if (normalizedCompanyId) {
2658
+ const scopedSecretRef = normalizeSecretRef(settings?.githubTokenRefs?.[normalizedCompanyId]);
2659
+ if (scopedSecretRef) {
2660
+ return scopedSecretRef;
2661
+ }
2662
+ }
2663
+ return normalizeGitHubTokenRef(settings?.githubTokenRef);
2664
+ }
2665
+ function getSavedGitHubTokenLogin(settings, companyId) {
2666
+ const normalizedCompanyId = normalizeCompanyId(companyId);
2667
+ if (normalizedCompanyId) {
2668
+ const scopedLogin = normalizeOptionalString2(settings?.githubTokenLoginsByCompanyId?.[normalizedCompanyId]);
2669
+ if (scopedLogin) {
2670
+ return scopedLogin;
2671
+ }
2672
+ }
2673
+ return normalizeOptionalString2(settings?.githubTokenLogin);
2674
+ }
2640
2675
  async function listAvailableAssignees(ctx, companyId) {
2641
2676
  try {
2642
2677
  const agents = await ctx.agents.list({
@@ -2940,11 +2975,13 @@ function normalizeConfig(value) {
2940
2975
  return {};
2941
2976
  }
2942
2977
  const record = value;
2978
+ const githubTokenRefs = normalizeGitHubTokenRefs(record.githubTokenRefs);
2943
2979
  const githubTokenRef = normalizeGitHubTokenRef(record.githubTokenRef);
2944
2980
  const githubToken = normalizeGitHubToken(record.githubToken);
2945
2981
  const paperclipBoardApiTokenRefs = normalizePaperclipBoardApiTokenRefs(record.paperclipBoardApiTokenRefs);
2946
2982
  const paperclipApiBaseUrl = normalizePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
2947
2983
  return {
2984
+ ...githubTokenRefs ? { githubTokenRefs } : {},
2948
2985
  ...githubTokenRef ? { githubTokenRef } : {},
2949
2986
  ...githubToken ? { githubToken } : {},
2950
2987
  ...paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs } : {},
@@ -3023,6 +3060,12 @@ async function readExternalConfig(ctx) {
3023
3060
  }
3024
3061
  }
3025
3062
  function normalizePaperclipBoardApiTokenRefs(value) {
3063
+ return normalizeCompanySecretRefs(value);
3064
+ }
3065
+ function normalizeGitHubTokenRefs(value) {
3066
+ return normalizeCompanySecretRefs(value);
3067
+ }
3068
+ function normalizeCompanySecretRefs(value) {
3026
3069
  if (!value || typeof value !== "object") {
3027
3070
  return void 0;
3028
3071
  }
@@ -3036,6 +3079,34 @@ function normalizePaperclipBoardApiTokenRefs(value) {
3036
3079
  }
3037
3080
  return Object.fromEntries(entries);
3038
3081
  }
3082
+ function normalizeGitHubTokenLoginsByCompanyId(value) {
3083
+ if (!value || typeof value !== "object") {
3084
+ return void 0;
3085
+ }
3086
+ const entries = Object.entries(value).map(([companyId, login]) => {
3087
+ const normalizedCompanyId = normalizeCompanyId(companyId);
3088
+ const normalizedLogin = normalizeOptionalString2(login);
3089
+ return normalizedCompanyId && normalizedLogin ? [normalizedCompanyId, normalizedLogin] : null;
3090
+ }).filter((entry) => entry !== null);
3091
+ if (entries.length === 0) {
3092
+ return void 0;
3093
+ }
3094
+ return Object.fromEntries(entries);
3095
+ }
3096
+ function normalizePaperclipBoardAccessIdentityByCompanyId(value) {
3097
+ if (!value || typeof value !== "object") {
3098
+ return void 0;
3099
+ }
3100
+ const entries = Object.entries(value).map(([companyId, identityLabel]) => {
3101
+ const normalizedCompanyId = normalizeCompanyId(companyId);
3102
+ const normalizedIdentityLabel = normalizeOptionalString2(identityLabel);
3103
+ return normalizedCompanyId && normalizedIdentityLabel ? [normalizedCompanyId, normalizedIdentityLabel] : null;
3104
+ }).filter((entry) => entry !== null);
3105
+ if (entries.length === 0) {
3106
+ return void 0;
3107
+ }
3108
+ return Object.fromEntries(entries);
3109
+ }
3039
3110
  function normalizeSyncCancellationRequest(value) {
3040
3111
  if (!value || typeof value !== "object") {
3041
3112
  return null;
@@ -3122,6 +3193,10 @@ function normalizeIgnoredIssueAuthorUsernames(value) {
3122
3193
  const entries = Array.isArray(value) ? value.map((entry) => normalizeGitHubUsername(entry)).filter((entry) => Boolean(entry)) : typeof value === "string" ? parseIgnoredIssueAuthorUsernames(value) : [];
3123
3194
  return [...new Set(entries)];
3124
3195
  }
3196
+ function normalizeAgentIds(value) {
3197
+ const entries = Array.isArray(value) ? value.map((entry) => normalizeOptionalString2(entry)).filter((entry) => Boolean(entry)) : [];
3198
+ return [...new Set(entries)].sort((left, right) => left.localeCompare(right));
3199
+ }
3125
3200
  function normalizeAdvancedSettings(value) {
3126
3201
  if (!value || typeof value !== "object") {
3127
3202
  return DEFAULT_ADVANCED_SETTINGS;
@@ -3130,10 +3205,12 @@ function normalizeAdvancedSettings(value) {
3130
3205
  const defaultAssigneeAgentId = normalizeOptionalString2(record.defaultAssigneeAgentId);
3131
3206
  const defaultStatus = "defaultStatus" in record ? coercePaperclipIssueStatus(record.defaultStatus) : DEFAULT_ADVANCED_SETTINGS.defaultStatus;
3132
3207
  const ignoredIssueAuthorUsernames = "ignoredIssueAuthorUsernames" in record ? normalizeIgnoredIssueAuthorUsernames(record.ignoredIssueAuthorUsernames) : DEFAULT_ADVANCED_SETTINGS.ignoredIssueAuthorUsernames;
3208
+ const githubTokenPropagationAgentIds = "githubTokenPropagationAgentIds" in record ? normalizeAgentIds(record.githubTokenPropagationAgentIds) : [];
3133
3209
  return {
3134
3210
  ...defaultAssigneeAgentId ? { defaultAssigneeAgentId } : {},
3135
3211
  defaultStatus,
3136
- ignoredIssueAuthorUsernames
3212
+ ignoredIssueAuthorUsernames,
3213
+ ...githubTokenPropagationAgentIds.length > 0 ? { githubTokenPropagationAgentIds } : {}
3137
3214
  };
3138
3215
  }
3139
3216
  function normalizeCompanyAdvancedSettingsByCompanyId(value) {
@@ -3234,16 +3311,26 @@ function normalizeSettings(value) {
3234
3311
  }
3235
3312
  const record = value;
3236
3313
  const paperclipApiBaseUrl = resolvePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
3314
+ const githubTokenRefs = normalizeGitHubTokenRefs(record.githubTokenRefs);
3315
+ const githubTokenLoginsByCompanyId = normalizeGitHubTokenLoginsByCompanyId(record.githubTokenLoginsByCompanyId);
3237
3316
  const githubTokenRef = normalizeGitHubTokenRef(record.githubTokenRef);
3317
+ const githubTokenLogin = normalizeOptionalString2(record.githubTokenLogin);
3238
3318
  const paperclipBoardApiTokenRefs = normalizePaperclipBoardApiTokenRefs(record.paperclipBoardApiTokenRefs);
3319
+ const paperclipBoardAccessIdentityByCompanyId = normalizePaperclipBoardAccessIdentityByCompanyId(
3320
+ record.paperclipBoardAccessIdentityByCompanyId
3321
+ );
3239
3322
  const companyAdvancedSettingsByCompanyId = normalizeCompanyAdvancedSettingsByCompanyId(record.companyAdvancedSettingsByCompanyId);
3240
3323
  return {
3241
3324
  mappings: normalizeMappings(record.mappings),
3242
3325
  syncState: normalizeSyncState(record.syncState),
3243
3326
  scheduleFrequencyMinutes: normalizeScheduleFrequencyMinutes(record.scheduleFrequencyMinutes),
3244
3327
  ...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {},
3328
+ ...githubTokenRefs ? { githubTokenRefs } : {},
3329
+ ...githubTokenLoginsByCompanyId ? { githubTokenLoginsByCompanyId } : {},
3245
3330
  ...githubTokenRef ? { githubTokenRef } : {},
3331
+ ...githubTokenLogin ? { githubTokenLogin } : {},
3246
3332
  ...paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs } : {},
3333
+ ...paperclipBoardAccessIdentityByCompanyId ? { paperclipBoardAccessIdentityByCompanyId } : {},
3247
3334
  ...companyAdvancedSettingsByCompanyId ? { companyAdvancedSettingsByCompanyId } : {},
3248
3335
  updatedAt: typeof record.updatedAt === "string" ? record.updatedAt : void 0
3249
3336
  };
@@ -4207,8 +4294,9 @@ async function isGitHubUserRepositoryMaintainer(octokit, repository, login, cach
4207
4294
  "X-GitHub-Api-Version": GITHUB_API_VERSION
4208
4295
  }
4209
4296
  });
4210
- const roleName = response.data && typeof response.data === "object" && "role_name" in response.data ? normalizeGitHubUserLogin(response.data.role_name) : void 0;
4211
- const isMaintainer = roleName ? GITHUB_REPOSITORY_MAINTAINER_ROLE_NAMES.has(roleName) : false;
4297
+ const permission = response.data && typeof response.data === "object" && "permission" in response.data ? normalizeGitHubLowercaseString(response.data.permission) : void 0;
4298
+ const roleName = response.data && typeof response.data === "object" && "role_name" in response.data ? normalizeGitHubLowercaseString(response.data.role_name) : void 0;
4299
+ const isMaintainer = (permission ? GITHUB_REPOSITORY_MAINTAINER_ROLE_NAMES.has(permission) : false) || (roleName ? GITHUB_REPOSITORY_MAINTAINER_ROLE_NAMES.has(roleName) : false);
4212
4300
  cache.set(cacheKey, isMaintainer);
4213
4301
  return isMaintainer;
4214
4302
  } catch (error) {
@@ -6133,19 +6221,20 @@ async function getResolvedConfig(ctx) {
6133
6221
  ...normalizeConfig(savedConfig)
6134
6222
  };
6135
6223
  }
6136
- function getConfiguredGithubTokenSource(settings, config) {
6137
- const secretRef = normalizeGitHubTokenRef(config.githubTokenRef) ?? normalizeGitHubTokenRef(settings?.githubTokenRef);
6224
+ function getConfiguredGithubTokenSource(settings, config, companyId) {
6225
+ const normalizedCompanyId = normalizeCompanyId(companyId);
6226
+ const secretRef = (normalizedCompanyId ? normalizeSecretRef(config.githubTokenRefs?.[normalizedCompanyId]) ?? getSavedGitHubTokenRef(settings, normalizedCompanyId) : void 0) ?? normalizeGitHubTokenRef(config.githubTokenRef) ?? getSavedGitHubTokenRef(settings);
6138
6227
  if (secretRef) {
6139
6228
  return { secretRef };
6140
6229
  }
6141
6230
  const token = normalizeGitHubToken(config.githubToken);
6142
6231
  return token ? { token } : {};
6143
6232
  }
6144
- function getConfiguredGithubTokenRef(settings, config) {
6145
- return getConfiguredGithubTokenSource(settings, config).secretRef;
6233
+ function getConfiguredGithubTokenRef(settings, config, companyId) {
6234
+ return getConfiguredGithubTokenSource(settings, config, companyId).secretRef;
6146
6235
  }
6147
- function hasConfiguredGithubToken(settings, config) {
6148
- const configuredTokenSource = getConfiguredGithubTokenSource(settings, config);
6236
+ function hasConfiguredGithubToken(settings, config, companyId) {
6237
+ const configuredTokenSource = getConfiguredGithubTokenSource(settings, config, companyId);
6149
6238
  return Boolean(configuredTokenSource.secretRef ?? configuredTokenSource.token);
6150
6239
  }
6151
6240
  function getSavedPaperclipBoardApiTokenRef(settings, companyId) {
@@ -6229,7 +6318,7 @@ async function resolvePaperclipApiAuthTokens(ctx, settings, config, mappings) {
6229
6318
  async function resolveGithubToken(ctx, options = {}) {
6230
6319
  const settings = options.settings ?? normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
6231
6320
  const config = options.config ?? await getResolvedConfig(ctx);
6232
- const configuredTokenSource = getConfiguredGithubTokenSource(settings, config);
6321
+ const configuredTokenSource = getConfiguredGithubTokenSource(settings, config, options.companyId);
6233
6322
  if (configuredTokenSource.secretRef) {
6234
6323
  return ctx.secrets.resolve(configuredTokenSource.secretRef);
6235
6324
  }
@@ -6307,8 +6396,8 @@ async function executeGitHubTool(fn) {
6307
6396
  return buildToolErrorResult(error);
6308
6397
  }
6309
6398
  }
6310
- async function createGitHubToolOctokit(ctx) {
6311
- const token = (await resolveGithubToken(ctx)).trim();
6399
+ async function createGitHubToolOctokit(ctx, companyId) {
6400
+ const token = (await resolveGithubToken(ctx, { companyId })).trim();
6312
6401
  if (!token) {
6313
6402
  throw new Error(MISSING_GITHUB_TOKEN_SYNC_MESSAGE);
6314
6403
  }
@@ -7730,7 +7819,7 @@ async function getOrLoadCachedProjectPullRequestMetricsEntry(ctx, scope, octokit
7730
7819
  return inFlightMetrics;
7731
7820
  }
7732
7821
  const loadMetricsPromise = (async () => {
7733
- const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
7822
+ const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
7734
7823
  const metrics = await listProjectPullRequestMetrics(resolvedOctokit, scope);
7735
7824
  return cacheProjectPullRequestMetricsEntry(scope, metrics);
7736
7825
  })();
@@ -7768,7 +7857,7 @@ async function getOrLoadCachedProjectPullRequestCount(ctx, scope, octokit) {
7768
7857
  return inFlightCount;
7769
7858
  }
7770
7859
  const loadCountPromise = (async () => {
7771
- const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
7860
+ const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
7772
7861
  const totalOpenPullRequests = await listProjectPullRequestCount(resolvedOctokit, scope);
7773
7862
  return setCacheValue(
7774
7863
  activeProjectPullRequestCountCache,
@@ -7880,7 +7969,7 @@ async function getOrLoadProjectPullRequestSummaryRecordsForNumbers(ctx, scope, p
7880
7969
  }
7881
7970
  const missingPullRequestNumbers = normalizedPullRequestNumbers.filter((pullRequestNumber) => !recordsByNumber.has(pullRequestNumber));
7882
7971
  if (missingPullRequestNumbers.length > 0) {
7883
- const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx);
7972
+ const resolvedOctokit = octokit ?? await createGitHubToolOctokit(ctx, scope.companyId);
7884
7973
  const loadedRecords = await listProjectPullRequestSummaryRecordsByNumbers(
7885
7974
  ctx,
7886
7975
  resolvedOctokit,
@@ -7990,7 +8079,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
7990
8079
  }
7991
8080
  const scope = await requireProjectPullRequestScope(ctx, input, projectMappings);
7992
8081
  const config = await getResolvedConfig(ctx);
7993
- if (!hasConfiguredGithubToken(settings, config)) {
8082
+ if (!hasConfiguredGithubToken(settings, config, companyId)) {
7994
8083
  return {
7995
8084
  status: "missing_token",
7996
8085
  projectId,
@@ -8009,7 +8098,7 @@ async function buildProjectPullRequestsPageData(ctx, input) {
8009
8098
  };
8010
8099
  }
8011
8100
  try {
8012
- const octokit = await createGitHubToolOctokit(ctx);
8101
+ const octokit = await createGitHubToolOctokit(ctx, companyId);
8013
8102
  const pageCacheKey = buildProjectPullRequestPageCacheKey(scope, filter, pageIndex, cursor);
8014
8103
  const cachedPage = getFreshCacheValue(activeProjectPullRequestPageCache, pageCacheKey);
8015
8104
  if (cachedPage) {
@@ -8181,7 +8270,7 @@ async function buildProjectPullRequestMetricsData(ctx, input) {
8181
8270
  };
8182
8271
  }
8183
8272
  const config = await getResolvedConfig(ctx);
8184
- if (!hasConfiguredGithubToken(settings, config)) {
8273
+ if (!hasConfiguredGithubToken(settings, config, companyId)) {
8185
8274
  return {
8186
8275
  status: "missing_token",
8187
8276
  projectId,
@@ -8230,7 +8319,7 @@ async function buildProjectPullRequestCountData(ctx, input) {
8230
8319
  };
8231
8320
  }
8232
8321
  const config = await getResolvedConfig(ctx);
8233
- if (!hasConfiguredGithubToken(settings, config)) {
8322
+ if (!hasConfiguredGithubToken(settings, config, companyId)) {
8234
8323
  return {
8235
8324
  status: "missing_token",
8236
8325
  projectId,
@@ -8267,7 +8356,7 @@ async function buildSettingsTokenPermissionAuditData(ctx, input) {
8267
8356
  }
8268
8357
  const settings = normalizeSettings(await ctx.state.get(SETTINGS_SCOPE));
8269
8358
  const config = await getResolvedConfig(ctx);
8270
- if (!hasConfiguredGithubToken(settings, config)) {
8359
+ if (!hasConfiguredGithubToken(settings, config, requestedCompanyId)) {
8271
8360
  return {
8272
8361
  status: "missing_token",
8273
8362
  allRequiredPermissionsGranted: false,
@@ -8288,7 +8377,7 @@ async function buildSettingsTokenPermissionAuditData(ctx, input) {
8288
8377
  };
8289
8378
  }
8290
8379
  try {
8291
- const octokit = await createGitHubToolOctokit(ctx);
8380
+ const octokit = await createGitHubToolOctokit(ctx, requestedCompanyId);
8292
8381
  const repositories = await Promise.all(
8293
8382
  [
8294
8383
  ...new Map(
@@ -8357,7 +8446,7 @@ async function buildProjectPullRequestDetailData(ctx, input) {
8357
8446
  buildProjectPullRequestSummaryRecordCacheKey(scope, pullRequestNumber)
8358
8447
  );
8359
8448
  const cachedLinkedIssue = cachedSummaryRecord ? getLinkedPaperclipIssueFromProjectPullRequestRecord(cachedSummaryRecord) : void 0;
8360
- const octokit = await createGitHubToolOctokit(ctx);
8449
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8361
8450
  const response = await octokit.rest.pulls.get({
8362
8451
  owner: scope.repository.owner,
8363
8452
  repo: scope.repository.repo,
@@ -8488,7 +8577,7 @@ async function createProjectPullRequestPaperclipIssue(ctx, input) {
8488
8577
  throw new Error("This Paperclip runtime does not expose plugin issue creation yet.");
8489
8578
  }
8490
8579
  const scope = await requireProjectPullRequestScope(ctx, input);
8491
- const octokit = await createGitHubToolOctokit(ctx);
8580
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8492
8581
  const pullRequestResponse = await octokit.rest.pulls.get({
8493
8582
  owner: scope.repository.owner,
8494
8583
  repo: scope.repository.repo,
@@ -8562,7 +8651,7 @@ async function updateProjectPullRequestBranch(ctx, input) {
8562
8651
  throw new Error("pullRequestNumber is required.");
8563
8652
  }
8564
8653
  const scope = await requireProjectPullRequestScope(ctx, input);
8565
- const octokit = await createGitHubToolOctokit(ctx);
8654
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8566
8655
  const pullRequestResponse = await octokit.rest.pulls.get({
8567
8656
  owner: scope.repository.owner,
8568
8657
  repo: scope.repository.repo,
@@ -8625,7 +8714,7 @@ async function mergeProjectPullRequest(ctx, input) {
8625
8714
  throw new Error("pullRequestNumber is required.");
8626
8715
  }
8627
8716
  const scope = await requireProjectPullRequestScope(ctx, input);
8628
- const octokit = await createGitHubToolOctokit(ctx);
8717
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8629
8718
  const response = await octokit.rest.pulls.merge({
8630
8719
  owner: scope.repository.owner,
8631
8720
  repo: scope.repository.repo,
@@ -8649,7 +8738,7 @@ async function closeProjectPullRequest(ctx, input) {
8649
8738
  throw new Error("pullRequestNumber is required.");
8650
8739
  }
8651
8740
  const scope = await requireProjectPullRequestScope(ctx, input);
8652
- const octokit = await createGitHubToolOctokit(ctx);
8741
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8653
8742
  const response = await octokit.rest.pulls.update({
8654
8743
  owner: scope.repository.owner,
8655
8744
  repo: scope.repository.repo,
@@ -8678,7 +8767,7 @@ async function addProjectPullRequestComment(ctx, input) {
8678
8767
  throw new Error("Comment body cannot be empty.");
8679
8768
  }
8680
8769
  const scope = await requireProjectPullRequestScope(ctx, input);
8681
- const octokit = await createGitHubToolOctokit(ctx);
8770
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8682
8771
  const response = await createProjectPullRequestGitHubComment(octokit, scope, pullRequestNumber, body);
8683
8772
  invalidateProjectPullRequestCaches(scope);
8684
8773
  return {
@@ -8735,7 +8824,7 @@ async function requestProjectPullRequestCopilotAction(ctx, input) {
8735
8824
  throw new Error('action must be one of "fix_ci", "rebase", "address_review_feedback", or "review".');
8736
8825
  }
8737
8826
  const scope = await requireProjectPullRequestScope(ctx, input);
8738
- const octokit = await createGitHubToolOctokit(ctx);
8827
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8739
8828
  const pullRequestResponse = await octokit.rest.pulls.get({
8740
8829
  owner: scope.repository.owner,
8741
8830
  repo: scope.repository.repo,
@@ -8849,7 +8938,7 @@ async function reviewProjectPullRequest(ctx, input) {
8849
8938
  }
8850
8939
  const body = typeof input.body === "string" ? input.body.trim() : "";
8851
8940
  const scope = await requireProjectPullRequestScope(ctx, input);
8852
- const octokit = await createGitHubToolOctokit(ctx);
8941
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8853
8942
  let response;
8854
8943
  try {
8855
8944
  response = await octokit.rest.pulls.createReview({
@@ -8896,7 +8985,7 @@ async function rerunProjectPullRequestCi(ctx, input) {
8896
8985
  throw new Error("pullRequestNumber is required.");
8897
8986
  }
8898
8987
  const scope = await requireProjectPullRequestScope(ctx, input);
8899
- const octokit = await createGitHubToolOctokit(ctx);
8988
+ const octokit = await createGitHubToolOctokit(ctx, scope.companyId);
8900
8989
  const pullRequestResponse = await octokit.rest.pulls.get({
8901
8990
  owner: scope.repository.owner,
8902
8991
  repo: scope.repository.repo,
@@ -9632,9 +9721,11 @@ async function startSync(ctx, trigger, options = {}) {
9632
9721
  getResolvedConfig(ctx),
9633
9722
  ctx.state.get(SETTINGS_SCOPE).then((value) => normalizeSettings(value))
9634
9723
  ]);
9724
+ const targetCompanyId = options.target?.companyId;
9635
9725
  const token = await resolveGithubToken(ctx, {
9636
9726
  config,
9637
- settings: persistedSettings
9727
+ settings: persistedSettings,
9728
+ companyId: targetCompanyId
9638
9729
  }).catch(() => "");
9639
9730
  let currentSettings = sanitizeSettingsForCurrentSetup(persistedSettings, {
9640
9731
  hasToken: Boolean(token.trim()),
@@ -9723,7 +9814,7 @@ function registerGitHubAgentTools(ctx) {
9723
9814
  getGitHubAgentToolDeclaration("search_repository_items"),
9724
9815
  async (params, runCtx) => executeGitHubTool(async () => {
9725
9816
  const input = getToolInputRecord(params);
9726
- const octokit = await createGitHubToolOctokit(ctx);
9817
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9727
9818
  const repository = await resolveGitHubToolRepository(ctx, runCtx, input);
9728
9819
  const rawQuery = normalizeOptionalToolString(input.query);
9729
9820
  if (!rawQuery) {
@@ -9792,7 +9883,7 @@ function registerGitHubAgentTools(ctx) {
9792
9883
  async (params, runCtx) => executeGitHubTool(async () => {
9793
9884
  const input = getToolInputRecord(params);
9794
9885
  const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
9795
- const octokit = await createGitHubToolOctokit(ctx);
9886
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9796
9887
  const response = await octokit.rest.issues.get({
9797
9888
  owner: target.repository.owner,
9798
9889
  repo: target.repository.repo,
@@ -9839,7 +9930,7 @@ function registerGitHubAgentTools(ctx) {
9839
9930
  async (params, runCtx) => executeGitHubTool(async () => {
9840
9931
  const input = getToolInputRecord(params);
9841
9932
  const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
9842
- const octokit = await createGitHubToolOctokit(ctx);
9933
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9843
9934
  const comments = await listAllGitHubIssueComments(octokit, target.repository, target.issueNumber);
9844
9935
  return buildToolSuccessResult(
9845
9936
  `Loaded ${comments.length} GitHub ${comments.length === 1 ? "comment" : "comments"} from issue #${target.issueNumber}.`,
@@ -9857,7 +9948,7 @@ function registerGitHubAgentTools(ctx) {
9857
9948
  async (params, runCtx) => executeGitHubTool(async () => {
9858
9949
  const input = getToolInputRecord(params);
9859
9950
  const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
9860
- const octokit = await createGitHubToolOctokit(ctx);
9951
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9861
9952
  const currentResponse = await octokit.rest.issues.get({
9862
9953
  owner: target.repository.owner,
9863
9954
  repo: target.repository.repo,
@@ -9929,7 +10020,7 @@ function registerGitHubAgentTools(ctx) {
9929
10020
  async (params, runCtx) => executeGitHubTool(async () => {
9930
10021
  const input = getToolInputRecord(params);
9931
10022
  const target = await resolveGitHubIssueToolTarget(ctx, runCtx, input);
9932
- const octokit = await createGitHubToolOctokit(ctx);
10023
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9933
10024
  const body = appendAiAuthorshipFooter(String(input.body ?? ""), normalizeOptionalToolString(input.llmModel) ?? "");
9934
10025
  const response = await octokit.rest.issues.createComment({
9935
10026
  owner: target.repository.owner,
@@ -9968,7 +10059,7 @@ function registerGitHubAgentTools(ctx) {
9968
10059
  if (!head || !base || !title) {
9969
10060
  throw new Error("head, base, and title are required.");
9970
10061
  }
9971
- const octokit = await createGitHubToolOctokit(ctx);
10062
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
9972
10063
  const response = await octokit.rest.pulls.create({
9973
10064
  owner: repository.owner,
9974
10065
  repo: repository.repo,
@@ -10005,7 +10096,7 @@ function registerGitHubAgentTools(ctx) {
10005
10096
  async (params, runCtx) => executeGitHubTool(async () => {
10006
10097
  const input = getToolInputRecord(params);
10007
10098
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10008
- const octokit = await createGitHubToolOctokit(ctx);
10099
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10009
10100
  const response = await octokit.rest.pulls.get({
10010
10101
  owner: target.repository.owner,
10011
10102
  repo: target.repository.repo,
@@ -10053,7 +10144,7 @@ function registerGitHubAgentTools(ctx) {
10053
10144
  async (params, runCtx) => executeGitHubTool(async () => {
10054
10145
  const input = getToolInputRecord(params);
10055
10146
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10056
- const octokit = await createGitHubToolOctokit(ctx);
10147
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10057
10148
  let currentResponse = await octokit.rest.pulls.get({
10058
10149
  owner: target.repository.owner,
10059
10150
  repo: target.repository.repo,
@@ -10118,7 +10209,7 @@ function registerGitHubAgentTools(ctx) {
10118
10209
  async (params, runCtx) => executeGitHubTool(async () => {
10119
10210
  const input = getToolInputRecord(params);
10120
10211
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10121
- const octokit = await createGitHubToolOctokit(ctx);
10212
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10122
10213
  const files = await listAllPullRequestFiles(octokit, target.repository, target.pullRequestNumber);
10123
10214
  return buildToolSuccessResult(
10124
10215
  `Loaded ${files.length} changed ${files.length === 1 ? "file" : "files"} from pull request #${target.pullRequestNumber}.`,
@@ -10136,7 +10227,7 @@ function registerGitHubAgentTools(ctx) {
10136
10227
  async (params, runCtx) => executeGitHubTool(async () => {
10137
10228
  const input = getToolInputRecord(params);
10138
10229
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10139
- const octokit = await createGitHubToolOctokit(ctx);
10230
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10140
10231
  const pullRequestResponse = await octokit.rest.pulls.get({
10141
10232
  owner: target.repository.owner,
10142
10233
  repo: target.repository.repo,
@@ -10234,7 +10325,7 @@ function registerGitHubAgentTools(ctx) {
10234
10325
  async (params, runCtx) => executeGitHubTool(async () => {
10235
10326
  const input = getToolInputRecord(params);
10236
10327
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10237
- const octokit = await createGitHubToolOctokit(ctx);
10328
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10238
10329
  const threads = await listDetailedPullRequestReviewThreads(octokit, target.repository, target.pullRequestNumber);
10239
10330
  return buildToolSuccessResult(
10240
10331
  `Loaded ${threads.length} review ${threads.length === 1 ? "thread" : "threads"} from pull request #${target.pullRequestNumber}.`,
@@ -10249,14 +10340,14 @@ function registerGitHubAgentTools(ctx) {
10249
10340
  ctx.tools.register(
10250
10341
  "reply_to_review_thread",
10251
10342
  getGitHubAgentToolDeclaration("reply_to_review_thread"),
10252
- async (params) => executeGitHubTool(async () => {
10343
+ async (params, runCtx) => executeGitHubTool(async () => {
10253
10344
  const input = getToolInputRecord(params);
10254
10345
  const threadId = normalizeOptionalToolString(input.threadId);
10255
10346
  if (!threadId) {
10256
10347
  throw new Error("threadId is required.");
10257
10348
  }
10258
10349
  const body = appendAiAuthorshipFooter(String(input.body ?? ""), normalizeOptionalToolString(input.llmModel) ?? "");
10259
- const octokit = await createGitHubToolOctokit(ctx);
10350
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10260
10351
  const response = await octokit.graphql(
10261
10352
  GITHUB_ADD_PULL_REQUEST_REVIEW_THREAD_REPLY_MUTATION,
10262
10353
  {
@@ -10285,13 +10376,13 @@ function registerGitHubAgentTools(ctx) {
10285
10376
  ctx.tools.register(
10286
10377
  "resolve_review_thread",
10287
10378
  getGitHubAgentToolDeclaration("resolve_review_thread"),
10288
- async (params) => executeGitHubTool(async () => {
10379
+ async (params, runCtx) => executeGitHubTool(async () => {
10289
10380
  const input = getToolInputRecord(params);
10290
10381
  const threadId = normalizeOptionalToolString(input.threadId);
10291
10382
  if (!threadId) {
10292
10383
  throw new Error("threadId is required.");
10293
10384
  }
10294
- const octokit = await createGitHubToolOctokit(ctx);
10385
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10295
10386
  const response = await octokit.graphql(
10296
10387
  GITHUB_RESOLVE_REVIEW_THREAD_MUTATION,
10297
10388
  {
@@ -10316,13 +10407,13 @@ function registerGitHubAgentTools(ctx) {
10316
10407
  ctx.tools.register(
10317
10408
  "unresolve_review_thread",
10318
10409
  getGitHubAgentToolDeclaration("unresolve_review_thread"),
10319
- async (params) => executeGitHubTool(async () => {
10410
+ async (params, runCtx) => executeGitHubTool(async () => {
10320
10411
  const input = getToolInputRecord(params);
10321
10412
  const threadId = normalizeOptionalToolString(input.threadId);
10322
10413
  if (!threadId) {
10323
10414
  throw new Error("threadId is required.");
10324
10415
  }
10325
- const octokit = await createGitHubToolOctokit(ctx);
10416
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10326
10417
  const response = await octokit.graphql(
10327
10418
  GITHUB_UNRESOLVE_REVIEW_THREAD_MUTATION,
10328
10419
  {
@@ -10355,7 +10446,7 @@ function registerGitHubAgentTools(ctx) {
10355
10446
  if (userReviewers.length === 0 && teamReviewers.length === 0) {
10356
10447
  throw new Error("Provide at least one user reviewer or team reviewer.");
10357
10448
  }
10358
- const octokit = await createGitHubToolOctokit(ctx);
10449
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10359
10450
  const response = await octokit.rest.pulls.requestReviewers({
10360
10451
  owner: target.repository.owner,
10361
10452
  repo: target.repository.repo,
@@ -10380,13 +10471,13 @@ function registerGitHubAgentTools(ctx) {
10380
10471
  ctx.tools.register(
10381
10472
  "list_organization_projects",
10382
10473
  getGitHubAgentToolDeclaration("list_organization_projects"),
10383
- async (params) => executeGitHubTool(async () => {
10474
+ async (params, runCtx) => executeGitHubTool(async () => {
10384
10475
  const input = getToolInputRecord(params);
10385
10476
  const organization = normalizeOptionalToolString(input.organization);
10386
10477
  if (!organization) {
10387
10478
  throw new Error("organization is required.");
10388
10479
  }
10389
- const octokit = await createGitHubToolOctokit(ctx);
10480
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10390
10481
  const projects = await listGitHubOrganizationProjects(octokit, organization, {
10391
10482
  includeClosed: input.includeClosed === true,
10392
10483
  query: normalizeOptionalToolString(input.query),
@@ -10407,7 +10498,7 @@ function registerGitHubAgentTools(ctx) {
10407
10498
  async (params, runCtx) => executeGitHubTool(async () => {
10408
10499
  const input = getToolInputRecord(params);
10409
10500
  const target = await resolveGitHubPullRequestToolTarget(ctx, runCtx, input);
10410
- const octokit = await createGitHubToolOctokit(ctx);
10501
+ const octokit = await createGitHubToolOctokit(ctx, runCtx.companyId);
10411
10502
  const projectTarget = await resolveGitHubProjectToolTarget(octokit, input);
10412
10503
  const pullRequest = await getGitHubPullRequestProjectItems(
10413
10504
  octokit,
@@ -10484,14 +10575,30 @@ var plugin = definePlugin({
10484
10575
  const importRegistry = normalizeImportRegistry(await ctx.state.get(IMPORT_REGISTRY_SCOPE));
10485
10576
  const normalizedSettings = normalizeSettings(saved);
10486
10577
  const config = await getResolvedConfig(ctx);
10487
- const githubTokenRef = getConfiguredGithubTokenRef(normalizedSettings, config);
10578
+ const configuredGitHubTokenRef = requestedCompanyId ? normalizeSecretRef(config.githubTokenRefs?.[requestedCompanyId]) : normalizeGitHubTokenRef(config.githubTokenRef);
10579
+ const savedGitHubTokenRef = getSavedGitHubTokenRef(normalizedSettings, requestedCompanyId);
10580
+ const githubTokenRef = getConfiguredGithubTokenRef(normalizedSettings, config, requestedCompanyId);
10581
+ const githubTokenLogin = getSavedGitHubTokenLogin(normalizedSettings, requestedCompanyId);
10488
10582
  const paperclipApiBaseUrl = getConfiguredPaperclipApiBaseUrl(normalizedSettings, config);
10489
- const githubTokenConfigured = hasConfiguredGithubToken(normalizedSettings, config);
10583
+ const githubTokenConfigured = hasConfiguredGithubToken(normalizedSettings, config, requestedCompanyId);
10490
10584
  const configuredBoardTokenRef = getConfiguredPaperclipBoardApiTokenRef(config, requestedCompanyId);
10491
10585
  const savedBoardTokenRef = getSavedPaperclipBoardApiTokenRef(normalizedSettings, requestedCompanyId);
10492
- const settingsWithResolvedToken = githubTokenRef === normalizedSettings.githubTokenRef && paperclipApiBaseUrl === normalizedSettings.paperclipApiBaseUrl ? normalizedSettings : {
10586
+ const settingsWithResolvedToken = githubTokenRef === getSavedGitHubTokenRef(normalizedSettings, requestedCompanyId) && githubTokenLogin === getSavedGitHubTokenLogin(normalizedSettings, requestedCompanyId) && paperclipApiBaseUrl === normalizedSettings.paperclipApiBaseUrl ? normalizedSettings : {
10493
10587
  ...normalizedSettings,
10494
- ...githubTokenRef ? { githubTokenRef } : {},
10588
+ ...requestedCompanyId && githubTokenRef ? {
10589
+ githubTokenRefs: {
10590
+ ...normalizedSettings.githubTokenRefs ?? {},
10591
+ [requestedCompanyId]: githubTokenRef
10592
+ }
10593
+ } : {},
10594
+ ...requestedCompanyId && githubTokenLogin ? {
10595
+ githubTokenLoginsByCompanyId: {
10596
+ ...normalizedSettings.githubTokenLoginsByCompanyId ?? {},
10597
+ [requestedCompanyId]: githubTokenLogin
10598
+ }
10599
+ } : {},
10600
+ ...!requestedCompanyId && githubTokenRef ? { githubTokenRef } : {},
10601
+ ...!requestedCompanyId && githubTokenLogin ? { githubTokenLogin } : {},
10495
10602
  ...paperclipApiBaseUrl ? { paperclipApiBaseUrl } : {}
10496
10603
  };
10497
10604
  const settingsForResponse = sanitizeSettingsForCurrentSetup(settingsWithResolvedToken, {
@@ -10508,6 +10615,9 @@ var plugin = definePlugin({
10508
10615
  ...includeAssignees ? { availableAssignees } : {},
10509
10616
  totalSyncedIssuesCount: countImportedIssuesForMappings(importRegistry, scopedMappings),
10510
10617
  githubTokenConfigured,
10618
+ ...githubTokenLogin ? { githubTokenLogin } : {},
10619
+ ...savedGitHubTokenRef ? { githubTokenConfigSyncRef: savedGitHubTokenRef } : {},
10620
+ githubTokenNeedsConfigSync: Boolean(requestedCompanyId && savedGitHubTokenRef && !configuredGitHubTokenRef),
10511
10621
  paperclipBoardAccessConfigured: requestedCompanyId ? hasConfiguredPaperclipBoardAccess(settingsForResponse, config, requestedCompanyId) : hasConfiguredPaperclipBoardAccessForMappings(settingsForResponse, config, scopedMappings),
10512
10622
  ...savedBoardTokenRef ? { paperclipBoardAccessConfigSyncRef: savedBoardTokenRef } : {},
10513
10623
  paperclipBoardAccessNeedsConfigSync: Boolean(savedBoardTokenRef && !configuredBoardTokenRef)
@@ -10560,11 +10670,32 @@ var plugin = definePlugin({
10560
10670
  const requestedCompanyId = normalizeCompanyId(record.companyId);
10561
10671
  const hasMappingsPatch = "mappings" in record;
10562
10672
  const hasAdvancedSettingsPatch = "advancedSettings" in record;
10563
- const githubTokenRef = "githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : normalizeGitHubTokenRef(previous.githubTokenRef) ?? normalizeGitHubTokenRef(config.githubTokenRef);
10673
+ const githubTokenRef = "githubTokenRef" in record ? normalizeGitHubTokenRef(record.githubTokenRef) : void 0;
10674
+ const githubTokenLogin = "githubTokenLogin" in record ? normalizeOptionalString2(record.githubTokenLogin) : void 0;
10564
10675
  const inputMappings = hasMappingsPatch ? normalizeMappings(record.mappings) : previous.mappings;
10676
+ const nextGitHubTokenRefs = {
10677
+ ...previous.githubTokenRefs ?? {}
10678
+ };
10679
+ const nextGitHubTokenLoginsByCompanyId = {
10680
+ ...previous.githubTokenLoginsByCompanyId ?? {}
10681
+ };
10565
10682
  const nextCompanyAdvancedSettingsByCompanyId = {
10566
10683
  ...previous.companyAdvancedSettingsByCompanyId ?? {}
10567
10684
  };
10685
+ if (requestedCompanyId && "githubTokenRef" in record) {
10686
+ if (githubTokenRef) {
10687
+ nextGitHubTokenRefs[requestedCompanyId] = githubTokenRef;
10688
+ } else {
10689
+ delete nextGitHubTokenRefs[requestedCompanyId];
10690
+ }
10691
+ }
10692
+ if (requestedCompanyId && "githubTokenLogin" in record) {
10693
+ if (githubTokenLogin) {
10694
+ nextGitHubTokenLoginsByCompanyId[requestedCompanyId] = githubTokenLogin;
10695
+ } else {
10696
+ delete nextGitHubTokenLoginsByCompanyId[requestedCompanyId];
10697
+ }
10698
+ }
10568
10699
  if (requestedCompanyId && hasAdvancedSettingsPatch) {
10569
10700
  nextCompanyAdvancedSettingsByCompanyId[requestedCompanyId] = normalizeAdvancedSettings(record.advancedSettings);
10570
10701
  }
@@ -10580,9 +10711,13 @@ var plugin = definePlugin({
10580
10711
  syncState: previous.syncState,
10581
10712
  scheduleFrequencyMinutes: "scheduleFrequencyMinutes" in record ? record.scheduleFrequencyMinutes : previous.scheduleFrequencyMinutes,
10582
10713
  paperclipApiBaseUrl: "paperclipApiBaseUrl" in record ? resolveTrustedPaperclipApiBaseUrlInput(record.paperclipApiBaseUrl, previous, config) : getConfiguredPaperclipApiBaseUrl(previous, config),
10714
+ ...Object.keys(nextGitHubTokenRefs).length > 0 ? { githubTokenRefs: nextGitHubTokenRefs } : {},
10715
+ ...Object.keys(nextGitHubTokenLoginsByCompanyId).length > 0 ? { githubTokenLoginsByCompanyId: nextGitHubTokenLoginsByCompanyId } : {},
10716
+ ...!requestedCompanyId ? githubTokenLogin ? { githubTokenLogin } : previous.githubTokenLogin ? { githubTokenLogin: previous.githubTokenLogin } : {} : {},
10583
10717
  paperclipBoardApiTokenRefs: previous.paperclipBoardApiTokenRefs,
10718
+ paperclipBoardAccessIdentityByCompanyId: previous.paperclipBoardAccessIdentityByCompanyId,
10584
10719
  ...Object.keys(nextCompanyAdvancedSettingsByCompanyId).length > 0 ? { companyAdvancedSettingsByCompanyId: nextCompanyAdvancedSettingsByCompanyId } : {},
10585
- ...githubTokenRef ? { githubTokenRef } : {}
10720
+ ...!requestedCompanyId ? githubTokenRef ? { githubTokenRef } : previous.githubTokenRef ? { githubTokenRef: previous.githubTokenRef } : {} : {}
10586
10721
  });
10587
10722
  const nextMappings = current.mappings.map((mapping, index) => ({
10588
10723
  id: mapping.id.trim() || createMappingId(index),
@@ -10596,19 +10731,25 @@ var plugin = definePlugin({
10596
10731
  syncState: previous.syncState,
10597
10732
  scheduleFrequencyMinutes: current.scheduleFrequencyMinutes,
10598
10733
  ...current.paperclipApiBaseUrl ? { paperclipApiBaseUrl: current.paperclipApiBaseUrl } : {},
10734
+ ...current.githubTokenRefs ? { githubTokenRefs: current.githubTokenRefs } : {},
10735
+ ...current.githubTokenLoginsByCompanyId ? { githubTokenLoginsByCompanyId: current.githubTokenLoginsByCompanyId } : {},
10736
+ ...current.githubTokenLogin ? { githubTokenLogin: current.githubTokenLogin } : {},
10599
10737
  ...current.paperclipBoardApiTokenRefs ? { paperclipBoardApiTokenRefs: current.paperclipBoardApiTokenRefs } : {},
10738
+ ...current.paperclipBoardAccessIdentityByCompanyId ? { paperclipBoardAccessIdentityByCompanyId: current.paperclipBoardAccessIdentityByCompanyId } : {},
10600
10739
  ...current.companyAdvancedSettingsByCompanyId ? { companyAdvancedSettingsByCompanyId: current.companyAdvancedSettingsByCompanyId } : {},
10601
- ...githubTokenRef ? { githubTokenRef } : {},
10740
+ ...current.githubTokenRef ? { githubTokenRef: current.githubTokenRef } : {},
10602
10741
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10603
10742
  }, {
10604
- hasToken: hasConfiguredGithubToken({ githubTokenRef }, config),
10743
+ hasToken: hasConfiguredGithubToken(current, config, requestedCompanyId),
10605
10744
  hasMappings: getSyncableMappings(nextMappings).length > 0
10606
10745
  });
10607
10746
  await ctx.state.set(SETTINGS_SCOPE, next);
10608
10747
  await ctx.state.set(SYNC_STATE_SCOPE, next.syncState);
10609
10748
  clearGitHubRepositoryTokenCapabilityAudits();
10749
+ const scopedGitHubTokenLogin = getSavedGitHubTokenLogin(next, requestedCompanyId);
10610
10750
  return {
10611
10751
  ...getPublicSettingsForScope(next, requestedCompanyId),
10752
+ ...scopedGitHubTokenLogin ? { githubTokenLogin: scopedGitHubTokenLogin } : {},
10612
10753
  availableAssignees: requestedCompanyId ? await listAvailableAssignees(ctx, requestedCompanyId) : []
10613
10754
  };
10614
10755
  });
@@ -10624,21 +10765,35 @@ var plugin = definePlugin({
10624
10765
  const nextPaperclipBoardApiTokenRefs = {
10625
10766
  ...previous.paperclipBoardApiTokenRefs ?? {}
10626
10767
  };
10768
+ const nextPaperclipBoardAccessIdentityByCompanyId = {
10769
+ ...previous.paperclipBoardAccessIdentityByCompanyId ?? {}
10770
+ };
10627
10771
  if (nextSecretRef) {
10628
10772
  nextPaperclipBoardApiTokenRefs[companyId] = nextSecretRef;
10629
10773
  } else {
10630
10774
  delete nextPaperclipBoardApiTokenRefs[companyId];
10775
+ delete nextPaperclipBoardAccessIdentityByCompanyId[companyId];
10776
+ }
10777
+ if ("paperclipBoardAccessIdentity" in record) {
10778
+ const nextIdentityLabel = normalizeOptionalString2(record.paperclipBoardAccessIdentity);
10779
+ if (nextIdentityLabel) {
10780
+ nextPaperclipBoardAccessIdentityByCompanyId[companyId] = nextIdentityLabel;
10781
+ } else {
10782
+ delete nextPaperclipBoardAccessIdentityByCompanyId[companyId];
10783
+ }
10631
10784
  }
10632
10785
  const {
10633
10786
  paperclipBoardApiTokenRefs: _previousPaperclipBoardApiTokenRefs,
10787
+ paperclipBoardAccessIdentityByCompanyId: _previousPaperclipBoardAccessIdentityByCompanyId,
10634
10788
  ...previousWithoutBoardAccess
10635
10789
  } = previous;
10636
10790
  const next = sanitizeSettingsForCurrentSetup({
10637
10791
  ...previousWithoutBoardAccess,
10638
10792
  ...Object.keys(nextPaperclipBoardApiTokenRefs).length > 0 ? { paperclipBoardApiTokenRefs: nextPaperclipBoardApiTokenRefs } : {},
10793
+ ...Object.keys(nextPaperclipBoardAccessIdentityByCompanyId).length > 0 ? { paperclipBoardAccessIdentityByCompanyId: nextPaperclipBoardAccessIdentityByCompanyId } : {},
10639
10794
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
10640
10795
  }, {
10641
- hasToken: hasConfiguredGithubToken(previous, config),
10796
+ hasToken: hasConfiguredGithubToken(previous, config, companyId),
10642
10797
  hasMappings: getSyncableMappings(previous.mappings).length > 0
10643
10798
  });
10644
10799
  await ctx.state.set(SETTINGS_SCOPE, next);