[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-105328":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":32,"readmeContent":33,"aiSummary":10,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":34,"discoverSource":35},105328,"shoulder","bjarneo\u002Fshoulder","bjarneo","Watch over your agents' shoulder. A TUI that shows Claude Code, Codex, Gemini CLI and opencode work in your project, live.","https:\u002F\u002Fbjarneo.github.io\u002Fshoulder\u002F",null,"Go",70,5,1,0,2,6,43.53,"MIT License",false,"main",true,[24,25,26,27,28,29,30,31],"ai-agents","bubbletea","claude-code","codex","gemini-cli","golang","opencode","tui","2026-11-01 00:14:21","# shoulder\n\n**Watch over your agents' shoulder.**\n\nSee your coding agents work, live. shoulder follows Claude Code, Codex, Gemini CLI, opencode and omp through your project. It shows the file that each agent reads or edits, the diff against your last commit, and the commands that it runs.\n\n[![Claude simplifies snake.js one line at a time while Codex adds tests. shoulder follows both.](site\u002Fposter.jpg)](https:\u002F\u002Fbjarneo.github.io\u002Fshoulder\u002F)\n\nTo see the 47-second demo, open the [website](https:\u002F\u002Fbjarneo.github.io\u002Fshoulder\u002F) or download [shoulder-demo.mp4](https:\u002F\u002Fgithub.com\u002Fbjarneo\u002Fshoulder\u002Freleases\u002Flatest\u002Fdownload\u002Fshoulder-demo.mp4).\n\n## Install\n\nInstall shoulder with Go 1.26 or later:\n\n```sh\ngo install github.com\u002Fbjarneo\u002Fshoulder@latest\n```\n\nOr download a binary from the [latest release](https:\u002F\u002Fgithub.com\u002Fbjarneo\u002Fshoulder\u002Freleases\u002Flatest). There are binaries for `linux-amd64`, `linux-arm64`, `darwin-amd64` and `darwin-arm64`:\n\n```sh\ncurl -sL https:\u002F\u002Fgithub.com\u002Fbjarneo\u002Fshoulder\u002Freleases\u002Flatest\u002Fdownload\u002Fshoulder-linux-amd64.tar.gz | tar xz\nsudo mv shoulder-linux-amd64\u002Fshoulder \u002Fusr\u002Flocal\u002Fbin\u002F\n```\n\nTo verify a download, compare it with `checksums.txt` in the release:\n\n```sh\nsha256sum -c checksums.txt --ignore-missing\n```\n\nWith Nix, run shoulder from the flake, or enter a shell with Go and its tools for development:\n\n```sh\nnix run github:bjarneo\u002Fshoulder\nnix develop\n```\n\n## Run\n\nRun shoulder in the project where your agents work:\n\n```sh\ncd ~\u002FCode\u002Fmyproject\nshoulder\n```\n\nThen start your agents in the same project. Each agent shows up within a few seconds. To watch a different project, give its path:\n\n```sh\nshoulder ~\u002FCode\u002Fmyproject\n```\n\nshoulder watches the git top level of the directory. It shows the sessions that started there or in a subdirectory.\n\n| Flag | Default | Description |\n|---|---|---|\n| `--since` | `1h` | Show sessions with activity in this period, for example `30m` or `6h` |\n| `--splits` | off | Start with one split per agent |\n| `--signs` | off | Show changes as signs in the gutter, without the deleted lines |\n| `--all` | off | Watch the agents of all projects, not only of this project |\n| `--hide-done` | off | Hide the agents that are done |\n| `--version` | | Print the version |\n\n### Set the defaults\n\nTo change the defaults of the flags, set them at the top of `~\u002F.config\u002Fshoulder\u002Fconfig.toml`. A flag on the command line has priority over the file.\n\n```toml\nsince = \"6h\"\nall = true\nhide_done = true\nsigns = false\nsplits = false\neditor = \"nvim\"\n```\n\n`editor` is the command that `e` runs. Without it, shoulder uses `VISUAL`, then `EDITOR`, then `vi`. The same file holds the [keys](#change-the-keys).\n\n## Supported agents\n\nshoulder reads the session logs that the agents already write. You do not configure the agents.\n\n| Agent | Session data | To use another location, set |\n|---|---|---|\n| Claude Code, with subagents | `~\u002F.claude\u002Fprojects\u002F` | `CLAUDE_CONFIG_DIR` |\n| Codex | `~\u002F.codex\u002Fsessions\u002F` | `CODEX_HOME` |\n| Gemini CLI | `~\u002F.gemini\u002Ftmp\u002F` | `GEMINI_CLI_HOME` |\n| opencode 2.x | `~\u002F.local\u002Fshare\u002Fopencode\u002Fopencode.db` | `XDG_DATA_HOME` |\n| omp | `~\u002F.omp\u002Fagent\u002Fsessions\u002F` | `PI_CODING_AGENT_DIR` |\n\nshoulder only reads. It does not send input to an agent, it does not change files, and it does not connect to the network. It opens the opencode database read-only.\n\n## Screen\n\n- The left panel lists the agents and the changed files. A dot next to a file shows which agent is in that file now.\n- Each agent has a tag, such as `A1`, and a color. The agent keeps its tag and its color while it is in the list.\n- When the terminal is too narrow for the left panel, the top bar shows a row of the agents.\n- The center pane shows the file of the focused agent. A cursor and a label, such as `● A1 editing`, show where the agent works.\n- In the inline diff, deleted lines show in red above the new lines. Added and changed lines have a green background. Press `d` to show the changes as signs in the gutter.\n- The terminal pane under the file shows the commands of the focused agent and their output, with the colors of the output. A command with more lines, such as a script in a heredoc, shows its first 5 lines.\n- The right panel shows the activity log of the focused agent: reads, searches, edits, commands, replies and prompts.\n- Press `s` for the split layout. Each agent gets a pane with its file and its activity log.\n\nThe bar under each agent shows how full its context window is.\n\nTo hide the agents that are done, press `x` or start with `--hide-done`. An agent stays for 1 minute after it finishes, and the focused agent always stays. The `✓` count in the sidebar includes the hidden agents.\n\n## Open the file in your editor\n\nTo open the file at the cursor in your editor, press `e`. shoulder gives the terminal to the editor and comes back when the editor closes. Most terminal editors get `+LINE FILE`. `zed`, `hx` and `subl` get `FILE:LINE`. VS Code and Cursor get `-g FILE:LINE`.\n\nWhen `EDITOR` is `omarchy-launch-editor`, shoulder runs the editor that Omarchy selects. The wrapper puts `--` before its arguments, so the editor would read `+LINE` as a file name.\n\nTo copy `path:line` of the cursor, press `y`. The copy uses OSC 52. In tmux, add `set -g set-clipboard on` to your tmux configuration.\n\n## History\n\nTo step back through the activity log of the focused agent, press `,`. To step forward, press `.`. You can also click an entry in the activity log.\n\n- The center pane shows the file at the read or the edit of the step.\n- The terminal pane shows the commands up to the step.\n- The status line shows `HISTORY`.\n\nA step past the newest entry, or `esc`, goes back to follow. The center pane shows each file as it is now, not as it was at the step.\n\n### While you were away\n\nWhen you come back to the terminal after 30 seconds or more, the message line lists what each agent did. An example is `while you were away · A1 claude edited 3 files · A2 codex asks you`. A line in the activity log marks the start of the time away.\n\nThis needs a terminal that reports focus changes. In tmux, add `set -g focus-events on` to your tmux configuration.\n\n## Auto focus\n\nAuto focus is on when shoulder starts. The view jumps to the work of the agents:\n\n- When an agent edits a file in the project, the focus goes to that agent and its file.\n- When an agent edits a file through the shell, such as with `sed -i`, a script or `gofmt -w`, the focus goes to that agent and the changed lines. See [Commands](#commands).\n- When an agent asks you a question or waits for your approval, the focus goes to that agent.\n- When the focused agent finishes, the focus goes to an agent that still works in the project.\n\nshoulder waits at least 1.5 seconds between two jumps, so agents that work at the same time do not make the view flicker. In free scroll, the view does not jump.\n\nTo keep the focus on one agent, select it with `1` … `9`, `tab` or a click. The key `3` selects `A3`. This pins the agent and turns auto focus off. To turn auto focus on again, press `a`. The status line shows `auto` or `pinned`.\n\n## Commands\n\nshoulder follows the commands that agents run in the shell:\n\n- `cat`, `head`, `sed -n` and `nl | sed -n` count as reads of a file. The view goes to the lines that the agent reads.\n- `rg`, `grep` and `git grep` count as searches.\n- A command with more parts, such as `cat a.go && sed -n 1,80p b.go`, gives a read for each file. A `cd DIR` part changes the directory of the paths after it.\n- When a file in `git status` changes on disk and no edit tool call explains the change, the edit goes to the agent that ran a command at that time.\n\n## All projects\n\nTo watch the agents of all projects, press `A` or start shoulder with `--all`. To go back to the agents of this project, press `A` again.\n\n- The row of an agent from another project starts with the name of that project, such as `preamp · Add a preset`.\n- The top line shows `all projects`.\n- The terminal pane shows the project of the agent in the prompt.\n- A file in another git repository shows the diff against the `HEAD` of that repository.\n\nAuto focus works the same way. It jumps to new edits in all projects.\n\n## Status bar\n\n`shoulder status` prints one line with the number of agents that work, that wait for you and that are done. With no agents, the line is empty.\n\n```sh\n$ shoulder status\n●2 ○1 ✓3\n```\n\nIt takes the flags `--since`, `--all` and `--json`, and a directory. It reads only the end of each session log, so it is fast enough for a status bar.\n\nTo show the agents of all projects in Waybar, add a custom module:\n\n```jsonc\n\"custom\u002Fshoulder\": {\n  \"exec\": \"shoulder status --all --json\",\n  \"return-type\": \"json\",\n  \"interval\": 5\n}\n```\n\nThe JSON has the class `waiting`, `active`, `done` or `none`. The tooltip lists each agent. To color the module when an agent waits for you, add this to the Waybar style:\n\n```css\n#custom-shoulder.waiting { color: #e0af68; }\n```\n\nTo show the agents of the current project in tmux, add this to your tmux configuration:\n\n```sh\nset -g status-right '#(shoulder status #{q:pane_current_path})'\nset -g status-interval 5\n```\n\n## Agent states\n\n- `●` The agent runs a tool or writes a reply.\n- `○` The agent waits for you. It asked a question, or a tool call needs your approval.\n- `✓` The turn ended. The state is `idle` when the agent had no activity for 10 minutes.\n\nA command, a task or a web call that runs for 1 minute or more shows how long it runs, such as `47m · $ go test .\u002F...`. A wait for you shows how long it waits. When a call has no result and the session log gets no write for 30 minutes, the agent stopped. Its state is then `idle`, with `no result`.\n\nA session with no activity in the `--since` period leaves the list. It comes back when the agent works again.\n\nGemini CLI logs when a tool call waits for approval. For the other agents, shoulder assumes approval when a file tool has no result after 20 seconds.\n\n## Keys\n\n| Key | Action |\n|---|---|\n| `1` … `9` | Pin the agent with that tag, such as `A3` for `3` |\n| `tab`, `shift+tab` | Pin the next or the previous agent |\n| `a` | Turn auto focus on or off |\n| `A` | Switch between the agents of this project and of all projects |\n| `x` | Hide or show the agents that are done |\n| `f` | Toggle follow and free scroll |\n| `esc` | Go back to follow |\n| `j`, `k` | Move the cursor |\n| `ctrl+d`, `ctrl+u` | Move half a page down or up |\n| `gg`, `G` | Go to the top or the bottom of the file |\n| `]c`, `[c` | Go to the next or the previous change |\n| `H`, `L`, `gT`, `gt` | Open the previous or the next file tab |\n| `,`, `.` | Step to the older or the newer entry of the activity log |\n| `e` | Open the file at the cursor in your editor |\n| `y` | Copy `path:line` of the cursor |\n| `s` | Toggle the follow layout and the split layout |\n| `d` | Toggle the inline diff and the signs |\n| `R` | Read all sessions again |\n| `?` | Show all keys |\n| `q` | Quit |\n\nYou can also click an agent, a file, a tab or a split pane.\n\n### Change the keys\n\nTo change a key, add a `[keys]` table to `~\u002F.config\u002Fshoulder\u002Fconfig.toml`. To use a different file, set `XDG_CONFIG_HOME` or `SHOULDER_CONFIG`. Without the file, shoulder uses the default keys.\n\n```toml\n[keys]\nhunk_next = \"n\"\nhunk_prev = \"p\"\ntop = [\"gg\", \"home\"]\nreload = []\n```\n\n- Give 1 key or an array of keys. An empty array removes all keys of the action.\n- Write a sequence of one-character keys without spaces, such as `gg` or `]c`. Put spaces between the keys of a longer sequence, such as `\"ctrl+w j\"` or `\"g g g\"`.\n- Write a named key the way Bubble Tea names it, such as `ctrl+n`, `alt+x`, `shift+tab`, `enter`, `space`, `pgdown` or `f5`.\n- When the config binds an action, the action loses its default keys. When another action has the same key by default, that action loses the key. A default sequence that starts with your key also goes away. For example, `top = \"g\"` removes `gt` and `gT`.\n- The keys `1` … `9` and `ctrl+c` do not change.\n\nshoulder stops with an error for an unknown action, an unknown key, or 2 actions on the same key. The help screen and the sidebar show the keys from your config.\n\n| Action | Default keys |\n|---|---|\n| `agent_next`, `agent_prev` | `tab`, `shift+tab` |\n| `auto` | `a` |\n| `all_projects` | `A` |\n| `hide_done` | `x` |\n| `follow` | `f` |\n| `back` | `esc` |\n| `down`, `up` | `j` `down`, `k` `up` |\n| `page_down`, `page_up` | `ctrl+d` `pgdown`, `ctrl+u` `pgup` |\n| `top`, `bottom` | `gg` `home`, `G` `end` |\n| `hunk_next`, `hunk_prev` | `]c`, `[c` |\n| `buffer_next`, `buffer_prev` | `L` `gt`, `H` `gT` |\n| `history_prev`, `history_next` | `,`, `.` |\n| `open_editor` | `e` |\n| `copy_path` | `y` |\n| `splits` | `s` |\n| `inline_diff` | `d` |\n| `reload` | `R` |\n| `help` | `?` |\n| `quit` | `q` |\n\n## Colors\n\nshoulder uses the colors of your terminal theme. Text uses the default colors and the 16 ANSI colors, so it changes when you change the theme.\n\nThe panel shades and the line highlights are mixed from the colors that the terminal reports. shoulder asks the terminal again every 3 seconds, so a theme change shows while shoulder runs. If your terminal does not report its colors, the panels use the terminal background and the change signs show the diff.\n\nIn tmux, shades show correctly only when tmux supports true color. To turn it on, add `set -as terminal-features \",*:RGB\"` to your tmux configuration.\n\n## Diff baseline\n\nIn a git repository, shoulder compares each file with `HEAD`. Outside git, it compares each file with the first content that it read.\n\n## Limits\n\n- shoulder reads opencode 2.x. It does not read the older `part` tables of opencode 1.x.\n- For Claude Code, Codex, opencode and omp, the approval state is an estimate. See [Agent states](#agent-states).\n- When omp moves a command to the background, shoulder shows it as running until omp writes the output of the finished job.\n- shoulder finds edits through the shell only for files in the `git status` of this project. When you edit a file in your editor while an agent runs a command, the edit also goes to that agent.\n- In all projects, `FILES` shows the git changes of this project only. For the other projects, it shows the files that agents edited.\n- The binaries are for Linux and macOS. shoulder is not tested on Windows.\n\n## Develop\n\n```sh\ngo test .\u002F...\ngo build -o shoulder .\n```\n\nThe code has three packages:\n\n- `internal\u002Fwatch` reads the session logs of each agent and turns them into one event model.\n- `internal\u002Frepo` reads the project files and compares them with the last commit.\n- `internal\u002Fui` draws the TUI with Bubble Tea.\n\nTo record the demo video again, run `demo\u002Frecord.py`. The script header lists what it needs.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","2026-10-31 04:26:27","CREATED_QUERY"]