vibeostheog 0.15.6 → 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.
Files changed (3) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +1 -1
  3. package/src/index.js +141 -122
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.15.8
2
+ - fix: load VIBEOS_API_TOKEN from .env.production if env var not set
3
+
4
+
5
+ ## 0.15.7
6
+ - fix: auto mode now actually applies optimization mode from API response
7
+
8
+
1
9
  ## 0.15.6
2
10
  - fix: auto mode cache with TTL 60s, preserve last mode on API failure
3
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.15.6",
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 readFileSync14, writeFileSync as writeFileSync12, existsSync as existsSync15, mkdirSync as mkdirSync10, copyFileSync as copyFileSync6, renameSync as renameSync6 } from "node:fs";
348
- import { join as join16, dirname as dirname8, basename as basename9 } from "node:path";
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 readFileSync5, 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 join6, dirname as dirname5, basename as basename5 } from "node:path";
3235
- import { homedir as homedir5, tmpdir as tmpdir4 } from "node:os";
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 VIBEOS_API_TOKEN = process.env.VIBEOS_API_TOKEN || "";
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 homedir5();
3765
+ return homedir6();
3748
3766
  } catch {
3749
3767
  return tmpdir4();
3750
3768
  }
3751
3769
  })();
3752
- var FILE_LOCK_DIR3 = join6(USER_HOME4, ".claude/.vibeOS-locks");
3753
- var BLACKBOX_STATE_FILE2 = join6(USER_HOME4, ".claude/blackbox-state.json");
3754
- var GLOBAL_LEARNING_FILE2 = join6(USER_HOME4, ".claude/global-learning.json");
3755
- var STATE_FILE3 = join6(USER_HOME4, ".claude/delegation-state.json");
3756
- var PROJECT_STATE_FILE2 = join6(USER_HOME4, ".claude/project-states.json");
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 = join6(USER_HOME4, ".claude", ".backups");
3789
+ const backupDir = join7(USER_HOME4, ".claude", ".backups");
3772
3790
  mkdirSync5(backupDir, { recursive: true });
3773
- const backupPath = join6(backupDir, basename5(path) + ".corrupted." + Date.now());
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 = join6(USER_HOME4, ".claude", ".state-corruption-log.jsonl");
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 join6(FILE_LOCK_DIR3, `${hash}.lock`);
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(readFileSync5(filePath, "utf-8"));
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 = join6(USER_HOME4, ".claude/model-tiers.json");
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(readFileSync5(p, "utf-8"));
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(readFileSync5(BLACKBOX_STATE_FILE2, "utf-8")) || { enabled: false, sessions: {} };
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(readFileSync5(GLOBAL_LEARNING_FILE2, "utf-8"));
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(readFileSync5(join6(dir, "package.json"), "utf-8"));
4111
+ const pkg = safeJsonParse3(readFileSync6(join7(dir, "package.json"), "utf-8"));
4094
4112
  if (pkg) {
4095
- if (pkg.devDependencies?.typescript || pkg.dependencies?.typescript || existsSync6(join6(dir, "tsconfig.json")))
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(join6(dir, "Cargo.toml")))
4122
+ if (existsSync6(join7(dir, "Cargo.toml")))
4105
4123
  stacks.push("rust");
4106
4124
  } catch {
4107
4125
  }
4108
4126
  try {
4109
- if (existsSync6(join6(dir, "go.mod")))
4127
+ if (existsSync6(join7(dir, "go.mod")))
4110
4128
  stacks.push("go");
4111
4129
  } catch {
4112
4130
  }
