Skip to main content

Incremental AI documentation system — Scriba + IA

Project description

ScribIA

ScribIA

Scriba + IA — the AI scribe that keeps your documentation in sync with your code.

License Python 3.11+ Claude Code skill Beta


Scribia is an incremental documentation system for AI-assisted development. When you run /scribia in Claude Code (or scribia run in your terminal), it detects what changed since the last run, extracts semantic entities (APIs, classes, models, config), updates only the impacted documentation sections, and optionally syncs a knowledge graph (Graphify) or LLM wiki.

It never regenerates everything from scratch. It never deletes existing content. It only patches what changed.


Why Scribia

Every AI-assisted workflow has the same problem: code evolves fast, documentation doesn't. Scribia sits between your git history and your docs directory. Run it when you're ready, get only the diff applied to your docs.

  • Manual only — you decide when to update. No background daemons, no hooks.
  • Incremental — compares to the last checkpoint, touches only affected sections.
  • Backend-agnostic — Markdown, Graphify, LLM Wiki, or your own plugin.
  • Claude Code skill — invoke with /scribia directly from your AI session.
  • Standalone CLI — works without Claude too: scribia run.

Installation

Requirements

  • Python 3.11+
  • git

Quick install

git clone https://github.com/marcolettieri/scribia.git
cd scribia
./install.sh

The installer will ask three questions:

  1. Primary documentation backend — Markdown (default), LLM Wiki, Graphify, or custom
  2. Knowledge backends — optional graph/wiki layers to run alongside the primary
  3. Confirms manual-only update mode

It then installs the Python package, creates scribia.yaml in your project, and links the Claude Code skill.

Manual install

pip install -e .

To use as a Claude Code skill:

ln -s "$(pwd)" ~/.claude/skills/scribia

Initialize in your project

Navigate to your project and run:

scribia init

This scaffolds the docs/ directory, creates .scribia/state.json with the current HEAD as checkpoint, and copies scribia.yaml from the template.


Usage

In Claude Code

/scribia                          # detect changes, update docs
/scribia init                     # scaffold docs/ + set initial checkpoint
/scribia --dry-run                # preview what would be documented
/scribia --force                  # reprocess even if already at HEAD
/scribia --from-commit abc1234    # override start commit
/scribia state show               # inspect last checkpoint
/scribia state reset              # move checkpoint to current HEAD
/scribia config                   # show effective configuration
/scribia backends                 # list available backends

In terminal

scribia run                       # same as /scribia
scribia run --dry-run
scribia run --from-commit abc1234
scribia init
scribia state show
scribia state reset
scribia config
scribia backends

How it works

git diff (from checkpoint → HEAD)
        │
        ▼
   Diff Engine          — identifies changed files, additions/deletions
        │
        ▼
 Semantic Analyzer      — extracts APIs, classes, models, config entries
        │                  filters formatting noise
        ▼
Documentation Updater   — writes only impacted sections using safe markers
        │                  never deletes, never overwrites unmanaged content
        ▼
  Backend Plugin(s)     — Markdown / Graphify / LLM Wiki / custom
        │
        ▼
 Checkpoint saved       — .scribia/state.json updated to current HEAD

Safe write contract

Every managed section is bounded by HTML comments:

<!-- scribia:start:api-my_module -->
| Name | Type | Change | File |
| ... |
<!-- scribia:end:api-my_module -->

Content outside markers is never touched.

Checkpoint

State is stored in .scribia/state.json:

{
  "last_commit": "abc1234...",
  "last_run": "2026-06-01T10:30:00Z",
  "last_summary": "12 files, 8 entities",
  "backend_config": { "backends": ["markdown"] },
  "run_count": 7
}

Configuration

scribia.yaml in your project root (or ~/.scribia.yaml for user-global defaults):

# Primary documentation backend
# Built-ins: markdown | graphify | llm_wiki | custom (plugins/)
backend: markdown

# Additional knowledge backends (run after primary)
# knowledge_backends:
#   - llm_wiki
#   - graphify

# Where to write docs
docs_dir: docs
changelog: CHANGELOG.md

# Output language (auto = detect from CLAUDE.md or system locale)
language: auto

# Files to ignore during diff analysis
exclude_patterns:
  - "test_*"
  - "*.test.ts"
  - "migrations/*"

# Graphify backend options
graphify:
  flags: "--update --wiki --no-viz"
  target_path: "."

