Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project follows [Semantic Versioning](https://semver.org/). From **v1.0.0**

### Added

- **`flightdeck demo`** — runs the packaged **examples/quickstart** workflow (init → pricing → policy → register → ingest → diff → promote → history) in a **temp workspace**, with no **`sed`** or repo paths; wheels ship fixtures under **`flightdeck/_bundled_quickstart`** via Hatch **`force-include`**. **`FLIGHTDECK_QUICKSTART_ROOT`** overrides fixture resolution for CI or forks.
- **Web UI (`flightdeck serve`):** **`/#/settings`** for appearance (Light / Dark / System, **`flightdeck-theme`**); collapsible sidebar (**`flightdeck-sidebar-collapsed`**); **offline system font stack** (no remote font CSS); sidebar + favicon use **bundled** **`/assets/flightdeck-icon-*.png`** with stable **`GET /flightdeck-icon.png`** fallback; **`html[data-theme="dark"]`** tokens and Playwright **`web/e2e/`** (`smoke` icon checks, `theme.spec.ts`, `sidebar.spec.ts`).
- **`flightdeck pricing check`** — reports **`flightdeck-bundled-*`** snapshot age vs **`--max-age-days`** (default **90**); **`--fail`** for CI. **`release diff`** / **`POST /v1/diff`** append **`pricing.warnings`** when bundled snapshots exceed the same age threshold.
- **`flightdeck.integrations.telemetry.configure_otel_tracing()`** — optional OTLP HTTP **`TracerProvider`** wiring when the **`telemetry`** extra is installed (see **`docs/sdk-integrations.md`**).
Expand Down
11 changes: 11 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ python -m ruff check src tests
python -m pytest
flightdeck --help
flightdeck doctor
flightdeck demo
flightdeck-quickstart-verify
```

**Fast path for contributors:** **`flightdeck demo`** runs the same core ledger steps as below in a **temp workspace** (fixtures from **`examples/quickstart`**, or **`flightdeck/_bundled_quickstart`** inside an installed wheel). **`flightdeck-quickstart-verify`** adds **`release verify`** + **`doctor`**.

Match **CI**’s CLI smoke: **`flightdeck --help`** must run successfully after changes to the CLI surface.

Full command flags and exit codes: [README.md](https://github.com/flightdeckdev/flightdeck/blob/main/README.md). Cross-platform quickstart parity: **`flightdeck-quickstart-verify`** / **`python -m flightdeck.quickstart_smoke`** (also run in CI). HTTP API reference: **[docs/http-api.md](docs/http-api.md)**. Python SDK: **[docs/sdk.md](docs/sdk.md)**.
Expand Down Expand Up @@ -151,6 +154,14 @@ If **PyPI** rejects **attestations** for your project, set **`attestations: fals

## Local Demo

**One command** (uses bundled **`examples/quickstart`** fixtures; no **`sed`**):

```bash
flightdeck demo
```

**Manual** (same story as **`flightdeck demo`**, in your cwd):

```bash
flightdeck init
flightdeck pricing import examples/quickstart/pricing-baseline.yaml
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,33 @@ flowchart LR

---

## Fast start

After **`pip install flightdeck-ai`** (or **`uv tool install flightdeck-ai`**):

```bash
flightdeck demo
```

**`flightdeck demo`** runs the full quickstart ledger flow in a disposable temp workspace—no **`sed`**, no fixture paths—using **`examples/quickstart`** from your checkout or packaged **`flightdeck/_bundled_quickstart`** from PyPI.

**Web UI** (needs a workspace in the current directory):

```bash
flightdeck init
flightdeck serve
```

Open **http://127.0.0.1:8765/**. Same end-to-end checks CI uses: **`flightdeck-quickstart-verify`** (contributors: **`uv run flightdeck-quickstart-verify`**).

---

## Install and smoke-test

```bash
uv sync --extra dev
uv run flightdeck --help
uv run flightdeck demo
uv run flightdeck-quickstart-verify
```

Expand Down Expand Up @@ -138,6 +160,7 @@ Bundled pricing from `init` is a **convenience snapshot**—`flightdeck pricing
uv sync --frozen --extra dev
uv run python -m ruff check src tests
uv run python -m pytest
uv run flightdeck demo
uv run flightdeck-quickstart-verify
uv run flightdeck --help
```
Expand Down
25 changes: 24 additions & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ serve` see [http-api.md](http-api.md).
| `--version` | Print the installed version and exit |
| `--help` | Print help for any command or subcommand |

All commands require a `flightdeck.yaml` in the working directory (or the default path
Most commands require `flightdeck.yaml` in the working directory (or the default path
`./flightdeck.yaml`). Run `flightdeck init` to create one. **`flightdeck init`** writes the
config, then loads it to migrate the ledger and (by default) import bundled pricing.

**`flightdeck demo`** is an exception: it creates a **temporary** workspace and does not read `./flightdeck.yaml` from your shell cwd.

## Actor resolution

Several commands that write to the audit ledger (`release promote`, `release rollback`,
Expand Down Expand Up @@ -76,6 +78,27 @@ set **`database_url`** to a `postgresql://…` (or `postgres://…`) DSN and ins

---

## `flightdeck demo`

Run the **examples/quickstart** workflow end-to-end in a **disposable temp directory**: **`init`** → custom **`pricing import`** (both YAMLs) → **`policy set`** → **`release register`** (both bundles) → substitute **`release_id`** placeholders in JSONL → **`runs ingest`** → **`release diff`** → **`release promote`** (baseline under policy) → **`release history`**.

Does **not** require **`flightdeck.yaml`** in the current directory. Fixtures resolve in order: **`--quickstart-root`**, **`FLIGHTDECK_QUICKSTART_ROOT`**, **`examples/quickstart`** relative to a git checkout, then **`flightdeck/_bundled_quickstart`** packaged in the wheel (PyPI installs).

```bash
flightdeck demo [--quickstart-root DIR] [--verify / --no-verify] [--doctor / --no-doctor] [--keep-workspace]
```

| Option | Default | Description |
|--------|---------|-------------|
| `--quickstart-root` | (see above) | Directory containing `policy.yaml`, pricing YAMLs, `*-events.jsonl`, and `baseline-release` / `candidate-release` |
| `--verify` | off | Also run **`release verify`** on the baseline bundle (parity with **`flightdeck-quickstart-verify`**) |
| `--doctor` | off | Also run **`flightdeck doctor`** |
| `--keep-workspace` | off | Keep the temp workspace and print its path |

On success, prints a short confirmation. Exit **0** on success, **1** on failure (same as subprocess failures from underlying CLI steps).

---

## `flightdeck doctor`

Run read-only health checks on the workspace ledger (SQLite file or PostgreSQL when
Expand Down
8 changes: 7 additions & 1 deletion examples/quickstart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ These files are meant to be copied or substituted locally:
- `policy.yaml` is an example active policy used by `release diff` and `release promote`.
- `*-events.jsonl` contain placeholder `release_id` values (`__BASELINE_RELEASE_ID__`, `__CANDIDATE_RELEASE_ID__`).

Fastest path (from **repository root**, with **uv**):
Fastest path after **`pip install flightdeck-ai`**:

```bash
flightdeck demo
```

Full CI parity (verify + doctor; from **repository root** with **uv**):

```bash
uv run flightdeck-quickstart-verify
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ flightdeck-quickstart-verify = "flightdeck.quickstart_smoke:quickstart_verify_ma

[tool.hatch.build.targets.wheel]
packages = ["src/flightdeck"]
force-include = { "examples/quickstart" = "src/flightdeck/_bundled_quickstart" }

[tool.uv]
# Contributor installs: `uv sync --extra dev` (see DEVELOPMENT.md). After changing
Expand Down
1 change: 1 addition & 0 deletions src/flightdeck/_bundled_quickstart/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Bundled quickstart fixtures (wheel: see pyproject hatch force-include)."""
60 changes: 60 additions & 0 deletions src/flightdeck/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from flightdeck import __version__
from flightdeck.bundle import bundle_checksum
from flightdeck.demo_flow import demo_session
from flightdeck.bundled_pricing_bootstrap import (
BUNDLED_PRICING_VERSION,
DEFAULT_CATALOG_RELATIVE_PATH,
Expand Down Expand Up @@ -106,6 +107,65 @@ def init(path_: str, no_bundled_pricing: bool) -> None:
)


@cli.command()
@click.option(
"--quickstart-root",
"quickstart_root_opt",
type=click.Path(exists=True, file_okay=False, path_type=Path),
default=None,
help="Directory with quickstart YAML/JSONL fixtures (default: repo examples/ or bundled wheel copy).",
)
@click.option(
"--verify/--no-verify",
default=False,
show_default=True,
help="Also run release verify on the baseline bundle (matches flightdeck-quickstart-verify).",
)
@click.option(
"--doctor/--no-doctor",
default=False,
show_default=True,
help="Also run flightdeck doctor after the workflow.",
)
@click.option(
"--keep-workspace",
is_flag=True,
default=False,
help="Keep the temp workspace and print its path (for inspection).",
)
def demo(
quickstart_root_opt: Path | None,
verify: bool,
doctor: bool,
keep_workspace: bool,
) -> None:
"""Run the bundled quickstart end-to-end in a disposable workspace (no manual sed).

Typical install: ``pip install flightdeck-ai`` then ``flightdeck demo``. Next: ``flightdeck init``
in your project and wire ``runs ingest`` / ``release diff`` from real agents.
"""
ws = demo_session(
verify=verify,
doctor=doctor,
qs_dir=str(quickstart_root_opt) if quickstart_root_opt is not None else None,
promote_reason="demo",
keep_workspace=keep_workspace,
)
click.echo(
"Demo OK — workspace initialized, releases registered, runs ingested, "
"diff computed, baseline promoted under policy."
)
extras = []
if verify:
extras.append("verify")
if doctor:
extras.append("doctor")
if extras:
click.echo(f"(also ran: {', '.join(extras)})")
if keep_workspace and ws is not None:
click.echo(f"Workspace: {ws}")


@cli.command("doctor")
@click.option(
"--backup",
Expand Down
Loading
Loading