@h-rig/cli 0.0.6-alpha.16 → 0.0.6-alpha.18

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/bin/rig.js CHANGED
@@ -4529,6 +4529,7 @@ function countDoctorFailures(checks) {
4529
4529
 
4530
4530
  // packages/cli/src/commands/init.ts
4531
4531
  var RIG_CONFIG_PACKAGE_DIST_TAG = "latest";
4532
+ var DEFAULT_REMOTE_RIG_URL = "https://where.rig-does.work";
4532
4533
  var RIG_CONFIG_DEV_DEPENDENCIES = {
4533
4534
  "@rig/core": `npm:@h-rig/core@${RIG_CONFIG_PACKAGE_DIST_TAG}`,
4534
4535
  "@rig/standard-plugin": `npm:@h-rig/standard-plugin@${RIG_CONFIG_PACKAGE_DIST_TAG}`
@@ -4633,6 +4634,19 @@ function readGhAuthToken() {
4633
4634
  }
4634
4635
  return result.stdout.trim();
4635
4636
  }
4637
+ function refreshGhProjectScopesAndReadToken() {
4638
+ const result = spawnSync("gh", ["auth", "refresh", "--scopes", "read:project"], {
4639
+ encoding: "utf8",
4640
+ stdio: ["inherit", "pipe", "pipe"]
4641
+ });
4642
+ if (result.status !== 0)
4643
+ return null;
4644
+ try {
4645
+ return readGhAuthToken();
4646
+ } catch {
4647
+ return null;
4648
+ }
4649
+ }
4636
4650
  async function loadClackPrompts() {
4637
4651
  return await import("@clack/prompts");
4638
4652
  }
@@ -4728,12 +4742,27 @@ async function promptManualProjectStatusMapping(prompts) {
4728
4742
  }
4729
4743
  return statuses;
4730
4744
  }
4731
- async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken) {
4745
+ function projectScopeError(value) {
4746
+ const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
4747
+ return /INSUFFICIENT_SCOPES|read:project|required scopes/i.test(text2);
4748
+ }
4749
+ function optionName(option) {
4750
+ return String(option.name ?? option.label ?? option.id ?? "").trim();
4751
+ }
4752
+ function autoProjectStatusValue(options, key, label) {
4753
+ const candidates = [DEFAULT_PROJECT_STATUS_OPTIONS[key], label].filter((value) => Boolean(value)).map((value) => value.trim().toLowerCase());
4754
+ const match = options.find((option) => candidates.includes(optionName(option).toLowerCase()));
4755
+ if (!match)
4756
+ return null;
4757
+ return String(match.id ?? match.name);
4758
+ }
4759
+ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, refreshProjectToken) {
4732
4760
  const projectChoice = await promptSelect(prompts, {
4733
4761
  message: "GitHub Projects status sync",
4762
+ initialValue: "select",
4734
4763
  options: [
4735
- { value: "off", label: "Off" },
4736
4764
  { value: "select", label: "Select accessible ProjectV2" },
4765
+ { value: "off", label: "Off" },
4737
4766
  { value: "manual", label: "Enter ProjectV2 ids manually" }
4738
4767
  ]
4739
4768
  });
@@ -4749,16 +4778,22 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4749
4778
  const owner = repoOwnerFromSlug(repoSlug);
4750
4779
  if (!owner)
4751
4780
  throw new CliError2(`Cannot derive GitHub owner from repo slug ${repoSlug}.`, 1);
4752
- const projectsPayload = await listGitHubProjectsForInit(context, owner, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4753
- const projects = recordArray(projectsPayload, "projects");
4781
+ let activeToken = githubToken?.trim() || null;
4782
+ let projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4783
+ let projects = recordArray(projectsPayload, "projects");
4784
+ if (projects.length === 0 && projectScopeError(projectsPayload.error) && refreshProjectToken) {
4785
+ prompts.outro?.("GitHub token is missing read:project; refreshing gh auth scopes and retrying Projects.");
4786
+ const refreshedToken = refreshProjectToken();
4787
+ if (refreshedToken) {
4788
+ activeToken = refreshedToken;
4789
+ projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4790
+ projects = recordArray(projectsPayload, "projects");
4791
+ }
4792
+ }
4754
4793
  if (projects.length === 0) {
4755
- const error = typeof projectsPayload.error === "string" ? ` (${projectsPayload.error})` : "";
4756
- prompts.outro?.(`No accessible GitHub Projects were returned${error}; falling back to manual ProjectV2 ids.`);
4757
- return {
4758
- githubProject: await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }),
4759
- githubProjectStatusField: await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" }),
4760
- githubProjectStatuses: await promptManualProjectStatusMapping(prompts)
4761
- };
4794
+ const error = typeof projectsPayload.error === "string" ? ` (${String(projectsPayload.error).replace(/\s+/g, " ").slice(0, 240)})` : "";
4795
+ prompts.outro?.(`No accessible GitHub Projects were returned${error}; continuing with GitHub Projects status sync off.`);
4796
+ return { githubProject: "off", ...activeToken ? { githubToken: activeToken } : {} };
4762
4797
  }
4763
4798
  const selectedProjectId = await promptSelect(prompts, {
4764
4799
  message: "GitHub ProjectV2 project",
@@ -4772,23 +4807,34 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4772
4807
  ]
4773
4808
  });
4774
4809
  const projectId = selectedProjectId === "manual" ? await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }) : selectedProjectId;
4775
- const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4810
+ const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4776
4811
  const fieldPayloadRecord = fieldPayload && typeof fieldPayload === "object" && !Array.isArray(fieldPayload) ? fieldPayload : {};
