@synkro-sh/cli 1.3.10 → 1.3.11

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
@@ -1,12 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined") return require.apply(this, arguments);
8
- throw Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
4
  var __esm = (fn, res) => function __init() {
11
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
6
  };
@@ -2645,7 +2639,7 @@ var init_githubSetup = __esm({
2645
2639
  });
2646
2640
 
2647
2641
  // cli/commands/repoConnect.ts
2648
- import { execSync as execSync2 } from "child_process";
2642
+ import { execSync as execSync2, execFileSync } from "child_process";
2649
2643
  import { createServer as createServer2 } from "http";
2650
2644
  import { createInterface } from "readline";
2651
2645
  function detectGitRepo() {
@@ -2718,11 +2712,10 @@ function waitForGithubToken() {
2718
2712
  });
2719
2713
  }
2720
2714
  function openBrowser2(url) {
2721
- const { execFile: execFile2 } = __require("child_process");
2722
2715
  const plat = process.platform;
2723
- if (plat === "darwin") execFile2("open", [url]);
2724
- else if (plat === "win32") execFile2("cmd", ["/c", "start", "", url]);
2725
- else execFile2("xdg-open", [url]);
2716
+ if (plat === "darwin") execFileSync("open", [url], { stdio: "ignore" });
2717
+ else if (plat === "win32") execFileSync("cmd", ["/c", "start", "", url], { stdio: "ignore" });
2718
+ else execFileSync("xdg-open", [url], { stdio: "ignore" });
2726
2719
  }
2727
2720
  async function connectGithubAndSelectRepos() {
2728
2721
  const url = `${SYNKRO_WEB_AUTH_URL2}/cli-github?port=${GITHUB_PORT}`;
@@ -2873,7 +2866,13 @@ function readConfig() {
2873
2866
  const t = line.trim();
2874
2867
  if (!t || t.startsWith("#")) continue;
2875
2868
  const eq = t.indexOf("=");
2876
- if (eq > 0) out[t.slice(0, eq).trim()] = t.slice(eq + 1).trim();
2869
+ if (eq > 0) {
2870
+ let val = t.slice(eq + 1).trim();
2871
+ if (val.startsWith("'") && val.endsWith("'") || val.startsWith('"') && val.endsWith('"')) {
2872
+ val = val.slice(1, -1);
2873
+ }
2874
+ out[t.slice(0, eq).trim()] = val;
2875
+ }
2877
2876
  }
2878
2877
  return out;
2879
2878
  }
