Skip to content

Repository files navigation

fragmt

npm CI License: MIT Node

Notion-style editing over the plain markdown already in your git repo.

Your repo is the storage. Docs stay ordinary markdown – readable on GitHub, diffable, reviewable through PRs, and directly usable by AI coding agents. Every save is a git commit under your own identity. Delete fragmt tomorrow and you still have a folder of markdown and its full history.

fragmt editing a markdown document

npx fragmt init     # inside any git clone containing markdown
npx fragmt serve    # opens the editor

Requires Node 22+.


Why

Documentation tools make you choose between a good editor and owning your content.

Notion and Confluence give you the editor and keep the content in their database – export is lossy, history lives in their pane instead of your toolchain, and your coding agent can't read any of it without an API integration. Plain markdown in git gives you ownership, review and agent-readability, but the editing experience is a text editor.

fragmt refuses the trade.

Notion / Confluence Markdown + text editor fragmt
Storage vendor database your repo your repo
Editing WYSIWYG text editor WYSIWYG
Diff and review their version history git diff / PRs git diff / PRs
Agent-readable via API yes yes, first-class
Cost at 5 seats per seat, monthly free free
Self-host seat limit capped or licensed – none

What it is not: an open-source Notion clone – only the editing UX is Notion-style – and not a CMS. The emphasis is documentation. Nearest relative is Wiki.js, differentiated by being agentic-ready from the ground up: the agent surface is the CLI itself, riding the same core library as the UI.

What you get

  • Notion-style WYSIWYG over plain markdown. Selection and right-click bubbles for headings, quotes, links and tables; a / menu for blocks and images. No markdown knowledge required.
  • Save is a commit. Frontmatter preserved byte-for-byte, a stale-base-hash guard against concurrent edits, and your real git identity on every commit.
  • Main is protected, whether the branch actually is or not. Editing a doc on main starts a draft branch automatically; a global Merge button lands it.
  • Merge conflicts resolve in the tool – per-hunk ours/theirs or a free-edit box, structural merging for comment sidecars, one concluding commit.
  • Draft changes are visible – on a draft branch, an amber bar marks every block the draft's commits touched, computed from git diff against main.
  • Inline comments anchored to text as marks in the markdown itself, threads versioned in JSON sidecars. No comment backend.
  • Ctrl/Cmd+K search across titles and bodies, and a side-by-side preview pane for reading one doc against another.
  • Full file lifecycle – create, rename, move, delete, drag and drop, a recycle bin, .gitignore respected, @ references between docs.
  • Agents are first-class users – see Agents.

Install

npx fragmt init      # scaffold: writes .fragmt.json, adopts existing markdown
npx fragmt serve     # start the editor, prints the URL

Or globally: npm i -g fragmt, then fragmt init and fragmt serve.

init must run inside a git clone. It never overwrites an existing config – a second run prints already initialized and exits 0. Scope it to a subfolder with fragmt init --root docs. Or give the docs a repo of their own, nested inside a code repo – see Docs in a code repo.

Platforms: tested on Windows. Linux and macOS verification is in progress – reports from those platforms are welcome.

Docs in a code repo

When the docs belong to a code repository, mixing docs commits into code history gets old fast: separate PRs, tangled diffs, agents wading through it all. fragmt can give the docs folder a git repo of its own, nested inside the working tree:

fragmt init --folder docs --new   # docs/ becomes its own git repo
fragmt serve                      # run from docs/ – the outer repo is untouched

The folder is created if missing, and markdown already sitting there rides the nested repo's initial commit – the outer repo's own history is left alone. After creation, init offers to wire up an origin: paste a fresh GitHub or GitLab URL and fragmt pushes the docs repo and stages it as a submodule in the outer repo, so the host renders docs/ as a linked folder and teammates get everything with git clone --recursive. Skip the prompt and fragmt writes a .gitignore entry instead and prints the exact commands for later – a re-run of init offers the wiring again.

An AGENTS.md lands at both roots: the outer one tells coding agents the docs live in the nested repo; the inner one carries the usual fragmt rules. Running serve or agent from the outer root simply points you at the folder.

OKF mode

fragmt can maintain the doc bundle as an open-knowledge-format (OKF v0.2) knowledge base: typed concept docs, a generated index.md per directory, and the doc-to-doc reference graph kept as derived frontmatter. Docs stay plain markdown – OKF is a file convention any tooling (and any agent) can read directly.

