Metadata-Version: 2.4
Name: devflow-engine
Version: 1.1.23
Summary: DevFlow v2 CLI-first engine (projects, stories, execution store, review packets)
Author: DevFlow
License: Proprietary
Requires-Python: >=3.11
Requires-Dist: cryptography>=45.0
Requires-Dist: pydantic>=2.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.7
Requires-Dist: typer>=0.12
Description-Content-Type: text/markdown

# DevFlow Engine (v2)

CLI-first Python engine for DevFlow v2.

## Goals
- Project lifecycle: draft shell -> bind workspace/repo -> init/register/list/remove
- Story lifecycle: index/validate/register/execute
- Planning support: repo analysis -> source docs -> scopes -> approved scope -> idea(s) -> DevFlow stories
- Implementation workflow: "green" gate = tests + typecheck + lint
- Review workflow: story-driven compliance/soundness/security review packets persisted in SQLite
- Error workflow: error queue + remediation runs
- Execution store: `.devflow/execution.sqlite`

## Documentation
- `docs/story-implementation-planning-node.md` — per-story planning/gating node before TestDesign/Red, with dependency findings, queue decisions, and registry expectations consumed by downstream implementation nodes.

## Install / Dev
This repo is intended to be run with **uv**.

```bash
cd devflow_engine
uv venv
uv pip install -e '.[dev]'
```

Run the CLI:
```bash
devflow --help
```

## Happy path
1. project shell created in control plane
2. workspace/repo bound to project
3. registration DAG runs via `devflow project init` or `devflow project import`
4. project reaches `ready_for_source_scope`
5. source docs -> scopes
6. approved scope -> idea(s)
7. idea -> DevFlow stories
8. story -> implementation
9. implementation -> review

## Quickstart
Register an existing repo with DevFlow:
```bash
devflow project init --name my-repo
```

Create and register a new repo from a template:
```bash
devflow project import /absolute/path/to/my-repo --init python
```

Clone and register an existing GitHub repo:
```bash
devflow project import owner/repo
```

Draft story contracts based on repo scan:
```bash
devflow plan analyze
ls .devflow/drafts
```

Validate and register a story:
```bash
devflow story validate .devflow/drafts/DF-PLAN-001.yaml
devflow story register .devflow/drafts/DF-PLAN-001.yaml
```

Run the "green gate":
```bash
devflow impl gate
# or
./scripts/green.sh
```

Generate a review packet:
```bash
devflow review run DF-PLAN-001
```

Inspect errors:
```bash
devflow error list
```

Inspect per-node outputs from a stored run:
```bash
# dump a specific run by run_id
python scripts/dump_run_node_outputs.py \
  --run-id <run_uuid>

# or dump the latest run for any DAG by dag_id
python scripts/dump_run_node_outputs.py \
  --dag-id implementation_dag

# second-most-recent run for that DAG
python scripts/dump_run_node_outputs.py \
  --dag-id implementation_dag \
  --latest-index 2
```

Dumps are written under `.devflow/node_output_dumps/<dag>/<label>/<timestamp>/` by default.
The navigation path intentionally stays human-readable and omits run IDs / object IDs where possible:
- `<dag>` comes from `runs.dag_id` unless it looks like an ID, in which case the folder falls back to `dag`
- `<label>` is derived from readable config fields such as `label`, `name`, `title`, `idea_title`, `scope_title`, or `story_title`
- the exact `run_id` still lands in `manifest.json` inside the dump directory

Use `--output-root /tmp/devflow-dumps` to write somewhere else.

Run the source -> scope scaffold end-to-end:
```bash
devflow source-scope run \
  --project-id proj_demo \
  --intake-id source_demo \
  --text "Customers approve quotes online. Approved quotes create jobs. Completed jobs create invoices and customers can pay online."
```

Gate a pre-shaped normalized packet + scope outline deterministically:
```bash
devflow source-scope gate \
  --project-id proj_demo \
  --source-packet .devflow/path/to/normalized_source_packet.json \
  --scope-outline .devflow/path/to/scope_outline.json
```

## Story contracts
Story contracts are YAML documents containing:
- `id`, `title`
- `planes`: required plane write-ups (`product`, `ux`, `technical`, `security`, `compliance`, `operations`)
- `plane_oracles`: list of `{plane, anchor}` entries used as verification anchors

The contract validator enforces presence of required planes + non-empty plane_oracles.

## Execution store
All runs/events/errors/review packets are stored in:
- `.devflow/execution.sqlite`

This database is created automatically on first CLI usage.

## Workers / Background services

### Supabase execution-event listener (`devflow worker supabase-events`)

This is the DFE-side listener/dispatcher for the `devflow_execution_events` Supabase table.
It is the single long-running process that bridges the control-plane (Supabase) to the local
DevFlow engine — picking up queued events and dispatching the appropriate DFE workflow for each.

**Normal operation (continuous loop with Realtime):**
```bash
devflow worker supabase-events
```

Starts an indefinite polling loop. While running it also opens a Supabase Realtime WebSocket
subscription on `devflow_execution_events`. New `INSERT` events on that table wake the dispatch
loop immediately rather than waiting for the next poll interval (default: 3 s). If the WebSocket
connection drops it reconnects automatically in the background; polling continues as the fallback
during any gap.

**Process a single queued event and exit:**
```bash
devflow worker supabase-events --once
```

Useful for manual trigger / smoke testing.

**Disable Realtime (polling only):**
```bash
devflow worker supabase-events --no-realtime
```

Runs the same polling loop but skips the WebSocket listener entirely. Use this when the
`websockets` Python package is unavailable, or when you need to debug without a live connection.

**Additional options:**
| Flag | Default | Description |
|---|---|---|
| `--sleep-seconds N` | `3.0` | Idle sleep between polls (also caps realtime wake latency) |
| `--max-iterations N` | unlimited | Stop after N loop iterations |
| `--json` | off | Emit JSON summary on exit |

**When queued events are not being picked up — checklist:**
1. Verify the worker is running: there should be a live `devflow worker supabase-events` process.
2. Check Supabase credentials: `SUPABASE_URL` and `SUPABASE_SERVICE_KEY` (or equivalent config)
   must be set and valid.
3. Confirm the event row in `devflow_execution_events` has `status = queued` and `run_id IS NULL`
   — events with any other status are skipped.
4. Check that the event's `event_type` is in the supported set (see
   `docs/queue-worker-infra.md` → *Supported event types*).
5. Run with `--once` to get an immediate result and check stderr/stdout for errors.
6. If Realtime is misbehaving (false wake-ups or missed wakes), try `--no-realtime` to isolate
   the issue to the polling path.

See `docs/queue-worker-infra.md` for full architecture details.

## Design notes
- `docs/scope-idea-agentification.md` — current scope->idea agentic runtime notes
- `docs/ui-grounding-curtis-medium-tier-doctrine.md` — follow-on UI grounding / wireframe planning doctrine from the Curtis pass, including the proposed `ui_screen_inventory.json` contract and the default medium-tier minimum for customer-facing wireframes
