You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add Vue desktop GUI and PyInstaller freeze path
Introduce docgen gui / docgen-gui as a Vue + Flask shell over the wizard,
with a Benchmark view that runs the standard scene-timing corpus. Asset
paths go through docgen.resources so templates, vendor Vue, and
benchmark_data resolve in an editable install and under sys._MEIPASS.
The freeze target is packaging/docgen-gui.spec (not the full Manim CLI).
Co-authored-by: jmjava <jmjava@gmail.com>
* Fix Vue/Jinja clash and frozen-path lookup
Wrap the Benchmark view in a Jinja raw block so Vue mustaches are not
compiled as templates. Make meipass_dir tolerate a missing _MEIPASS so
is_frozen patches in tests cannot crash create_app.
Co-authored-by: jmjava <jmjava@gmail.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+4-3Lines changed: 4 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,8 @@ The Playwright/VHS/demo-function/per-function/discover-tests/catalog surface are
41
41
Commands registered on the **`docgen`** CLI include:
42
42
43
43
-**`init`** — scaffold bundle layout and `docgen.yaml`.
44
-
-**`wizard`** — local web UI for narration/bootstrap workflows (focus files, **in-place narration revise**, per-segment **asset freshness** + **rebuild-from-here**, **Tool** tab to pip-upgrade docgen and pin `requirements-docgen.txt`).
44
+
-**`wizard`** — local web UI for narration/bootstrap workflows (focus files, **in-place narration revise**, per-segment **asset freshness** + **rebuild-from-here**, Vue **Benchmark** view, **Tool** tab to pip-upgrade docgen and pin `requirements-docgen.txt`).
45
+
-**`gui`** — desktop window over the same Vue/Flask UI (`pip install 'docgen[gui]'` for pywebview). PyInstaller spec: ``packaging/docgen-gui.spec`` (`pip install 'docgen[packaging]'`). Frozen apps resolve templates/static/benchmark JSON via ``docgen.resources``.
45
46
-**`tts`** — text-to-speech for segment files.
46
47
-**`timestamps`** — word/segment timing (`timing.json`). Default engine **`local`** aligns the known narration text against the mp3 offline (ffmpeg silencedetect, no API); **`--engine whisper`** keeps OpenAI whisper-1 transcription. Both emit the same Whisper-shaped blocks.
47
48
-**`image-generate`** — render scene-spec **image elements** (`image:` + `prompt:` boxes) via the OpenAI Images API into the bundle (also runs for missing assets inside `generate-all`).
@@ -84,7 +85,7 @@ String assertions on compiled ``scenes.py`` and ``simulate_reveal_timeline`` are
84
85
85
86
## Testing (downstream relevance)
86
87
87
-
Tests should cover **CLI-visible behavior** and contracts that adopters rely on: **`yaml-generate`**, **`scene-spec-generate`**, **`scene-compile`**, **`validate`**, **`compose`**, **`generate-all`**, **`pages`**, **`init`**, **`benchmark`**, **config** loading (`repo_root`, `env_file`), and package exports. Use small in-tree fixtures; this library does not ship a dogfood bundle. Clock / compile changes must keep ``docgen benchmark`` at or above ``benchmark_data/baseline.json`` — string assertions on ``scenes.py`` are not enough.
88
+
Tests should cover **CLI-visible behavior** and contracts that adopters rely on: **`yaml-generate`**, **`scene-spec-generate`**, **`scene-compile`**, **`validate`**, **`compose`**, **`generate-all`**, **`pages`**, **`init`**, **`benchmark`**, **`gui`** / freeze-safe ``docgen.resources`` paths, **config** loading (`repo_root`, `env_file`), and package exports. Use small in-tree fixtures; this library does not ship a dogfood bundle. Clock / compile changes must keep ``docgen benchmark`` at or above ``benchmark_data/baseline.json`` — string assertions on ``scenes.py`` are not enough. Do not run a full PyInstaller freeze in routine pytest.
88
89
89
90
## Cursor Cloud specific instructions
90
91
@@ -94,4 +95,4 @@ Tests should cover **CLI-visible behavior** and contracts that adopters rely on:
94
95
-**OpenAI-gated vs offline commands:**`tts`, `timestamps --engine whisper`, `image-generate`, `narration-generate`, `scene-spec-generate`, and `yaml-generate --llm` call OpenAI and need `OPENAI_API_KEY` (integration tests auto-skip without it). Fully offline: `init`, `scene-compile`, `manim`, `compose`, `validate`, `lint`, `pages`, `concat`, `yaml-generate` (no `--llm`), `timestamps` (default `local` engine), and `benchmark`.
95
96
-**`scene-compile` gotcha:** paced specs (`wait_word`) need a `timing.json` entry for that stem (`docgen timestamps` after TTS). Prefer `scene-compile --retime` after fresh timestamps; for a fully offline smoke render, author rows without wait indices only if you accept unpaced reveals.
96
97
-**No in-repo dogfood bundle:** exercise the pipeline against a scratch bundle (`docgen init /tmp/<name> --defaults` in a throwaway git dir). Do not hand-edit consumer generated assets (see `.cursor/rules/no-asset-edits.mdc`).
97
-
-**Wizard:**`docgen wizard --port 8501` is an optional local Flask app (long-lived); run it from a bundle directory that contains `docgen.yaml`.
98
+
-**Wizard / desktop GUI:**`docgen wizard --port 8501` is the Flask UI (bundle optional for the Benchmark view). `docgen gui` / `docgen benchmark --gui` open the Vue benchmark view in a desktop window when `pywebview` is installed. Do not run a full PyInstaller freeze in routine CI; keep `packaging/docgen-gui.spec` and `docgen.gui.packaging` in sync instead.
|`docgen wizard [--port 8501]`| Local web GUI: focus files, **revise narration**, asset freshness / rebuild-from-here, and a **Tool** tab to upgrade the installed `docgen` package (pip) + rewrite `requirements-docgen.txt`|
132
+
|`docgen wizard [--port 8501]`| Local web GUI: focus files, **revise narration**, asset freshness / rebuild-from-here, Vue **Benchmark** view, and a **Tool** tab to upgrade the installed `docgen` package (pip) + rewrite `requirements-docgen.txt`|
133
+
|`docgen gui [--view benchmark] [--browser]`| Desktop GUI (Vue + Flask). Install `docgen[gui]` for a pywebview window; `--browser` uses the system browser. Freeze with `pyinstaller packaging/docgen-gui.spec`|
|`docgen image-generate [--segment 01 \| --all \| --spec PATH] [--force] [--dry-run] [--model …] [--size …]`| Generate scene-spec image assets (`image:` + `prompt:` boxes) via the OpenAI Images API into the bundle |
@@ -142,7 +147,7 @@ docgen validate --pre-push
142
147
|`docgen yaml-generate [--merge-defaults] [--llm] [--dry-run] [--list-gaps]`| Merge defaults into `docgen.yaml`; optional OpenAI refresh of `tts.instructions` / `wizard.system_prompt` (rewrites the file — review in Git) |
143
148
|`docgen scene-compile [SPEC.scene.yaml \| --all] [--retime] [--dry-run]`| Compile declarative scene YAML into `animations/scenes.py`. **`--all --retime`** re-derives `wait_word` from current `timing.json` with no OpenAI; unmatched labels fail closed (or set `pace: none`) |
144
149
|`docgen scene-spec-generate [--segment 01 \| --all] [--compile] [--print-only] [--output PATH] [--hint …] [--model …]`| Call OpenAI to emit YAML only (same schema as `scene-compile`); rejects frame-budget overflow and **subject-beat coverage** failures (hold board on same topic; cover topic shifts; no invented labels — not a blind count); auto-paginate + word-alignment; optionally writes `animations/specs/<stem>.scene.yaml` and `--compile`s into `scenes.py`|
145
-
|`docgen benchmark [--case ID] [--format text\|json] [--update-baseline]`| Score the **standard scene-timing corpus** (execute compiled `construct()` on the real `_TimedScene` clock, no Manim). Diffs a committed baseline so clock changes are measured, not guessed |
150
+
|`docgen benchmark [--case ID] [--format text\|json] [--update-baseline] [--gui]`| Score the **standard scene-timing corpus** (execute compiled `construct()` on the real `_TimedScene` clock, no Manim). Diffs a committed baseline so clock changes are measured, not guessed. `--gui` opens the Vue view|
0 commit comments