@synkro-sh/cli 1.3.57 → 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 +44 -77
- package/dist/bootstrap.js.map +1 -1
- package/package.json +2 -4
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
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3231
|
+
ghSecretSet(opts.token, owner, repo, "CLAUDE_CODE_OAUTH_TOKEN", secrets.claudeCodeOauthToken);
|
|
3263
3232
|
}
|
|
3264
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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";
|
|
@@ -3594,7 +3563,9 @@ function captureClaudeSetupToken() {
|
|
|
3594
3563
|
let raw = "";
|
|
3595
3564
|
try {
|
|
3596
3565
|
raw = readFileSync4(tmpFile, "utf-8");
|
|
3597
|
-
} catch {
|
|
3566
|
+
} catch (e) {
|
|
3567
|
+
reject(new Error(`Could not read script output file: ${e.message}`));
|
|
3568
|
+
return;
|
|
3598
3569
|
}
|
|
3599
3570
|
try {
|
|
3600
3571
|
unlinkSync3(tmpFile);
|
|
@@ -3604,20 +3575,16 @@ function captureClaudeSetupToken() {
|
|
|
3604
3575
|
reject(new Error(`claude setup-token exited with code ${code}`));
|
|
3605
3576
|
return;
|
|
3606
3577
|
}
|
|
3607
|
-
const
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
const section = stripped.slice(startIdx, endIdx).replace(/\s/g, "");
|
|
3615
|
-
const match = section.match(/sk-ant-oat01-[A-Za-z0-9_-]+/);
|
|
3616
|
-
if (!match) {
|
|
3617
|
-
reject(new Error("Could not find token in claude setup-token output"));
|
|
3578
|
+
const yellowRe = /\x1B\[38;2;255;193;7m([^\x1B]*)/g;
|
|
3579
|
+
let yellow = "";
|
|
3580
|
+
let m;
|
|
3581
|
+
while ((m = yellowRe.exec(raw)) !== null) yellow += m[1];
|
|
3582
|
+
const token = yellow.replace(/\s/g, "").match(/sk-ant-oat01-[A-Za-z0-9_-]+/);
|
|
3583
|
+
if (!token) {
|
|
3584
|
+
reject(new Error(`Could not find token in claude setup-token output (file=${raw.length}b, yellow=${yellow.length}b)`));
|
|
3618
3585
|
return;
|
|
3619
3586
|
}
|
|
3620
|
-
resolve2(
|
|
3587
|
+
resolve2(token[0]);
|
|
3621
3588
|
});
|
|
3622
3589
|
});
|
|
3623
3590
|
}
|
|
@@ -3727,7 +3694,7 @@ async function setupGithubCommand(opts = {}) {
|
|
|
3727
3694
|
}
|
|
3728
3695
|
} catch {
|
|
3729
3696
|
try {
|
|
3730
|
-
ghToken =
|
|
3697
|
+
ghToken = execSync4("gh auth token", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
3731
3698
|
} catch {
|
|
3732
3699
|
console.error("GitHub not connected. Run `synkro-cli setup-github` interactively to connect.");
|
|
3733
3700
|
return;
|
|
@@ -3761,7 +3728,7 @@ async function setupGithubCommand(opts = {}) {
|
|
|
3761
3728
|
}
|
|
3762
3729
|
console.log(" Validating token...");
|
|
3763
3730
|
try {
|
|
3764
|
-
const validateResult =
|
|
3731
|
+
const validateResult = execSync4(
|
|
3765
3732
|
'claude --print --output-format json "say ok"',
|
|
3766
3733
|
{ env: { ...process.env, CLAUDE_CODE_OAUTH_TOKEN: claudeToken }, encoding: "utf-8", timeout: 3e4, stdio: ["ignore", "pipe", "pipe"] }
|
|
3767
3734
|
);
|
|
@@ -3778,7 +3745,7 @@ async function setupGithubCommand(opts = {}) {
|
|
|
3778
3745
|
if (opts.nonInteractive) {
|
|
3779
3746
|
let currentFullName = null;
|
|
3780
3747
|
try {
|
|
3781
|
-
const remoteUrl =
|
|
3748
|
+
const remoteUrl = execSync4("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
3782
3749
|
const m = remoteUrl.match(/(?:github\.com)[:/](.+?)(?:\.git)?$/);
|
|
3783
3750
|
if (m) currentFullName = m[1];
|
|
3784
3751
|
} catch {
|
|
@@ -3881,7 +3848,7 @@ __export(install_exports, {
|
|
|
3881
3848
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, chmodSync, readFileSync as readFileSync5, readdirSync } from "fs";
|
|
3882
3849
|
import { homedir as homedir5 } from "os";
|
|
3883
3850
|
import { join as join6 } from "path";
|
|
3884
|
-
import { execSync as
|
|
3851
|
+
import { execSync as execSync5 } from "child_process";
|
|
3885
3852
|
import { createInterface as createInterface3 } from "readline";
|
|
3886
3853
|
function sanitizeGatewayCandidate(raw) {
|
|
3887
3854
|
if (!raw) return void 0;
|
|
@@ -3987,7 +3954,7 @@ function writeConfigEnv(opts) {
|
|
|
3987
3954
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3988
3955
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3989
3956
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3990
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.3.
|
|
3957
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.3.59")}`
|
|
3991
3958
|
];
|
|
3992
3959
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
3993
3960
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|
|
@@ -4002,11 +3969,11 @@ function writeConfigEnv(opts) {
|
|
|
4002
3969
|
function collectLocalMetadata() {
|
|
4003
3970
|
const meta = { platform: process.platform };
|
|
4004
3971
|
try {
|
|
4005
|
-
meta.display_name =
|
|
3972
|
+
meta.display_name = execSync5("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
4006
3973
|
} catch {
|
|
4007
3974
|
}
|
|
4008
3975
|
try {
|
|
4009
|
-
const remote =
|
|
3976
|
+
const remote = execSync5("git remote get-url origin", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
4010
3977
|
const sshMatch = remote.match(/^git@[^:]+:(.+?)(?:\.git)?$/);
|
|
4011
3978
|
const httpMatch = remote.match(/^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/);
|
|
4012
3979
|
const m = sshMatch || httpMatch;
|
|
@@ -4014,7 +3981,7 @@ function collectLocalMetadata() {
|
|
|
4014
3981
|
} catch {
|
|
4015
3982
|
}
|
|
4016
3983
|
try {
|
|
4017
|
-
meta.cc_version =
|
|
3984
|
+
meta.cc_version = execSync5("claude --version", { encoding: "utf-8", timeout: 5e3 }).trim().split("\n")[0];
|
|
4018
3985
|
} catch {
|
|
4019
3986
|
}
|
|
4020
3987
|
const claudeDir = join6(homedir5(), ".claude");
|
|
@@ -4032,7 +3999,7 @@ function collectLocalMetadata() {
|
|
|
4032
3999
|
} catch {
|
|
4033
4000
|
}
|
|
4034
4001
|
try {
|
|
4035
|
-
const mcpList =
|
|
4002
|
+
const mcpList = execSync5("claude mcp list 2>/dev/null", { encoding: "utf-8", timeout: 1e4 });
|
|
4036
4003
|
const connected = mcpList.split("\n").filter((l) => l.includes("Connected")).map((l) => l.split(":")[0].trim()).filter(Boolean);
|
|
4037
4004
|
if (connected.length) meta.mcp_servers_connected = connected;
|
|
4038
4005
|
} catch {
|
|
@@ -4335,7 +4302,7 @@ async function installCommand(opts = {}) {
|
|
|
4335
4302
|
}
|
|
4336
4303
|
function detectGitRepo2() {
|
|
4337
4304
|
try {
|
|
4338
|
-
const remoteUrl =
|
|
4305
|
+
const remoteUrl = execSync5("git remote get-url origin", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
4339
4306
|
const sshMatch = remoteUrl.match(/^git@[^:]+:(.+?)(?:\.git)?$/);
|
|
4340
4307
|
const httpMatch = remoteUrl.match(/^https?:\/\/[^/]+\/(.+?)(?:\.git)?$/);
|
|
4341
4308
|
const match = sshMatch || httpMatch;
|
|
@@ -4917,7 +4884,7 @@ var scanPr_exports = {};
|
|
|
4917
4884
|
__export(scanPr_exports, {
|
|
4918
4885
|
scanPrCommand: () => scanPrCommand
|
|
4919
4886
|
});
|
|
4920
|
-
import { execSync as
|
|
4887
|
+
import { execSync as execSync6, spawn } from "child_process";
|
|
4921
4888
|
import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
|
|
4922
4889
|
import { join as join9 } from "path";
|
|
4923
4890
|
function parseMatchSpec(condition) {
|
|
@@ -5025,7 +4992,7 @@ function shouldSkipFile(filename) {
|
|
|
5025
4992
|
return SKIP_FILE_PATTERNS.some((p) => p.test(filename));
|
|
5026
4993
|
}
|
|
5027
4994
|
function ghJson(args2) {
|
|
5028
|
-
const out =
|
|
4995
|
+
const out = execSync6(`gh ${args2.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ")}`, {
|
|
5029
4996
|
encoding: "utf-8",
|
|
5030
4997
|
maxBuffer: 16 * 1024 * 1024
|
|
5031
4998
|
});
|
|
@@ -5323,7 +5290,7 @@ function postPrReview(repo, prNumber, sha, review, skipLineReview = false) {
|
|
|
5323
5290
|
${review.summary}
|
|
5324
5291
|
|
|
5325
5292
|
` + review.comments.map((c) => `**${c.path}:${c.line}** \u2014 ${c.body}`).join("\n\n");
|
|
5326
|
-
|
|
5293
|
+
execSync6(`gh api -X POST /repos/${repo}/issues/${prNumber}/comments --input -`, {
|
|
5327
5294
|
encoding: "utf-8",
|
|
5328
5295
|
input: JSON.stringify({ body }),
|
|
5329
5296
|
stdio: ["pipe", "ignore", "pipe"]
|
|
@@ -5348,7 +5315,7 @@ ${review.summary}`,
|
|
|
5348
5315
|
comments: review.comments
|
|
5349
5316
|
});
|
|
5350
5317
|
try {
|
|
5351
|
-
|
|
5318
|
+
execSync6(`gh api -X POST /repos/${repo}/pulls/${prNumber}/reviews --input -`, {
|
|
5352
5319
|
encoding: "utf-8",
|
|
5353
5320
|
input: body,
|
|
5354
5321
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -5383,7 +5350,7 @@ function postCheckRun(repo, sha, conclusion, findings) {
|
|
|
5383
5350
|
}
|
|
5384
5351
|
});
|
|
5385
5352
|
try {
|
|
5386
|
-
|
|
5353
|
+
execSync6(`gh api -X POST /repos/${repo}/check-runs --input -`, {
|
|
5387
5354
|
encoding: "utf-8",
|
|
5388
5355
|
input: body,
|
|
5389
5356
|
stdio: ["pipe", "ignore", "pipe"]
|
|
@@ -5409,7 +5376,7 @@ function readRepoDeps() {
|
|
|
5409
5376
|
}
|
|
5410
5377
|
function getFullFileContent(filename) {
|
|
5411
5378
|
try {
|
|
5412
|
-
return
|
|
5379
|
+
return execSync6(`git show HEAD:${filename}`, { encoding: "utf-8", maxBuffer: 128 * 1024 });
|
|
5413
5380
|
} catch {
|
|
5414
5381
|
return null;
|
|
5415
5382
|
}
|