Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 5 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,16 @@ specleft features add-scenario \
specleft status
```

### Path 2: Bulk-generate feature specs from a PRD
### Path 2: Discover specs from existing code

Create `prd.md` describing intended behavior.

**Recommended**: Update `.specleft/templates/prd-template.yml` to customize how your PRD sections map to features/scenarios.

Then run:
For brownfield projects, discover and stage draft specs from existing tests/routes/docstrings:

```bash

# Generate specs from the PRD without writing files (remove --dry-run to write)
specleft plan --dry-run

# Validate the generated specs
specleft features validate

# Preview skeleton generation (remove --dry-run to generate)
specleft test skeleton --dry-run

# Confirm and generate skeleton tests
specleft test skeleton

# Show traceability / coverage status
specleft discover
specleft discover promote --all
specleft status

# Run your tests with pytest as normal
pytest
```

That flow converts `prd.md` into `.specleft/specs/*.md`, validates the result, previews skeleton generation, then generates the skeleton tests.

## When to Use SpecLeft

- Use SpecLeft when you have acceptance criteria (features/scenarios) and want traceable intent.
Expand Down Expand Up @@ -110,6 +89,7 @@ Otherwise begin with:
specleft doctor --format json
specleft contract --format json
specleft features stats --format json
specleft discover --format json
```

SpecLeft includes a verifiable skill file at `.specleft/SKILL.md`. Verify integrity with:
Expand Down
6 changes: 6 additions & 0 deletions docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ Builds an HTML report from `.specleft/results/`.
`--analyze` inspects PRD structure without writing files.
`--template` uses a YAML section-matching template.

## Discovery

`specleft discover --format json [PROJECT_ROOT] [--dry-run] [--language python|typescript] [--output-dir PATH] [--specs-dir PATH]`

`specleft discover promote --format json [--all] [FEATURE_ID...] [--specs-dir PATH] [--overwrite] [--dry-run]`

## Contract

### Show contract
Expand Down
77 changes: 77 additions & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,83 @@ Options:
--format [table|json] Output format (default: table)
```

## Discover

### `specleft discover`

Run the full discovery pipeline and stage generated draft specs.

```bash
specleft discover [OPTIONS] [PROJECT_ROOT]

Options:
--format [table|json] Output format (default: auto-detect TTY)
--dry-run Preview without writing files
--output-dir PATH Override staging dir (default: .specleft/specs/_discovered/)
--language [python|typescript]
Limit languages (repeatable)
--specs-dir PATH Existing specs dir for traceability matching
--pretty Pretty-print JSON output
```

Table output example:

```text
Scanning project...
✓ Python (pytest) — 142 test functions
✓ API routes — 24 routes
✓ Docstrings — 67 items
✓ Git history — 200 commits

Generating draft specs...

Feature Scenarios Written to
─────────────────────── ───────── ──────────────────────────────────────
user-authentication 8 .specleft/specs/_discovered/user-authentication.md
payment-processing 5 .specleft/specs/_discovered/payment-processing.md

14 features, 47 scenarios written to .specleft/specs/_discovered
Review drafts, then promote with: specleft discover promote
```

JSON output schema:

```json
{
"features": [
{
"feature_id": "user-authentication",
"name": "User Authentication",
"scenario_count": 8,
"output_file": ".specleft/specs/_discovered/user-authentication.md",
"confidence": 0.8
}
],
"total_features": 14,
"total_scenarios": 47,
"output_dir": ".specleft/specs/_discovered",
"dry_run": false,
"written": [".specleft/specs/_discovered/user-authentication.md"],
"errors": []
}
```

### `specleft discover promote`

Promote draft specs into the active specs directory. Draft files remain in staging.

```bash
specleft discover promote [OPTIONS] [FEATURE_ID...]

Options:
--all Promote every staged draft file
--specs-dir PATH Destination specs dir (default: resolve_specs_dir())
--overwrite Replace existing files at destination
--dry-run Preview without writing files
--format [table|json]
--pretty
```

## Status

### `specleft status`
Expand Down
9 changes: 9 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ mkdir -p .specleft/specs/calculator/addition

Create `.specleft/specs/calculator/_feature.md`, `.specleft/specs/calculator/addition/_story.md`, and a scenario file like `.specleft/specs/calculator/addition/basic_addition.md`.

## Discover Specs From Existing Code

```bash
specleft discover
specleft discover promote --all
```

`specleft discover` stages generated drafts in `.specleft/specs/_discovered/` so they can be reviewed before promotion.

## Generate Tests

```bash
Expand Down
28 changes: 28 additions & 0 deletions features/feature-spec-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,29 @@ Add shared discovery infrastructure for Issues #125 and #126: centralized parser
**When** `generate_draft_specs(..., traceability_links=links)` writes markdown
**Then** the scenario block includes a `linked_tests` frontmatter section with file, function, and confidence values.

### Story 16: Discover command and draft promotion flow
**Scenario:** As a user onboarding from an existing codebase, I need one command to run discovery and stage draft specs.
**Given** a repository with supported source files and tests
**When** I run `specleft discover`
**Then** discovery runs end-to-end and writes draft specs to `.specleft/specs/_discovered/`.

**Scenario:** As an automation client, I need structured machine-readable output.
**Given** discovery succeeds or miners report partial failures
**When** I run `specleft discover --format json`
**Then** the command exits successfully and outputs valid JSON with features, totals, output dir, dry-run state, and `errors`.

**Scenario:** As a user reviewing generated drafts, I need a safe promotion step.
**Given** staged files exist in `.specleft/specs/_discovered/`
**When** I run `specleft discover promote --all`
**Then** all draft files are copied to the active specs directory.
**And** the files remain in `_discovered/` after promotion.

**Scenario:** As a user promoting incrementally, I need targeted and non-destructive behavior.
**Given** staged draft files and existing active specs
**When** I run `specleft discover promote user-authentication`
**Then** only that feature file is copied.
**And** existing destination files are skipped unless `--overwrite` is passed.

## Acceptance Criteria
- Language abstraction returns `SupportedLanguage` members for `.py`, `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs` and `None` otherwise.
- `LanguageRegistry().parse(path_to_py_file)` returns `(node, SupportedLanguage.PYTHON)` for valid Python input.
Expand Down Expand Up @@ -299,3 +322,8 @@ Add shared discovery infrastructure for Issues #125 and #126: centralized parser
- `specleft status` marks convention-linked scenarios as implemented with `match_kind="convention"` in verbose JSON output.
- `specleft status --format table` displays `✓ (convention)` for convention-linked scenarios.
- `generate_draft_specs(..., traceability_links=...)` emits `linked_tests` frontmatter for matched scenarios.
- `specleft discover --dry-run` does not write files and reports planned outputs.
- `specleft discover --format json` exits `0` with valid JSON output even when miners report errors.
- `specleft discover` writes drafts to `.specleft/specs/_discovered/` by default and supports `--output-dir` override.
- `specleft discover promote --all` copies staged drafts to active specs while keeping staged drafts intact.
- `specleft discover promote <feature-id>` copies only the requested draft and skips existing files unless `--overwrite`.
2 changes: 2 additions & 0 deletions src/specleft/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from specleft.commands import (
contract,
coverage,
discover,
doctor,
features,
guide,
Expand Down Expand Up @@ -48,6 +49,7 @@ def cli() -> None:
cli.add_command(coverage)
cli.add_command(init)
cli.add_command(contract)
cli.add_command(discover)
cli.add_command(skill_group)
cli.add_command(guide)
cli.add_command(mcp)
Expand Down
2 changes: 2 additions & 0 deletions src/specleft/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from specleft.commands.contract import contract
from specleft.commands.coverage import coverage
from specleft.commands.discover import discover
from specleft.commands.doctor import doctor
from specleft.commands.features import features
from specleft.commands.guide import guide
Expand All @@ -21,6 +22,7 @@
__all__ = [
"contract",
"coverage",
"discover",
"doctor",
"features",
"guide",
Expand Down
Loading