@synkro-sh/cli 1.6.94 → 1.6.95

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 CHANGED
@@ -3687,6 +3687,31 @@ export function countEditLineDelta(source: {
3687
3687
  return { linesAdded, linesRemoved };
3688
3688
  }
3689
3689
 
3690
+ // Build the recorded edit diff (code_change) for the audit trail, same format as
3691
+ // the routed hook's summarizeEdit: trim the common prefix/suffix between the file
3692
+ // before the edit and the proposed full content, then emit minus/plus prefixed,
3693
+ // line-numbered rows (the dashboard CodeChangeCard colors each row by its leading
3694
+ // sign). Without this the event detail falls back to the raw file/content dump
3695
+ // instead of an added/removed diff.
3696
+ export function summarizeEditDiff(baseContent: string, proposed: string): string {
3697
+ const EDIT_AUDIT_CAP = 16000;
3698
+ const a = baseContent ? baseContent.split('\\n') : [];
3699
+ const b = proposed ? proposed.split('\\n') : [];
3700
+ let start = 0;
3701
+ while (start < a.length && start < b.length && a[start] === b[start]) start++;
3702
+ let endA = a.length;
3703
+ let endB = b.length;
3704
+ while (endA > start && endB > start && a[endA - 1] === b[endB - 1]) { endA--; endB--; }
3705
+ const removed = a.slice(start, endA);
3706
+ const added = b.slice(start, endB);
3707
+ const out: string[] = [];
3708
+ for (let i = 0; i < removed.length; i++) out.push('-' + String(start + 1 + i).padStart(5) + ' ' + removed[i]);
3709
+ for (let i = 0; i < added.length; i++) out.push('+' + String(start + 1 + i).padStart(5) + ' ' + added[i]);
3710
+ let diff = out.join('\\n');
3711
+ if (diff.length > EDIT_AUDIT_CAP) diff = diff.slice(0, EDIT_AUDIT_CAP) + '\\n... [truncated]';
3712
+ return diff;
3713
+ }
3714
+
3690
3715
  /** Normalize model names so the same Cursor session doesn't split across agent buckets. */
3691
3716
  export function normalizeCaptureModel(model: string): string {
3692
3717
  const m = (model || '').trim();
@@ -4291,7 +4316,7 @@ import {
4291
4316
  readStdin, extractTranscript, readLastPrompt, findNearestDeps, filePathFromToolInput,
4292
4317
  appendSessionAction, readSessionLog, compressSessionLog, sessionLogForGrade, log,
4293
4318
  outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isEditTool, hookSessionId, GATEWAY_URL,
4294
- logGraderUnavailable, graderUnavailableMessage, filterRules, ruleFilterText, normalizeMode, countEditLineDelta,
4319
+ logGraderUnavailable, graderUnavailableMessage, filterRules, ruleFilterText, normalizeMode, countEditLineDelta, summarizeEditDiff,
4295
4320
  captureLineMetrics, cursorModelFromPayload, resolveTranscriptPath, isCursorInvokingCcHook,
4296
4321
  loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
4297
4322
  type HookConfig, type Rule,
@@ -4386,6 +4411,11 @@ async function main() {
4386
4411
  try { fileBefore = readFileSync(fullPath, 'utf-8').slice(0, 65536); } catch {}
4387
4412
  }
4388
4413
 
4414
+ // Audit diff (code_change): added/removed lines for the event detail's Code Change
4415
+ // card. Base = the file before this edit (Write \u2192 file on disk if any). Captured on
4416
+ // every edit verdict below so cloud-graded events show the diff, not a raw dump.
4417
+ const editDiff = summarizeEditDiff(toolName === 'Write' ? existingContent : fileBefore, proposed);
4418
+
4389
4419
  // Extract transcript context
4390
4420
  const transcript = extractTranscript(transcriptPath);
4391
4421
  const lastPrompt = readLastPrompt(sessionId);
@@ -4530,7 +4560,7 @@ async function main() {
4530
4560
  toolName, gitRepo, sessionId, config.captureDepth, {
4531
4561
  command: editContent, reasoning: guardReason,
4532
4562
  rulesChecked: relevantRules, violatedRules,
4533
- ccModel: captureModel, ...lineMetrics,
4563
+ ccModel: captureModel, codeChange: editDiff, ...lineMetrics,
4534
4564
  });
4535
4565
  outputJson({
4536
4566
  systemMessage: tagStr + ' editGuard ' + fileShort + ' \u2192 blocked: ' + guardReason + (cweFindings.length ? ' (+' + cweFindings.length + ' CWE)' : ''),
@@ -4554,7 +4584,7 @@ async function main() {
4554
4584
  toolName, gitRepo, sessionId, config.captureDepth, {
4555
4585
  command: editContent, reasoning: ruleVerdict.reason || 'no violations (rules + CWE)',
4556
4586
  rulesChecked: relevantRules, violatedRules: [],
4557
- ccModel: captureModel, ...lineMetrics,
4587
+ ccModel: captureModel, codeChange: editDiff, ...lineMetrics,
4558
4588
  });
4559
4589
  const cPassLine = tagStr + ' editGuard ' + fileShort + ' \u2192 pass: ' + (ruleVerdict.reason || 'clean (rules + CWE)');
4560
4590
  const cTaskMsg = await taskDriftP;
@@ -4587,7 +4617,7 @@ async function main() {
4587
4617
  toolName, gitRepo, sessionId, config.captureDepth, {
4588
4618
  command: editContent, reasoning: guardReason,
4589
4619
  rulesChecked: relevantRules, violatedRules,
4590
- ccModel: captureModel, ...lineMetrics,
4620
+ ccModel: captureModel, codeChange: editDiff, ...lineMetrics,
4591
4621
  });
4592
4622
  outputJson({
4593
4623
  systemMessage: tagStr + ' editGuard ' + fileShort + ' \u2192 blocked: ' + guardReason,
@@ -4601,7 +4631,7 @@ async function main() {
4601
4631
  toolName, gitRepo, sessionId, config.captureDepth, {
4602
4632
  command: editContent, reasoning: verdict.reason || 'no policy violations detected',
4603
4633
  rulesChecked: relevantRules, violatedRules: [],
4604
- ccModel: captureModel, ...lineMetrics,
4634
+ ccModel: captureModel, codeChange: editDiff, ...lineMetrics,
4605
4635
  });
4606
4636
  const passLine = tagStr + ' editGuard ' + fileShort + ' \u2192 pass: ' + (verdict.reason || 'no policy violations detected');
4607
4637
  const rTaskMsg = await taskDriftP;
@@ -11269,7 +11299,7 @@ function writeConfigEnv(opts) {
11269
11299
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
11270
11300
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
11271
11301
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
11272
- `SYNKRO_VERSION=${shellQuoteSingle("1.6.94")}`
11302
+ `SYNKRO_VERSION=${shellQuoteSingle("1.6.95")}`
11273
11303
  ];
11274
11304
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
11275
11305
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -15334,7 +15364,7 @@ var args = process.argv.slice(2);
15334
15364
  var cmd = args[0] || "";
15335
15365
  var subArgs = args.slice(1);
15336
15366
  function printVersion() {
15337
- console.log("1.6.94");
15367
+ console.log("1.6.95");
15338
15368
  }
15339
15369
  function printHelp2() {
15340
15370
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents