feat(extensions): support async extension factory functions

Extensions can now use async initialization, enabling:
- Dynamic imports (e.g., loading tools from external packages)
- Async setup (config fetching, service connections)
- Lazy-loaded dependencies

Changes:
- ExtensionFactory type now returns void | Promise<void>
- loadExtensionFromFactory is now async, returns Promise<LoadedExtension>
- All factory(api) calls are now awaited

Backwards compatible: sync extensions continue to work unchanged.
This commit is contained in:
Austin Mudd 2026-01-06 14:35:43 -08:00
parent 282273e156
commit aea9f8439d
3 changed files with 8 additions and 8 deletions

View file

@ -313,7 +313,7 @@ async function loadExtensionWithBun(
setFlagValue,
} = createExtensionAPI(handlers, tools, cwd, extensionPath, eventBus, sharedUI);
factory(api);
await factory(api);
return {
extension: {
@ -401,7 +401,7 @@ async function loadExtension(
setFlagValue,
} = createExtensionAPI(handlers, tools, cwd, extensionPath, eventBus, sharedUI);
factory(api);
await factory(api);
return {
extension: {
@ -436,13 +436,13 @@ async function loadExtension(
/**
* Create a LoadedExtension from an inline factory function.
*/
export function loadExtensionFromFactory(
export async function loadExtensionFromFactory(
factory: ExtensionFactory,
cwd: string,
eventBus: EventBus,
sharedUI: { ui: ExtensionUIContext; hasUI: boolean },
name = "<inline>",
): LoadedExtension {
): Promise<LoadedExtension> {
const handlers = new Map<string, HandlerFn[]>();
const tools = new Map<string, RegisteredTool>();
const {
@ -464,7 +464,7 @@ export function loadExtensionFromFactory(
setFlagValue,
} = createExtensionAPI(handlers, tools, cwd, name, eventBus, sharedUI);
factory(api);
await factory(api);
return {
path: name,