Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 458bfe18a0 | |||
| 4cfb9b5008 | |||
| 06542e382a | |||
| bcdf6ab5fb | |||
| 314f669f10 | |||
| a24275e21b | |||
| 872e620342 | |||
| 6d9c6fd2b1 |
+26
-7
@@ -49,7 +49,10 @@ export class ClaudeAgent implements Agent {
|
|||||||
try {
|
try {
|
||||||
const result = await spawn({
|
const result = await spawn({
|
||||||
cmd: "bash",
|
cmd: "bash",
|
||||||
args: ["-c", "curl -fsSL https://claude.ai/install.sh | bash -s 1.0.93"],
|
args: [
|
||||||
|
"-c",
|
||||||
|
"curl -fsSL https://claude.ai/install.sh | bash -s 1.0.93",
|
||||||
|
],
|
||||||
env: { ANTHROPIC_API_KEY: this.apiKey },
|
env: { ANTHROPIC_API_KEY: this.apiKey },
|
||||||
timeout: 120000, // 2 minute timeout
|
timeout: 120000, // 2 minute timeout
|
||||||
onStdout: () => {},
|
onStdout: () => {},
|
||||||
@@ -57,7 +60,9 @@ export class ClaudeAgent implements Agent {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
throw new Error(`Installation failed with exit code ${result.exitCode}: ${result.stderr}`);
|
throw new Error(
|
||||||
|
`Installation failed with exit code ${result.exitCode}: ${result.stderr}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
core.info("Claude Code installed successfully");
|
core.info("Claude Code installed successfully");
|
||||||
@@ -80,12 +85,15 @@ export class ClaudeAgent implements Agent {
|
|||||||
"--output-format",
|
"--output-format",
|
||||||
"stream-json",
|
"stream-json",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
|
"--debug",
|
||||||
"--permission-mode",
|
"--permission-mode",
|
||||||
"bypassPermissions",
|
"bypassPermissions",
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!process.env.GITHUB_INSTALLATION_TOKEN) {
|
if (!process.env.GITHUB_INSTALLATION_TOKEN) {
|
||||||
throw new Error("GITHUB_INSTALLATION_TOKEN is required for GitHub integration");
|
throw new Error(
|
||||||
|
"GITHUB_INSTALLATION_TOKEN is required for GitHub integration"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mcpConfig = createMcpConfig(process.env.GITHUB_INSTALLATION_TOKEN);
|
const mcpConfig = createMcpConfig(process.env.GITHUB_INSTALLATION_TOKEN);
|
||||||
@@ -151,7 +159,8 @@ export class ClaudeAgent implements Agent {
|
|||||||
try {
|
try {
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
} catch {}
|
} catch {}
|
||||||
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
const errorMessage =
|
||||||
|
error instanceof Error ? error.message : "Unknown error";
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: `Failed to execute Claude Code: ${errorMessage}`,
|
error: `Failed to execute Claude Code: ${errorMessage}`,
|
||||||
@@ -177,7 +186,12 @@ function processJSONChunk(chunk: string, agent?: ClaudeAgent): void {
|
|||||||
["model", parsedChunk.model],
|
["model", parsedChunk.model],
|
||||||
["cwd", parsedChunk.cwd],
|
["cwd", parsedChunk.cwd],
|
||||||
["permission_mode", parsedChunk.permissionMode],
|
["permission_mode", parsedChunk.permissionMode],
|
||||||
["tools", parsedChunk.tools?.length ? `${parsedChunk.tools.length} tools` : "none"],
|
[
|
||||||
|
"tools",
|
||||||
|
parsedChunk.tools?.length
|
||||||
|
? `${parsedChunk.tools.length} tools`
|
||||||
|
: "none",
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"mcp_servers",
|
"mcp_servers",
|
||||||
parsedChunk.mcp_servers?.length
|
parsedChunk.mcp_servers?.length
|
||||||
@@ -204,7 +218,9 @@ function processJSONChunk(chunk: string, agent?: ClaudeAgent): void {
|
|||||||
for (const content of parsedChunk.message.content) {
|
for (const content of parsedChunk.message.content) {
|
||||||
if (content.type === "text") {
|
if (content.type === "text") {
|
||||||
if (content.text.trim()) {
|
if (content.text.trim()) {
|
||||||
core.info(boxString(content.text.trim(), { title: "Claude Code" }));
|
core.info(
|
||||||
|
boxString(content.text.trim(), { title: "Claude Code" })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (content.type === "tool_use") {
|
} else if (content.type === "tool_use") {
|
||||||
if (agent) {
|
if (agent) {
|
||||||
@@ -289,7 +305,10 @@ function processJSONChunk(chunk: string, agent?: ClaudeAgent): void {
|
|||||||
if (parsedChunk.subtype === "success") {
|
if (parsedChunk.subtype === "success") {
|
||||||
core.info(
|
core.info(
|
||||||
tableString([
|
tableString([
|
||||||
["Cost", `$${parsedChunk.total_cost_usd?.toFixed(4) || "0.0000"}`],
|
[
|
||||||
|
"Cost",
|
||||||
|
`$${parsedChunk.total_cost_usd?.toFixed(4) || "0.0000"}`,
|
||||||
|
],
|
||||||
["Input Tokens", parsedChunk.usage?.input_tokens || 0],
|
["Input Tokens", parsedChunk.usage?.input_tokens || 0],
|
||||||
["Output Tokens", parsedChunk.usage?.output_tokens || 0],
|
["Output Tokens", parsedChunk.usage?.output_tokens || 0],
|
||||||
["Duration", `${parsedChunk.duration_ms}ms`],
|
["Duration", `${parsedChunk.duration_ms}ms`],
|
||||||
|
|||||||
@@ -25508,7 +25508,9 @@ var actionPath = process.env.GITHUB_ACTION_PATH || process.cwd();
|
|||||||
function createMcpConfig(githubInstallationToken) {
|
function createMcpConfig(githubInstallationToken) {
|
||||||
const githubRepository = process.env.GITHUB_REPOSITORY;
|
const githubRepository = process.env.GITHUB_REPOSITORY;
|
||||||
if (!githubRepository) {
|
if (!githubRepository) {
|
||||||
throw new Error("GITHUB_REPOSITORY environment variable is required for MCP GitHub integration");
|
throw new Error(
|
||||||
|
"GITHUB_REPOSITORY environment variable is required for MCP GitHub integration"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return JSON.stringify(
|
return JSON.stringify(
|
||||||
{
|
{
|
||||||
@@ -25518,7 +25520,8 @@ function createMcpConfig(githubInstallationToken) {
|
|||||||
args: [`${actionPath}/mcp/server.ts`],
|
args: [`${actionPath}/mcp/server.ts`],
|
||||||
env: {
|
env: {
|
||||||
GITHUB_INSTALLATION_TOKEN: githubInstallationToken,
|
GITHUB_INSTALLATION_TOKEN: githubInstallationToken,
|
||||||
GITHUB_REPOSITORY: githubRepository
|
GITHUB_REPOSITORY: githubRepository,
|
||||||
|
LOG_LEVEL: "debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25731,7 +25734,10 @@ var ClaudeAgent = class {
|
|||||||
try {
|
try {
|
||||||
const result = await spawn({
|
const result = await spawn({
|
||||||
cmd: "bash",
|
cmd: "bash",
|
||||||
args: ["-c", "curl -fsSL https://claude.ai/install.sh | bash -s 1.0.93"],
|
args: [
|
||||||
|
"-c",
|
||||||
|
"curl -fsSL https://claude.ai/install.sh | bash -s 1.0.93"
|
||||||
|
],
|
||||||
env: { ANTHROPIC_API_KEY: this.apiKey },
|
env: { ANTHROPIC_API_KEY: this.apiKey },
|
||||||
timeout: 12e4,
|
timeout: 12e4,
|
||||||
// 2 minute timeout
|
// 2 minute timeout
|
||||||
@@ -25740,7 +25746,9 @@ var ClaudeAgent = class {
|
|||||||
onStderr: (chunk) => process.stderr.write(chunk)
|
onStderr: (chunk) => process.stderr.write(chunk)
|
||||||
});
|
});
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
throw new Error(`Installation failed with exit code ${result.exitCode}: ${result.stderr}`);
|
throw new Error(
|
||||||
|
`Installation failed with exit code ${result.exitCode}: ${result.stderr}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
core.info("Claude Code installed successfully");
|
core.info("Claude Code installed successfully");
|
||||||
} catch (error2) {
|
} catch (error2) {
|
||||||
@@ -25760,11 +25768,14 @@ var ClaudeAgent = class {
|
|||||||
"--output-format",
|
"--output-format",
|
||||||
"stream-json",
|
"stream-json",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
|
"--debug",
|
||||||
"--permission-mode",
|
"--permission-mode",
|
||||||
"bypassPermissions"
|
"bypassPermissions"
|
||||||
];
|
];
|
||||||
if (!process.env.GITHUB_INSTALLATION_TOKEN) {
|
if (!process.env.GITHUB_INSTALLATION_TOKEN) {
|
||||||
throw new Error("GITHUB_INSTALLATION_TOKEN is required for GitHub integration");
|
throw new Error(
|
||||||
|
"GITHUB_INSTALLATION_TOKEN is required for GitHub integration"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const mcpConfig = createMcpConfig(process.env.GITHUB_INSTALLATION_TOKEN);
|
const mcpConfig = createMcpConfig(process.env.GITHUB_INSTALLATION_TOKEN);
|
||||||
console.log("\u{1F4CB} MCP Config:", mcpConfig);
|
console.log("\u{1F4CB} MCP Config:", mcpConfig);
|
||||||
@@ -25847,7 +25858,10 @@ function processJSONChunk(chunk, agent) {
|
|||||||
["model", parsedChunk.model],
|
["model", parsedChunk.model],
|
||||||
["cwd", parsedChunk.cwd],
|
["cwd", parsedChunk.cwd],
|
||||||
["permission_mode", parsedChunk.permissionMode],
|
["permission_mode", parsedChunk.permissionMode],
|
||||||
["tools", parsedChunk.tools?.length ? `${parsedChunk.tools.length} tools` : "none"],
|
[
|
||||||
|
"tools",
|
||||||
|
parsedChunk.tools?.length ? `${parsedChunk.tools.length} tools` : "none"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"mcp_servers",
|
"mcp_servers",
|
||||||
parsedChunk.mcp_servers?.length ? `${parsedChunk.mcp_servers.length} servers` : "none"
|
parsedChunk.mcp_servers?.length ? `${parsedChunk.mcp_servers.length} servers` : "none"
|
||||||
@@ -25868,7 +25882,9 @@ function processJSONChunk(chunk, agent) {
|
|||||||
for (const content of parsedChunk.message.content) {
|
for (const content of parsedChunk.message.content) {
|
||||||
if (content.type === "text") {
|
if (content.type === "text") {
|
||||||
if (content.text.trim()) {
|
if (content.text.trim()) {
|
||||||
core.info(boxString(content.text.trim(), { title: "Claude Code" }));
|
core.info(
|
||||||
|
boxString(content.text.trim(), { title: "Claude Code" })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (content.type === "tool_use") {
|
} else if (content.type === "tool_use") {
|
||||||
if (agent) {
|
if (agent) {
|
||||||
@@ -25935,7 +25951,10 @@ function processJSONChunk(chunk, agent) {
|
|||||||
if (parsedChunk.subtype === "success") {
|
if (parsedChunk.subtype === "success") {
|
||||||
core.info(
|
core.info(
|
||||||
tableString([
|
tableString([
|
||||||
["Cost", `$${parsedChunk.total_cost_usd?.toFixed(4) || "0.0000"}`],
|
[
|
||||||
|
"Cost",
|
||||||
|
`$${parsedChunk.total_cost_usd?.toFixed(4) || "0.0000"}`
|
||||||
|
],
|
||||||
["Input Tokens", parsedChunk.usage?.input_tokens || 0],
|
["Input Tokens", parsedChunk.usage?.input_tokens || 0],
|
||||||
["Output Tokens", parsedChunk.usage?.output_tokens || 0],
|
["Output Tokens", parsedChunk.usage?.output_tokens || 0],
|
||||||
["Duration", `${parsedChunk.duration_ms}ms`],
|
["Duration", `${parsedChunk.duration_ms}ms`],
|
||||||
|
|||||||
+4
-1
@@ -6,7 +6,9 @@ const actionPath = process.env.GITHUB_ACTION_PATH || process.cwd();
|
|||||||
export function createMcpConfig(githubInstallationToken: string) {
|
export function createMcpConfig(githubInstallationToken: string) {
|
||||||
const githubRepository = process.env.GITHUB_REPOSITORY;
|
const githubRepository = process.env.GITHUB_REPOSITORY;
|
||||||
if (!githubRepository) {
|
if (!githubRepository) {
|
||||||
throw new Error('GITHUB_REPOSITORY environment variable is required for MCP GitHub integration');
|
throw new Error(
|
||||||
|
"GITHUB_REPOSITORY environment variable is required for MCP GitHub integration"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.stringify(
|
return JSON.stringify(
|
||||||
@@ -18,6 +20,7 @@ export function createMcpConfig(githubInstallationToken: string) {
|
|||||||
env: {
|
env: {
|
||||||
GITHUB_INSTALLATION_TOKEN: githubInstallationToken,
|
GITHUB_INSTALLATION_TOKEN: githubInstallationToken,
|
||||||
GITHUB_REPOSITORY: githubRepository,
|
GITHUB_REPOSITORY: githubRepository,
|
||||||
|
LOG_LEVEL: "debug",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
+14
-3
@@ -6,6 +6,7 @@ import { Octokit } from "@octokit/rest";
|
|||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { resolveRepoContext } from "../utils/repo-context.ts";
|
import { resolveRepoContext } from "../utils/repo-context.ts";
|
||||||
|
import { writeFileSync } from "fs";
|
||||||
|
|
||||||
const server = new McpServer({
|
const server = new McpServer({
|
||||||
name: "Minimal GitHub Issue Comment Server",
|
name: "Minimal GitHub Issue Comment Server",
|
||||||
@@ -31,7 +32,9 @@ server.tool(
|
|||||||
|
|
||||||
const githubInstallationToken = process.env.GITHUB_INSTALLATION_TOKEN;
|
const githubInstallationToken = process.env.GITHUB_INSTALLATION_TOKEN;
|
||||||
if (!githubInstallationToken) {
|
if (!githubInstallationToken) {
|
||||||
throw new Error("GITHUB_INSTALLATION_TOKEN environment variable is required");
|
throw new Error(
|
||||||
|
"GITHUB_INSTALLATION_TOKEN environment variable is required"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve repository context from environment
|
// Resolve repository context from environment
|
||||||
@@ -66,7 +69,8 @@ server.tool(
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
const errorMessage =
|
||||||
|
error instanceof Error ? error.message : String(error);
|
||||||
return {
|
return {
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
@@ -89,4 +93,11 @@ async function runServer() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
runServer().catch(console.error);
|
runServer().catch((error) => {
|
||||||
|
// Write error to file for GitHub Actions visibility
|
||||||
|
try {
|
||||||
|
writeFileSync('/tmp/mcp-error.log', `${new Date().toISOString()} MCP Server Error: ${error.message}\nStack: ${error.stack}\n`, { flag: 'a' });
|
||||||
|
} catch {}
|
||||||
|
console.error('MCP Server Error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@pullfrog/action",
|
"name": "@pullfrog/action",
|
||||||
"version": "0.0.18",
|
"version": "0.0.24",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"index.js",
|
"index.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user