diff --git a/.cache/plugin/social/free/0ceaa4011f118a003cafeddcd267228e.png b/.cache/plugin/social/free/0ceaa4011f118a003cafeddcd267228e.png deleted file mode 100644 index cb340ef..0000000 Binary files a/.cache/plugin/social/free/0ceaa4011f118a003cafeddcd267228e.png and /dev/null differ diff --git a/.cache/plugin/social/free/55f4dda4dd0a3b14fc453b137a4c7309.png b/.cache/plugin/social/free/55f4dda4dd0a3b14fc453b137a4c7309.png deleted file mode 100644 index c106a0d..0000000 Binary files a/.cache/plugin/social/free/55f4dda4dd0a3b14fc453b137a4c7309.png and /dev/null differ diff --git a/.cache/plugin/social/free/5db207fa2d241e9a9fb4316f853eb845.png b/.cache/plugin/social/free/5db207fa2d241e9a9fb4316f853eb845.png deleted file mode 100644 index 6cc1b38..0000000 Binary files a/.cache/plugin/social/free/5db207fa2d241e9a9fb4316f853eb845.png and /dev/null differ diff --git a/.cache/plugin/social/free/60c6a6f583218bd4ae054f9f909f55da.png b/.cache/plugin/social/free/60c6a6f583218bd4ae054f9f909f55da.png deleted file mode 100644 index 52c65a9..0000000 Binary files a/.cache/plugin/social/free/60c6a6f583218bd4ae054f9f909f55da.png and /dev/null differ diff --git a/.cache/plugin/social/free/73301d9c47cb48d5deeb56b76ba332bc.png b/.cache/plugin/social/free/73301d9c47cb48d5deeb56b76ba332bc.png deleted file mode 100644 index 02b1861..0000000 Binary files a/.cache/plugin/social/free/73301d9c47cb48d5deeb56b76ba332bc.png and /dev/null differ diff --git a/.cache/plugin/social/free/97d8108442c7cd2817778089e33dbd33.png b/.cache/plugin/social/free/97d8108442c7cd2817778089e33dbd33.png deleted file mode 100644 index c454d9f..0000000 Binary files a/.cache/plugin/social/free/97d8108442c7cd2817778089e33dbd33.png and /dev/null differ diff --git a/.cache/plugin/social/free/b6af24fb2868f5ad625dc9910973aebd.png b/.cache/plugin/social/free/b6af24fb2868f5ad625dc9910973aebd.png deleted file mode 100644 index 0a23286..0000000 Binary files a/.cache/plugin/social/free/b6af24fb2868f5ad625dc9910973aebd.png and /dev/null differ diff --git a/.cache/plugin/social/free/d3dfd532afad13b6d6d64f4aec5037b5.png b/.cache/plugin/social/free/d3dfd532afad13b6d6d64f4aec5037b5.png deleted file mode 100644 index 7c01f61..0000000 Binary files a/.cache/plugin/social/free/d3dfd532afad13b6d6d64f4aec5037b5.png and /dev/null differ diff --git a/.cache/plugin/social/free/dbcf0fa66953452cd518f7eb13566471.png b/.cache/plugin/social/free/dbcf0fa66953452cd518f7eb13566471.png deleted file mode 100644 index 238b40a..0000000 Binary files a/.cache/plugin/social/free/dbcf0fa66953452cd518f7eb13566471.png and /dev/null differ diff --git a/.cache/plugin/social/free/eaab646d01539ca852049029a2a043ce.png b/.cache/plugin/social/free/eaab646d01539ca852049029a2a043ce.png deleted file mode 100644 index 006a097..0000000 Binary files a/.cache/plugin/social/free/eaab646d01539ca852049029a2a043ce.png and /dev/null differ diff --git a/.cache/plugin/social/free/f4a6f09e0751c892fb997d7353c134dd.png b/.cache/plugin/social/free/f4a6f09e0751c892fb997d7353c134dd.png deleted file mode 100644 index 28361de..0000000 Binary files a/.cache/plugin/social/free/f4a6f09e0751c892fb997d7353c134dd.png and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold Italic.ttf deleted file mode 100644 index fabdca0..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold.ttf deleted file mode 100644 index 258c10a..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Bold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold Italic.ttf deleted file mode 100644 index 924b914..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold.ttf deleted file mode 100644 index 064ffb4..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Bold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight Italic.ttf deleted file mode 100644 index 9b9f6ce..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight.ttf deleted file mode 100644 index cdf06a1..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed ExtraLight.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Italic.ttf deleted file mode 100644 index 03de618..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light Italic.ttf deleted file mode 100644 index b0cd1b2..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light.ttf deleted file mode 100644 index f8f53b9..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Light.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium Italic.ttf deleted file mode 100644 index 0a09a4f..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium.ttf deleted file mode 100644 index 7ae38ba..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Medium.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Regular.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Regular.ttf deleted file mode 100644 index fd7f8a0..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Regular.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold Italic.ttf deleted file mode 100644 index 1ca1180..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold.ttf deleted file mode 100644 index a715d67..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed SemiBold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin Italic.ttf deleted file mode 100644 index b2ff4b1..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin.ttf deleted file mode 100644 index f2bce48..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Condensed Thin.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight Italic.ttf deleted file mode 100644 index 6fac7fa..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight.ttf deleted file mode 100644 index 46f52c4..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/ExtraLight.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Italic.ttf deleted file mode 100644 index 6232aaa..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Light Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Light Italic.ttf deleted file mode 100644 index 1e2e86a..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Light Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Light.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Light.ttf deleted file mode 100644 index 56e7db7..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Light.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium Italic.ttf deleted file mode 100644 index 1b059be..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium.ttf deleted file mode 100644 index fb75072..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Medium.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Regular.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Regular.ttf deleted file mode 100644 index 9add875..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Regular.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold Italic.ttf deleted file mode 100644 index 981d514..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold.ttf deleted file mode 100644 index a63f1c5..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiBold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold Italic.ttf deleted file mode 100644 index 15a7756..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold.ttf deleted file mode 100644 index e6f7439..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Bold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight Italic.ttf deleted file mode 100644 index ec6f0f0..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight.ttf deleted file mode 100644 index cd72939..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed ExtraLight.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Italic.ttf deleted file mode 100644 index 0b6665d..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light Italic.ttf deleted file mode 100644 index 64cb0e7..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light.ttf deleted file mode 100644 index 3a24359..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Light.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium Italic.ttf deleted file mode 100644 index c8f51aa..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium.ttf deleted file mode 100644 index a432758..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Medium.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Regular.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Regular.ttf deleted file mode 100644 index ad9a625..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Regular.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold Italic.ttf deleted file mode 100644 index 6f11e69..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold.ttf deleted file mode 100644 index 77832b0..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed SemiBold.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin Italic.ttf deleted file mode 100644 index 4d4518e..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin.ttf deleted file mode 100644 index dda2e8a..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/SemiCondensed Thin.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin Italic.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin Italic.ttf deleted file mode 100644 index f7d1dab..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin Italic.ttf and /dev/null differ diff --git a/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin.ttf b/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin.ttf deleted file mode 100644 index 918d4a0..0000000 Binary files a/.cache/plugin/social/free/fonts/IBM Plex Sans/Thin.ttf and /dev/null differ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..f8c4006 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,72 @@ +name: Deploy docs to GitHub Pages + +on: + push: + branches: [astro] + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: pages-deploy + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout docs + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Clone python-sdk at latest release tag + run: | + set -euo pipefail + git clone https://github.com/codellm-devkit/python-sdk.git ../python-sdk + cd ../python-sdk + LATEST_TAG=$(git tag --sort=-v:refname | head -n1) + echo "Using python-sdk release tag: ${LATEST_TAG}" + git checkout "tags/${LATEST_TAG}" + + - name: Install the SDK and the doc generator deps + run: | + set -euo pipefail + python -m pip install --upgrade pip + # Installing cldk (from the release-tagged clone) pulls in the + # codeanalyzer-* backends that the schema pages re-export from. + pip install -e ../python-sdk + pip install griffe + + - name: Generate API reference markdown + run: python scripts/gen_api_docs.py + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build site + run: npm run build + + - name: Publish dist to gh-pages + run: | + set -euo pipefail + cd dist + touch .nojekyll + git init + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add -A + git commit -m "Deploy ${GITHUB_SHA}" || true + git branch -M gh-pages + git remote add origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" + git push -f origin gh-pages diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml deleted file mode 100644 index 33524ea..0000000 --- a/.github/workflows/mkdocs-deploy.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: mkdocs-deploy -on: - push: - branches: - - main - -permissions: - contents: write -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Configure Git Credentials - run: | - git config --global user.name 'GitHub Actions' - git config --global user.email 'actions@github.com' - - name: Set up Python 3.12.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12.12" - - name: Set up uv - uses: astral-sh/setup-uv@v3 - - name: Clone python-sdk - run: git clone --depth 1 https://github.com/codellm-devkit/python-sdk.git ../python-sdk - - name: Install Dependencies - run: uv sync - - name: Install python-sdk into uv venv - run: uv pip install -e ../python-sdk - - name: Deploy docs - run: uv run mkdocs gh-deploy --force --verbose diff --git a/.github/workflows/update-api-docs.yml b/.github/workflows/update-api-docs.yml new file mode 100644 index 0000000..339849b --- /dev/null +++ b/.github/workflows/update-api-docs.yml @@ -0,0 +1,95 @@ +name: Update Python API reference + +# Regenerates src/content/docs/reference/python-api/*.md from a python-sdk release +# and opens a PR when anything changed. This keeps the *source-controlled* API +# reference matched to the SDK; the deploy workflow regenerates the same docs +# ephemerally for the published build, but never commits them back. +# +# Trigger: a python-sdk *release* only. python-sdk's release workflow +# (.github/workflows/release.yml) sends a repository_dispatch after it publishes, +# carrying the released tag in client_payload.ref: +# +# - name: Trigger docs API-reference update +# uses: peter-evans/repository-dispatch@v3 +# with: +# token: ${{ secrets.DOCS_DISPATCH_TOKEN }} # PAT/fine-grained token with +# # contents:write on codellm-devkit/docs +# repository: codellm-devkit/docs +# event-type: sdk-release +# client-payload: '{"ref": "${{ github.ref_name }}"}' + +on: + repository_dispatch: + types: [sdk-release] + +permissions: + contents: write + pull-requests: write + +concurrency: + group: update-api-docs + cancel-in-progress: true + +jobs: + regenerate: + runs-on: ubuntu-latest + steps: + - name: Checkout docs + uses: actions/checkout@v4 + with: + ref: astro + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Clone python-sdk at the released tag + id: sdk + run: | + set -euo pipefail + git clone https://github.com/codellm-devkit/python-sdk.git ../python-sdk + cd ../python-sdk + # The release workflow sends the released tag in client_payload.ref. + # Fall back to the latest release tag if a dispatch ever arrives without one. + REF="${{ github.event.client_payload.ref }}" + if [ -z "${REF}" ]; then + REF=$(git tag --sort=-v:refname | head -n1) + fi + echo "Generating API reference from python-sdk release: ${REF}" + git checkout "${REF}" + SDK_VERSION=$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])") + echo "ref=${REF}" >> "$GITHUB_OUTPUT" + echo "version=${SDK_VERSION}" >> "$GITHUB_OUTPUT" + + - name: Install the SDK and the generator deps + run: | + set -euo pipefail + python -m pip install --upgrade pip + # Installing cldk pulls in the codeanalyzer-* backends whose models the + # schema pages re-export (needed for griffe alias resolution). + pip install -e ../python-sdk + pip install -r scripts/requirements.txt + + - name: Regenerate API reference markdown + run: python scripts/gen_api_docs.py + + - name: Open a PR if the reference changed + uses: peter-evans/create-pull-request@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + base: astro + branch: auto/api-docs + add-paths: src/content/docs/reference/python-api/** + commit-message: "docs(api): sync Python API reference to python-sdk ${{ steps.sdk.outputs.version }}" + title: "docs(api): sync Python API reference to python-sdk ${{ steps.sdk.outputs.version }}" + body: | + Automated regeneration of the Python API reference from the + [`python-sdk`](https://github.com/codellm-devkit/python-sdk) release + `${{ steps.sdk.outputs.ref }}` (version `${{ steps.sdk.outputs.version }}`). + + Generated by `scripts/gen_api_docs.py` (griffe). Authored intros above the + `CLDK:API:START` markers are preserved; only the generated symbol + reference changed. Review the diff and merge to ship. + labels: documentation, automated + delete-branch: true diff --git a/.gitignore b/.gitignore index 600903c..a960266 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,28 @@ -# Mac file +# macOS .DS_Store -# environment file +# environment files .env +.env.production -# log file -*.json -!devcontainer.json +# Astro build output & generated types +dist/ +.astro/ + +# dependencies +node_modules/ +# logs +npm-debug.log* +yarn-debug.log* +pnpm-debug.log* -# Python compiled files and env +# Python (API doc generation) __pycache__/ *.py[cod] .python-version .venv/ +.venv-docs/ -# Build files -dist/ - -# Build system lock files -uv.lock - -# Cache +# cache .cache/ - -# Site folder -site/ diff --git a/README.md b/README.md index 3d4d411..e0dd453 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ - - - Logo + + + Logo

