vercel 53.2.0 → 53.3.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.
Files changed (71) hide show
  1. package/dist/chunks/{add-C7TQF4LB.js → add-PGPQCMJK.js} +9 -9
  2. package/dist/chunks/{chunk-HQU26P3O.js → chunk-25WI74GM.js} +7 -7
  3. package/dist/chunks/{chunk-TPBMA2WF.js → chunk-2TNGZL25.js} +2 -2
  4. package/dist/chunks/{chunk-FFKXMQXF.js → chunk-3GJFG6GX.js} +4 -4
  5. package/dist/chunks/{chunk-4Q5VS23S.js → chunk-3NSIZGHP.js} +3 -3
  6. package/dist/chunks/{chunk-3GBASY24.js → chunk-3YDXZRSZ.js} +2 -2
  7. package/dist/chunks/{chunk-QT4W4DLL.js → chunk-4L73BR7G.js} +11 -12
  8. package/dist/chunks/{chunk-HMM7V4AU.js → chunk-4LDQIDKG.js} +2 -2
  9. package/dist/chunks/{chunk-4Z7KJQGN.js → chunk-4OEA5ILS.js} +0 -1
  10. package/dist/chunks/{chunk-7FQIXP2G.js → chunk-4VJ3GTBX.js} +1 -1
  11. package/dist/chunks/{chunk-4M7OEHTY.js → chunk-7EJTBI6M.js} +11 -11
  12. package/dist/chunks/{chunk-YEGTCAP6.js → chunk-7Z5XFBB4.js} +140 -86
  13. package/dist/chunks/{chunk-6N4RFT24.js → chunk-AAPG3P4D.js} +9 -11
  14. package/dist/chunks/{chunk-RJWHOSUL.js → chunk-AORK3I3E.js} +1 -1
  15. package/dist/chunks/{chunk-IABMY4Q3.js → chunk-AXQNAI65.js} +1 -1
  16. package/dist/chunks/{chunk-XZ7CVBQ4.js → chunk-EBEBY45K.js} +11 -1
  17. package/dist/chunks/{chunk-LN5ZMLBU.js → chunk-GCKUEAUE.js} +2 -2
  18. package/dist/chunks/{chunk-JNOMOD7R.js → chunk-GQLARSTH.js} +1 -1
  19. package/dist/chunks/{chunk-AMXEAJTC.js → chunk-H57DZL5B.js} +3 -3
  20. package/dist/chunks/{chunk-NCUOSZ6X.js → chunk-HAJ2XRTQ.js} +2 -2
  21. package/dist/chunks/{chunk-2STWVKG7.js → chunk-HJVSVCAZ.js} +28 -13
  22. package/dist/chunks/{chunk-3LRN4Q7G.js → chunk-IS56OO2J.js} +3 -3
  23. package/dist/chunks/{chunk-AB7YF6KM.js → chunk-JJ36CB7A.js} +719 -923
  24. package/dist/chunks/{chunk-P3H4MP5H.js → chunk-JZLADLMF.js} +2 -2
  25. package/dist/chunks/{chunk-ABDTA3V2.js → chunk-KSIISCB2.js} +1 -1
  26. package/dist/chunks/{chunk-VS4O4MKY.js → chunk-MUBKPS2Z.js} +1 -1
  27. package/dist/chunks/{chunk-DFUTSURK.js → chunk-NF7HK5MP.js} +2 -2
  28. package/dist/chunks/{chunk-77JGNI4Z.js → chunk-NIOGCTVR.js} +2 -2
  29. package/dist/chunks/{chunk-5EDL2IVB.js → chunk-ONYQGA2O.js} +2 -2
  30. package/dist/chunks/{chunk-FLZW555J.js → chunk-PR72OE3G.js} +2 -2
  31. package/dist/chunks/{chunk-IEKDY4FP.js → chunk-QGLS47RE.js} +1 -1
  32. package/dist/chunks/{chunk-MAPNH6ND.js → chunk-QV34LTI7.js} +403 -101
  33. package/dist/chunks/{chunk-2TJ5Y674.js → chunk-RI23R2QO.js} +4 -4
  34. package/dist/chunks/{chunk-MZVW2VM7.js → chunk-RYUPBGRO.js} +34 -45
  35. package/dist/chunks/{chunk-4DLW7XLJ.js → chunk-SOSCFYOT.js} +2 -2
  36. package/dist/chunks/{chunk-X6H25N2H.js → chunk-TR6DYQV6.js} +1 -1
  37. package/dist/chunks/{chunk-JCLLQ23G.js → chunk-WOWCXMTU.js} +1 -1
  38. package/dist/chunks/{chunk-MSJX3VKI.js → chunk-X7KU44KR.js} +1 -1
  39. package/dist/chunks/{chunk-FK7LDWAI.js → chunk-XYYGNWMQ.js} +4 -4
  40. package/dist/chunks/{compile-vercel-config-QKQSM6VM.js → compile-vercel-config-H4BUE5BZ.js} +5 -5
  41. package/dist/chunks/{delete-LUW77HWU.js → delete-HVWVDBQF.js} +7 -7
  42. package/dist/chunks/{disable-ITW6P3R3.js → disable-CMBQPZ7L.js} +7 -7
  43. package/dist/chunks/{discard-GDFQ4V4V.js → discard-ZDNWUYLY.js} +7 -7
  44. package/dist/chunks/{edit-ZN7PQWZH.js → edit-YJYM3EKS.js} +9 -9
  45. package/dist/chunks/{enable-VTJNEZ5Q.js → enable-ITE7U5C4.js} +7 -7
  46. package/dist/chunks/{export-54A2LINR.js → export-VVN33IBK.js} +7 -7
  47. package/dist/chunks/{inspect-UMXWXZMZ.js → inspect-I7ILS3E2.js} +9 -9
  48. package/dist/chunks/{list-OJCLL4JA.js → list-6PZO3UIZ.js} +7 -7
  49. package/dist/chunks/{list-JZMV62KB.js → list-BWIEHOTA.js} +10 -10
  50. package/dist/chunks/{ls-B677IDAB.js → ls-LZZFID76.js} +9 -9
  51. package/dist/chunks/{publish-SI4H6WPL.js → publish-NULVZ7RB.js} +7 -7
  52. package/dist/chunks/{query-2CL2LAOA.js → query-BGI3AVJA.js} +9 -9
  53. package/dist/chunks/{reorder-E6R3ZL6W.js → reorder-G66QSKTR.js} +7 -7
  54. package/dist/chunks/{restore-ZVC2USSZ.js → restore-LHDVXFOH.js} +7 -7
  55. package/dist/chunks/{rm-F3ESGYZE.js → rm-DTAOTWXD.js} +9 -9
  56. package/dist/chunks/{routes-KDWN24QA.js → routes-2YVMQEPC.js} +2 -2
  57. package/dist/chunks/{rule-inspect-AWORVTNG.js → rule-inspect-AOITFBTB.js} +9 -9
  58. package/dist/chunks/{rules-KSDPKR6Z.js → rules-IW3XGCNA.js} +8 -8
  59. package/dist/chunks/{schema-UGF5QQ3K.js → schema-2VCQ2MAA.js} +10 -10
  60. package/dist/chunks/{types-FAFL42RV.js → types-7VDI75PV.js} +4 -4
  61. package/dist/chunks/{update-GXZVHW4O.js → update-L3DZ5STE.js} +9 -9
  62. package/dist/commands/build/index.js +21 -26
  63. package/dist/commands/deploy/index.js +64 -33
  64. package/dist/commands/dev/index.js +15 -15
  65. package/dist/commands/env/index.js +19 -19
  66. package/dist/commands/link/index.js +20 -20
  67. package/dist/commands/list/index.js +11 -11
  68. package/dist/commands-bulk.js +378 -210
  69. package/dist/index.js +298 -48
  70. package/dist/version.mjs +1 -1
  71. package/package.json +21 -19
