vibeostheog 0.25.8 → 0.25.9

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.
@@ -1,5 +1 @@
1
- <<<<<<< HEAD
2
- window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:53142";
3
- =======
4
1
  window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:60078";
5
- >>>>>>> fix/flash-icon
package/dist/vibeOS.js CHANGED
@@ -458,6 +458,7 @@ function getRuntimeState() {
458
458
  apiConnected: true,
459
459
  apiFallbackMode: false,
460
460
  apiFallbackSince: null,
461
+ apiEnabled: true,
461
462
  sessionId: "opencode-" + (process.pid || "x") + "-" + Date.now()
462
463
  };
463
464
  }
@@ -485,6 +486,33 @@ function resetApiConnection() {
485
486
  state.apiFallbackMode = false;
486
487
  state.apiFallbackSince = null;
487
488
  }
489
+ function isApiConnected() {
490
+ const state = getRuntimeState();
491
+ return state.apiEnabled;
492
+ }
493
+ function isApiFallbackMode() {
494
+ return getRuntimeState().apiFallbackMode;
495
+ }
496
+ function getApiFallbackSince() {
497
+ return getRuntimeState().apiFallbackSince;
498
+ }
499
+ function isApiEnabled() {
500
+ return getRuntimeState().apiEnabled;
501
+ }
502
+ function setApiEnabled(enabled) {
503
+ getRuntimeState().apiEnabled = enabled;
504
+ }
505
+ function setApiFallbackSince(since) {
506
+ getRuntimeState().apiFallbackSince = since;
507
+ }
508
+ function setApiFallbackMode(on) {
509
+ const state = getRuntimeState();
510
+ state.apiFallbackMode = on;
511
+ if (on && !state.apiFallbackSince)
512
+ state.apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
513
+ if (!on)
514
+ state.apiFallbackSince = null;
515
+ }
488
516
  var RUNTIME_KEY;
