@gonzih/cc-agent 0.14.7 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,119 @@
1
+ import { existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { spawn } from "child_process";
4
+ import { getPricing } from "./pricing.js";
5
+ import { BaseAgentProcess } from "./types.js";
6
+ /**
7
+ * AiderDriver wraps the `aider` CLI (https://github.com/paul-gauthier/aider).
8
+ * Spawns: aider --message "<task>" --yes --no-pretty --no-stream --model <model>
9
+ */
10
+ export class AiderDriver {
11
+ name = "aider";
12
+ resolveBinary() {
13
+ const dirs = (process.env.PATH ?? "").split(":");
14
+ for (const dir of dirs) {
15
+ const p = `${dir}/aider`;
16
+ if (existsSync(p))
17
+ return p;
18
+ }
19
+ const fallbacks = [
20
+ "/opt/homebrew/bin/aider",
21
+ "/usr/local/bin/aider",
22
+ "/usr/bin/aider",
23
+ `${process.env.HOME}/.local/bin/aider`,
24
+ ];
25
+ for (const p of fallbacks) {
26
+ if (existsSync(p))
27
+ return p;
28
+ }
29
+ return "aider";
30
+ }
31
+ hasSession(cwd) {
32
+ return existsSync(join(cwd, ".aider.chat.history.md"));
33
+ }
34
+ spawn(options) {
35
+ const bin = this.resolveBinary();
36
+ const model = options.model ?? "gpt-4o";
37
+ const args = [
38
+ "--message", options.task,
39
+ "--yes",
40
+ "--no-pretty",
41
+ "--no-stream",
42
+ "--model", model,
43
+ ];
44
+ const env = {
45
+ ...process.env,
46
+ ...(options.env ?? {}),
47
+ };
48
+ // Map token to OPENAI_API_KEY if it looks like an OpenAI key
49
+ if (options.token && options.token.startsWith("sk-")) {
50
+ env.OPENAI_API_KEY = options.token;
51
+ }
52
+ let killed = false;
53
+ const emitter = new BaseAgentProcess();
54
+ let proc;
55
+ try {
56
+ proc = spawn(bin, args, { cwd: options.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
57
+ }
58
+ catch (err) {
59
+ process.nextTick(() => {
60
+ emitter.emit("text", `[aider] Failed to spawn: ${String(err)}\nInstall with: pip install aider-install && aider-install`);
61
+ emitter.emit("exit", 1);
62
+ });
63
+ emitter.kill = () => { killed = true; };
64
+ return emitter;
65
+ }
66
+ emitter.pid = proc.pid;
67
+ let buffer = "";
68
+ proc.stdout?.on("data", (chunk) => {
69
+ const text = chunk.toString();
70
+ buffer += text;
71
+ const lines = buffer.split("\n");
72
+ buffer = lines.pop() ?? "";
73
+ for (const line of lines) {
74
+ if (line.trim())
75
+ emitter.emit("text", line);
76
+ }
77
+ });
78
+ proc.stderr?.on("data", (chunk) => {
79
+ const s = chunk.toString().trim();
80
+ if (s)
81
+ emitter.emit("text", `[aider stderr] ${s}`);
82
+ });
83
+ proc.on("error", (err) => {
84
+ if (!killed) {
85
+ emitter.emit("text", `[aider] Error: ${err.message}\nInstall with: pip install aider-install && aider-install`);
86
+ emitter.emit("exit", 1);
87
+ }
88
+ });
89
+ proc.on("exit", (code) => {
90
+ if (buffer.trim())
91
+ emitter.emit("text", buffer.trim());
92
+ if (!killed)
93
+ emitter.emit("exit", code);
94
+ });
95
+ emitter.kill = (signal) => {
96
+ killed = true;
97
+ try {
98
+ proc.kill((signal ?? "SIGTERM"));
99
+ }
100
+ catch { }
101
+ };
102
+ emitter.writeStdin = (data) => {
103
+ if (proc.stdin && !proc.stdin.destroyed) {
104
+ proc.stdin.write(data);
105
+ }
106
+ };
107
+ return emitter;
108
+ }
109
+ estimateCost(usage, model) {
110
+ if (usage.costUsd != null)
111
+ return usage.costUsd;
112
+ const pricing = getPricing(model ?? "gpt-4o");
113
+ const cost = (usage.inputTokens * pricing.inputPer1M +
114
+ usage.outputTokens * pricing.outputPer1M) /
115
+ 1_000_000;
116
+ return Math.round(cost * 10000) / 10000;
117
+ }
118
+ }
119
+ //# sourceMappingURL=aider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aider.js","sourceRoot":"","sources":["../../src/drivers/aider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent } from "./types.js";
2
+ /**
3
+ * ClaudeCodeDriver wraps the existing runClaude() function from claude.ts.
4
+ * All session management, binary resolution, and stream-json parsing is
5
+ * delegated to the existing implementation — behaviour is byte-for-byte identical.
6
+ */
7
+ export declare class ClaudeCodeDriver implements AgentDriver {
8
+ readonly name = "claude";
9
+ resolveBinary(): string;
10
+ hasSession(cwd: string): boolean;
11
+ spawn(options: SpawnOptions): AgentProcess;
12
+ estimateCost(usage: UsageEvent, model?: string): number;
13
+ }
14
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/drivers/claude-code.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtF;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAClD,QAAQ,CAAC,IAAI,YAAY;IAEzB,aAAa,IAAI,MAAM;IAIvB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAiBhC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY;IA6C1C,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;CAWxD"}
@@ -0,0 +1,86 @@
1
+ import { existsSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { runClaude, resolveClaude } from "../claude.js";
5
+ import { getPricing } from "./pricing.js";
6
+ import { BaseAgentProcess } from "./types.js";
7
+ /**
8
+ * ClaudeCodeDriver wraps the existing runClaude() function from claude.ts.
9
+ * All session management, binary resolution, and stream-json parsing is
10
+ * delegated to the existing implementation — behaviour is byte-for-byte identical.
11
+ */
12
+ export class ClaudeCodeDriver {
13
+ name = "claude";
14
+ resolveBinary() {
15
+ return resolveClaude();
16
+ }
17
+ hasSession(cwd) {
18
+ // Claude stores sessions under ~/.claude/projects/<encoded-cwd>/
19
+ // Path encoding: leading slash stripped, remaining slashes → dashes
20
+ const projectsDir = join(homedir(), ".claude", "projects");
21
+ if (!existsSync(projectsDir))
22
+ return false;
23
+ try {
24
+ // Claude Code encodes the path by stripping the leading '/' and replacing all '/' with '-'
25
+ const encoded = cwd.replace(/^\//, "").replace(/\//g, "-");
26
+ if (existsSync(join(projectsDir, encoded)))
27
+ return true;
28
+ // Some versions prefix with a leading dash
29
+ if (existsSync(join(projectsDir, `-${encoded}`)))
30
+ return true;
31
+ }
32
+ catch {
33
+ // ignore
34
+ }
35
+ return false;
36
+ }
37
+ spawn(options) {
38
+ // Extract ollama config encoded in env by agent.ts
39
+ const ollamaModel = options.env?.CC_DRIVER_OLLAMA_MODEL;
40
+ const ollamaHost = options.env?.CC_DRIVER_OLLAMA_HOST;
41
+ const proc = runClaude(options.task, options.cwd, options.token, {
42
+ continueSession: options.continueSession,
43
+ maxBudgetUsd: options.budgetUsd,
44
+ sessionId: options.sessionId,
45
+ model: options.model,
46
+ ollamaModel,
47
+ ollamaHost,
48
+ });
49
+ // Adapt OneShot interface → AgentProcess interface
50
+ // Main difference: "session" event → "sessionId" event
51
+ const emitter = new BaseAgentProcess();
52
+ proc.on("text", (text) => emitter.emit("text", text));
53
+ proc.on("tool", (name) => emitter.emit("tool", name));
54
+ proc.on("usage", (u) => emitter.emit("usage", u));
55
+ proc.on("session", (id) => emitter.emit("sessionId", id));
56
+ proc.on("error", (err) => {
57
+ // Translate error events into a non-zero exit so agent.ts sees a failure
58
+ emitter.emit("text", `[cc-agent] Claude error: ${err.message}`);
59
+ emitter.emit("exit", 1);
60
+ });
61
+ proc.on("exit", (code) => emitter.emit("exit", code));
62
+ emitter.pid = proc.pid;
63
+ emitter.kill = (signal) => {
64
+ void signal; // ClaudeCodeDriver always SIGTERMs the process group
65
+ proc.kill();
66
+ };
67
+ emitter.writeStdin = (data) => {
68
+ if (proc.stdin && !proc.stdin.destroyed) {
69
+ proc.stdin.write(data);
70
+ }
71
+ };
72
+ return emitter;
73
+ }
74
+ estimateCost(usage, model) {
75
+ if (usage.costUsd != null)
76
+ return usage.costUsd;
77
+ const pricing = getPricing(model ?? "claude-sonnet-4-6");
78
+ const cost = (usage.inputTokens * pricing.inputPer1M +
79
+ usage.outputTokens * pricing.outputPer1M +
80
+ (usage.cacheReadTokens ?? 0) * (pricing.cacheReadPer1M ?? 0) +
81
+ (usage.cacheWriteTokens ?? 0) * (pricing.cacheWritePer1M ?? 0)) /
82
+ 1_000_000;
83
+ return Math.round(cost * 10000) / 10000;
84
+ }
85
+ }
86
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/drivers/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { AgentDriver } from "./types.js";
2
+ export { ClaudeCodeDriver } from "./claude-code.js";
3
+ export { AiderDriver } from "./aider.js";
4
+ export { OpenAICompatibleDriver } from "./openai-compatible.js";
5
+ export type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent, AgentPricing } from "./types.js";
6
+ export { getPricing } from "./pricing.js";
7
+ declare const VALID_DRIVERS: readonly ["claude", "claude-code", "aider", "openai", "openai-compatible", "qwen", "kimi", "deepseek", "pi"];
8
+ export type DriverName = typeof VALID_DRIVERS[number];
9
+ /**
10
+ * Return an AgentDriver instance for the given name.
11
+ * Throws a descriptive error for unknown names.
12
+ */
13
+ export declare function getDriver(name: string): AgentDriver;
14
+ /** Return the list of valid driver names. */
15
+ export declare function listDrivers(): string[];
16
+ /**
17
+ * Return status info for each driver (whether the binary / API key is available).
18
+ */
19
+ export declare function getDriverStatus(): Array<{
20
+ name: string;
21
+ available: boolean;
22
+ note: string;
23
+ }>;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,QAAA,MAAM,aAAa,8GAA+G,CAAC;AACnI,MAAM,MAAM,UAAU,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAsBnD;AAED,6CAA6C;AAC7C,wBAAgB,WAAW,IAAI,MAAM,EAAE,CAEtC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAiD3F"}
@@ -0,0 +1,84 @@
1
+ import { existsSync } from "fs";
2
+ import { ClaudeCodeDriver } from "./claude-code.js";
3
+ import { AiderDriver } from "./aider.js";
4
+ import { OpenAICompatibleDriver } from "./openai-compatible.js";
5
+ export { ClaudeCodeDriver } from "./claude-code.js";
6
+ export { AiderDriver } from "./aider.js";
7
+ export { OpenAICompatibleDriver } from "./openai-compatible.js";
8
+ export { getPricing } from "./pricing.js";
9
+ const VALID_DRIVERS = ["claude", "claude-code", "aider", "openai", "openai-compatible", "qwen", "kimi", "deepseek", "pi"];
10
+ /**
11
+ * Return an AgentDriver instance for the given name.
12
+ * Throws a descriptive error for unknown names.
13
+ */
14
+ export function getDriver(name) {
15
+ switch (name) {
16
+ case "claude":
17
+ case "claude-code":
18
+ return new ClaudeCodeDriver();
19
+ case "aider":
20
+ return new AiderDriver();
21
+ case "openai":
22
+ case "openai-compatible":
23
+ case "qwen":
24
+ case "kimi":
25
+ case "deepseek":
26
+ case "pi":
27
+ return new OpenAICompatibleDriver(name);
28
+ default:
29
+ throw new Error(`Unknown agent driver: '${name}'. Valid drivers: ${VALID_DRIVERS.join(", ")}`);
30
+ }
31
+ }
32
+ /** Return the list of valid driver names. */
33
+ export function listDrivers() {
34
+ return [...VALID_DRIVERS];
35
+ }
36
+ /**
37
+ * Return status info for each driver (whether the binary / API key is available).
38
+ */
39
+ export function getDriverStatus() {
40
+ const drivers = [];
41
+ // Claude Code
42
+ {
43
+ const d = new ClaudeCodeDriver();
44
+ const bin = d.resolveBinary?.() ?? "claude";
45
+ const hasToken = !!(process.env.ANTHROPIC_API_KEY ?? process.env.CLAUDE_CODE_OAUTH_TOKEN ?? process.env.CLAUDE_CODE_TOKEN);
46
+ const hasBin = existsSync(bin);
47
+ drivers.push({
48
+ name: "claude",
49
+ available: hasBin,
50
+ note: hasBin
51
+ ? hasToken ? "binary found, token configured" : "binary found (no token — uses ~/.claude auth)"
52
+ : `binary not found at: ${bin}`,
53
+ });
54
+ }
55
+ // Aider
56
+ {
57
+ const d = new AiderDriver();
58
+ const bin = d.resolveBinary?.() ?? "aider";
59
+ const hasBin = existsSync(bin);
60
+ drivers.push({
61
+ name: "aider",
62
+ available: hasBin,
63
+ note: hasBin ? "binary found" : `aider not installed — run: pip install aider-install && aider-install`,
64
+ });
65
+ }
66
+ // OpenAI-compatible drivers
67
+ const apiDrivers = [
68
+ { name: "openai", envKey: "OPENAI_API_KEY" },
69
+ { name: "qwen", envKey: "QWEN_API_KEY" },
70
+ { name: "kimi", envKey: "KIMI_API_KEY" },
71
+ { name: "deepseek", envKey: "DEEPSEEK_API_KEY" },
72
+ { name: "pi", envKey: "PI_API_KEY" },
73
+ ];
74
+ for (const { name, envKey } of apiDrivers) {
75
+ const hasKey = !!(process.env[envKey] ?? process.env.OPENAI_API_KEY);
76
+ drivers.push({
77
+ name,
78
+ available: hasKey,
79
+ note: hasKey ? `${envKey} configured` : `set ${envKey} or OPENAI_API_KEY to enable`,
80
+ });
81
+ }
82
+ return drivers;
83
+ }
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * OpenAICompatibleDriver — embedded agentic loop for any OpenAI-API-compatible model.
3
+ *
4
+ * Supports: OpenAI, Qwen, Kimi, DeepSeek, Pi, and any other provider with an
5
+ * OpenAI-compatible /v1/chat/completions endpoint.
6
+ *
7
+ * The driver runs a tool-call loop inside cc-agent itself:
8
+ * 1. Call model API with messages + tool definitions
9
+ * 2. If model calls a tool → execute in cwd → append result → continue
10
+ * 3. If model returns text → emit as text events
11
+ * 4. If model outputs TASK_COMPLETE → terminate loop
12
+ * 5. Track token usage → emit usage events
13
+ *
14
+ * Security: tool execution has a 30s timeout; output is truncated to 8000 chars.
15
+ * Max 50 iterations to prevent runaway loops.
16
+ */
17
+ import type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent } from "./types.js";
18
+ export declare class OpenAICompatibleDriver implements AgentDriver {
19
+ readonly name: string;
20
+ constructor(name: string);
21
+ resolveBinary(): string;
22
+ hasSession(_cwd: string): boolean;
23
+ spawn(options: SpawnOptions): AgentProcess;
24
+ private resolveApiKey;
25
+ private resolveBaseUrl;
26
+ private resolveModel;
27
+ /** Resolve a user-provided path safely within cwd. */
28
+ private safePath;
29
+ private executeTool;
30
+ private runLoop;
31
+ estimateCost(usage: UsageEvent, model?: string): number;
32
+ }
33
+ //# sourceMappingURL=openai-compatible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../src/drivers/openai-compatible.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAmItF,qBAAa,sBAAuB,YAAW,WAAW;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;IAIxB,aAAa,IAAI,MAAM;IAIvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY;IAoB1C,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,YAAY;IAKpB,sDAAsD;IACtD,OAAO,CAAC,QAAQ;YAUF,WAAW;YAyDX,OAAO;IAsIrB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;CASxD"}