From e4f63f585f01a8ff6483cd0b7058acb685cd2768 Mon Sep 17 00:00:00 2001 From: Melih Mucuk Date: Mon, 5 Jan 2026 13:26:41 +0300 Subject: [PATCH 1/3] fix(coding-agent): load extensions from settings.json SettingsManager was created after extension loading, so extensions defined in settings.json were never loaded. Move SettingsManager.create before discoverAndLoadExtensions and merge settings extensions with CLI --extension args. --- packages/coding-agent/src/main.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts index d740b7fa..eaa164cd 100644 --- a/packages/coding-agent/src/main.ts +++ b/packages/coding-agent/src/main.ts @@ -298,7 +298,10 @@ export async function main(args: string[]) { const cwd = process.cwd(); const agentDir = getAgentDir(); const eventBus = createEventBus(); - const extensionPaths = firstPass.extensions ?? []; + const settingsManager = SettingsManager.create(cwd); + time("SettingsManager.create"); + // Merge CLI --extension args with settings.json extensions + const extensionPaths = [...settingsManager.getExtensionPaths(), ...(firstPass.extensions ?? [])]; const { extensions: loadedExtensions } = await discoverAndLoadExtensions(extensionPaths, cwd, agentDir, eventBus); time("discoverExtensionFlags"); @@ -357,8 +360,6 @@ export async function main(args: string[]) { process.exit(1); } - const settingsManager = SettingsManager.create(cwd); - time("SettingsManager.create"); const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize()); time("prepareInitialMessage"); const isInteractive = !parsed.print && parsed.mode === undefined; From 7e829273b0520b4396e963ab9d6770fe6ff95583 Mon Sep 17 00:00:00 2001 From: Melih Mucuk Date: Mon, 5 Jan 2026 13:53:18 +0300 Subject: [PATCH 2/3] docs(coding-agent): add changelog entry for #463 --- packages/coding-agent/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 31353915..d8b730ad 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Extensions defined in `settings.json` were not loaded ([#463](https://github.com/badlogic/pi-mono/pull/463) by [@melihmucuk](https://github.com/melihmucuk)) + ## [0.36.0] - 2026-01-05 ### Added From 3129e2ac10e91979ed34c34acf552e9ca01c1896 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 5 Jan 2026 18:00:32 +0100 Subject: [PATCH 3/3] docs: clarify SDK extension discovery and settings.json support --- packages/coding-agent/docs/sdk.md | 16 ++++++++++++---- packages/coding-agent/src/core/sdk.ts | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/coding-agent/docs/sdk.md b/packages/coding-agent/docs/sdk.md index b1c04d4e..8d62c0f4 100644 --- a/packages/coding-agent/docs/sdk.md +++ b/packages/coding-agent/docs/sdk.md @@ -468,12 +468,15 @@ Custom tools passed via `customTools` are combined with extension-registered too ### Extensions -Extensions are discovered from `~/.pi/agent/extensions/` and `.pi/extensions/`. You can also pass inline extensions or additional paths: +By default, extensions are discovered from multiple locations: +- `~/.pi/agent/extensions/` (global) +- `.pi/extensions/` (project-local) +- Paths listed in `settings.json` `"extensions"` array ```typescript import { createAgentSession, type ExtensionFactory } from "@mariozechner/pi-coding-agent"; -// Inline extension +// Inline extension factory const myExtension: ExtensionFactory = (pi) => { pi.on("tool_call", async (event, ctx) => { console.log(`Tool: ${event.toolName}`); @@ -487,15 +490,20 @@ const myExtension: ExtensionFactory = (pi) => { }); }; -// Pass inline extensions (merged with discovery) +// Pass inline extensions (skips file discovery) const { session } = await createAgentSession({ extensions: [myExtension], }); -// Or add paths to load (merged with discovery) +// Add paths to load (merged with discovery) const { session } = await createAgentSession({ additionalExtensionPaths: ["/path/to/my-extension.ts"], }); + +// Disable extension discovery entirely +const { session } = await createAgentSession({ + extensions: [], +}); ``` Extensions can register tools, subscribe to events, add commands, and more. See [extensions.md](extensions.md) for the full API. diff --git a/packages/coding-agent/src/core/sdk.ts b/packages/coding-agent/src/core/sdk.ts index b89f6e85..e84901b0 100644 --- a/packages/coding-agent/src/core/sdk.ts +++ b/packages/coding-agent/src/core/sdk.ts @@ -101,7 +101,7 @@ export interface CreateAgentSessionOptions { tools?: Tool[]; /** Custom tools to register (in addition to built-in tools). */ customTools?: ToolDefinition[]; - /** Inline extensions (merged with discovery). */ + /** Inline extensions. When provided (even if empty), skips file discovery. */ extensions?: ExtensionFactory[]; /** Additional extension paths to load (merged with discovery). */ additionalExtensionPaths?: string[];