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/ui/index.js CHANGED
@@ -22400,6 +22400,11 @@ function requiresPaperclipBoardAccess(value) {
22400
22400
  const health = normalizePaperclipHealthResponse(value);
22401
22401
  return health?.deploymentMode?.toLowerCase() === "authenticated";
22402
22402
  }
22403
+ function shouldShowPaperclipBoardAccessSettings(value) {
22404
+ const health = normalizePaperclipHealthResponse(value);
22405
+ const deploymentMode = health?.deploymentMode?.toLowerCase();
22406
+ return deploymentMode === "authenticated" || deploymentMode === "local_trusted";
22407
+ }
22403
22408
 
22404
22409
  // src/ui/assignees.ts
22405
22410
  function normalizeCompanyAssigneeOptionsResponse(response) {
@@ -22648,18 +22653,32 @@ function normalizePluginConfigBoardTokenRefs(value) {
22648
22653
  }
22649
22654
  return Object.fromEntries(entries);
22650
22655
  }
22656
+ function normalizePluginConfigGitHubTokenRefs(value) {
22657
+ if (!value || typeof value !== "object") {
22658
+ return void 0;
22659
+ }
22660
+ const entries = Object.entries(value).map(([companyId, secretRef]) => {
22661
+ const normalizedCompanyId = normalizeOptionalString2(companyId);
22662
+ const normalizedSecretRef = normalizeOptionalString2(secretRef);
22663
+ return normalizedCompanyId && normalizedSecretRef ? [normalizedCompanyId, normalizedSecretRef] : null;
22664
+ }).filter((entry) => Boolean(entry));
22665
+ if (entries.length === 0) {
22666
+ return void 0;
22667
+ }
22668
+ return Object.fromEntries(entries);
22669
+ }
22651
22670
  function normalizePluginConfig(value) {
22652
22671
  if (!value || typeof value !== "object") {
22653
22672
  return {};
22654
22673
  }
22655
22674
  const record = { ...value };
22656
- const githubTokenRef = normalizeOptionalString2(record.githubTokenRef);
22675
+ const githubTokenRefs = normalizePluginConfigGitHubTokenRefs(record.githubTokenRefs);
22657
22676
  const paperclipBoardApiTokenRefs = normalizePluginConfigBoardTokenRefs(record.paperclipBoardApiTokenRefs);
22658
22677
  const paperclipApiBaseUrl = normalizePaperclipApiBaseUrl(record.paperclipApiBaseUrl);
22659
- if (githubTokenRef) {
22660
- record.githubTokenRef = githubTokenRef;
22678
+ if (githubTokenRefs) {
22679
+ record.githubTokenRefs = githubTokenRefs;
22661
22680
  } else {
22662
- delete record.githubTokenRef;
22681
+ delete record.githubTokenRefs;
22663
22682
  }
22664
22683
  if (paperclipBoardApiTokenRefs) {
22665
22684
  record.paperclipBoardApiTokenRefs = paperclipBoardApiTokenRefs;
@@ -22675,12 +22694,27 @@ function normalizePluginConfig(value) {
22675
22694
  }
22676
22695
  function mergePluginConfig(currentValue, patch5) {
22677
22696
  const current = normalizePluginConfig(currentValue);
22697
+ const currentGitHubTokenRefs = normalizePluginConfigGitHubTokenRefs(current.githubTokenRefs);
22698
+ const patchGitHubTokenRefs = normalizePluginConfigGitHubTokenRefs(patch5.githubTokenRefs);
22678
22699
  const currentBoardTokenRefs = normalizePluginConfigBoardTokenRefs(current.paperclipBoardApiTokenRefs);
22679
22700
  const patchBoardTokenRefs = normalizePluginConfigBoardTokenRefs(patch5.paperclipBoardApiTokenRefs);
22680
22701
  const next2 = normalizePluginConfig({
22681
22702
  ...current,
22682
22703
  ...patch5
22683
22704
  });
22705
+ if ("githubTokenRefs" in patch5) {
22706
+ const mergedGitHubTokenRefs = {
22707
+ ...currentGitHubTokenRefs ?? {},
22708
+ ...patchGitHubTokenRefs ?? {}
22709
+ };
22710
+ if (Object.keys(mergedGitHubTokenRefs).length > 0) {
22711
+ next2.githubTokenRefs = mergedGitHubTokenRefs;
22712
+ } else {
22713
+ delete next2.githubTokenRefs;
22714
+ }
22715
+ } else if (currentGitHubTokenRefs) {
22716
+ next2.githubTokenRefs = currentGitHubTokenRefs;
22717
+ }
22684
22718
  if ("paperclipBoardApiTokenRefs" in patch5) {
22685
22719
  const mergedBoardTokenRefs = {
22686
22720
  ...currentBoardTokenRefs ?? {},
@@ -23011,6 +23045,7 @@ function getSyncSetupMessage(issue, hasCompanyContext) {
23011
23045
  }
23012
23046
  function usePaperclipBoardAccessRequirement() {
23013
23047
  const [status, setStatus] = useState2("loading");
23048
+ const [visible, setVisible] = useState2(false);
23014
23049
  useEffect2(() => {
23015
23050
  let cancelled = false;
23016
23051
  void (async () => {
@@ -23020,8 +23055,10 @@ function usePaperclipBoardAccessRequirement() {
23020
23055
  }
23021
23056
  if (!health) {
23022
23057
  setStatus("unknown");
23058
+ setVisible(false);
23023
23059
  return;
23024
23060
  }
23061
+ setVisible(shouldShowPaperclipBoardAccessSettings(health));
23025
23062
  setStatus(requiresPaperclipBoardAccess(health) ? "required" : "not_required");
23026
23063
  })();
23027
23064
  return () => {
@@ -23030,7 +23067,8 @@ function usePaperclipBoardAccessRequirement() {
23030
23067
  }, []);
23031
23068
  return {
23032
23069
  status,
23033
- required: status === "required"
23070
+ required: status === "required",
23071
+ visible
23034
23072
  };
23035
23073
  }
23036
23074
  function getGitHubRateLimitResourceLabel(resource) {
@@ -26535,12 +26573,21 @@ function normalizeGitHubUsername(value) {
26535
26573
  const trimmed = value.trim().replace(/^@+/, "").toLowerCase();
26536
26574
  return trimmed ? trimmed : null;
26537
26575
  }
26576
+ function normalizeOptionalText(value) {
26577
+ return typeof value === "string" && value.trim() ? value.trim() : null;
26578
+ }
26538
26579
  function normalizeIgnoredIssueAuthorUsernames(value) {
26539
26580
  const rawEntries = Array.isArray(value) ? value : typeof value === "string" ? value.split(/[\s,]+/g) : [];
26540
26581
  return [...new Set(
26541
26582
  rawEntries.map((entry) => typeof entry === "string" ? normalizeGitHubUsername(entry) : null).filter((entry) => Boolean(entry))
26542
26583
  )];
26543
26584
  }
26585
+ function normalizeAgentIds(value) {
26586
+ const rawEntries = Array.isArray(value) ? value : [];
26587
+ return [...new Set(
26588
+ rawEntries.map((entry) => typeof entry === "string" && entry.trim() ? entry.trim() : null).filter((entry) => Boolean(entry))
26589
+ )].sort((left, right) => left.localeCompare(right));
26590
+ }
26544
26591
  function normalizeAdvancedSettings(value) {
26545
26592
  if (!value || typeof value !== "object") {
26546
26593
  return DEFAULT_ADVANCED_SETTINGS;
@@ -26550,7 +26597,8 @@ function normalizeAdvancedSettings(value) {
26550
26597
  return {
26551
26598
  ...defaultAssigneeAgentId ? { defaultAssigneeAgentId } : {},
26552
26599
  defaultStatus: normalizePaperclipIssueStatus(record.defaultStatus),
26553
- ignoredIssueAuthorUsernames: "ignoredIssueAuthorUsernames" in record ? normalizeIgnoredIssueAuthorUsernames(record.ignoredIssueAuthorUsernames) : DEFAULT_ADVANCED_SETTINGS.ignoredIssueAuthorUsernames
26600
+ ignoredIssueAuthorUsernames: "ignoredIssueAuthorUsernames" in record ? normalizeIgnoredIssueAuthorUsernames(record.ignoredIssueAuthorUsernames) : DEFAULT_ADVANCED_SETTINGS.ignoredIssueAuthorUsernames,
26601
+ ...normalizeAgentIds(record.githubTokenPropagationAgentIds).length > 0 ? { githubTokenPropagationAgentIds: normalizeAgentIds(record.githubTokenPropagationAgentIds) } : {}
26554
26602
  };
26555
26603
  }
26556
26604
  function getComparableMappings(mappings) {
@@ -26567,7 +26615,8 @@ function getComparableAdvancedSettings(value) {
26567
26615
  return {
26568
26616
  ...settings.defaultAssigneeAgentId ? { defaultAssigneeAgentId: settings.defaultAssigneeAgentId } : {},
26569
26617
  defaultStatus: settings.defaultStatus,
26570
- ignoredIssueAuthorUsernames: [...settings.ignoredIssueAuthorUsernames].sort((left, right) => left.localeCompare(right))
26618
+ ignoredIssueAuthorUsernames: [...settings.ignoredIssueAuthorUsernames].sort((left, right) => left.localeCompare(right)),
26619
+ ...settings.githubTokenPropagationAgentIds?.length ? { githubTokenPropagationAgentIds: [...settings.githubTokenPropagationAgentIds].sort((left, right) => left.localeCompare(right)) } : {}
26571
26620
  };
26572
26621
  }
26573
26622
  function formatAssigneeOptionLabel(option) {
@@ -26583,7 +26632,20 @@ function getAvailableAssigneeOptions(options, selectedAgentId) {
26583
26632
  }
26584
26633
  return normalizedOptions;
26585
26634
  }
26586
- function formatAdvancedSettingsSummary(advancedSettings, availableAssignees) {
26635
+ function getAvailablePropagationAgentOptions(options, selectedAgentIds) {
26636
+ const normalizedOptions = [...options ?? []];
26637
+ const selectedIds = normalizeAgentIds(selectedAgentIds);
26638
+ for (const selectedAgentId of selectedIds) {
26639
+ if (!normalizedOptions.some((option) => option.id === selectedAgentId)) {
26640
+ normalizedOptions.push({
26641
+ id: selectedAgentId,
26642
+ name: "Unavailable agent"
26643
+ });
26644
+ }
26645
+ }
26646
+ return normalizedOptions.sort((left, right) => left.name.localeCompare(right.name));
26647
+ }
26648
+ function formatAdvancedSettingsSummary(advancedSettings, availableAssignees, options) {
26587
26649
  const assigneeLabel = advancedSettings.defaultAssigneeAgentId ? formatAssigneeOptionLabel(
26588
26650
  availableAssignees.find((option) => option.id === advancedSettings.defaultAssigneeAgentId) ?? {
26589
26651
  id: advancedSettings.defaultAssigneeAgentId,
@@ -26592,8 +26654,41 @@ function formatAdvancedSettingsSummary(advancedSettings, availableAssignees) {
26592
26654
  ) : "Unassigned";
26593
26655
  const statusLabel = PAPERCLIP_STATUS_OPTIONS.find((option) => option.value === advancedSettings.defaultStatus)?.label ?? "Backlog";
26594
26656
  const ignoredAuthorsLabel = advancedSettings.ignoredIssueAuthorUsernames.length > 0 ? advancedSettings.ignoredIssueAuthorUsernames.join(", ") : "none";
26657
+ if (options?.includePropagation) {
26658
+ const propagatedAgentsLabel = advancedSettings.githubTokenPropagationAgentIds?.length ? `${advancedSettings.githubTokenPropagationAgentIds.length} selected` : "none";
26659
+ return `Assignee: ${assigneeLabel} \xB7 Status: ${statusLabel} \xB7 Ignore: ${ignoredAuthorsLabel} \xB7 Propagate: ${propagatedAgentsLabel}`;
26660
+ }
26595
26661
  return `Assignee: ${assigneeLabel} \xB7 Status: ${statusLabel} \xB7 Ignore: ${ignoredAuthorsLabel}`;
26596
26662
  }
26663
+ function resolveSavedTokenUiState(params) {
26664
+ if (params.githubTokenConfigured) {
26665
+ return {
26666
+ showSavedTokenHint: true,
26667
+ showTokenEditor: false,
26668
+ tokenStatusOverride: "valid",
26669
+ validatedLogin: normalizeOptionalText(params.githubTokenLogin)
26670
+ };
26671
+ }
26672
+ return {
26673
+ showSavedTokenHint: false,
26674
+ showTokenEditor: true,
26675
+ tokenStatusOverride: null,
26676
+ validatedLogin: null
26677
+ };
26678
+ }
26679
+ function formatAgentMultiSelectionLabel(values, options) {
26680
+ if (values.length === 0) {
26681
+ return "No agents selected";
26682
+ }
26683
+ const labels = values.map((value) => options.find((option) => option.value === value)?.label ?? "Unavailable agent").filter((label) => label.trim().length > 0);
26684
+ if (labels.length === 0) {
26685
+ return "No agents selected";
26686
+ }
26687
+ if (labels.length <= 2) {
26688
+ return labels.join(", ");
26689
+ }
26690
+ return `${labels.length} agents selected`;
26691
+ }
26597
26692
  function PickerChevronIcon() {
26598
26693
  return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M4 6.5L8 10.5L12 6.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
26599
26694
  }
@@ -26748,6 +26843,122 @@ function SettingsAssigneePicker(props) {
26748
26843
  ] }) : null
26749
26844
  ] });
26750
26845
  }
26846
+ function SettingsAgentMultiPicker(props) {
26847
+ const { id, values, options, disabled, onChange } = props;
26848
+ const [open, setOpen] = useState2(false);
26849
+ const [query, setQuery] = useState2("");
26850
+ const rootRef = useRef(null);
26851
+ const searchInputRef = useRef(null);
26852
+ const selectedValues = normalizeAgentIds(values);
26853
+ const selectedValueSet = new Set(selectedValues);
26854
+ const normalizedQuery = query.trim().toLowerCase();
26855
+ const filteredOptions = normalizedQuery ? options.filter((option) => option.label.toLowerCase().includes(normalizedQuery)) : options;
26856
+ const selectedLabel = formatAgentMultiSelectionLabel(selectedValues, options);
26857
+ useEffect2(() => {
26858
+ if (!open) {
26859
+ setQuery("");
26860
+ return;
26861
+ }
26862
+ const handlePointerDown = (event) => {
26863
+ const target = event.target;
26864
+ if (target instanceof Node && rootRef.current?.contains(target)) {
26865
+ return;
26866
+ }
26867
+ setOpen(false);
26868
+ };
26869
+ const handleKeyDown = (event) => {
26870
+ if (event.key === "Escape") {
26871
+ setOpen(false);
26872
+ }
26873
+ };
26874
+ document.addEventListener("pointerdown", handlePointerDown);
26875
+ document.addEventListener("keydown", handleKeyDown);
26876
+ globalThis.setTimeout(() => {
26877
+ searchInputRef.current?.focus();
26878
+ searchInputRef.current?.select();
26879
+ }, 0);
26880
+ return () => {
26881
+ document.removeEventListener("pointerdown", handlePointerDown);
26882
+ document.removeEventListener("keydown", handleKeyDown);
26883
+ };
26884
+ }, [open]);
26885
+ useEffect2(() => {
26886
+ if (disabled && open) {
26887
+ setOpen(false);
26888
+ }
26889
+ }, [disabled, open]);
26890
+ return /* @__PURE__ */ jsxs2("div", { className: "ghsync__picker", ref: rootRef, children: [
26891
+ /* @__PURE__ */ jsxs2(
26892
+ "button",
26893
+ {
26894
+ id,
26895
+ type: "button",
26896
+ className: "ghsync__picker-trigger ghsync__picker-trigger--assignee",
26897
+ disabled,
26898
+ "aria-haspopup": "dialog",
26899
+ "aria-expanded": open,
26900
+ onClick: () => {
26901
+ if (disabled) {
26902
+ return;
26903
+ }
26904
+ setOpen((current) => !current);
26905
+ },
26906
+ children: [
26907
+ /* @__PURE__ */ jsxs2("span", { className: "ghsync__picker-trigger-main", children: [
26908
+ /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-agent-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(AgentIcon, {}) }),
26909
+ /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-trigger-label", children: selectedLabel })
26910
+ ] }),
26911
+ /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-trigger-icon", children: /* @__PURE__ */ jsx2(PickerChevronIcon, {}) })
26912
+ ]
26913
+ }
26914
+ ),
26915
+ open ? /* @__PURE__ */ jsxs2("div", { className: "ghsync__picker-panel ghsync__picker-panel--assignee", role: "dialog", "aria-label": "Choose agents", children: [
26916
+ /* @__PURE__ */ jsx2("div", { className: "ghsync__picker-search", children: /* @__PURE__ */ jsx2(
26917
+ "input",
26918
+ {
26919
+ ref: searchInputRef,
26920
+ type: "text",
26921
+ className: "ghsync__picker-search-input",
26922
+ placeholder: "Search agents...",
26923
+ value: query,
26924
+ onChange: (event) => {
26925
+ setQuery(event.currentTarget.value);
26926
+ },
26927
+ onKeyDown: (event) => {
26928
+ if (event.key === "Escape") {
26929
+ event.preventDefault();
26930
+ setOpen(false);
26931
+ }
26932
+ }
26933
+ }
26934
+ ) }),
26935
+ /* @__PURE__ */ jsx2("div", { className: "ghsync__picker-list", role: "listbox", "aria-labelledby": id, "aria-multiselectable": "true", children: filteredOptions.length > 0 ? filteredOptions.map((option) => {
26936
+ const selected = selectedValueSet.has(option.value);
26937
+ return /* @__PURE__ */ jsxs2(
26938
+ "button",
26939
+ {
26940
+ type: "button",
26941
+ role: "option",
26942
+ "aria-selected": selected,
26943
+ className: `ghsync__picker-option${selected ? " ghsync__picker-option--selected" : ""}`,
26944
+ onClick: () => {
26945
+ const nextValues = selected ? selectedValues.filter((value) => value !== option.value) : normalizeAgentIds([...selectedValues, option.value]);
26946
+ onChange(nextValues);
26947
+ },
26948
+ children: [
26949
+ /* @__PURE__ */ jsxs2("span", { className: "ghsync__picker-trigger-main", children: [
26950
+ option.icon === "agent" ? /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-agent-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(AgentIcon, {}) }) : null,
26951
+ /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-option-label", children: option.label })
26952
+ ] }),
26953
+ /* @__PURE__ */ jsx2("span", { className: "ghsync__picker-option-check", "aria-hidden": "true", children: selected ? /* @__PURE__ */ jsx2(PickerCheckIcon, {}) : null })
26954
+ ]
26955
+ },
26956
+ option.value
26957
+ );
26958
+ }) : /* @__PURE__ */ jsx2("div", { className: "ghsync__picker-empty", children: "No agents match." }) })
26959
+ ] }) : null
26960
+ ] });
26961
+ }
26751
26962
  function SettingsStatusPicker(props) {
26752
26963
  const { id, value, options, disabled, onChange } = props;
26753
26964
  const [open, setOpen] = useState2(false);
@@ -27678,6 +27889,117 @@ async function patchPluginConfig(pluginId, patch5) {
27678
27889
  })
27679
27890
  });
27680
27891
  }
27892
+ var GITHUB_TOKEN_PROPAGATION_CONCURRENCY_LIMIT = 4;
27893
+ function normalizeAgentAdapterConfig(value) {
27894
+ return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
27895
+ }
27896
+ function normalizeAgentEnvBindings(value) {
27897
+ return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
27898
+ }
27899
+ function isMatchingSecretRefEnvBinding(value, secretId) {
27900
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
27901
+ return false;
27902
+ }
27903
+ const record = value;
27904
+ return record.type === "secret_ref" && record.secretId === secretId;
27905
+ }
27906
+ function getAgentPropagationPatch(params) {
27907
+ const adapterConfig = normalizeAgentAdapterConfig(params.adapterConfig);
27908
+ const currentEnv = normalizeAgentEnvBindings(adapterConfig.env);
27909
+ if (params.mode === "ensure") {
27910
+ const nextEnv2 = {
27911
+ ...currentEnv,
27912
+ GITHUB_TOKEN: {
27913
+ type: "secret_ref",
27914
+ secretId: params.githubTokenSecretRef
27915
+ }
27916
+ };
27917
+ if (JSON.stringify(nextEnv2) === JSON.stringify(currentEnv)) {
27918
+ return null;
27919
+ }
27920
+ return {
27921
+ ...adapterConfig,
27922
+ env: nextEnv2
27923
+ };
27924
+ }
27925
+ if (!isMatchingSecretRefEnvBinding(currentEnv.GITHUB_TOKEN, params.githubTokenSecretRef)) {
27926
+ return null;
27927
+ }
27928
+ const nextEnv = { ...currentEnv };
27929
+ delete nextEnv.GITHUB_TOKEN;
27930
+ const nextAdapterConfig = {
27931
+ ...adapterConfig
27932
+ };
27933
+ if (Object.keys(nextEnv).length > 0) {
27934
+ nextAdapterConfig.env = nextEnv;
27935
+ } else {
27936
+ delete nextAdapterConfig.env;
27937
+ }
27938
+ return nextAdapterConfig;
27939
+ }
27940
+ async function runWithConcurrencyLimit(items, concurrencyLimit, worker) {
27941
+ if (items.length === 0) {
27942
+ return;
27943
+ }
27944
+ let nextIndex = 0;
27945
+ const runnerCount = Math.min(concurrencyLimit, items.length);
27946
+ await Promise.all(
27947
+ Array.from({ length: runnerCount }, async () => {
27948
+ while (nextIndex < items.length) {
27949
+ const currentIndex = nextIndex;
27950
+ nextIndex += 1;
27951
+ await worker(items[currentIndex]);
27952
+ }
27953
+ })
27954
+ );
27955
+ }
27956
+ async function applyGitHubTokenPropagationUpdate(params) {
27957
+ const agent = await fetchJson(`/api/agents/${params.agentId}`);
27958
+ const nextAdapterConfig = getAgentPropagationPatch({
27959
+ adapterConfig: agent?.adapterConfig,
27960
+ githubTokenSecretRef: params.githubTokenSecretRef,
27961
+ mode: params.mode
27962
+ });
27963
+ if (!nextAdapterConfig) {
27964
+ return;
27965
+ }
27966
+ await fetchJson(`/api/agents/${params.agentId}`, {
27967
+ method: "PATCH",
27968
+ body: JSON.stringify({
27969
+ adapterConfig: nextAdapterConfig
27970
+ })
27971
+ });
27972
+ }
27973
+ async function syncGitHubTokenPropagationForAgents(params) {
27974
+ const selectedAgentIds = normalizeAgentIds(params.selectedAgentIds);
27975
+ const selectedAgentIdSet = new Set(selectedAgentIds);
27976
+ const previousAgentIds = normalizeAgentIds(params.previousAgentIds);
27977
+ const failures = /* @__PURE__ */ new Set();
27978
+ const operations = [
27979
+ ...selectedAgentIds.map((agentId) => ({ agentId, mode: "ensure" })),
27980
+ ...previousAgentIds.filter((agentId) => !selectedAgentIdSet.has(agentId)).map((agentId) => ({ agentId, mode: "remove" }))
27981
+ ];
27982
+ await runWithConcurrencyLimit(
27983
+ operations,
27984
+ GITHUB_TOKEN_PROPAGATION_CONCURRENCY_LIMIT,
27985
+ async (operation) => {
27986
+ try {
27987
+ await applyGitHubTokenPropagationUpdate({
27988
+ agentId: operation.agentId,
27989
+ githubTokenSecretRef: params.githubTokenSecretRef,
27990
+ mode: operation.mode
27991
+ });
27992
+ } catch {
27993
+ failures.add(operation.agentId);
27994
+ }
27995
+ }
27996
+ );
27997
+ if (failures.size > 0) {
27998
+ throw new Error(
27999
+ `GitHub token propagation could not update these agents: ${[...failures].join(", ")}.`
28000
+ );
28001
+ }
28002
+ }
27681
28003
  function normalizeCliAuthPollIntervalMs(value) {
27682
28004
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
27683
28005
  return CLI_AUTH_POLL_INTERVAL_FALLBACK_MS;
@@ -30765,6 +31087,7 @@ function GitHubSyncSettingsPage() {
30765
31087
  const themeMode = useResolvedThemeMode();
30766
31088
  const boardAccessRequirement = usePaperclipBoardAccessRequirement();
30767
31089
  const armSyncCompletionToast = useSyncCompletionToast(form.syncState, toast);
31090
+ const githubTokenConfigSyncAttemptRef = useRef(null);
30768
31091
  const boardAccessConfigSyncAttemptRef = useRef(null);
30769
31092
  const assigneeFallbackAttemptRef = useRef(null);
30770
31093
  const currentSettings = settings.data ?? cachedSettings;
@@ -30778,6 +31101,11 @@ function GitHubSyncSettingsPage() {
30778
31101
  if (!settings.data) {
30779
31102
  return;
30780
31103
  }
31104
+ const tokenUiState = resolveSavedTokenUiState({
31105
+ githubTokenConfigured: settings.data.githubTokenConfigured,
31106
+ githubTokenLogin: settings.data.githubTokenLogin
31107
+ });
31108
+ const savedBoardAccessIdentity = typeof settings.data.paperclipBoardAccessIdentity === "string" && settings.data.paperclipBoardAccessIdentity.trim() ? settings.data.paperclipBoardAccessIdentity.trim() : null;
30781
31109
  const nextScheduleFrequencyMinutes = normalizeScheduleFrequencyMinutes(settings.data.scheduleFrequencyMinutes);
30782
31110
  setForm({
30783
31111
  mappings: settings.data.mappings ?? [],
@@ -30794,18 +31122,12 @@ function GitHubSyncSettingsPage() {
30794
31122
  setScheduleFrequencyDraft(String(nextScheduleFrequencyMinutes));
30795
31123
  setIgnoredAuthorsDraft(normalizeAdvancedSettings(settings.data.advancedSettings).ignoredIssueAuthorUsernames.join(", "));
30796
31124
  setTokenDraft("");
30797
- if (!settings.data.paperclipBoardAccessConfigured) {
30798
- setBoardAccessIdentity(null);
30799
- }
30800
- if (settings.data.githubTokenConfigured) {
30801
- setShowSavedTokenHint(true);
30802
- setShowTokenEditor(false);
30803
- setTokenStatusOverride("valid");
30804
- } else if (!showSavedTokenHint) {
30805
- setShowTokenEditor(true);
30806
- setValidatedLogin(null);
30807
- }
30808
- }, [settings.data, showSavedTokenHint]);
31125
+ setValidatedLogin(tokenUiState.validatedLogin);
31126
+ setBoardAccessIdentity(settings.data.paperclipBoardAccessConfigured ? savedBoardAccessIdentity : null);
31127
+ setShowSavedTokenHint(tokenUiState.showSavedTokenHint);
31128
+ setShowTokenEditor(tokenUiState.showTokenEditor);
31129
+ setTokenStatusOverride(tokenUiState.tokenStatusOverride);
31130
+ }, [settings.data]);
30809
31131
  useEffect2(() => {
30810
31132
  const companyId = hostContext.companyId;
30811
31133
  if (!companyId || tokenStatusOverride === "invalid") {
@@ -30879,6 +31201,75 @@ function GitHubSyncSettingsPage() {
30879
31201
  cancelled = true;
30880
31202
  };
30881
31203
  }, [currentSettings?.availableAssignees?.length, currentSettings?.updatedAt, hostContext.companyId]);
31204
+ useEffect2(() => {
31205
+ const companyId = hostContext.companyId;
31206
+ const secretRef = settings.data?.githubTokenNeedsConfigSync ? settings.data.githubTokenConfigSyncRef : void 0;
31207
+ if (!companyId || !secretRef) {
31208
+ return;
31209
+ }
31210
+ const attemptKey = `${companyId}:${secretRef}`;
31211
+ if (githubTokenConfigSyncAttemptRef.current === attemptKey) {
31212
+ return;
31213
+ }
31214
+ githubTokenConfigSyncAttemptRef.current = attemptKey;
31215
+ let cancelled = false;
31216
+ void (async () => {
31217
+ try {
31218
+ const pluginId = await resolveCurrentPluginId(pluginIdFromLocation);
31219
+ if (!pluginId) {
31220
+ throw new Error("Plugin id is required to finish syncing the GitHub token secret into plugin config.");
31221
+ }
31222
+ await patchPluginConfig(pluginId, {
31223
+ githubTokenRefs: {
31224
+ [companyId]: secretRef
31225
+ }
31226
+ });
31227
+ if (cancelled) {
31228
+ return;
31229
+ }
31230
+ const selectedAgentIds = normalizeAgentIds(settings.data?.advancedSettings?.githubTokenPropagationAgentIds);
31231
+ if (selectedAgentIds.length > 0) {
31232
+ try {
31233
+ await propagateGitHubTokenToSelectedAgents({
31234
+ selectedAgentIds,
31235
+ previousAgentIds: selectedAgentIds,
31236
+ githubTokenSecretRef: secretRef
31237
+ });
31238
+ } catch {
31239
+ }
31240
+ }
31241
+ notifyGitHubSyncSettingsChanged();
31242
+ try {
31243
+ await settings.refresh();
31244
+ } catch {
31245
+ return;
31246
+ }
31247
+ } catch (error) {
31248
+ if (cancelled) {
31249
+ return;
31250
+ }
31251
+ toast({
31252
+ title: "GitHub token needs reconnection",
31253
+ body: getActionErrorMessage(
31254
+ error,
31255
+ "GitHub Sync could not finish migrating the saved GitHub token secret into plugin config."
31256
+ ),
31257
+ tone: "error"
31258
+ });
31259
+ }
31260
+ })();
31261
+ return () => {
31262
+ cancelled = true;
31263
+ };
31264
+ }, [
31265
+ hostContext.companyId,
31266
+ pluginIdFromLocation,
31267
+ settings.data?.advancedSettings?.githubTokenPropagationAgentIds,
31268
+ settings.data?.githubTokenConfigSyncRef,
31269
+ settings.data?.githubTokenNeedsConfigSync,
31270
+ settings.refresh,
31271
+ toast
31272
+ ]);
30882
31273
  useEffect2(() => {
30883
31274
  const companyId = hostContext.companyId;
30884
31275
  const secretRef = settings.data?.paperclipBoardAccessNeedsConfigSync ? settings.data.paperclipBoardAccessConfigSyncRef : void 0;
@@ -31006,6 +31397,7 @@ function GitHubSyncSettingsPage() {
31006
31397
  const hasSavedToken = Boolean(form.githubTokenConfigured || showSavedTokenHint);
31007
31398
  const boardAccessConfigured = Boolean(form.paperclipBoardAccessConfigured);
31008
31399
  const boardAccessRequired = boardAccessRequirement.required;
31400
+ const boardAccessVisible = boardAccessRequirement.visible;
31009
31401
  const boardAccessReady = !boardAccessRequired || hasCompanyContext && boardAccessConfigured;
31010
31402
  const tokenStatus = tokenStatusOverride ?? (hasSavedToken ? "valid" : "required");
31011
31403
  const tokenTone = tokenStatus === "valid" ? "success" : tokenStatus === "invalid" ? "danger" : "warning";
@@ -31028,6 +31420,10 @@ function GitHubSyncSettingsPage() {
31028
31420
  (currentSettings?.availableAssignees?.length ? currentSettings.availableAssignees : null) ?? (form.availableAssignees?.length ? form.availableAssignees : null) ?? browserAvailableAssignees,
31029
31421
  form.advancedSettings.defaultAssigneeAgentId
31030
31422
  );
31423
+ const propagationAgents = getAvailablePropagationAgentOptions(
31424
+ (currentSettings?.availableAssignees?.length ? currentSettings.availableAssignees : null) ?? (form.availableAssignees?.length ? form.availableAssignees : null) ?? browserAvailableAssignees,
31425
+ form.advancedSettings.githubTokenPropagationAgentIds
31426
+ );
31031
31427
  const savedMappingsSource = currentSettings ? currentSettings.mappings ?? [] : form.mappings;
31032
31428
  const savedMappings = getComparableMappings(savedMappingsSource);
31033
31429
  const draftMappings = getComparableMappings(form.mappings);
@@ -31069,7 +31465,7 @@ function GitHubSyncSettingsPage() {
31069
31465
  const canConnectBoardAccess = hasCompanyContext && !settingsMutationsLocked && !connectingBoardAccess && !showInitialLoadingState;
31070
31466
  const boardAccessStatusLabel = !hasCompanyContext ? "Unavailable" : boardAccessBannerLabel;
31071
31467
  const boardAccessStatusTone = !hasCompanyContext ? boardAccessRequired ? "warning" : "neutral" : boardAccessTone;
31072
- const boardAccessSummaryText = !hasCompanyContext ? boardAccessRequired ? "Select a company." : "Select a company." : connectingBoardAccess ? "Approval in progress." : boardAccessConfigured ? "Connected." : boardAccessRequired ? "Required for sync." : boardAccessRequirement.status === "loading" ? "Checking requirement." : "Optional.";
31468
+ const boardAccessSummaryText = !hasCompanyContext ? boardAccessRequired ? "Select a company." : "Select a company." : connectingBoardAccess ? "Approval in progress." : boardAccessConfigured ? boardAccessIdentity ? `Connected as ${boardAccessIdentity}.` : "Connected." : boardAccessRequired ? "Required for sync." : boardAccessRequirement.status === "loading" ? "Checking requirement." : "Optional.";
31073
31469
  const showTokenForm = tokenStatus !== "valid" || showTokenEditor;
31074
31470
  const lastUpdated = formatDate(form.updatedAt ?? currentSettings?.updatedAt, "Not saved yet");
31075
31471
  const lastSync = formatDate(displaySyncState.checkedAt, "Never");
@@ -31095,7 +31491,9 @@ function GitHubSyncSettingsPage() {
31095
31491
  const manualSyncScopePillClass = hasCompanyContext ? "ghsync__scope-pill ghsync__scope-pill--company" : "ghsync__scope-pill ghsync__scope-pill--mixed";
31096
31492
  const manualSyncScopePillLabel = hasCompanyContext ? "This company" : "All companies";
31097
31493
  const manualSyncButtonLabel = hasCompanyContext ? "Run sync for this company" : "Run sync across all companies";
31098
- const advancedSettingsSummary = formatAdvancedSettingsSummary(form.advancedSettings, availableAssignees);
31494
+ const advancedSettingsSummary = formatAdvancedSettingsSummary(form.advancedSettings, availableAssignees, {
31495
+ includePropagation: boardAccessVisible
31496
+ });
31099
31497
  const assigneeSelectOptions = [
31100
31498
  { value: "", label: "Unassigned" },
31101
31499
  ...availableAssignees.map((option) => ({
@@ -31104,6 +31502,11 @@ function GitHubSyncSettingsPage() {
31104
31502
  icon: "agent"
31105
31503
  }))
31106
31504
  ];
31505
+ const propagationAgentOptions = propagationAgents.map((option) => ({
31506
+ value: option.id,
31507
+ label: formatAssigneeOptionLabel(option),
31508
+ icon: "agent"
31509
+ }));
31107
31510
  const statusSelectOptions = PAPERCLIP_STATUS_OPTIONS.map((option) => ({
31108
31511
  value: option.value,
31109
31512
  label: option.label,
@@ -31234,6 +31637,37 @@ function GitHubSyncSettingsPage() {
31234
31637
  };
31235
31638
  });
31236
31639
  }
31640
+ async function propagateGitHubTokenToSelectedAgents(options) {
31641
+ if (!boardAccessVisible) {
31642
+ return;
31643
+ }
31644
+ const selectedAgentIds = normalizeAgentIds(options.selectedAgentIds);
31645
+ const previousAgentIds = normalizeAgentIds(options.previousAgentIds);
31646
+ if (selectedAgentIds.length === 0 && previousAgentIds.length === 0) {
31647
+ return;
31648
+ }
31649
+ let githubTokenSecretRef = typeof options.githubTokenSecretRef === "string" && options.githubTokenSecretRef.trim() ? options.githubTokenSecretRef.trim() : void 0;
31650
+ if (!githubTokenSecretRef) {
31651
+ const companyId = hostContext.companyId;
31652
+ if (!companyId) {
31653
+ throw new Error("Company context is required to propagate the GitHub token to selected agents.");
31654
+ }
31655
+ const pluginId = await resolveCurrentPluginId(pluginIdFromLocation);
31656
+ if (!pluginId) {
31657
+ throw new Error("Plugin id is required to propagate the GitHub token to selected agents.");
31658
+ }
31659
+ const currentConfigResponse = await fetchJson(`/api/plugins/${pluginId}/config`);
31660
+ githubTokenSecretRef = normalizePluginConfig(currentConfigResponse?.configJson).githubTokenRefs?.[companyId];
31661
+ }
31662
+ if (!githubTokenSecretRef) {
31663
+ throw new Error("GitHub token propagation requires a GitHub token saved through this settings page.");
31664
+ }
31665
+ await syncGitHubTokenPropagationForAgents({
31666
+ githubTokenSecretRef,
31667
+ selectedAgentIds,
31668
+ previousAgentIds
31669
+ });
31670
+ }
31237
31671
  async function handleSaveToken(event) {
31238
31672
  event.preventDefault();
31239
31673
  setSubmittingToken(true);
@@ -31273,12 +31707,26 @@ function GitHubSyncSettingsPage() {
31273
31707
  const secretName = `github_sync_${companyId.replace(/[^a-z0-9]+/gi, "_").toLowerCase()}`;
31274
31708
  const secret = await resolveOrCreateCompanySecret(companyId, secretName, trimmedToken);
31275
31709
  await patchPluginConfig(pluginId, {
31276
- githubTokenRef: secret.id
31710
+ githubTokenRefs: {
31711
+ [companyId]: secret.id
31712
+ }
31277
31713
  });
31278
31714
  await saveRegistration({
31279
31715
  companyId,
31280
- githubTokenRef: secret.id
31716
+ githubTokenRef: secret.id,
31717
+ githubTokenLogin: validation.login
31281
31718
  });
31719
+ const selectedAgentIds = normalizeAgentIds(currentSettings?.advancedSettings?.githubTokenPropagationAgentIds);
31720
+ let propagationError = null;
31721
+ try {
31722
+ await propagateGitHubTokenToSelectedAgents({
31723
+ selectedAgentIds,
31724
+ previousAgentIds: selectedAgentIds,
31725
+ githubTokenSecretRef: secret.id
31726
+ });
31727
+ } catch (error) {
31728
+ propagationError = error;
31729
+ }
31282
31730
  setForm((current) => ({
31283
31731
  ...current,
31284
31732
  githubTokenConfigured: true
@@ -31293,6 +31741,16 @@ function GitHubSyncSettingsPage() {
31293
31741
  body: "Token saved.",
31294
31742
  tone: "success"
31295
31743
  });
31744
+ if (propagationError) {
31745
+ toast({
31746
+ title: "GitHub token saved, but agent propagation needs attention",
31747
+ body: getActionErrorMessage(
31748
+ propagationError,
31749
+ "GitHub Sync could not update the selected agents with the saved token."
31750
+ ),
31751
+ tone: "error"
31752
+ });
31753
+ }
31296
31754
  notifyGitHubSyncSettingsChanged();
31297
31755
  try {
31298
31756
  await settings.refresh();
@@ -31348,7 +31806,8 @@ function GitHubSyncSettingsPage() {
31348
31806
  });
31349
31807
  await updateBoardAccess({
31350
31808
  companyId,
31351
- paperclipBoardApiTokenRef: secret.id
31809
+ paperclipBoardApiTokenRef: secret.id,
31810
+ paperclipBoardAccessIdentity: identity ?? ""
31352
31811
  });
31353
31812
  setBoardAccessIdentity(identity);
31354
31813
  setForm((current) => ({
@@ -31428,6 +31887,15 @@ function GitHubSyncSettingsPage() {
31428
31887
  scheduleFrequencyMinutes,
31429
31888
  ...trustedPaperclipApiBaseUrl ? { paperclipApiBaseUrl: trustedPaperclipApiBaseUrl } : {}
31430
31889
  });
31890
+ let propagationError = null;
31891
+ try {
31892
+ await propagateGitHubTokenToSelectedAgents({
31893
+ selectedAgentIds: normalizeAgentIds(normalizeAdvancedSettings(result.advancedSettings).githubTokenPropagationAgentIds),
31894
+ previousAgentIds: normalizeAgentIds(currentSettings?.advancedSettings?.githubTokenPropagationAgentIds)
31895
+ });
31896
+ } catch (error) {
31897
+ propagationError = error;
31898
+ }
31431
31899
  setForm((current) => ({
31432
31900
  ...current,
31433
31901
  mappings: result.mappings.length > 0 ? result.mappings : [createEmptyMapping(0)],
@@ -31444,6 +31912,16 @@ function GitHubSyncSettingsPage() {
31444
31912
  body: `Advanced defaults, mappings, and automatic sync are saved for ${currentCompanyName}.`,
31445
31913
  tone: "success"
31446
31914
  });
31915
+ if (propagationError) {
31916
+ toast({
31917
+ title: "Settings saved, but agent propagation needs attention",
31918
+ body: getActionErrorMessage(
31919
+ propagationError,
31920
+ "GitHub Sync could not apply the selected agent token propagation updates."
31921
+ ),
31922
+ tone: "error"
31923
+ });
31924
+ }
31447
31925
  notifyGitHubSyncSettingsChanged();
31448
31926
  try {
31449
31927
  await settings.refresh();
@@ -31685,7 +32163,7 @@ function GitHubSyncSettingsPage() {
31685
32163
  /* @__PURE__ */ jsx2("div", { className: "ghsync__permission-audit-list", children: /* @__PURE__ */ jsx2("div", { className: "ghsync__permission-audit-item", children: /* @__PURE__ */ jsx2("span", { children: tokenPermissionAuditData?.warnings[0] ?? "Add a mapped repository in this company so GitHub Sync can verify the token permissions it needs." }) }) })
31686
32164
  ] }) : null
31687
32165
  ] }),
31688
- /* @__PURE__ */ jsxs2("section", { className: "ghsync__section", children: [
32166
+ boardAccessVisible ? /* @__PURE__ */ jsxs2("section", { className: "ghsync__section", children: [
31689
32167
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__section-head", children: [
31690
32168
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__section-copy", children: [
31691
32169
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__section-title-row", children: [
@@ -31699,7 +32177,7 @@ function GitHubSyncSettingsPage() {
31699
32177
  hostContext.companyId ? /* @__PURE__ */ jsxs2("div", { className: "ghsync__connected", children: [
31700
32178
  /* @__PURE__ */ jsxs2("div", { children: [
31701
32179
  /* @__PURE__ */ jsx2("strong", { children: boardAccessConfigured ? boardAccessIdentity ? `Connected as ${boardAccessIdentity}` : "Connected" : boardAccessRequired ? "Required" : boardAccessRequirement.status === "loading" ? "Checking requirement" : "Optional" }),
31702
- /* @__PURE__ */ jsx2("span", { children: boardAccessConfigured ? "Used for Paperclip API calls." : boardAccessRequired ? "Required in authenticated deployments." : boardAccessRequirement.status === "loading" ? "Checking whether it is required." : "Only needed when Paperclip API calls require sign-in." })
32180
+ /* @__PURE__ */ jsx2("span", { children: boardAccessConfigured ? "Used for Paperclip API calls." : boardAccessRequired ? "Required in authenticated deployments." : boardAccessRequirement.status === "loading" ? "Checking whether it is required." : "Available here for local testing and only required when Paperclip API calls need sign-in." })
31703
32181
  ] }),
31704
32182
  /* @__PURE__ */ jsx2(
31705
32183
  "button",
@@ -31727,7 +32205,7 @@ function GitHubSyncSettingsPage() {
31727
32205
  ] }),
31728
32206
  /* @__PURE__ */ jsx2("span", { className: "ghsync__badge ghsync__badge--neutral", children: "Unavailable" })
31729
32207
  ] })
31730
- ] }),
32208
+ ] }) : null,
31731
32209
  /* @__PURE__ */ jsxs2("section", { className: "ghsync__section", children: [
31732
32210
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__section-head", children: [
31733
32211
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__section-copy", children: [
@@ -31954,7 +32432,29 @@ function GitHubSyncSettingsPage() {
31954
32432
  }
31955
32433
  ),
31956
32434
  /* @__PURE__ */ jsx2("p", { className: "ghsync__hint", children: "Comma or newline separated." })
31957
- ] })
32435
+ ] }),
32436
+ boardAccessVisible ? /* @__PURE__ */ jsxs2("div", { className: "ghsync__field", children: [
32437
+ /* @__PURE__ */ jsx2("label", { htmlFor: "advanced-token-propagation", children: "Propagate GitHub token to agents" }),
32438
+ /* @__PURE__ */ jsx2(
32439
+ SettingsAgentMultiPicker,
32440
+ {
32441
+ id: "advanced-token-propagation",
32442
+ values: form.advancedSettings.githubTokenPropagationAgentIds ?? [],
32443
+ options: propagationAgentOptions,
32444
+ disabled: settingsMutationsLocked || tokenStatus !== "valid",
32445
+ onChange: (nextValues) => {
32446
+ setForm((current) => ({
32447
+ ...current,
32448
+ advancedSettings: {
32449
+ ...current.advancedSettings,
32450
+ ...nextValues.length > 0 ? { githubTokenPropagationAgentIds: nextValues } : { githubTokenPropagationAgentIds: void 0 }
32451
+ }
32452
+ }));
32453
+ }
32454
+ }
32455
+ ),
32456
+ /* @__PURE__ */ jsx2("p", { className: "ghsync__hint", children: tokenStatus === "valid" ? "Selected agents receive `GITHUB_TOKEN` from the saved GitHub secret when you save settings." : "Save a valid GitHub token before choosing agents to propagate it to." })
32457
+ ] }) : null
31958
32458
  ] }) : null
31959
32459
  ] }),
31960
32460
  /* @__PURE__ */ jsxs2("section", { className: "ghsync__section", children: [
@@ -32107,13 +32607,13 @@ function GitHubSyncSettingsPage() {
32107
32607
  ] }),
32108
32608
  /* @__PURE__ */ jsx2("span", { children: !repositoriesUnlocked ? "Requires a token." : savedMappingCount > 0 ? hasCompanyContext ? `${savedMappingCount} saved.` : `${savedMappingCount} saved.` : hasCompanyContext ? "Add a repository." : "Select a company." })
32109
32609
  ] }),
32110
- /* @__PURE__ */ jsxs2("div", { className: "ghsync__check", children: [
32610
+ boardAccessVisible ? /* @__PURE__ */ jsxs2("div", { className: "ghsync__check", children: [
32111
32611
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__check-top", children: [
32112
32612
  /* @__PURE__ */ jsx2("strong", { children: "Paperclip board access" }),
32113
32613
  /* @__PURE__ */ jsx2("span", { className: `ghsync__badge ${getToneClass(boardAccessStatusTone)}`, children: boardAccessStatusLabel })
32114
32614
  ] }),
32115
32615
  /* @__PURE__ */ jsx2("span", { children: boardAccessSummaryText })
32116
- ] }),
32616
+ ] }) : null,
32117
32617
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__check", children: [
32118
32618
  /* @__PURE__ */ jsxs2("div", { className: "ghsync__check-top", children: [
32119
32619
  /* @__PURE__ */ jsx2("strong", { children: "Sync" }),
@@ -33123,6 +33623,8 @@ export {
33123
33623
  GitHubSyncProjectPullRequestsSidebarItem,
33124
33624
  GitHubSyncSettingsPage,
33125
33625
  index_default as default,
33126
- resolveOrCreateProject
33626
+ resolveOrCreateProject,
33627
+ resolveSavedTokenUiState,
33628
+ syncGitHubTokenPropagationForAgents
33127
33629
  };
33128
33630
  //# sourceMappingURL=index.js.map