firegoat 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +37 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ tests:
|
|
|
47
47
|
- run: grep -q '"command":"acme deploy' "$FIREGOAT_SESSION"
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
Whatever `setup` writes to `$FIREGOAT_OUT` is first on the agent's `PATH`.
|
|
50
|
+
Whatever `setup` writes to `$FIREGOAT_OUT` is first on the agent's `PATH`. That only helps for binaries called by bare name: if users run your CLI via `npx`/`uvx`, pack and install it like the npm example, or `npx` fetches the registry release.
|
|
51
51
|
|
|
52
52
|
### Can an agent find the right package from my docs alone?
|
|
53
53
|
|
package/dist/cli.js
CHANGED
|
@@ -6947,7 +6947,7 @@ var require_public_api = __commonJS(function(exports) {
|
|
|
6947
6947
|
// package.json
|
|
6948
6948
|
var package_default = {
|
|
6949
6949
|
name: "firegoat",
|
|
6950
|
-
version: "0.9.
|
|
6950
|
+
version: "0.9.4",
|
|
6951
6951
|
repository: {
|
|
6952
6952
|
type: "git",
|
|
6953
6953
|
url: "git+https://github.com/firegoat-ai/firegoat-cli.git"
|
|
@@ -7250,12 +7250,15 @@ async function runClaude(opts) {
|
|
|
7250
7250
|
return;
|
|
7251
7251
|
}
|
|
7252
7252
|
});
|
|
7253
|
-
const init = events
|
|
7254
|
-
if (init
|
|
7253
|
+
const init = events.find((e) => e?.type === "system" && e.subtype === "init");
|
|
7254
|
+
if (!init) {
|
|
7255
|
+
const said = stdout.trim().split(`
|
|
7256
|
+
`)[0]?.slice(0, 300);
|
|
7255
7257
|
return {
|
|
7256
7258
|
ok: false,
|
|
7257
|
-
reason: `claude did not start a session (exit ${exited.code ?? "by signal"}), see stderr.txt`
|
|
7259
|
+
reason: `claude did not start a session (exit ${exited.code ?? "by signal"})${said ? `: ${said}` : ", see stderr.txt"}`
|
|
7258
7260
|
};
|
|
7261
|
+
}
|
|
7259
7262
|
const sessionId = String(init.session_id);
|
|
7260
7263
|
const result = events.findLast((e) => e?.type === "result");
|
|
7261
7264
|
if (exited.timedOut)
|
|
@@ -7274,7 +7277,7 @@ async function runClaude(opts) {
|
|
|
7274
7277
|
if (result.is_error === true || result.subtype !== "success")
|
|
7275
7278
|
return {
|
|
7276
7279
|
ok: false,
|
|
7277
|
-
reason: `claude result is an error (subtype=${result.subtype})`,
|
|
7280
|
+
reason: `claude result is an error (subtype=${result.subtype})${result.result ? `: ${result.result.slice(0, 300)}` : ""}`,
|
|
7278
7281
|
result,
|
|
7279
7282
|
sessionId
|
|
7280
7283
|
};
|
|
@@ -7557,6 +7560,15 @@ function findSession(configDir, sessionId) {
|
|
|
7557
7560
|
}
|
|
7558
7561
|
return null;
|
|
7559
7562
|
}
|
|
7563
|
+
function usage(r) {
|
|
7564
|
+
const parts = [];
|
|
7565
|
+
if (r.cost !== null)
|
|
7566
|
+
parts.push(`$${r.cost.toFixed(2)}`);
|
|
7567
|
+
if (r.num_turns !== null)
|
|
7568
|
+
parts.push(`${r.num_turns} turns`);
|
|
7569
|
+
parts.push(`${Math.round(r.duration_ms / 1000)}s`);
|
|
7570
|
+
return parts.join(", ");
|
|
7571
|
+
}
|
|
7560
7572
|
function newRunId() {
|
|
7561
7573
|
const ts = new Date().toISOString().replace(/\.\d+Z$/, "Z").replace(/[-:]/g, "");
|
|
7562
7574
|
return `${ts}-${randomBytes(2).toString("hex")}`;
|
|
@@ -7690,6 +7702,7 @@ async function evalCommand(args, root) {
|
|
|
7690
7702
|
const firegoatDir = ensureFiregoatDir(root);
|
|
7691
7703
|
const configDir = join3(firegoatDir, ".claude");
|
|
7692
7704
|
mkdirSync2(configDir, { recursive: true });
|
|
7705
|
+
say(process.env.ANTHROPIC_API_KEY ? "auth: ANTHROPIC_API_KEY (claude bills the API key; unset it to use your claude login)" : "auth: your claude login");
|
|
7693
7706
|
const loginProblem = checkLogin({
|
|
7694
7707
|
bin: claudePath,
|
|
7695
7708
|
env: claudeEnv(configDir),
|
|
@@ -7733,7 +7746,7 @@ async function evalCommand(args, root) {
|
|
|
7733
7746
|
vars
|
|
7734
7747
|
});
|
|
7735
7748
|
results.push(r);
|
|
7736
|
-
say(`${r.status.toUpperCase()} ${r.test}#${r.n} ${r.reason}`);
|
|
7749
|
+
say(`${r.status.toUpperCase()} ${r.test}#${r.n} ${r.reason} (${usage(r)})`);
|
|
7737
7750
|
}
|
|
7738
7751
|
const totals = { pass: 0, fail: 0, error: 0 };
|
|
7739
7752
|
for (const r of results)
|
|
@@ -7741,8 +7754,9 @@ async function evalCommand(args, root) {
|
|
|
7741
7754
|
const doc = { runId, runsDir: runDir, totals, runs: results };
|
|
7742
7755
|
writeFileSync2(join3(runDir, "summary.json"), `${JSON.stringify(doc, null, 2)}
|
|
7743
7756
|
`);
|
|
7757
|
+
const cost = results.reduce((sum, r) => sum + (r.cost ?? 0), 0);
|
|
7744
7758
|
say(`
|
|
7745
|
-
${totals.pass} passed, ${totals.fail} failed, ${totals.error} not graded (${results.length} runs)`);
|
|
7759
|
+
${totals.pass} passed, ${totals.fail} failed, ${totals.error} not graded (${results.length} runs, $${cost.toFixed(2)})`);
|
|
7746
7760
|
say(`runs: ${runDir} (end_goal is for you to judge: see run.json per run)`);
|
|
7747
7761
|
if (opts.json)
|
|
7748
7762
|
console.log(JSON.stringify(doc, null, 2));
|
|
@@ -7787,8 +7801,10 @@ runs: 1
|
|
|
7787
7801
|
# setup: uv build --wheel --out-dir "$FIREGOAT_OUT"
|
|
7788
7802
|
# workdir_setup: uv venv && uv pip install "$FIREGOAT_OUT"/*.whl
|
|
7789
7803
|
#
|
|
7790
|
-
# a CLI binary:
|
|
7804
|
+
# a CLI binary users call by bare name (on PATH as is):
|
|
7791
7805
|
# setup: go build -o "$FIREGOAT_OUT/mycli" ./cmd/mycli
|
|
7806
|
+
# (an npm/pypi CLI that users run via npx/uvx: pack + install it as above instead;
|
|
7807
|
+
# a binary on PATH does not stop "npx mycli" from fetching the registry release)
|
|
7792
7808
|
#
|
|
7793
7809
|
# Helper files (scripts, sample data) go in .firegoat/fixtures/ (committed), not inline here.
|
|
7794
7810
|
# setup runs in this folder, so: setup: cp -R .firegoat/fixtures/. "$FIREGOAT_OUT"
|
|
@@ -7871,18 +7887,28 @@ ${INIT_HELP}`);
|
|
|
7871
7887
|
const r = spawnSync2("npx", ["-y", ...SKILLS_ARGV], {
|
|
7872
7888
|
cwd,
|
|
7873
7889
|
env,
|
|
7874
|
-
stdio: "inherit"
|
|
7890
|
+
stdio: interactive ? "inherit" : "pipe",
|
|
7891
|
+
encoding: "utf8"
|
|
7875
7892
|
});
|
|
7876
7893
|
if (r.error || r.status !== 0) {
|
|
7894
|
+
if (!interactive)
|
|
7895
|
+
process.stderr.write(`${r.stdout ?? ""}${r.stderr ?? ""}`);
|
|
7877
7896
|
console.error(`firegoat init: installing the skills failed (${r.error?.message ?? `exit ${r.status}`}). Run it yourself: npx ${SKILLS_ARGV.join(" ")}`);
|
|
7878
7897
|
return EXIT.notGraded;
|
|
7879
7898
|
}
|
|
7899
|
+
console.log("installed skills firegoat-onboarding, suggesting-eval-prompts in .claude/skills/");
|
|
7900
|
+
const ignored = spawnSync2("git", ["check-ignore", "-q", ".claude/skills"], {
|
|
7901
|
+
cwd
|
|
7902
|
+
});
|
|
7903
|
+
if (ignored.status === 0)
|
|
7904
|
+
console.error("warning: git ignores .claude/skills, so teammates and CI won't get the skills. Commit them with: git add -f .claude/skills");
|
|
7880
7905
|
}
|
|
7881
|
-
console.log(`
|
|
7906
|
+
console.log(interactive ? `
|
|
7882
7907
|
Paste this into your coding agent:
|
|
7883
7908
|
|
|
7884
7909
|
${AGENT_PROMPT}
|
|
7885
|
-
`
|
|
7910
|
+
` : `
|
|
7911
|
+
Prompt for your coding agent: ${AGENT_PROMPT}`);
|
|
7886
7912
|
if (interactive && copyToClipboard(AGENT_PROMPT))
|
|
7887
7913
|
console.log("\x1B[32mPrompt copied!\x1B[0m");
|
|
7888
7914
|
return EXIT.pass;
|