This commit is contained in:
Shawn Morreau
2025-11-20 06:54:04 -05:00
27 changed files with 156950 additions and 218 deletions
+1
View File
@@ -19,6 +19,7 @@ export const claude = agent({
process.env.ANTHROPIC_API_KEY = apiKey;
const prompt = addInstructions(payload);
console.log(prompt);
const queryInstance = query({
prompt,
+3 -1
View File
@@ -1,13 +1,15 @@
import type { AgentName } from "../external.ts";
import { claude } from "./claude.ts";
import { codex } from "./codex.ts";
import { cursor } from "./cursor.ts";
import { gemini } from "./gemini.ts";
import type { Agent } from "./shared.ts";
export const agents = {
claude,
codex,
cursor,
gemini,
} as const;
} satisfies Record<AgentName, Agent>;
export type AgentInputKey = (typeof agents)[keyof typeof agents]["inputKeys"][number];
+10 -6
View File
@@ -1,5 +1,5 @@
import type { Payload } from "../external.ts";
import { ghPullfrogMcpName } from "../mcp/index.ts";
import { ghPullfrogMcpName } from "../external.ts";
import { modes } from "../modes.ts";
export const addInstructions = (payload: Payload) =>
@@ -46,16 +46,20 @@ Ensure after your edits are done, your final comments do not contain intermediat
## Mode Selection
choose the appropriate mode based on the prompt payload:
Before starting any work, you must first determine which mode to use by examining the request and calling ${ghPullfrogMcpName}/select_mode.
Available modes:
${[...modes, ...payload.modes].map((w) => ` - "${w.name}": ${w.description}`).join("\n")}
## Modes
${[...modes, ...payload.modes].map((w) => `### ${w.name}\n\n${w.prompt}`).join("\n\n")}
**IMPORTANT**: The first thing you must do is:
1. Examine the user's request/prompt carefully
2. Determine which mode is most appropriate based on the mode descriptions above
3. Call ${ghPullfrogMcpName}/select_mode with the chosen mode name
4. The tool will return detailed instructions for that mode - follow those instructions exactly
************* USER PROMPT *************
${payload.prompt}
${JSON.stringify(payload.event, null, 2)}`;
${typeof payload.event === "string" ? payload.event : JSON.stringify(payload.event, null, 2)}`;
+3 -14
View File
@@ -1,7 +1,5 @@
import { spawnSync } from "node:child_process";
import { chmodSync, createWriteStream, existsSync } from "node:fs";
import { mkdtemp } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { pipeline } from "node:stream/promises";
import type { McpStdioServerConfig } from "@anthropic-ai/claude-agent-sdk";
@@ -108,11 +106,7 @@ export async function installFromNpmTarball({
log.info(`📦 Installing ${packageName}@${resolvedVersion}...`);
// Derive temp directory prefix from package name (remove @, replace / with -, add trailing -)
const tempDirPrefix = packageName.replace("@", "").replace(/\//g, "-") + "-";
// Create temp directory
const tempDir = await mkdtemp(join(tmpdir(), tempDirPrefix));
const tempDir = process.env.PULLFROG_TEMP_DIR!;
const tarballPath = join(tempDir, "package.tgz");
// Download tarball from npm
@@ -279,12 +273,7 @@ export async function installFromCurl({
}: InstallFromCurlParams): Promise<string> {
log.info(`📦 Installing ${executableName}...`);
// Derive temp directory prefix from executable name (sanitize similar to package name)
// Replace any special characters with - and ensure trailing -
const tempDirPrefix = executableName.replace(/[^a-zA-Z0-9]/g, "-") + "-";
// Create temp directory
const tempDir = await mkdtemp(join(tmpdir(), tempDirPrefix));
const tempDir = process.env.PULLFROG_TEMP_DIR!;
const installScriptPath = join(tempDir, "install.sh");
// Download the install script
@@ -302,7 +291,7 @@ export async function installFromCurl({
// Make install script executable
chmodSync(installScriptPath, 0o755);
log.info("Installing to temp directory...");
log.info(`Installing to temp directory at ${tempDir}...`);
// Run the install script with HOME set to temp directory
// The Cursor install script installs to $HOME/.local/bin/{executableName}