fragmt init --okf      # enable on a fresh OR existing repo
fragmt validate        # print conformance findings, one per line
fragmt validate --fix  # apply the mechanical repairs in one commit

init --okf adopts, never rewrites: existing files are validated and the findings printed, the index.md set and the reference fields are committed, and validate --fix finishes adoption in a single pass. It composes with --folder --new for a nested docs repo.

In OKF mode fragmt maintains:

  • Conformant defaults – new docs are born with a type: concept and status: draft frontmatter block; any non-empty type is conformant.
  • Generated index.md – per directory holding docs: concepts grouped under # <Type> sections with absolute links, subdirectory entries linking the subdirectory's own index.md; regenerated on membership changes (create, move, rename, delete, merge) – never on content saves.
  • references / referenced-by – frontmatter fields derived from body links, recomputed on every save. Body links stay canonical; the fields are a cache.
  • Trust stamping – every save rewrites generated: { by, at }: by is the committing identity as human:<email-local-part>, or an agent's self-declared --as-actor string (default fragmt-agent/unspecified – a machine never claims a human's review). verified is an append-only event log with four affordances, each appending { by, at } in the same commit as its act: resolving a comment thread, the doc head's Verify button, Save as Verified beside Save, and fragmt agent verify <doc> (its --as-actor defaulting to the same self-declared string).
  • Trust badges – derived, never stored: doc cards and the doc head show the §5.3 tier (unverified / machine-confirmed / human-reviewed) from the verified actors, and a stale chip once now >= stale_after. An absent status renders nothing – stable is silence, never implied. The Verify button shows its already-mine state (Verified, from the server-derived verifiedByYou) while staying clickable – events are append-only.
  • Unified metadata editing – a collapsible metadata block between the doc head and the content shows every key: value (collapsed by default). The one Edit button edits content AND metadata together; the one Save commits both in a single commit through field splices (never re-serialized YAML, unknown keys byte-preserved). Beyond the curated fields (type, description, tags, status, stale_after) any §4.1 extension key is editable and new keys can be added – several per save. status is enum-only – draft / stable / deprecated, enforced at the API seam; the UI's select is convenience.
  • References pane – the right pane's References mode lists the open doc's outgoing and incoming references; a row opens the target in the pane's preview split beside the current doc (the side-by-side default), with open-in-main one click away in the preview head.
  • Reference graph – a full-pane view of the whole bundle's link graph: one node per doc, an edge per body link, node color the §5.3 trust tier, a dashed ring when stale, isolated docs kept visible. Hover shows the detail, click opens the doc through the same unsaved-changes guard as every navigation. Derived fresh from body links on every open – never the frontmatter cache – and nothing about it is stored.
  • Export – the graph as Mermaid (renders on GitHub), Graphviz DOT, or JSON, and the docs working tree as a plain zip for sharing outside git: fragmt export [--format mermaid|dot|json] [--out <file>], or fragmt export --bundle. The graph view's toolbar carries the same set as copy/download buttons.
  • Reserved names – index.md and log.md never hold concepts; creates and renames targeting them are refused, and the UI keeps them read-only (their metadata area explains why, per §3.1).

validate --fix prepends missing frontmatter, adds missing types and status: draft, repopulates the derived fields, and regenerates the index.md set (adopted bundles self-heal their link shapes) – all in one commit, existing YAML never re-serialized. While non-conformant docs remain, the sidebar shows a banner listing them by path and clause.

CLI

fragmt init [--root <path>] [--folder <name>] [--new] [--okf]
fragmt serve [--port <n>] [--auth]
fragmt validate [--fix]
fragmt export [--format mermaid|dot|json] [--out <file>] [--bundle]
fragmt agent [status]
fragmt agent comment <doc> [--thread <id>] [--body <text>] [--resolve] [--author <who>] [--as-actor "<producer>/<version>"] [--full]
fragmt agent draft <doc> [--merge] [--as-actor "<producer>/<version>"]
fragmt agent verify <doc> [--as-actor "<producer>/<version>"] [--author <who>]
fragmt --help

serve --auth turns the editor into a small multi-user server: GitHub sign-in, your repo's collaborator permissions as access control, Docker samples included – see HOSTING. Commit authors are recognized by their GitHub avatar – automatically for signed-in users, and via a two-line authors map in .fragmt.json for everyone else.

Pull requests

