refactor: unwrap TuiPluginRuntime namespace + self-reexport (#22980)
This commit is contained in:
@@ -918,113 +918,113 @@ async function installPluginBySpec(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace TuiPluginRuntime {
|
let dir = ""
|
||||||
let dir = ""
|
let loaded: Promise<void> | undefined
|
||||||
let loaded: Promise<void> | undefined
|
let runtime: RuntimeState | undefined
|
||||||
let runtime: RuntimeState | undefined
|
export const Slot = View
|
||||||
export const Slot = View
|
|
||||||
|
|
||||||
export async function init(input: { api: HostPluginApi; config: TuiConfig.Info }) {
|
export async function init(input: { api: HostPluginApi; config: TuiConfig.Info }) {
|
||||||
const cwd = process.cwd()
|
const cwd = process.cwd()
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
if (dir !== cwd) {
|
if (dir !== cwd) {
|
||||||
throw new Error(`TuiPluginRuntime.init() called with a different working directory. expected=${dir} got=${cwd}`)
|
throw new Error(`TuiPluginRuntime.init() called with a different working directory. expected=${dir} got=${cwd}`)
|
||||||
}
|
|
||||||
return loaded
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = cwd
|
|
||||||
loaded = load(input)
|
|
||||||
return loaded
|
return loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
export function list() {
|
dir = cwd
|
||||||
if (!runtime) return []
|
loaded = load(input)
|
||||||
return listPluginStatus(runtime)
|
return loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function activatePlugin(id: string) {
|
export function list() {
|
||||||
return activatePluginById(runtime, id, true)
|
if (!runtime) return []
|
||||||
}
|
return listPluginStatus(runtime)
|
||||||
|
}
|
||||||
|
|
||||||
export async function deactivatePlugin(id: string) {
|
export async function activatePlugin(id: string) {
|
||||||
return deactivatePluginById(runtime, id, true)
|
return activatePluginById(runtime, id, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addPlugin(spec: string) {
|
export async function deactivatePlugin(id: string) {
|
||||||
return addPluginBySpec(runtime, spec)
|
return deactivatePluginById(runtime, id, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function installPlugin(spec: string, options?: { global?: boolean }) {
|
export async function addPlugin(spec: string) {
|
||||||
return installPluginBySpec(runtime, spec, options?.global)
|
return addPluginBySpec(runtime, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function dispose() {
|
export async function installPlugin(spec: string, options?: { global?: boolean }) {
|
||||||
const task = loaded
|
return installPluginBySpec(runtime, spec, options?.global)
|
||||||
loaded = undefined
|
}
|
||||||
dir = ""
|
|
||||||
if (task) await task
|
|
||||||
const state = runtime
|
|
||||||
runtime = undefined
|
|
||||||
if (!state) return
|
|
||||||
const queue = [...state.plugins].reverse()
|
|
||||||
for (const plugin of queue) {
|
|
||||||
await deactivatePluginEntry(state, plugin, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function load(input: { api: Api; config: TuiConfig.Info }) {
|
export async function dispose() {
|
||||||
const { api, config } = input
|
const task = loaded
|
||||||
const cwd = process.cwd()
|
loaded = undefined
|
||||||
const slots = setupSlots(api)
|
dir = ""
|
||||||
const next: RuntimeState = {
|
if (task) await task
|
||||||
directory: cwd,
|
const state = runtime
|
||||||
api,
|
runtime = undefined
|
||||||
slots,
|
if (!state) return
|
||||||
plugins: [],
|
const queue = [...state.plugins].reverse()
|
||||||
plugins_by_id: new Map(),
|
for (const plugin of queue) {
|
||||||
pending: new Map(),
|
await deactivatePluginEntry(state, plugin, false)
|
||||||
}
|
|
||||||
runtime = next
|
|
||||||
try {
|
|
||||||
await Instance.provide({
|
|
||||||
directory: cwd,
|
|
||||||
fn: async () => {
|
|
||||||
const records = Flag.OPENCODE_PURE ? [] : (config.plugin_origins ?? [])
|
|
||||||
if (Flag.OPENCODE_PURE && config.plugin_origins?.length) {
|
|
||||||
log.info("skipping external tui plugins in pure mode", { count: config.plugin_origins.length })
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const item of INTERNAL_TUI_PLUGINS) {
|
|
||||||
log.info("loading internal tui plugin", { id: item.id })
|
|
||||||
const entry = loadInternalPlugin(item)
|
|
||||||
const meta = createMeta(entry.source, entry.spec, entry.target, undefined, entry.id)
|
|
||||||
addPluginEntry(next, {
|
|
||||||
id: entry.id,
|
|
||||||
load: entry,
|
|
||||||
meta,
|
|
||||||
themes: {},
|
|
||||||
plugin: entry.module.tui,
|
|
||||||
enabled: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const ready = await resolveExternalPlugins(records, () => TuiConfig.waitForDependencies())
|
|
||||||
await addExternalPluginEntries(next, ready)
|
|
||||||
|
|
||||||
applyInitialPluginEnabledState(next, config)
|
|
||||||
for (const plugin of next.plugins) {
|
|
||||||
if (!plugin.enabled) continue
|
|
||||||
// Keep plugin execution sequential for deterministic side effects:
|
|
||||||
// command registration order affects keybind/command precedence,
|
|
||||||
// route registration is last-wins when ids collide,
|
|
||||||
// and hook chains rely on stable plugin ordering.
|
|
||||||
await activatePluginEntry(next, plugin, false)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
fail("failed to load tui plugins", { directory: cwd, error })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function load(input: { api: Api; config: TuiConfig.Info }) {
|
||||||
|
const { api, config } = input
|
||||||
|
const cwd = process.cwd()
|
||||||
|
const slots = setupSlots(api)
|
||||||
|
const next: RuntimeState = {
|
||||||
|
directory: cwd,
|
||||||
|
api,
|
||||||
|
slots,
|
||||||
|
plugins: [],
|
||||||
|
plugins_by_id: new Map(),
|
||||||
|
pending: new Map(),
|
||||||
|
}
|
||||||
|
runtime = next
|
||||||
|
try {
|
||||||
|
await Instance.provide({
|
||||||
|
directory: cwd,
|
||||||
|
fn: async () => {
|
||||||
|
const records = Flag.OPENCODE_PURE ? [] : (config.plugin_origins ?? [])
|
||||||
|
if (Flag.OPENCODE_PURE && config.plugin_origins?.length) {
|
||||||
|
log.info("skipping external tui plugins in pure mode", { count: config.plugin_origins.length })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of INTERNAL_TUI_PLUGINS) {
|
||||||
|
log.info("loading internal tui plugin", { id: item.id })
|
||||||
|
const entry = loadInternalPlugin(item)
|
||||||
|
const meta = createMeta(entry.source, entry.spec, entry.target, undefined, entry.id)
|
||||||
|
addPluginEntry(next, {
|
||||||
|
id: entry.id,
|
||||||
|
load: entry,
|
||||||
|
meta,
|
||||||
|
themes: {},
|
||||||
|
plugin: entry.module.tui,
|
||||||
|
enabled: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const ready = await resolveExternalPlugins(records, () => TuiConfig.waitForDependencies())
|
||||||
|
await addExternalPluginEntries(next, ready)
|
||||||
|
|
||||||
|
applyInitialPluginEnabledState(next, config)
|
||||||
|
for (const plugin of next.plugins) {
|
||||||
|
if (!plugin.enabled) continue
|
||||||
|
// Keep plugin execution sequential for deterministic side effects:
|
||||||
|
// command registration order affects keybind/command precedence,
|
||||||
|
// route registration is last-wins when ids collide,
|
||||||
|
// and hook chains rely on stable plugin ordering.
|
||||||
|
await activatePluginEntry(next, plugin, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
fail("failed to load tui plugins", { directory: cwd, error })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export * as TuiPluginRuntime from "./runtime"
|
||||||
|
|||||||
Reference in New Issue
Block a user