Thanks for this package everyone - it's beautiful! I just started using it for a project, and so far it's been so much better than any other docs package I've used!
Also, I worked with Claude to help me try and diagnose what's going on here since I'm new to the project's source code. I read through things carefully, so hopefully this is an accurate assessment.
Prework
Description
The issue I'm having is that I don't see a way to have a live preview loop running on it's own. I tried great-docs build --watch, but it watches the generated copies of the source files inside great-docs/, not the original source files themselves.
To reproduce: run great-docs build --watch, then edit index.qmd or some other source file. Nothing happens in the browser, the generated copies still hold the old text. The cause looks like the Step 16 handoff in core.py:
if watch:
...
subprocess.run(["quarto", "preview", "--no-browser"], env=quarto_env)
quarto preview runs inside great-docs/ and watches that directory. The sources are copied and transformed into it during Step 1, and nothing watches them afterwards. So watch mode watches files that are regenerated and discarded on the next build, and ignores the ones an author actually edits.
The natural workaround also fails. Leaving the watch running and calling great-docs build in a second terminal breaks the preview because _prepare_build_directory() does shutil.rmtree(self.project_path) on the directory Quarto is using as its working directory. Re-renders then fail with failed resolving cwd: No such file or directory (os error 2), and it is quiet — the server keeps returning 200 with a broken page, and live reload never recovers.
What does hold up is great-docs preview. Running great-docs build in a second terminal while it serves does not break it: the server stays up, sub-pages keep returning 200, and the rebuilt content is served. That is because preview() never chdirs into great-docs/ — it hands directory=str(site_path) to SimpleHTTPRequestHandler, which resolves the path on every request, so deleting and recreating the directory underneath it is invisible. That is the behavior I expected --watch to have but it doesn't.
But preview is only a static file server. It has no watcher, and the pages it serves carry no live-reload client, so the authoring loop is: edit a source file, switch to another terminal, run great-docs build, wait for the full build, then refresh the browser by hand. Nothing is broken, it's just entirely manual, and the manual step has to be repeated for every edit.
Expected result
Editing a source file (e.g., index.qmd) should re-render that page and reload the browser, with no second terminal and no manual refresh. That is what the help text promises: "Use '--watch' to automatically rebuild when source files change" (cli.py), and great-docs build --watch # Watch for changes and rebuild (core.py).
Editing great-docs.yml should take effect too, since the hero, navbar and SEO tags are baked into the generated project at synthesis time and cannot be picked up any other way.
Development environment
- Operating System: macOS 26.5 (Apple silicon)
- Great Docs Version: 0.17.0, and
main at cb3d2e0 (the Step 16 handoff is unchanged there)
- Quarto: 1.9.38
Additional context
Rebuilding everything on change would hit the rmtree above, so a fix probably has to be incremental: watch the source inputs and, on a change, re-run only that one file's copy-and-transform into great-docs/, letting Quarto's existing watcher do the rest. The transform is per-section rather than a plain copy — index.qmd gains the hero preamble, reference/*.qmd gains bread-crumbs: false and a quoted description, and user_guide/NN-*.qmd additionally has the NN- prefix stripped from its filename and from cross-links in the body.
A great-docs.yml change is the one case that genuinely needs full re-synthesis. Stopping Quarto, rebuilding and restarting would be correct, and even printing "config changed, restart the watch" would beat the current silence.
Whichever command ends up owning this, one of them should be a preview you can leave running. preview is the one I'd prefer as it's how quarto preview works, and it already has the property that makes it safe to rebuild underneath, so great-docs preview seems like the natural home. One smaller thing in the same area: the --watch port is chosen by Quarto and changes on every restart, so a pinned browser tab or an IDE viewer pane cannot be kept open across restarts, while preview has a stable --port.
Thanks for this package everyone - it's beautiful! I just started using it for a project, and so far it's been so much better than any other docs package I've used!
Also, I worked with Claude to help me try and diagnose what's going on here since I'm new to the project's source code. I read through things carefully, so hopefully this is an accurate assessment.
Prework
Description
The issue I'm having is that I don't see a way to have a live preview loop running on it's own. I tried
great-docs build --watch, but it watches the generated copies of the source files insidegreat-docs/, not the original source files themselves.To reproduce: run
great-docs build --watch, then editindex.qmdor some other source file. Nothing happens in the browser, the generated copies still hold the old text. The cause looks like the Step 16 handoff incore.py:quarto previewruns insidegreat-docs/and watches that directory. The sources are copied and transformed into it during Step 1, and nothing watches them afterwards. So watch mode watches files that are regenerated and discarded on the next build, and ignores the ones an author actually edits.The natural workaround also fails. Leaving the watch running and calling
great-docs buildin a second terminal breaks the preview because_prepare_build_directory()doesshutil.rmtree(self.project_path)on the directory Quarto is using as its working directory. Re-renders then fail withfailed resolving cwd: No such file or directory (os error 2), and it is quiet — the server keeps returning200with a broken page, and live reload never recovers.What does hold up is
great-docs preview. Runninggreat-docs buildin a second terminal while it serves does not break it: the server stays up, sub-pages keep returning200, and the rebuilt content is served. That is becausepreview()neverchdirs intogreat-docs/— it handsdirectory=str(site_path)toSimpleHTTPRequestHandler, which resolves the path on every request, so deleting and recreating the directory underneath it is invisible. That is the behavior I expected--watchto have but it doesn't.But
previewis only a static file server. It has no watcher, and the pages it serves carry no live-reload client, so the authoring loop is: edit a source file, switch to another terminal, rungreat-docs build, wait for the full build, then refresh the browser by hand. Nothing is broken, it's just entirely manual, and the manual step has to be repeated for every edit.Expected result
Editing a source file (e.g.,
index.qmd) should re-render that page and reload the browser, with no second terminal and no manual refresh. That is what the help text promises: "Use '--watch' to automatically rebuild when source files change" (cli.py), andgreat-docs build --watch # Watch for changes and rebuild(core.py).Editing
great-docs.ymlshould take effect too, since the hero, navbar and SEO tags are baked into the generated project at synthesis time and cannot be picked up any other way.Development environment
mainat cb3d2e0 (the Step 16 handoff is unchanged there)Additional context
Rebuilding everything on change would hit the
rmtreeabove, so a fix probably has to be incremental: watch the source inputs and, on a change, re-run only that one file's copy-and-transform intogreat-docs/, letting Quarto's existing watcher do the rest. The transform is per-section rather than a plain copy —index.qmdgains the hero preamble,reference/*.qmdgainsbread-crumbs: falseand a quoteddescription, anduser_guide/NN-*.qmdadditionally has theNN-prefix stripped from its filename and from cross-links in the body.A
great-docs.ymlchange is the one case that genuinely needs full re-synthesis. Stopping Quarto, rebuilding and restarting would be correct, and even printing "config changed, restart the watch" would beat the current silence.Whichever command ends up owning this, one of them should be a preview you can leave running.
previewis the one I'd prefer as it's howquarto previewworks, and it already has the property that makes it safe to rebuild underneath, sogreat-docs previewseems like the natural home. One smaller thing in the same area: the--watchport is chosen by Quarto and changes on every restart, so a pinned browser tab or an IDE viewer pane cannot be kept open across restarts, whilepreviewhas a stable--port.