With serve --auth, pull requests are part of the editor: draft branches push and open PRs as the signed-in user – the review, merge and sync ride that user's own GitHub token, never the operator's credentials.

  • The branch menu carries a PR chip per draft branch; the review lives in the slideout's Pull requests mode – the open list, paged diffs (20 files per page), and Merge with your own token. A conflicted PR states it and links out to GitHub.
  • Sync mirrors every branch to origin (never force), so no work lives only on the local disk – plain serve keeps pushing with machine credentials.
  • Branch delete is gated on merged: an unmerged branch can't be deleted from the menu.
  • None of this exists in local mode – a solo operator wanting PRs runs serve --auth.

Agents

AI coding agents are first-class users, and the contract is the fragmt agent CLI – token-lean output, aggregates inline, next-step hints, exit codes 0/1/2, no interactive prompts.

Verb What it does
fragmt agent status Branch, protected-main mark, draft map, merge state
fragmt agent comment docs/x.md List threads; --thread <id> for detail, --full for untruncated bodies
fragmt agent comment docs/x.md --thread <id> --body "…" Reply on a thread (one commit)
fragmt agent comment docs/x.md --thread <id> --resolve Resolve a thread
fragmt agent draft docs/x.md Start or reuse the doc's draft branch
fragmt agent draft docs/x.md --merge Merge the draft into main
fragmt agent verify docs/x.md Append a verified event to the doc in its own commit

Doc bodies are plain markdown, so agents read and diff them directly; the CLI matters for drafts, comments and merge state. Mutations accept --author (Name <address>) so an agent's commits carry its own identity – list the name under agents in .fragmt.json and the UI marks its comments with a chip. In OKF mode, agents also self-declare the generated stamp's actor with --as-actor "<producer>/<version>" (default fragmt-agent/unspecified) – verbatim, never a false human: claim. draft --merge stamps the doc on the draft branch before merging; comment --resolve appends the actor's verified event beside the sidecar write; verify appends it standalone – the UI's Verify button without the HTTP detour.

fragmt init also writes a delimited <!-- fragmt:begin -->…<!-- fragmt:end --> block into AGENTS.md, teaching any agent the drafting rules; with --okf the block additionally teaches the OKF rules – the conformance contract, the reserved and generated files, which fields fragmt owns, and the verify/validate loop. Nothing outside the markers is touched.

On Windows with git's default core.autocrlf, every content commit prints warning: … LF will be replaced by CRLF the next time Git touches it. That is git's working-copy layer talking, not a fragmt problem: fragmt stores doc bodies as LF and canonicalizes them on every read and write, so the warning never reflects a change to the repository. It is noise – no action is needed. If the noise bothers you, git config core.autocrlf (user level) is the knob; fragmt adds no .gitattributes of its own.

Configuration

.fragmt.json at the repo root is the whole configuration surface:

{
  "docsRoot": ".",
  "order": {},
  "authors": { "you@example.com": "YourGitHubUsername" },
  "agents": ["ZCode"]
}
Key Meaning
docsRoot Path, relative to the repo root, that fragmt treats as the doc tree. "." is the whole repo.
order Reserved for explicit doc ordering (v1.x). Always {} for now.
authors Optional map of commit emails to GitHub usernames, for avatars.
agents Optional list of agent display names; their comments get an agent chip.
okf Optional. true maintains the bundle as OKF – set by fragmt init --okf. Absent means legacy behavior.

Parsing is strict – a malformed config fails loudly with the file path rather than falling back to a silent default.

Status

Beta. The full v1 feature set works. What stands between this and 1.0 is dogfood hardening – a long-running effort that closes when it closes, not on a schedule.

Documentation

Reference docs live in docs/: architecture and design principles.

The design decisions, the build log and the wrong turns – including why Tiptap won the editor spike and what was deliberately cut from v1 – are written up at migatchev.co.za/projects/fragmt.

Contributing

See CONTRIBUTING.md. Scope is deliberately tight, so open an issue before a large PR. The most useful contribution right now is dogfooding and issue reports – especially on Linux and macOS.

Built with TypeScript, Node 22, Hono, React 19 + Vite, Tiptap 3, and a thin execFile wrapper around system git.

License

MIT – see LICENSE. Copyright © 2026 Andrei Migatchev and contributors.

About

An open-source, git-native documentation environment for small dev teams, start-ups, and solo developers.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages