vibeostheog 0.23.26 → 0.23.28

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,11 @@
1
+ ## 0.23.28
2
+ - fix: sync all .ts sources + 21 ML pipeline integration tests (805/0)
3
+
4
+
5
+ ## 0.23.27
6
+ - fix: ML-chosen optimization_mode dances in footer + → arrow
7
+
8
+
1
9
  ## 0.23.26
2
10
  - fix: footer primary tier = ML decision (vector_changed_slot), ✓ when applied
3
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.23.26",
3
+ "version": "0.23.28",
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",
@@ -14,8 +14,8 @@
14
14
  "checkpoint:validate": "node scripts/checkpoint-validate.mjs",
15
15
  "test:scripts": "node --test scripts/tests/checkpoint-validate.test.mjs tests/release-pack.test.mjs",
16
16
  "ts:audit": "node scripts/ts-audit.mjs",
17
- "test": "VIBEOS_MCP_PORT=0 node --test --test-timeout=240000 tests/deep_integration.test.mjs tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_trinity_mega_regression.test.mjs tests/test_multisession_mega.test.mjs tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
18
- "test:ci": "VIBEOS_MCP_PORT=0 node --test --test-timeout=120000 tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_first_install_autoconfig.mjs tests/deep_integration.test.mjs tests/e2e_workflows.test.mjs tests/integration_cross_module.test.mjs tests/privacy_telemetry.test.mjs tests/release-pack.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_ml_cache_mega.test.mjs tests/test_mode_brand.test.mjs tests/test_multisession_mega.test.mjs tests/test_trinity_mega_regression.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
17
+ "test": "VIBEOS_MCP_PORT=0 node --test --test-timeout=240000 tests/deep_integration.test.mjs tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_trinity_mega_regression.test.mjs tests/test_multisession_mega.test.mjs tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_ml_pipeline_e2e.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
18
+ "test:ci": "VIBEOS_MCP_PORT=0 node --test --test-timeout=120000 tests/production_regressions.test.mjs tests/release_hardening_tigerteam.test.mjs tests/test_const_assignment_regression.test.mjs tests/test_diagnose_cmd.test.mjs tests/test_install_and_recovery.test.mjs tests/test_saveos_e2e_cleanup.test.mjs tests/test_tdd_enforcer.test.mjs tests/test_10fixes_regression.test.mjs tests/test_cross_session_regression.test.mjs tests/test_mega_all_fixes.test.mjs tests/test_smart_cache_regression.test.mjs src/tests/*.test.js src/utils/tests/*.test.mjs \"src/vibeOS-lib/tests/auto-select-mode.test.mjs\" \"src/vibeOS-lib/tests/blackbox-regression.test.mjs\" \"src/vibeOS-lib/tests/blackbox-smoke.test.mjs\" \"src/vibeOS-lib/tests/budget-first-mode.test.mjs\" \"src/vibeOS-lib/tests/flow-enforcer.test.mjs\" \"src/vibeOS-lib/tests/flow-secrets.test.mjs\" \"src/vibeOS-lib/tests/session-metrics.test.mjs\" \"src/vibeOS-lib/tests/test_stress.test.mjs\" tests/test_blackbox_default_enabled.test.mjs tests/test_mega_regressions.test.mjs tests/test_delegation_enforcer.test.mjs tests/test_first_install_autoconfig.mjs tests/deep_integration.test.mjs tests/e2e_workflows.test.mjs tests/integration_cross_module.test.mjs tests/privacy_telemetry.test.mjs tests/release-pack.test.mjs tests/test_api_migration.neutral.test.mjs tests/test_internals_stress_patterns_offtopic.test.mjs tests/test_ml_cache_mega.test.mjs tests/test_mode_brand.test.mjs tests/test_multisession_mega.test.mjs tests/test_trinity_mega_regression.test.mjs tests/test_ml_pipeline_e2e.test.mjs tests/test_vibeultrax_pipeline_integration.test.mjs tests/test_cv_ml_integration.test.mjs src/lib/hooks/tests/chat-transform-cv-gate.test.js src/lib/hooks/tests/sync-control-settings.test.mjs",
19
19
  "guard": "bash plugins/vibetheog-guard/scripts/run-guard.sh",
20
20
  "guard:full": "VIBETHEOG_GUARD_FULL=1 bash plugins/vibetheog-guard/scripts/run-guard.sh",
21
21
  "hook:precommit": "bash plugins/vibetheog-guard/hooks/pre-commit.sh",
@@ -4,7 +4,7 @@ import { join, basename } from "node:path";
4
4
  import { createHash } from "node:crypto";
5
5
  import { currentModel, currentProjectFingerprint, currentProjectName, _blackboxEnabled, loadSelection, writeSelection, safeJsonParse, applyDecadence, getSessionScratchpadDir, ensureSessionScratchpadDirs, indexAppend, briefedProjects, getActiveJobForProject, loadTodos, promotedProjectPatterns, detectTechStack, projectFingerprint, SCRATCHPAD_ROOT, TRINITY_OPENCODE_CONFIG, TIERS_FILE, loadGlobalLearning, setCurrentProjectFingerprint, setCurrentProjectName, stableJson, TOOL_NAME_NORMALIZE, _cacheDb, recordCacheSaving, } from "../state.js";
