@synkro-sh/cli 1.4.91 → 1.4.93
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 +98 -35
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -2297,12 +2297,14 @@ async function main() {
|
|
|
2297
2297
|
if (!proposed) { outputEmpty(); return; }
|
|
2298
2298
|
|
|
2299
2299
|
let cweContent: string;
|
|
2300
|
+
let cweDiffSection = '';
|
|
2300
2301
|
if (toolName === 'Edit' || toolName === 'MultiEdit' || toolName === 'edit_file' || toolName === 'reapply' || toolName === 'ApplyPatch' || toolName === 'apply_patch') {
|
|
2301
2302
|
const newStr = toolName === 'Edit' || toolName === 'edit_file' || toolName === 'reapply'
|
|
2302
2303
|
? (toolInput.new_string || '')
|
|
2303
2304
|
: toolName === 'ApplyPatch' || toolName === 'apply_patch'
|
|
2304
2305
|
? (toolInput.patch || toolInput.content || toolInput.code_edit || '')
|
|
2305
2306
|
: (Array.isArray(toolInput.edits) ? toolInput.edits.map((e: any) => e?.new_string || '').join('\n') : '');
|
|
2307
|
+
cweDiffSection = newStr.slice(0, 4000);
|
|
2306
2308
|
const changeIdx = proposed.indexOf(newStr);
|
|
2307
2309
|
if (changeIdx >= 0 && proposed.length > 6000) {
|
|
2308
2310
|
const start = Math.max(0, changeIdx - 2000);
|
|
@@ -2333,14 +2335,28 @@ async function main() {
|
|
|
2333
2335
|
|
|
2334
2336
|
if (rt === 'local') {
|
|
2335
2337
|
let cweRules: any[] = [];
|
|
2338
|
+
let cweRuleFetchFailed = false;
|
|
2336
2339
|
try {
|
|
2337
2340
|
const resp = await fetch(GATEWAY_URL + '/api/v1/cwe-rules?ext=' + encodeURIComponent(fileExt), {
|
|
2338
2341
|
headers: { Authorization: 'Bearer ' + jwt },
|
|
2339
2342
|
signal: AbortSignal.timeout(4000),
|
|
2340
2343
|
});
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
+
if (!resp.ok) {
|
|
2345
|
+
log('CWE rules fetch failed: HTTP ' + resp.status);
|
|
2346
|
+
cweRuleFetchFailed = true;
|
|
2347
|
+
} else {
|
|
2348
|
+
const data = await resp.json() as any;
|
|
2349
|
+
cweRules = data.rules || [];
|
|
2350
|
+
}
|
|
2351
|
+
} catch (fetchErr: any) {
|
|
2352
|
+
log('CWE rules fetch error: ' + (fetchErr?.message || String(fetchErr)));
|
|
2353
|
+
cweRuleFetchFailed = true;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
if (cweRuleFetchFailed) {
|
|
2357
|
+
outputJson({ systemMessage: cweTag + ' ' + fileShort + ' \u2192 CWE rules unavailable \u2014 scan skipped' });
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2344
2360
|
|
|
2345
2361
|
if (cweRules.length === 0) {
|
|
2346
2362
|
outputJson({ systemMessage: cweTag + ' ' + fileShort + ' \u2192 clean (no CWE rules for ' + fileExt + ')' });
|
|
@@ -2359,40 +2375,86 @@ async function main() {
|
|
|
2359
2375
|
}
|
|
2360
2376
|
}
|
|
2361
2377
|
|
|
2362
|
-
const
|
|
2363
|
-
'
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
+
const exemptionNote = exemptedCwes.size > 0
|
|
2379
|
+
? '\n\nEXEMPTED CWEs (already known, DO NOT report these — focus on NEW weaknesses only): ' + [...exemptedCwes].join(', ')
|
|
2380
|
+
: '';
|
|
2381
|
+
|
|
2382
|
+
function buildCwePrompt(content: string): string {
|
|
2383
|
+
const diffBlock = cweDiffSection
|
|
2384
|
+
? '\n\n=== NEW/CHANGED CODE (evaluate THIS for CWE weaknesses) ===\n' + cweDiffSection + '\n=== END NEW CODE ===\n\nThe surrounding content below is CONTEXT ONLY to help you understand imports, variables, and scope. Do NOT report issues found only in the context section.\n'
|
|
2385
|
+
: '';
|
|
2386
|
+
return [
|
|
2387
|
+
'File: ' + filePath,
|
|
2388
|
+
diffBlock,
|
|
2389
|
+
'Full content window:',
|
|
2390
|
+
content,
|
|
2391
|
+
'',
|
|
2392
|
+
'CWE rules to check against:',
|
|
2393
|
+
JSON.stringify(cweRules),
|
|
2394
|
+
].join('\n') + localPkgContext + exemptionNote;
|
|
2378
2395
|
}
|
|
2379
2396
|
|
|
2380
|
-
const
|
|
2397
|
+
const SPLIT_THRESHOLD = 4000;
|
|
2398
|
+
const OVERLAP = 500;
|
|
2399
|
+
let gradeResponses: string[] = [];
|
|
2381
2400
|
|
|
2382
|
-
if (
|
|
2383
|
-
const
|
|
2384
|
-
const
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2401
|
+
if (cweContent.length > SPLIT_THRESHOLD) {
|
|
2402
|
+
const mid = Math.floor(cweContent.length / 2);
|
|
2403
|
+
const chunk1 = cweContent.slice(0, mid + OVERLAP);
|
|
2404
|
+
const chunk2 = cweContent.slice(mid - OVERLAP);
|
|
2405
|
+
try {
|
|
2406
|
+
const [resp1, resp2] = await Promise.all([
|
|
2407
|
+
localGradeCwe(buildCwePrompt(chunk1)),
|
|
2408
|
+
localGradeCwe(buildCwePrompt(chunk2)),
|
|
2409
|
+
]);
|
|
2410
|
+
gradeResponses = [resp1, resp2];
|
|
2411
|
+
} catch (gradeErr: any) {
|
|
2412
|
+
const reason = gradeErr?.message || String(gradeErr);
|
|
2413
|
+
outputJson({ systemMessage: cweTag + ' ' + fileShort + ' \u2192 grader unavailable (' + reason + '), skipped' });
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2416
|
+
} else {
|
|
2417
|
+
try {
|
|
2418
|
+
gradeResponses = [await localGradeCwe(buildCwePrompt(cweContent))];
|
|
2419
|
+
} catch (gradeErr: any) {
|
|
2420
|
+
const reason = gradeErr?.message || String(gradeErr);
|
|
2421
|
+
outputJson({ systemMessage: cweTag + ' ' + fileShort + ' \u2192 grader unavailable (' + reason + '), skipped' });
|
|
2422
|
+
return;
|
|
2388
2423
|
}
|
|
2424
|
+
}
|
|
2389
2425
|
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2426
|
+
const cweIds: string[] = [];
|
|
2427
|
+
const fixes: Record<string, string> = {};
|
|
2428
|
+
let mergedReason = '';
|
|
2429
|
+
let mergedSeverity = '';
|
|
2430
|
+
let mergedCategory = '';
|
|
2431
|
+
let anyFailed = false;
|
|
2432
|
+
|
|
2433
|
+
for (const gradeResp of gradeResponses) {
|
|
2434
|
+
const v = parseVerdict(gradeResp);
|
|
2435
|
+
if (!v.ok) {
|
|
2436
|
+
anyFailed = true;
|
|
2437
|
+
if (v.reason) mergedReason = mergedReason || v.reason;
|
|
2438
|
+
if (v.severity) mergedSeverity = mergedSeverity || v.severity;
|
|
2439
|
+
if (v.category) mergedCategory = mergedCategory || v.category;
|
|
2440
|
+
const ruleIdMatches = gradeResp.match(/<rule_id>([^<]+)<\/rule_id>/g) || [];
|
|
2441
|
+
for (const m of ruleIdMatches.slice(0, 5)) {
|
|
2442
|
+
const id = m.replace(/<\/?rule_id>/g, '').trim().replace(/^cwe-/, 'CWE-');
|
|
2443
|
+
if (id && !cweIds.includes(id)) cweIds.push(id);
|
|
2444
|
+
}
|
|
2445
|
+
const fMatches = gradeResp.match(/<suggested_fix>([^<]+)<\/suggested_fix>/g) || [];
|
|
2446
|
+
const respIds = ruleIdMatches.map(rm => rm.replace(/<\/?rule_id>/g, '').trim().replace(/^cwe-/, 'CWE-'));
|
|
2447
|
+
for (let i = 0; i < Math.min(respIds.length, fMatches.length); i++) {
|
|
2448
|
+
if (!fixes[respIds[i]]) fixes[respIds[i]] = fMatches[i].replace(/<\/?suggested_fix>/g, '').trim();
|
|
2449
|
+
}
|
|
2394
2450
|
}
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
const verdict = anyFailed
|
|
2454
|
+
? { ok: false, reason: mergedReason, severity: mergedSeverity, category: mergedCategory }
|
|
2455
|
+
: { ok: true, reason: '', severity: '', category: '' };
|
|
2395
2456
|
|
|
2457
|
+
if (!verdict.ok) {
|
|
2396
2458
|
const activeCweIds = cweIds.filter(id => !exemptedCwes.has(id.toUpperCase()));
|
|
2397
2459
|
|
|
2398
2460
|
if (activeCweIds.length === 0) {
|
|
@@ -5660,7 +5722,7 @@ function writeConfigEnv(opts) {
|
|
|
5660
5722
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
5661
5723
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
5662
5724
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
5663
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
5725
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.93")}`
|
|
5664
5726
|
];
|
|
5665
5727
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
5666
5728
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -5677,12 +5739,13 @@ function writeConfigEnv(opts) {
|
|
|
5677
5739
|
chmodSync2(CONFIG_PATH2, 384);
|
|
5678
5740
|
}
|
|
5679
5741
|
function resolveDeploymentMode() {
|
|
5680
|
-
const envOverride = process.env.SYNKRO_DEPLOYMENT_MODE;
|
|
5681
|
-
if (envOverride) return envOverride
|
|
5742
|
+
const envOverride = process.env.SYNKRO_DEPLOYMENT_MODE?.toLowerCase();
|
|
5743
|
+
if (envOverride === "bare-host" || envOverride === "docker") return envOverride;
|
|
5682
5744
|
try {
|
|
5683
5745
|
if (existsSync9(CONFIG_PATH2)) {
|
|
5684
5746
|
const m = readFileSync7(CONFIG_PATH2, "utf-8").match(/^SYNKRO_DEPLOYMENT_MODE='([^']*)'/m);
|
|
5685
|
-
|
|
5747
|
+
const val = m?.[1]?.toLowerCase();
|
|
5748
|
+
if (val === "bare-host" || val === "docker") return val;
|
|
5686
5749
|
}
|
|
5687
5750
|
} catch {
|
|
5688
5751
|
}
|
|
@@ -7095,7 +7158,7 @@ var args = process.argv.slice(2);
|
|
|
7095
7158
|
var cmd = args[0] || "";
|
|
7096
7159
|
var subArgs = args.slice(1);
|
|
7097
7160
|
function printVersion() {
|
|
7098
|
-
console.log("1.4.
|
|
7161
|
+
console.log("1.4.93");
|
|
7099
7162
|
}
|
|
7100
7163
|
function printHelp() {
|
|
7101
7164
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|