Skip to content

Add llms.txt generation, docs version updater, and CHANGELOG integration#24

Merged
koxudaxi merged 1 commit into
mainfrom
feat/llms-txt-docs-tooling
Mar 18, 2026
Merged

Add llms.txt generation, docs version updater, and CHANGELOG integration#24
koxudaxi merged 1 commit into
mainfrom
feat/llms-txt-docs-tooling

Conversation

@koxudaxi

@koxudaxi koxudaxi commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added comprehensive documentation files for enhanced documentation integration and AI model compatibility
  • Chores

    • Automated changelog synchronization and version updates across documentation
    • Enhanced documentation build workflows for improved consistency
    • Improved changelog generation to exclude draft releases

@github-actions

Copy link
Copy Markdown
Contributor

📚 Docs Preview: https://pr-24.tstring-structured-data.pages.dev

@coderabbitai

coderabbitai Bot commented Mar 18, 2026

Copy link
Copy Markdown

Walkthrough

This PR introduces automated documentation workflows and script-based generators. It extends GitHub Actions to synchronize changelogs and generate llms.txt documentation files from zensical.toml navigation structures, adds Python scripts for version pinning updates in docs, and creates AI-friendly documentation outputs.

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/docs.yaml, .github/workflows/llms-txt.yaml
Modified docs workflow to copy/generate changelog and run version update script before build. Added new llms-txt workflow to generate docs/llms.txt and docs/llms-full.txt on relevant doc/config changes, with logic for forked PRs and PR-target events.
Documentation Generation Scripts
scripts/build_llms_txt.py, scripts/update_docs_version.py, scripts/generate_changelog.sh
Added build_llms_txt.py to parse zensical.toml and extract Markdown metadata, generating summary and full llms.txt files with optional check mode. Added update_docs_version.py to update version pins in docs from latest GitHub release. Modified generate_changelog.sh to exclude draft releases.
Generated Documentation
docs/llms.txt, docs/llms-full.txt
Added new documentation files: llms.txt with structured link and description summaries, llms-full.txt with complete page contents for AI consumption.
Configuration & Metadata
.gitignore, CHANGELOG.md
Added docs/changelog.md to gitignore under docs build artifacts. Updated CHANGELOG.md with 0.1.1 release notes.

Sequence Diagram