4113
4131
  try {
4114
- if (existsSync6(join6(dir, "requirements.txt")))
4132
+ if (existsSync6(join7(dir, "requirements.txt")))
4115
4133
  stacks.push("python");
4116
- if (existsSync6(join6(dir, "setup.py")))
4134
+ if (existsSync6(join7(dir, "setup.py")))
4117
4135
  stacks.push("python");
4118
- if (existsSync6(join6(dir, "pyproject.toml")))
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 readFileSync6, existsSync as existsSync7 } from "node:fs";
4227
- import { join as join7 } from "node:path";
4228
- import { homedir as homedir6, tmpdir as tmpdir5 } from "node:os";
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 homedir6();
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 = join7(USER_HOME5, ".claude/scratch");
4238
- var SCRATCHPAD_GLOBAL_DIR2 = join7(SCRATCHPAD_ROOT2, "by-hash");
4239
- var SCRATCHPAD_SESSIONS_DIR2 = join7(SCRATCHPAD_ROOT2, "sessions");
4240
- var STATE_FILE4 = join7(USER_HOME5, ".claude/delegation-state.json");
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 join7(SCRATCHPAD_SESSIONS_DIR2, _OC_SID3);
4261
+ return join8(SCRATCHPAD_SESSIONS_DIR2, _OC_SID3);
4244
4262
  }
4245
4263
  function getSessionScratchpadDir2() {
4246
- return join7(getSessionRoot2(), "by-hash");
4264
+ return join8(getSessionRoot2(), "by-hash");
4247
4265
  }
4248
4266
  function getGlobalIndexPath2() {
4249
- return join7(SCRATCHPAD_ROOT2, "index.jsonl");
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 = readFileSync6(indexPath, "utf-8").trim().split("\n").filter(Boolean);
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 = join7(getSessionScratchpadDir2(), hash + ".summary.txt");
4273
- const summaryPathGlobal = join7(SCRATCHPAD_GLOBAL_DIR2, hash + ".summary.txt");
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 = readFileSync6(summaryPath, "utf-8").slice(0, 200);
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(readFileSync6(STATE_FILE4, "utf-8"));
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 readFileSync7, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync6, statSync as statSync7, copyFileSync as copyFileSync5, rmSync as rmSync4 } from "node:fs";
4347
- import { join as join8, basename as basename6 } from "node:path";
4348
- import { homedir as homedir7, tmpdir as tmpdir6 } from "node:os";
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 homedir7();
4369
+ return homedir8();
4352
4370
  } catch {
4353
4371
  return tmpdir6();
4354
4372
  }
4355
4373
  })();
4356
- var REPORTS_DIR2 = join8(USER_HOME6, ".claude/reports");
4357
- var REPORTS_INDEX = join8(REPORTS_DIR2, "index.json");
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 = join8(USER_HOME6, ".claude", ".backups");
4380
+ const backupDir = join9(USER_HOME6, ".claude", ".backups");
4363
4381
  mkdirSync6(backupDir, { recursive: true });
4364
- const backupPath = join8(backupDir, basename6(path) + ".corrupted." + Date.now());
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(readFileSync7(filePath, "utf-8"));
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(join8(REPORTS_DIR2, `${r.id}.json`));
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(join8(REPORTS_DIR2, `${id2}.json`), JSON.stringify(report, null, 2) + "\n");
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 = join8(REPORTS_DIR2, `${id2}.json`);
4557
+ const path = join9(REPORTS_DIR2, `${id2}.json`);
4540
4558
  try {
4541
4559
  if (!existsSync8(path))
4542
4560
  return null;
4543
- return safeJsonParse3(readFileSync7(path, "utf-8"));
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 readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync9 } from "node:fs";
4551
- import { join as join9 } from "node:path";
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(readFileSync8(AUTH_F, "utf-8")) : {};
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(readFileSync8(CREDIT_CACHE_F, "utf-8"));
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 = join9(USER_HOME2, ".claude/model-tiers.json");
4648
+ const p = join10(USER_HOME2, ".claude/model-tiers.json");
4631
4649
  if (existsSync9(p)) {
4632
- const j = safeJsonParse4(readFileSync8(p, "utf-8"));
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 = join9(USER_HOME2, ".claude/credit-percent");
4681
+ const f = join10(USER_HOME2, ".claude/credit-percent");
4664
4682
  if (existsSync9(f)) {
4665
- const n = parseInt(readFileSync8(f, "utf-8").trim(), 10);
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 join10 } from "node:path";
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 = join10(deps.USER_HOME, ".claude/delegation-state.json");
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 = join10(deps.USER_HOME, ".config/opencode/opencode.json");
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 = join10(deps.REPORTS_DIR, `${r.id}.json`);
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 readFileSync9, existsSync as existsSync10 } from "node:fs";
5609
- import { join as join11 } from "node:path";
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 readFileSync11 } from "node:fs";
5813
- import { join as join14 } from "node:path";
5814
- import { homedir as homedir8, tmpdir as tmpdir7 } from "node:os";
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 readFileSync10, writeFileSync as writeFileSync9, existsSync as existsSync11, mkdirSync as mkdirSync7 } from "node:fs";
5818
- import { join as join13, basename as basename7 } from "node:path";
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 join12 } from "node:path";
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 = join12(sd, "delegation-state-hint.txt");
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 = join13(dir, ".opencode", "skills");
6304
+ const skillsDir = join14(dir, ".opencode", "skills");
6287
6305
  const projectName = basename7(dir);