4777
4812
  const rawField = fieldPayloadRecord.field;
4778
4813
  const field = rawField && typeof rawField === "object" && !Array.isArray(rawField) ? rawField : null;
4779
4814
  const fieldId = typeof field?.id === "string" && field.id.trim() ? field.id : await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" });
4780
4815
  const options = Array.isArray(field?.options) ? field.options.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
4781
4816
  if (options.length === 0) {
4782
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: await promptManualProjectStatusMapping(prompts) };
4817
+ return {
4818
+ githubProject: projectId,
4819
+ githubProjectStatusField: fieldId,
4820
+ githubProjectStatuses: await promptManualProjectStatusMapping(prompts),
4821
+ ...activeToken ? { githubToken: activeToken } : {}
4822
+ };
4783
4823
  }
4784
4824
  const statuses = {};
4785
4825
  for (const [key, label] of Object.entries(PROJECT_STATUS_PROMPTS)) {
4786
- statuses[key] = await promptSelect(prompts, {
4826
+ const auto = autoProjectStatusValue(options, key, label);
4827
+ statuses[key] = auto ?? await promptSelect(prompts, {
4787
4828
  message: `Project status option for ${label}`,
4788
- options: options.map((option) => ({ value: String(option.id ?? option.name), label: String(option.name ?? option.id) }))
4829
+ options: options.map((option) => ({ value: String(option.id ?? option.name), label: optionName(option) }))
4789
4830
  });
4790
4831
  }
4791
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined };
4832
+ return {
4833
+ githubProject: projectId,
4834
+ githubProjectStatusField: fieldId,
4835
+ githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined,
4836
+ ...activeToken ? { githubToken: activeToken } : {}
4837
+ };
4792
4838
  }
4793
4839
  function sleep2(ms) {
4794
4840
  return new Promise((resolve18) => setTimeout(resolve18, ms));
@@ -5119,12 +5165,13 @@ async function runInteractiveControlPlaneInit(context, prompts) {
5119
5165
  });
5120
5166
  const serverChoice = await promptSelect(prompts, {
5121
5167
  message: "Rig server",
5168
+ initialValue: "remote",
5122
5169
  options: [
5123
- { value: "local", label: "Local server", hint: "run on this machine" },
5124
- { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" }
5170
+ { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" },
5171
+ { value: "local", label: "Local server", hint: "run on this machine" }
5125
5172
  ]
5126
5173
  });
5127
- const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: "https://rig.example.com" }) : undefined;
5174
+ const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: DEFAULT_REMOTE_RIG_URL, initialValue: DEFAULT_REMOTE_RIG_URL }) : undefined;
5128
5175
  let remoteCheckout;
5129
5176
  if (serverChoice === "remote") {
5130
5177
  const checkout = await promptSelect(prompts, {
@@ -5156,31 +5203,35 @@ async function runInteractiveControlPlaneInit(context, prompts) {
5156
5203
  { value: "skip", label: "Skip for now" }
5157
5204
  ]
5158
5205
  });
5206
+ let remoteGhTokenConfirmed = false;
5159
5207
  if (serverChoice === "remote" && authMethod === "gh") {
5160
5208
  if (!prompts.confirm)
5161
5209
  throw new CliError2("Remote gh-token import requires explicit confirmation.", 1);
5162
5210
  const confirmed = await prompts.confirm({
5163
5211
  message: `This sends a GitHub token from this machine to ${remoteUrl}. Continue?`,
5164
- initialValue: false
5212
+ initialValue: true
5165
5213
  });
5166
5214
  if (prompts.isCancel(confirmed) || confirmed !== true) {
5167
5215
  throw new CliError2("Remote gh-token import cancelled.", 1);
5168
5216
  }
5217
+ remoteGhTokenConfirmed = true;
5169
5218
  }
5170
5219
  const githubToken = authMethod === "token" ? await promptRequiredText(prompts, { message: "GitHub token", placeholder: "ghp_..." }) : authMethod === "gh" ? readGhAuthToken() : undefined;
5171
- const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken);
5220
+ const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, authMethod === "gh" ? refreshGhProjectScopesAndReadToken : undefined);
5221
+ const effectiveGithubToken = projectConfig.githubToken ?? githubToken;
5172
5222
  const result = await runControlPlaneInit(context, {
5173
5223
  server: serverChoice,
5174
5224
  remoteUrl,
5175
5225
  repoSlug,
5176
- githubToken,
5226
+ githubToken: effectiveGithubToken,
5177
5227
  githubAuthMethod: authMethod,
5178
5228
  githubProject: projectConfig.githubProject,
5179
5229
  githubProjectStatusField: projectConfig.githubProjectStatusField,
5180
5230
  githubProjectStatuses: projectConfig.githubProjectStatuses,
5181
5231
  remoteCheckout,
5182
5232
  repair,
5183
- privateStateOnly
5233
+ privateStateOnly,
5234
+ yes: remoteGhTokenConfirmed || undefined
5184
5235
  });
5185
5236
  const details = result.details && typeof result.details === "object" && !Array.isArray(result.details) ? result.details : {};
5186
5237
  const deviceAuth = details.deviceAuth && typeof details.deviceAuth === "object" && !Array.isArray(details.deviceAuth) ? details.deviceAuth : null;
