Metadata-Version: 2.4
Name: selfdoc
Version: 0.27.0
Summary: Code-aware static site generator with directive-based content extraction
Project-URL: Repository, https://github.com/smm-h/selfdoc
Author: smm-h
License-Expression: MIT
License-File: LICENSE
Keywords: docstring,documentation,jsdoc,rlsbl,selfdoc,static-site-generator
Requires-Python: >=3.12
Requires-Dist: strictcli
Provides-Extra: og
Requires-Dist: predraw; extra == 'og'
Provides-Extra: perf
Requires-Dist: brotli>=1.1; extra == 'perf'
Description-Content-Type: text/markdown

<!-- Auto-generated by selfdoc from docs/_README.md — do not edit -->

# selfdocumenting

Code-aware documentation site generator. Builds full static sites from Markdown templates and source code. Your code is the documentation -- directives in Markdown pull live content from your codebase at build time.

Supports Python, Go, and TypeScript/JavaScript. One runtime dependency (strictcli). Pure Python.

## Install

```
pip install selfdocumenting
```

or via npm (delegates to Python under the hood):

```
npm install -g selfdocumenting
```

Requires Python 3.11+.

The npm package is named `selfdocumenting` (npm blocks `selfdoc` due to name similarity). The CLI command remains `selfdoc`.

## Quick start

```bash
# Initialize in an existing project (auto-detects language)
selfdoc init

# Auto-generate API and CLI reference pages
selfdoc gen

# Edit docs/ pages -- add directives referencing your code

# Build HTML output
selfdoc build

# Validate directives, coverage, and SEO lint
selfdoc check

# Serve locally with live reload
selfdoc serve
```

Your `selfdoc.json` needs `versions` and `locales` -- even for a single-version, single-locale project:

```json
{
  "language": "python",
  "source": ["src/"],
  "base_url": "https://my-project.example.com",
  "versions": [{"version": "1.0.0", "indexed": true}],
  "locales": [{"code": "en", "label": "English", "default": true}]
}
```

## Features

- **Directive syntax** -- embed live API references, schemas, tests, and CLI help directly from source code (`:-:`, `:<:`, `:>:`)
- **Auto-generated pages** -- API reference and CLI docs from source code structure (`selfdoc gen`)
- **Multi-version docs** -- build from git tags, cached builds, version picker UI
- **Localization** -- parallel locale directories, hreflang tags, locale picker, per-locale sitemaps
- **Monorepo support** -- unified site builder combines multiple projects into one docs site
- **Faceted search** -- key=value filter syntax, 7 dimensions, chip UI, auto-injected version default
- **Sandboxed data generation** -- run scripts in bubblewrap isolation (`selfdoc gen-data`)
- **Theming** -- dark mode, accent colors, custom CSS overrides
- **Search engines** -- builtin, Fuse.js, or MiniSearch
- **SEO** -- 15+ lint rules, WCAG contrast validation, JSON-LD structured data, sitemaps
- **Coverage tracking** -- per-symbol documentation coverage with configurable thresholds
- **Syntax highlighting** -- build-time Pygments, code tabs, sortable tables
- **Performance** -- CSS/JS/HTML minification, critical CSS inlining, gzip and Brotli pre-compression
- **Feeds and AI** -- Atom feed, `robots.txt` with AI crawler controls, `llms.txt` / `llms-full.txt`
- **Landing page** -- hero section, tagline, and feature cards
- **Live reload** -- SSE-based dev server
- **Auto-commit** -- generated files committed automatically (prefers safegit)

## Directive syntax

Directives are inline blocks in your Markdown templates. They get replaced with content extracted from your source code at build time.

```
:-: directive-name path="arg"
```

Self-closing directives use `:-:`. Block directives that wrap a body use `:<:` to open, `:>:` to close, with `:=:` and `:::` to delimit sections inside. Directives inside fenced code blocks are ignored.

## Built-in directives

