Shared modules
A feature earns a module by being needed twice.
Everything else stays inside the app that needed it. These five came out because they kept reappearing — and once something is here, the next tool starts closer to done.
ai-object
28
consumers
The substrate behind every studio: an AI edits a structured object through tool calls instead of regenerating it.
Written once for Doc Studio. By the third app it was obvious the object type was the only thing changing — the block model, the planner and the chat surface were identical every time. It now carries fifteen apps, and a Python twin held to identical output by parity vectors — the planner has no randomness in it, so the two propose the same edits for the same sentence or a test goes red.
What ships
- block model
- deterministic mock planner (intent → edit ops)
- chat + edit-event UI
- pure exporters
Used by
- Agent Runbook
- AI Feed
- API Mock Studio
- Bookmark Digest
- Changelog
- Contract Studio
- CRM
- CV Studio
- Deck Studio
- Diagram Studio
- Doc Studio
- Email Studio
- Form Studio
- Recipe Studio
- Table Studio
- Doc Studio · Flask
- Deck Studio · Flask
- Doc Studio · Django
- CV Studio · Flask
- Agent Runbook · Flask
- API Mock Studio · Flask
- Bookmark Digest · Flask
- Contract Studio · Flask
- Form Studio · Flask
- Email Studio · Flask
- Recipe Studio · Flask
- Diagram Studio · Flask
- Table Studio · Flask
crm
01
consumer
Contacts, pipeline and activity — headless, embeddable, or standalone.
Started as an app. Turned out every tool that touches people wants the same pipeline and activity feed, so the app became a thin wrapper around a module anyone can mount.
What ships
- Convex schema factory
- pure pipeline & rollup logic
- props-driven React UI kit
- MCP tool descriptors
Used by
changelog
01
consumer
Changelog and roadmap as a public status page that also embeds anywhere.
Every app eventually needs a 'what's new'. Building it per app was the obvious waste — this runs standalone and drops in as a widget.
What ships
- Convex schema factory
- grouping & semver logic
- changelog feed, roadmap board, embeddable widget
- MCP tool descriptors
Used by
lab-languages
15
consumers
One language registry for every surface that answers in a language — real languages, and fictional ones only a fake AI can offer.
It was extracted the moment three places had grown their own trimmed copies of the same table: the faker, the Convex AI engine and the Python port. That is the exact shape of a drift bug waiting to happen. The data lives here now; everything else reads from it, and the one copy that genuinely cannot import it — the dependency-free Convex engine — is held to the registry by a test that names the missing language.
What ships
- 13 real languages, including RTL Arabic and unspaced Japanese
- 9 fictional: Klingon, Elvish, Dothraki, Pirate, Minionese, Simlish, Orcish, Machine, Lorem
- per-language typography — joining, terminators, capitalisation, direction
- forgiving resolution: codes, BCP-47 tags, names, endonyms, Accept-Language
- generators that emit the Python data and its parity vectors
Used by
studio-core
13
consumers
An AI object studio, minus the web framework — vocabulary, block store and the AI turn.
Doc Studio was written first, at eight hundred lines, then reduced to forty-three by extracting the generic half. That extraction was a Flask package — and the split between what a studio *is* and how it is *served* was sitting inside it unmarked: three modules with no framework imports, next to three with them. Making that a package boundary is what let a Django studio be an adapter rather than a second implementation.
What ships
- StudioSpec — the vocabulary that is the only thing a studio changes
- SQLite block store with float ordering and subtree deletes
- the AI turn: plan → resolve generation requests → apply → record
- no web framework, and no provider — offline and deterministic
Used by
flask-studio
12
consumers
The Flask adapter for studio-core — blueprints and Jinja templates.
Contributes request handling and templates, and nothing else. Everything it serves comes from studio-core — twelve studios now run on it, each one a vocabulary of thirty-eight to forty-three lines.
What ships
- blueprint factories for the API and the editor
- Jinja templates driven by the spec
Used by
django-studio
01
consumer
The Django adapter for studio-core — views, URLconf and templates.
The second adapter, and the reason the core can be called framework-free rather than merely untested elsewhere. Flask and Django disagree about request objects, routing, CSRF and templating; nothing in the core needed a special case for either. Seven tests run both adapters against the same request and assert the responses are identical — if they ever diverge, one of them has grown logic that belongs in the core.
What ships
- view and URLconf factories, bound to a spec and store
- Django templates — the same design, in Django's syntax
- CSRF-exempt API with a test that the exemption holds
Used by
phantom-core
16
consumers
Faker for AI responses — deterministic, provider-shaped fakes across models and modalities.
Every app in the lab needs fake AI responses; none of them should own the faking. It ships twice — TypeScript and Python — and the two are held byte-identical for a given seed by parity vectors, so "the same faker in two languages" is a checked claim rather than a hopeful one.
What ships
- provider response shapes
- seeded determinism
- modality coverage
- latency & cost modelling
Used by
- Phantom
- Phantom · Flask
- Phantom · Django
- Doc Studio · Flask
- Deck Studio · Flask
- Doc Studio · Django
- CV Studio · Flask
- Agent Runbook · Flask
- API Mock Studio · Flask
- Bookmark Digest · Flask
- Contract Studio · Flask
- Form Studio · Flask
- Email Studio · Flask
- Recipe Studio · Flask
- Diagram Studio · Flask
- Table Studio · Flask
phantom
00
consumers
Remote client and drop-in provider shims over phantom-core.
Splitting the client from the core meant the same fakes work offline locally and behind an HTTP API remotely, without the apps knowing which.
What ships
- provider shims
- remote HTTP client
- offline fallback
Not yet shared
17 tools own all of their machinery. That is not a backlog — most of them are the only thing that will ever need it. A few are candidates: Media Manager keeps rebuilding the same library screen the media tools want, and it should probably graduate next.