@synkro-sh/cli 1.3.58 → 1.3.59

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
@@ -3186,50 +3186,15 @@ jobs:
3186
3186
 
3187
3187
  // cli/installer/githubSetup.ts
3188
3188
  import { existsSync as existsSync5, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
3189
+ import { execSync as execSync2 } from "child_process";
3189
3190
  import { join as join4 } from "path";
3190
- async function encryptSecret(publicKeyBase64, secret) {
3191
- const sodium = await import("libsodium-wrappers").then((m) => m.default ?? m);
3192
- await sodium.ready;
3193
- const keyBytes = sodium.from_base64(publicKeyBase64, sodium.base64_variants.ORIGINAL);
3194
- const messageBytes = sodium.from_string(secret);
3195
- const encryptedBytes = sodium.crypto_box_seal(messageBytes, keyBytes);
3196
- return sodium.to_base64(encryptedBytes, sodium.base64_variants.ORIGINAL);
3197
- }
3198
- async function getRepoPublicKey(opts, owner, repo) {
3199
- const url = `https://api.github.com/repos/${owner}/${repo}/actions/secrets/public-key`;
3200
- const resp = await fetch(url, {
3201
- headers: {
3202
- Authorization: `Bearer ${opts.token}`,
3203
- Accept: "application/vnd.github+json",
3204
- "X-GitHub-Api-Version": "2022-11-28"
3205
- }
3206
- });
3207
- if (!resp.ok) {
3208
- const text = await resp.text().catch(() => "");
3209
- throw new Error(`GitHub API ${resp.status} fetching public key for ${owner}/${repo}: ${text.slice(0, 200)}`);
3210
- }
3211
- return await resp.json();
3212
- }
3213
- async function putRepoSecret(opts, owner, repo, secretName, secretValue, publicKey) {
3214
- const encryptedValue = await encryptSecret(publicKey.key, secretValue);
3215
- const url = `https://api.github.com/repos/${owner}/${repo}/actions/secrets/${encodeURIComponent(secretName)}`;
3216
- const resp = await fetch(url, {
3217
- method: "PUT",
3218
- headers: {
3219
- Authorization: `Bearer ${opts.token}`,
3220
- Accept: "application/vnd.github+json",
3221
- "X-GitHub-Api-Version": "2022-11-28",
3222
- "Content-Type": "application/json"
3223
- },
3224
- body: JSON.stringify({
3225
- encrypted_value: encryptedValue,
3226
- key_id: publicKey.key_id
3227
- })
3191
+ function ghSecretSet(token, owner, repo, name, value) {
3192
+ execSync2(`gh secret set ${name} --repo ${owner}/${repo} --body -`, {
3193
+ input: value,
3194
+ env: { ...process.env, GH_TOKEN: token },
3195
+ stdio: ["pipe", "ignore", "pipe"],
3196
+ timeout: 3e4
3228
3197
  });
3229
- if (!resp.ok) {
3230
- const text = await resp.text().catch(() => "");
3231
- throw new Error(`GitHub API ${resp.status} setting secret ${secretName}: ${text.slice(0, 200)}`);
3232
- }
3233
3198
  }
3234
3199
  async function listAccessibleRepos(opts) {
3235
3200
  const repos = [];
@@ -3257,11 +3222,15 @@ async function listAccessibleRepos(opts) {
3257
3222
  return repos;
3258
3223
  }
3259
3224
  async function pushSecretsToRepo(opts, owner, repo, secrets) {
3260
- const pubkey = await getRepoPublicKey(opts, owner, repo);
3225
+ try {
3226
+ execSync2("gh --version", { stdio: "ignore", timeout: 5e3 });
3227
+ } catch {
3228
+ throw new Error("GitHub CLI (gh) not found. Install it: https://cli.github.com");
3229
+ }
3261
3230
  if (secrets.claudeCodeOauthToken) {
3262
- await putRepoSecret(opts, owner, repo, "CLAUDE_CODE_OAUTH_TOKEN", secrets.claudeCodeOauthToken, pubkey);
3231
+ ghSecretSet(opts.token, owner, repo, "CLAUDE_CODE_OAUTH_TOKEN", secrets.claudeCodeOauthToken);
3263
3232
  }
3264
- await putRepoSecret(opts, owner, repo, "SYNKRO_API_KEY", secrets.synkroApiKey, pubkey);
3233
+ ghSecretSet(opts.token, owner, repo, "SYNKRO_API_KEY", secrets.synkroApiKey);
3265
3234
  }
3266
3235
  function writeWorkflowFile(repoRootPath) {
3267
3236
  const workflowDir = join4(repoRootPath, ".github", "workflows");
@@ -3294,12 +3263,12 @@ var init_githubSetup = __esm({
3294
3263
  });
3295
3264
 
3296
3265
  // cli/commands/repoConnect.ts
3297
- import { execSync as execSync2 } from "child_process";
3266
+ import { execSync as execSync3 } from "child_process";
3298
3267
  import { createServer as createServer2 } from "http";
3299
3268
  import { createInterface } from "readline";
3300
3269
  function detectGitRepo() {
3301
3270
  try {
3302
- const remoteUrl = execSync2("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
3271
+ const remoteUrl = execSync3("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
3303
3272
  const sshMatch = remoteUrl.match(/^git@[^:]+:(.+?)(?:\.git)?$/);
3304
3273
  const httpMatch = remoteUrl.match(/^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/);
3305
3274
  const match = sshMatch || httpMatch;
@@ -3515,7 +3484,7 @@ __export(setupGithub_exports, {
3515
3484
  });
3516
3485
  import { createInterface as createInterface2 } from "readline/promises";
3517
3486
  import { stdin as input, stdout as output } from "process";
3518
- import { execSync as execSync3, spawn as nodeSpawn } from "child_process";
3487
+ import { execSync as execSync4, spawn as nodeSpawn } from "child_process";
3519
3488
  import { existsSync as existsSync6, readFileSync as readFileSync4, unlinkSync as unlinkSync3 } from "fs";
3520
3489
  import { homedir as homedir4, platform as platform2 } from "os";
3521
3490
  import { join as join5 } from "path";
@@ -3725,7 +3694,7 @@ async function setupGithubCommand(opts = {}) {
3725
3694
  }
3726
3695
  } catch {
3727
3696
  try {
3728
- ghToken = execSync3("gh auth token", { encoding: "utf-8", timeout: 5e3 }).trim();
3697
+ ghToken = execSync4("gh auth token", { encoding: "utf-8", timeout: 5e3 }).trim();
3729
3698
  } catch {
3730
3699
  console.error("GitHub not connected. Run `synkro-cli setup-github` interactively to connect.");
3731
3700
  return;
@@ -3759,7 +3728,7 @@ async function setupGithubCommand(opts = {}) {
3759
3728
  }
3760
3729
  console.log(" Validating token...");
3761
3730
  try {
3762
- const validateResult = execSync3(
3731
+ const validateResult = execSync4(
3763
3732
  'claude --print --output-format json "say ok"',
3764
3733
  { env: { ...process.env, CLAUDE_CODE_OAUTH_TOKEN: claudeToken }, encoding: "utf-8", timeout: 3e4, stdio: ["ignore", "pipe", "pipe"] }
3765
3734
  );
@@ -3776,7 +3745,7 @@ async function setupGithubCommand(opts = {}) {
3776
3745
  if (opts.nonInteractive) {
3777
3746
  let currentFullName = null;
3778
3747
  try {
3779
- const remoteUrl = execSync3("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
3748
+ const remoteUrl = execSync4("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
3780
3749
  const m = remoteUrl.match(/(?:github\.com)[:/](.+?)(?:\.git)?$/);
3781
3750
  if (m) currentFullName = m[1];
3782
3751
  } catch {
@@ -3879,7 +3848,7 @@ __export(install_exports, {
3879
3848
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, chmodSync, readFileSync as readFileSync5, readdirSync } from "fs";
3880
3849
  import { homedir as homedir5 } from "os";
3881
3850
  import { join as join6 } from "path";
3882
- import { execSync as execSync4 } from "child_process";
3851
+ import { execSync as execSync5 } from "child_process";
3883
3852
  import { createInterface as createInterface3 } from "readline";
3884
3853
  function sanitizeGatewayCandidate(raw) {
3885
3854
  if (!raw) return void 0;
@@ -3985,7 +3954,7 @@ function writeConfigEnv(opts) {
3985
3954
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3986
3955
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3987
3956
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
3988
- `SYNKRO_VERSION=${shellQuoteSingle("1.3.58")}`
3957
+ `SYNKRO_VERSION=${shellQuoteSingle("1.3.59")}`
3989
3958
  ];
3990
3959
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
3991
3960
  if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
@@ -4000,11 +3969,11 @@ function writeConfigEnv(opts) {
4000
3969
  function collectLocalMetadata() {
4001
3970
  const meta = { platform: process.platform };
4002
3971
  try {
4003
- meta.display_name = execSync4("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
3972
+ meta.display_name = execSync5("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
4004
3973
  } catch {
4005
3974
  }
4006
3975
  try {
4007
- const remote = execSync4("git remote get-url origin", { encoding: "utf-8", timeout: 3e3 }).trim();
3976
+ const remote = execSync5("git remote get-url origin", { encoding: "utf-8", timeout: 3e3 }).trim();
4008
3977
  const sshMatch = remote.match(/^git@[^:]+:(.+?)(?:\.git)?$/);
4009
3978
  const httpMatch = remote.match(/^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/);
4010
3979
  const m = sshMatch || httpMatch;
@@ -4012,7 +3981,7 @@ function collectLocalMetadata() {
4012
3981
  } catch {
4013
3982
  }
4014
3983
  try {
4015
- meta.cc_version = execSync4("claude --version", { encoding: "utf-8", timeout: 5e3 }).trim().split("\n")[0];
3984
+ meta.cc_version = execSync5("claude --version", { encoding: "utf-8", timeout: 5e3 }).trim().split("\n")[0];
4016
3985
  } catch {
4017
3986
  }
4018
3987
  const claudeDir = join6(homedir5(), ".claude");
@@ -4030,7 +3999,7 @@ function collectLocalMetadata() {
4030
3999
  } catch {
4031
4000
  }
4032
4001
  try {
4033
- const mcpList = execSync4("claude mcp list 2>/dev/null", { encoding: "utf-8", timeout: 1e4 });
4002
+ const mcpList = execSync5("claude mcp list 2>/dev/null", { encoding: "utf-8", timeout: 1e4 });
4034
4003
  const connected = mcpList.split("\n").filter((l) => l.includes("Connected")).map((l) => l.split(":")[0].trim()).filter(Boolean);
4035
4004
  if (connected.length) meta.mcp_servers_connected = connected;
4036
4005
  } catch {
@@ -4333,7 +4302,7 @@ async function installCommand(opts = {}) {
4333
4302
  }
4334
4303
  function detectGitRepo2() {
4335
4304
  try {
4336
- const remoteUrl = execSync4("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
4305
+ const remoteUrl = execSync5("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
4337
4306
  const sshMatch = remoteUrl.match(/^git@[^:]+:(.+?)(?:\.git)?$/);
4338
4307
  const httpMatch = remoteUrl.match(/^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/);
4339
4308
  const match = sshMatch || httpMatch;
@@ -4915,7 +4884,7 @@ var scanPr_exports = {};
4915
4884
  __export(scanPr_exports, {
4916
4885
  scanPrCommand: () => scanPrCommand
4917
4886
  });
4918
- import { execSync as execSync5, spawn } from "child_process";
4887
+ import { execSync as execSync6, spawn } from "child_process";
4919
4888
  import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
4920
4889
  import { join as join9 } from "path";
4921
4890
  function parseMatchSpec(condition) {
@@ -5023,7 +4992,7 @@ function shouldSkipFile(filename) {
5023
4992
  return SKIP_FILE_PATTERNS.some((p) => p.test(filename));
5024
4993
  }
5025
4994
  function ghJson(args2) {
5026
- const out = execSync5(`gh ${args2.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ")}`, {
4995
+ const out = execSync6(`gh ${args2.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ")}`, {
5027
4996
  encoding: "utf-8",
5028
4997
  maxBuffer: 16 * 1024 * 1024
5029
4998
  });
@@ -5321,7 +5290,7 @@ function postPrReview(repo, prNumber, sha, review, skipLineReview = false) {
5321
5290
  ${review.summary}
5322
5291
 
5323
5292
  ` + review.comments.map((c) => `**${c.path}:${c.line}** \u2014 ${c.body}`).join("\n\n");
5324
- execSync5(`gh api -X POST /repos/${repo}/issues/${prNumber}/comments --input -`, {
5293
+ execSync6(`gh api -X POST /repos/${repo}/issues/${prNumber}/comments --input -`, {
5325
5294
  encoding: "utf-8",
5326
5295
  input: JSON.stringify({ body }),
5327
5296
  stdio: ["pipe", "ignore", "pipe"]
@@ -5346,7 +5315,7 @@ ${review.summary}`,
5346
5315
  comments: review.comments
5347
5316
  });
5348
5317
  try {
5349
- execSync5(`gh api -X POST /repos/${repo}/pulls/${prNumber}/reviews --input -`, {
5318
+ execSync6(`gh api -X POST /repos/${repo}/pulls/${prNumber}/reviews --input -`, {
5350
5319
  encoding: "utf-8",
5351
5320
  input: body,
5352
5321
  stdio: ["pipe", "pipe", "pipe"]
@@ -5381,7 +5350,7 @@ function postCheckRun(repo, sha, conclusion, findings) {
5381
5350
  }
5382
5351
  });
5383
5352
  try {
5384
- execSync5(`gh api -X POST /repos/${repo}/check-runs --input -`, {
5353
+ execSync6(`gh api -X POST /repos/${repo}/check-runs --input -`, {
5385
5354
  encoding: "utf-8",
5386
5355
  input: body,
5387
5356
  stdio: ["pipe", "ignore", "pipe"]
@@ -5407,7 +5376,7 @@ function readRepoDeps() {
5407
5376
  }
5408
5377
  function getFullFileContent(filename) {
5409
5378
  try {
5410
- return execSync5(`git show HEAD:${filename}`, { encoding: "utf-8", maxBuffer: 128 * 1024 });
5379
+ return execSync6(`git show HEAD:${filename}`, { encoding: "utf-8", maxBuffer: 128 * 1024 });
5411
5380
  } catch {
5412
5381
  return null;
5413
5382
  }