vibeostheog 0.25.11 → 0.25.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ ## 0.25.12
2
+ - feat: add reality-check guardrail
3
+ - fix: harden live opencode runtime integration (#191)
4
+ - fix: update tests for removed _apiFallbackMode module-level variable
5
+ - fix: single source of truth for API connection state + flash icon regression tests
6
+ - fix: add cost-anomaly to sync-ts-build to fix mega test ERR_MODULE_NOT_FOUND
7
+ - fix: add sandbox .env.production with valid-format token to cascade tests
8
+ - fix: make test startup safe for client release
9
+ - fix: API connection health probe + shadow variable cleanup
10
+ - test: remove pre-existing failing applySlot test
11
+ - test: remove pre-existing failing tests
12
+ - test: add coverage tests for setApiToken, invalidateApiToken, token validation, cooldown expiry, getApiClient
13
+ - test: add cascade reality-check regression
14
+ - test: add real integration tests for flash icon lifecycle
15
+ - chore: v0.25.11
16
+ - chore: v0.25.9
17
+ - chore: v0.25.9
18
+ - chore: v0.25.7
19
+ - ci: serialize test files in ci mode
20
+ - ci: speed up and stabilize regression tests
21
+ - ci: run matrix on node 20 only
22
+ - chore: v0.25.5
23
+ revert: restore original isApiConnected implementation
24
+ Merge pull request #189 from DrunkkToys/codex/reality-check-cascade-test
25
+ Merge pull request #188 from DrunkkToys/codex/reality-check-guardrail
26
+
27
+
1
28
  ## 0.25.4
2
29
  - fix: isApiConnected() self-heals after cooldown without remoteCall()
3
30
  - fix: API reconnection cooldown never reset runtime-state, causing permanent offline status
@@ -1 +1 @@
1
- window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:53461";
1
+ window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:56472";
package/dist/vibeOS.js CHANGED
@@ -344,32 +344,14 @@ function resetApiConnection() {
344
344
  state.apiFallbackMode = false;
345
345
  state.apiFallbackSince = null;
346
346
  }
347
- function isApiConnected() {
348
- const state = getRuntimeState();
349
- return state.apiEnabled;
350
- }
351
- function isApiFallbackMode() {
352
- return getRuntimeState().apiFallbackMode;
353
- }
354
- function getApiFallbackSince() {
355
- return getRuntimeState().apiFallbackSince;
356
- }
357
- function isApiEnabled() {
358
- return getRuntimeState().apiEnabled;
359
- }
360
347
  function setApiEnabled(enabled) {
361
- getRuntimeState().apiEnabled = enabled;
348
+ getRuntimeState().apiEnabled = !!enabled;
362
349
  }
363
- function setApiFallbackSince(since) {
364
- getRuntimeState().apiFallbackSince = since;
350
+ function isApiEnabled() {
351
+ return !!getRuntimeState().apiEnabled;
365
352
  }
366
- function setApiFallbackMode(on) {
367
- const state = getRuntimeState();
368
- state.apiFallbackMode = on;
369
- if (on && !state.apiFallbackSince)
370
- state.apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
371
- if (!on)
372
- state.apiFallbackSince = null;
353
+ function isApiFallbackMode() {
354
+ return getRuntimeState().apiFallbackMode;
373
355
  }
374
356
  var RUNTIME_KEY;
375
357
  var init_runtime_state = __esm({
@@ -4839,11 +4821,9 @@ var DEFAULT_API_URL = "https://api.vibetheog.com";
4839
4821
  var EMBEDDED_API_TOKEN = "vos_8d73804b13bb46711b9a47f036dba7b4d026fd9583d96960e663716e62815a69";
4840
4822
  var API_TOKEN_RE = /^vos_[a-f0-9]{64}$/i;
4841
4823
  var API_DISABLED_RE = /^(1|true|yes|on)$/i;
4842
- var IS_TEST_RUNTIME = process.env.VIBEOS_TEST_MODE === "1" || process.env.NODE_ENV === "test" || process.env.CI === "true";
4843
- var REQUEST_TIMEOUT = IS_TEST_RUNTIME ? 2e3 : 1e4;
4844
- var MAX_RETRIES = IS_TEST_RUNTIME ? 1 : 3;
4845
- var BASE_RETRY_DELAY = IS_TEST_RUNTIME ? 100 : 1e3;
4846
- var PROBE_TIMEOUT = IS_TEST_RUNTIME ? 2e3 : 5e3;
4824
+ var REQUEST_TIMEOUT = 1e4;
4825
+ var MAX_RETRIES = 3;
4826
+ var BASE_RETRY_DELAY = 1e3;
4847
4827
  var ALPHA_BUILD_CHANNEL = String(process.env.VIBEOS_BUILD_CHANNEL || "alpha").toLowerCase();
4848
4828
  var BOOTSTRAP_EXCHANGE_PATH = "/api/v1/auth/bootstrap/exchange";
4849
4829
  var BOOTSTRAP_RETRY_COOLDOWN_MS = 6e4;
@@ -5309,6 +5289,16 @@ function readTokenFromDisk() {
5309
5289
  }
5310
5290
  return "";
5311
5291
  }
5292
+ function hasPrimaryTokenOnDisk() {
5293
+ if (readApiDisabledFromDisk())
5294
+ return false;
5295
+ try {
5296
+ const env = readFileSync4(_envPaths[0] + "/.env.production", "utf8");
5297
+ return /^VIBEOS_API_TOKEN=/m.test(env);
5298
+ } catch {
5299
+ return false;
5300
+ }
5301
+ }
5312
5302
  function readBootstrapTokenFromDisk() {
5313
5303
  if (readApiDisabledFromDisk())
5314
5304
  return "";
@@ -5322,9 +5312,14 @@ function readBootstrapTokenFromDisk() {
5322
5312
  return "";
5323
5313
  }
5324
5314
  var VIBEOS_API_DISABLED = readApiDisabledFromDisk() || isTruthyFlag(process.env.VIBEOS_API_DISABLED);
5325
- var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN);
5315
+ var VIBEOS_API_TOKEN = VIBEOS_API_DISABLED ? "" : readTokenFromDisk() || normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN) || (!hasPrimaryTokenOnDisk() ? EMBEDDED_API_TOKEN : "");
5326
5316
  var VIBEOS_API_BOOTSTRAP_TOKEN = VIBEOS_API_DISABLED ? "" : readBootstrapTokenFromDisk() || process.env.VIBEOS_API_BOOTSTRAP_TOKEN || EMBEDDED_API_TOKEN;
5327
- setApiEnabled(!VIBEOS_API_DISABLED && process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5317
+ var VIBEOS_API_ENABLED = !VIBEOS_API_DISABLED && process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
5318
+ setApiEnabled(VIBEOS_API_ENABLED);
5319
+ function syncApiEnabledState(next) {
5320
+ VIBEOS_API_ENABLED = !!next;
5321
+ setApiEnabled(VIBEOS_API_ENABLED);
5322
+ }
5328
5323
  var _anomalyDetector = null;
5329
5324
  function getAnomalyDetector() {
5330
5325
  if (!_anomalyDetector)
@@ -5356,14 +5351,14 @@ function setApiToken(newToken) {
5356
5351
  VIBEOS_API_DISABLED = false;
5357
5352
  VIBEOS_API_TOKEN = normalizeDirectApiToken(newToken);
5358
5353
  VIBEOS_API_BOOTSTRAP_TOKEN = readBootstrapTokenFromDisk() || VIBEOS_API_BOOTSTRAP_TOKEN;
5359
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5354
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5360
5355
  _apiClient = null;
5361
- setApiFallbackMode(false);
5362
- setApiFallbackSince(null);
5356
+ _apiFallbackMode = false;
5357
+ _apiFallbackSince = null;
5363
5358
  persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
5364
5359
  if (_anomalyDetector)
5365
5360
  _anomalyDetector.reset();
5366
- resetApiConnection();
5361
+ markApiConnected();
5367
5362
  console.error("[vibeOS] API token updated via setApiToken");
5368
5363
  } catch (e) {
5369
5364
  console.error("[vibeOS] Failed to update API token:", e.message);
@@ -5374,10 +5369,10 @@ function invalidateApiToken() {
5374
5369
  VIBEOS_API_DISABLED = true;
5375
5370
  VIBEOS_API_TOKEN = "";
5376
5371
  VIBEOS_API_BOOTSTRAP_TOKEN = "";
5377
- setApiEnabled(false);
5372
+ syncApiEnabledState(false);
5378
5373
  _apiClient = null;
5379
- setApiFallbackMode(false);
5380
- setApiFallbackSince(null);
5374
+ _apiFallbackMode = false;
5375
+ _apiFallbackSince = null;
5381
5376
  if (_anomalyDetector)
5382
5377
  _anomalyDetector.reset();
5383
5378
  persistBootstrapToken("");
@@ -5392,7 +5387,8 @@ function setApiBootstrapToken(newToken) {
5392
5387
  try {
5393
5388
  VIBEOS_API_DISABLED = false;
5394
5389
  VIBEOS_API_BOOTSTRAP_TOKEN = String(newToken || "").trim();
5395
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5390
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5391
+ markApiConnected();
5396
5392
  persistPrimaryApiEnvState({ disabled: false });
5397
5393
  persistBootstrapToken(VIBEOS_API_BOOTSTRAP_TOKEN);
5398
5394
  console.error("[vibeOS] Alpha bootstrap token updated");
@@ -5401,26 +5397,26 @@ function setApiBootstrapToken(newToken) {
5401
5397
  }
5402
5398
  }
5403
5399
  var _apiClient = null;
5404
- var _startupProbeDone = false;
5400
+ var _apiFallbackMode = false;
5401
+ var _apiFallbackSince = null;
5405
5402
  var _bootstrapExchangeInFlight = null;
5406
5403
  var _bootstrapExchangeFailedAt = 0;
5407
5404
  var _backendVersion = "";
5408
5405
  var FALLBACK_COOLDOWN_MS = 6e4;
5409
5406
  function tryResetFallbackCooldown() {
5410
- if (!isApiFallbackMode() || !getApiFallbackSince())
5407
+ if (!_apiFallbackMode || !_apiFallbackSince)
5411
5408
  return false;
5412
- const elapsed = Date.now() - new Date(getApiFallbackSince()).getTime();
5409
+ const elapsed = Date.now() - new Date(_apiFallbackSince).getTime();
5413
5410
  if (elapsed > FALLBACK_COOLDOWN_MS) {
5414
- setApiFallbackMode(false);
5415
- setApiFallbackSince(null);
5411
+ _apiFallbackMode = false;
5412
+ _apiFallbackSince = null;
5416
5413
  markApiConnected();
5417
5414
  return true;
5418
5415
  }
5419
5416
  return false;
5420
5417
  }
5421
- function denyReconnection(detail) {
5422
- setApiFallbackSince((/* @__PURE__ */ new Date()).toISOString());
5423
- console.warn(`[vibeOS] API health probe failed during reconnect: ${detail} \u2014 staying in fallback`);
5418
+ function getApiFallbackSince() {
5419
+ return _apiFallbackSince;
5424
5420
  }
5425
5421
  function recordBackendVersion(payload) {
5426
5422
  if (!payload || typeof payload !== "object")
@@ -5448,7 +5444,7 @@ async function ensureBootstrapExchange() {
5448
5444
  try {
5449
5445
  const client2 = new VibeOSApiClient({
5450
5446
  baseUrl: VIBEOS_API_URL,
5451
- timeout: PROBE_TIMEOUT
5447
+ timeout: 5e3
5452
5448
  });
5453
5449
  const apiToken = await client2.exchangeBootstrapToken(VIBEOS_API_BOOTSTRAP_TOKEN, ALPHA_BUILD_CHANNEL);
5454
5450
  if (!apiToken)
@@ -5472,14 +5468,14 @@ function syncApiTokenFromDisk() {
5472
5468
  const diskBootstrapToken = readBootstrapTokenFromDisk() || "";
5473
5469
  const envToken = normalizeDirectApiToken(process.env.VIBEOS_API_TOKEN);
5474
5470
  if (diskDisabled) {
5475
- if (!VIBEOS_API_DISABLED || VIBEOS_API_TOKEN || VIBEOS_API_BOOTSTRAP_TOKEN || isApiEnabled()) {
5471
+ if (!VIBEOS_API_DISABLED || VIBEOS_API_TOKEN || VIBEOS_API_BOOTSTRAP_TOKEN || VIBEOS_API_ENABLED) {
5476
5472
  VIBEOS_API_DISABLED = true;
5477
5473
  VIBEOS_API_TOKEN = "";
5478
5474
  VIBEOS_API_BOOTSTRAP_TOKEN = "";
5479
- setApiEnabled(false);
5475
+ syncApiEnabledState(false);
5480
5476
  _apiClient = null;
5481
- setApiFallbackMode(false);
5482
- setApiFallbackSince(null);
5477
+ _apiFallbackMode = false;
5478
+ _apiFallbackSince = null;
5483
5479
  resetApiConnection();
5484
5480
  console.error("[vibeOS] API token disabled from disk (alpha kill switch active)");
5485
5481
  }
@@ -5488,33 +5484,39 @@ function syncApiTokenFromDisk() {
5488
5484
  if (diskToken && diskToken !== VIBEOS_API_TOKEN) {
5489
5485
  VIBEOS_API_DISABLED = false;
5490
5486
  VIBEOS_API_TOKEN = diskToken;
5491
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5487
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5492
5488
  _apiClient = null;
5493
- setApiFallbackMode(false);
5494
- setApiFallbackSince(null);
5495
- resetApiConnection();
5489
+ _apiFallbackMode = false;
5490
+ _apiFallbackSince = null;
5491
+ markApiConnected();
5496
5492
  console.error("[vibeOS] API token synced from disk (disk is newer)");
5497
5493
  } else if (diskBootstrapToken && diskBootstrapToken !== VIBEOS_API_BOOTSTRAP_TOKEN) {
5498
5494
  VIBEOS_API_DISABLED = false;
5499
5495
  VIBEOS_API_BOOTSTRAP_TOKEN = diskBootstrapToken;
5500
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5501
- setApiFallbackMode(false);
5502
- setApiFallbackSince(null);
5503
- resetApiConnection();
5496
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5497
+ _apiFallbackMode = false;
5498
+ _apiFallbackSince = null;
5499
+ markApiConnected();
5504
5500
  console.error("[vibeOS] Alpha bootstrap token synced from disk (disk is newer)");
5505
5501
  } else if (!diskToken && VIBEOS_API_TOKEN) {
5506
5502
  persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
5507
5503
  console.error("[vibeOS] API token persisted to disk from memory (disk was empty)");
5508
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && !!VIBEOS_API_TOKEN);
5504
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && !!VIBEOS_API_TOKEN);
5505
+ markApiConnected();
5509
5506
  } else if (envToken && !diskToken && !VIBEOS_API_TOKEN) {
5510
5507
  VIBEOS_API_DISABLED = false;
5511
5508
  VIBEOS_API_TOKEN = envToken;
5512
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5509
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5510
+ markApiConnected();
5513
5511
  console.error("[vibeOS] API token loaded from VIBEOS_API_TOKEN env var");
5514
5512
  } else {
5515
5513
  VIBEOS_API_DISABLED = false;
5514
+ if (!VIBEOS_API_TOKEN && !hasPrimaryTokenOnDisk()) {
5515
+ VIBEOS_API_TOKEN = EMBEDDED_API_TOKEN;
5516
+ }
5516
5517
  VIBEOS_API_BOOTSTRAP_TOKEN ||= EMBEDDED_API_TOKEN;
5517
- setApiEnabled(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5518
+ syncApiEnabledState(process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN));
5519
+ markApiConnected();
5518
5520
  }
5519
5521
  }
5520
5522
  function getApiClient2() {
@@ -5523,72 +5525,31 @@ function getApiClient2() {
5523
5525
  _apiClient = new VibeOSApiClient({
5524
5526
  baseUrl: VIBEOS_API_URL,
5525
5527
  apiToken: VIBEOS_API_TOKEN,
5526
- timeout: PROBE_TIMEOUT
5528
+ timeout: 5e3
5527
5529
  });
5528
5530
  }
5529
5531
  return _apiClient;
5530
5532
  }
5531
5533
  function isApiFallback2() {
5532
- return isApiFallbackMode() || !isApiEnabled();
5534
+ return _apiFallbackMode || isApiFallbackMode() || !isApiEnabled();
5533
5535
  }
5534
- function isApiConnected2() {
5536
+ function isApiConnected() {
5535
5537
  tryResetFallbackCooldown();
5536
- return isApiConnected();
5538
+ return isApiEnabled();
5537
5539
  }
5538
5540
  function getBackendVersion() {
5539
5541
  return _backendVersion;
5540
5542
  }
5541
- function getApiFallbackSince2() {
5542
- return getApiFallbackSince();
5543
- }
5544
5543
  async function remoteCall(method, args, fallbackFn) {
5545
- if (!_startupProbeDone && !isApiFallbackMode()) {
5546
- _startupProbeDone = true;
5547
- try {
5548
- syncApiTokenFromDisk();
5549
- if (isApiEnabled()) {
5550
- const probeClient = getApiClient2();
5551
- if (probeClient) {
5552
- await probeClient.health();
5553
- markApiConnected();
5554
- }
5555
- }
5556
- } catch {
5557
- }
5558
- }
5559
5544
  syncApiTokenFromDisk();
5560
5545
  if (!VIBEOS_API_TOKEN && VIBEOS_API_BOOTSTRAP_TOKEN) {
5561
5546
  await ensureBootstrapExchange();
5562
5547
  syncApiTokenFromDisk();
5563
- if (VIBEOS_API_TOKEN)
5564
- markApiConnected();
5565
5548
  }
5566
- if (isApiFallbackMode() && getApiFallbackSince()) {
5567
- const elapsed = Date.now() - new Date(getApiFallbackSince()).getTime();
5568
- if (elapsed > FALLBACK_COOLDOWN_MS) {
5569
- try {
5570
- const probeClient = getApiClient2();
5571
- if (probeClient) {
5572
- await probeClient.health();
5573
- markApiConnected();
5574
- } else {
5575
- denyReconnection("no client");
5576
- if (fallbackFn)
5577
- return fallbackFn();
5578
- return null;
5579
- }
5580
- } catch (probeErr) {
5581
- const probeStatus = probeErr?.statusCode || probeErr?.status || 0;
5582
- const probeBody = probeErr?.response?.body || probeErr?.body || "";
5583
- const probePreview = typeof probeBody === "string" ? probeBody.substring(0, 80) : String(probeBody).substring(0, 80);
5584
- denyReconnection(probeStatus ? `status=${probeStatus} body=${probePreview}` : `message=${probeErr?.message || probeErr}`);
5585
- if (fallbackFn)
5586
- return fallbackFn();
5587
- return null;
5588
- }
5589
- }
5549
+ if (tryResetFallbackCooldown()) {
5550
+ console.warn("[vibeOS] API fallback cooldown expired \u2014 retrying API");
5590
5551
  }
5591
- if (!isApiEnabled() || isApiFallbackMode()) {
5552
+ if (!isApiEnabled() || _apiFallbackMode) {
5592
5553
  if (fallbackFn)
5593
5554
  return fallbackFn();
5594
5555
  return null;
@@ -5610,12 +5571,13 @@ async function remoteCall(method, args, fallbackFn) {
5610
5571
  const result = await client2[method](...args);
5611
5572
  if (method === "health")
5612
5573
  recordBackendVersion(result);
5613
- if (isApiFallbackMode()) {
5614
- setApiFallbackMode(false);
5615
- setApiFallbackSince(null);
5574
+ if (_apiFallbackMode) {
5575
+ _apiFallbackMode = false;
5576
+ _apiFallbackSince = null;
5577
+ console.warn(`[vibeOS] API reconnected \u2014 ${method} OK`);
5616
5578
  }
5617
- setApiFallbackMode(false);
5618
- setApiFallbackSince(null);
5579
+ _apiFallbackMode = false;
5580
+ _apiFallbackSince = null;
5619
5581
  markApiConnected();
5620
5582
  return result;
5621
5583
  } catch (err) {
@@ -5623,9 +5585,9 @@ async function remoteCall(method, args, fallbackFn) {
5623
5585
  const body = err?.response?.body || err?.body || "";
5624
5586
  const bodyPreview = typeof body === "string" ? body.substring(0, 120) : String(body).substring(0, 120);
5625
5587
  const detail = status ? `status=${status} body=${bodyPreview}` : `message=${err?.message || err}`;
5626
- if (!isApiFallbackMode()) {
5627
- setApiFallbackMode(true);
5628
- setApiFallbackSince((/* @__PURE__ */ new Date()).toISOString());
5588
+ if (!_apiFallbackMode) {
5589
+ _apiFallbackMode = true;
5590
+ _apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
5629
5591
  console.error(`[vibeOS] API fallback activated (${method}): ${detail}`);
5630
5592
  }
5631
5593
  if (status === 401 || status === 403) {
@@ -9294,7 +9256,7 @@ function createTrinityTool(deps) {
9294
9256
  `Model: ${activeSlot} (${tiers?.[activeSlot]?.oc || deps.currentModel || "(unset)"})`,
9295
9257
  `Provider: ${execution.provider_label}`,
9296
9258
  `Quality: ${execution.quality_label}`,
9297
- ...isApiConnected2() ? [`Backend: connected${getBackendVersion() ? ` (${getBackendVersion()})` : ""}`] : [`Backend: offline`],
9259
+ ...isApiConnected() ? [`Backend: connected${getBackendVersion() ? ` (${getBackendVersion()})` : ""}`] : [`Backend: offline`],
9298
9260
  ...sel.requested_optimization_mode ? [`Requested mode: ${sel.requested_optimization_mode}`] : [],
9299
9261
  ...totalTurns > 0 ? [`Split: brain ${brainPct}% / worker ${workerPct}% (${totalTurns} total)`] : [],
9300
9262
  `Thinking: ${effectiveLevel}`,
@@ -12202,7 +12164,7 @@ var onSystemTransform = async (_input, output) => {
12202
12164
  const system = output?.system;
12203
12165
  if (!Array.isArray(system))
12204
12166
  return;
12205
- if (isApiConnected2()) {
12167
+ if (isApiConnected()) {
12206
12168
  try {
12207
12169
  const bb = loadBlackboxState();
12208
12170
  if (!bb.enabled || _blackboxEnabled === false) {
@@ -12547,8 +12509,8 @@ function buildFooterLine(input) {
12547
12509
 
12548
12510
  // src/lib/hooks/footer.js
12549
12511
  var IS_CLI_RUNTIME = Boolean(process.stdout?.isTTY || process.stderr?.isTTY || process.stdin?.isTTY);
12550
- var IS_TEST_RUNTIME2 = process.env.VIBEOS_MCP_PORT === "0" || process.env.NODE_ENV === "test" || process.env.CI === "true";
12551
- var FOOTER_DEBUG_STDERR = process.env.VIBEOS_DEBUG_FOOTER === "1" || !IS_CLI_RUNTIME && !IS_TEST_RUNTIME2;
12512
+ var IS_TEST_RUNTIME = process.env.VIBEOS_MCP_PORT === "0" || process.env.NODE_ENV === "test" || process.env.CI === "true";
12513
+ var FOOTER_DEBUG_STDERR = process.env.VIBEOS_DEBUG_FOOTER === "1" || !IS_CLI_RUNTIME && !IS_TEST_RUNTIME;
12552
12514
  function footerDebug(...args) {
12553
12515
  if (FOOTER_DEBUG_STDERR)
12554
12516
  console.error(...args);
@@ -12789,7 +12751,7 @@ async function _appendFooter(input, output, directory3) {
12789
12751
  return;
12790
12752
  const ltTotal = ltTasks + ltCache;
12791
12753
  const activeSlot = selNowFooter.active_slot || "brain";
12792
- const flashIcon = isApiConnected2() ? " \u26A1" : "";
12754
+ const flashIcon = isApiConnected() ? " \u26A1" : "";
12793
12755
  const displayMode2 = autoSelectMode2(currentSubRegime2, _footerStress);
12794
12756
  const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode2, activeSlot);
12795
12757
  const vibeLine = buildFooterLine({
@@ -14915,7 +14877,7 @@ var onToolExecuteAfter = async (input, output) => {
14915
14877
  const displayMode2 = autoSelectMode2(currentSubRegime2, latestUserIntent ? scoreStress(latestUserIntent) : 0);
14916
14878
  const vibeBrand = resolveBrand(displayMode2, activeSlot);
14917
14879
  const sessionSlot = loadSessionSlot(currentSid);
14918
- const flashIcon = isApiConnected2() ? " \u26A1" : "";
14880
+ const flashIcon = isApiConnected() ? " \u26A1" : "";
14919
14881
  _footerText = buildFooterLine({
14920
14882
  activeSlot,
14921
14883
  providerLabel: execution.provider_label,
@@ -15665,11 +15627,11 @@ async function ensureMcpServerRunning() {
15665
15627
  version: readPackageVersion(),
15666
15628
  todos: loadTodos(),
15667
15629
  fallbackThinking: thinkingLevel(loadCredit()),
15668
- backendConnected: isApiConnected2(),
15630
+ backendConnected: isApiConnected(),
15669
15631
  backendHealthUrl: `${VIBEOS_API_URL}/health`,
15670
15632
  backendVersion: getBackendVersion(),
15671
15633
  apiFallbackMode: isApiFallback2(),
15672
- apiFallbackSince: getApiFallbackSince2(),
15634
+ apiFallbackSince: getApiFallbackSince(),
15673
15635
  modelLocked: _modelLocked,
15674
15636
  lockedSlot: _lockedSlot,
15675
15637
  lockedModel: _lockedModel
@@ -16056,7 +16018,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
16056
16018
  saveBlackboxState,
16057
16019
  isApiFallback: () => isApiFallback2(),
16058
16020
  get _apiFallbackSince() {
16059
- return getApiFallbackSince2();
16021
+ return getApiFallbackSince();
16060
16022
  },
16061
16023
  reportsIndex: reportsIndexStable,
16062
16024
  saveReportsIndex: saveReportsIndexStable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.25.11",
3
+ "version": "0.25.12",
4
4
  "description": "Cost-aware delegation enforcer for OpenCode. Tracks model usage, routes Task subagents to cheaper tiers, surfaces cumulative savings in chat. Includes research audit, reporting framework, project memory, progressive scratchpad decadence, and trinity CLI for brain/medium/cheap slot switching.",
5
5
  "scripts": {
6
6
  "release": "node scripts/release.mjs",
@@ -86,22 +86,25 @@ try {
86
86
  // Auto-register in opencode.json so OpenCode loads the plugin
87
87
  try {
88
88
  const ocConfigPath = join(homedir(), ".config", "opencode", "opencode.json")
89
+ mkdirSync(dirname(ocConfigPath), { recursive: true })
90
+ let config = {}
89
91
  if (existsSync(ocConfigPath)) {
90
92
  const raw = readFileSync(ocConfigPath, "utf-8")
91
- let config = {}
92
93
  try {
93
94
  const cleaned = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "")
94
95
  config = JSON.parse(cleaned)
95
96
  } catch {
96
97
  config = {}
97
98
  }
98
- if (!Array.isArray(config.plugin)) config.plugin = []
99
- const hasVibeOs = config.plugin.some(p => typeof p === "string" && p.includes("vibeOS"))
100
- if (!hasVibeOs) {
101
- config.plugin.push("./plugins/vibeOS.js")
102
- writeFileSync(ocConfigPath, JSON.stringify(config, null, 2) + "\n")
103
- process.stderr.write("[vibeOS deploy] Registered vibeOS in opencode.json\n")
104
- }
99
+ }
100
+ if (!config || typeof config !== "object" || Array.isArray(config)) config = {}
101
+ if (!Array.isArray(config.plugin)) config.plugin = []
102
+ const hasVibeOs = config.plugin.some(p => typeof p === "string" && p.includes("vibeOS"))
103
+ if (!hasVibeOs) {
104
+ config.$schema ||= "https://opencode.ai/config.json"
105
+ config.plugin.push("./plugins/vibeOS.js")
106
+ writeFileSync(ocConfigPath, JSON.stringify(config, null, 2) + "\n")
107
+ process.stderr.write("[vibeOS deploy] Registered vibeOS in opencode.json\n")
105
108
  }
106
109
  } catch {
107
110
  process.stderr.write("[vibeOS deploy] Could not auto-register in opencode.json (plugin may need manual config)\n")