https://github.com/empathic/toolpath
The story of how we got here
https://github.com/empathic/toolpath
Last synced: 2 months ago
JSON representation
The story of how we got here
- Host: GitHub
- URL: https://github.com/empathic/toolpath
- Owner: empathic
- License: other
- Created: 2026-02-12T14:24:33.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-30T14:49:54.000Z (3 months ago)
- Last Synced: 2026-03-30T16:35:30.862Z (3 months ago)
- Language: Rust
- Size: 476 KB
- Stars: 3
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Toolpath
A tool-agnostic format for tracking artifact transformation provenance.
## What is this?
Toolpath records the complete history of how code (and other artifacts) evolved:
- **Who** made changes (humans, AI agents, formatters, linters, CI)
- **What** they changed (unified diffs + structural AST operations)
- **Why** they changed it (intent, linked issues, reasoning)
- **What else they tried** (dead ends preserved for reflection)
- **Verification** (cryptographic signatures, identity resolution)
## Three core objects
| Object | What it represents | Example |
|-----------|-------------------------------------------|------------------------|
| **Step** | A single change to artifact(s) | One commit, one edit |
| **Path** | A sequence of steps with a base context | A PR, a coding session |
| **Graph** | A collection of related paths | A release |
Steps form a DAG via parent references. Dead ends are implicit: steps not in the ancestry of `path.head`.
```
+-- step-3a -- step-4a (dead end)
step-1 -- step-2 --+
+-- step-3b -- step-4b -- step-5b (head)
```
## Install
```bash
cargo install toolpath-cli
```
This installs a binary called `path`.
## Workspace
```
crates/
toolpath/ Core types, builders, query API
toolpath-convo/ Provider-agnostic conversation types and traits
toolpath-git/ Derive from git repository history
toolpath-github/ Derive from GitHub pull requests
toolpath-claude/ Derive from Claude conversation logs
toolpath-dot/ Graphviz DOT visualization
toolpath-md/ Markdown rendering for LLM consumption
toolpath-cli/ Unified CLI (binary: path)
```
See each crate's README for library-level documentation.
## Quick start
```bash
# Build everything
cargo build --workspace
# Derive a Toolpath document from this repo's git history
path derive git --repo . --branch main --pretty
# Visualize it
path derive git --repo . --branch main | path render dot | dot -Tpng -o graph.png
# Render as Markdown for an LLM
path derive git --repo . --branch main | path render md
# Derive from a GitHub pull request
path derive github --repo owner/repo --pr 42 --pretty
# Derive from Claude conversation logs
path derive claude --project /path/to/project --pretty
# Query for dead ends (abandoned approaches)
path query dead-ends --input doc.json
# Filter steps by actor
path query filter --input doc.json --actor "agent:"
# Walk the ancestry of a step
path query ancestors --input doc.json --step-id step-003
# Merge multiple documents into a graph
path merge doc1.json doc2.json --title "Release v2" --pretty
# Validate a document
path validate --input examples/step-01-minimal.json
```
## CLI reference
```
path
list
git [--repo PATH] [--remote NAME] [--json]
github --repo OWNER/REPO [--json]
claude [--project PATH] [--json]
derive
git --repo PATH --branch NAME[:START] [--base COMMIT] [--remote NAME] [--title TEXT]
github --repo OWNER/REPO --pr NUMBER [--no-ci] [--no-comments]
claude --project PATH [--session ID] [--all]
query
ancestors --input FILE --step-id ID
dead-ends --input FILE
filter --input FILE [--actor PREFIX] [--artifact PATH] [--after TIME] [--before TIME]
render
dot [--input FILE] [--output FILE] [--show-files] [--show-timestamps]
md [--input FILE] [--output FILE] [--detail summary|full] [--front-matter]
merge FILE... [--title TEXT]
track
init --file PATH --actor ACTOR [--title TEXT] [--base-uri URI] [--base-ref REF]
step --session FILE --seq N [--actor ACTOR] [--intent TEXT]
visit --session FILE --seq N
note --session FILE --intent TEXT
export --session FILE
close --session FILE
list
validate --input FILE
haiku
```
Global: `--pretty` for formatted JSON output.
## Using the libraries
### Core types
```rust
use toolpath::{Step, Path, Base, Document};
let step = Step::new("step-001", "human:alex", "2026-01-29T10:00:00Z")
.with_parent("step-000")
.with_raw_change("src/main.rs", "@@ -1,1 +1,1 @@\n-hello\n+world")
.with_intent("Fix greeting");
let path = Path::new(
"path-pr-42",
Some(Base::vcs("github:org/repo", "abc123")),
"step-001",
);
```
### Query operations
```rust
use toolpath::query;
let ancestors = query::ancestors(&path.steps, &path.path.head);
let dead_ends = query::dead_ends(&path.steps, &path.path.head);
let by_actor = query::filter_by_actor(&path.steps, "agent:");
let artifacts = query::all_artifacts(&path.steps);
```
### Git derivation
```rust
use toolpath_git::{derive, DeriveConfig};
let repo = git2::Repository::open(".")?;
let config = DeriveConfig { remote: "origin".into(), title: None, base: None };
let doc = derive(&repo, &["main".into()], &config)?;
```
### DOT rendering
```rust
use toolpath_dot::{render, RenderOptions};
let dot_string = render(&doc, &RenderOptions::default());
```
### Markdown rendering
```rust
use toolpath_md::{render, RenderOptions};
let md_string = render(&doc, &RenderOptions::default());
```
## Documentation
- [RFC.md](RFC.md) -- Full format specification
- [FAQ.md](FAQ.md) -- Design rationale and FAQ
- [CHANGELOG.md](CHANGELOG.md) -- Release history
- [schema/toolpath.schema.json](schema/toolpath.schema.json) -- JSON Schema
- [examples/](examples/) -- 11 example documents covering steps, paths, and graphs
## Requirements
Rust 1.85+ (edition 2024).
## License
Apache-2.0