@pcamarajr/scout 0.4.0 → 0.6.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/README.md +14 -2
- package/dist/cli.js +9 -19
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/engine.d.ts +29 -0
- package/dist/engine.js +117 -3
- package/dist/engine.js.map +1 -1
- package/dist/init.d.ts +26 -0
- package/dist/init.js +60 -0
- package/dist/init.js.map +1 -0
- package/dist/report.js +4 -0
- package/dist/report.js.map +1 -1
- package/dist/runner/ai-runner.js +3 -3
- package/dist/runner/ai-runner.js.map +1 -1
- package/dist/runner/browser.d.ts +10 -1
- package/dist/runner/browser.js +31 -10
- package/dist/runner/browser.js.map +1 -1
- package/dist/runner/script-runner.d.ts +14 -0
- package/dist/runner/script-runner.js +32 -0
- package/dist/runner/script-runner.js.map +1 -1
- package/dist/runner/video.d.ts +72 -0
- package/dist/runner/video.js +197 -0
- package/dist/runner/video.js.map +1 -0
- package/dist/scaffold.d.ts +31 -0
- package/dist/scaffold.js +82 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/package.json +3 -2
- package/templates/AGENTS.md +100 -0
- package/templates/SKILL.md +25 -0
- package/templates/scout.mdc +21 -0
package/dist/scaffold.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
/**
|
|
5
|
+
* Onboarding artifacts written by `scout init` so any AI agent in the consuming
|
|
6
|
+
* repo can help a QA team configure Scout and author `.scout.md` scenarios.
|
|
7
|
+
*
|
|
8
|
+
* Three files, two ownership models:
|
|
9
|
+
* - AGENTS.md (repo root) — SHARED with the user and other tools. Scout owns
|
|
10
|
+
* only a managed block delimited by the markers below; everything outside
|
|
11
|
+
* it is left untouched.
|
|
12
|
+
* - .claude/skills/scout/SKILL.md and .cursor/rules/scout.mdc — Scout-OWNED,
|
|
13
|
+
* overwritten on every init (init is the upgrade path).
|
|
14
|
+
*
|
|
15
|
+
* Re-running init refreshes all three. `scout.config.json` is never touched here.
|
|
16
|
+
*/
|
|
17
|
+
export const SCOUT_BLOCK_START = "<!-- scout:start -->";
|
|
18
|
+
export const SCOUT_BLOCK_END = "<!-- scout:end -->";
|
|
19
|
+
const AGENTS_FILE = "AGENTS.md";
|
|
20
|
+
const SKILL_FILE = path.join(".claude", "skills", "scout", "SKILL.md");
|
|
21
|
+
const CURSOR_RULE_FILE = path.join(".cursor", "rules", "scout.mdc");
|
|
22
|
+
/** Resolve the bundled `templates/` dir, whether running from `src/` or `dist/`. */
|
|
23
|
+
export function templatesDir() {
|
|
24
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
// here is <pkg>/src or <pkg>/dist → templates sits at <pkg>/templates
|
|
26
|
+
return path.join(here, "..", "templates");
|
|
27
|
+
}
|
|
28
|
+
function readTemplate(name) {
|
|
29
|
+
return fs.readFileSync(path.join(templatesDir(), name), "utf8");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Embed `body` inside the scout managed block in `existing` content.
|
|
33
|
+
*
|
|
34
|
+
* - no existing content → just the block.
|
|
35
|
+
* - existing WITH a block → replace ONLY the block's contents.
|
|
36
|
+
* - existing WITHOUT a block → append the block, preserving everything else.
|
|
37
|
+
*/
|
|
38
|
+
export function applyManagedBlock(existing, body) {
|
|
39
|
+
const block = `${SCOUT_BLOCK_START}\n${body.trim()}\n${SCOUT_BLOCK_END}\n`;
|
|
40
|
+
if (existing === undefined || existing.trim() === "") {
|
|
41
|
+
return block;
|
|
42
|
+
}
|
|
43
|
+
const startIdx = existing.indexOf(SCOUT_BLOCK_START);
|
|
44
|
+
const endIdx = existing.indexOf(SCOUT_BLOCK_END);
|
|
45
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
46
|
+
const before = existing.slice(0, startIdx);
|
|
47
|
+
const after = existing.slice(endIdx + SCOUT_BLOCK_END.length);
|
|
48
|
+
// Trim a leading newline off `after` so we don't accumulate blank lines.
|
|
49
|
+
return `${before}${block}${after.replace(/^\n/, "")}`;
|
|
50
|
+
}
|
|
51
|
+
// No block yet — append, keeping the user's content and a clean separator.
|
|
52
|
+
const sep = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
53
|
+
return `${existing}${sep}${block}`;
|
|
54
|
+
}
|
|
55
|
+
/** Write/refresh AGENTS.md (managed block), the Claude skill, and the Cursor rule. */
|
|
56
|
+
export function scaffoldAgentOnboarding(deps = {}) {
|
|
57
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
58
|
+
const log = deps.log ?? ((m) => console.log(m));
|
|
59
|
+
// 1. AGENTS.md — managed block, never clobbers surrounding content.
|
|
60
|
+
const agentsPath = path.join(cwd, AGENTS_FILE);
|
|
61
|
+
const body = readTemplate("AGENTS.md");
|
|
62
|
+
const existing = fs.existsSync(agentsPath) ? fs.readFileSync(agentsPath, "utf8") : undefined;
|
|
63
|
+
const had = existing !== undefined;
|
|
64
|
+
const hadBlock = had && existing.includes(SCOUT_BLOCK_START);
|
|
65
|
+
fs.writeFileSync(agentsPath, applyManagedBlock(existing, body));
|
|
66
|
+
log(hadBlock
|
|
67
|
+
? `✓ ${AGENTS_FILE} — refreshed the Scout block.`
|
|
68
|
+
: had
|
|
69
|
+
? `✓ ${AGENTS_FILE} — appended the Scout block (your content kept).`
|
|
70
|
+
: `✓ ${AGENTS_FILE} created.`);
|
|
71
|
+
// 2. Claude Code skill — Scout-owned, overwrite.
|
|
72
|
+
const skillPath = path.join(cwd, SKILL_FILE);
|
|
73
|
+
fs.mkdirSync(path.dirname(skillPath), { recursive: true });
|
|
74
|
+
fs.writeFileSync(skillPath, readTemplate("SKILL.md"));
|
|
75
|
+
log(`✓ ${SKILL_FILE}`);
|
|
76
|
+
// 3. Cursor rule — Scout-owned, overwrite.
|
|
77
|
+
const cursorPath = path.join(cwd, CURSOR_RULE_FILE);
|
|
78
|
+
fs.mkdirSync(path.dirname(cursorPath), { recursive: true });
|
|
79
|
+
fs.writeFileSync(cursorPath, readTemplate("scout.mdc"));
|
|
80
|
+
log(`✓ ${CURSOR_RULE_FILE}`);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -82,6 +82,8 @@ export interface RunResult {
|
|
|
82
82
|
durationMs: number;
|
|
83
83
|
screenshots: string[];
|
|
84
84
|
trace?: string;
|
|
85
|
+
/** Paced preview clip (MP4, or WebM fallback) — only when --record-video and verified */
|
|
86
|
+
video?: string;
|
|
85
87
|
/** true when this AI run replaced a broken cached script */
|
|
86
88
|
healed?: boolean;
|
|
87
89
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pcamarajr/scout",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Self-healing browser QA: natural-language scenarios verified by an AI agent, replayed deterministically in CI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"files": [
|
|
38
|
-
"dist"
|
|
38
|
+
"dist",
|
|
39
|
+
"templates"
|
|
39
40
|
],
|
|
40
41
|
"scripts": {
|
|
41
42
|
"build": "tsc",
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Scout — browser QA for AI agents
|
|
2
|
+
|
|
3
|
+
Scout turns **natural-language scenarios** into **AI-verified, deterministically-replayed** browser tests. A scenario is written in plain English in a `.scout.md` file; on its first `scout go` an AI agent drives a real browser (Playwright), judges the outcome, and records a deterministic script. Every later run replays that script with **no LLM** — fast and free — and only falls back to AI when the script breaks (self-heal).
|
|
4
|
+
|
|
5
|
+
This file is the **single source of truth** for how an AI agent should help a QA team work with Scout in this repo. The Claude Code skill and the Cursor rule both point here.
|
|
6
|
+
|
|
7
|
+
## Your primary job: co-author scenarios with QA
|
|
8
|
+
|
|
9
|
+
When a QA person describes a flow they want covered, **you write the `.scout.md` directly** — do not make them hand-write it. You have full repo context (routes, components, copy, auth), so you can author a richer, more accurate spec than the CLI scaffold (`scout create`) ever could. Then you verify it and iterate with the human until it is green.
|
|
10
|
+
|
|
11
|
+
The loop:
|
|
12
|
+
|
|
13
|
+
1. **Author** — translate the QA person's intent into one or more scenarios in a `.scout.md` file (format below). Capture the flow *and* the expected behavior, in plain language. No selectors, no code.
|
|
14
|
+
2. **Verify** — run `scout go` (optionally `-s <slug>` to target one scenario). The first run is AI-driven, in a real browser.
|
|
15
|
+
3. **Interpret** — read the verdict Scout reports and relay it to the human verbatim (see *Verdicts* below).
|
|
16
|
+
4. **Iterate** — refine the scenario text with QA until the verdict is `verified`, then commit the `.scout.md` and the recorded script.
|
|
17
|
+
|
|
18
|
+
> `scout create <name> -f <feature> -c <text>` exists as a convenience for **humans without an agent**. As the agent, prefer authoring the `.scout.md` directly — you can write a fuller spec from repo context.
|
|
19
|
+
|
|
20
|
+
## ⛔ Verification-integrity rule (non-negotiable)
|
|
21
|
+
|
|
22
|
+
**Never declare a scenario working, passing, or done without actually running `scout go` and reporting the real verdict.**
|
|
23
|
+
|
|
24
|
+
- Do **not** fabricate, assume, or predict success. Run it.
|
|
25
|
+
- Report the verdict Scout produced **verbatim** — including the `reason` line.
|
|
26
|
+
- If the result is `failed`, `partial`, or `blocked`, say so honestly. If a replay **healed**, surface that and show the script diff so a human can review what changed.
|
|
27
|
+
|
|
28
|
+
This rule protects Scout's entire value proposition: a verdict is trustworthy only because it came from a real run. Inventing one poisons the suite.
|
|
29
|
+
|
|
30
|
+
## The `.scout.md` authoring guide
|
|
31
|
+
|
|
32
|
+
Scenarios live as markdown under `.scout/specs/**/*.scout.md` — **one file per feature/component**, versioned and reviewed like any other test. The markdown is a **pure input**: a run never writes back to it (status lives in `.scout/runs/`), so the spec diff only ever reflects an intent change.
|
|
33
|
+
|
|
34
|
+
Format:
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
---
|
|
38
|
+
feature: Paywall # optional; defaults to the filename
|
|
39
|
+
profile: anon # optional; default auth profile for scenarios below
|
|
40
|
+
tags: [monetization] # optional
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Free user hits paywall on ep 3
|
|
44
|
+
Open ep 3 of series X without login; the paywall appears with a signup CTA.
|
|
45
|
+
|
|
46
|
+
## Subscriber bypasses paywall
|
|
47
|
+
profile: qa # per-scenario override (also: notes, tags)
|
|
48
|
+
|
|
49
|
+
Logged-in subscriber opens ep 3; the episode plays with no paywall.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Rules that matter when you author:
|
|
53
|
+
|
|
54
|
+
- **Frontmatter** (YAML, optional): `feature` (defaults to the filename), `profile` (default auth profile), `tags`.
|
|
55
|
+
- **Each `## heading` is one scenario.** Its logical slug is `<file-slug>/<scenario-slug>` (e.g. `paywall/free-user-hits-paywall-on-ep-3`) and must be unique across the suite. Duplicate headings in a file, or a scenario with no body text, are hard errors.
|
|
56
|
+
- **Per-scenario overrides:** immediately under a heading you may place `profile:`, `notes:`, and `tags:` lines (before the prose) to override the file-level defaults.
|
|
57
|
+
- **Body = flow + expected behavior, in plain language.** Describe what the user does and what must (or must not) be true. No CSS selectors, no Playwright code — the agent discovers the real elements at run time and records them.
|
|
58
|
+
- A `.scout.md` whose every `##` lives inside a fenced ```` ``` ```` block parses as **zero scenarios** (that is how `example.scout.md` documents the format without polluting the suite).
|
|
59
|
+
|
|
60
|
+
## Base URL and secrets
|
|
61
|
+
|
|
62
|
+
There is a **default base URL** set at `scout init` (in `scout.config.json`). It can be **overridden per run** without editing the file:
|
|
63
|
+
|
|
64
|
+
- `scout go --base-url https://staging.example.com`
|
|
65
|
+
- `SCOUT_BASE_URL=https://staging.example.com scout go`
|
|
66
|
+
- Precedence: `--base-url` flag > `SCOUT_BASE_URL` env > `baseUrl` in `scout.config.json`.
|
|
67
|
+
|
|
68
|
+
Recorded scripts store navigation **relative to the base URL in effect at record time**, so a script recorded against `:3000` replays unchanged against staging.
|
|
69
|
+
|
|
70
|
+
For credentials and tokens, never put a literal secret in a scenario. Use a **`$ENV:VAR` placeholder** — Scout resolves it from the environment at run time, in both **form fills** and **`browser_navigate` URLs** (e.g. `/renew?token=$ENV:RENEW_TOKEN`). The real value never enters the committed script and never passes through the LLM. Declare the allowed env vars per auth profile in `scout.config.json` (`profiles.<name>.env`).
|
|
71
|
+
|
|
72
|
+
## Verdicts (what `scout go` reports)
|
|
73
|
+
|
|
74
|
+
| Verdict | Meaning |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `verified` ✅ | All expected behavior confirmed by assertions. |
|
|
77
|
+
| `failed` ❌ | Broken behavior — the `reason` says exactly what. |
|
|
78
|
+
| `partial` ⚠️ | Only part of the expected behavior was confirmed. |
|
|
79
|
+
| `blocked` 🚫 | Couldn't reach the flow at all (app down, login broken). |
|
|
80
|
+
|
|
81
|
+
**Healed:** when a cached script breaks but the AI re-verifies and re-records it, the run is flagged `healed`. The recorded-script diff is the heal diff — review it; a legitimate UI change is fine to commit, an unexpected one is a real regression.
|
|
82
|
+
|
|
83
|
+
**Runner failure ≠ UI verdict:** an AI run can die without producing a verdict (turn budget exhausted, SDK error). Scout flags that as `runnerFailure` / 💥 — it is an infrastructure failure, **not** a judgment about the app. Rerun it; don't debug the app over it.
|
|
84
|
+
|
|
85
|
+
## Secondary: helping triage a failed replay
|
|
86
|
+
|
|
87
|
+
When a replay comes back `failed`/`partial`/`blocked` or `healed`, you can help — but the **human stays in the loop on intent**. Triage flow:
|
|
88
|
+
|
|
89
|
+
1. Read the `reason` and open the run artifacts under `.scout/runs/<timestamp>-<slug>/` — `report.md` (verdict + recorded script), `trace.zip` (`npx playwright show-trace`), screenshots, and `transcript.md` for AI runs.
|
|
90
|
+
2. Decide *with the human* whether this is a **real regression** (the app broke → fix the app) or a **legitimate UI change** (the spec/script is stale → re-verify with `scout go --ai -s <slug>` to re-record, then review the diff).
|
|
91
|
+
3. Never silently re-record to make a red suite green. A green verdict must reflect reality.
|
|
92
|
+
|
|
93
|
+
## Defer to the live CLI for commands and flags
|
|
94
|
+
|
|
95
|
+
Commands and flags evolve — read them live instead of trusting a copy:
|
|
96
|
+
|
|
97
|
+
- `scout --help` — all commands.
|
|
98
|
+
- `scout <command> --help` — flags for one command (e.g. `scout go --help`).
|
|
99
|
+
|
|
100
|
+
The core commands you will use: `scout go` (verify/replay), `scout list` (scenarios + status), `scout report` (suite summary, `--check` for a CI gate). `scout init` is the setup/upgrade entry point and also refreshes these onboarding files.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scout
|
|
3
|
+
description: >
|
|
4
|
+
Help a QA team use Scout — browser QA where natural-language scenarios are
|
|
5
|
+
AI-verified once and then replayed deterministically. TRIGGER when the user
|
|
6
|
+
mentions Scout, a `.scout.md` scenario, `scout.config.json`, `scout go` /
|
|
7
|
+
`scout init` / `scout report`, browser/E2E/QA testing of a user flow, or asks
|
|
8
|
+
to author, verify, replay, or triage a browser test scenario. Do NOT trigger
|
|
9
|
+
for unrelated unit tests or non-browser work.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Scout
|
|
13
|
+
|
|
14
|
+
Scout is self-healing browser QA: QA describes a flow in plain English, an AI
|
|
15
|
+
agent verifies it once in a real browser and records a deterministic script,
|
|
16
|
+
and every later run replays that script with no LLM.
|
|
17
|
+
|
|
18
|
+
Your job is to **co-author `.scout.md` scenarios** with QA, **verify** them with
|
|
19
|
+
`scout go`, and **report the real verdict** — never claim a scenario passes
|
|
20
|
+
without running it.
|
|
21
|
+
|
|
22
|
+
**Read `AGENTS.md` at the repo root — it is the canonical, always-current guide**
|
|
23
|
+
to the authoring loop, the `.scout.md` format, base-URL/secret handling,
|
|
24
|
+
verdicts, and failure triage. Follow it. For commands and flags, run
|
|
25
|
+
`scout --help` / `scout <command> --help`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scout browser QA — authoring and verifying .scout.md scenarios.
|
|
3
|
+
globs:
|
|
4
|
+
- "**/*.scout.md"
|
|
5
|
+
- "scout.config.json"
|
|
6
|
+
alwaysApply: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Scout
|
|
10
|
+
|
|
11
|
+
When working with Scout files (`*.scout.md`, `scout.config.json`), you are
|
|
12
|
+
helping a QA team with **browser QA**: natural-language scenarios that are
|
|
13
|
+
AI-verified once and then replayed deterministically.
|
|
14
|
+
|
|
15
|
+
Co-author `.scout.md` scenarios with QA, verify them with `scout go`, and report
|
|
16
|
+
the **real** verdict — never claim a scenario passes without running it.
|
|
17
|
+
|
|
18
|
+
**Read `AGENTS.md` at the repo root** — it is the canonical, always-current
|
|
19
|
+
guide to the authoring loop, the `.scout.md` format, base-URL/secret handling,
|
|
20
|
+
verdicts, and failure triage. For commands and flags, run `scout --help` /
|
|
21
|
+
`scout <command> --help`.
|