# LLM Wiki backend options
llm_wiki:
  output_dir: wiki

Backends

Markdown (default)

No dependencies. Writes plain .md files:

docs/
  index.md
  api/<module>.md
  features/
  architecture/data-models.md
  configuration.md
CHANGELOG.md

Graphify

Triggers a /graphify . --update --wiki run after documentation is updated. Requires the graphify Claude Code skill. When used via /scribia in Claude Code, Scribia invokes graphify automatically. In CLI mode it prints the command to run manually.

LLM Wiki

Writes per-module structured summaries to wiki/ — optimized for LLM context retrieval. Each file is a flat, machine-readable summary of what exists in that module and what changed.

Custom backend

  1. Copy templates/custom_backend.py.template to plugins/my_backend.py
  2. Set name = "my_backend" on the class
  3. Implement init(), update(), persist()
  4. Set backend: my_backend in scribia.yaml

No core code changes required. The plugin is loaded dynamically at runtime.

from scribia.backends.base import BackendPlugin
from scribia.engine.models import ChangeSet

class MyBackend(BackendPlugin):
    name = "my_backend"

    def init(self, config: dict) -> None: ...
    def update(self, changeset: ChangeSet) -> list[str]: ...
    def persist(self) -> None: ...

Docs structure generated

After first run on a typical Python project:

docs/
  index.md                     # navigation index
  api/
    my_module.md               # per-module API table
    service.md
  architecture/
    data-models.md             # data model registry
  configuration.md             # config reference
CHANGELOG.md                   # prepend-only changelog
wiki/                          # only if llm_wiki backend enabled
  index.md
  my_module.md

Project structure

scribia/
├── SKILL.md                   # Claude Code skill (/scribia)
├── scribia.yaml.example       # configuration template
├── install.sh                 # interactive installer
├── pyproject.toml
├── plugins/                   # custom backend plugins go here
│   └── example_custom_backend.py
├── templates/
│   └── custom_backend.py.template
└── src/
    └── scribia/
        ├── cli.py             # CLI entry point
        ├── config.py          # configuration loader
        ├── engine/
        │   ├── models.py      # ChangeSet, FileChange, SemanticEntity
        │   ├── diff.py        # git diff engine
        │   └── analyzer.py    # semantic entity extraction
        ├── updater/
        │   └── safe_write.py  # section-aware file writer
        ├── backends/
        │   ├── base.py        # BackendPlugin ABC
        │   ├── loader.py      # dynamic backend loader
        │   ├── markdown.py    # Markdown backend
        │   ├── graphify.py    # Graphify backend
        │   └── llm_wiki.py    # LLM Wiki backend
        └── state/
            └── manager.py     # .scribia/state.json checkpoint

Contributing

Contributions welcome. The cleanest way to extend Scribia is to write a new backend plugin — see templates/custom_backend.py.template. If your backend is general enough to be useful to others, open a PR to add it to src/scribia/backends/.


License

MIT with Attribution Requirement — free for personal use, attribution required for organizational or commercial use. See LICENSE for the full terms.

© 2026 M. Lettieri

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scribia-0.1.0.tar.gz (26.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scribia-0.1.0-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file scribia-0.1.0.tar.gz.

File metadata

  • Download URL: scribia-0.1.0.tar.gz
  • Upload date:
  • Size: 26.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scribia-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7af66293a99678f8d9f6c0b880a5a173e9e3e376a58bd7736735610a66159aad
MD5 f57c8811c70b248db8ade9c95705dadd
BLAKE2b-256 044c215d089776c215cf8490c3cdd6f3ca7fccea727e808dce1b4100ae59d155

See more details on using hashes here.

Provenance

The following attestation bundles were made for scribia-0.1.0.tar.gz:

Publisher: publish.yml on marcolettieri/scribIA

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scribia-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: scribia-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scribia-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 da020672d54c35a75045f930b5d9e9541856aa7eb432c54a44dbf56de2b6b15a
MD5 62675d5231563e3aabcc65296fa8d541
BLAKE2b-256 782cdd060dd74ef6a3e8b86a2b8c425cd6d1d86c9843451eddaa9403bfeb283f

See more details on using hashes here.

Provenance

The following attestation bundles were made for scribia-0.1.0-py3-none-any.whl:

Publisher: publish.yml on marcolettieri/scribIA

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page