vibeostheog 0.24.8 → 0.24.10

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.24.10
2
+ - fix: wire npm auth for GitHub releases
3
+
4
+
5
+ ## 0.24.9
6
+ - fix: preserve live metrics context in reports
7
+
8
+
1
9
  ## 0.24.5
2
10
  - fix: cap saveEst at to prevent runaway pricing data corruption
3
11
  - chore: v0.24.4
package/dist/vibeOS.js CHANGED
@@ -1596,7 +1596,7 @@ import { dirname as dirname3 } from "node:path";
1596
1596
  import { fileURLToPath as fileURLToPath3 } from "node:url";
1597
1597
  import { homedir } from "node:os";
1598
1598
 
1599
- // src/lib/runtime-state.js
1599
+ // src/lib/runtime-state.ts
1600
1600
  var RUNTIME_KEY = "__vibeOSRuntimeState";
1601
1601
  function getRuntimeState() {
1602
1602
  const g = globalThis;
@@ -1623,8 +1623,7 @@ function markApiDisconnected() {
1623
1623
  const state = getRuntimeState();
1624
1624
  state.apiConnected = false;
1625
1625
  state.apiFallbackMode = true;
1626
- if (!state.apiFallbackSince)
1627
- state.apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
1626
+ if (!state.apiFallbackSince) state.apiFallbackSince = (/* @__PURE__ */ new Date()).toISOString();
1628
1627
  }
1629
1628
  function resetApiConnection() {
1630
1629
  const state = getRuntimeState();
@@ -2529,56 +2528,42 @@ function writeSessionOptMode(sid, mode) {
2529
2528
  }
2530
2529
  }
2531
2530
 
2532
- // src/lib/pattern-helpers.js
2531
+ // src/lib/pattern-helpers.ts
2533
2532
  import { relative, basename as basename2 } from "node:path";
2534
2533
  function normalizeObservedPath(filePath, directory3) {
2535
- if (!filePath || typeof filePath !== "string")
2536
- return "unknown";
2534
+ if (!filePath || typeof filePath !== "string") return "unknown";
2537
2535
  let p = filePath;
2538
2536
  try {
2539
2537
  if (directory3 && p.startsWith("/")) {
2540
2538
  const rel = relative(directory3, p);
2541
- if (rel && !rel.startsWith("..") && !rel.startsWith("/"))
2542
- p = rel;
2539
+ if (rel && !rel.startsWith("..") && !rel.startsWith("/")) p = rel;
2543
2540
  }
2544
2541
  } catch {
2545
2542
  }
2546
2543
  p = p.replace(/\\/g, "/").replace(/^\.\/+/, "");
2547
- if (/^(src\/index\.js|package\.json|README\.md|CHANGELOG\.md|tsconfig\.json)$/i.test(p))
2548
- return p;
2544
+ if (/^(src\/index\.js|package\.json|README\.md|CHANGELOG\.md|tsconfig\.json)$/i.test(p)) return p;
2549
2545
  const m = p.match(/\.([a-z0-9]+)$/i);
2550
- if (p.startsWith("src/") && m)
2551
- return `src/*.${m[1].toLowerCase()}`;
2552
- if (p.startsWith("tests/") && m)
2553
- return `tests/*.${m[1].toLowerCase()}`;
2546
+ if (p.startsWith("src/") && m) return `src/*.${m[1].toLowerCase()}`;
2547
+ if (p.startsWith("tests/") && m) return `tests/*.${m[1].toLowerCase()}`;
2554
2548
  return basename2(p) || "unknown";
2555
2549
  }
2556
2550
  function commandFamily(command) {
2557
2551
  const c = String(command || "").trim().toLowerCase();
2558
- if (!c)
2559
- return "unknown";
2560
- if (/\bnode\s+--check\b/.test(c))
2561
- return "syntax-check";
2562
- if (/\bnpm\s+run\s+typecheck\b|\btsc\b.*--noemit/.test(c))
2563
- return "typecheck";
2564
- if (/\bnpm\s+test\b|\bnode\s+--test\b|\bvitest\b|\bjest\b|\bpytest\b/.test(c))
2565
- return "test";
2566
- if (/\bnpm\s+run\s+build\b|\btsc\s+-p\b/.test(c))
2567
- return "build";
2568
- if (/\bgit\s+status\b/.test(c))
2569
- return "git-status";
2570
- if (/\bgit\s+commit\b/.test(c))
2571
- return "git-commit";
2552
+ if (!c) return "unknown";
2553
+ if (/\bnode\s+--check\b/.test(c)) return "syntax-check";
2554
+ if (/\bnpm\s+run\s+typecheck\b|\btsc\b.*--noemit/.test(c)) return "typecheck";
2555
+ if (/\bnpm\s+test\b|\bnode\s+--test\b|\bvitest\b|\bjest\b|\bpytest\b/.test(c)) return "test";
2556
+ if (/\bnpm\s+run\s+build\b|\btsc\s+-p\b/.test(c)) return "build";
2557
+ if (/\bgit\s+status\b/.test(c)) return "git-status";
2558
+ if (/\bgit\s+commit\b/.test(c)) return "git-commit";
2572
2559
  const first = c.replace(/^[a-z_][a-z0-9_]*=\S+\s+/g, "").split(/\s+/)[0];
2573
2560
  return /^[a-z0-9._/-]{1,30}$/.test(first) ? first : "command";
2574
2561
  }
2575
2562
  function commandFailed(output) {
2576
2563
  const code = output?.exitCode ?? output?.statusCode ?? output?.code;
2577
- if (Number.isFinite(Number(code)) && Number(code) !== 0)
2578
- return true;
2564
+ if (Number.isFinite(Number(code)) && Number(code) !== 0) return true;
2579
2565
  const raw = output?.result ?? output?.text ?? output?.content ?? output?.data ?? "";
2580
- if (typeof raw !== "string")
2581
- return false;
2566
+ if (typeof raw !== "string") return false;
2582
2567
  return /\b(exit code|exited with code)\s*[:=]?\s*[1-9]\b|\b(assertionerror|syntaxerror|typeerror|referenceerror)\b|\b(failed|error:|err!)\b/i.test(raw);
2583
2568
  }
2584
2569
  function mergeProjectBucket(dst, src) {
@@ -2595,8 +2580,7 @@ function mergeProjectBucket(dst, src) {
2595
2580
  row.sessions = [.../* @__PURE__ */ new Set([...row.sessions || [], ...v?.sessions || []])].slice(-10);
2596
2581
  row.lastSeen = [row.lastSeen, v?.lastSeen].filter(Boolean).sort().slice(-1)[0] || null;
2597
2582
  row.summary = row.summary || v?.summary || "";
2598
- if (v?.kind)
2599
- row.kind = v.kind;
2583
+ if (v?.kind) row.kind = v.kind;
2600
2584
  out[key] = row;
2601
2585
  }
2602
2586
  }
@@ -2615,11 +2599,9 @@ function mergeProjectBucket(dst, src) {
2615
2599
  };
2616
2600
  }