@@ -6,10 +6,10 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __dirname_(__filename);
7
7
  import {
8
8
  getLocalPathConfig
9
- } from "./chunk-QT4W4DLL.js";
9
+ } from "./chunk-4L73BR7G.js";
10
10
  import {
11
11
  table
12
- } from "./chunk-ABDTA3V2.js";
12
+ } from "./chunk-KSIISCB2.js";
13
13
  import {
14
14
  VERCEL_DIR_PROJECT,
15
15
  VERCEL_DIR_README,
@@ -17,6 +17,9 @@ import {
17
17
  compileVercelConfig,
18
18
  createProject,
19
19
  detectProjects,
20
+ fetchProjectsForRepoUrl,
21
+ findProjectsFromPath,
22
+ findRepoRoot,
20
23
  findSourceVercelConfigFile,
21
24
  getLinkedProject,
22
25
  getProjectByNameOrId,
@@ -26,25 +29,28 @@ import {
26
29
  humanizePath,
27
30
  isDirectory,
28
31
  linkFolderToProject,
32
+ linkRepoProject,
29
33
  parseGitConfig,
30
34
  pluckRemoteUrls,
35
+ pull,
31
36
  readJSONFile,
32
37
  require_dist3 as require_dist,
33
38
  require_frameworks,
34
39
  require_lib,
35
40
  require_slugify,
41
+ resolveGitRemote,
36
42
  selectAndParseRemoteUrl,
37
43
  selectOrg,
38
44
  writeServicesConfig
39
- } from "./chunk-AB7YF6KM.js";
45
+ } from "./chunk-JJ36CB7A.js";
40
46
  import {
41
47
  printError
42
- } from "./chunk-JNOMOD7R.js";
48
+ } from "./chunk-GQLARSTH.js";
43
49
  import {
44
50
  CantParseJSONFile,
45
51
  ProjectNotFound,
46
52
  isAPIError
47
- } from "./chunk-XZ7CVBQ4.js";
53
+ } from "./chunk-EBEBY45K.js";
48
54
  import {
49
55
  output_manager_default
50
56
  } from "./chunk-ZQKJVHXY.js";
