@synkro-sh/cli 1.6.35 → 1.6.36
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 +58 -23
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1198,6 +1198,7 @@ export interface SynkroFileConfig {
|
|
|
1198
1198
|
version: number;
|
|
1199
1199
|
harness: ('claude-code' | 'cursor')[];
|
|
1200
1200
|
grader: { pool: 'auto' | 'claude' | 'cursor'; mode?: string };
|
|
1201
|
+
workers: { claude?: number; cursor?: number };
|
|
1201
1202
|
ruleset: string;
|
|
1202
1203
|
skills: string[];
|
|
1203
1204
|
scanning: { cwe: boolean; cve: boolean };
|
|
@@ -1207,6 +1208,7 @@ const SYNKRO_FILE_DEFAULTS: SynkroFileConfig = {
|
|
|
1207
1208
|
version: 1,
|
|
1208
1209
|
harness: ['claude-code', 'cursor'],
|
|
1209
1210
|
grader: { pool: 'auto' },
|
|
1211
|
+
workers: {},
|
|
1210
1212
|
ruleset: 'default',
|
|
1211
1213
|
skills: [],
|
|
1212
1214
|
scanning: { cwe: true, cve: true },
|
|
@@ -1282,6 +1284,10 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1282
1284
|
pool: ['auto', 'claude', 'cursor'].includes(parsed.grader?.pool) ? parsed.grader.pool : 'auto',
|
|
1283
1285
|
mode: ['local', 'byok'].includes(parsed.grader?.mode) ? parsed.grader.mode : undefined,
|
|
1284
1286
|
},
|
|
1287
|
+
workers: {
|
|
1288
|
+
...(typeof parsed.workers?.claude === 'number' ? { claude: parsed.workers.claude } : {}),
|
|
1289
|
+
...(typeof parsed.workers?.cursor === 'number' ? { cursor: parsed.workers.cursor } : {}),
|
|
1290
|
+
},
|
|
1285
1291
|
ruleset: typeof parsed.ruleset === 'string' ? parsed.ruleset : 'default',
|
|
1286
1292
|
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((s: unknown) => typeof s === 'string') : [],
|
|
1287
1293
|
scanning: {
|
|
@@ -7200,19 +7206,21 @@ function parseSynkroYaml(raw) {
|
|
|
7200
7206
|
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
7201
7207
|
return result;
|
|
7202
7208
|
}
|
|
7203
|
-
function
|
|
7209
|
+
function readSynkroFileConfig() {
|
|
7204
7210
|
try {
|
|
7205
7211
|
const root = execSync4("git rev-parse --show-toplevel 2>/dev/null", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
7206
|
-
if (!root) return "auto";
|
|
7212
|
+
if (!root) return { pool: "auto" };
|
|
7207
7213
|
const fp = join6(root, ".synkro");
|
|
7208
|
-
if (!existsSync8(fp)) return "auto";
|
|
7214
|
+
if (!existsSync8(fp)) return { pool: "auto" };
|
|
7209
7215
|
const raw = readFileSync7(fp, "utf-8");
|
|
7210
7216
|
const parsed = raw.trimStart().startsWith("{") ? JSON.parse(raw) : parseSynkroYaml(raw);
|
|
7211
|
-
const pool = parsed?.grader?.pool;
|
|
7212
|
-
|
|
7217
|
+
const pool = ["auto", "claude", "cursor"].includes(parsed?.grader?.pool) ? parsed.grader.pool : "auto";
|
|
7218
|
+
const cw = typeof parsed?.workers?.claude === "number" ? Math.max(0, Math.floor(parsed.workers.claude)) : void 0;
|
|
7219
|
+
const curw = typeof parsed?.workers?.cursor === "number" ? Math.max(0, Math.floor(parsed.workers.cursor)) : void 0;
|
|
7220
|
+
return { pool, claudeWorkers: cw, cursorWorkers: curw };
|
|
7213
7221
|
} catch {
|
|
7214
7222
|
}
|
|
7215
|
-
return "auto";
|
|
7223
|
+
return { pool: "auto" };
|
|
7216
7224
|
}
|
|
7217
7225
|
function resolveWorkerConfig(rest) {
|
|
7218
7226
|
let workers = 8;
|
|
@@ -7247,10 +7255,15 @@ function resolveWorkerConfig(rest) {
|
|
|
7247
7255
|
workers = Math.min(workers, 64);
|
|
7248
7256
|
let provs = providers;
|
|
7249
7257
|
if (provs.length === 0) {
|
|
7250
|
-
const
|
|
7251
|
-
if (
|
|
7258
|
+
const sc = readSynkroFileConfig();
|
|
7259
|
+
if (sc.claudeWorkers != null || sc.cursorWorkers != null) {
|
|
7260
|
+
const cw = sc.claudeWorkers || 0;
|
|
7261
|
+
const curw = sc.cursorWorkers || 0;
|
|
7262
|
+
if (cw + curw > 0) return { claudeWorkers: cw, cursorWorkers: curw, explicit };
|
|
7263
|
+
}
|
|
7264
|
+
if (sc.pool === "cursor") {
|
|
7252
7265
|
provs = ["cursor"];
|
|
7253
|
-
} else if (
|
|
7266
|
+
} else if (sc.pool === "claude") {
|
|
7254
7267
|
provs = ["claude_code"];
|
|
7255
7268
|
} else {
|
|
7256
7269
|
provs = detectAgents().map((a) => a.kind);
|
|
@@ -8271,7 +8284,7 @@ function writeConfigEnv(opts) {
|
|
|
8271
8284
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8272
8285
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8273
8286
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8274
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8287
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.36")}`
|
|
8275
8288
|
];
|
|
8276
8289
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8277
8290
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -8679,19 +8692,32 @@ async function installCommand(opts = {}) {
|
|
|
8679
8692
|
await promptCursorApiKey(opts);
|
|
8680
8693
|
}
|
|
8681
8694
|
console.log("Installing Synkro server container...");
|
|
8682
|
-
const
|
|
8683
|
-
|
|
8684
|
-
let
|
|
8685
|
-
if (
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8695
|
+
const sf = readFullSynkroFile();
|
|
8696
|
+
let claudeWorkers;
|
|
8697
|
+
let cursorWorkers;
|
|
8698
|
+
if (sf && (sf.workers.claude != null || sf.workers.cursor != null)) {
|
|
8699
|
+
claudeWorkers = Math.max(0, Math.floor(sf.workers.claude || 0));
|
|
8700
|
+
cursorWorkers = Math.max(0, Math.floor(sf.workers.cursor || 0));
|
|
8701
|
+
if (claudeWorkers + cursorWorkers === 0) {
|
|
8702
|
+
claudeWorkers = 0;
|
|
8703
|
+
cursorWorkers = 8;
|
|
8704
|
+
}
|
|
8705
|
+
console.log(` .synkro: explicit workers \u2014 ${claudeWorkers} claude + ${cursorWorkers} cursor`);
|
|
8689
8706
|
} else {
|
|
8690
|
-
|
|
8691
|
-
|
|
8707
|
+
const totalWorkers = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "8", 10);
|
|
8708
|
+
const synkroFilePool = sf?.grader?.pool || readSynkroFilePool();
|
|
8709
|
+
let providers = [];
|
|
8710
|
+
if (synkroFilePool === "cursor") {
|
|
8711
|
+
providers = ["cursor"];
|
|
8712
|
+
} else if (synkroFilePool === "claude") {
|
|
8713
|
+
providers = ["claude_code"];
|
|
8714
|
+
} else {
|
|
8715
|
+
if (hasClaudeCode) providers.push("claude_code");
|
|
8716
|
+
if (hasCursor) providers.push("cursor");
|
|
8717
|
+
}
|
|
8718
|
+
({ claudeWorkers, cursorWorkers } = splitWorkers(totalWorkers, providers));
|
|
8719
|
+
if (synkroFilePool !== "auto") console.log(` .synkro: grader pool set to ${synkroFilePool}`);
|
|
8692
8720
|
}
|
|
8693
|
-
const { claudeWorkers, cursorWorkers } = splitWorkers(totalWorkers, providers);
|
|
8694
|
-
if (synkroFilePool !== "auto") console.log(` .synkro: grader pool set to ${synkroFilePool}`);
|
|
8695
8721
|
console.log(` worker pool: ${claudeWorkers} claude + ${cursorWorkers} cursor`);
|
|
8696
8722
|
const connectedRepo = detectGitRepo2() || void 0;
|
|
8697
8723
|
const { image, hostMcpPort, hostGraderPort, hostCwePort, hostPglitePort } = await dockerInstall({ claudeWorkers, cursorWorkers, connectedRepo });
|
|
@@ -8887,7 +8913,7 @@ function writeSynkroFileIfMissing(opts) {
|
|
|
8887
8913
|
} catch {
|
|
8888
8914
|
}
|
|
8889
8915
|
}
|
|
8890
|
-
function
|
|
8916
|
+
function readSynkroFilePool() {
|
|
8891
8917
|
try {
|
|
8892
8918
|
const root = execSync6("git rev-parse --show-toplevel", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
8893
8919
|
if (!root) return "auto";
|
|
@@ -8915,6 +8941,10 @@ function readFullSynkroFile() {
|
|
|
8915
8941
|
pool: ["auto", "claude", "cursor"].includes(parsed.grader?.pool) ? parsed.grader.pool : "auto",
|
|
8916
8942
|
mode: ["local", "byok"].includes(parsed.grader?.mode) ? parsed.grader.mode : "local"
|
|
8917
8943
|
},
|
|
8944
|
+
workers: {
|
|
8945
|
+
...typeof parsed.workers?.claude === "number" ? { claude: parsed.workers.claude } : {},
|
|
8946
|
+
...typeof parsed.workers?.cursor === "number" ? { cursor: parsed.workers.cursor } : {}
|
|
8947
|
+
},
|
|
8918
8948
|
ruleset: parsed.ruleset || "default",
|
|
8919
8949
|
skills: Array.isArray(parsed.skills) ? parsed.skills.filter((s) => typeof s === "string" && s.endsWith(".md")) : [],
|
|
8920
8950
|
scanning: { cwe: parsed.scanning?.cwe !== false, cve: parsed.scanning?.cve !== false },
|
|
@@ -8992,6 +9022,11 @@ function reconcileHarness() {
|
|
|
8992
9022
|
if (uninstallCursorHooks(cursorHooks)) console.log(" \u2717 Cursor hooks removed");
|
|
8993
9023
|
if (uninstallCursorMcpConfig()) console.log(" \u2717 Cursor MCP removed");
|
|
8994
9024
|
}
|
|
9025
|
+
if (sf.workers.claude != null || sf.workers.cursor != null) {
|
|
9026
|
+
const cw = Math.max(0, Math.floor(sf.workers.claude || 0));
|
|
9027
|
+
const curw = Math.max(0, Math.floor(sf.workers.cursor || 0));
|
|
9028
|
+
if (cw + curw > 0) return { claudeWorkers: cw, cursorWorkers: curw };
|
|
9029
|
+
}
|
|
8995
9030
|
const total = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "8", 10);
|
|
8996
9031
|
const providers = [];
|
|
8997
9032
|
if (sf.grader.pool === "cursor") {
|
|
@@ -11292,7 +11327,7 @@ var args = process.argv.slice(2);
|
|
|
11292
11327
|
var cmd = args[0] || "";
|
|
11293
11328
|
var subArgs = args.slice(1);
|
|
11294
11329
|
function printVersion() {
|
|
11295
|
-
console.log("1.6.
|
|
11330
|
+
console.log("1.6.36");
|
|
11296
11331
|
}
|
|
11297
11332
|
function printHelp2() {
|
|
11298
11333
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|