Text Forge is a toolkit for working with long-form Markdown as a living text: a website, a book, an editable workspace, an AI-readable corpus, and a source model for agent memory and future meaning graphs.
It grew out of the whattodo / WTD approach — Жизнь как Текст (“Life as Text”): important thinking should remain plain, readable, public, versioned, and useful to both humans and agents. Markdown stays the roots. Everything else is a projection.
A meaningful text is not only a page to publish. It is also:
- a book to read offline;
- a website with stable public addresses;
- an editor for continuous work;
- a corpus for search, review, and AI feedback;
- a memory substrate for agents;
- a future graph of sections, concepts, references, aliases, and changes.
Text Forge keeps these roles connected through one source of truth:
plain Markdown + MkDocs navigation + Git history
↓
Text Forge source model
↓
website / EPUB / editor / AI-readable export
↓
inventory → memory projections → meaning graph projections
The key principle is: do not pollute the source text with infrastructure concerns. Keep Markdown readable. Put publication, memory, graph, and agent mechanics into generated layers.
The WTD approach treats life, work, product thinking, references, doubts, and decisions as a text that can be revised, linked, published, questioned, and remembered.
That creates a different kind of tooling requirement:
- chapters can be published or still in draft, but both may be useful for feedback;
- explicit anchors are public addresses for ideas, not just HTML implementation details;
- source history matters because meanings evolve;
- agents should cite sections, not vaguely “remember something”;
- future tools should map meanings without forcing technical IDs into the Markdown.
Text Forge is the infrastructure layer for that workflow.
Text Forge extends MkDocs Material with:
- theme overrides;
- custom partials and assets;
- source links;
- editor/download/header integrations;
- custom content blocks used by long-form text projects.
The same source can become an EPUB:
- chapters are combined from
mkdocs.ymlnavigation; - PyMdown syntax is normalized for Pandoc;
- assets are bundled;
- metadata can include Git-derived dates/versioning;
- output is compatible with normal e-readers.
The live editor supports:
- browser-based Markdown editing;
- real-time preview through Pyodide + PyMdown Extensions;
- local save during
mkdocs serve; - GitHub API commits in production;
- split-pane interface with synchronized scrolling;
- Russian translations.
Text Forge can generate AI-readable material:
- combined Markdown export;
- normalized anchors and links;
- privacy-first behavior: AI-readable export is opt-in.
The next layer is a deterministic inventory of the text:
Markdown files + mkdocs.yml + Git metadata
↓
chapters, sections, anchors, line ranges, URLs, draft/published status
This inventory is the common input for downstream tools. They should not reimplement MkDocs parsing.
Current building block:
scripts/wtd-inventory.py
Despite the name, it is the first implementation of a broader pattern: derive a stable source model from a MkDocs text project.
Text Forge also includes a public Hindsight adapter:
scripts/hindsight-ingest.py
It consumes inventory JSON and writes citable documents into Hindsight. This makes a text available to agents as structured memory while preserving public URLs, GitHub source links, chapter/section identity, and tags.
The public adapter is intentionally infrastructure-neutral. Private paths, hostnames, bank names, backups, and operational rituals belong in local Hermes skills or wrappers.
See:
docs/hindsight-memory.md— reference for the Hindsight projection shape;docs/hindsight-memory/SKILL.md— example Hermes skill workflow using Text Forge scripts.
Text Forge is not meant to become a monolith. It should be the reusable source-model layer.
┌────────────────────┐
│ plain Markdown text │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ MkDocs + Git roots │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ Text Forge model │
└─────────┬──────────┘
│
┌───────────────────┼────────────────────┐
│ │ │
┌───────▼────────┐ ┌───────▼────────┐ ┌────────▼─────────┐
│ Website / EPUB │ │ Agent memory │ │ Meaning graph │
│ Editor / AI md │ │ Hindsight etc. │ │ future layer │
└────────────────┘ └────────────────┘ └──────────────────┘
For WTD specifically:
WTD roots
= source Markdown, anchors, references, Git history
WTD Hindsight corpus
= agent-memory projection of those roots
WTD graph
= future meaning representation: concepts, mappings, aliases, splits, merges, evolution
The graph can eventually preserve anchor renames and section mappings without adding hidden metadata comments to the Markdown.
Text Forge distinguishes:
- published chapters — included in
mkdocs.ymlnavigation and released in the table of contents; - draft chapters — Markdown files under
docs_dirbut not in navigation yet.
Draft does not mean useless or private. A draft page may still have a stable preview/public URL and can be used for feedback, review, and memory. It is simply not part of the released table of contents.
Explicit heading anchors are treated as public addresses for ideas:
## Form of the Book {#book_form}A chapter with no anchored headings still has a chapter-level address:
https://example.org/chapter-slug/
This is enough for the source. More complex identity mapping belongs in a generated graph layer, not in the Markdown.
pip install sg-text-forge# .github/workflows/publish.yml
- uses: shared-goals/text-forge@main
with:
mkdocs_config: mkdocs.yml
docs_dir: text/ru
site_dir: public/ruAdd the plugin to mkdocs.yml:
plugins:
- text-forge:
editor_enabled: true
nobr_emoticons_enabled: true
downloads_enabled: false
ai_readable_enabled: false
epub_title: "My Book"
epub_author: "Author Name"Build EPUB:
text-forge epub --config=mkdocs.yml --build-dir=buildBuild complete site:
text-forge build --config=mkdocs.yml --build-dir=buildGenerate inventory:
python scripts/wtd-inventory.py --config mkdocs.yml --include-drafts --format jsonDry-run a Hindsight memory projection:
python scripts/wtd-inventory.py --config mkdocs.yml --include-drafts --format json \
| python scripts/hindsight-ingest.py \
--api-url http://localhost:8889 \
--bank hermes \
--strategy wtd-primary \
--dry-runBuild EPUB from a MkDocs project.
text-forge epub [OPTIONS]
Options:
--config PATH Path to mkdocs.yml (default: mkdocs.yml)
--build-dir PATH Build output directory (default: build)Build complete site: EPUB + MkDocs site.
text-forge build [OPTIONS]
Options:
--config PATH Path to mkdocs.yml (default: mkdocs.yml)
--build-dir PATH Build directory (default: build)
--site-dir PATH MkDocs output (default: from mkdocs.yml)
--strict/--no-strict Fail on warnings (default: true)
--copy-artifacts/--no-copy-artifacts
Copy EPUB to site root (default: true)
--create-404-redirect/--no-create-404-redirect
Create 404.html for /ru/* redirects (default: true)plugins:
- text-forge:
# Editor
editor_enabled: true
nobr_emoticons_enabled: true
# Downloads and AI-readable export
downloads_enabled: false
ai_readable_enabled: false
# EPUB metadata
epub_title: ""
epub_subtitle: ""
epub_author: ""
epub_identifier: ""
epub_publisher: ""
epub_rights: ""
# UI labels
source_file_published_title: "Published"
# Theme integration
auto_configure_theme: truetext-forge/
├── text_forge/ # Python package
│ ├── plugin.py # MkDocs plugin
│ ├── build.py # Build pipeline
│ ├── cli.py # CLI commands
│ └── obsidian/ # Obsidian-related templates/helpers
├── scripts/
│ ├── mkdocs-combine.py # Chapter combiner / AI-readable export helper
│ ├── mkdocs_common.py # Shared MkDocs helpers for scripts
│ ├── wtd-inventory.py # Source inventory generator
│ ├── hindsight-ingest.py # Public Hindsight adapter
│ ├── pymdown-pandoc.lua # Pandoc Lua filter
│ └── process-epub-meta.py # EPUB metadata processor
├── docs/
│ └── hindsight-memory/ # Example Hermes skill for memory projection
├── mkdocs/
│ ├── overrides/ # Material theme overrides
│ └── hooks/ # MkDocs hooks
├── epub/ # EPUB templates and styles
└── tests/ # Pytest tests
git clone https://github.com/shared-goals/text-forge.git
cd text-forge
make install
make testUseful commands:
make format # Format code with ruff
make lint # Run linters
make test # Run tests with pytest
make check-i18n # Validate translation keys
make release # Interactive release: bump version, tag, push- Python ≥ 3.11
- Pandoc, for EPUB generation
- MkDocs Material
- Git, for version/date/source metadata
MIT License — see LICENSE.
Contributions welcome. Please open issues or pull requests at github.com/shared-goals/text-forge.