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.)
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user