@@ -832,6 +832,7 @@ function countDoctorFailures(checks) {
832
832
 
833
833
  // packages/cli/src/commands/init.ts
834
834
  var RIG_CONFIG_PACKAGE_DIST_TAG = "latest";
835
+ var DEFAULT_REMOTE_RIG_URL = "https://where.rig-does.work";
835
836
  var RIG_CONFIG_DEV_DEPENDENCIES = {
836
837
  "@rig/core": `npm:@h-rig/core@${RIG_CONFIG_PACKAGE_DIST_TAG}`,
837
838
  "@rig/standard-plugin": `npm:@h-rig/standard-plugin@${RIG_CONFIG_PACKAGE_DIST_TAG}`
@@ -936,6 +937,19 @@ function readGhAuthToken() {
936
937
  }
937
938
  return result.stdout.trim();
938
939
  }
940
+ function refreshGhProjectScopesAndReadToken() {
941
+ const result = spawnSync("gh", ["auth", "refresh", "--scopes", "read:project"], {
942
+ encoding: "utf8",
943
+ stdio: ["inherit", "pipe", "pipe"]
944
+ });
945
+ if (result.status !== 0)
946
+ return null;
947
+ try {
948
+ return readGhAuthToken();
949
+ } catch {
950
+ return null;
951
+ }
952
+ }
939
953
  async function loadClackPrompts() {
940
954
  return await import("@clack/prompts");
941
955
  }
@@ -1031,12 +1045,27 @@ async function promptManualProjectStatusMapping(prompts) {
1031
1045
  }
1032
1046
  return statuses;
1033
1047
  }
1034
- async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken) {
1048
+ function projectScopeError(value) {
1049
+ const text = typeof value === "string" ? value : JSON.stringify(value ?? "");
1050
+ return /INSUFFICIENT_SCOPES|read:project|required scopes/i.test(text);
1051
+ }
1052
+ function optionName(option) {
1053
+ return String(option.name ?? option.label ?? option.id ?? "").trim();
1054
+ }
1055
+ function autoProjectStatusValue(options, key, label) {
1056
+ const candidates = [DEFAULT_PROJECT_STATUS_OPTIONS[key], label].filter((value) => Boolean(value)).map((value) => value.trim().toLowerCase());
1057
+ const match = options.find((option) => candidates.includes(optionName(option).toLowerCase()));
1058
+ if (!match)
1059
+ return null;
1060
+ return String(match.id ?? match.name);
1061
+ }
1062
+ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, refreshProjectToken) {
1035
1063
  const projectChoice = await promptSelect(prompts, {
1036
1064
  message: "GitHub Projects status sync",
1065
+ initialValue: "select",
1037
1066
  options: [
1038
- { value: "off", label: "Off" },
1039
1067
  { value: "select", label: "Select accessible ProjectV2" },
1068
+ { value: "off", label: "Off" },
1040
1069
  { value: "manual", label: "Enter ProjectV2 ids manually" }
1041
1070
  ]
1042
1071
  });
@@ -1052,16 +1081,22 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
1052
1081
  const owner = repoOwnerFromSlug(repoSlug);
1053
1082
  if (!owner)
1054
1083
  throw new CliError2(`Cannot derive GitHub owner from repo slug ${repoSlug}.`, 1);
1055
- const projectsPayload = await listGitHubProjectsForInit(context, owner, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
1056
- const projects = recordArray(projectsPayload, "projects");
1084
+ let activeToken = githubToken?.trim() || null;
1085
+ let projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
1086
+ let projects = recordArray(projectsPayload, "projects");
1087
+ if (projects.length === 0 && projectScopeError(projectsPayload.error) && refreshProjectToken) {
1088
+ prompts.outro?.("GitHub token is missing read:project; refreshing gh auth scopes and retrying Projects.");
1089
+ const refreshedToken = refreshProjectToken();
1090
+ if (refreshedToken) {
1091
+ activeToken = refreshedToken;
1092
+ projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
1093
+ projects = recordArray(projectsPayload, "projects");
1094
+ }
1095
+ }
1057
1096
  if (projects.length === 0) {
1058
- const error = typeof projectsPayload.error === "string" ? ` (${projectsPayload.error})` : "";
1059
- prompts.outro?.(`No accessible GitHub Projects were returned${error}; falling back to manual ProjectV2 ids.`);
1060
- return {
1061
- githubProject: await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }),
1062
- githubProjectStatusField: await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" }),
1063
- githubProjectStatuses: await promptManualProjectStatusMapping(prompts)
1064
- };
1097
+ const error = typeof projectsPayload.error === "string" ? ` (${String(projectsPayload.error).replace(/\s+/g, " ").slice(0, 240)})` : "";
1098
+ prompts.outro?.(`No accessible GitHub Projects were returned${error}; continuing with GitHub Projects status sync off.`);
1099
+ return { githubProject: "off", ...activeToken ? { githubToken: activeToken } : {} };
1065
1100
  }
1066
1101
  const selectedProjectId = await promptSelect(prompts, {
1067
1102
  message: "GitHub ProjectV2 project",
@@ -1075,23 +1110,34 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
1075
1110
  ]
1076
1111
  });
1077
1112
  const projectId = selectedProjectId === "manual" ? await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }) : selectedProjectId;
1078
- const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
1113
+ const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
1079
1114
  const fieldPayloadRecord = fieldPayload && typeof fieldPayload === "object" && !Array.isArray(fieldPayload) ? fieldPayload : {};
1080
1115
  const rawField = fieldPayloadRecord.field;
1081
1116
  const field = rawField && typeof rawField === "object" && !Array.isArray(rawField) ? rawField : null;
1082
1117
  const fieldId = typeof field?.id === "string" && field.id.trim() ? field.id : await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" });
1083
1118
  const options = Array.isArray(field?.options) ? field.options.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
