From a512f3616b5ddfb2b65f6bffd4487d3c1e77c95f Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Wed, 17 Dec 2025 17:37:56 +0000 Subject: [PATCH 1/3] Add AI-friendly documentation outputs (llms.txt, JSON index) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add sphinx-llm extension to generate llms.txt and llms-full.txt following the llmstxt.org standard for AI-consumable docs - Create custom sphinx_json_index extension for structured JSON metadata with page titles, paths, and navigation hierarchy - Update CI workflow to verify AI outputs are generated - Update Python version requirement to >=3.12,<3.14 - Fix sphinx_design_elements git reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/build-docs.yml | 8 + docs/source/conf.py | 9 ++ docs/source/platform-api.rst | 9 ++ pdm.lock | 253 +++++++++++++++++++++++++++---- pyproject.toml | 5 +- tools/sphinx_json_index.py | 80 ++++++++++ 6 files changed, 329 insertions(+), 35 deletions(-) create mode 100644 docs/source/platform-api.rst create mode 100644 tools/sphinx_json_index.py diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index f97ee32..b7e9796 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -24,6 +24,14 @@ jobs: - name: Build docs run: pdm docs + - name: Verify AI-friendly outputs + run: | + echo "Checking for AI-friendly documentation outputs..." + test -f docs/build/llms.txt && echo "✓ llms.txt found" || (echo "✗ llms.txt missing" && exit 1) + test -f docs/build/llms-full.txt && echo "✓ llms-full.txt found" || (echo "✗ llms-full.txt missing" && exit 1) + test -f docs/build/docs-index.json && echo "✓ docs-index.json found" || (echo "✗ docs-index.json missing" && exit 1) + echo "All AI-friendly outputs generated successfully" + - name: Upload docs artifact uses: actions/upload-artifact@v4 with: diff --git a/docs/source/conf.py b/docs/source/conf.py index 1c0670b..8971d80 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -72,6 +72,8 @@ 'sphinxext.rediraffe', 'autoapi.extension', 'sphinx_design', + 'sphinx_llm.txt', + 'sphinx_json_index', ] rst_prolog = """ @@ -135,6 +137,13 @@ "amaranth-soc/cover.rst", ] +# -- llms.txt configuration (AI-friendly documentation) +llms_txt_description = """ +ChipFlow is an open-source platform for designing, testing, and manufacturing +custom silicon using Python and the Amaranth HDL. This documentation covers +the ChipFlow library, Digital IP library, Amaranth language, and Amaranth SoC toolkit. +""" +llms_txt_build_parallel = True intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), diff --git a/docs/source/platform-api.rst b/docs/source/platform-api.rst new file mode 100644 index 0000000..20a6923 --- /dev/null +++ b/docs/source/platform-api.rst @@ -0,0 +1,9 @@ +Platform API Reference +====================== + +This section provides the API reference for the ChipFlow platform library. + +.. toctree:: + :maxdepth: 3 + + chipflow-lib/autoapi/chipflow/index diff --git a/pdm.lock b/pdm.lock index 5722ca0..db2b937 100644 --- a/pdm.lock +++ b/pdm.lock @@ -3,18 +3,19 @@ [metadata] groups = ["default"] -strategy = [] +strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:ad4feefa03bbfa322c22bc78d36543381eb6e56af95282302331334c4cb2da20" +content_hash = "sha256:ebf653ccec476cecaa3e3397b676711a755cf49146878ad2e859da4ffffa540d" [[metadata.targets]] -requires_python = ">=3.12,<3.13" +requires_python = ">=3.12,<3.14" [[package]] name = "alabaster" version = "0.7.16" requires_python = ">=3.9" summary = "A light, configurable Sphinx theme" +groups = ["default"] files = [ {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, @@ -22,18 +23,18 @@ files = [ [[package]] name = "anyio" -version = "4.11.0" +version = "4.12.0" requires_python = ">=3.9" summary = "High-level concurrency and networking framework on top of asyncio or Trio" +groups = ["default"] dependencies = [ "exceptiongroup>=1.0.2; python_version < \"3.11\"", "idna>=2.8", - "sniffio>=1.1", "typing-extensions>=4.5; python_version < \"3.13\"", ] files = [ - {file = "anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}, - {file = "anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}, + {file = "anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb"}, + {file = "anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0"}, ] [[package]] @@ -41,6 +42,8 @@ name = "astroid" version = "4.0.2" requires_python = ">=3.10.0" summary = "An abstract syntax tree for Python with inference support." +groups = ["default"] +marker = "python_version >= \"3.12\"" dependencies = [ "typing-extensions>=4; python_version < \"3.11\"", ] @@ -54,6 +57,7 @@ name = "babel" version = "2.17.0" requires_python = ">=3.8" summary = "Internationalization utilities" +groups = ["default"] dependencies = [ "pytz>=2015.7; python_version < \"3.9\"", ] @@ -64,16 +68,17 @@ files = [ [[package]] name = "beautifulsoup4" -version = "4.14.2" +version = "4.14.3" requires_python = ">=3.7.0" summary = "Screen-scraping library" +groups = ["default"] dependencies = [ - "soupsieve>1.2", + "soupsieve>=1.6.1", "typing-extensions>=4.0.0", ] files = [ - {file = "beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515"}, - {file = "beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e"}, + {file = "beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb"}, + {file = "beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"}, ] [[package]] @@ -81,6 +86,7 @@ name = "certifi" version = "2025.11.12" requires_python = ">=3.7" summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default"] files = [ {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, @@ -91,6 +97,7 @@ name = "charset-normalizer" version = "3.4.4" requires_python = ">=3.7" summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +groups = ["default"] files = [ {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"}, {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"}, @@ -108,21 +115,38 @@ files = [ {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"}, {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"}, {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"}, + {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"}, {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"}, {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"}, ] [[package]] name = "click" -version = "8.3.0" +version = "8.3.1" requires_python = ">=3.10" summary = "Composable command line interface toolkit" +groups = ["default"] dependencies = [ "colorama; platform_system == \"Windows\"", ] files = [ - {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, - {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, + {file = "click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6"}, + {file = "click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a"}, ] [[package]] @@ -130,6 +154,7 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." +groups = ["default"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -140,6 +165,7 @@ name = "docutils" version = "0.21.2" requires_python = ">=3.9" summary = "Docutils -- Python Documentation Utilities" +groups = ["default"] files = [ {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, @@ -150,6 +176,7 @@ name = "furo" version = "2024.8.6" requires_python = ">=3.8" summary = "A clean customisable Sphinx documentation theme." +groups = ["default"] dependencies = [ "beautifulsoup4", "pygments>=2.7", @@ -166,6 +193,7 @@ name = "h11" version = "0.16.0" requires_python = ">=3.8" summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +groups = ["default"] files = [ {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, @@ -176,6 +204,7 @@ name = "idna" version = "3.11" requires_python = ">=3.8" summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default"] files = [ {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, @@ -186,6 +215,7 @@ name = "imagesize" version = "1.4.1" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" summary = "Getting image size from png/jpeg/jpeg2000/gif file" +groups = ["default"] files = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, @@ -196,6 +226,7 @@ name = "jinja2" version = "3.1.6" requires_python = ">=3.7" summary = "A very fast and expressive template engine." +groups = ["default"] dependencies = [ "MarkupSafe>=2.0", ] @@ -209,6 +240,7 @@ name = "jschon" version = "0.11.1" requires_python = "~=3.8" summary = "A JSON toolkit for Python developers." +groups = ["default"] dependencies = [ "rfc3986", ] @@ -222,6 +254,7 @@ name = "json5" version = "0.12.1" requires_python = ">=3.8.0" summary = "A Python implementation of the JSON5 data format." +groups = ["default"] files = [ {file = "json5-0.12.1-py3-none-any.whl", hash = "sha256:d9c9b3bc34a5f54d43c35e11ef7cb87d8bdd098c6ace87117a7b7e83e705c1d5"}, {file = "json5-0.12.1.tar.gz", hash = "sha256:b2743e77b3242f8d03c143dd975a6ec7c52e2f2afe76ed934e53503dd4ad4990"}, @@ -232,6 +265,7 @@ name = "markdown-it-py" version = "3.0.0" requires_python = ">=3.8" summary = "Python port of markdown-it. Markdown parsing, done right!" +groups = ["default"] dependencies = [ "mdurl~=0.1", ] @@ -245,6 +279,7 @@ name = "markupsafe" version = "3.0.3" requires_python = ">=3.9" summary = "Safely add untrusted strings to HTML/XML markup." +groups = ["default"] files = [ {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, @@ -257,6 +292,28 @@ files = [ {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, + {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, + {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, + {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, + {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, + {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, + {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, + {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, + {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, + {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, ] @@ -265,6 +322,7 @@ name = "mdit-py-plugins" version = "0.5.0" requires_python = ">=3.10" summary = "Collection of plugins for markdown-it-py" +groups = ["default"] dependencies = [ "markdown-it-py<5.0.0,>=2.0.0", ] @@ -278,6 +336,7 @@ name = "mdurl" version = "0.1.2" requires_python = ">=3.7" summary = "Markdown URL utilities" +groups = ["default"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -288,6 +347,7 @@ name = "myst-parser" version = "4.0.1" requires_python = ">=3.10" summary = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," +groups = ["default"] dependencies = [ "docutils<0.22,>=0.19", "jinja2", @@ -306,6 +366,7 @@ name = "packaging" version = "25.0" requires_python = ">=3.8" summary = "Core utilities for Python packages" +groups = ["default"] files = [ {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, @@ -316,6 +377,7 @@ name = "pygments" version = "2.19.2" requires_python = ">=3.8" summary = "Pygments is a syntax highlighting package written in Python." +groups = ["default"] files = [ {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, @@ -326,6 +388,7 @@ name = "pyyaml" version = "6.0.3" requires_python = ">=3.8" summary = "YAML parser and emitter for Python" +groups = ["default"] files = [ {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, @@ -337,6 +400,16 @@ files = [ {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, + {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, + {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, + {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, + {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, + {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, ] @@ -344,6 +417,7 @@ files = [ name = "quickjs" version = "1.19.4" summary = "Wrapping the quickjs C library." +groups = ["default"] files = [ {file = "quickjs-1.19.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1bc38a840144a54e90668fb1f99441148429ab1d1b1355ecafbbe656eaeff788"}, {file = "quickjs-1.19.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45d0e68570425d8322c48fb8989865df9b8c3e3ad3a01726151e0451d3c637eb"}, @@ -357,6 +431,7 @@ name = "requests" version = "2.32.5" requires_python = ">=3.9" summary = "Python HTTP for Humans." +groups = ["default"] dependencies = [ "certifi>=2017.4.17", "charset-normalizer<4,>=2", @@ -373,26 +448,18 @@ name = "rfc3986" version = "2.0.0" requires_python = ">=3.7" summary = "Validating URI References per RFC 3986" +groups = ["default"] files = [ {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, ] -[[package]] -name = "sniffio" -version = "1.3.1" -requires_python = ">=3.7" -summary = "Sniff out which async library your code is running under" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - [[package]] name = "snowballstemmer" version = "3.0.1" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*" summary = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." +groups = ["default"] files = [ {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, @@ -403,6 +470,7 @@ name = "soupsieve" version = "2.8" requires_python = ">=3.9" summary = "A modern CSS selector implementation for Beautiful Soup." +groups = ["default"] files = [ {file = "soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c"}, {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"}, @@ -413,6 +481,7 @@ name = "sphinx" version = "7.4.7" requires_python = ">=3.9" summary = "Python documentation generator" +groups = ["default"] dependencies = [ "Jinja2>=3.1", "Pygments>=2.17", @@ -443,6 +512,7 @@ name = "sphinx-autoapi" version = "3.6.1" requires_python = ">=3.9" summary = "Sphinx API documentation generator" +groups = ["default"] dependencies = [ "Jinja2", "PyYAML", @@ -461,6 +531,7 @@ name = "sphinx-autobuild" version = "2024.10.3" requires_python = ">=3.9" summary = "Rebuild Sphinx documentation on changes, with hot reloading in the browser." +groups = ["default"] dependencies = [ "colorama>=0.4.6", "sphinx", @@ -479,6 +550,7 @@ name = "sphinx-basic-ng" version = "1.0.0b2" requires_python = ">=3.7" summary = "A modern skeleton for Sphinx themes." +groups = ["default"] dependencies = [ "sphinx>=4.0", ] @@ -492,6 +564,7 @@ name = "sphinx-copybutton" version = "0.5.2" requires_python = ">=3.7" summary = "Add a copy button to each of your code cells." +groups = ["default"] dependencies = [ "sphinx>=1.8", ] @@ -505,6 +578,7 @@ name = "sphinx-design" version = "0.6.1" requires_python = ">=3.9" summary = "A sphinx extension for designing beautiful, view size responsive web components." +groups = ["default"] dependencies = [ "sphinx<9,>=6", ] @@ -515,14 +589,52 @@ files = [ [[package]] name = "sphinx-design-elements" -version = "0.1.0.post7" -requires_python = ">=3.7" -git = "https://github.com/panodata/sphinx-design-elements" -ref = "linktree" -revision = "4fad8a81ec706ef297a019d1d13c9a308c39cd4a" +version = "0.4.0.post72" +requires_python = ">=3.9" +git = "https://github.com/tech-writing/sphinx-design-elements" +ref = "origin/linktree" +revision = "23f8faa84648e5e4f3e5cb9f26ff0cf3b85a73c0" summary = "A collection of composite web elements based on components from sphinx-design." +groups = ["default"] dependencies = [ - "sphinx-design<1", + "beautifulsoup4", + "docutils<0.23", + "furo", + "myst-parser", + "sphinx-design==0.6.1", + "sphinx<10", + "standard-imghdr; python_version >= \"3.13\"", +] + +[[package]] +name = "sphinx-llm" +version = "0.2.1" +requires_python = ">=3.9" +summary = "" +groups = ["default"] +dependencies = [ + "sphinx-markdown-builder>=0.6.8", + "sphinx>=5", +] +files = [ + {file = "sphinx_llm-0.2.1-py3-none-any.whl", hash = "sha256:77e389a82277bdcddc2fd4a18736f16a973ae18f8eed8cad1068db8070a44140"}, + {file = "sphinx_llm-0.2.1.tar.gz", hash = "sha256:72aafb400145507774b40af4a0f44bc4e73c6a82576ee67b884ed5998b84f456"}, +] + +[[package]] +name = "sphinx-markdown-builder" +version = "0.6.9" +requires_python = ">=3.7" +summary = "A Sphinx extension to add markdown generation support." +groups = ["default"] +dependencies = [ + "docutils", + "sphinx>=5.1.0", + "tabulate", +] +files = [ + {file = "sphinx_markdown_builder-0.6.9-py3-none-any.whl", hash = "sha256:35b555760c48d4a38fe4b27813cb5ca636bbd22d8ef0742ac6959043f8000840"}, + {file = "sphinx_markdown_builder-0.6.9.tar.gz", hash = "sha256:e89dc1b9eb837da430c2c230011fad95a3dfab0345ad503a32e35a31d284a722"}, ] [[package]] @@ -530,6 +642,7 @@ name = "sphinx-multiproject" version = "1.0.0" requires_python = ">=3.7" summary = "Build multiple Sphinx projects from a single repository on Read the Docs" +groups = ["default"] files = [ {file = "sphinx_multiproject-1.0.0-py3-none-any.whl", hash = "sha256:928d02982f5b8f83d7aff9f87b413781b1b6774fa458a6d8c826a6309eb50695"}, {file = "sphinx_multiproject-1.0.0.tar.gz", hash = "sha256:93aac0cc046b488ecf951a052edbc462243a2cdc1bbb1a0b89de6a014df99d88"}, @@ -540,6 +653,7 @@ name = "sphinx-rtd-theme" version = "3.0.2" requires_python = ">=3.8" summary = "Read the Docs theme for Sphinx" +groups = ["default"] dependencies = [ "docutils<0.22,>0.18", "sphinx<9,>=6", @@ -555,6 +669,7 @@ name = "sphinxcontrib-applehelp" version = "2.0.0" requires_python = ">=3.9" summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +groups = ["default"] files = [ {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, @@ -565,6 +680,7 @@ name = "sphinxcontrib-devhelp" version = "2.0.0" requires_python = ">=3.9" summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +groups = ["default"] files = [ {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, @@ -575,6 +691,7 @@ name = "sphinxcontrib-htmlhelp" version = "2.1.0" requires_python = ">=3.9" summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +groups = ["default"] files = [ {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, @@ -585,6 +702,7 @@ name = "sphinxcontrib-jquery" version = "4.1" requires_python = ">=2.7" summary = "Extension to include jQuery on newer Sphinx releases" +groups = ["default"] dependencies = [ "Sphinx>=1.8", ] @@ -598,6 +716,7 @@ name = "sphinxcontrib-jsmath" version = "1.0.1" requires_python = ">=3.5" summary = "A sphinx extension which renders display math in HTML via JavaScript" +groups = ["default"] files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, @@ -607,6 +726,7 @@ files = [ name = "sphinxcontrib-platformpicker" version = "1.4" summary = "Platform picker extension for Sphinx" +groups = ["default"] dependencies = [ "Sphinx>=2.0", ] @@ -619,6 +739,7 @@ name = "sphinxcontrib-qthelp" version = "2.0.0" requires_python = ">=3.9" summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +groups = ["default"] files = [ {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, @@ -629,6 +750,7 @@ name = "sphinxcontrib-serializinghtml" version = "2.0.0" requires_python = ">=3.9" summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +groups = ["default"] files = [ {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, @@ -639,6 +761,7 @@ name = "sphinxcontrib-yowasp-wavedrom" version = "1.8" requires_python = "~=3.8" summary = "A Sphinx extension for embedding WaveDrom diagrams" +groups = ["default"] dependencies = [ "Sphinx~=7.1", "importlib-resources; python_version < \"3.9\"", @@ -654,6 +777,7 @@ name = "sphinxext-rediraffe" version = "0.3.0" requires_python = ">=3.9" summary = "Sphinx Extension that redirects non-existent pages to working pages" +groups = ["default"] dependencies = [ "Sphinx>=6.0", ] @@ -662,11 +786,23 @@ files = [ {file = "sphinxext_rediraffe-0.3.0.tar.gz", hash = "sha256:f319b3ccb7c3c3b6f63ffa6fd3eeb171b6d272df55075a9e84364394f391f507"}, ] +[[package]] +name = "standard-imghdr" +version = "3.13.0" +summary = "Standard library imghdr redistribution. \"dead battery\"." +groups = ["default"] +marker = "python_version >= \"3.13\"" +files = [ + {file = "standard_imghdr-3.13.0-py3-none-any.whl", hash = "sha256:30a1bff5465605bb496f842a6ac3cc1f2131bf3025b0da28d4877d6d4b7cc8e9"}, + {file = "standard_imghdr-3.13.0.tar.gz", hash = "sha256:8d9c68058d882f6fc3542a8d39ef9ff94d2187dc90bd0c851e0902776b7b7a42"}, +] + [[package]] name = "starlette" version = "0.50.0" requires_python = ">=3.10" summary = "The little ASGI library that shines." +groups = ["default"] dependencies = [ "anyio<5,>=3.6.2", "typing-extensions>=4.10.0; python_version < \"3.13\"", @@ -676,11 +812,23 @@ files = [ {file = "starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca"}, ] +[[package]] +name = "tabulate" +version = "0.9.0" +requires_python = ">=3.7" +summary = "Pretty-print tabular data" +groups = ["default"] +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + [[package]] name = "typing-extensions" version = "4.15.0" requires_python = ">=3.9" summary = "Backported and Experimental Type Hints for Python 3.9+" +groups = ["default"] files = [ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, @@ -688,12 +836,13 @@ files = [ [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.2" requires_python = ">=3.9" summary = "HTTP library with thread-safe connection pooling, file post, and more." +groups = ["default"] files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, + {file = "urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd"}, + {file = "urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797"}, ] [[package]] @@ -701,6 +850,7 @@ name = "uvicorn" version = "0.38.0" requires_python = ">=3.9" summary = "The lightning-fast ASGI server." +groups = ["default"] dependencies = [ "click>=7.0", "h11>=0.8", @@ -716,6 +866,7 @@ name = "watchfiles" version = "1.1.1" requires_python = ">=3.9" summary = "Simple, modern and high performance file watching and code reload in python." +groups = ["default"] dependencies = [ "anyio>=3.0.0", ] @@ -733,6 +884,29 @@ files = [ {file = "watchfiles-1.1.1-cp312-cp312-win32.whl", hash = "sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9"}, {file = "watchfiles-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9"}, {file = "watchfiles-1.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404"}, + {file = "watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18"}, + {file = "watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae"}, + {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d"}, + {file = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b"}, + {file = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374"}, + {file = "watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0"}, + {file = "watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42"}, + {file = "watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18"}, + {file = "watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da"}, + {file = "watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04"}, + {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77"}, + {file = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef"}, + {file = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf"}, {file = "watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2"}, ] @@ -741,6 +915,7 @@ name = "websockets" version = "15.0.1" requires_python = ">=3.9" summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +groups = ["default"] files = [ {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3"}, {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665"}, @@ -753,6 +928,17 @@ files = [ {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597"}, {file = "websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9"}, {file = "websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675"}, + {file = "websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f"}, + {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d"}, + {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4"}, + {file = "websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa"}, + {file = "websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561"}, {file = "websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f"}, {file = "websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee"}, ] @@ -762,6 +948,7 @@ name = "yowasp-wavedrom" version = "3.5.0.8" requires_python = "~=3.8" summary = "WaveDrom generates diagrams for digital waveforms, bit fields, and simple combinational circuits" +groups = ["default"] dependencies = [ "importlib-resources; python_version < \"3.9\"", "quickjs~=1.19", diff --git a/pyproject.toml b/pyproject.toml index 32ee942..1948eb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ authors = [ ] readme = "README.md" -requires-python = "<3.13" +requires-python = ">=3.12,<3.14" dependencies = [ "sphinx>=7.1", "sphinxcontrib-platformpicker~=1.4", @@ -19,10 +19,11 @@ dependencies = [ "sphinx-autobuild>=2024.10.3", "sphinx-multiproject>=1.0.0", "sphinx-design>=0.6.0", - "sphinx_design_elements @ git+https://github.com/panodata/sphinx-design-elements@linktree", + "sphinx_design_elements @ git+https://github.com/tech-writing/sphinx-design-elements@origin/linktree", "sphinxext-rediraffe>=0.2.7", "sphinx-autoapi>=3.6.0", "jschon>=0.11.1", + "sphinx-llm>=0.2.0", ] [build-system] diff --git a/tools/sphinx_json_index.py b/tools/sphinx_json_index.py new file mode 100644 index 0000000..4ea71f7 --- /dev/null +++ b/tools/sphinx_json_index.py @@ -0,0 +1,80 @@ +""" +Sphinx extension to generate a structured JSON index of documentation. + +This extension generates a docs-index.json file that provides machine-readable +metadata about all documentation pages, including titles, paths, and navigation +structure. This is useful for AI agents and tools that need to understand the +documentation structure programmatically. +""" +import json +from pathlib import Path +from sphinx.application import Sphinx +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def build_json_index(app: Sphinx, exception): + """Generate docs-index.json after build completes.""" + if exception: + return + + # Only run for HTML builders + if app.builder.name not in ('html', 'dirhtml'): + logger.info("Skipping JSON index generation (not an HTML builder)") + return + + outdir = Path(app.outdir) + + index = { + "project": app.config.project, + "version": app.config.version, + "description": getattr(app.config, 'llms_txt_description', '').strip(), + "pages": [] + } + + # Iterate through all documents + for docname in sorted(app.env.found_docs): + try: + doc = app.env.get_doctree(docname) + title = "" + for node in doc.traverse(): + if node.__class__.__name__ == 'title': + title = node.astext() + break + + # Determine the HTML path based on builder type + if app.builder.name == 'dirhtml': + html_path = f"{docname}/index.html" if docname != 'index' else "index.html" + else: + html_path = f"{docname}.html" + + page_info = { + "path": html_path, + "title": title or docname, + "docname": docname, + } + + # Add toctree children if available + if hasattr(app.env, 'toctree_includes') and docname in app.env.toctree_includes: + page_info["children"] = app.env.toctree_includes[docname] + + index["pages"].append(page_info) + except Exception as e: + logger.warning(f"Could not process {docname}: {e}") + + # Write JSON index + output_path = outdir / "docs-index.json" + with open(output_path, 'w', encoding='utf-8') as f: + json.dump(index, f, indent=2, ensure_ascii=False) + + logger.info(f"Generated JSON index with {len(index['pages'])} pages at {output_path}") + + +def setup(app: Sphinx): + app.connect('build-finished', build_json_index) + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } From 349d9bd19d333b92b5c9e266cbaab7a6fe5496ba Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Wed, 17 Dec 2025 18:21:10 +0000 Subject: [PATCH 2/3] Trigger CI From d5c45d6aaef26cecd4b814fb4342bf3b51ed89ff Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Wed, 17 Dec 2025 20:32:00 +0000 Subject: [PATCH 3/3] Add LLM discovery enhancements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ''' + + # Add to metatags which Sphinx/Furo will include in + if 'metatags' not in context: + context['metatags'] = '' + context['metatags'] = context.get('metatags', '') + llms_script + + +def reorganize_llms_txt(app: Sphinx, exception) -> None: + """Post-process llms.txt to organize pages into logical sections.""" + if exception: + return + + outdir = Path(app.outdir) + llms_txt_path = outdir / "llms.txt" + + if not llms_txt_path.exists(): + logger.warning("llms.txt not found, skipping reorganization") + return + + # Read current llms.txt + content = llms_txt_path.read_text(encoding='utf-8') + + # Parse the header (everything before ## Pages) + header_match = re.match(r'^(.*?)(?=^## Pages|\Z)', content, re.MULTILINE | re.DOTALL) + if not header_match: + logger.warning("Could not parse llms.txt header") + return + + header = header_match.group(1).strip() + + # Extract all page links + page_pattern = re.compile(r'^- \[([^\]]+)\]\(([^)]+)\)(?::\s*(.*))?$', re.MULTILINE) + pages = [(m.group(1), m.group(2), m.group(3) or '') for m in page_pattern.finditer(content)] + + if not pages: + logger.warning("No pages found in llms.txt") + return + + # Get section mappings from config or use defaults + section_mappings = getattr(app.config, 'llms_sections', DEFAULT_SECTION_MAPPINGS) + + # Categorize pages into sections + sections = {name: [] for name in section_mappings.keys()} + sections["Other"] = [] # Catch-all + + for title, path, description in pages: + categorized = False + for section_name, patterns in section_mappings.items(): + for pattern in patterns: + if re.search(pattern, path): + sections[section_name].append((title, path, description)) + categorized = True + break + if categorized: + break + if not categorized: + sections["Other"].append((title, path, description)) + + # Build new llms.txt with sections + new_content = header + "\n\n" + + for section_name, section_pages in sections.items(): + if not section_pages: + continue + + new_content += f"## {section_name}\n\n" + for title, path, description in section_pages: + if description: + new_content += f"- [{title}]({path}): {description}\n" + else: + new_content += f"- [{title}]({path})\n" + new_content += "\n" + + # Write reorganized llms.txt + llms_txt_path.write_text(new_content.strip() + "\n", encoding='utf-8') + logger.info(f"Reorganized llms.txt with {len(sections)} sections") + + +def setup(app: Sphinx): + # Config value for custom section mappings + app.add_config_value('llms_sections', DEFAULT_SECTION_MAPPINGS, 'html') + + # Add script tag to each HTML page + app.connect('html-page-context', add_llms_script_tag) + + # Reorganize llms.txt after build (run after sphinx-llm) + app.connect('build-finished', reorganize_llms_txt, priority=900) + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + }