vibeostheog 0.24.8 → 0.24.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 +14 -0
- package/dist/vibeOS.js +149 -274
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 0.24.12
|
|
2
|
+
- feat: smooth delegation UX — conversational reasoning over error injection
|
|
3
|
+
- fix: write npm auth for github release publish
|
|
4
|
+
- fix: reset api fallback on token refresh (#138)
|
|
5
|
+
- fix: _prevBlackboxState -> _latestBlackboxState, update pattern key test
|
|
6
|
+
- fix: sync-ts-build was cleaning JS artifacts without copying compiled output back
|
|
7
|
+
- fix: forensic anti-lying + quality enforcement pipeline
|
|
8
|
+
- docs: add cross-project index, DEV ONLY markers, ESLint cleanup
|
|
9
|
+
- test: add 13 cascade integration tests for forensic quality pipeline
|
|
10
|
+
- chore: sync package version to latest github release
|
|
11
|
+
- chore: sync package version to latest release
|
|
12
|
+
Merge pull request #136 from DrunkkToys/release/v0.24.8-merge
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
## 0.24.5
|
|
2
16
|
- fix: cap saveEst at to prevent runaway pricing data corruption
|
|
3
17
|
- chore: v0.24.4
|
package/dist/vibeOS.js
CHANGED
|
@@ -2152,9 +2152,13 @@ function setApiToken(newToken) {
|
|
|
2152
2152
|
VIBEOS_API_TOKEN = normalizeApiToken(newToken, EMBEDDED_API_TOKEN);
|
|
2153
2153
|
VIBEOS_API_BOOTSTRAP_TOKEN = readBootstrapTokenFromDisk() || VIBEOS_API_BOOTSTRAP_TOKEN;
|
|
2154
2154
|
VIBEOS_API_ENABLED = process.env.VIBEOS_API_ENABLED !== "false" && (!!VIBEOS_API_TOKEN || !!VIBEOS_API_BOOTSTRAP_TOKEN);
|
|
2155
|
+
_apiClient = null;
|
|
2156
|
+
_apiFallbackMode = false;
|
|
2157
|
+
_apiFallbackSince = null;
|
|
2155
2158
|
persistPrimaryApiEnvState({ token: VIBEOS_API_TOKEN, disabled: false });
|
|
2156
2159
|
if (_anomalyDetector)
|
|
2157
2160
|
_anomalyDetector.reset();
|
|
2161
|
+
resetApiConnection();
|
|
2158
2162
|
console.error("[vibeOS] API token updated via setApiToken");
|
|
2159
2163
|
} catch (e) {
|
|
2160
2164
|
console.error("[vibeOS] Failed to update API token:", e.message);
|
|
@@ -2529,56 +2533,42 @@ function writeSessionOptMode(sid, mode) {
|
|
|
2529
2533
|
}
|
|
2530
2534
|
}
|
|
2531
2535
|
|
|
2532
|
-
// src/lib/pattern-helpers.
|
|
2536
|
+
// src/lib/pattern-helpers.ts
|
|
2533
2537
|
import { relative, basename as basename2 } from "node:path";
|
|
2534
2538
|
function normalizeObservedPath(filePath, directory3) {
|
|
2535
|
-
if (!filePath || typeof filePath !== "string")
|
|
2536
|
-
return "unknown";
|
|
2539
|
+
if (!filePath || typeof filePath !== "string") return "unknown";
|
|
2537
2540
|
let p = filePath;
|
|
2538
2541
|
try {
|
|
2539
2542
|
if (directory3 && p.startsWith("/")) {
|
|
2540
2543
|
const rel = relative(directory3, p);
|
|
2541
|
-
if (rel && !rel.startsWith("..") && !rel.startsWith("/"))
|
|
2542
|
-
p = rel;
|
|
2544
|
+
if (rel && !rel.startsWith("..") && !rel.startsWith("/")) p = rel;
|
|
2543
2545
|
}
|
|
2544
2546
|
} catch {
|
|
2545
2547
|
}
|
|
2546
2548
|
p = p.replace(/\\/g, "/").replace(/^\.\/+/, "");
|
|
2547
|
-
if (/^(src\/index\.js|package\.json|README\.md|CHANGELOG\.md|tsconfig\.json)$/i.test(p))
|
|
2548
|
-
return p;
|
|
2549
|
+
if (/^(src\/index\.js|package\.json|README\.md|CHANGELOG\.md|tsconfig\.json)$/i.test(p)) return p;
|
|
2549
2550
|
const m = p.match(/\.([a-z0-9]+)$/i);
|
|
2550
|
-
if (p.startsWith("src/") && m)
|
|
2551
|
-
|
|
2552
|
-
if (p.startsWith("tests/") && m)
|
|
2553
|
-
return `tests/*.${m[1].toLowerCase()}`;
|
|
2551
|
+
if (p.startsWith("src/") && m) return `src/*.${m[1].toLowerCase()}`;
|
|
2552
|
+
if (p.startsWith("tests/") && m) return `tests/*.${m[1].toLowerCase()}`;
|
|
2554
2553
|
return basename2(p) || "unknown";
|
|
2555
2554
|
}
|
|
2556
2555
|
function commandFamily(command) {
|
|
2557
2556
|
const c = String(command || "").trim().toLowerCase();
|
|
2558
|
-
if (!c)
|
|
2559
|
-
|
|
2560
|
-
if (/\
|
|
2561
|
-
|
|
2562
|
-
if (/\bnpm\s+run\s+
|
|
2563
|
-
|
|
2564
|
-
if (/\
|
|
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";
|
|
2557
|
+
if (!c) return "unknown";
|
|
2558
|
+
if (/\bnode\s+--check\b/.test(c)) return "syntax-check";
|
|
2559
|
+
if (/\bnpm\s+run\s+typecheck\b|\btsc\b.*--noemit/.test(c)) return "typecheck";
|
|
2560
|
+
if (/\bnpm\s+test\b|\bnode\s+--test\b|\bvitest\b|\bjest\b|\bpytest\b/.test(c)) return "test";
|
|
2561
|
+
if (/\bnpm\s+run\s+build\b|\btsc\s+-p\b/.test(c)) return "build";
|
|
2562
|
+
if (/\bgit\s+status\b/.test(c)) return "git-status";
|
|
2563
|
+
if (/\bgit\s+commit\b/.test(c)) return "git-commit";
|
|
2572
2564
|
const first = c.replace(/^[a-z_][a-z0-9_]*=\S+\s+/g, "").split(/\s+/)[0];
|
|
2573
2565
|
return /^[a-z0-9._/-]{1,30}$/.test(first) ? first : "command";
|
|
2574
2566
|
}
|
|
2575
2567
|
function commandFailed(output) {
|
|
2576
2568
|
const code = output?.exitCode ?? output?.statusCode ?? output?.code;
|
|
2577
|
-
if (Number.isFinite(Number(code)) && Number(code) !== 0)
|
|
2578
|
-
return true;
|
|
2569
|
+
if (Number.isFinite(Number(code)) && Number(code) !== 0) return true;
|
|
2579
2570
|
const raw = output?.result ?? output?.text ?? output?.content ?? output?.data ?? "";
|
|
2580
|
-
if (typeof raw !== "string")
|
|
2581
|
-
return false;
|
|
2571
|
+
if (typeof raw !== "string") return false;
|
|
2582
2572
|
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
2573
|
}
|
|
2584
2574
|
function mergeProjectBucket(dst, src) {
|
|
@@ -2595,8 +2585,7 @@ function mergeProjectBucket(dst, src) {
|
|
|
2595
2585
|
row.sessions = [.../* @__PURE__ */ new Set([...row.sessions || [], ...v?.sessions || []])].slice(-10);
|
|
2596
2586
|
row.lastSeen = [row.lastSeen, v?.lastSeen].filter(Boolean).sort().slice(-1)[0] || null;
|
|
2597
2587
|
row.summary = row.summary || v?.summary || "";
|
|
2598
|
-
if (v?.kind)
|
|
2599
|
-
row.kind = v.kind;
|
|
2588
|
+
if (v?.kind) row.kind = v.kind;
|
|
2600
2589
|
out[key] = row;
|
|
2601
2590
|
}
|
|
2602
2591
|
}
|
|
@@ -2615,11 +2604,9 @@ function mergeProjectBucket(dst, src) {
|
|
|
2615
2604
|
};
|
|
2616
2605
|
}
|
|
2617
2606
|
function _pruneOldSessions(state) {
|
|
2618
|
-
if (!state?.sessions)
|
|
2619
|
-
return;
|
|
2607
|
+
if (!state?.sessions) return;
|
|
2620
2608
|
const entries = Object.entries(state.sessions);
|
|
2621
|
-
if (entries.length <= 30)
|
|
2622
|
-
return;
|
|
2609
|
+
if (entries.length <= 30) return;
|
|
2623
2610
|
entries.sort((a, b) => {
|
|
2624
2611
|
const da = a[1]?.started || a[1]?.last_costed || "";
|
|
2625
2612
|
const db = b[1]?.started || b[1]?.last_costed || "";
|
|
@@ -9456,7 +9443,7 @@ import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, appen
|
|
|
9456
9443
|
import { join as join14, dirname as dirname10, basename as basename6 } from "node:path";
|
|
9457
9444
|
import { createHash as createHash3 } from "node:crypto";
|
|
9458
9445
|
|
|
9459
|
-
// src/lib/mode-policy.
|
|
9446
|
+
// src/lib/mode-policy.ts
|
|
9460
9447
|
var STRESS_QUALITY_THRESHOLD = 1.5;
|
|
9461
9448
|
var BASELINE_MODE = "budget";
|
|
9462
9449
|
var LOOP_REGIMES = /* @__PURE__ */ new Set(["LOOPING", "DIVERGENT"]);
|
|
@@ -9464,8 +9451,7 @@ var QUALITY_REGIMES = /* @__PURE__ */ new Set(["CONVERGING", "CLOSED"]);
|
|
|
9464
9451
|
var MANUAL_MODES = /* @__PURE__ */ new Set(["balanced", "quality", "speed", "longrun", "vibemax", "vibeqmax", "vibeultrax"]);
|
|
9465
9452
|
function normalizeMode(mode) {
|
|
9466
9453
|
const normalized = String(mode || BASELINE_MODE).toLowerCase();
|
|
9467
|
-
if (normalized === "auto" || normalized === "")
|
|
9468
|
-
return BASELINE_MODE;
|
|
9454
|
+
if (normalized === "auto" || normalized === "") return BASELINE_MODE;
|
|
9469
9455
|
if (normalized === "budget" || normalized === "quality" || normalized === "speed" || normalized === "longrun" || normalized === "balanced" || normalized === "vibemax" || normalized === "vibeqmax" || normalized === "vibeultrax") {
|
|
9470
9456
|
return normalized;
|
|
9471
9457
|
}
|
|
@@ -9478,12 +9464,9 @@ function isManualOverride(mode) {
|
|
|
9478
9464
|
return MANUAL_MODES.has(normalizeMode(mode));
|
|
9479
9465
|
}
|
|
9480
9466
|
function chooseEpisodeMode(regime, suggestedMode, stress) {
|
|
9481
|
-
if (suggestedMode === "vibeultrax" || suggestedMode === "vibeqmax" || suggestedMode === "vibemax")
|
|
9482
|
-
|
|
9483
|
-
if (
|
|
9484
|
-
return "speed";
|
|
9485
|
-
if (QUALITY_REGIMES.has(regime) || suggestedMode === "quality")
|
|
9486
|
-
return "quality";
|
|
9467
|
+
if (suggestedMode === "vibeultrax" || suggestedMode === "vibeqmax" || suggestedMode === "vibemax") return suggestedMode;
|
|
9468
|
+
if (LOOP_REGIMES.has(regime) || suggestedMode === "speed") return "speed";
|
|
9469
|
+
if (QUALITY_REGIMES.has(regime) || suggestedMode === "quality") return "quality";
|
|
9487
9470
|
return stress > STRESS_QUALITY_THRESHOLD ? "quality" : "budget";
|
|
9488
9471
|
}
|
|
9489
9472
|
function defaultPolicy() {
|
|
@@ -9504,19 +9487,15 @@ function defaultPolicy() {
|
|
|
9504
9487
|
}
|
|
9505
9488
|
function modeToSlot(mode) {
|
|
9506
9489
|
const normalized = normalizeMode(mode);
|
|
9507
|
-
if (normalized === "speed")
|
|
9508
|
-
|
|
9509
|
-
if (normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax")
|
|
9510
|
-
return "brain";
|
|
9490
|
+
if (normalized === "speed") return "medium";
|
|
9491
|
+
if (normalized === "quality" || normalized === "longrun" || normalized === "vibeultrax" || normalized === "vibeqmax") return "brain";
|
|
9511
9492
|
return "cheap";
|
|
9512
9493
|
}
|
|
9513
9494
|
function loadSessionPolicy() {
|
|
9514
9495
|
const state = loadBlackboxState();
|
|
9515
|
-
if (!state.sessions || typeof state.sessions !== "object")
|
|
9516
|
-
state.sessions = {};
|
|
9496
|
+
if (!state.sessions || typeof state.sessions !== "object") state.sessions = {};
|
|
9517
9497
|
const sid = _OC_SID;
|
|
9518
|
-
if (!state.sessions[sid] || typeof state.sessions[sid] !== "object")
|
|
9519
|
-
state.sessions[sid] = {};
|
|
9498
|
+
if (!state.sessions[sid] || typeof state.sessions[sid] !== "object") state.sessions[sid] = {};
|
|
9520
9499
|
const session = state.sessions[sid];
|
|
9521
9500
|
if (!session.mode_policy || typeof session.mode_policy !== "object") {
|
|
9522
9501
|
session.mode_policy = defaultPolicy();
|
|
@@ -9644,7 +9623,7 @@ function recordBudgetFirstOutcome(input = {}) {
|
|
|
9644
9623
|
import { join as join13 } from "node:path";
|
|
9645
9624
|
import { writeFileSync as writeFileSync11 } from "node:fs";
|
|
9646
9625
|
|
|
9647
|
-
// src/lib/text-compress.
|
|
9626
|
+
// src/lib/text-compress.ts
|
|
9648
9627
|
var VERBOSE_LINE_RE = [
|
|
9649
9628
|
/^[\s#*/\\\-_=+|~:;'"`@\$%^&<>{}\[\]()!?.,0-9]+$/,
|
|
9650
9629
|
/^(Filed|Created|Modified|Deleted|Updated|Renamed|Copied|Moved|Changed):/,
|
|
@@ -9661,15 +9640,12 @@ function extractBulletLines(lines, targetChars, minLines) {
|
|
|
9661
9640
|
const keyLines = [];
|
|
9662
9641
|
const otherLines = [];
|
|
9663
9642
|
for (const line of lines) {
|
|
9664
|
-
if (BULLET_PATTERNS.some((re) => re.test(line)))
|
|
9665
|
-
|
|
9666
|
-
else
|
|
9667
|
-
otherLines.push(line);
|
|
9643
|
+
if (BULLET_PATTERNS.some((re) => re.test(line))) keyLines.push(line);
|
|
9644
|
+
else otherLines.push(line);
|
|
9668
9645
|
}
|
|
9669
9646
|
const selected = [...keyLines];
|
|
9670
9647
|
for (const line of otherLines) {
|
|
9671
|
-
if (selected.length >= minLines && selected.join("\n").length >= targetChars)
|
|
9672
|
-
break;
|
|
9648
|
+
if (selected.length >= minLines && selected.join("\n").length >= targetChars) break;
|
|
9673
9649
|
selected.push(line);
|
|
9674
9650
|
}
|
|
9675
9651
|
while (selected.length > minLines && selected.join("\n").length > targetChars * 2) {
|
|
@@ -9678,8 +9654,7 @@ function extractBulletLines(lines, targetChars, minLines) {
|
|
|
9678
9654
|
return selected;
|
|
9679
9655
|
}
|
|
9680
9656
|
function compressText(text) {
|
|
9681
|
-
if (!text || typeof text !== "string")
|
|
9682
|
-
return text;
|
|
9657
|
+
if (!text || typeof text !== "string") return text;
|
|
9683
9658
|
let lines = text.split("\n");
|
|
9684
9659
|
let removed = 0;
|
|
9685
9660
|
const out = [];
|
|
@@ -9692,16 +9667,14 @@ function compressText(text) {
|
|
|
9692
9667
|
break;
|
|
9693
9668
|
}
|
|
9694
9669
|
}
|
|
9695
|
-
if (!skip)
|
|
9696
|
-
out.push(line);
|
|
9670
|
+
if (!skip) out.push(line);
|
|
9697
9671
|
}
|
|
9698
9672
|
const collapsed = [];
|
|
9699
9673
|
let blanks = 0;
|
|
9700
9674
|
for (const line of out) {
|
|
9701
9675
|
if (line.trim() === "") {
|
|
9702
9676
|
blanks++;
|
|
9703
|
-
if (blanks <= 2)
|
|
9704
|
-
collapsed.push(line);
|
|
9677
|
+
if (blanks <= 2) collapsed.push(line);
|
|
9705
9678
|
} else {
|
|
9706
9679
|
blanks = 0;
|
|
9707
9680
|
collapsed.push(line);
|
|
@@ -9709,7 +9682,10 @@ function compressText(text) {
|
|
|
9709
9682
|
}
|
|
9710
9683
|
let result = collapsed.join("\n").trim();
|
|
9711
9684
|
if (result.length > COMPRESS_THRESHOLD) {
|
|
9712
|
-
const targetChars = Math.max(
|
|
9685
|
+
const targetChars = Math.max(
|
|
9686
|
+
Math.round(result.length * COMPRESS_RATIO),
|
|
9687
|
+
COMPRESS_THRESHOLD
|
|
9688
|
+
);
|
|
9713
9689
|
const minLines = Math.max(1, Math.round(collapsed.length * MIN_KEPT_LINES_RATIO));
|
|
9714
9690
|
const bulletLines = extractBulletLines(collapsed, targetChars, minLines);
|
|
9715
9691
|
result = bulletLines.join("\n").trim();
|
|
@@ -10024,7 +10000,7 @@ function recordSaving(tool2, reason, saveEst, meta = {}) {
|
|
|
10024
10000
|
}
|
|
10025
10001
|
}
|
|
10026
10002
|
|
|
10027
|
-
// src/lib/constants.
|
|
10003
|
+
// src/lib/constants.ts
|
|
10028
10004
|
var SAVE_EST = {
|
|
10029
10005
|
// Realistic: v4-pro (0.00057) - v4-flash (0.000182) = 0.000388/turn
|
|
10030
10006
|
WRITE_EDIT: 4e-4,
|
|
@@ -10042,7 +10018,7 @@ var COMPRESS_MARKER = "[ctx-compressed-v1]";
|
|
|
10042
10018
|
var PROTOCOL_MARKER = "[wbp-v1]";
|
|
10043
10019
|
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
10020
|
|
|
10045
|
-
// src/lib/templates.
|
|
10021
|
+
// src/lib/templates.ts
|
|
10046
10022
|
var TEMPLATES = {
|
|
10047
10023
|
save: {
|
|
10048
10024
|
tier_bias: "cheap",
|
|
@@ -10092,8 +10068,7 @@ var TEMPLATES = {
|
|
|
10092
10068
|
var DEFAULT_TEMPLATE = "save";
|
|
10093
10069
|
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
10070
|
function detectSecuritySignal(text) {
|
|
10095
|
-
if (!text || typeof text !== "string")
|
|
10096
|
-
return false;
|
|
10071
|
+
if (!text || typeof text !== "string") return false;
|
|
10097
10072
|
return SEC_KEYWORDS.test(text);
|
|
10098
10073
|
}
|
|
10099
10074
|
function detectBudgetSignal(creditPercent) {
|
|
@@ -10106,25 +10081,20 @@ function detectStressSpike(stressScore) {
|
|
|
10106
10081
|
return delta > 0.3 && stressScore > 0.5;
|
|
10107
10082
|
}
|
|
10108
10083
|
function resolveTemplate(prevTemplate, stressScore, userText, creditPercent, subRegime) {
|
|
10109
|
-
if (detectSecuritySignal(userText))
|
|
10110
|
-
return "security";
|
|
10084
|
+
if (detectSecuritySignal(userText)) return "security";
|
|
10111
10085
|
if (detectBudgetSignal(creditPercent)) {
|
|
10112
10086
|
const regime = String(subRegime || "").toUpperCase();
|
|
10113
|
-
if (regime === "LOOPING" || regime === "DIVERGENT")
|
|
10114
|
-
return "speed";
|
|
10087
|
+
if (regime === "LOOPING" || regime === "DIVERGENT") return "speed";
|
|
10115
10088
|
return "save";
|
|
10116
10089
|
}
|
|
10117
|
-
if (detectStressSpike(stressScore))
|
|
10118
|
-
return "quality";
|
|
10090
|
+
if (detectStressSpike(stressScore)) return "quality";
|
|
10119
10091
|
return prevTemplate || DEFAULT_TEMPLATE;
|
|
10120
10092
|
}
|
|
10121
10093
|
var _turnCount = 0;
|
|
10122
10094
|
function shouldInjectTemplate(template, prevTemplate) {
|
|
10123
10095
|
_turnCount++;
|
|
10124
|
-
if (template !== prevTemplate)
|
|
10125
|
-
|
|
10126
|
-
if (_turnCount % 10 === 0)
|
|
10127
|
-
return true;
|
|
10096
|
+
if (template !== prevTemplate) return true;
|
|
10097
|
+
if (_turnCount % 10 === 0) return true;
|
|
10128
10098
|
return false;
|
|
10129
10099
|
}
|
|
10130
10100
|
|
|
@@ -11313,7 +11283,7 @@ import { writeFileSync as writeFileSync14, appendFileSync as appendFileSync8, ex
|
|
|
11313
11283
|
import { join as join17, dirname as dirname12, basename as basename7 } from "node:path";
|
|
11314
11284
|
import { createHash as createHash5 } from "node:crypto";
|
|
11315
11285
|
|
|
11316
|
-
// src/lib/cost-anomaly.
|
|
11286
|
+
// src/lib/cost-anomaly.ts
|
|
11317
11287
|
var COST_WINDOW_SIZE = 20;
|
|
11318
11288
|
var COST_ANOMALY_THRESHOLD = 3;
|
|
11319
11289
|
var COST_WARMUP_SAMPLES = 5;
|
|
@@ -11324,26 +11294,21 @@ var CostAnomalyDetector = class {
|
|
|
11324
11294
|
currentAnomalyCost = 0;
|
|
11325
11295
|
currentAnomalyMean = 0;
|
|
11326
11296
|
record(cost) {
|
|
11327
|
-
if (this.disabled)
|
|
11328
|
-
return;
|
|
11297
|
+
if (this.disabled) return;
|
|
11329
11298
|
this.costHistory.push(cost);
|
|
11330
11299
|
if (this.costHistory.length > COST_WINDOW_SIZE) {
|
|
11331
11300
|
this.costHistory.shift();
|
|
11332
11301
|
}
|
|
11333
11302
|
}
|
|
11334
11303
|
get mean() {
|
|
11335
|
-
if (this.costHistory.length === 0)
|
|
11336
|
-
return 0;
|
|
11304
|
+
if (this.costHistory.length === 0) return 0;
|
|
11337
11305
|
return this.costHistory.reduce((a, b) => a + b, 0) / this.costHistory.length;
|
|
11338
11306
|
}
|
|
11339
11307
|
checkAnomaly(model, cost) {
|
|
11340
|
-
if (this.disabled)
|
|
11341
|
-
|
|
11342
|
-
if (this.costHistory.length < COST_WARMUP_SAMPLES)
|
|
11343
|
-
return false;
|
|
11308
|
+
if (this.disabled) return false;
|
|
11309
|
+
if (this.costHistory.length < COST_WARMUP_SAMPLES) return false;
|
|
11344
11310
|
const avg = this.mean;
|
|
11345
|
-
if (avg <= 0 || cost <= avg)
|
|
11346
|
-
return false;
|
|
11311
|
+
if (avg <= 0 || cost <= avg) return false;
|
|
11347
11312
|
const ratio = cost / avg;
|
|
11348
11313
|
if (ratio > COST_ANOMALY_THRESHOLD) {
|
|
11349
11314
|
this.currentAnomalyModel = model;
|
|
@@ -11365,8 +11330,7 @@ var CostAnomalyDetector = class {
|
|
|
11365
11330
|
};
|
|
11366
11331
|
var _costDetector = null;
|
|
11367
11332
|
function getCostAnomalyDetector() {
|
|
11368
|
-
if (!_costDetector)
|
|
11369
|
-
_costDetector = new CostAnomalyDetector();
|
|
11333
|
+
if (!_costDetector) _costDetector = new CostAnomalyDetector();
|
|
11370
11334
|
return _costDetector;
|
|
11371
11335
|
}
|
|
11372
11336
|
|
|
@@ -11378,10 +11342,9 @@ import { readFileSync as readFileSync15, writeFileSync as writeFileSync13, appen
|
|
|
11378
11342
|
import { join as join16, dirname as dirname11 } from "node:path";
|
|
11379
11343
|
import { createHash as createHash4 } from "node:crypto";
|
|
11380
11344
|
|
|
11381
|
-
// src/utils/tdd-helpers.
|
|
11345
|
+
// src/utils/tdd-helpers.ts
|
|
11382
11346
|
function extractExports(sourceContent, ext) {
|
|
11383
|
-
if (!sourceContent || typeof sourceContent !== "string")
|
|
11384
|
-
return [];
|
|
11347
|
+
if (!sourceContent || typeof sourceContent !== "string") return [];
|
|
11385
11348
|
const exports = [];
|
|
11386
11349
|
const seen = /* @__PURE__ */ new Set();
|
|
11387
11350
|
const add = (name, type = "function") => {
|
|
@@ -11392,69 +11355,51 @@ function extractExports(sourceContent, ext) {
|
|
|
11392
11355
|
};
|
|
11393
11356
|
switch (ext) {
|
|
11394
11357
|
case "py": {
|
|
11395
|
-
for (const m of sourceContent.matchAll(/^def\s+([a-zA-Z]\w*)\s*\(/gm))
|
|
11396
|
-
|
|
11397
|
-
for (const m of sourceContent.matchAll(/^class\s+([a-zA-Z_]\w*)\s*[\(:]/gm))
|
|
11398
|
-
add(m[1], "class");
|
|
11358
|
+
for (const m of sourceContent.matchAll(/^def\s+([a-zA-Z]\w*)\s*\(/gm)) add(m[1]);
|
|
11359
|
+
for (const m of sourceContent.matchAll(/^class\s+([a-zA-Z_]\w*)\s*[\(:]/gm)) add(m[1], "class");
|
|
11399
11360
|
break;
|
|
11400
11361
|
}
|
|
11401
11362
|
case "js":
|
|
11402
11363
|
case "mjs":
|
|
11403
11364
|
case "jsx": {
|
|
11404
|
-
for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g))
|
|
11405
|
-
|
|
11406
|
-
for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*=/g))
|
|
11407
|
-
add(m[1]);
|
|
11365
|
+
for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
|
|
11366
|
+
for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*=/g)) add(m[1]);
|
|
11408
11367
|
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]);
|
|
11368
|
+
for (const m of sourceContent.matchAll(/^(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/gm)) add(m[1]);
|
|
11411
11369
|
}
|
|
11412
11370
|
break;
|
|
11413
11371
|
}
|
|
11414
11372
|
case "ts":
|
|
11415
11373
|
case "tsx": {
|
|
11416
|
-
for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g))
|
|
11417
|
-
|
|
11418
|
-
for (const m of sourceContent.matchAll(/export\s+
|
|
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");
|
|
11374
|
+
for (const m of sourceContent.matchAll(/export\s+(?:async\s+)?function\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
|
|
11375
|
+
for (const m of sourceContent.matchAll(/export\s+const\s+([a-zA-Z_$]\w*)\s*[:=]/g)) add(m[1]);
|
|
11376
|
+
for (const m of sourceContent.matchAll(/export\s+class\s+([a-zA-Z_$]\w*)/g)) add(m[1], "class");
|
|
11422
11377
|
break;
|
|
11423
11378
|
}
|
|
11424
11379
|
case "go": {
|
|
11425
|
-
for (const m of sourceContent.matchAll(/func\s+(?:\([^)]+\)\s+)?([A-Z]\w*)\s*\(/g))
|
|
11426
|
-
add(m[1]);
|
|
11380
|
+
for (const m of sourceContent.matchAll(/func\s+(?:\([^)]+\)\s+)?([A-Z]\w*)\s*\(/g)) add(m[1]);
|
|
11427
11381
|
break;
|
|
11428
11382
|
}
|
|
11429
11383
|
case "rs": {
|
|
11430
|
-
for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*</g))
|
|
11431
|
-
|
|
11432
|
-
for (const m of sourceContent.matchAll(/pub\s+
|
|
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");
|
|
11384
|
+
for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*</g)) add(m[1]);
|
|
11385
|
+
for (const m of sourceContent.matchAll(/pub\s+fn\s+([a-zA-Z_]\w*)\s*\(/g)) add(m[1]);
|
|
11386
|
+
for (const m of sourceContent.matchAll(/pub\s+struct\s+([a-zA-Z_]\w*)/g)) add(m[1], "struct");
|
|
11436
11387
|
break;
|
|
11437
11388
|
}
|
|
11438
11389
|
case "rb": {
|
|
11439
|
-
for (const m of sourceContent.matchAll(/def\s+(?:self\.)?([a-zA-Z_]\w*[?!=]?)/g))
|
|
11440
|
-
|
|
11441
|
-
for (const m of sourceContent.matchAll(/class\s+([A-Z]\w*)/g))
|
|
11442
|
-
add(m[1], "class");
|
|
11390
|
+
for (const m of sourceContent.matchAll(/def\s+(?:self\.)?([a-zA-Z_]\w*[?!=]?)/g)) add(m[1]);
|
|
11391
|
+
for (const m of sourceContent.matchAll(/class\s+([A-Z]\w*)/g)) add(m[1], "class");
|
|
11443
11392
|
break;
|
|
11444
11393
|
}
|
|
11445
11394
|
case "java":
|
|
11446
11395
|
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
|
-
|
|
11449
|
-
for (const m of sourceContent.matchAll(/fun\s+([a-zA-Z_$]\w*)\s*\(/g))
|
|
11450
|
-
add(m[1]);
|
|
11396
|
+
for (const m of sourceContent.matchAll(/(?:public|protected)\s+(?:static\s+)?(?:final\s+)?\S+\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
|
|
11397
|
+
for (const m of sourceContent.matchAll(/fun\s+([a-zA-Z_$]\w*)\s*\(/g)) add(m[1]);
|
|
11451
11398
|
break;
|
|
11452
11399
|
}
|
|
11453
11400
|
case "sh": {
|
|
11454
|
-
for (const m of sourceContent.matchAll(/^(?:function\s+)?([a-zA-Z_]\w*)\s*\(\)\s*\{/gm))
|
|
11455
|
-
|
|
11456
|
-
for (const m of sourceContent.matchAll(/^function\s+([a-zA-Z_]\w*)/gm))
|
|
11457
|
-
add(m[1]);
|
|
11401
|
+
for (const m of sourceContent.matchAll(/^(?:function\s+)?([a-zA-Z_]\w*)\s*\(\)\s*\{/gm)) add(m[1]);
|
|
11402
|
+
for (const m of sourceContent.matchAll(/^function\s+([a-zA-Z_]\w*)/gm)) add(m[1]);
|
|
11458
11403
|
break;
|
|
11459
11404
|
}
|
|
11460
11405
|
}
|
|
@@ -11476,8 +11421,7 @@ function generateTestCaseNames(funcName, _type, quality = false) {
|
|
|
11476
11421
|
];
|
|
11477
11422
|
}
|
|
11478
11423
|
function inferFunctionParams(sourceContent, funcName) {
|
|
11479
|
-
if (!sourceContent || !funcName)
|
|
11480
|
-
return [];
|
|
11424
|
+
if (!sourceContent || !funcName) return [];
|
|
11481
11425
|
const patterns = [
|
|
11482
11426
|
new RegExp(`(?:export\\s+)?(?:async\\s+)?function\\s+${funcName}\\s*\\(([^)]*)\\)`, "m"),
|
|
11483
11427
|
new RegExp(`(?:export\\s+)?const\\s+${funcName}\\s*[:=]\\s*(?:async\\s+)?\\(([^)]*)\\)`, "m"),
|
|
@@ -11490,8 +11434,7 @@ function inferFunctionParams(sourceContent, funcName) {
|
|
|
11490
11434
|
if (m) {
|
|
11491
11435
|
return m[1].split(",").map((s) => {
|
|
11492
11436
|
const trimmed = s.trim();
|
|
11493
|
-
if (!trimmed)
|
|
11494
|
-
return null;
|
|
11437
|
+
if (!trimmed) return null;
|
|
11495
11438
|
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
11439
|
const rawName = trimmed.replace(/^[^a-zA-Z_$]*/, "").replace(/[=:].*$/, "").replace(/\s+.*$/, "").trim();
|
|
11497
11440
|
const defaultMatch = trimmed.match(/=\s*(.+)$/);
|
|
@@ -11507,35 +11450,22 @@ function inferFunctionParams(sourceContent, funcName) {
|
|
|
11507
11450
|
return [];
|
|
11508
11451
|
}
|
|
11509
11452
|
function inferTypeFromName(paramName, defaultValue) {
|
|
11510
|
-
if (!paramName)
|
|
11511
|
-
return "any";
|
|
11453
|
+
if (!paramName) return "any";
|
|
11512
11454
|
const name = paramName.toLowerCase();
|
|
11513
11455
|
if (defaultValue !== null && defaultValue !== void 0) {
|
|
11514
|
-
if (/^["']/.test(defaultValue))
|
|
11515
|
-
|
|
11516
|
-
if (
|
|
11517
|
-
|
|
11518
|
-
if (
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
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";
|
|
11456
|
+
if (/^["']/.test(defaultValue)) return "string";
|
|
11457
|
+
if (/^\d+\.?\d*$/.test(defaultValue)) return "number";
|
|
11458
|
+
if (/^(true|false)$/i.test(defaultValue)) return "boolean";
|
|
11459
|
+
if (/^\[/.test(defaultValue)) return "array";
|
|
11460
|
+
if (/^\{/.test(defaultValue)) return "object";
|
|
11461
|
+
if (/^null$/i.test(defaultValue)) return "null";
|
|
11462
|
+
}
|
|
11463
|
+
if (/^(is|has|can|should|will|did|was|are|contains?_|[A-Z])/.test(name)) return "boolean";
|
|
11464
|
+
if (/^(count|index|limit|offset|max|min|size|length|total|num|age)_?/.test(name)) return "number";
|
|
11465
|
+
if (/^(name|title|label|msg|message|text|str|prefix|suffix|path|url|email|id)_?/.test(name)) return "string";
|
|
11466
|
+
if (/^(items|list|arr|entries|data|values|args)_?/.test(name)) return "array";
|
|
11467
|
+
if (/^(obj|config|opts|options|settings|params|props)_?/.test(name)) return "object";
|
|
11468
|
+
if (/^(fn|cb|callback|handler|on[A-Z])/.test(name)) return "function";
|
|
11539
11469
|
return "any";
|
|
11540
11470
|
}
|
|
11541
11471
|
function _langComment(lang) {
|
|
@@ -11548,22 +11478,14 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
|
|
|
11548
11478
|
let block = "";
|
|
11549
11479
|
const testValues = params.map((p) => {
|
|
11550
11480
|
const t = p.type || inferTypeFromName(p.name, p.defaultValue);
|
|
11551
|
-
if (t === "string" || t === "String")
|
|
11552
|
-
|
|
11553
|
-
if (t === "
|
|
11554
|
-
|
|
11555
|
-
if (t === "
|
|
11556
|
-
|
|
11557
|
-
if (t === "
|
|
11558
|
-
|
|
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";
|
|
11481
|
+
if (t === "string" || t === "String") return '"sample_input"';
|
|
11482
|
+
if (t === "number" || t === "int" || t === "float" || t === "Number") return "42";
|
|
11483
|
+
if (t === "boolean" || t === "bool" || t === "Boolean") return "true";
|
|
11484
|
+
if (t === "array" || t === "Array" || t === "list" || t === "List") return "[]";
|
|
11485
|
+
if (t === "object" || t === "Object" || t === "dict" || t === "Dict") return "{}";
|
|
11486
|
+
if (t === "function" || t === "Function") return "() => {}";
|
|
11487
|
+
if (t === "any") return '"test"';
|
|
11488
|
+
if (t === "null") return "null";
|
|
11567
11489
|
return '"test"';
|
|
11568
11490
|
});
|
|
11569
11491
|
const args = testValues.join(", ");
|
|
@@ -11593,10 +11515,8 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
|
|
|
11593
11515
|
`;
|
|
11594
11516
|
const ecArgs = params.map((p) => {
|
|
11595
11517
|
const t = p.type || inferTypeFromName(p.name, p.defaultValue);
|
|
11596
|
-
if (t === "string")
|
|
11597
|
-
|
|
11598
|
-
if (t === "number" || t === "int" || t === "float")
|
|
11599
|
-
return "0";
|
|
11518
|
+
if (t === "string") return '""';
|
|
11519
|
+
if (t === "number" || t === "int" || t === "float") return "0";
|
|
11600
11520
|
return '"edge"';
|
|
11601
11521
|
}).join(", ");
|
|
11602
11522
|
block += `${indent} result = ${funcName}(${ecArgs})
|
|
@@ -11634,16 +11554,11 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
|
|
|
11634
11554
|
`;
|
|
11635
11555
|
const ecArgsJS = params.map((p) => {
|
|
11636
11556
|
const t = p.type || inferTypeFromName(p.name, p.defaultValue);
|
|
11637
|
-
if (t === "string")
|
|
11638
|
-
|
|
11639
|
-
if (t === "
|
|
11640
|
-
|
|
11641
|
-
if (t === "
|
|
11642
|
-
return "false";
|
|
11643
|
-
if (t === "array")
|
|
11644
|
-
return "[]";
|
|
11645
|
-
if (t === "object")
|
|
11646
|
-
return "{}";
|
|
11557
|
+
if (t === "string") return '""';
|
|
11558
|
+
if (t === "number" || t === "int" || t === "float") return "0";
|
|
11559
|
+
if (t === "boolean") return "false";
|
|
11560
|
+
if (t === "array") return "[]";
|
|
11561
|
+
if (t === "object") return "{}";
|
|
11647
11562
|
return "undefined";
|
|
11648
11563
|
}).join(", ");
|
|
11649
11564
|
block += `${indent} const result = mod.${funcName}(${ecArgsJS});
|
|
@@ -11676,15 +11591,14 @@ function buildQualityAssertionsForFunc(funcName, params, lang, indent) {
|
|
|
11676
11591
|
return block;
|
|
11677
11592
|
}
|
|
11678
11593
|
function isSkeletonUseless(content) {
|
|
11679
|
-
if (!content)
|
|
11680
|
-
return true;
|
|
11594
|
+
if (!content) return true;
|
|
11681
11595
|
const lines = content.split("\n").filter((l) => l.trim() && !l.trim().startsWith("//") && !l.trim().startsWith("#") && !l.trim().startsWith("/*") && !l.trim().startsWith("*"));
|
|
11682
11596
|
const todoLines = content.split("\n").filter((l) => /TODO|placeholder|smoke|is exported|module loads/.test(l));
|
|
11683
11597
|
const meaningfulLines = lines.filter((l) => !/TODO|placeholder|smoke|is exported|module loads|throw new Error|raise AssertionError|pytest\.skip|assert.*true/.test(l));
|
|
11684
11598
|
return meaningfulLines.length < 2;
|
|
11685
11599
|
}
|
|
11686
11600
|
|
|
11687
|
-
// src/lib/test-skeletons.
|
|
11601
|
+
// src/lib/test-skeletons.ts
|
|
11688
11602
|
var TEST_SKELETONS = {
|
|
11689
11603
|
py: (name, exports = [], depth = "full", strict = true, quality = true, sourceContent = "") => {
|
|
11690
11604
|
const moduleImport = name.replace(/-/g, "_");
|
|
@@ -11712,8 +11626,7 @@ var TEST_SKELETONS = {
|
|
|
11712
11626
|
|
|
11713
11627
|
`;
|
|
11714
11628
|
for (const exp of exports) {
|
|
11715
|
-
if (exp.type === "class")
|
|
11716
|
-
continue;
|
|
11629
|
+
if (exp.type === "class") continue;
|
|
11717
11630
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
11718
11631
|
content += `# TODO: implement tests for ${exp.name}
|
|
11719
11632
|
`;
|
|
@@ -11721,12 +11634,10 @@ var TEST_SKELETONS = {
|
|
|
11721
11634
|
const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
11722
11635
|
content += `def test_${caseFunc}():
|
|
11723
11636
|
`;
|
|
11724
|
-
if (strict)
|
|
11725
|
-
content += ` raise AssertionError("TODO: implement ${caseName}")
|
|
11637
|
+
if (strict) content += ` raise AssertionError("TODO: implement ${caseName}")
|
|
11726
11638
|
|
|
11727
11639
|
`;
|
|
11728
|
-
else
|
|
11729
|
-
content += ` pytest.skip("TODO: implement ${caseName}")
|
|
11640
|
+
else content += ` pytest.skip("TODO: implement ${caseName}")
|
|
11730
11641
|
|
|
11731
11642
|
`;
|
|
11732
11643
|
}
|
|
@@ -11738,12 +11649,10 @@ var TEST_SKELETONS = {
|
|
|
11738
11649
|
if (exports.length === 0) {
|
|
11739
11650
|
content += `def test_${name}_placeholder():
|
|
11740
11651
|
`;
|
|
11741
|
-
if (strict)
|
|
11742
|
-
content += ` raise AssertionError("TODO: implement tests for ${name}")
|
|
11652
|
+
if (strict) content += ` raise AssertionError("TODO: implement tests for ${name}")
|
|
11743
11653
|
|
|
11744
11654
|
`;
|
|
11745
|
-
else
|
|
11746
|
-
content += ` pytest.skip("TODO: implement tests for ${name}")
|
|
11655
|
+
else content += ` pytest.skip("TODO: implement tests for ${name}")
|
|
11747
11656
|
|
|
11748
11657
|
`;
|
|
11749
11658
|
}
|
|
@@ -11777,8 +11686,7 @@ var TEST_SKELETONS = {
|
|
|
11777
11686
|
|
|
11778
11687
|
`;
|
|
11779
11688
|
for (const exp of exports) {
|
|
11780
|
-
if (exp.type === "class")
|
|
11781
|
-
continue;
|
|
11689
|
+
if (exp.type === "class") continue;
|
|
11782
11690
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
11783
11691
|
content += ` // TODO: implement tests for ${exp.name}
|
|
11784
11692
|
`;
|
|
@@ -11794,11 +11702,9 @@ var TEST_SKELETONS = {
|
|
|
11794
11702
|
`;
|
|
11795
11703
|
content += ` // TODO: implement ${caseName}
|
|
11796
11704
|
`;
|
|
11797
|
-
if (strict)
|
|
11798
|
-
content += ` throw new Error('TODO: implement ${caseName}');
|
|
11705
|
+
if (strict) content += ` throw new Error('TODO: implement ${caseName}');
|
|
11799
11706
|
`;
|
|
11800
|
-
else
|
|
11801
|
-
content += ` expect(true).toBe(true);
|
|
11707
|
+
else content += ` expect(true).toBe(true);
|
|
11802
11708
|
`;
|
|
11803
11709
|
content += ` });
|
|
11804
11710
|
|
|
@@ -11851,8 +11757,7 @@ var TEST_SKELETONS = {
|
|
|
11851
11757
|
|
|
11852
11758
|
`;
|
|
11853
11759
|
for (const exp of exports) {
|
|
11854
|
-
if (exp.type === "class")
|
|
11855
|
-
continue;
|
|
11760
|
+
if (exp.type === "class") continue;
|
|
11856
11761
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
11857
11762
|
content += ` // TODO: implement tests for ${exp.name}
|
|
11858
11763
|
`;
|
|
@@ -11868,11 +11773,9 @@ var TEST_SKELETONS = {
|
|
|
11868
11773
|
`;
|
|
11869
11774
|
content += ` // TODO: implement ${caseName}
|
|
11870
11775
|
`;
|
|
11871
|
-
if (strict)
|
|
11872
|
-
content += ` throw new Error('TODO: implement ${caseName}');
|
|
11776
|
+
if (strict) content += ` throw new Error('TODO: implement ${caseName}');
|
|
11873
11777
|
`;
|
|
11874
|
-
else
|
|
11875
|
-
content += ` expect(true).toBe(true);
|
|
11778
|
+
else content += ` expect(true).toBe(true);
|
|
11876
11779
|
`;
|
|
11877
11780
|
content += ` });
|
|
11878
11781
|
|
|
@@ -11925,8 +11828,7 @@ var TEST_SKELETONS = {
|
|
|
11925
11828
|
|
|
11926
11829
|
`;
|
|
11927
11830
|
for (const exp of exports) {
|
|
11928
|
-
if (exp.type === "class")
|
|
11929
|
-
continue;
|
|
11831
|
+
if (exp.type === "class") continue;
|
|
11930
11832
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
11931
11833
|
content += ` // TODO: implement tests for ${exp.name}
|
|
11932
11834
|
`;
|
|
@@ -11942,11 +11844,9 @@ var TEST_SKELETONS = {
|
|
|
11942
11844
|
`;
|
|
11943
11845
|
content += ` // TODO: implement ${caseName}
|
|
11944
11846
|
`;
|
|
11945
|
-
if (strict)
|
|
11946
|
-
content += ` throw new Error('TODO: implement ${caseName}');
|
|
11847
|
+
if (strict) content += ` throw new Error('TODO: implement ${caseName}');
|
|
11947
11848
|
`;
|
|
11948
|
-
else
|
|
11949
|
-
content += ` expect(true).toBe(true);
|
|
11849
|
+
else content += ` expect(true).toBe(true);
|
|
11950
11850
|
`;
|
|
11951
11851
|
content += ` });
|
|
11952
11852
|
|
|
@@ -12006,8 +11906,7 @@ var TEST_SKELETONS = {
|
|
|
12006
11906
|
|
|
12007
11907
|
`;
|
|
12008
11908
|
for (const exp of exports) {
|
|
12009
|
-
if (exp.type === "class")
|
|
12010
|
-
continue;
|
|
11909
|
+
if (exp.type === "class") continue;
|
|
12011
11910
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
12012
11911
|
const expCap = exp.name.charAt(0).toUpperCase() + exp.name.slice(1);
|
|
12013
11912
|
content += `// TODO: implement tests for ${exp.name}
|
|
@@ -12016,11 +11915,9 @@ var TEST_SKELETONS = {
|
|
|
12016
11915
|
const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
12017
11916
|
content += `func Test${cap}_${caseFunc}(t *testing.T) {
|
|
12018
11917
|
`;
|
|
12019
|
-
if (strict)
|
|
12020
|
-
content += ` t.Error("TODO: implement ${caseName}")
|
|
11918
|
+
if (strict) content += ` t.Error("TODO: implement ${caseName}")
|
|
12021
11919
|
`;
|
|
12022
|
-
else
|
|
12023
|
-
content += ` t.Skip("TODO: implement ${caseName}")
|
|
11920
|
+
else content += ` t.Skip("TODO: implement ${caseName}")
|
|
12024
11921
|
`;
|
|
12025
11922
|
content += `}
|
|
12026
11923
|
|
|
@@ -12040,11 +11937,9 @@ var TEST_SKELETONS = {
|
|
|
12040
11937
|
if (exports.length === 0) {
|
|
12041
11938
|
content += `func Test${cap}_Placeholder(t *testing.T) {
|
|
12042
11939
|
`;
|
|
12043
|
-
if (strict)
|
|
12044
|
-
content += ` t.Error("TODO: implement tests for ${name}")
|
|
11940
|
+
if (strict) content += ` t.Error("TODO: implement tests for ${name}")
|
|
12045
11941
|
`;
|
|
12046
|
-
else
|
|
12047
|
-
content += ` t.Skip("TODO: implement tests for ${name}")
|
|
11942
|
+
else content += ` t.Skip("TODO: implement tests for ${name}")
|
|
12048
11943
|
`;
|
|
12049
11944
|
content += `}
|
|
12050
11945
|
`;
|
|
@@ -12077,11 +11972,9 @@ var TEST_SKELETONS = {
|
|
|
12077
11972
|
`;
|
|
12078
11973
|
content += ` echo "TODO: implement ${caseName}"
|
|
12079
11974
|
`;
|
|
12080
|
-
if (strict)
|
|
12081
|
-
content += ` exit 1
|
|
11975
|
+
if (strict) content += ` exit 1
|
|
12082
11976
|
`;
|
|
12083
|
-
else
|
|
12084
|
-
content += ` echo "SKIP: ${caseName}"
|
|
11977
|
+
else content += ` echo "SKIP: ${caseName}"
|
|
12085
11978
|
`;
|
|
12086
11979
|
content += `}
|
|
12087
11980
|
|
|
@@ -12095,11 +11988,9 @@ var TEST_SKELETONS = {
|
|
|
12095
11988
|
if (exports.length === 0) {
|
|
12096
11989
|
content += `function test_smoke {
|
|
12097
11990
|
`;
|
|
12098
|
-
if (strict)
|
|
12099
|
-
content += ` echo "TODO: implement tests for ${name}" && exit 1
|
|
11991
|
+
if (strict) content += ` echo "TODO: implement tests for ${name}" && exit 1
|
|
12100
11992
|
`;
|
|
12101
|
-
else
|
|
12102
|
-
content += ` echo "TODO: implement tests for ${name}"
|
|
11993
|
+
else content += ` echo "TODO: implement tests for ${name}"
|
|
12103
11994
|
`;
|
|
12104
11995
|
content += `}
|
|
12105
11996
|
`;
|
|
@@ -12139,8 +12030,7 @@ mod tests {
|
|
|
12139
12030
|
|
|
12140
12031
|
`;
|
|
12141
12032
|
for (const exp of exports) {
|
|
12142
|
-
if (exp.type === "class")
|
|
12143
|
-
continue;
|
|
12033
|
+
if (exp.type === "class") continue;
|
|
12144
12034
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
12145
12035
|
content += ` // TODO: implement tests for ${exp.name}
|
|
12146
12036
|
`;
|
|
@@ -12149,11 +12039,9 @@ mod tests {
|
|
|
12149
12039
|
content += ` #[test]
|
|
12150
12040
|
fn test_${caseFunc}() {
|
|
12151
12041
|
`;
|
|
12152
|
-
if (strict)
|
|
12153
|
-
content += ` panic!("TODO: implement ${caseName}");
|
|
12042
|
+
if (strict) content += ` panic!("TODO: implement ${caseName}");
|
|
12154
12043
|
`;
|
|
12155
|
-
else
|
|
12156
|
-
content += ` // TODO: implement ${caseName}
|
|
12044
|
+
else content += ` // TODO: implement ${caseName}
|
|
12157
12045
|
`;
|
|
12158
12046
|
content += ` }
|
|
12159
12047
|
|
|
@@ -12168,11 +12056,9 @@ mod tests {
|
|
|
12168
12056
|
content += ` #[test]
|
|
12169
12057
|
fn ${name}_placeholder() {
|
|
12170
12058
|
`;
|
|
12171
|
-
if (strict)
|
|
12172
|
-
content += ` panic!("TODO: implement tests for ${name}");
|
|
12059
|
+
if (strict) content += ` panic!("TODO: implement tests for ${name}");
|
|
12173
12060
|
`;
|
|
12174
|
-
else
|
|
12175
|
-
content += ` // TODO: implement tests for ${name}
|
|
12061
|
+
else content += ` // TODO: implement tests for ${name}
|
|
12176
12062
|
`;
|
|
12177
12063
|
content += ` }
|
|
12178
12064
|
`;
|
|
@@ -12212,8 +12098,7 @@ mod tests {
|
|
|
12212
12098
|
|
|
12213
12099
|
`;
|
|
12214
12100
|
for (const exp of exports) {
|
|
12215
|
-
if (exp.type === "class")
|
|
12216
|
-
continue;
|
|
12101
|
+
if (exp.type === "class") continue;
|
|
12217
12102
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
12218
12103
|
content += ` # TODO: implement tests for ${exp.name}
|
|
12219
12104
|
`;
|
|
@@ -12221,11 +12106,9 @@ mod tests {
|
|
|
12221
12106
|
const caseFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
12222
12107
|
content += ` def test_${caseFunc}
|
|
12223
12108
|
`;
|
|
12224
|
-
if (strict)
|
|
12225
|
-
content += ` flunk "TODO: implement ${caseName}"
|
|
12109
|
+
if (strict) content += ` flunk "TODO: implement ${caseName}"
|
|
12226
12110
|
`;
|
|
12227
|
-
else
|
|
12228
|
-
content += ` # TODO: implement ${caseName}
|
|
12111
|
+
else content += ` # TODO: implement ${caseName}
|
|
12229
12112
|
`;
|
|
12230
12113
|
content += ` end
|
|
12231
12114
|
|
|
@@ -12239,11 +12122,9 @@ mod tests {
|
|
|
12239
12122
|
if (exports.length === 0) {
|
|
12240
12123
|
content += ` def test_placeholder
|
|
12241
12124
|
`;
|
|
12242
|
-
if (strict)
|
|
12243
|
-
content += ` flunk "TODO: implement tests for ${name}"
|
|
12125
|
+
if (strict) content += ` flunk "TODO: implement tests for ${name}"
|
|
12244
12126
|
`;
|
|
12245
|
-
else
|
|
12246
|
-
content += ` # TODO: implement tests for ${name}
|
|
12127
|
+
else content += ` # TODO: implement tests for ${name}
|
|
12247
12128
|
`;
|
|
12248
12129
|
content += ` end
|
|
12249
12130
|
`;
|
|
@@ -12289,18 +12170,15 @@ mod tests {
|
|
|
12289
12170
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
12290
12171
|
for (const caseName of cases) {
|
|
12291
12172
|
const testFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
12292
|
-
if (!strict)
|
|
12293
|
-
content += ` // @Disabled("TODO")
|
|
12173
|
+
if (!strict) content += ` // @Disabled("TODO")
|
|
12294
12174
|
`;
|
|
12295
12175
|
content += ` @Test
|
|
12296
12176
|
`;
|
|
12297
12177
|
content += ` void test${testFunc.charAt(0).toUpperCase() + testFunc.slice(1)}() {
|
|
12298
12178
|
`;
|
|
12299
|
-
if (strict)
|
|
12300
|
-
content += ` fail("TODO: implement ${caseName}");
|
|
12179
|
+
if (strict) content += ` fail("TODO: implement ${caseName}");
|
|
12301
12180
|
`;
|
|
12302
|
-
else
|
|
12303
|
-
content += ` assertTrue(true); // TODO: implement ${caseName}
|
|
12181
|
+
else content += ` assertTrue(true); // TODO: implement ${caseName}
|
|
12304
12182
|
`;
|
|
12305
12183
|
content += ` }
|
|
12306
12184
|
|
|
@@ -12362,18 +12240,15 @@ mod tests {
|
|
|
12362
12240
|
const cases = generateTestCaseNames(exp.name, exp.type, quality);
|
|
12363
12241
|
for (const caseName of cases) {
|
|
12364
12242
|
const testFunc = caseName.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
|
|
12365
|
-
if (!strict)
|
|
12366
|
-
content += ` // @Disabled("TODO")
|
|
12243
|
+
if (!strict) content += ` // @Disabled("TODO")
|
|
12367
12244
|
`;
|
|
12368
12245
|
content += ` @Test
|
|
12369
12246
|
`;
|
|
12370
12247
|
content += ` fun test${testFunc.charAt(0).toUpperCase() + testFunc.slice(1)}() {
|
|
12371
12248
|
`;
|
|
12372
|
-
if (strict)
|
|
12373
|
-
content += ` fail("TODO: implement ${caseName}")
|
|
12249
|
+
if (strict) content += ` fail("TODO: implement ${caseName}")
|
|
12374
12250
|
`;
|
|
12375
|
-
else
|
|
12376
|
-
content += ` assertTrue(true) // TODO: implement ${caseName}
|
|
12251
|
+
else content += ` assertTrue(true) // TODO: implement ${caseName}
|
|
12377
12252
|
`;
|
|
12378
12253
|
content += ` }
|
|
12379
12254
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.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",
|