1084
1119
  if (options.length === 0) {
1085
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: await promptManualProjectStatusMapping(prompts) };
1120
+ return {
1121
+ githubProject: projectId,
1122
+ githubProjectStatusField: fieldId,
1123
+ githubProjectStatuses: await promptManualProjectStatusMapping(prompts),
1124
+ ...activeToken ? { githubToken: activeToken } : {}
1125
+ };
1086
1126
  }
1087
1127
  const statuses = {};
1088
1128
  for (const [key, label] of Object.entries(PROJECT_STATUS_PROMPTS)) {
1089
- statuses[key] = await promptSelect(prompts, {
1129
+ const auto = autoProjectStatusValue(options, key, label);
1130
+ statuses[key] = auto ?? await promptSelect(prompts, {
1090
1131
  message: `Project status option for ${label}`,
1091
- options: options.map((option) => ({ value: String(option.id ?? option.name), label: String(option.name ?? option.id) }))
1132
+ options: options.map((option) => ({ value: String(option.id ?? option.name), label: optionName(option) }))
1092
1133
  });
1093
1134
  }
1094
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined };
1135
+ return {
1136
+ githubProject: projectId,
1137
+ githubProjectStatusField: fieldId,
1138
+ githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined,
1139
+ ...activeToken ? { githubToken: activeToken } : {}
1140
+ };
1095
1141
  }
1096
1142
  function sleep2(ms) {
1097
1143
  return new Promise((resolve7) => setTimeout(resolve7, ms));
@@ -1422,12 +1468,13 @@ async function runInteractiveControlPlaneInit(context, prompts) {
1422
1468
  });
1423
1469
  const serverChoice = await promptSelect(prompts, {
1424
1470
  message: "Rig server",
1471
+ initialValue: "remote",
1425
1472
  options: [
1426
- { value: "local", label: "Local server", hint: "run on this machine" },
1427
- { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" }
1473
+ { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" },
1474
+ { value: "local", label: "Local server", hint: "run on this machine" }
1428
1475
  ]
1429
1476
  });
1430
- const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: "https://rig.example.com" }) : undefined;
1477
+ const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: DEFAULT_REMOTE_RIG_URL, initialValue: DEFAULT_REMOTE_RIG_URL }) : undefined;
1431
1478
  let remoteCheckout;
1432
1479
  if (serverChoice === "remote") {
1433
1480
  const checkout = await promptSelect(prompts, {
@@ -1459,31 +1506,35 @@ async function runInteractiveControlPlaneInit(context, prompts) {
1459
1506
  { value: "skip", label: "Skip for now" }
1460
1507
  ]
1461
1508
  });
1509
+ let remoteGhTokenConfirmed = false;
1462
1510
  if (serverChoice === "remote" && authMethod === "gh") {
1463
1511
  if (!prompts.confirm)
1464
1512
  throw new CliError2("Remote gh-token import requires explicit confirmation.", 1);
1465
1513
  const confirmed = await prompts.confirm({
1466
1514
  message: `This sends a GitHub token from this machine to ${remoteUrl}. Continue?`,
1467
- initialValue: false
1515
+ initialValue: true
1468
1516
  });
1469
1517
  if (prompts.isCancel(confirmed) || confirmed !== true) {
1470
1518
  throw new CliError2("Remote gh-token import cancelled.", 1);
1471
1519
  }
1520
+ remoteGhTokenConfirmed = true;
1472
1521
  }
1473
1522
  const githubToken = authMethod === "token" ? await promptRequiredText(prompts, { message: "GitHub token", placeholder: "ghp_..." }) : authMethod === "gh" ? readGhAuthToken() : undefined;
1474
- const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken);
1523
+ const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, authMethod === "gh" ? refreshGhProjectScopesAndReadToken : undefined);
1524
+ const effectiveGithubToken = projectConfig.githubToken ?? githubToken;
1475
1525
  const result = await runControlPlaneInit(context, {
1476
1526
  server: serverChoice,
1477
1527
  remoteUrl,
1478
1528
  repoSlug,
1479
- githubToken,
1529
+ githubToken: effectiveGithubToken,
1480
1530
  githubAuthMethod: authMethod,
1481
1531
  githubProject: projectConfig.githubProject,
1482
1532
  githubProjectStatusField: projectConfig.githubProjectStatusField,
1483
1533
  githubProjectStatuses: projectConfig.githubProjectStatuses,
1484
1534
  remoteCheckout,
1485
1535
  repair,
1486
- privateStateOnly
1536
+ privateStateOnly,
1537
+ yes: remoteGhTokenConfirmed || undefined
1487
1538
  });
1488
1539
  const details = result.details && typeof result.details === "object" && !Array.isArray(result.details) ? result.details : {};
1489
1540
  const deviceAuth = details.deviceAuth && typeof details.deviceAuth === "object" && !Array.isArray(details.deviceAuth) ? details.deviceAuth : null;
@@ -4322,6 +4322,7 @@ function countDoctorFailures(checks) {
4322
4322
 
4323
4323
  // packages/cli/src/commands/init.ts
4324
4324
  var RIG_CONFIG_PACKAGE_DIST_TAG = "latest";
4325
+ var DEFAULT_REMOTE_RIG_URL = "https://where.rig-does.work";
4325
4326
  var RIG_CONFIG_DEV_DEPENDENCIES = {
4326
4327
  "@rig/core": `npm:@h-rig/core@${RIG_CONFIG_PACKAGE_DIST_TAG}`,
4327
4328
  "@rig/standard-plugin": `npm:@h-rig/standard-plugin@${RIG_CONFIG_PACKAGE_DIST_TAG}`
@@ -4426,6 +4427,19 @@ function readGhAuthToken() {
4426
4427
  }
4427
4428
  return result.stdout.trim();
4428
4429
  }
4430
+ function refreshGhProjectScopesAndReadToken() {
4431
+ const result = spawnSync("gh", ["auth", "refresh", "--scopes", "read:project"], {
4432
+ encoding: "utf8",
4433
+ stdio: ["inherit", "pipe", "pipe"]
4434
+ });
4435
+ if (result.status !== 0)
4436
+ return null;
4437
+ try {
4438
+ return readGhAuthToken();
4439
+ } catch {
4440
+ return null;
4441
+ }
4442
+ }
4429
4443
  async function loadClackPrompts() {
4430
4444
  return await import("@clack/prompts");
4431
4445
  }
@@ -4521,12 +4535,27 @@ async function promptManualProjectStatusMapping(prompts) {
4521
4535
  }
4522
4536
  return statuses;
4523
4537
  }
