latch is a CLI for literate patches: Markdown documents that carry
patch intent in prose and executable diffs in fenced code blocks. A
Latch document is a literate patch.
latch draft turns a diff into a first-pass Latch document. The draft
keeps the full diff inline, assigns deterministic patch ids, and emits
instructions for an LLM or human editor to turn the mechanical output
into a coherent patch narrative.
That document is meant to be both readable and runnable. After the
human pass, latch apply reads the executable diff fences and
materializes the patch onto a target tree.
latch skill prints the checked-in Agent skill for turning code changes
into a Latch narrative.
# Add `--json` output to `todo list`
## Tree
```text
.
├── src
│ └── cli.zig +6 -1
└── test
└── cli_test.zig +6 -0
```
2 files changed, 12 insertions(+), 1 deletion(-)
## Behavior
`todo list --json` should produce a stable machine-readable format for
scripts and tooling. The first patch makes that contract explicit.
```diff id=8f31ac44 depends-on=2d4e91b0
diff --git a/test/cli_test.zig b/test/cli_test.zig
--- a/test/cli_test.zig
+++ b/test/cli_test.zig
@@ -21,6 +21,12 @@ test "todo list prints one item per line" {
try expectEqualStrings("buy milk\\ncall mom\\n", output);
}
+
+test "todo list --json emits a JSON array" {
+ const output = try runCli(.{ "todo", "list", "--json" });
+ try expectEqualStrings("[\"buy milk\",\"call mom\"]\\n", output);
+}
```
## Implementation
The implementation then parses the flag and switches the renderer.
```diff id=2d4e91b0
diff --git a/src/cli.zig b/src/cli.zig
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -48,10 +48,16 @@ pub fn runListCommand(args: []const []const u8) !void {
+ const json = std.mem.indexOfScalar([]const u8, args, "--json") != null;
+
const todos = try loadTodos();
- try renderList(todos);
+ if (json) {
+ try renderListJson(todos);
+ } else {
+ try renderList(todos);
+ }
}
```Draft a Latch document from the current worktree diff:
latch draft -o change.latch.mdDraft from a specific commit or range:
latch draft HEAD~1 -o change.latch.md
latch draft main..HEAD -o change.latch.mdDraft from stdin:
git diff | latch draft -o change.latch.mdApply a Latch document from a path or stdin:
latch apply change.latch.md
cat change.latch.md | latch apply
latch apply --dir /tmp/repo -Create a compact Latch Git commit, then reconstruct the full document from that commit:
git add src README.md
latch commit
latch show > change.latch.mdlatch commit without a path drafts from the staged changes, opens the
draft in Git's editor, and commits the edited Latch document. You can
also commit an existing document directly with latch commit change.latch.md. The document's first H1 becomes the Git commit subject.
The commit body stores the prose with compact latch-ref fences rather
than full diff bodies; latch show expands those refs from the commit's
canonical parent diff and defaults to HEAD, like git show. When
stdout is a TTY, it renders colored Markdown/diff output through a pager;
when redirected, it writes raw reconstructed Markdown.
Extract reviewer comments from a Latch document path or stdin:
latch review change.latch.md
cat change.latch.md | latch review
latch review --json change.latch.mdPrint the repo skill:
latch skilllatch show is human-friendly by default on a terminal and
machine-friendly when redirected:
latch show # render HEAD through a pager
latch show > change.md # write raw reconstructed MarkdownPager selection follows:
LATCH_PAGERGIT_PAGERPAGERless -R
Set LATCH_PAGER=cat to skip paging. Set NO_COLOR to disable ANSI
color.
A small Neovim plugin lives in contrib/nvim/latch.nvim. It applies to
*.latch.md files, completes patch ids, inserts review fences, and can
run latch review from the current buffer.
- Make code changes normally.
- Run
latch draftfrom the current diff, a commit, a range, or stdin. - Rewrite the generated draft into a real patch narrative.
- Keep executable
difffences intact while reordering sections and improving the prose. - Optionally run
latch commit change.latch.mdto create a Git commit whose message stores a compact Latch recipe. - Use
latch show [commit]to reconstruct the full Latch document from such a commit. With no commit argument, it showsHEAD. - Reviewers may add non-executable
reviewfences with optionalid=patch-idmetadata. - Run
latch reviewto extract those comments for the next authoring pass, orlatch applyto materialize the document onto a target tree.
Generated drafts are intentionally mechanical. They preserve fine-grained Git hunks, assign deterministic patch ids, and include instructions for the human pass.
latch shells out to git for diff collection and patch application,
so git needs to be available on PATH.
Build the binary:
zig build -Doptimize=ReleaseSafeInstall it somewhere on PATH:
zig build -Doptimize=ReleaseSafe install --prefix ~/.localLatch is both a CLI and a document format. The normative format and
application rules live in SPECIFICATION.md.
Short version:
- patch fences are fenced code blocks whose info string starts with
diff - supported patch metadata keys are
id,depends-on, andpart - review fences are fenced code blocks whose info string starts with
review; optionalid=patch-idscopes a comment to a patch - compact Git commits store
latch-reffences withranges=...;latch showexpands them back into executabledifffences depends-oncontrols apply order, not Markdown position- split patches reuse the same
idwith contiguouspart=1..N
See SPECIFICATION.md for the full grammar, validation rules, assembly
rules, and application semantics.