2617
2601
  function _pruneOldSessions(state) {
2618
- if (!state?.sessions)
2619
- return;
2602
+ if (!state?.sessions) return;
2620
2603
  const entries = Object.entries(state.sessions);
2621
- if (entries.length <= 30)
2622
- return;
2604
+ if (entries.length <= 30) return;
2623
2605
  entries.sort((a, b) => {
2624
2606
  const da = a[1]?.started || a[1]?.last_costed || "";
2625
2607
  const db = b[1]?.started || b[1]?.last_costed || "";
@@ -7350,7 +7332,6 @@ function getReportsIndexPath() {
7350
7332
  }
7351
7333
  var REPORTS_DIR2 = getReportsDir();
7352
7334
  var REPORTS_INDEX = getReportsIndexPath();
7353
- var _OC_SID3 = "opencode-" + (process.pid || "x") + "-" + Date.now();
7354
7335
  var currentProjectFingerprint2 = "";
7355
7336
  var currentProjectName2 = "";
7356
7337
  function _handleStateCorruption4(path) {
@@ -7483,12 +7464,22 @@ function _parseMetrics(v) {
7483
7464
  function saveReport({ type = "manual", summary = "", findings = null, metrics = null, narrative = "", tags = [], fingerprint = null, status = "pending", task_description = "", outcome_verified = false } = {}) {
7484
7465
  const parsedFindings = _parseFindings(findings);
7485
7466
  const parsedMetrics = _parseMetrics(metrics);
7467
+ const metricsObject = parsedMetrics && typeof parsedMetrics === "object" && !Array.isArray(parsedMetrics) ? parsedMetrics : {};
7468
+ const metricsSessionId = typeof metricsObject.sessionId === "string" && metricsObject.sessionId.trim() ? metricsObject.sessionId.trim() : "";
7469
+ const metricsProjectName = typeof metricsObject.projectName === "string" && metricsObject.projectName.trim() ? metricsObject.projectName.trim() : "";
7470
+ const metricsProjectFingerprint = typeof metricsObject.projectFingerprint === "string" && metricsObject.projectFingerprint.trim() ? metricsObject.projectFingerprint.trim() : "";
7486
7471
  if (_wouldBeDuplicate(type, summary))
7487
7472
  return null;
7488
- const fp2 = fingerprint || currentProjectFingerprint2 || "unknown";
7473
+ if (!currentProjectFingerprint2 && metricsProjectFingerprint)
7474
+ currentProjectFingerprint2 = metricsProjectFingerprint;
7475
+ if (!currentProjectName2 && metricsProjectName)
7476
+ currentProjectName2 = metricsProjectName;
7477
+ const fp2 = fingerprint || metricsProjectFingerprint || currentProjectFingerprint2 || "unknown";
7478
+ const sessionId = metricsSessionId || getOcSessionId();
7479
+ const projectName = metricsProjectName || currentProjectName2 || "unknown";
7489
7480
  const id2 = generateReportId(type, fp2);
7490
7481
  const report = {
7491
- meta: { id: id2, project: currentProjectName2 || "unknown", fingerprint: fp2, type, created: (/* @__PURE__ */ new Date()).toISOString(), sessionId: _OC_SID3 },
7482
+ meta: { id: id2, project: projectName, fingerprint: fp2, type, created: (/* @__PURE__ */ new Date()).toISOString(), sessionId },
7492
7483
  summary,
7493
7484
  findings: parsedFindings,
7494
7485
  metrics: parsedMetrics,
@@ -9456,7 +9447,7 @@ import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, appen
9456
9447
  import { join as join14, dirname as dirname10, basename as basename6 } from "node:path";
9457
9448
  import { createHash as createHash3 } from "node:crypto";
9458
9449
 
9459
- // src/lib/mode-policy.js
9450
+ // src/lib/mode-policy.ts
9460
9451
  var STRESS_QUALITY_THRESHOLD = 1.5;
9461
9452
  var BASELINE_MODE = "budget";
9462
9453
  var LOOP_REGIMES = /* @__PURE__ */ new Set(["LOOPING", "DIVERGENT"]);
@@ -9464,8 +9455,7 @@ var QUALITY_REGIMES = /* @__PURE__ */ new Set(["CONVERGING", "CLOSED"]);
9464
9455
  var MANUAL_MODES = /* @__PURE__ */ new Set(["balanced", "quality", "speed", "longrun", "vibemax", "vibeqmax", "vibeultrax"]);
9465
9456
  function normalizeMode(mode) {
9466
9457
  const normalized = String(mode || BASELINE_MODE).toLowerCase();
9467
- if (normalized === "auto" || normalized === "")
9468
- return BASELINE_MODE;
9458
+ if (normalized === "auto" || normalized === "") return BASELINE_MODE;
9469
9459
  if (normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "balanced" || normalized === "vibemax" || normalized === "vibeqmax" || normalized === "vibeultrax") {
9470
9460
  return normalized;
9471
9461
  }
@@ -9478,12 +9468,9 @@ function isManualOverride(mode) {
9478
9468
  return MANUAL_MODES.has(normalizeMode(mode));
9479
9469
  }
9480
9470
  function chooseEpisodeMode(regime, suggestedMode, stress) {
9481
- if (suggestedMode === "vibeultrax" || suggestedMode === "vibeqmax" || suggestedMode === "vibemax")
9482
- return suggestedMode;
9483
- if (LOOP_REGIMES.has(regime) || suggestedMode === "speed")
9484
- return "speed";
9485
- if (QUALITY_REGIMES.has(regime) || suggestedMode === "quality")
9486
- return "quality";
9471
+ if (suggestedMode === "vibeultrax" || suggestedMode === "vibeqmax" || suggestedMode === "vibemax") return suggestedMode;
9472
+ if (LOOP_REGIMES.has(regime) || suggestedMode === "speed") return "speed";
9473
+ if (QUALITY_REGIMES.has(regime) || suggestedMode === "quality") return "quality";
9487
9474
  return stress > STRESS_QUALITY_THRESHOLD ? "quality" : "budget";
9488
9475
  }
9489
9476
  function defaultPolicy() {
@@ -9504,19 +9491,15 @@ function defaultPolicy() {
9504
9491
  }
9505
9492
  function modeToSlot(mode) {
9506
9493
  const normalized = normalizeMode(mode);
9507
- if (normalized === "speed")
9508
- return "medium";
9509
- if (normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax")
9510
- return "brain";
9494
+ if (normalized === "speed") return "medium";
9495
+ if (normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax") return "brain";
9511
9496
  return "cheap";
9512
9497
  }
9513
9498
  function loadSessionPolicy() {
9514
9499
  const state = loadBlackboxState();
9515
- if (!state.sessions || typeof state.sessions !== "object")
9516
- state.sessions = {};
9500
+ if (!state.sessions || typeof state.sessions !== "object") state.sessions = {};
9517
9501
  const sid = _OC_SID;
9518
- if (!state.sessions[sid] || typeof state.sessions[sid] !== "object")
9519
- state.sessions[sid] = {};
9502
+ if (!state.sessions[sid] || typeof state.sessions[sid] !== "object") state.sessions[sid] = {};
9520
9503
  const session = state.sessions[sid];
9521
9504
  if (!session.mode_policy || typeof session.mode_policy !== "object") {
9522
9505
  session.mode_policy = defaultPolicy();
@@ -9644,7 +9627,7 @@ function recordBudgetFirstOutcome(input = {}) {
9644
9627
  import { join as join13 } from "node:path";
9645
9628
  import { writeFileSync as writeFileSync11 } from "node:fs";
9646
9629
 
9647
- // src/lib/text-compress.js
9630
+ // src/lib/text-compress.ts
9648
9631
  var VERBOSE_LINE_RE = [
9649
9632
  /^[\s#*/\\\-_=+|~:;'"`@\$%^&<>{}\[\]()!?.,0-9]+$/,
9650
9633
  /^(Filed|Created|Modified|Deleted|Updated|Renamed|Copied|Moved|Changed):/,
@@ -9661,15 +9644,12 @@ function extractBulletLines(lines, targetChars, minLines) {
9661
9644
  const keyLines = [];
9662
9645
  const otherLines = [];
9663
9646
  for (const line of lines) {
9664
- if (BULLET_PATTERNS.some((re) => re.test(line)))
9665
- keyLines.push(line);
9666
- else
9667
- otherLines.push(line);
9647
+ if (BULLET_PATTERNS.some((re) => re.test(line))) keyLines.push(line);
9648
+ else otherLines.push(line);
9668
9649
  }
9669
9650
  const selected = [...keyLines];
9670
9651
  for (const line of otherLines) {
9671
- if (selected.length >= minLines && selected.join("\n").length >= targetChars)
9672
- break;
9652
+ if (selected.length >= minLines && selected.join("\n").length >= targetChars) break;
9673
9653
  selected.push(line);
9674
9654
  }
9675
9655
  while (selected.length > minLines && selected.join("\n").length > targetChars * 2) {
@@ -9678,8 +9658,7 @@ function extractBulletLines(lines, targetChars, minLines) {
9678
9658
  return selected;
9679
9659
  }
9680
9660
  function compressText(text) {
9681
- if (!text || typeof text !== "string")
9682
- return text;
9661
+ if (!text || typeof text !== "string") return text;
9683
9662
  let lines = text.split("\n");
9684
9663
  let removed = 0;
9685
9664
  const out = [];
@@ -9692,16 +9671,14 @@ function compressText(text) {
9692
9671
  break;
9693
9672
  }
9694
9673
  }
9695
- if (!skip)
9696
- out.push(line);
9674
+ if (!skip) out.push(line);
9697
9675
  }
9698
9676
  const collapsed = [];
9699
9677
  let blanks = 0;
9700
9678
  for (const line of out) {
9701
9679
  if (line.trim() === "") {
9702
9680
  blanks++;
9703
- if (blanks <= 2)
9704
- collapsed.push(line);
9681
+ if (blanks <= 2) collapsed.push(line);
9705
9682
  } else {
9706
9683
  blanks = 0;
9707
9684
  collapsed.push(line);
@@ -9709,7 +9686,10 @@ function compressText(text) {
9709
9686
  }
9710
9687
  let result = collapsed.join("\n").trim();
9711
9688
  if (result.length > COMPRESS_THRESHOLD) {
9712
- const targetChars = Math.max(Math.round(result.length * COMPRESS_RATIO), COMPRESS_THRESHOLD);
9689
+ const targetChars = Math.max(
9690
+ Math.round(result.length * COMPRESS_RATIO),
9691
+ COMPRESS_THRESHOLD
9692
+ );
9713
9693
  const minLines = Math.max(1, Math.round(collapsed.length * MIN_KEPT_LINES_RATIO));
9714
9694
  const bulletLines = extractBulletLines(collapsed, targetChars, minLines);
9715
9695
  result = bulletLines.join("\n").trim();
@@ -10024,7 +10004,7 @@ function recordSaving(tool2, reason, saveEst, meta = {}) {
10024
10004
  }
10025
10005
  }
10026
10006
 
10027
- // src/lib/constants.js
10007
+ // src/lib/constants.ts
10028
10008
  var SAVE_EST = {
10029
10009
  // Realistic: v4-pro (0.00057) - v4-flash (0.000182) = 0.000388/turn
10030
10010
  WRITE_EDIT: 4e-4,
@@ -10042,7 +10022,7 @@ var COMPRESS_MARKER = "[ctx-compressed-v1]";
10042
10022
  var PROTOCOL_MARKER = "[wbp-v1]";
10043
10023
  var PROTOCOL_TEXT = PROTOCOL_MARKER + " [Worker-to-Brain Report Protocol] When synthesizing the preceding Task output: 1) EXTRACT core findings/data. 2) REFORMAT into bullet points. 3) VERIFY against the original ask. 4) SYNTHESIZE into final response.";
10044
10024
 
10045
- // src/lib/templates.js
10025
+ // src/lib/templates.ts
10046
10026
  var TEMPLATES = {
10047
10027
  save: {
10048
10028
  tier_bias: "cheap",
@@ -10092,8 +10072,7 @@ var TEMPLATES = {
10092
10072
  var DEFAULT_TEMPLATE = "save";
10093
10073
  var SEC_KEYWORDS = /\b(security|vuln|exploit|injection|xss|csrf|secret|credential|token leak|auth bypass|privacy|breach|backdoor|sql injection|cve)\b/i;
10094
10074
  function detectSecuritySignal(text) {
10095
- if (!text || typeof text !== "string")
10096
- return false;
10075
+ if (!text || typeof text !== "string") return false;
10097
10076
  return SEC_KEYWORDS.test(text);
10098
10077
  }
10099
10078
  function detectBudgetSignal(creditPercent) {
@@ -10106,25 +10085,20 @@ function detectStressSpike(stressScore) {
10106
10085
  return delta > 0.3 && stressScore > 0.5;
10107
10086
  }
10108
10087
  function resolveTemplate(prevTemplate, stressScore, userText, creditPercent, subRegime) {
10109
- if (detectSecuritySignal(userText))
10110
- return "security";
10088
+ if (detectSecuritySignal(userText)) return "security";
10111
10089
  if (detectBudgetSignal(creditPercent)) {
10112
10090
  const regime = String(subRegime || "").toUpperCase();
10113
- if (regime === "LOOPING" || regime === "DIVERGENT")
10114
- return "speed";
10091
+ if (regime === "LOOPING" || regime === "DIVERGENT") return "speed";
10115
10092
  return "save";
10116
10093
  }
10117
- if (detectStressSpike(stressScore))
10118
- return "quality";
10094
+ if (detectStressSpike(stressScore)) return "quality";
10119
10095
  return prevTemplate || DEFAULT_TEMPLATE;
10120
10096
  }
10121
10097
  var _turnCount = 0;
10122
10098
  function shouldInjectTemplate(template, prevTemplate) {
10123
10099
  _turnCount++;
10124
- if (template !== prevTemplate)
10125
- return true;
10126
- if (_turnCount % 10 === 0)
10127
- return true;
10100
+ if (template !== prevTemplate) return true;
10101
+ if (_turnCount % 10 === 0) return true;
10128
10102
  return false;
10129
10103
  }
10130
10104
 
@@ -10171,7 +10145,7 @@ function ensureProjectContext(hookDirectory) {
10171
10145
  return resolved;
10172
10146
  }
10173
10147
  var latestUserIntent = null;
10174
- var _OC_SID4 = "opencode-" + (process.pid || "x") + "-" + Date.now();
10148
+ var _OC_SID3 = "opencode-" + (process.pid || "x") + "-" + Date.now();
10175
10149
  var _latestBlackboxState3 = null;
10176
10150
  var _latestBlackboxLoopMsg3 = null;
10177
10151
  var _latestBlackboxPivotMsg3 = null;
@@ -10313,7 +10287,7 @@ function syncControlSettings(cv, options = {}) {
10313
10287
  if (!cv)
10314
10288
  return;
10315
10289
  try {
10316
- const sid = _OC_SID4;
10290
+ const sid = _OC_SID3;
10317
10291
  if (!cv.agent_mode) {
10318
10292
  try {
10319
10293
  clearWorkspaceFollowupPauseForSession(sid);
@@ -10533,7 +10507,7 @@ async function trackBlackbox(messages) {
10533
10507
  const tracker = getBlackboxTracker();
10534
10508
  const localState = tracker.update(latestUserIntent);
10535
10509
  const state = loadBlackboxState();
10536
- const sid = _OC_SID4;
10510
+ const sid = _OC_SID3;
10537
10511
  ensureProjectContext(process.cwd() || "");
10538
10512
  const serialized = tracker.serialize();
10539
10513
  const existingSession = state.sessions[sid] || {};
@@ -10861,7 +10835,7 @@ var onSystemTransform = async (_input, output) => {
10861
10835
  const regime2 = _latestBlackboxState3?.sub_regime || classifyTurnSimple2(latestUserIntent || "");
10862
10836
  const calRecord = JSON.stringify({
10863
10837
  ts: (/* @__PURE__ */ new Date()).toISOString(),
10864
- sid: _OC_SID4,
10838
+ sid: _OC_SID3,
10865
10839
  mode: _currentTemplate,
10866
10840
  regime: regime2,
10867
10841
  stress: stressScore,
@@ -11028,7 +11002,7 @@ function readLifetimeSavings2() {
11028
11002
  reconcileStateFromLedger();
11029
11003
  const raw = readFileSync14(STATE_FILE2, "utf-8");
11030
11004
  const state = safeJsonParse3(raw);
11031
- const ses = state?.sessions?.[typeof _OC_SID5 !== "undefined" ? _OC_SID5 : ""] || {};
11005
+ const ses = state?.sessions?.[typeof _OC_SID4 !== "undefined" ? _OC_SID4 : ""] || {};
11032
11006
  return {
11033
11007
  ltTasks: roundUsd2(state?.lifetime?.total_savings_usd || 0),
11034
11008
  ltCache: roundUsd2(state?.lifetime?.cache_savings_usd || 0),
@@ -11056,7 +11030,7 @@ function readLifetimeSavings2() {
11056
11030
  return { ltTasks: 0, ltCache: 0, ltCost: 0, count: 0, sesTasks: 0, sesCache: 0, sesTaskDelegations: 0, sesDuration: 0, sesRatePerHour: 0, sesTrend: "", sesToolBreakdown: {}, sesModelTurns: {}, quality_avg: 0 };
11057
11031
  }
11058
11032
  }
11059
- var _OC_SID5 = "opencode-" + (process.pid || "x") + "-" + Date.now();
11033
+ var _OC_SID4 = "opencode-" + (process.pid || "x") + "-" + Date.now();
11060
11034
  function scoreTaskQuality(outputText, promptText) {
11061
11035
  if (typeof outputText !== "string" || outputText.length === 0)
11062
11036
  return 0;
@@ -11083,7 +11057,7 @@ function scoreTaskQuality(outputText, promptText) {
11083
11057
  function readRewardSignals() {
11084
11058
  try {
11085
11059
  const state = loadBlackboxState();
11086
- const session = state?.sessions?.[_OC_SID5] || {};
11060
+ const session = state?.sessions?.[_OC_SID4] || {};
11087
11061
  const policy = session?.mode_policy || {};
11088
11062
  return {
11089
11063
  stableStreak: Math.max(0, Number(policy.stable_streak || 0)),
@@ -11160,7 +11134,7 @@ async function _appendFooter(input, output, directory3) {
11160
11134
  return;
11161
11135
  const { ltTasks, ltCache, ltCost, count, sesTasks, sesEdit, sesCredit, sesC7, sesQuota, sesCache, sesTaskDelegations, sesDuration, sesRatePerHour, sesTrend, sesToolBreakdown, sesModelTurns, quality_avg } = readLifetimeSavings2();
11162
11136
  const { stableStreak, problemStreak } = readRewardSignals();
11163
- const sessionSlot = loadBlackboxState()?.sessions?.[_OC_SID5]?.active_slot || loadSessionSlot(_OC_SID5);
11137
+ const sessionSlot = loadBlackboxState()?.sessions?.[_OC_SID4]?.active_slot || loadSessionSlot(_OC_SID4);
11164
11138
  const slot = sessionSlot || loadSelection3().active_slot || "brain";
11165
11139
  const brainModel = slot === "brain" ? TRINITY_BRAIN || currentModel : slot === "medium" ? TRINITY_MEDIUM || currentModel : TRINITY_CHEAP || currentModel || "";
11166
11140
  let liveModel = "";
@@ -11194,7 +11168,7 @@ async function _appendFooter(input, output, directory3) {
11194
11168
  type: "session",
11195
11169
  summary: "Session cost: $" + formatUsd(ltCost) + " | cache saved: $" + formatUsd(ltCache) + " | delegation saved: $" + formatUsd(Number(sesTasks || 0)) + " | task delegations: " + Number(sesTaskDelegations || 0),
11196
11170
  metrics: {
11197
- sessionId: _OC_SID5,
11171
+ sessionId: _OC_SID4,
11198
11172
  projectFingerprint: currentProjectFingerprint || "unknown",
11199
11173
  projectName: currentProjectName || "unknown",
11200
11174
  sessionCost: ltCost,
@@ -11283,7 +11257,7 @@ ${vibeLine}`;
11283
11257
  syncOutcomeToApi(finalOutcome);
11284
11258
  try {
11285
11259
  mkdirSync11(getVibeOSHome10(), { recursive: true });
11286
- appendFileSync6(join15(getVibeOSHome10(), "calibration-data.jsonl"), JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), event: "outcome", sid: _OC_SID5, outcome: finalOutcome }) + "\n");
11260
+ appendFileSync6(join15(getVibeOSHome10(), "calibration-data.jsonl"), JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), event: "outcome", sid: _OC_SID4, outcome: finalOutcome }) + "\n");
11287
11261
  } catch {
11288
11262
  }
11289
11263
  }
@@ -11313,7 +11287,7 @@ import { writeFileSync as writeFileSync14, appendFileSync as appendFileSync8, ex
11313
11287
  import { join as join17, dirname as dirname12, basename as basename7 } from "node:path";
11314
11288
  import { createHash as createHash5 } from "node:crypto";
11315
11289
 
11316
- // src/lib/cost-anomaly.js
11290
+ // src/lib/cost-anomaly.ts
11317
11291
  var COST_WINDOW_SIZE = 20;
11318
11292
  var COST_ANOMALY_THRESHOLD = 3;
11319
11293
  var COST_WARMUP_SAMPLES = 5;
@@ -11324,26 +11298,21 @@ var CostAnomalyDetector = class {
11324
11298
  currentAnomalyCost = 0;
11325
11299
  currentAnomalyMean = 0;
11326
11300
  record(cost) {
11327
- if (this.disabled)
11328
- return;
11301
+ if (this.disabled) return;
11329
11302
  this.costHistory.push(cost);
11330
11303
  if (this.costHistory.length > COST_WINDOW_SIZE) {
11331
11304
  this.costHistory.shift();
11332
11305
  }
11333
11306
  }
11334
11307
  get mean() {
11335
- if (this.costHistory.length === 0)
11336
- return 0;
11308
+ if (this.costHistory.length === 0) return 0;
11337
11309
  return this.costHistory.reduce((a, b) => a + b, 0) / this.costHistory.length;
11338
11310
  }
11339
11311
  checkAnomaly(model, cost) {
11340
- if (this.disabled)
11341
- return false;
11342
- if (this.costHistory.length < COST_WARMUP_SAMPLES)
11343
- return false;
11312
+ if (this.disabled) return false;
11313
+ if (this.costHistory.length < COST_WARMUP_SAMPLES) return false;
11344
11314
  const avg = this.mean;
11345
- if (avg <= 0 || cost <= avg)
11346
- return false;
11315
+ if (avg <= 0 || cost <= avg) return false;
11347
11316
  const ratio = cost / avg;
11348
11317
  if (ratio > COST_ANOMALY_THRESHOLD) {
11349
11318
  this.currentAnomalyModel = model;
@@ -11365,8 +11334,7 @@ var CostAnomalyDetector = class {
11365
11334
  };
11366
11335
  var _costDetector = null;
11367
11336
  function getCostAnomalyDetector() {
11368
- if (!_costDetector)
11369
- _costDetector = new CostAnomalyDetector();
11337
+ if (!_costDetector) _costDetector = new CostAnomalyDetector();
11370
11338
  return _costDetector;
11371
11339
  }
11372
11340
 
@@ -11378,10 +11346,9 @@ import { readFileSync as readFileSync15, writeFileSync as writeFileSync13, appen
11378
11346
  import { join as join16, dirname as dirname11 } from "node:path";
11379
11347
  import { createHash as createHash4 } from "node:crypto";
11380
11348
 
11381
- // src/utils/tdd-helpers.js
11349
+ // src/utils/tdd-helpers.ts
11382
11350
  function extractExports(sourceContent, ext) {
11383
- if (!sourceContent || typeof sourceContent !== "string")
11384
- return [];
11351
+ if (!sourceContent || typeof sourceContent !== "string") return [];
11385
11352
  const exports = [];
11386
11353
  const seen = /* @__PURE__ */ new Set();
11387
11354
  const add = (name, type = "function") => {
@@ -11392,69 +11359,51 @@ function extractExports(sourceContent, ext) {
11392
11359
  };
11393
11360
  switch (ext) {
11394
11361
  case "py": {
11395
- for (const m of sourceContent.matchAll(/^def\s+([a-zA-Z]\w*)\s*\(/gm))
11396
- add(m[1]);
11397
- for (const m of sourceContent.matchAll(/^class\s+([a-zA-Z_]\w*)\s*[\(:]/gm))
11398
- add(m[1], "class");
11362
+ for (const m of sourceContent.matchAll(/^def\s+([a-zA-Z]\w*)\s*\(/gm)) add(m[1]);
11363
+ for (const m of sourceContent.matchAll(/^class\s+([a-zA-Z_]\w*)\s*[\(:]/gm)) add(m[1], "class");
11399
11364
  break;
11400
11365
  }
11401
11366
  case "js":
11402
11367
  case "mjs":
11403
11368
  case "jsx": {
11404
- for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g))
11405
- add(m[1]);
11406
- for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*=/g))
11407
- add(m[1]);
11369
+ for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
11370
+ for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*=/g)) add(m[1]);
11408
11371
  if (exports.length === 0) {
11409
- for (const m of sourceContent.matchAll(/^(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/gm))
11410
- add(m[1]);
11372
+ for (const m of sourceContent.matchAll(/^(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/gm)) add(m[1]);
11411
11373
  }
11412
11374
  break;
11413
11375
  }
11414
11376
  case "ts":
11415
11377
  case "tsx": {
11416
- for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g))
11417
- add(m[1]);
11418
- for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*[:=]/g))
11419
- add(m[1]);
11420
- for (const m of sourceContent.matchAll(/export\s+class\s+([a-zA-Z_$]\w*)/g))
11421
- add(m[1], "class");
11378
+ for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
11379
+ for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*[:=]/g)) add(m[1]);
11380
+ for (const m of sourceContent.matchAll(/export\s+class\s+([a-zA-Z_$]\w*)/g)) add(m[1], "class");
11422
11381
  break;
11423
11382
  }
11424
11383
  case "go": {
11425
- for (const m of sourceContent.matchAll(/func\s+(?:\([^)]+\)\s+)?([A-Z]\w*)\s*\(/g))
11426
- add(m[1]);
11384
+ for (const m of sourceContent.matchAll(/func\s+(?:\([^)]+\)\s+)?([A-Z]\w*)\s*\(/g)) add(m[1]);
11427
11385
  break;
11428
11386
  }
11429
11387
  case "rs": {
11430
- for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*</g))
11431
- add(m[1]);
11432
- for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*\(/g))
11433
- add(m[1]);
11434
- for (const m of sourceContent.matchAll(/pub\s+struct\s+([a-zA-Z_]\w*)/g))
11435
- add(m[1], "struct");
11388
+ for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*</g)) add(m[1]);
11389
+ for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*\(/g)) add(m[1]);
11390
+ for (const m of sourceContent.matchAll(/pub\s+struct\s+([a-zA-Z_]\w*)/g)) add(m[1], "struct");
11436
11391
  break;
11437
11392
  }
11438
11393
  case "rb": {
11439
- for (const m of sourceContent.matchAll(/def\s+(?:self\.)?([a-zA-Z_]\w*[?!=]?)/g))
11440
- add(m[1]);
11441
- for (const m of sourceContent.matchAll(/class\s+([A-Z]\w*)/g))
11442
- add(m[1], "class");
11394
+ for (const m of sourceContent.matchAll(/def\s+(?:self\.)?([a-zA-Z_]\w*[?!=]?)/g)) add(m[1]);
11395
+ for (const m of sourceContent.matchAll(/class\s+([A-Z]\w*)/g)) add(m[1], "class");
11443
11396
  break;
11444
11397
  }
11445
11398
  case "java":
11446
11399
  case "kt": {
11447
- for (const m of sourceContent.matchAll(/(?:public|protected)\s+(?:static\s+)?(?:final\s+)?\S+\s+([a-zA-Z_$]\w*)\s*\(/g))
11448
- add(m[1]);
11449
- for (const m of sourceContent.matchAll(/fun\s+([a-zA-Z_$]\w*)\s*\(/g))
11450
- add(m[1]);
11400
+ for (const m of sourceContent.matchAll(/(?:public|protected)\s+(?:static\s+)?(?:final\s+)?\S+\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
11401
+ for (const m of sourceContent.matchAll(/fun\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
11451
11402
  break;
11452
11403
  }
11453
11404
  case "sh": {
11454
- for (const m of sourceContent.matchAll(/^(?:function\s+)?([a-zA-Z_]\w*)\s*\(\)\s*\{/gm))
11455
- add(m[1]);
11456
- for (const m of sourceContent.matchAll(/^function\s+([a-zA-Z_]\w*)/gm))
11457
- add(m[1]);
11405
+ for (const m of sourceContent.matchAll(/^(?:function\s+)?([a-zA-Z_]\w*)\s*\(\)\s*\{/gm)) add(m[1]);
11406
+ for (const m of sourceContent.matchAll(/^function\s+([a-zA-Z_]\w*)/gm)) add(m[1]);
11458
11407
  break;
11459
11408
  }
11460
11409
  }
@@ -11476,8 +11425,7 @@ function generateTestCaseNames(funcName, _type, quality = false) {
11476
11425
  ];
11477
11426
  }
11478
11427
  function inferFunctionParams(sourceContent, funcName) {
11479
- if (!sourceContent || !funcName)
11480
- return [];
11428
+ if (!sourceContent || !funcName) return [];
11481
11429
  const patterns = [
11482
11430
  new RegExp(`(?:export\\s+)?(?:async\\s+)?function\\s+${funcName}\\s*\\(([^)]*)\\)`, "m"),
11483
11431
  new RegExp(`(?:export\\s+)?const\\s+${funcName}\\s*[:=]\\s*(?:async\\s+)?\\(([^)]*)\\)`, "m"),
@@ -11490,8 +11438,7 @@ function inferFunctionParams(sourceContent, funcName) {
11490
11438
  if (m) {
11491
11439
  return m[1].split(",").map((s) => {
11492
11440
  const trimmed = s.trim();
11493
- if (!trimmed)
11494
- return null;
11441
+ if (!trimmed) return null;
11495
11442
  const nameMatch = trimmed.match(/^\s*((?:public|protected)|static|final|val|var|let|const)?\s*(?:readonly\s+)?(?:[_$a-zA-Z][_$a-zA-Z0-9]*)\s*(?::|(?=\s*=)|(?=\s*[,)]))/);
11496
11443
  const rawName = trimmed.replace(/^[^a-zA-Z_$]*/, "").replace(/[=:].*$/, "").replace(/\s+.*$/, "").trim();
11497
11444
  const defaultMatch = trimmed.match(/=\s*(.+)$/);
@@ -11507,35 +11454,22 @@ function inferFunctionParams(sourceContent, funcName) {
11507
11454
  return [];
11508
11455
  }
11509
11456
  function inferTypeFromName(paramName, defaultValue) {
11510
- if (!paramName)
11511
- return "any";
11457
+ if (!paramName) return "any";
11512
11458
  const name = paramName.toLowerCase();
11513
11459
  if (defaultValue !== null && defaultValue !== void 0) {
11514
- if (/^["']/.test(defaultValue))
11515
- return "string";
11516
- if (/^\d+\.?\d*$/.test(defaultValue))
11517
- return "number";
11518
- if (/^(true|false)$/i.test(defaultValue))
11519
- return "boolean";
11520
- if (/^\[/.test(defaultValue))
11521
- return "array";
11522
- if (/^\{/.test(defaultValue))
11523
- return "object";
11524
- if (/^null$/i.test(defaultValue))
11525
- return "null";
11526
- }
11527
- if (/^(is|has|can|should|will|did|was|are|contains?_|[A-Z])/.test(name))
11528
- return "boolean";
11529
- if (/^(count|index|limit|offset|max|min|size|length|total|num|age)_?/.test(name))
11530
- return "number";
11531
- if (/^(name|title|label|msg|message|text|str|prefix|suffix|path|url|email|id)_?/.test(name))
11532
- return "string";
11533
- if (/^(items|list|arr|entries|data|values|args)_?/.test(name))
11534
- return "array";
11535
- if (/^(obj|config|opts|options|settings|params|props)_?/.test(name))
11536
- return "object";
11537
- if (/^(fn|cb|callback|handler|on[A-Z])/.test(name))
11538
- return "function";
11460
+ if (/^["']/.test(defaultValue)) return "string";
11461
+ if (/^\d+\.?\d*$/.test(defaultValue)) return "number";
11462
+ if (/^(true|false)$/i.test(defaultValue)) return "boolean";
11463
+ if (/^\[/.test(defaultValue)) return "array";
11464
+ if (/^\{/.test(defaultValue)) return "object";
11465
+ if (/^null$/i.test(defaultValue)) return "null";
11466
+ }
11467
+ if (/^(is|has|can|should|will|did|was|are|contains?_|[A-Z])/.test(name)) return "boolean";
11468
+ if (/^(count|index|limit|offset|max|min|size|length|total|num|age)_?/.test(name)) return "number";
11469
+ if (/^(name|title|label|msg|message|text|str|prefix|suffix|path|url|email|id)_?/.test(name)) return "string";
11470
+ if (/^(items|list|arr|entries|data|values|args)_?/.test(name)) return "array";
11471
+ if (/^(obj|config|opts|options|settings|params|props)_?/.test(name)) return "object";
11472
+ if (/^(fn|cb|callback|handler|on[A-Z])/.test(name)) return "function";
11539
11473
  return "any";
11540
11474
  }
11541
11475
  function _langComment(lang) {
@@ -11548,22 +11482,14 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
11548
11482
  let block = "";
11549
11483
  const testValues = params.map((p) => {
11550
11484
  const t = p.type || inferTypeFromName(p.name, p.defaultValue);
11551
- if (t === "string" || t === "String")
11552
- return '"sample_input"';
11553
- if (t === "number" || t === "int" || t === "float" || t === "Number")
11554
- return "42";
11555
- if (t === "boolean" || t === "bool" || t === "Boolean")
11556
- return "true";
11557
- if (t === "array" || t === "Array" || t === "list" || t === "List")
11558
- return "[]";
11559
- if (t === "object" || t === "Object" || t === "dict" || t === "Dict")
11560
- return "{}";
11561
- if (t === "function" || t === "Function")
11562
- return "() => {}";
11563
- if (t === "any")
11564
- return '"test"';
11565
- if (t === "null")
11566
- return "null";
11485
+ if (t === "string" || t === "String") return '"sample_input"';
11486
+ if (t === "number" || t === "int" || t === "float" || t === "Number") return "42";
11487
+ if (t === "boolean" || t === "bool" || t === "Boolean") return "true";
11488
+ if (t === "array" || t === "Array" || t === "list" || t === "List") return "[]";
11489
+ if (t === "object" || t === "Object" || t === "dict" || t === "Dict") return "{}";
11490
+ if (t === "function" || t === "Function") return "() => {}";
11491
+ if (t === "any") return '"test"';
11492
+ if (t === "null") return "null";
11567
11493
  return '"test"';
11568
11494
  });
11569
11495
  const args = testValues.join(", ");
@@ -11593,10 +11519,8 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
11593
11519
  `;
11594
11520
  const ecArgs = params.map((p) => {
11595
11521
  const t = p.type || inferTypeFromName(p.name, p.defaultValue);
11596
- if (t === "string")
11597
- return '""';
11598
- if (t === "number" || t === "int" || t === "float")
11599
- return "0";
11522
+ if (t === "string") return '""';
11523
+ if (t === "number" || t === "int" || t === "float") return "0";
11600
11524
  return '"edge"';
11601
11525
  }).join(", ");
11602
11526
  block += `${indent} result = ${funcName}(${ecArgs})
@@ -11634,16 +11558,11 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
11634
11558
  `;
11635
11559
  const ecArgsJS = params.map((p) => {
11636
11560
  const t = p.type || inferTypeFromName(p.name, p.defaultValue);
11637
- if (t === "string")
11638
- return '""';
11639
- if (t === "number" || t === "int" || t === "float")
11640
- return "0";
11641
- if (t === "boolean")
11642
- return "false";
11643
- if (t === "array")
11644
- return "[]";
11645
- if (t === "object")
11646
- return "{}";
11561
+ if (t === "string") return '""';
11562
+ if (t === "number" || t === "int" || t === "float") return "0";
11563
+ if (t === "boolean") return "false";
11564
+ if (t === "array") return "[]";
11565
+ if (t === "object") return "{}";
11647
11566
  return "undefined";
11648
11567
  }).join(", ");
11649
11568
  block += `${indent} const result = mod.${funcName}(${ecArgsJS});
@@ -11676,15 +11595,14 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
11676
11595
  return block;
11677
11596
  }
11678
11597
  function isSkeletonUseless(content) {
11679
- if (!content)
11680
- return true;
11598
+ if (!content) return true;
11681
11599
  const lines = content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("//") && !l.trim().startsWith("#") && !l.trim().startsWith("/*") && !l.trim().startsWith("*"));
11682
11600
  const todoLines = content.split("\n").filter((l) => /TODO|placeholder|smoke|is exported|module loads/.test(l));
11683
11601
  const meaningfulLines = lines.filter((l) => !/TODO|placeholder|smoke|is exported|module loads|throw new Error|raise AssertionError|pytest\.skip|assert.*true/.test(l));
11684
11602
  return meaningfulLines.length < 2;
11685
11603
  }
11686
11604
 
11687
- // src/lib/test-skeletons.js
11605
+ // src/lib/test-skeletons.ts
11688
11606
  var TEST_SKELETONS = {
11689
11607
  py: (name, exports = [], depth = "full", strict = true, quality = true, sourceContent = "") => {
11690
11608
  const moduleImport = name.replace(/-/g, "_");
@@ -11712,8 +11630,7 @@ var TEST_SKELETONS = {
11712
11630
 
11713
11631
  `;
11714
11632
  for (const exp of exports) {
11715
- if (exp.type === "class")
11716
- continue;
11633
+ if (exp.type === "class") continue;
11717
11634
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
11718
11635
  content += `# TODO: implement tests for ${exp.name}
11719
11636
  `;
@@ -11721,12 +11638,10 @@ var TEST_SKELETONS = {
11721
11638
  const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
11722
11639
  content += `def test_${caseFunc}():
11723
11640
  `;
11724
- if (strict)
11725
- content += ` raise AssertionError("TODO: implement ${caseName}")
11641
+ if (strict) content += ` raise AssertionError("TODO: implement ${caseName}")
11726
11642
 
11727
11643
  `;
11728
- else
11729
- content += ` pytest.skip("TODO: implement ${caseName}")
11644
+ else content += ` pytest.skip("TODO: implement ${caseName}")
11730
11645
 
11731
11646
  `;
11732
11647
  }
@@ -11738,12 +11653,10 @@ var TEST_SKELETONS = {
11738
11653
  if (exports.length === 0) {
11739
11654
  content += `def test_${name}_placeholder():
11740
11655
  `;
11741
- if (strict)
11742
- content += ` raise AssertionError("TODO: implement tests for ${name}")
11656
+ if (strict) content += ` raise AssertionError("TODO: implement tests for ${name}")
11743
11657
 
11744
11658
  `;
11745
- else
11746
- content += ` pytest.skip("TODO: implement tests for ${name}")
11659
+ else content += ` pytest.skip("TODO: implement tests for ${name}")
11747
11660
 
11748
11661
  `;
11749
11662
  }
@@ -11777,8 +11690,7 @@ var TEST_SKELETONS = {
11777
11690
 
11778
11691
  `;
11779
11692
  for (const exp of exports) {
11780
- if (exp.type === "class")
11781
- continue;
11693
+ if (exp.type === "class") continue;
11782
11694
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
11783
11695
  content += ` // TODO: implement tests for ${exp.name}
11784
11696
  `;
@@ -11794,11 +11706,9 @@ var TEST_SKELETONS = {
11794
11706
  `;
11795
11707
  content += ` // TODO: implement ${caseName}
11796
11708
  `;
11797
- if (strict)
11798
- content += ` throw new Error('TODO: implement ${caseName}');
11709
+ if (strict) content += ` throw new Error('TODO: implement ${caseName}');
11799
11710
  `;
11800
- else
11801
- content += ` expect(true).toBe(true);
11711
+ else content += ` expect(true).toBe(true);
11802
11712
  `;
11803
11713
  content += ` });
11804
11714
 
@@ -11851,8 +11761,7 @@ var TEST_SKELETONS = {
11851
11761
 
11852
11762
  `;
11853
11763
  for (const exp of exports) {
11854
- if (exp.type === "class")
11855
- continue;
11764
+ if (exp.type === "class") continue;
11856
11765
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
11857
11766
  content += ` // TODO: implement tests for ${exp.name}
11858
11767
  `;
@@ -11868,11 +11777,9 @@ var TEST_SKELETONS = {
11868
11777
  `;
11869
11778
  content += ` // TODO: implement ${caseName}
11870
11779
  `;
11871
- if (strict)
11872
- content += ` throw new Error('TODO: implement ${caseName}');
11780
+ if (strict) content += ` throw new Error('TODO: implement ${caseName}');
11873
11781
  `;
11874
- else
11875
- content += ` expect(true).toBe(true);
11782
+ else content += ` expect(true).toBe(true);
11876
11783
  `;
11877
11784
  content += ` });
11878
11785
 
@@ -11925,8 +11832,7 @@ var TEST_SKELETONS = {
11925
11832
 
11926
11833
  `;
11927
11834
  for (const exp of exports) {
11928
- if (exp.type === "class")
11929
- continue;
11835
+ if (exp.type === "class") continue;
11930
11836
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
11931
11837
  content += ` // TODO: implement tests for ${exp.name}
11932
11838
  `;
@@ -11942,11 +11848,9 @@ var TEST_SKELETONS = {
11942
11848
  `;
11943
11849
  content += ` // TODO: implement ${caseName}
11944
11850
  `;
11945
- if (strict)
11946
- content += ` throw new Error('TODO: implement ${caseName}');
11851
+ if (strict) content += ` throw new Error('TODO: implement ${caseName}');
11947
11852
  `;
11948
- else
11949
- content += ` expect(true).toBe(true);
11853
+ else content += ` expect(true).toBe(true);
11950
11854
  `;
11951
11855
  content += ` });
11952
11856
 
@@ -12006,8 +11910,7 @@ var TEST_SKELETONS = {
12006
11910
 
12007
11911
  `;
12008
11912
  for (const exp of exports) {
12009
- if (exp.type === "class")
12010
- continue;
11913
+ if (exp.type === "class") continue;
12011
11914
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
12012
11915
  const expCap = exp.name.charAt(0).toUpperCase() + exp.name.slice(1);
12013
11916
  content += `// TODO: implement tests for ${exp.name}
@@ -12016,11 +11919,9 @@ var TEST_SKELETONS = {
12016
11919
  const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
12017
11920
  content += `func Test${cap}_${caseFunc}(t *testing.T) {
12018
11921
  `;
12019
- if (strict)
12020
- content += ` t.Error("TODO: implement ${caseName}")
11922
+ if (strict) content += ` t.Error("TODO: implement ${caseName}")
12021
11923
  `;
12022
- else
12023
- content += ` t.Skip("TODO: implement ${caseName}")
11924
+ else content += ` t.Skip("TODO: implement ${caseName}")
12024
11925
  `;
12025
11926
  content += `}
12026
11927
 
@@ -12040,11 +11941,9 @@ var TEST_SKELETONS = {
12040
11941
  if (exports.length === 0) {
12041
11942
  content += `func Test${cap}_Placeholder(t *testing.T) {
12042
11943
  `;
12043
- if (strict)
12044
- content += ` t.Error("TODO: implement tests for ${name}")
11944
+ if (strict) content += ` t.Error("TODO: implement tests for ${name}")
12045
11945
  `;
12046
- else
12047
- content += ` t.Skip("TODO: implement tests for ${name}")
11946
+ else content += ` t.Skip("TODO: implement tests for ${name}")
12048
11947
  `;
12049
11948
  content += `}
12050
11949
  `;
@@ -12077,11 +11976,9 @@ var TEST_SKELETONS = {
12077
11976
  `;
12078
11977
  content += ` echo "TODO: implement ${caseName}"
12079
11978
  `;
12080
- if (strict)
12081
- content += ` exit 1
11979
+ if (strict) content += ` exit 1
12082
11980
  `;
12083
- else
12084
- content += ` echo "SKIP: ${caseName}"
11981
+ else content += ` echo "SKIP: ${caseName}"
12085
11982
  `;
12086
11983
  content += `}
12087
11984
 
@@ -12095,11 +11992,9 @@ var TEST_SKELETONS = {
12095
11992
  if (exports.length === 0) {
12096
11993
  content += `function test_smoke {
12097
11994
  `;
12098
- if (strict)
12099
- content += ` echo "TODO: implement tests for ${name}" && exit 1
11995
+ if (strict) content += ` echo "TODO: implement tests for ${name}" && exit 1
12100
11996
  `;
12101
- else
12102
- content += ` echo "TODO: implement tests for ${name}"
11997
+ else content += ` echo "TODO: implement tests for ${name}"
12103
11998
  `;
12104
11999
  content += `}
12105
12000
  `;
@@ -12139,8 +12034,7 @@ mod tests {
12139
12034
 
12140
12035
  `;
12141
12036
  for (const exp of exports) {
12142
- if (exp.type === "class")
12143
- continue;
12037
+ if (exp.type === "class") continue;
12144
12038
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
12145
12039
  content += ` // TODO: implement tests for ${exp.name}
12146
12040
  `;
@@ -12149,11 +12043,9 @@ mod tests {
12149
12043
  content += ` #[test]
12150
12044
  fn test_${caseFunc}() {
12151
12045
  `;
12152
- if (strict)
12153
- content += ` panic!("TODO: implement ${caseName}");
12046
+ if (strict) content += ` panic!("TODO: implement ${caseName}");
12154
12047
  `;
12155
- else
12156
- content += ` // TODO: implement ${caseName}
12048
+ else content += ` // TODO: implement ${caseName}
12157
12049
  `;
12158
12050
  content += ` }
12159
12051
 
@@ -12168,11 +12060,9 @@ mod tests {
12168
12060
  content += ` #[test]
12169
12061
  fn ${name}_placeholder() {
12170
12062
  `;
12171
- if (strict)
12172
- content += ` panic!("TODO: implement tests for ${name}");
12063
+ if (strict) content += ` panic!("TODO: implement tests for ${name}");
12173
12064
  `;
12174
- else
12175
- content += ` // TODO: implement tests for ${name}
12065
+ else content += ` // TODO: implement tests for ${name}
12176
12066
  `;
12177
12067
  content += ` }
12178
12068
  `;
@@ -12212,8 +12102,7 @@ mod tests {
12212
12102
 
12213
12103
  `;
12214
12104
  for (const exp of exports) {
12215
- if (exp.type === "class")
12216
- continue;
12105
+ if (exp.type === "class") continue;
12217
12106
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
12218
12107
  content += ` # TODO: implement tests for ${exp.name}
12219
12108
  `;
@@ -12221,11 +12110,9 @@ mod tests {
12221
12110
  const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
12222
12111
  content += ` def test_${caseFunc}
12223
12112
  `;
12224
- if (strict)
12225
- content += ` flunk "TODO: implement ${caseName}"
12113
+ if (strict) content += ` flunk "TODO: implement ${caseName}"
12226
12114
  `;
12227
- else
12228
- content += ` # TODO: implement ${caseName}
12115
+ else content += ` # TODO: implement ${caseName}
12229
12116
  `;
12230
12117
  content += ` end
12231
12118
 
@@ -12239,11 +12126,9 @@ mod tests {
12239
12126
  if (exports.length === 0) {
12240
12127
  content += ` def test_placeholder
12241
12128
  `;
12242
- if (strict)
12243
- content += ` flunk "TODO: implement tests for ${name}"
12129
+ if (strict) content += ` flunk "TODO: implement tests for ${name}"
12244
12130
  `;
12245
- else
12246
- content += ` # TODO: implement tests for ${name}
12131
+ else content += ` # TODO: implement tests for ${name}
12247
12132
  `;
12248
12133
  content += ` end
12249
12134
  `;
@@ -12289,18 +12174,15 @@ mod tests {
12289
12174
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
12290
12175
  for (const caseName of cases) {
12291
12176
  const testFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
12292
- if (!strict)
12293
- content += ` // @Disabled("TODO")
12177
+ if (!strict) content += ` // @Disabled("TODO")
12294
12178
  `;
12295
12179
  content += ` @Test
12296
12180
  `;
12297
12181
  content += ` void test${testFunc.charAt(0).toUpperCase() + testFunc.slice(1)}() {
12298
12182
  `;
12299
- if (strict)
12300
- content += ` fail("TODO: implement ${caseName}");
12183
+ if (strict) content += ` fail("TODO: implement ${caseName}");
12301
12184
  `;
12302
- else
12303
- content += ` assertTrue(true); // TODO: implement ${caseName}
12185
+ else content += ` assertTrue(true); // TODO: implement ${caseName}
12304
12186
  `;
12305
12187
  content += ` }
12306
12188
 
@@ -12362,18 +12244,15 @@ mod tests {
12362
12244
  const cases = generateTestCaseNames(exp.name, exp.type, quality);
12363
12245
  for (const caseName of cases) {
12364
12246
  const testFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
12365
- if (!strict)
12366
- content += ` // @Disabled("TODO")
12247
+ if (!strict) content += ` // @Disabled("TODO")
12367
12248
  `;
12368
12249
  content += ` @Test
12369
12250
  `;
12370
12251
  content += ` fun test${testFunc.charAt(0).toUpperCase() + testFunc.slice(1)}() {
12371
12252
  `;
12372
- if (strict)
12373
- content += ` fail("TODO: implement ${caseName}")
12253
+ if (strict) content += ` fail("TODO: implement ${caseName}")
12374
12254
  `;
12375
- else
12376
- content += ` assertTrue(true) // TODO: implement ${caseName}
12255
+ else content += ` assertTrue(true) // TODO: implement ${caseName}
12377
12256
  `;
12378
12257
  content += ` }
12379
12258
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.24.8",
3
+ "version": "0.24.10",
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",