@@ -25,24 +25,22 @@

-Codellm-Devkit (CLDK) is a multilingual program analysis framework that bridges the gap between traditional static analysis tools and Large Language Models (LLMs) specialized for code (CodeLLMs). Codellm-Devkit allows developers to streamline the process of transforming raw code into actionable insights by providing a unified interface for integrating outputs from various analysis tools and preparing them for effective use by CodeLLMs. +Codellm-Devkit (CLDK) is a multilingual program analysis framework for CodeLLM workflows. It turns source code into structured program facts such as symbols, method bodies, call graphs, and data-model objects that an LLM pipeline can query. -Codellm-Devkit simplifies the complex process of analyzing codebases that span multiple programming languages, making it easier to extract meaningful insights and drive LLM-based code analysis. `CLDK` achieves this through an open-source Python library that abstracts the intricacies of program analysis and LLM interactions. With this library, developer can streamline the process of transforming raw code into actionable insights by providing a unified interface for integrating outputs from various analysis tools and preparing them for effective use by CodeLLMs. +CLDK is an open-source Python library over language-specific analysis backends. The user calls one API; the backend handles parsing, symbol resolution, and graph construction for the selected language. -**The purpose of Codellm-Devkit is to enable the development and experimentation of robust analysis pipelines that harness the power of both traditional program analysis tools and CodeLLMs.** -By providing a consistent and extensible framework, Codellm-Devkit aims to reduce the friction associated with multi-language code analysis and ensure compatibility across different analysis tools and LLM platforms. +**The purpose of Codellm-Devkit is to help build analysis pipelines that combine program-analysis results with CodeLLMs.** +It gives those pipelines a consistent shape across languages and analysis tools. -Codellm-Devkit is designed to integrate seamlessly with a variety of popular analysis tools, such as WALA, Tree-sitter, LLVM, and CodeQL, each implemented in different languages. Codellm-Devkit acts as a crucial intermediary layer, enabling efficient and consistent communication between these tools and the CodeLLMs. +CLDK integrates with tools such as WALA, Tree-sitter, LLVM, and CodeQL. It normalizes their outputs into typed models that downstream code can consume. -Codellm-Devkit is constantly evolving to include new tools and frameworks, ensuring it remains a versatile solution for code analysis and LLM integration. +CLDK is an ongoing IBM Research project. Codellm-Devkit is: -- **Unified**: Provides a single framework for integrating multiple analysis tools and CodeLLMs, regardless of the programming languages involved. -- **Extensible**: Designed to support new analysis tools and LLM platforms, making it adaptable to the evolving landscape of code analysis. -- **Streamlined**: Simplifies the process of transforming raw code into structured, LLM-ready inputs, reducing the overhead typically associated with multi-language analysis. - -Codellm-Devkit is an ongoing project, developed at IBM Research. +- **Unified**: one API over language-specific analysis backends. +- **Extensible**: new backends can add languages or analysis tools. +- **Structured**: code becomes typed models, call graphs, and other queryable artifacts. ## Contact @@ -68,7 +66,7 @@ For any questions, feedback, or suggestions, please contact the authors: ## Architectural and Design Overview -Below is a very high-level overview of the architectural of CLDK: +Below is a high-level view of CLDK's architecture: ```mermaid @@ -96,17 +94,17 @@ User <--> A[CLDK] X[‡ Yet to be implemented] ``` -The user interacts by invoking the CLDK API. The CLDK API is responsible for handling the user requests and delegating them to the appropriate language-specific modules. +The user invokes the CLDK API. CLDK delegates the request to the language-specific module. -Each language comprises of two key components: data models and backends. +Each language has two main components: data models and backends. -1. **Data Models:** These are high level abstractions that represent the various language constructs and componentes in a structured format using pydantic. This confers a high degree of flexibility and extensibility to the models as well as allowing for easy accees of various data components via a simple dot notation. In addition, the data models are designed to be easily serializable and deserializable, making it easy to store and retrieve data from various sources. +1. **Data Models:** Pydantic models for language constructs such as files, classes, methods, fields, and call edges. They support attribute access and serialization. -2. **Analysis Backends:** These are the components that are responsible for interfacing with the various program analysis tools. The core backends are Treesitter, Javaparse, WALA, LLVM, and CodeQL. The backends are responsible for handling the user requests and delegating them to the appropriate analysis tools. The analysis tools perfrom the requisite analysis and return the results to the user. The user merely calls one of several high-level API functions such as `get_method_body`, `get_method_signature`, `get_call_graph`, etc. and the backend takes care of the rest. +2. **Analysis Backends:** Components that call program-analysis tools such as Treesitter, Javaparser, WALA, LLVM, and CodeQL. The user calls high-level methods such as `get_method_body`, `get_method_signature`, or `get_call_graph`; the backend runs the required analysis and returns the result. - Some langugages may have multiple backends. For example, Java has WALA, Javaparser, Treesitter, and CodeQL backends. The user has freedom to choose the backend that best suits their needs. + Some languages may have multiple backends. For example, Java uses WALA, Javaparser, Treesitter, and CodeQL-backed analysis. -We are currently working on implementing the retrieval and prompting components. The retrieval component will be responsible for retrieving the relevant code snippets from the codebase for RAG usecases. The prompting component will be responsible for generating the prompts for the CodeLLMs using popular prompting frameworks such as `PDL`, `Guidance`, or `LMQL`. +Retrieval and prompting components are still in progress. Retrieval will pull relevant code snippets for RAG use cases. Prompting will generate CodeLLM prompts with frameworks such as `PDL`, `Guidance`, or `LMQL`. ## Quick Start: Example Walkthrough @@ -292,3 +290,36 @@ if __name__ == "__main__": 1. Krishna, Rahul, Rangeet Pan, Raju Pavuluri, Srikanth Tamilselvam, Maja Vukovic, and Saurabh Sinha. "[Codellm-Devkit: A Framework for Contextualizing Code LLMs with Program Analysis Insights.](https://arxiv.org/pdf/2410.13007)" arXiv preprint arXiv:2410.13007 (2024). 2. Pan, Rangeet, Myeongsoo Kim, Rahul Krishna, Raju Pavuluri, and Saurabh Sinha. "[Multi-language Unit Test Generation using LLMs.](https://arxiv.org/abs/2409.03093)" arXiv preprint arXiv:2409.03093 (2024). 3. Pan, Rangeet, Rahul Krishna, Raju Pavuluri, Saurabh Sinha, and Maja Vukovic., "[Simplify your Code LLM solutions using CodeLLM Dev Kit (CLDK).](https://www.linkedin.com/pulse/simplify-your-code-llm-solutions-using-codellm-dev-kit-rangeet-pan-vnnpe/?trackingId=kZ3U6d8GSDCs8S1oApXZgg%3D%3D)", Blog. + +--- + +## Building the documentation site + +This documentation site is built with [Astro](https://astro.build/) + +[Starlight](https://starlight.astro.build/) (migrated from MkDocs). + +```sh +npm install +npm run dev # dev server at http://localhost:4321 +npm run build # production build into dist/ +``` + +### Regenerating the Python API reference + +The `src/content/docs/reference/python-api/{core,java,python,c-cpp}.md` pages are +auto-generated from the release-tagged +[`codellm-devkit/python-sdk`](https://github.com/codellm-devkit/python-sdk) +with [griffe](https://mkdocstrings.github.io/griffe/) (the engine behind +mkdocstrings). Run it from an environment where `cldk` is installed, so the +re-exported schema models resolve to their real definitions: + +```sh +python -m venv .venv-docs && . .venv-docs/bin/activate +pip install cldk griffe # or: pip install -e ../python-sdk +python scripts/gen_api_docs.py # pass --search-path ../python-sdk for a local checkout +``` + +Deployment is automated by `.github/workflows/deploy.yml` on every push to +`main`: it clones the python-sdk at its latest release tag, regenerates the API +reference, builds the site, and publishes `dist/` to `gh-pages` +(custom domain `codellm-devkit.info` via `public/CNAME`). diff --git a/REDESIGN_PLAN.md b/REDESIGN_PLAN.md new file mode 100644 index 0000000..e34bfea --- /dev/null +++ b/REDESIGN_PLAN.md @@ -0,0 +1,261 @@ +# CLDK Docs — Total Redesign Plan + +> **Status: IMPLEMENTED (2026-06-04).** Phases A–C built and shipped on the +> `astro` branch — foundations (mermaid + Carbon palette + Space Grotesk/Mono + +> new IA), flagship pages (splash landing, agent recipes, Java 3-zone), and the +> long-tail pages (concepts, common tasks, cheat sheet, CLDK-over-MCP, quickstart +> reframe, python/c/core reference zones). Verified by a clean `npm run build` +> (15 pages) and an adversarial per-page review (0 blockers; 11 major + 4 minor +> findings fixed). The visual direction chosen was "MCP-restraint on Carbon". + +> Goal: make **static analysis feel as approachable as pandas/scikit-learn made +> dataframes/ML**, with the polish and agent-orientation of the **MCP** and +> **Claude SDK** docs — and a through-line that **agents should reach for CLDK** +> as their grounding/analysis layer. +> +> Reference aesthetics: MCP (modelcontextprotocol.io), Claude developer docs +> (docs.claude.com), pandas, scikit-learn. Stack: Astro 5 + Starlight 0.37. + +This plan is grounded in (a) a verified read of the real CLDK API in +`../python-sdk`, (b) a capability audit of this Starlight site, and (c) design +analysis of the four reference sites. **No invented API.** + +--- + +## 0. The single most important correction (locked facts) + +The old todo guessed an `is_reachable()` method and a `target_method_name` arg. +The source says otherwise. **These are the verified, real names** (cite +`cldk/analysis/java/java_analysis.py`): + +| Need | Real API | Notes | +| --- | --- | --- | +| Construct | `CLDK(language="java").analysis(project_path=APP)` | java also supports `source_code=`; python/c require `project_path` | +| Method body | `analysis.get_method(qualified_class_name, qualified_method_name).code` | **not** `get_method_body`; body is the `.code` attr of `JCallable` | +| Callers | `analysis.get_callers(target_class_name, target_method_declaration, using_symbol_table=False)` | returns `Dict` | +| Callees | `analysis.get_callees(source_class_name, source_method_declaration, using_symbol_table=False)` | returns `Dict` | +| Call graph | `analysis.get_call_graph() -> networkx.DiGraph` | edges caller→callee; also `get_call_graph_json()` | +| Class call graph | `analysis.get_class_call_graph(qualified_class_name, method_signature=None)` | | +| **Reachability** | **No `is_reachable()`.** Use `nx.has_path(cg, src, sink)` / `nx.all_simple_paths(cg, src, sink)` over `get_call_graph()` | this is the killer teaching point — see §6 | +| Tree-sitter prune | `cldk.tree_sitter_utils(source_code).sanitize_focal_class(focal_method)` | | + +**Language coverage caveats (drive scope):** +- **Java** — richest: symbol table, classes/methods, call graph, callers/callees, class hierarchy, CRUD, comments, tree-sitter. *Anchor all flagship examples here.* +- **Python** — strong: `get_call_graph`, `get_callers`, `get_callees`, symbol table. (No `source_code` mode.) +- **C** — minimal: `get_c_application()`, `get_functions()`. **No call graph / callers / callees.** Do not show call-graph recipes for C. +- **TypeScript** — exists (`cldk.analysis.typescript`) but less mature; keep out of the flagship narrative for now. + +--- + +## 1. North star & principles (from the reference sites) + +1. **Lead with a definition + one analogy, not a feature wall** (MCP: "USB-C port for AI"). CLDK's analog: *"CLDK is pandas for source code — one object model over call graphs, symbol tables, and ASTs across languages, ready to hand to an LLM."* +2. **Time-to-first-analysis in seconds** (pandas): `pip install cldk` on line one; a 5-line "first analysis" above the fold. +3. **A capability map at a glance** (scikit-learn's 6-card grid): the landing *is* a map of what CLDK can do, each card = one capability with a one-line definition + a real artifact thumbnail + example bullets. +4. **Task language, not API nouns** (pandas/scikit): pages titled "Find who calls this method", "Is this sink reachable?", not "`get_callers`". +5. **The generated symbol dump is the *appendix* of a page, not the page** (MCP). Author the top; generate the bottom. +6. **Separate LEARN from REFERENCE** (all four): Guides/Concepts vs API Reference as distinct top-level lanes. +7. **Agent-native is the headline, not a footnote**: analysis methods are *tools the model calls*. CLDK = the deterministic ground truth that stops the model hallucinating about code. +8. **Honest input→output everywhere** (pandas/scikit): every snippet shows its printed/returned result. +9. **One recurring sample codebase** (pandas' Titanic): use **Apache Commons CLI** (already in the quickstart) as the "Titanic of CLDK" across all Java examples. + +--- + +## 2. Visual design system + +**Direction:** MCP-style restraint (near-monochrome, let code + diagrams carry +color, disciplined typography/whitespace) carried on CLDK's existing **IBM +Carbon** identity (IBM Plex + `#0f62fe` blue). Warmth/approachability comes from +pandas/scikit devices (cards, thumbnails, friendly task titles), not loud color. + +- **Palette:** extend `src/styles/docs.css` beyond the accent ramp — define the full Starlight token set (gray scale, `--sl-color-bg`/`-bg-nav`/`-bg-sidebar`/`-bg-inline-code`, hairlines, callout colors) for both themes so it stops looking like "default Starlight + blue". Carbon-influenced neutrals; one accent (`#0f62fe`), darker surfaces in dark mode. +- **Type:** keep IBM Plex Sans / Plex Mono (already wired). Tighten the `--sl-text-*` scale and `--sl-content-width` for a denser, reference-grade feel. +- **Components to actually use** (mostly unused today): `Steps` (quickstart/recipes loop), `LinkCard`/`CardGrid` (landing + "next steps"), `LinkButton` (hero CTAs), `Badge` (language/maturity tags, e.g. `Java` `Python` `C: limited`), `Tabs` with `syncKey` (sync language across the whole site), `FileTree` (project layout), `Aside` (replace the raw `
` in quickstart), `Code` (render generated/imported snippets). +- **Mermaid:** **not wired today.** Add `astro-mermaid` (`npm i astro-mermaid mermaid`), register **before** `starlight()`, `autoTheme: true`. Restores the architecture diagram lost in the migration and powers the call-graph / data-layer diagrams. +- **Expressive Code:** add `@expressive-code/plugin-collapsible-sections` (fold boilerplate in long recipe snippets) and `@expressive-code/plugin-line-numbers`; set `styleOverrides.borderRadius`. Use frames + titles + line highlighting (already partly used). +- **Custom landing:** switch home to Starlight's `template: splash` with a structured `hero` (title/tagline/dark+light image/action buttons). Optionally a `Hero` component override for a bespoke marketing band above the capability grid. +- **Tailwind:** *not* required — the CSS-custom-property approach is enough. (Note `@astrojs/starlight-tailwind` as an option if we later want utility-class landing sections.) + +--- + +## 3. Information architecture (new sidebar) + +Two-axis IA: **personas on the landing page**, **Learn vs Reference in the sidebar.** + +``` +Top nav / sidebar groups +├─ Start here +│ ├─ What is CLDK? (concept + analogy + architecture mermaid) [new] +│ ├─ Quickstart (agent-native, 3 Steps) [rework] +│ └─ Installation +├─ Guides (LEARN — prose-first, deep-link into Reference) +│ ├─ Core concepts: symbol table, call graph, reachability, analysis levels [new] +│ ├─ Common tasks (task-titled snippet index) [new, todo #9] +│ ├─ Agent recipes ★ (the centerpiece — agent-native, Anthropic SDK) [new, todo #1] +│ └─ Coming from… (tree-sitter / CodeQL / raw mkdocstrings) [new, stretch] +├─ API Reference (REFERENCE — authored top, generated bottom) +│ ├─ Overview (mental model + capability grid + mermaid) [rework, todo #2] +│ ├─ Core (CLDK) +│ ├─ Java analysis (3-zone: overview/backend → worked example → symbols) [rework, todo #3] +│ ├─ Python analysis (3-zone) +│ └─ C analysis (3-zone; mark call-graph features N/A) +└─ Resources + ├─ Cheat sheet (one-page quick reference; pandas-style) [new] + └─ CLDK over MCP (analysis methods as MCP tools) [stretch, todo #8] +``` + +Covers every todo item: #1 Agent recipes, #2 reference overview, #3 three-zone +language pages, #4 IA split, #5 symbol-gen, #6 quickstart, #7 mermaid+EC, #8 MCP, +#9 common tasks. + +--- + +## 4. Landing page (`index.mdx` → splash) + +Anatomy (scikit-learn grid × pandas approachability × MCP restraint): + +1. **Hero**: wordmark + one sentence ("pandas for source code…") + `pip install cldk` + two `LinkButton`s: **Quickstart** and **Agent recipes**. +2. **First analysis above the fold**: a ~6-line tabbed (Java/Python) snippet that loads a project and prints the call graph size — *input→output*. +3. **Capability grid (the scikit-learn move)** — `CardGrid` of 6 cards, each = one-line definition + thumbnail (a real rendered artifact — call-graph mermaid, symbol-table JSON, sanitized class) + 2 example bullets, linking to the matching capability/reference page: + - Symbol tables · Call graphs · Reachability · Class structure & hierarchy · CRUD/data-access · Tree-sitter utilities +4. **"Agents prefer CLDK" band**: short pitch + the data-layer mermaid (Claude ⇄ tool loop ⇄ CLDK ⇄ {call graph, symbol table, tree-sitter}) → link to Agent recipes. +5. **Start-building / Learn-more `CardGrid`s** (MCP pattern) and the existing badges/contact. + +--- + +## 5. "What is CLDK?" + reference overview (todo #2) + +- Plain-language mental model: **`CLDK(language)` → `analysis` facade → typed `models`/schema**, backed by real engines (Java=WALA/codeanalyzer, Python=Jedi+CodeQL, C=libclang, all + Tree-sitter). The home page name-drops these engines but never connects them to the API — **make that connection explicit** (todo #3, Zone A). +- **Architecture mermaid** (restored/expanded from README) and the analysis-level model. +- Replace the bullet-link reference index with the capability `CardGrid` + `LinkCard`s. + +--- + +## 6. Agent recipes — the centerpiece (todo #1) + +New page `src/content/docs/guides/agent-recipes.mdx`. Anthropic SDK tool-use, +**prompt caching from the start** (per the `claude-api` skill), three recipes on +**one shared, verified tool layer**. Anchor in **Java + Commons CLI**. + +**Shared tool layer (verified against source):** + +```python +import anthropic, networkx as nx +from cldk import CLDK + +analysis = CLDK(language="java").analysis(project_path=APP) # JavaAnalysis facade + +TOOLS = [ + {"name": "get_method_body", "description": "...", + "input_schema": {"type":"object","properties":{ + "qualified_class_name":{"type":"string"}, + "qualified_method_name":{"type":"string"}}, "required":[...]}}, + {"name": "get_callers", "description": "...", + "input_schema": {... "target_class_name","target_method_declaration" ...}}, + {"name": "get_callees", "description": "...", + "input_schema": {... "source_class_name","source_method_declaration" ...}}, + {"name": "is_reachable", "description": "Is sink reachable from source in the call graph?", + "input_schema": {... "source","sink" ...}}, +] + +CG = analysis.get_call_graph() # networkx.DiGraph, cached once + +def dispatch(name, args): + if name == "get_method_body": + return analysis.get_method(args["qualified_class_name"], + args["qualified_method_name"]).code + if name == "get_callers": + return analysis.get_callers(args["target_class_name"], + args["target_method_declaration"]) + if name == "get_callees": + return analysis.get_callees(args["source_class_name"], + args["source_method_declaration"]) + if name == "is_reachable": + return nx.has_path(CG, args["source"], args["sink"]) # ground truth, not a guess + +# run_agent(task): messages.create tool-use loop until stop_reason != "tool_use". +# Cache the stable TOOLS + system block: "cache_control": {"type": "ephemeral"} +``` + +> **Build-time TODO:** confirm the exact node-identity convention of the +> `get_call_graph()` DiGraph (node = method id?) on a real Commons CLI run before +> finalizing the `is_reachable` node resolution. Verify by inspecting a live graph, +> not by guessing. + +- **Recipe 1 — Call-graph-guided Q&A** (gentle intro): "How does `Option.create` work, and what calls it?" Show the trace of tool calls the model chooses. Establishes the loop. +- **Recipe 2 — Source-to-sink reachability** (the killer demo): feed a Bandit/Semgrep-style alert; agent calls `get_callers`/`is_reachable` to confirm or refute. **Teaching point, stated explicitly:** CLDK returns *ground truth the model would otherwise hallucinate*. Cross-link the `poe-with-cldk` / `triage-and-pov` skills. +- **Recipe 3 — Targeted refactor**: agent enumerates **all** callers via CLDK *before* proposing an API change, so the edit is safe — CLDK preventing a whole class of agent mistakes. +- Components: `Steps` for the loop, `Tabs` for request/response pairs, `Aside type="caution"` for gotchas, the data-layer **mermaid**, collapsible EC sections for boilerplate. + +--- + +## 7. Per-language API reference → three zones (todo #3) + +For `java.md` / `python.md` / `c-cpp.md` (+ `core.md`): +- **Zone A — Overview**: what this analyzer does, which **backend** it wraps, analysis levels, a `Badge` maturity row. +- **Zone B — Worked example**: `Tabs`/`Steps` walkthrough ("Get the symbol table" / "Build a call graph" / "Find callers") on Commons CLI, input→output. +- **Zone C — Reference**: the generated symbols (from §8), grouped by category. + +C page explicitly marks call-graph/callers/callees as **not available**. + +--- + +## 8. API symbol generation (todo #5) + +Keep & **extend** `scripts/gen_api_docs.py` (griffe). Port the spirit of the old +mkdocstrings options: group **by category** (use the `category` we already derive), +clean signatures, source links, `filters: ["!^_"]`, source member order. Emit the +**Zone C** block that gets composed under the authored Zones A/B (e.g. generate a +partial that the hand-authored page imports, or generate full pages whose top +matter is hand-authored and bottom is generated between markers). Decision to lock +at build time: *generated partial included into authored MDX* (cleanest). + +--- + +## 9. Quickstart reframe (todo #6) + +Current example is the old paradigm (build prompt string → `ollama.generate()` → +text). Reframe as **agent-native** with `Steps`, or explicitly label it the +"hello world" and link to Agent recipes as the real pattern. Recommendation: +keep a 3-step *hello world* (install → load project → one analysis call with +printed output), then a prominent `LinkCard` to Agent recipes. Replace raw +`
` with `