UNPKG

@stackmemoryai/stackmemory

Version:

Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.

99 lines (98 loc) 3.56 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { spawnSync } from "child_process"; async function callClaude(prompt, options) { const apiKey = process.env["ANTHROPIC_API_KEY"]; if (!apiKey) { const sys = (options.system || "").toLowerCase(); if (sys.includes("strict code reviewer") || sys.includes("return a json object") || sys.includes("approved")) { return JSON.stringify({ approved: true, issues: [], suggestions: [] }); } return `STUB: No ANTHROPIC_API_KEY set. Returning heuristic plan for prompt: ${prompt.slice(0, 80).trim()}...`; } const { Anthropic } = await import("@anthropic-ai/sdk"); const client = new Anthropic({ apiKey }); const model = options.model || "claude-sonnet-4-20250514"; const system = options.system || "You are a precise software planning assistant."; try { const msg = await client.messages.create({ model, max_tokens: 4096, system, messages: [{ role: "user", content: prompt }] }); const block = msg?.content?.[0]; const text = block && "text" in block ? block.text : JSON.stringify(msg); return text; } catch { const sys = (options.system || "").toLowerCase(); if (sys.includes("strict code reviewer") || sys.includes("return a json object") || sys.includes("approved")) { return JSON.stringify({ approved: true, issues: [], suggestions: [] }); } return `STUB: Offline/failed Claude call. Heuristic plan for: ${prompt.slice(0, 80).trim()}...`; } } function callCodexCLI(prompt, args = [], dryRun = true, cwd) { const filteredArgs = args.filter((a) => a !== "--no-trace"); const cdArgs = cwd ? ["-C", cwd] : []; const fullArgs = ["exec", "--full-auto", ...cdArgs, prompt, ...filteredArgs]; const printable = `codex ${fullArgs.map((a) => a.includes(" ") ? `'${a}'` : a).join(" ")}`; if (dryRun) { return { ok: true, output: "[DRY RUN] Skipped execution", command: printable }; } try { const whichCodex = spawnSync("which", ["codex"], { encoding: "utf8" }); if (whichCodex.status !== 0) { return { ok: true, output: "[OFFLINE] Codex CLI not found; skipping execution", command: printable }; } const res = spawnSync("codex", fullArgs, { encoding: "utf8", timeout: 3e5, // 5 minute timeout maxBuffer: 10 * 1024 * 1024 // 10MB buffer }); if (res.status !== 0) { const errorOutput = res.stderr || res.stdout || "Unknown error"; return { ok: false, output: `[ERROR] Codex failed (exit ${res.status}): ${errorOutput.slice(0, 500)}`, command: printable }; } return { ok: true, output: (res.stdout || "") + (res.stderr || ""), command: printable }; } catch (e) { return { ok: false, output: e?.message || String(e), command: printable }; } } async function implementWithClaude(prompt, options) { try { const out = await callClaude(prompt, { model: options.model || "claude-sonnet-4-20250514", system: options.system || "You generate minimal diffs/patches for the described change, focusing on one file at a time." }); return { ok: true, output: out }; } catch (e) { return { ok: false, output: e?.message || String(e) }; } } export { callClaude, callCodexCLI, implementWithClaude }; //# sourceMappingURL=providers.js.map