fix: move managed binaries to bin/ and ignore hidden files in migration check

This commit is contained in:
Jake 2026-01-06 07:52:49 +13:00
parent 05b9d55656
commit 0a736e858d
3 changed files with 65 additions and 6 deletions

View file

@ -142,11 +142,16 @@ export function getSettingsPath(): string {
return join(getAgentDir(), "settings.json");
}
/** Get path to tools directory */
/** Get path to tools directory (deprecated, use extensions/ for JS/TS tools) */
export function getToolsDir(): string {
return join(getAgentDir(), "tools");
}
/** Get path to managed binaries directory (fd, rg) */
export function getBinDir(): string {
return join(getAgentDir(), "bin");
}
/** Get path to prompt templates directory */
export function getPromptsDir(): string {
return join(getAgentDir(), "prompts");

View file

@ -3,9 +3,9 @@
*/
import chalk from "chalk";
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "fs";
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
import { dirname, join } from "path";
import { CONFIG_DIR_NAME, getAgentDir } from "./config.js";
import { CONFIG_DIR_NAME, getAgentDir, getBinDir } from "./config.js";
const MIGRATION_GUIDE_URL =
"https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration";
@ -152,6 +152,50 @@ function migrateCommandsToPrompts(baseDir: string, label: string): boolean {
return false;
}
/**
* Move fd/rg binaries from tools/ to bin/ if they exist.
*/
function migrateToolsToBin(): void {
const agentDir = getAgentDir();
const toolsDir = join(agentDir, "tools");
const binDir = getBinDir();
if (!existsSync(toolsDir)) return;
const binaries = ["fd", "rg", "fd.exe", "rg.exe"];
let movedAny = false;
for (const bin of binaries) {
const oldPath = join(toolsDir, bin);
const newPath = join(binDir, bin);
if (existsSync(oldPath)) {
if (!existsSync(binDir)) {
mkdirSync(binDir, { recursive: true });
}
if (!existsSync(newPath)) {
try {
renameSync(oldPath, newPath);
movedAny = true;
} catch {
// Ignore errors
}
} else {
// Target exists, just delete the old one
try {
rmSync?.(oldPath, { force: true });
} catch {
// Ignore
}
}
}
}
if (movedAny) {
console.log(chalk.green(`Migrated managed binaries tools/ → bin/`));
}
}
/**
* Check for deprecated hooks/ and tools/ directories.
* Note: tools/ may contain fd/rg binaries extracted by pi, so only warn if it has other files.
@ -169,7 +213,16 @@ function checkDeprecatedExtensionDirs(baseDir: string, label: string): string[]
// Check if tools/ contains anything other than fd/rg (which are auto-extracted binaries)
try {
const entries = readdirSync(toolsDir);
const customTools = entries.filter((e) => e !== "fd" && e !== "rg" && e !== "fd.exe" && e !== "rg.exe");
const customTools = entries.filter((e) => {
const lower = e.toLowerCase();
return (
lower !== "fd" &&
lower !== "rg" &&
lower !== "fd.exe" &&
lower !== "rg.exe" &&
!e.startsWith(".") // Ignore .DS_Store and other hidden files
);
});
if (customTools.length > 0) {
warnings.push(
`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`,
@ -240,6 +293,7 @@ export function runMigrations(cwd: string = process.cwd()): {
} {
const migratedAuthProviders = migrateAuthToAuthJson();
migrateSessionsFromAgentRoot();
migrateToolsToBin();
const deprecationWarnings = migrateExtensionSystem(cwd);
return { migratedAuthProviders, deprecationWarnings };
}

View file

@ -5,9 +5,9 @@ import { arch, platform } from "os";
import { join } from "path";
import { Readable } from "stream";
import { finished } from "stream/promises";
import { APP_NAME, getToolsDir } from "../config.js";
import { APP_NAME, getBinDir } from "../config.js";
const TOOLS_DIR = getToolsDir();
const TOOLS_DIR = getBinDir();
interface ToolConfig {
name: string;