A terminal-first setup for driving hosted frontier models and models on your own hardware through the same workflow. tmux holds the screen, Neovim takes the left, an agent takes the right, and every harness — Claude Code, Cursor, Codex CLI, OpenCode — reads its rules from one shared source of truth.
One command — gw — is the whole entry point. Editing and AI
land on one screen, in the directory you're already standing in.
Hand off a task larger than you'd chat through, and it gets sorted into those three states while you keep editing on the left.
how it fits together
The thing people call "an AI setup" is four independent layers. Keeping them separate is the whole point: the model and the harness don't know about each other, so you can swap a hosted frontier model for one running on your own machine without changing how you work.
.friday/mcp.json.gw puts on screen, and what .friday/ configures. Each harness
reads instructions from a different path — which is the problem .friday/ solves.:11434 for everything cheap, private, or offline.models
Neither choice is the right one for every task. Hosted frontier models are still where the hard reasoning happens. Local models are free, private and work on a plane. Because the harness sits above both, choosing is a per-task decision rather than an architecture decision.
| task | runs on | why |
|---|---|---|
| multi-file refactor, architecture | hosted | long loops need tool-calling that holds up |
| summarise a git diff | local | runs constantly; zero cloud tokens |
| anything under NDA or unreleased | local | the context never leaves the machine |
| research, long-context reading | hosted | context window is the constraint |
| on a train, no signal | local | it's the only one that answers |
One hard rule from the research: use weights released in the last six months. Stalled local agent loops are almost always an old model with poor tool-call adherence, not a broken harness. Full write-up in docs/tooling-research.md.
the workspace
Nothing here is a new application. It's tmux, Neovim and an agent CLI arranged so that handing off work never means leaving the screen you're working on.
gw always targets the top-level socket,
even when invoked from a shell nested inside Neovim.gw in the current directory
execs Neovim into the very pane you typed it in, so no window is wasted..friday/. Narrow on purpose: it's a
task queue you glance at, not something you stare into.Current directory. Reuses this tab — agent splits in on the right, Neovim takes over this pane.
Another directory. Opens its own tab, named after the folder, so unrelated workspaces never share a screen.
Don't know the path yet. An fzf popup, bound in tmux, browses
directories and hands the one you pick straight to gw.
the idea
Every harness reads its instructions, MCP config, skills and commands from a different path.
Left alone, that means four copies of the same rules drifting apart. .friday/
holds the canonical copy, and .friday/init symlinks it into whatever each tool
expects. Edit once, every tool picks it up.
Four copies. Three of them are already wrong.
One file. Every tool reads it.
| tool | links created |
|---|---|
| Claude Code | CLAUDE.md, .mcp.json, .claude/skills,
.claude/commands, .claude/settings.json |
| Cursor | .cursorrules |
| Codex CLI / OpenCode | AGENTS.md |
Idempotent — re-run any time to repair drifted links. A real file sitting at
a link path is backed up to <file>.bak first. The links themselves are
per-machine setup, not project source, so they're gitignored.
.friday/vendor/, with the individual skill directory symlinked
into .friday/skills/. vendor/ stays an untouched upstream clone;
skills/ is the curated surface. Locally authored skills and commands are prefixed
friday- so git tracks them and leaves the generated symlinks alone.extend
Both are just directories of Markdown. Add a file, and it shows up in the harness — no plugin system, no build step, and everything is diffable.
Skills work across harnesses. Slash commands are Claude Code-only today — the other tools each use a different format, and no shared standard exists yet.
setup
Asks which harnesses you use and symlinks accordingly. Point it at a
cloned project to wire that repo back to the same shared config:
bash .friday/init repos/<name>
.friday/ everywhere? Keep the canonical copy at
~/.friday and symlink it into each project with ln -s ~/.friday .friday.
Harnesses resolve the path relative to the working directory, so a project can't point at your
home directory on its own. Projects needing their own rules keep a real local
.friday/ instead.Read the source on GitHub · the research behind these choices · the design language for this page