{"_id":"@ahmedalbarghouti/farq","_rev":"6-869dea61928ef5bbfc3070aa6749926a","name":"@ahmedalbarghouti/farq","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.1":{"name":"@ahmedalbarghouti/farq","version":"0.0.1","keywords":["git","pr","cli","diff","changelog"],"license":"MIT","_id":"@ahmedalbarghouti/farq@0.0.1","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"bin":{"farq":"dist/index.js"},"dist":{"shasum":"b7db429c969cf52490b6f46828dbc6487b1aee87","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.0.1.tgz","fileCount":47,"integrity":"sha512-PdZM4If2yU9+ERTrkG3wTbqCYVokwRuQ2WXjyzU0yeWWMsusp7D4HZYcNkqQwRSQ9hYFCGUQdv3MxotG30lZBw==","signatures":[{"sig":"MEYCIQC4ssFuUVvUGD//m8fpbh32sk4oHkMJQq4Mvhpb9wtulAIhAJzbKrpZ0u1O5Q6G6v2HcIhZn19Dqw4NrMU/5hK9zlci","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":80277},"type":"module","engines":{"node":">=20"},"gitHead":"99f465015e147ec68f2b9dea9b25cfeb0cfb7bf2","scripts":{"test":"vitest run","build":"tsc","pretest":"npm run build","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"repository":{"url":"git+https://github.com/AhmedAlbarghouti/farq.git","type":"git"},"_npmVersion":"10.8.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.24.0","execa":"^9.0.0","commander":"^13.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/farq_0.0.1_1785040855239_0.06695652929712681","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@ahmedalbarghouti/farq","version":"0.0.2","keywords":["git","pr","cli","diff","changelog"],"license":"MIT","_id":"@ahmedalbarghouti/farq@0.0.2","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"bin":{"farq":"dist/index.js"},"dist":{"shasum":"47dad4a68f46a2fde29817a8e1a5776edf32db9a","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.0.2.tgz","fileCount":61,"integrity":"sha512-cK+VxsIDJou/Cn2DRTfEUThObfvmt1eQcDXU8DcAwLgk/t8LuUYT6eUrkDg2qUBHQ+MI/ZvEkHdtfTey+15IRg==","signatures":[{"sig":"MEYCIQClA//h/MjxAE3lrWvXtWlXwFQEDoIPN1qx8ZTAtIbuagIhAO24lzagzk1s9x1JV4WaYxArQ6zrCBQXZtXIG3r9WFZW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":95971},"type":"module","engines":{"node":">=20"},"gitHead":"660bea119362a64d165d11802bbb465675f13be9","scripts":{"test":"vitest run","build":"tsc","pretest":"npm run build","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"repository":{"url":"git+https://github.com/AhmedAlbarghouti/farq.git","type":"git"},"_npmVersion":"10.8.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.24.0","execa":"^9.0.0","commander":"^13.0.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/farq_0.0.2_1785042712251_0.04419883375910438","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@ahmedalbarghouti/farq","version":"0.0.3","keywords":["git","pr","cli","diff","changelog"],"license":"MIT","_id":"@ahmedalbarghouti/farq@0.0.3","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"bin":{"farq":"dist/index.js"},"dist":{"shasum":"8b44d34d470983c26672271e020d5b3194e51ba3","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.0.3.tgz","fileCount":65,"integrity":"sha512-csas1wnEn2CFrE/9F11bADkUlOr3Bui7zAuPB7vCWwdJ29rCnVxxzDnJtsCMK/YzUp81NHeDRA4PeBtrHyJQNg==","signatures":[{"sig":"MEYCIQDK7UUO3UhkHfA2Y//LSJAkqtppTunOdWgoecCs8Tn0jAIhAJlvkAS+Qf4+mW5RX61iooa3r0JCiFFHFEwDzxySbdaV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":112716},"type":"module","engines":{"node":">=20"},"gitHead":"820a5e65f973338b6ea504695138dacec1f9d572","scripts":{"test":"vitest run","build":"tsc","pretest":"npm run build","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"repository":{"url":"git+https://github.com/AhmedAlbarghouti/farq.git","type":"git"},"_npmVersion":"10.8.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.24.0","execa":"^9.0.0","commander":"^13.0.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/farq_0.0.3_1785044455124_0.4422740125878606","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@ahmedalbarghouti/farq","version":"0.1.0","keywords":["git","pr","cli","diff","changelog"],"license":"MIT","_id":"@ahmedalbarghouti/farq@0.1.0","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"bin":{"farq":"dist/index.js"},"dist":{"shasum":"83aa8a69844a6363004e96c09fda31abb0f91c65","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.1.0.tgz","fileCount":71,"integrity":"sha512-sJZvqT9W8Gzl35rHxiywp5r9QRrIdzWqTAsxkbjC5AdISoguWfnoe9CPNg+XO77ysFvQU0VHZE/DTaB8VFjV+g==","signatures":[{"sig":"MEUCIQCWM6g8HBrkHuVletFynGWCQorosztDcBTj8z2E3+bEygIgT8/O8bH6LKT0Mwl91VYB+PeQPsUqMiXaFR/l5YGeV/M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":161613},"type":"module","engines":{"node":">=20"},"gitHead":"8f3c176df84687cdceb03ed9004533a4ef5b370f","scripts":{"test":"vitest run","build":"tsc","pretest":"npm run build","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"repository":{"url":"git+https://github.com/AhmedAlbarghouti/farq.git","type":"git"},"_npmVersion":"10.8.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.24.0","execa":"^9.0.0","commander":"^13.0.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/farq_0.1.0_1785170427119_0.04598960794845364","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ahmedalbarghouti/farq","version":"0.1.1","keywords":["git","pr","cli","diff","changelog"],"license":"MIT","_id":"@ahmedalbarghouti/farq@0.1.1","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"bin":{"farq":"dist/index.js"},"dist":{"shasum":"a269df74276f67e4ef1998e8efb966fe39576fed","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.1.1.tgz","fileCount":73,"integrity":"sha512-LxwpO7GC4PXlusnsYrrUdjypn7VLo3HkeCde0dI89/vGgrTs0l3FYL4SdmEYVMSBEzNfFVaG9Yl4FlkZuBXi3g==","signatures":[{"sig":"MEUCIQCsm2q5FFMW5v4j3tVsOAd/ZoinZfITb+x+q/rPRK1D8QIgNg4k23I9hDLd8xOdW9A/fbZECCXD3fC2pNi/R+iPSSo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":166291},"type":"module","engines":{"node":">=20"},"gitHead":"da5c2dccbb48fbe128142c9e6aa6c484a106b8b5","scripts":{"test":"vitest run","build":"tsc","pretest":"npm run build","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"repository":{"url":"git+https://github.com/AhmedAlbarghouti/farq.git","type":"git"},"_npmVersion":"10.8.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","directories":{},"_nodeVersion":"20.20.2","dependencies":{"zod":"^3.24.0","execa":"^9.0.0","commander":"^13.0.0","picocolors":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/farq_0.1.1_1785241415114_0.653050985974476","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ahmedalbarghouti/farq","version":"0.1.2","description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","type":"module","engines":{"node":">=20"},"bin":{"farq":"dist/index.js"},"scripts":{"build":"tsc","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build","pretest":"npm run build"},"keywords":["git","pr","cli","diff","changelog"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AhmedAlbarghouti/farq.git"},"dependencies":{"commander":"^13.0.0","execa":"^9.0.0","picocolors":"^1.1.1","zod":"^3.24.0"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.7.0","vitest":"^3.0.0"},"bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"homepage":"https://github.com/AhmedAlbarghouti/farq#readme","publishConfig":{"access":"public"},"_id":"@ahmedalbarghouti/farq@0.1.2","gitHead":"1f74d9393b03a34b3266ecc8df151ff44dba0cbe","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-sw3zQ3FkATxD2d1PypG6vTsNywEU0H0DnZIt3WB+6bnrWGl0wXzWBycpjngsu9TnEX0S7jXiAI6xNmZ+/g+/XQ==","shasum":"69605109be926a106ff7dcf9e7ba9ebdd60ea9bf","tarball":"https://registry.npmjs.org/@ahmedalbarghouti/farq/-/farq-0.1.2.tgz","fileCount":75,"unpackedSize":168727,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ahmedalbarghouti%2ffarq@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCjkH+5ohA++2k4zkc/7IrFmXN6E5KW2FS2mtc649tDWAIgI+tmk95B6C4whye2TUHgw2qBLwbwF/St3kzWWWYWEU8="}]},"_npmUser":{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"},"directories":{},"maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/farq_0.1.2_1785242331323_0.9292502443709929"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T04:40:54.976Z","modified":"2026-07-28T12:38:51.782Z","0.0.1":"2026-07-26T04:40:55.390Z","0.0.2":"2026-07-26T05:11:52.406Z","0.0.3":"2026-07-26T05:40:55.316Z","0.1.0":"2026-07-27T16:40:27.280Z","0.1.1":"2026-07-28T12:23:35.251Z","0.1.2":"2026-07-28T12:38:51.477Z"},"bugs":{"url":"https://github.com/AhmedAlbarghouti/farq/issues"},"license":"MIT","homepage":"https://github.com/AhmedAlbarghouti/farq#readme","keywords":["git","pr","cli","diff","changelog"],"repository":{"type":"git","url":"git+https://github.com/AhmedAlbarghouti/farq.git"},"description":"Turn git branch changes into paste-ready PR/Slack updates with optional before/after visuals","maintainers":[{"name":"ahmedalbarghouti","email":"ahmedalbarghou@gmail.com"}],"readme":"# farq\n\n**farq** (فرق, \"difference\") turns a git branch's changes into a paste-ready update: an AI-written summary plus an optional before/after visual.\n\nOne command. No servers. No API keys. Auth stays with your local `claude` or `opencode` CLI.\n\n```bash\nnpx @ahmedalbarghouti/farq@0.1.2 pr           # title + markdown body (+ image when feasible)\nnpx farq slack              # Slack mrkdwn daily update\nnpx farq json               # structured JSON\nnpx farq pr --open          # fill PR template + create with gh\n```\n\n> **0.1.2** — GitHub Release on tag publish; interactive provider picker when both CLIs are installed. CLI surface (`pr` / `slack` / `json`) is the stable bit.\n\n## Install\n\n```bash\nnpm i -g @ahmedalbarghouti/farq\nfarq --help\n```\n\nOr run without installing:\n\n```bash\nnpx @ahmedalbarghouti/farq@0.1.2 --help\n```\n\nGenerated images land in a **user cache directory outside the repo** by default (no `.gitignore` change needed). Use `--out .farq` if you want them in-tree.\n\n## Requirements\n\nChecked at runtime when needed — nothing native is bundled.\n\n| Tool | When needed |\n|------|-------------|\n| **Node ≥ 20** | always |\n| **git** | always |\n| **`claude` or `opencode`** | summarizing / generating visuals (`--provider fake` for dry runs) |\n| **Google Chrome / Chromium** | image generation or `--before`/`--after` compose (`CHROME_PATH` override OK) |\n| **`gh`** | only for `farq pr --open` |\n\nMissing a required tool → one-line fix hint + non-zero exit. Optional visuals soft-degrade (see below).\n\n## Quick start\n\n```bash\n# On a feature branch with commits (or dirty worktree):\nfarq pr --no-images          # text only\nfarq pr                      # text + visual attempt\nfarq slack                   # paste into Slack\nfarq pr --open               # create the GitHub PR\n```\n\nStdout is the artifact only (pipe-friendly):\n\n```bash\nfarq pr --no-images | pbcopy          # macOS\nfarq pr --no-images | clip            # Windows\n```\n\n## Commands\n\n### `farq pr` (default)\n\nLine 1 = title. Blank line. Then markdown body (overview, optional before/after, changes, breaking).\n\n```bash\nfarq pr\nfarq pr --provider fake --no-images\nfarq pr --before shot-a.png --after shot-b.png\nfarq pr --open\n```\n\n**`--open`** (feature branches only):\n\n1. Pushes the current branch to `origin` (`git push -u origin HEAD`) if needed  \n2. Reads `.github` PR template if present and fills known sections  \n3. Infers title style from recent merged PR titles when `gh` works  \n4. Best-effort uploads composed image(s) as prerelease assets and embeds the URL(s)  \n5. Creates the PR with `gh pr create`, or **updates** title/body with `gh pr edit` if one already exists for the branch, then opens it in the browser  \n\nOn the default branch (`main` / `master` / repo default), `--open` skips create and still prints the artifact. Titles are capped at GitHub's **256** character limit (overflow goes into the body).\n\n### `farq slack`\n\nSlack mrkdwn with category emoji. Images off by default.\n\n### `farq json`\n\nValidated change summary plus an `images` array of produced file paths.\n\n## Images (honesty policy)\n\n- Visuals come from the diff only. The summarize call also returns the grouping of items into **up to 5** visual topics by intent (same feature → one image; truly unrelated domains → separate), so no extra model round-trip is spent on it. A dedicated grouping call, then file-overlap, are the fallbacks. UI markup gets a mockup attempt; everything else gets a small concept flowchart. If a topic is infeasible, it is skipped (still exit 0).\n- Every visual is **1280×720** and carries a small **generated preview** badge.\n- Diagrams stay conceptual — no code dumps.\n- Missing Chrome / visual failure **soft-degrades** to text-only with a stderr warning (exit 0), unless you passed `--before`/`--after` (then hard-fail).\n- A local image path will not render on GitHub until the file is attached or uploaded. `--open` tries a best-effort upload (and rewrites stdout to the hosted URL).\n\n### Consistent visual style\n\nfarq owns the page frame — background, header, Before/After labels, badge, typography and the colour palette. The model only fills in the two panel interiors, and it must draw every colour, font and radius from a fixed set of CSS custom properties (`--fq-accent`, `--fq-text-muted`, `--fq-surface`, …). The only literals it may use are colours the diff states outright. That is what keeps two runs on two branches looking like the same product.\n\nTwo palettes ship today, `midnight` (default) and `daylight`:\n\n```bash\nfarq pr --theme daylight\nfarq pr --accent \"#ff5722\"\n```\n\nContent is measured and scaled to fit the frame after rendering, so a tall mockup shrinks instead of getting clipped, and the model is not asked to guess at pixel budgets.\n\n## Config\n\nPrecedence: **flags → project → global**.\n\n- Project: `.farqrc` or `.farqrc.json`\n- Global: `~/.config/farq/config.json`\n\n```json\n{\n  \"provider\": \"claude\",\n  \"tone\": \"technical\",\n  \"models\": {\n    \"claudeCheap\": \"haiku\",\n    \"opencodeCheap\": \"provider/model\"\n  },\n  \"visual\": {\n    \"theme\": \"midnight\",\n    \"accent\": \"#4dd0e1\",\n    \"maxTopics\": 3,\n    \"concurrency\": 3\n  }\n}\n```\n\n`visual.maxTopics` caps how many images a run may generate (each costs one model call), and `visual.concurrency` is how many are generated at once. `visual.fontImport` can point at a webfont stylesheet; leaving it unset keeps rendering offline and fast.\n\nIf both `claude` and `opencode` are installed and no default is set (`provider` in config or `--provider`), farq **asks which to use** in an interactive terminal. Non-interactive runs (CI, pipes) fall back to **claude** and print how to set a default.\n\n## Flags\n\n| Flag | Meaning |\n|------|---------|\n| `-r, --range` | git range (default: merge-base…HEAD, else worktree) |\n| `-p, --provider` | `claude` \\| `opencode` \\| `fake` |\n| `-t, --tone` | `technical` \\| `client` |\n| `--before` / `--after` | manual screenshots (skips generation) |\n| `--no-images` | skip visuals |\n| `-o, --out` | image output dir (default: OS user cache, outside the repo) |\n| `--model-cheap` | cheap model id for visuals |\n| `--theme` | visual palette: `midnight` \\| `daylight` |\n| `--accent` | override the theme accent colour |\n| `--max-visuals` | cap generated visuals (1–5) |\n| `-v, --verbose` | verbose logs (incl. `feasible: false` reasons) |\n| `--open` | (`pr` only) create PR with `gh` |\n\n## Exit codes\n\n| Code | Meaning |\n|------|---------|\n| `0` | success (including no feasible image / skipped `--open` on default branch) |\n| `1` | user/environment error |\n| `2` | AI failure after retry / timeout |\n\nProgress → **stderr**. Artifact → **stdout**.\n\n## Progress output\n\nEach stage is numbered, names what it is doing, and reports how long it took:\n\n```\nfarq ⠹ [2/3] summary · claude is naming things (hard part)… · 11s\nfarq ✓ summarized with claude 12.4s\nfarq ⠸ [3/3] visuals · claude is sketching the after… · 1/3 · Refund status badge · 8s\nfarq ✓ 3 visuals ready 41.2s\n```\n\nNon-interactive terminals (CI, pipes) get one plain line per stage transition instead of a spinner.\n\n## Speed\n\nA `farq pr` run makes as few model calls as it can, and overlaps everything that does not depend on the model:\n\n- Provider detection, the diff and the `gh` title lookup all start at once.\n- Topic grouping rides along on the summarize response instead of being its own request.\n- File contents for the visuals are read while the summary is still being written.\n- Each visual is a **single** HTML document with one shared stylesheet — roughly half the tokens of emitting two standalone pages, and one Chrome screenshot instead of three.\n- Visuals for different topics are generated in parallel (`visual.concurrency`).\n\nIf a run still feels slow, the lever with the most travel is `--model-cheap` (for example `haiku`), followed by `--max-visuals 1`.\n\n## Repository ops\n\n- **CI** runs on every PR and on pushes to `main` (test + build + `--help` smoke).\n- **`main` is protected** — changes go through PRs; the `CI / test` check must pass.\n- **Releases** are tag-triggered: after merge, tag `v0.1.2` (or later). The publish workflow runs tests, `npm publish`, then creates the GitHub Release (`--generate-notes`). Needs repo secret `NPM_TOKEN`.\n- **`--open` image assets:** uploaded as `farq-assets-<branch>` prereleases; farq deletes orphaned tags whose branch no longer has an open PR.\n\n## Roadmap\n\n- Harder GitHub image upload (`user-attachments` URLs)\n- Optional CDP snap of an already-running Chrome tab\n- Richer multi-template chooser\n\n## License\n\nMIT © Ahmed Albarghouti\n","readmeFilename":"README.md"}