From af84d212feb155f118b2d796115d0181d26a25e6 Mon Sep 17 00:00:00 2001 From: Sebastian Herrlinger Date: Thu, 26 Mar 2026 20:58:32 +0100 Subject: [PATCH] source --- .../src/cli/cmd/tui/plugin/runtime.ts | 23 +++++++++++-------- packages/opencode/src/plugin/meta.ts | 9 ++------ packages/opencode/src/plugin/shared.ts | 10 ++++++-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/plugin/runtime.ts b/packages/opencode/src/cli/cmd/tui/plugin/runtime.ts index 5c1b3a333d..1d80118912 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin/runtime.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin/runtime.ts @@ -20,9 +20,11 @@ import { Instance } from "@/project/instance" import { getDefaultPlugin, isDeprecatedPlugin, + pluginSource, readPluginId, resolvePluginId, resolvePluginTarget, + type PluginSource, } from "@/plugin/shared" import { PluginMeta } from "@/plugin/meta" import { addTheme, hasTheme } from "../context/theme" @@ -38,6 +40,7 @@ type PluginLoad = { spec: string target: string retry: boolean + source: PluginSource | "internal" id: string module: TuiPluginModule install_theme: TuiTheme["install"] @@ -193,7 +196,8 @@ async function loadExternalPlugin( return } - const root = resolveRoot(spec.startsWith("file://") ? spec : target) + const source = pluginSource(spec) + const root = resolveRoot(source === "file" ? spec : target) const install_theme = createThemeInstaller(meta, root, spec) const mod = await import(target) .then((raw) => { @@ -207,7 +211,7 @@ async function loadExternalPlugin( }) if (!mod) return - const id = await resolvePluginId(spec, target, readPluginId(mod.id, spec)).catch((error) => { + const id = await resolvePluginId(source, spec, target, readPluginId(mod.id, spec)).catch((error) => { fail("failed to load tui plugin", { path: spec, target, retry, error }) return }) @@ -218,6 +222,7 @@ async function loadExternalPlugin( spec, target, retry, + source, id, module: mod, install_theme, @@ -225,6 +230,7 @@ async function loadExternalPlugin( } function createMeta( + source: PluginLoad["source"], spec: string, target: string, meta: { state: PluginMeta.State; entry: PluginMeta.Entry } | undefined, @@ -237,13 +243,11 @@ function createMeta( } } - const source = spec.startsWith("internal:") ? "internal" : "npm" - const kind = source === "npm" && spec.startsWith("file://") ? "file" : source const now = Date.now() return { - state: kind === "internal" ? "same" : "first", + state: source === "internal" ? "same" : "first", id: id ?? spec, - source: kind, + source, spec, target, first_time: now, @@ -262,6 +266,7 @@ function loadInternalPlugin(item: InternalTuiPlugin): PluginLoad { spec, target, retry: false, + source: "internal", id: item.id, module: item, install_theme: createThemeInstaller( @@ -630,7 +635,7 @@ export namespace TuiPluginRuntime { for (const item of INTERNAL_TUI_PLUGINS) { log.info("loading internal tui plugin", { id: item.id }) const entry = loadInternalPlugin(item) - const meta = createMeta(entry.spec, entry.target, undefined, entry.id) + const meta = createMeta(entry.source, entry.spec, entry.target, undefined, entry.id) for (const plugin of collectPluginEntries(entry, meta)) { addPluginEntry(next, plugin) } @@ -645,7 +650,7 @@ export namespace TuiPluginRuntime { const item = plugins[i] if (!item) continue const spec = Config.pluginSpecifier(item) - if (!spec.startsWith("file://")) continue + if (pluginSource(spec) !== "file") continue deps.wait ??= TuiConfig.waitForDependencies().catch((error) => { log.warn("failed waiting for tui plugin dependencies", { error }) }) @@ -682,7 +687,7 @@ export namespace TuiPluginRuntime { }) } - const row = createMeta(entry.spec, entry.target, hit, entry.id) + const row = createMeta(entry.source, entry.spec, entry.target, hit, entry.id) for (const plugin of collectPluginEntries(entry, row)) { addPluginEntry(next, plugin) } diff --git a/packages/opencode/src/plugin/meta.ts b/packages/opencode/src/plugin/meta.ts index f3ed2807f9..bf93870cb0 100644 --- a/packages/opencode/src/plugin/meta.ts +++ b/packages/opencode/src/plugin/meta.ts @@ -6,7 +6,7 @@ import { Global } from "@/global" import { Filesystem } from "@/util/filesystem" import { Flock } from "@/util/flock" -import { parsePluginSpecifier } from "./shared" +import { parsePluginSpecifier, pluginSource } from "./shared" export namespace PluginMeta { type Source = "file" | "npm" @@ -46,11 +46,6 @@ export namespace PluginMeta { return `plugin-meta:${file}` } - function sourceKind(spec: string): Source { - if (spec.startsWith("file://")) return "file" - return "npm" - } - function fileTarget(spec: string, target: string) { if (spec.startsWith("file://")) return fileURLToPath(spec) if (target.startsWith("file://")) return fileURLToPath(target) @@ -81,7 +76,7 @@ export namespace PluginMeta { async function entryCore(item: Touch): Promise { const spec = item.spec const target = item.target - const source = sourceKind(spec) + const source = pluginSource(spec) if (source === "file") { const file = fileTarget(spec, target) return { diff --git a/packages/opencode/src/plugin/shared.ts b/packages/opencode/src/plugin/shared.ts index 769a737b8f..55060c7138 100644 --- a/packages/opencode/src/plugin/shared.ts +++ b/packages/opencode/src/plugin/shared.ts @@ -18,6 +18,12 @@ export function parsePluginSpecifier(spec: string) { return { pkg, version } } +export type PluginSource = "file" | "npm" + +export function pluginSource(spec: string): PluginSource { + return spec.startsWith("file://") ? "file" : "npm" +} + export function isPathPluginSpec(spec: string) { return spec.startsWith("file://") || spec.startsWith(".") || path.isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec) } @@ -61,8 +67,8 @@ export function readPluginId(id: unknown, spec: string) { return value } -export async function resolvePluginId(spec: string, target: string, id: string | undefined) { - if (spec.startsWith("file://")) { +export async function resolvePluginId(source: PluginSource, spec: string, target: string, id: string | undefined) { + if (source === "file") { if (id) return id throw new TypeError(`Path plugin ${spec} must export id`) }