fix(cli): missing plugin deps cause TUI to black screen (#14432)
This commit is contained in:
@@ -292,7 +292,9 @@ export namespace Config {
|
|||||||
...(proxied() ? ["--no-cache"] : []),
|
...(proxied() ? ["--no-cache"] : []),
|
||||||
],
|
],
|
||||||
{ cwd: dir },
|
{ cwd: dir },
|
||||||
).catch(() => {})
|
).catch((err) => {
|
||||||
|
log.warn("failed to install dependencies", { dir, error: err })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isWritable(dir: string) {
|
async function isWritable(dir: string) {
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ export namespace Plugin {
|
|||||||
|
|
||||||
for (const plugin of INTERNAL_PLUGINS) {
|
for (const plugin of INTERNAL_PLUGINS) {
|
||||||
log.info("loading internal plugin", { name: plugin.name })
|
log.info("loading internal plugin", { name: plugin.name })
|
||||||
const init = await plugin(input)
|
const init = await plugin(input).catch((err) => {
|
||||||
hooks.push(init)
|
log.error("failed to load internal plugin", { name: plugin.name, error: err })
|
||||||
|
})
|
||||||
|
if (init) hooks.push(init)
|
||||||
}
|
}
|
||||||
|
|
||||||
let plugins = config.plugin ?? []
|
let plugins = config.plugin ?? []
|
||||||
@@ -59,37 +61,40 @@ export namespace Plugin {
|
|||||||
const lastAtIndex = plugin.lastIndexOf("@")
|
const lastAtIndex = plugin.lastIndexOf("@")
|
||||||
const pkg = lastAtIndex > 0 ? plugin.substring(0, lastAtIndex) : plugin
|
const pkg = lastAtIndex > 0 ? plugin.substring(0, lastAtIndex) : plugin
|
||||||
const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : "latest"
|
const version = lastAtIndex > 0 ? plugin.substring(lastAtIndex + 1) : "latest"
|
||||||
const builtin = BUILTIN.some((x) => x.startsWith(pkg + "@"))
|
|
||||||
plugin = await BunProc.install(pkg, version).catch((err) => {
|
plugin = await BunProc.install(pkg, version).catch((err) => {
|
||||||
if (!builtin) throw err
|
const cause = err instanceof Error ? err.cause : err
|
||||||
|
const detail = cause instanceof Error ? cause.message : String(cause ?? err)
|
||||||
const message = err instanceof Error ? err.message : String(err)
|
log.error("failed to install plugin", { pkg, version, error: detail })
|
||||||
log.error("failed to install builtin plugin", {
|
|
||||||
pkg,
|
|
||||||
version,
|
|
||||||
error: message,
|
|
||||||
})
|
|
||||||
Bus.publish(Session.Event.Error, {
|
Bus.publish(Session.Event.Error, {
|
||||||
error: new NamedError.Unknown({
|
error: new NamedError.Unknown({
|
||||||
message: `Failed to install built-in plugin ${pkg}@${version}: ${message}`,
|
message: `Failed to install plugin ${pkg}@${version}: ${detail}`,
|
||||||
}).toObject(),
|
}).toObject(),
|
||||||
})
|
})
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
})
|
})
|
||||||
if (!plugin) continue
|
if (!plugin) continue
|
||||||
}
|
}
|
||||||
const mod = await import(plugin)
|
|
||||||
// Prevent duplicate initialization when plugins export the same function
|
// Prevent duplicate initialization when plugins export the same function
|
||||||
// as both a named export and default export (e.g., `export const X` and `export default X`).
|
// as both a named export and default export (e.g., `export const X` and `export default X`).
|
||||||
// Object.entries(mod) would return both entries pointing to the same function reference.
|
// Object.entries(mod) would return both entries pointing to the same function reference.
|
||||||
const seen = new Set<PluginInstance>()
|
await import(plugin)
|
||||||
for (const [_name, fn] of Object.entries<PluginInstance>(mod)) {
|
.then(async (mod) => {
|
||||||
if (seen.has(fn)) continue
|
const seen = new Set<PluginInstance>()
|
||||||
seen.add(fn)
|
for (const [_name, fn] of Object.entries<PluginInstance>(mod)) {
|
||||||
const init = await fn(input)
|
if (seen.has(fn)) continue
|
||||||
hooks.push(init)
|
seen.add(fn)
|
||||||
}
|
hooks.push(await fn(input))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const message = err instanceof Error ? err.message : String(err)
|
||||||
|
log.error("failed to load plugin", { path: plugin, error: message })
|
||||||
|
Bus.publish(Session.Event.Error, {
|
||||||
|
error: new NamedError.Unknown({
|
||||||
|
message: `Failed to load plugin ${plugin}: ${message}`,
|
||||||
|
}).toObject(),
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user