@synkro-sh/cli 1.6.49 → 1.6.51
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 +108 -44
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1239,6 +1239,29 @@ function parseSynkroYaml(raw: string): Record<string, any> {
|
|
|
1239
1239
|
|
|
1240
1240
|
let _synkroFileCache: SynkroFileConfig | undefined;
|
|
1241
1241
|
|
|
1242
|
+
/** Map any provider alias to the internal pool token. */
|
|
1243
|
+
function normalizePoolToken(p: unknown): 'auto' | 'claude' | 'cursor' {
|
|
1244
|
+
if (p === 'cursor') return 'cursor';
|
|
1245
|
+
if (p === 'claude' || p === 'claude-code' || p === 'cc' || p === 'claude_code') return 'claude';
|
|
1246
|
+
return 'auto';
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Pull an explicit worker count for a provider, accepting both the unified
|
|
1251
|
+
* grader-block form (grader: claude-code: N) and the legacy workers block
|
|
1252
|
+
* (workers: claude: N). Provider aliases (claude / claude-code / cc) all match.
|
|
1253
|
+
*/
|
|
1254
|
+
function pickWorkerCount(parsed: any, kind: 'claude_code' | 'cursor'): number | undefined {
|
|
1255
|
+
const keys = kind === 'cursor' ? ['cursor'] : ['claude-code', 'claude', 'cc', 'claude_code'];
|
|
1256
|
+
for (const src of [parsed?.grader, parsed?.workers]) {
|
|
1257
|
+
if (!src || typeof src !== 'object') continue;
|
|
1258
|
+
for (const k of keys) {
|
|
1259
|
+
if (typeof src[k] === 'number') return Math.max(0, Math.floor(src[k]));
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
return undefined;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1242
1265
|
export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
1243
1266
|
if (_synkroFileCache) return _synkroFileCache;
|
|
1244
1267
|
const root = cwd ? findGitRoot(cwd) : '';
|
|
@@ -1256,12 +1279,14 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1256
1279
|
version: parsed.version || 1,
|
|
1257
1280
|
harness: harness.length > 0 ? harness : ['claude-code', 'cursor'],
|
|
1258
1281
|
grader: {
|
|
1259
|
-
pool:
|
|
1282
|
+
pool: normalizePoolToken(parsed.grader?.pool),
|
|
1260
1283
|
mode: ['local', 'byok'].includes(parsed.grader?.mode) ? parsed.grader.mode : undefined,
|
|
1261
1284
|
},
|
|
1262
1285
|
workers: {
|
|
1263
|
-
|
|
1264
|
-
|
|
1286
|
+
// Counts may live under the grader block (unified form) or the legacy
|
|
1287
|
+
// workers block, keyed by claude / claude-code / cc / cursor.
|
|
1288
|
+
...(pickWorkerCount(parsed, 'claude_code') != null ? { claude: pickWorkerCount(parsed, 'claude_code') } : {}),
|
|
1289
|
+
...(pickWorkerCount(parsed, 'cursor') != null ? { cursor: pickWorkerCount(parsed, 'cursor') } : {}),
|
|
1265
1290
|
},
|
|
1266
1291
|
ruleset: typeof parsed.ruleset === 'string' ? parsed.ruleset : 'default',
|
|
1267
1292
|
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((s: unknown) => typeof s === 'string') : [],
|
|
@@ -1278,8 +1303,9 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1278
1303
|
}
|
|
1279
1304
|
|
|
1280
1305
|
export function effectiveGraderPool(synkroFile: SynkroFileConfig, hookAgentKind: AgentKind): AgentKind {
|
|
1281
|
-
|
|
1282
|
-
if (
|
|
1306
|
+
const pool = normalizePoolToken(synkroFile.grader.pool);
|
|
1307
|
+
if (pool === 'auto') return hookAgentKind;
|
|
1308
|
+
if (pool === 'claude') return 'claude_code';
|
|
1283
1309
|
return 'cursor';
|
|
1284
1310
|
}
|
|
1285
1311
|
|
|
@@ -1294,7 +1320,16 @@ export function synkroFilePresent(cwd?: string): boolean {
|
|
|
1294
1320
|
try {
|
|
1295
1321
|
const root = cwd ? findGitRoot(cwd) : '';
|
|
1296
1322
|
if (!root) return false;
|
|
1297
|
-
|
|
1323
|
+
// ~/.synkro is Synkro's CONFIG DIRECTORY, not a repo marker. If the git root
|
|
1324
|
+
// resolves to HOME (dotfiles tracked in git, or working in a non-git folder
|
|
1325
|
+
// under ~), never treat it as onboarded \u2014 otherwise grading fires in every
|
|
1326
|
+
// directory under home.
|
|
1327
|
+
if (root === HOME) return false;
|
|
1328
|
+
// A repo is onboarded ONLY via a regular .synkro FILE at its root. statSync +
|
|
1329
|
+
// isFile is required because existsSync also matches a DIRECTORY named
|
|
1330
|
+
// .synkro (exactly what ~/.synkro is) \u2014 the root cause of grading running in
|
|
1331
|
+
// repos that have no .synkro file.
|
|
1332
|
+
return statSync(root + '/.synkro').isFile();
|
|
1298
1333
|
} catch { return false; }
|
|
1299
1334
|
}
|
|
1300
1335
|
|
|
@@ -7396,7 +7431,10 @@ __export(dockerInstall_exports, {
|
|
|
7396
7431
|
dockerStop: () => dockerStop,
|
|
7397
7432
|
dockerUpdate: () => dockerUpdate,
|
|
7398
7433
|
imageTag: () => imageTag,
|
|
7434
|
+
normalizeProvider: () => normalizeProvider,
|
|
7435
|
+
poolLabel: () => poolLabel,
|
|
7399
7436
|
readContainerConfig: () => readContainerConfig,
|
|
7437
|
+
resolveGraderPool: () => resolveGraderPool,
|
|
7400
7438
|
resolveWorkerConfig: () => resolveWorkerConfig,
|
|
7401
7439
|
splitWorkers: () => splitWorkers,
|
|
7402
7440
|
waitForContainerReady: () => waitForContainerReady,
|
|
@@ -7423,6 +7461,39 @@ function normalizeProvider(p) {
|
|
|
7423
7461
|
if (v === "cursor") return "cursor";
|
|
7424
7462
|
return null;
|
|
7425
7463
|
}
|
|
7464
|
+
function resolveGraderPool(parsed) {
|
|
7465
|
+
const warnings = [];
|
|
7466
|
+
const grader = parsed?.grader && typeof parsed.grader === "object" ? parsed.grader : {};
|
|
7467
|
+
const counts = {};
|
|
7468
|
+
const collect = (obj, where, flagUnknown) => {
|
|
7469
|
+
if (!obj || typeof obj !== "object") return;
|
|
7470
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
7471
|
+
if (typeof v !== "number") continue;
|
|
7472
|
+
const np = normalizeProvider(k);
|
|
7473
|
+
if (np === "claude_code") counts.claude_code = Math.max(0, Math.floor(v));
|
|
7474
|
+
else if (np === "cursor") counts.cursor = Math.max(0, Math.floor(v));
|
|
7475
|
+
else if (flagUnknown) {
|
|
7476
|
+
warnings.push(`.synkro: ${where}.${k} is not a known provider (use claude-code or cursor) \u2014 ignored`);
|
|
7477
|
+
}
|
|
7478
|
+
}
|
|
7479
|
+
};
|
|
7480
|
+
collect(grader, "grader", true);
|
|
7481
|
+
collect(parsed?.workers, "workers", false);
|
|
7482
|
+
let pool = "auto";
|
|
7483
|
+
const rawPool = grader.pool;
|
|
7484
|
+
if (rawPool != null && rawPool !== "auto") {
|
|
7485
|
+
const np = normalizeProvider(String(rawPool));
|
|
7486
|
+
if (np) pool = np;
|
|
7487
|
+
else warnings.push(`.synkro: grader.pool="${rawPool}" is not recognized (use auto | claude-code | cursor) \u2014 falling back to auto`);
|
|
7488
|
+
}
|
|
7489
|
+
if (counts.claude_code != null || counts.cursor != null) {
|
|
7490
|
+
return { claudeWorkers: counts.claude_code, cursorWorkers: counts.cursor, pool, warnings };
|
|
7491
|
+
}
|
|
7492
|
+
return { pool, warnings };
|
|
7493
|
+
}
|
|
7494
|
+
function poolLabel(pool) {
|
|
7495
|
+
return pool === "claude_code" ? "claude-code" : pool;
|
|
7496
|
+
}
|
|
7426
7497
|
function parseSynkroYaml(raw) {
|
|
7427
7498
|
const result = {};
|
|
7428
7499
|
const lines = raw.split("\n");
|
|
@@ -7469,18 +7540,15 @@ function parseSynkroYaml(raw) {
|
|
|
7469
7540
|
function readSynkroFileConfig() {
|
|
7470
7541
|
try {
|
|
7471
7542
|
const root = execSync4("git rev-parse --show-toplevel 2>/dev/null", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
7472
|
-
if (!root) return { pool: "auto" };
|
|
7543
|
+
if (!root) return { pool: "auto", warnings: [] };
|
|
7473
7544
|
const fp = join6(root, ".synkro");
|
|
7474
|
-
if (!existsSync8(fp)) return { pool: "auto" };
|
|
7545
|
+
if (!existsSync8(fp)) return { pool: "auto", warnings: [] };
|
|
7475
7546
|
const raw = readFileSync6(fp, "utf-8");
|
|
7476
7547
|
const parsed = raw.trimStart().startsWith("{") ? JSON.parse(raw) : parseSynkroYaml(raw);
|
|
7477
|
-
|
|
7478
|
-
const cw = typeof parsed?.workers?.claude === "number" ? Math.max(0, Math.floor(parsed.workers.claude)) : void 0;
|
|
7479
|
-
const curw = typeof parsed?.workers?.cursor === "number" ? Math.max(0, Math.floor(parsed.workers.cursor)) : void 0;
|
|
7480
|
-
return { pool, claudeWorkers: cw, cursorWorkers: curw };
|
|
7548
|
+
return resolveGraderPool(parsed);
|
|
7481
7549
|
} catch {
|
|
7482
7550
|
}
|
|
7483
|
-
return { pool: "auto" };
|
|
7551
|
+
return { pool: "auto", warnings: [] };
|
|
7484
7552
|
}
|
|
7485
7553
|
function resolveWorkerConfig(rest) {
|
|
7486
7554
|
let workers = 8;
|
|
@@ -7516,6 +7584,7 @@ function resolveWorkerConfig(rest) {
|
|
|
7516
7584
|
let provs = providers;
|
|
7517
7585
|
if (provs.length === 0) {
|
|
7518
7586
|
const sc = readSynkroFileConfig();
|
|
7587
|
+
for (const w of sc.warnings) console.warn(` \u26A0 ${w}`);
|
|
7519
7588
|
if (sc.claudeWorkers != null || sc.cursorWorkers != null) {
|
|
7520
7589
|
const cw = sc.claudeWorkers || 0;
|
|
7521
7590
|
const curw = sc.cursorWorkers || 0;
|
|
@@ -7523,7 +7592,7 @@ function resolveWorkerConfig(rest) {
|
|
|
7523
7592
|
}
|
|
7524
7593
|
if (sc.pool === "cursor") {
|
|
7525
7594
|
provs = ["cursor"];
|
|
7526
|
-
} else if (sc.pool === "
|
|
7595
|
+
} else if (sc.pool === "claude_code") {
|
|
7527
7596
|
provs = ["claude_code"];
|
|
7528
7597
|
} else {
|
|
7529
7598
|
provs = detectAgents().map((a) => a.kind);
|
|
@@ -8647,7 +8716,7 @@ function writeConfigEnv(opts) {
|
|
|
8647
8716
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8648
8717
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8649
8718
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8650
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8719
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.51")}`
|
|
8651
8720
|
];
|
|
8652
8721
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8653
8722
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -8830,8 +8899,8 @@ async function installCommand(opts = {}) {
|
|
|
8830
8899
|
let agents;
|
|
8831
8900
|
let gradingMode;
|
|
8832
8901
|
let storageMode;
|
|
8833
|
-
let transcriptCC =
|
|
8834
|
-
let transcriptCursor =
|
|
8902
|
+
let transcriptCC = false;
|
|
8903
|
+
let transcriptCursor = false;
|
|
8835
8904
|
if (existingSynkro) {
|
|
8836
8905
|
const wantCC = existingSynkro.harness.includes("claude-code");
|
|
8837
8906
|
const wantCursor = existingSynkro.harness.includes("cursor");
|
|
@@ -8841,11 +8910,10 @@ async function installCommand(opts = {}) {
|
|
|
8841
8910
|
if (agents.length === 0 && detected.length > 0) agents = detected;
|
|
8842
8911
|
gradingMode = existingSynkro.grader.mode === "byok" ? "byok" : "local";
|
|
8843
8912
|
storageMode = "local";
|
|
8844
|
-
transcriptCC = agents.some((a) => a.kind === "claude_code");
|
|
8845
|
-
transcriptCursor = agents.some((a) => a.kind === "cursor");
|
|
8846
8913
|
console.log(`Using .synkro config:`);
|
|
8914
|
+
for (const w of existingSynkro.warnings) console.warn(` \u26A0 ${w}`);
|
|
8847
8915
|
console.log(` harness: ${existingSynkro.harness.join(", ")}`);
|
|
8848
|
-
console.log(` grading: ${gradingMode} pool: ${existingSynkro.grader.pool}`);
|
|
8916
|
+
console.log(` grading: ${gradingMode} pool: ${poolLabel(existingSynkro.grader.pool)}`);
|
|
8849
8917
|
for (const a of agents) {
|
|
8850
8918
|
console.log(` \u2713 ${a.name}${a.version ? ` (${a.version})` : ""}`);
|
|
8851
8919
|
}
|
|
@@ -8873,18 +8941,23 @@ async function installCommand(opts = {}) {
|
|
|
8873
8941
|
console.log(" BYOK grading uses your own provider key \u2014 register one in the");
|
|
8874
8942
|
console.log(" dashboard under Settings \u2192 Provider Keys if you have not already.\n");
|
|
8875
8943
|
}
|
|
8944
|
+
}
|
|
8945
|
+
{
|
|
8876
8946
|
const wantCC = agents.some((a) => a.kind === "claude_code");
|
|
8877
8947
|
const wantCursor = agents.some((a) => a.kind === "cursor");
|
|
8878
|
-
if (process.stdin.isTTY) {
|
|
8948
|
+
if ((wantCC || wantCursor) && process.stdin.isTTY) {
|
|
8879
8949
|
const src = await promptTranscriptSources(wantCC, wantCursor);
|
|
8880
8950
|
transcriptCC = src.cc;
|
|
8881
8951
|
transcriptCursor = src.cursor;
|
|
8882
8952
|
const chosen = [src.cc && "Claude Code", src.cursor && "Cursor"].filter(Boolean).join(" + ");
|
|
8883
8953
|
console.log(chosen ? ` \u2713 Session import: ${chosen}
|
|
8884
8954
|
` : " \u2717 Session import skipped\n");
|
|
8885
|
-
} else {
|
|
8955
|
+
} else if ((wantCC || wantCursor) && process.env.SYNKRO_IMPORT_TRANSCRIPTS === "yes") {
|
|
8886
8956
|
transcriptCC = wantCC;
|
|
8887
8957
|
transcriptCursor = wantCursor;
|
|
8958
|
+
console.log(" \u2713 Session import: SYNKRO_IMPORT_TRANSCRIPTS=yes\n");
|
|
8959
|
+
} else if (!process.stdin.isTTY) {
|
|
8960
|
+
console.log(" \u2717 Session import skipped (non-interactive; set SYNKRO_IMPORT_TRANSCRIPTS=yes to opt in)\n");
|
|
8888
8961
|
}
|
|
8889
8962
|
}
|
|
8890
8963
|
const transcriptConsent = transcriptCC || transcriptCursor;
|
|
@@ -9089,6 +9162,7 @@ async function installCommand(opts = {}) {
|
|
|
9089
9162
|
}
|
|
9090
9163
|
console.log("Installing Synkro server container...");
|
|
9091
9164
|
const sf = readFullSynkroFile();
|
|
9165
|
+
for (const w of sf?.warnings || []) console.warn(` \u26A0 ${w}`);
|
|
9092
9166
|
let claudeWorkers;
|
|
9093
9167
|
let cursorWorkers;
|
|
9094
9168
|
if (sf && (sf.workers.claude != null || sf.workers.cursor != null)) {
|
|
@@ -9101,18 +9175,18 @@ async function installCommand(opts = {}) {
|
|
|
9101
9175
|
console.log(` .synkro: explicit workers \u2014 ${claudeWorkers} claude + ${cursorWorkers} cursor`);
|
|
9102
9176
|
} else {
|
|
9103
9177
|
const totalWorkers = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "8", 10);
|
|
9104
|
-
const synkroFilePool = sf?.grader?.pool ||
|
|
9178
|
+
const synkroFilePool = sf?.grader?.pool || "auto";
|
|
9105
9179
|
let providers = [];
|
|
9106
9180
|
if (synkroFilePool === "cursor") {
|
|
9107
9181
|
providers = ["cursor"];
|
|
9108
|
-
} else if (synkroFilePool === "
|
|
9182
|
+
} else if (synkroFilePool === "claude_code") {
|
|
9109
9183
|
providers = ["claude_code"];
|
|
9110
9184
|
} else {
|
|
9111
9185
|
if (hasClaudeCode) providers.push("claude_code");
|
|
9112
9186
|
if (hasCursor) providers.push("cursor");
|
|
9113
9187
|
}
|
|
9114
9188
|
({ claudeWorkers, cursorWorkers } = splitWorkers(totalWorkers, providers));
|
|
9115
|
-
if (synkroFilePool !== "auto") console.log(` .synkro: grader pool set to ${synkroFilePool}`);
|
|
9189
|
+
if (synkroFilePool !== "auto") console.log(` .synkro: grader pool set to ${poolLabel(synkroFilePool)}`);
|
|
9116
9190
|
}
|
|
9117
9191
|
console.log(` worker pool: ${claudeWorkers} claude + ${cursorWorkers} cursor`);
|
|
9118
9192
|
const connectedRepo = detectGitRepo2() || void 0;
|
|
@@ -9333,19 +9407,6 @@ function writeSynkroFileIfMissing(opts) {
|
|
|
9333
9407
|
} catch {
|
|
9334
9408
|
}
|
|
9335
9409
|
}
|
|
9336
|
-
function readSynkroFilePool() {
|
|
9337
|
-
try {
|
|
9338
|
-
const root = execSync6("git rev-parse --show-toplevel", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
9339
|
-
if (!root) return "auto";
|
|
9340
|
-
const fp = join8(root, ".synkro");
|
|
9341
|
-
if (!existsSync10(fp)) return "auto";
|
|
9342
|
-
const parsed = parseSynkroFileRaw(readFileSync8(fp, "utf-8"));
|
|
9343
|
-
const pool = parsed?.grader?.pool;
|
|
9344
|
-
if (pool === "cursor" || pool === "claude") return pool;
|
|
9345
|
-
} catch {
|
|
9346
|
-
}
|
|
9347
|
-
return "auto";
|
|
9348
|
-
}
|
|
9349
9410
|
function readFullSynkroFile() {
|
|
9350
9411
|
try {
|
|
9351
9412
|
const root = execSync6("git rev-parse --show-toplevel", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
@@ -9355,16 +9416,18 @@ function readFullSynkroFile() {
|
|
|
9355
9416
|
const parsed = parseSynkroFileRaw(readFileSync8(fp, "utf-8"));
|
|
9356
9417
|
const valid = ["claude-code", "cursor"];
|
|
9357
9418
|
const harness = Array.isArray(parsed.harness) ? parsed.harness.filter((h) => valid.includes(h)) : ["claude-code", "cursor"];
|
|
9419
|
+
const resolved = resolveGraderPool(parsed);
|
|
9358
9420
|
return {
|
|
9359
9421
|
harness: harness.length > 0 ? harness : ["claude-code", "cursor"],
|
|
9360
9422
|
grader: {
|
|
9361
|
-
pool:
|
|
9423
|
+
pool: resolved.pool,
|
|
9362
9424
|
mode: ["local", "byok"].includes(parsed.grader?.mode) ? parsed.grader.mode : "local"
|
|
9363
9425
|
},
|
|
9364
9426
|
workers: {
|
|
9365
|
-
...
|
|
9366
|
-
...
|
|
9427
|
+
...resolved.claudeWorkers != null ? { claude: resolved.claudeWorkers } : {},
|
|
9428
|
+
...resolved.cursorWorkers != null ? { cursor: resolved.cursorWorkers } : {}
|
|
9367
9429
|
},
|
|
9430
|
+
warnings: resolved.warnings,
|
|
9368
9431
|
ruleset: parsed.ruleset || "default",
|
|
9369
9432
|
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((s) => typeof s === "string" && s.endsWith(".md")) : [],
|
|
9370
9433
|
scanning: { cwe: parsed.scanning?.cwe !== false, cve: parsed.scanning?.cve !== false },
|
|
@@ -9382,7 +9445,8 @@ function reconcileHarness() {
|
|
|
9382
9445
|
}
|
|
9383
9446
|
const wantCC = sf.harness.includes("claude-code");
|
|
9384
9447
|
const wantCursor = sf.harness.includes("cursor");
|
|
9385
|
-
|
|
9448
|
+
for (const w of sf.warnings) console.warn(` \u26A0 ${w}`);
|
|
9449
|
+
console.log(`.synkro: harness=[${sf.harness.join(", ")}] pool=${poolLabel(sf.grader.pool)} mode=${sf.grader.mode}`);
|
|
9386
9450
|
const scripts = writeHookScripts(resolvePersistedHookMode());
|
|
9387
9451
|
console.log("Wrote hook scripts to ~/.synkro/hooks/");
|
|
9388
9452
|
const ccSettings = join8(homedir8(), ".claude", "settings.json");
|
|
@@ -9451,7 +9515,7 @@ function reconcileHarness() {
|
|
|
9451
9515
|
const providers = [];
|
|
9452
9516
|
if (sf.grader.pool === "cursor") {
|
|
9453
9517
|
providers.push("cursor");
|
|
9454
|
-
} else if (sf.grader.pool === "
|
|
9518
|
+
} else if (sf.grader.pool === "claude_code") {
|
|
9455
9519
|
providers.push("claude_code");
|
|
9456
9520
|
} else {
|
|
9457
9521
|
if (wantCC) providers.push("claude_code");
|
|
@@ -11836,7 +11900,7 @@ var args = process.argv.slice(2);
|
|
|
11836
11900
|
var cmd = args[0] || "";
|
|
11837
11901
|
var subArgs = args.slice(1);
|
|
11838
11902
|
function printVersion() {
|
|
11839
|
-
console.log("1.6.
|
|
11903
|
+
console.log("1.6.51");
|
|
11840
11904
|
}
|
|
11841
11905
|
function printHelp2() {
|
|
11842
11906
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|