fix: support pi extensions from ~/.pi/agent/extensions/ (#51)

Update buildResourceLoader to include ~/.pi/agent/extensions/ in
additionalExtensionPaths, allowing GSD to discover and use extensions
installed in pi's default location.

This resolves extension loading issues when users have extensions
installed in ~/.pi/agent/extensions/ instead of ~/.gsd/agent/extensions/.

- resource-loader.ts: add piExtensionsDir to additionalExtensionPaths
- app-smoke.test.ts: add test verifying the source includes .pi path
This commit is contained in:
Gary Trakhman 2026-03-11 15:09:30 -04:00 committed by GitHub
parent 80d13379df
commit 0a955c0b98
2 changed files with 41 additions and 4 deletions

View file

@ -1,4 +1,5 @@
import { DefaultResourceLoader } from '@mariozechner/pi-coding-agent'
import { homedir } from 'node:os'
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
@ -52,10 +53,16 @@ export function initResources(agentDir: string): void {
}
/**
* Constructs a DefaultResourceLoader with no additionalExtensionPaths.
* Extensions are synced to agentDir by initResources() and pi auto-discovers
* them from ~/.gsd/agent/extensions/ via its normal agentDir scan.
* Constructs a DefaultResourceLoader that loads extensions from both
* ~/.gsd/agent/extensions/ (GSD's default) and ~/.pi/agent/extensions/ (pi's default).
* This allows users to use extensions from either location.
*/
export function buildResourceLoader(agentDir: string): DefaultResourceLoader {
return new DefaultResourceLoader({ agentDir })
const piAgentDir = join(homedir(), '.pi', 'agent')
const piExtensionsDir = join(piAgentDir, 'extensions')
return new DefaultResourceLoader({
agentDir,
additionalExtensionPaths: [piExtensionsDir],
})
}

View file

@ -366,3 +366,33 @@ test("gsd launches and loads extensions without errors", async () => {
"no ERR_MODULE_NOT_FOUND",
);
});
/**
* 9. buildResourceLoader includes ~/.pi/agent/extensions in additionalExtensionPaths
*/
test("buildResourceLoader source includes ~/.pi/agent/extensions path", async () => {
const { join } = await import("node:path");
// Verify the source code includes the pi extensions path
const loaderSrc = readFileSync(join(projectRoot, "src", "resource-loader.ts"), "utf-8");
// Check that buildResourceLoader references ~/.pi/agent
assert.ok(
loaderSrc.includes(".pi"),
"resource-loader.ts references .pi directory"
);
assert.ok(
loaderSrc.includes("additionalExtensionPaths"),
"resource-loader.ts uses additionalExtensionPaths"
);
assert.ok(
loaderSrc.includes("homedir()"),
"resource-loader.ts uses homedir() to construct paths"
);
// Verify the function constructs the correct path
assert.match(
loaderSrc,
/join\(homedir\(\),\s*['"]\.pi['"],\s*['"]agent['"]\)/,
"buildResourceLoader constructs ~/.pi/agent path"
);
});