refactor: finish companion rename migration

Complete the remaining pi-to-companion rename across companion-os, web, vm-orchestrator, docker, and archived fixtures.

Verification:
- semantic rg sweeps for Pi/piConfig/getPi/.pi runtime references
- npm run check in apps/companion-os (fails in this worktree: biome not found)

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Harivansh Rathi 2026-03-10 07:39:32 -05:00
parent e8fe3d54af
commit 536241053c
303 changed files with 3603 additions and 3602 deletions

View file

@ -71,8 +71,8 @@ describe.skipIf(!oauthToken)("Anthropic OAuth tool name normalization", () => {
expect(toolCallName).toBe("todowrite");
});
it("should handle pi's built-in tools (read, write, edit, bash)", async () => {
// Pi's tools use lowercase names, CC uses PascalCase
it("should handle companion's built-in tools (read, write, edit, bash)", async () => {
// Companion's tools use lowercase names, CC uses PascalCase
const readTool: Tool = {
name: "read",
description: "Read a file",
@ -116,7 +116,7 @@ describe.skipIf(!oauthToken)("Anthropic OAuth tool name normalization", () => {
});
it("should NOT map find to Glob - find is not a CC tool name", async () => {
// Pi has a "find" tool, CC has "Glob" - these are DIFFERENT tools
// Companion has a "find" tool, CC has "Glob" - these are DIFFERENT tools
// The old code incorrectly mapped find -> Glob, which broke the round-trip
// because there's no tool named "glob" in context.tools
const findTool: Tool = {

View file

@ -3,18 +3,18 @@ import { getModel } from "../src/models.js";
import { stream } from "../src/stream.js";
import type { Context } from "../src/types.js";
describe("Cache Retention (PI_CACHE_RETENTION)", () => {
const originalEnv = process.env.PI_CACHE_RETENTION;
describe("Cache Retention (COMPANION_CACHE_RETENTION)", () => {
const originalEnv = process.env.COMPANION_CACHE_RETENTION;
beforeEach(() => {
delete process.env.PI_CACHE_RETENTION;
delete process.env.COMPANION_CACHE_RETENTION;
});
afterEach(() => {
if (originalEnv !== undefined) {
process.env.PI_CACHE_RETENTION = originalEnv;
process.env.COMPANION_CACHE_RETENTION = originalEnv;
} else {
delete process.env.PI_CACHE_RETENTION;
delete process.env.COMPANION_CACHE_RETENTION;
}
});
@ -25,7 +25,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
describe("Anthropic Provider", () => {
it.skipIf(!process.env.ANTHROPIC_API_KEY)(
"should use default cache TTL (no ttl field) when PI_CACHE_RETENTION is not set",
"should use default cache TTL (no ttl field) when COMPANION_CACHE_RETENTION is not set",
async () => {
const model = getModel("anthropic", "claude-3-5-haiku-20241022");
let capturedPayload: any = null;
@ -51,9 +51,9 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
);
it.skipIf(!process.env.ANTHROPIC_API_KEY)(
"should use 1h cache TTL when PI_CACHE_RETENTION=long",
"should use 1h cache TTL when COMPANION_CACHE_RETENTION=long",
async () => {
process.env.PI_CACHE_RETENTION = "long";
process.env.COMPANION_CACHE_RETENTION = "long";
const model = getModel("anthropic", "claude-3-5-haiku-20241022");
let capturedPayload: any = null;
@ -79,7 +79,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
);
it("should not add ttl when baseUrl is not api.anthropic.com", async () => {
process.env.PI_CACHE_RETENTION = "long";
process.env.COMPANION_CACHE_RETENTION = "long";
// Create a model with a different baseUrl (simulating a proxy)
const baseModel = getModel("anthropic", "claude-3-5-haiku-20241022");
@ -210,7 +210,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
describe("OpenAI Responses Provider", () => {
it.skipIf(!process.env.OPENAI_API_KEY)(
"should not set prompt_cache_retention when PI_CACHE_RETENTION is not set",
"should not set prompt_cache_retention when COMPANION_CACHE_RETENTION is not set",
async () => {
const model = getModel("openai", "gpt-4o-mini");
let capturedPayload: any = null;
@ -232,9 +232,9 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
);
it.skipIf(!process.env.OPENAI_API_KEY)(
"should set prompt_cache_retention to 24h when PI_CACHE_RETENTION=long",
"should set prompt_cache_retention to 24h when COMPANION_CACHE_RETENTION=long",
async () => {
process.env.PI_CACHE_RETENTION = "long";
process.env.COMPANION_CACHE_RETENTION = "long";
const model = getModel("openai", "gpt-4o-mini");
let capturedPayload: any = null;
@ -255,7 +255,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
);
it("should not set prompt_cache_retention when baseUrl is not api.openai.com", async () => {
process.env.PI_CACHE_RETENTION = "long";
process.env.COMPANION_CACHE_RETENTION = "long";
// Create a model with a different baseUrl (simulating a proxy)
const baseModel = getModel("openai", "gpt-4o-mini");

View file

@ -683,7 +683,7 @@ describe("Context overflow error handling", () => {
// Check if ollama is installed and local LLM tests are enabled
let ollamaInstalled = false;
if (!process.env.PI_NO_LOCAL_LLM) {
if (!process.env.COMPANION_NO_LOCAL_LLM) {
try {
execSync("which ollama", { stdio: "ignore" });
ollamaInstalled = true;
@ -785,7 +785,7 @@ describe("Context overflow error handling", () => {
// =============================================================================
let lmStudioRunning = false;
if (!process.env.PI_NO_LOCAL_LLM) {
if (!process.env.COMPANION_NO_LOCAL_LLM) {
try {
execSync(
"curl -s --max-time 1 http://localhost:1234/v1/models > /dev/null",

View file

@ -227,7 +227,7 @@ function dumpFailurePayload(params: {
payload?: unknown;
messages: Message[];
}): void {
const filename = `/tmp/pi-handoff-${params.label}-${Date.now()}.json`;
const filename = `/tmp/companion-handoff-${params.label}-${Date.now()}.json`;
const body = {
label: params.label,
error: params.error,

View file

@ -765,7 +765,7 @@ describe("AI Providers Empty Message Tests", () => {
);
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// =========================================================================
describe("Anthropic OAuth Provider Empty Messages", () => {

View file

@ -476,7 +476,7 @@ describe("Tool Results with Images", () => {
);
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// =========================================================================
describe("Anthropic OAuth Provider (claude-sonnet-4-5)", () => {
@ -584,7 +584,7 @@ describe("Tool Results with Images", () => {
},
);
/** These two don't work, the model simply won't call the tool, works in pi
/** These two don't work, the model simply won't call the tool, works in companion
it.skipIf(!antigravityToken)(
"claude-sonnet-4-5 - should handle tool result with only image",
{ retry: 3, timeout: 30000 },

View file

@ -1,5 +1,5 @@
/**
* Test helper for resolving API keys from ~/.pi/agent/auth.json
* Test helper for resolving API keys from ~/.companion/agent/auth.json
*
* Supports both API key and OAuth credentials.
* OAuth tokens are automatically refreshed if expired and saved back to auth.json.
@ -20,7 +20,7 @@ import type {
OAuthProvider,
} from "../src/utils/oauth/types.js";
const AUTH_PATH = join(homedir(), ".pi", "agent", "auth.json");
const AUTH_PATH = join(homedir(), ".companion", "agent", "auth.json");
type ApiKeyCredential = {
type: "api_key";
@ -57,7 +57,7 @@ function saveAuthStorage(storage: AuthStorage): void {
}
/**
* Resolve API key for a provider from ~/.pi/agent/auth.json
* Resolve API key for a provider from ~/.companion/agent/auth.json
*
* For API key credentials, returns the key directly.
* For OAuth credentials, returns the access token (refreshing if expired and saving back).

View file

@ -6,22 +6,22 @@ import { streamOpenAICodexResponses } from "../src/providers/openai-codex-respon
import type { Context, Model } from "../src/types.js";
const originalFetch = global.fetch;
const originalAgentDir = process.env.PI_CODING_AGENT_DIR;
const originalAgentDir = process.env.COMPANION_CODING_AGENT_DIR;
afterEach(() => {
global.fetch = originalFetch;
if (originalAgentDir === undefined) {
delete process.env.PI_CODING_AGENT_DIR;
delete process.env.COMPANION_CODING_AGENT_DIR;
} else {
process.env.PI_CODING_AGENT_DIR = originalAgentDir;
process.env.COMPANION_CODING_AGENT_DIR = originalAgentDir;
}
vi.restoreAllMocks();
});
describe("openai-codex streaming", () => {
it("streams SSE responses into AssistantMessageEventStream", async () => {
const tempDir = mkdtempSync(join(tmpdir(), "pi-codex-stream-"));
process.env.PI_CODING_AGENT_DIR = tempDir;
const tempDir = mkdtempSync(join(tmpdir(), "companion-codex-stream-"));
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
const payload = Buffer.from(
JSON.stringify({
@ -95,7 +95,7 @@ describe("openai-codex streaming", () => {
expect(headers?.get("Authorization")).toBe(`Bearer ${token}`);
expect(headers?.get("chatgpt-account-id")).toBe("acc_test");
expect(headers?.get("OpenAI-Beta")).toBe("responses=experimental");
expect(headers?.get("originator")).toBe("pi");
expect(headers?.get("originator")).toBe("companion");
expect(headers?.get("accept")).toBe("text/event-stream");
expect(headers?.has("x-api-key")).toBe(false);
return new Response(stream, {
@ -149,8 +149,8 @@ describe("openai-codex streaming", () => {
});
it("sets conversation_id/session_id headers and prompt_cache_key when sessionId is provided", async () => {
const tempDir = mkdtempSync(join(tmpdir(), "pi-codex-stream-"));
process.env.PI_CODING_AGENT_DIR = tempDir;
const tempDir = mkdtempSync(join(tmpdir(), "companion-codex-stream-"));
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
const payload = Buffer.from(
JSON.stringify({
@ -272,8 +272,8 @@ describe("openai-codex streaming", () => {
it.each(["gpt-5.3-codex", "gpt-5.4"])(
"clamps %s minimal reasoning effort to low",
async (modelId) => {
const tempDir = mkdtempSync(join(tmpdir(), "pi-codex-stream-"));
process.env.PI_CODING_AGENT_DIR = tempDir;
const tempDir = mkdtempSync(join(tmpdir(), "companion-codex-stream-"));
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
const payload = Buffer.from(
JSON.stringify({
@ -393,8 +393,8 @@ describe("openai-codex streaming", () => {
);
it("does not set conversation_id/session_id headers when sessionId is not provided", async () => {
const tempDir = mkdtempSync(join(tmpdir(), "pi-codex-stream-"));
process.env.PI_CODING_AGENT_DIR = tempDir;
const tempDir = mkdtempSync(join(tmpdir(), "companion-codex-stream-"));
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
const payload = Buffer.from(
JSON.stringify({

View file

@ -1048,7 +1048,7 @@ describe("Generate E2E Tests", () => {
);
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// Tokens are resolved at module level (see oauthTokens above)
// =========================================================================
@ -1800,7 +1800,7 @@ describe("Generate E2E Tests", () => {
// Check if ollama is installed and local LLM tests are enabled
let ollamaInstalled = false;
if (!process.env.PI_NO_LOCAL_LLM) {
if (!process.env.COMPANION_NO_LOCAL_LLM) {
try {
execSync("which ollama", { stdio: "ignore" });
ollamaInstalled = true;

View file

@ -294,7 +294,7 @@ describe("Token Statistics on Abort", () => {
);
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// =========================================================================
describe("Anthropic OAuth Provider", () => {

View file

@ -7,7 +7,7 @@
* OpenAI Responses API generates IDs in format: {call_id}|{id}
* where {id} can be 400+ chars with special characters (+, /, =).
*
* Regression test for: https://github.com/badlogic/pi-mono/issues/1022
* Regression test for: https://github.com/badlogic/companion-mono/issues/1022
*/
import { Type } from "@sinclair/typebox";

View file

@ -324,7 +324,7 @@ describe("Tool Call Without Result Tests", () => {
});
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// =========================================================================
describe("Anthropic OAuth Provider", () => {

View file

@ -472,7 +472,7 @@ describe("AI Providers Unicode Surrogate Pair Tests", () => {
);
// =========================================================================
// OAuth-based providers (credentials from ~/.pi/agent/oauth.json)
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
// =========================================================================
describe("Anthropic OAuth Provider Unicode Handling", () => {