Getting started¶
This page installs the felt CLI and walks one fiber from creation to a closed
outcome. It takes about five minutes. The quickest path needs only curl and
tar.
Install¶
The install script downloads the release binary for your platform:
curl -fsSL https://raw.githubusercontent.com/cailmdaley/felt/main/install.sh | sh
It installs to /usr/local/bin if that is writable, otherwise ~/.local/bin.
Override with FELT_INSTALL_DIR. It supports macOS and Linux on x86_64 and
arm64. There is no Windows build.
Homebrew:
brew install cailmdaley/tap/felt
From source, if you have Go 1.23.4 or newer (go.mod declares go 1.23.4, so
an earlier 1.23 patch triggers a toolchain download):
go install github.com/cailmdaley/felt@latest
Check the install:
felt --version
If the command is not found, the install directory is not on your PATH. The
script prints the line to add.
The script also wires up your coding agents
If claude or codex is on your PATH, install.sh runs felt setup
claude and felt setup codex for you. That registers felt's plugin
marketplace and installs its hooks, which writes to ~/.claude and
~/.codex. There is no opt-out flag. The script prints what it is doing
before it does it, and felt uninstall reverses it. If you would rather
decide yourself, download the script and run it after reading, or use
Homebrew and run felt setup claude when you want it.
Later, upgrade with felt update. That swaps the binary and refreshes the agent
plugin in the same step, so the two never skew.
Create a store¶
Create a store — a .felt/ directory — at the root of the project where your
work lives:
cd ~/dev/my-project
felt init
felt init creates or repairs .felt/ and writes two support files: a
myst.yml so the store can render as a site, and a .gitignore for felt's
per-fiber write locks. Run it again any time — it is idempotent.
Rendering the site needs mystmd, a separate tool felt
does not install. npm install -g mystmd, then myst start from the store
root.
Commit .felt/ to your repository. The trail is worth versioning.
File a fiber¶
felt add covariance-estimation "Covariance estimation" -s open
Two arguments: the slug you will address it by, and the human name. Everything
else is optional. -s open opts this fiber into status tracking, which is what
makes it show up in felt ls.
Most fibers do not need a status. A fiber that records a decision or a finding
completes the moment you write it. Nothing stays to do. Reach for -s when you
want the thing to nag you.
Give it a body:
felt edit covariance-estimation \
-b "Analytic covariance is too slow for our bin count. Trying jackknife."
Warning
felt edit -b replaces the whole body. For anything longer than a couple of
sentences, open .felt/covariance-estimation/covariance-estimation.md in
your editor and write there. felt reads it back on the next command.
Add a child and nest it¶
Work grows sub-questions. Give them their own fibers:
felt add jackknife-patches "Jackknife patch count" -s active
felt nest jackknife-patches covariance-estimation
Nested jackknife-patches under covariance-estimation as covariance-estimation/jackknife-patches
felt nest <child> <parent> moves the whole subtree on disk and rewrites the
addresses that point at it. The directory tree carries containment on its own,
so no parent field can drift. felt unnest <child> promotes it back to the top
level.
Look at the store¶
felt ls
○ covariance-estimation
Covariance estimation
◐ covariance-estimation/jackknife-patches
Jackknife patch count
felt ls shows tracked fibers only, open and active by default. Pass a query to
search names, outcomes, frontmatter text, and slugs. Any filter widens the
search to every status automatically:
felt ls "jackknife" # search
felt ls -s all # everything tracked, closed included
felt ls --body "patches" # search bodies too
felt tree shows containment:
○ covariance-estimation Covariance estimation
└── ◐ .../jackknife-patches Jackknife patch count
felt show reads one fiber:
felt show jackknife-patches
A bare slug resolves when it is globally unique, so you rarely have to type the
full path. felt show has four detail levels — felt show <id> -d compact for
metadata and outcome only, -d full for everything.
Close it with a real outcome¶
This part matters most.
felt edit jackknife-patches -s closed \
-o "150 patches: stable off-diagonal, <2% bias at all scales"
Write the outcome as a one-line conclusion. felt show -d compact puts that
line in front of you months later. Say what you learned, decided, or measured,
in a sentence that stands alone. An outcome that says "done" has failed — the
status field already said that.
Closing stamps closed-at. The fiber stays in the tree. felt ls -s all still
finds it. felt deletes nothing.
The file on disk¶
---
id: 01KYTG89NAA3MZ68RZSG6MS7VT
name: Jackknife patch count
status: closed
created-at: 2026-07-30T14:52:55-07:00
updated-at: 2026-07-30T15:10:41-07:00
closed-at: 2026-07-30T15:10:41-07:00
outcome: "150 patches: stable off-diagonal, <2% bias at all scales"
---
Tried 50 and 300 as well. Below 100 the off-diagonal is noise-dominated.
Rolls up into [[covariance-estimation]].
That covers the whole storage format. felt mints the id as a ULID at felt
add and preserves it across moves. The [[wikilink]] points at another fiber
in the narrative. felt computes the reverse direction on demand, so felt show
covariance-estimation --citations finds this fiber pointing at it.
Next steps¶
Wire up your coding agent. If the install script did not already do it:
felt setup claude # or: felt setup codex
This installs the felt plugin: a SessionStart hook that lists active and
recently touched fibers, a gate that nudges the agent to load the felt skill
before it starts editing, and the felt and shuttle skills themselves. The
agent then reads and writes the same store you do. See
Agent integration.
Keep reading. Fibers covers the data model in full, and Organizing covers the judgment calls — when a status earns its keep, when to nest, how to write an outcome, and when a wikilink is doing real work.