vibeostheog 0.25.20 → 0.25.22
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 +8 -0
- package/bin/setup.js +5 -15
- package/dist/assets/dashboard/vibeos-dashboard-config.js +1 -1
- package/dist/vibeOS.js +75 -43
- package/package.json +2 -1
- package/scripts/deploy.mjs +1 -11
- package/scripts/lib/opencode-homes.mjs +49 -0
package/CHANGELOG.md
CHANGED
package/bin/setup.js
CHANGED
|
@@ -4,18 +4,7 @@ import { execSync } from "node:child_process";
|
|
|
4
4
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
5
5
|
import { dirname, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
function resolveOpenCodeHomes() {
|
|
10
|
-
const override = process.env.VIBEOS_OPENCODE_HOME;
|
|
11
|
-
if (override) return [override];
|
|
12
|
-
const base = homedir();
|
|
13
|
-
const desktopHome = process.env.VIBEOS_OPENCODE_DESKTOP_HOME
|
|
14
|
-
|| (process.platform === "darwin" ? resolve(base, "Library", "Application Support", "ai.opencode.desktop") : null);
|
|
15
|
-
const configHome = resolve(base, ".config", "opencode");
|
|
16
|
-
const dotHome = resolve(base, ".opencode");
|
|
17
|
-
return [desktopHome, configHome, dotHome].filter(Boolean);
|
|
18
|
-
}
|
|
7
|
+
import { resolveOpenCodeHome } from "../scripts/lib/opencode-homes.mjs";
|
|
19
8
|
|
|
20
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
10
|
const root = resolve(__dirname, "..");
|
|
@@ -35,7 +24,7 @@ if (!existsSync(deployScript)) {
|
|
|
35
24
|
console.error("Fatal: scripts/deploy.mjs not found at", deployScript);
|
|
36
25
|
process.exit(1);
|
|
37
26
|
}
|
|
38
|
-
execSync(`node "${deployScript}"`, { stdio: "inherit", cwd:
|
|
27
|
+
execSync(`node "${deployScript}"`, { stdio: "inherit", cwd: process.cwd() });
|
|
39
28
|
|
|
40
29
|
// For per-project setup, also register in project-level opencode.json
|
|
41
30
|
if (isProject) {
|
|
@@ -51,8 +40,9 @@ if (isProject) {
|
|
|
51
40
|
if (!config || typeof config !== "object" || Array.isArray(config)) config = {};
|
|
52
41
|
if (!config.$schema) config.$schema = "https://opencode.ai/config.json";
|
|
53
42
|
if (!Array.isArray(config.plugin)) config.plugin = [];
|
|
54
|
-
const
|
|
55
|
-
const pluginRef = resolve(installHome
|
|
43
|
+
const installHome = resolveOpenCodeHome({ cwd: process.cwd() });
|
|
44
|
+
const pluginRef = resolve(installHome, "plugins", "vibeOS.js");
|
|
45
|
+
config.plugin = config.plugin.filter((p) => !(typeof p === "string" && p.includes("vibeOS")));
|
|
56
46
|
if (!config.plugin.includes(pluginRef)) {
|
|
57
47
|
config.plugin.push(pluginRef);
|
|
58
48
|
mkdirSync(dirname(configPath), { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:
|
|
1
|
+
window.__VIBEOS_DASHBOARD_BASE__ = "http://127.0.0.1:50016";
|
package/dist/vibeOS.js
CHANGED
|
@@ -978,22 +978,30 @@ function getVibeOSHome2() {
|
|
|
978
978
|
function hasOpenCodeConfig(dir) {
|
|
979
979
|
return existsSync2(join2(dir, "opencode.json")) || existsSync2(join2(dir, "opencode.jsonc"));
|
|
980
980
|
}
|
|
981
|
-
function
|
|
981
|
+
function resolveOpenCodeHomes() {
|
|
982
982
|
const override = process.env.VIBEOS_OPENCODE_HOME;
|
|
983
983
|
if (override)
|
|
984
|
-
return override;
|
|
984
|
+
return [override];
|
|
985
985
|
const base = process.env.HOME || USER_HOME2;
|
|
986
|
+
const desktopHome = process.env.VIBEOS_OPENCODE_DESKTOP_HOME || (process.platform === "darwin" ? join2(base, "Library", "Application Support", "ai.opencode.desktop") : null);
|
|
986
987
|
const configHome = join2(base, ".config", "opencode");
|
|
987
988
|
const dotHome = join2(base, ".opencode");
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
989
|
+
return [desktopHome, configHome, dotHome].filter(Boolean);
|
|
990
|
+
}
|
|
991
|
+
function resolveOpenCodeHome() {
|
|
992
|
+
const homes = resolveOpenCodeHomes();
|
|
993
|
+
for (const home of homes) {
|
|
994
|
+
if (hasOpenCodeConfig(home))
|
|
995
|
+
return home;
|
|
996
|
+
}
|
|
997
|
+
for (const home of homes) {
|
|
998
|
+
if (existsSync2(home))
|
|
999
|
+
return home;
|
|
1000
|
+
}
|
|
1001
|
+
return homes[0] || join2(process.env.HOME || USER_HOME2, ".config", "opencode");
|
|
1002
|
+
}
|
|
1003
|
+
function getOpenCodeHome() {
|
|
1004
|
+
return resolveOpenCodeHome();
|
|
997
1005
|
}
|
|
998
1006
|
function setVibeOSHomeContext(home) {
|
|
999
1007
|
VIBEOS_CONTEXT.enterWith({ home: String(home || "") });
|
|
@@ -2690,7 +2698,7 @@ var init_state = __esm({
|
|
|
2690
2698
|
})();
|
|
2691
2699
|
VIBEOS_CONTEXT = new AsyncLocalStorage();
|
|
2692
2700
|
VIBEOS_HOME = process.env.VIBEOS_HOME || join2(USER_HOME2, ".claude");
|
|
2693
|
-
OPENCODE_HOME =
|
|
2701
|
+
OPENCODE_HOME = resolveOpenCodeHome();
|
|
2694
2702
|
FILE_LOCK_DIR = join2(VIBEOS_HOME, ".vibeOS-locks");
|
|
2695
2703
|
DELEGATION_STATE_FILE = join2(VIBEOS_HOME, "delegation-state.json");
|
|
2696
2704
|
SAVINGS_LEDGER_FILE = join2(VIBEOS_HOME, "savings-ledger.jsonl");
|
|
@@ -2858,6 +2866,9 @@ function safeJsonParse3(raw) {
|
|
|
2858
2866
|
return null;
|
|
2859
2867
|
}
|
|
2860
2868
|
}
|
|
2869
|
+
function getRealityCheckSettingsFile() {
|
|
2870
|
+
return join3(getVibeOSHome3(), "reality-check-settings.json");
|
|
2871
|
+
}
|
|
2861
2872
|
function resolveRulesPath() {
|
|
2862
2873
|
if (process.env.VIBEOS_FLOW_RULES_PATH && existsSync3(process.env.VIBEOS_FLOW_RULES_PATH)) {
|
|
2863
2874
|
return process.env.VIBEOS_FLOW_RULES_PATH;
|
|
@@ -2995,14 +3006,15 @@ function defaultRealityCheckRules() {
|
|
|
2995
3006
|
];
|
|
2996
3007
|
}
|
|
2997
3008
|
function readRealityCheckSettings() {
|
|
2998
|
-
const
|
|
3009
|
+
const settingsFile = getRealityCheckSettingsFile();
|
|
3010
|
+
const settingsMtime = existsSync3(settingsFile) ? statSync3(settingsFile).mtimeMs : 0;
|
|
2999
3011
|
if (_cachedRealityCheck && settingsMtime === _realityCheckMtime) {
|
|
3000
3012
|
return _cachedRealityCheck;
|
|
3001
3013
|
}
|
|
3002
3014
|
let parsed = {};
|
|
3003
3015
|
try {
|
|
3004
|
-
if (existsSync3(
|
|
3005
|
-
const raw = readFileSync3(
|
|
3016
|
+
if (existsSync3(settingsFile)) {
|
|
3017
|
+
const raw = readFileSync3(settingsFile, "utf-8");
|
|
3006
3018
|
const json2 = safeJsonParse3(raw);
|
|
3007
3019
|
if (json2 && typeof json2 === "object")
|
|
3008
3020
|
parsed = json2;
|
|
@@ -3085,7 +3097,8 @@ function loadRules() {
|
|
|
3085
3097
|
const rulesPath = resolveRulesPath();
|
|
3086
3098
|
try {
|
|
3087
3099
|
const rulesMtime = existsSync3(rulesPath) ? statSync3(rulesPath).mtimeMs : 0;
|
|
3088
|
-
const
|
|
3100
|
+
const realityFile = getRealityCheckSettingsFile();
|
|
3101
|
+
const realityMtime = existsSync3(realityFile) ? statSync3(realityFile).mtimeMs : 0;
|
|
3089
3102
|
const scopeKey = String(currentProjectFingerprint || "");
|
|
3090
3103
|
const cacheKey = `${rulesMtime}:${realityMtime}:${scopeKey}`;
|
|
3091
3104
|
if (_cachedRules && _realityCheckCacheKey === "__test__")
|
|
@@ -3311,7 +3324,7 @@ function syncFlowTodosToNative(upsertFn) {
|
|
|
3311
3324
|
}
|
|
3312
3325
|
return count;
|
|
3313
3326
|
}
|
|
3314
|
-
var VIBEOS_STDERR_DEBUG, VIBEOS_CONSOLE_ERROR_GUARD, globalConsoleState, __dirname2,
|
|
3327
|
+
var VIBEOS_STDERR_DEBUG, VIBEOS_CONSOLE_ERROR_GUARD, globalConsoleState, __dirname2, REALITY_CHECK_RULE_IDS, RULES_PATH_CANDIDATES, GUARD_AGENTS_TEMPLATE, GUARD_README_TEMPLATE, FLOW_DEDUP_FILE2, MAX_FLOW_TODOS, _flowWarnsSeen, _stateWriter, _cachedRules, _rulesMtime, _cachedRealityCheck, _realityCheckMtime, _realityCheckCacheKey;
|
|
3315
3328
|
var init_flow_enforcer = __esm({
|
|
3316
3329
|
"src/vibeOS-lib/flow-enforcer.js"() {
|
|
3317
3330
|
"use strict";
|
|
@@ -3346,7 +3359,6 @@ var init_flow_enforcer = __esm({
|
|
|
3346
3359
|
globalConsoleState[VIBEOS_CONSOLE_ERROR_GUARD] = true;
|
|
3347
3360
|
}
|
|
3348
3361
|
__dirname2 = dirname2(fileURLToPath(import.meta.url));
|
|
3349
|
-
REALITY_CHECK_SETTINGS_FILE = join3(getVibeOSHome3(), "reality-check-settings.json");
|
|
3350
3362
|
REALITY_CHECK_RULE_IDS = /* @__PURE__ */ new Set([
|
|
3351
3363
|
"require-read-before-claim",
|
|
3352
3364
|
"verify-state-on-disk",
|
|
@@ -7158,7 +7170,8 @@ var ResolutionTracker = class _ResolutionTracker {
|
|
|
7158
7170
|
return 1 - cosineSimilarity2(a, b);
|
|
7159
7171
|
}
|
|
7160
7172
|
detectLoop() {
|
|
7161
|
-
|
|
7173
|
+
const repeatSignal = Math.max(this.getRepeatStreak(), this.getActivityRepeatStreak(), this.getTargetRepeatStreak());
|
|
7174
|
+
return this.loopCount >= 2 || repeatSignal >= 2;
|
|
7162
7175
|
}
|
|
7163
7176
|
computeIntentState() {
|
|
7164
7177
|
const last = this.history[this.history.length - 1];
|
|
@@ -7418,8 +7431,16 @@ function detectOutcomeSignal(text) {
|
|
|
7418
7431
|
return "negative";
|
|
7419
7432
|
return null;
|
|
7420
7433
|
}
|
|
7421
|
-
function
|
|
7422
|
-
if (!
|
|
7434
|
+
function normalizeActivitySignature(event) {
|
|
7435
|
+
if (!event || typeof event !== "object")
|
|
7436
|
+
return "";
|
|
7437
|
+
const tool2 = String(event.tool || "").trim().toLowerCase();
|
|
7438
|
+
const target = String(event.target || "").trim().toLowerCase();
|
|
7439
|
+
const action = String(event.action || event.kind || "").trim().toLowerCase();
|
|
7440
|
+
return [tool2, target, action].filter(Boolean).join(":");
|
|
7441
|
+
}
|
|
7442
|
+
function countBehavioralRepeat(items, signatureOf, minLength = 2) {
|
|
7443
|
+
if (!Array.isArray(items) || items.length < minLength)
|
|
7423
7444
|
return 0;
|
|
7424
7445
|
const last = signatureOf(items[items.length - 1]);
|
|
7425
7446
|
if (!last)
|
|
@@ -7432,13 +7453,26 @@ function countTrailingRepeat(items, signatureOf) {
|
|
|
7432
7453
|
}
|
|
7433
7454
|
return streak;
|
|
7434
7455
|
}
|
|
7435
|
-
function
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
const
|
|
7439
|
-
const
|
|
7440
|
-
const
|
|
7441
|
-
|
|
7456
|
+
function getBehavioralStressSignals(context, blackboxState) {
|
|
7457
|
+
const recentEvents = Array.isArray(context?.recentToolEvents) ? context.recentToolEvents : Array.isArray(recentToolEvents) ? recentToolEvents : [];
|
|
7458
|
+
const recentWindow = recentEvents.slice(-8);
|
|
7459
|
+
const toolRepeatStreak = countBehavioralRepeat(recentWindow, normalizeActivitySignature);
|
|
7460
|
+
const targetRepeatStreak = countBehavioralRepeat(recentWindow, (event) => String(event?.target || "").trim().toLowerCase());
|
|
7461
|
+
const outcomeHistory = Array.isArray(context?.outcomeHistory) ? context.outcomeHistory : Array.isArray(blackboxState?.outcomeHistory) ? blackboxState.outcomeHistory : [];
|
|
7462
|
+
const negativeOutcomes = outcomeHistory.slice(-5).filter((o) => /negative|failed|unresolved|loop_detected/i.test(String(o?.outcome || ""))).length;
|
|
7463
|
+
const loopCount = Number(blackboxState?.loop_count ?? blackboxState?.loopConsecutive ?? blackboxState?.loop_consecutive ?? 0);
|
|
7464
|
+
const repeatStreak = Number(blackboxState?.repeat_streak ?? 0);
|
|
7465
|
+
const activityRepeatStreak = Number(blackboxState?.activity_repeat_streak ?? 0);
|
|
7466
|
+
const targetRepeatStateStreak = Number(blackboxState?.target_repeat_streak ?? 0);
|
|
7467
|
+
return {
|
|
7468
|
+
toolRepeatStreak,
|
|
7469
|
+
targetRepeatStreak,
|
|
7470
|
+
negativeOutcomes,
|
|
7471
|
+
loopCount,
|
|
7472
|
+
repeatStreak,
|
|
7473
|
+
activityRepeatStreak,
|
|
7474
|
+
targetRepeatStateStreak
|
|
7475
|
+
};
|
|
7442
7476
|
}
|
|
7443
7477
|
function scoreStress(text, context = {}) {
|
|
7444
7478
|
if (!text || typeof text !== "string")
|
|
@@ -7497,29 +7531,27 @@ function scoreStress(text, context = {}) {
|
|
|
7497
7531
|
} catch {
|
|
7498
7532
|
}
|
|
7499
7533
|
}
|
|
7500
|
-
const
|
|
7501
|
-
const recentWindow = recentEvents.slice(-8);
|
|
7502
|
-
const toolRepeatStreak = countTrailingRepeat(recentWindow, normalizeActivitySignature);
|
|
7534
|
+
const { toolRepeatStreak, targetRepeatStreak, negativeOutcomes, loopCount, repeatStreak, activityRepeatStreak, targetRepeatStateStreak } = getBehavioralStressSignals(context, blackboxState);
|
|
7503
7535
|
if (toolRepeatStreak >= 2) {
|
|
7504
|
-
score += 0.
|
|
7536
|
+
score += 0.08 + Math.min(0.24, (toolRepeatStreak - 1) * 0.05);
|
|
7505
7537
|
}
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
score += 0.04 + Math.min(0.12, (repeatedTargets - 1) * 0.03);
|
|
7538
|
+
if (targetRepeatStreak >= 2) {
|
|
7539
|
+
score += 0.05 + Math.min(0.16, (targetRepeatStreak - 1) * 0.035);
|
|
7509
7540
|
}
|
|
7510
|
-
const outcomeHistory = Array.isArray(context?.outcomeHistory) ? context.outcomeHistory : Array.isArray(blackboxState?.outcomeHistory) ? blackboxState.outcomeHistory : [];
|
|
7511
|
-
const recentOutcomes = outcomeHistory.slice(-5);
|
|
7512
|
-
const negativeOutcomes = recentOutcomes.filter((o) => /negative|failed|unresolved|loop_detected/i.test(String(o?.outcome || ""))).length;
|
|
7513
7541
|
if (negativeOutcomes >= 1) {
|
|
7514
|
-
score += 0.
|
|
7542
|
+
score += 0.05 * negativeOutcomes + Math.min(0.18, negativeOutcomes * 0.03);
|
|
7515
7543
|
}
|
|
7516
|
-
const loopCount = Number(blackboxState?.loop_count ?? blackboxState?.loopConsecutive ?? blackboxState?.loop_consecutive ?? 0);
|
|
7517
7544
|
if (blackboxState?.is_looping || loopCount >= 2) {
|
|
7518
|
-
score += 0.
|
|
7545
|
+
score += 0.1 + Math.min(0.18, loopCount * 0.03);
|
|
7519
7546
|
}
|
|
7520
|
-
const repeatStreak = Number(blackboxState?.repeat_streak ?? 0);
|
|
7521
7547
|
if (repeatStreak >= 2) {
|
|
7522
|
-
score += 0.
|
|
7548
|
+
score += 0.06 + Math.min(0.12, repeatStreak * 0.025);
|
|
7549
|
+
}
|
|
7550
|
+
if (activityRepeatStreak >= 2) {
|
|
7551
|
+
score += 0.05 + Math.min(0.1, activityRepeatStreak * 0.02);
|
|
7552
|
+
}
|
|
7553
|
+
if (targetRepeatStateStreak >= 2) {
|
|
7554
|
+
score += 0.04 + Math.min(0.08, targetRepeatStateStreak * 0.015);
|
|
7523
7555
|
}
|
|
7524
7556
|
if (text.length < 30)
|
|
7525
7557
|
score += 0.06;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeostheog",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.22",
|
|
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",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"bin/setup.js",
|
|
61
61
|
".opencode/plugins/vibeOS-tui.tsx",
|
|
62
62
|
"scripts/deploy.mjs",
|
|
63
|
+
"scripts/lib/**/*",
|
|
63
64
|
"model-tiers.sample.json",
|
|
64
65
|
"README.md",
|
|
65
66
|
"CHANGELOG.md",
|
package/scripts/deploy.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { cpSync, readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync
|
|
|
4
4
|
import { join, dirname } from "node:path"
|
|
5
5
|
import { fileURLToPath } from "node:url"
|
|
6
6
|
import { homedir } from "node:os"
|
|
7
|
+
import { resolveOpenCodeHomes } from "./lib/opencode-homes.mjs"
|
|
7
8
|
|
|
8
9
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
10
|
const ROOT = join(__dirname, "..")
|
|
@@ -11,17 +12,6 @@ const ROOT = join(__dirname, "..")
|
|
|
11
12
|
const bundlePath = join(ROOT, "dist", "vibeOS.js")
|
|
12
13
|
const assetsPath = join(ROOT, "dist", "assets")
|
|
13
14
|
|
|
14
|
-
function resolveOpenCodeHomes() {
|
|
15
|
-
const override = process.env.VIBEOS_OPENCODE_HOME
|
|
16
|
-
if (override) return [override]
|
|
17
|
-
const base = homedir()
|
|
18
|
-
const desktopHome = process.env.VIBEOS_OPENCODE_DESKTOP_HOME
|
|
19
|
-
|| (process.platform === "darwin" ? join(base, "Library", "Application Support", "ai.opencode.desktop") : null)
|
|
20
|
-
const configHome = join(base, ".config", "opencode")
|
|
21
|
-
const dotHome = join(base, ".opencode")
|
|
22
|
-
return [desktopHome, configHome, dotHome].filter(Boolean)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
15
|
if (!existsSync(bundlePath)) {
|
|
26
16
|
process.stderr.write("[vibeOS deploy] ERROR: dist/vibeOS.js not found\n")
|
|
27
17
|
process.exit(1)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
2
|
+
import { dirname, join, resolve } from "node:path"
|
|
3
|
+
import { homedir } from "node:os"
|
|
4
|
+
|
|
5
|
+
function hasOpenCodeConfig(dir) {
|
|
6
|
+
return existsSync(join(dir, "opencode.json")) || existsSync(join(dir, "opencode.jsonc"))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function collectWorkspaceOpenCodeHomes(cwd) {
|
|
10
|
+
const homes = []
|
|
11
|
+
const seen = new Set()
|
|
12
|
+
let dir = resolve(cwd || process.cwd())
|
|
13
|
+
while (true) {
|
|
14
|
+
for (const candidate of [dir, join(dir, "opencode"), join(dir, ".opencode")]) {
|
|
15
|
+
if (seen.has(candidate)) continue
|
|
16
|
+
if (hasOpenCodeConfig(candidate)) {
|
|
17
|
+
seen.add(candidate)
|
|
18
|
+
homes.push(candidate)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const parent = dirname(dir)
|
|
22
|
+
if (parent === dir) break
|
|
23
|
+
dir = parent
|
|
24
|
+
}
|
|
25
|
+
return homes
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function collectHomeOpenCodeHomes(baseHome) {
|
|
29
|
+
const home = baseHome || homedir()
|
|
30
|
+
const desktopHome = process.env.VIBEOS_OPENCODE_DESKTOP_HOME
|
|
31
|
+
|| (process.platform === "darwin" ? join(home, "Library", "Application Support", "ai.opencode.desktop") : null)
|
|
32
|
+
return [desktopHome, join(home, ".config", "opencode"), join(home, ".opencode")].filter(Boolean)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function resolveOpenCodeHomes({ cwd = process.cwd(), home = homedir() } = {}) {
|
|
36
|
+
const override = process.env.VIBEOS_OPENCODE_HOME
|
|
37
|
+
if (override) return [override]
|
|
38
|
+
const workspaceHomes = collectWorkspaceOpenCodeHomes(cwd)
|
|
39
|
+
if (workspaceHomes.length > 0) return workspaceHomes
|
|
40
|
+
const homeHomes = collectHomeOpenCodeHomes(home)
|
|
41
|
+
const activeHomeHomes = homeHomes.filter((dir) => existsSync(dir))
|
|
42
|
+
if (activeHomeHomes.length > 0) return activeHomeHomes
|
|
43
|
+
return homeHomes
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function resolveOpenCodeHome(opts = {}) {
|
|
47
|
+
const homes = resolveOpenCodeHomes(opts)
|
|
48
|
+
return homes[0] || join(opts.home || homedir(), ".config", "opencode")
|
|
49
|
+
}
|