4524
- async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken) {
4538
+ function projectScopeError(value) {
4539
+ const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
4540
+ return /INSUFFICIENT_SCOPES|read:project|required scopes/i.test(text2);
4541
+ }
4542
+ function optionName(option) {
4543
+ return String(option.name ?? option.label ?? option.id ?? "").trim();
4544
+ }
4545
+ function autoProjectStatusValue(options, key, label) {
4546
+ const candidates = [DEFAULT_PROJECT_STATUS_OPTIONS[key], label].filter((value) => Boolean(value)).map((value) => value.trim().toLowerCase());
4547
+ const match = options.find((option) => candidates.includes(optionName(option).toLowerCase()));
4548
+ if (!match)
4549
+ return null;
4550
+ return String(match.id ?? match.name);
4551
+ }
4552
+ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, refreshProjectToken) {
4525
4553
  const projectChoice = await promptSelect(prompts, {
4526
4554
  message: "GitHub Projects status sync",
4555
+ initialValue: "select",
4527
4556
  options: [
4528
- { value: "off", label: "Off" },
4529
4557
  { value: "select", label: "Select accessible ProjectV2" },
4558
+ { value: "off", label: "Off" },
4530
4559
  { value: "manual", label: "Enter ProjectV2 ids manually" }
4531
4560
  ]
4532
4561
  });
@@ -4542,16 +4571,22 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4542
4571
  const owner = repoOwnerFromSlug(repoSlug);
4543
4572
  if (!owner)
4544
4573
  throw new CliError2(`Cannot derive GitHub owner from repo slug ${repoSlug}.`, 1);
4545
- const projectsPayload = await listGitHubProjectsForInit(context, owner, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4546
- const projects = recordArray(projectsPayload, "projects");
4574
+ let activeToken = githubToken?.trim() || null;
4575
+ let projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4576
+ let projects = recordArray(projectsPayload, "projects");
4577
+ if (projects.length === 0 && projectScopeError(projectsPayload.error) && refreshProjectToken) {
4578
+ prompts.outro?.("GitHub token is missing read:project; refreshing gh auth scopes and retrying Projects.");
4579
+ const refreshedToken = refreshProjectToken();
4580
+ if (refreshedToken) {
4581
+ activeToken = refreshedToken;
4582
+ projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4583
+ projects = recordArray(projectsPayload, "projects");
4584
+ }
4585
+ }
4547
4586
  if (projects.length === 0) {
4548
- const error = typeof projectsPayload.error === "string" ? ` (${projectsPayload.error})` : "";
4549
- prompts.outro?.(`No accessible GitHub Projects were returned${error}; falling back to manual ProjectV2 ids.`);
4550
- return {
4551
- githubProject: await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }),
4552
- githubProjectStatusField: await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" }),
4553
- githubProjectStatuses: await promptManualProjectStatusMapping(prompts)
4554
- };
4587
+ const error = typeof projectsPayload.error === "string" ? ` (${String(projectsPayload.error).replace(/\s+/g, " ").slice(0, 240)})` : "";
4588
+ prompts.outro?.(`No accessible GitHub Projects were returned${error}; continuing with GitHub Projects status sync off.`);
4589
+ return { githubProject: "off", ...activeToken ? { githubToken: activeToken } : {} };
4555
4590
  }
4556
4591
  const selectedProjectId = await promptSelect(prompts, {
4557
4592
  message: "GitHub ProjectV2 project",
@@ -4565,23 +4600,34 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4565
4600
  ]
4566
4601
  });
4567
4602
  const projectId = selectedProjectId === "manual" ? await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }) : selectedProjectId;
4568
- const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4603
+ const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4569
4604
  const fieldPayloadRecord = fieldPayload && typeof fieldPayload === "object" && !Array.isArray(fieldPayload) ? fieldPayload : {};
4570
4605
  const rawField = fieldPayloadRecord.field;
4571
4606
  const field = rawField && typeof rawField === "object" && !Array.isArray(rawField) ? rawField : null;
4572
4607
  const fieldId = typeof field?.id === "string" && field.id.trim() ? field.id : await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" });
4573
4608
  const options = Array.isArray(field?.options) ? field.options.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
4574
4609
  if (options.length === 0) {
4575
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: await promptManualProjectStatusMapping(prompts) };
4610
+ return {
4611
+ githubProject: projectId,
4612
+ githubProjectStatusField: fieldId,
4613
+ githubProjectStatuses: await promptManualProjectStatusMapping(prompts),
4614
+ ...activeToken ? { githubToken: activeToken } : {}
4615
+ };
4576
4616
  }
4577
4617
  const statuses = {};