@@ -700,12 +706,22 @@ async function promptForInferredServicesSetup({
700
706
 
701
707
  // src/util/projects/search-project-across-teams.ts
702
708
  var import_slugify2 = __toESM(require_slugify(), 1);
703
- async function searchProjectAcrossTeams(client, projectName) {
704
- const teams = await getTeams(client);
709
+ import { relative as relative2 } from "path";
710
+ async function searchProjectAcrossTeams(client, projectName, cwd, {
711
+ autoConfirm = false,
712
+ nonInteractive = false,
713
+ teams,
714
+ skipLimited,
715
+ gitProjectName
716
+ } = {}) {
717
+ const teamsToSearch = teams ?? await getTeams(client);
718
+ const shouldSkipLimited = skipLimited ?? true;
705
719
  const accessibleTeams = [];
720
+ const skippedTeams = [];
706
721
  const skippedSlugs = [];
707
- for (const t of teams) {
708
- if (t.limited) {
722
+ for (const t of teamsToSearch) {
723
+ if (shouldSkipLimited && t.limited) {
724
+ skippedTeams.push(t);
709
725
  skippedSlugs.push(t.slug);
710
726
  } else {
711
727
  accessibleTeams.push(t);
@@ -716,24 +732,37 @@ async function searchProjectAcrossTeams(client, projectName) {
716
732
  `Skipping limited teams during cross-team project search: ${skippedSlugs.join(", ")}`
717
733
  );
718
734
  }
735
+ const searchedTeamSlugs = accessibleTeams.map((team) => team.slug);
719
736
  const orgs = accessibleTeams.map((t) => ({
720
737
  type: "team",
721
738
  id: t.id,
722
739
  slug: t.slug
723
740
  }));
741
+ const repoMatchesPromise = searchProjectsByRepoRoot({
742
+ client,
743
+ cwd,
744
+ gitProjectName,
745
+ orgs,
746
+ autoConfirm,
747
+ nonInteractive
748
+ });
724
749
  const slugifiedName = (0, import_slugify2.default)(projectName);
725
750
  const searchNames = [projectName];
726
751
  if (slugifiedName !== projectName) {
727
752
  searchNames.push(slugifiedName);
728
753
  }
729
- const searchPromises = orgs.flatMap(
754
+ const folderNameSearchPromises = orgs.flatMap(
730
755
  (org) => searchNames.map(
731
756
  (name) => getProjectByNameOrId(client, name, org.id).then(
732
- (result) => result instanceof ProjectNotFound ? null : { project: result, org }
757
+ (result) => result instanceof ProjectNotFound ? null : { project: result, org, reason: "folder-name" }
733
758
  ).catch(() => null)
734
759
  )
735
760
  );
736
- const results = await Promise.all(searchPromises);
761
+ const [repoMatches, folderNameMatches] = await Promise.all([
762
+ repoMatchesPromise,
763
+ Promise.all(folderNameSearchPromises)
764
+ ]);
765
+ const results = [...repoMatches, ...folderNameMatches];
737
766
  const seen = /* @__PURE__ */ new Set();
738
767
  const matches = [];
739
768
  for (const r of results) {
@@ -742,23 +771,320 @@ async function searchProjectAcrossTeams(client, projectName) {
742
771
  matches.push(r);
743
772
  }
744
773
  }
745
- return matches;
774
+ return {
775
+ matches,
776
+ searchedTeamSlugs,
777
+ skippedLimitedTeamSlugs: skippedSlugs,
778
+ skippedLimitedTeams: skippedTeams
779
+ };
780
+ }
781
+ async function searchProjectsByRepoRoot({
782
+ client,
783
+ cwd,
784
+ gitProjectName,
785
+ orgs,
786
+ autoConfirm,
787
+ nonInteractive
788
+ }) {
789
+ const rootPath = await findRepoRoot(cwd);
790
+ if (!rootPath) {
791
+ return [];
792
+ }
793
+ let remote;
794
+ try {
795
+ remote = await resolveGitRemote(client, rootPath, {
796
+ yes: autoConfirm || nonInteractive
797
+ });
798
+ } catch (error) {
799
+ output_manager_default.debug(
800
+ `Failed to resolve Git remote for cross-team search: ${error}`
801
+ );
802
+ return [];
803
+ }
804
+ if (!remote) {
805
+ return [];
806
+ }
807
+ const relativePath = relative2(rootPath, cwd);
808
+ const results = await Promise.all(
809
+ orgs.map(async (org) => {
810
+ try {
811
+ const projects = await fetchProjectsForRepoUrl(
812
+ client,
813
+ remote.repoUrl,
814
+ org.id
815
+ );
816
+ const repoProjectConfigs = projects.filter(
817
+ (project) => !gitProjectName || project.id === gitProjectName || project.name === gitProjectName
818
+ ).map((project) => ({
819
+ id: project.id,
820
+ name: project.name,
821
+ directory: project.rootDirectory || ".",
822
+ orgId: org.id
823
+ }));
824
+ const matchingProjects = findProjectsFromPath(
825
+ repoProjectConfigs,
826
+ relativePath
827
+ );
828
+ return matchingProjects.map((match) => {
829
+ const project = projects.find((p) => p.id === match.id);
830
+ if (!project) {
831
+ return null;
832
+ }
833
+ return {
834
+ project,
835
+ org,
836
+ reason: "repo-root",
837
+ repo: {
838
+ ...remote,
839
+ directory: match.directory
840
+ }
841
+ };
842
+ }).filter(Boolean);
843
+ } catch (error) {
844
+ output_manager_default.debug(
845
+ `Failed to search Git-linked projects under ${org.slug}: ${error}`
846
+ );
847
+ return [];
848
+ }
849
+ })
850
+ );
851
+ return results.flat();
746
852
  }
747
853
 
748
854
  // src/util/link/setup-and-link.ts
855
+ function formatMatchReason(match) {
856
+ if (match.reason === "repo-root") {
857
+ return import_chalk6.default.gray("(linked by git)");
858
+ }
859
+ return import_chalk6.default.gray("(folder name)");
860
+ }
861
+ function formatCrossTeamMatch(match) {
862
+ return `${import_chalk6.default.blue(match.org.slug)}/${match.project.name} ${formatMatchReason(
863
+ match
864
+ )}`;
865
+ }
866
+ function formatTeamList(slugs) {
867
+ const shown = slugs.slice(0, 5);
868
+ const suffix = slugs.length > shown.length ? `, and ${slugs.length - shown.length} more` : "";
869
+ return `${shown.join(", ")}${suffix}`;
870
+ }
871
+ function printCrossTeamSearchScope({
872
+ searchedTeamSlugs,
873
+ skippedLimitedTeamSlugs
874
+ }) {
875
+ if (searchedTeamSlugs.length > 0) {
876
+ output_manager_default.log(`Searched teams: ${formatTeamList(searchedTeamSlugs)}`);
877
+ }
878
+ if (skippedLimitedTeamSlugs.length > 0) {
879
+ output_manager_default.log(
880
+ `Skipped ${skippedLimitedTeamSlugs.length} SSO-protected ${skippedLimitedTeamSlugs.length === 1 ? "team" : "teams"}`
881
+ );
882
+ }
883
+ }
884
+ async function maybePullEnvAfterLink(client, path2, autoConfirm, pullEnv) {
885
+ if (!pullEnv || !client.stdin.isTTY || client.nonInteractive) {
886
+ return;
887
+ }
888
+ const pullEnvConfirmed = autoConfirm || await client.input.confirm(
889
+ "Would you like to pull environment variables now?",
890
+ true
891
+ );
892
+ if (!pullEnvConfirmed) {
893
+ return;
894
+ }
895
+ const originalCwd = client.cwd;
896
+ try {
897
+ client.cwd = path2;
898
+ const args = autoConfirm ? ["--yes"] : [];
899
+ const exitCode = await pull(client, args, "vercel-cli:link");
900
+ if (exitCode !== 0) {
901
+ output_manager_default.error(
902
+ "Failed to pull environment variables. You can run `vc env pull` manually."
903
+ );
904
+ }
905
+ } catch (_error) {
906
+ output_manager_default.error(
907
+ "Failed to pull environment variables. You can run `vc env pull` manually."
908
+ );
909
+ } finally {
910
+ client.cwd = originalCwd;
911
+ }
912
+ }
913
+ async function linkCrossTeamMatch({
914
+ client,
915
+ path: path2,
916
+ match,
917
+ successEmoji,
918
+ autoConfirm,
919
+ pullEnv
920
+ }) {
921
+ client.config.currentTeam = match.org.type === "team" ? match.org.id : void 0;
922
+ if (match.reason === "repo-root" && match.repo) {
923
+ await linkRepoProject(client, path2, {
924
+ project: match.project,
925
+ orgId: match.org.id,
926
+ orgSlug: match.org.slug,
927
+ remoteName: match.repo.remoteName,
928
+ successEmoji
929
+ });
930
+ await maybePullEnvAfterLink(client, path2, autoConfirm, pullEnv);
931
+ return {
932
+ status: "linked",
933
+ org: match.org,
934
+ project: match.project,
935
+ repoRoot: match.repo.rootPath
936
+ };
937
+ }
938
+ await linkFolderToProject(
939
+ client,
940
+ path2,
941
+ { projectId: match.project.id, orgId: match.org.id },
942
+ match.project.name,
943
+ match.org.slug,
944
+ successEmoji,
945
+ autoConfirm,
946
+ pullEnv
947
+ );
948
+ return { status: "linked", org: match.org, project: match.project };
949
+ }
950
+ async function promptForLimitedTeams(client, teams) {
951
+ if (teams.length === 0) {
952
+ return [];
953
+ }
954
+ return await client.input.checkbox({
955
+ message: "Which SSO-protected teams should be searched?",
956
+ choices: teams.map((team) => ({
957
+ name: team.name ? `${team.name} (${team.slug})` : team.slug,
958
+ value: team
959
+ }))
960
+ });
961
+ }
962
+ async function searchSelectedLimitedTeams({
963
+ client,
964
+ path: path2,
965
+ projectName,
966
+ gitProjectName,
967
+ teams
968
+ }) {
969
+ const selectedTeams = await promptForLimitedTeams(client, teams);
970
+ if (selectedTeams.length === 0) {
971
+ return [];
972
+ }
973
+ output_manager_default.spinner("Searching selected SSO-protected teams\u2026", 1e3);
974
+ try {
975
+ const result = await searchProjectAcrossTeams(client, projectName, path2, {
976
+ teams: selectedTeams,
977
+ skipLimited: false,
978
+ gitProjectName
979
+ });
980
+ printCrossTeamSearchScope({
981
+ searchedTeamSlugs: result.searchedTeamSlugs,
982
+ skippedLimitedTeamSlugs: []
983
+ });
984
+ return result.matches;
985
+ } catch (err) {
986
+ output_manager_default.debug(`Selected SSO-protected team search failed: ${err}`);
987
+ return [];
988
+ } finally {
989
+ output_manager_default.stopSpinner();
990
+ }
991
+ }
992
+ async function linkCrossTeamMatches({
993
+ client,
994
+ path: path2,
995
+ matches,
996
+ successEmoji,
997
+ autoConfirm,
998
+ nonInteractive,
999
+ pullEnv
1000
+ }) {
1001
+ if (matches.length === 0) {
1002
+ return null;
1003
+ }
1004
+ if (matches.length === 1) {
1005
+ const match = matches[0];
1006
+ if (autoConfirm || nonInteractive) {
1007
+ return await linkCrossTeamMatch({
1008
+ client,
1009
+ path: path2,
1010
+ match,
1011
+ successEmoji,
1012
+ autoConfirm,
1013
+ pullEnv
1014
+ });
1015
+ }
1016
+ const confirmed = await client.input.confirm(
1017
+ `Found project ${formatCrossTeamMatch(match)}. Link to it?`,
1018
+ true
1019
+ );
1020
+ if (confirmed) {
1021
+ return await linkCrossTeamMatch({
1022
+ client,
1023
+ path: path2,
1024
+ match,
1025
+ successEmoji,
1026
+ autoConfirm,
1027
+ pullEnv
1028
+ });
1029
+ }
1030
+ return null;
1031
+ }
1032
+ const currentTeamMatch = matches.find(
1033
+ (match) => match.org.id === client.config.currentTeam
1034
+ );
1035
+ if (autoConfirm && currentTeamMatch) {
1036
+ return await linkCrossTeamMatch({
1037
+ client,
1038
+ path: path2,
1039
+ match: currentTeamMatch,
1040
+ successEmoji,
1041
+ autoConfirm,
1042
+ pullEnv
1043
+ });
1044
+ }
1045
+ if (nonInteractive) {
1046
+ return null;
1047
+ }
1048
+ const choices = matches.map((match) => ({
1049
+ name: formatCrossTeamMatch(match),
1050
+ value: match
1051
+ }));
1052
+ choices.push({
1053
+ name: "Not one of these projects",
1054
+ value: null
1055
+ });
1056
+ const selected = await client.input.select({
1057
+ message: "Found matching projects across teams. Which one do you want to link?",
1058
+ choices,
1059
+ default: currentTeamMatch ?? void 0
1060
+ });
1061
+ if (!selected) {
1062
+ return null;
1063
+ }
1064
+ return await linkCrossTeamMatch({
1065
+ client,
1066
+ path: path2,
1067
+ match: selected,
1068
+ successEmoji,
1069
+ autoConfirm,
1070
+ pullEnv
1071
+ });
1072
+ }
749
1073
  async function setupAndLink(client, path2, {
750
1074
  autoConfirm = false,
751
1075
  forceDelete = false,
752
1076
  link,
753
1077
  successEmoji = "link",
754
1078
  setupMsg = "Set up",
755
- projectName = basename(path2),
1079
+ projectName,
756
1080
  nonInteractive = false,
757
1081
  pullEnv = true,
758
1082
  v0,
759
1083
  searchAcrossTeams = false
760
1084
  }) {
761
1085
  const { config } = client;
1086
+ const gitProjectName = projectName;
1087
+ projectName = projectName ?? basename(path2);
762
1088
  if (!isDirectory(path2)) {
763
1089
  output_manager_default.error(`Expected directory but found file: ${path2}`);
764
1090
  return { status: "error", exitCode: 1, reason: "PATH_IS_FILE" };
@@ -793,105 +1119,81 @@ async function setupAndLink(client, path2, {
793
1119
  let skipAutoDetect = false;
794
1120
  if (searchAcrossTeams) {
795
1121
  let crossTeamMatches = [];
1122
+ let searchedTeamSlugs = [];
1123
+ let skippedLimitedTeamSlugs = [];
1124
+ let skippedLimitedTeams = [];
796
1125
  output_manager_default.spinner("Searching for existing projects\u2026", 1e3);
797
1126
  try {
798
- crossTeamMatches = await searchProjectAcrossTeams(client, projectName);
1127
+ const searchResult = await searchProjectAcrossTeams(
1128
+ client,
1129
+ projectName,
1130
+ path2,
1131
+ {
1132
+ autoConfirm,
1133
+ nonInteractive,
1134
+ gitProjectName
1135
+ }
1136
+ );
1137
+ crossTeamMatches = searchResult.matches;
1138
+ searchedTeamSlugs = searchResult.searchedTeamSlugs;
1139
+ skippedLimitedTeamSlugs = searchResult.skippedLimitedTeamSlugs;
1140
+ skippedLimitedTeams = searchResult.skippedLimitedTeams;
799
1141
  } catch (err) {
800
1142
  output_manager_default.debug(`Cross-team search failed: ${err}`);
801
1143
  } finally {
802
1144
  output_manager_default.stopSpinner();
803
1145
  }
804
- if (crossTeamMatches.length === 1) {
805
- const match = crossTeamMatches[0];
806
- if (autoConfirm || nonInteractive) {
807
- config.currentTeam = match.org.type === "team" ? match.org.id : void 0;
808
- await linkFolderToProject(
809
- client,
810
- path2,
811
- { projectId: match.project.id, orgId: match.org.id },
812
- match.project.name,
813
- match.org.slug,
814
- successEmoji,
815
- autoConfirm,
816
- pullEnv
1146
+ if (crossTeamMatches.length > 0 && !autoConfirm && !nonInteractive) {
1147
+ printCrossTeamSearchScope({
1148
+ searchedTeamSlugs,
1149
+ skippedLimitedTeamSlugs
1150
+ });
1151
+ }
1152
+ const linkedMatch = await linkCrossTeamMatches({
1153
+ client,
1154
+ path: path2,
1155
+ matches: crossTeamMatches,
1156
+ successEmoji,
1157
+ autoConfirm,
1158
+ nonInteractive,
1159
+ pullEnv
1160
+ });
1161
+ if (linkedMatch) {
1162
+ return linkedMatch;
1163
+ }
1164
+ if (!autoConfirm && !nonInteractive && skippedLimitedTeams.length > 0) {
1165
+ if (crossTeamMatches.length === 0) {
1166
+ output_manager_default.log(
1167
+ `No matching projects found in the ${searchedTeamSlugs.length} ${searchedTeamSlugs.length === 1 ? "team" : "teams"} available in your current session.`
817
1168
  );
818
- return { status: "linked", org: match.org, project: match.project };
819
1169
  }
820
- const confirmed = await client.input.confirm(
821
- `Found project ${import_chalk6.default.blue(match.org.slug)}/${match.project.name}. Link to it?`,
822
- true
823
- );
824
- if (confirmed) {
825
- config.currentTeam = match.org.type === "team" ? match.org.id : void 0;
826
- await linkFolderToProject(
827
- client,
828
- path2,
829
- { projectId: match.project.id, orgId: match.org.id },
830
- match.project.name,
831
- match.org.slug,
832
- successEmoji,
833
- autoConfirm,
834
- pullEnv
835
- );
836
- return { status: "linked", org: match.org, project: match.project };
1170
+ const limitedTeamMatches = await searchSelectedLimitedTeams({
1171
+ client,
1172
+ path: path2,
1173
+ projectName,
1174
+ gitProjectName,
1175
+ teams: skippedLimitedTeams
1176
+ });
1177
+ const linkedLimitedMatch = await linkCrossTeamMatches({
1178
+ client,
1179
+ path: path2,
1180
+ matches: limitedTeamMatches,
1181
+ successEmoji,
1182
+ autoConfirm,
1183
+ nonInteractive,
1184
+ pullEnv
1185
+ });
1186
+ if (linkedLimitedMatch) {
1187
+ return linkedLimitedMatch;
837
1188
  }
838
- skipAutoDetect = true;
839
- } else if (crossTeamMatches.length > 1) {
840
- const currentTeamMatch = autoConfirm ? crossTeamMatches.find((m) => m.org.id === config.currentTeam) : void 0;
841
- if (currentTeamMatch) {
842
- config.currentTeam = currentTeamMatch.org.type === "team" ? currentTeamMatch.org.id : void 0;
843
- await linkFolderToProject(
844
- client,
845
- path2,
846
- {
847
- projectId: currentTeamMatch.project.id,
848
- orgId: currentTeamMatch.org.id
849
- },
850
- currentTeamMatch.project.name,
851
- currentTeamMatch.org.slug,
852
- successEmoji,
853
- autoConfirm,
854
- pullEnv
1189
+ if (limitedTeamMatches.length === 0) {
1190
+ output_manager_default.log(
1191
+ "No matching projects found in the selected SSO-protected teams."
855
1192
  );
856
- return {
857
- status: "linked",
858
- org: currentTeamMatch.org,
859
- project: currentTeamMatch.project
860
- };
861
- }
862
- if (!nonInteractive) {
863
- const choices = crossTeamMatches.map((m) => ({
864
- name: `${import_chalk6.default.blue(m.org.slug)}/${m.project.name}`,
865
- value: m
866
- }));
867
- choices.push({
868
- name: "Don't link to an existing project",
869
- value: null
870
- });
871
- const selected = await client.input.select({
872
- message: "Found matching projects across teams. Which one do you want to link?",
873
- choices
874
- });
875
- if (selected) {
876
- config.currentTeam = selected.org.type === "team" ? selected.org.id : void 0;
877
- await linkFolderToProject(
878
- client,
879
- path2,
880
- { projectId: selected.project.id, orgId: selected.org.id },
881
- selected.project.name,
882
- selected.org.slug,
883
- successEmoji,
884
- autoConfirm,
885
- pullEnv
886
- );
887
- return {
888
- status: "linked",
889
- org: selected.org,
890
- project: selected.project
891
- };
892
- }
893
- skipAutoDetect = true;
894
1193
  }
1194
+ skipAutoDetect = skipAutoDetect || crossTeamMatches.length > 0 || limitedTeamMatches.length > 0;
1195
+ } else if (crossTeamMatches.length > 0) {
1196
+ skipAutoDetect = true;
895
1197
  }
896
1198
  }
897
1199
  try {
@@ -9,22 +9,22 @@ import {
9
9
  } from "./chunk-HTOH3MSD.js";
10
10
  import {
11
11
  getScope
12
- } from "./chunk-FLZW555J.js";
12
+ } from "./chunk-PR72OE3G.js";
13
13
  import {
14
14
  AGENT_REASON
15
15
  } from "./chunk-E3NE4SKN.js";
16
16
  import {
17
17
  getLinkedProject,
18
18
  getProjectByNameOrId
19
- } from "./chunk-AB7YF6KM.js";
19
+ } from "./chunk-JJ36CB7A.js";
20
20
  import {
21
21
  buildCommandWithGlobalFlags,
22
22
  outputAgentError
23
- } from "./chunk-IABMY4Q3.js";
23
+ } from "./chunk-AXQNAI65.js";
24
24
  import {
25
25
  ProjectNotFound,
26
26
  isAPIError
27
- } from "./chunk-XZ7CVBQ4.js";
27
+ } from "./chunk-EBEBY45K.js";
28
28
 
29
29
  // src/commands/alerts/resolve-alerts-scope.ts
30
30
  function emitAlertsScopeError(client, jsonOutput, code, message, agent) {