6288
- const skillDir = join13(skillsDir, projectName);
6289
- const skillPath = join13(skillDir, "SKILL.md");
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 = join13(getSessionScratchpadDir(), `${hash}.txt`);
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(readFileSync10(TIERS_FILE2, "utf-8")).trinity?.brain?.oc || brainModel;
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(readFileSync10(TIERS_FILE2, "utf-8")).trinity || {};
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 homedir8();
6731
+ return homedir9();
6714
6732
  } catch {
6715
6733
  return tmpdir7();
6716
6734
  }
6717
6735
  })();
6718
- var STATE_FILE5 = join14(USER_HOME7, ".claude/delegation-state.json");
6719
- var SAVINGS_LEDGER_FILE2 = join14(USER_HOME7, ".claude/savings-ledger.jsonl");
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 = readFileSync11(join14(USER_HOME7, ".claude/model-tiers.json"), "utf-8");
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 = readFileSync11(STATE_FILE5, "utf-8");
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 {
@@ -6878,6 +6896,7 @@ async function _appendFooter(input, output, directory3) {
6878
6896
  const autoStress = scoreStress(latestUserIntent || "");
6879
6897
  const autoActive = await apiAutoSelectMode(autoRegime, autoStress);
6880
6898
  const autoTag = { audit: "AUDIT", budget: "BUDGET", quality: "QUALITY", speed: "SPEED", longrun: "LONGRUN", balanced: "BALANCED" };
6899
+ saveOptimizationMode(autoActive);
6881
6900
  optTagFooter = `[AUTO\u2192${autoTag[autoActive] || autoActive.toUpperCase()}]`;
6882
6901
  const slot2 = autoActive === "quality" ? "brain" : autoActive === "speed" ? "medium" : "cheap";
6883
6902
  if (!_modelLocked) {
@@ -6960,8 +6979,8 @@ import { dirname as dirname7, basename as basename8 } from "node:path";
6960
6979
  init_flow_enforcer();
6961
6980
 
6962
6981
  // src/lib/tdd-enforcer.js
6963
- import { readFileSync as readFileSync12, 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";
6964
- import { join as join15, dirname as dirname6 } from "node:path";
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";
6965
6984
  import { createHash as createHash5 } from "node:crypto";
6966
6985
 
6967
6986
  // src/utils/tdd-helpers.js
@@ -8000,9 +8019,9 @@ function _detectTestFramework() {
8000
8019
  let testExt = null;
8001
8020
  try {
8002
8021
  const root = directory || process.cwd();
8003
- const pkgPath = join15(root, "package.json");
8022
+ const pkgPath = join16(root, "package.json");
8004
8023
  if (existsSync12(pkgPath)) {
8005
- const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
8024
+ const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
8006
8025
  const testScript = String(pkg?.scripts?.test || "");
8007
8026
  const deps = { ...pkg?.devDependencies, ...pkg?.dependencies };
8008
8027
  if (testScript.includes("vitest") || deps["vitest"]) {
@@ -8022,12 +8041,12 @@ function _detectTestFramework() {
8022
8041
  if (!framework) {
8023
8042
  const testDirs = ["src/tests", "tests", "test", "__tests__"];
8024
8043
  for (const td of testDirs) {
8025
- const dirPath = join15(root, td);
8044
+ const dirPath = join16(root, td);
8026
8045
  if (!existsSync12(dirPath))
8027
8046
  continue;
8028
8047
  const files = readdirSync2(dirPath).filter((f) => /\.test\./.test(f) || /\.spec\./.test(f));
8029
8048
  if (files.length > 0) {
8030
- const content = readFileSync12(join15(dirPath, files[0]), "utf-8");
8049
+ const content = readFileSync13(join16(dirPath, files[0]), "utf-8");
8031
8050
  if (/from\s+['"]node:test['"]/.test(content)) {
8032
8051
  framework = "node-test";
8033
8052
  testExt = files[0].split(".").pop();
@@ -8053,16 +8072,16 @@ function _detectTestFramework() {
8053
8072
  console.error(`[vibeOS] [tdd] detected test framework: ${framework || "default"} (ext: ${testExt || "match source"})`);
8054
8073
  return _detectedFramework;
8055
8074
  }
8056
- var ENFORCEMENT_LOCK_DIR = join15(USER_HOME2, ".claude/.enforcement-lock");
8075
+ var ENFORCEMENT_LOCK_DIR = join16(USER_HOME2, ".claude/.enforcement-lock");
8057
8076
  var LOCK_EXPIRE_MS = 3e4;
8058
- var ENFORCEMENT_COOLDOWN_FILE2 = join15(USER_HOME2, ".claude/.enforcement-cooldown.jsonl");
8077
+ var ENFORCEMENT_COOLDOWN_FILE2 = join16(USER_HOME2, ".claude/.enforcement-cooldown.jsonl");
8059
8078
  var COOLDOWN_MS = 6e4;
8060
8079
  var _enforcementCooldown = /* @__PURE__ */ new Set();
8061
8080
  function _acquireLock(testPath) {
8062
8081
  try {
8063
8082
  mkdirSync8(ENFORCEMENT_LOCK_DIR, { recursive: true });
8064
8083
  const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
8065
- const lockPath = join15(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
8084
+ const lockPath = join16(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
8066
8085
  try {
8067
8086
  openSync4(lockPath, "wx");
8068
8087
  return true;
@@ -8090,7 +8109,7 @@ function _acquireLock(testPath) {
8090
8109
  function _releaseLock(testPath) {
8091
8110
  try {
8092
8111
  const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
8093
- const lockPath = join15(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
8112
+ const lockPath = join16(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
8094
8113
  rmSync5(lockPath);
8095
8114
  } catch {
8096
8115
  }
@@ -8100,7 +8119,7 @@ function _isInCooldown(testPath) {
8100
8119
  if (!existsSync12(ENFORCEMENT_COOLDOWN_FILE2))
8101
8120
  return false;
8102
8121
  const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
8103
- const lines = readFileSync12(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
8122
+ const lines = readFileSync13(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
8104
8123
  const now = Date.now();
8105
8124
  for (const line of lines) {
8106
8125
  try {
@@ -8121,7 +8140,7 @@ function _recordCooldown(testPath) {
8121
8140
  const hash = createHash5("sha256").update(testPath).digest("hex").slice(0, 16);
8122
8141
  const entry = JSON.stringify({ h: hash, ts: Date.now() }) + "\n";
8123
8142
  appendFileSync6(ENFORCEMENT_COOLDOWN_FILE2, entry);
8124
- const lines = readFileSync12(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
8143
+ const lines = readFileSync13(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
8125
8144
  if (lines.length > 500) {
8126
8145
  writeFileSync10(ENFORCEMENT_COOLDOWN_FILE2, lines.slice(-200).join("\n") + "\n");
8127
8146
  }
@@ -8192,7 +8211,7 @@ function enforceTestFile(filePath) {
8192
8211
  let sourceContent = "";
8193
8212
  try {
8194
8213
  if (existsSync12(filePath)) {
8195
- sourceContent = readFileSync12(filePath, "utf-8");
8214
+ sourceContent = readFileSync13(filePath, "utf-8");
8196
8215
  }
8197
8216
  } catch {
8198
8217
  }
@@ -8813,7 +8832,7 @@ ${pendingUiNote}`;
8813
8832
  };
8814
8833
 
8815
8834
  // src/lib/hooks/session-compact.js
8816
- import { readFileSync as readFileSync13, existsSync as existsSync14 } from "node:fs";
8835
+ import { readFileSync as readFileSync14, existsSync as existsSync14 } from "node:fs";
8817
8836
  var onSessionCompacting = async (_input, output) => {
8818
8837
  if (!loadSelection().enabled)
8819
8838
  return;
@@ -8822,7 +8841,7 @@ var onSessionCompacting = async (_input, output) => {
8822
8841
  let recent = "";
8823
8842
  if (existsSync14(indexPath)) {
8824
8843
  try {
8825
- const lines = readFileSync13(indexPath, "utf-8").trim().split("\n").slice(-30);
8844
+ const lines = readFileSync14(indexPath, "utf-8").trim().split("\n").slice(-30);
8826
8845
  recent = lines.map((l) => {
8827
8846
  try {
8828
8847
  return JSON.parse(l);
@@ -8876,17 +8895,17 @@ var _mcpServerRuntime = null;
8876
8895
  var _mcpServerHooked = false;
8877
8896
  function _loadOpenCodeProviders() {
8878
8897
  try {
8879
- const cfg = _readOpenCodeConfigObject(join16(USER_HOME2, ".config", "opencode"));
8898
+ const cfg = _readOpenCodeConfigObject(join17(USER_HOME2, ".config", "opencode"));
8880
8899
  return cfg?.provider || {};
8881
8900
  } catch {
8882
8901
  return {};
8883
8902
  }
8884
8903
  }
8885
8904
  function _readOpenCodeConfigObject(dir) {
8886
- const jsonPath = join16(dir, "opencode.json");
8887
- const jsoncPath = join16(dir, "opencode.jsonc");
8888
- if (existsSync15(jsonPath)) return safeJsonParse3(readFileSync14(jsonPath, "utf-8"));
8889
- if (existsSync15(jsoncPath)) return _parseJsonc(readFileSync14(jsoncPath, "utf-8"));
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"));
8890
8909
  return {};
8891
8910
  }
8892
8911
  function _parseJsonc(raw) {
@@ -8912,9 +8931,9 @@ function _modelTier2(id2) {
8912
8931
  function backupFile(path, label) {
8913
8932
  try {
8914
8933
  if (!existsSync15(path)) return null;
8915
- const bkDir = join16(USER_HOME2, ".claude", ".backups");
8934
+ const bkDir = join17(USER_HOME2, ".claude", ".backups");
8916
8935
  mkdirSync10(bkDir, { recursive: true });
8917
- const bk = join16(bkDir, `${basename9(path)}.${label}.${Date.now()}.bak`);
8936
+ const bk = join17(bkDir, `${basename9(path)}.${label}.${Date.now()}.bak`);
8918
8937
  copyFileSync6(path, bk);
8919
8938
  return bk;
8920
8939
  } catch {
@@ -8923,7 +8942,7 @@ function backupFile(path, label) {
8923
8942
  }
8924
8943
  function readPackageVersion() {
8925
8944
  try {
8926
- const pkg = safeJsonParse3(readFileSync14(join16(process.cwd(), "package.json"), "utf-8"));
8945
+ const pkg = safeJsonParse3(readFileSync15(join17(process.cwd(), "package.json"), "utf-8"));
8927
8946
  return String(pkg?.version || "");
8928
8947
  } catch {
8929
8948
  return "";
@@ -8938,7 +8957,7 @@ function loadMcpPort() {
8938
8957
  }
8939
8958
  try {
8940
8959
  if (existsSync15(TIERS_FILE2)) {
8941
- const tiers = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
8960
+ const tiers = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
8942
8961
  const cfg = tiers?.selection?.mcp_port ?? tiers?.mcp_port;
8943
8962
  if (cfg === false || cfg === "disabled" || cfg === 0) return 0;
8944
8963
  const n = Number(cfg);
@@ -8951,7 +8970,7 @@ function loadMcpPort() {
8951
8970
  function persistMcpPort(port) {
8952
8971
  try {
8953
8972
  if (!existsSync15(TIERS_FILE2)) return;
8954
- const tiers = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
8973
+ const tiers = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
8955
8974
  tiers.selection ??= {};
8956
8975
  if (Number(tiers.selection.mcp_port) === Number(port)) return;
8957
8976
  tiers.selection.mcp_port = port;
@@ -8966,7 +8985,7 @@ function computeStatusPayload() {
8966
8985
  const sel = loadSelection();
8967
8986
  let tiersData = {};
8968
8987
  try {
8969
- tiersData = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
8988
+ tiersData = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
8970
8989
  } catch {
8971
8990
  }
8972
8991
  const credit = loadCredit();
@@ -9119,13 +9138,13 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9119
9138
  setCurrentModel(readConfig(directory3));
9120
9139
  if (!currentModel) {
9121
9140
  const home = process.env.HOME || "";
9122
- if (home) setCurrentModel(readConfig(join16(home, ".config/opencode")));
9141
+ if (home) setCurrentModel(readConfig(join17(home, ".config/opencode")));
9123
9142
  }
9124
9143
  if (!currentModel) setCurrentModel(process?.env?.OPENCODE_MODEL || "");
9125
9144
  if (currentModel) {
9126
9145
  setCurrentTier(classify(currentModel));
9127
9146
  try {
9128
- const _tiersData2 = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
9147
+ const _tiersData2 = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
9129
9148
  const _activeSlot = _tiersData2?.selection?.active_slot || "brain";
9130
9149
  if (_activeSlot === "brain") {
9131
9150
  const _brainOcModel = _tiersData2?.trinity?.brain?.oc || "";
@@ -9150,7 +9169,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9150
9169
  let _wasCorrupted = false;
9151
9170
  if (existsSync15(TIERS_FILE2)) {
9152
9171
  try {
9153
- _tiersData2 = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
9172
+ _tiersData2 = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
9154
9173
  } catch {
9155
9174
  _tiersData2 = { selection: { enabled: true, active_slot: "brain", delegation_enforce: true, tdd_strict: true }, trinity: {} };
9156
9175
  _wasCorrupted = true;
@@ -9226,7 +9245,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9226
9245
  writeFileSync12(_tmp, JSON.stringify(_tiersData2, null, 2) + "\n", "utf-8");
9227
9246
  renameSync6(_tmp, TIERS_FILE2);
9228
9247
  console.error(`[vibeOS] auto-synced model-tiers.json: brain=${_brain.id} medium=${_tiersData2.trinity?.medium?.oc || ""} cheap=${_tiersData2.trinity?.cheap?.oc || ""}`);
9229
- const _tiersCfg = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
9248
+ const _tiersCfg = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
9230
9249
  const _b = _tiersCfg?.trinity?.brain?.oc;
9231
9250
  const _m = _tiersCfg?.trinity?.medium?.oc;
9232
9251
  const _c = _tiersCfg?.trinity?.cheap?.oc;
@@ -9243,7 +9262,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9243
9262
  }
9244
9263
  }
9245
9264
  try {
9246
- const _mt = safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
9265
+ const _mt = safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
9247
9266
  if (_mt.selection && (_mt.selection.mcp_port === void 0 || _mt.selection.mcp_port === null)) {
9248
9267
  _mt.selection.mcp_port = 9578;
9249
9268
  const _tmp = TIERS_FILE2 + ".tmp." + Date.now();
@@ -9281,7 +9300,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9281
9300
  }
9282
9301
  const _tiersData = (() => {
9283
9302
  try {
9284
- return safeJsonParse3(readFileSync14(TIERS_FILE2, "utf-8"));
9303
+ return safeJsonParse3(readFileSync15(TIERS_FILE2, "utf-8"));
9285
9304
  } catch {
9286
9305
  return {};
9287
9306
  }
@@ -9304,7 +9323,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
9304
9323
  latestUserIntent,
9305
9324
  directory: directory3,
9306
9325
  safeJsonParse: safeJsonParse3,
9307
- readFileSync: readFileSync14,
9326
+ readFileSync: readFileSync15,
9308
9327
  writeFileSync: writeFileSync12,
9309
9328
  existsSync: existsSync15,
9310
9329
  renameSync: renameSync6,