{"id":49721477,"url":"https://github.com/vzwjustin/advisor","last_synced_at":"2026-06-14T20:01:32.275Z","repository":{"id":351569599,"uuid":"1209702882","full_name":"vzwjustin/advisor","owner":"vzwjustin","description":"Opus-led Claude Code agent team — strategist plans, Sonnet runners read and fix. Live two-way review-and-fix pipeline. Zero API calls. NOW IN RUST!","archived":false,"fork":false,"pushed_at":"2026-06-11T23:35:38.000Z","size":5691,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T00:10:24.734Z","etag":null,"topics":["agent-framework","agentic-ai","ai-agents","ai-code-review","anthropic","automated-code-review","claude","claude-code","cli","code-audit","code-quality","code-review","developer-tools","llm","multi-agent","opus","python","security-audit","sonnet","static-analysis"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/advisor-agent/","language":"Python","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/vzwjustin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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-04-13T17:39:40.000Z","updated_at":"2026-06-11T23:35:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vzwjustin/advisor","commit_stats":null,"previous_names":["vzwjustin/advisor"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/vzwjustin/advisor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzwjustin%2Fadvisor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzwjustin%2Fadvisor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzwjustin%2Fadvisor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzwjustin%2Fadvisor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vzwjustin","download_url":"https://codeload.github.com/vzwjustin/advisor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vzwjustin%2Fadvisor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34335688,"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-14T02:00:07.365Z","response_time":62,"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":["agent-framework","agentic-ai","ai-agents","ai-code-review","anthropic","automated-code-review","claude","claude-code","cli","code-audit","code-quality","code-review","developer-tools","llm","multi-agent","opus","python","security-audit","sonnet","static-analysis"],"created_at":"2026-05-09T01:42:00.926Z","updated_at":"2026-06-14T20:01:32.071Z","avatar_url":"https://github.com/vzwjustin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# advisor\n\n![advisor demo](assets/demo.png)\n\nA one-command, Opus-led code review-and-fix pipeline for Claude Code. Opus\ngoes first — does its own Glob+Grep discovery, ranks files P1–P5, and\n**writes a unique, file-aware prompt for every agent** based on what it\njust learned. Then it stays online and **actively steers the team\nthroughout**: redirecting drift, answering questions in real time, verifying\neach output the moment it lands, and adjusting the plan when a finding\nchanges the picture. Opus is the strategist that never goes idle until the\nfinal report ships. Optional fix wave applies edits the same way.\n\nNo external API calls. Runs entirely through Claude Code's native\n`TeamCreate` / `Agent` / `SendMessage` tools.\n\n**Implementation:** Rust (`advisor-rs` crate, `advisor` CLI). The Python\npackage has been superseded on `main`; see [`RUST_PORT_PLAN.md`](RUST_PORT_PLAN.md)\nand [`PORT_NOTES.md`](PORT_NOTES.md) for migration status.\n\n## Team (three-tier, default)\n\n| Role | Model | Agent type | Job |\n|------|-------|------------|-----|\n| **Advisor** | Opus 4.8 (`claude-opus-4-8`) | `generalPurpose` | Glob+Grep discovery, P1–P5 ranking, sizes explorer + coder pools, writes per-agent prompts, dispatches explore + fix waves — stays live: redirects drift, answers questions, verifies each output, adjusts plan mid-wave |\n| **Explorer pool** | Haiku 4.5 (`claude-haiku-4-5`) × N | `explore` | Read-only structural discovery on advisor-assigned file batches; reports findings to team-lead → advisor |\n| **Coder pool** | Sonnet 4.6 (`claude-sonnet-4-6`) × N | `generalPurpose` | Long-lived fix workers; each gets a domain-specific prompt (with exploration context on fix assignments); reports findings + diffs to team-lead → advisor |\n\nPriority scale: **P5** auth/secrets · **P4** user input/parsing · **P3** handlers/DB/exec · **P2** config/crypto/logging · **P1** utils/tests.\n\nLoop: **Explorer discovers → Advisor reasons → Coder fixes.**\n\n\u003cdetails\u003e\n\u003csummary\u003eLegacy two-tier mode\u003c/summary\u003e\n\nSet `max_explorers=0` or `ADVISOR_MAX_EXPLORERS=0` to skip the explorer\nwave and run the original advisor + Sonnet-runner pipeline.\n\n\u003c/details\u003e\n\n## Install\n\n### From source (recommended)\n\nRequires [Rust](https://rustup.rs/) **1.74+**. The binary has **zero runtime\ndependencies** — only the Rust toolchain is needed to build.\n\n```bash\ngit clone https://github.com/vzwjustin/advisor \u0026\u0026 cd advisor\ncargo install --path .\nadvisor install          # wire SKILL.md + CLAUDE.md nudge (idempotent)\nadvisor status           # confirm what landed where\n```\n\nAfter edits, reinstall with `cargo install --path . --force`.\n\n\u003cdetails\u003e\n\u003csummary\u003eOther install methods\u003c/summary\u003e\n\n```bash\n# Install a tagged release without cloning (needs Rust + git)\ncargo install --git https://github.com/vzwjustin/advisor --tag v0.8.7\n\n# Run without installing\ncargo run -- version\ncargo run -- pipeline src/\n\n# PyPI (published releases — package name advisor-agent)\npipx install advisor-agent\npipx upgrade advisor-agent\n\n# Plain pip / uv\npip install advisor-agent\nuv tool install advisor-agent\n```\n\nPyPI releases may trail `main` during the Rust migration. For the latest\nfeatures (three-tier architecture, Rust port), build from source.\n\n\u003c/details\u003e\n\nThe first `advisor install` wires `~/.claude/CLAUDE.md` and the `/advisor`\nslash command automatically. The CLAUDE.md block also embeds a 4-rule\n**Behavioral Guidelines** section (Think Before · Simplicity First ·\nSurgical Changes · Goal-Driven Execution). Every upgrade prints a \"What's\nnew\" digest from `CHANGELOG.md`.\n\n\u003cdetails\u003e\n\u003csummary\u003eManage the nudge / skill manually\u003c/summary\u003e\n\n```bash\nadvisor status               # install health check\nadvisor install              # append / update the nudge + skill (idempotent)\nadvisor install --check      # dry-run: print status, exit 3 if anything missing\nadvisor uninstall            # cleanly remove the nudge + skill\nadvisor install --path /x    # target a different CLAUDE.md\n```\n\nOpt out of auto-install with `ADVISOR_NO_NUDGE=1`. Suppress the diagnostic TTY spinner with `ADVISOR_QUIET=1`. The CLAUDE.md block is\nwrapped in `\u003c!-- advisor:nudge:start --\u003e` / `\u003c!-- advisor:nudge:end --\u003e`\nmarkers so reinstalls update in place.\n\n\u003c/details\u003e\n\n## Usage\n\nInvoke from inside Claude Code:\n\n```\n/advisor                    # review the cwd\n/advisor src/               # review a specific dir\n/advisor review the auth flow      # add scope context\n```\n\nOr use the standalone CLI to inspect the prompts and plans:\n\n```bash\nadvisor pipeline src/                  # full pipeline reference (three-tier by default)\nadvisor protocol                       # print the strict team-lifecycle protocol\nadvisor plan src/                      # rank local files, print dispatch plan\nadvisor plan src/ --json               # same, machine-readable for `jq` etc.\nadvisor plan src/ --format json        # explicit selector (alias of --json; pretty overrides)\nadvisor plan src/ --sarif out.sarif    # SARIF 2.1.0 output for Code Scanning\nadvisor audit RUN_ID [TARGET]          # post-hoc diagnostic for a completed run\nadvisor prompt advisor src/            # the advisor's prompt body\nadvisor prompt runner src/ --runner-id 1   # a coder's bootstrap prompt\nadvisor prompt verify src/ \u003c findings  # verify-pass prompt\nadvisor status                         # install health check\nadvisor status --json                  # JSON-formatted health for scripting\nadvisor doctor                         # extended diagnostic: git/claude/codex/env checks\nadvisor install                        # install nudge + /advisor skill (prints What's new on upgrade)\nadvisor update                         # self-upgrade via PyPI, then re-runs install\nadvisor changelog [VERSION]            # print bundled CHANGELOG section(s); --since X.Y.Z for a digest\nadvisor uninstall                      # remove nudge + /advisor skill\nadvisor ui                             # launch local web dashboard on 127.0.0.1:8765 (Findings · Live · Plan · Run config · Cost)\nadvisor live tail                      # tail the live event stream (the Live tab subscribes to this)\nadvisor history                        # recent findings from .advisor/history.jsonl\nadvisor history --stats                # aggregate: confirm rate, breakdowns, top files\nadvisor baseline create                # snapshot current findings as baseline\nadvisor baseline diff                  # compare current run vs. baseline\nadvisor checkpoints                    # list saved plan checkpoints\nadvisor checkpoints --rm RUN_ID        # delete a single checkpoint\nadvisor checkpoints --clear            # delete all checkpoints\nadvisor presets                        # list available rule-pack presets\nadvisor suppressions --list            # list active false-positive suppressions\nadvisor version                        # print version + environment info\n```\n\nEvery subcommand's `target` defaults to `.` (current directory). Piping a\nlong scope description is supported via `--context -` (reads stdin).\n\nFlags: `--team`, `--file-types`, `--max-runners` (advisory — Opus may\nexceed for large repos), `--min-priority`, `--context`, `--advisor-model`,\n`--runner-model`. Default models: `claude-opus-4-8` / `claude-sonnet-4-6` / `claude-haiku-4-5` (full IDs pin the version; bare aliases `opus`/`sonnet`/`haiku` resolve to the latest at spawn time). Mid-form IDs like `opus-4-8` are auto-normalized to `claude-opus-4-8`.\n\nEnvironment overrides (also read by `default_team_config`):\n\n| Variable | Default | Effect |\n|----------|---------|--------|\n| `ADVISOR_MODEL` | `claude-opus-4-8` | Advisor model |\n| `ADVISOR_RUNNER_MODEL` | `claude-sonnet-4-6` | Coder model |\n| `ADVISOR_EXPLORER_MODEL` | `claude-haiku-4-5` | Explorer model |\n| `ADVISOR_MAX_RUNNERS` | `5` | Suggested coder pool size |\n| `ADVISOR_MAX_EXPLORERS` | same as max runners | Explorer pool size (`0` = legacy two-tier) |\n| `ADVISOR_MIN_PRIORITY` | `3` | Minimum P-rank to include |\n| `ADVISOR_FILE_TYPES` | `*.*` | Glob filter for `advisor plan` |\n| `ADVISOR_EXPLORER_OUTPUT_CHAR_CEILING` | `40000` | Explorer output budget |\n| `ADVISOR_EXPLORER_FILE_READ_CEILING` | `40` | Explorer distinct-file-read cap |\n\nContext-pressure knobs (reduce coder context exhaustion):\n`--max-fixes-per-runner N` · `--large-file-line-threshold N` · `--large-file-max-fixes M` · `--runner-output-char-ceiling K` · `--runner-file-read-ceiling L`.\n\nAutomation flags: `--json` on `status`/`plan`/`install --check`,\n`--quiet` on `install`/`uninstall`, `--strict` on `status`/`install`/`uninstall`\n(exit `3` when nothing changed or the install is unhealthy).\n\nColors are on by default. Opt out with `NO_COLOR=1` or `TERM=dumb`.\n\n## Excluding files (`.advisorignore`)\n\nDrop an `.advisorignore` file into your project root to skip paths during\n`advisor plan` and the live pipeline:\n\n```gitignore\n# comments begin with #\ntests/            # skip directories (trailing slash)\n*.md              # skip by filename glob\nvendor/\ngenerated/**/*.py # ** recursive globs are supported\n```\n\nPatterns follow `fnmatch` semantics for filename matches, and use\n`PurePath.match` when `**` is present. Bare words match any path\ncomponent (`docs` matches both `docs/` and `foo/docs/bar.py`).\n\n## Rust library\n\nThe crate root re-exports the same surface the Python package exposed:\n\n```rust\nuse advisor::{\n    default_team_config, TeamConfig, TeamConfigInput,\n    build_advisor_prompt, build_explorer_prompt, build_explorer_pool_agents,\n    build_coder_prompt, build_runner_pool_prompt, build_runner_dispatch_messages,\n    build_fix_assignment_message, build_verify_dispatch_prompt, build_verify_message,\n    render_pipeline, rank_files, create_focus_tasks, parse_findings_from_text,\n    estimate_cost, findings_to_sarif, resolve_version,\n};\n\nlet config = default_team_config(TeamConfigInput::new(\"src/\"));\nprintln!(\"{}\", render_pipeline(\u0026config));\n```\n\nBuilder functions return plain strings or JSON-friendly structs — drop them\ninto Claude Code `Agent(...)` or `SendMessage(...)` calls. See `src/lib.rs`\nfor the full export list.\n\n## Modules (`src/`)\n\n| Module | Role |\n|--------|------|\n| `config.rs` | `TeamConfig`, env-var assembly, model validation |\n| `orchestrate/` | Advisor, explorer, and coder prompt builders; `render_pipeline` |\n| `rank.rs` | `rank_files`, keyword-signal P1–P5 ranking |\n| `focus.rs` | `create_focus_tasks` / `create_focus_batches`, plan formatters |\n| `verify.rs` | `Finding`, `parse_findings_from_text`, verify-pass builders |\n| `runner_budget.rs` | Per-coder output-char budget and rotation |\n| `install.rs` | Idempotent CLAUDE.md nudge + `/advisor` skill install |\n| `doctor.rs` | Git / Claude / Codex / install health checks |\n| `audit.rs` | Post-hoc run transcript diagnostics |\n| `baseline.rs` | Finding baselines for drift detection |\n| `checkpoint.rs` | Plan checkpoints for `--resume` |\n| `cost.rs` | Per-tier token and cost range estimates |\n| `git_scope.rs` | `--since` / `--staged` / `--branch` scoping |\n| `history.rs` | Confirmed findings log (`.advisor/history.jsonl`) |\n| `sarif.rs` | SARIF 2.1.0 serializer |\n| `suppressions.rs` | Per-rule false-positive suppressions |\n| `skill_asset.rs` | Bundled `/advisor` skill content |\n| `web.rs` | Local dashboard (`advisor ui`) |\n| `live.rs` | Ephemeral event stream for the Live tab |\n\nPrompt templates live under `src/assets/` (`advisor.txt`, `explorer.txt`, …).\n\n## Live dashboard (new in 0.8.0)\n\nRun `advisor ui` and open http://127.0.0.1:8765 to watch a `/advisor`\nrun in real time without keeping Claude Code in the foreground. The\n**Live** tab polls `/api/events` every 2s and renders the team-lead's\nevent stream as a feed: each runner spawn, every report relay, every\nfix dispatch, and the final run summary. Newly-arrived rows briefly\nflash; FIFO-trimmed at 500 rows; respects `prefers-reduced-motion`.\n\nThe team-lead emits events via `advisor live record` at three\ncheckpoints (`run_start`, every `report_relay`, `run_end`), instructed\nby the bundled `/advisor` skill body. Events are best-effort: a failed\nwrite never halts the pipeline. Users who never start `advisor ui` see\nno behavior change — the events file just accumulates harmlessly in\n`\u003ctarget\u003e/.advisor/live/events.jsonl`.\n\nThe event store is deliberately separate from `history.jsonl`:\n- `history.jsonl` — authoritative CONFIRMED findings; drives ranker\n  boost, SARIF emission, repeat-offender analytics.\n- `live/events.jsonl` — ephemeral event feed; opaque to the\n  orchestrator, advisory to the dashboard, free-form payload.\n\nFor ad-hoc inspection from the terminal: `advisor live tail --limit 50`\n(`--json` for scripting). `advisor live clear` removes the file; the\ncursor preserves cleanly so the next run resumes the stream.\n\n## Orchestration rules\n\n- `TeamCreate` before any agent spawn; `TeamDelete` before creating a new team.\n- Opus goes first — no explorers or coders until Opus's first pass produces pool sizes.\n- Each agent is spawned with the **verbatim per-agent prompt** from\n  Opus's dispatch plan. Don't substitute a generic template.\n- Dispatch agents in a **single message** with `run_in_background=true`\n  so they come up in parallel.\n- Every agent prompt must end with a `SendMessage(...)` — agents go idle\n  silently otherwise.\n- Shut down teammates individually by name; broadcast shutdown does not work.\n\nSee `CLAUDE.md` for the full protocol.\n\n## Development\n\n```bash\ngit clone https://github.com/vzwjustin/advisor \u0026\u0026 cd advisor\ncargo build\nmake check        # clippy + fmt --check + test\ncargo test        # 125+ parity tests (Linux, macOS, Windows in CI)\ncargo fmt         # format\ncargo clippy --all-targets\n```\n\nRelease checklist: `make release-check` (prints version + tag commands).\n\nVersion lives in `Cargo.toml`; tag with `git tag vX.Y.Z \u0026\u0026 git push origin vX.Y.Z`.\n\n## GitHub Action\n\nReusable workflow that runs `advisor plan`, uploads SARIF 2.1.0 output to\nGitHub Code Scanning, and (optionally) posts a PR comment. Paste this into\n`.github/workflows/advisor.yml` in your repo:\n\n```yaml\nname: Advisor\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\njobs:\n  advisor:\n    uses: vzwjustin/advisor/.github/workflows/advisor.yml@v0.8.7\n    with:\n      target: \".\"\n      min-priority: 3\n      preset: \"python-web\"   # optional rule-pack tuning\n      post-pr-comment: false\n```\n\n\u003e [!NOTE]\n\u003e The `fail-on` parameter is enforced by a SARIF-parsing step that runs after `actions/upload-sarif`. Because `advisor plan --sarif` emits an empty-results document by design, the gate is a no-op unless a downstream step replaces `advisor.sarif` with real findings (e.g. SARIF captured from a live `/advisor` run). Threshold semantics match `advisor audit --fail-on`: the gate reads each result's `properties.severity` (which advisor's SARIF writer emits) so `critical` and `high` are correctly distinguished. For third-party SARIF that lacks `properties.severity`, the gate falls back to the SARIF level field (CRITICAL/HIGH → `error`, MEDIUM → `warning`, LOW → `note`) which cannot distinguish CRITICAL from HIGH.\n\nOr roll your own: any CI system can run `advisor plan --sarif advisor.sarif`\nand upload the file to whatever scanner you use.\n\n## Presets\n\nCurated rule-pack bundles tune file-type defaults and priority keywords for\ncommon stacks:\n\n| Preset             | Stack                        | Defaults                           |\n|--------------------|------------------------------|------------------------------------|\n| `general-python`   | Generic Python codebase      | `*.py`, no stack-specific boosting |\n| `python-web`       | Flask / Django / FastAPI     | `*.py`, P5 auth keywords           |\n| `python-cli`       | argparse / click CLIs        | `*.py`, P3 subprocess keywords     |\n| `node-api`         | Express / Fastify / Koa      | `*.js,*.ts`, P5 JWT/session        |\n| `typescript-react` | React + TS                   | `*.ts,*.tsx`, P4 DOM sinks         |\n| `go-service`       | net/http services            | `*.go`, P3 net/http/sql            |\n| `rust-crate`       | library / crate              | `*.rs`, P3 unsafe/transmute        |\n\n```bash\nadvisor plan src/ --preset python-web\nadvisor presets            # list presets\nadvisor presets --json     # machine-readable\n```\n\n## Automation flags\n\nFindings come from `advisor audit` (the verify pass) — `advisor plan`\nprints the dispatch ranking. The gating + emit flags that depend on\nfindings (`--fail-on`, `--format pr-comment`, `--baseline`) only exist\non `audit`. `--sarif` exists on both — `plan` writes an empty-results\ndocument (no findings yet), `audit` writes the real one.\n\n| Flag                       | Applies to      | Effect                                    |\n|----------------------------|-----------------|-------------------------------------------|\n| `--sarif PATH`             | `plan`, `audit` | Write SARIF 2.1.0 for Code Scanning       |\n| `--fail-on LEVEL`          | `audit`         | Exit 4 if any finding ≥ LEVEL             |\n| `--format pr-comment`      | `audit`         | Emit a PR-body-ready markdown summary     |\n| `--baseline PATH`          | `audit`         | Suppress findings matching a baseline     |\n| `--no-history`             | `plan`          | Ignore history for deterministic CI plans |\n| `--json` / `--output FILE` | `plan`, `audit` | Machine-readable output                   |\n\nExit codes: `0` clean · `4` `--fail-on` threshold tripped · `3` `--strict`\nno-op or unhealthy install · `2` argparse / user error · `1` unexpected.\n\n## Findings lifecycle\n\n- **`advisor history`** — recent confirmed findings from `.advisor/history.jsonl` (`--stats` for an aggregate view)\n- **`advisor baseline create`** — snapshot current findings as an accepted baseline\n- **`advisor baseline diff`** — compare current run vs. baseline\n- **`.advisor/suppressions.jsonl`** — per-rule, per-file suppressions with\n  expiry dates (run `advisor suppressions` to list, add `--expired` to filter)\n\n## Further reading\n\n- [`docs/architecture.md`](docs/architecture.md) — module dependency graph,\n  runtime flow, data contract, design invariants\n- [`docs/prompts.md`](docs/prompts.md) — prompt engineering notes for\n  contributors modifying prompt templates\n- [`RUST_PORT_PLAN.md`](RUST_PORT_PLAN.md) — Rust migration plan\n- [`PORT_NOTES.md`](PORT_NOTES.md) — Python parity status\n\n## License\n\n[MIT](LICENSE) — Copyright (c) 2025–2026 Justin Adams ([@vzwjustin](https://github.com/vzwjustin)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzwjustin%2Fadvisor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvzwjustin%2Fadvisor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvzwjustin%2Fadvisor/lists"}