4578
4618
  for (const [key, label] of Object.entries(PROJECT_STATUS_PROMPTS)) {
4579
- statuses[key] = await promptSelect(prompts, {
4619
+ const auto = autoProjectStatusValue(options, key, label);
4620
+ statuses[key] = auto ?? await promptSelect(prompts, {
4580
4621
  message: `Project status option for ${label}`,
4581
- options: options.map((option) => ({ value: String(option.id ?? option.name), label: String(option.name ?? option.id) }))
4622
+ options: options.map((option) => ({ value: String(option.id ?? option.name), label: optionName(option) }))
4582
4623
  });
4583
4624
  }
4584
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined };
4625
+ return {
4626
+ githubProject: projectId,
4627
+ githubProjectStatusField: fieldId,
4628
+ githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined,
4629
+ ...activeToken ? { githubToken: activeToken } : {}
4630
+ };
4585
4631
  }
4586
4632
  function sleep2(ms) {
4587
4633
  return new Promise((resolve17) => setTimeout(resolve17, ms));
@@ -4912,12 +4958,13 @@ async function runInteractiveControlPlaneInit(context, prompts) {
4912
4958
  });
4913
4959
  const serverChoice = await promptSelect(prompts, {
4914
4960
  message: "Rig server",
4961
+ initialValue: "remote",
4915
4962
  options: [
4916
- { value: "local", label: "Local server", hint: "run on this machine" },
4917
- { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" }
4963
+ { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" },
4964
+ { value: "local", label: "Local server", hint: "run on this machine" }
4918
4965
  ]
4919
4966
  });
4920
- const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: "https://rig.example.com" }) : undefined;
4967
+ const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: DEFAULT_REMOTE_RIG_URL, initialValue: DEFAULT_REMOTE_RIG_URL }) : undefined;
4921
4968
  let remoteCheckout;
4922
4969
  if (serverChoice === "remote") {
4923
4970
  const checkout = await promptSelect(prompts, {
@@ -4949,31 +4996,35 @@ async function runInteractiveControlPlaneInit(context, prompts) {
4949
4996
  { value: "skip", label: "Skip for now" }
4950
4997
  ]
4951
4998
  });
4999
+ let remoteGhTokenConfirmed = false;
4952
5000
  if (serverChoice === "remote" && authMethod === "gh") {
4953
5001
  if (!prompts.confirm)
4954
5002
  throw new CliError2("Remote gh-token import requires explicit confirmation.", 1);
4955
5003
  const confirmed = await prompts.confirm({
4956
5004
  message: `This sends a GitHub token from this machine to ${remoteUrl}. Continue?`,
4957
- initialValue: false
5005
+ initialValue: true
4958
5006
  });
4959
5007
  if (prompts.isCancel(confirmed) || confirmed !== true) {
4960
5008
  throw new CliError2("Remote gh-token import cancelled.", 1);
4961
5009
  }
5010
+ remoteGhTokenConfirmed = true;
4962
5011
  }
4963
5012
  const githubToken = authMethod === "token" ? await promptRequiredText(prompts, { message: "GitHub token", placeholder: "ghp_..." }) : authMethod === "gh" ? readGhAuthToken() : undefined;
4964
- const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken);
5013
+ const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, authMethod === "gh" ? refreshGhProjectScopesAndReadToken : undefined);
5014
+ const effectiveGithubToken = projectConfig.githubToken ?? githubToken;
4965
5015
  const result = await runControlPlaneInit(context, {
4966
5016
  server: serverChoice,
4967
5017
  remoteUrl,
4968
5018
  repoSlug,
4969
- githubToken,
5019
+ githubToken: effectiveGithubToken,
4970
5020
  githubAuthMethod: authMethod,
4971
5021
  githubProject: projectConfig.githubProject,
4972
5022
  githubProjectStatusField: projectConfig.githubProjectStatusField,
4973
5023
  githubProjectStatuses: projectConfig.githubProjectStatuses,
4974
5024
  remoteCheckout,
4975
5025
  repair,
4976
- privateStateOnly
5026
+ privateStateOnly,
5027
+ yes: remoteGhTokenConfirmed || undefined
4977
5028
  });
4978
5029
  const details = result.details && typeof result.details === "object" && !Array.isArray(result.details) ? result.details : {};
4979
5030
  const deviceAuth = details.deviceAuth && typeof details.deviceAuth === "object" && !Array.isArray(details.deviceAuth) ? details.deviceAuth : null;
package/dist/src/index.js CHANGED
@@ -4525,6 +4525,7 @@ function countDoctorFailures(checks) {
4525
4525
 
4526
4526
  // packages/cli/src/commands/init.ts
4527
4527
  var RIG_CONFIG_PACKAGE_DIST_TAG = "latest";
4528
+ var DEFAULT_REMOTE_RIG_URL = "https://where.rig-does.work";
4528
4529
  var RIG_CONFIG_DEV_DEPENDENCIES = {
4529
4530
  "@rig/core": `npm:@h-rig/core@${RIG_CONFIG_PACKAGE_DIST_TAG}`,
4530
4531
  "@rig/standard-plugin": `npm:@h-rig/standard-plugin@${RIG_CONFIG_PACKAGE_DIST_TAG}`
@@ -4629,6 +4630,19 @@ function readGhAuthToken() {
4629
4630
  }
4630
4631
  return result.stdout.trim();
4631
4632
  }
4633
+ function refreshGhProjectScopesAndReadToken() {
4634
+ const result = spawnSync("gh", ["auth", "refresh", "--scopes", "read:project"], {
4635
+ encoding: "utf8",
4636
+ stdio: ["inherit", "pipe", "pipe"]
4637
+ });
4638
+ if (result.status !== 0)
4639
+ return null;
4640
+ try {
4641
+ return readGhAuthToken();
4642
+ } catch {
4643
+ return null;
4644
+ }
4645
+ }
4632
4646
  async function loadClackPrompts() {
4633
4647
  return await import("@clack/prompts");
4634
4648
  }
@@ -4724,12 +4738,27 @@ async function promptManualProjectStatusMapping(prompts) {
4724
4738
  }
4725
4739
  return statuses;
4726
4740
  }
