spectoflow 0.14.2 → 0.15.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 -0
- package/bin/spectoflow.js +14 -0
- package/lib/adapters.js +12 -0
- package/lib/mcp.js +44 -0
- package/package.json +1 -1
- package/templates/AGENTS.md +25 -6
- package/templates/README.md +72 -0
- package/templates/agents/product-manager.md +6 -4
- package/templates/agents/qa-engineer.md +5 -0
- package/templates/capabilities.md +5 -0
- package/templates/skills/clarify/SKILL.md +83 -0
- package/templates/skills/write-e2e-tests/SKILL.md +16 -6
package/README.md
CHANGED
|
@@ -158,6 +158,20 @@ runs a skill. Improve a skill without touching the agent.
|
|
|
158
158
|
Agents and skills follow real domain standards, cited in-file — TDD, OWASP ASVS/Top 10, C4/ADR,
|
|
159
159
|
INVEST, Playwright E2E, Conventional Commits, and more — not generic one-liners.
|
|
160
160
|
|
|
161
|
+
**Clarify before acting.** spectoflow is an **expert analyst, not an order-taker**. When a request is
|
|
162
|
+
vague ("login displays badly, users can't sign in"), an always-on **Clarify reflex** — in the agent's
|
|
163
|
+
memory (`AGENTS.md`) and backed by the `clarify` skill — reflects it back and asks **one targeted
|
|
164
|
+
question at a time**, each with a recommendation anchored in the project's goals and best practices,
|
|
165
|
+
until the need is crisp; then it runs the normal workflow. It's additive: it feeds the router, never
|
|
166
|
+
replaces it, and it's mode-aware.
|
|
167
|
+
|
|
168
|
+
**End-to-end tests via Playwright MCP.** `init` idempotently wires a `playwright` entry into the target
|
|
169
|
+
project's `.mcp.json` (and `.cursor/mcp.json` for Cursor) so the QA agent can drive a real browser and
|
|
170
|
+
generate/run Playwright specs — `npx` fetches the server on first use, so spectoflow stays zero-dep
|
|
171
|
+
(the config lives in *your* project). If the MCP isn't available, `write-e2e-tests` falls back down a
|
|
172
|
+
ladder (native browser tooling → local Playwright → write the spec and raise a `need`), never faking a
|
|
173
|
+
pass. The durable artifact is always the committed `*.spec.ts`.
|
|
174
|
+
|
|
161
175
|
A `governance` capability adds a **Spec Source Guardian** (skill `audit-source`): it keeps the spec
|
|
162
176
|
(intent) and the code/tests (reality) coherent — flagging drift in both directions, never auto-fixing,
|
|
163
177
|
surfacing findings to the Attention tab, and gating only at `done`/Major. It ships with a zero-dep
|
package/bin/spectoflow.js
CHANGED
|
@@ -9,6 +9,7 @@ const adapters = require('../lib/adapters');
|
|
|
9
9
|
const detect = require('../lib/detect');
|
|
10
10
|
const ownership = require('../lib/ownership');
|
|
11
11
|
const manifest = require('../lib/manifest');
|
|
12
|
+
const mcp = require('../lib/mcp');
|
|
12
13
|
|
|
13
14
|
const KIT = path.resolve(__dirname, '..');
|
|
14
15
|
const TPL = path.join(KIT, 'templates');
|
|
@@ -133,6 +134,19 @@ function init() {
|
|
|
133
134
|
// per-agent shims
|
|
134
135
|
const written = adapters.generate(target, agents);
|
|
135
136
|
|
|
137
|
+
// wire Playwright MCP into the project's MCP config so the E2E agent can drive a real browser and
|
|
138
|
+
// generate/run Playwright tests. Idempotent + non-destructive: never touches an existing entry.
|
|
139
|
+
// npx fetches the server on first use, so this config IS the whole install — spectoflow stays
|
|
140
|
+
// zero-dep (this writes into the user's project, never into spectoflow).
|
|
141
|
+
const mcpTargets = [path.join(target, '.mcp.json')];
|
|
142
|
+
if (agents.includes('cursor')) mcpTargets.push(path.join(target, '.cursor', 'mcp.json'));
|
|
143
|
+
for (const fp of mcpTargets) {
|
|
144
|
+
const rel = path.relative(target, fp).split(path.sep).join('/');
|
|
145
|
+
const r = mcp.mergeMcpServer(fp, 'playwright', mcp.PLAYWRIGHT_MCP);
|
|
146
|
+
if (r === 'created' || r === 'added') notes.push(`Wired Playwright MCP into ${rel} (npx @playwright/mcp — for the E2E agent; commit it to share).`);
|
|
147
|
+
else if (r === 'skipped') notes.push(`Left ${rel} as-is (couldn't parse it) — add a 'playwright' MCP server yourself for browser-driven E2E.`);
|
|
148
|
+
}
|
|
149
|
+
|
|
136
150
|
// gitignore the volatile runtime
|
|
137
151
|
const gi = path.join(target, '.gitignore');
|
|
138
152
|
const giText = fs.existsSync(gi) ? fs.readFileSync(gi, 'utf8') : '';
|
package/lib/adapters.js
CHANGED
|
@@ -21,6 +21,10 @@ instructions (intent router, workflow, standing rules).
|
|
|
21
21
|
> install. Merge its project-specific content into this file, then delete \`CLAUDE.md.tomerge\`,
|
|
22
22
|
> before anything else.
|
|
23
23
|
|
|
24
|
+
**Be an expert analyst, not an order-taker.** When a request is ambiguous, **clarify before acting**:
|
|
25
|
+
reflect it back and ask **one targeted question at a time** (each with a recommendation) until the need
|
|
26
|
+
is clear — then execute. See the Clarify reflex in \`.spectoflow/AGENTS.md\`.
|
|
27
|
+
|
|
24
28
|
- Command: \`/spectoflow\` (\`init\` / \`status\` / or just a request).
|
|
25
29
|
- Dashboard: \`node .spectoflow/dashboard/server.js\` → http://localhost:4319
|
|
26
30
|
- Artifacts are markdown in \`specs/\` and \`plans/\`; volatile state in \`.spectoflow/runtime.json\`.
|
|
@@ -30,6 +34,10 @@ const ROOT_AGENTS_MD = `# AGENTS.md — spectoflow
|
|
|
30
34
|
|
|
31
35
|
This project uses **spectoflow**. **Read \`.spectoflow/AGENTS.md\` and follow it** as your operating
|
|
32
36
|
instructions. Artifacts are markdown in \`specs/\` and \`plans/\`; the workflow is \`.spectoflow/workflow.md\`.
|
|
37
|
+
|
|
38
|
+
**Be an expert analyst, not an order-taker.** When a request is ambiguous, **clarify before acting**:
|
|
39
|
+
reflect it back and ask **one targeted question at a time** (each with a recommendation) until the need
|
|
40
|
+
is clear — then execute. See the Clarify reflex in \`.spectoflow/AGENTS.md\`.
|
|
33
41
|
`;
|
|
34
42
|
|
|
35
43
|
const GEMINI_MD = `# GEMINI.md — spectoflow
|
|
@@ -37,6 +45,10 @@ const GEMINI_MD = `# GEMINI.md — spectoflow
|
|
|
37
45
|
This project uses **spectoflow**. **Read \`.spectoflow/AGENTS.md\` and follow it** as your operating
|
|
38
46
|
instructions (intent router, workflow, standing rules). Artifacts are markdown in \`specs/\` and
|
|
39
47
|
\`plans/\`; the workflow is \`.spectoflow/workflow.md\`.
|
|
48
|
+
|
|
49
|
+
**Be an expert analyst, not an order-taker.** When a request is ambiguous, **clarify before acting**:
|
|
50
|
+
reflect it back and ask **one targeted question at a time** (each with a recommendation) until the need
|
|
51
|
+
is clear — then execute. See the Clarify reflex in \`.spectoflow/AGENTS.md\`.
|
|
40
52
|
`;
|
|
41
53
|
|
|
42
54
|
const SLASH_CMD = `---
|
package/lib/mcp.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*
|
|
3
|
+
* Idempotent MCP server wiring for `spectoflow init`.
|
|
4
|
+
*
|
|
5
|
+
* MCP-capable clients (Claude Code, and others that read a project `.mcp.json`) discover MCP servers
|
|
6
|
+
* from a JSON file with an `mcpServers` map. init seeds a `playwright` entry so the E2E agent can
|
|
7
|
+
* drive a real browser and generate/run Playwright tests — WITHOUT ever touching an entry the user
|
|
8
|
+
* (or another tool) already put there. Nothing is installed globally: the server runs via `npx`,
|
|
9
|
+
* fetched on first use, so wiring this config IS the whole "install".
|
|
10
|
+
*
|
|
11
|
+
* spectoflow's own zero-runtime-dependency invariant is unaffected — this writes into the USER's
|
|
12
|
+
* project, never into spectoflow.
|
|
13
|
+
*/
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
// The Playwright MCP server (Microsoft). npx fetches it on first use — no global install.
|
|
18
|
+
const PLAYWRIGHT_MCP = { command: 'npx', args: ['@playwright/mcp@latest'] };
|
|
19
|
+
|
|
20
|
+
// Merge a single MCP server into a project's MCP config file, idempotently and non-destructively.
|
|
21
|
+
// Returns one of:
|
|
22
|
+
// 'created' — file did not exist, created with just this server.
|
|
23
|
+
// 'added' — file existed; server inserted alongside the existing ones.
|
|
24
|
+
// 'exists' — server already present; file left exactly as-is (idempotent).
|
|
25
|
+
// 'skipped' — file present but not parseable/shaped as expected; left untouched (never clobbered).
|
|
26
|
+
function mergeMcpServer(filePath, name, config) {
|
|
27
|
+
if (fs.existsSync(filePath)) {
|
|
28
|
+
let doc;
|
|
29
|
+
try { doc = JSON.parse(fs.readFileSync(filePath, 'utf8')); }
|
|
30
|
+
catch { return 'skipped'; } // never clobber a file we can't understand
|
|
31
|
+
if (!doc || typeof doc !== 'object' || Array.isArray(doc)) return 'skipped';
|
|
32
|
+
const servers = doc.mcpServers && typeof doc.mcpServers === 'object' && !Array.isArray(doc.mcpServers)
|
|
33
|
+
? doc.mcpServers : null;
|
|
34
|
+
if (servers && Object.prototype.hasOwnProperty.call(servers, name)) return 'exists';
|
|
35
|
+
doc.mcpServers = { ...(servers || {}), [name]: config };
|
|
36
|
+
fs.writeFileSync(filePath, JSON.stringify(doc, null, 2) + '\n');
|
|
37
|
+
return 'added';
|
|
38
|
+
}
|
|
39
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
40
|
+
fs.writeFileSync(filePath, JSON.stringify({ mcpServers: { [name]: config } }, null, 2) + '\n');
|
|
41
|
+
return 'created';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { mergeMcpServer, PLAYWRIGHT_MCP };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectoflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Agent-agnostic spec-driven development framework + real-time local control plane. Markdown artifacts, intent router, workflow-by-scope.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spec-driven-development",
|
package/templates/AGENTS.md
CHANGED
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
A spec-driven development (SDD) framework. The user speaks in **plain language**; **you classify the
|
|
9
9
|
intent and run the right workflow.** Simplicity stays on the user's side — no ceremonial command to start.
|
|
10
10
|
|
|
11
|
+
## Stance — expert analyst, not an order-taker
|
|
12
|
+
|
|
13
|
+
You are a domain expert, not a passive executor. Reason from **two anchors at once**: the project's own
|
|
14
|
+
objectives (`specs/`, `plans/`, stated goals) **and** software best practices. Advise, recommend, and
|
|
15
|
+
push back when a request is unclear, risky, or contradicts the spec — always with a concrete, reasoned
|
|
16
|
+
recommendation, never a bare "it depends". A framework that blindly does what it's told just ships the
|
|
17
|
+
wrong thing faster; clarify and steer first, then execute.
|
|
18
|
+
|
|
11
19
|
## Language
|
|
12
20
|
|
|
13
21
|
Read `.spectoflow/config.json` → `language` (default `en`). Produce **all output in that language**:
|
|
@@ -37,15 +45,26 @@ whole file. This lets the dashboard and you co-edit without clobbering. Reflect
|
|
|
37
45
|
|
|
38
46
|
## The Router (run internally on every request)
|
|
39
47
|
|
|
40
|
-
1. **Intake** — known task ("develop T-012") → load it from `plans/*.md`. New request or tweak →
|
|
41
|
-
Explicit override ("just do it quick" / "full change") → forced
|
|
42
|
-
|
|
48
|
+
1. **Intake** — known task ("develop T-012") → load it from `plans/*.md`. New request or tweak →
|
|
49
|
+
clarify (step 2) then classify. Explicit override ("just do it quick" / "full change") → forced
|
|
50
|
+
level, **policy still applies**.
|
|
51
|
+
2. **Clarify (before classifying)** — if the request is ambiguous or under-specified (a vague symptom
|
|
52
|
+
like "login doesn't work" or "displays badly", missing acceptance, several plausible readings,
|
|
53
|
+
unclear scope/users), **do not guess and do not start**. Reflect it back in one sentence, then **ask
|
|
54
|
+
ONE targeted question at a time** — each carrying your recommended default and a one-line reason —
|
|
55
|
+
wait for the answer, and if it's still unclear ask the next. Stop the moment the intent is crisp,
|
|
56
|
+
then proceed. **Never dump a block of questions at once.** Anchor every question in the project's
|
|
57
|
+
objectives and best practices, not trivia. Load `.spectoflow/skills/clarify` for the procedure.
|
|
58
|
+
This step is **additive** — it feeds the steps below, it never replaces them. Mode-aware:
|
|
59
|
+
`autopilot` states one assumption and proceeds; `semi`/`manual` clarify. "Just do it / you decide"
|
|
60
|
+
is a valid answer → proceed on explicit, recorded assumptions (policy still applies).
|
|
61
|
+
3. **Classify** — Quick / Standard / Major. Highest signal wins: **scope · risk/reversibility ·
|
|
43
62
|
ambiguity · novelty**. Risk can force the level up even for tiny effort.
|
|
44
|
-
|
|
63
|
+
4. **Gate** — by `mode` (`.spectoflow/config.json`): **autopilot** proceeds · **semi** (default)
|
|
45
64
|
confirms if ambiguous/borderline/risky **and always for a Major** · **manual** confirms each step.
|
|
46
|
-
|
|
65
|
+
5. **Load** — read the enabled steps from `.spectoflow/workflow.md` (single source of truth), plus the
|
|
47
66
|
`.spectoflow/skills/` needed for those steps. Load only what this task needs.
|
|
48
|
-
|
|
67
|
+
6. **Run** — execute. A **policy gate** (`.spectoflow/policy.md`) can interrupt at any point, any mode.
|
|
49
68
|
|
|
50
69
|
## New / empty project → Intake
|
|
51
70
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# `.spectoflow/` — what this folder is
|
|
2
|
+
|
|
3
|
+
You're looking at the **spectoflow** framework for this project. spectoflow is an **agent-agnostic,
|
|
4
|
+
spec-driven development (SDD)** framework with a **real-time local control plane** (a dashboard). You
|
|
5
|
+
talk to your AI coding agent in plain language; spectoflow classifies the intent, runs the right
|
|
6
|
+
workflow, and tracks everything as **markdown artifacts** you can diff and own.
|
|
7
|
+
|
|
8
|
+
Everything the framework needs lives here in `.spectoflow/`, so your project root stays clean and the
|
|
9
|
+
framework is swappable/updatable. Your per-agent entry files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`)
|
|
10
|
+
sit at the project root and just point back here.
|
|
11
|
+
|
|
12
|
+
## How you use it
|
|
13
|
+
|
|
14
|
+
- **Just say what you want** to your agent ("add a login feature", "fix T-042"). The router in
|
|
15
|
+
`AGENTS.md` classifies it (quick / standard / major), gates it by your **mode** and **policy**, and
|
|
16
|
+
runs the matching workflow — no ceremonial command.
|
|
17
|
+
- **When your ask is vague, it clarifies first.** spectoflow behaves like an expert analyst, not an
|
|
18
|
+
order-taker: on an ambiguous request ("login displays badly") it reflects it back and asks **one
|
|
19
|
+
targeted question at a time** (each with a recommendation) until the need is crisp, then executes
|
|
20
|
+
(skill `clarify`, wired into the agent's memory in `AGENTS.md`).
|
|
21
|
+
- **Watch it live** in the dashboard:
|
|
22
|
+
```
|
|
23
|
+
spectoflow dashboard # → http://localhost:4319 (or: node .spectoflow/dashboard/server.js)
|
|
24
|
+
spectoflow dashboard stop # stop it (alias: spectoflow stop)
|
|
25
|
+
spectoflow status # progress + whether the dashboard is running
|
|
26
|
+
```
|
|
27
|
+
- **Change how it runs** in the dashboard's **Settings** tab (autonomy mode, output language, and the
|
|
28
|
+
dashboard **design**), or by editing `config.json`.
|
|
29
|
+
- **Update the framework** to a newer kit: `spectoflow update` (preserves your edits; a file you
|
|
30
|
+
changed is kept and its new version is written next to it as `*.new`).
|
|
31
|
+
|
|
32
|
+
## Where your work lives
|
|
33
|
+
|
|
34
|
+
Your **artifacts are markdown, and they live at the project root, not in here**:
|
|
35
|
+
|
|
36
|
+
- `specs/` — the specifications (intent, decisions, acceptance criteria) — your source of truth.
|
|
37
|
+
- `plans/` — checkbox task plans (`- [ ] T-001 Title @owner ~level %status`). The dashboard parses
|
|
38
|
+
these and writes back **one line at a time** (granular), so your agent and the dashboard never
|
|
39
|
+
clobber each other.
|
|
40
|
+
|
|
41
|
+
## What each file/folder here is
|
|
42
|
+
|
|
43
|
+
| Path | What it is |
|
|
44
|
+
|------|------------|
|
|
45
|
+
| `AGENTS.md` | **The brain** — the intent router, the modes, and the standing rules your agent follows. |
|
|
46
|
+
| `workflow.md` | The **single** workflow definition (the pipeline steps and their capability/skill). |
|
|
47
|
+
| `capabilities.md` | The capability palette (intake, analysis, planning, implementation, testing, quality, security, governance…) and how it adapts to the project type. |
|
|
48
|
+
| `policy.md` | **Non-negotiable gates** — actions that need explicit human approval regardless of mode (prod deploy, destructive migration, security change, spend, source-of-truth drift at done/Major). |
|
|
49
|
+
| `config.json` | Your settings: `mode`, `language`, active `agent`, `runners`, `design`, plans/specs dir. **Yours to edit** — `update` never overwrites it. |
|
|
50
|
+
| `agents/` | **Stable team personas** (product-manager, developer, qa-engineer, code-reviewer, spec-source-guardian…) — the *who*. |
|
|
51
|
+
| `skills/` | **Evolving procedures** (clarify, brainstorm, write-spec, write-plan, implement, write-e2e-tests, code-review, audit-source…) — the *how*. A workflow step → a capability → its agent → runs a skill. |
|
|
52
|
+
| `dashboard/` | The zero-dependency control plane: `server.js` (SSE + file-watch), `runner.js`, `orchestrator.js`, and `public/` (the UI, charts, designs, fonts). |
|
|
53
|
+
| `lib/` | The markdown storage engine (`store.js`) and helpers (e.g. `spec-drift.js` for the spec-source-guardian). |
|
|
54
|
+
| `hooks/` | Optional Claude Code hooks you can wire in yourself (e.g. `spec-drift.js`, a `Stop` hook that surfaces source-of-truth drift to the Attention tab). |
|
|
55
|
+
| `runtime.json` | **Volatile execution state** (running agents, orchestration, group-chat messages, attention items, history). Gitignored — safe to delete; it's rebuilt. |
|
|
56
|
+
| `.dashboard.lock` | Ephemeral pidfile so `spectoflow stop` can find the running dashboard. Gitignored. |
|
|
57
|
+
| `.manifest.json` | Hashes of the framework files at install time, so `update` can tell an untouched file from one you edited. |
|
|
58
|
+
|
|
59
|
+
## Principles (why it's shaped this way)
|
|
60
|
+
|
|
61
|
+
- **Artifacts are markdown** in `specs/`/`plans/`; volatile state is `runtime.json`. Writes are granular.
|
|
62
|
+
- **The framework lives here**; per-agent entry files are thin shims that point back — never duplicate
|
|
63
|
+
framework content per agent.
|
|
64
|
+
- **Agents are stable personas; skills are the evolving procedures.** Workflow → capability → agent → skill.
|
|
65
|
+
- **Mode ≠ policy.** Mode is routine friction; policy is approvals required regardless of mode.
|
|
66
|
+
- **Spec-anchored:** the spec is the intent of record; the code and tests are the enforced reality; the
|
|
67
|
+
`spec-source-guardian` keeps them from drifting apart (it flags, it never silently auto-fixes).
|
|
68
|
+
- **Zero runtime dependencies** — native Node only. The dashboard works offline.
|
|
69
|
+
|
|
70
|
+
## More
|
|
71
|
+
|
|
72
|
+
Project & docs: https://github.com/georgesmomo/spectoflow · installed via `npm i -g spectoflow`.
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
name: product-manager
|
|
3
3
|
title: Product Manager
|
|
4
4
|
capability: intake
|
|
5
|
-
uses: [brainstorm]
|
|
5
|
+
uses: [clarify, brainstorm]
|
|
6
6
|
description: Frames the need: problem, users, scope, out-of-scope.
|
|
7
7
|
standards: [product discovery]
|
|
8
8
|
---
|
|
9
9
|
# Product Manager
|
|
10
10
|
|
|
11
|
-
Stable team persona (the "who") for the `intake` capability. The *how* lives in the `
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Stable team persona (the "who") for the `intake` capability. The *how* lives in the `clarify` and
|
|
12
|
+
`brainstorm` skills (see `uses`): `clarify` is the always-on reflex that turns an ambiguous request
|
|
13
|
+
into a crisp, agreed need — one targeted question at a time — before anything else; `brainstorm` then
|
|
14
|
+
frames that need (problem, users, scope, risks) for a new build. Delegate here whenever a new or
|
|
15
|
+
unclear need arrives and must be understood before it becomes a spec or a plan.
|
|
14
16
|
|
|
15
17
|
## Mandate
|
|
16
18
|
Turn a raw ask into a framed problem — problem, users, constraints, risks, success metric — before
|
|
@@ -32,6 +32,11 @@ after-the-fact check. Owns the test suite's health (signal, speed, isolation), n
|
|
|
32
32
|
edge cases and failure paths — not just the happy path. Prefer the fastest level (unit) that gives
|
|
33
33
|
real confidence; escalate to integration or `write-e2e-tests` only when the behaviour crosses a
|
|
34
34
|
boundary (network, DB, filesystem, another service) that a unit test cannot honestly exercise.
|
|
35
|
+
- **For end-to-end flows, drive the browser via Playwright MCP when available** (wired into the
|
|
36
|
+
project's `.mcp.json` by `spectoflow init`), falling back down the `write-e2e-tests` capability
|
|
37
|
+
ladder (native browser tooling → local Playwright headed/codegen → write the spec and raise a
|
|
38
|
+
`need`). The committed Playwright spec is always the deliverable; live driving is only the means, and
|
|
39
|
+
a flow you couldn't actually run is reported as such, never as a pass.
|
|
35
40
|
|
|
36
41
|
## Definition of done
|
|
37
42
|
Every acceptance criterion has a corresponding test, plus its meaningful edge cases (empty/null,
|
|
@@ -9,6 +9,11 @@ Palette: intake · research · analysis · architecture · planning · testing
|
|
|
9
9
|
(skill `audit-source`) watches that the spec (intent) and the code/tests (reality) stay coherent, and
|
|
10
10
|
surfaces drift to the Attention tab; it gates only at `done`/Major (see `policy.md`), never mid-edit.
|
|
11
11
|
|
|
12
|
+
`clarify` is a **reflex under `intake`, not a workflow step** either: on *any* ambiguous request the
|
|
13
|
+
agent reflects it back and asks **one targeted question at a time** (each with a recommendation) until
|
|
14
|
+
the need is crisp, then proceeds — it feeds the workflow, never replaces it. See `skills/clarify` and
|
|
15
|
+
the Clarify step in `AGENTS.md`.
|
|
16
|
+
|
|
12
17
|
| Project type | Active capabilities |
|
|
13
18
|
|---|---|
|
|
14
19
|
| app / web / API | all |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clarify
|
|
3
|
+
description: When a request is ambiguous, act as an analyst — reflect it back and ask one targeted question at a time (each with a recommendation) until the need is crisp, then execute.
|
|
4
|
+
capability: intake
|
|
5
|
+
inputs: The raw request from the user, plus the project's objectives (specs/, plans/, goals) and the mode/policy.
|
|
6
|
+
outputs: A crisp, confirmed statement of the need (or explicit assumptions to proceed on), ready for classification and the normal workflow.
|
|
7
|
+
standard: requirements elicitation
|
|
8
|
+
---
|
|
9
|
+
# Clarify
|
|
10
|
+
|
|
11
|
+
Turn a vague request into a crisp, agreed need **before** classifying or acting — the way a good
|
|
12
|
+
analyst does: reflect, ask the sharpest question, listen, repeat. This is a **reflex**, always in the
|
|
13
|
+
agent's memory (see the Clarify step in `AGENTS.md`), not a workflow stage — it fires on *any*
|
|
14
|
+
request, including bug reports and change requests on an existing project ("the login page doesn't
|
|
15
|
+
display well, users can't sign in").
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
Whenever a request is ambiguous or under-specified and acting on it would mean guessing:
|
|
19
|
+
- a **vague symptom** ("doesn't work", "displays badly", "is slow") with no observable, testable meaning;
|
|
20
|
+
- **missing acceptance** — you can't yet name what "done" looks like;
|
|
21
|
+
- **several plausible readings** that would lead to genuinely different work;
|
|
22
|
+
- **unclear scope or users** ("everyone"? one browser? mobile only?);
|
|
23
|
+
- a request that **contradicts the spec** or a best practice — clarify the intent before complying.
|
|
24
|
+
|
|
25
|
+
Skip it when the request is already unambiguous and testable — over-questioning is its own failure.
|
|
26
|
+
|
|
27
|
+
## Method — reflect, then one question at a time
|
|
28
|
+
1. **Reflect it back.** Restate the request in one sentence and name the goal as you understand it.
|
|
29
|
+
Surface your assumptions explicitly so a wrong one is easy to correct.
|
|
30
|
+
2. **Ask ONE question — the highest-value one first.** The single question that most reduces
|
|
31
|
+
uncertainty about what to build. Carry **your recommended default and a one-line reason** ("I'd
|
|
32
|
+
assume the layout breaks on mobile, since that's the common case — is that it?"). Prefer a small set
|
|
33
|
+
of concrete options over an open prompt. **Never send a block of questions.**
|
|
34
|
+
3. **Wait, then decide if you still need more.** Read the answer. If the intent is now crisp, stop and
|
|
35
|
+
proceed. If not, ask the next single question. Keep looping until it's clear — typically 1-3
|
|
36
|
+
questions, rarely more.
|
|
37
|
+
4. **Anchor every question in the two sources of truth.** Each question and recommendation must follow
|
|
38
|
+
from (a) the project's objectives (`specs/`, `plans/`, stated goals) and (b) domain best practices —
|
|
39
|
+
so you're steering like an expert, not fishing. For a login bug that means asking about the
|
|
40
|
+
observable failure, the affected users/browser, and the acceptance ("signed-in and redirected"),
|
|
41
|
+
not cosmetic trivia.
|
|
42
|
+
5. **Converge and confirm.** Once clear, restate the crisp need in one or two lines and get a yes
|
|
43
|
+
before running: "So: <need>, for <users>, done when <acceptance>. Correct?"
|
|
44
|
+
6. **Then hand off** the confirmed need to the normal Router flow (Classify → Gate → Load → Run), or to
|
|
45
|
+
`brainstorm` / `analyze-requirements` for a new build. Clarify **replaces nothing** downstream.
|
|
46
|
+
|
|
47
|
+
## Guardrails
|
|
48
|
+
- **One question at a time** — never a wall of questions. This is the whole point.
|
|
49
|
+
- **Only ask what changes the outcome.** If an answer wouldn't change what you'd do, don't ask it.
|
|
50
|
+
- **Always recommend.** A question without your reasoned default offloads the thinking back onto the
|
|
51
|
+
user — give the expert view, let them correct it.
|
|
52
|
+
- **Respect the mode** (`config.json`): `autopilot` → state one assumption and proceed (record it);
|
|
53
|
+
`semi` (default) → clarify when ambiguous/risky; `manual` → clarify. "Just do it / you decide" is a
|
|
54
|
+
valid answer → proceed on explicit, recorded assumptions (`policy.md` still applies).
|
|
55
|
+
- **Cap the loop.** If it's still unclear after a few rounds, propose the most reasonable
|
|
56
|
+
interpretation as a recommendation and ask for a yes/no — don't interrogate indefinitely.
|
|
57
|
+
- **Never fabricate the answer** to keep moving; a decision-blocking gap that isn't yours to settle is
|
|
58
|
+
a `need`, raised per `policy.md`.
|
|
59
|
+
|
|
60
|
+
## Output contract
|
|
61
|
+
The confirmed need (or the assumptions being proceeded on) is recorded granularly — a note/task
|
|
62
|
+
comment, or the spec if one exists — one line at a time. Report to the orchestrator and group chat:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
::spectoflow role=intake kind=clarify msg=<the one crisp question you just asked, or the confirmed need>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Quality bar
|
|
69
|
+
- [ ] The request was reflected back in one sentence before any question was asked.
|
|
70
|
+
- [ ] Questions were asked **one at a time**, never as a block.
|
|
71
|
+
- [ ] Every question carried a recommended default with a one-line reason.
|
|
72
|
+
- [ ] Each question was anchored in the project's objectives and/or a best practice — not trivia.
|
|
73
|
+
- [ ] The loop stopped as soon as the need was crisp (no over-questioning), and the crisp need was
|
|
74
|
+
confirmed with the user before execution.
|
|
75
|
+
- [ ] Mode was respected; "you decide" was honored by proceeding on explicit, recorded assumptions.
|
|
76
|
+
|
|
77
|
+
## References
|
|
78
|
+
- Anthropic, "Claude Code best practices" (be specific; let the agent ask before acting) —
|
|
79
|
+
https://www.anthropic.com/engineering/claude-code-best-practices
|
|
80
|
+
- IIBA, *A Guide to the Business Analysis Body of Knowledge (BABOK)* — Elicitation & Collaboration —
|
|
81
|
+
https://www.iiba.org/career-resources/a-business-analysis-professionals-foundation/babok/
|
|
82
|
+
- Gojko Adzic, *Specification by Example* (Manning, 2011) — converging on a shared, testable
|
|
83
|
+
understanding before building — https://gojko.net/books/specification-by-example/
|
|
@@ -44,12 +44,22 @@ Practices below are current Playwright guidance (see References for exact source
|
|
|
44
44
|
8. **Keep specs scoped to one flow each**, named for the behavior under test, and placed under
|
|
45
45
|
`tests/e2e/*.spec.ts` in the user's project.
|
|
46
46
|
|
|
47
|
-
**
|
|
48
|
-
|
|
49
|
-
the
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
**Driving the browser (live repro + test generation) — use the best available, in this order:**
|
|
48
|
+
1. **Playwright MCP** (`@playwright/mcp`, wired into the project's `.mcp.json` by `spectoflow init`):
|
|
49
|
+
the **agent-agnostic** way to drive a real browser and **generate** a spec from a recorded flow.
|
|
50
|
+
Works in any MCP client (Claude Code, Codex, Cursor, …). `npx` fetches it on first use — nothing to
|
|
51
|
+
install; if it isn't wired yet, add it or run `spectoflow init` again (idempotent).
|
|
52
|
+
2. **The client's native browser tooling** (for Claude Code, the Chrome extension / `claude-in-chrome`)
|
|
53
|
+
for live/exploratory checks when MCP isn't wired.
|
|
54
|
+
3. **Local Playwright** — `npx playwright codegen` / headed mode for a quick, throwaway look;
|
|
55
|
+
`npx playwright install` provides the browsers. Needs `@playwright/test` as the project's devDependency.
|
|
56
|
+
4. **If no browser can run at all** (restricted CI, no browsers installed): still **write the durable
|
|
57
|
+
spec** (the artifact that lasts), then raise a `need` / Attention item with the exact commands to
|
|
58
|
+
enable it — never report a pass you couldn't actually observe.
|
|
59
|
+
|
|
60
|
+
**Live/exploratory verification is not this skill's output.** Whichever rung above you're on, the
|
|
61
|
+
durable, CI-runnable artifact this skill produces is always the Playwright **spec file**, not the live
|
|
62
|
+
session — the live drive is only the means to write and check it.
|
|
53
63
|
|
|
54
64
|
**Playwright is a dependency of the user's project, never of spectoflow.** This skill authors tests
|
|
55
65
|
against whatever Playwright version the target project has (or proposes adding `@playwright/test` as a
|