Dependency tracking for prose
Depend on whole files or slices by line range, regex markers, or heading. Know which input changed.
mdship tracks the sources behind every AI-written and generated section of your Markdown. When the code changes, it tells you what to regenerate, and leaves everything else alone.
$ mdship ai-list docs/api.md
[{"name": "api-summary", "line": 3, "status": "up_to_date"}]
$ $EDITOR src/api.py # add farewell()
$ mdship ai-check docs/api.md
Error: docs/api.md: AI placeholder 'api-summary': dep ../src/api.py has changed since last generation
$ mdship ai-list docs/api.md
[{"name": "api-summary", "line": 3, "status": "needs_update"}]
$
The code changes. The paragraph that describes it does not. Nothing tells you which paragraph is now wrong, so you either regenerate everything, rewriting text that was fine, or you ship docs that lie.
`greet(name)` returns a friendly greeting…
…and there is nothing else in the module.
silently wrong since last TuesdayEvery generated section declares its inputs: the prompt, the source files or slices it depends on, and a shared writing brief. mdship checksums all of them, so staleness is a fact you can check, not a feeling.
Three steps, and the loop runs itself from then on.
An AI placeholder names its prompt and the sources it depends on.
<!--AI name: "api-summary" prompt: | Summarize the public functions. deps: - path: ../src/api.py --> <!--/AI-->
ai_context says whether anything relevant changed and, only if something did, hands the agent exactly the source slices, previous text, and brief. ai_update installs the result and records every checksum.
# in Claude Code
/ai-placeholder docs/api.md
Change a source file and ai-check fails with the precise reason. Regenerate only what is stale.
Error: docs/api.md:
AI placeholder 'api-summary':
dep ../src/api.py has changed
since last generation
Depend on whole files or slices by line range, regex markers, or heading. Know which input changed.
ai_context answers "does anything need regenerating?" before a single token is spent on writing.
Generated regions carry a checksum. Edit one by hand and mdship update stops instead of overwriting your work.
get_section, replace_section, list_headings and friends: agents change the part they need, not the whole file.
INCLUDE code, generate a TOC, load variables from JSON/YAML/TOML, render Jinja2 and Mermaid, run project scripts.
All control lives in HTML comments. GitHub and every renderer show clean, ordinary Markdown.
mdship detects problems; it doesn't prevent them. Checksums are compared when a check runs, so put the check where it can't be skipped:
ai-listjobs: docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: verhas/mdship@v1 with: command: ai-check files: README.md docs/**/*.md
Each one is protected by the same checksum model.
Install, run mdship init, add one placeholder, and let ai-check tell you the moment it goes stale.