{"id":50895258,"url":"https://github.com/jimmy-guzman/sideye","last_synced_at":"2026-06-30T15:00:40.592Z","repository":{"id":364115151,"uuid":"1264506675","full_name":"jimmy-guzman/sideye","owner":"jimmy-guzman","description":"A read-only terminal UI for watching a repo while a CLI coding agent changes it.","archived":false,"fork":false,"pushed_at":"2026-06-23T15:10:32.000Z","size":4484,"stargazers_count":0,"open_issues_count":6,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-23T15:28:32.824Z","etag":null,"topics":["effect-ts","opentui","solidjs"],"latest_commit_sha":null,"homepage":"","language":"MDX","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jimmy-guzman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-10T00:17:03.000Z","updated_at":"2026-06-23T15:10:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jimmy-guzman/sideye","commit_stats":null,"previous_names":["jimmy-guzman/sideye"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/jimmy-guzman/sideye","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimmy-guzman%2Fsideye","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimmy-guzman%2Fsideye/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimmy-guzman%2Fsideye/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimmy-guzman%2Fsideye/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jimmy-guzman","download_url":"https://codeload.github.com/jimmy-guzman/sideye/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimmy-guzman%2Fsideye/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34971621,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["effect-ts","opentui","solidjs"],"created_at":"2026-06-16T00:00:19.903Z","updated_at":"2026-06-30T15:00:40.568Z","avatar_url":"https://github.com/jimmy-guzman.png","language":"MDX","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sideye\n\n`sideye` is a read-only companion TUI with IDE-grade insight into agent changes.\n\nThe usual workflow is awkward. The agent is in one terminal pane, but you still\nopen an editor just to answer basic questions:\n\n- What files are in this repo?\n- What changed?\n- What did the agent touch most recently?\n- Are there errors or warnings in what changed?\n\n`sideye` is meant to sit in the next pane and answer those questions without\nbecoming part of the agent loop. It does not review code, approve changes, talk\nto the agent, or manage a workflow. It shows you the repo, the diff, and the\nproblems. You decide what to say next.\n\n![sideye showing the repo tree beside a diff of a changed file](assets/screenshots/sideye.png)\n\n## What it does\n\n- Shows the full repo tree, including tracked files and untracked files that are\n  not ignored by git.\n- Marks changed files in place, with staged, unstaged, mixed, and untracked\n  states.\n- Opens unchanged files read-only, with syntax highlighting for any language Shiki supports.\n- Opens changed files as diffs, with a toggle for the full file.\n- Finds text within the open file and cycles through the matches.\n- Searches file contents across the repo, scoped to the changes or the whole\n  tree.\n- Switches scope from a picker: all changes, staged, unstaged, everything since\n  sideye launched, or just the last commit.\n- Switches between git worktrees in place, re-pointing the tree, diffs,\n  refresh, and checks at the chosen worktree.\n- Watches the filesystem and refreshes the moment the agent changes something,\n  then keeps the current file and selection stable as the view refreshes.\n- Marks recent activity and lets you jump to the latest touched file.\n- Shows diagnostics in the tree, in the viewer, and in a problems panel.\n- Copies a reference and snippet to paste back into the agent conversation: the\n  file `path` in the tree and `path:line:col` in the viewer (`path:line` after\n  clicking a line number).\n\nThe git-backed file tree renders first. Diagnostics come in later as decorations.\nThat keeps the basic view useful even when checks are still running.\n\n## Install\n\n```sh\n# standalone binary (macOS / Linux, no runtime needed)\ncurl -fsSL https://raw.githubusercontent.com/jimmy-guzman/sideye/main/install.sh | bash\n\n# npm (works with npm, bun, pnpm, yarn; pulls a prebuilt binary)\nnpm i -g sideye\n\n# homebrew\nbrew install jimmy-guzman/tap/sideye\n```\n\n## Upgrade\n\n```sh\nsideye upgrade\n```\n\nUpdates sideye to the latest release using whichever channel it was installed\nthrough: a standalone install re-runs the install script, an npm install runs\nnpm, and a Homebrew install runs `brew upgrade`. If the install channel cannot\nbe determined, it prints the upgrade commands instead. It checks the latest\nGitHub release first and reports `sideye X.Y.Z is already up to date` without\nrunning anything when you are current, falling back to the channel update if it\ncannot reach GitHub.\n\nsideye also checks for a newer release in the background while it runs, and\nprints a one-line notice on clean exit when one is available, the way `gh` does.\nThe check is non-blocking and never interrupts the session.\n\n## Usage\n\n```sh\nsideye            # whole repo, worktree vs HEAD\nsideye main       # compare against another ref\nsideye --staged   # start in the staged scope\nsideye --unstaged # start in the unstaged scope\nsideye --no-icons # plain tree without Nerd Font file-type icons\nsideye --wrap     # wrap long lines in the viewer instead of scrolling them horizontally\nsideye --editor \"nvim +{line} {file}\"   # terminal editor for the e key\nsideye --ide    \"code --goto {file}:{line}\" # GUI/IDE for the o key\n```\n\nThe tree shows a file-type icon next to each file and a folder glyph for each\ndirectory; symlinks get a distinct symlink icon and show their target path as\ncontent (the same thing git stores), not the file they point at. These are\n[Nerd Font](https://www.nerdfonts.com/) glyphs and only render with a Nerd Font\nselected in your terminal; without one they appear as empty boxes, so pass\n`--no-icons` to fall back to a plain tree.\n\n## Features\n\n### Read any file\n\nOpen any file and read it with syntax highlighting for any language Shiki\nsupports. Unchanged files open read-only with no diff gutters, just the source.\n\n![read-only file view showing a source file with syntax highlighting and no diff gutters](assets/screenshots/read-only.png)\n\n### Browse, go back, and pin tabs\n\nBrowsing the tree previews files in one calm view, so nothing piles up; the\npreview shows in italic to mark it as ephemeral. `\u003c` and `\u003e` step back and forward\nthrough where you've been, restoring each spot's cursor and scroll. When you want\nto keep a file while you look at another, `ctrl-t` pins it as a tab (and `ctrl-t`\nagain unpins it), or double-click the tab or the file in the tree to pin it; `{` /\n`}` switch tabs and `ctrl-w` closes one. Each tab carries its own history and\nremembered position, and a tab's label is tinted by its diff status.\n\n![tab strip with pinned, diff-status-tinted tabs and the active file](assets/screenshots/tabs.png)\n\n### Switch scope\n\nPress `s` to pick what the diff compares: all changes, staged, unstaged,\neverything since sideye launched, or just the last commit.\n\n![scope picker listing the five diff scopes with the active one marked](assets/screenshots/scope-picker.png)\n\n### Switch worktrees\n\nPress `w` to jump between git worktrees without leaving the view. Type to\nfilter by branch or path, `↑↓` to move, `⏎` to switch. The tree, diffs,\npolling, and checks all re-point at the chosen worktree.\n\n![worktree combobox with a filter input listing worktrees, the current one marked](assets/screenshots/worktree-picker.png)\n\n### Switch themes\n\nPress `t` to open the theme switcher: filter by name and move (or hover) to\npreview the whole UI live, `enter` to apply, `esc` to revert. The switch lasts the\nsession; [config](#configuration) is where a theme is made permanent.\n\n![theme switcher listing themes with color swatches, previewing the highlighted one live](assets/screenshots/theme-switcher.png)\n\n### Go to file\n\nPress `ctrl-p` to fuzzy-search the whole repo and open any file.\n\n![go-to-file overlay fuzzy-matching paths across the repo](assets/screenshots/go-to-file.png)\n\n### Find in the viewer\n\nPress `/` to search within the open file. `n` and `N` cycle through matches, a\ncounter tracks your place, and `esc` clears the search.\n\n![find-in-viewer search highlighting matches in the open file with a match counter](assets/screenshots/find.png)\n\n### Search file contents\n\nPress `ctrl-f` to search file contents across the repo. Matches show up in the\ntree and the viewer, and `ctrl-a` toggles between the changed files and the\nwhole tree.\n\n![project content search listing matches for a term across several files in the repo](assets/screenshots/search.png)\n\n### Go to definition\n\nPut the caret on a symbol and press `F12` to jump to its definition, backed by\nthe same language servers that drive diagnostics. A cross-file jump records your\nspot, so `\u003c` returns to the call site. It's a read-only LSP request, exactly\nlike the diagnostics it shares servers with: it never writes to the repo.\n\n### Hover\n\nPress `K` with the caret on a symbol to show its type and docs in a small card\nanchored at the caret, the way an editor's hover does. The type signature is\nsyntax-highlighted with the same theme as the diff; the docs read as plain text.\nThe card clears as soon as you move the caret, scroll, switch files, or press\n`esc`. It's the same read-only LSP request family as go-to-definition.\n\n![hover card anchored at the caret showing a syntax-highlighted type signature above its docs](assets/screenshots/hover.png)\n\n### Problems\n\nDiagnostics from the repo's language servers stream into a problems panel as\nchecks finish: type errors from TypeScript and lint findings from oxlint, each\ntagged with its source and pinpointed to its `line:col`. Press `p` to open it and\n`enter` to jump to a finding.\n\nNo language server installed? sideye fetches one on first use (preferring the\nrepo's own, then your `PATH`), so diagnostics work out of the box. Pass\n`--no-lsp-download` to turn that off.\n\n![problems panel docked below a diff, listing diagnostics with their file locations](assets/screenshots/problems.png)\n\n## Keys\n\n### navigation\n\n| Key       | Action                                           |\n| --------- | ------------------------------------------------ |\n| `j` / `k` | move in the tree, viewer, or problems panel      |\n| `h` / `l` | collapse / expand folders, or word-hop the caret |\n| `tab`     | switch focus between tree and viewer             |\n| `enter`   | open the focused item / jump to a problem        |\n| `ctrl-p`  | go to file: fuzzy-search the whole repo          |\n| `.`       | jump to the most recently changed file           |\n| `n`       | jump to the next file with findings              |\n\n### viewer\n\n| Key        | Action                                              |\n| ---------- | --------------------------------------------------- |\n| `/`        | find in the viewer; `n`/`N` cycle, `esc` clears     |\n| `ctrl-f`   | search files; `ctrl-a` toggles changes/repo scope   |\n| `v`        | toggle diff \u003c-\u003e full file view for a changed file   |\n| `z`        | toggle long-line wrap in the viewer                 |\n| `f`        | load full content when truncated                    |\n| `ctrl-d/u` | half-page cursor movement in the viewer             |\n| `g` / `G`  | jump to first / last line                           |\n| `F12`      | go to definition of the symbol under the caret      |\n| `K`        | hover: type and docs for the symbol under the caret |\n| `\u003c` / `\u003e`  | back / forward through viewer history               |\n| `y`        | copy `path`, `path:line`, or `path:line:col`        |\n| `Y`        | copy the entire contents of the viewed file         |\n\n### tabs\n\n| Key       | Action                                |\n| --------- | ------------------------------------- |\n| `ctrl-t`  | pin / unpin the current file as a tab |\n| `ctrl-w`  | close the active tab                  |\n| `{` / `}` | previous / next tab                   |\n\n### workspace\n\n| Key | Action                                         |\n| --- | ---------------------------------------------- |\n| `s` | scope picker: unstaged/staged/all/session/last |\n| `t` | theme switcher: filter, live-preview, apply    |\n| `w` | switch to another git worktree                 |\n| `c` | toggle changes-only filter for the tree        |\n| `r` | re-run checks                                  |\n\n### layout\n\n| Key       | Action                                            |\n| --------- | ------------------------------------------------- |\n| `p`       | toggle the problems panel                         |\n| `b`       | toggle the file tree sidebar                      |\n| `[` / `]` | shrink / grow the sidebar (shrink past min hides) |\n| `\\`       | reset the sidebar to its default width            |\n\n### app\n\n| Key         | Action                                       |\n| ----------- | -------------------------------------------- |\n| `e`         | open file in terminal editor (suspends TUI)  |\n| `o`         | open file in GUI / IDE (renderer stays live) |\n| `?`         | show all keybindings                         |\n| `q` / `esc` | quit (esc closes the problems panel first)   |\n\nPress `?` anytime to see the full list in the app:\n\n![keybindings help overlay showing all shortcuts](assets/screenshots/keys.png)\n\n## Mouse\n\nThe keyboard drives everything, but the mouse works too. Click a file to open\nit, a folder to expand or collapse it, a diff line to move the cursor there, or\na problem to jump to it. Double-click a file in the tree, or a tab in the strip,\nto pin it as a tab. Clicks also work in the overlays: a go-to-file or\nsearch result, a worktree to switch to, or a theme to apply (hovering a theme\npreviews it live). Clicking a pane focuses it, and the wheel scrolls whichever\npane the pointer is over.\n\n## Configuration\n\nOptional, at `~/.config/sideye/config.jsonc` (`$XDG_CONFIG_HOME` is honored;\n`config.json` also works). Without it, sideye follows your terminal's light/dark.\nA malformed or invalid config never blocks startup: it falls back to defaults and\nshows a notice.\n\nDefine themes under `themes` and pick one with `theme`: a single name, or a\n`{ \"dark\": ..., \"light\": ... }` pair that follows the terminal live (flip your\nterminal's appearance and sideye re-themes). A theme is a full set of `#rrggbb` tokens, or\n`{ \"base\": \u003cname\u003e, ... }` that inherits another theme and overrides only the\ntokens you name. Its `\"syntax\"` is a bundled Shiki theme name, or an object\noverriding individual tokens (`keyword`, `string`, ...).\n\nUse `editor` and `ide` to set persistent command templates for `e` and `o`. Both\nuse `{file}` and `{line}` as placeholders; `{line}` is omitted automatically\nwhen no cursor line is available. Without a config value, each key falls back to\n`SIDEYE_EDITOR` / `SIDEYE_IDE`, then `$EDITOR` / `$VISUAL`, then `vim` (editor\nonly); `o` does nothing if nothing is configured. A bare editor name (no\n`{file}`) is expanded to a known template (`nvim` becomes `nvim +{line} {file}`,\n`code` becomes `code --goto {file}:{line}`, and so on). Templates are split on\nwhitespace, so file paths with spaces in the editor binary path are not\nsupported.\n\n```jsonc\n{\n  \"editor\": \"nvim +{line} {file}\",\n  \"ide\": \"code --goto {file}:{line}\",\n}\n```\n\n```jsonc\n{\n  // follow the terminal, with a custom theme on each side\n  \"theme\": { \"dark\": \"my-dark\", \"light\": \"my-light\" },\n  \"themes\": {\n    \"my-dark\": { \"base\": \"dark\", \"accent\": { \"primary\": \"#ffa7d9\" } },\n    \"my-light\": { \"base\": \"light\", \"accent\": { \"primary\": \"#b4267a\" } },\n    \"mocha\": { \"base\": \"dark\", \"syntax\": \"catppuccin-mocha\" }, // sideye chrome, Catppuccin code\n    \"tweaked\": { \"base\": \"dark\", \"syntax\": { \"keyword\": \"#ff8800\" } }, // one token changed\n  },\n}\n```\n\nPress `t` to open the theme switcher and try any of these without editing the\nconfig: filter by name, move (or hover) to preview the whole UI live, `enter`\n(or click) to apply, `esc` to revert. The switch lasts the session; `config` is\nstill where a theme is made permanent.\n\n## Requirements\n\n- git\n- a clipboard tool for copy (`y`): `pbcopy` on macOS (built in), or `wl-copy`,\n  `xclip`, or `xsel` on Linux\n- a Nerd Font for the tree's file-type icons (optional; use `--no-icons` without one)\n\n## Development\n\n```sh\nbun install\nbun run src/main.tsx     # run from source\nbun run check            # tests + typecheck\nbun run build:dist       # build standalone binaries for all targets\n```\n\n## Non-goals\n\n`sideye` is deliberately not an agent integration.\n\nNo approvals. No accept/reject protocol. No generated review explanation. No PR\nworkflow. No database. The agent never hears from `sideye`, only from you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimmy-guzman%2Fsideye","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjimmy-guzman%2Fsideye","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimmy-guzman%2Fsideye/lists"}