6
6
  import { applySlot, TRINITY_CHEAP, TRINITY_MEDIUM, cacheSavePer1MInputTokens, } from "../pricing.js";
7
- import { scoreStress, classifyTurnSimple, loadOptimizationMode, saveOptimizationMode, selectOptimizationModeRemote, computeControlVector, getBlackboxTracker, loadBlackboxState as loadBlackboxStateFromCtx, saveBlackboxState as saveBlackboxStateToCtx, extractLastUserText, isLikelyOffTopic, fetchBlackboxEnrichment, estimateContextBudget, buildControlHistoryEntry, setBlackboxEnabled, } from "../turn-classify.js";
7
+ import { scoreStress, classifyTurnSimple, loadOptimizationMode, selectOptimizationModeRemote, computeControlVector, getBlackboxTracker, loadBlackboxState as loadBlackboxStateFromCtx, saveBlackboxState as saveBlackboxStateToCtx, extractLastUserText, isLikelyOffTopic, fetchBlackboxEnrichment, estimateContextBudget, buildControlHistoryEntry, setBlackboxEnabled, } from "../turn-classify.js";
8
8
  import { applyBudgetFirstMode, peekBudgetFirstMode } from "../mode-policy.js";
9
9
  import { BRANDED_MODES, RUNTIME_MODES } from "../mode-router.js";
10
10
  import { addCacheEntry, extractRecentCacheOutputs } from "../../vibeOS-lib/smart-cache.js";
@@ -49,7 +49,7 @@ async function apiComputeControlVector(state, action, optimizationMode) {
49
49
  const res = await remoteCall("blackboxControlVector", [state, action, optimizationMode], null);
50
50
  if (res?.control_vector) {
51
51
  const local = computeControlVector(state, action, optimizationMode);
52
- return { ...res.control_vector, tier_bias: local.tier_bias };
52
+ return { ...res.control_vector, tier_bias: local.tier_bias, optimization_mode: local.optimization_mode };
53
53
  }
54
54
  }
55
55
  catch { }
