mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 07:04:25 +00:00
Add migration for commands->prompts, warn about deprecated hooks/tools dirs
- Auto-migrate commands/ to prompts/ on startup - Warn if hooks/ or tools/ directories contain custom extensions - Show deprecation warnings in interactive mode with keypress to continue - Update CHANGELOG and docs with full migration guide
This commit is contained in:
parent
cf1c4c31f4
commit
91cca23d23
8 changed files with 540 additions and 57 deletions
|
|
@ -27,7 +27,7 @@ import { SettingsManager } from "./core/settings-manager.js";
|
|||
import { resolvePromptInput } from "./core/system-prompt.js";
|
||||
import { printTimings, time } from "./core/timings.js";
|
||||
import { allTools } from "./core/tools/index.js";
|
||||
import { runMigrations } from "./migrations.js";
|
||||
import { runMigrations, showDeprecationWarnings } from "./migrations.js";
|
||||
import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.js";
|
||||
import { initTheme, stopThemeWatcher } from "./modes/interactive/theme/theme.js";
|
||||
import { getChangelogPath, getNewEntries, parseChangelog } from "./utils/changelog.js";
|
||||
|
|
@ -282,8 +282,8 @@ function buildSessionOptions(
|
|||
export async function main(args: string[]) {
|
||||
time("start");
|
||||
|
||||
// Run migrations
|
||||
const { migratedAuthProviders: migratedProviders } = runMigrations();
|
||||
// Run migrations (pass cwd for project-local migrations)
|
||||
const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
|
||||
|
||||
// Create AuthStorage and ModelRegistry upfront
|
||||
const authStorage = discoverAuthStorage();
|
||||
|
|
@ -366,6 +366,11 @@ export async function main(args: string[]) {
|
|||
initTheme(settingsManager.getTheme(), isInteractive);
|
||||
time("initTheme");
|
||||
|
||||
// Show deprecation warnings in interactive mode
|
||||
if (isInteractive && deprecationWarnings.length > 0) {
|
||||
await showDeprecationWarnings(deprecationWarnings);
|
||||
}
|
||||
|
||||
let scopedModels: ScopedModel[] = [];
|
||||
const modelPatterns = parsed.models ?? settingsManager.getEnabledModels();
|
||||
if (modelPatterns && modelPatterns.length > 0) {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,14 @@
|
|||
* One-time migrations that run on startup.
|
||||
*/
|
||||
|
||||
import chalk from "chalk";
|
||||
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
||||
import { dirname, join } from "path";
|
||||
import { getAgentDir } from "./config.js";
|
||||
import { CONFIG_DIR_NAME, getAgentDir } from "./config.js";
|
||||
|
||||
const MIGRATION_GUIDE_URL =
|
||||
"https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration";
|
||||
const EXTENSIONS_DOC_URL = "https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/extensions.md";
|
||||
|
||||
/**
|
||||
* Migrate legacy oauth.json and settings.json apiKeys to auth.json.
|
||||
|
|
@ -123,13 +128,118 @@ export function migrateSessionsFromAgentRoot(): void {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate commands/ to prompts/ if needed.
|
||||
* Works for both regular directories and symlinks.
|
||||
*/
|
||||
function migrateCommandsToPrompts(baseDir: string, label: string): boolean {
|
||||
const commandsDir = join(baseDir, "commands");
|
||||
const promptsDir = join(baseDir, "prompts");
|
||||
|
||||
if (existsSync(commandsDir) && !existsSync(promptsDir)) {
|
||||
try {
|
||||
renameSync(commandsDir, promptsDir);
|
||||
console.log(chalk.green(`Migrated ${label} commands/ → prompts/`));
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`Warning: Could not migrate ${label} commands/ to prompts/: ${err instanceof Error ? err.message : err}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function checkDeprecatedExtensionDirs(baseDir: string, label: string): string[] {
|
||||
const hooksDir = join(baseDir, "hooks");
|
||||
const toolsDir = join(baseDir, "tools");
|
||||
const warnings: string[] = [];
|
||||
|
||||
if (existsSync(hooksDir)) {
|
||||
warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);
|
||||
}
|
||||
|
||||
if (existsSync(toolsDir)) {
|
||||
// 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");
|
||||
if (customTools.length > 0) {
|
||||
warnings.push(
|
||||
`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`,
|
||||
);
|
||||
}
|
||||
} catch {
|
||||
// Ignore read errors
|
||||
}
|
||||
}
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run extension system migrations (commands→prompts) and collect warnings about deprecated directories.
|
||||
*/
|
||||
function migrateExtensionSystem(cwd: string): string[] {
|
||||
const agentDir = getAgentDir();
|
||||
const projectDir = join(cwd, CONFIG_DIR_NAME);
|
||||
|
||||
// Migrate commands/ to prompts/
|
||||
migrateCommandsToPrompts(agentDir, "Global");
|
||||
migrateCommandsToPrompts(projectDir, "Project");
|
||||
|
||||
// Check for deprecated directories
|
||||
const warnings = [
|
||||
...checkDeprecatedExtensionDirs(agentDir, "Global"),
|
||||
...checkDeprecatedExtensionDirs(projectDir, "Project"),
|
||||
];
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print deprecation warnings and wait for keypress.
|
||||
*/
|
||||
export async function showDeprecationWarnings(warnings: string[]): Promise<void> {
|
||||
if (warnings.length === 0) return;
|
||||
|
||||
for (const warning of warnings) {
|
||||
console.log(chalk.yellow(`Warning: ${warning}`));
|
||||
}
|
||||
console.log(chalk.yellow(`\nMove your extensions to the extensions/ directory.`));
|
||||
console.log(chalk.yellow(`Migration guide: ${MIGRATION_GUIDE_URL}`));
|
||||
console.log(chalk.yellow(`Documentation: ${EXTENSIONS_DOC_URL}`));
|
||||
console.log(chalk.dim(`\nPress any key to continue...`));
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
process.stdin.setRawMode?.(true);
|
||||
process.stdin.resume();
|
||||
process.stdin.once("data", () => {
|
||||
process.stdin.setRawMode?.(false);
|
||||
process.stdin.pause();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
console.log();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all migrations. Called once on startup.
|
||||
*
|
||||
* @returns Object with migration results
|
||||
* @returns Object with migration results and deprecation warnings
|
||||
*/
|
||||
export function runMigrations(): { migratedAuthProviders: string[] } {
|
||||
export function runMigrations(cwd: string = process.cwd()): {
|
||||
migratedAuthProviders: string[];
|
||||
deprecationWarnings: string[];
|
||||
} {
|
||||
const migratedAuthProviders = migrateAuthToAuthJson();
|
||||
migrateSessionsFromAgentRoot();
|
||||
return { migratedAuthProviders };
|
||||
const deprecationWarnings = migrateExtensionSystem(cwd);
|
||||
return { migratedAuthProviders, deprecationWarnings };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue