vibeostheog 0.25.48 → 0.25.49
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/dist/assets/dashboard/vibeos-dashboard-config.js +1 -1
- package/dist/vibeOS.js +229 -286
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## 0.25.49
|
|
2
|
+
- fix: keep scratchpad cache session-only (#271)
|
|
3
|
+
- test: cover empty reward input (#269)
|
|
4
|
+
Merge remote-tracking branch 'origin/release/v0.25.48'
|
|
5
|
+
Stabilize claim status footer (#270)
|
|
6
|
+
|
|
7
|
+
|
|
1
8
|
## 0.25.48
|
|
2
9
|
- feat: reward engine — quality credits, saving bonus, lie/laziness penalties (#266)
|
|
3
10
|
- fix: forward claim evidence into reward scoring (#268)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:
|
|
1
|
+
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:41975";
|
package/dist/vibeOS.js
CHANGED
|
@@ -1538,6 +1538,21 @@ function ensureSessionScratchpadDirs() {
|
|
|
1538
1538
|
return false;
|
|
1539
1539
|
}
|
|
1540
1540
|
}
|
|
1541
|
+
function safeCopyIntoSession(hash, fromPath, targetScratchpadDir = getSessionScratchpadDir()) {
|
|
1542
|
+
try {
|
|
1543
|
+
mkdirSync(targetScratchpadDir, { recursive: true });
|
|
1544
|
+
const sessionPath = join2(targetScratchpadDir, `${hash}.txt`);
|
|
1545
|
+
if (!existsSync2(sessionPath)) {
|
|
1546
|
+
copyFileSync(fromPath, sessionPath);
|
|
1547
|
+
const globalSummary = join2(SCRATCHPAD_GLOBAL_DIR, `${hash}.summary.txt`);
|
|
1548
|
+
const sessionSummary = join2(targetScratchpadDir, `${hash}.summary.txt`);
|
|
1549
|
+
if (existsSync2(globalSummary) && !existsSync2(sessionSummary)) {
|
|
1550
|
+
copyFileSync(globalSummary, sessionSummary);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
} catch {
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1541
1556
|
function cleanupCurrentSessionScratchpad() {
|
|
1542
1557
|
if (_sessionCacheCleaned)
|
|
1543
1558
|
return;
|
|
@@ -1732,52 +1747,6 @@ function indexAppend(hash, tool2, size, extra) {
|
|
|
1732
1747
|
console.error(`[vibeOS] index write failed: ${err.message}`);
|
|
1733
1748
|
}
|
|
1734
1749
|
}
|
|
1735
|
-
function scanRecentScratchpad(dir, titleCase, maxScan = 2e3) {
|
|
1736
|
-
try {
|
|
1737
|
-
if (!existsSync2(dir))
|
|
1738
|
-
return null;
|
|
1739
|
-
const entries = readdirSync(dir);
|
|
1740
|
-
const ptrFiles = entries.filter((e) => e.endsWith(".ptr"));
|
|
1741
|
-
const ptrCandidates = [];
|
|
1742
|
-
for (const pf of ptrFiles) {
|
|
1743
|
-
if (ptrCandidates.length >= MAX_PTR_CANDIDATES)
|
|
1744
|
-
break;
|
|
1745
|
-
try {
|
|
1746
|
-
const st = statSync2(join2(dir, pf));
|
|
1747
|
-
ptrCandidates.push({ ptrPath: join2(dir, pf), mtimeMs: st.mtimeMs });
|
|
1748
|
-
} catch {
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
ptrCandidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
1752
|
-
let scanned = 0;
|
|
1753
|
-
for (const { ptrPath } of ptrCandidates) {
|
|
1754
|
-
if (scanned++ >= maxScan)
|
|
1755
|
-
break;
|
|
1756
|
-
try {
|
|
1757
|
-
const ptrData = safeJsonParse2(readFileSync2(ptrPath, "utf-8"));
|
|
1758
|
-
if (!ptrData?.contentHash)
|
|
1759
|
-
continue;
|
|
1760
|
-
const ptrTool = typeof ptrData.tool === "string" ? TOOL_NAME_NORMALIZE[ptrData.tool] || ptrData.tool : null;
|
|
1761
|
-
if (titleCase && ptrTool && ptrTool !== titleCase)
|
|
1762
|
-
continue;
|
|
1763
|
-
const contentHash = String(ptrData.contentHash);
|
|
1764
|
-
const f = join2(dir, `${contentHash}.txt`);
|
|
1765
|
-
if (!existsSync2(f))
|
|
1766
|
-
continue;
|
|
1767
|
-
const st = statSync2(f);
|
|
1768
|
-
const ageSec = (Date.now() - st.mtimeMs) / 1e3;
|
|
1769
|
-
if (ageSec > SCRATCHPAD_MAX_AGE_SEC)
|
|
1770
|
-
continue;
|
|
1771
|
-
const sumPath = join2(dir, `${contentHash}.summary.txt`);
|
|
1772
|
-
return { hash: contentHash, fullPath: f, sizeBytes: st.size, ageSec: Math.round(ageSec), summaryPath: existsSync2(sumPath) ? sumPath : null };
|
|
1773
|
-
} catch {
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
return null;
|
|
1777
|
-
} catch {
|
|
1778
|
-
return null;
|
|
1779
|
-
}
|
|
1780
|
-
}
|
|
1781
1750
|
function getScratchpadHit(toolLower, args, baseDir = null) {
|
|
1782
1751
|
if (!SCRATCHPAD_TOOLS.has(toolLower))
|
|
1783
1752
|
return null;
|
|
@@ -1804,12 +1773,8 @@ ${inputJson}
|
|
|
1804
1773
|
} catch {
|
|
1805
1774
|
}
|
|
1806
1775
|
}
|
|
1807
|
-
if (!fullPath)
|
|
1808
|
-
const recent = scanRecentScratchpad(sessionDir, titleCase, 2e3);
|
|
1809
|
-
if (recent)
|
|
1810
|
-
return recent;
|
|
1776
|
+
if (!fullPath)
|
|
1811
1777
|
return null;
|
|
1812
|
-
}
|
|
1813
1778
|
}
|
|
1814
1779
|
try {
|
|
1815
1780
|
const st = statSync2(fullPath);
|
|
@@ -2683,7 +2648,7 @@ function saveSessionCheckpoint() {
|
|
|
2683
2648
|
} catch {
|
|
2684
2649
|
}
|
|
2685
2650
|
}
|
|
2686
|
-
var USER_HOME2, VIBEOS_CONTEXT, VIBEOS_HOME, OPENCODE_HOME, FILE_LOCK_DIR, DELEGATION_STATE_FILE, SAVINGS_LEDGER_FILE, GLOBAL_LEARNING_FILE, PRICING_CACHE_FILE, BLACKBOX_STATE_FILE, PROJECT_STATE_FILE, TIERS_FILE, ACTIVE_JOBS_FILE, AUTH_F, CREDIT_CACHE_F, FLOW_TODO_QUEUE_FILE, FLOW_DEDUP_FILE, ENFORCEMENT_COOLDOWN_FILE, TODOS_FILE, REPORTS_DIR, CONTEXT7_INSTALL_FLAG, TRINITY_OPENCODE_CONFIG, TRINITY_OPENCODE_CONFIGC, SCRATCHPAD_ROOT, SCRATCHPAD_GLOBAL_DIR, SCRATCHPAD_SESSIONS_DIR, SCRATCHPAD_SESSION_TTL_MS, SCRATCHPAD_MAX_AGE_SEC, MAX_SCRATCHPAD_FILES, MAX_SCRATCHPAD_BYTES, MAX_SESSION_SCRATCHPAD_FILES, MAX_SESSION_SCRATCHPAD_BYTES, CORRUPTION_BACKUP_MAX, CORRUPTION_BACKUP_TTL_MS, LEDGER_ROTATE_MAX_BYTES, LEDGER_ROTATE_MAX_LINES, LEDGER_ROTATE_MAX_AGE_MS, ACTIVE_JOBS_STALE_MS,
|
|
2651
|
+
var USER_HOME2, VIBEOS_CONTEXT, VIBEOS_HOME, OPENCODE_HOME, FILE_LOCK_DIR, DELEGATION_STATE_FILE, SAVINGS_LEDGER_FILE, GLOBAL_LEARNING_FILE, PRICING_CACHE_FILE, BLACKBOX_STATE_FILE, PROJECT_STATE_FILE, TIERS_FILE, ACTIVE_JOBS_FILE, AUTH_F, CREDIT_CACHE_F, FLOW_TODO_QUEUE_FILE, FLOW_DEDUP_FILE, ENFORCEMENT_COOLDOWN_FILE, TODOS_FILE, REPORTS_DIR, CONTEXT7_INSTALL_FLAG, TRINITY_OPENCODE_CONFIG, TRINITY_OPENCODE_CONFIGC, SCRATCHPAD_ROOT, SCRATCHPAD_GLOBAL_DIR, SCRATCHPAD_SESSIONS_DIR, SCRATCHPAD_SESSION_TTL_MS, SCRATCHPAD_MAX_AGE_SEC, MAX_SCRATCHPAD_FILES, MAX_SCRATCHPAD_BYTES, MAX_SESSION_SCRATCHPAD_FILES, MAX_SESSION_SCRATCHPAD_BYTES, CORRUPTION_BACKUP_MAX, CORRUPTION_BACKUP_TTL_MS, LEDGER_ROTATE_MAX_BYTES, LEDGER_ROTATE_MAX_LINES, LEDGER_ROTATE_MAX_AGE_MS, ACTIVE_JOBS_STALE_MS, SUMMARY_HEAD_TRUNCATE, DECADENCE_FRESH_MS, DECADENCE_WARM_MS, DECADENCE_COLD_MS, DECADENCE_EXPIRE_MS, DECADENCE_THROTTLE_MS, DECADENCE_GLOBAL_THROTTLE_MS, TOOL_NAME_NORMALIZE, SCRATCHPAD_TOOLS, WARN_DEDUPE_WINDOW_MS, SOFT_QUOTA_LIMIT, _OC_SID, currentSessionId, _sessionStart, currentTier, currentModel, currentProjectFingerprint, currentProjectName, recentToolEvents, frictionSessionKeys, _savingsCache, _savingsCacheMtime, _ledgerReconciledMtime, _ledgerTotalsCache, _mlGraph, _cacheDb, ML_ENABLED, ML_CONFIDENCE_THRESHOLD, _mlSavePending, _blackboxEnabled, _latestBlackboxState, _latestBlackboxLoopMsg, _latestBlackboxPivotMsg, _modelLocked, _lockedSlot, _lockedModel, _sessionCleanupRegistered, _sessionCacheCleaned, prunedThisProcess, _lastDecadenceRun, briefedProjects, _ledgerBuffer, _ledgerBufferTimer, LEDGER_BUFFER_MAX, LEDGER_BUFFER_FLUSH_MS, testReminderSeen, DFLT_GL, tool, _startupMaintenanceHome, FALLBACK_HIGH, FALLBACK_MID, HIGH_TIER_RE, MID_TIER_RE, scratchpadHitsSeen;
|
|
2687
2652
|
var init_state = __esm({
|
|
2688
2653
|
"src/lib/state.js"() {
|
|
2689
2654
|
"use strict";
|
|
@@ -2736,7 +2701,6 @@ var init_state = __esm({
|
|
|
2736
2701
|
LEDGER_ROTATE_MAX_LINES = 1e4;
|
|
2737
2702
|
LEDGER_ROTATE_MAX_AGE_MS = 48 * 60 * 60 * 1e3;
|
|
2738
2703
|
ACTIVE_JOBS_STALE_MS = 72 * 60 * 60 * 1e3;
|
|
2739
|
-
MAX_PTR_CANDIDATES = 50;
|
|
2740
2704
|
SUMMARY_HEAD_TRUNCATE = 500;
|
|
2741
2705
|
DECADENCE_FRESH_MS = 5 * 60 * 1e3;
|
|
2742
2706
|
DECADENCE_WARM_MS = 60 * 60 * 1e3;
|
|
@@ -5126,8 +5090,8 @@ var init_vibeultrax = __esm({
|
|
|
5126
5090
|
|
|
5127
5091
|
// src/index.ts
|
|
5128
5092
|
init_flow_enforcer();
|
|
5129
|
-
import { readFileSync as
|
|
5130
|
-
import { join as
|
|
5093
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync18, existsSync as existsSync20, mkdirSync as mkdirSync15, copyFileSync as copyFileSync2, renameSync as renameSync6, statSync as statSync9 } from "node:fs";
|
|
5094
|
+
import { join as join20, dirname as dirname13, basename as basename5 } from "node:path";
|
|
5131
5095
|
|
|
5132
5096
|
// src/vibeOS-lib/session-metrics.js
|
|
5133
5097
|
function formatDuration(totalSeconds) {
|
|
@@ -11248,16 +11212,76 @@ async function probeModel(modelId, auth, providers = null) {
|
|
|
11248
11212
|
}
|
|
11249
11213
|
|
|
11250
11214
|
// src/lib/hooks/footer.js
|
|
11251
|
-
import { readFileSync as
|
|
11252
|
-
import { join as
|
|
11215
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync15, appendFileSync as appendFileSync5, mkdirSync as mkdirSync12 } from "node:fs";
|
|
11216
|
+
import { join as join17 } from "node:path";
|
|
11253
11217
|
|
|
11254
11218
|
// src/lib/hooks/chat-transform.js
|
|
11255
11219
|
init_state();
|
|
11256
|
-
import { readFileSync as
|
|
11257
|
-
import { join as
|
|
11220
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync14, appendFileSync as appendFileSync4, existsSync as existsSync16, mkdirSync as mkdirSync11, rmSync as rmSync5, readdirSync as readdirSync3, statSync as statSync7 } from "node:fs";
|
|
11221
|
+
import { join as join16, dirname as dirname10, basename as basename3 } from "node:path";
|
|
11258
11222
|
import { createHash as createHash3 } from "node:crypto";
|
|
11259
11223
|
import { homedir as homedir6 } from "node:os";
|
|
11260
11224
|
|
|
11225
|
+
// src/lib/claim-verification.js
|
|
11226
|
+
import { existsSync as existsSync14, readFileSync as readFileSync13 } from "node:fs";
|
|
11227
|
+
import { join as join13 } from "node:path";
|
|
11228
|
+
var CLAIM_PATTERNS = [
|
|
11229
|
+
/(?:I|we|the)\s+(?:pushed|released|merged|deployed|fixed|wrote|implemented|completed|committed)\b/i,
|
|
11230
|
+
/(?:tests?|build|CI|checks?|suite|output|result)\s+(?:is\s+|are\s+)?(?:pass(?:ing|ed|es)?|green|clean|succeed|stable|positive)/i,
|
|
11231
|
+
/v\d+\.\d+\.\d+/,
|
|
11232
|
+
/\d+\s*(?:test|spec)s?\s*(?:pass|passing)/i,
|
|
11233
|
+
/(?:exit\s*code\s*0|0\s*errors|0\s*failures)/i
|
|
11234
|
+
];
|
|
11235
|
+
function extractClaimMatches(text) {
|
|
11236
|
+
if (!text || typeof text !== "string")
|
|
11237
|
+
return [];
|
|
11238
|
+
const claims = [];
|
|
11239
|
+
const lines = String(text).split("\n");
|
|
11240
|
+
for (let i = 0; i < lines.length; i++) {
|
|
11241
|
+
for (const pat of CLAIM_PATTERNS) {
|
|
11242
|
+
if (pat.test(lines[i])) {
|
|
11243
|
+
claims.push({ line: i + 1, text: lines[i].trim().substring(0, 120), pattern: pat.source });
|
|
11244
|
+
break;
|
|
11245
|
+
}
|
|
11246
|
+
}
|
|
11247
|
+
}
|
|
11248
|
+
return claims;
|
|
11249
|
+
}
|
|
11250
|
+
function loadRecentCascadeRuns(vibeHome) {
|
|
11251
|
+
try {
|
|
11252
|
+
const cascadeFile = join13(vibeHome, "cascade-audit", "cascade-audit.jsonl");
|
|
11253
|
+
if (!existsSync14(cascadeFile))
|
|
11254
|
+
return [];
|
|
11255
|
+
const raw = readFileSync13(cascadeFile, "utf-8");
|
|
11256
|
+
if (!raw || typeof raw !== "string")
|
|
11257
|
+
return [];
|
|
11258
|
+
return raw.trim().split("\n").filter(Boolean).slice(-30).map((l) => {
|
|
11259
|
+
try {
|
|
11260
|
+
return JSON.parse(l);
|
|
11261
|
+
} catch {
|
|
11262
|
+
return null;
|
|
11263
|
+
}
|
|
11264
|
+
}).filter(Boolean);
|
|
11265
|
+
} catch {
|
|
11266
|
+
return [];
|
|
11267
|
+
}
|
|
11268
|
+
}
|
|
11269
|
+
function evaluateClaimVerification({ text, vibeHome = process.env.VIBEOS_HOME || join13(process.env.HOME || "", ".claude"), now = Date.now(), windowMs = 12e4 }) {
|
|
11270
|
+
const claims = extractClaimMatches(text);
|
|
11271
|
+
if (claims.length === 0)
|
|
11272
|
+
return { claims, unsubstantiatedCount: 0, claimTag: "" };
|
|
11273
|
+
const cascadeRuns = loadRecentCascadeRuns(vibeHome);
|
|
11274
|
+
const substantiated = cascadeRuns.some((cr) => {
|
|
11275
|
+
const cTs = typeof cr === "object" && cr ? cr._ts || "" : "";
|
|
11276
|
+
return Boolean(cTs) && Math.abs(new Date(cTs).getTime() - now) < windowMs;
|
|
11277
|
+
});
|
|
11278
|
+
return {
|
|
11279
|
+
claims,
|
|
11280
|
+
unsubstantiatedCount: substantiated ? 0 : claims.length,
|
|
11281
|
+
claimTag: substantiated ? "\u2713" : `\u26A0${claims.length}`
|
|
11282
|
+
};
|
|
11283
|
+
}
|
|
11284
|
+
|
|
11261
11285
|
// src/lib/mode-policy.js
|
|
11262
11286
|
init_state();
|
|
11263
11287
|
var STRESS_QUALITY_THRESHOLD = 1.5;
|
|
@@ -11453,15 +11477,15 @@ init_api_client();
|
|
|
11453
11477
|
init_selection_manager();
|
|
11454
11478
|
|
|
11455
11479
|
// src/lib/index-helpers.js
|
|
11456
|
-
import { join as
|
|
11480
|
+
import { join as join15 } from "node:path";
|
|
11457
11481
|
import { writeFileSync as writeFileSync13 } from "node:fs";
|
|
11458
11482
|
|
|
11459
11483
|
// src/vibeOS-lib/semantic-observer.js
|
|
11460
11484
|
init_state();
|
|
11461
11485
|
init_pattern_helpers();
|
|
11462
11486
|
init_pattern_helpers();
|
|
11463
|
-
import { join as
|
|
11464
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync12, readFileSync as
|
|
11487
|
+
import { join as join14 } from "node:path";
|
|
11488
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync12, readFileSync as readFileSync14, existsSync as existsSync15 } from "node:fs";
|
|
11465
11489
|
function deriveRole(toolName, input, output) {
|
|
11466
11490
|
if (["write", "edit", "notebookedit", "multiedit"].includes(toolName))
|
|
11467
11491
|
return "mutation";
|
|
@@ -11488,15 +11512,15 @@ function deriveTags(input, output) {
|
|
|
11488
11512
|
};
|
|
11489
11513
|
}
|
|
11490
11514
|
function getSessionEventLogPath(sid) {
|
|
11491
|
-
const dir =
|
|
11515
|
+
const dir = join14(VIBEOS_HOME, "session-events");
|
|
11492
11516
|
mkdirSync10(dir, { recursive: true });
|
|
11493
|
-
return
|
|
11517
|
+
return join14(dir, sid + ".jsonl");
|
|
11494
11518
|
}
|
|
11495
11519
|
function writeEvent(sid, event) {
|
|
11496
11520
|
const path = getSessionEventLogPath(sid);
|
|
11497
11521
|
let lines = [];
|
|
11498
|
-
if (
|
|
11499
|
-
const raw =
|
|
11522
|
+
if (existsSync15(path)) {
|
|
11523
|
+
const raw = readFileSync14(path, "utf-8").trim();
|
|
11500
11524
|
if (raw)
|
|
11501
11525
|
lines = raw.split("\n");
|
|
11502
11526
|
}
|
|
@@ -11507,9 +11531,9 @@ function writeEvent(sid, event) {
|
|
|
11507
11531
|
}
|
|
11508
11532
|
function readRecentEvents(sid, n) {
|
|
11509
11533
|
const path = getSessionEventLogPath(sid);
|
|
11510
|
-
if (!
|
|
11534
|
+
if (!existsSync15(path))
|
|
11511
11535
|
return [];
|
|
11512
|
-
const raw =
|
|
11536
|
+
const raw = readFileSync14(path, "utf-8").trim();
|
|
11513
11537
|
if (!raw)
|
|
11514
11538
|
return [];
|
|
11515
11539
|
const lines = raw.split("\n");
|
|
@@ -11691,9 +11715,9 @@ function sessionCompact(sid, fingerprint) {
|
|
|
11691
11715
|
for (const p of patterns) {
|
|
11692
11716
|
recordFrictionPattern(p.key, p.summary, { kind: p.kind, sessions: [sid], fingerprint });
|
|
11693
11717
|
}
|
|
11694
|
-
const bbPath =
|
|
11695
|
-
if (
|
|
11696
|
-
const raw =
|
|
11718
|
+
const bbPath = join14(VIBEOS_HOME, "blackbox-state.json");
|
|
11719
|
+
if (existsSync15(bbPath)) {
|
|
11720
|
+
const raw = readFileSync14(bbPath, "utf-8");
|
|
11697
11721
|
if (raw) {
|
|
11698
11722
|
const bb = JSON.parse(raw);
|
|
11699
11723
|
const ses = bb?.sessions?.[sid];
|
|
@@ -11951,7 +11975,7 @@ function recordSaving(tool2, reason, saveEst, meta = {}) {
|
|
|
11951
11975
|
try {
|
|
11952
11976
|
const sd = getSessionScratchpadDir();
|
|
11953
11977
|
if (sd) {
|
|
11954
|
-
const sp =
|
|
11978
|
+
const sp = join15(sd, "delegation-state-hint.txt");
|
|
11955
11979
|
try {
|
|
11956
11980
|
writeFileSync13(sp, JSON.stringify({ sid, total_savings: s.lifetime.total_savings_usd, last_reason: reason }), "utf8");
|
|
11957
11981
|
} catch {
|
|
@@ -12116,7 +12140,7 @@ var ANTI_LOOP_DIRECTIVE = "[anti-loop cost guard] Token waste is real money: if
|
|
|
12116
12140
|
var _cachedC7Full = null;
|
|
12117
12141
|
var _cachedC7Urgency = null;
|
|
12118
12142
|
function getVibeOSHome9() {
|
|
12119
|
-
return process.env.VIBEOS_HOME ||
|
|
12143
|
+
return process.env.VIBEOS_HOME || join16(process.env.HOME || "", ".claude");
|
|
12120
12144
|
}
|
|
12121
12145
|
function mergeRemoteControlVector(remoteControlVector, localControlVector) {
|
|
12122
12146
|
return {
|
|
@@ -12135,14 +12159,14 @@ function resolveRestorableOpenCodeAgent(currentSel) {
|
|
|
12135
12159
|
if (remembered && remembered !== "plan")
|
|
12136
12160
|
return remembered;
|
|
12137
12161
|
try {
|
|
12138
|
-
const configDir = dirname10(TRINITY_OPENCODE_CONFIG ||
|
|
12162
|
+
const configDir = dirname10(TRINITY_OPENCODE_CONFIG || join16(getOpenCodeHome(), "opencode.json"));
|
|
12139
12163
|
const candidates = readdirSync3(configDir).filter((name) => /^opencode\.json\.bak/.test(name)).map((name) => {
|
|
12140
|
-
const path =
|
|
12164
|
+
const path = join16(configDir, name);
|
|
12141
12165
|
return { path, mtime: statSync7(path).mtimeMs };
|
|
12142
12166
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
12143
12167
|
for (const candidate of candidates) {
|
|
12144
12168
|
try {
|
|
12145
|
-
const snapshot = safeJsonParse2(
|
|
12169
|
+
const snapshot = safeJsonParse2(readFileSync15(candidate.path, "utf-8"));
|
|
12146
12170
|
const agent = typeof snapshot?.default_agent === "string" ? snapshot.default_agent.trim() : "";
|
|
12147
12171
|
if (agent && agent !== "plan")
|
|
12148
12172
|
return agent;
|
|
@@ -12246,11 +12270,11 @@ function buildProjectBriefing(directory3) {
|
|
|
12246
12270
|
return `[project memory] Active project: ${label}. Stay focused on the current repository and prefer the existing workflow.`;
|
|
12247
12271
|
}
|
|
12248
12272
|
function ensureProjectSkill(dir, fp2) {
|
|
12249
|
-
const skillsDir =
|
|
12273
|
+
const skillsDir = join16(dir, ".opencode", "skills");
|
|
12250
12274
|
const projectName = basename3(dir);
|
|
12251
|
-
const skillDir =
|
|
12252
|
-
const skillPath =
|
|
12253
|
-
if (
|
|
12275
|
+
const skillDir = join16(skillsDir, projectName);
|
|
12276
|
+
const skillPath = join16(skillDir, "SKILL.md");
|
|
12277
|
+
if (existsSync16(skillPath)) {
|
|
12254
12278
|
return { created: false, skipped: true, path: skillPath };
|
|
12255
12279
|
}
|
|
12256
12280
|
const promoted = promotedProjectPatterns(fp2);
|
|
@@ -12428,9 +12452,9 @@ function syncControlSettings(cv, options = {}) {
|
|
|
12428
12452
|
}
|
|
12429
12453
|
if (cv.agent_mode) {
|
|
12430
12454
|
try {
|
|
12431
|
-
const OC_CONFIG = TRINITY_OPENCODE_CONFIG ||
|
|
12432
|
-
if (
|
|
12433
|
-
const oc = safeJsonParse2(
|
|
12455
|
+
const OC_CONFIG = TRINITY_OPENCODE_CONFIG || join16(getOpenCodeHome(), "opencode.json");
|
|
12456
|
+
if (existsSync16(OC_CONFIG)) {
|
|
12457
|
+
const oc = safeJsonParse2(readFileSync15(OC_CONFIG, "utf-8"));
|
|
12434
12458
|
if (!oc)
|
|
12435
12459
|
return;
|
|
12436
12460
|
if (oc.default_agent !== cv.agent_mode) {
|
|
@@ -12445,9 +12469,9 @@ function syncControlSettings(cv, options = {}) {
|
|
|
12445
12469
|
}
|
|
12446
12470
|
} else {
|
|
12447
12471
|
try {
|
|
12448
|
-
const OC_CONFIG = TRINITY_OPENCODE_CONFIG ||
|
|
12449
|
-
if (
|
|
12450
|
-
const oc = safeJsonParse2(
|
|
12472
|
+
const OC_CONFIG = TRINITY_OPENCODE_CONFIG || join16(getOpenCodeHome(), "opencode.json");
|
|
12473
|
+
if (existsSync16(OC_CONFIG)) {
|
|
12474
|
+
const oc = safeJsonParse2(readFileSync15(OC_CONFIG, "utf-8"));
|
|
12451
12475
|
if (!oc)
|
|
12452
12476
|
return;
|
|
12453
12477
|
const restoreAgent = oc.default_agent === "plan" ? resolveRestorableOpenCodeAgent(currentSel) : null;
|
|
@@ -12514,25 +12538,26 @@ function compressToolOutputs(messages) {
|
|
|
12514
12538
|
const hash = createHash3("sha256").update(`tool_result
|
|
12515
12539
|
${raw}
|
|
12516
12540
|
`).digest("hex").slice(0, 16);
|
|
12517
|
-
const globalDir =
|
|
12518
|
-
const sessPath =
|
|
12519
|
-
const globalPath =
|
|
12541
|
+
const globalDir = join16(SCRATCHPAD_ROOT, "by-hash");
|
|
12542
|
+
const sessPath = join16(getSessionScratchpadDir(), `${hash}.txt`);
|
|
12543
|
+
const globalPath = join16(globalDir, `${hash}.txt`);
|
|
12520
12544
|
try {
|
|
12521
12545
|
mkdirSync11(globalDir, { recursive: true });
|
|
12522
12546
|
ensureSessionScratchpadDirs();
|
|
12523
|
-
if (!
|
|
12547
|
+
if (!existsSync16(globalPath)) {
|
|
12524
12548
|
writeFileSync14(globalPath, raw);
|
|
12525
12549
|
indexAppend(hash, part.tool, raw.length);
|
|
12526
|
-
if (
|
|
12550
|
+
if (existsSync16(sessPath))
|
|
12527
12551
|
rmSync5(sessPath, { force: true });
|
|
12528
12552
|
}
|
|
12553
|
+
safeCopyIntoSession(hash, globalPath);
|
|
12529
12554
|
const invPart = parts.slice(0, parts.indexOf(part)).reverse().find((p) => p?.type === "tool" && p?.tool === part.tool && p?.state?.input && p?.state?.status !== "completed");
|
|
12530
12555
|
if (invPart?.state?.input) {
|
|
12531
12556
|
const toolKey2 = TOOL_NAME_NORMALIZE[part.tool] || part.tool;
|
|
12532
12557
|
const inputHash = createHash3("sha256").update(`${toolKey2}
|
|
12533
12558
|
${stableJson(invPart.state.input)}
|
|
12534
12559
|
`).digest("hex").slice(0, 16);
|
|
12535
|
-
const ptrPath =
|
|
12560
|
+
const ptrPath = join16(getSessionScratchpadDir(), `${inputHash}.ptr`);
|
|
12536
12561
|
try {
|
|
12537
12562
|
writeFileSync14(ptrPath, JSON.stringify({ contentHash: hash, tool: part.tool }));
|
|
12538
12563
|
} catch {
|
|
@@ -12680,78 +12705,30 @@ var onMessagesTransform = async (_input, output) => {
|
|
|
12680
12705
|
try {
|
|
12681
12706
|
if (!Array.isArray(messages) || Object.isFrozen(messages))
|
|
12682
12707
|
return;
|
|
12683
|
-
const vibeHome = process.env.VIBEOS_HOME ||
|
|
12708
|
+
const vibeHome = process.env.VIBEOS_HOME || join16(process.env.HOME || homedir6(), ".claude");
|
|
12684
12709
|
if (typeof vibeHome !== "string" || vibeHome.length === 0)
|
|
12685
12710
|
return;
|
|
12686
|
-
|
|
12687
|
-
const cascadeFile = join15(vibeHome, "cascade-audit", "cascade-audit.jsonl");
|
|
12688
|
-
if (!existsSync15(claimFile))
|
|
12689
|
-
return;
|
|
12690
|
-
const st = statSync7(claimFile);
|
|
12691
|
-
if (!st || st.size <= 0)
|
|
12692
|
-
return;
|
|
12693
|
-
const claimRaw = readFileSync14(claimFile, "utf-8");
|
|
12694
|
-
if (!claimRaw || typeof claimRaw !== "string")
|
|
12695
|
-
return;
|
|
12696
|
-
const claimLines = claimRaw.trim().split("\n").filter(Boolean).slice(-5);
|
|
12697
|
-
if (claimLines.length === 0)
|
|
12698
|
-
return;
|
|
12699
|
-
const cascadeRaw = existsSync15(cascadeFile) ? readFileSync14(cascadeFile, "utf-8") : "";
|
|
12700
|
-
const cascadeLines = cascadeRaw && typeof cascadeRaw === "string" ? cascadeRaw.trim().split("\n").filter(Boolean).slice(-20) : [];
|
|
12701
|
-
const cascadeRuns = cascadeLines.map((l) => {
|
|
12702
|
-
try {
|
|
12703
|
-
return JSON.parse(l);
|
|
12704
|
-
} catch {
|
|
12705
|
-
return null;
|
|
12706
|
-
}
|
|
12707
|
-
}).filter(Boolean);
|
|
12708
|
-
const unsubClaims = [];
|
|
12711
|
+
let currentAssistantText = "";
|
|
12709
12712
|
let lastInjectTs = 0;
|
|
12710
12713
|
for (let i = messages.length - 1; i >= Math.max(0, messages.length - 4); i--) {
|
|
12711
12714
|
const m = messages[i];
|
|
12712
12715
|
if (!m || typeof m !== "object")
|
|
12713
12716
|
continue;
|
|
12714
12717
|
if (m.role === "assistant" && Array.isArray(m.parts)) {
|
|
12718
|
+
currentAssistantText = m.parts.filter((p) => p && typeof p === "object" && p.type === "text" && typeof p.text === "string").map((p) => p.text).join("\n");
|
|
12715
12719
|
for (const p of m.parts) {
|
|
12716
12720
|
if (p && typeof p === "object" && p.type === "text" && typeof p.text === "string" && p.text.includes("[verify]")) {
|
|
12717
12721
|
lastInjectTs = Date.now();
|
|
12718
12722
|
}
|
|
12719
12723
|
}
|
|
12724
|
+
if (currentAssistantText)
|
|
12725
|
+
break;
|
|
12720
12726
|
}
|
|
12721
12727
|
}
|
|
12722
12728
|
if (Date.now() - lastInjectTs < 3e4)
|
|
12723
12729
|
return;
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
continue;
|
|
12727
|
-
let entry;
|
|
12728
|
-
try {
|
|
12729
|
-
entry = JSON.parse(cl);
|
|
12730
|
-
} catch {
|
|
12731
|
-
continue;
|
|
12732
|
-
}
|
|
12733
|
-
if (!entry || typeof entry !== "object")
|
|
12734
|
-
continue;
|
|
12735
|
-
const claimTexts = (entry.claims || []).filter(Boolean).map((c) => typeof c === "object" && c.text ? c.text : "").filter(Boolean).join(" | ");
|
|
12736
|
-
if (!claimTexts)
|
|
12737
|
-
continue;
|
|
12738
|
-
if (!/(?:I|we|the)\s+(?:pushed|released|merged|deployed|fixed)\b|(?:tests?|build|CI|checks?)\s+(?:is\s+|are\s+)?(?:pass|green|clean)\b|v\d+\.\d+\.\d+|done|fixed|works|exit\s*code\s*0|\d+%|score|passed/i.test(claimTexts))
|
|
12739
|
-
continue;
|
|
12740
|
-
let cascadeMatch = false;
|
|
12741
|
-
for (const cr of cascadeRuns) {
|
|
12742
|
-
const cTs = typeof cr === "object" && cr ? cr._ts || "" : "";
|
|
12743
|
-
if (cTs && entry.ts && Math.abs(new Date(cTs).getTime() - new Date(entry.ts).getTime()) < 12e4) {
|
|
12744
|
-
cascadeMatch = true;
|
|
12745
|
-
break;
|
|
12746
|
-
}
|
|
12747
|
-
}
|
|
12748
|
-
if (!cascadeMatch) {
|
|
12749
|
-
for (const c of entry.claims || []) {
|
|
12750
|
-
if (c && typeof c === "object" && c.text)
|
|
12751
|
-
unsubClaims.push(c.text);
|
|
12752
|
-
}
|
|
12753
|
-
}
|
|
12754
|
-
}
|
|
12730
|
+
const claimStatus = evaluateClaimVerification({ text: currentAssistantText, vibeHome });
|
|
12731
|
+
const unsubClaims = claimStatus.unsubstantiatedCount > 0 ? claimStatus.claims.map((c) => c.text).filter(Boolean) : [];
|
|
12755
12732
|
if (unsubClaims.length > 0 && !Object.isFrozen(messages)) {
|
|
12756
12733
|
const verifyText = "\n[vibeOS verify]\nUnsubstantiated claims from previous turn:\n" + unsubClaims.slice(0, 5).map((t) => ' - "' + (typeof t === "string" ? t.substring(0, 80) : "") + '"').join("\n") + "\nPlease verify each claim and correct if inaccurate.";
|
|
12757
12734
|
try {
|
|
@@ -12821,7 +12798,7 @@ function orchestratorDirective(cv, sel) {
|
|
|
12821
12798
|
const tierBias = cv?.tier_bias || "auto";
|
|
12822
12799
|
let brainModel = "(brain)";
|
|
12823
12800
|
try {
|
|
12824
|
-
brainModel = safeJsonParse2(
|
|
12801
|
+
brainModel = safeJsonParse2(readFileSync15(TIERS_FILE, "utf-8")).trinity?.brain?.oc || brainModel;
|
|
12825
12802
|
} catch {
|
|
12826
12803
|
}
|
|
12827
12804
|
const cheapModel = TRINITY_CHEAP || "the cheaper model";
|
|
@@ -12869,7 +12846,7 @@ function welcomeDirective() {
|
|
|
12869
12846
|
const sel = loadSelection();
|
|
12870
12847
|
let tiers = {};
|
|
12871
12848
|
try {
|
|
12872
|
-
tiers = safeJsonParse2(
|
|
12849
|
+
tiers = safeJsonParse2(readFileSync15(TIERS_FILE, "utf-8")).trinity || {};
|
|
12873
12850
|
} catch {
|
|
12874
12851
|
}
|
|
12875
12852
|
const active = sel.active_slot || "medium";
|
|
@@ -13126,7 +13103,7 @@ var onSystemTransform = async (_input, output) => {
|
|
|
13126
13103
|
}) + "\n");
|
|
13127
13104
|
if (_turnCountInject % 10 === 0 && _calBuffer.length > 0) {
|
|
13128
13105
|
try {
|
|
13129
|
-
const calFile =
|
|
13106
|
+
const calFile = join16(getVibeOSHome9(), "calibration-data.jsonl");
|
|
13130
13107
|
mkdirSync11(getVibeOSHome9(), { recursive: true });
|
|
13131
13108
|
appendFileSync4(calFile, _calBuffer.join(""));
|
|
13132
13109
|
_calBuffer.length = 0;
|
|
@@ -13398,7 +13375,7 @@ function detectLaziness(input) {
|
|
|
13398
13375
|
}
|
|
13399
13376
|
|
|
13400
13377
|
// src/vibeOS-lib/lie-detector.js
|
|
13401
|
-
var
|
|
13378
|
+
var CLAIM_PATTERNS2 = [
|
|
13402
13379
|
/(?:I|we|the)\s+(?:pushed|released|merged|deployed|fixed|wrote|implemented|completed|committed)\b/i,
|
|
13403
13380
|
/(?:tests?|build|CI|checks?|suite|output|result)\s+(?:is\s+|are\s+)?(?:pass(?:ing|ed|es)?|green|clean|succeed|stable|positive)/i,
|
|
13404
13381
|
/(?:done|finished|complete)/i,
|
|
@@ -13418,7 +13395,7 @@ function scanClaims(text) {
|
|
|
13418
13395
|
const claims = [];
|
|
13419
13396
|
const lines = text.split("\n");
|
|
13420
13397
|
for (let i = 0; i < lines.length; i++) {
|
|
13421
|
-
for (const pat of
|
|
13398
|
+
for (const pat of CLAIM_PATTERNS2) {
|
|
13422
13399
|
if (pat.test(lines[i])) {
|
|
13423
13400
|
claims.push({ line: i + 1, text: lines[i].trim().substring(0, 120) });
|
|
13424
13401
|
break;
|
|
@@ -13463,17 +13440,17 @@ function footerDebug(...args) {
|
|
|
13463
13440
|
console.error(...args);
|
|
13464
13441
|
}
|
|
13465
13442
|
function getVibeOSHome10() {
|
|
13466
|
-
return process.env.VIBEOS_HOME ||
|
|
13443
|
+
return process.env.VIBEOS_HOME || join17(process.env.HOME || "", ".claude");
|
|
13467
13444
|
}
|
|
13468
|
-
var STATE_FILE2 =
|
|
13469
|
-
var SAVINGS_LEDGER_FILE2 =
|
|
13445
|
+
var STATE_FILE2 = join17(getVibeOSHome10(), "delegation-state.json");
|
|
13446
|
+
var SAVINGS_LEDGER_FILE2 = join17(getVibeOSHome10(), "savings-ledger.jsonl");
|
|
13470
13447
|
var _prevOutputText = "";
|
|
13471
13448
|
var _autoReportCount = 0;
|
|
13472
13449
|
var textCompletePainted = /* @__PURE__ */ new Set();
|
|
13473
13450
|
var _lastStrippedText = "";
|
|
13474
13451
|
function loadSelection2() {
|
|
13475
13452
|
try {
|
|
13476
|
-
const raw =
|
|
13453
|
+
const raw = readFileSync16(join17(getVibeOSHome10(), "model-tiers.json"), "utf-8");
|
|
13477
13454
|
return safeJsonParse2(raw)?.selection || { active_slot: "medium", enabled: true, delegation_enforce: true, flow_enabled: true, flow_enforce: true, tdd_enforce: false, tdd_strict: false };
|
|
13478
13455
|
} catch {
|
|
13479
13456
|
return { active_slot: "medium", enabled: true, delegation_enforce: true, flow_enabled: true, flow_enforce: true, tdd_enforce: false, tdd_strict: false };
|
|
@@ -13486,7 +13463,7 @@ function isGreetingLike(text) {
|
|
|
13486
13463
|
function readLifetimeSavings2() {
|
|
13487
13464
|
try {
|
|
13488
13465
|
reconcileStateFromLedger();
|
|
13489
|
-
const raw =
|
|
13466
|
+
const raw = readFileSync16(STATE_FILE2, "utf-8");
|
|
13490
13467
|
const state = safeJsonParse2(raw);
|
|
13491
13468
|
const ses = state?.sessions?.[getSessionId()] || {};
|
|
13492
13469
|
return {
|
|
@@ -13655,7 +13632,7 @@ async function _appendFooter(input, output, directory3) {
|
|
|
13655
13632
|
} catch {
|
|
13656
13633
|
}
|
|
13657
13634
|
if (!liveModel) {
|
|
13658
|
-
liveModel = readConfig(directory3) || readConfig(
|
|
13635
|
+
liveModel = readConfig(directory3) || readConfig(join17(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
|
|
13659
13636
|
}
|
|
13660
13637
|
const displayModel = resolveTrinityDisplayModel(directory3, slot, liveModel, currentModel) || brainModel || liveModel || currentModel;
|
|
13661
13638
|
const resolvedModel = displayModel || liveModel || brainModel || currentModel || "";
|
|
@@ -13724,53 +13701,8 @@ async function _appendFooter(input, output, directory3) {
|
|
|
13724
13701
|
const rawMode = (typeof loadSelection2 === "function" ? loadSelection2()?.requested_optimization_mode || loadSelection2()?.optimization_mode : null) || displayMode;
|
|
13725
13702
|
const cv = computeControlVector2({ sub_regime: currentSubRegime, latest_stress_multiplier: _footerStress, user_text: latestUserIntent || "" }, void 0, rawMode);
|
|
13726
13703
|
const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode, activeSlot);
|
|
13727
|
-
|
|
13704
|
+
const claimStatus = evaluateClaimVerification({ text, vibeHome: VIBEOS_HOME });
|
|
13728
13705
|
let _rewardTag = "";
|
|
13729
|
-
try {
|
|
13730
|
-
const claimAuditFile = join16(VIBEOS_HOME, "cascade-audit", "claim-audit.jsonl");
|
|
13731
|
-
const cascadeAuditFile = join16(VIBEOS_HOME, "cascade-audit", "cascade-audit.jsonl");
|
|
13732
|
-
if (existsSync16(claimAuditFile) && statSync8(claimAuditFile).size > 0) {
|
|
13733
|
-
const claimLines = readFileSync15(claimAuditFile, "utf-8").trim().split("\n").slice(-10);
|
|
13734
|
-
const cascadeLines = existsSync16(cascadeAuditFile) ? readFileSync15(cascadeAuditFile, "utf-8").trim().split("\n").slice(-30) : [];
|
|
13735
|
-
const cascadeRuns = cascadeLines.filter(Boolean).map(function(l) {
|
|
13736
|
-
try {
|
|
13737
|
-
return JSON.parse(l);
|
|
13738
|
-
} catch {
|
|
13739
|
-
}
|
|
13740
|
-
}).filter(Boolean);
|
|
13741
|
-
let unsub = 0;
|
|
13742
|
-
for (const cl of claimLines) {
|
|
13743
|
-
if (!cl.trim())
|
|
13744
|
-
continue;
|
|
13745
|
-
let entry;
|
|
13746
|
-
try {
|
|
13747
|
-
entry = JSON.parse(cl);
|
|
13748
|
-
} catch {
|
|
13749
|
-
continue;
|
|
13750
|
-
}
|
|
13751
|
-
if (!entry)
|
|
13752
|
-
continue;
|
|
13753
|
-
const claimTexts = (entry.claims || []).map(function(c) {
|
|
13754
|
-
return c.text;
|
|
13755
|
-
}).join(" | ");
|
|
13756
|
-
let cascadeMatch = false;
|
|
13757
|
-
for (const cr of cascadeRuns) {
|
|
13758
|
-
const cTs = cr._ts || "";
|
|
13759
|
-
if (cTs && entry.ts && Math.abs(new Date(cTs).getTime() - new Date(entry.ts).getTime()) < 12e4) {
|
|
13760
|
-
cascadeMatch = true;
|
|
13761
|
-
break;
|
|
13762
|
-
}
|
|
13763
|
-
}
|
|
13764
|
-
if (!cascadeMatch)
|
|
13765
|
-
unsub++;
|
|
13766
|
-
}
|
|
13767
|
-
if (unsub > 0)
|
|
13768
|
-
_claimTag = "\u26A0" + unsub;
|
|
13769
|
-
else
|
|
13770
|
-
_claimTag = "\u2713";
|
|
13771
|
-
}
|
|
13772
|
-
} catch {
|
|
13773
|
-
}
|
|
13774
13706
|
const vibeLine = buildFooterLine({
|
|
13775
13707
|
activeSlot,
|
|
13776
13708
|
providerLabel: execution.provider_label,
|
|
@@ -13786,7 +13718,7 @@ async function _appendFooter(input, output, directory3) {
|
|
|
13786
13718
|
subRegime: currentSubRegime,
|
|
13787
13719
|
stressGauge: _footerStress > 0.85 ? "\u2588" : _footerStress > 0.7 ? "\u2586" : _footerStress > 0.5 ? "\u2585" : _footerStress > 0.3 ? "\u2583" : _footerStress > 0.1 ? "\u2582" : "\u2581",
|
|
13788
13720
|
cascadeIcon: (cv?.cascade_depth || 1) >= 3 ? "\u25B8\u25B8\u25B8" : (cv?.cascade_depth || 1) >= 2 ? "\u25B8\u25B8" : "",
|
|
13789
|
-
claimTag:
|
|
13721
|
+
claimTag: claimStatus.claimTag || void 0,
|
|
13790
13722
|
rewardTag: _rewardTag || void 0
|
|
13791
13723
|
});
|
|
13792
13724
|
const footerText = stripped + `
|
|
@@ -13831,8 +13763,8 @@ ${vibeLine}`;
|
|
|
13831
13763
|
if (rewardResult.credits !== 0) {
|
|
13832
13764
|
_rewardTag = rewardResult.credits > 0 ? `+${rewardResult.credits} XP` : `${rewardResult.credits} XP`;
|
|
13833
13765
|
try {
|
|
13834
|
-
const statePath =
|
|
13835
|
-
const state = safeJsonParse2(
|
|
13766
|
+
const statePath = join17(VIBEOS_HOME, "delegation-state.json");
|
|
13767
|
+
const state = safeJsonParse2(readFileSync16(statePath, "utf-8"), {});
|
|
13836
13768
|
const sid2 = getCurrentSessionId();
|
|
13837
13769
|
if (!state.sessions)
|
|
13838
13770
|
state.sessions = {};
|
|
@@ -13850,7 +13782,7 @@ ${vibeLine}`;
|
|
|
13850
13782
|
}
|
|
13851
13783
|
try {
|
|
13852
13784
|
mkdirSync12(getVibeOSHome10(), { recursive: true });
|
|
13853
|
-
appendFileSync5(
|
|
13785
|
+
appendFileSync5(join17(getVibeOSHome10(), "calibration-data.jsonl"), JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), event: "outcome", sid: getSessionId(), outcome: finalOutcome }) + "\n");
|
|
13854
13786
|
} catch {
|
|
13855
13787
|
}
|
|
13856
13788
|
}
|
|
@@ -13878,7 +13810,7 @@ ${vibeLine} \u2014`);
|
|
|
13878
13810
|
// src/lib/hooks/tool-execute.js
|
|
13879
13811
|
init_state();
|
|
13880
13812
|
import { writeFileSync as writeFileSync17, appendFileSync as appendFileSync7, existsSync as existsSync18, mkdirSync as mkdirSync14 } from "node:fs";
|
|
13881
|
-
import { join as
|
|
13813
|
+
import { join as join19, dirname as dirname12, basename as basename4 } from "node:path";
|
|
13882
13814
|
import { createHash as createHash5 } from "node:crypto";
|
|
13883
13815
|
init_selection_manager();
|
|
13884
13816
|
init_api_client();
|
|
@@ -13947,8 +13879,8 @@ init_smart_cache();
|
|
|
13947
13879
|
|
|
13948
13880
|
// src/lib/tdd-enforcer.js
|
|
13949
13881
|
init_state();
|
|
13950
|
-
import { readFileSync as
|
|
13951
|
-
import { join as
|
|
13882
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync16, appendFileSync as appendFileSync6, existsSync as existsSync17, mkdirSync as mkdirSync13, statSync as statSync8, readdirSync as readdirSync4, rmSync as rmSync6, openSync as openSync3 } from "node:fs";
|
|
13883
|
+
import { join as join18, dirname as dirname11 } from "node:path";
|
|
13952
13884
|
import { createHash as createHash4 } from "node:crypto";
|
|
13953
13885
|
|
|
13954
13886
|
// src/utils/tdd-helpers.js
|
|
@@ -15077,7 +15009,7 @@ var test_skeletons_default = TEST_SKELETONS;
|
|
|
15077
15009
|
|
|
15078
15010
|
// src/lib/tdd-enforcer.js
|
|
15079
15011
|
function getVibeOSHome11() {
|
|
15080
|
-
return process.env.VIBEOS_HOME ||
|
|
15012
|
+
return process.env.VIBEOS_HOME || join18(process.env.HOME || "", ".claude");
|
|
15081
15013
|
}
|
|
15082
15014
|
var _detectedFramework = null;
|
|
15083
15015
|
var directory = void 0;
|
|
@@ -15090,9 +15022,9 @@ function _detectTestFramework() {
|
|
|
15090
15022
|
let testExt = null;
|
|
15091
15023
|
try {
|
|
15092
15024
|
const root = directory || process.cwd();
|
|
15093
|
-
const pkgPath =
|
|
15025
|
+
const pkgPath = join18(root, "package.json");
|
|
15094
15026
|
if (existsSync17(pkgPath)) {
|
|
15095
|
-
const pkg = JSON.parse(
|
|
15027
|
+
const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
|
|
15096
15028
|
const testScript = String(pkg?.scripts?.test || "");
|
|
15097
15029
|
const deps = { ...pkg?.devDependencies, ...pkg?.dependencies };
|
|
15098
15030
|
if (testScript.includes("vitest") || deps["vitest"]) {
|
|
@@ -15112,12 +15044,12 @@ function _detectTestFramework() {
|
|
|
15112
15044
|
if (!framework) {
|
|
15113
15045
|
const testDirs = ["src/tests", "tests", "test", "__tests__"];
|
|
15114
15046
|
for (const td of testDirs) {
|
|
15115
|
-
const dirPath =
|
|
15047
|
+
const dirPath = join18(root, td);
|
|
15116
15048
|
if (!existsSync17(dirPath))
|
|
15117
15049
|
continue;
|
|
15118
15050
|
const files = readdirSync4(dirPath).filter((f) => /\.test\./.test(f) || /\.spec\./.test(f));
|
|
15119
15051
|
if (files.length > 0) {
|
|
15120
|
-
const content =
|
|
15052
|
+
const content = readFileSync17(join18(dirPath, files[0]), "utf-8");
|
|
15121
15053
|
if (/from\s+['"]node:test['"]/.test(content)) {
|
|
15122
15054
|
framework = "node-test";
|
|
15123
15055
|
testExt = files[0].split(".").pop();
|
|
@@ -15143,16 +15075,16 @@ function _detectTestFramework() {
|
|
|
15143
15075
|
console.error(`[vibeOS] [tdd] detected test framework: ${framework || "default"} (ext: ${testExt || "match source"})`);
|
|
15144
15076
|
return _detectedFramework;
|
|
15145
15077
|
}
|
|
15146
|
-
var ENFORCEMENT_LOCK_DIR =
|
|
15078
|
+
var ENFORCEMENT_LOCK_DIR = join18(getVibeOSHome11(), ".enforcement-lock");
|
|
15147
15079
|
var LOCK_EXPIRE_MS = 3e4;
|
|
15148
|
-
var ENFORCEMENT_COOLDOWN_FILE2 =
|
|
15080
|
+
var ENFORCEMENT_COOLDOWN_FILE2 = join18(getVibeOSHome11(), ".enforcement-cooldown.jsonl");
|
|
15149
15081
|
var COOLDOWN_MS = 6e4;
|
|
15150
15082
|
var _enforcementCooldown = /* @__PURE__ */ new Set();
|
|
15151
15083
|
function _acquireLock(testPath) {
|
|
15152
15084
|
try {
|
|
15153
15085
|
mkdirSync13(ENFORCEMENT_LOCK_DIR, { recursive: true });
|
|
15154
15086
|
const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
15155
|
-
const lockPath =
|
|
15087
|
+
const lockPath = join18(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
|
|
15156
15088
|
try {
|
|
15157
15089
|
openSync3(lockPath, "wx");
|
|
15158
15090
|
return true;
|
|
@@ -15160,7 +15092,7 @@ function _acquireLock(testPath) {
|
|
|
15160
15092
|
if (err.code !== "EEXIST")
|
|
15161
15093
|
return false;
|
|
15162
15094
|
try {
|
|
15163
|
-
const st =
|
|
15095
|
+
const st = statSync8(lockPath);
|
|
15164
15096
|
if (Date.now() - st.mtimeMs >= LOCK_EXPIRE_MS) {
|
|
15165
15097
|
rmSync6(lockPath, { force: true });
|
|
15166
15098
|
try {
|
|
@@ -15180,7 +15112,7 @@ function _acquireLock(testPath) {
|
|
|
15180
15112
|
function _releaseLock(testPath) {
|
|
15181
15113
|
try {
|
|
15182
15114
|
const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
15183
|
-
const lockPath =
|
|
15115
|
+
const lockPath = join18(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
|
|
15184
15116
|
rmSync6(lockPath);
|
|
15185
15117
|
} catch {
|
|
15186
15118
|
}
|
|
@@ -15190,7 +15122,7 @@ function _isInCooldown(testPath) {
|
|
|
15190
15122
|
if (!existsSync17(ENFORCEMENT_COOLDOWN_FILE2))
|
|
15191
15123
|
return false;
|
|
15192
15124
|
const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
15193
|
-
const lines =
|
|
15125
|
+
const lines = readFileSync17(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
|
|
15194
15126
|
const now = Date.now();
|
|
15195
15127
|
for (const line of lines) {
|
|
15196
15128
|
try {
|
|
@@ -15211,7 +15143,7 @@ function _recordCooldown(testPath) {
|
|
|
15211
15143
|
const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
15212
15144
|
const entry = JSON.stringify({ h: hash, ts: Date.now() }) + "\n";
|
|
15213
15145
|
appendFileSync6(ENFORCEMENT_COOLDOWN_FILE2, entry);
|
|
15214
|
-
const lines =
|
|
15146
|
+
const lines = readFileSync17(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
|
|
15215
15147
|
if (lines.length > 500) {
|
|
15216
15148
|
writeFileSync16(ENFORCEMENT_COOLDOWN_FILE2, lines.slice(-200).join("\n") + "\n");
|
|
15217
15149
|
}
|
|
@@ -15282,7 +15214,7 @@ function enforceTestFile(filePath) {
|
|
|
15282
15214
|
let sourceContent = "";
|
|
15283
15215
|
try {
|
|
15284
15216
|
if (existsSync17(filePath)) {
|
|
15285
|
-
sourceContent =
|
|
15217
|
+
sourceContent = readFileSync17(filePath, "utf-8");
|
|
15286
15218
|
}
|
|
15287
15219
|
} catch {
|
|
15288
15220
|
}
|
|
@@ -15386,7 +15318,7 @@ var BYTES_PER_TOKEN2 = 4;
|
|
|
15386
15318
|
var DEBUG_INTERNALS2 = process.env.VIBEOS_DEBUG_INTERNALS === "1";
|
|
15387
15319
|
var IS_CLI_RUNTIME2 = Boolean(process.stdout?.isTTY || process.stderr?.isTTY || process.stdin?.isTTY);
|
|
15388
15320
|
function getVibeOSHome12() {
|
|
15389
|
-
return process.env.VIBEOS_HOME ||
|
|
15321
|
+
return process.env.VIBEOS_HOME || join19(process.env.HOME || "", ".claude");
|
|
15390
15322
|
}
|
|
15391
15323
|
var projectDirectory = "";
|
|
15392
15324
|
var pendingUiNote = null;
|
|
@@ -15502,7 +15434,7 @@ function _resolveToolPath(pathValue) {
|
|
|
15502
15434
|
return raw;
|
|
15503
15435
|
if (raw.startsWith("/"))
|
|
15504
15436
|
return raw;
|
|
15505
|
-
return projectDirectory ?
|
|
15437
|
+
return projectDirectory ? join19(projectDirectory, raw).replace(/\\/g, "/") : raw;
|
|
15506
15438
|
}
|
|
15507
15439
|
function _isProtectedToolPath(pathValue) {
|
|
15508
15440
|
const raw = _normalizeToolPath(pathValue);
|
|
@@ -15641,14 +15573,14 @@ ${argsJson}
|
|
|
15641
15573
|
`).digest("hex").slice(0, 16);
|
|
15642
15574
|
const sessionDir = getSessionScratchpadDir();
|
|
15643
15575
|
const globalDir = SCRATCHPAD_GLOBAL_DIR;
|
|
15644
|
-
const ptrPath =
|
|
15576
|
+
const ptrPath = join19(sessionDir, `${curHash}.ptr`);
|
|
15645
15577
|
if (!existsSync18(ptrPath)) {
|
|
15646
15578
|
for (const similar of prediction.similarEntries) {
|
|
15647
15579
|
const targetHash = similar.entry.hash;
|
|
15648
15580
|
if (targetHash.length < 16)
|
|
15649
15581
|
continue;
|
|
15650
|
-
const cachedFile =
|
|
15651
|
-
const globalFile =
|
|
15582
|
+
const cachedFile = join19(sessionDir, `${targetHash}.txt`);
|
|
15583
|
+
const globalFile = join19(globalDir, `${targetHash}.txt`);
|
|
15652
15584
|
if (existsSync18(cachedFile) || existsSync18(globalFile)) {
|
|
15653
15585
|
ensureSessionScratchpadDirs();
|
|
15654
15586
|
writeFileSync17(ptrPath, JSON.stringify({
|
|
@@ -16025,7 +15957,7 @@ var onToolExecuteAfter = async (input, output) => {
|
|
|
16025
15957
|
} catch {
|
|
16026
15958
|
}
|
|
16027
15959
|
if (!liveModel) {
|
|
16028
|
-
liveModel = readConfig(projectDirectory) || readConfig(
|
|
15960
|
+
liveModel = readConfig(projectDirectory) || readConfig(join19(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
|
|
16029
15961
|
}
|
|
16030
15962
|
const displayModel = resolveTrinityDisplayModel(projectDirectory, selNow.active_slot || "", liveModel, currentModel) || liveModel || currentModel;
|
|
16031
15963
|
const resolvedModel = displayModel || liveModel || currentModel || "";
|
|
@@ -16101,7 +16033,7 @@ var onToolExecuteAfter = async (input, output) => {
|
|
|
16101
16033
|
const trinityAction = trinityArgs?.action || trinityArgs?.todo || "";
|
|
16102
16034
|
if (trinityAction === "todo") {
|
|
16103
16035
|
try {
|
|
16104
|
-
const flowTodoFilePath =
|
|
16036
|
+
const flowTodoFilePath = join19(getVibeOSHome12(), ".flow-todo-queue.jsonl");
|
|
16105
16037
|
let todoLines = [];
|
|
16106
16038
|
if (__require("fs").existsSync(flowTodoFilePath)) {
|
|
16107
16039
|
const raw2 = __require("fs").readFileSync(flowTodoFilePath, "utf-8").trim();
|
|
@@ -16398,7 +16330,7 @@ ${pendingUiNote}`;
|
|
|
16398
16330
|
|
|
16399
16331
|
// src/lib/hooks/session-compact.js
|
|
16400
16332
|
init_state();
|
|
16401
|
-
import { readFileSync as
|
|
16333
|
+
import { readFileSync as readFileSync18, existsSync as existsSync19 } from "node:fs";
|
|
16402
16334
|
var onSessionCompacting = async (_input, output) => {
|
|
16403
16335
|
if (!loadSelection().enabled)
|
|
16404
16336
|
return;
|
|
@@ -16409,7 +16341,7 @@ var onSessionCompacting = async (_input, output) => {
|
|
|
16409
16341
|
let recent = "";
|
|
16410
16342
|
if (existsSync19(indexPath)) {
|
|
16411
16343
|
try {
|
|
16412
|
-
const lines =
|
|
16344
|
+
const lines = readFileSync18(indexPath, "utf-8").trim().split("\n").slice(-30);
|
|
16413
16345
|
recent = lines.map((l) => {
|
|
16414
16346
|
try {
|
|
16415
16347
|
return JSON.parse(l);
|
|
@@ -16495,13 +16427,13 @@ init_state();
|
|
|
16495
16427
|
init_state();
|
|
16496
16428
|
init_api_client();
|
|
16497
16429
|
function getVibeOSHome13() {
|
|
16498
|
-
return process.env.VIBEOS_HOME ||
|
|
16430
|
+
return process.env.VIBEOS_HOME || join20(process.env.HOME || "", ".claude");
|
|
16499
16431
|
}
|
|
16500
16432
|
function getTiersFile() {
|
|
16501
|
-
return
|
|
16433
|
+
return join20(getVibeOSHome13(), "model-tiers.json");
|
|
16502
16434
|
}
|
|
16503
16435
|
function getReportsDir2() {
|
|
16504
|
-
return
|
|
16436
|
+
return join20(getVibeOSHome13(), "reports");
|
|
16505
16437
|
}
|
|
16506
16438
|
function ensureDeferredBootstrap() {
|
|
16507
16439
|
if (_deferredBootstrapDone || _modelLocked)
|
|
@@ -16512,7 +16444,7 @@ function ensureDeferredBootstrap() {
|
|
|
16512
16444
|
} catch {
|
|
16513
16445
|
}
|
|
16514
16446
|
}
|
|
16515
|
-
var
|
|
16447
|
+
var CLAIM_PATTERNS3 = [
|
|
16516
16448
|
/(?:I|we|the)\s+(?:pushed|released|merged|deployed|fixed|wrote|implemented|completed|committed)\b/i,
|
|
16517
16449
|
/(?:tests?|build|CI|checks?|suite|output|result)\s+(?:is\s+|are\s+)?(?:pass(?:ing|ed|es)?|green|clean|succeed|stable|positive)/i,
|
|
16518
16450
|
/v\d+\.\d+\.\d+/,
|
|
@@ -16524,19 +16456,30 @@ var CLAIM_PATTERNS2 = [
|
|
|
16524
16456
|
/(?:\d+%|score|scored|passing|passed)/i
|
|
16525
16457
|
];
|
|
16526
16458
|
function scanClaimsInOutput(output) {
|
|
16527
|
-
|
|
16459
|
+
let text = "";
|
|
16460
|
+
if (typeof output === "string") {
|
|
16461
|
+
text = output;
|
|
16462
|
+
} else if (output && typeof output === "object") {
|
|
16463
|
+
const payload = typeof output.message === "object" && output.message ? output.message : output;
|
|
16464
|
+
if (typeof payload.text === "string") text = payload.text;
|
|
16465
|
+
else if (typeof payload.result === "string") text = payload.result;
|
|
16466
|
+
else if (typeof payload.content === "string") text = payload.content;
|
|
16467
|
+
else if (Array.isArray(payload.content)) text = payload.content.filter((p) => p?.type === "text").map((p) => p.text).filter(Boolean).join("\n");
|
|
16468
|
+
else if (Array.isArray(payload.parts)) text = payload.parts.filter((p) => p?.type === "text").map((p) => p.text).filter(Boolean).join("\n");
|
|
16469
|
+
}
|
|
16470
|
+
if (!text) return;
|
|
16528
16471
|
try {
|
|
16529
16472
|
const claims = [];
|
|
16530
|
-
const lines = String(
|
|
16473
|
+
const lines = String(text).split(String.fromCharCode(10));
|
|
16531
16474
|
for (let i = 0; i < lines.length; i++) {
|
|
16532
|
-
for (const pat of
|
|
16475
|
+
for (const pat of CLAIM_PATTERNS3) {
|
|
16533
16476
|
if (pat.test(lines[i])) claims.push({ line: i + 1, text: lines[i].trim().substring(0, 120), pattern: pat.source });
|
|
16534
16477
|
}
|
|
16535
16478
|
}
|
|
16536
16479
|
if (claims.length === 0) return;
|
|
16537
|
-
const auditDir =
|
|
16480
|
+
const auditDir = join20(getVibeOSHome13(), "cascade-audit");
|
|
16538
16481
|
mkdirSync15(auditDir, { recursive: true });
|
|
16539
|
-
const auditFile =
|
|
16482
|
+
const auditFile = join20(auditDir, "claim-audit.jsonl");
|
|
16540
16483
|
const entry = JSON.stringify({
|
|
16541
16484
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16542
16485
|
claims: claims.slice(0, 10),
|
|
@@ -16560,18 +16503,18 @@ var _deferredBootstrapDone = false;
|
|
|
16560
16503
|
var _skillsEnsured = /* @__PURE__ */ new Set();
|
|
16561
16504
|
var _runDeferredStartupBootstrap = null;
|
|
16562
16505
|
function _readOpenCodeConfigObject(dir) {
|
|
16563
|
-
const jsonPath =
|
|
16564
|
-
const jsoncPath =
|
|
16506
|
+
const jsonPath = join20(dir, "opencode.json");
|
|
16507
|
+
const jsoncPath = join20(dir, "opencode.jsonc");
|
|
16565
16508
|
if (existsSync20(jsonPath))
|
|
16566
|
-
return safeJsonParse2(
|
|
16509
|
+
return safeJsonParse2(readFileSync19(jsonPath, "utf-8"));
|
|
16567
16510
|
if (existsSync20(jsoncPath))
|
|
16568
|
-
return _parseJsonc(
|
|
16511
|
+
return _parseJsonc(readFileSync19(jsoncPath, "utf-8"));
|
|
16569
16512
|
return {};
|
|
16570
16513
|
}
|
|
16571
16514
|
function _loadOpenCodeProviders(directory3) {
|
|
16572
16515
|
try {
|
|
16573
16516
|
const merged = {};
|
|
16574
|
-
const dirs = [directory3 ?
|
|
16517
|
+
const dirs = [directory3 ? join20(directory3, ".") : null, getOpenCodeHome()].filter(Boolean);
|
|
16575
16518
|
for (const dir of dirs) {
|
|
16576
16519
|
const cfg = _readOpenCodeConfigObject(String(dir));
|
|
16577
16520
|
const providers = cfg?.provider || {};
|
|
@@ -16613,13 +16556,13 @@ async function _resolveBootstrapModel(client2, directory3) {
|
|
|
16613
16556
|
return { model: "", source: "" };
|
|
16614
16557
|
}
|
|
16615
16558
|
function _loadActiveJobForProject(directory3, fp2 = "") {
|
|
16616
|
-
const candidates = [getVibeOSHome13(), directory3 ?
|
|
16559
|
+
const candidates = [getVibeOSHome13(), directory3 ? join20(directory3, "..") : ""].filter(Boolean);
|
|
16617
16560
|
for (const base of candidates) {
|
|
16618
16561
|
try {
|
|
16619
|
-
const activeJobsPath =
|
|
16562
|
+
const activeJobsPath = join20(String(base), "active-jobs.json");
|
|
16620
16563
|
if (!existsSync20(activeJobsPath))
|
|
16621
16564
|
continue;
|
|
16622
|
-
const jobs = safeJsonParse2(
|
|
16565
|
+
const jobs = safeJsonParse2(readFileSync19(activeJobsPath, "utf-8")) || {};
|
|
16623
16566
|
const job = fp2 ? jobs?.[fp2] : null;
|
|
16624
16567
|
if (job && typeof job === "object")
|
|
16625
16568
|
return job;
|
|
@@ -16641,12 +16584,12 @@ async function _seedOrRepairModelTiers(directory3) {
|
|
|
16641
16584
|
let existing = null;
|
|
16642
16585
|
if (existsSync20(TIERS_FILE3)) {
|
|
16643
16586
|
try {
|
|
16644
|
-
const st =
|
|
16587
|
+
const st = statSync9(TIERS_FILE3);
|
|
16645
16588
|
if (st.size > 10485760) {
|
|
16646
16589
|
_handleStateCorruption(TIERS_FILE3);
|
|
16647
16590
|
return false;
|
|
16648
16591
|
}
|
|
16649
|
-
existing = safeJsonParse2(
|
|
16592
|
+
existing = safeJsonParse2(readFileSync19(TIERS_FILE3, "utf-8")) || {};
|
|
16650
16593
|
} catch {
|
|
16651
16594
|
existing = null;
|
|
16652
16595
|
}
|
|
@@ -16737,7 +16680,7 @@ function _modelTier2(id2) {
|
|
|
16737
16680
|
}
|
|
16738
16681
|
function readPackageVersion() {
|
|
16739
16682
|
try {
|
|
16740
|
-
const pkg = safeJsonParse2(
|
|
16683
|
+
const pkg = safeJsonParse2(readFileSync19(join20(process.cwd(), "package.json"), "utf-8"));
|
|
16741
16684
|
return String(pkg?.version || "");
|
|
16742
16685
|
} catch {
|
|
16743
16686
|
return "";
|
|
@@ -16753,7 +16696,7 @@ function loadMcpPort() {
|
|
|
16753
16696
|
}
|
|
16754
16697
|
try {
|
|
16755
16698
|
if (existsSync20(getTiersFile())) {
|
|
16756
|
-
const tiers = safeJsonParse2(
|
|
16699
|
+
const tiers = safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
16757
16700
|
const cfg = tiers?.selection?.mcp_port;
|
|
16758
16701
|
if (cfg === false || cfg === "disabled" || cfg === 0)
|
|
16759
16702
|
return 0;
|
|
@@ -16769,7 +16712,7 @@ function persistMcpPort(port) {
|
|
|
16769
16712
|
try {
|
|
16770
16713
|
if (!existsSync20(getTiersFile()))
|
|
16771
16714
|
return;
|
|
16772
|
-
const tiers = safeJsonParse2(
|
|
16715
|
+
const tiers = safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
16773
16716
|
tiers.selection ??= {};
|
|
16774
16717
|
if (Number(tiers.selection.mcp_port) === Number(port) && !("mcp_port" in tiers))
|
|
16775
16718
|
return;
|
|
@@ -16833,7 +16776,7 @@ async function ensureMcpServerRunning() {
|
|
|
16833
16776
|
selection: loadSelection(),
|
|
16834
16777
|
tiersData: (() => {
|
|
16835
16778
|
try {
|
|
16836
|
-
return safeJsonParse2(
|
|
16779
|
+
return safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
16837
16780
|
} catch {
|
|
16838
16781
|
return {};
|
|
16839
16782
|
}
|
|
@@ -16849,7 +16792,7 @@ async function ensureMcpServerRunning() {
|
|
|
16849
16792
|
optimizationMode: loadSelection()?.optimization_mode || null,
|
|
16850
16793
|
tiers: (() => {
|
|
16851
16794
|
try {
|
|
16852
|
-
return safeJsonParse2(
|
|
16795
|
+
return safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"))?.trinity;
|
|
16853
16796
|
} catch {
|
|
16854
16797
|
return null;
|
|
16855
16798
|
}
|
|
@@ -17041,7 +16984,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17041
16984
|
if (currentModel) {
|
|
17042
16985
|
setCurrentTier(classify(currentModel));
|
|
17043
16986
|
try {
|
|
17044
|
-
const _tiersData2 = safeJsonParse2(
|
|
16987
|
+
const _tiersData2 = safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
17045
16988
|
const _slotOrder = getTrinitySlotOrder(_tiersData2);
|
|
17046
16989
|
const _primarySlot = _slotOrder[0] || "brain";
|
|
17047
16990
|
const _activeSlot = _tiersData2?.selection?.active_slot || _primarySlot;
|
|
@@ -17067,7 +17010,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17067
17010
|
const lockedSlot = ["brain", "medium", "cheap"].includes(String(startupSelection.active_slot || "").trim()) ? String(startupSelection.active_slot) : "brain";
|
|
17068
17011
|
let lockedModel = currentModel || null;
|
|
17069
17012
|
try {
|
|
17070
|
-
const tiers = safeJsonParse2(
|
|
17013
|
+
const tiers = safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
17071
17014
|
lockedModel = tiers?.trinity?.[lockedSlot]?.oc || lockedModel || null;
|
|
17072
17015
|
} catch {
|
|
17073
17016
|
}
|
|
@@ -17100,14 +17043,14 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17100
17043
|
activeJob2 = _loadActiveJobForProject(directory3, fp);
|
|
17101
17044
|
const systemBriefedProjects = /* @__PURE__ */ new Set();
|
|
17102
17045
|
const hookVibeHome = getVibeOSHome13();
|
|
17103
|
-
const hookStateFile =
|
|
17104
|
-
const hookProjectStateFile =
|
|
17105
|
-
const hookReportsDir =
|
|
17106
|
-
const hookReportsIndex =
|
|
17107
|
-
const hookTiersFile =
|
|
17046
|
+
const hookStateFile = join20(hookVibeHome, "delegation-state.json");
|
|
17047
|
+
const hookProjectStateFile = join20(hookVibeHome, "project-states.json");
|
|
17048
|
+
const hookReportsDir = join20(hookVibeHome, "reports");
|
|
17049
|
+
const hookReportsIndex = join20(hookReportsDir, "index.json");
|
|
17050
|
+
const hookTiersFile = join20(hookVibeHome, "model-tiers.json");
|
|
17108
17051
|
const loadProjectStateStable = () => {
|
|
17109
17052
|
try {
|
|
17110
|
-
const state = safeJsonParse2(
|
|
17053
|
+
const state = safeJsonParse2(readFileSync19(hookProjectStateFile, "utf-8"));
|
|
17111
17054
|
if (state && typeof state === "object") {
|
|
17112
17055
|
state.project_hashes ??= {};
|
|
17113
17056
|
return state;
|
|
@@ -17127,7 +17070,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17127
17070
|
};
|
|
17128
17071
|
const reportsIndexStable = () => {
|
|
17129
17072
|
try {
|
|
17130
|
-
const idx = safeJsonParse2(
|
|
17073
|
+
const idx = safeJsonParse2(readFileSync19(hookReportsIndex, "utf-8"));
|
|
17131
17074
|
if (!idx || !Array.isArray(idx.reports))
|
|
17132
17075
|
return { reports: [] };
|
|
17133
17076
|
return idx;
|
|
@@ -17146,9 +17089,9 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17146
17089
|
try {
|
|
17147
17090
|
if (!existsSync20(path))
|
|
17148
17091
|
return null;
|
|
17149
|
-
const bkDir =
|
|
17092
|
+
const bkDir = join20(hookVibeHome, ".backups");
|
|
17150
17093
|
mkdirSync15(bkDir, { recursive: true });
|
|
17151
|
-
const bk =
|
|
17094
|
+
const bk = join20(bkDir, `${basename5(path)}.${label}.${Date.now()}.bak`);
|
|
17152
17095
|
copyFileSync2(path, bk);
|
|
17153
17096
|
return bk;
|
|
17154
17097
|
} catch {
|
|
@@ -17159,7 +17102,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17159
17102
|
};
|
|
17160
17103
|
const _tiersData = (() => {
|
|
17161
17104
|
try {
|
|
17162
|
-
return safeJsonParse2(
|
|
17105
|
+
return safeJsonParse2(readFileSync19(getTiersFile(), "utf-8"));
|
|
17163
17106
|
} catch {
|
|
17164
17107
|
return {};
|
|
17165
17108
|
}
|
|
@@ -17182,7 +17125,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17182
17125
|
},
|
|
17183
17126
|
directory: directory3,
|
|
17184
17127
|
safeJsonParse: safeJsonParse2,
|
|
17185
|
-
readFileSync:
|
|
17128
|
+
readFileSync: readFileSync19,
|
|
17186
17129
|
writeFileSync: writeFileSync18,
|
|
17187
17130
|
existsSync: existsSync20,
|
|
17188
17131
|
renameSync: renameSync6,
|
|
@@ -17353,15 +17296,15 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17353
17296
|
setCurrentProjectName(directory3 ? directory3.split("/").pop() : "unknown");
|
|
17354
17297
|
}
|
|
17355
17298
|
ensureDeferredBootstrap();
|
|
17356
|
-
await _appendFooter(_input, output, directory3);
|
|
17357
17299
|
scanClaimsInOutput(output);
|
|
17300
|
+
await _appendFooter(_input, output, directory3);
|
|
17358
17301
|
try {
|
|
17359
|
-
const auditDir =
|
|
17360
|
-
const claimFile =
|
|
17361
|
-
const cascadeFile =
|
|
17362
|
-
if (existsSync20(claimFile) &&
|
|
17363
|
-
const claimLines =
|
|
17364
|
-
const cascadeLines = existsSync20(cascadeFile) ?
|
|
17302
|
+
const auditDir = join20(getVibeOSHome13(), "cascade-audit");
|
|
17303
|
+
const claimFile = join20(auditDir, "claim-audit.jsonl");
|
|
17304
|
+
const cascadeFile = join20(auditDir, "cascade-audit.jsonl");
|
|
17305
|
+
if (existsSync20(claimFile) && statSync9(claimFile).size > 0) {
|
|
17306
|
+
const claimLines = readFileSync19(claimFile, "utf-8").trim().split("\n").slice(-10);
|
|
17307
|
+
const cascadeLines = existsSync20(cascadeFile) ? readFileSync19(cascadeFile, "utf-8").trim().split("\n").slice(-30) : [];
|
|
17365
17308
|
const cascadeRuns = cascadeLines.filter(Boolean).map((l) => {
|
|
17366
17309
|
try {
|
|
17367
17310
|
return JSON.parse(l);
|
|
@@ -17381,7 +17324,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17381
17324
|
const claimTexts = (entry.claims || []).map(function(c) {
|
|
17382
17325
|
return c.text;
|
|
17383
17326
|
}).join(" | ");
|
|
17384
|
-
if (!
|
|
17327
|
+
if (!CLAIM_PATTERNS3.some(function(p) {
|
|
17385
17328
|
return p.test(claimTexts);
|
|
17386
17329
|
})) continue;
|
|
17387
17330
|
let cascadeMatch = false;
|
|
@@ -17408,15 +17351,15 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17408
17351
|
setCurrentProjectName(directory3 ? directory3.split("/").pop() : "unknown");
|
|
17409
17352
|
}
|
|
17410
17353
|
ensureDeferredBootstrap();
|
|
17411
|
-
await _appendFooter(_input, output, directory3);
|
|
17412
17354
|
scanClaimsInOutput(output);
|
|
17355
|
+
await _appendFooter(_input, output, directory3);
|
|
17413
17356
|
try {
|
|
17414
|
-
const auditDir =
|
|
17415
|
-
const claimFile =
|
|
17416
|
-
const cascadeFile =
|
|
17417
|
-
if (existsSync20(claimFile) &&
|
|
17418
|
-
const claimLines =
|
|
17419
|
-
const cascadeLines = existsSync20(cascadeFile) ?
|
|
17357
|
+
const auditDir = join20(getVibeOSHome13(), "cascade-audit");
|
|
17358
|
+
const claimFile = join20(auditDir, "claim-audit.jsonl");
|
|
17359
|
+
const cascadeFile = join20(auditDir, "cascade-audit.jsonl");
|
|
17360
|
+
if (existsSync20(claimFile) && statSync9(claimFile).size > 0) {
|
|
17361
|
+
const claimLines = readFileSync19(claimFile, "utf-8").trim().split("\n").slice(-10);
|
|
17362
|
+
const cascadeLines = existsSync20(cascadeFile) ? readFileSync19(cascadeFile, "utf-8").trim().split("\n").slice(-30) : [];
|
|
17420
17363
|
const cascadeRuns = cascadeLines.filter(Boolean).map((l) => {
|
|
17421
17364
|
try {
|
|
17422
17365
|
return JSON.parse(l);
|
|
@@ -17436,7 +17379,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
17436
17379
|
const claimTexts = (entry.claims || []).map(function(c) {
|
|
17437
17380
|
return c.text;
|
|
17438
17381
|
}).join(" | ");
|
|
17439
|
-
if (!
|
|
17382
|
+
if (!CLAIM_PATTERNS3.some(function(p) {
|
|
17440
17383
|
return p.test(claimTexts);
|
|
17441
17384
|
})) continue;
|
|
17442
17385
|
let cascadeMatch = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.49",
|
|
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",
|