{"_id":"@aiherrera/devsnap","_rev":"3-29639ea0b01a6493bbc17907331026cd","name":"@aiherrera/devsnap","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@aiherrera/devsnap","version":"0.1.0","keywords":["devtools","environment","snapshot","cli","macos"],"author":{"name":"aiherrera"},"license":"MIT","_id":"@aiherrera/devsnap@0.1.0","maintainers":[{"name":"aiherrera","email":"alain.iherrera@gmail.com"}],"homepage":"https://devsnap.app","bugs":{"url":"https://github.com/aiherrera/devsnap/issues"},"bin":{"devsnap":"dist/cli.js"},"dist":{"shasum":"6cca4d20d39550c353e9a34a7e3043d85c03dfec","tarball":"https://registry.npmjs.org/@aiherrera/devsnap/-/devsnap-0.1.0.tgz","fileCount":159,"integrity":"sha512-KF7tn7XnKGGKVf6H0Z1KK0N9qDA4/irLmmcrAT6zkB2GEkEGvAOjBZcxdPAsgAgU+bvqckBTOVLab83Hv0Hmsw==","signatures":[{"sig":"MEYCIQD4Phj6o2kbgxCyqoP5gPIT/spgVQe7pyl7yp/kxyVhvAIhAJ/MJa8dM01TPOsYU+Dtg6+KWo11baGulKuzvG/ivhbJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":355697},"type":"module","engines":{"node":">=22.0.0"},"gitHead":"37da78ad812741f92a76d7d73e41647e8aa4c4fa","scripts":{"dev":"tsx src/cli.ts","test":"npm run build && node --test test/snapshot-ids.test.mjs","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"aiherrera","email":"alain.iherrera@gmail.com"},"repository":{"url":"git+https://github.com/aiherrera/devsnap.git","type":"git"},"_npmVersion":"11.3.0","description":"macOS CLI: scan your dev environment, annotate, diff locally; optional cloud sync to your own API.","directories":{},"_nodeVersion":"24.1.0","dependencies":{"ora":"9.3.0","open":"11.0.0","chalk":"5.6.2","execa":"9.6.1","commander":"14.0.3","cli-table3":"0.6.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.21.0","typescript":"6.0.2","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/devsnap_0.1.0_1775071194981_0.7668506424082091","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aiherrera/devsnap","version":"0.2.0","keywords":["devtools","environment","snapshot","cli","macos"],"author":{"name":"aiherrera"},"license":"MIT","_id":"@aiherrera/devsnap@0.2.0","maintainers":[{"name":"aiherrera","email":"alain.iherrera@gmail.com"}],"homepage":"https://devsnap.app","bugs":{"url":"https://github.com/aiherrera/devsnap/issues"},"bin":{"devsnap":"dist/cli.js"},"dist":{"shasum":"417fb40722afeaadbed6b04bd8d24572b2859ed3","tarball":"https://registry.npmjs.org/@aiherrera/devsnap/-/devsnap-0.2.0.tgz","fileCount":159,"integrity":"sha512-wjqJlwLdZGMpAS1q+0wpi4FTC3V7SvghUwmhlIG6pJ/43ptKeKwQDbgjCm/LANCEzTss2f4RfTqTTOmNbQ5vyA==","signatures":[{"sig":"MEUCID9NKLkHkd6aA40CXXobaad6RwH+/4ZYuERSriQMqsffAiEAjMKiJzQ+eNKUg+6FgIZlQM7i3eCQuUcUeJpUxRtrlK0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359904},"type":"module","engines":{"node":">=22.0.0"},"gitHead":"6518e89d83308162d562457a2e75d09817acc2c2","scripts":{"dev":"tsx src/cli.ts","test":"npm run build && node --test test/snapshot-ids.test.mjs","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"aiherrera","email":"alain.iherrera@gmail.com"},"repository":{"url":"git+https://github.com/aiherrera/devsnap.git","type":"git"},"_npmVersion":"10.9.7","description":"macOS CLI: scan your dev environment, annotate, diff locally; optional cloud sync to your own API.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"ora":"9.3.0","open":"11.0.0","chalk":"5.6.2","execa":"9.6.1","commander":"14.0.3","cli-table3":"0.6.5"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"4.21.0","typescript":"6.0.2","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/devsnap_0.2.0_1775754517548_0.9908611699982739","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aiherrera/devsnap","version":"0.3.0","author":{"name":"aiherrera"},"repository":{"type":"git","url":"git+https://github.com/aiherrera/devsnap.git"},"bugs":{"url":"https://github.com/aiherrera/devsnap/issues"},"homepage":"https://devsnap.app","description":"macOS CLI: scan your dev environment, annotate, diff locally; optional cloud sync to your own API.","keywords":["devtools","environment","snapshot","cli","macos"],"license":"MIT","type":"module","bin":{"devsnap":"dist/cli.js"},"engines":{"node":">=22.0.0"},"scripts":{"build":"tsc","dev":"tsx src/cli.ts","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run build","typecheck":"tsc --noEmit","test":"npm run build && node --test test/*.test.mjs"},"dependencies":{"chalk":"5.6.2","cli-table3":"0.6.5","commander":"14.0.3","execa":"9.6.1","open":"11.0.0","ora":"9.3.0"},"devDependencies":{"@types/node":"^22.0.0","tsx":"4.21.0","typescript":"6.0.2"},"_id":"@aiherrera/devsnap@0.3.0","gitHead":"03dc4b96da5a5674d9eb09b72ebc3226a9523114","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-SpiJlXpobUQ2E4dw3frVw6bgAu2cru1fIk4bknzW5jufEclOY+ujKYhUts+Pq1y1sVgQ+TqjzlrHSwRR5E08FA==","shasum":"2c6e54dba2336b20e1ed07b84f04ce77d0e87a90","tarball":"https://registry.npmjs.org/@aiherrera/devsnap/-/devsnap-0.3.0.tgz","fileCount":159,"unpackedSize":373939,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBKf+ZvyxY0tnZaMMx99jzN6G3w6A/S9F/H4KIsm6suPAiEAlAt5MFlYVsjoh0Aq166uUnIhknUmdhtjUAiRMXc/E30="}]},"_npmUser":{"name":"aiherrera","email":"alain.iherrera@gmail.com"},"directories":{},"maintainers":[{"name":"aiherrera","email":"alain.iherrera@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/devsnap_0.3.0_1775769433275_0.10866209925551251"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-01T19:19:54.859Z","modified":"2026-04-09T21:17:13.547Z","0.1.0":"2026-04-01T19:19:55.149Z","0.2.0":"2026-04-09T17:08:37.729Z","0.3.0":"2026-04-09T21:17:13.435Z"},"bugs":{"url":"https://github.com/aiherrera/devsnap/issues"},"author":{"name":"aiherrera"},"license":"MIT","homepage":"https://devsnap.app","keywords":["devtools","environment","snapshot","cli","macos"],"repository":{"type":"git","url":"git+https://github.com/aiherrera/devsnap.git"},"description":"macOS CLI: scan your dev environment, annotate, diff locally; optional cloud sync to your own API.","maintainers":[{"name":"aiherrera","email":"alain.iherrera@gmail.com"}],"readme":"# devsnap\n\n<p align=\"center\">\n  <strong>Local-first macOS dev environment scanner: scan, annotate, diff—no account required.</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/@aiherrera/devsnap\"><img src=\"https://img.shields.io/npm/v/@aiherrera%2Fdevsnap?style=flat-square&label=npm\" alt=\"npm version\" /></a>\n  <a href=\"https://github.com/aiherrera/devsnap/blob/main/LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-blue?style=flat-square\" alt=\"MIT License\" /></a>\n  <img src=\"https://img.shields.io/node/v/@aiherrera%2Fdevsnap?style=flat-square\" alt=\"Node version\" />\n</p>\n\n---\n\n**devsnap** is a **CLI-only** project for **macOS**: it captures a structured snapshot of your machine (OS and hardware, **Homebrew**, **Node**, **runtimes**, **Docker**, **databases**, **browsers**, **terminals**, **editors**, **LLM / AI CLIs**, **CLI tools**), saves everything under `~/.devsnap`, and diffs locally. Optional **`devsnap cloud`** commands can talk to **your own** HTTP API (for example a private dashboard backend you host separately)—this repository does not ship a server or web UI.\n\n<p align=\"center\">\n  <sub>Built for developers who want one command instead of twenty screenshots.</sub>\n</p>\n\n---\n\n## Why devsnap?\n\n| You need… | devsnap gives you… |\n|-----------|-------------------|\n| A single inventory of “what’s on this Mac?” | `devsnap scan` → terminal, Markdown, HTML, or JSON |\n| To see what changed after an upgrade | `devsnap diff` between two snapshots |\n| Context for teammates or support | `devsnap share clipboard` or gist (Markdown/HTML) |\n| To remember *why* a tool is installed | `devsnap annotate` on tool keys |\n| A starting point to reproduce a machine | `devsnap export brewfile` or `bootstrap` |\n| Low-friction drift awareness | `devsnap schedule install` — recurring **`launchd`** scans (presets + **`--time`** below; default **24h** at **08:00** local) |\n| A lightweight security pass | `devsnap audit` (optional `--html`) |\n| Optional upload to your own API | `devsnap cloud push` (after `cloud auth` or `cloud register`) |\n\n---\n\n## Installation\n\n**Requirements:** macOS · **Node.js ≥ 22**\n\n```bash\nnpm install -g @aiherrera/devsnap\n```\n\nThe `devsnap` command name is unchanged (see `bin` in `package.json`). Scoped packages are private on npm by default; the first publish must use `npm publish --access public`.\n\nFrom source:\n\n```bash\ngit clone https://github.com/aiherrera/devsnap.git\ncd devsnap\nnpm install\nnpm run build\nnpm link   # or: node dist/cli.js\n```\n\n---\n\n## Quick start\n\n```bash\n# Full scan, print to terminal and save JSON snapshot under ~/.devsnap/snapshots/\ndevsnap scan\n\n# Scan + write Markdown and HTML reports (HTML opens in browser by default)\ndevsnap scan --md --html\n\n# Machine-readable output only (still can save with default behavior)\ndevsnap scan --json\n\n# Compare the last two snapshots\ndevsnap diff\n\n# Search the latest snapshot\ndevsnap search docker\n\n# Optional (macOS): recurring scans via launchd\ndevsnap schedule install --interval 24h --time 08:00\ndevsnap schedule install --interval 1w\ndevsnap schedule status\n```\n\n---\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `devsnap scan` | Scan environment. Flags: `--html`, `--md`, `--json`, `--no-save` |\n| `devsnap list` | List saved snapshots |\n| `devsnap diff [id1] [id2]` | Diff two snapshots (defaults to latest pair) |\n| `devsnap open` | Open the latest HTML report in your browser |\n| `devsnap annotate` | Add or manage notes on tools (`--list`, `--show`, `--remove`) |\n| `devsnap search <query>` | Search latest snapshot; `-s, --snapshot <id>` for a specific one |\n| `devsnap export <format> [output]` | `brewfile` or `bootstrap` from latest snapshot |\n| `devsnap clean` | Drop old snapshots; `-k, --keep <n>` (default **5**) |\n| `devsnap schedule <action>` | `install` \\| `uninstall` \\| `status` — **launchd** job. **`-i, --interval`**: **`1h`**, **`8h`**, **`24h`** (default), **`1w`**, **`1m`**. **`-t, --time HH:MM`**: local time for **`24h`** (daily), **`1w`** (Mondays), **`1m`** (1st of each month); default **`08:00`**. Ignored for **`1h`** / **`8h`** (`StartInterval` only). |\n| `devsnap share <target>` | `clipboard` \\| `gist` — `--format md\\|html` (gist needs `gh` CLI; see **Privacy** below) |\n| `devsnap audit` | Security-oriented audit; `--html` for report |\n| `devsnap config show` | Print config |\n| `devsnap config set <key> <value>` | Update `~/.devsnap/config.json` (only documented keys are accepted) |\n| `devsnap cloud register` | Create an account on **your** API; saves API key to `~/.devsnap/cloud.json` |\n| `devsnap cloud auth` | Save API key, API base URL, optional dashboard URL (`--key`, `--url`, `--dashboard`) |\n| `devsnap cloud logout` | Remove `~/.devsnap/cloud.json` |\n| `devsnap cloud status` | Show whether cloud credentials are configured |\n| `devsnap cloud push` | `POST` latest (or `--id`) snapshot JSON to your API; optional `--tag`, `--note`, `--redacted` |\n| `devsnap cloud list` | List snapshots from your API |\n| `devsnap cloud open` | Open the saved dashboard URL in a browser |\n\nRun `devsnap --help` or `devsnap <command> --help` for details.\n\n**Environment:** `DEVSNAP_CLOUD_API` overrides the API base URL when not passed via `cloud auth --url` (default for local development: `http://localhost:3001`).\n\n---\n\n## Optional cloud API (your own backend)\n\nThis repo stays **CLI-only**. If you run a separate private service, implement endpoints compatible with the CLI:\n\n| Method | Path | Notes |\n|--------|------|--------|\n| `POST` | `/api/auth/register` | Body: `{ \"email\": string \\| null }`. Response: `{ \"apiKey\": string }` (plaintext key, show once). |\n| `POST` | `/api/snapshots` | Header: `Authorization: Bearer <apiKey>`. Body: `{ \"payload\": <snapshot JSON>, \"tag\": string \\| null, \"note\": string \\| null }`. Response: `{ \"id\": string, \"localId\": string }`. |\n| `GET` | `/api/snapshots?limit=50` | Same auth. Response: array of `{ id, localId, createdAt, tag, note }`. |\n| `GET` | `/api/snapshots/:id` | Same auth. Full row including `payload`. |\n\n`snapshot` objects are the same shape as `devsnap scan --json` (see **What gets scanned**). New scans include optional `schemaVersion` for forward compatibility.\n\n---\n\n## What gets scanned\n\nSnapshots include (when available on your system):\n\n- **System** — macOS version, architecture, chip, memory, disk\n- **Homebrew** — formulae and casks\n- **Node** — versions, package managers, global packages\n- **Runtimes** — e.g. Python, Ruby, Go, Rust (as detected)\n- **Docker** — version, images, running containers\n- **Databases** — common DB CLI presence / versions\n- **Browsers** — installed browsers\n- **Terminals** — terminal apps\n- **Editors** — VS Code, Cursor, JetBrains, etc.\n- **LLMs** — AI/LLM-related CLIs and tooling\n- **CLI tools** — curated list of developer utilities (configurable)\n\nExact coverage evolves with releases; use `devsnap scan --json` to inspect the schema.\n\n**`--json` output** can include paths, tool names, and versions. Avoid piping it into shared logs or CI artifacts if that is sensitive for your environment.\n\n---\n\n## Privacy\n\n- **`devsnap share gist`** uploads your Markdown report to **GitHub Gists** (public by default for anonymous gists, or per your `gh` account defaults). Treat it like publishing environment inventory.\n- **Clipboard** copies the report into the system pasteboard; anyone with access to the machine or universal clipboard may see it.\n\n---\n\n## Configuration\n\nConfig lives at **`~/.devsnap/config.json`**. You can edit it or use the CLI:\n\n```bash\ndevsnap config show\ndevsnap config set autoOpenHtml false\ndevsnap config set staleDays 365\n```\n\n| Key | Purpose |\n|-----|---------|\n| `disabledScanners` | Skip categories: `brew`, `node`, `runtimes`, `docker`, `databases`, `browsers`, `terminals`, `editors`, `llms`, `cliTools`, `system` (case-insensitive) |\n| `extraCliTools` | Extra **binary names** to probe (letters, digits, `.`, `_`, `-` only; no paths). Duplicates of built-in tools are ignored. |\n| `staleDays` | Days before a tool is treated as stale (default **180**) |\n| `cleanKeep` | Default keep count for `devsnap clean` (default **5**) |\n| `autoOpenHtml` | Open browser after `devsnap scan --html` (default **true**) |\n\n---\n\n## Data on disk\n\n| Path | Contents |\n|------|----------|\n| `~/.devsnap/snapshots/` | Snapshot JSON files (timestamp-style ids; `devsnap list` shows valid ids for `diff`) |\n| `~/.devsnap/reports/` | Generated `.html` and `.md` reports |\n| `~/.devsnap/config.json` | User configuration |\n| `~/.devsnap/annotations.json` | Tool annotations |\n| `~/.devsnap/cloud.json` | Optional cloud API key + URLs (mode `600`; created by `devsnap cloud auth` / `register`) |\n| `~/.devsnap/schedule.log` | Stdout from scheduled `devsnap scan` (when using `schedule install`) |\n| `~/.devsnap/schedule.err` | Stderr from scheduled runs |\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm run dev -- --help    # tsx src/cli.ts\nnpm run build            # tsc → dist/\nnpm run typecheck\n```\n\n**CI** (`.github/workflows/ci.yml`) runs typecheck, tests, and a pack dry-run on pushes and PRs. It does **not** publish to npm.\n\n### Automated versioning and releases ([Release Please](https://github.com/googleapis/release-please))\n\nThis repo uses **[Release Please](https://github.com/googleapis/release-please)** (`.github/workflows/release-please.yml`):\n\n1. Use **[Conventional Commits](https://www.conventionalcommits.org/)** on `main`, for example:\n   - `fix: …` → patch bump  \n   - `feat: …` → minor bump  \n   - `feat!: …` or `BREAKING CHANGE:` in the body → major bump  \n   - `chore:`, `docs:`, etc. usually do not trigger a release by themselves (see Release Please rules).\n2. On each push to **`main`**, the workflow opens or updates a **Release PR** that bumps **`package.json`**, updates **`CHANGELOG.md`**, and prepares the next version.\n3. When you **merge that Release PR**, Release Please creates the **GitHub release and tag**, then **`npm publish --access public`** runs in the **same** job (so you do not depend on a second workflow).\n\n**Setup**\n\n- Add the **`NPM_TOKEN`** Actions secret (npm automation/publish token), same as below.\n- Under **Settings → Actions → General**, allow **“Read and write permissions”** for the workflow token and (if prompted) allow workflows to **create pull requests**.\n\n**Other tools people use:** [semantic-release](https://semantic-release.gitbook.io/) (fully automated from commits, no merge step), [Changesets](https://github.com/changesets/changesets) (human-written changeset files). Release Please fits GitHub-centric teams who like a visible **Release PR**.\n\n### Manual npm publish (optional)\n\n**Actions → Publish to npm (manual) → Run workflow** publishes whatever **`version`** is on **`main`** today. Use for hotfixes or if you skip Release Please. Still requires **`NPM_TOKEN`**.\n\n### npm token\n\n1. Create an **automation** (or **publish**) token at [npmjs.com](https://www.npmjs.com/) → **Access Tokens**.\n2. Repo **Settings → Secrets and variables → Actions** → **`NPM_TOKEN`**.\n\nScoped packages need **`npm publish --access public`**; the workflows already pass that. Your npm user must be allowed to publish **`@aiherrera/*`**.\n\n---\n\n## License\n\nMIT © [aiherrera](https://github.com/aiherrera)\n\n---\n\n<p align=\"center\">\n  If devsnap saves you time, a ⭐ on <a href=\"https://github.com/aiherrera/devsnap\">GitHub</a> helps others find it.\n</p>\n","readmeFilename":"README.md"}