skeptic-cli 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/README.md ADDED
@@ -0,0 +1,393 @@
1
+ # skeptic
2
+
3
+ CLI-first end-to-end testing for TypeScript specs. Skeptic runs Playwright tests,
4
+ adds agent-friendly page discovery, and captures QA evidence that is useful in
5
+ local debugging, CI, and coding-agent workflows.
6
+
7
+ > Agent authors should also read [AGENTS.md](./AGENTS.md) for the recommended
8
+ > inspect → author → run loop and the full fixture API.
9
+
10
+ ## Install For Development
11
+
12
+ ```bash
13
+ git clone https://github.com/iamjr15/skeptic
14
+ cd skeptic/cli
15
+ npm install
16
+ npm run build
17
+ node dist/skeptic.mjs --help
18
+ ```
19
+
20
+ To use the local checkout as a command:
21
+
22
+ ```bash
23
+ npm link
24
+ skeptic --help
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```bash
30
+ # Initialize a project
31
+ skeptic init
32
+
33
+ # Discover stable selectors before authoring a test
34
+ skeptic inspect https://example.com
35
+
36
+ # Capture an ad hoc QA evidence bundle without writing a spec
37
+ skeptic observe https://example.com
38
+
39
+ # Run TypeScript specs with full QA evidence
40
+ skeptic run tests/homepage.spec.ts --observability --video --trace
41
+
42
+ # Generate a validated TypeScript spec with AI
43
+ skeptic generate -m "test the login page"
44
+
45
+ # Check local setup
46
+ skeptic doctor
47
+ ```
48
+
49
+ `skeptic init` creates:
50
+
51
+ - `package.json` when missing, or adds a `test:e2e` script and `skeptic-cli` dev dependency when present
52
+ - `tests/`
53
+ - `tests/package.json` with `type: "module"` so specs can use ESM without changing your app package mode
54
+ - `tests/example.spec.ts`
55
+ - `skeptic.config.yaml`
56
+ - `tsconfig.json`
57
+ - `.skeptic/.gitignore`
58
+ - root `.gitignore` entries for `.skeptic/` and `skeptic-output/`
59
+
60
+ ## Agent Skills
61
+
62
+ The npm package includes a `skeptic` skill for Claude Code, Codex, Cursor, and
63
+ OpenCode. During `npm install`, Skeptic installs that skill into user-level agent
64
+ skill directories when possible:
65
+
66
+ | Agent | User skill directory |
67
+ |---|---|
68
+ | Claude Code | `~/.claude/skills/skeptic` |
69
+ | Codex | `${CODEX_HOME:-~/.codex}/skills/skeptic` |
70
+ | Cursor | `~/.cursor/skills/skeptic` |
71
+ | OpenCode | `~/.opencode/skills/skeptic` |
72
+
73
+ The installer only replaces skills previously managed by `skeptic-cli`; existing
74
+ custom skills are left untouched. To skip automatic installation, set
75
+ `SKEPTIC_SKIP_AGENT_SKILL_INSTALL=1` or `SKEPTIC_INSTALL_AGENT_SKILLS=0`.
76
+ Automatic installation is skipped in CI unless `SKEPTIC_INSTALL_AGENT_SKILLS=1`
77
+ is set. To install only selected agents, set
78
+ `SKEPTIC_AGENT_SKILLS=claude,codex`.
79
+
80
+ For a repository-scoped skill that should be committed with a project, run:
81
+
82
+ ```bash
83
+ skeptic add skill --agent all --scope project
84
+ ```
85
+
86
+ For an explicit user-level reinstall, run:
87
+
88
+ ```bash
89
+ skeptic add skill --agent all --scope user
90
+ ```
91
+
92
+ ## Test Format
93
+
94
+ Skeptic specs are ordinary TypeScript files that import from `skeptic-cli`.
95
+
96
+ ```ts
97
+ import { test, expect } from "skeptic-cli";
98
+
99
+ test("homepage smoke", async ({ page, snapshot, screenshot, observability }) => {
100
+ await page.goto("https://example.com");
101
+ await expect(page).toHaveTitle(/Example Domain/);
102
+
103
+ const tree = await snapshot(page);
104
+ await expect(tree.byRole("heading", { name: "Example Domain" })).toBeVisible();
105
+
106
+ await screenshot("homepage", { fullPage: true });
107
+ await observability.expectNoConsoleErrors();
108
+ });
109
+ ```
110
+
111
+ The fixture exposes:
112
+
113
+ | Member | Purpose |
114
+ |---|---|
115
+ | `page` | Playwright `Page`, wrapped for cursor/action markers when video is enabled |
116
+ | `snapshot` | ARIA + cursor-interactive discovery with refs and locator helpers |
117
+ | `screenshot` | PNG screenshots, including annotated numbered-ref captures |
118
+ | `settle` | Network-idle settle helper |
119
+ | `observability` | Performance, network, console, and accessibility assertions |
120
+ | `ai` | Vision-backed assertions, defect checks, and text extraction |
121
+ | `ctx` | Per-test execution context and artifact paths |
122
+
123
+ `expect` is re-exported from Playwright Test, so matchers like
124
+ `toHaveURL`, `toBeVisible`, and `toHaveText` are available without a second
125
+ import.
126
+
127
+ ## Discovery
128
+
129
+ `skeptic inspect <url>` opens the page, captures an ARIA/cursor snapshot, and
130
+ prints stable `selectorHint:` lines.
131
+
132
+ ```bash
133
+ skeptic inspect https://example.com --interactive --compact
134
+ skeptic inspect https://example.com --json
135
+ skeptic inspect https://example.com --annotated --annotate-output inspect.png
136
+ ```
137
+
138
+ Useful flags:
139
+
140
+ | Flag | Purpose |
141
+ |---|---|
142
+ | `--interactive` | Show only ref-bearing entries |
143
+ | `--compact` | Show interactive entries with minimal ancestors |
144
+ | `--selector <css>` | Scope discovery to part of the page |
145
+ | `--json` | Emit machine-readable refs, hints, and stats |
146
+ | `--device <id>` | Inspect under a configured device profile |
147
+ | `--connect <url>` | Attach to an existing browser over CDP |
148
+ | `--with-playwright-hints` | Emit equivalent Playwright locator snippets |
149
+ | `--annotated` | Save a numbered-ref screenshot |
150
+
151
+ Refs like `e3` are runtime handles. Copy `selectorHint` strings into durable
152
+ tests, or use `tree.byRef("e3")` only after a matching `snapshot(page)` call in
153
+ the same test.
154
+
155
+ ## Running Tests
156
+
157
+ ```bash
158
+ skeptic tui
159
+ skeptic tui tests/login.spec.ts
160
+ skeptic run
161
+ skeptic run tests/login.spec.ts
162
+ skeptic run tests/**/*.spec.ts --tag smoke
163
+ skeptic run --parallel 4
164
+ skeptic run --shard-split 4 --shard-index 1
165
+ skeptic run --watch
166
+ ```
167
+
168
+ `skeptic tui` is the discoverable interactive entrypoint. `skeptic run` opens
169
+ the same TUI automatically in an interactive terminal when the console reporter
170
+ is active; use `skeptic run --no-tui` for plain console output.
171
+
172
+ Important flags:
173
+
174
+ | Flag | Purpose |
175
+ |---|---|
176
+ | `--headed` | Show the browser |
177
+ | `--ci` | Force headless CI behavior |
178
+ | `--bail` | Stop after the first failing test |
179
+ | `--retries <n>` | Retry failed tests |
180
+ | `--timeout <ms>` | Playwright default action timeout |
181
+ | `--hard-timeout <ms>` | Per-test ceiling enforced by the runner |
182
+ | `--parallel <n>` | Run up to N spec-file workers concurrently |
183
+ | `--shard-split <n>` | Split tests across N independent shard runs |
184
+ | `--shard-all <n>` | Run all tests on each shard for variance checks |
185
+ | `--reporter <format...>` | `console`, `json`, `junit`, `html` |
186
+ | `--output <dir>` | Report and artifact directory |
187
+ | `--list` | Discover tests without launching a browser |
188
+
189
+ `--parallel` runs different spec files concurrently. Tests inside one file stay
190
+ ordered so hooks, module state, and duplicate names remain predictable.
191
+
192
+ ## Observability
193
+
194
+ `--observability` enables the full QA bundle:
195
+
196
+ - visual settle before screenshots
197
+ - full-page screenshots by default
198
+ - performance metrics
199
+ - network capture and issue detection
200
+ - console capture
201
+ - accessibility audit with automatic per-test `audit.md`
202
+ - sidecar artifacts when report defaults allow them
203
+
204
+ Use `--observability-write-sidecars` to force sidecars even when the reporter
205
+ profile would not otherwise write them.
206
+
207
+ ```ts
208
+ test("checkout stays healthy", async ({ page, observability }) => {
209
+ await page.goto("/checkout");
210
+ await observability.expectPerformance({ lcp: "<2500ms", cls: "<0.1" });
211
+ await observability.expectNoNetworkErrors();
212
+ await observability.expectNoConsoleErrors();
213
+ await observability.expectAccessible({ standard: "WCAG21AA" });
214
+ });
215
+ ```
216
+
217
+ Artifacts can include:
218
+
219
+ - `results.json`
220
+ - `report.html`
221
+ - `junit.xml`
222
+ - screenshots
223
+ - WebM videos
224
+ - Playwright trace zips
225
+ - `perf-trace.md`
226
+ - `network.json`
227
+ - `console.json`
228
+ - `accessibility.json`
229
+ - `audit.md`
230
+
231
+ ## Observe
232
+
233
+ `skeptic observe <url>` is the one-command evidence path for exploratory QA.
234
+
235
+ ```bash
236
+ skeptic observe https://example.com --full-page
237
+ skeptic observe https://example.com --no-video --no-trace
238
+ ```
239
+
240
+ It writes an output directory containing an HTML report, JSON report,
241
+ screenshots, annotated screenshots, snapshot text/JSON, console/network data,
242
+ performance summary, accessibility JSON, and an accessibility markdown audit.
243
+
244
+ ## AI Features
245
+
246
+ Skeptic supports Gemini, OpenAI, and Anthropic.
247
+
248
+ ```yaml
249
+ ai:
250
+ provider: openai
251
+ model: gpt-4o
252
+ ```
253
+
254
+ Set the matching provider key with `GEMINI_API_KEY`, `OPENAI_API_KEY`, or
255
+ `ANTHROPIC_API_KEY`. You can also use `SKEPTIC_AI_PROVIDER` and
256
+ `SKEPTIC_AI_API_KEY` to override config in CI.
257
+
258
+ Available AI paths:
259
+
260
+ - `ai.assert("the dashboard greets the user")`
261
+ - `ai.assertNoDefects()`
262
+ - `ai.extract("the invoice total")`
263
+ - `skeptic generate --message "test checkout"`
264
+ - `skeptic generate --diff`
265
+ - `skeptic run --analyze`
266
+
267
+ Generated specs are typechecked and imported before being written.
268
+
269
+ ## MCP And ACP
270
+
271
+ `skeptic mcp` exposes testing and browser QA tools over stdio:
272
+
273
+ | Tool | Purpose |
274
+ |---|---|
275
+ | `list_tests` | Discover specs |
276
+ | `validate_tests` | Typecheck and import-check specs |
277
+ | `generate_test` | Generate a validated TypeScript spec |
278
+ | `run_test` | Run specs and stream progress |
279
+ | `browser_open` | Open a page with config-driven browser/auth/safety |
280
+ | `browser_snapshot` | Capture ARIA/cursor refs |
281
+ | `browser_playwright` | Run focused Playwright code |
282
+ | `browser_screenshot` | Capture PNG, annotated PNG, or snapshot-only output |
283
+ | `browser_console_logs` | Read console messages |
284
+ | `browser_network_requests` | Read requests and computed issues |
285
+ | `browser_performance_metrics` | Capture Web Vitals, LoAF, resources, and `perf-trace.md` |
286
+ | `browser_accessibility_audit` | Run axe-core plus IBM Equal Access when available |
287
+ | `browser_close` | Close the browser session |
288
+
289
+ `skeptic acp` exposes a testing-focused agent server for editors that support
290
+ Agent Client Protocol.
291
+
292
+ ## Configuration
293
+
294
+ `skeptic.config.yaml` lives in the project root.
295
+
296
+ ```yaml
297
+ url: http://localhost:3000
298
+ tests: "tests/**/*.spec.ts"
299
+
300
+ browser:
301
+ engine: chromium
302
+ headless: true
303
+ timeout: 30000
304
+ viewport:
305
+ width: 1280
306
+ height: 720
307
+
308
+ execution:
309
+ retries: 0
310
+ bail: false
311
+ parallel: 1
312
+
313
+ output:
314
+ dir: ./skeptic-output
315
+ reporters: [console]
316
+
317
+ observability:
318
+ collectors: []
319
+ defaultsForReports: passive
320
+ networkCaptureLimit: 500
321
+ duplicateWindowMs: 500
322
+ accessibilityDualEngine: false
323
+ autoAccessibilityAudit: false
324
+
325
+ safety:
326
+ allowedDomains: []
327
+ confirmActions: []
328
+ maxOutputChars: 120000
329
+
330
+ env:
331
+ BASE_URL: http://localhost:3000
332
+ ```
333
+
334
+ ## Cookie Injection
335
+
336
+ ```bash
337
+ skeptic cookies list
338
+ skeptic run --cookies
339
+ skeptic run --cookies-from chrome
340
+ ```
341
+
342
+ Cookie extraction is opt-in. Cookies are injected into local test browser
343
+ contexts and are not sent to Skeptic services.
344
+
345
+ ## CI
346
+
347
+ ```bash
348
+ skeptic add github-action
349
+ skeptic add github-action --ai --provider openai
350
+ ```
351
+
352
+ The generated workflow installs dependencies, installs Chromium, starts your dev
353
+ server, runs Skeptic, uploads artifacts, and posts a PR comment with
354
+ `skeptic comment`.
355
+
356
+ ## Notifications
357
+
358
+ Optional Slack and webhook notifications are configured under `notifications`.
359
+ Notification failures warn but do not fail the test run.
360
+
361
+ ```yaml
362
+ notifications:
363
+ slack:
364
+ webhookUrl: ${SLACK_WEBHOOK_URL}
365
+ onFailure: true
366
+ onSuccess: false
367
+
368
+ webhook:
369
+ url: ${SKEPTIC_WEBHOOK_URL}
370
+ onFailure: true
371
+ onSuccess: false
372
+ ```
373
+
374
+ Webhook payloads use a `tests` array with name, file, status, duration, error,
375
+ and optional shard metadata.
376
+
377
+ ## Diagnostics
378
+
379
+ ```bash
380
+ skeptic doctor
381
+ skeptic doctor --json --quick
382
+ skeptic browsers install chromium
383
+ skeptic daemon status
384
+ skeptic daemon stop
385
+ ```
386
+
387
+ `skeptic doctor` checks config, output directories, browser installs, optional
388
+ accessibility/cookie engines, daemon state, cookie profiles, and AI provider
389
+ setup.
390
+
391
+ ## License
392
+
393
+ MIT
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: skeptic
3
+ description: Use Skeptic for CLI-first browser QA and TypeScript E2E tests. Use when asked to inspect pages, write or run skeptic-cli specs, validate UI changes, capture observability evidence, or use Skeptic MCP tools. Not for unit-only logic with no browser behavior.
4
+ ---
5
+
6
+ <!-- skeptic-agent-skill: managed by skeptic-cli -->
7
+
8
+ # Skeptic
9
+
10
+ Use Skeptic when a coding agent needs browser evidence: page inspection, TypeScript E2E specs, one-off QA captures, AI-backed checks, or MCP browser validation. Do not claim a UI/browser change works until you have run a relevant Skeptic command or MCP tool and checked the evidence.
11
+
12
+ ## Choose The Surface
13
+
14
+ - One-off QA or bug hunt: run `skeptic observe <url> --full-page`.
15
+ - Persistent regression coverage: run `skeptic inspect <url> --interactive --compact --with-playwright-hints`, write a `tests/*.spec.ts`, then run `skeptic run`.
16
+ - Changed-code verification: run `skeptic run --diff` when the project has specs, or use `skeptic generate --diff` to create one.
17
+ - Agent-integrated browser work: if Skeptic MCP tools are available, use `browser_open`, `browser_snapshot`, `browser_playwright`, `browser_screenshot`, `browser_console_logs`, `browser_network_requests`, `browser_performance_metrics`, `browser_accessibility_audit`, and `browser_close`.
18
+
19
+ If the `skeptic` binary is not on PATH, try `npx skeptic-cli` or `npx --yes skeptic-cli@latest`.
20
+
21
+ ## Fast Loop
22
+
23
+ ```bash
24
+ skeptic doctor --quick
25
+ skeptic inspect <url> --interactive --compact --with-playwright-hints
26
+ skeptic run tests/<scenario>.spec.ts --observability --video --trace
27
+ ```
28
+
29
+ For a page with no existing spec:
30
+
31
+ ```bash
32
+ skeptic observe <url> --full-page --video --trace
33
+ ```
34
+
35
+ Use the generated `results.json`, `report.html`, screenshots, videos, traces, `network.json`, `console.json`, `accessibility.json`, and `perf-trace.md` as the evidence source. Reference artifact paths from `results.json` instead of guessing filenames.
36
+
37
+ ## Writing Specs
38
+
39
+ Skeptic specs import from `skeptic-cli`.
40
+
41
+ ```ts
42
+ import { test, expect } from "skeptic-cli";
43
+
44
+ test("homepage smoke", async ({ page, snapshot, screenshot, observability }) => {
45
+ await page.goto("https://example.com");
46
+ await expect(page).toHaveTitle(/Example Domain/);
47
+
48
+ const tree = await snapshot(page, { interactive: true, compact: true });
49
+ await tree.byRole("link", { name: "More information..." }).click();
50
+
51
+ await screenshot("homepage", { fullPage: true });
52
+ await observability.expectNoConsoleErrors();
53
+ });
54
+ ```
55
+
56
+ Rules:
57
+
58
+ - Put browser side effects inside `test(...)`, hooks, or helper functions called from tests.
59
+ - Prefer role, label, text, and test-id locators over CSS.
60
+ - Use `snapshot(page)` before interacting through refs or snapshot helpers.
61
+ - Re-snapshot after navigation, route changes, modal open/close, or major DOM mutation.
62
+ - Do not paste CLI `@eN` refs directly into specs. Use `selectorHint` from `inspect`, or use `tree.byRef("eN")` only for refs returned by the same in-test `snapshot(page)` call.
63
+ - Add `screenshot("name")` for states that would help debug a failure.
64
+
65
+ ## Observability Checks
66
+
67
+ Use `--observability` for real QA evidence. In specs, assert the signals that match the risk:
68
+
69
+ ```ts
70
+ await observability.expectNoConsoleErrors();
71
+ await observability.expectNoNetworkErrors({ allow: [/analytics/] });
72
+ await observability.expectPerformance({ lcp: "<2500ms", cls: "<0.1" });
73
+ await observability.expectAccessible({ standard: "WCAG21AA" });
74
+ ```
75
+
76
+ If an observability artifact reports a failure, fix the product or the test and re-run the same flow immediately.
77
+
78
+ ## MCP Workflow
79
+
80
+ When Skeptic is exposed through MCP:
81
+
82
+ 1. `browser_open` the target URL.
83
+ 2. `browser_snapshot` or `browser_screenshot` with snapshot mode to get refs.
84
+ 3. Use one `browser_playwright` call for actions that share the same DOM state. Use the `ref` helper for snapshot refs and `return` structured evidence.
85
+ 4. After DOM-changing actions, request a fresh snapshot.
86
+ 5. Check `browser_console_logs`, `browser_network_requests`, `browser_accessibility_audit`, and `browser_performance_metrics`.
87
+ 6. `browser_close` when done so video and trace artifacts flush.
88
+
89
+ Batch fills, clicks, and data collection when the DOM is stable. Do not take a new snapshot between plain text fills unless the page structure changed.
90
+
91
+ ## Verification Standard
92
+
93
+ Before reporting completion for browser-facing work:
94
+
95
+ - Run the smallest Skeptic command or MCP workflow that actually exercises the changed behavior.
96
+ - Test at least one adjacent or negative path when forms, routing, validation, auth, persistence, or shared components changed.
97
+ - Read the full command/tool output. Passing navigation alone is not enough.
98
+ - If there are console errors, network failures, serious accessibility issues, poor Web Vitals, or visible regressions, fix and re-run.
99
+ - State the exact command/tool run and the main artifact path in the final report.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Skeptic"
3
+ short_description: "Use Skeptic to inspect pages, write TypeScript E2E tests, run browser QA, and collect observability evidence."
4
+ default_prompt: "Use Skeptic to verify this UI or browser behavior with real evidence and report the relevant artifacts."
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ // JS package launcher.
3
+ //
4
+ // The published package always includes the JS bundle at `dist/skeptic.mjs`.
5
+ //
6
+ // This file is intentionally NOT processed by tsup — it's hand-written and
7
+ // stays under `bin/` in the published tarball (declared in package.json
8
+ // `files`). tsup output goes to `dist/skeptic.mjs`.
9
+
10
+ import { fileURLToPath, pathToFileURL } from "node:url";
11
+ import { dirname, join } from "node:path";
12
+
13
+ const here = dirname(fileURLToPath(import.meta.url));
14
+ const entrypoint = join(here, "..", "dist", "skeptic.mjs");
15
+
16
+ // ESM `import()` rejects raw Windows paths like `C:\...`; convert to
17
+ // `file://` URL first.
18
+ await import(pathToFileURL(entrypoint).href);