This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Source-of-truth content repo for the Tidy3D FAQ. Authors edit Markdown files in _faqs/; two CI pipelines compile that content into (a) Sphinx-flavored Markdown under docs/faq/ for the Tidy3D documentation site and (b) Jekyll-style frontmatter + Algolia search index for the marketing site (flexcompute/flex).
There is no application to build or test — this repo is a content + transformation pipeline.
- Add or edit a file in
_faqs/<slug>.md. Filenames are slugified titles. - Frontmatter required (YAML between
---fences):title— human-readable questiondate—YYYY-MM-DD HH:MM:SSenabled—trueto publish,falseto hide. An FAQ withenabled: falseis dropped from both pipelines (it won't appear indocs/faq/or sync to the marketing site).category— must match acategorystring infaq_categories.jsonversion— optional; rendered into the docs site header table when present
- Add the new file's relative path (e.g.
_faqs/how-can-i-foo.md) to the matching category'sfaqsarray infaq_categories.json. Order in this array controls display order. - Images go in
_faqs/img/. Reference them with relative Markdown () — the marketing-site pipeline rewrites these paths to/assets/tidy3d/faqs/<filename>automatically. - Push to
develop. Both GitHub Actions fire on changes under_faqs/**or tofaq_categories.json.
Same source files, two destinations, two scripts:
Triggered by .github/workflows/compile_docs.yaml on push to develop. The bot commits results back to develop (recent commits like Compile FAQ to documentation markdown :robot: are these auto-commits — do not hand-edit files under docs/faq/ or the per-category .rst files; they will be overwritten).
What it does:
- Copies each
_faqs/*.mdintodocs/faq/, stripping frontmatter and replacing it with a Markdown title + a metadata table (Date / Category / optional Version). - Strips Jekyll-isms:
{: ... }attribute blocks,{% highlight python %} ... {% endhighlight %}→ fenced ```python blocks, → space, residual ``/`
`/`` tags. - Generates one
docs/<category-id>.rsttoctree per category fromfaq_categories.json, plus the top-leveldocs/index.rstlisting every category.rst.
Triggered by .github/workflows/sync.yml on push to develop. Runs in CI only (touches Algolia and pushes to another repo). Steps:
- Walks
_faqs/**/*.md, parses frontmatter, skips entries whereenabledis falsy. - Uploads FAQ titles as Algolia search suggestions to index
faq-titles(app7HAKFDYBT6). Usesreplace_all_objects— every run is a full replacement of the index. - For each enabled FAQ: rewrites image URLs from local paths to
/assets/tidy3d/faqs/<file>, writes the rewritten file totemp/. - Regenerates
faq_categories.ymlfromfaq_categories.json(including auto-adding any new category found in frontmatter that isn't already in the JSON). - The workflow then
rsyncstemp/,_faqs/img/, andfaq_categories.ymlinto a checkout offlexcompute/flexand commits.
temp/ and faq_categories.yml are CI build artifacts — both are gitignored and should not be committed.
Run the docs pipeline locally (safe — no network):
pip install PyYAML
python docs/compile_rst_categories.pyRun the sync pipeline locally — caveat: this calls Algolia and replaces the live faq-titles index with the credentials in script/config.ini. Use only if you mean to:
pip install -r script/requirements.txt
python script/convert-and-sync.pyTo dry-run the sync transformations without touching Algolia, comment out the Sync() call at the bottom of script/convert-and-sync.py and inspect temp/ + faq_categories.yml.
There are no tests, no linter config, and no build. script/crawler.py is an empty stub.
- Two slug spaces. The on-disk filename slug (e.g.
how-can-i-define-graphene.md) is independent of theidinjected into Jekyll frontmatter byconvert-and-sync.py(which isslugify(title)). They usually agree but don't have to. The categoryidinfaq_categories.jsonis similarly derived from the category name. faq_categories.jsonis the ordering source of truth. A file existing in_faqs/is not enough — if it's not listed under a category'sfaqsarray, the docs pipeline won't include it. The sync pipeline will still pick it up via frontmatter and append it to the matching category (creating a new category entry if needed).- Date format matters.
extract_content_between_dashedparses YAML, then re-serializes datetimes as%Y-%m-%d %H:%M:%S. Bare dates (no time) work but get normalized. developis the working branch for both workflows; PRs are merged intodevelop, notmain.- Algolia credentials are checked in at
script/config.ini(writable key). Treat any change there as security-sensitive.