Skip to main content
metalworks saves your work. Run research once, and every later step — positioning, the design system, the build spec, launch copy — reads from that same saved report instead of re-running research. It all lives in a .metalworks/ folder in your project, created the same way git init creates .git. This is what lets the CLI and the Claude Code plugin work in steps: one command produces a report, the next takes its report_id and builds on it.

It’s opt-in — zero footprint until you ask

metalworks writes nothing to disk unless you create a project. A one-off mw.research(...) or metalworks research run with no project keeps everything in memory and leaves no trace — exactly like running git status outside a repo. Create the memory when you want it to stick:
That makes .metalworks/ in the current directory. From then on, runs persist and commands chain. (In Python, the facade auto-detects a project by walking up from the working directory, just like git finds .git.)

What’s inside .metalworks/

metalworks init writes a .gitignore inside .metalworks/ that excludes corpus.db for you, so committing the directory captures your research and outputs without the bulky, re-buildable cache.

How commands chain

Every run mints a report_id. List your runs to find it, then pass it to any later command:
Re-running research mints a new report_id and a new runs/<id>/ directory — your history is the set of run directories plus git, nothing is overwritten. Later-stage artifacts record the report_id they were built from, so a stale positioning brief is detectable by comparing its stamp to your latest run. You can also update a report instead of starting fresh: metalworks research refresh <report_id> re-runs it against everything you’ve collected since and shows what changed, saved as a new version. metalworks research versions <report_id> lists every version; older ones are kept exactly as they were. See your research data. In Python the chaining is implicit — you hold the bundle and pass it along — but the same persistence happens underneath when a project exists:

Where memory lives when there’s no project

The CLI also keeps a global store at ~/.metalworks/ for runs you make outside any project, and that’s where the Reddit post-log.jsonl audit trail and any connected-account tokens (encrypted at rest) live.

Under the hood: the stores

The corpus database is backed by a set of typed repositories — CorpusRepo (source-neutral records, comments, embeddings), RunRepo (runs + finished reports), OpportunityRepo, InboxRepo, AccountRepo, BriefRepo. Two backends ship in core: MemoryStores (the zero-footprint default) and SqliteStores (the project file). They’re protocols, so you can point metalworks at a hosted backend (Postgres/PostgREST) — see Bring your own store.

See also