@@ -207,9 +207,8 @@ export function syncControlSettings(cv, options = {}) {
207
207
  if (cv.thinking_mode && currentSel.thinking_level !== "full")
208
208
  writeIf("thinking_level", cv.thinking_mode);
209
209
  if (persistOptimizationMode && cv.optimization_mode && userOptMode !== "auto") {
210
- if (userOptMode !== cv.optimization_mode && !userSetMode) {
211
- writeSessionSlot(sid + "_opt", cv.optimization_mode);
212
- saveOptimizationMode(cv.optimization_mode);
210
+ if (userOptMode !== cv.optimization_mode) {
211
+ writeIf("optimization_mode", cv.optimization_mode);
213
212
  }
214
213
  }
215
214
  const slot = cv.tier_bias;
@@ -219,7 +218,7 @@ export function syncControlSettings(cv, options = {}) {
219
218
  writeSessionSlot(sid, slot);
220
219
  writeIf("vector_changed_slot", slot);
221
220
  writeIf("vector_changed_at", Date.now());
222
- const applied = applySlot(slot, onSystemTransform._directory || "");
221
+ const applied = applySlot(slot);
223
222
  if (!applied?.ok) {
224
223
  console.error(`[vibeOS] failed to apply slot ${slot}: ${applied?.reason || "unknown"}`);
225
224
  }
@@ -288,39 +288,22 @@ async function _appendFooter(input, output, directory) {
288
288
  const activeSlot = selNowFooter.vector_changed_slot || selNowFooter.active_slot || "brain";
289
289
  const vibeBrand = brandMap[optModeFooter] || (activeSlot === "brain" ? "VibeQMaX" : "VibeMaX");
290
290
  const modeLabel = modeCapitalized(brandedToRuntime[optMode] || optMode);
291
- const tierIcon = activeSlot === "brain" ? "\ud83e\udde0" : activeSlot === "medium" ? "\u2699" : activeSlot === "cheap" ? "\ud83c\udf81" : "\u26a1";
292
- const flashIcon = isApiConnected() ? " \u26a1" : "";
293
- let vibeLine = `\u2014 ${tierIcon} ${activeSlot} | ${execution.provider_label} | ${modelDisplayName(execution.model)}`;
291
+ const tierIcon = activeSlot === "brain" ? "🧠" : activeSlot === "medium" ? "" : activeSlot === "cheap" ? "🎁" : "";
292
+ const flashIcon = isApiConnected() ? " " : "";
293
+ let vibeLine = `— ${tierIcon} ${activeSlot} | ${execution.provider_label} | ${modelDisplayName(execution.model)}`;
294
294
  if (ltTotal > 0) {
295
295
  vibeLine += ` | $${formatUsd(ltTotal)}`;
296
296
  }
297
297
  if (isApiConnected()) {
298
298
  vibeLine += ` | ${vibeBrand}${flashIcon}`;
299
299
  }
300
- try {
301
- const sel = loadSelection();
302
- const realSlot = sel?.active_slot || "brain";
303
- const wantedSlot = sel?.vector_changed_slot;
304
- if (wantedSlot) {
305
- if (wantedSlot !== realSlot) {
306
- vibeLine += ` | \u2192 ${wantedSlot}`;
307
- } else {
308
- vibeLine += ` | \u2713`;
309
- }
310
- }
300
+ const displayMode = selNowFooter?.optimization_mode || optMode || "auto";
301
+ if (displayMode && displayMode !== "auto") {
302
+ vibeLine += ` | ${displayMode}`;
311
303
  }
312
- catch { }
313
- try {
314
- const sel = loadSelection();
315
- if (sel?.vector_changed_slot) {
316
- if (sel.vector_changed_slot !== activeSlot) {
317
- vibeLine += ` | → ${sel.vector_changed_slot}`;
318
- } else {
319
- vibeLine += ` | ✓`;
320
- }
321
- }
304
+ if (selNowFooter?.vector_changed_slot) {
305
+ vibeLine += ` | → ${selNowFooter.vector_changed_slot}`;
322
306
  }
323
- catch { }
324
307
  const footerText = stripped + `\n\n${vibeLine} —`;
325
308
  if (_blackboxEnabled) {
326
309
  try {
@@ -79,7 +79,7 @@ function persistSessionPolicy(state, session, policy, mode) {
79
79
  active: !!policy.active,
80
80
  mode,
81
81
  reason: policy.reason || BASELINE_MODE,
82
- shouldPersistRequestedMode: false,
82
+ shouldPersistRequestedMode: true,
83
83
  };
84
84
  }
85
85
  export function peekBudgetFirstMode(input = {}) {
@@ -90,14 +90,14 @@ export function peekBudgetFirstMode(input = {}) {
90
90
  active: true,
91
91
  mode: normalizeMode(policy.active_mode),
92
92
  reason: policy.reason || "episode",
93
- shouldPersistRequestedMode: false,
93
+ shouldPersistRequestedMode: true,
94
94
  };
95
95
  }
96
96
  return {
97
97
  active: false,
98
98
  mode: BASELINE_MODE,
99
99
  reason: "budget",
100
- shouldPersistRequestedMode: false,
100
+ shouldPersistRequestedMode: true,
101
101
  };
102
102
  }
103
103
  export function applyBudgetFirstMode(input = {}) {
@@ -1213,7 +1213,7 @@ export function _refreshModel(directory) {
1213
1213
  for (const s of getTrinitySlotOrder(t)) {
1214
1214
  if (t?.trinity?.[s]?.oc === cfgModel) {
1215
1215
  t.selection.active_slot = s;
1216
- const _tmp = TIERS_FILE + ".tmp." + Date.now();
1216
+ const _tmp = TIERS_FILE + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
1217
1217
  writeFileSync(_tmp, JSON.stringify(t, null, 2) + "\n", "utf-8");
1218
1218
  renameSync(_tmp, TIERS_FILE);
1219
1219
  if (DEBUG_INTERNALS)
@@ -1237,9 +1237,10 @@ export function applySlot(slot, projectDir = "") {
1237
1237
  if (!ocModel)
1238
1238
  return { ok: false, reason: `slot '${slot}' has no oc model` };
1239
1239
  j.selection.active_slot = slot;
1240
- const _tmp = TIERS_FILE + ".tmp." + Date.now() + "." + Math.random().toString(36).slice(2, 8);
1240
+ const _tmp = TIERS_FILE + ".tmp." + Date.now();
1241
1241
  writeFileSync(_tmp, JSON.stringify(j, null, 2) + "\n", "utf-8");
1242
1242
  renameSync(_tmp, TIERS_FILE);
1243
+ // Prefer project-local config to avoid mutating global provider/dropdown config.
1243
1244
  const dir = projectDir || process.cwd();
1244
1245
  const localOcConfig = join(dir, "opencode.json");
1245
1246
  const ocConfig = existsSync(localOcConfig)
@@ -67,8 +67,9 @@ export function bootstrapOptimizationSession() {
67
67
  return { mode: resolvedMode, slot: resolvedSlot };
68
68
  }
69
69
  export async function selectOptimizationModeRemote(subRegime, stressMultiplier, fallbackMode) {
70
- if (!isApiFallback()) return autoSelectMode(subRegime || "INIT", stressMultiplier);
71
70
  const fallback = resolveOptimizationMode(subRegime, stressMultiplier, fallbackMode);
71
+ if (!isApiFallback())
72
+ return autoSelectMode(subRegime || "INIT", stressMultiplier);
72
73
  try {
73
74
  if (!isApiFallback()) {
74
75
  const client = getApiClient();