94 lines
2.6 KiB
JavaScript
94 lines
2.6 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Claude Safe Run - Team Edition
|
|
*/
|
|
|
|
const { execSync } = require("child_process");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
// ---------- Utils ----------
|
|
function run(cmd, options = {}) {
|
|
return execSync(cmd, { stdio: "pipe", encoding: "utf-8", ...options });
|
|
}
|
|
|
|
function exists(p) {
|
|
return fs.existsSync(p);
|
|
}
|
|
|
|
function fatal(msg) {
|
|
console.error(`❌ ${msg}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// ---------- Args ----------
|
|
const agentPrompt = process.argv[2];
|
|
if (!agentPrompt) {
|
|
fatal("Usage: node scripts/claude-safe-run.js <agent_prompt_path>");
|
|
}
|
|
|
|
if (!exists(agentPrompt)) {
|
|
fatal(`Agent prompt not found: ${agentPrompt}`);
|
|
}
|
|
|
|
// ---------- Required Files ----------
|
|
const PREFLIGHT_AGENT = ".claude/agents/preflight.md";
|
|
const POSTFLIGHT_AGENT = ".claude/agents/postflight.md";
|
|
const RUNS_DIR = ".claude/runs";
|
|
|
|
[PREFLIGHT_AGENT, POSTFLIGHT_AGENT, RUNS_DIR].forEach((p) => {
|
|
if (!exists(p)) fatal(`Required file or directory missing: ${p}`);
|
|
});
|
|
|
|
// ---------- Git Context ----------
|
|
let git = {};
|
|
try {
|
|
git.user = run("git config user.name").trim();
|
|
git.branch = run("git rev-parse --abbrev-ref HEAD").trim();
|
|
git.commit = run("git rev-parse HEAD").trim();
|
|
} catch {
|
|
fatal("Git context unavailable. Are you in a git repository?");
|
|
}
|
|
|
|
// ---------- Metadata ----------
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
const agentName = path.basename(agentPrompt, ".md");
|
|
const runId = `${timestamp}-${agentName}-${git.user.replace(/\s+/g, "_")}`;
|
|
|
|
console.log(`🧠 Claude Safe Run`);
|
|
console.log(`- Agent: ${agentName}`);
|
|
console.log(`- Author: ${git.user}`);
|
|
console.log(`- Branch: ${git.branch}`);
|
|
console.log(`- Commit: ${git.commit}`);
|
|
console.log(`- Run ID: ${runId}`);
|
|
|
|
// ---------- Preflight ----------
|
|
console.log("\n🔍 Running Preflight Agent...");
|
|
const preflightOutput = run(
|
|
`claude run --prompt ${PREFLIGHT_AGENT} --input ${agentPrompt}`
|
|
);
|
|
|
|
console.log(preflightOutput);
|
|
|
|
if (!preflightOutput.includes("PRECHECK: PASS")) {
|
|
fatal("Preflight check failed or unclear. Execution aborted.");
|
|
}
|
|
|
|
// ---------- Run Main Agent ----------
|
|
console.log("\n🚀 Running Main Agent...");
|
|
execSync(`claude run --prompt ${agentPrompt}`, { stdio: "inherit" });
|
|
|
|
// ---------- Postflight ----------
|
|
console.log("\n🧪 Running Postflight Agent...");
|
|
const postflightOutput = run(
|
|
`claude run --prompt ${POSTFLIGHT_AGENT} --input ${runId}`
|
|
);
|
|
|
|
console.log(postflightOutput);
|
|
|
|
if (!postflightOutput.includes("POSTCHECK: PASS")) {
|
|
fatal("Postflight validation failed. Run logs invalid or missing.");
|
|
}
|
|
|
|
console.log("\n✅ Claude run completed successfully.");
|
|
console.log(`📄 Run ID: ${runId}`); |