4727
- async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken) {
4741
+ function projectScopeError(value) {
4742
+ const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
4743
+ return /INSUFFICIENT_SCOPES|read:project|required scopes/i.test(text2);
4744
+ }
4745
+ function optionName(option) {
4746
+ return String(option.name ?? option.label ?? option.id ?? "").trim();
4747
+ }
4748
+ function autoProjectStatusValue(options, key, label) {
4749
+ const candidates = [DEFAULT_PROJECT_STATUS_OPTIONS[key], label].filter((value) => Boolean(value)).map((value) => value.trim().toLowerCase());
4750
+ const match = options.find((option) => candidates.includes(optionName(option).toLowerCase()));
4751
+ if (!match)
4752
+ return null;
4753
+ return String(match.id ?? match.name);
4754
+ }
4755
+ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, refreshProjectToken) {
4728
4756
  const projectChoice = await promptSelect(prompts, {
4729
4757
  message: "GitHub Projects status sync",
4758
+ initialValue: "select",
4730
4759
  options: [
4731
- { value: "off", label: "Off" },
4732
4760
  { value: "select", label: "Select accessible ProjectV2" },
4761
+ { value: "off", label: "Off" },
4733
4762
  { value: "manual", label: "Enter ProjectV2 ids manually" }
4734
4763
  ]
4735
4764
  });
@@ -4745,16 +4774,22 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4745
4774
  const owner = repoOwnerFromSlug(repoSlug);
4746
4775
  if (!owner)
4747
4776
  throw new CliError2(`Cannot derive GitHub owner from repo slug ${repoSlug}.`, 1);
4748
- const projectsPayload = await listGitHubProjectsForInit(context, owner, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4749
- const projects = recordArray(projectsPayload, "projects");
4777
+ let activeToken = githubToken?.trim() || null;
4778
+ let projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4779
+ let projects = recordArray(projectsPayload, "projects");
4780
+ if (projects.length === 0 && projectScopeError(projectsPayload.error) && refreshProjectToken) {
4781
+ prompts.outro?.("GitHub token is missing read:project; refreshing gh auth scopes and retrying Projects.");
4782
+ const refreshedToken = refreshProjectToken();
4783
+ if (refreshedToken) {
4784
+ activeToken = refreshedToken;
4785
+ projectsPayload = await listGitHubProjectsForInit(context, owner, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error), projects: [] }));
4786
+ projects = recordArray(projectsPayload, "projects");
4787
+ }
4788
+ }
4750
4789
  if (projects.length === 0) {
4751
- const error = typeof projectsPayload.error === "string" ? ` (${projectsPayload.error})` : "";
4752
- prompts.outro?.(`No accessible GitHub Projects were returned${error}; falling back to manual ProjectV2 ids.`);
4753
- return {
4754
- githubProject: await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }),
4755
- githubProjectStatusField: await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" }),
4756
- githubProjectStatuses: await promptManualProjectStatusMapping(prompts)
4757
- };
4790
+ const error = typeof projectsPayload.error === "string" ? ` (${String(projectsPayload.error).replace(/\s+/g, " ").slice(0, 240)})` : "";
4791
+ prompts.outro?.(`No accessible GitHub Projects were returned${error}; continuing with GitHub Projects status sync off.`);
4792
+ return { githubProject: "off", ...activeToken ? { githubToken: activeToken } : {} };
4758
4793
  }
4759
4794
  const selectedProjectId = await promptSelect(prompts, {
4760
4795
  message: "GitHub ProjectV2 project",
@@ -4768,23 +4803,34 @@ async function promptGitHubProjectConfig(context, prompts, repoSlug, githubToken
4768
4803
  ]
4769
4804
  });
4770
4805
  const projectId = selectedProjectId === "manual" ? await promptRequiredText(prompts, { message: "GitHub ProjectV2 id", placeholder: "PVT_..." }) : selectedProjectId;
4771
- const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, githubToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4806
+ const fieldPayload = await getGitHubProjectStatusFieldForInit(context, projectId, activeToken).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }));
4772
4807
  const fieldPayloadRecord = fieldPayload && typeof fieldPayload === "object" && !Array.isArray(fieldPayload) ? fieldPayload : {};
4773
4808
  const rawField = fieldPayloadRecord.field;
4774
4809
  const field = rawField && typeof rawField === "object" && !Array.isArray(rawField) ? rawField : null;
4775
4810
  const fieldId = typeof field?.id === "string" && field.id.trim() ? field.id : await promptRequiredText(prompts, { message: "Project Status field id", placeholder: "field_status" });
4776
4811
  const options = Array.isArray(field?.options) ? field.options.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
4777
4812
  if (options.length === 0) {
4778
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: await promptManualProjectStatusMapping(prompts) };
4813
+ return {
4814
+ githubProject: projectId,
4815
+ githubProjectStatusField: fieldId,
4816
+ githubProjectStatuses: await promptManualProjectStatusMapping(prompts),
4817
+ ...activeToken ? { githubToken: activeToken } : {}
4818
+ };
4779
4819
  }
4780
4820
  const statuses = {};
