@synkro-sh/cli 1.3.11 → 1.3.13

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/bootstrap.js CHANGED
@@ -2580,7 +2580,7 @@ async function listAccessibleRepos(opts) {
2580
2580
  const repos = [];
2581
2581
  let page = 1;
2582
2582
  while (page <= 5) {
2583
- const url = `https://api.github.com/user/repos?per_page=100&page=${page}&affiliation=owner,collaborator`;
2583
+ const url = `https://api.github.com/user/repos?per_page=100&page=${page}&affiliation=owner,collaborator,organization_member`;
2584
2584
  const resp = await fetch(url, {
2585
2585
  headers: {
2586
2586
  Authorization: `Bearer ${opts.token}`,
@@ -2941,7 +2941,11 @@ async function setupGithubCommand(opts = {}) {
2941
2941
  console.error(`Failed to mint CI API key: ${err.message}`);
2942
2942
  process.exit(1);
2943
2943
  }
2944
- const rl = createInterface2({ input, output });
2944
+ let _rl = null;
2945
+ function getRL() {
2946
+ if (!_rl) _rl = createInterface2({ input, output });
2947
+ return _rl;
2948
+ }
2945
2949
  let ghToken = opts.githubToken || "";
2946
2950
  if (!ghToken) {
2947
2951
  try {
@@ -2967,13 +2971,13 @@ async function setupGithubCommand(opts = {}) {
2967
2971
  console.log(" \u2713 GitHub authorized");
2968
2972
  } catch (err) {
2969
2973
  console.error(`GitHub authorization failed: ${err.message}`);
2970
- rl.close();
2974
+ _rl?.close();
2971
2975
  process.exit(1);
2972
2976
  }
2973
2977
  }
2974
2978
  if (!ghToken) {
2975
2979
  console.error("No GitHub token available.");
2976
- rl.close();
2980
+ _rl?.close();
2977
2981
  process.exit(1);
2978
2982
  }
2979
2983
  let claudeToken = opts.claudeOauthToken || "";
@@ -3042,35 +3046,65 @@ async function setupGithubCommand(opts = {}) {
3042
3046
  const repos = await listAccessibleRepos({ token: ghToken });
3043
3047
  if (repos.length === 0) {
3044
3048
  console.error("No accessible repos found. Verify the GitHub token has `repo` scope.");
3045
- rl.close();
3049
+ _rl?.close();
3046
3050
  process.exit(1);
3047
3051
  }
3048
- console.log(`
3052
+ let selected;
3053
+ if (opts.nonInteractive) {
3054
+ let currentFullName = null;
3055
+ try {
3056
+ const { execSync: gs } = await import("child_process");
3057
+ const remoteUrl = gs("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
3058
+ const m = remoteUrl.match(/(?:github\.com)[:/](.+?)(?:\.git)?$/);
3059
+ if (m) currentFullName = m[1];
3060
+ } catch {
3061
+ }
3062
+ if (currentFullName) {
3063
+ const match = repos.find(
3064
+ (r) => r.full_name === currentFullName || r.full_name.toLowerCase() === currentFullName.toLowerCase()
3065
+ );
3066
+ if (match) {
3067
+ selected = [match];
3068
+ console.log(` Auto-selected current repo: ${match.full_name}`);
3069
+ } else {
3070
+ console.warn(` \u26A0 Current repo "${currentFullName}" not found in accessible repos. Skipping PR scan setup.`);
3071
+ console.warn(" Run `synkro-cli setup-github` manually to select a repo.");
3072
+ return;
3073
+ }
3074
+ } else {
3075
+ console.warn(" \u26A0 Not in a GitHub repo. Skipping PR scan setup.");
3076
+ console.warn(" Run `synkro-cli setup-github` from inside a repo.");
3077
+ return;
3078
+ }
3079
+ } else {
3080
+ console.log(`
3049
3081
  Found ${repos.length} accessible repo(s):
3050
3082
  `);
3051
- repos.slice(0, 100).forEach((r, i) => {
3052
- console.log(` ${String(i + 1).padStart(3)}. ${r.full_name}`);
3053
- });
3054
- console.log();
3055
- const selectionRaw = await prompt(rl, "Select repos to enable (comma-separated numbers, e.g. 1,3,5): ");
3056
- const selectedIdx = selectionRaw.split(",").map((s) => parseInt(s.trim(), 10) - 1).filter((n) => !isNaN(n) && n >= 0 && n < repos.length);
3057
- if (selectedIdx.length === 0) {
3058
- console.error("No valid selections.");
3059
- rl.close();
3060
- process.exit(1);
3061
- }
3062
- const selected = selectedIdx.map((i) => repos[i]);
3063
- console.log(`
3083
+ repos.slice(0, 100).forEach((r, i) => {
3084
+ console.log(` ${String(i + 1).padStart(3)}. ${r.full_name}`);
3085
+ });
3086
+ console.log();
3087
+ const rl = getRL();
3088
+ const selectionRaw = await prompt(rl, "Select repos to enable (comma-separated numbers, e.g. 1,3,5): ");
3089
+ const selectedIdx = selectionRaw.split(",").map((s) => parseInt(s.trim(), 10) - 1).filter((n) => !isNaN(n) && n >= 0 && n < repos.length);
3090
+ if (selectedIdx.length === 0) {
3091
+ console.error("No valid selections.");
3092
+ rl.close();
3093
+ process.exit(1);
3094
+ }
3095
+ selected = selectedIdx.map((i) => repos[i]);
3096
+ console.log(`
3064
3097
  Will push secrets to ${selected.length} repo(s):`);
3065
- for (const r of selected) console.log(` \u2022 ${r.full_name}`);
3066
- console.log();
3067
- const confirm = (await prompt(rl, "Continue? (yes/no): ")).trim().toLowerCase();
3068
- if (confirm !== "yes" && confirm !== "y") {
3069
- console.log("Cancelled.");
3070
- rl.close();
3071
- process.exit(0);
3098
+ for (const r of selected) console.log(` \u2022 ${r.full_name}`);
3099
+ console.log();
3100
+ const confirm = (await prompt(rl, "Continue? (yes/no): ")).trim().toLowerCase();
3101
+ if (confirm !== "yes" && confirm !== "y") {
3102
+ console.log("Cancelled.");
3103
+ rl.close();
3104
+ process.exit(0);
3105
+ }
3072
3106
  }
3073
- rl.close();
3107
+ _rl?.close();
3074
3108
  console.log();
3075
3109
  for (const r of selected) {
3076
3110
  process.stdout.write(`Pushing secrets to ${r.full_name}... `);
@@ -3086,7 +3120,7 @@ Will push secrets to ${selected.length} repo(s):`);
3086
3120
  );
3087
3121
  console.log("\u2713");
3088
3122
  } catch (err) {
3089
- console.log(`\u2717 (${err.message})`);
3123
+ console.log(`\u2717 (${err instanceof Error ? err.message : String(err)})`);
3090
3124
  }
3091
3125
  }
3092
3126
  console.log();
@@ -3236,7 +3270,7 @@ function writeConfigEnv(opts) {
3236
3270
  `SYNKRO_GATEWAY_URL=${shellQuoteSingle(safeGateway)}`,
3237
3271
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3238
3272
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3239
- `SYNKRO_VERSION=${shellQuoteSingle("1.3.11")}`
3273
+ `SYNKRO_VERSION=${shellQuoteSingle("1.3.13")}`
3240
3274
  ];
3241
3275
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
3242
3276
  if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
@@ -3512,7 +3546,7 @@ async function installCommand(opts = {}) {
3512
3546
  }
3513
3547
  if (choice === "1") {
3514
3548
  try {
3515
- await setupGithubCommand({ githubToken: opts.githubToken });
3549
+ await setupGithubCommand({ githubToken: opts.githubToken, nonInteractive: opts.nonInteractive });
3516
3550
  } catch (err) {
3517
3551
  console.warn(` \u26A0 GitHub setup failed: ${err.message}`);
3518
3552
  console.warn(" Run `synkro-cli setup-github` to retry.\n");
@@ -3574,7 +3608,7 @@ async function installCommand(opts = {}) {
3574
3608
  }
3575
3609
  }
3576
3610
  try {
3577
- await setupGithubCommand({ skipClaudeToken: true, githubToken: opts.githubToken });
3611
+ await setupGithubCommand({ skipClaudeToken: true, githubToken: opts.githubToken, nonInteractive: opts.nonInteractive });
3578
3612
  } catch (err) {
3579
3613
  console.warn(` \u26A0 GitHub setup failed: ${err.message}`);
3580
3614
  console.warn(" Run `synkro-cli setup-github` to retry.\n");