| Directive | Description |
| --- | --- |
| `callout-danger` | Styled danger callout block |
| `callout-important` | Styled important callout block |
| `callout-note` | Styled note callout block |
| `callout-tip` | Styled tip callout block |
| `callout-warning` | Styled warning callout block |
| `code-help` | Extract CLI help/usage text and flag definitions |
| `code-test` | Embed test source code (whole file or specific function) |
| `list-features` | Module summaries from docstring first lines |
| `list-glossary` | Definition list from **Term**: Definition lines |
| `list-modules` | List source modules with file paths and docstring summaries |
| `list-tree` | File/directory tree listing |
| `prose-desc` | Extract module/package docstring as prose text |
| `ref` | Extract module docstring, exported functions, and classes |
| `table-commands` | CLI command summary table from strictcli structure |
| `table-config` | Render a config file (JSON/TOML) as a key-value table |
| `table-config-schema` | Configuration field reference table from schema |
| `table-dep` | Dependencies table from pyproject.toml |
| `table-directives` | Table of all core built-in directives |
| `table-endpoint` | REST API endpoint table from OpenAPI spec |
| `table-schema` | Extract dataclass/struct fields as a markdown table |
| `var` | Interpolate project metadata value |

Example -- embed the API docs for a Python module:

```markdown
## API Reference

:-: ref path="selfdoc.config"
```

Example -- show a JSON schema as a table:

```markdown
:-: table-schema path="selfdoc.json"
```

## Custom directives

Register custom directives in `selfdoc.json` under the `directives` key. Each entry maps a directive name to a Python script (relative to project root) that exports a `resolve(attrs, config, body)` function returning a Markdown string.

```json
{
  "directives": {
    "changelog": "scripts/changelog_directive.py"
  }
}
```

Script interface:

```python
def resolve(attrs: dict, config: dict, body: list) -> str:
    """Return Markdown string to replace the directive block.

    attrs  -- directive attributes as str->str dict (e.g. {"path": "v1.0.0"})
    config -- the full selfdoc.json config dict
    body   -- body lines from the directive block (empty list for one-liners)
    """
    version = attrs.get("path")
    ...
```

Use in templates:

```markdown
:-: changelog path="v1.0.0"
```

Custom directives take priority over built-in names.

## Configuration

`selfdoc.json` at the project root:

```json
{
  "language": "python",
  "source": ["selfdoc/"],
  "docs": "docs/",
  "output": "docs/_build/",
  "base_url": "https://my-project.example.com",
  "versions": [{"version": "1.0.0", "indexed": true}],
  "locales": [{"code": "en", "label": "English", "default": true}],
  "deploy": {
    "provider": "cloudflare-pages",
    "project": "my-docs"
  },
  "directives": {}
}
```

| Field | Required | Description |
| --- | --- | --- |
| `source` | yes | List of source entries to extract documentation from. |
| `base_url` | yes | Base URL of the generated site, used for canonical links and SEO. |
| `version` | no | Project version. When present, used by deploy instead of reading from pyproject.toml/package.json. |
| `docs` | no | Directory containing Markdown documentation templates. |
| `output` | no | Output directory for generated HTML files. |
| `theme` | no | Visual theme for the generated site. |
| `repo` | no | GitHub repository URL shown in the site header. |
| `lang` | no | BCP 47 language tag for the site content (e.g. 'en', 'pt-BR'). |
| `description` | no | Short description of the project, used in meta tags and SEO. |
| `branch` | no | Git branch used for source links in the generated site. |
| `search` | no | Search UI mode: icon button, full bar, or hidden. |
| `search_engine` | no | Client-side search engine implementation to use. |
| `code_icons` | no | Style of language icons shown on code blocks. |
| `line_numbers` | no | Show line numbers in code blocks. |
| `run_button` | no | Show a run button on code blocks for supported languages. |
| `page_nav` | no | Show previous/next navigation links between pages. |
| `page_progress` | no | Show a reading progress bar at the top of each page. |
| `glossary` | no | Auto-generate a glossary page from dfn terms. |
| `feed_max_entries` | no | Maximum number of entries in the Atom feed, sorted by most recent. |
| `lint_ignore` | no | List of lint rule IDs to suppress (e.g. 'SEO007', 'STALE001'). |
| `root_files` | no | List of underscore-prefixed template paths in docs/ for root file generation. |
| `redirects` | no | Page-level redirects expanded across all locale/version combos. |
| `deploy` | no | Deployment configuration for publishing the generated site. |
| `directives` | no | Custom directive mappings from directive name to source file path. |
| `author` | no | Author information for meta tags and structured data. |
| `feedback` | no | Feedback collection configuration (at least one of webhook or ga required). |
| `branding` | no | Landing page branding and call-to-action configuration. |
| `auto_detect` | no | Automatic content detection settings for step guides and API entries. |
| `gen` | no | Configuration for the gen command. |
| `gen_data` | no | Configuration for the gen-data command. |
| `schema_types` | no | Mapping from page type to schema.org @type (e.g. guide -> TechArticle). |
| `versions` | no | List of documentation versions to build. |
| `locales` | no | List of locales for multi-language documentation. |
| `unified` | no | Configuration for unified multi-project documentation. |
| `posts` | no | Blog post configuration. |
| `topology` | no | Deployment topology for multi-project unified sites. |
| `assembly` | no | Assembly configuration for unified site deployment. |

