firegoat 0.0.2 → 0.2.0

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/package.json CHANGED
@@ -1,27 +1,42 @@
1
1
  {
2
- "name": "firegoat",
3
- "version": "0.0.2",
4
- "description": "Local-first AX evals: how well coding agents use your SDK, CLI, API and docs.",
5
- "license": "MIT",
6
- "type": "module",
7
- "bin": {
8
- "firegoat": "bin/firegoat.js"
9
- },
10
- "files": [
11
- "bin"
12
- ],
13
- "engines": {
14
- "node": ">=18"
15
- },
16
- "repository": {
17
- "type": "git",
18
- "url": "git+https://github.com/team2027/firegoat-cli.git"
19
- },
20
- "homepage": "https://github.com/team2027/firegoat-cli#readme",
21
- "publishConfig": {
22
- "access": "public"
23
- },
24
- "scripts": {
25
- "test": "node --test"
26
- }
2
+ "name": "firegoat",
3
+ "version": "0.2.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/team2027/firegoat-cli.git"
7
+ },
8
+ "devDependencies": {
9
+ "@biomejs/biome": "^2.5.15",
10
+ "@types/bun": "latest",
11
+ "yaml": "^2.9.1"
12
+ },
13
+ "peerDependencies": {
14
+ "typescript": "^7"
15
+ },
16
+ "bin": {
17
+ "firegoat": "dist/cli.js"
18
+ },
19
+ "description": "Local-first AX evals: how well coding agents use your SDK, CLI, API and docs.",
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "skills"
26
+ ],
27
+ "homepage": "https://github.com/team2027/firegoat-cli#readme",
28
+ "license": "MIT",
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "build": "bun build src/cli.ts --target node --outfile dist/cli.js",
34
+ "test": "bun test",
35
+ "typecheck": "bun check",
36
+ "lint": "biome check .",
37
+ "format": "biome check --write .",
38
+ "prepack": "bun run build"
39
+ },
40
+ "type": "module",
41
+ "packageManager": "bun@1.4.3"
27
42
  }
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: firegoat-onboarding
3
+ description: Draft 2-3 firegoat evals (firegoat.yaml) for the current repo by reading its README, docs and package manifests, phrasing each test as a real user's problem with a gradeable goal and script checks. Use when the user says "write firegoat evals", "draft evals", "set up firegoat", "firegoat init", or asks for agent-experience (AX) evals of their SDK, CLI, API or docs.
4
+ ---
5
+
6
+ # Draft firegoat evals
7
+
8
+ firegoat runs a coding agent (Claude Code) in an empty, isolated workdir with one prompt,
9
+ then grades the run. Your job: write 2-3 tests into `firegoat.yaml` that tell the
10
+ maintainer whether an agent can succeed with their product the way a new user would.
11
+
12
+ ## 1. Learn the product (read, don't run)
13
+
14
+ Read, in this order, and stop when you can answer the questions below:
15
+ - `README*`, then the docs dir (`docs/`, `website/`, `*.mdx`), quickstart/getting-started pages first.
16
+ - Package manifests: `package.json` (`name`, `bin`, `exports`), `pyproject.toml`, `go.mod`,
17
+ `Cargo.toml`, `*.gemspec`, `Package.swift`. They tell you the install name and entry points.
18
+ - `examples/`, `templates/`, `samples/`: the shapes users actually build.
19
+ - An existing `firegoat.yaml`, if any: keep its tests (see step 5).
20
+
21
+ Answer: What is it (SDK, CLI, API, framework)? Who uses it? What is the first thing a new
22
+ user wants to have working? What is the public docs URL? Which credentials does it need
23
+ (env var names only)?
24
+
25
+ ## 2. Pick 2-3 outcomes
26
+
27
+ Choose the most important first-time user outcomes, e.g. "first successful API call",
28
+ "the core feature end to end", "the thing users most often ask about". Prefer outcomes
29
+ that leave observable proof. Skip admin, billing and anything needing a browser login
30
+ unless credentials can come from env vars.
31
+
32
+ ## 3. Write each prompt as a user's problem
33
+
34
+ A prompt is what a user would type to their agent, not a recipe. Each prompt has:
35
+ - **What they want, not how.** No numbered implementation steps, no "use template X, add package Y".
36
+ The eval measures whether the agent finds its way with your docs.
37
+ - **One concrete outcome**, small enough to finish in a few minutes.
38
+ - **Observable proof**: print a marker to stdout, write a file, or take a screenshot.
39
+ - **"Keep it minimal."** so the agent doesn't build a demo app.
40
+ - **The docs URL as the only hint** (omit it if the test is about discovery).
41
+ - **Credentials as env var names**, never values: "Credentials are in env vars ACME_API_KEY and ACME_API_URL."
42
+ - If the test should use the build under test, say so: "The package is already installed
43
+ from the build under test. Do not install or upgrade it from the registry."
44
+
45
+ ## 4. Write the goal and checks
46
+
47
+ `goal`: one sentence a judge could check from the transcript and workdir, e.g. "A minimal
48
+ project runs and prints the answer, a numeric score and a reason."
49
+
50
+ `checks`: shell scripts, run in the agent's workdir after the run. Exit code 0 = pass.
51
+ Env: `FIREGOAT_WORKDIR` (the workdir) and `FIREGOAT_SESSION` (the agent's stream-json
52
+ transcript, one JSON event per line). Checks should prove the outcome and catch cheating:
53
+ - Output exists with the expected marker: `grep -rq hello-from-acme "$FIREGOAT_WORKDIR"`
54
+ or `test -s "$FIREGOAT_WORKDIR/screenshot.png"`.
55
+ - The real thing was used, not faked: the transcript shows the SDK/CLI being called,
56
+ e.g. `grep -q '"command":"[^"]*acme ' "$FIREGOAT_SESSION"`.
57
+ - Cleanup happened: the transcript shows the delete call after the create call.
58
+ - The local build was used, not a registry install:
59
+ `! grep -Eq '"command":"[^"]*(pip install|npm (install|i) [^"]*acme@)' "$FIREGOAT_SESSION"`.
60
+ - Only local docs were used (when that's the point): `! grep -q '"name":"WebFetch"' "$FIREGOAT_SESSION"`.
61
+
62
+ Match tool-call JSON (`"command":"...`) rather than plain words, so the prompt text or the
63
+ agent saying "I won't pip install" doesn't trip the check. Checks run in the agent's
64
+ workdir, which does not contain the repo, so keep them self-contained: one-liners, or a
65
+ `run: |` block for longer scripts. Never reference repo files by relative path.
66
+
67
+ Do not emit `judge:` checks: v1 skips them with a warning.
68
+
69
+ ## 5. Write firegoat.yaml
70
+
71
+ Schema (v1):
72
+
73
+ ```yaml
74
+ agents: [claude-code] # only claude-code in v1
75
+ runs: 1 # runs per test, positive integer
76
+ tests:
77
+ - name: quickstart # letters, digits, '.', '_', '-'; unique
78
+ prompt: >-
79
+ ...
80
+ goal: ...
81
+ checks: # optional
82
+ - run: grep -rq some-marker "$FIREGOAT_WORKDIR"
83
+ timeout: 600 # optional, seconds
84
+ ```
85
+
86
+ If `firegoat.yaml` exists, merge: keep every existing test and top-level key untouched, append
87
+ yours, and rename yours (`-2` suffix) if a name collides. Never delete or rewrite user tests.
88
+ Quote prompts with `>-` folded blocks so colons and quotes stay valid YAML.
89
+
90
+ Before finishing, re-read the file and check: it parses as YAML, every test has a non-empty
91
+ `name`, `prompt` and `goal`, names are unique and match `^[A-Za-z0-9._-]+$`, and no credential
92
+ values appear anywhere.
93
+
94
+ ## 6. Hand off
95
+
96
+ Tell the user, in a few lines: which tests you added and why, which env vars they must export,
97
+ and to run `npx firegoat eval`.
98
+
99
+ ## Examples
100
+
101
+ See `references/examples.md` for good and bad tests with their YAML. Short version:
102
+
103
+ Good: "Create a new app - a coffee timer. Run it on the simulator and get the screenshot."
104
+ Bad: "Create a sandbox. https://docs.acme.dev" with no goal and no checks: every run passes,
105
+ so it measures nothing.
@@ -0,0 +1,114 @@
1
+ # Example firegoat tests
2
+
3
+ Product names are fictional. Copy the shape, not the words.
4
+
5
+ ## Good
6
+
7
+ ### 1. Core feature end to end, printed proof
8
+
9
+ An agent framework with scorers. The prompt names the outcome and what to print; the agent
10
+ has to find how in the docs.
11
+
12
+ ```yaml
13
+ tests:
14
+ - name: agent-with-scorer
15
+ prompt: >-
16
+ Build an agent with a scorer using https://docs.acme.dev/agents. Ask the agent
17
+ to explain recursion in one sentence, then run a scorer that grades whether the
18
+ answer is concise and accurate. Print the agent answer, the numeric score and
19
+ the scorer reason to stdout. Keep it minimal.
20
+ goal: >-
21
+ A minimal project runs and prints the agent's answer, a numeric score and the
22
+ scorer's reason.
23
+ checks:
24
+ - run: grep -Eq '"command":"[^"]*(node|npx|tsx|bun) ' "$FIREGOAT_SESSION"
25
+ ```
26
+
27
+ ### 2. Multi-step workflow, one realistic input
28
+
29
+ ```yaml
30
+ tests:
31
+ - name: support-workflow
32
+ prompt: >-
33
+ Using https://docs.acme.dev/workflows, build a three-step workflow: extract the
34
+ issue type from a support message, have an agent draft a response, then add a
35
+ priority label. Run it once on a customer asking for a refund and print the
36
+ final result. Keep it minimal.
37
+ goal: >-
38
+ The workflow runs once on a refund request and prints a result containing the
39
+ issue type, a drafted response and a priority label.
40
+ ```
41
+
42
+ ### 3. Local build under test, cleanup, no registry install
43
+
44
+ ```yaml
45
+ tests:
46
+ - name: sandbox-hello
47
+ prompt: >-
48
+ Using the Acme Python SDK, create a sandbox, run `echo hello-from-acme` inside
49
+ it, print the output, then delete the sandbox. The package is already installed
50
+ from the build under test. Do not install or upgrade it from PyPI.
51
+ Docs: https://docs.acme.dev/python. Credentials are in env vars ACME_API_KEY
52
+ and ACME_API_URL.
53
+ goal: >-
54
+ The script prints hello-from-acme from inside a sandbox and deletes the sandbox
55
+ at the end.
56
+ checks:
57
+ - run: grep -Eq '\.(delete|remove)\(' -r "$FIREGOAT_WORKDIR" --include='*.py'
58
+ - run: "! grep -Eq '\"command\":\"[^\"]*pip3? install[^\"]*acme' \"$FIREGOAT_SESSION\""
59
+ timeout: 900
60
+ ```
61
+
62
+ ### 4. Pure user need, discovery
63
+
64
+ No docs URL, no package names: the test is whether the agent finds the right packages.
65
+
66
+ ```yaml
67
+ tests:
68
+ - name: which-packages
69
+ prompt: >-
70
+ I'm building a mobile app with Acme. It needs a local database, maps, age
71
+ gating, localization, Sign in with Apple and a small on-device model. Does Acme
72
+ offer packages for these? Which ones would you use?
73
+ goal: >-
74
+ The answer names the right Acme package for each requirement and relies on the
75
+ docs shipped in the project, not web search.
76
+ checks:
77
+ - run: "! grep -q '\"name\":\"WebFetch\"' \"$FIREGOAT_SESSION\""
78
+ ```
79
+
80
+ ### 5. Shortest
81
+
82
+ ```yaml
83
+ tests:
84
+ - name: coffee-timer
85
+ prompt: Create a new app - a coffee timer. Run it on the simulator and get the screenshot.
86
+ goal: A screenshot shows a working coffee timer app running on the simulator.
87
+ checks:
88
+ - run: find "$FIREGOAT_WORKDIR" -name '*.png' -size +1k | grep -q .
89
+ ```
90
+
91
+ ## Bad
92
+
93
+ ### No goal, no checks
94
+
95
+ ```text
96
+ prompt: "Create a sandbox. https://docs.acme.dev"
97
+ ```
98
+
99
+ Ungradeable: nothing says what success looks like, so every run "succeeds". Add an
100
+ observable outcome ("run echo hello-from-acme inside it and print the output"), a goal
101
+ and a check.
102
+
103
+ ### Implementation steps
104
+
105
+ ```text
106
+ prompt: >-
107
+ 1. Create a project from the acme-starter template.
108
+ 2. Add the acme-maps package.
109
+ 3. Render a map centered on Berlin.
110
+ ```
111
+
112
+ This tests instruction-following, not whether an agent finds its way with your docs.
113
+ Rewrite as the user's need: "Show a map centered on Berlin in a new Acme app. Keep it
114
+ minimal. Take a screenshot."
package/bin/firegoat.js DELETED
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import { readFileSync } from "node:fs";
3
-
4
- const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
5
- const [cmd] = process.argv.slice(2);
6
-
7
- if (cmd === "--version" || cmd === "-v") {
8
- console.log(pkg.version);
9
- process.exit(0);
10
- }
11
-
12
- console.log(`firegoat ${pkg.version}: not built yet. See https://github.com/team2027/firegoat-cli`);
13
- process.exit(cmd ? 1 : 0);