|
|
@@ -28,6 +28,7 @@ import { existsSync } from "fs"
|
|
|
import { Bus } from "@/bus"
|
|
|
import { GlobalBus } from "@/bus/global"
|
|
|
import { Event } from "../server/event"
|
|
|
+import { PackageRegistry } from "@/bun/registry"
|
|
|
|
|
|
export namespace Config {
|
|
|
const log = Log.create({ service: "config" })
|
|
|
@@ -154,9 +155,10 @@ export namespace Config {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- const exists = existsSync(path.join(dir, "node_modules"))
|
|
|
- const installing = installDependencies(dir)
|
|
|
- if (!exists) await installing
|
|
|
+ const shouldInstall = await needsInstall(dir)
|
|
|
+ if (shouldInstall) {
|
|
|
+ await installDependencies(dir)
|
|
|
+ }
|
|
|
|
|
|
result.command = mergeDeep(result.command ?? {}, await loadCommand(dir))
|
|
|
result.agent = mergeDeep(result.agent, await loadAgent(dir))
|
|
|
@@ -235,6 +237,7 @@ export namespace Config {
|
|
|
|
|
|
export async function installDependencies(dir: string) {
|
|
|
const pkg = path.join(dir, "package.json")
|
|
|
+ const targetVersion = Installation.isLocal() ? "latest" : Installation.VERSION
|
|
|
|
|
|
if (!(await Bun.file(pkg).exists())) {
|
|
|
await Bun.write(pkg, "{}")
|
|
|
@@ -244,18 +247,43 @@ export namespace Config {
|
|
|
const hasGitIgnore = await Bun.file(gitignore).exists()
|
|
|
if (!hasGitIgnore) await Bun.write(gitignore, ["node_modules", "package.json", "bun.lock", ".gitignore"].join("\n"))
|
|
|
|
|
|
- await BunProc.run(
|
|
|
- ["add", "@opencode-ai/plugin@" + (Installation.isLocal() ? "latest" : Installation.VERSION), "--exact"],
|
|
|
- {
|
|
|
- cwd: dir,
|
|
|
- },
|
|
|
- ).catch(() => {})
|
|
|
+ await BunProc.run(["add", `@opencode-ai/plugin@${targetVersion}`, "--exact"], {
|
|
|
+ cwd: dir,
|
|
|
+ }).catch(() => {})
|
|
|
|
|
|
// Install any additional dependencies defined in the package.json
|
|
|
// This allows local plugins and custom tools to use external packages
|
|
|
await BunProc.run(["install"], { cwd: dir }).catch(() => {})
|
|
|
}
|
|
|
|
|
|
+ async function needsInstall(dir: string) {
|
|
|
+ const nodeModules = path.join(dir, "node_modules")
|
|
|
+ if (!existsSync(nodeModules)) return true
|
|
|
+
|
|
|
+ const pkg = path.join(dir, "package.json")
|
|
|
+ const pkgFile = Bun.file(pkg)
|
|
|
+ const pkgExists = await pkgFile.exists()
|
|
|
+ if (!pkgExists) return true
|
|
|
+
|
|
|
+ const parsed = await pkgFile.json().catch(() => null)
|
|
|
+ const dependencies = parsed?.dependencies ?? {}
|
|
|
+ const depVersion = dependencies["@opencode-ai/plugin"]
|
|
|
+ if (!depVersion) return true
|
|
|
+
|
|
|
+ const targetVersion = Installation.isLocal() ? "latest" : Installation.VERSION
|
|
|
+ if (targetVersion === "latest") {
|
|
|
+ const isOutdated = await PackageRegistry.isOutdated("@opencode-ai/plugin", depVersion, dir)
|
|
|
+ if (!isOutdated) return false
|
|
|
+ log.info("Cached version is outdated, proceeding with install", {
|
|
|
+ pkg: "@opencode-ai/plugin",
|
|
|
+ cachedVersion: depVersion,
|
|
|
+ })
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if (depVersion === targetVersion) return false
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
function rel(item: string, patterns: string[]) {
|
|
|
for (const pattern of patterns) {
|
|
|
const index = item.indexOf(pattern)
|