@synkro-sh/cli 1.6.91 → 1.6.92
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 +67 -23
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1415,8 +1415,19 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1415
1415
|
}
|
|
1416
1416
|
}
|
|
1417
1417
|
|
|
1418
|
-
export function effectiveGraderPool(synkroFile: SynkroFileConfig, hookAgentKind: AgentKind): AgentKind {
|
|
1419
|
-
|
|
1418
|
+
export function effectiveGraderPool(synkroFile: SynkroFileConfig, hookAgentKind: AgentKind, config?: HookConfig): AgentKind {
|
|
1419
|
+
// Source of truth for the pool SPLIT depends on grading location:
|
|
1420
|
+
// \u2022 cloud / byok \u2192 SERVER-managed (the user's dashboard choice, delivered as
|
|
1421
|
+
// config.graderPool from /v1/hook/config). synkro.toml isn't even written
|
|
1422
|
+
// for cloud installs, so it can't be the source there.
|
|
1423
|
+
// \u2022 local \u2192 synkro.toml [grader] pool (on-device, user-owned).
|
|
1424
|
+
// Falls back to synkro.toml whenever the server pool is absent, so a missing
|
|
1425
|
+
// value never breaks grading \u2014 it just reverts to today's behavior.
|
|
1426
|
+
const managed = process.env.SYNKRO_DEPLOY_LOCATION === 'cloud'
|
|
1427
|
+
|| (process.env.SYNKRO_GRADING_MODE || synkroFile.grader?.mode || config?.gradingMode) === 'byok';
|
|
1428
|
+
const pool = (managed && config?.graderPool)
|
|
1429
|
+
? normalizePoolToken(config.graderPool)
|
|
1430
|
+
: normalizePoolToken(synkroFile.grader.pool);
|
|
1420
1431
|
if (pool === 'auto') return hookAgentKind;
|
|
1421
1432
|
if (pool === 'claude') return 'claude_code';
|
|
1422
1433
|
return 'cursor';
|
|
@@ -1517,6 +1528,11 @@ export interface HookConfig {
|
|
|
1517
1528
|
// value from /v1/hook/config is only a fallback when the env var is unset.
|
|
1518
1529
|
gradingMode: string;
|
|
1519
1530
|
storageMode: string;
|
|
1531
|
+
// Server-managed pool SPLIT (auto | claude | cursor) + canonical grading
|
|
1532
|
+
// location, from /v1/hook/config. Authoritative ONLY for cloud/byok grading
|
|
1533
|
+
// (synkro.toml governs local). Undefined when the gateway didn't report one.
|
|
1534
|
+
graderPool?: string;
|
|
1535
|
+
inferenceMode?: string;
|
|
1520
1536
|
}
|
|
1521
1537
|
|
|
1522
1538
|
/** True when telemetry + rules must stay on-machine (PGLite). Default: local. */
|
|
@@ -1597,6 +1613,9 @@ export async function loadConfig(jwt: string, query?: string): Promise<HookConfi
|
|
|
1597
1613
|
config.silent = data.silent_mode === true || data.silent_mode === 'true';
|
|
1598
1614
|
if (!process.env.SYNKRO_GRADING_MODE && data.grading_mode) config.gradingMode = data.grading_mode;
|
|
1599
1615
|
if (!process.env.SYNKRO_STORAGE_MODE && data.storage_mode) config.storageMode = data.storage_mode;
|
|
1616
|
+
// Server-managed pool split + location (cloud/byok only \u2014 see effectiveGraderPool).
|
|
1617
|
+
if (data.grader_pool) config.graderPool = data.grader_pool;
|
|
1618
|
+
if (data.inference_mode) config.inferenceMode = data.inference_mode;
|
|
1600
1619
|
config.policyName = data.active_policy_name || '';
|
|
1601
1620
|
if (Array.isArray(data.scan_exemptions)) {
|
|
1602
1621
|
config.scanExemptions = data.scan_exemptions
|
|
@@ -4364,7 +4383,7 @@ async function main() {
|
|
|
4364
4383
|
// Load config and decide route
|
|
4365
4384
|
const config = await loadConfig(jwt);
|
|
4366
4385
|
const synkroFile = loadSynkroFile(cwd);
|
|
4367
|
-
const graderPool = effectiveGraderPool(synkroFile, agentKind);
|
|
4386
|
+
const graderPool = effectiveGraderPool(synkroFile, agentKind, config);
|
|
4368
4387
|
const rt = await route(config, synkroFile);
|
|
4369
4388
|
const tagStr = tag(rt, config, graderPool);
|
|
4370
4389
|
|
|
@@ -4858,7 +4877,7 @@ async function main() {
|
|
|
4858
4877
|
|
|
4859
4878
|
const config = await loadConfig(jwt);
|
|
4860
4879
|
const synkroFile = loadSynkroFile(cwd);
|
|
4861
|
-
const graderPool = effectiveGraderPool(synkroFile, agentKind);
|
|
4880
|
+
const graderPool = effectiveGraderPool(synkroFile, agentKind, config);
|
|
4862
4881
|
const rt = await cweRoute(config, synkroFile);
|
|
4863
4882
|
|
|
4864
4883
|
// Combined-grade mode: the edit-precheck hook runs CWE inside its single
|
|
@@ -5586,7 +5605,7 @@ async function main() {
|
|
|
5586
5605
|
const config = await loadConfig(jwt);
|
|
5587
5606
|
const isCursor = isCursorHookFormat();
|
|
5588
5607
|
const synkroFile = loadSynkroFile(cwd);
|
|
5589
|
-
const graderPool = effectiveGraderPool(synkroFile, isCursor ? 'cursor' : 'claude_code');
|
|
5608
|
+
const graderPool = effectiveGraderPool(synkroFile, isCursor ? 'cursor' : 'claude_code', config);
|
|
5590
5609
|
const rt = await route(config, synkroFile);
|
|
5591
5610
|
const tagStr = tag(rt, config, graderPool);
|
|
5592
5611
|
|
|
@@ -5768,7 +5787,7 @@ async function main() {
|
|
|
5768
5787
|
|
|
5769
5788
|
const config = await loadConfig(jwt);
|
|
5770
5789
|
const synkroFile = loadSynkroFile(cwd);
|
|
5771
|
-
const graderPool = effectiveGraderPool(synkroFile, 'claude_code');
|
|
5790
|
+
const graderPool = effectiveGraderPool(synkroFile, 'claude_code', config);
|
|
5772
5791
|
const rt = await route(config, synkroFile);
|
|
5773
5792
|
const tagStr = tag(rt, config, graderPool);
|
|
5774
5793
|
|
|
@@ -6058,7 +6077,7 @@ async function main() {
|
|
|
6058
6077
|
|
|
6059
6078
|
const config = await loadConfig(jwt);
|
|
6060
6079
|
const synkroFile = loadSynkroFile(cwd);
|
|
6061
|
-
const graderPool = effectiveGraderPool(synkroFile, agentKind);
|
|
6080
|
+
const graderPool = effectiveGraderPool(synkroFile, agentKind, config);
|
|
6062
6081
|
const rt = await route(config, synkroFile);
|
|
6063
6082
|
const tagStr = tag(rt, config, graderPool);
|
|
6064
6083
|
|
|
@@ -6277,7 +6296,7 @@ async function main() {
|
|
|
6277
6296
|
|
|
6278
6297
|
const config = await loadConfig(jwt);
|
|
6279
6298
|
const synkroFile = loadSynkroFile(cwd);
|
|
6280
|
-
const graderPool = effectiveGraderPool(synkroFile, agentKind);
|
|
6299
|
+
const graderPool = effectiveGraderPool(synkroFile, agentKind, config);
|
|
6281
6300
|
const rt = await route(config, synkroFile);
|
|
6282
6301
|
const tagStr = tag(rt, config, graderPool);
|
|
6283
6302
|
|
|
@@ -6513,12 +6532,15 @@ async function main() {
|
|
|
6513
6532
|
return;
|
|
6514
6533
|
}
|
|
6515
6534
|
|
|
6516
|
-
// Sync grading
|
|
6517
|
-
|
|
6535
|
+
// Sync the canonical 3-state grading location to the API profile so the
|
|
6536
|
+
// dashboard reflects the machine's ACTUAL config. byok (own API key) wins;
|
|
6537
|
+
// else the cloud worker pool; else on-device workers. The API derives the
|
|
6538
|
+
// legacy fast_inference boolean from this, so we only send one field.
|
|
6539
|
+
const inferenceMode = gradingMode === 'byok' ? 'byok' : (deployCloud ? 'cloud' : 'local');
|
|
6518
6540
|
fetch(GATEWAY_URL + '/api/v1/cli/me', {
|
|
6519
6541
|
method: 'PATCH',
|
|
6520
6542
|
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + jwt },
|
|
6521
|
-
body: JSON.stringify({
|
|
6543
|
+
body: JSON.stringify({ inference_mode: inferenceMode }),
|
|
6522
6544
|
signal: AbortSignal.timeout(3000),
|
|
6523
6545
|
}).catch(() => {});
|
|
6524
6546
|
|
|
@@ -6873,7 +6895,7 @@ async function main() {
|
|
|
6873
6895
|
if (config.silent) finishAllow();
|
|
6874
6896
|
|
|
6875
6897
|
const synkroFile = loadSynkroFile(cwd);
|
|
6876
|
-
const graderPool = effectiveGraderPool(synkroFile, 'cursor');
|
|
6898
|
+
const graderPool = effectiveGraderPool(synkroFile, 'cursor', config);
|
|
6877
6899
|
const rt = await route(config, synkroFile);
|
|
6878
6900
|
const tagStr = tag(rt, config, graderPool);
|
|
6879
6901
|
|
|
@@ -11208,7 +11230,7 @@ function writeConfigEnv(opts) {
|
|
|
11208
11230
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
11209
11231
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
11210
11232
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
11211
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
11233
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.92")}`
|
|
11212
11234
|
];
|
|
11213
11235
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
11214
11236
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -15115,6 +15137,11 @@ function updateConfigValue(key, value) {
|
|
|
15115
15137
|
if (!found) updated.splice(updated.length - 1, 0, `${key}='${value}'`);
|
|
15116
15138
|
writeFileSync13(CONFIG_PATH6, updated.join("\n"), "utf-8");
|
|
15117
15139
|
}
|
|
15140
|
+
function resolveInferenceMode(cfg) {
|
|
15141
|
+
if ((cfg.SYNKRO_GRADING_MODE || "local") === "byok") return "byok";
|
|
15142
|
+
if (cfg.SYNKRO_DEPLOY_LOCATION === "cloud") return "cloud";
|
|
15143
|
+
return "local";
|
|
15144
|
+
}
|
|
15118
15145
|
async function reconcileContainer() {
|
|
15119
15146
|
const cfg = readConfigEnv2();
|
|
15120
15147
|
const cloudOnly = (cfg.SYNKRO_GRADING_MODE || "local") === "byok" && (cfg.SYNKRO_STORAGE_MODE || "local") === "cloud";
|
|
@@ -15142,17 +15169,18 @@ async function configCommand(args2) {
|
|
|
15142
15169
|
if (args2.length === 0) {
|
|
15143
15170
|
const config2 = readConfigEnv2();
|
|
15144
15171
|
console.log("Synkro config:\n");
|
|
15145
|
-
console.log(`
|
|
15172
|
+
console.log(` inference: ${resolveInferenceMode(config2)}`);
|
|
15146
15173
|
console.log(` storage: ${config2.SYNKRO_STORAGE_MODE || "local"}`);
|
|
15147
|
-
console.log(` inference: ${config2.SYNKRO_INFERENCE || "fast"}`);
|
|
15148
15174
|
console.log(` tier: ${config2.SYNKRO_TIER || "pro"}`);
|
|
15149
15175
|
console.log(` gateway: ${config2.SYNKRO_GATEWAY_URL || "https://api.synkro.sh"}`);
|
|
15150
15176
|
console.log(` version: ${config2.SYNKRO_VERSION || "?"}`);
|
|
15151
15177
|
console.log(`
|
|
15152
15178
|
To change:`);
|
|
15153
|
-
console.log(` synkro config
|
|
15154
|
-
console.log(`
|
|
15155
|
-
console.log(`
|
|
15179
|
+
console.log(` synkro config --inference <local|cloud|byok> \u2014 where grading runs`);
|
|
15180
|
+
console.log(` local \u2014 Claude/Cursor workers on this machine (your subscription)`);
|
|
15181
|
+
console.log(` cloud \u2014 Claude/Cursor workers in the Synkro cloud pool`);
|
|
15182
|
+
console.log(` byok \u2014 graded via your own provider API key`);
|
|
15183
|
+
console.log(` synkro config storage <local|cloud> \u2014 where telemetry is stored`);
|
|
15156
15184
|
return;
|
|
15157
15185
|
}
|
|
15158
15186
|
if (args2[0] === "grading") {
|
|
@@ -15186,8 +15214,8 @@ To change:`);
|
|
|
15186
15214
|
if (a.startsWith("--inference=")) inferenceValue = a.slice("--inference=".length);
|
|
15187
15215
|
else if (a === "--inference" && args2.indexOf(a) + 1 < args2.length) inferenceValue = args2[args2.indexOf(a) + 1];
|
|
15188
15216
|
}
|
|
15189
|
-
if (!inferenceValue || !["
|
|
15190
|
-
console.error("Usage: synkro config --inference
|
|
15217
|
+
if (!inferenceValue || !["local", "cloud", "byok"].includes(inferenceValue)) {
|
|
15218
|
+
console.error("Usage: synkro config --inference <local|cloud|byok>");
|
|
15191
15219
|
process.exit(1);
|
|
15192
15220
|
}
|
|
15193
15221
|
if (!isAuthenticated()) {
|
|
@@ -15204,7 +15232,7 @@ To change:`);
|
|
|
15204
15232
|
"Authorization": `Bearer ${token}`,
|
|
15205
15233
|
"Content-Type": "application/json"
|
|
15206
15234
|
},
|
|
15207
|
-
body: JSON.stringify({
|
|
15235
|
+
body: JSON.stringify({ inference_mode: inferenceValue })
|
|
15208
15236
|
});
|
|
15209
15237
|
if (!resp.ok) {
|
|
15210
15238
|
const errText = await resp.text().catch(() => "");
|
|
@@ -15215,8 +15243,24 @@ To change:`);
|
|
|
15215
15243
|
console.error(`Failed to reach server: ${err.message}`);
|
|
15216
15244
|
process.exit(1);
|
|
15217
15245
|
}
|
|
15218
|
-
|
|
15246
|
+
if (inferenceValue === "byok") {
|
|
15247
|
+
updateConfigValue("SYNKRO_GRADING_MODE", "byok");
|
|
15248
|
+
updateConfigValue("SYNKRO_DEPLOY_LOCATION", "local");
|
|
15249
|
+
} else if (inferenceValue === "cloud") {
|
|
15250
|
+
updateConfigValue("SYNKRO_GRADING_MODE", "local");
|
|
15251
|
+
updateConfigValue("SYNKRO_DEPLOY_LOCATION", "cloud");
|
|
15252
|
+
} else {
|
|
15253
|
+
updateConfigValue("SYNKRO_GRADING_MODE", "local");
|
|
15254
|
+
updateConfigValue("SYNKRO_DEPLOY_LOCATION", "local");
|
|
15255
|
+
}
|
|
15219
15256
|
console.log(`\u2713 Inference set to '${inferenceValue}'.`);
|
|
15257
|
+
if (inferenceValue === "byok") {
|
|
15258
|
+
console.log(" BYOK grading uses your own provider key \u2014 register one in the");
|
|
15259
|
+
console.log(" dashboard under Settings \u2192 Provider Keys if you have not already.");
|
|
15260
|
+
} else if (inferenceValue === "cloud") {
|
|
15261
|
+
console.log(" Grading runs on the Synkro cloud worker pool (containers.synkro.sh).");
|
|
15262
|
+
}
|
|
15263
|
+
if (inferenceValue !== "cloud") await reconcileContainer();
|
|
15220
15264
|
}
|
|
15221
15265
|
var SYNKRO_DIR7, CONFIG_PATH6;
|
|
15222
15266
|
var init_config = __esm({
|
|
@@ -15251,7 +15295,7 @@ var args = process.argv.slice(2);
|
|
|
15251
15295
|
var cmd = args[0] || "";
|
|
15252
15296
|
var subArgs = args.slice(1);
|
|
15253
15297
|
function printVersion() {
|
|
15254
|
-
console.log("1.6.
|
|
15298
|
+
console.log("1.6.92");
|
|
15255
15299
|
}
|
|
15256
15300
|
function printHelp2() {
|
|
15257
15301
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|