vibeostheog 0.25.22 → 0.25.25
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.25.25
|
|
2
|
+
- fix: make deploy install tests platform-aware (skip macOS path on Linux)
|
|
3
|
+
- fix: resolveOpenCodeHomes() merges workspace + desktop homes
|
|
4
|
+
- fix: resolveOpenCodeHomes() now merges workspace + desktop homes
|
|
5
|
+
- fix: use getVibeOSHome() for hookVibeHome instead of hardcoded join(home, .claude) (#202)
|
|
6
|
+
Merge branch 'origin/master' — incorporate upstream changes
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## 0.25.22
|
|
2
10
|
- fix: include installer helper in package
|
|
3
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:
|
|
1
|
+
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:37161";
|
package/dist/vibeOS.js
CHANGED
|
@@ -6851,6 +6851,7 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
6851
6851
|
this.pivotHistory = [];
|
|
6852
6852
|
this.outcomeHistory = [];
|
|
6853
6853
|
this.calibratedWeights = null;
|
|
6854
|
+
this.recentMessageLengths = [];
|
|
6854
6855
|
}
|
|
6855
6856
|
static extractFeatures(text) {
|
|
6856
6857
|
if (!text || typeof text !== "string")
|
|
@@ -6925,13 +6926,18 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
6925
6926
|
getRepeatStreak() {
|
|
6926
6927
|
if (this.history.length < 2)
|
|
6927
6928
|
return 0;
|
|
6928
|
-
const
|
|
6929
|
-
if (
|
|
6929
|
+
const lastWords = new Set(this.history[this.history.length - 1].text.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
6930
|
+
if (lastWords.size === 0)
|
|
6930
6931
|
return 0;
|
|
6931
6932
|
let streak = 1;
|
|
6932
6933
|
for (let i = this.history.length - 2; i >= 0; i--) {
|
|
6933
|
-
const
|
|
6934
|
-
if (
|
|
6934
|
+
const currWords = new Set(this.history[i].text.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
6935
|
+
if (currWords.size === 0)
|
|
6936
|
+
break;
|
|
6937
|
+
const intersection = new Set([...lastWords].filter((w) => currWords.has(w)));
|
|
6938
|
+
const union = /* @__PURE__ */ new Set([...lastWords, ...currWords]);
|
|
6939
|
+
const jaccard = intersection.size / Math.max(union.size, 1);
|
|
6940
|
+
if (jaccard < 0.7)
|
|
6935
6941
|
break;
|
|
6936
6942
|
streak++;
|
|
6937
6943
|
}
|
|
@@ -6967,6 +6973,39 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
6967
6973
|
}
|
|
6968
6974
|
return streak;
|
|
6969
6975
|
}
|
|
6976
|
+
getRecentNegativeOutcomeStreak() {
|
|
6977
|
+
if (this.outcomeHistory.length < 1)
|
|
6978
|
+
return 0;
|
|
6979
|
+
let streak = 0;
|
|
6980
|
+
for (let i = this.outcomeHistory.length - 1; i >= 0; i--) {
|
|
6981
|
+
const o = this.outcomeHistory[i];
|
|
6982
|
+
if (/negative|failed|unresolved|loop_detected/i.test(String(o?.outcome || "")))
|
|
6983
|
+
streak++;
|
|
6984
|
+
else
|
|
6985
|
+
break;
|
|
6986
|
+
}
|
|
6987
|
+
return streak;
|
|
6988
|
+
}
|
|
6989
|
+
computeMessageLengthTrend() {
|
|
6990
|
+
const lengths = this.recentMessageLengths;
|
|
6991
|
+
if (lengths.length < 3)
|
|
6992
|
+
return { trend: "stable", slope: 0 };
|
|
6993
|
+
const pairs = lengths.slice(-4);
|
|
6994
|
+
let decreasingCount = 0;
|
|
6995
|
+
let totalSlope = 0;
|
|
6996
|
+
for (let i = 1; i < pairs.length; i++) {
|
|
6997
|
+
const diff = pairs[i] - pairs[i - 1];
|
|
6998
|
+
if (diff < 0)
|
|
6999
|
+
decreasingCount++;
|
|
7000
|
+
totalSlope += diff;
|
|
7001
|
+
}
|
|
7002
|
+
const ratio = decreasingCount / (pairs.length - 1);
|
|
7003
|
+
const avgSlope = pairs.length > 1 ? totalSlope / (pairs.length - 1) : 0;
|
|
7004
|
+
return {
|
|
7005
|
+
trend: ratio >= 0.6 && avgSlope < 0 ? "shortening" : "stable",
|
|
7006
|
+
slope: avgSlope
|
|
7007
|
+
};
|
|
7008
|
+
}
|
|
6970
7009
|
update(userText, features, action, entropy, uncertainty, embedding = null, activity = null) {
|
|
6971
7010
|
const normalizedActivity = this.normalizeActivity(activity, action, userText);
|
|
6972
7011
|
const entry = {
|
|
@@ -6986,6 +7025,9 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
6986
7025
|
}
|
|
6987
7026
|
}
|
|
6988
7027
|
this.history.push(entry);
|
|
7028
|
+
this.recentMessageLengths.push((userText || "").length);
|
|
7029
|
+
if (this.recentMessageLengths.length > 6)
|
|
7030
|
+
this.recentMessageLengths.shift();
|
|
6989
7031
|
if (this.history.length > this.maxHistory) {
|
|
6990
7032
|
this.history.shift();
|
|
6991
7033
|
}
|
|
@@ -7121,6 +7163,9 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7121
7163
|
pivot_detected: pivotDetected,
|
|
7122
7164
|
pivot_score: Math.round(pivotScore * 1e4) / 1e4,
|
|
7123
7165
|
outcome: lastEntry.outcome || null,
|
|
7166
|
+
outcome_negative_streak: this.getRecentNegativeOutcomeStreak(),
|
|
7167
|
+
message_length_trend: this.computeMessageLengthTrend().trend,
|
|
7168
|
+
message_length_slope: this.computeMessageLengthTrend().slope,
|
|
7124
7169
|
n_interactions: n
|
|
7125
7170
|
};
|
|
7126
7171
|
}
|
|
@@ -7171,7 +7216,8 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7171
7216
|
}
|
|
7172
7217
|
detectLoop() {
|
|
7173
7218
|
const repeatSignal = Math.max(this.getRepeatStreak(), this.getActivityRepeatStreak(), this.getTargetRepeatStreak());
|
|
7174
|
-
|
|
7219
|
+
const negativeOutcomeStreak = this.getRecentNegativeOutcomeStreak();
|
|
7220
|
+
return this.loopCount >= 2 || repeatSignal >= 2 || negativeOutcomeStreak >= 2;
|
|
7175
7221
|
}
|
|
7176
7222
|
computeIntentState() {
|
|
7177
7223
|
const last = this.history[this.history.length - 1];
|
|
@@ -7215,6 +7261,7 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7215
7261
|
this.loopCount = 0;
|
|
7216
7262
|
this.pivotHistory = [];
|
|
7217
7263
|
this.outcomeHistory = [];
|
|
7264
|
+
this.recentMessageLengths = [];
|
|
7218
7265
|
}
|
|
7219
7266
|
recordOutcome(outcome) {
|
|
7220
7267
|
const entry = this.history[this.history.length - 1];
|
|
@@ -7280,6 +7327,7 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7280
7327
|
loopCount: this.loopCount,
|
|
7281
7328
|
pivotHistory: this.pivotHistory,
|
|
7282
7329
|
outcomeHistory: this.outcomeHistory,
|
|
7330
|
+
recentMessageLengths: this.recentMessageLengths,
|
|
7283
7331
|
calibratedWeights: this.calibratedWeights
|
|
7284
7332
|
};
|
|
7285
7333
|
}
|
|
@@ -7292,6 +7340,7 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7292
7340
|
tracker.loopCount = Number(data.loopCount || 0);
|
|
7293
7341
|
tracker.pivotHistory = Array.isArray(data.pivotHistory) ? data.pivotHistory : [];
|
|
7294
7342
|
tracker.outcomeHistory = Array.isArray(data.outcomeHistory) ? data.outcomeHistory : [];
|
|
7343
|
+
tracker.recentMessageLengths = Array.isArray(data.recentMessageLengths) ? data.recentMessageLengths : [];
|
|
7295
7344
|
tracker.calibratedWeights = data.calibratedWeights || null;
|
|
7296
7345
|
return tracker;
|
|
7297
7346
|
}
|
|
@@ -7425,9 +7474,9 @@ init_state();
|
|
|
7425
7474
|
function detectOutcomeSignal(text) {
|
|
7426
7475
|
if (!text)
|
|
7427
7476
|
return null;
|
|
7428
|
-
if (/thank|perfect|exactly|that.?s it|works great|works perfectly|solved|fixed|awesome|you rock/i.test(text))
|
|
7477
|
+
if (/thank|perfect|exactly|that.?s it|works great|works perfectly|solved|fixed|awesome|you rock|that works|finally|progress|much better|getting there|closer now/i.test(text))
|
|
7429
7478
|
return "positive";
|
|
7430
|
-
if (/doesn.?t work|still broken|not working|incorrect|wrong|failed|error|useless|stuck/i.test(text))
|
|
7479
|
+
if (/doesn.?t work|still broken|not working|incorrect|wrong|failed|error|useless|stuck|still failing|broke again|worse|regression|new (problem|bug|issue|error)|made it worse|every (fix|change|attempt) (broke|breaks|introduces)|went backwards|back to square|start over|same (issue|problem|error) (again|still)|(another|yet another|different) (error|problem|issue)|(still|again|still not) (the|at|same)|\d+\s*(times|attempts|tries) (and|but) (still|same|same result)/i.test(text))
|
|
7431
7480
|
return "negative";
|
|
7432
7481
|
return null;
|
|
7433
7482
|
}
|
|
@@ -7464,6 +7513,8 @@ function getBehavioralStressSignals(context, blackboxState) {
|
|
|
7464
7513
|
const repeatStreak = Number(blackboxState?.repeat_streak ?? 0);
|
|
7465
7514
|
const activityRepeatStreak = Number(blackboxState?.activity_repeat_streak ?? 0);
|
|
7466
7515
|
const targetRepeatStateStreak = Number(blackboxState?.target_repeat_streak ?? 0);
|
|
7516
|
+
const messageLengthTrend = String(blackboxState?.message_length_trend || "stable");
|
|
7517
|
+
const messageLengthSlope = Number(blackboxState?.message_length_slope ?? 0);
|
|
7467
7518
|
return {
|
|
7468
7519
|
toolRepeatStreak,
|
|
7469
7520
|
targetRepeatStreak,
|
|
@@ -7471,10 +7522,13 @@ function getBehavioralStressSignals(context, blackboxState) {
|
|
|
7471
7522
|
loopCount,
|
|
7472
7523
|
repeatStreak,
|
|
7473
7524
|
activityRepeatStreak,
|
|
7474
|
-
targetRepeatStateStreak
|
|
7525
|
+
targetRepeatStateStreak,
|
|
7526
|
+
messageLengthTrend,
|
|
7527
|
+
messageLengthSlope
|
|
7475
7528
|
};
|
|
7476
7529
|
}
|
|
7477
7530
|
function scoreStress(text, context = {}) {
|
|
7531
|
+
const blackboxState = loadBlackboxState();
|
|
7478
7532
|
if (!text || typeof text !== "string")
|
|
7479
7533
|
return 0;
|
|
7480
7534
|
const t = text.toLowerCase();
|
|
@@ -7516,22 +7570,25 @@ function scoreStress(text, context = {}) {
|
|
|
7516
7570
|
const behavioralPhrases = [
|
|
7517
7571
|
{ re: /\b(restart|restarts|restarted|restart again|restart it|retry|retries|retrial|rerun|redo|repeat the step|try again|another attempt|another pass)\b/gi, weight: 0.09 },
|
|
7518
7572
|
{ re: /\b(still failing|keeps failing|keeps breaking|still broken|same issue|same result|same error|new error|new issue|broke again|breaks again|every fix|every time|over and over|again and again)\b/gi, weight: 0.12 },
|
|
7519
|
-
{ re: /\b(blocked again|stuck again|failed again|fails again|this is not working|nothing changed|no change)\b/gi, weight: 0.1 }
|
|
7573
|
+
{ re: /\b(blocked again|stuck again|failed again|fails again|this is not working|nothing changed|no change)\b/gi, weight: 0.1 },
|
|
7574
|
+
{ re: /\b(start over|from scratch|back to square|back to the drawing board|reset|rethink|different approach)\b/gi, weight: 0.12 },
|
|
7575
|
+
{ re: /\b(made it worse|went backwards|regression|introduced (a |a new |another )(problem|bug|issue)|worse than before|new (problem|bug|issue) (emerged|appeared|showed))\b/gi, weight: 0.15 },
|
|
7576
|
+
{ re: /\b(\d+)\s*(times|attempts|tries)\b/gi, dynamic: true }
|
|
7520
7577
|
];
|
|
7521
|
-
for (const { re, weight } of behavioralPhrases) {
|
|
7522
|
-
const
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7578
|
+
for (const { re, weight, dynamic } of behavioralPhrases) {
|
|
7579
|
+
const matches = t.match(re);
|
|
7580
|
+
if (!matches)
|
|
7581
|
+
continue;
|
|
7582
|
+
if (dynamic) {
|
|
7583
|
+
for (const m of matches) {
|
|
7584
|
+
const num = parseInt(m, 10) || 0;
|
|
7585
|
+
score += Math.min(0.2, num * 0.04);
|
|
7586
|
+
}
|
|
7587
|
+
} else {
|
|
7588
|
+
score += matches.length * weight;
|
|
7532
7589
|
}
|
|
7533
7590
|
}
|
|
7534
|
-
const { toolRepeatStreak, targetRepeatStreak, negativeOutcomes, loopCount, repeatStreak, activityRepeatStreak, targetRepeatStateStreak } = getBehavioralStressSignals(context, blackboxState);
|
|
7591
|
+
const { toolRepeatStreak, targetRepeatStreak, negativeOutcomes, loopCount, repeatStreak, activityRepeatStreak, targetRepeatStateStreak, messageLengthTrend, messageLengthSlope } = getBehavioralStressSignals(context, blackboxState);
|
|
7535
7592
|
if (toolRepeatStreak >= 2) {
|
|
7536
7593
|
score += 0.08 + Math.min(0.24, (toolRepeatStreak - 1) * 0.05);
|
|
7537
7594
|
}
|
|
@@ -7553,6 +7610,9 @@ function scoreStress(text, context = {}) {
|
|
|
7553
7610
|
if (targetRepeatStateStreak >= 2) {
|
|
7554
7611
|
score += 0.04 + Math.min(0.08, targetRepeatStateStreak * 0.015);
|
|
7555
7612
|
}
|
|
7613
|
+
if (messageLengthTrend === "shortening" && messageLengthSlope < -0.3) {
|
|
7614
|
+
score += 0.08;
|
|
7615
|
+
}
|
|
7556
7616
|
if (text.length < 30)
|
|
7557
7617
|
score += 0.06;
|
|
7558
7618
|
else if (text.length < 80)
|
|
@@ -7916,19 +7976,22 @@ function summarizeRecentToolActivity(limit = 5) {
|
|
|
7916
7976
|
if (events.length === 0)
|
|
7917
7977
|
return null;
|
|
7918
7978
|
const last = events[events.length - 1] || {};
|
|
7919
|
-
const
|
|
7979
|
+
const actionType = String(last.action || last.kind || "").trim().toLowerCase();
|
|
7980
|
+
const toolTarget = `${String(last.tool || "").trim().toLowerCase()}:${String(last.target || "").trim().toLowerCase()}`;
|
|
7981
|
+
const signature = `${toolTarget}:${actionType}`;
|
|
7920
7982
|
let repeatCount = 0;
|
|
7921
7983
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
7922
7984
|
const cur = events[i] || {};
|
|
7923
|
-
const
|
|
7924
|
-
|
|
7985
|
+
const curAction = String(cur.action || cur.kind || "").trim().toLowerCase();
|
|
7986
|
+
const curSig = `${String(cur.tool || "").trim().toLowerCase()}:${String(cur.target || "").trim().toLowerCase()}:${curAction}`;
|
|
7987
|
+
if (curSig !== signature)
|
|
7925
7988
|
break;
|
|
7926
7989
|
repeatCount++;
|
|
7927
7990
|
}
|
|
7928
7991
|
return {
|
|
7929
7992
|
tool: String(last.tool || "").toLowerCase(),
|
|
7930
7993
|
target: String(last.target || "").toLowerCase(),
|
|
7931
|
-
action:
|
|
7994
|
+
action: actionType,
|
|
7932
7995
|
signature,
|
|
7933
7996
|
repeat_count: repeatCount,
|
|
7934
7997
|
recent_count: events.length
|
|
@@ -16007,7 +16070,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
16007
16070
|
globalThis.__vibeOS_sessionId = `opencode-${process.pid || "x"}-${Date.now()}`;
|
|
16008
16071
|
}
|
|
16009
16072
|
const hookSessionId = globalThis.__vibeOS_sessionId;
|
|
16010
|
-
setVibeOSHomeContext(
|
|
16073
|
+
setVibeOSHomeContext(getVibeOSHome13());
|
|
16011
16074
|
setCurrentSessionId(hookSessionId);
|
|
16012
16075
|
if (hookFp) {
|
|
16013
16076
|
setCurrentProjectFingerprint(hookFp);
|
|
@@ -16086,7 +16149,7 @@ async function DelegationEnforcer({ client: client2, directory: directory3 } = {
|
|
|
16086
16149
|
briefedProjects.clear();
|
|
16087
16150
|
activeJob2 = _loadActiveJobForProject(directory3, fp);
|
|
16088
16151
|
const systemBriefedProjects = /* @__PURE__ */ new Set();
|
|
16089
|
-
const hookVibeHome =
|
|
16152
|
+
const hookVibeHome = getVibeOSHome13();
|
|
16090
16153
|
const hookStateFile = join18(hookVibeHome, "delegation-state.json");
|
|
16091
16154
|
const hookProjectStateFile = join18(hookVibeHome, "project-states.json");
|
|
16092
16155
|
const hookReportsDir = join18(hookVibeHome, "reports");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.25",
|
|
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",
|
|
@@ -35,12 +35,19 @@ function collectHomeOpenCodeHomes(baseHome) {
|
|
|
35
35
|
export function resolveOpenCodeHomes({ cwd = process.cwd(), home = homedir() } = {}) {
|
|
36
36
|
const override = process.env.VIBEOS_OPENCODE_HOME
|
|
37
37
|
if (override) return [override]
|
|
38
|
+
|
|
38
39
|
const workspaceHomes = collectWorkspaceOpenCodeHomes(cwd)
|
|
39
|
-
if (workspaceHomes.length > 0) return workspaceHomes
|
|
40
40
|
const homeHomes = collectHomeOpenCodeHomes(home)
|
|
41
41
|
const activeHomeHomes = homeHomes.filter((dir) => existsSync(dir))
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
|
|
43
|
+
const homeCandidates = activeHomeHomes.length > 0 ? activeHomeHomes : homeHomes
|
|
44
|
+
const seen = new Set()
|
|
45
|
+
return [...workspaceHomes, ...homeCandidates].filter((dir) => {
|
|
46
|
+
if (dir == null) return false
|
|
47
|
+
if (seen.has(dir)) return false
|
|
48
|
+
seen.add(dir)
|
|
49
|
+
return true
|
|
50
|
+
})
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export function resolveOpenCodeHome(opts = {}) {
|