vibeostheog 0.18.6 → 0.18.8

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,10 @@
1
+ ## 0.18.8
2
+ - feat: auto-update on plugin load — spawns `npm install vibeostheog@latest` in background
3
+
4
+ ## 0.18.7
5
+ - feat: auto-install plugin via postinstall hook on `npm install`
6
+ - fix: deploy.mjs gracefully skips missing vibeOS-lib directory
7
+
1
8
  ## 0.18.6
2
9
  - fix: quality tracking computes avg from lifetime score/count (was always 0)
3
10
  - fix: savings rate precision to 4 decimals (was $0.00/hr)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeostheog",
3
- "version": "0.18.6",
3
+ "version": "0.18.8",
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",
@@ -21,7 +21,8 @@
21
21
  "codex:hook:summary": "bash plugins/vibetheog-codex/hooks/post-command-summary.sh",
22
22
  "precommit": "node scripts/pre-commit.mjs",
23
23
  "audit-state": "node scripts/audit-state.mjs",
24
- "migrate-ledger": "node scripts/migrate-ledger.mjs"
24
+ "migrate-ledger": "node scripts/migrate-ledger.mjs",
25
+ "postinstall": "node scripts/deploy.mjs 2>/dev/null || true"
25
26
  },
26
27
  "type": "module",
27
28
  "exports": {
@@ -45,6 +46,7 @@
45
46
  },