sequenceDiagram
    participant GHA as GitHub Actions
    participant Script as build_llms_txt.py
    participant TOML as zensical.toml
    participant Docs as docs/*.md
    participant FS as File System
    participant Git as Git Repo

    GHA->>Script: Trigger (on docs/TOML/script change)
    Script->>TOML: Parse site config & nav
    TOML-->>Script: site_name, description, nav tree
    Script->>Docs: Extract metadata per page
    Docs-->>Script: title, description, content
    Script->>FS: Generate llms.txt (summary)
    Script->>FS: Generate llms-full.txt (full content)
    FS-->>Script: Write confirmation
    Script->>Git: Commit & push updates
    Git-->>GHA: Workflow complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through docs so neat,
Building llms.txt—a comprehensive treat!
Versions sync, changelogs flow,
AI feeds on knowledge we grow.
From Zensical gardens to files so bright,
Documentation automation feels just right! 📚✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes in the pull request: adding llms.txt generation, docs version updater, and CHANGELOG integration. It is specific, concise, and directly reflects the primary objectives of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/llms-txt-docs-tooling
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/build_llms_txt.py (1)

173-186: Optional-section grouping is not recursion-safe for deeper nav trees.

Line 173-Line 186 only evaluate one nesting level, so nested optional descendants can be classified/rendered incorrectly when nav depth grows.

Suggested refactor
+    def section_all_optional(section: NavSection) -> bool:
+        if section.path:
+            return is_optional(section.path)
+        return bool(section.children) and all(section_all_optional(c) for c in section.children)
+
+    def iter_leaf_pages(section: NavSection) -> list[PageInfo]:
+        if section.path:
+            p = page_map.get(section.path)
+            return [p] if p else []
+        out: list[PageInfo] = []
+        for c in section.children:
+            out.extend(iter_leaf_pages(c))
+        return out
+
     main, optional = [], []
     for s in sections:
-        is_opt = (s.path and is_optional(s.path)) or (s.children and all(is_optional(c.path) for c in s.children))
+        is_opt = section_all_optional(s)
         (optional if is_opt else main).append(s)
@@
-        lines.extend(
-            fmt(p)
-            for s in optional
-            for item in ([s] if s.path else s.children)
-            if item.path and (p := page_map.get(item.path))
-        )
+        for s in optional:
+            for p in iter_leaf_pages(s):
+                lines.append(fmt(p))
         lines.append("")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/build_llms_txt.py` around lines 173 - 186, The current grouping logic
using is_opt = (s.path and is_optional(s.path)) or (s.children and
all(is_optional(c.path) for c in s.children)) is only one-level deep and
misclassifies deeper optional descendants; replace it with a recursion-safe
approach: add a helper (e.g., has_optional_descendant(node) or
classify_nav(node)) that walks s.children recursively to determine whether any
descendant path is optional (using is_optional) and to collect nodes into main
or optional lists; update the loop that builds main/optional to call that helper
for each top-level s and update the optional rendering block to iterate
recursively (similar to render(s)) using page_map.get to find pages (symbols:
is_opt/is_optional, s.children, main, optional, render, fmt, page_map) so nested
optional items are correctly grouped and rendered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/llms-txt.yaml:
- Around line 16-48: The workflow currently uses the pull_request_target trigger
and secrets.PAT while checking out PR code (see pull_request_target,
jobs.update-llms-txt, and uses: actions/checkout@v4), and the condition includes
github.actor == 'koxudaxi' which bypasses the safe-to-fix gating; change the
trigger to pull_request (restricting to non-fork PRs by checking that
pull_request.head.repo.full_name == github.repository or similar), remove the
pull_request_target branch/logic entirely, replace secrets.PAT with github.token
in the checkout step token field, and remove the github.actor == 'koxudaxi'
clause from the if condition so only labeled safe-to-fix PRs (and controlled
push events) can run the job.

---

Nitpick comments:
In `@scripts/build_llms_txt.py`:
- Around line 173-186: The current grouping logic using is_opt = (s.path and
is_optional(s.path)) or (s.children and all(is_optional(c.path) for c in
s.children)) is only one-level deep and misclassifies deeper optional
descendants; replace it with a recursion-safe approach: add a helper (e.g.,
has_optional_descendant(node) or classify_nav(node)) that walks s.children
recursively to determine whether any descendant path is optional (using
is_optional) and to collect nodes into main or optional lists; update the loop
that builds main/optional to call that helper for each top-level s and update
the optional rendering block to iterate recursively (similar to render(s)) using
page_map.get to find pages (symbols: is_opt/is_optional, s.children, main,
optional, render, fmt, page_map) so nested optional items are correctly grouped
and rendered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51b2452e-ba8b-4811-954e-8ea44b69a5af

📥 Commits

Reviewing files that changed from the base of the PR and between 9712e21 and 350d7c0.

📒 Files selected for processing (9)
  • .github/workflows/docs.yaml
  • .github/workflows/llms-txt.yaml
  • .gitignore
  • CHANGELOG.md
  • docs/llms-full.txt
  • docs/llms.txt
  • scripts/build_llms_txt.py
  • scripts/generate_changelog.sh
  • scripts/update_docs_version.py

Comment thread .github/workflows/llms-txt.yaml
@koxudaxi
koxudaxi merged commit 21fc49f into main Mar 18, 2026
9 checks passed
@koxudaxi
koxudaxi deleted the feat/llms-txt-docs-tooling branch March 18, 2026 10:22
@github-actions github-actions Bot added the breaking-change-analyzed PR has been analyzed for breaking changes label Mar 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: PR #24 only adds documentation tooling (llms.txt generation, docs version updater, changelog improvements) and CI workflow enhancements. No changes were made to library source code, public APIs, parsing behavior, output serialization, or runtime requirements. All changed files are in .github/workflows/, scripts/, docs/, CHANGELOG.md, and .gitignore - none of which affect the library's public interface or behavior.


This analysis was performed by Claude Code Action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change-analyzed PR has been analyzed for breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant