vibeostheog 0.25.54 → 0.26.0
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 +110 -0
- package/README.md +75 -36
- package/bin/setup.js +184 -39
- package/dist/assets/dashboard/assets/index-BAFoSUYT.css +1 -0
- package/dist/assets/dashboard/assets/index-BC32ZQ0q.css +1 -0
- package/dist/assets/dashboard/assets/index-BFPdi_Ph.css +1 -0
- package/dist/assets/dashboard/assets/index-BHjsjrCc.js +5 -0
- package/dist/assets/dashboard/assets/index-BUDvTrCq.css +1 -0
- package/dist/assets/dashboard/assets/index-BY7bffmm.js +3 -0
- package/dist/assets/dashboard/assets/index-BZu3dyXH.css +1 -0
- package/dist/assets/dashboard/assets/index-Brj9Ui6Z.js +3 -0
- package/dist/assets/dashboard/assets/index-C-ScsrcN.js +3 -0
- package/dist/assets/dashboard/assets/index-C5VfzSA8.js +3 -0
- package/dist/assets/dashboard/assets/index-C5tPTUjx.js +3 -0
- package/dist/assets/dashboard/assets/index-Cb3hwMDH.css +1 -0
- package/dist/assets/dashboard/assets/index-CjHF2vTf.css +1 -0
- package/dist/assets/dashboard/assets/index-CkX-loOf.js +3 -0
- package/dist/assets/dashboard/assets/index-D3bLrmaq.css +1 -0
- package/dist/assets/dashboard/assets/index-DGIMdqp_.css +1 -0
- package/dist/assets/dashboard/assets/index-DK4e4oaB.js +3 -0
- package/dist/assets/dashboard/assets/index-DhtwzMRd.js +3 -0
- package/dist/assets/dashboard/assets/index-DnK3sBqN.js +3 -0
- package/dist/assets/dashboard/assets/index-Dwg0W0mM.js +3 -0
- package/dist/assets/dashboard/assets/index-H09FCi_1.js +5 -0
- package/dist/assets/dashboard/assets/index-IZRaK1J1.js +3 -0
- package/dist/assets/dashboard/assets/index-UkrMFHPp.css +1 -0
- package/dist/assets/dashboard/assets/index-VITT_Lum.js +3 -0
- package/dist/assets/dashboard/assets/index-Xf82CCxe.css +1 -0
- package/dist/assets/dashboard/assets/index-ZWfKo4FL.js +3 -0
- package/dist/assets/dashboard/assets/index-fhy-rD-W.css +1 -0
- package/dist/assets/dashboard/assets/index-mizr4ifp.js +5 -0
- package/dist/assets/dashboard/assets/index-rDxjSA11.css +1 -0
- package/dist/assets/dashboard/assets/index-xMN9Z-Zy.js +3 -0
- package/dist/assets/dashboard/index.html +3 -1076
- package/dist/assets/dashboard/vibeos-dashboard-config.js +2 -1
- package/dist/vibeOS.js +14382 -11760
- package/package.json +5 -5
- package/scripts/deploy.mjs +27 -17
- package/scripts/lib/opencode-homes.mjs +15 -48
- package/scripts/lib/plugin-config.mjs +35 -0
- package/scripts/lib/vibe-skill.mjs +62 -10
- package/scripts/lib/vibe-tier-agents.mjs +132 -0
- package/.opencode/skills/vibe/SKILL.md +0 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,113 @@
|
|
|
1
|
+
## 0.26.0
|
|
2
|
+
- feat: add classify/escalate cascade API wiring (#398)
|
|
3
|
+
- feat: rebuild dashboard home and session workspace (#389)
|
|
4
|
+
- feat: dashboard orchestrator backend + UX overhaul + MiniLM routing (#384)
|
|
5
|
+
- feat: learned flow rules from user corrections + content-aware pattern detection
|
|
6
|
+
- feat: redesign dashboard as home-first shell
|
|
7
|
+
- feat: port orchestrator frontend from vibeOScore
|
|
8
|
+
- fix: active API health probe — no passive 60s fallback, +audit path safety
|
|
9
|
+
- fix: local cascade escalation was discarded by any backend route, resolved_tier stuck at None (#412)
|
|
10
|
+
- fix: footer tier label/depth-icon desync, silent fallback trip, broken dead imports (#411)
|
|
11
|
+
- fix: isApiFallback() never self-heals, keeping BE non-authoritative for the session (#409)
|
|
12
|
+
- fix: cascade route_path pinned at full pipeline forever, never deescalates (#407)
|
|
13
|
+
- fix: remove dead cascade fields, footer model name follows escalated tier (#406)
|
|
14
|
+
- fix: single source of truth for cascade tier + fix deescalation (#405)
|
|
15
|
+
- fix: collapse cascade tier-routing to one source of truth, fix dead loop detector (#404)
|
|
16
|
+
- fix: collapse cascade subagent routing to one source of truth (#403)
|
|
17
|
+
- fix: use pending_escalation_tier for loop_break/web_search override (#402)
|
|
18
|
+
- fix: FE consumes web_search and loop_break from BE classify response (#401)
|
|
19
|
+
- fix: wire escalation re-route and loop context consumption (#399)
|
|
20
|
+
- fix: collapse 3-painter footer architecture into 1 shared resolver + 1 degrade path (#396)
|
|
21
|
+
- fix: cascade-aware model display in footer using trinity slot models (#395)
|
|
22
|
+
- fix: move hardcoded big-pickle fallback after resolveTrinityDisplayModel in shell-env (#394)
|
|
23
|
+
- fix: stop hardcoded opencode/big-pickle fallback from overriding real model in footer (#393)
|
|
24
|
+
- fix: footer honesty — expired reroute pulse removed, cascade icon shows at depth 1 (#391)
|
|
25
|
+
- fix: preserve native opencode mode selectors (#390)
|
|
26
|
+
- fix: align fallback footer with turn truth (#388)
|
|
27
|
+
- fix: align runtime footer and cascade truth (#387)
|
|
28
|
+
- fix: footer honesty + pivot cache TTL + quality floor in syncControlSettings (#386)
|
|
29
|
+
- fix: footer alert isApiFallback, session schema tier/model, cascade a… (#385)
|
|
30
|
+
- fix: replace vitest skeletons with node:test to unbreak CI
|
|
31
|
+
- fix: global agent config, session recording, and stale opencode config
|
|
32
|
+
- fix: remove hardcoded footer mode branding
|
|
33
|
+
- fix: preserve web search shell text for api tests
|
|
34
|
+
- fix: update stale ~/.claude/ state paths to VIBEOS_HOME
|
|
35
|
+
- fix: update stale ~/.claude/ state paths to VIBEOS_HOME
|
|
36
|
+
- fix: durable dashboard snapshots + stale-proof MCP discovery (#371)
|
|
37
|
+
- fix: cascade footer shows escalated tier + correct arrow count (#370)
|
|
38
|
+
- fix: persist cascade depth from backend route so footer shows cascade icon (#369)
|
|
39
|
+
- fix: make the cascade real — canonical blackbox records, live audit trail, durable bridges (#366)
|
|
40
|
+
- fix: stop config.update/opencode.json mid-turn writes that abort OpenCode turns (#365)
|
|
41
|
+
- fix: stop mid-turn opencode.json writes that abort OpenCode turns (#357)
|
|
42
|
+
- fix: stop vibeultrax from over-triggering stall recovery (#354)
|
|
43
|
+
- fix: clean up legacy config stubs before turns (#353)
|
|
44
|
+
- fix: unify vibe primary agent topology (#352)
|
|
45
|
+
- fix: add tool-call loop circuit-breaker to stop runaway bash poll loops (#350)
|
|
46
|
+
- fix: remove VIBEOS_API_DISABLED=true persistence from disk (#348)
|
|
47
|
+
- fix: allow explicit setting of embedded API token (#347)
|
|
48
|
+
- fix: deploy script never overwrites VIBEOS_HOME/.env.production (#346)
|
|
49
|
+
- fix: api hot-path deadline + blackbox state consolidation + spec contract (#345)
|
|
50
|
+
- fix: persist cascade depth/root to blackbox state across turns (#343)
|
|
51
|
+
- fix: prevent stale .js shadowing and cascade de-escalation (#342)
|
|
52
|
+
- fix: consolidate runtime OpenCode home resolution to single ~/.opencode (#338)
|
|
53
|
+
- fix: single source of truth for the footer — kill the "always cut" fallback (#331)
|
|
54
|
+
- fix: force pipeline repair when manual mode pipeline is collapsed (#330)
|
|
55
|
+
- fix: force pipeline repair when manual mode pipeline is collapsed
|
|
56
|
+
- fix: footer bail-out + pipeline collapse (#329)
|
|
57
|
+
- refactor: split state.ts into modules, fix resolved_tier freeze during API fallback (#413)
|
|
58
|
+
- refactor: dedupe the 8-field loop-notice reset block in loop-state.ts (#410)
|
|
59
|
+
- refactor: delete the dead ML learned-graph and the claim-verification wrapper (#408)
|
|
60
|
+
- refactor: mode axis consolidation + footer display fixes (#383)
|
|
61
|
+
- refactor: remove dead code and toy test (post-merge cleanup)
|
|
62
|
+
- refactor: consolidate mode system to vibemax|vibeqmax|vibeultrax|vibelitex|raw
|
|
63
|
+
- refactor: split maintainability boundaries into focused modules (#358)
|
|
64
|
+
- refactor: consolidate safeJsonParse to one canonical helper (#356)
|
|
65
|
+
- docs: update README for v0.26.0 Containment of Potential; add codename mapping in release.mjs
|
|
66
|
+
- test: add cascade escalation and mode-router real tests + API shape c… (#400)
|
|
67
|
+
- test: add SPEC §14 coverage tests and fix TS loader compilation (#397)
|
|
68
|
+
- chore: untrack internal-only MD files from repo (#351)
|
|
69
|
+
Fix dashboard home hierarchy and sidebar status (#392)
|
|
70
|
+
Merge pull request #380 from DrunkkToys/refactor/learned-flow-patterns
|
|
71
|
+
Merge pull request #379 from DrunkkToys/fix/global-config-dashboard
|
|
72
|
+
Merge pull request #378 from DrunkkToys/codex/dashboard-home-mirror
|
|
73
|
+
Fix footer integration test expectations
|
|
74
|
+
Merge pull request #377 from DrunkkToys/codex/fix-vibeultrax-cheap-first-startup
|
|
75
|
+
Fix syncControlSettings fallback slot scope
|
|
76
|
+
Update README regime and feature counts
|
|
77
|
+
Fix VibeUltraX cheap-first startup routing
|
|
78
|
+
Merge pull request #376 from DrunkkToys/codex/fix-plugin-status-savings
|
|
79
|
+
Hide footer backend icon during auth fallback
|
|
80
|
+
Fix plugin registration, status fallback, and savings sync
|
|
81
|
+
Merge pull request #375 from DrunkkToys/codex/minilm-authoritative-mode
|
|
82
|
+
Use embedding selector for authoritative mode decisions
|
|
83
|
+
Merge pull request #374 from DrunkkToys/codex/unify-dashboard-fastify
|
|
84
|
+
Preserve health probe metadata in MCP status
|
|
85
|
+
Add dashboard bridge write-behind sync
|
|
86
|
+
Merge pull request #373 from DrunkkToys/codex/port-vibeoscore-orchestrator-dashboard
|
|
87
|
+
fix cascade: complex prompts at any confidence route to brain tier (#368)
|
|
88
|
+
Fix local loop authority (#367)
|
|
89
|
+
Fix mega test loader paths and spec claims (#364)
|
|
90
|
+
Narrow shell loop guard to polling (#363)
|
|
91
|
+
Suppress repeated LOOPING notices (#362)
|
|
92
|
+
Make LOOPING sticky across authoritative state writes (#361)
|
|
93
|
+
Show cascade escalation labels (#360)
|
|
94
|
+
Unify session events under VIBEOS_HOME (#359)
|
|
95
|
+
Fix/api client consolidation (#355)
|
|
96
|
+
Migrate test suite to TS and fix buildFooterAlert null crash (#344)
|
|
97
|
+
Migrate repo to TS-only sources (#341)
|
|
98
|
+
Codex/fix cascade authority (#340)
|
|
99
|
+
Consolidate vibeOS skill install (#339)
|
|
100
|
+
Bind vibe tiers to live OpenCode agents (#337)
|
|
101
|
+
Fix VibeUltraX cheap-tier default via the OpenCode dropdown lever (#336)
|
|
102
|
+
Fix VibeUltraX cascade with tier subagents (#335)
|
|
103
|
+
Fix VibeUltraX live root state (#334)
|
|
104
|
+
Fix VibeUltraX cascade routing (#333)
|
|
105
|
+
Fix live control vector persistence (#332)
|
|
106
|
+
Revert "fix: force pipeline repair when manual mode pipeline is collapsed"
|
|
107
|
+
Fix blackbox session-id fragmentation freezing all sessions at INIT (#328)
|
|
108
|
+
Fix footer runtime probe path (#327)
|
|
109
|
+
|
|
110
|
+
|
|
1
111
|
## 0.25.53
|
|
2
112
|
- fix: add project/blackbox cards to home summary, fix template source detection, expand recommendations (#302)
|
|
3
113
|
Merge release v0.25.52 into master
|
package/README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
# vibeOS for OpenCode --
|
|
1
|
+
# vibeOS for OpenCode -- Containment of Potential v0.26.0
|
|
2
|
+
|
|
3
|
+
> **VIBEOS_HOME** = `/Users/drunkktoys/Library/Application Support/ai.opencode.desktop/vibeOS/`
|
|
4
|
+
> All runtime state files live under `$VIBEOS_HOME` (set via `VIBEOS_HOME` env var on this machine).
|
|
2
5
|
|
|
3
6
|
A quality-first control plane for AI-assisted coding.
|
|
4
7
|
|
|
5
8
|
When AI coding is cheap, you use more of it. That is the upside of the current moment -- the marginal cost of a code suggestion has collapsed. But volume does not equal quality. The more you delegate to AI, the more often a mediocre suggestion slips through: a half-implemented fix, a fabricated API call, a test that passes only because the assertions are stubs. The quality problem gets worse as the cost problem gets better. vibeOS exists to solve the quality problem. The savings are a side effect.
|
|
6
9
|
|
|
7
|
-
OpenCode Desktop gives you access to the most capable language models ever created -- Opus, Sonnet, DeepSeek v4 Pro -- but running them on every single turn adds up fast. More importantly, routing every turn through the most expensive model does not guarantee the best output.
|
|
10
|
+
OpenCode Desktop gives you access to the most capable language models ever created -- Opus, Sonnet, DeepSeek v4 Pro -- but running them on every single turn adds up fast. More importantly, routing every turn through the most expensive model does not guarantee the best output. vibeOS keeps one primary `vibe` agent in the dropdown, lets same-provider tier changes swap in-thread, and delegates cross-provider tier work to tier subagents without rewriting the active agent every turn.
|
|
8
11
|
|
|
9
12
|
The real system is smaller than the feature list makes it sound:
|
|
10
13
|
|
|
@@ -33,17 +36,17 @@ The lie detector flags when the assistant claims success without evidence. The l
|
|
|
33
36
|
|
|
34
37
|
## The Cascade Engine
|
|
35
38
|
|
|
36
|
-
vibeOS uses a three
|
|
39
|
+
vibeOS uses a single primary `vibe` agent plus three tier subagents to route every turn through the cheapest model that can produce a quality result.
|
|
37
40
|
|
|
38
41
|
### How It Works
|
|
39
42
|
|
|
40
|
-
1. **Cheap proposal** --
|
|
41
|
-
2. **Flash review** --
|
|
42
|
-
3. **Pro polish** -- The brain
|
|
43
|
+
1. **Cheap proposal** -- The unified `vibe` primary starts on your configured cheap slot (e.g., a local Ollama model via `vibe set cheap magiccoder:7b`, or any API model).
|
|
44
|
+
2. **Flash review** -- The medium tier runs as a subagent and critiques/refines the proposal without changing the dropdown agent.
|
|
45
|
+
3. **Pro polish** -- The brain tier runs as a subagent on complex sections; cross-provider work delegates there instead of flipping the active agent.
|
|
43
46
|
|
|
44
47
|
Not every turn goes through all three stages. The cascade router estimates input difficulty and routes simple queries directly to the cheap tier. Complex reasoning, multi-file edits, and ambiguous instructions escalate to medium or brain. The router learns from session outcomes and calibrates its thresholds over time.
|
|
45
48
|
|
|
46
|
-
Benchmarked at **107% of raw brain quality at 58% of cost**. Local inference is free; only the Flash and Pro stages incur API costs. This is the first routing strategy that Pareto-dominates the raw brain baseline -- better quality, lower cost.
|
|
49
|
+
Benchmarked at **107% of raw brain quality at 58% of cost**. Local inference is free; only the Flash and Pro stages incur API costs. This is the first routing strategy that Pareto-dominates the raw brain baseline -- better quality, lower cost, without per-turn agent churn.
|
|
47
50
|
|
|
48
51
|
### Research Foundation
|
|
49
52
|
|
|
@@ -51,14 +54,16 @@ The cascade shape follows the general LLM routing literature, but the live sourc
|
|
|
51
54
|
|
|
52
55
|
### VibeBoX Decision Engine
|
|
53
56
|
|
|
54
|
-
At the core of vibeOS is a real-time decision engine that classifies every user turn into one of
|
|
57
|
+
At the core of vibeOS is a real-time decision engine that classifies every user turn into one of fourteen sub-regimes:
|
|
55
58
|
|
|
56
59
|
- **INIT / DIVERGENT / EXPLORING** -- You are learning the codebase, asking questions, browsing. cheap model, relaxed enforcement. Stay out of your way.
|
|
57
|
-
- **REFINING** -- You are iterating on a solution. Default mode: VibeUltraX, auto-escalate on complexity.
|
|
60
|
+
- **REFINING / IMPLEMENTING / DESIGNING** -- You are iterating on a solution or actively building. Default mode: VibeUltraX, auto-escalate on complexity.
|
|
61
|
+
- **RESEARCH / REVIEWING** -- You are investigating, comparing, or checking work. Routing and enforcement tighten as evidence requirements increase.
|
|
58
62
|
- **CONVERGING / CLOSED** -- You are finalizing. Full quality mode, brain tier, strict enforcement and flow checks.
|
|
59
|
-
- **LOOPING** -- You are stuck. Speed mode
|
|
63
|
+
- **LOOPING / ESCALATED** -- You are stuck or the session needs intervention. Speed mode or hard escalation paths activate to break cycles.
|
|
64
|
+
- **FORENSIC / AUDIT** -- You are doing deep investigation or security-style review. Brain tier, strict enforcement, detailed verification.
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
For VibeMaX, feature extraction currently yields 14 numeric features per turn: 8 normalized metrics plus 6 raw/boolean indicators. Four escalating intervention levels prevent infinite loops. PIVOT/SWITCH detection recognizes context changes and injects scope-confirmation directives.
|
|
62
67
|
|
|
63
68
|
When the VibeBoX is disabled, a lightweight classifyTurnSimple fallback distinguishes Q&A from implementation intent using regex patterns.
|
|
64
69
|
|
|
@@ -68,7 +73,7 @@ A real-time stress scoring pipeline analyzes user messages for frustration signa
|
|
|
68
73
|
|
|
69
74
|
### Pattern Learner
|
|
70
75
|
|
|
71
|
-
Per-project friction and routine tracking. The learner watches repeated tool failures, recovery loops, and stable workflows, then stores the result locally first. Cross-project hints are merged later into `global-learning.json` so the client can stay small while still learning.
|
|
76
|
+
Per-project friction and routine tracking. The learner watches repeated tool failures, recovery loops, and stable workflows, then stores the result locally first. Cross-project hints are merged later into `VIBEOS_HOME/global-learning.json` so the client can stay small while still learning.
|
|
72
77
|
|
|
73
78
|
### Context Compression
|
|
74
79
|
|
|
@@ -107,14 +112,14 @@ The smart cache predicts whether a tool query will hit scratchpad cache before e
|
|
|
107
112
|
|
|
108
113
|
The prediction engine (`predictCacheHit`) computes a confidence score and returns whether caching is worthwhile, estimated savings, and the most similar cached entries. Per-tool hit rates are tracked with exponential decay (DECAY = 0.9) so recent performance matters more than historical averages.
|
|
109
114
|
|
|
110
|
-
Cache state persists across sessions in
|
|
115
|
+
Cache state persists across sessions in `VIBEOS_HOME/global-learning.json` with a 7-day TTL eviction. The prediction results feed into the delegation enforcer's cost calculations and appear in the live footer savings display.
|
|
111
116
|
|
|
112
117
|
### Pivot and Counter-Pivot
|
|
113
118
|
|
|
114
119
|
Two complementary mechanisms manage context transitions:
|
|
115
120
|
|
|
116
121
|
**Forward pivot** -- Detects when you abruptly change topic mid-session. Uses a composite score of word-overlap distance, instruction-density delta, message-length ratio, and action-type change. Fires when `pivotScore > 0.45`. When detected:
|
|
117
|
-
1. Snapshots the current workflow (intent, files, decisions, blockers, code) to
|
|
122
|
+
1. Snapshots the current workflow (intent, files, decisions, blockers, code) to `$VIBEOS_HOME/.vibeos-pivot-cache.json`
|
|
118
123
|
2. Downgrades mode to budget (cheap tier, thinking off, relaxed enforcement)
|
|
119
124
|
3. Injects a context-shift directive into the system prompt
|
|
120
125
|
|
|
@@ -138,7 +143,7 @@ The savings are real and measurable. Every write/edit on the brain tier is inter
|
|
|
138
143
|
| Opus -> Sonnet | $0.0264 | $0.26 | $2.64 | $26.40 |
|
|
139
144
|
| Sonnet -> Haiku | $0.0044 | $0.04 | $0.44 | $4.40 |
|
|
140
145
|
|
|
141
|
-
The running total is persisted in
|
|
146
|
+
The running total is persisted in $VIBEOS_HOME/delegation-state.json and displayed in the live footer. Cache savings are tracked separately under cache_savings_usd.
|
|
142
147
|
|
|
143
148
|
### Model Tiers
|
|
144
149
|
|
|
@@ -157,28 +162,30 @@ DeepSeek Chat costs $0/turn when routed through the Direct DeepSeek provider (no
|
|
|
157
162
|
|
|
158
163
|
| Policy | Quality vs Brain | Cost vs Brain | Savings | Method |
|
|
159
164
|
|--------|-----------------|--------------|---------|--------|
|
|
160
|
-
| VibeUltraX | 107% | 0.58x | 42% |
|
|
165
|
+
| VibeUltraX | 107% | 0.58x | 42% | vibe primary + tier subagents |
|
|
161
166
|
| VibeQMaX | ~100% | 0.50x | 50% | same model, framework optimizations |
|
|
162
|
-
| Raw Brain | 100% | 1.00x | - | baseline |
|
|
163
167
|
| VibeMaX | ~75% | 0.18x | 82% | trained cascade (conservative escalate) |
|
|
168
|
+
| VibeLiteX | ~40% | 0.00x | 100% | direct cheap routing |
|
|
164
169
|
| Budget | ~40% | 0.00x | 100% | direct routing |
|
|
165
170
|
|
|
166
|
-
**VibeUltraX** -- Default mode.
|
|
171
|
+
**VibeUltraX** -- Default mode. The unified `vibe` primary starts on cheap, medium and brain run as subagents, and same-provider escalations stay in-thread. 107% quality at 58% cost.
|
|
167
172
|
|
|
168
173
|
**VibeQMaX** -- Routes strategic turns through v4 Pro with full thinking, strict enforcement, strict flow checks, and quality TDD. Write/edit delegated per enforcement rules. Blended cost ~$0.00029/turn (50% of brain baseline).
|
|
169
174
|
|
|
170
175
|
**VibeMaX** -- ML-optimized medium mode. Routes through v4 Flash with a random forest classifier (29 trees, gini-split, trained on telemetry) that decides each turn. ~75% quality at 18% cost.
|
|
171
176
|
|
|
177
|
+
**VibeLiteX** -- Cheap direct routing with relaxed enforcement. Ideal for exploration and Q&A.
|
|
178
|
+
|
|
172
179
|
**Budget** -- DeepSeek Chat. Direct routing. ~40% quality at zero cost.
|
|
173
180
|
|
|
174
181
|
### Mode Configuration
|
|
175
182
|
|
|
176
183
|
| Mode | Model | Thinking | Enforcement | Flow | TDD |
|
|
177
184
|
|------|-------|----------|-------------|------|-----|
|
|
178
|
-
| Raw Brain | v4 Pro | full | - | - | - |
|
|
179
185
|
| VibeQMaX | v4 Pro | full | strict | strict | quality |
|
|
180
|
-
| VibeUltraX |
|
|
186
|
+
| VibeUltraX | vibe primary + tier subagents | auto | auto | auto | auto |
|
|
181
187
|
| VibeMaX | v4 Flash (auto-escalate) | auto | auto | auto | auto |
|
|
188
|
+
| VibeLiteX | cheap | off | relaxed | audit | lazy |
|
|
182
189
|
| Speed | v4 Flash | off | relaxed | audit | lazy |
|
|
183
190
|
| Budget | DeepSeek Chat | off | relaxed | audit | lazy |
|
|
184
191
|
|
|
@@ -201,11 +208,11 @@ Stress > 1.5 escalates any regime to quality mode regardless of the above mappin
|
|
|
201
208
|
| Delegation enforcement | Blocks write/edit on brain tier, routes to cheaper tiers transparently |
|
|
202
209
|
| Live savings footer | Tier, provider, model name, total savings, mode -- one line of reassurance |
|
|
203
210
|
| Web dashboard | Session-first SolidJS SPA with executive Home summary, session actions, per-session templates, polling refresh for model split, savings, session history, controls |
|
|
204
|
-
| Trinity runtime | Update tier slots through the native OpenCode config path, change optimization mode, toggle subsystems live |
|
|
211
|
+
| Trinity runtime | Update tier slots and keep the unified vibe primary plus tier subagents synced through the native OpenCode config path, change optimization mode, toggle subsystems live |
|
|
205
212
|
| Flow enforcer | Pattern-rule checks on write/edit. Extracts TODO/FIXME into append-only queue. |
|
|
206
213
|
| TDD enforcer | Auto-creates test skeletons for changed source. Strict mode fails TODO tests. |
|
|
207
214
|
| Pattern learner | Tracks recurring struggle/routine patterns per project, cross-project too |
|
|
208
|
-
| VibeBoX |
|
|
215
|
+
| VibeBoX | 14 sub-regimes, 14 features per turn, loop intervention, PIVOT/SWITCH detection |
|
|
209
216
|
| Stress-aware routing | Real-time stress scoring, auto-escalation, system prompt inoculation |
|
|
210
217
|
| Cache savings | Separate cache_savings_usd tracking for scratchpad cache hits |
|
|
211
218
|
| Report tools | report-save, report-list, report-read, research-audit |
|
|
@@ -222,10 +229,13 @@ Stress > 1.5 escalates any regime to quality mode regardless of the above mappin
|
|
|
222
229
|
| Claim verification | Scans assistant output for made-up references, validates against codebase |
|
|
223
230
|
| Token compression | Web fetch output stripped to 30% of original size -- verbose lines, bullet prefixes, and blank lines collapsed. Tool output history compressed to cold-storage references after the hot window (last 10 messages). Project memory condensed to single-line directives for system prompts. |
|
|
224
231
|
| Rotation memory | Scratchpad files age through a four-stage lifecycle: fresh (< 5 min, full content), warm (5 min - 24 hr, 500-char summary), cold (24 - 48 hr, 200-char summary), expired (> 48 hr, deleted). Rotation runs opportunistically on every tool execution, throttled to once per minute. Cache hits degrade gracefully over time instead of failing abruptly. |
|
|
225
|
-
| Smart cache | Predicts whether a tool query will hit scratchpad cache using composite similarity scoring (Jaccard + cosine bigram + weighted keyword overlap). Per-tool hit rates tracked with exponential decay. Estimated savings calculated and displayed in the live footer. Cache entries persisted across sessions via global-learning.json with 7-day TTL eviction. |
|
|
232
|
+
| Smart cache | Predicts whether a tool query will hit scratchpad cache using composite similarity scoring (Jaccard + cosine bigram + weighted keyword overlap). Per-tool hit rates tracked with exponential decay. Estimated savings calculated and displayed in the live footer. Cache entries persisted across sessions via `VIBEOS_HOME/global-learning.json` with 7-day TTL eviction. |
|
|
226
233
|
| Pivot / counter-pivot | Detects when you switch topics mid-session (forward pivot) and when you return to a previously abandoned workflow (counter-pivot). Forward pivots snapshot the old workflow context and downgrade to budget mode. Counter-pivots restore files, decisions, blockers, and code snippets from cached workflow snapshots into the system prompt. |
|
|
227
234
|
| Deferred reports | saveReport deferred to setTimeout to avoid blocking tool output |
|
|
228
235
|
| Stress gauge footer | Live indicator in footer -- ▁▂▃▅▆█ (none/minimal/calm/elevated/high/critical) |
|
|
236
|
+
| Cascade escalation API | classifyTurn + escalateTurn endpoints wired through the cascade pipeline with real-time tier resolution |
|
|
237
|
+
| Backend-authoritative slot sync | Active API health probe syncs slot state from backend authority without passive fallback |
|
|
238
|
+
| SPEC §14 coverage | Certified test coverage for cascade tier-routing, deescalation, mode-router, and API shape compliance |
|
|
229
239
|
|
|
230
240
|
## Install
|
|
231
241
|
|
|
@@ -259,8 +269,8 @@ Local dev checkout:
|
|
|
259
269
|
| `vibe set brain\|medium\|cheap [model=<model_id>]` | Switch active model tier or override slot |
|
|
260
270
|
| `vibe brain\|medium\|cheap` | Shorthand tier switch |
|
|
261
271
|
| `vibe enable|disable` | Toggle plugin on/off |
|
|
262
|
-
| `vibe mode budget
|
|
263
|
-
| `vibe thinking full
|
|
272
|
+
| `vibe mode budget\|quality\|speed\|longrun\|auto\|balanced\|audit\|forensic\|vibeultrax\|vibeqmax\|vibemax\|vibelitex` | Set optimization mode (generic or branded) |
|
|
273
|
+
| `vibe thinking full\|brief\|off` | Reasoning depth |
|
|
264
274
|
| `vibe enforce on|off` | Toggle delegation enforcement |
|
|
265
275
|
| `vibe lock on|off` | Freeze model for session |
|
|
266
276
|
| `vibe flow on|off` | Toggle flow enforcer |
|
|
@@ -271,6 +281,7 @@ Local dev checkout:
|
|
|
271
281
|
| `vibe rebuild` | Re-detect models from all providers |
|
|
272
282
|
| `vibe project` | Per-project analytics |
|
|
273
283
|
| `vibe patterns` / `vibe patterns clear` / `vibe patterns suggest` | Pattern inspection |
|
|
284
|
+
| `vibe axis [status\|reset\|<name> <value>]` | Axis overrides for enforcement, flow, tdd, tier, thinking, context7_urgency, wbp_verbosity, websearch |
|
|
274
285
|
| `vibe todo` / `vibe todo-done <id>` / `vibe todo-sync` | View pending todos, mark done, sync flow todos |
|
|
275
286
|
| `vibe verify-claims` | Audit recent claim output against cascade evidence |
|
|
276
287
|
| `vibe diagnose` | Health check |
|
|
@@ -289,22 +300,24 @@ Local dev checkout:
|
|
|
289
300
|
|
|
290
301
|
### Architecture
|
|
291
302
|
|
|
292
|
-
vibeOS hooks into OpenCode Desktop through
|
|
303
|
+
vibeOS hooks into OpenCode Desktop through 10 extension points:
|
|
293
304
|
|
|
294
305
|
| Hook | Purpose |
|
|
295
306
|
|------|---------|
|
|
296
307
|
| experimental.text.complete | Appends footer to assistant responses |
|
|
297
308
|
| experimental.chat.messages.transform | Injects delegation protocol content |
|
|
298
309
|
| experimental.chat.system.transform | Injects cost optimization, stress inoculation, enforcement directives |
|
|
310
|
+
| experimental.chat.params | Modifies chat parameters before requests |
|
|
311
|
+
| experimental.chat.headers | Injects custom HTTP headers into chat requests |
|
|
299
312
|
| tool.execute.before | Blocks write/edit on brain tier |
|
|
300
313
|
| tool.execute.after | Injects delegation UI notes |
|
|
301
314
|
| message.updated | Fallback footer for versions without text.complete |
|
|
302
315
|
| experimental.session.compacting | Preserves savings state |
|
|
303
316
|
| shell.env | Injects OPENCODE_MODEL_TIER and OPENCODE_MODEL |
|
|
304
317
|
|
|
305
|
-
### State Files (
|
|
318
|
+
### State Files (`VIBEOS_HOME/`)
|
|
306
319
|
|
|
307
|
-
The plugin persists state to
|
|
320
|
+
The plugin persists state to `VIBEOS_HOME/` for cross-session continuity:
|
|
308
321
|
|
|
309
322
|
- **delegation-state.json** -- Sessions, warns, cache hits, lifetime totals
|
|
310
323
|
- **model-tiers.json** -- Brain/medium/cheap model IDs
|
|
@@ -320,10 +333,6 @@ Core features work fully offline: model tier classification, static pricing, str
|
|
|
320
333
|
|
|
321
334
|
Remote API (api.vibetheog.com) enables: bootstrap token exchange, advanced VibeBoX with full session history, dynamic per-prompt delegation, cross-session calibration, live pricing fetch, learned subagent routing. Falls back gracefully when unreachable.
|
|
322
335
|
|
|
323
|
-
### What Is Missing For A True Session Orchestrator
|
|
324
|
-
|
|
325
|
-
The live dashboard now covers the executive Home summary, session actions, and session-scoped templates. Still missing: session versioning/undo, template versioning, batch operations, live push transport, session comparison, and export/import.
|
|
326
|
-
|
|
327
336
|
### Live Footer
|
|
328
337
|
|
|
329
338
|
The footer is the primary status line, appended to every assistant response. It surfaces model assignment, savings, mode, alerts, and session metrics in a single line.
|
|
@@ -406,6 +415,19 @@ The footer is the primary status line, appended to every assistant response. It
|
|
|
406
415
|
| ⟡ medium | Active slot changed to medium this turn |
|
|
407
416
|
| ⟡ brain | Active slot changed to brain this turn |
|
|
408
417
|
|
|
418
|
+
#### Alert Tags
|
|
419
|
+
|
|
420
|
+
The alert is part of the one footer (it is **not** a separate line). When present it renders
|
|
421
|
+
after the enforcement tags and before the stress gauge. Multiple alerts join with ` · `.
|
|
422
|
+
This table is the single source of truth — `buildFooterAlert()` must match it exactly.
|
|
423
|
+
|
|
424
|
+
| Alert | Trigger |
|
|
425
|
+
|-------|---------|
|
|
426
|
+
| ⚠ api degraded | API latency is degraded / the backend is unhealthy this turn |
|
|
427
|
+
| ⚠ switch pending | A tier switch is deferred and will apply at the next turn boundary |
|
|
428
|
+
| ⚠ model drift | The live model is outside the cascade tiers and differs from the expected slot model |
|
|
429
|
+
| ⚠ model unreachable | The last model call failed with a network error (EHOSTUNREACH / ENOTFOUND / ETIMEDOUT) |
|
|
430
|
+
|
|
409
431
|
**Segments (left to right):**
|
|
410
432
|
|
|
411
433
|
| Segment | Format | Example | Meaning |
|
|
@@ -418,22 +440,39 @@ The footer is the primary status line, appended to every assistant response. It
|
|
|
418
440
|
| Brand + mode label | VibeBrand . modeLabel | VibeUltraX . Quality | Requested mode + regime-derived label |
|
|
419
441
|
| Cascade icon | >>> or >> | >>> | VibeUltraX cascade depth >= 3 |
|
|
420
442
|
| Enforcement tags | guarded, flow steady, tests live | guarded | Guard state summary |
|
|
443
|
+
| Alert tags | ⚠ alert · ⚠ alert | ⚠ model drift | Live status alerts (see Alert Tags) |
|
|
421
444
|
| Stress gauge | gaugeChar | _ | Current stress level |
|
|
422
445
|
| Vector pulse | slot | cheap | Active slot changed this turn |
|
|
423
446
|
|
|
424
|
-
Controls: `vibe status` for full state, `vibe enable/disable` to toggle. Persisted in
|
|
447
|
+
Controls: `vibe status` for full state, `vibe enable/disable` to toggle. Persisted in $VIBEOS_HOME/delegation-state.json.
|
|
425
448
|
|
|
426
449
|
### Environment Variables
|
|
427
450
|
|
|
428
451
|
| Variable | Default | Effect |
|
|
429
452
|
|----------|---------|--------|
|
|
453
|
+
| VIBEOS_HOME | ~/.vibeos | Runtime state directory |
|
|
430
454
|
| VIBEOS_API_URL | https://api.vibetheog.com | Remote API base URL |
|
|
431
455
|
| VIBEOS_API_TOKEN | unset | Remote API auth |
|
|
432
|
-
| VIBEOS_API_DISABLED | false | Invalidate alpha token |
|
|
433
456
|
| VIBEOS_API_BOOTSTRAP_TOKEN | unset | Bootstrap exchange |
|
|
434
|
-
| VIBEOS_API_ENABLED | true | Set false for local-only |
|
|
435
|
-
| CLAUDE_CREDIT_PERCENT | 100 | Credit override |
|
|
436
457
|
| VIBEOS_MCP_PORT | 3001 | MCP server port |
|
|
458
|
+
| VIBEOS_BUILD_CHANNEL | alpha | Build channel for API client |
|
|
459
|
+
| VIBEOS_DEBUG | unset | Verbose debug logging |
|
|
460
|
+
| VIBEOS_DEBUG_INTERNALS | unset | Internal state debug logging |
|
|
461
|
+
| VIBEOS_DEBUG_DELEGATION | unset | Delegation enforcer debug logging |
|
|
462
|
+
| VIBEOS_DEBUG_FOOTER | unset | Footer builder debug logging |
|
|
463
|
+
| VIBEOS_DEBUG_LOGS | unset | Flow enforcer debug logging |
|
|
464
|
+
| VIBEOS_DEBUG_STDERR | unset | Flow enforcer stderr debug logging |
|
|
465
|
+
| VIBEOS_FLOW_RULES_PATH | unset | Custom flow rules file path |
|
|
466
|
+
| VIBEOS_DASHBOARD_SYNC_MS | 20000 | Dashboard polling interval (ms) |
|
|
467
|
+
| VIBEOS_ACTIVE_PROBE_MS | 10000 | Backend health probe interval (ms) |
|
|
468
|
+
| VIBEOS_REMOTE_LATENCY_DEGRADE_MS | 800 | Latency threshold for degraded alert (ms) |
|
|
469
|
+
| VIBEOS_REMOTE_LATENCY_DEGRADE_COOLDOWN_MS | 120000 | Cooldown between degraded alerts (ms) |
|
|
470
|
+
| VIBEOS_VIBEMAX_MODEL_PATH | unset | Custom VibeMaX model path |
|
|
471
|
+
| VIBEOS_OPENCODE_DESKTOP_HOME | unset | OpenCode Desktop home override |
|
|
472
|
+
| VIBEOS_OPENCODE_HOME | unset | OpenCode config home override |
|
|
473
|
+
| VIBEOS_API_MASTER_KEY | unset | API master key for backend auth |
|
|
474
|
+
| VIBEOS_BACKEND_HEALTH_URL | unset | Custom backend health check URL |
|
|
475
|
+
| CLAUDE_CREDIT_PERCENT | 50 | Credit override percentage |
|
|
437
476
|
|
|
438
477
|
### Troubleshooting
|
|
439
478
|
|
package/bin/setup.js
CHANGED
|
@@ -1,47 +1,193 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
// src/bin/setup.ts
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "node:fs";
|
|
6
|
+
import { dirname as dirname2, resolve as resolve2 } from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { resolveOpenCodeHome, resolveOpenCodeHomes } from "../scripts/lib/opencode-homes.mjs";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
// scripts/lib/opencode-homes.mjs
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
function resolveOpenCodeHomes({ home = homedir() } = {}) {
|
|
13
|
+
const override = process.env.VIBEOS_OPENCODE_HOME;
|
|
14
|
+
if (override) return [override];
|
|
15
|
+
return [join(home, ".opencode")];
|
|
16
|
+
}
|
|
17
|
+
function resolveOpenCodeHome(opts = {}) {
|
|
18
|
+
return resolveOpenCodeHomes(opts)[0];
|
|
19
|
+
}
|
|
16
20
|
|
|
21
|
+
// scripts/lib/vibe-tier-agents.mjs
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "node:fs";
|
|
23
|
+
import { dirname, join as join2 } from "node:path";
|
|
24
|
+
import { homedir as homedir2 } from "node:os";
|
|
25
|
+
var VIBE_TIER_AGENT_BY_SLOT = {
|
|
26
|
+
cheap: "vibe-cheap",
|
|
27
|
+
medium: "vibe-medium",
|
|
28
|
+
brain: "vibe-brain"
|
|
29
|
+
};
|
|
30
|
+
var VIBE_PRIMARY_AGENT = "vibe";
|
|
31
|
+
var NATIVE_OPENCODE_AGENTS = ["build", "plan", "vibe"];
|
|
32
|
+
function isNativeOpenCodeAgent(value) {
|
|
33
|
+
return NATIVE_OPENCODE_AGENTS.includes(String(value || "").trim().toLowerCase());
|
|
34
|
+
}
|
|
35
|
+
function normalizeNativeOpenCodeAgent(value, fallback = VIBE_PRIMARY_AGENT) {
|
|
36
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
37
|
+
return isNativeOpenCodeAgent(normalized) ? normalized : fallback;
|
|
38
|
+
}
|
|
39
|
+
function readJson(path) {
|
|
40
|
+
if (!existsSync(path)) return {};
|
|
41
|
+
try {
|
|
42
|
+
const raw = readFileSync(path, "utf8");
|
|
43
|
+
const cleaned = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
44
|
+
const parsed = JSON.parse(cleaned);
|
|
45
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
46
|
+
} catch {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function readTiers(home = homedir2()) {
|
|
51
|
+
return readJson(join2(process.env.VIBEOS_HOME || join2(home, ".claude"), "model-tiers.json"));
|
|
52
|
+
}
|
|
53
|
+
function primaryAgent(existing = {}) {
|
|
54
|
+
const next = {
|
|
55
|
+
...existing && typeof existing === "object" ? existing : {},
|
|
56
|
+
description: "VibeUltraX primary agent",
|
|
57
|
+
mode: "primary",
|
|
58
|
+
permission: {
|
|
59
|
+
read: "allow",
|
|
60
|
+
edit: "allow",
|
|
61
|
+
glob: "allow",
|
|
62
|
+
grep: "allow",
|
|
63
|
+
list: "allow",
|
|
64
|
+
bash: "allow",
|
|
65
|
+
task: "allow",
|
|
66
|
+
webfetch: "allow",
|
|
67
|
+
websearch: "allow",
|
|
68
|
+
...existing?.permission && typeof existing.permission === "object" ? existing.permission : {}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
delete next.model;
|
|
72
|
+
return next;
|
|
73
|
+
}
|
|
74
|
+
function tierAgent(slot, model, existing = {}) {
|
|
75
|
+
return {
|
|
76
|
+
...existing && typeof existing === "object" ? existing : {},
|
|
77
|
+
description: `VibeUltraX ${slot} tier subagent`,
|
|
78
|
+
mode: "subagent",
|
|
79
|
+
model,
|
|
80
|
+
permission: {
|
|
81
|
+
read: "allow",
|
|
82
|
+
edit: "allow",
|
|
83
|
+
glob: "allow",
|
|
84
|
+
grep: "allow",
|
|
85
|
+
list: "allow",
|
|
86
|
+
bash: "allow",
|
|
87
|
+
task: "allow",
|
|
88
|
+
webfetch: "allow",
|
|
89
|
+
websearch: "allow",
|
|
90
|
+
...existing?.permission && typeof existing.permission === "object" ? existing.permission : {}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function installVibeTierAgentsInConfig(config, tiers = readTiers()) {
|
|
95
|
+
if (!config || typeof config !== "object" || Array.isArray(config)) return false;
|
|
96
|
+
const trinity = tiers?.trinity || {};
|
|
97
|
+
config.$schema ||= "https://opencode.ai/config.json";
|
|
98
|
+
config.agent = config.agent && typeof config.agent === "object" ? config.agent : {};
|
|
99
|
+
let changed = false;
|
|
100
|
+
const existingPrimary = config.agent[VIBE_PRIMARY_AGENT];
|
|
101
|
+
const nextPrimary = primaryAgent(existingPrimary);
|
|
102
|
+
if (JSON.stringify(existingPrimary || null) !== JSON.stringify(nextPrimary)) {
|
|
103
|
+
config.agent[VIBE_PRIMARY_AGENT] = nextPrimary;
|
|
104
|
+
changed = true;
|
|
105
|
+
}
|
|
106
|
+
const nextDefaultAgent = normalizeNativeOpenCodeAgent(String(config.default_agent || "").trim() || VIBE_PRIMARY_AGENT);
|
|
107
|
+
if (config.default_agent !== nextDefaultAgent) {
|
|
108
|
+
config.default_agent = nextDefaultAgent;
|
|
109
|
+
changed = true;
|
|
110
|
+
}
|
|
111
|
+
for (const slot of ["cheap", "medium", "brain"]) {
|
|
112
|
+
const model = String(trinity?.[slot]?.oc || "").trim();
|
|
113
|
+
const name = VIBE_TIER_AGENT_BY_SLOT[slot];
|
|
114
|
+
if (!model || !name) continue;
|
|
115
|
+
const existing = config.agent[name];
|
|
116
|
+
const next = tierAgent(slot, model, existing);
|
|
117
|
+
if (JSON.stringify(existing || null) !== JSON.stringify(next)) {
|
|
118
|
+
config.agent[name] = next;
|
|
119
|
+
changed = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return changed;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// scripts/lib/plugin-config.mjs
|
|
126
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
127
|
+
import { resolve } from "node:path";
|
|
128
|
+
function resolveVibeOSPluginRef(home) {
|
|
129
|
+
return resolve(home, "plugins", "vibeOS.js");
|
|
130
|
+
}
|
|
131
|
+
function normalizeVibeOSPluginRefs(pluginList, canonicalPluginRef) {
|
|
132
|
+
const refs = Array.isArray(pluginList) ? pluginList : [];
|
|
133
|
+
const kept = [];
|
|
134
|
+
let hasCanonical = false;
|
|
135
|
+
for (const ref of refs) {
|
|
136
|
+
if (typeof ref !== "string") {
|
|
137
|
+
kept.push(ref);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (!ref.includes("vibeOS")) {
|
|
141
|
+
kept.push(ref);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const normalized = resolve(ref);
|
|
145
|
+
if (normalized === canonicalPluginRef || ref === canonicalPluginRef) {
|
|
146
|
+
if (!hasCanonical) {
|
|
147
|
+
hasCanonical = true;
|
|
148
|
+
kept.push(canonicalPluginRef);
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (existsSync2(normalized)) continue;
|
|
153
|
+
}
|
|
154
|
+
if (!hasCanonical) kept.push(canonicalPluginRef);
|
|
155
|
+
return kept;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/bin/setup.ts
|
|
159
|
+
var __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
160
|
+
var root = resolve2(__dirname, "..");
|
|
161
|
+
var args = process.argv.slice(2);
|
|
162
|
+
var command = args.find((a) => !a.startsWith("-")) ?? "setup";
|
|
163
|
+
var isInstallCommand = command === "setup" || command === "set";
|
|
164
|
+
var isProject = args.includes("--project");
|
|
165
|
+
var writeLine = (text = "") => {
|
|
166
|
+
process.stdout.write(text + "\n");
|
|
167
|
+
};
|
|
17
168
|
if (!isInstallCommand || args.includes("--help") || args.includes("-h")) {
|
|
18
169
|
console.error("Usage: npx vibeostheog set [--project]");
|
|
19
170
|
console.error(" npx vibeostheog setup [--project]");
|
|
20
171
|
process.exit(1);
|
|
21
172
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Deploy plugin files to ~/.config/opencode/plugins/ and register globally
|
|
31
|
-
const deployScript = resolve(root, "scripts", "deploy.mjs");
|
|
32
|
-
if (!existsSync(deployScript)) {
|
|
173
|
+
writeLine();
|
|
174
|
+
writeLine("vibeOS \u2014 cost-aware delegation enforcer for OpenCode");
|
|
175
|
+
writeLine();
|
|
176
|
+
writeLine("Installing to:");
|
|
177
|
+
for (const h of resolveOpenCodeHomes({ cwd: process.cwd() })) writeLine(" " + h);
|
|
178
|
+
writeLine();
|
|
179
|
+
var deployScript = resolve2(root, "scripts", "deploy.mjs");
|
|
180
|
+
if (!existsSync3(deployScript)) {
|
|
33
181
|
console.error("Fatal: scripts/deploy.mjs not found at", deployScript);
|
|
34
182
|
process.exit(1);
|
|
35
183
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// For per-project setup, also register in project-level opencode.json
|
|
184
|
+
execFileSync(process.execPath, [deployScript], { stdio: "inherit", cwd: process.cwd() });
|
|
39
185
|
if (isProject) {
|
|
40
|
-
const configPath =
|
|
186
|
+
const configPath = resolve2(process.cwd(), "opencode.json");
|
|
41
187
|
let config = {};
|
|
42
|
-
if (
|
|
188
|
+
if (existsSync3(configPath)) {
|
|
43
189
|
try {
|
|
44
|
-
config = JSON.parse(
|
|
190
|
+
config = JSON.parse(readFileSync2(configPath, "utf8"));
|
|
45
191
|
} catch {
|
|
46
192
|
config = {};
|
|
47
193
|
}
|
|
@@ -50,15 +196,14 @@ if (isProject) {
|
|
|
50
196
|
if (!config.$schema) config.$schema = "https://opencode.ai/config.json";
|
|
51
197
|
if (!Array.isArray(config.plugin)) config.plugin = [];
|
|
52
198
|
const installHome = resolveOpenCodeHome({ cwd: process.cwd() });
|
|
53
|
-
const pluginRef =
|
|
54
|
-
config.plugin = config.plugin
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
199
|
+
const pluginRef = resolveVibeOSPluginRef(installHome);
|
|
200
|
+
config.plugin = normalizeVibeOSPluginRefs(config.plugin, pluginRef);
|
|
201
|
+
installVibeTierAgentsInConfig(config);
|
|
202
|
+
mkdirSync2(dirname2(configPath), { recursive: true });
|
|
203
|
+
const tmp = `${configPath}.tmp.${process.pid}.${Date.now()}`;
|
|
204
|
+
writeFileSync2(tmp, JSON.stringify(config, null, 2) + "\n");
|
|
205
|
+
renameSync2(tmp, configPath);
|
|
206
|
+
writeLine(`vibeOS registered in ${configPath}`);
|
|
61
207
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
console.log("Done. Restart OpenCode to activate the plugin.");
|
|
208
|
+
writeLine();
|
|
209
|
+
writeLine("Done. Restart OpenCode to activate the plugin.");
|