Files
shockbot/agents/claude.ts
T
Colin McDonnell 1abbd7ff41 Refactor action with agent interface system and make anthropic_api_key optional
- Created extensible agent interface with install() and execute() methods
- Moved Claude Code logic to agents/claude.ts implementing Agent interface
- Added utilities directory for reusable functions (exec, files)
- Refactored index.ts to be minimal (35 lines) using agent abstraction
- Made anthropic_api_key optional in action.yml
- Updated Node.js imports to use node: prefix convention
- Bumped version to 0.0.5
- Architecture now supports multiple agents (OpenAI, Gemini, etc.)
2025-08-28 13:37:20 -07:00

79 lines
2.0 KiB
TypeScript

import * as core from "@actions/core";
import { executeCommand } from "../utils/exec";
import { createTempFile } from "../utils/files";
import type { Agent, AgentConfig, AgentResult } from "./types";
/**
* Claude Code agent implementation
*/
export class ClaudeAgent implements Agent {
private apiKey: string;
constructor(config: AgentConfig) {
if (!config.apiKey) {
throw new Error("Claude agent requires an API key");
}
this.apiKey = config.apiKey;
}
/**
* Install Claude Code CLI
*/
async install(): Promise<void> {
core.info("Installing Claude Code...");
try {
await executeCommand("curl -fsSL https://claude.ai/install.sh | bash -s 1.0.93");
core.info("Claude Code installed successfully");
} catch (error) {
throw new Error(`Failed to install Claude Code: ${error}`);
}
}
/**
* Execute Claude Code with the given prompt
*/
async execute(prompt: string): Promise<AgentResult> {
core.info("Executing Claude Code...");
try {
// Create a temporary file for the prompt
const promptFile = createTempFile(prompt, "prompt.txt");
// Execute Claude Code with the prompt
const command = `$HOME/.local/bin/claude --dangerously-skip-permissions "${promptFile}"`;
core.info(`Executing: ${command}`);
const { stdout, stderr } = await executeCommand(command, {
ANTHROPIC_API_KEY: this.apiKey,
});
if (stderr) {
core.warning(`Claude Code stderr: ${stderr}`);
}
if (stdout) {
core.info("Claude Code output:");
console.log(stdout);
}
core.info("Claude Code executed successfully");
return {
success: true,
output: stdout,
error: stderr || undefined,
metadata: {
promptFile,
command,
},
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error";
return {
success: false,
error: `Failed to execute Claude Code: ${errorMessage}`,
};
}
}
}