README
¶
redthread
A sticky-note pegboard for your terminal. Mouse-first, keyboard-friendly, transparent over your tmux theme. ASCII-textured cork, dangling red strings, smooth zoom, and multiple named boards you can switch between.

What it is
- A small TUI meant to live in a tmux pane, always open.
- A cork pegboard rendered entirely in ASCII — your terminal background shows through, no solid fill.
- Sticky notes you drag with the mouse or nudge with the keyboard. Colored paper, red pin, ornate woven borders, paper-fiber flecks, drop shadow, fold glyph.
- Red strings between notes (or pinned to bare cork). Slack or tight. In-front-of or behind the notes. A weighted "swoop" while you pull the free end.
- Multiple named boards you cycle through like tmux windows
(
work,personal,ideas, …). Each board has its own notes, strings, zoom, font, highlight color, and a unique cork grain. - Workspace zoom — 5 levels (
-3..+1) that scale note sizes and positions, so you can pack many stickies into an overview or lean in on a few. - 3D zoom-to-edit — a smooth scale + lift + shadow animation that settles into a card with a live textarea.
- 9 paper tints + 9 highlight colors + 8 text styles (Unicode math alphabets: plain, bold, italic, bold-italic, script, fraktur, double-struck, monospace).
- Persists to
$XDG_DATA_HOME/redthread/notes.jsonwith debounced writes.
Install
Requires Go 1.23+.
git clone https://github.com/B33pBeeps/redthread.git
cd redthread
go build -o redthread ./cmd/redthread
./redthread
Or:
go install github.com/B33pBeeps/redthread/cmd/redthread@latest
redthread
First run with no save file gets a small demo board. redthread --fresh
ignores the save and reseeds.
Demos
Notes & feel
Click without moving for a small jiggle, drag for a drop bounce, tab
cycles with the same jiggle, enter zooms into a card with a smooth 3D
transition, esc lands back with a thud.

Red strings
Pull strings between notes (or to bare cork as wall-pins) — the free end
swoops behind the cursor with weight. [ ] cycles the hovered string;
t toggles tight / slack; f toggles in-front-of / behind notes; x
cuts. Strings stay visibly attached when you drag a note.

Boards
Top tab bar shows all boards; each has its own cork grain so they feel
distinct. > / < cycle, B creates and drops you straight into rename,
R renames, D D deletes (two-press confirm).

Controls
Mouse
| click a note | select + raise |
| drag | move (drops with a bounce) |
| double-click | zoom-to-edit |
| click empty cork while pulling a string | place a wall-pin |
Keyboard — board
| key | action |
|---|---|
tab / shift+tab |
cycle note selection |
← ↑ ↓ → or hjkl |
nudge (overshoots in motion direction) |
shift + ← ↑ ↓ → |
nudge ×5 |
enter |
zoom-to-edit |
n / d / r |
new / delete / raise note |
u |
undo the last delete (single step) |
ctrl+y / ctrl+p |
copy / paste the selected note |
1 – 9 |
tint the selected note (yellow, pink, blue, green, purple, orange, teal, cream, coral) |
c |
cycle the global highlight (border) color |
a |
open the font menu (live preview, enter to commit, esc to cancel) |
- / = / 0 |
zoom out / in / reset (5 levels) |
s |
start pulling a red string (arrows/hjkl nudge endpoint, tab snap to next note, enter commit, esc cancel) |
[ / ] |
cycle the hovered string |
t |
toggle tight / slack on the hovered string |
f |
toggle in-front-of / behind notes |
x |
cut the hovered string |
X |
cut every string on the selected note |
? |
toggle the help panel (slides up from the bottom) |
q / ctrl+c |
quit (saves) |
Keyboard — boards
| key | action |
|---|---|
> (or .) |
next board |
< (or ,) |
previous board |
{ / } |
re-order: move the active board left / right (wraps) |
B |
new board (drops you into rename) |
R |
rename the active board |
D |
delete the active board (press twice within 2s; refuses if it's the last one) |
Keyboard — edit
| key | action |
|---|---|
| typing | edit body (first non-empty line is the title; text renders in the board's font) |
ctrl+y / ctrl+p |
copy the note / paste at cursor (system clipboard) |
| drag mouse | native terminal selection — copy with your terminal's hotkey |
esc |
close + save with reverse transition |
ctrl+s |
save without closing |
Data
Notes live at $XDG_DATA_HOME/redthread/notes.json, defaulting to
~/.local/share/redthread/notes.json. Writes are debounced (400 ms) so
rapid drags coalesce into one flush.
A legacy brainfartadhdfixerupper/ directory auto-migrates on first
launch under the new name. v3 single-board files migrate forward into
the v4 workspace envelope.
Schema (v4):
{
"schemaVersion": 4,
"activeIdx": 0,
"boards": [
{
"name": "main",
"grainSeed": 1777118907643042768,
"zoom": 0,
"textMode": 0,
"highlightColor": 0,
"notes": [ { "id": "…", "title": "…", "body": "…",
"x": 3, "y": 1, "tint": "yellow",
"created": "…", "updated": "…" } ],
"strings": [ { "a": { "note": "idA" }, "b": { "note": "idB" },
"tight": false, "front": false } ]
}
]
}
Customizing
Color palettes and text styles live in internal/app/theme.go:
Tints+TintOrder— the 9 paper colors.SelBorderChoices— the 9 highlight colors.TextModes— the Unicode-alphabet font options.StarChars/PoreChars/BlotchChars— cork-texture char pools.
Edit any of those, rebuild, and the whole app picks up the new values (help panel + menu + cycle included).
File layout
cmd/redthread/
main.go thin entry — calls internal/app.Run()
internal/app/
app.go Run(): flag parsing, load/seed workspace, launch
model.go MVU (Model/Update/View, key + mouse routing,
tab bar, help panel, rename mode)
notes.go Note, Board, Workspace, StringConn, cork gen
draw.go cork + note rendering (shadow, tape, borders,
text, fibers)
wire.go red-string curve rendering + pull physics
render.go cell grid + coalesced ANSI emitter (transparent bg)
theme.go colors, tints, dither, halftone, text styles
anim.go zoom transition timeline + easings
edit.go canvas-drawn edit frame + bubbles/textarea splice
menu.go font-picker popup
storage.go XDG JSON persistence + v3→v4 migration
docs/
screenshot.png
DESIGN.md early design notes (historical)
Changelog
Latest
Fixes
- Fullwidth font removed — it never rendered correctly.
}(move-active-board-right) was a no-op; it now actually shifts the active board.- Opening a freshly created blank note no longer drops the cursor two rows below the title.
Features
- New notes start empty (only the initial seed has demo content).
- Open notes now render in the board's selected font.
- Strings are fully keyboard-drivable from
s— arrows /hjklnudge the free end,tabsnaps to next note,entercommits,esccancels. - Boards re-orderable in the tab bar with
{and}. - Native terminal text selection inside open notes (mouse capture is released in edit mode).
ctrl+ycopies the selected note's text;ctrl+ppastes — into the cursor in edit mode, or onto the selected note in board mode.uundoes the most recent note delete (restores connected strings too).- Subtle dim-crossfade + horizontal slide when switching boards.
License
Personal project. MIT — use it, fork it, do whatever.