-
Notifications
You must be signed in to change notification settings - Fork 0
chore: phi integration and mcp client improvements #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| #!/usr/bin/env bun | ||
|
|
||
| import { mkdir, rm, writeFile } from "node:fs/promises"; | ||
| import { join } from "node:path"; | ||
|
|
||
| /** | ||
| * Prepares dist/phi-extension/ so it can be symlinked into phi's extensions dir. | ||
| * | ||
| * Goals: | ||
| * - no POSIX shell dependencies (mkdir -p / ln -sf / echo >) | ||
| * - idempotent + fails build on errors | ||
| */ | ||
| async function main() { | ||
| const pkgRoot = process.cwd(); | ||
|
|
||
| const distDir = join(pkgRoot, "dist"); | ||
| const extDir = join(distDir, "phi-extension"); | ||
| const pkgJsonPath = join(extDir, "package.json"); | ||
| const indexJsPath = join(extDir, "index.js"); | ||
|
|
||
| await mkdir(extDir, { recursive: true }); | ||
|
|
||
| // Ensure we never leave a dangling symlink behind from previous builds. | ||
| // (On Windows, symlink creation may require elevated privileges.) | ||
| await rm(indexJsPath, { force: true }); | ||
|
|
||
| // Minimal package.json: ensure ESM semantics for index.js. | ||
| await writeFile(pkgJsonPath, '{"type":"module"}\n', "utf8"); | ||
|
|
||
| // Avoid symlink entirely for portability: create a tiny re-export shim. | ||
| // This replaces the previous `ln -sf ../phi.js dist/phi-extension/index.js`. | ||
| // NOTE: We resolve realpath to ensure symlinked extension dirs can find dist/phi.js. | ||
| await writeFile( | ||
| indexJsPath, | ||
| `import { realpath } from "node:fs/promises"; | ||
| import { dirname, join } from "node:path"; | ||
| import { fileURLToPath, pathToFileURL } from "node:url"; | ||
|
|
||
| const here = dirname(fileURLToPath(import.meta.url)); | ||
| const realHere = await realpath(here); | ||
| const targetUrl = pathToFileURL(join(realHere, "..", "phi.js")).href; | ||
| const mod = await import(targetUrl); | ||
|
|
||
| export default mod.default; | ||
| `, | ||
| "utf8", | ||
| ); | ||
| } | ||
|
|
||
| main().catch((err) => { | ||
| console.error(err); | ||
| process.exitCode = 1; | ||
| }); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -47,6 +47,7 @@ Usage: | |||||
| agentsbox init [--dry-run] [--force] | ||||||
| agentsbox setup opencode [--dry-run] [--force] | ||||||
| agentsbox setup pi [--dry-run] [--force] | ||||||
| agentsbox setup phi [--dry-run] [--force] | ||||||
|
|
||||||
| Commands: | ||||||
| init | ||||||
|
|
@@ -58,11 +59,15 @@ Commands: | |||||
| setup pi | ||||||
| Install agentsbox as a local pi extension (auto-discovered). | ||||||
|
|
||||||
| setup phi | ||||||
| Install agentsbox as a local phi extension (auto-discovered). | ||||||
|
|
||||||
| Defaults: | ||||||
| agentsbox config dir: ~/.config/agentsbox | ||||||
| OpenCode plugins dir: ~/.config/opencode/plugins | ||||||
| pi extensions dir: ~/.pi/agent/extensions | ||||||
| pi skills dir: ~/.pi/agent/skills | ||||||
| phi extensions dir: ~/.phi/agent/extensions | ||||||
| skills dir: ~/.agents/skills | ||||||
|
|
||||||
| Options: | ||||||
| --dry-run Print planned filesystem changes only | ||||||
|
|
@@ -565,50 +570,51 @@ async function planSetupOpencode(opts: { | |||||
| return actions; | ||||||
| } | ||||||
|
|
||||||
| async function planSetupPi(opts: { | ||||||
| async function planSetupAgent(opts: { | ||||||
| agentName: "pi" | "phi"; | ||||||
| configDir: string; | ||||||
| force: boolean; | ||||||
| pkgRoot: string; | ||||||
| piExtensionsDir: string; | ||||||
| piSkillsDir: string; | ||||||
| extensionsDir: string; | ||||||
| sharedSkillsDir: string; | ||||||
| }): Promise<Action[]> { | ||||||
| const { configDir, force, pkgRoot, piExtensionsDir, piSkillsDir } = opts; | ||||||
| const { agentName, configDir, force, pkgRoot, extensionsDir, sharedSkillsDir } = opts; | ||||||
|
|
||||||
| const actions: Action[] = []; | ||||||
|
|
||||||
| // dist/pi.js is a fully-bundled entrypoint — no wrapper needed. | ||||||
| const srcPiEntrypoint = join(pkgRoot, "dist", "pi.js"); | ||||||
| actions.push({ kind: "assert-exists", path: srcPiEntrypoint, hint: "Run: bun run build" }); | ||||||
| // dist/{agent}.js is a fully-bundled entrypoint — no wrapper needed. | ||||||
| const srcEntrypoint = join(pkgRoot, "dist", `${agentName}.js`); | ||||||
| actions.push({ kind: "assert-exists", path: srcEntrypoint, hint: "Run: bun run build" }); | ||||||
|
|
||||||
| // Ensure agentsbox config + skill | ||||||
| actions.push(...(await planInit({ configDir, force, pkgRoot }))); | ||||||
|
|
||||||
| // Clean up legacy flat symlink (pre-v0.3 created agentsbox.js directly). | ||||||
| const legacyFlatSymlink = join(piExtensionsDir, "agentsbox.js"); | ||||||
| const legacyFlatSymlink = join(extensionsDir, "agentsbox.js"); | ||||||
| actions.push({ kind: "remove", path: legacyFlatSymlink, onlyIfSymlink: true }); | ||||||
|
|
||||||
| // Symlink entire extension directory: ~/.pi/agent/extensions/agentsbox/ → dist/pi-extension/ | ||||||
| // dist/pi-extension/ contains: package.json (type:module) + index.js → ../pi.js | ||||||
| const srcExtDir = join(pkgRoot, "dist", "pi-extension"); | ||||||
| // Symlink entire extension directory: ~/.{agent}/agent/extensions/agentsbox/ → dist/{agent}-extension/ | ||||||
| // dist/{agent}-extension/ contains: package.json (type:module) + index.js → ../{agent}.js | ||||||
| const srcExtDir = join(pkgRoot, "dist", `${agentName}-extension`); | ||||||
| actions.push({ kind: "assert-exists", path: srcExtDir, hint: "Run: bun run build" }); | ||||||
|
|
||||||
| actions.push({ kind: "mkdir", path: piExtensionsDir }); | ||||||
| actions.push({ kind: "mkdir", path: extensionsDir }); | ||||||
| actions.push({ | ||||||
| kind: "symlink", | ||||||
| from: srcExtDir, | ||||||
| to: join(piExtensionsDir, "agentsbox"), | ||||||
| to: join(extensionsDir, "agentsbox"), | ||||||
| mode: force ? "overwrite" : "link-if-different", | ||||||
| }); | ||||||
|
|
||||||
| // Symlink skill into pi's skill discovery path (~/.pi/agent/skills/agentsbox). | ||||||
| // Pi discovers skills from ~/.pi/agent/skills/**/SKILL.md recursively. | ||||||
| // Symlink skill into shared skills dir (~/.agents/skills/agentsbox). | ||||||
| // As of Feb 2026, all coding agents use this unified location. | ||||||
|
||||||
| // As of Feb 2026, all coding agents use this unified location. | |
| // All supported coding agents use this unified location for shared skills. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MAX_SEARCHABLE_TEXT is reallocated on every call. Since it's a constant policy value, consider moving it to module scope (or a shared constants module) to avoid repeated allocation and to make the limit easier to reuse/tune.