@synkro-sh/cli 1.6.34 → 1.6.35
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 +167 -18
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1212,6 +1212,54 @@ const SYNKRO_FILE_DEFAULTS: SynkroFileConfig = {
|
|
|
1212
1212
|
scanning: { cwe: true, cve: true },
|
|
1213
1213
|
};
|
|
1214
1214
|
|
|
1215
|
+
function parseSynkroYaml(raw: string): Record<string, any> {
|
|
1216
|
+
const result: Record<string, any> = {};
|
|
1217
|
+
const lines = raw.split('\\n');
|
|
1218
|
+
let currentKey = '';
|
|
1219
|
+
let currentObj: Record<string, any> | null = null;
|
|
1220
|
+
let currentArr: string[] | null = null;
|
|
1221
|
+
|
|
1222
|
+
for (const line of lines) {
|
|
1223
|
+
if (!line.trim() || line.trim().startsWith('#')) continue;
|
|
1224
|
+
|
|
1225
|
+
if (line.match(/^\\S/) && line.includes(':')) {
|
|
1226
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
1227
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
1228
|
+
currentObj = null;
|
|
1229
|
+
currentArr = null;
|
|
1230
|
+
|
|
1231
|
+
const colonIdx = line.indexOf(':');
|
|
1232
|
+
const key = line.slice(0, colonIdx).trim();
|
|
1233
|
+
const val = line.slice(colonIdx + 1).trim();
|
|
1234
|
+
currentKey = key;
|
|
1235
|
+
|
|
1236
|
+
if (val) {
|
|
1237
|
+
if (val === '[]') result[key] = [];
|
|
1238
|
+
else if (val === 'true') result[key] = true;
|
|
1239
|
+
else if (val === 'false') result[key] = false;
|
|
1240
|
+
else if (/^\\d+$/.test(val)) result[key] = parseInt(val, 10);
|
|
1241
|
+
else result[key] = val;
|
|
1242
|
+
currentKey = '';
|
|
1243
|
+
}
|
|
1244
|
+
} else if (line.match(/^ - /)) {
|
|
1245
|
+
if (!currentArr) currentArr = [];
|
|
1246
|
+
currentArr.push(line.replace(/^ - /, '').trim());
|
|
1247
|
+
} else if (line.match(/^ \\S/) && line.includes(':')) {
|
|
1248
|
+
if (!currentObj) currentObj = {};
|
|
1249
|
+
const colonIdx = line.indexOf(':');
|
|
1250
|
+
const k = line.slice(0, colonIdx).trim();
|
|
1251
|
+
const v = line.slice(colonIdx + 1).trim();
|
|
1252
|
+
if (v === 'true') currentObj[k] = true;
|
|
1253
|
+
else if (v === 'false') currentObj[k] = false;
|
|
1254
|
+
else if (/^\\d+$/.test(v)) currentObj[k] = parseInt(v, 10);
|
|
1255
|
+
else currentObj[k] = v;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
1259
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
1260
|
+
return result;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1215
1263
|
let _synkroFileCache: SynkroFileConfig | undefined;
|
|
1216
1264
|
|
|
1217
1265
|
export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
@@ -1221,7 +1269,8 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1221
1269
|
const fp = root + '/.synkro';
|
|
1222
1270
|
try {
|
|
1223
1271
|
if (!existsSync(fp)) { _synkroFileCache = SYNKRO_FILE_DEFAULTS; return _synkroFileCache; }
|
|
1224
|
-
const
|
|
1272
|
+
const raw = readFileSync(fp, 'utf-8');
|
|
1273
|
+
const parsed = raw.trimStart().startsWith('{') ? JSON.parse(raw) : parseSynkroYaml(raw);
|
|
1225
1274
|
const validHarness = ['claude-code', 'cursor'] as const;
|
|
1226
1275
|
const harness = Array.isArray(parsed.harness)
|
|
1227
1276
|
? parsed.harness.filter((h: string) => validHarness.includes(h as any))
|
|
@@ -7108,13 +7157,57 @@ function normalizeProvider(p) {
|
|
|
7108
7157
|
if (v === "cursor") return "cursor";
|
|
7109
7158
|
return null;
|
|
7110
7159
|
}
|
|
7160
|
+
function parseSynkroYaml(raw) {
|
|
7161
|
+
const result = {};
|
|
7162
|
+
const lines = raw.split("\n");
|
|
7163
|
+
let currentKey = "";
|
|
7164
|
+
let currentObj = null;
|
|
7165
|
+
let currentArr = null;
|
|
7166
|
+
for (const line of lines) {
|
|
7167
|
+
if (!line.trim() || line.trim().startsWith("#")) continue;
|
|
7168
|
+
if (/^\S/.test(line) && line.includes(":")) {
|
|
7169
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
7170
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
7171
|
+
currentObj = null;
|
|
7172
|
+
currentArr = null;
|
|
7173
|
+
const ci = line.indexOf(":");
|
|
7174
|
+
const key = line.slice(0, ci).trim();
|
|
7175
|
+
const val = line.slice(ci + 1).trim();
|
|
7176
|
+
currentKey = key;
|
|
7177
|
+
if (val) {
|
|
7178
|
+
if (val === "[]") result[key] = [];
|
|
7179
|
+
else if (val === "true") result[key] = true;
|
|
7180
|
+
else if (val === "false") result[key] = false;
|
|
7181
|
+
else if (/^\d+$/.test(val)) result[key] = parseInt(val, 10);
|
|
7182
|
+
else result[key] = val;
|
|
7183
|
+
currentKey = "";
|
|
7184
|
+
}
|
|
7185
|
+
} else if (/^ - /.test(line)) {
|
|
7186
|
+
if (!currentArr) currentArr = [];
|
|
7187
|
+
currentArr.push(line.replace(/^ - /, "").trim());
|
|
7188
|
+
} else if (/^ \S/.test(line) && line.includes(":")) {
|
|
7189
|
+
if (!currentObj) currentObj = {};
|
|
7190
|
+
const ci = line.indexOf(":");
|
|
7191
|
+
const k = line.slice(0, ci).trim();
|
|
7192
|
+
const v = line.slice(ci + 1).trim();
|
|
7193
|
+
if (v === "true") currentObj[k] = true;
|
|
7194
|
+
else if (v === "false") currentObj[k] = false;
|
|
7195
|
+
else if (/^\d+$/.test(v)) currentObj[k] = parseInt(v, 10);
|
|
7196
|
+
else currentObj[k] = v;
|
|
7197
|
+
}
|
|
7198
|
+
}
|
|
7199
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
7200
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
7201
|
+
return result;
|
|
7202
|
+
}
|
|
7111
7203
|
function readSynkroFilePool() {
|
|
7112
7204
|
try {
|
|
7113
7205
|
const root = execSync4("git rev-parse --show-toplevel 2>/dev/null", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
7114
7206
|
if (!root) return "auto";
|
|
7115
7207
|
const fp = join6(root, ".synkro");
|
|
7116
7208
|
if (!existsSync8(fp)) return "auto";
|
|
7117
|
-
const
|
|
7209
|
+
const raw = readFileSync7(fp, "utf-8");
|
|
7210
|
+
const parsed = raw.trimStart().startsWith("{") ? JSON.parse(raw) : parseSynkroYaml(raw);
|
|
7118
7211
|
const pool = parsed?.grader?.pool;
|
|
7119
7212
|
if (pool === "cursor" || pool === "claude") return pool;
|
|
7120
7213
|
} catch {
|
|
@@ -8178,7 +8271,7 @@ function writeConfigEnv(opts) {
|
|
|
8178
8271
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8179
8272
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8180
8273
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8181
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8274
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.35")}`
|
|
8182
8275
|
];
|
|
8183
8276
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8184
8277
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -8704,6 +8797,52 @@ async function installCommand(opts = {}) {
|
|
|
8704
8797
|
}
|
|
8705
8798
|
console.log("\u2713 Synkro installed.");
|
|
8706
8799
|
}
|
|
8800
|
+
function parseSynkroYaml2(raw) {
|
|
8801
|
+
const result = {};
|
|
8802
|
+
const lines = raw.split("\n");
|
|
8803
|
+
let currentKey = "";
|
|
8804
|
+
let currentObj = null;
|
|
8805
|
+
let currentArr = null;
|
|
8806
|
+
for (const line of lines) {
|
|
8807
|
+
if (!line.trim() || line.trim().startsWith("#")) continue;
|
|
8808
|
+
if (/^\S/.test(line) && line.includes(":")) {
|
|
8809
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
8810
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
8811
|
+
currentObj = null;
|
|
8812
|
+
currentArr = null;
|
|
8813
|
+
const colonIdx = line.indexOf(":");
|
|
8814
|
+
const key = line.slice(0, colonIdx).trim();
|
|
8815
|
+
const val = line.slice(colonIdx + 1).trim();
|
|
8816
|
+
currentKey = key;
|
|
8817
|
+
if (val) {
|
|
8818
|
+
if (val === "[]") result[key] = [];
|
|
8819
|
+
else if (val === "true") result[key] = true;
|
|
8820
|
+
else if (val === "false") result[key] = false;
|
|
8821
|
+
else if (/^\d+$/.test(val)) result[key] = parseInt(val, 10);
|
|
8822
|
+
else result[key] = val;
|
|
8823
|
+
currentKey = "";
|
|
8824
|
+
}
|
|
8825
|
+
} else if (/^ - /.test(line)) {
|
|
8826
|
+
if (!currentArr) currentArr = [];
|
|
8827
|
+
currentArr.push(line.replace(/^ - /, "").trim());
|
|
8828
|
+
} else if (/^ \S/.test(line) && line.includes(":")) {
|
|
8829
|
+
if (!currentObj) currentObj = {};
|
|
8830
|
+
const colonIdx = line.indexOf(":");
|
|
8831
|
+
const k = line.slice(0, colonIdx).trim();
|
|
8832
|
+
const v = line.slice(colonIdx + 1).trim();
|
|
8833
|
+
if (v === "true") currentObj[k] = true;
|
|
8834
|
+
else if (v === "false") currentObj[k] = false;
|
|
8835
|
+
else if (/^\d+$/.test(v)) currentObj[k] = parseInt(v, 10);
|
|
8836
|
+
else currentObj[k] = v;
|
|
8837
|
+
}
|
|
8838
|
+
}
|
|
8839
|
+
if (currentObj && currentKey) result[currentKey] = currentObj;
|
|
8840
|
+
if (currentArr && currentKey) result[currentKey] = currentArr;
|
|
8841
|
+
return result;
|
|
8842
|
+
}
|
|
8843
|
+
function parseSynkroFileRaw(content) {
|
|
8844
|
+
return content.trimStart().startsWith("{") ? JSON.parse(content) : parseSynkroYaml2(content);
|
|
8845
|
+
}
|
|
8707
8846
|
function writeSynkroFileIfMissing(opts) {
|
|
8708
8847
|
try {
|
|
8709
8848
|
const root = execSync6("git rev-parse --show-toplevel", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
@@ -8723,18 +8862,28 @@ function writeSynkroFileIfMissing(opts) {
|
|
|
8723
8862
|
harness.push("cursor");
|
|
8724
8863
|
if (!opts.hasClaudeCode) pool = "cursor";
|
|
8725
8864
|
}
|
|
8726
|
-
const
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8865
|
+
const mode = opts.gradingMode === "byok" ? "byok" : "local";
|
|
8866
|
+
const yaml = [
|
|
8867
|
+
"version: 1",
|
|
8868
|
+
"",
|
|
8869
|
+
"harness:",
|
|
8870
|
+
...harness.map((h) => ` - ${h}`),
|
|
8871
|
+
"",
|
|
8872
|
+
"grader:",
|
|
8873
|
+
` pool: ${pool}`,
|
|
8874
|
+
` mode: ${mode}`,
|
|
8875
|
+
"",
|
|
8876
|
+
"ruleset: default",
|
|
8877
|
+
"",
|
|
8878
|
+
"skills: []",
|
|
8879
|
+
"",
|
|
8880
|
+
"scanning:",
|
|
8881
|
+
" cwe: true",
|
|
8882
|
+
" cve: true",
|
|
8883
|
+
""
|
|
8884
|
+
].join("\n");
|
|
8885
|
+
writeFileSync7(fp, yaml, "utf-8");
|
|
8886
|
+
console.log(` .synkro: wrote ${fp} (pool=${pool}, mode=${mode})`);
|
|
8738
8887
|
} catch {
|
|
8739
8888
|
}
|
|
8740
8889
|
}
|
|
@@ -8744,7 +8893,7 @@ function readSynkroFilePool2() {
|
|
|
8744
8893
|
if (!root) return "auto";
|
|
8745
8894
|
const fp = join8(root, ".synkro");
|
|
8746
8895
|
if (!existsSync10(fp)) return "auto";
|
|
8747
|
-
const parsed =
|
|
8896
|
+
const parsed = parseSynkroFileRaw(readFileSync9(fp, "utf-8"));
|
|
8748
8897
|
const pool = parsed?.grader?.pool;
|
|
8749
8898
|
if (pool === "cursor" || pool === "claude") return pool;
|
|
8750
8899
|
} catch {
|
|
@@ -8757,7 +8906,7 @@ function readFullSynkroFile() {
|
|
|
8757
8906
|
if (!root) return null;
|
|
8758
8907
|
const fp = join8(root, ".synkro");
|
|
8759
8908
|
if (!existsSync10(fp)) return null;
|
|
8760
|
-
const parsed =
|
|
8909
|
+
const parsed = parseSynkroFileRaw(readFileSync9(fp, "utf-8"));
|
|
8761
8910
|
const valid = ["claude-code", "cursor"];
|
|
8762
8911
|
const harness = Array.isArray(parsed.harness) ? parsed.harness.filter((h) => valid.includes(h)) : ["claude-code", "cursor"];
|
|
8763
8912
|
return {
|
|
@@ -11143,7 +11292,7 @@ var args = process.argv.slice(2);
|
|
|
11143
11292
|
var cmd = args[0] || "";
|
|
11144
11293
|
var subArgs = args.slice(1);
|
|
11145
11294
|
function printVersion() {
|
|
11146
|
-
console.log("1.6.
|
|
11295
|
+
console.log("1.6.35");
|
|
11147
11296
|
}
|
|
11148
11297
|
function printHelp2() {
|
|
11149
11298
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|