# docs-autogen
On-demand regeneration of `README.AUTOGEN.md` companion files for every
package under `ts/packages/**` in the TypeAgent monorepo.
This package implements the workflow described in
[`ts/docs/architecture/doc-autogen.md`](../../docs/architecture/doc-autogen.md).
It is intended to be invoked manually from CI via `workflow_dispatch`
(no schedule) and exposes a CLI (`docs-autogen`) for local invocation.
> **Important:** `docs-autogen` writes to a parallel
> `README.AUTOGEN.md` file alongside each package's hand-written
> `README.md` and **never modifies `README.md`**. The hand-written
> README is treated as authoritative source material — its content is
> read on every run and forwarded to the LLM as context the AI-authored
> documentation should mirror and extend, never overwrite.
>
> This README itself is hand-written and **not** regenerated by
> `docs-autogen` — the generator skips its own package and anything
> outside `ts/packages/**`.
## What it produces
For each eligible package, `docs-autogen` writes a `README.AUTOGEN.md`
file at the package root with this structure:
1. Copyright header (markdown comments).
2. `<!-- AUTOGEN:DOCS:START -->` marker.
3. Content hash + `SOURCE` comment pointing back at `./README.md`.
4. `# <pkg-name> — AI-generated documentation` H1 title.
5. AI-authored documentation banner.
6. AI-authored multi-section body (Overview / What it does / Key Files
/ How to extend, plus optional sections). Validated for
length, tone, link integrity, and required sections.
7. Deterministic `## Reference` appendix: entry points, dependencies,
used-by graph, files of interest, agent surface, and a per-action
reference table for agent packages — all computed from
`package.json`, `src/`, and the workspace graph at the commit
recorded in the staleness footer.
8. Staleness footer (commit SHA + ISO date + verify hint).
9. `<!-- AUTOGEN:DOCS:END -->` marker.
Regeneration is content-hash gated; packages whose inputs are
unchanged are skipped, and packages whose new file differs only in the
staleness footer/hash are also skipped so repeated dispatches don't
churn unchanged docs.
## Usage (local)
After `pnpm install` and `pnpm --filter @typeagent/docs-autogen build`:
```bash
# Plan-only (default): print which packages would be regenerated.
pnpm docs:generate:dry
# Regenerate README.AUTOGEN.md for every changed package and write the
# new content to disk (placeholder body — no LLM call). Useful for
# refreshing the deterministic Reference section without spending tokens.
pnpm docs:generate
# Same, plus author the documentation body via Azure OpenAI (requires
# AZURE_OPENAI_ENDPOINT + AZURE_OPENAI_API_KEY in ts/.env).
pnpm docs:generate:llm
# Spot-check that every link in every package's README.AUTOGEN.md still
# resolves on disk.
pnpm docs:verify-links
```
The CLI accepts more granular flags:
```bash
# Regenerate one package only. The `-agent` suffix on agent packages
# is optional; both `--package list-agent` and `--package list` resolve.
node tools/docsAutogen/bin/docs-autogen.cjs --package list --render --write --llm
# Diff against an explicit ref instead of the watermark.
node tools/docsAutogen/bin/docs-autogen.cjs --since main --render --write
# Dry-run preview without touching disk.
node tools/docsAutogen/bin/docs-autogen.cjs --package list --render --write --dry-run
# JSON output for tool-driven consumers.
node tools/docsAutogen/bin/docs-autogen.cjs --all --render --json > /tmp/plan.json
# Cap how many packages a single run touches (default 25).
node tools/docsAutogen/bin/docs-autogen.cjs --all --render --write --max-packages 5
```
> The `bin/docs-autogen.cjs` shim is a thin launcher that silences a
> Node 24 deprecation warning from `simple-git` and filters a known
> Windows libuv shutdown-race assertion from stderr. The underlying
> CLI is still `dist/cli.js` and accepts identical flags if you need
> to invoke it directly — the launcher sets `DOCS_AUTOGEN_LAUNCHED=1`
> so the CLI can suppress the launcher tip when invoked correctly.
>
> **Known limitation (Windows + Node 24, `--llm` only):** the libuv
> shutdown bug (`STATUS_STACK_BUFFER_OVERRUN` / exit code
> `-1073740791`) fires from inside `aiclient`'s dependency tree
> _after_ a successful LLM run completes. The launcher hides the
> stderr text and rewrites the abnormal exit code to `0`; Node 22 is
> the repo's documented minimum and is not affected, and CI runs on
> Linux and is not affected. Treat the run as successful if every
> per-package `write=...` line shows `wrote`, `unchanged`, or
> `footer-only` — those are emitted before exit, so any real failure
> would be visible there.
`--render` without `--write` prints the assembled `README.AUTOGEN.md`
contents to stdout so you can inspect what would be written. `--write`
requires `--render`. Every link inside the generated file is validated
against on-disk paths before the file is written; broken links produce
a `broken-links` verdict and the file is left untouched.
## First-run cleanup
Earlier prototypes embedded the AUTOGEN region directly inside each
package's `README.md` between
`<!-- AUTOGEN:DOCS:START -->` / `<!-- AUTOGEN:DOCS:END -->` markers.
That has been removed in favour of the parallel `README.AUTOGEN.md`
file. If you find a `README.md` that still contains those markers
(e.g. on a stale branch), splice the marker block out by hand or
restore the file from `main`. The new generator does not touch
`README.md` and will silently leave such legacy blocks in place
otherwise.
`gatherPackageInputs` will fall back to reading a legacy AUTOGEN block
from `README.md` if no `README.AUTOGEN.md` exists yet — purely so the
first regeneration after the migration can refine prior LLM output
instead of starting from scratch.
## Operations
### CI workflow
The on-demand GitHub Action lives at
[`.github/workflows/docs-generate.yml`](../../../.github/workflows/docs-generate.yml).
It is **not** scheduled — runs are triggered manually via
`workflow_dispatch` with the same flags the CLI exposes. The job is
bound to the `development-fork` GitHub environment (the same
environment used by `smoke-tests.yml` and `build-docker-container.yml`)
so federated-credential exchange against the existing build-pipeline
Entra App registration succeeds and `getKeys.mjs` can read
`build-pipeline-kv` for Azure OpenAI credentials.
> **First-time pipeline setup** — installing the GitHub App,
> provisioning secrets and variables, and validating the first run
> — is covered in
> [`ts/docs/architecture/doc-autogen-setup.md`](../../docs/architecture/doc-autogen-setup.md).
> The summary below is reference-only; do not use it as a substitute
> for the setup guide on a fresh repo.
Required repository configuration (provision once):
| Kind | Name | Purpose |
| -------- | -------------------------- | --------------------------------------- |
| variable | `DOCS_BOT_APP_ID` | GitHub App that opens the generated PR |
| secret | `DOCS_BOT_APP_PRIVATE_KEY` | Private key for the same GitHub App |
| secret | `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL |
| secret | `AZURE_OPENAI_API_KEY` | Azure OpenAI key (or wire OIDC instead) |
The GitHub App needs `contents: write` and `pull-requests: write` on
this repo. Until those are provisioned the workflow will run but fail
at the "Generate GitHub App token" step — that's safe (it cannot
modify anything before that step).
### Triggering manually
From the GitHub UI: **Actions → docs-generate → Run workflow**. The
dispatch form mirrors the CLI flags:
- `dry-run` — analyse and render only, never write or open a PR.
- `packages` — comma-separated list to override change detection.
- `since` — git ref to diff against, overriding the watermark.
- `llm` — toggle the AI authoring (default on; off emits placeholder
documentation alongside the deterministic Reference).
- `max-packages` — per-run cap (default 25).
The workflow never advances the `docs-bot/last-run` watermark — there
is no scheduled run to protect against — so any dispatch is safely
idempotent against the operator's chosen `since` baseline.
### Resetting the watermark
The watermark is a lightweight git tag pointing at the SHA of the
commit a prior run was generated against. The workflow no longer
auto-advances it; operators advance, reset, or delete it by hand to
control the default diff baseline used when `since` is left blank:
```bash
# Inspect the current watermark.
git fetch origin --tags
git rev-parse refs/tags/docs-bot/last-run
# Force the watermark to a specific commit (e.g. force a full re-sweep).
git tag -f docs-bot/last-run <sha>
git push origin docs-bot/last-run --force
# Delete the watermark entirely (subsequent dispatches that omit
# `since` will fall back to "regenerate everything"; supply `since`
# explicitly to avoid that).
git tag -d docs-bot/last-run
git push origin :refs/tags/docs-bot/last-run
```
### First-run bootstrap
If the watermark tag does not exist, dispatches that leave `since`
blank have no diff baseline. Either tag a known-good SHA on `main`
manually, or use `workflow_dispatch` with `since: main` (or any other
ref) to seed.
### Cost expectations
Placeholder runs (`--llm` off) make zero LLM calls and are cheap
enough to run on every commit if needed. With `--llm` on, each
package costs roughly one `gpt-4`-class chat completion sized at
~6–10k input tokens (the documentation prompt forwards the
hand-written `README.md`, source samples, action list, and the
deterministic Reference) and ~1000–1500 output tokens, plus one retry
on validation failure. The default `--max-packages 25` cap bounds the
worst-case at ~50 calls per run.
### Opting a package out
Not yet implemented in v1. If a package should not be regenerated,
delete its `README.AUTOGEN.md` and add it to a future ignore list
when one is built. The hand-written `README.md` is never affected
either way. Explicit opt-out (`docs-autogen-opt-out: true` in
`package.json`) is tracked in the design doc.
## Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.microsoft/TypeAgent
Publicmirrored from https://github.com/microsoft/TypeAgentAvailable
ts/tools/docsAutogen/README.md
237lines · modepreview