489
517
  var init_runtime_state = __esm({
490
518
  "src/lib/runtime-state.js"() {
@@ -494,7 +522,7 @@ var init_runtime_state = __esm({
494
522
  });
495
523
 
496
524
  // src/lib/selection-manager.js
497
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync4, statSync as statSync3, renameSync as renameSync2 } from "node:fs";
525
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, existsSync as existsSync4, statSync as statSync3, renameSync as renameSync2 } from "node:fs";
498
526
  import { join as join3 } from "node:path";
499
527
  import { homedir as homedir2, tmpdir } from "node:os";
500
528
  function getVibeOSHome2() {
@@ -563,7 +591,7 @@ function writeSelection(key, value) {
563
591
  j.selection = {};
564
592
  j.selection[key] = value;
565
593
  const tmp = TIERS_FILE3 + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
566
- writeFileSync3(tmp, JSON.stringify(j, null, 2) + "\n");
594
+ writeFileSync4(tmp, JSON.stringify(j, null, 2) + "\n");
567
595
  renameSync2(tmp, TIERS_FILE3);
568
596
  return true;
569
597
  });
@@ -593,7 +621,7 @@ function writeSessionSlot2(sid, slot) {
593
621
  j.sessions[sid] = {};
594
622
  j.sessions[sid].active_slot = slot;
595
623
  const tmp = BLACKBOX_FILE + ".tmp";
596
- writeFileSync3(tmp, JSON.stringify(j, null, 2) + "\n");
624
+ writeFileSync4(tmp, JSON.stringify(j, null, 2) + "\n");
597
625
  renameSync2(tmp, BLACKBOX_FILE);
598
626
  return true;
599
627
  } catch (err) {
@@ -633,7 +661,7 @@ function writeSessionOptMode2(sid, mode) {
633
661
  j.sessions[sid] = {};
634
662
  j.sessions[sid].optimization_mode = mode;
635
663
  const tmp = BLACKBOX_FILE + ".tmp";
636
- writeFileSync3(tmp, JSON.stringify(j, null, 2) + "\n");
664
+ writeFileSync4(tmp, JSON.stringify(j, null, 2) + "\n");
637
665
  renameSync2(tmp, BLACKBOX_FILE);
638
666
  return true;
639
667
  } catch (err) {
@@ -1391,7 +1419,7 @@ var init_smart_cache = __esm({
1391
1419
  });
1392
1420
 
1393
1421
  // src/lib/state.js
1394
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, appendFileSync as appendFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, statSync as statSync4, readdirSync, openSync, readSync, closeSync, rmSync as rmSync2, copyFileSync, renameSync as renameSync3 } from "node:fs";
1422
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync5, appendFileSync as appendFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync4, statSync as statSync4, readdirSync, openSync, readSync, closeSync, rmSync as rmSync2, copyFileSync, renameSync as renameSync3 } from "node:fs";
1395
1423
  import { join as join4, dirname as dirname4, basename as basename2 } from "node:path";
1396
1424
  import { spawn } from "node:child_process";
1397
1425
  import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
@@ -1495,14 +1523,14 @@ function runStartupMaintenanceOnce() {
1495
1523
  function _ensureVibeOSHomeDir() {
1496
1524
  try {
1497
1525
  if (!existsSync5(VIBEOS_HOME)) {
1498
- mkdirSync3(VIBEOS_HOME, { recursive: true });
1526
+ mkdirSync4(VIBEOS_HOME, { recursive: true });
1499
1527
  return VIBEOS_HOME;
1500
1528
  }
1501
1529
  const st = statSync4(VIBEOS_HOME);
1502
1530
  if (!st.isDirectory()) {
1503
1531
  const backup = VIBEOS_HOME + ".backup." + Date.now();
1504
1532
  renameSync3(VIBEOS_HOME, backup);
1505
- mkdirSync3(VIBEOS_HOME, { recursive: true });
1533
+ mkdirSync4(VIBEOS_HOME, { recursive: true });
1506
1534
  }
1507
1535
  return VIBEOS_HOME;
1508
1536
  } catch {
@@ -1513,7 +1541,7 @@ function _handleStateCorruption2(path) {
1513
1541
  _ensureVibeOSHomeDir();
1514
1542
  const backupDir = join4(VIBEOS_HOME, ".backups");
1515
1543
  try {
1516
- mkdirSync3(backupDir, { recursive: true });
1544
+ mkdirSync4(backupDir, { recursive: true });
1517
1545
  } catch {
1518
1546
  }
1519
1547
  const backupPath = join4(backupDir, basename2(path) + ".corrupted." + Date.now());
@@ -1540,10 +1568,10 @@ function withFileLock(filePath, fn, opts = {}) {
1540
1568
  const start = Date.now();
1541
1569
  while (Date.now() - start < timeoutMs) {
1542
1570
  try {
1543
- mkdirSync3(FILE_LOCK_DIR, { recursive: true });
1571
+ mkdirSync4(FILE_LOCK_DIR, { recursive: true });
1544
1572
  const fd = openSync(lockPath, "wx");
1545
1573
  try {
1546
- writeFileSync4(fd, `${process.pid}
1574
+ writeFileSync5(fd, `${process.pid}
1547
1575
  ${Date.now()}
1548
1576
  `);
1549
1577
  } catch {
@@ -1648,9 +1676,9 @@ function updateState(mutator) {
1648
1676
  state._gen = preGen + 1;
1649
1677
  const next = mutator(state) ?? state;
1650
1678
  validateState(next, delegationStateFile);
1651
- mkdirSync3(dirname4(delegationStateFile), { recursive: true });
1679
+ mkdirSync4(dirname4(delegationStateFile), { recursive: true });
1652
1680
  const tmp = delegationStateFile + ".tmp";
1653
- writeFileSync4(tmp, JSON.stringify(next, null, 2) + "\n");
1681
+ writeFileSync5(tmp, JSON.stringify(next, null, 2) + "\n");
1654
1682
  renameSync3(tmp, delegationStateFile);
1655
1683
  invalidateSavingsCache();
1656
1684
  return next;
@@ -1739,9 +1767,9 @@ function updateGlobalLearning(mutator) {
1739
1767
  const s = loadGlobalLearning();
1740
1768
  const next = mutator(s) ?? s;
1741
1769
  next.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1742
- mkdirSync3(dirname4(globalLearningFile), { recursive: true });
1770
+ mkdirSync4(dirname4(globalLearningFile), { recursive: true });
1743
1771
  const tmp = globalLearningFile + ".tmp";
1744
- writeFileSync4(tmp, JSON.stringify(next, null, 2));
1772
+ writeFileSync5(tmp, JSON.stringify(next, null, 2));
1745
1773
  renameSync3(tmp, globalLearningFile);
1746
1774
  return next;
1747
1775
  });
@@ -1829,9 +1857,9 @@ function saveBlackboxState(state) {
1829
1857
  continue;
1830
1858
  next.sessions[sid] = normalizeBlackboxRecord(session, sid, now).record;
1831
1859
  }
1832
- mkdirSync3(dirname4(blackboxFile), { recursive: true });
1860
+ mkdirSync4(dirname4(blackboxFile), { recursive: true });
1833
1861
  const tmp = blackboxFile + ".tmp";
1834
- writeFileSync4(tmp, JSON.stringify(next, null, 2) + "\n");
1862
+ writeFileSync5(tmp, JSON.stringify(next, null, 2) + "\n");
1835
1863
  renameSync3(tmp, blackboxFile);
1836
1864
  } catch (err) {
1837
1865
  console.error(`[vibeOS] saveBlackboxState failed: ${err.message}`);
@@ -1926,7 +1954,7 @@ function getGlobalIndexPath() {
1926
1954
  }
1927
1955
  function ensureSessionScratchpadDirs() {
1928
1956
  try {
1929
- mkdirSync3(getSessionScratchpadDir(), { recursive: true });
1957
+ mkdirSync4(getSessionScratchpadDir(), { recursive: true });
1930
1958
  return true;
1931
1959
  } catch {
1932
1960
  return false;
@@ -2118,8 +2146,8 @@ function indexAppend(hash, tool2, size, extra) {
2118
2146
  const entry = JSON.stringify(entryObj) + "\n";
2119
2147
  const globalIndex = getGlobalIndexPath();
2120
2148
  const sessionIndex = getSessionIndexPath();
2121
- mkdirSync3(dirname4(globalIndex), { recursive: true });
2122
- mkdirSync3(dirname4(sessionIndex), { recursive: true });
2149
+ mkdirSync4(dirname4(globalIndex), { recursive: true });
2150
+ mkdirSync4(dirname4(sessionIndex), { recursive: true });
2123
2151
  appendFileSync2(globalIndex, entry);
2124
2152
  appendFileSync2(sessionIndex, entry);
2125
2153
  } catch (err) {
@@ -2291,13 +2319,13 @@ function _pruneScratchpadDir(targetDir, opts = {}) {
2291
2319
  if (!existsSync5(summaryPath))
2292
2320
  try {
2293
2321
  const content = readFileSync4(fullPath, "utf-8");
2294
- writeFileSync4(summaryPath, content.slice(0, 200).replace(/\n+/g, " ").trim() + (content.length > 200 ? "\u2026" : ""));
2322
+ writeFileSync5(summaryPath, content.slice(0, 200).replace(/\n+/g, " ").trim() + (content.length > 200 ? "\u2026" : ""));
2295
2323
  } catch {
2296
2324
  }
2297
2325
  const head = _readHead(fullPath);
2298
2326
  if (!head.includes("[cold-storage]"))
2299
2327
  try {
2300
- writeFileSync4(fullPath, `[cold-storage] ${st.size}B original \u2192 ${hash}.summary.txt`);
2328
+ writeFileSync5(fullPath, `[cold-storage] ${st.size}B original \u2192 ${hash}.summary.txt`);
2301
2329
  rotated++;
2302
2330
  } catch {
2303
2331
  }
@@ -2308,13 +2336,13 @@ function _pruneScratchpadDir(targetDir, opts = {}) {
2308
2336
  if (!existsSync5(summaryPath))
2309
2337
  try {
2310
2338
  const content = readFileSync4(fullPath, "utf-8");
2311
- writeFileSync4(summaryPath, content.slice(0, SUMMARY_HEAD_TRUNCATE).replace(/\n+/g, " ").trim() + (content.length > SUMMARY_HEAD_TRUNCATE ? "\u2026" : ""));
2339
+ writeFileSync5(summaryPath, content.slice(0, SUMMARY_HEAD_TRUNCATE).replace(/\n+/g, " ").trim() + (content.length > SUMMARY_HEAD_TRUNCATE ? "\u2026" : ""));
2312
2340
  } catch {
2313
2341
  }
2314
2342
  const head = _readHead(fullPath);
2315
2343
  if (!head.includes("[warm-storage]") && !head.includes("[cold-storage]"))
2316
2344
  try {
2317
- writeFileSync4(fullPath, `[warm-storage] ${st.size}B original at ${hash}.summary.txt`);
2345
+ writeFileSync5(fullPath, `[warm-storage] ${st.size}B original at ${hash}.summary.txt`);
2318
2346
  rotated++;
2319
2347
  } catch {
2320
2348
  }
@@ -2386,9 +2414,9 @@ function _readActiveJobsRaw() {
2386
2414
  }
2387
2415
  function _writeActiveJobsRaw(jobs) {
2388
2416
  try {
2389
- mkdirSync3(dirname4(ACTIVE_JOBS_FILE), { recursive: true });
2417
+ mkdirSync4(dirname4(ACTIVE_JOBS_FILE), { recursive: true });
2390
2418
  const tmp = ACTIVE_JOBS_FILE + ".tmp";
2391
- writeFileSync4(tmp, JSON.stringify(jobs, null, 2) + "\n");
2419
+ writeFileSync5(tmp, JSON.stringify(jobs, null, 2) + "\n");
2392
2420
  renameSync3(tmp, ACTIVE_JOBS_FILE);
2393
2421
  } catch {
2394
2422
  }
@@ -2496,9 +2524,9 @@ function saveProjectState(state) {
2496
2524
  const projectStateFile = join4(getVibeOSHome3(), "project-states.json");
2497
2525
  try {
2498
2526
  withFileLock(projectStateFile, () => {
2499
- mkdirSync3(dirname4(projectStateFile), { recursive: true });
2527
+ mkdirSync4(dirname4(projectStateFile), { recursive: true });
2500
2528
  const _tmp = projectStateFile + ".tmp." + Date.now();
2501
- writeFileSync4(_tmp, JSON.stringify(state, null, 2) + "\n", "utf-8");
2529
+ writeFileSync5(_tmp, JSON.stringify(state, null, 2) + "\n", "utf-8");
2502
2530
  renameSync3(_tmp, projectStateFile);
2503
2531
  });
2504
2532
  } catch (err) {
@@ -2789,9 +2817,9 @@ function loadTodos() {
2789
2817
  }
2790
2818
  function saveTodos(todos) {
2791
2819
  try {
2792
- mkdirSync3(dirname4(TODOS_FILE), { recursive: true });
2820
+ mkdirSync4(dirname4(TODOS_FILE), { recursive: true });
2793
2821
  const tmp = TODOS_FILE + ".tmp." + Date.now();
2794
- writeFileSync4(tmp, JSON.stringify(todos, null, 2), "utf-8");
2822
+ writeFileSync5(tmp, JSON.stringify(todos, null, 2), "utf-8");
2795
2823
  renameSync3(tmp, TODOS_FILE);
2796
2824
  } catch {
2797
2825
  }
@@ -2872,7 +2900,7 @@ function _compactSavingsLedgerIfNeeded() {
2872
2900
  const compacted = kept.reverse().join("\n") + "\n";
2873
2901
  if (compacted.trim() && compacted !== raw) {
2874
2902
  const tmp = SAVINGS_LEDGER_FILE + ".tmp." + Date.now();
2875
- writeFileSync4(tmp, compacted, "utf-8");
2903
+ writeFileSync5(tmp, compacted, "utf-8");
2876
2904
  renameSync3(tmp, SAVINGS_LEDGER_FILE);
2877
2905
  }
2878
2906
  }, { timeoutMs: 4e3 });
@@ -3070,9 +3098,9 @@ function saveSessionCheckpoint() {
3070
3098
  model: session.model || ""
3071
3099
  };
3072
3100
  const cpPath = join4(getSessionRoot(), "checkpoint.json");
3073
- mkdirSync3(dirname4(cpPath), { recursive: true });
3101
+ mkdirSync4(dirname4(cpPath), { recursive: true });
3074
3102
  const tmp = cpPath + ".tmp";
3075
- writeFileSync4(tmp, JSON.stringify(cp, null, 2) + "\n");
3103
+ writeFileSync5(tmp, JSON.stringify(cp, null, 2) + "\n");
3076
3104
  renameSync3(tmp, cpPath);
3077
3105
  } catch {
3078
3106
  }
@@ -3426,7 +3454,7 @@ var init_meta_controller = __esm({
3426
3454
  });
3427
3455
 
3428
3456
  // src/vibeOS-lib/blackbox/pivot-cache.js
3429
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
3457
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "node:fs";
3430
3458
  import { join as join6, dirname as dirname6 } from "node:path";
3431
3459
  import { homedir as homedir5 } from "node:os";
3432
3460
  var PivotCache;
@@ -3464,8 +3492,8 @@ var init_pivot_cache = __esm({
3464
3492
  const p = this._storePath();
3465
3493
  const dir = dirname6(p);
3466
3494
  if (!existsSync7(dir))
3467
- mkdirSync5(dir, { recursive: true });
3468
- writeFileSync6(p, JSON.stringify(this.store, null, 2), "utf-8");
3495
+ mkdirSync6(dir, { recursive: true });
3496
+ writeFileSync7(p, JSON.stringify(this.store, null, 2), "utf-8");
3469
3497
  } catch {
3470
3498
  }
3471
3499
  }
@@ -3635,7 +3663,7 @@ __export(vibemax_exports, {
3635
3663
  vibemaxPipeline: () => vibemaxPipeline,
3636
3664
  vibemaxSelectMode: () => vibemaxSelectMode
3637
3665
  });
3638
- import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
3666
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync8 } from "node:fs";
3639
3667
  import { resolve as resolve2, dirname as dirname7 } from "node:path";
3640
3668
  import { fileURLToPath as fileURLToPath4 } from "node:url";
3641
3669
  function fallback(sr, text) {
@@ -3917,8 +3945,8 @@ function loadVibeMaXModel() {
3917
3945
  return null;
3918
3946
  }
3919
3947
  function saveVibeMaXModel(model) {
3920
- mkdirSync6(dirname7(MODEL_PATH), { recursive: true });
3921
- writeFileSync7(MODEL_PATH, JSON.stringify(model, null, 2) + "\n", "utf-8");
3948
+ mkdirSync7(dirname7(MODEL_PATH), { recursive: true });
3949
+ writeFileSync8(MODEL_PATH, JSON.stringify(model, null, 2) + "\n", "utf-8");
3922
3950
  }
3923
3951
  function getVibeMaXModelMeta() {
3924
3952
  const m = loadVibeMaXModel();
@@ -4086,7 +4114,7 @@ var init_vibeultrax = __esm({
4086
4114
 
4087
4115
  // src/index.ts
4088
4116
  init_flow_enforcer();
4089
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync15, existsSync as existsSync18, mkdirSync as mkdirSync13, copyFileSync as copyFileSync2, renameSync as renameSync6, statSync as statSync9 } from "node:fs";
4117
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync16, existsSync as existsSync18, mkdirSync as mkdirSync14, copyFileSync as copyFileSync2, renameSync as renameSync6, statSync as statSync9 } from "node:fs";
4090
4118
  import { join as join18, dirname as dirname13, basename as basename5 } from "node:path";
4091
4119
 
4092
4120
  // src/vibeOS-lib/session-metrics.js
@@ -4232,7 +4260,7 @@ function computeSessionMetrics(state, sessionId) {
4232
4260
  // src/lib/vibeos-mcp-server.js
4233
4261
  import http from "node:http";
4234
4262
  import { parse as parseUrl } from "node:url";
4235
- import { createReadStream, existsSync as existsSync2, statSync as statSync2 } from "node:fs";
4263
+ import { createReadStream, existsSync as existsSync2, mkdirSync as mkdirSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
4236
4264
  import { extname, join as join2, dirname as dirname2 } from "node:path";
4237
4265
  import { fileURLToPath as fileURLToPath2 } from "node:url";
4238
4266
  var MIME_MAP = {
@@ -4278,7 +4306,9 @@ var _MCP_FILENAME = fileURLToPath2(import.meta.url);
4278
4306
  var _MCP_DIR = dirname2(_MCP_FILENAME);
4279
4307
  function resolveDashboardDir() {
4280
4308
  const c = [
4281
- join2(_MCP_DIR, "dashboard", "dist")
4309
+ join2(_MCP_DIR, "dashboard", "dist"),
4310
+ join2(_MCP_DIR, "assets", "dashboard"),
4311
+ join2(_MCP_DIR, "assets", "dashboard", "dist")
4282
4312
  ];
4283
4313
  for (const p of c) {
4284
4314
  if (existsSync2(join2(p, "index.html")))
@@ -4287,6 +4317,20 @@ function resolveDashboardDir() {
4287
4317
  return c[0];
4288
4318
  }
4289
4319
  var DASHBOARD_DIR = resolveDashboardDir();
4320
+ var DASHBOARD_CONFIG_PATH = join2(DASHBOARD_DIR, "vibeos-dashboard-config.js");
4321
+ function writeDashboardBaseConfig(baseUrl) {
4322
+ try {
4323
+ if (!baseUrl)
4324
+ return null;
4325
+ mkdirSync2(DASHBOARD_DIR, { recursive: true });
4326
+ const payload = `window.__VIBEOS_DASHBOARD_BASE__ = ${JSON.stringify(baseUrl.replace(/\/$/, ""))};
4327
+ `;
4328
+ writeFileSync2(DASHBOARD_CONFIG_PATH, payload, "utf-8");
4329
+ return DASHBOARD_CONFIG_PATH;
4330
+ } catch {
4331
+ return null;
4332
+ }
4333
+ }
4290
4334
  function resolveBackendHealthUrl() {
4291
4335
  const explicit = process.env.VIBEOS_BACKEND_HEALTH_URL?.trim();
4292
4336
  if (explicit)
@@ -4613,7 +4657,7 @@ function createMcpServer(deps) {
4613
4657
 
4614
4658
  // src/lib/api-client.js
4615
4659
  init_runtime_state();
4616
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, rmSync } from "node:fs";
4660
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync3, rmSync } from "node:fs";
4617
4661
  import { dirname as dirname3 } from "node:path";
4618
4662
  import { fileURLToPath as fileURLToPath3 } from "node:url";
4619
4663
  import { homedir } from "node:os";
@@ -4621,9 +4665,11 @@ var DEFAULT_API_URL = "https://api.vibetheog.com";
4621
4665
  var EMBEDDED_API_TOKEN = "vos_8d73804b13bb46711b9a47f036dba7b4d026fd9583d96960e663716e62815a69";
4622
4666
  var API_TOKEN_RE = /^vos_[a-f0-9]{64}$/i;
4623
4667
  var API_DISABLED_RE = /^(1|true|yes|on)$/i;
4624
- var REQUEST_TIMEOUT = 1e4;
4625
- var MAX_RETRIES = 3;
4626
- var BASE_RETRY_DELAY = 1e3;
4668
+ var IS_TEST_RUNTIME = process.env.VIBEOS_TEST_MODE === "1" || process.env.NODE_ENV === "test" || process.env.CI === "true";
4669
+ var REQUEST_TIMEOUT = IS_TEST_RUNTIME ? 2e3 : 1e4;
4670
+ var MAX_RETRIES = IS_TEST_RUNTIME ? 1 : 3;
4671
+ var BASE_RETRY_DELAY = IS_TEST_RUNTIME ? 100 : 1e3;
4672
+ var PROBE_TIMEOUT = IS_TEST_RUNTIME ? 2e3 : 5e3;
4627
4673
  var ALPHA_BUILD_CHANNEL = String(process.env.VIBEOS_BUILD_CHANNEL || "alpha").toLowerCase();
4628
4674
  var BOOTSTRAP_EXCHANGE_PATH = "/api/v1/auth/bootstrap/exchange";
4629
4675
  var BOOTSTRAP_RETRY_COOLDOWN_MS = 6e4;
@@ -4759,8 +4805,8 @@ function persistPrimaryApiEnvState(next) {
4759
4805
  }
4760
4806
  const parentDir = _envPaths[0];
4761
4807
  if (!existsSync3(parentDir))
4762
- mkdirSync2(parentDir, { recursive: true });
4763
- writeFileSync2(primaryPath, envContent.endsWith("\n") ? envContent : envContent + "\n", "utf8");
4808
+ mkdirSync3(parentDir, { recursive: true });
4809
+ writeFileSync3(primaryPath, envContent.endsWith("\n") ? envContent : envContent + "\n", "utf8");
4764
4810
  } catch (diskErr) {
4765
4811
  console.error("[vibeOS] Failed to persist API env state:", diskErr.message);
4766
4812
  }
@@ -5089,16 +5135,6 @@ function readTokenFromDisk() {
5089
5135
  }
5090
5136
  return "";
5091
5137
  }
5092
- function hasPrimaryTokenOnDisk() {
5093
- if (readApiDisabledFromDisk())
5094
- return false;
5095
- try {
5096
- const env = readFileSync2(_envPaths[0] + "/.env.production", "utf8");
5097
- return /^VIBEOS_API_TOKEN=/m.test(env);
5098
- } catch {
5099
- return false;
5100
- }
5101
- }
5102
5138
  function readBootstrapTokenFromDisk() {
5103
5139
  if (readApiDisabledFromDisk())
5104
5140
  return "";
@@ -5112,9 +5148,9 @@ function readBootstrapTokenFromDisk() {
5112
5148
  return "";
5113
5149
  }
5114
5150
  var VIBEOS_API_DISABLED = readApiDisabledFromDisk() || isTruthyFlag(process.env.VIBEOS_API_DISABLED);
5115
- var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN) || (!hasPrimaryTokenOnDisk() ? EMBEDDED_API_TOKEN : "");
5151
+ var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN);
5116
5152
  var VIBEOS_API_BOOTSTRAP_TOKEN = VIBEOS_API_DISABLED ? "" : readBootstrapTokenFromDisk() || process.env.VIBEOS_API_BOOTSTRAP_TOKEN || EMBEDDED_API_TOKEN;
5117
- var VIBEOS_API_ENABLED = !VIBEOS_API_DISABLED && process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5153
+ setApiEnabled(!VIBEOS_API_DISABLED && process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5118
5154
  var _anomalyDetector = null;
5119
5155
  function getAnomalyDetector() {
5120
5156
  if (!_anomalyDetector)
@@ -5134,8 +5170,8 @@ function persistBootstrapToken(token) {
5134
5170
  }
5135
5171
  const parentDir = _envPaths[0];
5136
5172
  if (!existsSync3(parentDir))
5137
- mkdirSync2(parentDir, { recursive: true });
5138
- writeFileSync2(_bootstrapEnvPath, `VIBEOS_API_BOOTSTRAP_TOKEN=${clean}
5173
+ mkdirSync3(parentDir, { recursive: true });
5174
+ writeFileSync3(_bootstrapEnvPath, `VIBEOS_API_BOOTSTRAP_TOKEN=${clean}
5139
5175
  `, "utf8");
5140
5176
  } catch (diskErr) {
5141
5177
  console.error("[vibeOS] Failed to persist alpha bootstrap token:", diskErr.message);
@@ -5146,10 +5182,10 @@ function setApiToken(newToken) {
5146
5182
  VIBEOS_API_DISABLED = false;
5147
5183
  VIBEOS_API_TOKEN = normalizeDirectApiToken(newToken);
5148
5184
  VIBEOS_API_BOOTSTRAP_TOKEN = readBootstrapTokenFromDisk() || VIBEOS_API_BOOTSTRAP_TOKEN;
5149
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5185
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5150
5186
  _apiClient = null;
5151
- _apiFallbackMode = false;
5152
- _apiFallbackSince = null;
5187
+ setApiFallbackMode(false);
5188
+ setApiFallbackSince(null);
5153
5189
  persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
5154
5190
  if (_anomalyDetector)
5155
5191
  _anomalyDetector.reset();
@@ -5164,10 +5200,10 @@ function invalidateApiToken() {
5164
5200
  VIBEOS_API_DISABLED = true;
5165
5201
  VIBEOS_API_TOKEN = "";
5166
5202
  VIBEOS_API_BOOTSTRAP_TOKEN = "";
5167
- VIBEOS_API_ENABLED = false;
5203
+ setApiEnabled(false);
5168
5204
  _apiClient = null;
5169
- _apiFallbackMode = false;
5170
- _apiFallbackSince = null;
5205
+ setApiFallbackMode(false);
5206
+ setApiFallbackSince(null);
5171
5207
  if (_anomalyDetector)
5172
5208
  _anomalyDetector.reset();
5173
5209
  persistBootstrapToken("");
@@ -5182,7 +5218,7 @@ function setApiBootstrapToken(newToken) {
5182
5218
  try {
5183
5219
  VIBEOS_API_DISABLED = false;
5184
5220
  VIBEOS_API_BOOTSTRAP_TOKEN = String(newToken || "").trim();
5185
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5221
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5186
5222
  persistPrimaryApiEnvState({ disabled: false });
5187
5223
  persistBootstrapToken(VIBEOS_API_BOOTSTRAP_TOKEN);
5188
5224
  console.error("[vibeOS] Alpha bootstrap token updated");
@@ -5191,24 +5227,27 @@ function setApiBootstrapToken(newToken) {
5191
5227
  }
5192
5228
  }
5193
5229
  var _apiClient = null;
5194
- var _apiFallbackMode = false;
5195
- var _apiFallbackSince = null;
5230
+ var _startupProbeDone = false;
5196
5231
  var _bootstrapExchangeInFlight = null;
5197
5232
  var _bootstrapExchangeFailedAt = 0;
5198
5233
  var _backendVersion = "";
5199
5234
  var FALLBACK_COOLDOWN_MS = 6e4;
5200
5235
  function tryResetFallbackCooldown() {
5201
- if (!_apiFallbackMode || !_apiFallbackSince)
5236
+ if (!isApiFallbackMode() || !getApiFallbackSince())
5202
5237
  return false;
5203
- const elapsed = Date.now() - new Date(_apiFallbackSince).getTime();
5238
+ const elapsed = Date.now() - new Date(getApiFallbackSince()).getTime();
5204
5239
  if (elapsed > FALLBACK_COOLDOWN_MS) {
5205
- _apiFallbackMode = false;
5206
- _apiFallbackSince = null;
5240
+ setApiFallbackMode(false);
5241
+ setApiFallbackSince(null);
5207
5242
  markApiConnected();
5208
5243
  return true;
5209
5244
  }
5210
5245
  return false;
5211
5246
  }
5247
+ function denyReconnection(detail) {
5248
+ setApiFallbackSince((/* @__PURE__ */ new Date()).toISOString());
5249
+ console.warn(`[vibeOS] API health probe failed during reconnect: ${detail} \u2014 staying in fallback`);
5250
+ }
5212
5251
  function recordBackendVersion(payload) {
5213
5252
  if (!payload || typeof payload !== "object")
5214
5253
  return;
@@ -5235,7 +5274,7 @@ async function ensureBootstrapExchange() {
5235
5274
  try {
5236
5275
  const client2 = new VibeOSApiClient({
5237
5276
  baseUrl: VIBEOS_API_URL,
5238
- timeout: 5e3
5277
+ timeout: PROBE_TIMEOUT
5239
5278
  });
5240
5279
  const apiToken = await client2.exchangeBootstrapToken(VIBEOS_API_BOOTSTRAP_TOKEN, ALPHA_BUILD_CHANNEL);
5241
5280
  if (!apiToken)
@@ -5259,14 +5298,14 @@ function syncApiTokenFromDisk() {
5259
5298
  const diskBootstrapToken = readBootstrapTokenFromDisk() || "";
5260
5299
  const envToken = normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN);
5261
5300
  if (diskDisabled) {
5262
- if (!VIBEOS_API_DISABLED || VIBEOS_API_TOKEN || VIBEOS_API_BOOTSTRAP_TOKEN || VIBEOS_API_ENABLED) {
5301
+ if (!VIBEOS_API_DISABLED || VIBEOS_API_TOKEN || VIBEOS_API_BOOTSTRAP_TOKEN || isApiEnabled()) {
5263
5302
  VIBEOS_API_DISABLED = true;
5264
5303
  VIBEOS_API_TOKEN = "";
5265
5304
  VIBEOS_API_BOOTSTRAP_TOKEN = "";
5266
- VIBEOS_API_ENABLED = false;
5305
+ setApiEnabled(false);
5267
5306
  _apiClient = null;
5268
- _apiFallbackMode = false;
5269
- _apiFallbackSince = null;
5307
+ setApiFallbackMode(false);
5308
+ setApiFallbackSince(null);
5270
5309
  resetApiConnection();
5271
5310
  console.error("[vibeOS] API token disabled from disk (alpha kill switch active)");
5272
5311
  }
@@ -5275,69 +5314,107 @@ function syncApiTokenFromDisk() {
5275
5314
  if (diskToken && diskToken !== VIBEOS_API_TOKEN) {
5276
5315
  VIBEOS_API_DISABLED = false;
5277
5316
  VIBEOS_API_TOKEN = diskToken;
5278
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5317
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5279
5318
  _apiClient = null;
5280
- _apiFallbackMode = false;
5281
- _apiFallbackSince = null;
5319
+ setApiFallbackMode(false);
5320
+ setApiFallbackSince(null);
5282
5321
  resetApiConnection();
5283
5322
  console.error("[vibeOS] API token synced from disk (disk is newer)");
5284
5323
  } else if (diskBootstrapToken && diskBootstrapToken !== VIBEOS_API_BOOTSTRAP_TOKEN) {
5285
5324
  VIBEOS_API_DISABLED = false;
5286
5325
  VIBEOS_API_BOOTSTRAP_TOKEN = diskBootstrapToken;
5287
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5288
- _apiFallbackMode = false;
5289
- _apiFallbackSince = null;
5326
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5327
+ setApiFallbackMode(false);
5328
+ setApiFallbackSince(null);
5290
5329
  resetApiConnection();
5291
5330
  console.error("[vibeOS] Alpha bootstrap token synced from disk (disk is newer)");
5292
5331
  } else if (!diskToken && VIBEOS_API_TOKEN) {
5293
5332
  persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
5294
5333
  console.error("[vibeOS] API token persisted to disk from memory (disk was empty)");
5295
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && !!VIBEOS_API_TOKEN;
5334
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && !!VIBEOS_API_TOKEN);
5296
5335
  } else if (envToken && !diskToken && !VIBEOS_API_TOKEN) {
5297
5336
  VIBEOS_API_DISABLED = false;
5298
5337
  VIBEOS_API_TOKEN = envToken;
5299
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5338
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5300
5339
  console.error("[vibeOS] API token loaded from VIBEOS_API_TOKEN env var");
5301
5340
  } else {
5302
5341
  VIBEOS_API_DISABLED = false;
5303
- if (!VIBEOS_API_TOKEN && !hasPrimaryTokenOnDisk()) {
5304
- VIBEOS_API_TOKEN = EMBEDDED_API_TOKEN;
5305
- }
5306
5342
  VIBEOS_API_BOOTSTRAP_TOKEN ||= EMBEDDED_API_TOKEN;
5307
- VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5343
+ setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5308
5344
  }
5309
5345
  }
5310
5346
  function getApiClient2() {
5311
5347
  syncApiTokenFromDisk();
5312
- if (!_apiClient && VIBEOS_API_ENABLED && VIBEOS_API_TOKEN) {
5348
+ if (!_apiClient && isApiEnabled() && VIBEOS_API_TOKEN) {
5313
5349
  _apiClient = new VibeOSApiClient({
5314
5350
  baseUrl: VIBEOS_API_URL,
5315
5351
  apiToken: VIBEOS_API_TOKEN,
5316
- timeout: 5e3
5352
+ timeout: PROBE_TIMEOUT
5317
5353
  });
5318
5354
  }
5319
5355
  return _apiClient;
5320
5356
  }
5321
5357
  function isApiFallback2() {
5322
- return _apiFallbackMode || !VIBEOS_API_ENABLED;
5358
+ return isApiFallbackMode() || !isApiEnabled();
5323
5359
  }
5324
- function isApiConnected() {
5360
+ function isApiConnected2() {
5325
5361
  tryResetFallbackCooldown();
5326
- return VIBEOS_API_ENABLED;
5362
+ return isApiConnected();
5327
5363
  }
5328
5364
  function getBackendVersion() {
5329
5365
  return _backendVersion;
5330
5366
  }
5367
+ function getApiFallbackSince2() {
5368
+ return getApiFallbackSince();
5369
+ }
5331
5370
  async function remoteCall(method, args, fallbackFn) {
5371
+ if (!_startupProbeDone && !isApiFallbackMode()) {
5372
+ _startupProbeDone = true;
5373
+ try {
5374
+ syncApiTokenFromDisk();
5375
+ if (isApiEnabled()) {
5376
+ const probeClient = getApiClient2();
5377
+ if (probeClient) {
5378
+ await probeClient.health();
5379
+ markApiConnected();
5380
+ }
5381
+ }
5382
+ } catch {
5383
+ }
5384
+ }
5332
5385
  syncApiTokenFromDisk();
5333
5386
  if (!VIBEOS_API_TOKEN && VIBEOS_API_BOOTSTRAP_TOKEN) {
5334
5387
  await ensureBootstrapExchange();
5335
5388
  syncApiTokenFromDisk();
5389
+ if (VIBEOS_API_TOKEN)
5390
+ markApiConnected();
5336
5391
  }
5337
- if (tryResetFallbackCooldown()) {
5338
- console.warn("[vibeOS] API fallback cooldown expired \u2014 retrying API");
5392
+ if (isApiFallbackMode() && getApiFallbackSince()) {
5393
+ const elapsed = Date.now() - new Date(getApiFallbackSince()).getTime();
5394
+ if (elapsed > FALLBACK_COOLDOWN_MS) {
5395
+ try {
5396
+ const probeClient = getApiClient2();
5397
+ if (probeClient) {
5398
+ await probeClient.health();
5399
+ markApiConnected();
5400
+ } else {
5401
+ denyReconnection("no client");
5402
+ if (fallbackFn)
5403
+ return fallbackFn();
5404
+ return null;
5405
+ }
5406
+ } catch (probeErr) {
5407
+ const probeStatus = probeErr?.statusCode || probeErr?.status || 0;
5408
+ const probeBody = probeErr?.response?.body || probeErr?.body || "";
5409
+ const probePreview = typeof probeBody === "string" ? probeBody.substring(0, 80) : String(probeBody).substring(0, 80);
5410
+ denyReconnection(probeStatus ? `status=${probeStatus} body=${probePreview}` : `message=${probeErr?.message || probeErr}`);
5411
+ if (fallbackFn)
5412
+ return fallbackFn();
5413
+ return null;
5414
+ }
5415
+ }
5339
5416
  }
5340
- if (!VIBEOS_API_ENABLED || _apiFallbackMode) {
5417
+ if (!isApiEnabled() || isApiFallbackMode()) {
5341
5418
  if (fallbackFn)
5342
5419
  return fallbackFn();
5343
5420
  return null;
@@ -5359,13 +5436,12 @@ async function remoteCall(method, args, fallbackFn) {
5359
5436
  const result = await client2[method](...args);
5360
5437
  if (method === "health")
5361
5438
  recordBackendVersion(result);
5362
- if (_apiFallbackMode) {
5363
- _apiFallbackMode = false;
5364
- _apiFallbackSince = null;
5365
- console.warn(`[vibeOS] API reconnected \u2014 ${method} OK`);
5439
+ if (isApiFallbackMode()) {
5440
+ setApiFallbackMode(false);
5441
+ setApiFallbackSince(null);
5366
5442
  }
5367
- _apiFallbackMode = false;
5368
- _apiFallbackSince = null;
5443
+ setApiFallbackMode(false);
5444
+ setApiFallbackSince(null);
5369
5445
  markApiConnected();
5370
5446
  return result;
5371
5447
  } catch (err) {
@@ -5373,9 +5449,9 @@ async function remoteCall(method, args, fallbackFn) {
5373
5449
  const body = err?.response?.body || err?.body || "";
5374
5450
  const bodyPreview = typeof body === "string" ? body.substring(0, 120) : String(body).substring(0, 120);
5375
5451
  const detail = status ? `status=${status} body=${bodyPreview}` : `message=${err?.message || err}`;
5376
- if (!_apiFallbackMode) {
5377
- _apiFallbackMode = true;
5378
- _apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
5452
+ if (!isApiFallbackMode()) {
5453
+ setApiFallbackMode(true);
5454
+ setApiFallbackSince((/* @__PURE__ */ new Date()).toISOString());
5379
5455
  console.error(`[vibeOS] API fallback activated (${method}): ${detail}`);
5380
5456
  }
5381
5457
  if (status === 401 || status === 403) {
@@ -5396,7 +5472,7 @@ async function remoteCall(method, args, fallbackFn) {
5396
5472
 
5397
5473
  // src/lib/pricing.js
5398
5474
  init_state();
5399
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync4, statSync as statSync5, renameSync as renameSync4, openSync as openSync2, closeSync as closeSync2, rmSync as rmSync3, readdirSync as readdirSync2 } from "node:fs";
5475
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync6, existsSync as existsSync6, mkdirSync as mkdirSync5, statSync as statSync5, renameSync as renameSync4, openSync as openSync2, closeSync as closeSync2, rmSync as rmSync3, readdirSync as readdirSync2 } from "node:fs";
5400
5476
  import { join as join5, dirname as dirname5, resolve } from "node:path";
5401
5477
  import { homedir as homedir4, tmpdir as tmpdir3 } from "node:os";
5402
5478
  import { createHash as createHash2 } from "node:crypto";
@@ -5443,10 +5519,10 @@ function withFileLock2(filePath, fn, opts = {}) {
5443
5519
  const start = Date.now();
5444
5520
  while (Date.now() - start < timeoutMs) {
5445
5521
  try {
5446
- mkdirSync4(join5(getVibeOSHome4(), ".vibeOS-locks"), { recursive: true });
5522
+ mkdirSync5(join5(getVibeOSHome4(), ".vibeOS-locks"), { recursive: true });
5447
5523
  const fd = openSync2(lockPath, "wx");
5448
5524
  try {
5449
- writeFileSync5(fd, `${process.pid}
5525
+ writeFileSync6(fd, `${process.pid}
5450
5526
  ${Date.now()}
5451
5527
  `);
5452
5528
  } catch {
@@ -6012,7 +6088,7 @@ function _writeDynamicPricingCache(modelsMap) {
6012
6088
  const PRICING_CACHE_FILE2 = join5(getVibeOSHome4(), "model-pricing-cache.json");
6013
6089
  try {
6014
6090
  withFileLock2(PRICING_CACHE_FILE2, () => {
6015
- mkdirSync4(dirname5(PRICING_CACHE_FILE2), { recursive: true });
6091
+ mkdirSync5(dirname5(PRICING_CACHE_FILE2), { recursive: true });
6016
6092
  let merged = {};
6017
6093
  try {
6018
6094
  if (existsSync6(PRICING_CACHE_FILE2)) {
@@ -6024,7 +6100,7 @@ function _writeDynamicPricingCache(modelsMap) {
6024
6100
  }
6025
6101
  merged = { ...merged, ...modelsMap };
6026
6102
  const tmp = PRICING_CACHE_FILE2 + ".tmp";
6027
- writeFileSync5(tmp, JSON.stringify({
6103
+ writeFileSync6(tmp, JSON.stringify({
6028
6104
  ts: Date.now(),
6029
6105
  source: "dynamic-model-pricing",
6030
6106
  models: merged
@@ -6352,7 +6428,7 @@ function clearWorkspaceFollowupPauseForSession(sessionId = "") {
6352
6428
  if (!touched)
6353
6429
  continue;
6354
6430
  outer["workspace:followup"] = JSON.stringify(followup);
6355
- writeFileSync5(file, JSON.stringify(outer, null, 2) + "\n");
6431
+ writeFileSync6(file, JSON.stringify(outer, null, 2) + "\n");
6356
6432
  changed = true;
6357
6433
  } catch {
6358
6434
  }
@@ -6562,7 +6638,7 @@ function _refreshModel(directory3) {
6562
6638
  if (t?.trinity?.[s]?.oc === cfgModel) {
6563
6639
  t.selection.active_slot = s;
6564
6640
  const _tmp = TIERS_FILE3 + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
6565
- writeFileSync5(_tmp, JSON.stringify(t, null, 2) + "\n", "utf-8");
6641
+ writeFileSync6(_tmp, JSON.stringify(t, null, 2) + "\n", "utf-8");
6566
6642
  renameSync4(_tmp, TIERS_FILE3);
6567
6643
  if (DEBUG_INTERNALS)
6568
6644
  console.error(`[vibeOS] model refresh (config fallback): synced active_slot \u2192 ${s}`);
@@ -6589,7 +6665,7 @@ function applySlot2(slot, projectDir = "") {
6589
6665
  return { ok: false, reason: `slot '${slot}' has no oc model` };
6590
6666
  j.selection.active_slot = slot;
6591
6667
  const _tmp = TIERS_FILE3 + ".tmp." + Date.now();
6592
- writeFileSync5(_tmp, JSON.stringify(j, null, 2) + "\n", "utf-8");
6668
+ writeFileSync6(_tmp, JSON.stringify(j, null, 2) + "\n", "utf-8");
6593
6669
  renameSync4(_tmp, TIERS_FILE3);
6594
6670
  const dir = projectDir || process.cwd();
6595
6671
  const localOcConfig = join5(dir, "opencode.json");
@@ -6597,7 +6673,7 @@ function applySlot2(slot, projectDir = "") {
6597
6673
  if (existsSync6(ocConfig)) {
6598
6674
  const oc = safeJsonParse3(readFileSync5(ocConfig, "utf-8"));
6599
6675
  oc.model = ocModel;
6600
- writeFileSync5(ocConfig, JSON.stringify(oc, null, 2) + "\n");
6676
+ writeFileSync6(ocConfig, JSON.stringify(oc, null, 2) + "\n");
6601
6677
  }
6602
6678
  clearWorkspaceFollowupPauseForSession(getCurrentSessionId());
6603
6679
  _refreshModel(dir);
@@ -6609,7 +6685,7 @@ function applySlot2(slot, projectDir = "") {
6609
6685
  }
6610
6686
 
6611
6687
  // src/lib/turn-classify.js
6612
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync8, existsSync as existsSync9, mkdirSync as mkdirSync7, renameSync as renameSync5 } from "node:fs";
6688
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync9, existsSync as existsSync9, mkdirSync as mkdirSync8, renameSync as renameSync5 } from "node:fs";
6613
6689
  import { join as join7, dirname as dirname8 } from "node:path";
6614
6690
 
6615
6691
  // src/vibeOS-lib/blackbox/resolution-tracker.js
@@ -8287,7 +8363,7 @@ function projectStructuredFromText(raw, selection, creditPercent = 0) {
8287
8363
  // src/lib/reporting.js
8288
8364
  init_state();
8289
8365
  init_runtime_state();
8290
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync9, existsSync as existsSync11, mkdirSync as mkdirSync8, statSync as statSync6, rmSync as rmSync4 } from "node:fs";
8366
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync10, existsSync as existsSync11, mkdirSync as mkdirSync9, statSync as statSync6, rmSync as rmSync4 } from "node:fs";
8291
8367
  import { join as join9 } from "node:path";
8292
8368
  function getVibeOSHome7() {
8293
8369
  return process.env.VIBEOS_HOME || join9(process.env.HOME || "", ".claude");
@@ -8329,8 +8405,8 @@ function saveReportsIndex(idx) {
8329
8405
  const reportsIndexPath = getReportsIndexPath();
8330
8406
  const reportsDir = getReportsDir();
8331
8407
  withFileLock(reportsIndexPath, () => {
8332
- mkdirSync8(reportsDir, { recursive: true });
8333
- writeFileSync9(reportsIndexPath, JSON.stringify(idx, null, 2) + "\n");
8408
+ mkdirSync9(reportsDir, { recursive: true });
8409
+ writeFileSync10(reportsIndexPath, JSON.stringify(idx, null, 2) + "\n");
8334
8410
  });
8335
8411
  } catch (err) {
8336
8412
  console.error(`[vibeOS] reports index write failed: ${err.message}`);
@@ -8501,12 +8577,12 @@ function saveReport({ type = "manual", summary = "", findings = null, metrics =
8501
8577
  const reportsIndexPath = getReportsIndexPath();
8502
8578
  const reportsDir = getReportsDir();
8503
8579
  withFileLock(reportsIndexPath, () => {
8504
- mkdirSync8(reportsDir, { recursive: true });
8505
- writeFileSync9(join9(reportsDir, `${id2}.json`), JSON.stringify(report, null, 2) + "\n");
8580
+ mkdirSync9(reportsDir, { recursive: true });
8581
+ writeFileSync10(join9(reportsDir, `${id2}.json`), JSON.stringify(report, null, 2) + "\n");
8506
8582
  const idx = reportsIndex();
8507
8583
  const _sum = (summary || "").slice(0, 80);
8508
8584
  idx.reports.push({ id: id2, type, project: report.meta.project, fingerprint: fp2, created: report.meta.created, summary: _sum });
8509
- writeFileSync9(reportsIndexPath, JSON.stringify(idx, null, 2) + "\n");
8585
+ writeFileSync10(reportsIndexPath, JSON.stringify(idx, null, 2) + "\n");
8510
8586
  });
8511
8587
  try {
8512
8588
  if (fp2 && fp2 !== "unknown") {
@@ -8563,7 +8639,7 @@ function readReport(id2) {
8563
8639
  init_selection_manager();
8564
8640
 
8565
8641
  // src/lib/credit-api.js
8566
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync10, existsSync as existsSync12 } from "node:fs";
8642
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync11, existsSync as existsSync12 } from "node:fs";
8567
8643
  import { join as join10 } from "node:path";
8568
8644
  init_state();
8569
8645
  function getVibeOSHome8() {
@@ -8634,7 +8710,7 @@ async function _snapshot() {
8634
8710
  }
8635
8711
  }
8636
8712
  try {
8637
- writeFileSync10(CREDIT_CACHE_F, JSON.stringify({ total, providers: provs, ts: Date.now() }));
8713
+ writeFileSync11(CREDIT_CACHE_F, JSON.stringify({ total, providers: provs, ts: Date.now() }));
8638
8714
  } catch {
8639
8715
  }
8640
8716
  }
@@ -9044,7 +9120,7 @@ function createTrinityTool(deps) {
9044
9120
  `Model: ${activeSlot} (${tiers?.[activeSlot]?.oc || deps.currentModel || "(unset)"})`,
9045
9121
  `Provider: ${execution.provider_label}`,
9046
9122
  `Quality: ${execution.quality_label}`,
9047
- ...isApiConnected() ? [`Backend: connected${getBackendVersion() ? ` (${getBackendVersion()})` : ""}`] : [`Backend: offline`],
9123
+ ...isApiConnected2() ? [`Backend: connected${getBackendVersion() ? ` (${getBackendVersion()})` : ""}`] : [`Backend: offline`],
9048
9124
  ...sel.requested_optimization_mode ? [`Requested mode: ${sel.requested_optimization_mode}`] : [],
9049
9125
  ...totalTurns > 0 ? [`Split: brain ${brainPct}% / worker ${workerPct}% (${totalTurns} total)`] : [],
9050
9126
  `Thinking: ${effectiveLevel}`,
@@ -10510,12 +10586,12 @@ async function probeModel(modelId, auth, providers = null) {
10510
10586
  }
10511
10587
 
10512
10588
  // src/lib/hooks/footer.js
10513
- import { readFileSync as readFileSync14, appendFileSync as appendFileSync4, mkdirSync as mkdirSync10 } from "node:fs";
10589
+ import { readFileSync as readFileSync14, appendFileSync as appendFileSync4, mkdirSync as mkdirSync11 } from "node:fs";
10514
10590
  import { join as join15 } from "node:path";
10515
10591
 
10516
10592
  // src/lib/hooks/chat-transform.js
10517
10593
  init_state();
10518
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, appendFileSync as appendFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync9, rmSync as rmSync5, readdirSync as readdirSync3, statSync as statSync7 } from "node:fs";
10594
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, appendFileSync as appendFileSync3, existsSync as existsSync14, mkdirSync as mkdirSync10, rmSync as rmSync5, readdirSync as readdirSync3, statSync as statSync7 } from "node:fs";
10519
10595
  import { join as join14, dirname as dirname10, basename as basename3 } from "node:path";
10520
10596
  import { createHash as createHash3 } from "node:crypto";
10521
10597
 
@@ -10712,7 +10788,7 @@ init_selection_manager();
10712
10788
  init_state();
10713
10789
  init_pattern_helpers();
10714
10790
  import { join as join13 } from "node:path";
10715
- import { writeFileSync as writeFileSync11 } from "node:fs";
10791
+ import { writeFileSync as writeFileSync12 } from "node:fs";
10716
10792
 
10717
10793
  // src/lib/text-compress.js
10718
10794
  var VERBOSE_LINE_RE = [
@@ -11070,7 +11146,7 @@ function recordSaving(tool2, reason, saveEst, meta = {}) {
11070
11146
  if (sd) {
11071
11147
  const sp = join13(sd, "delegation-state-hint.txt");
11072
11148
  try {
11073
- writeFileSync11(sp, JSON.stringify({ sid, total_savings: s.lifetime.total_savings_usd, last_reason: reason }), "utf8");
11149
+ writeFileSync12(sp, JSON.stringify({ sid, total_savings: s.lifetime.total_savings_usd, last_reason: reason }), "utf8");
11074
11150
  } catch {
11075
11151
  }
11076
11152
  }
@@ -11423,8 +11499,8 @@ function ensureProjectSkill(dir, fp2) {
11423
11499
  content += "\n";
11424
11500
  }
11425
11501
  try {
11426
- mkdirSync9(skillDir, { recursive: true });
11427
- writeFileSync12(skillPath, content, "utf-8");
11502
+ mkdirSync10(skillDir, { recursive: true });
11503
+ writeFileSync13(skillPath, content, "utf-8");
11428
11504
  console.error(`[vibeOS] Project Guard: created .opencode/skills/${projectName}/SKILL.md`);
11429
11505
  return { created: true, path: skillPath, skipped: false };
11430
11506
  } catch (err) {
@@ -11541,7 +11617,7 @@ function syncControlSettings(cv, options = {}) {
11541
11617
  writeSelection("previous_default_agent", oc.default_agent);
11542
11618
  }
11543
11619
  oc.default_agent = cv.agent_mode;
11544
- writeFileSync12(OC_CONFIG, JSON.stringify(oc, null, 2) + "\n");
11620
+ writeFileSync13(OC_CONFIG, JSON.stringify(oc, null, 2) + "\n");
11545
11621
  }
11546
11622
  }
11547
11623
  } catch {
@@ -11554,7 +11630,7 @@ function syncControlSettings(cv, options = {}) {
11554
11630
  const restoreAgent = oc.default_agent === "plan" ? resolveRestorableOpenCodeAgent(currentSel) : null;
11555
11631
  if (restoreAgent && oc.default_agent === "plan") {
11556
11632
  oc.default_agent = restoreAgent;
11557
- writeFileSync12(OC_CONFIG, JSON.stringify(oc, null, 2) + "\n");
11633
+ writeFileSync13(OC_CONFIG, JSON.stringify(oc, null, 2) + "\n");
11558
11634
  if (currentSel.previous_default_agent)
11559
11635
  writeSelection("previous_default_agent", null);
11560
11636
  }
@@ -11616,10 +11692,10 @@ ${raw}
11616
11692
  const sessPath = join14(getSessionScratchpadDir(), `${hash}.txt`);
11617
11693
  const globalPath = join14(globalDir, `${hash}.txt`);
11618
11694
  try {
11619
- mkdirSync9(globalDir, { recursive: true });
11695
+ mkdirSync10(globalDir, { recursive: true });
11620
11696
  ensureSessionScratchpadDirs();
11621
11697
  if (!existsSync14(globalPath)) {
11622
- writeFileSync12(globalPath, raw);
11698
+ writeFileSync13(globalPath, raw);
11623
11699
  indexAppend(hash, part.tool, raw.length);
11624
11700
  if (existsSync14(sessPath))
11625
11701
  rmSync5(sessPath, { force: true });
@@ -11632,7 +11708,7 @@ ${stableJson(invPart.state.input)}
11632
11708
  `).digest("hex").slice(0, 16);
11633
11709
  const ptrPath = join14(getSessionScratchpadDir(), `${inputHash}.ptr`);
11634
11710
  try {
11635
- writeFileSync12(ptrPath, JSON.stringify({ contentHash: hash, tool: part.tool }));
11711
+ writeFileSync13(ptrPath, JSON.stringify({ contentHash: hash, tool: part.tool }));
11636
11712
  } catch {
11637
11713
  }
11638
11714
  }
@@ -11912,7 +11988,7 @@ var onSystemTransform = async (_input, output) => {
11912
11988
  const system = output?.system;
11913
11989
  if (!Array.isArray(system))
11914
11990
  return;
11915
- if (isApiConnected()) {
11991
+ if (isApiConnected2()) {
11916
11992
  try {
11917
11993
  const bb = loadBlackboxState();
11918
11994
  if (!bb.enabled || _blackboxEnabled === false) {
@@ -12072,7 +12148,7 @@ var onSystemTransform = async (_input, output) => {
12072
12148
  fp: currentProjectFingerprint || ""
12073
12149
  }) + "\n";
12074
12150
  try {
12075
- mkdirSync9(calDir, { recursive: true });
12151
+ mkdirSync10(calDir, { recursive: true });
12076
12152
  appendFileSync3(calFile, calRecord);
12077
12153
  } catch {
12078
12154
  }
@@ -12254,8 +12330,8 @@ function buildFooterLine(input) {
12254
12330
 
12255
12331
  // src/lib/hooks/footer.js
12256
12332
  var IS_CLI_RUNTIME = Boolean(process.stdout?.isTTY || process.stderr?.isTTY || process.stdin?.isTTY);
12257
- var IS_TEST_RUNTIME = process.env.VIBEOS_MCP_PORT === "0" || process.env.NODE_ENV === "test" || process.env.CI === "true";
12258
- var FOOTER_DEBUG_STDERR = process.env.VIBEOS_DEBUG_FOOTER === "1" || !IS_CLI_RUNTIME && !IS_TEST_RUNTIME;
12333
+ var IS_TEST_RUNTIME2 = process.env.VIBEOS_MCP_PORT === "0" || process.env.NODE_ENV === "test" || process.env.CI === "true";
12334
+ var FOOTER_DEBUG_STDERR = process.env.VIBEOS_DEBUG_FOOTER === "1" || !IS_CLI_RUNTIME && !IS_TEST_RUNTIME2;
12259
12335
  function footerDebug(...args) {
12260
12336
  if (FOOTER_DEBUG_STDERR)
12261
12337
  console.error(...args);
@@ -12496,7 +12572,7 @@ async function _appendFooter(input, output, directory3) {
12496
12572
  return;
12497
12573
  const ltTotal = ltTasks + ltCache;
12498
12574
  const activeSlot = selNowFooter.active_slot || "brain";
12499
- const flashIcon = isApiConnected() ? " \u26A1" : "";
12575
+ const flashIcon = isApiConnected2() ? " \u26A1" : "";
12500
12576
  const displayMode2 = autoSelectMode2(currentSubRegime2, _footerStress);
12501
12577
  const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode2, activeSlot);
12502
12578
  const vibeLine = buildFooterLine({
@@ -12538,7 +12614,7 @@ ${vibeLine}`;
12538
12614
  tracker.recordOutcome(finalOutcome);
12539
12615
  syncOutcomeToApi(finalOutcome);
12540
12616
  try {
12541
- mkdirSync10(getVibeOSHome10(), { recursive: true });
12617
+ mkdirSync11(getVibeOSHome10(), { recursive: true });
12542
12618
  appendFileSync4(join15(getVibeOSHome10(), "calibration-data.jsonl"), JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), event: "outcome", sid: getSessionId(), outcome: finalOutcome }) + "\n");
12543
12619
  } catch {
12544
12620
  }
@@ -12566,7 +12642,7 @@ ${vibeLine} \u2014`);
12566
12642
 
12567
12643
  // src/lib/hooks/tool-execute.js
12568
12644
  init_state();
12569
- import { writeFileSync as writeFileSync14, appendFileSync as appendFileSync6, existsSync as existsSync16, mkdirSync as mkdirSync12 } from "node:fs";
12645
+ import { writeFileSync as writeFileSync15, appendFileSync as appendFileSync6, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "node:fs";
12570
12646
  import { join as join17, dirname as dirname12, basename as basename4 } from "node:path";
12571
12647
  import { createHash as createHash5 } from "node:crypto";
12572
12648
  init_selection_manager();
@@ -12635,7 +12711,7 @@ init_smart_cache();
12635
12711
 
12636
12712
  // src/lib/tdd-enforcer.js
12637
12713
  init_state();
12638
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync13, appendFileSync as appendFileSync5, existsSync as existsSync15, mkdirSync as mkdirSync11, statSync as statSync8, readdirSync as readdirSync4, rmSync as rmSync6, openSync as openSync3 } from "node:fs";
12714
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync14, appendFileSync as appendFileSync5, existsSync as existsSync15, mkdirSync as mkdirSync12, statSync as statSync8, readdirSync as readdirSync4, rmSync as rmSync6, openSync as openSync3 } from "node:fs";
12639
12715
  import { join as join16, dirname as dirname11 } from "node:path";
12640
12716
  import { createHash as createHash4 } from "node:crypto";
12641
12717
 
@@ -13738,7 +13814,7 @@ var COOLDOWN_MS = 6e4;
13738
13814
  var _enforcementCooldown = /* @__PURE__ */ new Set();
13739
13815
  function _acquireLock(testPath) {
13740
13816
  try {
13741
- mkdirSync11(ENFORCEMENT_LOCK_DIR, { recursive: true });
13817
+ mkdirSync12(ENFORCEMENT_LOCK_DIR, { recursive: true });
13742
13818
  const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
13743
13819
  const lockPath = join16(ENFORCEMENT_LOCK_DIR, `${hash}.lock`);
13744
13820
  try {
@@ -13795,13 +13871,13 @@ function _isInCooldown(testPath) {
13795
13871
  }
13796
13872
  function _recordCooldown(testPath) {
13797
13873
  try {
13798
- mkdirSync11(dirname11(ENFORCEMENT_COOLDOWN_FILE2), { recursive: true });
13874
+ mkdirSync12(dirname11(ENFORCEMENT_COOLDOWN_FILE2), { recursive: true });
13799
13875
  const hash = createHash4("sha256").update(testPath).digest("hex").slice(0, 16);
13800
13876
  const entry = JSON.stringify({ h: hash, ts: Date.now() }) + "\n";
13801
13877
  appendFileSync5(ENFORCEMENT_COOLDOWN_FILE2, entry);
13802
13878
  const lines = readFileSync15(ENFORCEMENT_COOLDOWN_FILE2, "utf-8").trim().split("\n").filter(Boolean);
13803
13879
  if (lines.length > 500) {
13804
- writeFileSync13(ENFORCEMENT_COOLDOWN_FILE2, lines.slice(-200).join("\n") + "\n");
13880
+ writeFileSync14(ENFORCEMENT_COOLDOWN_FILE2, lines.slice(-200).join("\n") + "\n");
13805
13881
  }
13806
13882
  } catch {
13807
13883
  }
@@ -13887,8 +13963,8 @@ function enforceTestFile(filePath) {
13887
13963
  if (!_acquireLock(skeleton.path))
13888
13964
  return null;
13889
13965
  try {
13890
- mkdirSync11(skeleton.dir, { recursive: true });
13891
- writeFileSync13(skeleton.path, skeleton.content);
13966
+ mkdirSync12(skeleton.dir, { recursive: true });
13967
+ writeFileSync14(skeleton.path, skeleton.content);
13892
13968
  _enforcementCooldown.add(skeleton.path);
13893
13969
  _recordCooldown(skeleton.path);
13894
13970
  try {
@@ -14231,7 +14307,7 @@ ${argsJson}
14231
14307
  const globalFile = join17(globalDir, `${targetHash}.txt`);
14232
14308
  if (existsSync16(cachedFile) || existsSync16(globalFile)) {
14233
14309
  ensureSessionScratchpadDirs();
14234
- writeFileSync14(ptrPath, JSON.stringify({
14310
+ writeFileSync15(ptrPath, JSON.stringify({
14235
14311
  contentHash: targetHash,
14236
14312
  tool: titleCase,
14237
14313
  warmed: true,
@@ -14530,8 +14606,8 @@ ${argsJson}
14530
14606
  const missed = recordMissedContext7(_estC7);
14531
14607
  if (!existsSync16(CONTEXT7_INSTALL_FLAG)) {
14532
14608
  try {
14533
- mkdirSync12(dirname12(CONTEXT7_INSTALL_FLAG), { recursive: true });
14534
- writeFileSync14(CONTEXT7_INSTALL_FLAG, "");
14609
+ mkdirSync13(dirname12(CONTEXT7_INSTALL_FLAG), { recursive: true });
14610
+ writeFileSync15(CONTEXT7_INSTALL_FLAG, "");
14535
14611
  } catch {
14536
14612
  }
14537
14613
  console.error(`[vibeOS] Small win: install context7 MCP to save about ~$0.06/turn on docs: \`claude mcp add context7 npx @upstash/context7-mcp\``);
@@ -14622,7 +14698,7 @@ var onToolExecuteAfter = async (input, output) => {
14622
14698
  const displayMode2 = autoSelectMode2(currentSubRegime2, latestUserIntent ? scoreStress(latestUserIntent) : 0);
14623
14699
  const vibeBrand = resolveBrand(displayMode2, activeSlot);
14624
14700
  const sessionSlot = loadSessionSlot(currentSid);
14625
- const flashIcon = isApiConnected() ? " \u26A1" : "";
14701
+ const flashIcon = isApiConnected2() ? " \u26A1" : "";
14626
14702
  _footerText = buildFooterLine({
14627
14703
  activeSlot,
14628
14704
  providerLabel: execution.provider_label,
@@ -15078,7 +15154,6 @@ function ensureDeferredBootstrap() {
15078
15154
  } catch {
15079
15155
  }
15080
15156
  }
15081
- var _apiFallbackSince2 = null;
15082
15157
  var activeJob2 = null;
15083
15158
  var fp = "";
15084
15159
  var _mcpServerRuntime = null;
@@ -15239,8 +15314,8 @@ async function _seedOrRepairModelTiers(directory3) {
15239
15314
  },
15240
15315
  trinity: nextTrinity
15241
15316
  };
15242
- mkdirSync13(dirname13(TIERS_FILE3), { recursive: true });
15243
- writeFileSync15(TIERS_FILE3, JSON.stringify(tiers, null, 2) + "\n", "utf-8");
15317
+ mkdirSync14(dirname13(TIERS_FILE3), { recursive: true });
15318
+ writeFileSync16(TIERS_FILE3, JSON.stringify(tiers, null, 2) + "\n", "utf-8");
15244
15319
  return true;
15245
15320
  }
15246
15321
  function _parseJsonc(raw) {
@@ -15295,9 +15370,7 @@ function loadMcpPort() {
15295
15370
  }
15296
15371
  } catch {
15297
15372
  }
15298
- if (process.env.VIBEOS_TEST_CONTEXT)
15299
- return 0;
15300
- return 3001;
15373
+ return null;
15301
15374
  }
15302
15375
  function persistMcpPort(port) {
15303
15376
  try {
@@ -15310,9 +15383,9 @@ function persistMcpPort(port) {
15310
15383
  tiers.selection.mcp_port = port;
15311
15384
  if ("mcp_port" in tiers)
15312
15385
  delete tiers.mcp_port;
15313
- mkdirSync13(dirname13(getTiersFile()), { recursive: true });
15386
+ mkdirSync14(dirname13(getTiersFile()), { recursive: true });
15314
15387
  const tmp = getTiersFile() + ".tmp." + Date.now();
15315
- writeFileSync15(tmp, JSON.stringify(tiers, null, 2) + "\n", "utf-8");
15388
+ writeFileSync16(tmp, JSON.stringify(tiers, null, 2) + "\n", "utf-8");
15316
15389
  renameSync6(tmp, getTiersFile());
15317
15390
  } catch {
15318
15391
  }
@@ -15332,6 +15405,7 @@ function scheduleMcpServerRestart() {
15332
15405
  _mcpServerRestartTimer = null;
15333
15406
  void ensureMcpServerRunning();
15334
15407
  }, 500);
15408
+ if (typeof _mcpServerRestartTimer.unref === "function") _mcpServerRestartTimer.unref();
15335
15409
  }
15336
15410
  function attachMcpServerWatchdog(server2) {
15337
15411
  server2?.once?.("close", () => {
@@ -15376,11 +15450,11 @@ async function ensureMcpServerRunning() {
15376
15450
  version: readPackageVersion(),
15377
15451
  todos: loadTodos(),
15378
15452
  fallbackThinking: thinkingLevel(loadCredit()),
15379
- backendConnected: isApiConnected(),
15453
+ backendConnected: isApiConnected2(),
15380
15454
  backendHealthUrl: `${VIBEOS_API_URL}/health`,
15381
15455
  backendVersion: getBackendVersion(),
15382
15456
  apiFallbackMode: isApiFallback2(),
15383
- apiFallbackSince: _apiFallbackSince2,
15457
+ apiFallbackSince: getApiFallbackSince2(),
15384
15458
  modelLocked: _modelLocked,
15385
15459
  lockedSlot: _lockedSlot,
15386
15460
  lockedModel: _lockedModel
@@ -15497,10 +15571,13 @@ async function ensureMcpServerRunning() {
15497
15571
  }
15498
15572
  });
15499
15573
  }
15500
- const mcpServer = await _mcpServerRuntime.start(port);
15501
- const actualPort = Number(mcpServer?.address?.()?.port || port);
15502
- if (actualPort && actualPort !== port)
15574
+ const requestedPort = port == null ? 0 : port;
15575
+ const mcpServer = await _mcpServerRuntime.start(requestedPort);
15576
+ const actualPort = Number(mcpServer?.address?.()?.port || requestedPort);
15577
+ if (actualPort && actualPort !== requestedPort)
15503
15578
  persistMcpPort(actualPort);
15579
+ if (actualPort)
15580
+ writeDashboardBaseConfig(`http://127.0.0.1:${actualPort}`);
15504
15581
  console.error(`[vibeOS] MCP server on http://127.0.0.1:${actualPort}`);
15505
15582
  if (actualPort)
15506
15583
  console.error(`[vibeOS] Dashboard at http://127.0.0.1:${actualPort}/`);
@@ -15640,9 +15717,9 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
15640
15717
  };
15641
15718
  const saveProjectStateStable = (state) => {
15642
15719
  try {
15643
- mkdirSync13(dirname13(hookProjectStateFile), { recursive: true });
15720
+ mkdirSync14(dirname13(hookProjectStateFile), { recursive: true });
15644
15721
  const tmp = hookProjectStateFile + ".tmp";
15645
- writeFileSync15(tmp, JSON.stringify(state, null, 2) + "\n");
15722
+ writeFileSync16(tmp, JSON.stringify(state, null, 2) + "\n");
15646
15723
  renameSync6(tmp, hookProjectStateFile);
15647
15724
  } catch {
15648
15725
  }
@@ -15659,8 +15736,8 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
15659
15736
  };
15660
15737
  const saveReportsIndexStable = (idx) => {
15661
15738
  try {
15662
- mkdirSync13(hookReportsDir, { recursive: true });
15663
- writeFileSync15(hookReportsIndex, JSON.stringify(idx, null, 2) + "\n");
15739
+ mkdirSync14(hookReportsDir, { recursive: true });
15740
+ writeFileSync16(hookReportsIndex, JSON.stringify(idx, null, 2) + "\n");
15664
15741
  } catch {
15665
15742
  }
15666
15743
  };
@@ -15669,7 +15746,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
15669
15746
  if (!existsSync18(path))
15670
15747
  return null;
15671
15748
  const bkDir = join18(hookVibeHome, ".backups");
15672
- mkdirSync13(bkDir, { recursive: true });
15749
+ mkdirSync14(bkDir, { recursive: true });
15673
15750
  const bk = join18(bkDir, `${basename5(path)}.${label}.${Date.now()}.bak`);
15674
15751
  copyFileSync2(path, bk);
15675
15752
  return bk;
@@ -15705,10 +15782,10 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
15705
15782
  directory: directory3,
15706
15783
  safeJsonParse: safeJsonParse3,
15707
15784
  readFileSync: readFileSync17,
15708
- writeFileSync: writeFileSync15,
15785
+ writeFileSync: writeFileSync16,
15709
15786
  existsSync: existsSync18,
15710
15787
  renameSync: renameSync6,
15711
- mkdirSync: mkdirSync13,
15788
+ mkdirSync: mkdirSync14,
15712
15789
  get TIERS_FILE() {
15713
15790
  return hookTiersFile;
15714
15791
  },
@@ -15764,7 +15841,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
15764
15841
  saveBlackboxState,
15765
15842
  isApiFallback: () => isApiFallback2(),
15766
15843
  get _apiFallbackSince() {
15767
- return _apiFallbackSince2;
15844
+ return getApiFallbackSince2();
15768
15845
  },
15769
15846
  reportsIndex: reportsIndexStable,
15770
15847
  saveReportsIndex: saveReportsIndexStable,
@@ -16009,7 +16086,7 @@ ${report.narrative}`);
16009
16086
  }
16010
16087
  };
16011
16088
  _pluginHooksRuntime = pluginHooks;
16012
- const _inTestEnv = process.env.VIBEOS_MCP_PORT === "0";
16089
+ const _inTestEnv = process.env.VIBEOS_MCP_PORT === "0" || process.env.NODE_ENV === "test" || process.execArgv.some((arg) => arg === "--test" || arg.startsWith("--test="));
16013
16090
  if (!_inTestEnv)
16014
16091
  void ensureMcpServerRunning();
16015
16092
  return pluginHooks;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.25.8",
3
+ "version": "0.25.9",
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",