{"id":39606187,"url":"https://github.com/watchapi/watchapi-cli","last_synced_at":"2026-01-18T08:00:56.379Z","repository":{"id":324366943,"uuid":"1093715719","full_name":"watchapi/watchapi-cli","owner":"watchapi","description":"CLI for WatchAPI + API Analyzer","archived":false,"fork":false,"pushed_at":"2025-12-20T09:34:07.000Z","size":6862,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-22T15:22:02.553Z","etag":null,"topics":["analyzer","api","monitoring","open-source","trpc","uptime"],"latest_commit_sha":null,"homepage":"https://watchapi.dev","language":"TypeScript","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/watchapi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-10T18:37:10.000Z","updated_at":"2025-12-20T09:34:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/watchapi/watchapi-cli","commit_stats":null,"previous_names":["watchapi/watchapi-cli"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/watchapi/watchapi-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watchapi%2Fwatchapi-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watchapi%2Fwatchapi-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watchapi%2Fwatchapi-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watchapi%2Fwatchapi-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/watchapi","download_url":"https://codeload.github.com/watchapi/watchapi-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watchapi%2Fwatchapi-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28533735,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"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":["analyzer","api","monitoring","open-source","trpc","uptime"],"created_at":"2026-01-18T08:00:32.784Z","updated_at":"2026-01-18T08:00:56.136Z","avatar_url":"https://github.com/watchapi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# API Monitoring \u0026 tRPC Analyzer CLI\n\n[![license](https://img.shields.io/npm/l/@watchapi/cli.svg)](https://github.com/yourusername/api-monitoring/blob/main/LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)\n[![Made for CI/CD](https://img.shields.io/badge/Made%20for-CI%2FCD-success.svg)]()\n[![npm version](https://img.shields.io/npm/v/@watchapi/cli.svg)](https://www.npmjs.com/package/@watchapi/cli)\n[![npm downloads](https://img.shields.io/npm/dm/@watchapi/cli.svg)](https://www.npmjs.com/package/@watchapi/cli)\n\nCLI tool for API monitoring and regression detection in CI/CD pipelines.\n\n![Showcase Main](./public/readme-showcase-main.gif)\n\n## Installation\n\n```bash\nnpm install -g @watchapi/cli\n# or\nnpx @watchapi/cli\n```\n\n## Quick Start\n\n### 1. Log in once (recommended)\n\n```bash\nwatchapi login --api-token your-api-token --api-url https://your-platform.com\n```\n\nThis stores credentials in `~/.watchapi/config.json` for reuse.\n\n### 3. Run checks in your CI/CD pipeline\n\n```bash\nwatchapi check --collection \u003ccollection-id\u003e --env production\n```\n\n## Usage\n\n### Login Command\n\nStore credentials locally so you can skip passing tokens on every run.\n\n```bash\nwatchapi login --api-token \u003ctoken\u003e [--api-url \u003curl\u003e]\n```\n\n### Logout Command\n\nRemove locally saved credentials.\n\n```bash\nwatchapi logout\n```\n\n### Check Command\n\nRun API checks for a collection and detect regressions.\n\n```bash\nwatchapi check [options]\n```\n\n**Options:**\n\n- `-c, --collection \u003cid\u003e` - **(Required)** Collection ID to check\n- `-e, --env \u003cenvironment\u003e` - Environment name (default: \"production\")\n- `--api-url \u003curl\u003e` - Platform API URL (default: flag → `WATCHAPI_URL` → saved login → production URL)\n- `--api-token \u003ctoken\u003e` - API authentication token (default: flag → `WATCHAPI_TOKEN` → saved login)\n- `--fail-on \u003cmode\u003e` - When to fail the CI/CD pipeline:\n  - `regressions` (default) - Fail only if regressions detected\n  - `any` - Fail if any check fails\n\n**Examples:**\n\n```bash\n# Basic usage\nwatchapi check --collection abc123\n\n# Specify environment\nwatchapi check --collection abc123 --env staging\n\n# Fail on any failure (not just regressions)\nwatchapi check --collection abc123 --fail-on any\n\n# Use custom API URL\nwatchapi check --collection abc123 --api-url https://api.example.com\n```\n\n### Sync Command\n\nDiscover APIs from your codebase (Next.js tRPC for now) and sync them to the platform. Endpoints are matched by `method + URL`, updated when they already exist, and stale ones are left untouched.\n\n```bash\nwatchapi sync --root . --tsconfig tsconfig.json --domain https://api.example.com --prefix api/trpc\n```\n\nFor Nest projects (OpenAPI 3.x), point to your schema file and switch targets (auto-detected when omitted):\n\n```bash\nwatchapi sync --target nest --include openapi.yaml --prefix api\n```\n\nIf you use the default Nest Swagger setup, omitting `--include` will try `api-json` first. You can also pass an exported spec file or a URL, which lets you sync without running the Nest app locally (e.g., `watchapi sync --target nest --include docs/openapi.json` or `--include https://example.com/api-json`).\n\n**Options:**\n\n- `-t, --target \u003ctarget\u003e` - Adapter target (auto-detected when omitted; options: `next-trpc` | `nest`)\n- `--root \u003cpath\u003e` - Project root to scan (default: cwd)\n- `--tsconfig \u003cpath\u003e` - Path to tsconfig (default: `tsconfig.json`)\n- `--include \u003cglobs...\u003e` - Override glob(s) for router files or OpenAPI file/URL\n- `--domain \u003curl\u003e` - Optional Base domain to prepend to synced endpoint paths\n- `--prefix \u003cpath\u003e` - Optional path prefix before the router/procedure (e.g., `api/trpc`)\n- `--api-url \u003curl\u003e` / `--api-token \u003ctoken\u003e` - Override platform connection\n- `--dry-run` - Print detected APIs without syncing\n- `--router-factory` / `--router-identifier-pattern` - Customize tRPC detection\n\nIf you omit `--target`, the CLI inspects `package.json` in your project root to decide:\n\n- Next.js + tRPC deps → `next-trpc`\n- NestJS + `@nestjs/swagger` deps → `nest`\n- Ambiguous/unknown → prompts you to pass `--target`\n\n## CI/CD Integration\n\n### GitHub Actions\n\n```yaml\nname: Deploy\n\non:\n  push:\n    branches: [main]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      # Your deployment steps here\n      - name: Deploy to production\n        run: ./deploy.sh\n\n      # Run API health checks\n      - name: API Health Check\n        run: npx @watchapi/cli check --collection ${{ secrets.COLLECTION_ID }} --env production\n        env:\n          WATCHAPI_TOKEN: ${{ secrets.WATCHAPI_TOKEN }}\n```\n\n### GitLab CI\n\n```yaml\ndeploy:\n  stage: deploy\n  script:\n    - ./deploy.sh\n    - npx @watchapi/cli check --collection $COLLECTION_ID --env production\n  variables:\n    WATCHAPI_TOKEN: $WATCHAPI_TOKEN\n```\n\n### CircleCI\n\n```yaml\nversion: 2.1\n\njobs:\n  deploy:\n    docker:\n      - image: node:20\n    steps:\n      - checkout\n      - run: ./deploy.sh\n      - run:\n          name: API Health Check\n          command: npx @watchapi/cli check --collection $COLLECTION_ID --env production\n          environment:\n            WATCHAPI_TOKEN: $WATCHAPI_TOKEN\n```\n\n### Jenkins\n\n```groovy\npipeline {\n  agent any\n\n  environment {\n    WATCHAPI_TOKEN = credentials('watchapi-token')\n  }\n\n  stages {\n    stage('Deploy') {\n      steps {\n        sh './deploy.sh'\n      }\n    }\n\n    stage('Health Check') {\n      steps {\n        sh 'npx @watchapi/cli check --collection ${COLLECTION_ID} --env production'\n      }\n    }\n  }\n}\n```\n\n## How It Works\n\n1. **Fetch Collection**: CLI fetches your collection definition from the platform (endpoints, expected responses, etc.)\n2. **Run Checks**: Executes HTTP requests to all endpoints in your environment\n3. **Analyze Results**: Compares results with historical data to detect:\n   - Status code changes (passing → failing)\n   - Performance regressions (2x slower than average)\n   - Response body changes\n4. **Report**: Sends results back to platform for tracking\n5. **Exit**: Returns appropriate exit code for CI/CD (0 = pass, 1 = fail)\n\n## Regression Detection\n\nThe CLI automatically detects regressions by comparing current results with historical data:\n\n### Status Regressions\n\n- Endpoint was passing in last 3 checks → now failing\n- Example: API returned 200 OK, now returns 500 Error\n\n### Performance Regressions\n\n- Response time is 2x slower than 5-check average\n- Example: Average 100ms → now 250ms\n\n### When using `--fail-on regressions`\n\n- [✓] New endpoint fails: Won't block deployment (no baseline)\n- [✓] Endpoint consistently failing: Won't block (not a regression)\n- [✗] Previously passing endpoint fails: **Blocks deployment**\n- [✗] Performance degradation (2x slower): **Blocks deployment**\n\n### When using `--fail-on any`\n\n- [✗] Any failure or error: **Blocks deployment**\n\n## Output Example\n\n```\n============================================================\n  API Check Results - production\n============================================================\n\nSummary:\n  Total:  5\n  ✓ Passed: 4\n  ✗ Failed: 1\n  ⚠ Errors: 0\n\n⚠ REGRESSIONS DETECTED:\n  • Endpoint api-endpoint-123: was passing in last 3 checks, now FAILED\n\nDetails:\n✓ Endpoint api-endpoint-123\n  Status: 200 | Response Time: 145ms\n\n✗ Endpoint api-endpoint-456\n  Failed assertions:\n    • Status code: expected different, got 500\n    • Response time: 2500ms (too slow)\n\n============================================================\n```\n\n## Authentication\n\nGet your API token from the platform:\n\n1. Log in to your account\n2. Go to Settings → API Tokens\n3. Create a new token for CI/CD\n4. Store it securely in your CI/CD secrets\n\n## Troubleshooting\n\n### \"API token is required\"\n\n- Set `WATCHAPI_TOKEN` environment variable\n- Or use `--api-token` flag\n\n### \"Collection not found\"\n\n- Verify collection ID is correct\n- Ensure your API token has access to the collection\n\n### Checks timing out\n\n- Increase timeout in endpoint configuration on the platform\n- Check network connectivity from CI/CD to your APIs\n\n## Analyzer-Only Quick Start\n\n![Showcase Analyzer](./public/readme-showcase-analyzer.gif)\n\nNeed just the static analyzer? It works standalone:\n\n```bash\n# Scan your project (table view)\nnpx @watchapi/cli analyze --root . --tsconfig tsconfig.json --include \"src/server/**/*.ts\"\n\n# JSON output for CI/pipelines\nnpx @watchapi/cli analyze --format json \u003e trpc-analyzer-report.json\n\n# Scan Next.js App Router route handlers\nnpx @watchapi/cli analyze --target next-app-router --include \"app/api/**/route.{ts,tsx}\"\n\n# Analyze a Nest OpenAPI 3.x spec\nnpx @watchapi/cli analyze --target nest --include openapi.yaml\n```\n\nProgrammatic API:\n\n```ts\nimport {\n  detectTargets,\n  getNextAppRoutes,\n  getNextTrpcProcedures,\n  getNestOperations,\n} from \"@watchapi/cli\";\n\n// Detect frameworks present in a repo\nconst detected = await detectTargets();\n\n// Get typed route/procedure lists without the CLI\nconst appRoutes = await getNextAppRoutes({ rootDir: \"/path/to/app\" });\nconst trpcProcedures = await getNextTrpcProcedures({ rootDir: \"/path/to/app\" });\nconst nestOperations = await getNestOperations({ include: [\"openapi.yaml\"] });\n```\n\n**What `analyze` shows you (so you can spot issues early):**\n- Every detected API (method + path/procedure) for a quick surface audit.\n- Missing `operationId` values in OpenAPI specs to keep endpoint identity stable.\n- OpenAPI summaries, descriptions, and tags to validate documentation coverage.\n- tRPC metadata like visibility, resolver size, DB usage, error handling, and side effects to flag risky handlers.\n- Next.js App Router handler metadata: method/path derivation, handler length, DB usage, error handling, side effects, and response-shape hints.\n- tRPC quality signals: missing input schemas, implicit outputs, naming mismatches, DB calls without error handling, heavy resolvers, side-effectful queries, public sensitive mutations that should have auth/rate limiting, and oversized/singular routers.\n- File/line references for fast jump-to-definition in your editor.\n\n**Key flags:**\n\n- `--root` (default: cwd) project root to scan\n- `--tsconfig` path to the tsconfig used by your tRPC project\n- `--include` glob(s) to target router/procedure files\n- `--format table|json` choose console table or machine-readable JSON\n- `--router-factory` / `--router-identifier-pattern` override router detection if you use custom helpers\n- `--target next-trpc|next-app-router|nest` force a specific analyzer target (auto-detected when possible)\n\n## Contributing\n\nSee `CONTRIBUTING.md` for a minimal setup and workflow guide.\n\n## Support\n\n- Documentation: https://watchapi.dev/docs\n- Issues: https://github.com/watchapi/watchapi-cli/issues\n- Email: support@watchapi.dev\n- Discord: https://discord.gg/5bANxHbfNx\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwatchapi%2Fwatchapi-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwatchapi%2Fwatchapi-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwatchapi%2Fwatchapi-cli/lists"}