{"id":49298173,"url":"https://github.com/aurokin/agentscan","last_synced_at":"2026-06-02T06:02:55.755Z","repository":{"id":353583939,"uuid":"1196517730","full_name":"aurokin/agentscan","owner":"aurokin","description":"Rust CLI and daemon for discovering and managing AI agent panes in tmux.","archived":false,"fork":false,"pushed_at":"2026-06-02T01:03:56.000Z","size":4344,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T01:12:59.973Z","etag":null,"topics":["ai-agents","cli","daemon","developer-tools","local-first","rust","tmux"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aurokin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","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-03-30T19:22:40.000Z","updated_at":"2026-06-02T00:59:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aurokin/agentscan","commit_stats":null,"previous_names":["aurokin/agentscan"],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/aurokin/agentscan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurokin%2Fagentscan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurokin%2Fagentscan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurokin%2Fagentscan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurokin%2Fagentscan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aurokin","download_url":"https://codeload.github.com/aurokin/agentscan/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aurokin%2Fagentscan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33808702,"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-02T02:00:07.132Z","response_time":109,"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":["ai-agents","cli","daemon","developer-tools","local-first","rust","tmux"],"created_at":"2026-04-26T05:01:15.021Z","updated_at":"2026-06-02T06:02:55.747Z","avatar_url":"https://github.com/aurokin.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/agentscan-logo.png\" alt=\"agentscan\" width=\"280\" /\u003e\n\u003c/p\u003e\n\n# agentscan\n\n`agentscan` is a standalone replacement stack for tmux agent discovery.\n\nThe current shell workflow in `~/.dotfiles` does too much work at TUI launch time:\n\n- full tmux pane scans\n- shell-heavy parsing\n- optional process inspection\n- pane capture heuristics for activity state\n\nThis project starts from a simpler baseline:\n\n- a Rust binary\n- tmux metadata as the primary source of truth\n- no `ps` scan in the steady-state path\n- no fast/full mode split\n- plug-and-play detection as a core product invariant\n- no provider log, transcript, or session-store scanning in the default\n  detection path\n\nCommon agent panes should be discoverable without asking users to install\nprovider hooks, extensions, launch wrappers, or shell integration. Those\nintegrations may eventually enrich labels, session ids, or state, but they are\ndeep-roadmap additions behind source analysis, local probing, and conservative\nplug-and-play detection.\n\nThe shell scripts in `~/.dotfiles` are reference material, not the target design.\nThey are useful for understanding current user-visible behavior and edge cases, but\nthey do not define a requirement to preserve the same implementation strategy,\nflags, heuristics, interactive flow, or output shape.\n\nThis repository is the central source for the product. If tmux helpers or shell\nintegration are still needed while the product matures, they should live here\nrather than being developed inside host-specific dotfiles. The host workflow can\nremain unchanged until `agentscan` is ready to replace it.\n\n## Docs\n\n- `docs/index.md`: map of the repo's progressively disclosed documentation\n- `AGENTS.md`: repo-local agent guardrails and conventions\n- `ROADMAP.md`: durable product direction, boundaries, and decision log\n- `CHANGELOG.md`: unreleased user-facing changes and migration notes\n- `docs/architecture.md`: runtime model, daemon/socket contract, command families, and guardrails\n- `docs/integration.md`: wrapper metadata, daemon-backed automation surfaces,\n  picker/live stream contracts, shell boundary, and migration posture\n- `docs/daemon-operations.md`: daemon auto-start, status, telemetry, and troubleshooting\n- `docs/desktop.md`: desktop app operation, local/SSH profiles, picker behavior, and debug log\n- `docs/desktop-client-contract.md`: local/SSH desktop command contract and failure surfaces\n- `docs/harness-engineering.md`: progressively disclosed harness engineering approach for the repo\n- `docs/macos-release-signing.md`: local and GitHub Actions Developer ID signing/notarization workflow\n- `docs/desktop-release-smoke.md`: macOS desktop build, signing, install, and smoke workflow\n- `docs/desktop-platform-posture.md`: desktop platform posture and future adapter seams\n\nActive milestone sequencing lives in Linear. The repo docs are intentionally for\nstable engineering guidance and operator-facing contracts, not live task\ntracking.\n\n## Quality Gates\n\nCurrent local baseline:\n\n- `cargo fmt --all --check`\n- `cargo clippy --all-targets --all-features -- -D warnings`\n- `cargo clippy --all-targets --all-features -- -D warnings -W clippy::cognitive_complexity -W clippy::too_many_arguments`\n- `cargo test`\n\nDesktop shell checks:\n\n- `cd desktop \u0026\u0026 npm run build`\n- `cargo test --manifest-path desktop/src-tauri/Cargo.toml`\n- `cd desktop \u0026\u0026 npm run tauri dev`\n- `scripts/check-desktop-version.sh`\n\nCurrent test coverage also includes committed file-based fixtures for representative\ntmux title snapshots and snapshot envelopes, plus property tests for parser and\nnormalization invariants, so parser and schema regressions can be checked against\nboth stable examples and generated inputs.\n\nDaemon reliability is also covered by isolated integration tests that start a\ntemporary tmux server, run the daemon, and assert state behavior for title\nchanges, pane/window add-remove events, session add/remove and rename events,\nwindow rename events, attached-session removal, wrapper-metadata helper flows,\nand tmux server disappearance.\n\nCurrent performance tooling:\n\n- `cargo bench --bench core_paths -- --noplot`\n\nThe benchmark target covers snapshot row parsing, row-to-pane conversion,\nsnapshot deserialization, and interactive row rendering against committed\nfixtures.\n\n## Current Architecture\n\nThe core architecture is a daemon-required, socket-backed model:\n\n- the daemon is the single source of live pane state\n- normal consumers auto-start the daemon unless explicitly opted out; on macOS,\n  detached auto-start runs only after parent-side executable trust preflight\n  succeeds\n- consumers read full `SnapshotEnvelope` frames over a Unix socket\n- the cache file is removed as an IPC boundary\n- the interactive command is `agentscan tui`\n- the `agentscan cache` command family is removed; use `agentscan snapshot`\n  for raw snapshot envelopes\n- `agentscan scan` and refresh-capable command flags remain direct tmux\n  recovery paths that do not start or require the daemon\n\nActive future sequencing lives in Linear.\n\n## Current Shipped Scope\n\nThe current branch centers on:\n\n- direct tmux snapshots from `tmux list-panes -a -F ...`\n- a control-mode daemon that serves socket snapshots\n- repo-local tmux helpers that stay thin and call the CLI\n- a Mac-first Tauri desktop shell in `desktop/` that talks to the installed\n  `agentscan` CLI through a narrow IPC/preflight boundary\n- local and SSH desktop profiles that consume the same CLI command contract\n- a runtime split by concern under `src/app/` rather than a single monolithic application file\n\nIt can:\n\n- run the daemon with tmux control mode and auto-start it for normal consumers,\n  including signed/trusted macOS binaries\n- fail fast when the daemon loses tmux, leaving restart policy to an external supervisor\n- preserve raw tmux `session_id` and `window_id` values in the canonical pane model for socket consumers and local daemon updates\n- refresh individual panes on daemon title and metadata updates, refresh affected windows or sessions when tmux emits stable ids for those scopes, and keep a periodic full reconcile as a safety net\n- preserve helper-published metadata across unrelated daemon writes\n- bypass daemon-backed state with a fresh direct tmux snapshot for refresh-capable one-shot commands using `-f` / `--refresh`\n- list panes through the default `list` flow\n- inspect a pane by `pane_id`, including provider source, status source, classification reasons, and targeted `/proc` fallback decisions\n- focus a pane by `pane_id`, with attached-client fallback when no explicit tty is provided and tested multi-client selection of the most recent attached client\n- open an interactive `agentscan tui` UI directly from the Rust binary\n- bootstrap `agentscan tui` from a live daemon socket subscription, show\n  connection state, preserve the last snapshot while reconnecting, and avoid\n  cache/direct-tmux discovery fallback in the TUI\n- page TUI rows when more panes exist than can fit the current key budget or viewport\n- redraw the TUI immediately on terminal resize and keep keys stable for rows that remain visible on the current page\n- infer likely agent panes from tmux metadata\n- normalize noisy provider prefixes and wrapper/script suffixes out of display labels for title-driven panes\n- populate `display.activity_label` for meaningful title-driven panes and authoritative wrapper labels, including non-generic Codex wrapper titles\n- keep labels conservative: show what tmux metadata actually tells us and avoid inventing richer task names from weak signals\n- use targeted live process evidence, including pane TTY foreground process\n  groups, only for unresolved ambiguous panes\n- use tightly scoped provider-specific pane output parsing as a final status\n  fallback for already-identified supported providers. When this path wins, JSON\n  reports `status.source=\"pane_output\"`.\n- treat Cursor CLI as metadata-first: command detection is enough to identify the provider, but generic tmux titles fall back to conservative pane labels until wrappers publish stronger metadata\n- infer Cursor CLI busy/idle status from the current Cursor footer only after\n  provider identity is already established\n- infer GitHub Copilot busy/idle status from current Copilot prompt, footer,\n  thinking, and trust-prompt shapes only after provider identity is already\n  established\n- classify Factory Droid CLI panes from the exact `droid` command or explicit\n  metadata aliases, treat `⛬ ...` titles as display labels only after provider\n  identity is known, and infer busy/idle from the current Droid prompt/footer\n  only after identity is established\n- classify Grok and Hermes panes from provider-specific command/title/metadata\n  evidence while keeping pane-output status fallback provider-scoped\n- resolve unresolved Claude Code launcher panes from targeted process evidence, including Claude Code CLI paths and tmux teammate-spawn argv/env markers\n- classify Antigravity CLI panes from the exact native `agy` command while\n  keeping status unknown until wrapper metadata or a future provider-scoped\n  output fallback supplies direct state\n- classify Pi coding agent panes from upstream-observed Greek terminal titles,\n  Linux `PI_CODING_AGENT=true` process evidence, and targeted package or shim\n  path evidence while keeping bare `pi` commands conservative\n- classify opencode panes from upstream-observed `OpenCode` / `OC | ...`\n  terminal titles, targeted package or shim path evidence, and Linux\n  `OPENCODE` process evidence while keeping default opencode status unknown\n  unless explicit metadata publishes state\n- publish, clear, and consume explicit wrapper metadata via pane-local `@agent.*` tmux options\n- emit canonical snapshot JSON\n\nAutomation contract:\n\n- `agentscan tui` is interactive-only and is not a supported machine-readable surface\n- `agentscan popup` has been removed rather than kept as a compatibility alias\n- local unsupported flags on the interactive command should remain normal parse errors,\n  and root-level `--format` routed to it should fail with migration\n  guidance; do not add TUI-specific compatibility shims to intercept or\n  emulate legacy formatting\n- `agentscan list --format json` is the supported machine-readable command for downstream consumers in normal automation flows\n- `agentscan list --all --format json` is the supported way to include non-agent panes in that machine-readable output\n- `agentscan snapshot --format json` exposes the raw snapshot envelope when a consumer explicitly needs envelope details rather than the normal `list` view\n- `agentscan subscribe --format json` exposes live JSON Lines daemon events for\n  terminal-adjacent tools and desktop clients\n- `agentscan providers --format json` exposes supported provider names,\n  display markers for all icon modes, marker codepoints, and matching aliases\n- `agentscan hotkeys --format json` exposes the shared picker row model\n- `agentscan hotkey \u003ckey\u003e` activates a shared picker key through the same focus path\n- `agentscan tmux hotkey \u003ckey\u003e` activates a shared picker key from tmux binds and reports misses with `display-message`\n- TUI-shaped TSV or JSON output is not a supported long-term contract\n\nOperational commands:\n\n- `agentscan`\n- `agentscan scan`\n- `agentscan list`\n- `agentscan inspect \u003cpane_id\u003e`\n- `agentscan focus \u003cpane_id\u003e`\n- `agentscan daemon start`\n- `agentscan daemon run`\n- `agentscan daemon status`\n- `agentscan daemon stop`\n- `agentscan daemon restart`\n- `agentscan snapshot`\n- `agentscan subscribe`\n- `agentscan providers`\n- `agentscan hotkeys`\n- `agentscan hotkey \u003ckey\u003e`\n- `agentscan tui`\n- `agentscan tmux hotkey \u003ckey\u003e`\n- `agentscan tmux set-metadata`\n- `agentscan tmux clear-metadata`\n\n`agentscan` without a subcommand runs the default daemon-backed `list` flow.\nFor local ad-hoc macOS builds or debugging detached-start failures, run the\ndaemon in the foreground:\n\n```sh\nagentscan daemon run\n```\n\nFor repo-local tmux `display-popup` testing without installing the binary on\n`PATH`, use `tmux display-popup -E \"$PWD/target/debug/agentscan\" tui` after\nbuilding once.\n\n## Configuration\n\n`agentscan` reads optional user configuration from:\n\n```toml\n# ${XDG_CONFIG_HOME:-~/.config}/agentscan/config.toml\nicons = \"emoji\"\npicker_keys = [\n  \"1\", \"2\", \"3\", \"4\", \"5\",\n  \"Q\", \"E\", \"R\", \"F\", \"G\", \"T\",\n  \"Z\", \"X\", \"C\", \"V\", \"B\",\n]\ndisable_reconcile = false\ndisable_proc_fallback = false\n```\n\nSupported icon modes:\n\n- `emoji`: default provider icons for terminals without Nerd Font coverage\n- `nerd-font`: current Nerd Font provider icons\n- `nerd-font-patched`: custom agent glyphs from the `agent-icons-v8` patched\n  font manifest; requires a terminal font patched with those private-use\n  codepoints\n\nIcon mode precedence is CLI, then environment, then config file, then default:\n\n```sh\nagentscan list --icons nerd-font\nAGENTSCAN_ICONS=nerd-font-patched agentscan tui\n```\n\nPicker keys use the config file only. If omitted, the default order is\n`1 2 3 4 5 Q E R F G T Z X C V B`. Custom keys remap those 16 selection\nslots, so the list must contain exactly 16 unique single ASCII letters or\ndigits; letters are normalized case-insensitively. `N` and `P` are reserved for\nTUI paging.\n\nDiagnostic toggles use environment values first, then config file values, then\nthe built-in `false` default:\n\n```sh\nAGENTSCAN_DISABLE_RECONCILE=1 agentscan daemon run\nAGENTSCAN_DISABLE_PROC_FALLBACK=1 agentscan daemon run\n```\n\n`disable_reconcile` turns off the daemon's periodic/timeout reconcile safety\nloop. `disable_proc_fallback` skips process-tree inspection for ambiguous panes.\nThe daemon reads these runtime options on startup. Both are intended for\ndebugging and observability, not as recommended defaults.\n\n`agentscan providers` previews the active text icon mode, and\n`agentscan providers --format json` exposes every icon mode and codepoint for\nscripts or font tweaking.\n\n## Automation Migration\n\nMachine-readable consumers should not call `agentscan tui`. The legacy\n`agentscan popup` command has been removed and is not a compatibility path.\n\nUse:\n\n- `agentscan list --format json` for the supported JSON automation surface\n- `agentscan list --all --format json` if the consumer previously depended on interactive `--all`\n- `agentscan snapshot --format json` only when the consumer intentionally needs the raw snapshot envelope\n- `agentscan subscribe --format json` for live JSON Lines daemon events\n- `agentscan daemon status --format json` for daemon lifecycle and readiness checks\n- `agentscan providers --format json` for supported provider names, display\n  markers for all icon modes, marker codepoints, and aliases\n- `agentscan hotkeys --format json` for shared picker rows\n- `agentscan hotkey \u003ckey\u003e` for strict picker-key activation from automation\n- `agentscan tmux hotkey \u003ckey\u003e` for tmux key bindings that should display\n  expected picker misses without opening command output view\n- `agentscan scan` or supported `--refresh` flags when a script intentionally\n  needs direct tmux state instead of daemon state\n\nKeep `agentscan tui` in tmux key bindings and other human-facing launch paths.\nDo not call it from scripts that parse stdout, and do not depend on terminal\nrendering, row ordering, key labels, or error frame text as a data contract.\n\nThe removed `agentscan cache` command family and `AGENTSCAN_CACHE_PATH` are not\ncompatibility paths. Use daemon socket snapshots through the documented command\nsurfaces instead.\n\nIf an automation consumer cannot migrate because required fields are missing from\nthe documented JSON surfaces, treat that as an API gap to close in `list` or\nsnapshot JSON. Do not add `--format` back to the interactive command, including\nhidden or compatibility-only parser paths.\n\n## Reference Behavior\n\nThe existing shell stack is still relevant as an input to design work. It shows\nthe kinds of things users currently rely on:\n\n- pane discovery across tmux\n- stable pane targeting for navigation and focus\n- provider inference and title normalization\n- interactive pane selection and targeting\n- rough busy/idle detection for some providers\n\nBut those scripts should be treated as a source of examples and migration context,\nnot as a contract for the Rust implementation. `agentscan` is free to adopt a\ndifferent internal model and different external commands as long as the new design\nis faster, clearer, and intentionally documented.\n\nThe useful design inputs are mostly at the data-model level:\n\n- wrapper-aware provider classification\n- separation between raw pane metadata and cleaned display labels\n- explicit `unknown` status when a fast answer is better than an expensive guess\n- explicit status provenance. `status.source` can be `tmux_title`,\n  `pane_metadata`, `pane_output`, or `not_checked`; `pane_output` means a\n  provider-scoped current prompt/footer pattern supplied the status after\n  stronger metadata/title sources were unavailable.\n- stable pane identity for downstream consumers such as TUIs or focus commands\n\n## CLI Families\n\nThe CLI centers on:\n\n- `agentscan daemon` as the primary runtime\n- `agentscan scan` for direct tmux snapshots\n- `agentscan list` for normal human output and the supported JSON automation surface\n- `agentscan inspect` for one-pane diagnostics\n- `agentscan focus` for pane targeting\n- `agentscan snapshot` for raw snapshot-envelope output\n- `agentscan subscribe` for live JSON Lines daemon events\n- `agentscan providers` for supported provider/icon metadata\n- `agentscan hotkeys` for the shared picker row model\n- `agentscan hotkey` for picker-key activation\n- `agentscan tui` for interactive pane selection only\n- `agentscan tmux` for tmux-facing integration helpers, including tmux-safe\n  hotkey activation\n\nShell remains the right place for aliases, launch wrappers, tmux binds, and\nTUI entrypoints. `agentscan` owns pane discovery, provider classification,\nmetadata consumption, daemon lifecycle policy, and the documented JSON surfaces\nthose shell entrypoints can call.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faurokin%2Fagentscan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faurokin%2Fagentscan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faurokin%2Fagentscan/lists"}