vibeostheog 0.22.10 → 0.22.12

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.22.12
2
+ - fix: harden scratchpad cache
3
+
4
+
5
+ ## 0.22.11
6
+ - fix: harden blackbox pivot detection and add regression coverage
7
+
1
8
  ## 0.22.10
2
9
  - fix: append enforcement tags (ENF, FLOW, TDD, LOCK) to live footer
3
10
  - fix: flow-todo-queue path inconsistency and loadRules loop bug (#105)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.22.10",
3
+ "version": "0.22.12",
4
4
  "description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
5
5
  "scripts": {
6
6
  "release": "node scripts/release.mjs",
package/src/lib/state.js CHANGED
@@ -831,72 +831,6 @@ function indexAppend(hash, tool, size, extra) {
831
831
  }
832
832
  // ── Scratchpad hit detection ─────────────────────────────────────────
833
833
  const scratchpadHitsSeen = new Set();
834
- function scanRecentScratchpad(dir, titleCase, maxScan = 2000) {
835
- try {
836
- if (!existsSync(dir))
837
- return null;
838
- const entries = readdirSync(dir);
839
- const ptrFiles = entries.filter(e => e.endsWith(".ptr"));
840
- // Try .ptr files first (created by compressToolOutputs mapping input hash -> content hash)
841
- const ptrCandidates = [];
842
- for (const pf of ptrFiles) {
843
- if (ptrCandidates.length >= 50)
844
- break;
845
- try {
846
- const st = statSync(join(dir, pf));
847
- ptrCandidates.push({ ptrPath: join(dir, pf), mtimeMs: st.mtimeMs });
848
- }
849
- catch { }
850
- }
851
- ptrCandidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
852
- for (const { ptrPath } of ptrCandidates) {
853
- try {
854
- const ptrData = safeJsonParse(readFileSync(ptrPath, "utf-8"));
855
- if (!ptrData?.contentHash)
856
- continue;
857
- if (titleCase && ptrData.tool && TOOL_NAME_NORMALIZE[ptrData.tool] !== titleCase)
858
- continue;
859
- const contentHash = ptrData.contentHash;
860
- const f = join(dir, `${contentHash}.txt`);
861
- if (!existsSync(f))
862
- continue;
863
- const st = statSync(f);
864
- const ageSec = (Date.now() - st.mtimeMs) / 1000;
865
- if (ageSec > SCRATCHPAD_MAX_AGE_SEC)
866
- continue;
867
- const sumPath = join(dir, `${contentHash}.summary.txt`);
868
- return { hash: contentHash, fullPath: f, sizeBytes: st.size, ageSec: Math.round(ageSec), summaryPath: existsSync(sumPath) ? sumPath : null };
869
- }
870
- catch { }
871
- }
872
- // Fallback: scan .txt files
873
- const txtFiles = entries.filter(e => e.endsWith(".txt") && !e.endsWith(".summary.txt"));
874
- if (txtFiles.length === 0)
875
- return null;
876
- const candidateHashes = [];
877
- for (let i = txtFiles.length - 1; i >= 0; i--) {
878
- const f = txtFiles[i];
879
- if (candidateHashes.length > 50)
880
- break;
881
- candidateHashes.push(f.replace(/\.txt$/, ""));
882
- }
883
- for (const hash of candidateHashes) {
884
- const f = join(dir, `${hash}.txt`);
885
- if (!existsSync(f))
886
- continue;
887
- const st = statSync(f);
888
- const ageSec = (Date.now() - st.mtimeMs) / 1000;
889
- if (ageSec > SCRATCHPAD_MAX_AGE_SEC)
890
- continue;
891
- const sumPath = join(dir, `${hash}.summary.txt`);
892
- return { hash, fullPath: f, sizeBytes: st.size, ageSec: Math.round(ageSec), summaryPath: existsSync(sumPath) ? sumPath : null };
893
- }
894
- return null;
895
- }
896
- catch {
897
- return null;
898
- }
899
- }
900
834
  function getScratchpadHit(toolLower, args, baseDir = null) {
901
835
  if (!SCRATCHPAD_TOOLS.has(toolLower))
902
836
  return null;
@@ -927,9 +861,6 @@ function getScratchpadHit(toolLower, args, baseDir = null) {
927
861
  catch { }
928
862
  }
929
863
  if (!fullPath) {
930
- const recent = scanRecentScratchpad(sessionDir, titleCase, 2000) || scanRecentScratchpad(globalDir, titleCase, 2000);
931
- if (recent)
932
- return recent;
933
864
  return null;
934
865
  }
935
866
  }
@@ -1809,7 +1740,7 @@ LEDGER_BUFFER_MAX, LEDGER_BUFFER_FLUSH_MS, _ledgerBuffer, _ledgerBufferTimer, _f
1809
1740
  // Stable JSON
1810
1741
  stableJson, _readHead, indexAppend,
1811
1742
  // Scratchpad hits
1812
- scratchpadHitsSeen, scanRecentScratchpad, getScratchpadHit, recordScratchpadObservation, _pruneScratchpadDir, runDecadenceCycle, applyDecadence, cleanupStaleSessionScratchpads, pruneScratchpadOnce,
1743
+ scratchpadHitsSeen, getScratchpadHit, recordScratchpadObservation, _pruneScratchpadDir, runDecadenceCycle, applyDecadence, cleanupStaleSessionScratchpads, pruneScratchpadOnce,
1813
1744
  // Active jobs
1814
1745
  loadActiveJobs, getActiveJobForProject, saveActiveJobForProject, saveJobRecord, loadJobRecord,
1815
1746
  // Project memory