Skip to content

Commit 87fdbb8

Browse files
committed
chore(tui): add host runtime linking dev script
1 parent e4d92a8 commit 87fdbb8

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"prepublishOnly": "npm run build",
1313
"dev": "opencode plugin dev",
1414
"typecheck": "tsc --noEmit",
15+
"tui:link-host-runtime": "node scripts/link-tui-host-runtime.mjs",
1516
"test": "node --import tsx --test tests/*.test.ts",
1617
"format": "prettier --write .",
1718
"format:check": "prettier --check .",

scripts/link-tui-host-runtime.mjs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import fs from "node:fs"
2+
import path from "node:path"
3+
import { createRequire } from "node:module"
4+
5+
const repoRoot = path.resolve(import.meta.dirname, "..")
6+
const tuiNodeModules = path.join(repoRoot, "tui", "node_modules")
7+
const hostRoot = path.resolve(
8+
process.argv[2] ?? process.env.OPENCODE_SOURCE_ROOT ?? "/home/dan/src/opencode",
9+
)
10+
const hostEntry = path.join(hostRoot, "packages", "opencode", "src", "cli", "cmd", "tui", "app.tsx")
11+
const pluginEntry = path.join(repoRoot, "tui", "index.tsx")
12+
13+
if (!fs.existsSync(hostEntry)) {
14+
throw new Error(`OpenCode TUI entry not found: ${hostEntry}`)
15+
}
16+
17+
const hostRequire = createRequire(hostEntry)
18+
const pluginRequire = createRequire(pluginEntry)
19+
20+
const findPackageRoot = (resolvedFile) => {
21+
let current = path.dirname(resolvedFile)
22+
while (true) {
23+
const manifest = path.join(current, "package.json")
24+
if (fs.existsSync(manifest)) return current
25+
const parent = path.dirname(current)
26+
if (parent === current) {
27+
throw new Error(`Could not find package root for ${resolvedFile}`)
28+
}
29+
current = parent
30+
}
31+
}
32+
33+
const resolveHostPackage = (specifier) => findPackageRoot(hostRequire.resolve(specifier))
34+
const resolvePluginPackage = (specifier) => findPackageRoot(pluginRequire.resolve(specifier))
35+
36+
const links = [
37+
{
38+
specifier: "solid-js",
39+
dest: path.join(tuiNodeModules, "solid-js"),
40+
},
41+
{
42+
specifier: "@opentui/solid",
43+
dest: path.join(tuiNodeModules, "@opentui", "solid"),
44+
},
45+
{
46+
specifier: "@opentui/core",
47+
dest: path.join(tuiNodeModules, "@opentui", "core"),
48+
},
49+
]
50+
51+
for (const link of links) {
52+
const target = resolveHostPackage(link.specifier)
53+
fs.mkdirSync(path.dirname(link.dest), { recursive: true })
54+
fs.rmSync(link.dest, { recursive: true, force: true })
55+
fs.symlinkSync(target, link.dest, "dir")
56+
57+
const pluginResolved = resolvePluginPackage(link.specifier)
58+
const pluginReal = fs.realpathSync.native(pluginResolved)
59+
const targetReal = fs.realpathSync.native(target)
60+
if (pluginReal !== targetReal) {
61+
throw new Error(`Failed to link ${link.specifier}: ${pluginReal} != ${targetReal}`)
62+
}
63+
64+
console.log(`linked ${link.specifier}`)
65+
console.log(` host: ${targetReal}`)
66+
console.log(` plugin: ${pluginReal}`)
67+
}

0 commit comments

Comments
 (0)