mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-21 20:04:55 +00:00
chore: rebrand companion-os to clanker-agent
- Rename all package names from companion-* to clanker-* - Update npm scopes from @mariozechner to @harivansh-afk - Rename config directories .companion -> .clanker - Rename environment variables COMPANION_* -> CLANKER_* - Update all documentation, README files, and install scripts - Rename package directories (companion-channels, companion-grind, companion-teams) - Update GitHub URLs to harivansh-afk/clanker-agent - Preserve full git history from companion-cloud monorepo
This commit is contained in:
parent
f93fe7d1a0
commit
67168d8289
356 changed files with 2249 additions and 10223 deletions
|
|
@ -71,8 +71,8 @@ describe.skipIf(!oauthToken)("Anthropic OAuth tool name normalization", () => {
|
|||
expect(toolCallName).toBe("todowrite");
|
||||
});
|
||||
|
||||
it("should handle companion's built-in tools (read, write, edit, bash)", async () => {
|
||||
// Companion's tools use lowercase names, CC uses PascalCase
|
||||
it("should handle clanker's built-in tools (read, write, edit, bash)", async () => {
|
||||
// Clanker'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 () => {
|
||||
// Companion has a "find" tool, CC has "Glob" - these are DIFFERENT tools
|
||||
// Clanker 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 = {
|
||||
|
|
|
|||
|
|
@ -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 (COMPANION_CACHE_RETENTION)", () => {
|
||||
const originalEnv = process.env.COMPANION_CACHE_RETENTION;
|
||||
describe("Cache Retention (CLANKER_CACHE_RETENTION)", () => {
|
||||
const originalEnv = process.env.CLANKER_CACHE_RETENTION;
|
||||
|
||||
beforeEach(() => {
|
||||
delete process.env.COMPANION_CACHE_RETENTION;
|
||||
delete process.env.CLANKER_CACHE_RETENTION;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (originalEnv !== undefined) {
|
||||
process.env.COMPANION_CACHE_RETENTION = originalEnv;
|
||||
process.env.CLANKER_CACHE_RETENTION = originalEnv;
|
||||
} else {
|
||||
delete process.env.COMPANION_CACHE_RETENTION;
|
||||
delete process.env.CLANKER_CACHE_RETENTION;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ describe("Cache Retention (COMPANION_CACHE_RETENTION)", () => {
|
|||
|
||||
describe("Anthropic Provider", () => {
|
||||
it.skipIf(!process.env.ANTHROPIC_API_KEY)(
|
||||
"should use default cache TTL (no ttl field) when COMPANION_CACHE_RETENTION is not set",
|
||||
"should use default cache TTL (no ttl field) when CLANKER_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 (COMPANION_CACHE_RETENTION)", () => {
|
|||
);
|
||||
|
||||
it.skipIf(!process.env.ANTHROPIC_API_KEY)(
|
||||
"should use 1h cache TTL when COMPANION_CACHE_RETENTION=long",
|
||||
"should use 1h cache TTL when CLANKER_CACHE_RETENTION=long",
|
||||
async () => {
|
||||
process.env.COMPANION_CACHE_RETENTION = "long";
|
||||
process.env.CLANKER_CACHE_RETENTION = "long";
|
||||
const model = getModel("anthropic", "claude-3-5-haiku-20241022");
|
||||
let capturedPayload: any = null;
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ describe("Cache Retention (COMPANION_CACHE_RETENTION)", () => {
|
|||
);
|
||||
|
||||
it("should not add ttl when baseUrl is not api.anthropic.com", async () => {
|
||||
process.env.COMPANION_CACHE_RETENTION = "long";
|
||||
process.env.CLANKER_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 (COMPANION_CACHE_RETENTION)", () => {
|
|||
|
||||
describe("OpenAI Responses Provider", () => {
|
||||
it.skipIf(!process.env.OPENAI_API_KEY)(
|
||||
"should not set prompt_cache_retention when COMPANION_CACHE_RETENTION is not set",
|
||||
"should not set prompt_cache_retention when CLANKER_CACHE_RETENTION is not set",
|
||||
async () => {
|
||||
const model = getModel("openai", "gpt-4o-mini");
|
||||
let capturedPayload: any = null;
|
||||
|
|
@ -232,9 +232,9 @@ describe("Cache Retention (COMPANION_CACHE_RETENTION)", () => {
|
|||
);
|
||||
|
||||
it.skipIf(!process.env.OPENAI_API_KEY)(
|
||||
"should set prompt_cache_retention to 24h when COMPANION_CACHE_RETENTION=long",
|
||||
"should set prompt_cache_retention to 24h when CLANKER_CACHE_RETENTION=long",
|
||||
async () => {
|
||||
process.env.COMPANION_CACHE_RETENTION = "long";
|
||||
process.env.CLANKER_CACHE_RETENTION = "long";
|
||||
const model = getModel("openai", "gpt-4o-mini");
|
||||
let capturedPayload: any = null;
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ describe("Cache Retention (COMPANION_CACHE_RETENTION)", () => {
|
|||
);
|
||||
|
||||
it("should not set prompt_cache_retention when baseUrl is not api.openai.com", async () => {
|
||||
process.env.COMPANION_CACHE_RETENTION = "long";
|
||||
process.env.CLANKER_CACHE_RETENTION = "long";
|
||||
|
||||
// Create a model with a different baseUrl (simulating a proxy)
|
||||
const baseModel = getModel("openai", "gpt-4o-mini");
|
||||
|
|
|
|||
|
|
@ -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.COMPANION_NO_LOCAL_LLM) {
|
||||
if (!process.env.CLANKER_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.COMPANION_NO_LOCAL_LLM) {
|
||||
if (!process.env.CLANKER_NO_LOCAL_LLM) {
|
||||
try {
|
||||
execSync(
|
||||
"curl -s --max-time 1 http://localhost:1234/v1/models > /dev/null",
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ function dumpFailurePayload(params: {
|
|||
payload?: unknown;
|
||||
messages: Message[];
|
||||
}): void {
|
||||
const filename = `/tmp/companion-handoff-${params.label}-${Date.now()}.json`;
|
||||
const filename = `/tmp/clanker-handoff-${params.label}-${Date.now()}.json`;
|
||||
const body = {
|
||||
label: params.label,
|
||||
error: params.error,
|
||||
|
|
|
|||
|
|
@ -765,7 +765,7 @@ describe("AI Providers Empty Message Tests", () => {
|
|||
);
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/agent/oauth.json)
|
||||
// =========================================================================
|
||||
|
||||
describe("Anthropic OAuth Provider Empty Messages", () => {
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ describe("Tool Results with Images", () => {
|
|||
);
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/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 companion
|
||||
/** These two don't work, the model simply won't call the tool, works in clanker
|
||||
it.skipIf(!antigravityToken)(
|
||||
"claude-sonnet-4-5 - should handle tool result with only image",
|
||||
{ retry: 3, timeout: 30000 },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Test helper for resolving API keys from ~/.companion/agent/auth.json
|
||||
* Test helper for resolving API keys from ~/.clanker/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(), ".companion", "agent", "auth.json");
|
||||
const AUTH_PATH = join(homedir(), ".clanker", "agent", "auth.json");
|
||||
|
||||
type ApiKeyCredential = {
|
||||
type: "api_key";
|
||||
|
|
@ -57,7 +57,7 @@ function saveAuthStorage(storage: AuthStorage): void {
|
|||
}
|
||||
|
||||
/**
|
||||
* Resolve API key for a provider from ~/.companion/agent/auth.json
|
||||
* Resolve API key for a provider from ~/.clanker/agent/auth.json
|
||||
*
|
||||
* For API key credentials, returns the key directly.
|
||||
* For OAuth credentials, returns the access token (refreshing if expired and saving back).
|
||||
|
|
|
|||
|
|
@ -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.COMPANION_CODING_AGENT_DIR;
|
||||
const originalAgentDir = process.env.CLANKER_CODING_AGENT_DIR;
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
if (originalAgentDir === undefined) {
|
||||
delete process.env.COMPANION_CODING_AGENT_DIR;
|
||||
delete process.env.CLANKER_CODING_AGENT_DIR;
|
||||
} else {
|
||||
process.env.COMPANION_CODING_AGENT_DIR = originalAgentDir;
|
||||
process.env.CLANKER_CODING_AGENT_DIR = originalAgentDir;
|
||||
}
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("openai-codex streaming", () => {
|
||||
it("streams SSE responses into AssistantMessageEventStream", async () => {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "companion-codex-stream-"));
|
||||
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "clanker-codex-stream-"));
|
||||
process.env.CLANKER_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("companion");
|
||||
expect(headers?.get("originator")).toBe("clanker");
|
||||
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(), "companion-codex-stream-"));
|
||||
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "clanker-codex-stream-"));
|
||||
process.env.CLANKER_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(), "companion-codex-stream-"));
|
||||
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "clanker-codex-stream-"));
|
||||
process.env.CLANKER_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(), "companion-codex-stream-"));
|
||||
process.env.COMPANION_CODING_AGENT_DIR = tempDir;
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "clanker-codex-stream-"));
|
||||
process.env.CLANKER_CODING_AGENT_DIR = tempDir;
|
||||
|
||||
const payload = Buffer.from(
|
||||
JSON.stringify({
|
||||
|
|
|
|||
|
|
@ -1048,7 +1048,7 @@ describe("Generate E2E Tests", () => {
|
|||
);
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/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.COMPANION_NO_LOCAL_LLM) {
|
||||
if (!process.env.CLANKER_NO_LOCAL_LLM) {
|
||||
try {
|
||||
execSync("which ollama", { stdio: "ignore" });
|
||||
ollamaInstalled = true;
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ describe("Token Statistics on Abort", () => {
|
|||
);
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/agent/oauth.json)
|
||||
// =========================================================================
|
||||
|
||||
describe("Anthropic OAuth Provider", () => {
|
||||
|
|
|
|||
|
|
@ -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/companion-mono/issues/1022
|
||||
* Regression test for: https://github.com/badlogic/clanker-mono/issues/1022
|
||||
*/
|
||||
|
||||
import { Type } from "@sinclair/typebox";
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ describe("Tool Call Without Result Tests", () => {
|
|||
});
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/agent/oauth.json)
|
||||
// =========================================================================
|
||||
|
||||
describe("Anthropic OAuth Provider", () => {
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ describe("AI Providers Unicode Surrogate Pair Tests", () => {
|
|||
);
|
||||
|
||||
// =========================================================================
|
||||
// OAuth-based providers (credentials from ~/.companion/agent/oauth.json)
|
||||
// OAuth-based providers (credentials from ~/.clanker/agent/oauth.json)
|
||||
// =========================================================================
|
||||
|
||||
describe("Anthropic OAuth Provider Unicode Handling", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue