mirror of
https://github.com/markwylde/claude-code-gitea-action.git
synced 2026-02-19 18:12:50 +08:00
Attempt to make this work
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
import Anthropic from "@anthropic-ai/sdk";
|
||||
import * as fs from "fs";
|
||||
import { spawn } from "child_process";
|
||||
import { promisify } from "util";
|
||||
|
||||
export interface ClaudeExecutorConfig {
|
||||
apiKey?: string;
|
||||
@@ -23,43 +25,43 @@ export interface ClaudeExecutorResult {
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface MCPServer {
|
||||
command: string;
|
||||
args: string[];
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface MCPConfig {
|
||||
mcpServers: Record<string, MCPServer>;
|
||||
}
|
||||
|
||||
export class ClaudeExecutor {
|
||||
private config: ClaudeExecutorConfig;
|
||||
private anthropic?: Anthropic;
|
||||
|
||||
constructor(config: ClaudeExecutorConfig) {
|
||||
this.config = config;
|
||||
this.initializeClient();
|
||||
}
|
||||
|
||||
private initializeClient() {
|
||||
if (this.config.useBedrock || this.config.useVertex) {
|
||||
throw new Error(
|
||||
"Bedrock and Vertex AI not supported in simplified implementation",
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.config.apiKey) {
|
||||
throw new Error("Anthropic API key is required");
|
||||
}
|
||||
|
||||
this.anthropic = new Anthropic({
|
||||
apiKey: this.config.apiKey,
|
||||
});
|
||||
}
|
||||
|
||||
private async readPrompt(): Promise<string> {
|
||||
console.log("[CLAUDE-EXECUTOR] Reading prompt...");
|
||||
|
||||
if (this.config.prompt) {
|
||||
console.log("[CLAUDE-EXECUTOR] Using direct prompt");
|
||||
return this.config.prompt;
|
||||
}
|
||||
|
||||
if (this.config.promptFile) {
|
||||
console.log(`[CLAUDE-EXECUTOR] Using prompt file: ${this.config.promptFile}`);
|
||||
if (!fs.existsSync(this.config.promptFile)) {
|
||||
console.error(`[CLAUDE-EXECUTOR] Prompt file not found: ${this.config.promptFile}`);
|
||||
throw new Error(`Prompt file not found: ${this.config.promptFile}`);
|
||||
}
|
||||
return fs.readFileSync(this.config.promptFile, "utf-8");
|
||||
const content = fs.readFileSync(this.config.promptFile, "utf-8");
|
||||
console.log(`[CLAUDE-EXECUTOR] Prompt file size: ${content.length} bytes`);
|
||||
return content;
|
||||
}
|
||||
|
||||
console.error("[CLAUDE-EXECUTOR] Neither prompt nor promptFile provided");
|
||||
throw new Error("Either prompt or promptFile must be provided");
|
||||
}
|
||||
|
||||
@@ -95,23 +97,63 @@ export class ClaudeExecutor {
|
||||
return logFile;
|
||||
}
|
||||
|
||||
private async setupMCPConfig(): Promise<string | null> {
|
||||
if (!this.config.mcpConfig) {
|
||||
console.log("[CLAUDE-EXECUTOR] No MCP config provided");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const mcpConfig: MCPConfig = JSON.parse(this.config.mcpConfig);
|
||||
const configFile = "/tmp/mcp-config.json";
|
||||
|
||||
console.log("[CLAUDE-EXECUTOR] Setting up MCP configuration...");
|
||||
console.log("[CLAUDE-EXECUTOR] MCP servers:", Object.keys(mcpConfig.mcpServers));
|
||||
|
||||
fs.writeFileSync(configFile, JSON.stringify(mcpConfig, null, 2));
|
||||
|
||||
console.log("[CLAUDE-EXECUTOR] MCP config written to:", configFile);
|
||||
return configFile;
|
||||
} catch (error) {
|
||||
console.error("[CLAUDE-EXECUTOR] Failed to parse MCP config:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async execute(): Promise<ClaudeExecutorResult> {
|
||||
try {
|
||||
const prompt = await this.readPrompt();
|
||||
const tools = this.parseTools();
|
||||
|
||||
console.log(`[CLAUDE-EXECUTOR] Prompt length: ${prompt.length} characters`);
|
||||
console.log(
|
||||
`Executing Claude with model: ${this.config.model || "claude-3-7-sonnet-20250219"}`,
|
||||
`[CLAUDE-EXECUTOR] Executing Claude with model: ${this.config.model || "claude-3-7-sonnet-20250219"}`,
|
||||
);
|
||||
console.log(`Allowed tools: ${tools.allowed.join(", ") || "none"}`);
|
||||
console.log(`Disallowed tools: ${tools.disallowed.join(", ") || "none"}`);
|
||||
console.log(`[CLAUDE-EXECUTOR] Allowed tools: ${tools.allowed.join(", ") || "none"}`);
|
||||
console.log(`[CLAUDE-EXECUTOR] Disallowed tools: ${tools.disallowed.join(", ") || "none"}`);
|
||||
|
||||
if (!this.anthropic) {
|
||||
throw new Error("Anthropic client not initialized");
|
||||
// For now, just log that we're using the simple API approach
|
||||
console.log("[CLAUDE-EXECUTOR] WARNING: Using simple Anthropic API - MCP tools not supported in this implementation");
|
||||
console.log("[CLAUDE-EXECUTOR] This explains why Claude cannot use mcp__local_git_ops tools");
|
||||
|
||||
if (this.config.mcpConfig) {
|
||||
console.log("[CLAUDE-EXECUTOR] MCP config provided but not used:");
|
||||
console.log(this.config.mcpConfig.substring(0, 200) + "...");
|
||||
}
|
||||
|
||||
// Create a simple message request
|
||||
const response = await this.anthropic.messages.create({
|
||||
if (!this.config.apiKey) {
|
||||
throw new Error("Anthropic API key is required");
|
||||
}
|
||||
|
||||
const anthropic = new Anthropic({
|
||||
apiKey: this.config.apiKey,
|
||||
});
|
||||
|
||||
console.log("[CLAUDE-EXECUTOR] Starting simple Anthropic API call...");
|
||||
console.log("[CLAUDE-EXECUTOR] Prompt preview:", prompt.substring(0, 500) + "...");
|
||||
|
||||
// Create a simple message request
|
||||
const response = await anthropic.messages.create({
|
||||
model: this.config.model || "claude-3-7-sonnet-20250219",
|
||||
max_tokens: 8192,
|
||||
messages: [
|
||||
@@ -122,7 +164,12 @@ export class ClaudeExecutor {
|
||||
],
|
||||
});
|
||||
|
||||
console.log("Claude response received successfully");
|
||||
console.log("[CLAUDE-EXECUTOR] Claude response received successfully");
|
||||
console.log("[CLAUDE-EXECUTOR] Response type:", response.content[0]?.type);
|
||||
|
||||
if (response.content[0]?.type === "text") {
|
||||
console.log("[CLAUDE-EXECUTOR] Response preview:", response.content[0].text.substring(0, 500) + "...");
|
||||
}
|
||||
|
||||
const executionFile = this.createExecutionLog(response);
|
||||
|
||||
@@ -131,7 +178,7 @@ export class ClaudeExecutor {
|
||||
executionFile,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Claude execution failed:", error);
|
||||
console.error("[CLAUDE-EXECUTOR] Claude execution failed:", error);
|
||||
|
||||
const executionFile = this.createExecutionLog(null, String(error));
|
||||
|
||||
|
||||
@@ -5,6 +5,17 @@ import { runClaude, type ClaudeExecutorConfig } from "../claude/executor";
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
console.log("[EXECUTE-CLAUDE] Starting execute-claude.ts entry point...");
|
||||
console.log(`[EXECUTE-CLAUDE] ANTHROPIC_API_KEY: ${process.env.ANTHROPIC_API_KEY ? '***' : 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] MODEL: ${process.env.MODEL || 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] ANTHROPIC_MODEL: ${process.env.ANTHROPIC_MODEL || 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] PROMPT_FILE: ${process.env.PROMPT_FILE || 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] ALLOWED_TOOLS: ${process.env.ALLOWED_TOOLS || 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] DISALLOWED_TOOLS: ${process.env.DISALLOWED_TOOLS || 'undefined'}`);
|
||||
console.log(`[EXECUTE-CLAUDE] MCP_CONFIG length: ${process.env.MCP_CONFIG?.length || 0}`);
|
||||
console.log(`[EXECUTE-CLAUDE] USE_BEDROCK: ${process.env.USE_BEDROCK}`);
|
||||
console.log(`[EXECUTE-CLAUDE] USE_VERTEX: ${process.env.USE_VERTEX}`);
|
||||
|
||||
const config: ClaudeExecutorConfig = {
|
||||
apiKey: process.env.ANTHROPIC_API_KEY,
|
||||
model: process.env.ANTHROPIC_MODEL || process.env.MODEL,
|
||||
@@ -23,7 +34,7 @@ async function main() {
|
||||
useVertex: process.env.USE_VERTEX === "true",
|
||||
};
|
||||
|
||||
console.log("Starting Claude execution...");
|
||||
console.log("[EXECUTE-CLAUDE] Configuration prepared, starting Claude execution...");
|
||||
const result = await runClaude(config);
|
||||
|
||||
// Set outputs for GitHub Actions
|
||||
|
||||
@@ -6,6 +6,14 @@ export async function prepareMcpConfig(
|
||||
repo: string,
|
||||
branch: string,
|
||||
): Promise<string> {
|
||||
console.log("[MCP-INSTALL] Preparing MCP configuration...");
|
||||
console.log(`[MCP-INSTALL] Owner: ${owner}`);
|
||||
console.log(`[MCP-INSTALL] Repo: ${repo}`);
|
||||
console.log(`[MCP-INSTALL] Branch: ${branch}`);
|
||||
console.log(`[MCP-INSTALL] GitHub token: ${githubToken ? '***' : 'undefined'}`);
|
||||
console.log(`[MCP-INSTALL] GITHUB_ACTION_PATH: ${process.env.GITHUB_ACTION_PATH}`);
|
||||
console.log(`[MCP-INSTALL] GITHUB_WORKSPACE: ${process.env.GITHUB_WORKSPACE}`);
|
||||
|
||||
try {
|
||||
const mcpConfig = {
|
||||
mcpServers: {
|
||||
@@ -42,8 +50,14 @@ export async function prepareMcpConfig(
|
||||
},
|
||||
};
|
||||
|
||||
return JSON.stringify(mcpConfig, null, 2);
|
||||
const configString = JSON.stringify(mcpConfig, null, 2);
|
||||
console.log("[MCP-INSTALL] Generated MCP configuration:");
|
||||
console.log(configString);
|
||||
console.log("[MCP-INSTALL] MCP config generation completed successfully");
|
||||
|
||||
return configString;
|
||||
} catch (error) {
|
||||
console.error("[MCP-INSTALL] MCP config generation failed:", error);
|
||||
core.setFailed(`Install MCP server failed with error: ${error}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -15,9 +15,17 @@ const REPO_DIR = process.env.REPO_DIR || process.cwd();
|
||||
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
|
||||
const GITEA_API_URL = process.env.GITEA_API_URL || "https://api.github.com";
|
||||
|
||||
console.log(`[LOCAL-GIT-MCP] Starting Local Git Operations MCP Server`);
|
||||
console.log(`[LOCAL-GIT-MCP] REPO_OWNER: ${REPO_OWNER}`);
|
||||
console.log(`[LOCAL-GIT-MCP] REPO_NAME: ${REPO_NAME}`);
|
||||
console.log(`[LOCAL-GIT-MCP] BRANCH_NAME: ${BRANCH_NAME}`);
|
||||
console.log(`[LOCAL-GIT-MCP] REPO_DIR: ${REPO_DIR}`);
|
||||
console.log(`[LOCAL-GIT-MCP] GITEA_API_URL: ${GITEA_API_URL}`);
|
||||
console.log(`[LOCAL-GIT-MCP] GITHUB_TOKEN: ${GITHUB_TOKEN ? '***' : 'undefined'}`);
|
||||
|
||||
if (!REPO_OWNER || !REPO_NAME || !BRANCH_NAME) {
|
||||
console.error(
|
||||
"Error: REPO_OWNER, REPO_NAME, and BRANCH_NAME environment variables are required",
|
||||
"[LOCAL-GIT-MCP] Error: REPO_OWNER, REPO_NAME, and BRANCH_NAME environment variables are required",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -30,19 +38,20 @@ const server = new McpServer({
|
||||
// Helper function to run git commands
|
||||
function runGitCommand(command: string): string {
|
||||
try {
|
||||
console.log(`Running git command: ${command}`);
|
||||
console.log(`[LOCAL-GIT-MCP] Running git command: ${command}`);
|
||||
console.log(`[LOCAL-GIT-MCP] Working directory: ${REPO_DIR}`);
|
||||
const result = execSync(command, {
|
||||
cwd: REPO_DIR,
|
||||
encoding: "utf8",
|
||||
stdio: ["inherit", "pipe", "pipe"],
|
||||
});
|
||||
console.log(`Git command result: ${result.trim()}`);
|
||||
console.log(`[LOCAL-GIT-MCP] Git command result: ${result.trim()}`);
|
||||
return result.trim();
|
||||
} catch (error: any) {
|
||||
console.error(`Git command failed: ${command}`);
|
||||
console.error(`Error: ${error.message}`);
|
||||
if (error.stdout) console.error(`Stdout: ${error.stdout}`);
|
||||
if (error.stderr) console.error(`Stderr: ${error.stderr}`);
|
||||
console.error(`[LOCAL-GIT-MCP] Git command failed: ${command}`);
|
||||
console.error(`[LOCAL-GIT-MCP] Error: ${error.message}`);
|
||||
if (error.stdout) console.error(`[LOCAL-GIT-MCP] Stdout: ${error.stdout}`);
|
||||
if (error.stderr) console.error(`[LOCAL-GIT-MCP] Stderr: ${error.stderr}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -104,16 +113,21 @@ server.tool(
|
||||
message: z.string().describe("Commit message"),
|
||||
},
|
||||
async ({ files, message }) => {
|
||||
console.log(`[LOCAL-GIT-MCP] commit_files called with files: ${JSON.stringify(files)}, message: ${message}`);
|
||||
try {
|
||||
// Add the specified files
|
||||
console.log(`[LOCAL-GIT-MCP] Adding ${files.length} files to git...`);
|
||||
for (const file of files) {
|
||||
const filePath = file.startsWith("/") ? file.slice(1) : file;
|
||||
console.log(`[LOCAL-GIT-MCP] Adding file: ${filePath}`);
|
||||
runGitCommand(`git add "${filePath}"`);
|
||||
}
|
||||
|
||||
// Commit the changes
|
||||
console.log(`[LOCAL-GIT-MCP] Committing with message: ${message}`);
|
||||
runGitCommand(`git commit -m "${message}"`);
|
||||
|
||||
console.log(`[LOCAL-GIT-MCP] Successfully committed ${files.length} files`);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
@@ -125,6 +139,7 @@ server.tool(
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : String(error);
|
||||
console.error(`[LOCAL-GIT-MCP] Error committing files: ${errorMessage}`);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
@@ -308,10 +323,14 @@ server.tool(
|
||||
|
||||
// Get git status tool
|
||||
server.tool("git_status", "Get the current git status", {}, async () => {
|
||||
console.log(`[LOCAL-GIT-MCP] git_status called`);
|
||||
try {
|
||||
const status = runGitCommand("git status --porcelain");
|
||||
const currentBranch = runGitCommand("git rev-parse --abbrev-ref HEAD");
|
||||
|
||||
console.log(`[LOCAL-GIT-MCP] Current branch: ${currentBranch}`);
|
||||
console.log(`[LOCAL-GIT-MCP] Git status: ${status || "Working tree clean"}`);
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
@@ -322,6 +341,7 @@ server.tool("git_status", "Get the current git status", {}, async () => {
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
console.error(`[LOCAL-GIT-MCP] Error getting git status: ${errorMessage}`);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
@@ -336,11 +356,19 @@ server.tool("git_status", "Get the current git status", {}, async () => {
|
||||
});
|
||||
|
||||
async function runServer() {
|
||||
console.log(`[LOCAL-GIT-MCP] Starting MCP server transport...`);
|
||||
const transport = new StdioServerTransport();
|
||||
console.log(`[LOCAL-GIT-MCP] Connecting to transport...`);
|
||||
await server.connect(transport);
|
||||
console.log(`[LOCAL-GIT-MCP] MCP server connected and ready!`);
|
||||
process.on("exit", () => {
|
||||
console.log(`[LOCAL-GIT-MCP] Server shutting down...`);
|
||||
server.close();
|
||||
});
|
||||
}
|
||||
|
||||
runServer().catch(console.error);
|
||||
console.log(`[LOCAL-GIT-MCP] Calling runServer()...`);
|
||||
runServer().catch((error) => {
|
||||
console.error(`[LOCAL-GIT-MCP] Server startup failed:`, error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user