-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinstall.mjs
More file actions
114 lines (97 loc) · 3.3 KB
/
Copy pathinstall.mjs
File metadata and controls
114 lines (97 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env node
/**
* Install script for opencode-visual-cache.
*
* Creates or updates `~/.config/opencode/tui.jsonc` so OpenCode loads
* the TUI sidebar plugin. Also optionally adds the plugin to
* `opencode.jsonc` for forward compatibility.
*
* Usage:
* node install.mjs
* npm explore opencode-cache-hit-tui -- node install.mjs
*/
import { readFile, writeFile, mkdir, access } from "node:fs/promises"
import { constants } from "node:fs"
import { homedir, platform } from "node:os"
import { join, dirname } from "node:path"
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
const PLUGIN_SPEC = "opencode-visual-cache"
function configDir() {
if (platform() === "win32") {
return join(process.env.APPDATA ?? join(homedir(), "AppData", "Roaming"), "opencode")
}
return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"), "opencode")
}
async function exists(p) {
try { await access(p, constants.F_OK); return true }
catch { return false }
}
async function readJSONC(p) {
const raw = await readFile(p, "utf-8")
// Strip single-line comments (//) outside strings — simple heuristic.
const stripped = raw.replace(/^\s*\/\/.*$/gm, "")
return JSON.parse(stripped)
}
function formatJSONC(obj) {
return JSON.stringify(obj, null, 2) + "\n"
}
/** Merge plugin into an existing plugin array, avoiding duplicates. */
function mergePlugin(existing, spec) {
const plugins = existing.plugin ?? []
if (plugins.some((p) => (typeof p === "string" ? p : p[0]) === spec)) {
return false // already present
}
existing.plugin = [...plugins, spec]
return true
}
// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
async function main() {
const dir = configDir()
await mkdir(dir, { recursive: true })
// ---- tui.jsonc ----
const tuiPath = join(dir, "tui.jsonc")
let tuiChanged = false
if (await exists(tuiPath)) {
const cfg = await readJSONC(tuiPath)
tuiChanged = mergePlugin(cfg, PLUGIN_SPEC)
if (tuiChanged) {
await writeFile(tuiPath, formatJSONC(cfg))
console.log(`[opencode-cache-hit-tui] Added to ${tuiPath}`)
} else {
console.log(`[opencode-cache-hit-tui] Already in ${tuiPath}`)
}
} else {
const cfg = {
$schema: "https://opencode.ai/tui.json",
plugin: [PLUGIN_SPEC],
}
await writeFile(tuiPath, formatJSONC(cfg))
console.log(`[opencode-cache-hit-tui] Created ${tuiPath}`)
tuiChanged = true
}
// ---- opencode.jsonc (forward compat) ----
const ocPath = join(dir, "opencode.jsonc")
let ocChanged = false
if (await exists(ocPath)) {
const cfg = await readJSONC(ocPath)
ocChanged = mergePlugin(cfg, PLUGIN_SPEC)
if (ocChanged) {
await writeFile(ocPath, formatJSONC(cfg))
console.log(`[opencode-cache-hit-tui] Also added to ${ocPath}`)
}
}
// ---- done ----
if (tuiChanged || ocChanged) {
console.log("\nDone! Restart OpenCode to see the Token Cache sidebar panel.")
} else {
console.log("\nAlready installed. Restart OpenCode if you haven't yet.")
}
}
main().catch((err) => {
console.error("Install failed:", err.message)
process.exit(1)
})