4781
4821
  for (const [key, label] of Object.entries(PROJECT_STATUS_PROMPTS)) {
4782
- statuses[key] = await promptSelect(prompts, {
4822
+ const auto = autoProjectStatusValue(options, key, label);
4823
+ statuses[key] = auto ?? await promptSelect(prompts, {
4783
4824
  message: `Project status option for ${label}`,
4784
- options: options.map((option) => ({ value: String(option.id ?? option.name), label: String(option.name ?? option.id) }))
4825
+ options: options.map((option) => ({ value: String(option.id ?? option.name), label: optionName(option) }))
4785
4826
  });
4786
4827
  }
4787
- return { githubProject: projectId, githubProjectStatusField: fieldId, githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined };
4828
+ return {
4829
+ githubProject: projectId,
4830
+ githubProjectStatusField: fieldId,
4831
+ githubProjectStatuses: Object.keys(statuses).length > 0 ? statuses : undefined,
4832
+ ...activeToken ? { githubToken: activeToken } : {}
4833
+ };
4788
4834
  }
4789
4835
  function sleep2(ms) {
4790
4836
  return new Promise((resolve18) => setTimeout(resolve18, ms));
@@ -5115,12 +5161,13 @@ async function runInteractiveControlPlaneInit(context, prompts) {
5115
5161
  });
5116
5162
  const serverChoice = await promptSelect(prompts, {
5117
5163
  message: "Rig server",
5164
+ initialValue: "remote",
5118
5165
  options: [
5119
- { value: "local", label: "Local server", hint: "run on this machine" },
5120
- { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" }
5166
+ { value: "remote", label: "Remote server", hint: "connect to an HTTPS Rig server" },
5167
+ { value: "local", label: "Local server", hint: "run on this machine" }
5121
5168
  ]
5122
5169
  });
5123
- const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: "https://rig.example.com" }) : undefined;
5170
+ const remoteUrl = serverChoice === "remote" ? await promptRequiredText(prompts, { message: "Remote Rig server URL", placeholder: DEFAULT_REMOTE_RIG_URL, initialValue: DEFAULT_REMOTE_RIG_URL }) : undefined;
5124
5171
  let remoteCheckout;
5125
5172
  if (serverChoice === "remote") {
5126
5173
  const checkout = await promptSelect(prompts, {
@@ -5152,31 +5199,35 @@ async function runInteractiveControlPlaneInit(context, prompts) {
5152
5199
  { value: "skip", label: "Skip for now" }
5153
5200
  ]
5154
5201
  });
5202
+ let remoteGhTokenConfirmed = false;
5155
5203
  if (serverChoice === "remote" && authMethod === "gh") {
5156
5204
  if (!prompts.confirm)
5157
5205
  throw new CliError2("Remote gh-token import requires explicit confirmation.", 1);
5158
5206
  const confirmed = await prompts.confirm({
5159
5207
  message: `This sends a GitHub token from this machine to ${remoteUrl}. Continue?`,
5160
- initialValue: false
5208
+ initialValue: true
5161
5209
  });
5162
5210
  if (prompts.isCancel(confirmed) || confirmed !== true) {
5163
5211
  throw new CliError2("Remote gh-token import cancelled.", 1);
5164
5212
  }
5213
+ remoteGhTokenConfirmed = true;
5165
5214
  }
5166
5215
  const githubToken = authMethod === "token" ? await promptRequiredText(prompts, { message: "GitHub token", placeholder: "ghp_..." }) : authMethod === "gh" ? readGhAuthToken() : undefined;
5167
- const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken);
5216
+ const projectConfig = await promptGitHubProjectConfig(context, prompts, repoSlug, githubToken, authMethod === "gh" ? refreshGhProjectScopesAndReadToken : undefined);
5217
+ const effectiveGithubToken = projectConfig.githubToken ?? githubToken;
5168
5218
  const result = await runControlPlaneInit(context, {
5169
5219
  server: serverChoice,
5170
5220
  remoteUrl,
5171
5221
  repoSlug,
5172
- githubToken,
5222
+ githubToken: effectiveGithubToken,
5173
5223
  githubAuthMethod: authMethod,
5174
5224
  githubProject: projectConfig.githubProject,
5175
5225
  githubProjectStatusField: projectConfig.githubProjectStatusField,
5176
5226
  githubProjectStatuses: projectConfig.githubProjectStatuses,
5177
5227
  remoteCheckout,
5178
5228
  repair,
5179
- privateStateOnly
5229
+ privateStateOnly,
5230
+ yes: remoteGhTokenConfirmed || undefined
5180
5231
  });
5181
5232
  const details = result.details && typeof result.details === "object" && !Array.isArray(result.details) ? result.details : {};
5182
5233
  const deviceAuth = details.deviceAuth && typeof details.deviceAuth === "object" && !Array.isArray(details.deviceAuth) ? details.deviceAuth : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h-rig/cli",
3
- "version": "0.0.6-alpha.16",
3
+ "version": "0.0.6-alpha.18",
4
4
  "type": "module",
5
5
  "description": "Rig package",
6
6
  "license": "UNLICENSED",
@@ -23,10 +23,10 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@clack/prompts": "^1.2.0",
26
- "@rig/core": "npm:@h-rig/core@0.0.6-alpha.16",
27
- "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.16",
28
- "@rig/client": "npm:@h-rig/client@0.0.6-alpha.16",
29
- "@rig/server": "npm:@h-rig/server@0.0.6-alpha.16",
26
+ "@rig/core": "npm:@h-rig/core@0.0.6-alpha.18",
27
+ "@rig/runtime": "npm:@h-rig/runtime@0.0.6-alpha.18",
28
+ "@rig/client": "npm:@h-rig/client@0.0.6-alpha.18",
29
+ "@rig/server": "npm:@h-rig/server@0.0.6-alpha.18",
30
30
  "picocolors": "^1.1.1"
31
31
  }
32
32
  }