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
29 changes: 18 additions & 11 deletions CURRENT_STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

## Active milestone

**S4 — Analysis parity+ (0.3.0): in progress.** S0–S3 are complete (the engine
and the native inspector). S4 reaches parity with the toolkit's analysis surface;
report generation (#41), anonymize-on-export (#42), semantic trace diff (#43), and
replay (#44 — engine + manual-scrub transport) have landed. Only the headless CLI
(#45) remains (see [ROADMAP.md](ROADMAP.md)).
**S4 — Analysis parity+ (0.3.0): complete.** S0–S4 are done. S4 reached parity
with the toolkit's analysis surface — report generation (#41), anonymize (#42),
semantic diff (#43), replay (#44), and a headless CLI in the same binary (#45).
Next up is **S5 — Live capture** (the flagship; see [ROADMAP.md](ROADMAP.md)).

## What's done

Expand Down Expand Up @@ -117,9 +116,9 @@ Deferred out of S3: interactive open — native dialog + drag-drop (#33) — and
timeline viewport scroll on jump (session/failure), both of which need an ejected
runner (see ADR-0006). Tracked as follow-ups, not blockers.

### S4 — Analysis parity+ (0.3.0) 🚧
### S4 — Analysis parity+ (0.3.0)

In progress. Landed so far:
Every issue landed:

- **Report generation (#41)** — `src/ocpp/report.zig` renders a trace analysis as
Markdown and self-contained HTML, mirroring the toolkit's reporter (the same six
Expand Down Expand Up @@ -150,12 +149,20 @@ In progress. Landed so far:
(filtered) events, reusing `select_event`. Real wall-clock auto-play is deferred
to the runner-eject bucket (#33), since the zero-config runner exposes no timer
effect (spiked).
- **Headless CLI (#45)** — `src/cli.zig`, a second face in the same binary:
`inspect` / `report` / `diff` / `anonymize` / `ci` / `scenario`, dispatched in
`main` before any window opens (no runner eject — the spike confirmed a clean
`main`-branch). A testable render core (pure `render*(bytes) → bytes`) under a
thin argv / `init.io` / stdout shell; `conformance/harness.zig` grew a callable
`runAll` / `runNamed` for `ci` / `scenario`. Parity and the intentional
differences are documented in [docs/cli-parity.md](docs/cli-parity.md).

## What's next

Remaining **S4 — Analysis parity+ (0.3.0)** work: the headless CLI subcommands
(#45) — a clean `main`-branch (argv → engine → stdout), per the spike. Then
**S5 — Live capture** (the flagship).
**S5 — Live capture ⭐ (0.4.0)** — the flagship: a live WebSocket proxy between a
charge point and its CSMS, decoding OCPP frames in flight, running detection as
events stream, recording to the canonical trace format, and surfacing it in a
live timeline with OS notifications on critical failures.

## Known blockers / decisions pending

Expand All @@ -170,5 +177,5 @@ Remaining **S4 — Analysis parity+ (0.3.0)** work: the headless CLI subcommands
| `ocpp` (engine) | ✅ S2 + ingestion (#29) + reports (#41) + anonymize (#42) + diff (#43) + replay core (#44); O(n) detection pending (#36) |
| `ui` (native views) | ✅ S3 inspector (#27–#32) + replay transport (#44) |
| `capture` (live proxy) | ⬜ not started (S5) |
| `cli` (headless) | ⬜ not started (S4) |
| `cli` (headless) | ✅ inspect/report/diff/anonymize/ci/scenario (#45) |
| `conformance` | ✅ done for S2 (15/15, `contract-v1`) |
16 changes: 10 additions & 6 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ the stable part.
| **S1** | 0.1.0 | Engine core | ✅ Complete |
| **S2** | 0.1.0 | Detection + conformance | ✅ Complete |
| **S3** | 0.2.0 | Inspector UI | ✅ Complete |
| **S4** | 0.3.0 | Analysis parity+ | Next up |
| **S4** | 0.3.0 | Analysis parity+ | ✅ Complete |
| **S5** | 0.4.0 | Live capture ⭐ | Planned |
| **S6** | 1.0.0 | 1.0 polish & launch | Planned |

Expand Down Expand Up @@ -49,12 +49,16 @@ tab can hold. Traces open from command-line paths and a built-in sample;
interactive open (native dialog + drag-drop) is deferred to #33 (needs an
ejected runner, ADR-0006).

## S4 — Analysis parity+ (0.3.0)
## S4 — Analysis parity+ (0.3.0)

Reach parity with the toolkit's analysis surface: Markdown / HTML reports,
anonymize-on-export, trace diffing, and replay — with real wall-clock playback
that the offline library cannot offer. A headless CLI mode ships in the same
binary.
Parity with the toolkit's analysis surface: Markdown / HTML reports,
anonymize-on-export, trace diffing, and a deterministic replay engine with a
manual-scrub transport. A headless CLI ships in the **same binary** (`inspect` /
`report` / `diff` / `anonymize` / `ci` / `scenario`) — see
[docs/cli-parity.md](docs/cli-parity.md). **Exit criteria met:** all six issues
(#41–#45) merged; `native test` green (123 tests) and the app builds and runs the
CLI. Real wall-clock replay playback is deferred to #33 (the zero-config runner
exposes no timer effect), tracked as a follow-up.

## S5 — Live capture ⭐ (0.4.0)

Expand Down
41 changes: 41 additions & 0 deletions docs/cli-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# CLI parity with the toolkit

Studio ships a headless CLI in the **same binary** as the GUI: if the first
argument is a subcommand, it runs to completion and exits without opening a
window (a bare trace path, or no arguments, opens the inspector instead). The CLI
mirrors the toolkit's `ocpp-debugkit` command surface (source of truth:
`packages/toolkit/src/cli/`); this table records the mapping and every
intentional difference.

| Toolkit command | Studio command | Parity |
| --- | --- | --- |
| `inspect <file>` | `studio inspect <file>` | ✅ Full — parses, analyzes, prints a counts + failures summary. |
| `report <file> -f <fmt>` | `studio report <file> [-f markdown\|html]` | ✅ Full — Markdown + self-contained HTML. |
| `diff <a> <b> --format <fmt>` | `studio diff <a> <b> [--format text\|json]` | ✅ Full — text and JSON. |
| `anonymize <file>` | `studio anonymize <file>` | ✅ Full — same field rules (see the anonymize module). |
| `ci [dir]` | `studio ci` | ⚠️ Runs the **vendored** `contract-v1` scenarios (Studio embeds the contract); the `[dir]` argument is not accepted. Exits `0` (all pass) / `1` (any fail). |
| `scenario list` | `studio scenario list` | ✅ Full. |
| `scenario run <name>` | `studio scenario run <name>` | ✅ Built-in scenarios. |
| `scenario run --file <path>` | — | ⚠️ Deferred — Studio runs only the built-in contract scenarios. |

## Intentional differences

- **Output is stdout; no `-o <file>` flag.** Redirect to save:
`studio report trace.json -f html > report.html`. The toolkit's `-o`
convenience is a deferred follow-up (it needs the sandboxed `init.io` write
path); redirection covers the same need today.
- **`ci` runs the embedded contract**, not a user directory. Studio vendors the
15 `contract-v1` fixtures + goldens under `src/ocpp/conformance/` (ADR-0004),
so `ci` is a self-contained conformance gate — the same logic the
`native test` conformance harness runs.
- **One binary, two faces.** The CLI shares the exact pure engine the GUI uses
(`src/ocpp/`); there is no separate code path to drift. A bare trace path opens
the GUI: `studio path/to/trace.json`.

## Exit codes

| Code | Meaning |
| --- | --- |
| `0` | Success (for `ci` / `scenario run`: all scenarios matched their goldens). |
| `1` | Runtime failure — a file could not be read, or a scenario mismatched. |
| `2` | Usage error — a missing/invalid argument, or an unknown scenario name. |
Loading
Loading