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 +7 -0
- package/package.json +1 -1
- package/src/lib/state.js +1 -70
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.
|
|
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,
|
|
1743
|
+
scratchpadHitsSeen, getScratchpadHit, recordScratchpadObservation, _pruneScratchpadDir, runDecadenceCycle, applyDecadence, cleanupStaleSessionScratchpads, pruneScratchpadOnce,
|
|
1813
1744
|
// Active jobs
|
|
1814
1745
|
loadActiveJobs, getActiveJobForProject, saveActiveJobForProject, saveJobRecord, loadJobRecord,
|
|
1815
1746
|
// Project memory
|