vibeostheog 0.24.30 → 0.24.32

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,13 +1,12 @@
1
- ## 0.24.30
2
- - fix: prefer trinity slot in footer
3
-
4
-
5
- ## 0.24.29
1
+ ## 0.24.32
6
2
  - feat: promote data-backed experimental regimes (#158)
7
3
  - feat: promote data-backed experimental regimes
8
- - fix: prefer trinity slot in footer
4
+ - fix: make footer state truthful
9
5
  - test: add live lifecycle regression
6
+ - chore: v0.24.31 (#163)
10
7
  - chore: v0.24.28
8
+ Merge pull request #162 from DrunkkToys/codex/test-production-proof
9
+ Merge pull request #160 from DrunkkToys/codex/release-patch-0.24.28
11
10
  Fix clean CI sync for generated modules
12
11
  Fix CI sync for generated modules
13
12
  Fix CI artifact sync
@@ -19,6 +18,12 @@ Strengthen cascade lifecycle coverage
19
18
  Merge branch 'master' of https://github.com/DrunkkToys/vibeOS into codex/release-patch-0.24.28
20
19
 
21
20
 
21
+ ## 0.24.31
22
+ - fix: make footer state truthful
23
+ - fix: quiet greetings should not inherit stale tdd tags
24
+ - test: add live regression for stale config footer mismatch
25
+
26
+
22
27
  ## 0.24.25
23
28
  - fix: heal stale vibelitex recovery across cascade
24
29
 
package/README.md CHANGED
@@ -104,7 +104,7 @@ Benchmarked on 1000 simulated questions across 20 runs, using model accuracies f
104
104
  | **Flow enforcer** | Pattern-rule checks on write/edit. Extracts TODO/FIXME into append-only queue. |
105
105
  | **TDD enforcer** | Auto-creates test skeletons for changed source. Strict mode: TODO tests fail. |
106
106
  | **Pattern learner** | Tracks recurring struggle/routine patterns per project. |
107
- | **VibeBoX** | 7 canonical sub-regimes plus promoted ML/runtime regimes (IMPLEMENTING, RESEARCH, REVIEWING, DESIGNING, AUDIT, FORENSIC), 11 features per turn, 4 loop intervention levels, PIVOT/SWITCH detection. Auto-mode maps regime to optimization mode. |
107
+ | **VibeBoX** | 7 sub-regimes, 11 features per turn, 4 loop intervention levels, PIVOT/SWITCH detection. Auto-mode maps regime to optimization mode. |
108
108
  | **Stress-aware routing** | Stress gauge in footer. Stress > 1.5 escalates to quality mode. |
109
109
  | **Cache savings** | Separate cache_savings_usd tracking for scratchpad cache hits. |
110
110
  | **Report tools** | report-save, report-list, report-read, research-audit. |
@@ -238,20 +238,15 @@ When the remote API is unreachable, the plugin degrades gracefully to rule-based
238
238
 
239
239
  ### VibeBoX Decision Engine
240
240
 
241
- Canonical blackbox core: 7 sub-regimes (INIT, DIVERGENT, EXPLORING, REFINING, CONVERGING, CLOSED, LOOPING). The runtime and ML layers also surface promoted regime tags for real workflow signals: IMPLEMENTING, RESEARCH, REVIEWING, DESIGNING, AUDIT, and FORENSIC. Classification uses entropy trends, action consistency, feature contradiction, and embedding drift. 11 derived features per turn. 4 loop intervention levels. PIVOT/SWITCH detection. Outcome tracking from satisfaction signals.
241
+ 7 sub-regimes (INIT, DIVERGENT, EXPLORING, REFINING, CONVERGING, CLOSED, LOOPING). Classification via entropy trends, action consistency, feature contradiction, embedding drift. 11 derived features per turn. 4 loop intervention levels. PIVOT/SWITCH detection. Outcome tracking from satisfaction signals.
242
242
 
243
243
  Regime -> mode mapping via syncControlSettings():
244
244
 
245
245
  | Regime | Mode | Enforce | Flow | TDD | Tier | Think |
246
246
  |--------|------|---------|------|-----|------|-------|
247
247
  | INIT / DIVERGENT / EXPLORING / REFINING | vibemax (default) | relaxed | audit | lazy | cheap | off |
248
- | IMPLEMENTING | quality | strict | strict | quality | brain | full |
249
- | RESEARCH / DESIGNING | longrun | relaxed | audit | lazy | medium | off |
250
- | REVIEWING | audit | relaxed | audit | lazy | medium | brief |
251
248
  | CONVERGING / CLOSED | quality | strict | strict | quality | brain | full |
252
249
  | LOOPING | speed | relaxed | audit | lazy | medium | off |
253
- | AUDIT | audit | relaxed | audit | lazy | medium | brief |
254
- | FORENSIC | forensic | relaxed | audit | lazy | medium | full |
255
250
 
256
251
  Stress > 1.5 escalates any regime to quality.
257
252
 
package/dist/vibeOS.js CHANGED
@@ -5290,12 +5290,6 @@ function resolveExecutionIdentity(modelId, directory3 = "") {
5290
5290
  model_label: shortModelName(resolved || raw)
5291
5291
  };
5292
5292
  }
5293
- function resolveTrinityDisplayModel(directory3 = "", activeSlot = "", liveModel = "", currentModelId = "") {
5294
- const slot = String(activeSlot || "").trim();
5295
- const slotModel = slot === "brain" ? TRINITY_BRAIN || "" : slot === "medium" ? TRINITY_MEDIUM || "" : slot === "cheap" ? TRINITY_CHEAP || "" : "";
5296
- const raw = [slotModel, liveModel, currentModelId].map((value) => String(value || "").trim()).find(Boolean) || "";
5297
- return resolveDisplayModelId(raw, directory3) || raw;
5298
- }
5299
5293
  function _providerOfModel(modelId, fallbackProvider = "") {
5300
5294
  const provider = getModelProvider(modelId);
5301
5295
  return provider || String(fallbackProvider || "").trim();
@@ -11278,6 +11272,28 @@ function thinkingDirective(level) {
11278
11272
  }
11279
11273
  return `[thinking policy] Reasoning depth: OFF (manually set, ${creditNote}). Respond directly, avoid extra scratch work, and reserve extended thinking for when the user asks for it.`;
11280
11274
  }
11275
+ function regimeAwareToolStyleDirective(regime, mode, stress) {
11276
+ const normalizedRegime = String(regime || "INIT").toUpperCase();
11277
+ const normalizedMode = String(mode || "budget").toLowerCase();
11278
+ const stressLabel = stress > 1.5 ? "high stress" : stress > 0.4 ? "elevated stress" : "calm";
11279
+ const regimeToneByName = {
11280
+ INIT: "The session is starting, so keep descriptions lightweight, status-oriented, and easy to scan.",
11281
+ DIVERGENT: "The session is branching, so keep descriptions exploratory and open to alternatives without sounding vague.",
11282
+ EXPLORING: "The session is investigating, so keep descriptions discovery-oriented, specific, and lightweight.",
11283
+ REFINING: "The session is polishing implementation, so keep descriptions action-oriented, concrete, and tied to the next visible code step.",
11284
+ IMPLEMENTING: "The session is executing implementation work, so keep descriptions exact, build-focused, and next-step driven.",
11285
+ RESEARCH: "The session is researching, so keep descriptions evidence-seeking, careful, and explicit about what was checked.",
11286
+ REVIEWING: "The session is reviewing, so keep descriptions audit-style, traceable, and focused on proof.",
11287
+ DESIGNING: "The session is designing, so keep descriptions structured, intent-driven, and aligned to the target shape.",
11288
+ CONVERGING: "The session is converging, so keep descriptions closure-oriented, exact, and ready for final verification.",
11289
+ CLOSED: "The session is closing, so keep descriptions final, concise, and clearly outcome-focused.",
11290
+ LOOPING: "The session is looping, so keep descriptions verification-first, state-aware, and loop-breaking.",
11291
+ AUDIT: "The session is auditing, so keep descriptions evidence-first, compliance-aware, and traceable.",
11292
+ FORENSIC: "The session is doing forensic work, so keep descriptions investigative, reproducible, and proof-heavy."
11293
+ };
11294
+ const regimeTone = regimeToneByName[normalizedRegime] || "The session should stay aligned to the active regime and avoid generic filler.";
11295
+ return `[tool style: dopamine] Active regime: ${normalizedRegime}; mode: ${normalizedMode}; stress: ${stressLabel}. When calling the bash tool, use a short, calm, progress-focused description that matches the current regime. ${regimeTone} Name the user-visible milestone being advanced, keep the wording human, and avoid hype or raw technical labels. Combine independent bash commands into a single call with && or ;.`;
11296
+ }
11281
11297
  function flowTodosDirective() {
11282
11298
  const pendingTodos = loadTodos().filter((t) => t.status === "pending").length;
11283
11299
  if (pendingTodos === 0)
@@ -11535,7 +11551,7 @@ var onSystemTransform = async (_input, output) => {
11535
11551
  pushSystem(output, "[vibeOS dashboard display] When the trinity tool returns output starting with '[vibeOS-dashboard]', use the question tool to display that data in a clean, human-readable format. Use the question field (not the header) to show the dashboard data. Format it with clear sections separated by blank lines, aligned columns with spaces, and plain text only. The header should be 'vibeOS Dashboard'. Include only one option in options: {label: 'Dismiss', description: ''}. Strip the '[vibeOS-dashboard]' marker line before displaying.");
11536
11552
  }
11537
11553
  if (!oneShot("vibeos_dopamine_style_" + fp2)) {
11538
- pushSystem(output, "[tool style: dopamine] When calling the bash tool, use a short, calm, progress-focused description that names the user-visible milestone being advanced. Combine independent bash commands into a single call with && or ;. Keep the wording human and avoid hype or raw technical labels.");
11554
+ pushSystem(output, regimeAwareToolStyleDirective(currentSubRegime, displayMode, stressScore));
11539
11555
  }
11540
11556
  } catch (err) {
11541
11557
  console.error(`[vibeOS] system.transform failed: ${err.message}`);
@@ -11558,6 +11574,21 @@ var REGIME_TAG = {
11558
11574
  AUDIT: "AUDT",
11559
11575
  FORENSIC: "FRNC"
11560
11576
  };
11577
+ var REGIME_ICON = {
11578
+ INIT: "\u25CC",
11579
+ DIVERGENT: "\u21C4",
11580
+ EXPLORING: "\u2315",
11581
+ REFINING: "\u270E",
11582
+ IMPLEMENTING: "\u2699",
11583
+ RESEARCH: "\u2301",
11584
+ REVIEWING: "\u2713",
11585
+ DESIGNING: "\u25EB",
11586
+ CONVERGING: "\u27F2",
11587
+ CLOSED: "\u25C6",
11588
+ LOOPING: "\u21BB",
11589
+ AUDIT: "\u2611",
11590
+ FORENSIC: "\u27C1"
11591
+ };
11561
11592
  var BRAND_MAP = {
11562
11593
  vibeultrax: "VibeUltraX",
11563
11594
  vibeqmax: "VibeQMaX",
@@ -11579,6 +11610,9 @@ function resolveBrand(optMode, activeSlot) {
11579
11610
  function resolveTierIcon(slot) {
11580
11611
  return TIER_ICON[slot] || "\u26A1";
11581
11612
  }
11613
+ function resolveRegimeIcon(subRegime) {
11614
+ return REGIME_ICON[String(subRegime || "").toUpperCase()] || "\u25E6";
11615
+ }
11582
11616
  function formatModeLabel(optMode) {
11583
11617
  const normalized = String(optMode || "").toLowerCase();
11584
11618
  if (!normalized)
@@ -11639,7 +11673,7 @@ function formatSavingsPulse(amountUsd, trend) {
11639
11673
  }
11640
11674
  function buildEnforcementTags(opts) {
11641
11675
  const tags = [];
11642
- if (opts.bbMode === "relaxed") {
11676
+ if (opts.quietIntent || opts.bbMode === "relaxed") {
11643
11677
  tags.push("[Q&A]");
11644
11678
  } else {
11645
11679
  if (opts.delegationEnforce)
@@ -11659,8 +11693,9 @@ function buildFooterLine(input) {
11659
11693
  const { activeSlot, sessionSlot, providerLabel, modelName, ltTotal, ltTrend, vibeBrand, optMode, flashIcon, enfTags, vectorChangedSlot, subRegime } = input;
11660
11694
  const tierIcon = resolveTierIcon(activeSlot);
11661
11695
  const regimeTag = subRegime ? REGIME_TAG[subRegime] || subRegime.slice(0, 4) : null;
11696
+ const regimeIcon = subRegime ? resolveRegimeIcon(subRegime) : null;
11662
11697
  const modeLabel = formatModeLabel(optMode);
11663
- let line = `\u2014 ${tierIcon} ${activeSlot} | ${providerLabel} | ${modelName}${regimeTag ? ` \u25B6 ${regimeTag}` : ""}`;
11698
+ let line = `\u2014 ${tierIcon} ${activeSlot} | ${providerLabel} | ${modelName}${regimeTag ? ` \u25B6 ${regimeIcon} ${regimeTag}` : ""}`;
11664
11699
  if (ltTotal > 0) {
11665
11700
  const savingsPulse = formatSavingsPulse(ltTotal, ltTrend);
11666
11701
  if (savingsPulse)
@@ -11709,6 +11744,10 @@ function loadSelection3() {
11709
11744
  return { active_slot: "medium", enabled: true, delegation_enforce: true, flow_enabled: true, flow_enforce: true, tdd_enforce: false, tdd_strict: false };
11710
11745
  }
11711
11746
  }
11747
+ function isGreetingLike(text) {
11748
+ const value = String(text || "").trim().toLowerCase();
11749
+ return value === "hi" || value === "hello" || value === "hey" || value === "yo" || /^hi[!.?\s]*$/.test(value) || /^hello[!.?\s]*$/.test(value) || /^hey[!.?\s]*$/.test(value);
11750
+ }
11712
11751
  function readLifetimeSavings2() {
11713
11752
  try {
11714
11753
  reconcileStateFromLedger();
@@ -11862,13 +11901,13 @@ async function _appendFooter(input, output, directory3) {
11862
11901
  if (!liveModel) {
11863
11902
  liveModel = readConfig(directory3) || readConfig(join15(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
11864
11903
  }
11865
- const displayModel = resolveTrinityDisplayModel(directory3, slot, liveModel, currentModel) || brainModel || liveModel || currentModel;
11904
+ const displayModel = resolveDisplayModelId(liveModel || brainModel || currentModel || "", directory3) || liveModel || brainModel || currentModel;
11866
11905
  const resolvedModel = displayModel || liveModel || brainModel || currentModel || "";
11867
11906
  if (resolvedModel && resolvedModel !== currentModel) {
11868
11907
  setCurrentModel(resolvedModel);
11869
11908
  setCurrentTier(classify(resolvedModel));
11870
11909
  }
11871
- const execution = resolveExecutionIdentity(displayModel || resolvedModel || "", directory3);
11910
+ const execution = resolveExecutionIdentity(input?.args?.model || resolvedModel || "", directory3);
11872
11911
  let modelTag = `[${shortModelName(displayModel)}]`;
11873
11912
  const _workerModel = slot === "brain" ? TRINITY_MEDIUM : null;
11874
11913
  const totalTurns = (sesModelTurns?.brain || 0) + (sesModelTurns?.worker || 0);
@@ -11907,14 +11946,15 @@ async function _appendFooter(input, output, directory3) {
11907
11946
  }
11908
11947
  const selNowFooter = loadSelection3();
11909
11948
  const normalizedIntent = classifyTurnSimple2(latestUserIntent || "");
11910
- const currentSubRegime = _latestBlackboxState?.sub_regime || normalizedIntent;
11949
+ const currentSubRegime2 = _latestBlackboxState?.sub_regime || normalizedIntent;
11911
11950
  const bbMode = resolveEnforcementMode();
11912
11951
  const enfTags = buildEnforcementTags({
11913
11952
  delegationEnforce: selNowFooter.delegation_enforce,
11914
11953
  flowEnforce: selNowFooter.flow_enforce,
11915
11954
  tddEnforce: selNowFooter.tdd_enforce,
11916
11955
  bbMode,
11917
- modelLocked: _modelLocked
11956
+ modelLocked: _modelLocked,
11957
+ quietIntent: isGreetingLike(latestUserIntent || "")
11918
11958
  });
11919
11959
  const stripped = text.replace(/\u2014 [^\u2014]+ \u2014\s*/g, "").trimEnd();
11920
11960
  if (stripped !== text)
@@ -11924,8 +11964,8 @@ async function _appendFooter(input, output, directory3) {
11924
11964
  const ltTotal = ltTasks + ltCache;
11925
11965
  const activeSlot = selNowFooter.active_slot || "brain";
11926
11966
  const flashIcon = isApiConnected2() ? " \u26A1" : "";
11927
- const displayMode = autoSelectMode2(currentSubRegime, _footerStress);
11928
- const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode, activeSlot);
11967
+ const displayMode2 = autoSelectMode2(currentSubRegime2, _footerStress);
11968
+ const vibeBrand = resolveBrand(loadOptimizationMode() || displayMode2, activeSlot);
11929
11969
  const vibeLine = buildFooterLine({
11930
11970
  activeSlot,
11931
11971
  providerLabel: execution.provider_label,
@@ -11933,12 +11973,12 @@ async function _appendFooter(input, output, directory3) {
11933
11973
  ltTotal,
11934
11974
  ltTrend: sesTrend,
11935
11975
  vibeBrand,
11936
- optMode: displayMode,
11976
+ optMode: displayMode2,
11937
11977
  flashIcon,
11938
11978
  enfTags,
11939
11979
  sessionSlot,
11940
11980
  vectorChangedSlot: selNowFooter?.vector_changed_slot,
11941
- subRegime: currentSubRegime
11981
+ subRegime: currentSubRegime2
11942
11982
  });
11943
11983
  const footerText = stripped + `
11944
11984
 
@@ -11996,7 +12036,7 @@ import { writeFileSync as writeFileSync14, appendFileSync as appendFileSync6, ex
11996
12036
  import { join as join17, dirname as dirname12, basename as basename4 } from "node:path";
11997
12037
  import { createHash as createHash5 } from "node:crypto";
11998
12038
 
11999
- // src/lib/cost-anomaly.js
12039
+ // src/lib/cost-anomaly.ts
12000
12040
  var COST_WINDOW_SIZE = 20;
12001
12041
  var COST_ANOMALY_THRESHOLD = 3;
12002
12042
  var COST_WARMUP_SAMPLES = 5;
@@ -12007,26 +12047,21 @@ var CostAnomalyDetector = class {
12007
12047
  currentAnomalyCost = 0;
12008
12048
  currentAnomalyMean = 0;
12009
12049
  record(cost) {
12010
- if (this.disabled)
12011
- return;
12050
+ if (this.disabled) return;
12012
12051
  this.costHistory.push(cost);
12013
12052
  if (this.costHistory.length > COST_WINDOW_SIZE) {
12014
12053
  this.costHistory.shift();
12015
12054
  }
12016
12055
  }
12017
12056
  get mean() {
12018
- if (this.costHistory.length === 0)
12019
- return 0;
12057
+ if (this.costHistory.length === 0) return 0;
12020
12058
  return this.costHistory.reduce((a, b) => a + b, 0) / this.costHistory.length;
12021
12059
  }
12022
12060
  checkAnomaly(model, cost) {
12023
- if (this.disabled)
12024
- return false;
12025
- if (this.costHistory.length < COST_WARMUP_SAMPLES)
12026
- return false;
12061
+ if (this.disabled) return false;
12062
+ if (this.costHistory.length < COST_WARMUP_SAMPLES) return false;
12027
12063
  const avg = this.mean;
12028
- if (avg <= 0 || cost <= avg)
12029
- return false;
12064
+ if (avg <= 0 || cost <= avg) return false;
12030
12065
  const ratio = cost / avg;
12031
12066
  if (ratio > COST_ANOMALY_THRESHOLD) {
12032
12067
  this.currentAnomalyModel = model;
@@ -12048,8 +12083,7 @@ var CostAnomalyDetector = class {
12048
12083
  };
12049
12084
  var _costDetector = null;
12050
12085
  function getCostAnomalyDetector() {
12051
- if (!_costDetector)
12052
- _costDetector = new CostAnomalyDetector();
12086
+ if (!_costDetector) _costDetector = new CostAnomalyDetector();
12053
12087
  return _costDetector;
12054
12088
  }
12055
12089
 
@@ -13382,6 +13416,10 @@ function buildTestReminder(filePath) {
13382
13416
  }
13383
13417
 
13384
13418
  // src/lib/hooks/tool-execute.js
13419
+ function isGreetingLike2(text) {
13420
+ const value = String(text || "").trim().toLowerCase();
13421
+ return value === "hi" || value === "hello" || value === "hey" || value === "yo" || /^hi[!.?\s]*$/.test(value) || /^hello[!.?\s]*$/.test(value) || /^hey[!.?\s]*$/.test(value);
13422
+ }
13385
13423
  var BYTES_PER_TOKEN2 = 4;
13386
13424
  var DEBUG_INTERNALS2 = process.env.VIBEOS_DEBUG_INTERNALS === "1";
13387
13425
  var IS_CLI_RUNTIME2 = Boolean(process.stdout?.isTTY || process.stderr?.isTTY || process.stdin?.isTTY);
@@ -14014,26 +14052,27 @@ var onToolExecuteAfter = async (input, output) => {
14014
14052
  if (!liveModel) {
14015
14053
  liveModel = readConfig(projectDirectory) || readConfig(join17(process.env.HOME || "", ".config", "opencode")) || process?.env?.OPENCODE_MODEL || "";
14016
14054
  }
14017
- const displayModel = resolveTrinityDisplayModel(projectDirectory, selNow.active_slot || "", liveModel, currentModel) || liveModel || currentModel;
14055
+ const displayModel = resolveDisplayModelId(liveModel || currentModel || "", projectDirectory) || liveModel || currentModel;
14018
14056
  const resolvedModel = displayModel || liveModel || currentModel || "";
14019
14057
  if (resolvedModel && resolvedModel !== currentModel) {
14020
14058
  setCurrentModel(resolvedModel);
14021
14059
  setCurrentTier(classify(resolvedModel));
14022
14060
  }
14023
- const execution = resolveExecutionIdentity(displayModel || resolvedModel || "", projectDirectory);
14061
+ const execution = resolveExecutionIdentity(input?.args?.model || resolvedModel || "", projectDirectory);
14024
14062
  const currentSid = _OC_SID;
14025
- const currentSubRegime = loadBlackboxState()?.sessions?.[currentSid]?.sub_regime || classifyTurnSimple2(latestUserIntent || "");
14063
+ const currentSubRegime2 = loadBlackboxState()?.sessions?.[currentSid]?.sub_regime || classifyTurnSimple2(latestUserIntent || "");
14026
14064
  const bbMode = resolveEnforcementMode();
14027
14065
  const enfTags = buildEnforcementTags({
14028
14066
  delegationEnforce: selNow.delegation_enforce,
14029
14067
  flowEnforce: selNow.flow_enforce,
14030
14068
  tddEnforce: selNow.tdd_enforce,
14031
14069
  bbMode,
14032
- modelLocked: _modelLocked
14070
+ modelLocked: _modelLocked,
14071
+ quietIntent: isGreetingLike2(latestUserIntent || "")
14033
14072
  });
14034
14073
  const activeSlot = selNow.active_slot || (execution.quality === "brain" ? "brain" : execution.quality === "medium" ? "medium" : "cheap");
14035
- const displayMode = autoSelectMode2(currentSubRegime, latestUserIntent ? scoreStress(latestUserIntent) : 0);
14036
- const vibeBrand = resolveBrand(displayMode, activeSlot);
14074
+ const displayMode2 = autoSelectMode2(currentSubRegime2, latestUserIntent ? scoreStress(latestUserIntent) : 0);
14075
+ const vibeBrand = resolveBrand(displayMode2, activeSlot);
14037
14076
  const sessionSlot = loadSessionSlot(currentSid);
14038
14077
  const flashIcon = isApiConnected2() ? " \u26A1" : "";
14039
14078
  _footerText = buildFooterLine({
@@ -14043,12 +14082,12 @@ var onToolExecuteAfter = async (input, output) => {
14043
14082
  ltTotal,
14044
14083
  ltTrend: sesTrend || "",
14045
14084
  vibeBrand,
14046
- optMode: displayMode,
14085
+ optMode: displayMode2,
14047
14086
  flashIcon,
14048
14087
  enfTags,
14049
14088
  sessionSlot,
14050
14089
  vectorChangedSlot: selNow.vector_changed_slot,
14051
- subRegime: currentSubRegime
14090
+ subRegime: currentSubRegime2
14052
14091
  }) + "\n\n";
14053
14092
  const footerTarget = _payload(output);
14054
14093
  output.title = _footerText.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.24.30",
3
+ "version": "0.24.32",
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",