`selfdoc init` auto-detects language and source paths from project files (pyproject.toml, go.mod, tsconfig.json, package.json).

## Commands

| Command | Description |
| --- | --- |
| `init` | Initialize selfdoc configuration and starter docs template |
| `build` | Build the documentation site from templates and source code |
| `serve` | Serve the documentation site locally with live reload |
| `deploy` | Deploy the built documentation site to the configured provider |
| `check` | Check documentation coverage, directive resolution, and lint rules |
| `gen` | Auto-generate documentation pages from project structure |
| `gen-data` | Generate data files by running sandboxed scripts via bwrap |
| **post** | Manage blog posts and chronological content for the documentation site |
| `post new` | Scaffold a new blog post markdown file with a date-prefixed filename and frontmatter template containing title, date, slug, tags, draft status, and project metadata. Creates the file in the configured posts directory and exits with an error if the file already exists. |
| `post list` | List all discovered blog posts with date, title, slug, and draft status. Scans the configured posts directory for markdown files with frontmatter, parses their metadata, and prints a formatted summary showing each post's publication date, title, slug identifier, and whether it is marked as a draft. |
| `post generate` | Generate a blog post markdown file from structured release metadata. Takes version, bump type, description, changelog, and registry URLs as inputs, produces a frontmatter-bearing post with title, date, tags, and body content, and updates the project manifest with the new post entry. |
| `post publish` | Publish non-draft blog posts to the documentation assembly. Builds posts locally, pushes built HTML and manifest to the assembly repo via the Git Data API, then dispatches a shared-only workflow to regenerate cross-project elements. |
| **assembly** | Manage the unified multi-project documentation assembly and deployment |
| `assembly init` | Create and initialize the assembly GitHub repository with workflow and configuration files. Creates a private GitHub repo, pushes initial files via the Contents API, creates a Cloudflare Pages project if credentials are available, and sets GitHub secrets for deployment authentication. |
| `assembly push` | Dispatch a GitHub Actions workflow to rebuild this project in the documentation assembly. Detects the source repository, resolves the latest git tag as the version reference, and sends a repository dispatch event to the assembly repo with the project slug, version, and commit SHA. |
| `assembly status` | Show the status of recent assembly build workflow runs on GitHub. Queries the assembly repository for recent workflow runs using the GitHub CLI and displays their status, conclusion, and timing information for monitoring deployment progress. |
| `assembly rebuild` | Dispatch rebuild workflows for every project registered in the assembly. Fetches the projects.json manifest from the assembly repository, then sends a separate GitHub Actions repository dispatch event for each registered project to trigger a full documentation rebuild. |
| `assembly redirects` | Generate a Cloudflare Pages _redirects file for this project that redirects standalone documentation URLs to the corresponding paths on the unified assembly site. Requires a project slug and assembly base URL as inputs, prints the redirect rules to stdout. |
| `assembly generate-shared` | Generate 6 shared cross-project elements for the assembled documentation site. Reads per-project manifest JSON files, merges post overlays, and produces a homepage, blog index, navigation JSON, RSS feed, XML sitemap, and security headers file in the site output directory. |

## Deploy

### Cloudflare Pages

Requires the [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) installed and authenticated.

```json
{
  "deploy": {
    "provider": "cloudflare-pages",
    "project": "my-docs-project"
  }
}
```

```bash
selfdoc build && selfdoc deploy
```

### GitHub Pages

Pushes the output directory to the `gh-pages` branch via force-push.

```json
{
  "deploy": {
    "provider": "github-pages"
  }
}
```

Enable GitHub Pages in your repo settings (source: `gh-pages` branch).

## Integration with rlsbl

When [rlsbl](https://github.com/smm-h/rlsbl) detects a `selfdoc.json` in the project, it can trigger `selfdoc build` and `selfdoc deploy` as part of the release lifecycle via the `.rlsbl/hooks/post-release.sh` hook.

## Documentation

Full documentation at [selfdoc.smmh.dev](https://selfdoc.smmh.dev).

## License

MIT
