vibeostheog 0.15.7 → 0.15.8
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 +4 -0
- package/package.json +1 -1
- package/src/index.js +140 -122
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.8",
|
|
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/index.js
CHANGED
|
@@ -344,8 +344,8 @@ var init_flow_enforcer = __esm({
|
|
|
344
344
|
|
|
345
345
|
// src/index.ts
|
|
346
346
|
init_flow_enforcer();
|
|
347
|
-
import { readFileSync as
|
|
348
|
-
import { join as
|
|
347
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync12, existsSync as existsSync15, mkdirSync as mkdirSync10, copyFileSync as copyFileSync6, renameSync as renameSync6 } from "node:fs";
|
|
348
|
+
import { join as join17, dirname as dirname8, basename as basename9 } from "node:path";
|
|
349
349
|
|
|
350
350
|
// src/vibeOS-lib/session-metrics.js
|
|
351
351
|
function formatDuration(totalSeconds) {
|
|
@@ -3230,9 +3230,9 @@ function applySlot2(slot) {
|
|
|
3230
3230
|
}
|
|
3231
3231
|
|
|
3232
3232
|
// src/lib/turn-classify.js
|
|
3233
|
-
import { readFileSync as
|
|
3234
|
-
import { join as
|
|
3235
|
-
import { homedir as
|
|
3233
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, appendFileSync as appendFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync5, statSync as statSync6, copyFileSync as copyFileSync4, renameSync as renameSync5, openSync as openSync3, closeSync as closeSync3, rmSync as rmSync3 } from "node:fs";
|
|
3234
|
+
import { join as join7, dirname as dirname5, basename as basename5 } from "node:path";
|
|
3235
|
+
import { homedir as homedir6, tmpdir as tmpdir4 } from "node:os";
|
|
3236
3236
|
import { createHash as createHash3 } from "node:crypto";
|
|
3237
3237
|
|
|
3238
3238
|
// ../vibeOScore/client.js
|
|
@@ -3491,8 +3491,26 @@ var VibeOSNetworkError = class extends Error {
|
|
|
3491
3491
|
};
|
|
3492
3492
|
|
|
3493
3493
|
// src/lib/api-client.js
|
|
3494
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
3495
|
+
import { join as join6 } from "node:path";
|
|
3496
|
+
import { homedir as homedir5 } from "node:os";
|
|
3494
3497
|
var VIBEOS_API_URL = process.env.VIBEOS_API_URL || "https://api.vibetheog.com";
|
|
3495
|
-
var
|
|
3498
|
+
var _envToken2 = "";
|
|
3499
|
+
try {
|
|
3500
|
+
const env = readFileSync5(join6(process.cwd(), ".env.production"), "utf8");
|
|
3501
|
+
const m = env.match(/^VIBEOS_API_TOKEN=(.+)$/m);
|
|
3502
|
+
if (m) _envToken2 = m[1].trim();
|
|
3503
|
+
} catch {
|
|
3504
|
+
}
|
|
3505
|
+
if (!_envToken2) {
|
|
3506
|
+
try {
|
|
3507
|
+
const env = readFileSync5(join6(homedir5(), ".env.production"), "utf8");
|
|
3508
|
+
const m = env.match(/^VIBEOS_API_TOKEN=(.+)$/m);
|
|
3509
|
+
if (m) _envToken2 = m[1].trim();
|
|
3510
|
+
} catch {
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
var VIBEOS_API_TOKEN = process.env.VIBEOS_API_TOKEN || _envToken2 || "";
|
|
3496
3514
|
var VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && !!VIBEOS_API_TOKEN;
|
|
3497
3515
|
var _apiClient = null;
|
|
3498
3516
|
var _apiFallbackMode = false;
|
|
@@ -3744,16 +3762,16 @@ var _BlackboxStub = class __BlackboxStub {
|
|
|
3744
3762
|
};
|
|
3745
3763
|
var USER_HOME4 = (() => {
|
|
3746
3764
|
try {
|
|
3747
|
-
return
|
|
3765
|
+
return homedir6();
|
|
3748
3766
|
} catch {
|
|
3749
3767
|
return tmpdir4();
|
|
3750
3768
|
}
|
|
3751
3769
|
})();
|
|
3752
|
-
var FILE_LOCK_DIR3 =
|
|
3753
|
-
var BLACKBOX_STATE_FILE2 =
|
|
3754
|
-
var GLOBAL_LEARNING_FILE2 =
|
|
3755
|
-
var STATE_FILE3 =
|
|
3756
|
-
var PROJECT_STATE_FILE2 =
|
|
3770
|
+
var FILE_LOCK_DIR3 = join7(USER_HOME4, ".claude/.vibeOS-locks");
|
|
3771
|
+
var BLACKBOX_STATE_FILE2 = join7(USER_HOME4, ".claude/blackbox-state.json");
|
|
3772
|
+
var GLOBAL_LEARNING_FILE2 = join7(USER_HOME4, ".claude/global-learning.json");
|
|
3773
|
+
var STATE_FILE3 = join7(USER_HOME4, ".claude/delegation-state.json");
|
|
3774
|
+
var PROJECT_STATE_FILE2 = join7(USER_HOME4, ".claude/project-states.json");
|
|
3757
3775
|
var DFLT_GL2 = { exploratory_words: {}, task_first_words: {}, updatedAt: null };
|
|
3758
3776
|
var _blackboxTracker = null;
|
|
3759
3777
|
var _OC_SID2 = "opencode-" + (process.pid || "x") + "-" + Date.now();
|
|
@@ -3768,14 +3786,14 @@ var WARN_MAX_PER_SESSION = 3;
|
|
|
3768
3786
|
var WARN_COALESCE_THRESHOLD = 10;
|
|
3769
3787
|
var warnCoalesceCounters = /* @__PURE__ */ new Map();
|
|
3770
3788
|
function _handleStateCorruption4(path) {
|
|
3771
|
-
const backupDir =
|
|
3789
|
+
const backupDir = join7(USER_HOME4, ".claude", ".backups");
|
|
3772
3790
|
mkdirSync5(backupDir, { recursive: true });
|
|
3773
|
-
const backupPath =
|
|
3791
|
+
const backupPath = join7(backupDir, basename5(path) + ".corrupted." + Date.now());
|
|
3774
3792
|
try {
|
|
3775
3793
|
copyFileSync4(path, backupPath);
|
|
3776
3794
|
} catch {
|
|
3777
3795
|
}
|
|
3778
|
-
const logPath =
|
|
3796
|
+
const logPath = join7(USER_HOME4, ".claude", ".state-corruption-log.jsonl");
|
|
3779
3797
|
try {
|
|
3780
3798
|
appendFileSync5(logPath, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), path, backup: backupPath }) + "\n");
|
|
3781
3799
|
} catch {
|
|
@@ -3783,7 +3801,7 @@ function _handleStateCorruption4(path) {
|
|
|
3783
3801
|
}
|
|
3784
3802
|
function _lockPathFor3(filePath) {
|
|
3785
3803
|
const hash = createHash3("sha1").update(String(filePath || "")).digest("hex");
|
|
3786
|
-
return
|
|
3804
|
+
return join7(FILE_LOCK_DIR3, `${hash}.lock`);
|
|
3787
3805
|
}
|
|
3788
3806
|
function withFileLock3(filePath, fn, opts = {}) {
|
|
3789
3807
|
const staleMs = Number(opts.staleMs || 3e4);
|
|
@@ -3838,7 +3856,7 @@ function readJsonOrEmpty2(filePath) {
|
|
|
3838
3856
|
_handleStateCorruption4(filePath);
|
|
3839
3857
|
return {};
|
|
3840
3858
|
}
|
|
3841
|
-
return safeJsonParse3(
|
|
3859
|
+
return safeJsonParse3(readFileSync6(filePath, "utf-8"));
|
|
3842
3860
|
} catch {
|
|
3843
3861
|
_handleStateCorruption4(filePath);
|
|
3844
3862
|
return {};
|
|
@@ -3846,10 +3864,10 @@ function readJsonOrEmpty2(filePath) {
|
|
|
3846
3864
|
}
|
|
3847
3865
|
function loadTrinityModels() {
|
|
3848
3866
|
try {
|
|
3849
|
-
const p =
|
|
3867
|
+
const p = join7(USER_HOME4, ".claude/model-tiers.json");
|
|
3850
3868
|
if (!existsSync6(p))
|
|
3851
3869
|
return { brain: "", cheap: "", medium: "" };
|
|
3852
|
-
const j = safeJsonParse3(
|
|
3870
|
+
const j = safeJsonParse3(readFileSync6(p, "utf-8"));
|
|
3853
3871
|
return {
|
|
3854
3872
|
brain: j?.trinity?.brain?.oc || j?.trinity?.brain || "",
|
|
3855
3873
|
cheap: j?.trinity?.cheap?.oc || j?.trinity?.cheap || "",
|
|
@@ -3871,7 +3889,7 @@ function loadBlackboxState() {
|
|
|
3871
3889
|
_handleStateCorruption4(BLACKBOX_STATE_FILE2);
|
|
3872
3890
|
return { enabled: false, sessions: {} };
|
|
3873
3891
|
}
|
|
3874
|
-
return safeJsonParse3(
|
|
3892
|
+
return safeJsonParse3(readFileSync6(BLACKBOX_STATE_FILE2, "utf-8")) || { enabled: false, sessions: {} };
|
|
3875
3893
|
} catch {
|
|
3876
3894
|
_handleStateCorruption4(BLACKBOX_STATE_FILE2);
|
|
3877
3895
|
return { enabled: false, sessions: {} };
|
|
@@ -4024,7 +4042,7 @@ function loadGlobalLearning2() {
|
|
|
4024
4042
|
_handleStateCorruption4(GLOBAL_LEARNING_FILE2);
|
|
4025
4043
|
return DFLT_GL2;
|
|
4026
4044
|
}
|
|
4027
|
-
const j = safeJsonParse3(
|
|
4045
|
+
const j = safeJsonParse3(readFileSync6(GLOBAL_LEARNING_FILE2, "utf-8"));
|
|
4028
4046
|
if (!j || typeof j !== "object")
|
|
4029
4047
|
return DFLT_GL2;
|
|
4030
4048
|
j.exploratory_words ??= {};
|
|
@@ -4090,9 +4108,9 @@ function saveProjectState2(state) {
|
|
|
4090
4108
|
function detectTechStack2(dir) {
|
|
4091
4109
|
const stacks = [];
|
|
4092
4110
|
try {
|
|
4093
|
-
const pkg = safeJsonParse3(
|
|
4111
|
+
const pkg = safeJsonParse3(readFileSync6(join7(dir, "package.json"), "utf-8"));
|
|
4094
4112
|
if (pkg) {
|
|
4095
|
-
if (pkg.devDependencies?.typescript || pkg.dependencies?.typescript || existsSync6(
|
|
4113
|
+
if (pkg.devDependencies?.typescript || pkg.dependencies?.typescript || existsSync6(join7(dir, "tsconfig.json")))
|
|
4096
4114
|
stacks.push("typescript");
|
|
4097
4115
|
if (pkg.dependencies?.react || pkg.devDependencies?.react)
|
|
4098
4116
|
stacks.push("react");
|
|
@@ -4101,21 +4119,21 @@ function detectTechStack2(dir) {
|
|
|
4101
4119
|
} catch {
|
|
4102
4120
|
}
|
|
4103
4121
|
try {
|
|
4104
|
-
if (existsSync6(
|
|
4122
|
+
if (existsSync6(join7(dir, "Cargo.toml")))
|
|
4105
4123
|
stacks.push("rust");
|
|
4106
4124
|
} catch {
|
|
4107
4125
|
}
|
|
4108
4126
|
try {
|
|
4109
|
-
if (existsSync6(
|
|
4127
|
+
if (existsSync6(join7(dir, "go.mod")))
|
|
4110
4128
|
stacks.push("go");
|
|
4111
4129
|
} catch {
|
|
4112
4130
|
}
|
|
4113
4131
|
try {
|
|
4114
|
-
if (existsSync6(
|
|
4132
|
+
if (existsSync6(join7(dir, "requirements.txt")))
|
|
4115
4133
|
stacks.push("python");
|
|
4116
|
-
if (existsSync6(
|
|
4134
|
+
if (existsSync6(join7(dir, "setup.py")))
|
|
4117
4135
|
stacks.push("python");
|
|
4118
|
-
if (existsSync6(
|
|
4136
|
+
if (existsSync6(join7(dir, "pyproject.toml")))
|
|
4119
4137
|
stacks.push("python");
|
|
4120
4138
|
} catch {
|
|
4121
4139
|
}
|
|
@@ -4223,30 +4241,30 @@ function saveOptimizationMode(mode) {
|
|
|
4223
4241
|
}
|
|
4224
4242
|
|
|
4225
4243
|
// src/lib/research-audit.js
|
|
4226
|
-
import { readFileSync as
|
|
4227
|
-
import { join as
|
|
4228
|
-
import { homedir as
|
|
4244
|
+
import { readFileSync as readFileSync7, existsSync as existsSync7 } from "node:fs";
|
|
4245
|
+
import { join as join8 } from "node:path";
|
|
4246
|
+
import { homedir as homedir7, tmpdir as tmpdir5 } from "node:os";
|
|
4229
4247
|
var USER_HOME5 = (() => {
|
|
4230
4248
|
try {
|
|
4231
|
-
return
|
|
4249
|
+
return homedir7();
|
|
4232
4250
|
} catch {
|
|
4233
4251
|
return tmpdir5();
|
|
4234
4252
|
}
|
|
4235
4253
|
})();
|
|
4236
4254
|
var _OC_SID3 = "opencode-" + (process.pid || "x") + "-" + Date.now();
|
|
4237
|
-
var SCRATCHPAD_ROOT2 =
|
|
4238
|
-
var SCRATCHPAD_GLOBAL_DIR2 =
|
|
4239
|
-
var SCRATCHPAD_SESSIONS_DIR2 =
|
|
4240
|
-
var STATE_FILE4 =
|
|
4255
|
+
var SCRATCHPAD_ROOT2 = join8(USER_HOME5, ".claude/scratch");
|
|
4256
|
+
var SCRATCHPAD_GLOBAL_DIR2 = join8(SCRATCHPAD_ROOT2, "by-hash");
|
|
4257
|
+
var SCRATCHPAD_SESSIONS_DIR2 = join8(SCRATCHPAD_ROOT2, "sessions");
|
|
4258
|
+
var STATE_FILE4 = join8(USER_HOME5, ".claude/delegation-state.json");
|
|
4241
4259
|
var currentModel2 = null;
|
|
4242
4260
|
function getSessionRoot2() {
|
|
4243
|
-
return
|
|
4261
|
+
return join8(SCRATCHPAD_SESSIONS_DIR2, _OC_SID3);
|
|
4244
4262
|
}
|
|
4245
4263
|
function getSessionScratchpadDir2() {
|
|
4246
|
-
return
|
|
4264
|
+
return join8(getSessionRoot2(), "by-hash");
|
|
4247
4265
|
}
|
|
4248
4266
|
function getGlobalIndexPath2() {
|
|
4249
|
-
return
|
|
4267
|
+
return join8(SCRATCHPAD_ROOT2, "index.jsonl");
|
|
4250
4268
|
}
|
|
4251
4269
|
var FETCH_TOOLS = /* @__PURE__ */ new Set(["WebFetch", "WebSearch", "webfetch", "websearch"]);
|
|
4252
4270
|
function researchAudit({ hours = 24, session: sessionFilter } = {}) {
|
|
@@ -4255,7 +4273,7 @@ function researchAudit({ hours = 24, session: sessionFilter } = {}) {
|
|
|
4255
4273
|
try {
|
|
4256
4274
|
const indexPath = getGlobalIndexPath2();
|
|
4257
4275
|
if (existsSync7(indexPath)) {
|
|
4258
|
-
const lines =
|
|
4276
|
+
const lines = readFileSync7(indexPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
4259
4277
|
const domainCache = {};
|
|
4260
4278
|
for (const line of lines) {
|
|
4261
4279
|
const e = JSON.parse(line);
|
|
@@ -4269,11 +4287,11 @@ function researchAudit({ hours = 24, session: sessionFilter } = {}) {
|
|
|
4269
4287
|
report.totalFetches++;
|
|
4270
4288
|
report.totalBytes += e.size || 0;
|
|
4271
4289
|
const hash = e.hash;
|
|
4272
|
-
const summaryPathSession =
|
|
4273
|
-
const summaryPathGlobal =
|
|
4290
|
+
const summaryPathSession = join8(getSessionScratchpadDir2(), hash + ".summary.txt");
|
|
4291
|
+
const summaryPathGlobal = join8(SCRATCHPAD_GLOBAL_DIR2, hash + ".summary.txt");
|
|
4274
4292
|
const summaryPath = existsSync7(summaryPathSession) ? summaryPathSession : summaryPathGlobal;
|
|
4275
4293
|
if (existsSync7(summaryPath)) {
|
|
4276
|
-
const summary =
|
|
4294
|
+
const summary = readFileSync7(summaryPath, "utf-8").slice(0, 200);
|
|
4277
4295
|
const urlMatch = summary.match(/https?:\/\/([^\/\s\)]+)/i);
|
|
4278
4296
|
const queryMatch = summary.match(/"query":"([^"]+)"/);
|
|
4279
4297
|
let domain;
|
|
@@ -4320,7 +4338,7 @@ function researchAudit({ hours = 24, session: sessionFilter } = {}) {
|
|
|
4320
4338
|
}
|
|
4321
4339
|
try {
|
|
4322
4340
|
if (existsSync7(STATE_FILE4)) {
|
|
4323
|
-
const state = safeJsonParse3(
|
|
4341
|
+
const state = safeJsonParse3(readFileSync7(STATE_FILE4, "utf-8"));
|
|
4324
4342
|
for (const [sid, s] of Object.entries(state.sessions || {})) {
|
|
4325
4343
|
if (sessionFilter && sid !== sessionFilter)
|
|
4326
4344
|
continue;
|
|
@@ -4343,25 +4361,25 @@ function researchAudit({ hours = 24, session: sessionFilter } = {}) {
|
|
|
4343
4361
|
}
|
|
4344
4362
|
|
|
4345
4363
|
// src/lib/reporting.js
|
|
4346
|
-
import { readFileSync as
|
|
4347
|
-
import { join as
|
|
4348
|
-
import { homedir as
|
|
4364
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync6, statSync as statSync7, copyFileSync as copyFileSync5, rmSync as rmSync4 } from "node:fs";
|
|
4365
|
+
import { join as join9, basename as basename6 } from "node:path";
|
|
4366
|
+
import { homedir as homedir8, tmpdir as tmpdir6 } from "node:os";
|
|
4349
4367
|
var USER_HOME6 = (() => {
|
|
4350
4368
|
try {
|
|
4351
|
-
return
|
|
4369
|
+
return homedir8();
|
|
4352
4370
|
} catch {
|
|
4353
4371
|
return tmpdir6();
|
|
4354
4372
|
}
|
|
4355
4373
|
})();
|
|
4356
|
-
var REPORTS_DIR2 =
|
|
4357
|
-
var REPORTS_INDEX =
|
|
4374
|
+
var REPORTS_DIR2 = join9(USER_HOME6, ".claude/reports");
|
|
4375
|
+
var REPORTS_INDEX = join9(REPORTS_DIR2, "index.json");
|
|
4358
4376
|
var _OC_SID4 = "opencode-" + (process.pid || "x") + "-" + Date.now();
|
|
4359
4377
|
var currentProjectFingerprint3 = "";
|
|
4360
4378
|
var currentProjectName2 = "";
|
|
4361
4379
|
function _handleStateCorruption5(path) {
|
|
4362
|
-
const backupDir =
|
|
4380
|
+
const backupDir = join9(USER_HOME6, ".claude", ".backups");
|
|
4363
4381
|
mkdirSync6(backupDir, { recursive: true });
|
|
4364
|
-
const backupPath =
|
|
4382
|
+
const backupPath = join9(backupDir, basename6(path) + ".corrupted." + Date.now());
|
|
4365
4383
|
try {
|
|
4366
4384
|
copyFileSync5(path, backupPath);
|
|
4367
4385
|
} catch {
|
|
@@ -4376,7 +4394,7 @@ function readJsonOrEmpty3(filePath) {
|
|
|
4376
4394
|
_handleStateCorruption5(filePath);
|
|
4377
4395
|
return {};
|
|
4378
4396
|
}
|
|
4379
|
-
return safeJsonParse3(
|
|
4397
|
+
return safeJsonParse3(readFileSync8(filePath, "utf-8"));
|
|
4380
4398
|
} catch {
|
|
4381
4399
|
_handleStateCorruption5(filePath);
|
|
4382
4400
|
return {};
|
|
@@ -4431,7 +4449,7 @@ function _pruneReports() {
|
|
|
4431
4449
|
continue;
|
|
4432
4450
|
if (now - created > 90 * 24 * 3600 * 1e3) {
|
|
4433
4451
|
try {
|
|
4434
|
-
rmSync4(
|
|
4452
|
+
rmSync4(join9(REPORTS_DIR2, `${r.id}.json`));
|
|
4435
4453
|
} catch {
|
|
4436
4454
|
}
|
|
4437
4455
|
continue;
|
|
@@ -4502,7 +4520,7 @@ function saveReport({ type = "manual", summary = "", findings = null, metrics =
|
|
|
4502
4520
|
try {
|
|
4503
4521
|
withFileLock(REPORTS_INDEX, () => {
|
|
4504
4522
|
mkdirSync6(REPORTS_DIR2, { recursive: true });
|
|
4505
|
-
writeFileSync6(
|
|
4523
|
+
writeFileSync6(join9(REPORTS_DIR2, `${id2}.json`), JSON.stringify(report, null, 2) + "\n");
|
|
4506
4524
|
const idx = reportsIndex();
|
|
4507
4525
|
const _sum = (summary || "").slice(0, 80);
|
|
4508
4526
|
idx.reports.push({ id: id2, type, project: report.meta.project, fingerprint: fp3, created: report.meta.created, summary: _sum });
|
|
@@ -4536,19 +4554,19 @@ function readReport(id2) {
|
|
|
4536
4554
|
return null;
|
|
4537
4555
|
if (!/^[\w-]+$/.test(String(id2)))
|
|
4538
4556
|
return null;
|
|
4539
|
-
const path =
|
|
4557
|
+
const path = join9(REPORTS_DIR2, `${id2}.json`);
|
|
4540
4558
|
try {
|
|
4541
4559
|
if (!existsSync8(path))
|
|
4542
4560
|
return null;
|
|
4543
|
-
return safeJsonParse3(
|
|
4561
|
+
return safeJsonParse3(readFileSync8(path, "utf-8"));
|
|
4544
4562
|
} catch {
|
|
4545
4563
|
return null;
|
|
4546
4564
|
}
|
|
4547
4565
|
}
|
|
4548
4566
|
|
|
4549
4567
|
// src/lib/credit-api.js
|
|
4550
|
-
import { readFileSync as
|
|
4551
|
-
import { join as
|
|
4568
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, existsSync as existsSync9 } from "node:fs";
|
|
4569
|
+
import { join as join10 } from "node:path";
|
|
4552
4570
|
function safeJsonParse4(raw) {
|
|
4553
4571
|
try {
|
|
4554
4572
|
return JSON.parse(raw);
|
|
@@ -4579,7 +4597,7 @@ var BALANCE_APIS = {
|
|
|
4579
4597
|
var _creditTimer = null;
|
|
4580
4598
|
function _readAuth() {
|
|
4581
4599
|
try {
|
|
4582
|
-
return existsSync9(AUTH_F) ? safeJsonParse4(
|
|
4600
|
+
return existsSync9(AUTH_F) ? safeJsonParse4(readFileSync9(AUTH_F, "utf-8")) : {};
|
|
4583
4601
|
} catch {
|
|
4584
4602
|
return {};
|
|
4585
4603
|
}
|
|
@@ -4622,14 +4640,14 @@ function _cachedPct() {
|
|
|
4622
4640
|
try {
|
|
4623
4641
|
if (!existsSync9(CREDIT_CACHE_F))
|
|
4624
4642
|
return null;
|
|
4625
|
-
const s = safeJsonParse4(
|
|
4643
|
+
const s = safeJsonParse4(readFileSync9(CREDIT_CACHE_F, "utf-8"));
|
|
4626
4644
|
if (s?.total == null || !s.ts)
|
|
4627
4645
|
return null;
|
|
4628
4646
|
let budget = 50;
|
|
4629
4647
|
try {
|
|
4630
|
-
const p =
|
|
4648
|
+
const p = join10(USER_HOME2, ".claude/model-tiers.json");
|
|
4631
4649
|
if (existsSync9(p)) {
|
|
4632
|
-
const j = safeJsonParse4(
|
|
4650
|
+
const j = safeJsonParse4(readFileSync9(p, "utf-8"));
|
|
4633
4651
|
if (j?.selection?.monthly_budget_usd)
|
|
4634
4652
|
budget = j.selection.monthly_budget_usd;
|
|
4635
4653
|
}
|
|
@@ -4660,9 +4678,9 @@ function loadCredit() {
|
|
|
4660
4678
|
return n;
|
|
4661
4679
|
}
|
|
4662
4680
|
try {
|
|
4663
|
-
const f =
|
|
4681
|
+
const f = join10(USER_HOME2, ".claude/credit-percent");
|
|
4664
4682
|
if (existsSync9(f)) {
|
|
4665
|
-
const n = parseInt(
|
|
4683
|
+
const n = parseInt(readFileSync9(f, "utf-8").trim(), 10);
|
|
4666
4684
|
if (!isNaN(n))
|
|
4667
4685
|
return n;
|
|
4668
4686
|
}
|
|
@@ -4679,7 +4697,7 @@ function thinkingLevel(credit) {
|
|
|
4679
4697
|
}
|
|
4680
4698
|
|
|
4681
4699
|
// src/lib/trinity-tool.js
|
|
4682
|
-
import { join as
|
|
4700
|
+
import { join as join11 } from "node:path";
|
|
4683
4701
|
function createTrinityTool(deps) {
|
|
4684
4702
|
return {
|
|
4685
4703
|
description: "Control the vibeOS plugin and active model slot. Use action='status' to see current state. Use action='enable' or 'disable' to toggle the plugin (takes effect immediately, no restart needed). Use action='set' with slot='brain'|'medium'|'cheap' to switch model tiers (writes opencode.json \u2014 active immediately). Use action='rebuild' to auto-detect available models from all configured providers and reassign brain/medium/cheap slots. Use action='flow' with slot='on'|'off' to toggle flow enforcer, or action='flow' alone for audit. Use action='flow' with slot='enforce' and level='on'|'off' to toggle auto-extract TODOs. Use action='enforce' with slot='on'|'off' to toggle delegation enforcement (blocks direct writes/edits on brain tier). Use action='tdd' with slot='on'|'off' to toggle auto-create test skeletons. Use action='tdd' with slot='strict' and level='on'|'off' to toggle strict failing TODO test templates. Use action='tdd' alone for audit. Use action='project' to show per-project analytics and optimization suggestions. Use action='patterns' to inspect learned project patterns or slot='clear' to clear them. Use action='guard' to ensure AGENTS.md and README.md exist and stay current. Call this when the user says things like 'switch to medium', 'use cheap model', 'disable plugin', 'trinity status'.",
|
|
@@ -4934,7 +4952,7 @@ Lock is per-session (resets on restart).`;
|
|
|
4934
4952
|
const ok = deps.writeSelection("tdd_enforce", slot === "on");
|
|
4935
4953
|
return ok ? `\u2705 TDD enforcement ${slot === "on" ? "ENABLED (auto-create skeletons)" : "DISABLED (nudge only)"}` : `\u274C Failed to write model-tiers.json`;
|
|
4936
4954
|
}
|
|
4937
|
-
const stateFile =
|
|
4955
|
+
const stateFile = join11(deps.USER_HOME, ".claude/delegation-state.json");
|
|
4938
4956
|
let enforced = 0;
|
|
4939
4957
|
try {
|
|
4940
4958
|
if (deps.existsSync(stateFile)) {
|
|
@@ -5314,7 +5332,7 @@ ${L.repeat(40)}`);
|
|
|
5314
5332
|
}
|
|
5315
5333
|
if (action === "diagnose") {
|
|
5316
5334
|
const results = [];
|
|
5317
|
-
const ocConfig =
|
|
5335
|
+
const ocConfig = join11(deps.USER_HOME, ".config/opencode/opencode.json");
|
|
5318
5336
|
const checks = [
|
|
5319
5337
|
{ path: deps.TIERS_FILE, label: "model-tiers.json" },
|
|
5320
5338
|
{ path: ocConfig, label: "opencode.json" },
|
|
@@ -5486,7 +5504,7 @@ ${L.repeat(40)}`);
|
|
|
5486
5504
|
for (const r of idx.reports || []) {
|
|
5487
5505
|
if (r.project !== name || r.fingerprint !== dstFp)
|
|
5488
5506
|
continue;
|
|
5489
|
-
const rf =
|
|
5507
|
+
const rf = join11(deps.REPORTS_DIR, `${r.id}.json`);
|
|
5490
5508
|
try {
|
|
5491
5509
|
if (!deps.existsSync(rf))
|
|
5492
5510
|
continue;
|
|
@@ -5605,8 +5623,8 @@ ${L.repeat(40)}`);
|
|
|
5605
5623
|
}
|
|
5606
5624
|
|
|
5607
5625
|
// src/lib/trinity-rebuild.js
|
|
5608
|
-
import { readFileSync as
|
|
5609
|
-
import { join as
|
|
5626
|
+
import { readFileSync as readFileSync10, existsSync as existsSync10 } from "node:fs";
|
|
5627
|
+
import { join as join12 } from "node:path";
|
|
5610
5628
|
var MODEL_RANK = { high: 3, mid: 2, budget: 1 };
|
|
5611
5629
|
var OPENCODE_GO_CATALOG = [
|
|
5612
5630
|
"deepseek/deepseek-v4-flash",
|
|
@@ -5809,17 +5827,17 @@ async function probeModel(modelId, auth) {
|
|
|
5809
5827
|
}
|
|
5810
5828
|
|
|
5811
5829
|
// src/lib/hooks/footer.js
|
|
5812
|
-
import { readFileSync as
|
|
5813
|
-
import { join as
|
|
5814
|
-
import { homedir as
|
|
5830
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
5831
|
+
import { join as join15 } from "node:path";
|
|
5832
|
+
import { homedir as homedir9, tmpdir as tmpdir7 } from "node:os";
|
|
5815
5833
|
|
|
5816
5834
|
// src/lib/hooks/chat-transform.js
|
|
5817
|
-
import { readFileSync as
|
|
5818
|
-
import { join as
|
|
5835
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync11, mkdirSync as mkdirSync7 } from "node:fs";
|
|
5836
|
+
import { join as join14, basename as basename7 } from "node:path";
|
|
5819
5837
|
import { createHash as createHash4 } from "node:crypto";
|
|
5820
5838
|
|
|
5821
5839
|
// src/lib/index-helpers.js
|
|
5822
|
-
import { join as
|
|
5840
|
+
import { join as join13 } from "node:path";
|
|
5823
5841
|
import { writeFileSync as writeFileSync8 } from "node:fs";
|
|
5824
5842
|
|
|
5825
5843
|
// src/lib/text-compress.js
|
|
@@ -6154,7 +6172,7 @@ function recordSaving(tool2, reason, saveEst, meta = {}) {
|
|
|
6154
6172
|
try {
|
|
6155
6173
|
const sd = getSessionScratchpadDir();
|
|
6156
6174
|
if (sd) {
|
|
6157
|
-
const sp =
|
|
6175
|
+
const sp = join13(sd, "delegation-state-hint.txt");
|
|
6158
6176
|
try {
|
|
6159
6177
|
writeFileSync8(sp, JSON.stringify({ sid, total_savings: s.lifetime.total_savings_usd, last_reason: reason }), "utf8");
|
|
6160
6178
|
} catch {
|
|
@@ -6283,10 +6301,10 @@ function buildProjectBriefing(directory3) {
|
|
|
6283
6301
|
return `[project memory] Active project: ${label}. Stay focused on the current repository and prefer the existing workflow.`;
|
|
6284
6302
|
}
|
|
6285
6303
|
function ensureProjectSkill(dir, fp3) {
|
|
6286
|
-
const skillsDir =
|
|
6304
|
+
const skillsDir = join14(dir, ".opencode", "skills");
|
|
6287
6305
|
const projectName = basename7(dir);
|
|
6288
|
-
const skillDir =
|
|
6289
|
-
const skillPath =
|
|
6306
|
+
const skillDir = join14(skillsDir, projectName);
|
|
6307
|
+
const skillPath = join14(skillDir, "SKILL.md");
|
|
6290
6308
|
if (existsSync11(skillPath)) {
|
|
6291
6309
|
return { created: false, skipped: true, path: skillPath };
|
|
6292
6310
|
}
|
|
@@ -6443,7 +6461,7 @@ var onMessagesTransform = async (_input, output) => {
|
|
|
6443
6461
|
const hash = createHash4("sha256").update(`tool_result
|
|
6444
6462
|
${raw}
|
|
6445
6463
|
`).digest("hex").slice(0, 16);
|
|
6446
|
-
const fullPath =
|
|
6464
|
+
const fullPath = join14(getSessionScratchpadDir(), `${hash}.txt`);
|
|
6447
6465
|
try {
|
|
6448
6466
|
ensureSessionScratchpadDirs();
|
|
6449
6467
|
if (!existsSync11(fullPath)) {
|
|
@@ -6617,7 +6635,7 @@ var onSystemTransform = async (_input, output) => {
|
|
|
6617
6635
|
const mediumModel = TRINITY_MEDIUM || "the medium model";
|
|
6618
6636
|
let brainModel = "(brain)";
|
|
6619
6637
|
try {
|
|
6620
|
-
brainModel = safeJsonParse3(
|
|
6638
|
+
brainModel = safeJsonParse3(readFileSync11(TIERS_FILE2, "utf-8")).trinity?.brain?.oc || brainModel;
|
|
6621
6639
|
} catch {
|
|
6622
6640
|
}
|
|
6623
6641
|
const targetModel = tierBias === "cheap" ? cheapModel : tierBias === "medium" ? mediumModel : tierBias === "brain" ? brainModel : `${cheapModel} or ${mediumModel}`;
|
|
@@ -6668,7 +6686,7 @@ var onSystemTransform = async (_input, output) => {
|
|
|
6668
6686
|
const sel2 = loadSelection();
|
|
6669
6687
|
let tiers = {};
|
|
6670
6688
|
try {
|
|
6671
|
-
tiers = safeJsonParse3(
|
|
6689
|
+
tiers = safeJsonParse3(readFileSync11(TIERS_FILE2, "utf-8")).trinity || {};
|
|
6672
6690
|
} catch {
|
|
6673
6691
|
}
|
|
6674
6692
|
const active = sel2.active_slot || "medium";
|
|
@@ -6710,19 +6728,19 @@ async function apiAutoSelectMode(regime, stress) {
|
|
|
6710
6728
|
}
|
|
6711
6729
|
var USER_HOME7 = (() => {
|
|
6712
6730
|
try {
|
|
6713
|
-
return
|
|
6731
|
+
return homedir9();
|
|
6714
6732
|
} catch {
|
|
6715
6733
|
return tmpdir7();
|
|
6716
6734
|
}
|
|
6717
6735
|
})();
|
|
6718
|
-
var STATE_FILE5 =
|
|
6719
|
-
var SAVINGS_LEDGER_FILE2 =
|
|
6736
|
+
var STATE_FILE5 = join15(USER_HOME7, ".claude/delegation-state.json");
|
|
6737
|
+
var SAVINGS_LEDGER_FILE2 = join15(USER_HOME7, ".claude/savings-ledger.jsonl");
|
|
6720
6738
|
var _prevOutputText = "";
|
|
6721
6739
|
var _autoReportCount = 0;
|
|
6722
6740
|
var textCompletePainted = /* @__PURE__ */ new Set();
|
|
6723
6741
|
function loadSelection3() {
|
|
6724
6742
|
try {
|
|
6725
|
-
const raw =
|
|
6743
|
+
const raw = readFileSync12(join15(USER_HOME7, ".claude/model-tiers.json"), "utf-8");
|
|
6726
6744
|
return safeJsonParse3(raw)?.selection || { active_slot: "medium", enabled: true, delegation_enforce: false, flow_enabled: false, flow_enforce: false, tdd_enforce: false, tdd_strict: false };
|
|
6727
6745
|
} catch {
|
|
6728
6746
|
return { active_slot: "medium", enabled: true, delegation_enforce: false, flow_enabled: false, flow_enforce: false, tdd_enforce: false, tdd_strict: false };
|
|
@@ -6731,7 +6749,7 @@ function loadSelection3() {
|
|
|
6731
6749
|
function readLifetimeSavings2() {
|
|
6732
6750
|
try {
|
|
6733
6751
|
reconcileStateFromLedger();
|
|
6734
|
-
const raw =
|
|
6752
|
+
const raw = readFileSync12(STATE_FILE5, "utf-8");
|
|
6735
6753
|
const state = safeJsonParse3(raw);
|
|
6736
6754
|
const ses = state?.sessions?.[typeof _OC_SID6 !== "undefined" ? _OC_SID6 : ""] || {};
|
|
6737
6755
|
return {
|
|
@@ -6961,8 +6979,8 @@ import { dirname as dirname7, basename as basename8 } from "node:path";
|
|
|
6961
6979
|
init_flow_enforcer();
|
|
6962
6980
|
|
|
6963
6981
|
// src/lib/tdd-enforcer.js
|
|
6964
|
-
import { readFileSync as
|
|
6965
|
-
import { join as
|
|
6982
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, appendFileSync as appendFileSync6, existsSync as existsSync12, mkdirSync as mkdirSync8, statSync as statSync8, readdirSync as readdirSync2, rmSync as rmSync5, openSync as openSync4 } from "node:fs";
|
|
6983
|
+
import { join as join16, dirname as dirname6 } from "node:path";
|
|
6966
6984
|
import { createHash as createHash5 } from "node:crypto";
|
|
6967
6985
|
|
|
6968
6986
|
// src/utils/tdd-helpers.js
|
|
@@ -8001,9 +8019,9 @@ function _detectTestFramework() {
|
|
|
8001
8019
|
let testExt = null;
|
|
8002
8020
|
try {
|
|
8003
8021
|
const root = directory || process.cwd();
|
|
8004
|
-
const pkgPath =
|
|
8022
|
+
const pkgPath = join16(root, "package.json");
|
|
8005
8023
|
if (existsSync12(pkgPath)) {
|
|
8006
|
-
const pkg = JSON.parse(
|
|
8024
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
|
|
8007
8025
|
const testScript = String(pkg?.scripts?.test || "");
|
|
8008
8026
|
const deps = { ...pkg?.devDependencies, ...pkg?.dependencies };
|
|
8009
8027
|
if (testScript.includes("vitest") || deps["vitest"]) {
|
|
@@ -8023,12 +8041,12 @@ function _detectTestFramework() {
|
|
|
8023
8041
|
if (!framework) {
|
|
8024
8042
|
const testDirs = ["src/tests", "tests", "test", "__tests__"];
|
|
8025
8043
|
for (const td of testDirs) {
|
|
8026
|
-
const dirPath =
|
|
8044
|
+
const dirPath = join16(root, td);
|
|
8027
8045
|
if (!existsSync12(dirPath))
|
|
8028
8046
|
continue;
|
|
8029
8047
|
const files = readdirSync2(dirPath).filter((f) => /\.test\./.test(f) || /\.spec\./.test(f));
|
|
8030
8048
|
if (files.length > 0) {
|
|
8031
|
-
const content =
|
|
8049
|
+
const content = readFileSync13(join16(dirPath, files[0]), "utf-8");
|
|
8032
8050
|
if (/from\s+['"]node:test['"]/.test(content)) {
|
|
8033
8051
|
framework = "node-test";
|
|
8034
8052
|
testExt = files[0].split(".").pop();
|
|
@@ -8054,16 +8072,16 @@ function _detectTestFramework() {
|
|
|
8054
8072
|
console.error(`[vibeOS] [tdd] detected test framework: ${framework || "default"} (ext: ${testExt || "match source"})`);
|
|
8055
8073
|
return _detectedFramework;
|
|
8056
8074
|
}
|
|
8057
|
-
var ENFORCEMENT_LOCK_DIR =
|
|
8075
|
+
var ENFORCEMENT_LOCK_DIR = join16(USER_HOME2, ".claude/.enforcement-lock");
|
|
8058
8076
|
var LOCK_EXPIRE_MS = 3e4;
|
|
8059
|
-
var ENFORCEMENT_COOLDOWN_FILE2 =
|
|
8077
|
+
var ENFORCEMENT_COOLDOWN_FILE2 = join16(USER_HOME2, ".claude/.enforcement-cooldown.jsonl");
|
|
8060
8078
|
var COOLDOWN_MS = 6e4;
|
|
8061
8079
|
var _enforcementCooldown = /* @__PURE__ */ new Set();
|
|
8062
8080
|
function _acquireLock(testPath) {
|
|
8063
8081
|
try {
|
|
8064
8082
|
mkdirSync8(ENFORCEMENT_LOCK_DIR, { recursive: true });
|
|
8065
8083
|
const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
8066
|
-
const lockPath =
|
|
8084
|
+
const lockPath = join16(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
|
|
8067
8085
|
try {
|
|
8068
8086
|
openSync4(lockPath, "wx");
|
|
8069
8087
|
return true;
|
|
@@ -8091,7 +8109,7 @@ function _acquireLock(testPath) {
|
|
|
8091
8109
|
function _releaseLock(testPath) {
|
|
8092
8110
|
try {
|
|
8093
8111
|
const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
8094
|
-
const lockPath =
|
|
8112
|
+
const lockPath = join16(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
|
|
8095
8113
|
rmSync5(lockPath);
|
|
8096
8114
|
} catch {
|
|
8097
8115
|
}
|
|
@@ -8101,7 +8119,7 @@ function _isInCooldown(testPath) {
|
|
|
8101
8119
|
if (!existsSync12(ENFORCEMENT_COOLDOWN_FILE2))
|
|
8102
8120
|
return false;
|
|
8103
8121
|
const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
8104
|
-
const lines =
|
|
8122
|
+
const lines = readFileSync13(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
|
|
8105
8123
|
const now = Date.now();
|
|
8106
8124
|
for (const line of lines) {
|
|
8107
8125
|
try {
|
|
@@ -8122,7 +8140,7 @@ function _recordCooldown(testPath) {
|
|
|
8122
8140
|
const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
|
|
8123
8141
|
const entry = JSON.stringify({ h: hash, ts: Date.now() }) + "\n";
|
|
8124
8142
|
appendFileSync6(ENFORCEMENT_COOLDOWN_FILE2, entry);
|
|
8125
|
-
const lines =
|
|
8143
|
+
const lines = readFileSync13(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
|
|
8126
8144
|
if (lines.length > 500) {
|
|
8127
8145
|
writeFileSync10(ENFORCEMENT_COOLDOWN_FILE2, lines.slice(-200).join("\n") + "\n");
|
|
8128
8146
|
}
|
|
@@ -8193,7 +8211,7 @@ function enforceTestFile(filePath) {
|
|
|
8193
8211
|
let sourceContent = "";
|
|
8194
8212
|
try {
|
|
8195
8213
|
if (existsSync12(filePath)) {
|
|
8196
|
-
sourceContent =
|
|
8214
|
+
sourceContent = readFileSync13(filePath, "utf-8");
|
|
8197
8215
|
}
|
|
8198
8216
|
} catch {
|
|
8199
8217
|
}
|
|
@@ -8814,7 +8832,7 @@ ${pendingUiNote}`;
|
|
|
8814
8832
|
};
|
|
8815
8833
|
|
|
8816
8834
|
// src/lib/hooks/session-compact.js
|
|
8817
|
-
import { readFileSync as
|
|
8835
|
+
import { readFileSync as readFileSync14, existsSync as existsSync14 } from "node:fs";
|
|
8818
8836
|
var onSessionCompacting = async (_input, output) => {
|
|
8819
8837
|
if (!loadSelection().enabled)
|
|
8820
8838
|
return;
|
|
@@ -8823,7 +8841,7 @@ var onSessionCompacting = async (_input, output) => {
|
|
|
8823
8841
|
let recent = "";
|
|
8824
8842
|
if (existsSync14(indexPath)) {
|
|
8825
8843
|
try {
|
|
8826
|
-
const lines =
|
|
8844
|
+
const lines = readFileSync14(indexPath, "utf-8").trim().split("\n").slice(-30);
|
|
8827
8845
|
recent = lines.map((l) => {
|
|
8828
8846
|
try {
|
|
8829
8847
|
return JSON.parse(l);
|
|
@@ -8877,17 +8895,17 @@ var _mcpServerRuntime = null;
|
|
|
8877
8895
|
var _mcpServerHooked = false;
|
|
8878
8896
|
function _loadOpenCodeProviders() {
|
|
8879
8897
|
try {
|
|
8880
|
-
const cfg = _readOpenCodeConfigObject(
|
|
8898
|
+
const cfg = _readOpenCodeConfigObject(join17(USER_HOME2, ".config", "opencode"));
|
|
8881
8899
|
return cfg?.provider || {};
|
|
8882
8900
|
} catch {
|
|
8883
8901
|
return {};
|
|
8884
8902
|
}
|
|
8885
8903
|
}
|
|
8886
8904
|
function _readOpenCodeConfigObject(dir) {
|
|
8887
|
-
const jsonPath =
|
|
8888
|
-
const jsoncPath =
|
|
8889
|
-
if (existsSync15(jsonPath)) return safeJsonParse3(
|
|
8890
|
-
if (existsSync15(jsoncPath)) return _parseJsonc(
|
|
8905
|
+
const jsonPath = join17(dir, "opencode.json");
|
|
8906
|
+
const jsoncPath = join17(dir, "opencode.jsonc");
|
|
8907
|
+
if (existsSync15(jsonPath)) return safeJsonParse3(readFileSync15(jsonPath, "utf-8"));
|
|
8908
|
+
if (existsSync15(jsoncPath)) return _parseJsonc(readFileSync15(jsoncPath, "utf-8"));
|
|
8891
8909
|
return {};
|
|
8892
8910
|
}
|
|
8893
8911
|
function _parseJsonc(raw) {
|
|
@@ -8913,9 +8931,9 @@ function _modelTier2(id2) {
|
|
|
8913
8931
|
function backupFile(path, label) {
|
|
8914
8932
|
try {
|
|
8915
8933
|
if (!existsSync15(path)) return null;
|
|
8916
|
-
const bkDir =
|
|
8934
|
+
const bkDir = join17(USER_HOME2, ".claude", ".backups");
|
|
8917
8935
|
mkdirSync10(bkDir, { recursive: true });
|
|
8918
|
-
const bk =
|
|
8936
|
+
const bk = join17(bkDir, `${basename9(path)}.${label}.${Date.now()}.bak`);
|
|
8919
8937
|
copyFileSync6(path, bk);
|
|
8920
8938
|
return bk;
|
|
8921
8939
|
} catch {
|
|
@@ -8924,7 +8942,7 @@ function backupFile(path, label) {
|
|
|
8924
8942
|
}
|
|
8925
8943
|
function readPackageVersion() {
|
|
8926
8944
|
try {
|
|
8927
|
-
const pkg = safeJsonParse3(
|
|
8945
|
+
const pkg = safeJsonParse3(readFileSync15(join17(process.cwd(), "package.json"), "utf-8"));
|
|
8928
8946
|
return String(pkg?.version || "");
|
|
8929
8947
|
} catch {
|
|
8930
8948
|
return "";
|
|
@@ -8939,7 +8957,7 @@ function loadMcpPort() {
|
|
|
8939
8957
|
}
|
|
8940
8958
|
try {
|
|
8941
8959
|
if (existsSync15(TIERS_FILE2)) {
|
|
8942
|
-
const tiers = safeJsonParse3(
|
|
8960
|
+
const tiers = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
8943
8961
|
const cfg = tiers?.selection?.mcp_port ?? tiers?.mcp_port;
|
|
8944
8962
|
if (cfg === false || cfg === "disabled" || cfg === 0) return 0;
|
|
8945
8963
|
const n = Number(cfg);
|
|
@@ -8952,7 +8970,7 @@ function loadMcpPort() {
|
|
|
8952
8970
|
function persistMcpPort(port) {
|
|
8953
8971
|
try {
|
|
8954
8972
|
if (!existsSync15(TIERS_FILE2)) return;
|
|
8955
|
-
const tiers = safeJsonParse3(
|
|
8973
|
+
const tiers = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
8956
8974
|
tiers.selection ??= {};
|
|
8957
8975
|
if (Number(tiers.selection.mcp_port) === Number(port)) return;
|
|
8958
8976
|
tiers.selection.mcp_port = port;
|
|
@@ -8967,7 +8985,7 @@ function computeStatusPayload() {
|
|
|
8967
8985
|
const sel = loadSelection();
|
|
8968
8986
|
let tiersData = {};
|
|
8969
8987
|
try {
|
|
8970
|
-
tiersData = safeJsonParse3(
|
|
8988
|
+
tiersData = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
8971
8989
|
} catch {
|
|
8972
8990
|
}
|
|
8973
8991
|
const credit = loadCredit();
|
|
@@ -9120,13 +9138,13 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9120
9138
|
setCurrentModel(readConfig(directory3));
|
|
9121
9139
|
if (!currentModel) {
|
|
9122
9140
|
const home = process.env.HOME || "";
|
|
9123
|
-
if (home) setCurrentModel(readConfig(
|
|
9141
|
+
if (home) setCurrentModel(readConfig(join17(home, ".config/opencode")));
|
|
9124
9142
|
}
|
|
9125
9143
|
if (!currentModel) setCurrentModel(process?.env?.OPENCODE_MODEL || "");
|
|
9126
9144
|
if (currentModel) {
|
|
9127
9145
|
setCurrentTier(classify(currentModel));
|
|
9128
9146
|
try {
|
|
9129
|
-
const _tiersData2 = safeJsonParse3(
|
|
9147
|
+
const _tiersData2 = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
9130
9148
|
const _activeSlot = _tiersData2?.selection?.active_slot || "brain";
|
|
9131
9149
|
if (_activeSlot === "brain") {
|
|
9132
9150
|
const _brainOcModel = _tiersData2?.trinity?.brain?.oc || "";
|
|
@@ -9151,7 +9169,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9151
9169
|
let _wasCorrupted = false;
|
|
9152
9170
|
if (existsSync15(TIERS_FILE2)) {
|
|
9153
9171
|
try {
|
|
9154
|
-
_tiersData2 = safeJsonParse3(
|
|
9172
|
+
_tiersData2 = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
9155
9173
|
} catch {
|
|
9156
9174
|
_tiersData2 = { selection: { enabled: true, active_slot: "brain", delegation_enforce: true, tdd_strict: true }, trinity: {} };
|
|
9157
9175
|
_wasCorrupted = true;
|
|
@@ -9227,7 +9245,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9227
9245
|
writeFileSync12(_tmp, JSON.stringify(_tiersData2, null, 2) + "\n", "utf-8");
|
|
9228
9246
|
renameSync6(_tmp, TIERS_FILE2);
|
|
9229
9247
|
console.error(`[vibeOS] auto-synced model-tiers.json: brain=${_brain.id} medium=${_tiersData2.trinity?.medium?.oc || ""} cheap=${_tiersData2.trinity?.cheap?.oc || ""}`);
|
|
9230
|
-
const _tiersCfg = safeJsonParse3(
|
|
9248
|
+
const _tiersCfg = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
9231
9249
|
const _b = _tiersCfg?.trinity?.brain?.oc;
|
|
9232
9250
|
const _m = _tiersCfg?.trinity?.medium?.oc;
|
|
9233
9251
|
const _c = _tiersCfg?.trinity?.cheap?.oc;
|
|
@@ -9244,7 +9262,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9244
9262
|
}
|
|
9245
9263
|
}
|
|
9246
9264
|
try {
|
|
9247
|
-
const _mt = safeJsonParse3(
|
|
9265
|
+
const _mt = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
9248
9266
|
if (_mt.selection && (_mt.selection.mcp_port === void 0 || _mt.selection.mcp_port === null)) {
|
|
9249
9267
|
_mt.selection.mcp_port = 9578;
|
|
9250
9268
|
const _tmp = TIERS_FILE2 + ".tmp." + Date.now();
|
|
@@ -9282,7 +9300,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9282
9300
|
}
|
|
9283
9301
|
const _tiersData = (() => {
|
|
9284
9302
|
try {
|
|
9285
|
-
return safeJsonParse3(
|
|
9303
|
+
return safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
|
|
9286
9304
|
} catch {
|
|
9287
9305
|
return {};
|
|
9288
9306
|
}
|
|
@@ -9305,7 +9323,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
9305
9323
|
latestUserIntent,
|
|
9306
9324
|
directory: directory3,
|
|
9307
9325
|
safeJsonParse: safeJsonParse3,
|
|
9308
|
-
readFileSync:
|
|
9326
|
+
readFileSync: readFileSync15,
|
|
9309
9327
|
writeFileSync: writeFileSync12,
|
|
9310
9328
|
existsSync: existsSync15,
|
|
9311
9329
|
renameSync: renameSync6,
|