All projects

DOLLY

How you build software, saved as a pattern

Extract the shape of a project, then scaffold, check and migrate other projects to it

Role Author. Designed and built it end to end: the pattern format, the deterministic extractor, the CLI, the local daemon, the GUI and the native shell.
Period Jul 2026 –
Outcome Released: v0.1.1 on GitHub, npm and Homebrew, with desktop installers.
Stack
  • TypeScript
  • Bun
  • Vue 3
  • Tauri
  • CodeMirror
  • Playwright
  • Biome
Open source · MIT · v0.1.1 GitHub

Context

Every project I start carries the same decisions as the last one: where files go, how they’re named, which linter and formatter, which test runner, how commits are written. None of that lives anywhere you can point at. It lives in the last repo you built, and it drifts. dolly is my answer, built outside work from July 2026. It’s a local-first tool that reads a real project and writes those decisions down as a pattern: a directory with one pattern.md (YAML facets for what a machine can enforce, Markdown prose for what only a person can) plus the config files and templates it captured. Then it applies the pattern anywhere. Named after Dolly the sheep: you clone how you build software.

My role

It’s mine end to end, and it’s released: v0.1.1 ships as one binary per platform with the GUI embedded, as the dollysheep package on npm, through a Homebrew tap and as desktop installers. The engine is a TypeScript library on Bun with a thin CLI over it. dolly extract infers a pattern from a repo with no annotations. dolly new scaffolds a fresh project from it. dolly check enforces it like a linter, with safe autofixes, a watch mode and a .dolly marker that ties a repo to its pattern, so it drops into CI and pre-commit as it is. dolly fit migrates an existing project. dolly export writes the pattern as a .dolly bundle or as the file a coding agent expects (CLAUDE.md, AGENTS.md, Cursor rules and a few more).

Around the engine there’s a local daemon, a Vue 3 GUI that reaches everything the CLI does, and a Tauri shell that spawns the compiled daemon as its sidecar. The AI layer is optional and bring-your-own-key: with it on, dolly suggests where an ambiguous file goes, translates files into the language the pattern sanctions, and drafts pattern edits from watching a project change. Everything deterministic works with it off.

  1. 01 An existing project no annotations needed
  2. 02 extract one tree walk feeds five deterministic scanners
    • a facet only when the evidence clears the bar
    • a counted note, never a guess, when it doesn’t
    • the same bytes give the same pattern on any OS
  3. 03 pattern.md the portable pattern, a directory you can read
    • YAML facets: naming, layout, toolchain, dependencies, commands, testing, license
    • prose conventions in Markdown
    • the configs and templates it captured
  4. 04 Apply it three verbs over one pattern
    • new scaffold a fresh project
    • check enforce like a linter: safe fixes, watch mode, CI
    • fit migrate: dry-run plan first, checkpoint branch, never half-applied
  5. 05 export share it, or hand it to a coding agent
    • .dolly bundle
    • CLAUDE.md
    • AGENTS.md
    • Cursor
    • Copilot
    • Gemini
AI layer, optional, bring your own key file placement, translation, learning from a project as it changes; everything deterministic works with it off
dolly serve a local daemon, the Vue 3 GUI that reaches everything the CLI does, and a Tauri shell that runs the daemon as its sidecar
From one real project to a pattern, and from the pattern to three ways of applying it: scaffold a new project, keep an existing one in line, or migrate it. Exports and the optional AI layer sit beside the engine; the GUI reaches all of it through a local daemon. All of it is mine.

The hard part

Extraction that never guesses. A wrong facet is worse than no facet, because check would then fail a project for something it never agreed to. So every scanner has explicit evidence classes, and a finding lands in exactly one of three places: a facet, when the evidence clears the bar; a counted prose note (“4 of 6 directories under src/ contain routes.ts; add it to layout if intentional”), when it doesn’t; or silence. One shared tree walk feeds all five scanners, so every facet in a pattern rests on the same evidence, and the same bytes produce a byte-identical pattern on any OS. Captured configs bind as subsets by default: your project can extend a config without dolly bleating.

Fit. Migrating a live repo is where a tool like this does damage. Fit is a dry run by default: it prints the whole plan, down to the unified diff of every file it would create or merge and every relative import a move would rewrite. --apply refuses a dirty tree, records a checkpoint branch so git switch is the undo, and commits the result. A move it can’t fully account for is declined with its reason, never half-applied.

Then shipping it whole: a single binary with the GUI embedded, installers for the three platforms out of one release workflow, API keys in the OS keychain (sealed with DPAPI on Windows), and Playwright walking every GUI view in CI.

One more, off the roadmap. In August the machine that held the repo was wiped, and the repo had never been pushed. I rebuilt it from the logs of the sessions that had built it: every file write and edit replayed in order, the shell commands that changed text re-run in a sandbox, each file reconciled against the fragments the logs had printed, and the whole gate (lint, types, build, tests) run again at the end. It came back green.

The GUI served by the local daemon: a pattern's page, with the facets extracted from this very repo, and a check report against it (two fixable violations, nothing guessed).The GUI served by the local daemon: a pattern's page, with the facets extracted from this very repo, and a check report against it (two fixable violations, nothing guessed).
The GUI served by the local daemon: a pattern's page, with the facets extracted from this very repo, and a check report against it (two fixable violations, nothing guessed).

Outcome

Released in September 2026 under MIT: v0.1.1 on GitHub, npm and Homebrew, over 300 tests plus end-to-end GUI tests, and installers built by the release workflow. It’s the tool I now start my own projects with. The repo is linked above.