{"repo": "adamcongdon/git-glass", "files": {"README.md": {"22ad3090500a20227bbab3e83b549d572ecede51": {"t": 1785674533.253344, "n": 5537, "h": "b2642625052101b4", "c": "# Git Glass\n\nA local-first PWA that surfaces repository status, triages feedback into GitHub/GitLab issues, and scores repo activity — all running as a single Bun process bound to `127.0.0.1:7777`.\n\n## Features\n\n**Feedback** — paste text or a screenshot; AI triages it and opens a GitHub or GitLab issue with the right labels, repo, and (for GitHub) an attached image.\n\n**Repos** — depth-first scan of configured paths; shows branch, dirty state, ahead/behind, and last-commit age. Supports pull, push, open in VS Code, reveal in Finder, AI commit message, AI triage, and safe delete.\n\n**Leaderboard** — composite activity score (`commits×10 + filesChanged + 0.05×lines ± recency decay`) across all scanned repos for 7d / 30d / 90d / all-time windows.\n\n## Requirements\n\n- [Bun](https://bun.sh) ≥ 1.0\n- [gh CLI](https://cli.github.com) authenticated (`gh auth login`) — required for creating GitHub issues and (if using the default Copilot provider) for token discovery; Git Glass never stores GitHub tokens\n- macOS (LaunchAgent install path; the server itself is cross-platform)\n\n## Setup\n\n```bash\ngit clone feedback-tool\ncd feedback-tool\nbun install\ncp config-example.json ~/.config/feedback-tool/config.json\n# Edit config.json — set scanPaths at minimum\n```\n\n**Config file** (`~/.config/feedback-tool/config.json`):\n\n```json\n{\n \"scanPaths\": [\"/Users/you/dev\", \"/Users/you/projects\"],\n \"scanDepth\": 3,\n \"port\": 7777,\n \"github\": {\n \"defaultAccount\": \"your-gh-username\"\n }\n}\n```\n\nAI provider and API keys are configured in the Settings UI — no manual JSON editing required. See [AI Provider](#ai-provider) below.\n\nFor GitLab, add per-host PATs (requires `api` scope) — also settable via Settings:\n\n```json\n{\n \"gitlab\": {\n \"tokens\": {\n \"gitlab.example.com\": \"glpat-...\"\n }\n }\n}\n```\n\n## Running\n\n```bash\nbun run start # one-shot\nbun run dev # with --watch reload\n```\n\nOpen `http://127.0.0.1:7777`.\n\n## Install as a macOS LaunchAgent\n\nRuns automatically at login; `KeepAlive=true` restarts on crash.\n\n```bash\n./install.sh # installs or refreshes the LaunchAgent\n./uninstall.sh # removes the LaunchAgent (config and logs preserved)\n```\n\nThe dashboard self-updates via **Settings → Update** (`git pull --ff-only` in its own checkout) and restarts cleanly via **Settings → Restart**.\n\n## AI Provider\n\nConfigure via **Settings → AI Provider**. Supports six providers out of the box:\n\n| Provider | Key required | Default model | Notes |\n|---|---|---|---|\n| **GitHub Copilot** (default) | No | `claude-haiku-4.5` | Token fetched live from `gh auth token`. Requires a Copilot subscription. |\n| **Claude (Anthropic)** | Yes (`sk-ant-…`) | `claude-haiku-4-5-20251001` | Direct Anthropic Messages API. |\n| **OpenAI** | Yes (`sk-…`) | `gpt-4o-mini` | OpenAI chat completions. |\n| **Grok (xAI)** | Yes | `grok-3-mini-fast` | OpenAI-compatible endpoint at `api.x.ai`. |\n| **OpenAI-compatible** | Yes | _(set manually)_ | Custom base URL — works with Azure OpenAI, Together, Fireworks, etc. |\n| **Local (Ollama / LM Studio)** | No | `llama3.2` | Base URL defaults to `http://localhost:11434/v1`. |\n\nYou can override the model name for any provider. API keys are stored in `config.json` (mode 0600) and are **never** returned by `GET /api/config` — only a `hasKey: true/false` flag is exposed to the UI.\n\n## Tests\n\n```bash\nbun test # all tests\nbun test tests/triage.test.ts # single file\nbun test -t \"parseAheadBehind\" # single test name\n```\n\nTests are pure-function focused (parsers, validators, scoring math) and don't boot the server.\n\n## Architecture\n\n```\nindex.ts Hono server — routes + CSRF guard (127.0.0.1 only)\nlib/\n config.ts Zod-validated config, atomic write, key/token redaction\n scanner.ts Repo discovery (depth-capped walk, skips node_modules/.git)\n gitStatus.ts Read-only git ops — runGit(), pMap(), validateRepoPath()\n gitOps.ts Mutations — pull/push/delete/openVSCode (triple-validated)\n triage.ts Multi-provider AI triage (Copilot/Anthropic/OpenAI/Grok/local)\n inference.ts AI commit messages via PAI Inference.ts (optional)\n leaderboard.ts Scoring + in-memory cache keyed by HEAD SHA\n github.ts Issue creation, screenshot upload to .github/issue-assets/\n gitlab.ts Issue creation via per-host PAT\n gh.ts gh CLI wrapper — multi-account token discovery\n remoteUrl.ts SSH/HTTPS remote → browser URL (mirrored in app.html)\npublic/\n app.html Single-file SPA — no build step\n sw.js Service worker — cache-first shell, network-only for /api/*\n```\n\nNo build step. `public/app.html` is hand-written HTML with inline scripts. Bump `CACHE_VERSION` in `sw.js` on every change to `app.html`.\n\n## Auth model\n\n| Action | Token source |\n|---|---|\n| AI triage | Configured AI provider — see Settings → AI Provider |\n| Create GitHub issue | `ownerAccounts[owner]` → `defaultAccount` → `gh auth token` |\n| Create GitLab issue | `config.gitlab.tokens[host]` (persisted PAT) |\n| AI commit / repo triage | PAI `Inference.ts` — no token managed here |\n\n## Security\n\n- Binds to `127.0.0.1` only.\n- Every mutating endpoint checks `Origin`/`Referer` (CSRF guard).\n- All path inputs go through `validateRepoPath()` — realpath + scanPaths containment + rejects `..`.\n- `GET /api/config` returns a redacted view: GitLab tokens and AI API keys are stripped; only host lists and a `hasKey` boolean are exposed.\n- `deleteRepo` triple-validates before `rm -rf`.\n"}}}}