@ericrisco/rsc 2.0.14 → 2.0.15

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/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.14",
2
+ "version": "2.0.15",
3
3
  "counts": {
4
4
  "skills": 273,
5
5
  "agents": 33,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ericrisco/rsc",
3
- "version": "2.0.14",
3
+ "version": "2.0.15",
4
4
  "description": "A guided harness builder that turns your goal into a minimal, verified AI-agent setup using strict best practices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -85,6 +85,10 @@
85
85
  {
86
86
  "fixedIn": "2.0.12",
87
87
  "symptom": "Security: session continuation context could come from a different git worktree"
88
+ },
89
+ {
90
+ "fixedIn": "2.0.15",
91
+ "symptom": "The 'consider compacting' notice never appears in sessions that edit files through the terminal instead of the Edit tool"
88
92
  }
89
93
  ]
90
94
  }
@@ -319,7 +319,20 @@ export function capture(input = {}) {
319
319
  if (input.event === 'start' && !existing) return { record: null, path: null, notice: null, compactionHint: false };
320
320
 
321
321
  const repo = snapshot(here, anchor.baselineHead);
322
- const editCount = Math.max(0, (existing?.editCount || 0) + (finiteOrNull(input.editDelta, true) || 0));
322
+ // Count what CHANGED, not which tool changed it. `editDelta` is +1 per Edit/Write tool event, and
323
+ // on its own it was blind to everything done through the shell — a heredoc, `sed -i`, a script, a
324
+ // formatter — which is how automated sessions work. The session that found this had touched dozens
325
+ // of files and its record said editCount=1, so the compaction hint never reached the long sessions
326
+ // it exists for.
327
+ //
328
+ // `snapshot` already fingerprints every modified file on every event. Comparing those fingerprints
329
+ // with the previous event's counts a change from any source. `max`, not `+`: an Edit that changed a
330
+ // file shows up in BOTH signals, and must count once.
331
+ const previousFingerprints = anchor.lastFingerprints || anchor.baselineFingerprints || {};
332
+ const observed = Object.entries(repo.fingerprints || {})
333
+ .filter(([path, fingerprint]) => fingerprint && previousFingerprints[path] !== fingerprint).length;
334
+ const editDelta = Math.max(finiteOrNull(input.editDelta, true) || 0, observed);
335
+ const editCount = Math.max(0, (existing?.editCount || 0) + editDelta);
323
336
  const baselineFiles = new Set(anchor.baselineFiles || []);
324
337
  const newDirtyPath = repo.files.some((path) => !baselineFiles.has(path));
325
338
  const baselineFingerprints = anchor.baselineFingerprints || {};
@@ -368,7 +381,17 @@ export function capture(input = {}) {
368
381
  // already written and `readRecords` would quietly drop the project's whole history.
369
382
  let compactionHint = Boolean(config.compactionHint && editCount >= config.editThreshold);
370
383
  if (compactionHint && anchor.compactionHintedAt) compactionHint = false;
371
- else if (compactionHint) atomicJson(anchorPath, { ...anchor, compactionHintedAt: now });
384
+ // One anchor write per event at most, carrying both pieces of per-session state: the fingerprints
385
+ // the next event compares against, and the once-per-session hint mark. Written only when either
386
+ // actually changed, so a read-only shell command costs no extra disk.
387
+ const fingerprintsMoved = observed > 0 || !anchor.lastFingerprints;
388
+ if (compactionHint || fingerprintsMoved) {
389
+ atomicJson(anchorPath, {
390
+ ...anchor,
391
+ lastFingerprints: repo.fingerprints || {},
392
+ ...(compactionHint ? { compactionHintedAt: now } : {}),
393
+ });
394
+ }
372
395
  return {
373
396
  record,
374
397
  path: recordPath,