@@ -2945,31 +2944,93 @@ async function setupGithubCommand(opts = {}) {
2945
2944
  const rl = createInterface2({ input, output });
2946
2945
  let ghToken = opts.githubToken || "";
2947
2946
  if (!ghToken) {
2948
- console.log("Synkro PR scan setup\n");
2949
- console.log("Requirements:");
2950
- console.log(" \u2022 A GitHub personal access token with `repo` scope");
2951
- console.log(" (create at https://github.com/settings/tokens?type=beta)\n");
2952
- ghToken = (await prompt(rl, "GitHub token (paste): ", { silent: true })).trim();
2953
- }
2954
- if (!ghToken || !ghToken.startsWith("ghp_") && !ghToken.startsWith("github_pat_")) {
2955
- console.error("Invalid GitHub token format. Expected ghp_... or github_pat_...");
2947
+ try {
2948
+ const connResp = await fetch(`${gatewayUrl}/api/integrations/github/token`, {
2949
+ headers: { "Authorization": `Bearer ${jwt2}` }
2950
+ });
2951
+ if (connResp.ok) {
2952
+ const data = await connResp.json();
2953
+ ghToken = data.token;
2954
+ console.log(" \u2713 Using existing GitHub connection");
2955
+ }
2956
+ } catch {
2957
+ }
2958
+ }
2959
+ if (!ghToken) {
2960
+ console.log("Opening browser for GitHub authorization...");
2961
+ const RAW_WEB_AUTH_URL3 = process.env.SYNKRO_WEB_AUTH_URL;
2962
+ const webAuthUrl = RAW_WEB_AUTH_URL3 && /^https?:\/\//.test(RAW_WEB_AUTH_URL3) ? RAW_WEB_AUTH_URL3 : "https://app.synkro.sh";
2963
+ openBrowser2(`${webAuthUrl}/cli-github?port=8101`);
2964
+ console.log("Waiting for GitHub authorization...");
2965
+ try {
2966
+ ghToken = await waitForGithubToken();
2967
+ console.log(" \u2713 GitHub authorized");
2968
+ } catch (err) {
2969
+ console.error(`GitHub authorization failed: ${err.message}`);
2970
+ rl.close();
2971
+ process.exit(1);
2972
+ }
2973
+ }
2974
+ if (!ghToken) {
2975
+ console.error("No GitHub token available.");
2956
2976
  rl.close();
2957
2977
  process.exit(1);
2958
2978
  }
2959
2979
  let claudeToken = opts.claudeOauthToken || "";
2960
2980
  if (!claudeToken && !opts.skipClaudeToken) {
2961
2981
  try {
2962
- const { execSync: execSync5 } = await import("child_process");
2982
+ const { execSync: execSyncImport } = await import("child_process");
2983
+ const { tmpdir } = await import("os");
2984
+ const tmpFile = join5(tmpdir(), `synkro-claude-token-${Date.now()}.txt`);
2963
2985
  console.log("\nGenerating Claude Code OAuth token \u2014 complete the browser auth...");
2964
- const tokenOutput = execSync5("claude setup-token", {
2965
- encoding: "utf-8",
2966
- timeout: 12e4,
2967
- stdio: ["inherit", "pipe", "inherit"]
2968
- }).trim();
2969
- const tokenLine = tokenOutput.split("\n").find((l) => l.includes("sk-ant-oat01-"));
2970
- claudeToken = tokenLine?.match(/(sk-ant-oat01-[A-Za-z0-9_-]+)/)?.[1] || "";
2986
+ try {
2987
+ if (process.platform === "darwin" || process.platform === "linux") {
2988
+ execSyncImport(`script -q ${tmpFile} claude setup-token`, {
2989
+ timeout: 12e4,
2990
+ stdio: "inherit"
2991
+ });
2992
+ } else {
2993
+ execSyncImport(`claude setup-token > "${tmpFile}" 2>&1`, {
2994
+ timeout: 12e4,
2995
+ stdio: "inherit",
2996
+ shell: true
2997
+ });
2998
+ }
2999
+ const { readFileSync: readSync, unlinkSync: unlinkSync3 } = await import("fs");
3000
+ const rawOutput = readSync(tmpFile, "utf-8");
3001
+ try {
3002
+ unlinkSync3(tmpFile);
3003
+ } catch {
3004
+ }
3005
+ const cleaned = rawOutput.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "").replace(/\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/[\r\n]+/g, " ");
3006
+ const match = cleaned.match(/(sk-ant-oat01-[A-Za-z0-9_-]{50,})/);
3007
+ claudeToken = match?.[1] || "";
3008
+ } catch {
3009
+ try {
3010
+ const { unlinkSync: unlinkSync3 } = await import("fs");
3011
+ unlinkSync3(tmpFile);
3012
+ } catch {
3013
+ }
3014
+ }
2971
3015
  if (claudeToken) {
2972
- console.log(" \u2713 Captured Claude Code OAuth token.\n");
3016
+ console.log(" \u2713 Captured Claude Code OAuth token.");
3017
+ process.stdout.write(" Verifying token... ");
3018
+ try {
3019
+ const { execSync: verifyExec } = await import("child_process");
3020
+ const result = verifyExec('claude --print "respond with just ok"', {
3021
+ encoding: "utf-8",
3022
+ timeout: 3e4,
3023
+ env: { ...process.env, CLAUDE_CODE_OAUTH_TOKEN: claudeToken },
3024
+ stdio: ["pipe", "pipe", "pipe"]
3025
+ }).trim().toLowerCase();
3026
+ if (result.includes("ok")) {
3027
+ console.log("\u2713 inference works.\n");
3028
+ } else {
3029
+ console.log("\u26A0 unexpected response, token may not work.\n");
3030
+ }
3031
+ } catch {
3032
+ console.log("\u26A0 verification failed, token may not work.\n");
3033
+ }
2973
3034
  } else {
2974
3035
  console.warn(" \u26A0 Could not capture token. PR scans will use BYOK inference only.\n");
2975
3036
  }
@@ -3052,6 +3113,7 @@ var init_setupGithub = __esm({
3052
3113
  "use strict";
3053
3114
  init_githubSetup();
3054
3115
  init_stub();
3116
+ init_repoConnect();
3055
3117
  SYNKRO_DIR = join5(homedir4(), ".synkro");
3056
3118
  CONFIG_PATH = join5(SYNKRO_DIR, "config.env");
3057
3119
  }
@@ -3174,7 +3236,7 @@ function writeConfigEnv(opts) {
3174
3236
  `SYNKRO_GATEWAY_URL=${shellQuoteSingle(safeGateway)}`,
3175
3237
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3176
3238
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3177
- `SYNKRO_VERSION=${shellQuoteSingle("1.3.10")}`
3239
+ `SYNKRO_VERSION=${shellQuoteSingle("1.3.11")}`
3178
3240
  ];
3179
3241
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
3180
3242
  if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
@@ -3420,7 +3482,7 @@ async function installCommand(opts = {}) {
3420
3482
  let ghConnected = false;
3421
3483
  let ghLogin = "";
3422
3484
  try {
3423
- const resp = await fetch(`${gatewayUrl}/api/v1/integrations/github/connect`, {
3485
+ const resp = await fetch(`${gatewayUrl}/api/integrations/github/connect`, {
3424
3486
  headers: { "Authorization": `Bearer ${token}` }
3425
3487
  });
3426
3488
  if (resp.ok) {