diff --git a/packages/coding-agent/examples/extensions/preset.ts b/packages/coding-agent/examples/extensions/preset.ts index e3642e6fc..f9338456b 100644 --- a/packages/coding-agent/examples/extensions/preset.ts +++ b/packages/coding-agent/examples/extensions/preset.ts @@ -6,8 +6,8 @@ * and can be activated via CLI flag, /preset command, or Ctrl+Shift+U to cycle. * * Config files (merged, project takes precedence): - * - ~/.pi/agent/presets.json (global) - * - /.pi/presets.json (project-local) + * - ~/.prime/agent/presets.json (global) + * - /.prime/agent/presets.json (project-local) * * Example presets.json: * ```json @@ -69,7 +69,7 @@ interface PresetsConfig { */ function loadPresets(cwd: string): PresetsConfig { const globalPath = join(getAgentDir(), "presets.json"); - const projectPath = join(cwd, ".pi", "presets.json"); + const projectPath = join(cwd, ".prime", "agent", "presets.json"); let globalPresets: PresetsConfig = {}; let projectPresets: PresetsConfig = {}; @@ -200,7 +200,7 @@ export default function presetExtension(pi: ExtensionAPI) { const presetNames = Object.keys(presets); if (presetNames.length === 0) { - ctx.ui.notify("No presets defined. Add presets to ~/.pi/agent/presets.json or .pi/presets.json", "warning"); + ctx.ui.notify("No presets defined. Add presets to ~/.prime/agent/presets.json", "warning"); return; } @@ -308,7 +308,7 @@ export default function presetExtension(pi: ExtensionAPI) { async function cyclePreset(ctx: ExtensionContext): Promise { const presetNames = getPresetOrder(); if (presetNames.length === 0) { - ctx.ui.notify("No presets defined. Add presets to ~/.pi/agent/presets.json or .pi/presets.json", "warning"); + ctx.ui.notify("No presets defined. Add presets to ~/.prime/agent/presets.json", "warning"); return; } diff --git a/packages/coding-agent/examples/extensions/provider-payload.ts b/packages/coding-agent/examples/extensions/provider-payload.ts index 860ddc00e..abf06e936 100644 --- a/packages/coding-agent/examples/extensions/provider-payload.ts +++ b/packages/coding-agent/examples/extensions/provider-payload.ts @@ -3,7 +3,7 @@ import { join } from "node:path"; import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; export default function (pi: ExtensionAPI) { - const logFile = join(process.cwd(), ".pi", "provider-payload.log"); + const logFile = join(process.cwd(), ".prime", "agent", "provider-payload.log"); pi.on("before_provider_request", (event) => { appendFileSync(logFile, `${JSON.stringify(event.payload, null, 2)}\n\n`, "utf8"); diff --git a/packages/coding-agent/examples/extensions/sandbox/index.ts b/packages/coding-agent/examples/extensions/sandbox/index.ts index 94f8f1cf1..55524872c 100644 --- a/packages/coding-agent/examples/extensions/sandbox/index.ts +++ b/packages/coding-agent/examples/extensions/sandbox/index.ts @@ -10,10 +10,10 @@ * via `tool_call` input mutation without replacing the tool. * * Config files (merged, project takes precedence): - * - ~/.pi/agent/extensions/sandbox.json (global) - * - /.pi/sandbox.json (project-local) + * - ~/.prime/agent/extensions/sandbox.json (global) + * - /.prime/agent/sandbox.json (project-local) * - * Example .pi/sandbox.json: + * Example .prime/agent/sandbox.json: * ```json * { * "enabled": true, @@ -35,8 +35,8 @@ * - `/sandbox` - show current sandbox configuration * * Setup: - * 1. Copy sandbox/ directory to ~/.pi/agent/extensions/ - * 2. Run `npm install` in ~/.pi/agent/extensions/sandbox/ + * 1. Copy sandbox/ directory to ~/.prime/agent/extensions/ + * 2. Run `npm install` in ~/.prime/agent/extensions/sandbox/ * * Linux also requires: bubblewrap, socat, ripgrep */ @@ -77,7 +77,7 @@ const DEFAULT_CONFIG: SandboxConfig = { }; function loadConfig(cwd: string): SandboxConfig { - const projectConfigPath = join(cwd, ".pi", "sandbox.json"); + const projectConfigPath = join(cwd, ".prime", "agent", "sandbox.json"); const globalConfigPath = join(getAgentDir(), "extensions", "sandbox.json"); let globalConfig: Partial = {}; diff --git a/packages/coding-agent/examples/extensions/subagent/agents.ts b/packages/coding-agent/examples/extensions/subagent/agents.ts index eab6c6302..bfd88e205 100644 --- a/packages/coding-agent/examples/extensions/subagent/agents.ts +++ b/packages/coding-agent/examples/extensions/subagent/agents.ts @@ -85,7 +85,7 @@ function isDirectory(p: string): boolean { function findNearestProjectAgentsDir(cwd: string): string | null { let currentDir = cwd; while (true) { - const candidate = path.join(currentDir, ".pi", "agents"); + const candidate = path.join(currentDir, ".prime", "agent", "agents"); if (isDirectory(candidate)) return candidate; const parentDir = path.dirname(currentDir); diff --git a/packages/coding-agent/examples/extensions/subagent/index.ts b/packages/coding-agent/examples/extensions/subagent/index.ts index 01b00dcdc..2ccd606f7 100644 --- a/packages/coding-agent/examples/extensions/subagent/index.ts +++ b/packages/coding-agent/examples/extensions/subagent/index.ts @@ -403,8 +403,8 @@ export default function (pi: ExtensionAPI) { description: [ "Delegate tasks to specialized subagents with isolated context.", "Modes: single (agent + task), parallel (tasks array), chain (sequential with {previous} placeholder).", - 'Default agent scope is "user" (from ~/.pi/agent/agents).', - 'To enable project-local agents in .pi/agents, set agentScope: "both" (or "project").', + 'Default agent scope is "user" (from ~/.prime/agent/agents).', + 'To enable project-local agents in .prime/agent/agents, set agentScope: "both" (or "project").', ].join(" "), parameters: SubagentParams, diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index f5e6b0adb..fe4f7f8a5 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -4,7 +4,7 @@ "description": "Coding agent CLI with ipython, bash, edit tools and session management", "type": "module", "piConfig": { - "configDir": ".pi" + "configDir": ".prime/agent" }, "bin": { "pi": "dist/cli.js" diff --git a/packages/coding-agent/src/cli/args.ts b/packages/coding-agent/src/cli/args.ts index 6a963bc74..3b2c26e4c 100644 --- a/packages/coding-agent/src/cli/args.ts +++ b/packages/coding-agent/src/cli/args.ts @@ -305,7 +305,7 @@ ${chalk.bold("Examples:")} ${APP_NAME} --tools bash -p "Run the project checks" # Export a session file to HTML - ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl + ${APP_NAME} --export ~/${CONFIG_DIR_NAME}/sessions/--path--/session.jsonl ${APP_NAME} --export session.jsonl output.html ${chalk.bold("Environment Variables:")} @@ -343,7 +343,7 @@ ${chalk.bold("Environment Variables:")} AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token) AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1) - ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent) + ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}) ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir) PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths) PI_OFFLINE - Disable startup network operations when set to 1/true/yes diff --git a/packages/coding-agent/src/config.ts b/packages/coding-agent/src/config.ts index bf268a77a..0e23aad63 100644 --- a/packages/coding-agent/src/config.ts +++ b/packages/coding-agent/src/config.ts @@ -420,7 +420,7 @@ const piConfigName: string | undefined = pkg.piConfig?.name; export const PACKAGE_NAME: string = pkg.name || "@earendil-works/pi-coding-agent"; export const APP_NAME: string = piConfigName || "pi"; export const APP_TITLE: string = piConfigName ? APP_NAME : "π"; -export const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || ".pi"; +export const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || ".prime/agent"; export const VERSION: string = pkg.version || "0.0.0"; // e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR @@ -451,7 +451,7 @@ export function getAgentDir(): string { if (envDir) { return expandTildePath(envDir); } - return join(homedir(), CONFIG_DIR_NAME, "agent"); + return join(homedir(), CONFIG_DIR_NAME); } /** Get path to user's custom themes directory */ diff --git a/packages/coding-agent/src/modes/interactive/components/config-selector.ts b/packages/coding-agent/src/modes/interactive/components/config-selector.ts index 0d4c8aba2..1c825e0af 100644 --- a/packages/coding-agent/src/modes/interactive/components/config-selector.ts +++ b/packages/coding-agent/src/modes/interactive/components/config-selector.ts @@ -61,7 +61,7 @@ function getGroupLabel(metadata: PathMetadata): string { } // Top-level resources if (metadata.source === "auto") { - return metadata.scope === "user" ? "User (~/.pi/agent/)" : "Project (.pi/)"; + return metadata.scope === "user" ? `User (~/${CONFIG_DIR_NAME}/)` : `Project (${CONFIG_DIR_NAME}/)`; } return metadata.scope === "user" ? "User settings" : "Project settings"; } diff --git a/packages/coding-agent/src/package-manager-cli.ts b/packages/coding-agent/src/package-manager-cli.ts index a41fb7a6c..4ea88d2db 100644 --- a/packages/coding-agent/src/package-manager-cli.ts +++ b/packages/coding-agent/src/package-manager-cli.ts @@ -3,6 +3,7 @@ import { spawn } from "child_process"; import { selectConfig } from "./cli/config-selector.js"; import { APP_NAME, + CONFIG_DIR_NAME, getAgentDir, getSelfUpdateCommand, getSelfUpdateUnavailableInstruction, @@ -64,7 +65,7 @@ function printPackageCommandHelp(command: PackageCommand): void { Install a package and add it to settings. Options: - -l, --local Install project-locally (.pi/settings.json) + -l, --local Install project-locally (${CONFIG_DIR_NAME}/settings.json) Examples: ${APP_NAME} install npm:@foo/bar @@ -84,7 +85,7 @@ Remove a package and its source from settings. Alias: ${APP_NAME} uninstall [-l] Options: - -l, --local Remove from project settings (.pi/settings.json) + -l, --local Remove from project settings (${CONFIG_DIR_NAME}/settings.json) Examples: ${APP_NAME} remove npm:@foo/bar diff --git a/packages/coding-agent/test/git-update.test.ts b/packages/coding-agent/test/git-update.test.ts index 2cfcb4041..5c184f38d 100644 --- a/packages/coding-agent/test/git-update.test.ts +++ b/packages/coding-agent/test/git-update.test.ts @@ -396,7 +396,7 @@ describe("DefaultPackageManager git update", () => { createCommit(remoteDir, "extension.ts", "// v2", "Second commit"); // The project-scope install path should not exist before or after update - const projectGitDir = join(tempDir, ".pi", "git", "github.com", "test", "extension"); + const projectGitDir = join(tempDir, ".prime", "agent", "git", "github.com", "test", "extension"); expect(existsSync(projectGitDir)).toBe(false); await packageManager.update(gitSource); diff --git a/packages/coding-agent/test/package-command-paths.test.ts b/packages/coding-agent/test/package-command-paths.test.ts index 03c8f4ca4..760ecddd6 100644 --- a/packages/coding-agent/test/package-command-paths.test.ts +++ b/packages/coding-agent/test/package-command-paths.test.ts @@ -141,7 +141,7 @@ describe("package commands", () => { const fakeNpmPath = join(tempDir, "fake-npm.cjs"); const recordPath = join(tempDir, "self-update.json"); mkdirSync(selfPackageDir, { recursive: true }); - mkdirSync(join(projectDir, ".pi"), { recursive: true }); + mkdirSync(join(projectDir, ".prime", "agent"), { recursive: true }); writeFileSync( fakeNpmPath, `const fs=require("node:fs"),path=require("node:path"),args=process.argv.slice(2),prefix=args[args.indexOf("--prefix")+1]; @@ -154,7 +154,7 @@ else fs.writeFileSync(${JSON.stringify(recordPath)},JSON.stringify(args)); JSON.stringify({ npmCommand: [originalExecPath, fakeNpmPath, "--prefix", globalPrefix] }, null, 2), ); writeFileSync( - join(projectDir, ".pi", "settings.json"), + join(projectDir, ".prime", "agent", "settings.json"), JSON.stringify({ npmCommand: [originalExecPath, fakeNpmPath, "--prefix", projectPrefix] }, null, 2), ); process.env.PI_PACKAGE_DIR = selfPackageDir; diff --git a/packages/coding-agent/test/package-manager.test.ts b/packages/coding-agent/test/package-manager.test.ts index 636877b32..e592def7e 100644 --- a/packages/coding-agent/test/package-manager.test.ts +++ b/packages/coding-agent/test/package-manager.test.ts @@ -136,7 +136,7 @@ Content`, }); it("should resolve project paths relative to .pi", async () => { - const extDir = join(tempDir, ".pi", "extensions"); + const extDir = join(tempDir, ".prime", "agent", "extensions"); mkdirSync(extDir, { recursive: true }); const extPath = join(extDir, "project-ext.ts"); writeFileSync(extPath, "export default function() {}"); @@ -188,15 +188,15 @@ Content`, writeFileSync(join(sharedThemesDir, "shared.json"), JSON.stringify({ name: "shared-theme" })); mkdirSync(join(agentDir), { recursive: true }); - mkdirSync(join(tempDir, ".pi"), { recursive: true }); + mkdirSync(join(tempDir, ".prime", "agent"), { recursive: true }); symlinkSync(sharedExtensionsDir, join(agentDir, "extensions"), "dir"); symlinkSync(sharedSkillsDir, join(agentDir, "skills"), "dir"); symlinkSync(sharedPromptsDir, join(agentDir, "prompts"), "dir"); symlinkSync(sharedThemesDir, join(agentDir, "themes"), "dir"); - symlinkSync(sharedExtensionsDir, join(tempDir, ".pi", "extensions"), "dir"); - symlinkSync(sharedSkillsDir, join(tempDir, ".pi", "skills"), "dir"); - symlinkSync(sharedPromptsDir, join(tempDir, ".pi", "prompts"), "dir"); - symlinkSync(sharedThemesDir, join(tempDir, ".pi", "themes"), "dir"); + symlinkSync(sharedExtensionsDir, join(tempDir, ".prime", "agent", "extensions"), "dir"); + symlinkSync(sharedSkillsDir, join(tempDir, ".prime", "agent", "skills"), "dir"); + symlinkSync(sharedPromptsDir, join(tempDir, ".prime", "agent", "prompts"), "dir"); + symlinkSync(sharedThemesDir, join(tempDir, ".prime", "agent", "themes"), "dir"); const result = await packageManager.resolve(); @@ -228,7 +228,7 @@ Content`, }); it("should auto-discover project prompts with overrides", async () => { - const promptsDir = join(tempDir, ".pi", "prompts"); + const promptsDir = join(tempDir, ".prime", "agent", "prompts"); mkdirSync(promptsDir, { recursive: true }); const promptPath = join(promptsDir, "is.md"); writeFileSync(promptPath, "Is prompt"); @@ -355,7 +355,7 @@ Content`, try { const cwd = join(tempDir, "scratch", "nested"); - const localAgentDir = join(tempDir, ".pi", "agent"); + const localAgentDir = join(tempDir, ".prime", "agent"); const localSettingsManager = SettingsManager.inMemory(); mkdirSync(cwd, { recursive: true }); mkdirSync(localAgentDir, { recursive: true }); @@ -437,9 +437,9 @@ Content`, }); it("should not apply parent .gitignore to .pi auto-discovery", async () => { - writeFileSync(join(tempDir, ".gitignore"), ".pi\n"); + writeFileSync(join(tempDir, ".gitignore"), ".prime/agent\n"); - const skillDir = join(tempDir, ".pi", "skills", "auto-skill"); + const skillDir = join(tempDir, ".prime", "agent", "skills", "auto-skill"); mkdirSync(skillDir, { recursive: true }); const skillPath = join(skillDir, "SKILL.md"); writeFileSync(skillPath, "---\nname: auto-skill\ndescription: Auto\n---\nContent"); @@ -609,7 +609,7 @@ Content`, it("should update git package dependencies with --omit=dev", async () => { const source = "git:github.com/user/repo"; - const targetDir = join(tempDir, ".pi", "git", "github.com", "user", "repo"); + const targetDir = join(tempDir, ".prime", "agent", "git", "github.com", "user", "repo"); mkdirSync(targetDir, { recursive: true }); writeFileSync(join(targetDir, "package.json"), JSON.stringify({ name: "repo", version: "1.0.0" })); settingsManager.setProjectPackages([source]); @@ -645,7 +645,7 @@ Content`, }); const source = "git:github.com/user/repo"; - const targetDir = join(tempDir, ".pi", "git", "github.com", "user", "repo"); + const targetDir = join(tempDir, ".prime", "agent", "git", "github.com", "user", "repo"); mkdirSync(targetDir, { recursive: true }); writeFileSync(join(targetDir, "package.json"), JSON.stringify({ name: "repo", version: "1.0.0" })); settingsManager.setProjectPackages([source]); @@ -804,7 +804,7 @@ Content`, expect(added).toBe(true); const settings = settingsManager.getProjectSettings(); - const rel = relative(join(tempDir, ".pi"), projectPkgDir); + const rel = relative(join(tempDir, ".prime", "agent"), projectPkgDir); const expected = rel.startsWith(".") ? rel : `./${rel}`; expect(settings.packages?.[0]).toBe(expected); }); @@ -1601,7 +1601,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te describe("offline mode and network timeouts", () => { it("should update project npm packages using @latest when newer version is available", async () => { - const installedPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(installedPath, { recursive: true }); writeFileSync(join(installedPath, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" })); settingsManager.setProjectPackages(["npm:example"]); @@ -1618,13 +1618,13 @@ export default function(api) { api.registerTool({ name: "test", description: "te ); expect(runCommandSpy).toHaveBeenCalledWith( "npm", - ["install", "example@latest", "--prefix", join(tempDir, ".pi", "npm")], + ["install", "example@latest", "--prefix", join(tempDir, ".prime", "agent", "npm")], undefined, ); }); it("should skip project npm update when installed version matches latest", async () => { - const installedPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(installedPath, { recursive: true }); writeFileSync(join(installedPath, "package.json"), JSON.stringify({ name: "example", version: "1.2.3" })); settingsManager.setProjectPackages(["npm:example"]); @@ -1648,8 +1648,8 @@ export default function(api) { api.registerTool({ name: "test", description: "te const userOldPath = join(agentDir, "node_modules", "user-old"); const userCurrentPath = join(agentDir, "node_modules", "user-current"); const userUnknownPath = join(agentDir, "node_modules", "user-unknown"); - const projectOldPath = join(tempDir, ".pi", "npm", "node_modules", "project-old"); - const projectCurrentPath = join(tempDir, ".pi", "npm", "node_modules", "project-current"); + const projectOldPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "project-old"); + const projectCurrentPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "project-current"); const installPaths = [userOldPath, userCurrentPath, userUnknownPath, projectOldPath, projectCurrentPath]; for (const installPath of installPaths) { mkdirSync(installPath, { recursive: true }); @@ -1743,7 +1743,13 @@ export default function(api) { api.registerTool({ name: "test", description: "te expect(runCommandSpy).toHaveBeenNthCalledWith( 2, "npm", - ["install", "project-old@latest", "project-missing@latest", "--prefix", join(tempDir, ".pi", "npm")], + [ + "install", + "project-old@latest", + "project-missing@latest", + "--prefix", + join(tempDir, ".prime", "agent", "npm"), + ], undefined, ); expect(updateGitSpy).toHaveBeenCalledTimes(3); @@ -1796,7 +1802,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te }); it("should not run npm view during resolve for installed unpinned packages", async () => { - const installedPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(join(installedPath, "extensions"), { recursive: true }); writeFileSync(join(installedPath, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" })); writeFileSync(join(installedPath, "extensions", "index.ts"), "export default function() {};"); @@ -1810,7 +1816,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te }); it("should reinstall pinned npm packages when installed version does not match", async () => { - const installedPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(installedPath, { recursive: true }); writeFileSync(join(installedPath, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" })); settingsManager.setProjectPackages(["npm:example@2.0.0"]); @@ -1833,7 +1839,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te }); it("should report updates for installed unpinned npm packages", async () => { - const installedPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(installedPath, { recursive: true }); writeFileSync(join(installedPath, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" })); settingsManager.setProjectPackages(["npm:example"]); @@ -1852,7 +1858,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te }); it("should skip pinned packages when checking for updates", async () => { - const installedNpmPath = join(tempDir, ".pi", "npm", "node_modules", "example"); + const installedNpmPath = join(tempDir, ".prime", "agent", "npm", "node_modules", "example"); mkdirSync(installedNpmPath, { recursive: true }); writeFileSync(join(installedNpmPath, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" })); const parsedGitSource = (packageManager as any).parseSource("git:github.com/example/repo@v1"); diff --git a/packages/coding-agent/test/resource-loader.test.ts b/packages/coding-agent/test/resource-loader.test.ts index 01adc9b36..ddd4cddfe 100644 --- a/packages/coding-agent/test/resource-loader.test.ts +++ b/packages/coding-agent/test/resource-loader.test.ts @@ -98,7 +98,7 @@ Prompt content.`, it("should prefer project resources over user on name collisions", async () => { const userPromptsDir = join(agentDir, "prompts"); - const projectPromptsDir = join(cwd, ".pi", "prompts"); + const projectPromptsDir = join(cwd, ".prime", "agent", "prompts"); mkdirSync(userPromptsDir, { recursive: true }); mkdirSync(projectPromptsDir, { recursive: true }); const userPromptPath = join(userPromptsDir, "commit.md"); @@ -107,7 +107,7 @@ Prompt content.`, writeFileSync(projectPromptPath, "Project prompt"); const userSkillDir = join(agentDir, "skills", "collision-skill"); - const projectSkillDir = join(cwd, ".pi", "skills", "collision-skill"); + const projectSkillDir = join(cwd, ".prime", "agent", "skills", "collision-skill"); mkdirSync(userSkillDir, { recursive: true }); mkdirSync(projectSkillDir, { recursive: true }); const userSkillPath = join(userSkillDir, "SKILL.md"); @@ -134,9 +134,9 @@ Project skill`, ) as { name: string; vars?: Record }; baseTheme.name = "collision-theme"; const userThemePath = join(agentDir, "themes", "collision.json"); - const projectThemePath = join(cwd, ".pi", "themes", "collision.json"); + const projectThemePath = join(cwd, ".prime", "agent", "themes", "collision.json"); mkdirSync(join(agentDir, "themes"), { recursive: true }); - mkdirSync(join(cwd, ".pi", "themes"), { recursive: true }); + mkdirSync(join(cwd, ".prime", "agent", "themes"), { recursive: true }); writeFileSync(userThemePath, JSON.stringify(baseTheme, null, 2)); if (baseTheme.vars) { baseTheme.vars.accent = "#ff00ff"; @@ -170,9 +170,9 @@ Project skill`, ); mkdirSync(agentDir, { recursive: true }); - mkdirSync(join(cwd, ".pi"), { recursive: true }); + mkdirSync(join(cwd, ".prime", "agent"), { recursive: true }); symlinkSync(sharedExtDir, join(agentDir, "extensions"), "dir"); - symlinkSync(sharedExtDir, join(cwd, ".pi", "extensions"), "dir"); + symlinkSync(sharedExtDir, join(cwd, ".prime", "agent", "extensions"), "dir"); const loader = new DefaultResourceLoader({ cwd, agentDir }); await loader.reload(); @@ -183,12 +183,12 @@ Project skill`, // mergePaths processes project paths before user paths, so the project // alias is the canonical survivor. - expect(extensionsResult.extensions[0].path).toBe(join(cwd, ".pi", "extensions", "shared.ts")); + expect(extensionsResult.extensions[0].path).toBe(join(cwd, ".prime", "agent", "extensions", "shared.ts")); }); it("should keep both extensions loaded when command names collide", async () => { const userExtDir = join(agentDir, "extensions"); - const projectExtDir = join(cwd, ".pi", "extensions"); + const projectExtDir = join(cwd, ".prime", "agent", "extensions"); mkdirSync(userExtDir, { recursive: true }); mkdirSync(projectExtDir, { recursive: true }); @@ -318,7 +318,7 @@ Content`, }); it("should discover SYSTEM.md from cwd/.pi", async () => { - const piDir = join(cwd, ".pi"); + const piDir = join(cwd, ".prime", "agent"); mkdirSync(piDir, { recursive: true }); writeFileSync(join(piDir, "SYSTEM.md"), "You are a helpful assistant."); @@ -329,7 +329,7 @@ Content`, }); it("should discover APPEND_SYSTEM.md", async () => { - const piDir = join(cwd, ".pi"); + const piDir = join(cwd, ".prime", "agent"); mkdirSync(piDir, { recursive: true }); writeFileSync(join(piDir, "APPEND_SYSTEM.md"), "Additional instructions."); diff --git a/packages/coding-agent/test/settings-manager-bug.test.ts b/packages/coding-agent/test/settings-manager-bug.test.ts index b79fd9f65..dd35f3009 100644 --- a/packages/coding-agent/test/settings-manager-bug.test.ts +++ b/packages/coding-agent/test/settings-manager-bug.test.ts @@ -25,7 +25,7 @@ describe("SettingsManager - External Edit Preservation", () => { rmSync(testDir, { recursive: true }); } mkdirSync(agentDir, { recursive: true }); - mkdirSync(join(projectDir, ".pi"), { recursive: true }); + mkdirSync(join(projectDir, ".prime", "agent"), { recursive: true }); }); afterEach(() => { @@ -100,7 +100,7 @@ describe("SettingsManager - External Edit Preservation", () => { }); it("should preserve external project settings changes when updating unrelated project field", async () => { - const projectSettingsPath = join(projectDir, ".pi", "settings.json"); + const projectSettingsPath = join(projectDir, ".prime", "agent", "settings.json"); writeFileSync( projectSettingsPath, JSON.stringify({ @@ -124,7 +124,7 @@ describe("SettingsManager - External Edit Preservation", () => { }); it("should let in-memory project changes override external changes for the same project field", async () => { - const projectSettingsPath = join(projectDir, ".pi", "settings.json"); + const projectSettingsPath = join(projectDir, ".prime", "agent", "settings.json"); writeFileSync( projectSettingsPath, JSON.stringify({ diff --git a/packages/coding-agent/test/settings-manager.test.ts b/packages/coding-agent/test/settings-manager.test.ts index d01b1363d..3c60c9477 100644 --- a/packages/coding-agent/test/settings-manager.test.ts +++ b/packages/coding-agent/test/settings-manager.test.ts @@ -15,7 +15,7 @@ describe("SettingsManager", () => { rmSync(testDir, { recursive: true }); } mkdirSync(agentDir, { recursive: true }); - mkdirSync(join(projectDir, ".pi"), { recursive: true }); + mkdirSync(join(projectDir, ".prime", "agent"), { recursive: true }); }); afterEach(() => { @@ -200,7 +200,7 @@ describe("SettingsManager", () => { describe("error tracking", () => { it("should collect and clear load errors via drainErrors", () => { const globalSettingsPath = join(agentDir, "settings.json"); - const projectSettingsPath = join(projectDir, ".pi", "settings.json"); + const projectSettingsPath = join(projectDir, ".prime", "agent", "settings.json"); writeFileSync(globalSettingsPath, "{ invalid global json"); writeFileSync(projectSettingsPath, "{ invalid project json"); @@ -220,13 +220,13 @@ describe("SettingsManager", () => { writeFileSync(settingsPath, JSON.stringify({ theme: "dark" })); // Delete the .pi folder that beforeEach created - rmSync(join(projectDir, ".pi"), { recursive: true }); + rmSync(join(projectDir, ".prime", "agent"), { recursive: true }); // Create SettingsManager (reads both global and project settings) const manager = SettingsManager.create(projectDir, agentDir); // .pi folder should NOT have been created just from reading - expect(existsSync(join(projectDir, ".pi"))).toBe(false); + expect(existsSync(join(projectDir, ".prime", "agent"))).toBe(false); // Settings should still be loaded from global expect(manager.getTheme()).toBe("dark"); @@ -238,22 +238,22 @@ describe("SettingsManager", () => { writeFileSync(settingsPath, JSON.stringify({ theme: "dark" })); // Delete the .pi folder that beforeEach created - rmSync(join(projectDir, ".pi"), { recursive: true }); + rmSync(join(projectDir, ".prime", "agent"), { recursive: true }); const manager = SettingsManager.create(projectDir, agentDir); // .pi folder should NOT exist yet - expect(existsSync(join(projectDir, ".pi"))).toBe(false); + expect(existsSync(join(projectDir, ".prime", "agent"))).toBe(false); // Write a project-specific setting manager.setProjectPackages([{ source: "npm:test-pkg" }]); await manager.flush(); // Now .pi folder should exist - expect(existsSync(join(projectDir, ".pi"))).toBe(true); + expect(existsSync(join(projectDir, ".prime", "agent"))).toBe(true); // And settings file should be created - expect(existsSync(join(projectDir, ".pi", "settings.json"))).toBe(true); + expect(existsSync(join(projectDir, ".prime", "agent", "settings.json"))).toBe(true); }); }); @@ -305,7 +305,10 @@ describe("SettingsManager", () => { it("should return project sessionDir, overriding global", () => { writeFileSync(join(agentDir, "settings.json"), JSON.stringify({ sessionDir: "/global/sessions" })); - writeFileSync(join(projectDir, ".pi", "settings.json"), JSON.stringify({ sessionDir: "./sessions" })); + writeFileSync( + join(projectDir, ".prime", "agent", "settings.json"), + JSON.stringify({ sessionDir: "./sessions" }), + ); const manager = SettingsManager.create(projectDir, agentDir); expect(manager.getSessionDir()).toBe("./sessions"); }); diff --git a/packages/coding-agent/test/stdout-cleanliness.test.ts b/packages/coding-agent/test/stdout-cleanliness.test.ts index f9455f89c..4c4ae7b6a 100644 --- a/packages/coding-agent/test/stdout-cleanliness.test.ts +++ b/packages/coding-agent/test/stdout-cleanliness.test.ts @@ -26,7 +26,7 @@ async function runCli(args: string[]): Promise<{ stdout: string; stderr: string; const tempRoot = createTempDir(); const agentDir = join(tempRoot, "agent"); const projectDir = join(tempRoot, "project"); - const projectConfigDir = join(projectDir, ".pi"); + const projectConfigDir = join(projectDir, ".prime", "agent"); mkdirSync(agentDir, { recursive: true }); mkdirSync(projectConfigDir, { recursive: true }); diff --git a/packages/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts b/packages/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts index e7e17f586..0bb93fb6f 100644 --- a/packages/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts +++ b/packages/coding-agent/test/suite/regressions/2781-skill-collision-precedence.test.ts @@ -45,7 +45,7 @@ describe("issue #2781 skill collision precedence: user skills should override pa } function createProjectSkill(name: string, description: string): string { - const skillDir = join(cwd, ".pi", "skills", name); + const skillDir = join(cwd, ".prime", "agent", "skills", name); mkdirSync(skillDir, { recursive: true }); const skillPath = join(skillDir, "SKILL.md"); writeFileSync(skillPath, `---\nname: ${name}\ndescription: ${description}\n---\nProject skill content`); @@ -53,7 +53,7 @@ describe("issue #2781 skill collision precedence: user skills should override pa } function createSettingsWithPackage(pkgDir: string, scope: "user" | "project"): void { - const settingsDir = scope === "user" ? agentDir : join(cwd, ".pi"); + const settingsDir = scope === "user" ? agentDir : join(cwd, ".prime", "agent"); mkdirSync(settingsDir, { recursive: true }); writeFileSync(join(settingsDir, "settings.json"), JSON.stringify({ packages: [pkgDir] }, null, 2)); } diff --git a/packages/tui/src/tui.ts b/packages/tui/src/tui.ts index 323e173e0..e1dcd0743 100644 --- a/packages/tui/src/tui.ts +++ b/packages/tui/src/tui.ts @@ -1017,7 +1017,7 @@ export class TUI extends Container { const debugRedraw = process.env.PI_DEBUG_REDRAW === "1"; const logRedraw = (reason: string): void => { if (!debugRedraw) return; - const logPath = path.join(os.homedir(), ".pi", "agent", "pi-debug.log"); + const logPath = path.join(os.homedir(), ".prime", "agent", "pi-debug.log"); const msg = `[${new Date().toISOString()}] fullRender: ${reason} (prev=${this.previousLines.length}, new=${newLines.length}, height=${height})\n`; fs.appendFileSync(logPath, msg); }; @@ -1183,7 +1183,7 @@ export class TUI extends Container { const isImage = isImageLine(line); if (!isImage && visibleWidth(line) > width) { // Log all lines to crash file for debugging - const crashLogPath = path.join(os.homedir(), ".pi", "agent", "pi-crash.log"); + const crashLogPath = path.join(os.homedir(), ".prime", "agent", "pi-crash.log"); const crashData = [ `Crash at ${new Date().toISOString()}`, `Terminal width: ${width}`, diff --git a/test.sh b/test.sh index 67aaaeaf7..19b21dade 100755 --- a/test.sh +++ b/test.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash set -e -AUTH_FILE="$HOME/.pi/agent/auth.json" -AUTH_BACKUP="$HOME/.pi/agent/auth.json.bak" +AUTH_FILE="$HOME/.prime/agent/auth.json" +AUTH_BACKUP="$HOME/.prime/agent/auth.json.bak" # Restore auth.json on exit (success or failure) cleanup() {