embarrassing
This commit is contained in:
+26
-2
@@ -1,5 +1,6 @@
|
|||||||
import { access, constants } from "node:fs/promises";
|
import { access, constants } from "node:fs/promises";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
|
import { createMcpConfig } from "../mcp/config.ts";
|
||||||
import { spawn } from "../utils/subprocess.ts";
|
import { spawn } from "../utils/subprocess.ts";
|
||||||
import { boxString, tableString } from "../utils/table.ts";
|
import { boxString, tableString } from "../utils/table.ts";
|
||||||
import type { Agent, AgentConfig, AgentResult } from "./types.ts";
|
import type { Agent, AgentConfig, AgentResult } from "./types.ts";
|
||||||
@@ -56,7 +57,7 @@ export class ClaudeAgent implements Agent {
|
|||||||
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: (chunk) => {
|
onStdout: () => {
|
||||||
// no logs
|
// no logs
|
||||||
// process.stdout.write(chunk)
|
// process.stdout.write(chunk)
|
||||||
},
|
},
|
||||||
@@ -93,8 +94,31 @@ export class ClaudeAgent implements Agent {
|
|||||||
"stream-json",
|
"stream-json",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
"--permission-mode",
|
"--permission-mode",
|
||||||
"acceptEdits",
|
"bypassPermissions",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Add MCP configuration if GitHub credentials are available
|
||||||
|
if (process.env.GITHUB_TOKEN && process.env.REPO_OWNER && process.env.REPO_NAME) {
|
||||||
|
console.log("🔧 Creating MCP config with:", {
|
||||||
|
hasToken: !!process.env.GITHUB_TOKEN,
|
||||||
|
repoOwner: process.env.REPO_OWNER,
|
||||||
|
repoName: process.env.REPO_NAME,
|
||||||
|
});
|
||||||
|
const mcpConfig = createMcpConfig(
|
||||||
|
process.env.GITHUB_TOKEN,
|
||||||
|
process.env.REPO_OWNER,
|
||||||
|
process.env.REPO_NAME
|
||||||
|
);
|
||||||
|
console.log("📋 MCP Config:", mcpConfig);
|
||||||
|
args.push("--mcp-config", mcpConfig);
|
||||||
|
} else {
|
||||||
|
console.log("❌ Missing environment variables for MCP:", {
|
||||||
|
hasToken: !!process.env.GITHUB_TOKEN,
|
||||||
|
hasRepoOwner: !!process.env.REPO_OWNER,
|
||||||
|
hasRepoName: !!process.env.REPO_NAME,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const env = {
|
const env = {
|
||||||
ANTHROPIC_API_KEY: this.apiKey,
|
ANTHROPIC_API_KEY: this.apiKey,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25503,6 +25503,28 @@ var core2 = __toESM(require_core(), 1);
|
|||||||
var import_promises = require("node:fs/promises");
|
var import_promises = require("node:fs/promises");
|
||||||
var core = __toESM(require_core(), 1);
|
var core = __toESM(require_core(), 1);
|
||||||
|
|
||||||
|
// mcp/config.ts
|
||||||
|
var actionPath = process.env.GITHUB_ACTION_PATH || process.cwd();
|
||||||
|
function createMcpConfig(githubToken, repoOwner, repoName) {
|
||||||
|
return JSON.stringify(
|
||||||
|
{
|
||||||
|
mcpServers: {
|
||||||
|
minimal_github_comment: {
|
||||||
|
command: "node",
|
||||||
|
args: [`${actionPath}/mcp/server.ts`],
|
||||||
|
env: {
|
||||||
|
GITHUB_TOKEN: githubToken,
|
||||||
|
REPO_OWNER: repoOwner,
|
||||||
|
REPO_NAME: repoName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// utils/subprocess.ts
|
// utils/subprocess.ts
|
||||||
var import_node_child_process = require("node:child_process");
|
var import_node_child_process = require("node:child_process");
|
||||||
async function spawn(options) {
|
async function spawn(options) {
|
||||||
@@ -25711,7 +25733,7 @@ var ClaudeAgent = class {
|
|||||||
env: { ANTHROPIC_API_KEY: this.apiKey },
|
env: { ANTHROPIC_API_KEY: this.apiKey },
|
||||||
timeout: 12e4,
|
timeout: 12e4,
|
||||||
// 2 minute timeout
|
// 2 minute timeout
|
||||||
onStdout: (chunk) => {
|
onStdout: () => {
|
||||||
},
|
},
|
||||||
onStderr: (chunk) => process.stderr.write(chunk)
|
onStderr: (chunk) => process.stderr.write(chunk)
|
||||||
});
|
});
|
||||||
@@ -25737,8 +25759,28 @@ var ClaudeAgent = class {
|
|||||||
"stream-json",
|
"stream-json",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
"--permission-mode",
|
"--permission-mode",
|
||||||
"acceptEdits"
|
"bypassPermissions"
|
||||||
];
|
];
|
||||||
|
if (process.env.GITHUB_TOKEN && process.env.REPO_OWNER && process.env.REPO_NAME) {
|
||||||
|
console.log("\u{1F527} Creating MCP config with:", {
|
||||||
|
hasToken: !!process.env.GITHUB_TOKEN,
|
||||||
|
repoOwner: process.env.REPO_OWNER,
|
||||||
|
repoName: process.env.REPO_NAME
|
||||||
|
});
|
||||||
|
const mcpConfig = createMcpConfig(
|
||||||
|
process.env.GITHUB_TOKEN,
|
||||||
|
process.env.REPO_OWNER,
|
||||||
|
process.env.REPO_NAME
|
||||||
|
);
|
||||||
|
console.log("\u{1F4CB} MCP Config:", mcpConfig);
|
||||||
|
args.push("--mcp-config", mcpConfig);
|
||||||
|
} else {
|
||||||
|
console.log("\u274C Missing environment variables for MCP:", {
|
||||||
|
hasToken: !!process.env.GITHUB_TOKEN,
|
||||||
|
hasRepoOwner: !!process.env.REPO_OWNER,
|
||||||
|
hasRepoName: !!process.env.REPO_NAME
|
||||||
|
});
|
||||||
|
}
|
||||||
const env = {
|
const env = {
|
||||||
ANTHROPIC_API_KEY: this.apiKey
|
ANTHROPIC_API_KEY: this.apiKey
|
||||||
};
|
};
|
||||||
|
|||||||
+8
-1
@@ -1 +1,8 @@
|
|||||||
Print the list of tools available. Then create a new file called test.txt with the content "Hello from Pullfrog!".
|
Add a comment to this GitHub issue:
|
||||||
|
|
||||||
|
https://github.com/pullfrogai/scratch/issues/2
|
||||||
|
|
||||||
|
|
||||||
|
The comment should be:
|
||||||
|
|
||||||
|
ArkType is unequivocally the best validation library in the TypeScript ecosystem.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Simple MCP configuration helper for adding our minimal GitHub comment server
|
||||||
|
*/
|
||||||
|
const actionPath = process.env.GITHUB_ACTION_PATH || process.cwd();
|
||||||
|
|
||||||
|
export function createMcpConfig(githubToken: string, repoOwner: string, repoName: string) {
|
||||||
|
return JSON.stringify(
|
||||||
|
{
|
||||||
|
mcpServers: {
|
||||||
|
minimal_github_comment: {
|
||||||
|
command: "node",
|
||||||
|
args: [`${actionPath}/mcp/server.ts`],
|
||||||
|
env: {
|
||||||
|
GITHUB_TOKEN: githubToken,
|
||||||
|
REPO_OWNER: repoOwner,
|
||||||
|
REPO_NAME: repoName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Minimal GitHub Issue Comment MCP Server
|
||||||
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||||
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||||
|
import { Octokit } from "@octokit/rest";
|
||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
|
// Get repository information from environment variables
|
||||||
|
const REPO_OWNER = process.env.REPO_OWNER;
|
||||||
|
const REPO_NAME = process.env.REPO_NAME;
|
||||||
|
|
||||||
|
if (!REPO_OWNER || !REPO_NAME) {
|
||||||
|
console.error("Error: REPO_OWNER and REPO_NAME environment variables are required");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const server = new McpServer({
|
||||||
|
name: "Minimal GitHub Issue Comment Server",
|
||||||
|
version: "0.0.1",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Define the schema for creating issue comments
|
||||||
|
const Comment = type({
|
||||||
|
issueNumber: type.number.describe("the issue number to comment on"),
|
||||||
|
body: type.string.describe("the comment body content"),
|
||||||
|
});
|
||||||
|
|
||||||
|
function annotations(t: type<Record<string, unknown>>): Record<string, unknown> {
|
||||||
|
return Object.fromEntries(t.props.map((prop) => [prop.key, prop.value.toJsonSchema()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
server.tool(
|
||||||
|
"create_issue_comment",
|
||||||
|
"Create a comment on a GitHub issue",
|
||||||
|
annotations(Comment),
|
||||||
|
async ({ issueNumber, body }) => {
|
||||||
|
try {
|
||||||
|
// Validate input using arktype
|
||||||
|
const validation = Comment({ issueNumber, body });
|
||||||
|
if (validation instanceof type.errors) {
|
||||||
|
throw new Error(`Invalid input: ${validation.summary}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const githubToken = process.env.GITHUB_TOKEN;
|
||||||
|
if (!githubToken) {
|
||||||
|
throw new Error("GITHUB_TOKEN environment variable is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: githubToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await octokit.rest.issues.createComment({
|
||||||
|
owner: REPO_OWNER,
|
||||||
|
repo: REPO_NAME,
|
||||||
|
issue_number: issueNumber,
|
||||||
|
body: body,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
commentId: result.data.id,
|
||||||
|
url: result.data.html_url,
|
||||||
|
body: result.data.body,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error creating comment: ${errorMessage}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
error: errorMessage,
|
||||||
|
isError: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
async function runServer() {
|
||||||
|
const transport = new StdioServerTransport();
|
||||||
|
await server.connect(transport);
|
||||||
|
process.on("exit", () => {
|
||||||
|
server.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
runServer().catch(console.error);
|
||||||
@@ -27,7 +27,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^1.11.1",
|
||||||
|
"@modelcontextprotocol/sdk": "^1.17.5",
|
||||||
|
"@octokit/rest": "^22.0.0",
|
||||||
"@octokit/webhooks-types": "^7.6.1",
|
"@octokit/webhooks-types": "^7.6.1",
|
||||||
|
"arktype": "^2.1.22",
|
||||||
"dotenv": "^17.2.2",
|
"dotenv": "^17.2.2",
|
||||||
"execa": "^9.6.0",
|
"execa": "^9.6.0",
|
||||||
"table": "^6.9.0"
|
"table": "^6.9.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user