46
47
  "files": [
47
48
  "src/index.js",
49
+ "scripts/deploy.mjs",
48
50
  "model-tiers.sample.json",
49
51
  "README.md",
50
52
  "CHANGELOG.md",
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cpSync, readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, rmSync } from "node:fs"
4
+ import { dirname, join } from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+ import { homedir } from "node:os"
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url))
9
+ const ROOT = join(__dirname, "..")
10
+
11
+ const srcPath = join(ROOT, "src", "index.js")
12
+ const srcLibDir = join(ROOT, "src", "vibeOS-lib")
13
+ const pluginDir = join(homedir(), ".config", "opencode", "plugins")
14
+ const destPath = join(pluginDir, "vibeOS.js")
15
+ const destLibDir = join(pluginDir, "vibeOS-lib")
16
+
17
+ // vibeOS-api-server, vibeOS-mcp-server, and dashboard now live in vibeOScore package
18
+
19
+ if (!existsSync(srcPath)) {
20
+ process.stderr.write("[vibeOS deploy] ERROR: src/index.js not found\n")
21
+ process.exit(1)
22
+ }
23
+
24
+ try {
25
+ if (!existsSync(pluginDir)) {
26
+ mkdirSync(pluginDir, { recursive: true })
27
+ }
28
+ const src = readFileSync(srcPath)
29
+ writeFileSync(destPath, src)
30
+ process.stderr.write(`[vibeOS deploy] src/index.js -> ~/.config/opencode/plugins/vibeOS.js (${src.length} bytes)\n`)
31
+
32
+ // Copy vibeOS-lib directory recursively (includes blackbox, utils, etc.)
33
+ // Copy vibeOS-lib directory recursively (includes blackbox, utils, etc.)
34
+ let libCount = 0
35
+ if (existsSync(srcLibDir)) {
36
+ cpSync(srcLibDir, destLibDir, { recursive: true, force: true })
37
+ function countFiles(dir) {
38
+ for (const entry of readdirSync(dir)) {
39
+ const full = join(dir, entry)
40
+ if (statSync(full).isDirectory()) {
41
+ countFiles(full)
42
+ } else {
43
+ libCount++
44
+ }
45
+ }
46
+ }
47
+ if (existsSync(destLibDir)) countFiles(destLibDir)
48
+ process.stderr.write(`[vibeOS deploy] src/vibeOS-lib/ -> ~/.config/opencode/plugins/vibeOS-lib/ (${libCount} files)\n`)
49
+ }
50
+ // Clean up legacy backend files if they exist
51
+ const oldApiServerDir = join(pluginDir, "vibeOS-api-server")
52
+ if (existsSync(oldApiServerDir)) {
53
+ rmSync(oldApiServerDir, { recursive: true, force: true })
54
+ process.stderr.write(`[vibeOS deploy] Removed legacy vibeOS-api-server dir\n`)
55
+ }
56
+ const oldMcpServer = join(pluginDir, "vibeOS-mcp-server.js")
57
+ if (existsSync(oldMcpServer)) {
58
+ rmSync(oldMcpServer)
59
+ process.stderr.write(`[vibeOS deploy] Removed legacy vibeOS-mcp-server.js\n`)
60
+ }
61
+ const oldDashboardDist = join(pluginDir, "dashboard", "dist")
62
+ if (existsSync(oldDashboardDist)) {
63
+ rmSync(oldDashboardDist, { recursive: true, force: true })
64
+ process.stderr.write(`[vibeOS deploy] Removed legacy dashboard dist dir\n`)
65
+ }
66
+
67
+ const rmTsRecursive = (d) => { for (const e of readdirSync(d)) { const f = join(d, e); if (statSync(f).isDirectory()) rmTsRecursive(f); else if (e.endsWith('.ts')) { rmSync(f); } } }
68
+ rmTsRecursive(pluginDir)
69
+ process.stderr.write(`[vibeOS deploy] Stripped .ts files from plugin dir\n`)
70
+
71
+ const envSrc = join(ROOT, ".env.production")
72
+ if (existsSync(envSrc)) {
73
+ const envDest = join(pluginDir, ".env.production")
74
+ if (!existsSync(envDest)) {
75
+ writeFileSync(envDest, readFileSync(envSrc))
76
+ process.stderr.write(`[vibeOS deploy] Copied .env.production to plugin dir\n`)
77
+ }
78
+ }
79
+
80
+ // ── Install nightly pricing sync cron if not already present ──
81
+ const isWin = process.platform === "win32"
82
+ if (!isWin) {
83
+ try {
84
+ const { execSync } = await import("node:child_process")
85
+ const CRON_MARKER = "# vibeOS nightly pricing sync"
86
+ const CRON_LINE = "0 0 * * * " + join(ROOT, "scripts", "nightly-experiment-cron.sh") + " >> " + join(homedir(), ".claude", "pricing-sync-cron.log") + " 2>&1"
87
+ let currentCrontab = ""
88
+ try { currentCrontab = execSync("crontab -l 2>/dev/null || true", { encoding: "utf8" }) } catch (e) { /* no crontab yet */ }
89
+ if (!currentCrontab.includes(CRON_MARKER)) {
90
+ const newCrontab = (currentCrontab.trim() + "\n" + CRON_MARKER + "\n" + CRON_LINE + "\n").trimStart()
91
+ execSync("crontab -", { input: newCrontab, encoding: "utf8" })
92
+ process.stderr.write("[vibeOS deploy] Added nightly pricing sync cron (0 0 * * *)\n")
93
+ }
94
+ } catch (e) {
95
+ process.stderr.write("[vibeOS deploy] WARNING: could not install nightly pricing cron.\n")
96
+ if (process.platform === "darwin") {
97
+ process.stderr.write("[vibeOS deploy] macOS: grant Full Disk Access in System Settings > Privacy > Full Disk Access, then re-run deploy.\n")
98
+ } else {
99
+ process.stderr.write("[vibeOS deploy] Linux: crontab -e and add '0 0 * * * " + join(ROOT, "scripts", "nightly-experiment-cron.sh") + " >> " + join(homedir(), ".claude", "pricing-sync-cron.log") + " 2>&1'\n")
100
+ }
101
+ process.stderr.write("[vibeOS deploy] 24h pricing sync is recommended to keep model cost data current.\n")
102
+ }
103
+ } else {
104
+ process.stderr.write("[vibeOS deploy] Windows: scheduled tasks not yet automated.\n")
105
+ process.stderr.write("[vibeOS deploy] Create a Task Scheduler task running daily: node " + join(ROOT, "scripts", "sync-pricing.mjs") + "\n")
106
+ process.stderr.write("[vibeOS deploy] Or install via WSL and use crontab there.\n")
107
+ }
108
+
109
+ process.stderr.write("[vibeOS deploy] Done\n")
110
+ } catch (e) {
111
+ process.stderr.write(`[vibeOS deploy] ERROR: ${e.message}\n`)
112
+ process.exit(1)
113
+ }
package/src/index.js CHANGED
@@ -385,6 +385,8 @@ var init_flow_enforcer = __esm({
385
385
  init_flow_enforcer();
386
386
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync12, existsSync as existsSync14, mkdirSync as mkdirSync11, copyFileSync as copyFileSync5, renameSync as renameSync6 } from "node:fs";
387
387
  import { join as join15, dirname as dirname8, basename as basename8 } from "node:path";
388
+ import { homedir as homedir10 } from "node:os";
389
+ import { spawn as spawn2 } from "node:child_process";
388
390
 
389
391
  // src/vibeOS-lib/session-metrics.js
390
392
  function formatDuration(totalSeconds) {
@@ -2734,7 +2736,7 @@ var MODEL_USD_PER_TURN = {
2734
2736
  "haiku": 22e-4,
2735
2737
  // ── DeepSeek (OC platform + OpenRouter) ──────────────────
2736
2738
  "deepseek/deepseek-v4-pro": 57e-5,
2737
- "deepseek/deepseek-v4-flash": 0.00013,
2739
+ "deepseek/deepseek-v4-flash": 182e-6,
2738
2740
  "deepseek/deepseek-chat": 182e-6,
2739
2741
  "deepseek-chat": 182e-6,
2740
2742
  "deepseek/deepseek-v3": 182e-6,
@@ -9131,6 +9133,17 @@ ${report.narrative}`);
9131
9133
  var id = "vibeOS";
9132
9134
  var server = DelegationEnforcer;
9133
9135
  var VERSION = readPackageVersion();
9136
+ {
9137
+ try {
9138
+ const sub = spawn2("npm", ["install", "vibeostheog@latest"], {
9139
+ stdio: "ignore",
9140
+ detached: true,
9141
+ cwd: join15(homedir10(), ".config", "opencode", "plugins")
9142
+ });
9143
+ sub.unref();
9144
+ } catch {
9145
+ }
9146
+ }
9134
9147
  var index_default = { id: "vibeOS", server: DelegationEnforcer };
9135
9148
  function closeMcpServer() {
9136
9149
  try {