{"_id":"@apidrift/cli","_rev":"3-7c7583cfd5ff410d433ab76e28aef348","name":"@apidrift/cli","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@apidrift/cli","version":"0.1.0","keywords":["api","codemod","migration","dependabot","breaking-changes","stripe","ast","pull-request","devtools"],"author":{"name":"APIdrift"},"license":"Apache-2.0","_id":"@apidrift/cli@0.1.0","maintainers":[{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"}],"homepage":"https://github.com/apidrift/apidrift#readme","bugs":{"url":"https://github.com/apidrift/apidrift/issues"},"bin":{"apidrift":"dist/cli.js"},"dist":{"shasum":"237472f3926e32cda1561aefc2ddeb7bb32c6912","tarball":"https://registry.npmjs.org/@apidrift/cli/-/cli-0.1.0.tgz","fileCount":24,"integrity":"sha512-iP1NSZKVAFbuChWLKJoP4IPxTh90PLdEJpmjadvMz+37Mb/GLV0VgPhK9seBm6auETkNAzrzJlLNe+lIjmD6Pw==","signatures":[{"sig":"MEUCIHMceF7/UY6jxb1DihSnLLYjKPPyRKCLh6N3vbZU83ysAiEAr4pNy2ybn7mkv1ogFD9z30ohKVKQMJ3J93/TWEHS25M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61649},"type":"module","engines":{"node":">=20"},"gitHead":"fe2f2ee054deab755ab5b71ed9d1bc7d0a5271c3","scripts":{"cli":"tsx src/cli.ts","demo":"tsx src/cli.ts run ./fixtures/acme-payments","test":"tsx --test tests/*.test.ts","build":"tsc","runner":"tsx src/runner.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"},"repository":{"url":"git+https://github.com/apidrift/apidrift.git","type":"git"},"_npmVersion":"10.9.8","description":"Open tested pull requests when a third-party API you depend on changes. Detect, fix, verify against your own tests, open a PR.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","@octokit/rest":"^21.0.0","@anthropic-ai/sdk":"^0.65.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.6.3","@types/node":"^22.9.0"},"optionalDependencies":{"@anthropic-ai/vertex-sdk":"^0.11.0","@anthropic-ai/bedrock-sdk":"^0.22.0"},"_npmOperationalInternal":{"tmp":"tmp/cli_0.1.0_1788118536063_0.1518498764678875","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@apidrift/cli","version":"0.2.0","keywords":["api","codemod","migration","dependabot","breaking-changes","stripe","ast","pull-request","devtools"],"author":{"name":"APIdrift"},"license":"Apache-2.0","_id":"@apidrift/cli@0.2.0","maintainers":[{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"}],"homepage":"https://github.com/apidrift/apidrift#readme","bugs":{"url":"https://github.com/apidrift/apidrift/issues"},"bin":{"apidrift":"dist/cli.js"},"dist":{"shasum":"d6c0a5dd75cea0fa4d84d65abd648c9f54504c22","tarball":"https://registry.npmjs.org/@apidrift/cli/-/cli-0.2.0.tgz","fileCount":28,"integrity":"sha512-20ZQguwXGFeDDod/wq/wjkuas4p0hbm4HpXpmKkIwyecgD2nAX2Cq9vofx3s/xmbwbMZKZE+qG28gz2QCb/vgQ==","signatures":[{"sig":"MEUCIQCrXwmZ00dy47hn4nAQpMuj8HGA2s1lQieAYUE8TAU26gIgFFZ6RDei9EaFmsXQCY4LyK+4/tXjQcqT2eM4zoYz610=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113691},"type":"module","engines":{"node":">=20"},"gitHead":"9579d78f8bf8d2b5fbed8c3636cf3da25c02d9b7","scripts":{"cli":"tsx src/cli.ts","demo":"tsx src/cli.ts run ./fixtures/acme-payments","test":"tsx --test tests/*.test.ts","build":"tsc","runner":"tsx src/runner.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"},"repository":{"url":"git+https://github.com/apidrift/apidrift.git","type":"git"},"_npmVersion":"10.9.8","description":"Open tested pull requests when a third-party API you depend on changes. Detect, fix, verify against your own tests, open a PR.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","@octokit/rest":"^21.0.0","@anthropic-ai/sdk":"^0.65.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.6.3","@types/node":"^22.9.0"},"optionalDependencies":{"@anthropic-ai/vertex-sdk":"^0.11.0","@anthropic-ai/bedrock-sdk":"^0.22.0"},"_npmOperationalInternal":{"tmp":"tmp/cli_0.2.0_1788296019103_0.330512640987755","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@apidrift/cli@0.3.0","bin":{"apidrift":"dist/cli.js"},"bugs":{"url":"https://github.com/apidrift/apidrift/issues"},"dist":{"shasum":"3273ea433a5b9e3bd5d08a95be8f7858cbd28d7e","tarball":"https://registry.npmjs.org/@apidrift/cli/-/cli-0.3.0.tgz","fileCount":31,"integrity":"sha512-UlqZKOLohyIyy1l/kN966biCDk8DvIRHstG7Bf2CPlzhgWLrfhXwOuyVPd2ma2x+MNW5yzTdtwibaYOiWjzPfA==","signatures":[{"sig":"MEUCIHWfsA5HyGMCUIZNdcAk0CCmTP8Q4DrFvvKrP1EmTAwQAiEA83Fzru4DYwYzauwnOSb4hEZYn4r75CRtZuud0CN+9GU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD7h7GvHuM5RGf9vsWo3rkNtpzU39t1RWVHGS17/vcNLgIhAP7LdxfngJY7dEu6xnNfYbxvNDaaNrboPlprdNili4uD"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@apidrift%2fcli@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":155892},"name":"@apidrift/cli","type":"module","author":{"name":"APIdrift"},"engines":{"node":">=20"},"gitHead":"9ab309a38eb54c09849628822f1be07b9c2fd46a","license":"Apache-2.0","scripts":{"cli":"tsx src/cli.ts","demo":"tsx src/cli.ts run ./fixtures/acme-payments","test":"tsx --test tests/*.test.ts","build":"tsc","runner":"tsx src/runner.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build && npm test"},"version":"0.3.0","_npmUser":{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"},"homepage":"https://github.com/apidrift/apidrift#readme","keywords":["api","codemod","migration","dependabot","breaking-changes","stripe","ast","pull-request","devtools"],"repository":{"url":"git+https://github.com/apidrift/apidrift.git","type":"git"},"_npmVersion":"10.9.8","description":"Open tested pull requests when a third-party API you depend on changes. Detect, fix, verify against your own tests, open a PR.","directories":{},"maintainers":[{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"}],"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","@octokit/rest":"^21.0.0","@anthropic-ai/sdk":"^0.65.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","typescript":"^5.6.3","@types/node":"^22.9.0"},"optionalDependencies":{"@anthropic-ai/vertex-sdk":"^0.11.0","@anthropic-ai/bedrock-sdk":"^0.22.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cli_0.3.0_1788969178753_0.7322099334319159"}}},"time":{"created":"2026-08-30T19:35:35.920Z","modified":"2026-09-09T15:52:59.250Z","0.1.0":"2026-08-30T19:35:36.185Z","0.2.0":"2026-09-01T20:53:39.243Z","0.3.0":"2026-09-09T15:52:58.879Z"},"bugs":{"url":"https://github.com/apidrift/apidrift/issues"},"author":{"name":"APIdrift"},"license":"Apache-2.0","homepage":"https://github.com/apidrift/apidrift#readme","keywords":["api","codemod","migration","dependabot","breaking-changes","stripe","ast","pull-request","devtools"],"repository":{"url":"git+https://github.com/apidrift/apidrift.git","type":"git"},"description":"Open tested pull requests when a third-party API you depend on changes. Detect, fix, verify against your own tests, open a PR.","maintainers":[{"name":"clemuscle_","email":"clementmaobenedetti@gmail.com"}],"readme":"# APIdrift\n\n[![CI](https://github.com/apidrift/apidrift/actions/workflows/ci.yml/badge.svg)](https://github.com/apidrift/apidrift/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/%40apidrift%2Fcli)](https://www.npmjs.com/package/@apidrift/cli)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE)\n\n**Dependabot, but for third-party API changes.**\n\nWhen a vendor you depend on changes their API, APIdrift finds where your code\nuses it, fixes the code, runs your own tests to prove the fix is safe, and opens\na pull request. Push model, not pull — you don't have to notice the change.\n\nThis repo is a **working tool**: one vendor (Stripe), one language (JS/TS), a\nreal git branch + PR artifact, and **two fixer tiers** — a deterministic AST\ncodemod (fast path) and an **AI agent** (the general mechanism, enabled with\n`ANTHROPIC_API_KEY`). Automated change detection is the documented next step.\n\n## Ship the Free tier tonight\n\nFree = the CLI. Your code never leaves your machine. Two inference modes:\n\n- **deterministic-only** (default, no key): fixes anything covered by the codemod\n  library. No model, nothing sent anywhere.\n- **BYOT** (bring your own token): set `ANTHROPIC_API_KEY` and pass `--ai` to also\n  fix changes with no codemod, using *your* key.\n\n```bash\n# try it (npx installs @apidrift/cli, which provides the `apidrift` command)\nnpx @apidrift/cli run .                    # deterministic-only\nANTHROPIC_API_KEY=sk-ant-... \\\n  npx @apidrift/cli run . --ai             # + AI fixer (BYOT)\n\napidrift run . --deterministic-only        # force no-model mode\napidrift --help\n```\n\nPublish it:\n\n```bash\nnpm run build && npm test             # prepublishOnly runs these too\nnpm publish                           # ships dist/ + action.yml + README + LICENSE + NOTICE\n```\n\nThe published package is lean (no fixtures/tests). Bedrock/Vertex are optional\ndeps — Free users never install them.\n\n### CI/CD (GitHub Actions)\n\n- **`.github/workflows/ci.yml`** — runs typecheck + build + test on every push and\n  PR (Node 20 & 22). This is the build pipeline.\n- **`.github/workflows/release.yml`** — publishes to npm when you cut a GitHub\n  Release, with **provenance** (supply-chain attestation). Flow:\n\n  ```bash\n  npm version patch          # bumps package.json + creates a git tag\n  git push --follow-tags\n  # then create a Release for that tag on GitHub -> the workflow publishes\n  ```\n\n`repository` in `package.json` must point at the real repo URL (needed for\nprovenance) and `package-lock.json` must be committed (needed by `npm ci`) —\nboth already true in this repo.\n\n## Quickstart\n\n```bash\nnpm install\nnpm run demo          # runs the pipeline against fixtures/acme-payments\nnpm test              # proves the happy path AND the \"moat\" (draft on red)\n```\n\n`npm run demo` prints a summary and writes a ready-to-review PR to\n`apidrift-out/apidrift-<change-id>.md` plus a matching `.patch` you can apply\nwith `git am` — one pair per change that matched.\n\nRun it against any repo:\n\n```bash\nnpx tsx src/cli.ts run <path-to-repo> --out ./apidrift-out\n```\n\n## What it does, end to end\n\nFor each known change, on a disposable copy of the target repo:\n\n1. **Detect** — the change is described as a normalized `Change` record\n   (hardcoded in the MVP; emitted by a diff engine in production).\n2. **Locate** — `src/matcher` uses the TypeScript AST (via ts-morph) to find\n   exactly where the changed symbol is used. AST, never regex.\n3. **Fix** — `src/fixer` applies a deterministic codemod, touching only the\n   matched code, and reformats to house style.\n4. **Verify** — `src/verifier` runs the target repo's **own, unmodified** test\n   suite in the workspace. This is the moat: a red suite never ships as a real PR.\n5. **Open PR** — `src/githost` creates a real branch + commit and emits the PR\n   body and patch. Green → PR; red → **draft** with the failure attached.\n\n## Why you can trust it\n\n- **It can't merge broken code.** A PR only leaves draft if your tests pass.\n- **Your tests are read-only.** The fixer edits source, never tests, so it\n  can't \"win\" by weakening what checks it. (`npm test` proves this path.)\n- **Blast radius only.** It edits only files that use the changed API.\n- **Your code can stay home.** The engine is designed to run inside your CI\n  (the `GitHost` abstraction makes the hosted vs self-hosted split trivial).\n\n## The AI fixer\n\nThe fix step has two tiers (see `src/fixer`):\n\n1. **Deterministic codemod** — when a change ships a hand-written `apply`, use it.\n   Fast, free, no tokens. This is the fast path / cache.\n2. **AI agent** (`src/fixer/agent.ts`) — for any change with no codemod (the\n   common case). An agentic loop with tools (`read_file`, `write_file`,\n   `run_tests`) migrates the code. Selected by inference policy (`--ai`/`--deterministic-only`, `apidrift.json`, or env); the\n   LLM client is injectable (`src/fixer/llm.ts`) so it runs for real with a key\n   and is proven by tests with a mock (`tests/ai-fixer.test.ts`).\n\nGuardrails are enforced **in code**, not just the prompt: the agent may edit\nonly blast-radius files, never tests, never outside the repo — and the verifier\nstill gates everything. Turn it on:\n\n```bash\nexport ANTHROPIC_API_KEY=sk-ant-...\nnpx @apidrift/cli run .   # AI fixer: ON\n```\n\n## Project layout\n\n```\nsrc/\n  types.ts            Change record + shared types (the pivot of the system)\n  changes/            the \"change feed\": one Codemod per supported change\n  matcher/            ts-morph AST matching\n  fixer/\n    index.ts            picks tier 1 (codemod) or tier 2 (AI agent)\n    agent.ts            the AI agentic loop + code-enforced guardrails\n    llm.ts              injectable LLM (AnthropicLLM | mock)\n  verifier/           runs the target repo's own tests (the moat)\n  githost/            GitHost interface (the seam between tiers)\n    local.ts            Free: branch + patch, code stays local\n    github.ts           Pro/Enterprise: push + open PR via Octokit\n  pipeline.ts         host-injectable engine (workspace | in-place modes)\n  cli.ts              Free entrypoint  -> `apidrift run <repo>`\n  runner.ts           Enterprise entrypoint -> runs in the client's CI\n  service/            Pro entrypoint -> job.ts (runForRepo) + poller.ts (skeleton)\naction.yml            the composite GitHub Action (Enterprise = one file)\nexamples/\n  enterprise-workflow.yml   drop-in workflow for a consumer repo\nfixtures/acme-payments/      a realistic target repo on the old Stripe API\ntests/pipeline.test.ts       happy path + the draft-on-failure moat\ndocs/\n  USAGE.md            how users use each tier (Free / Pro / Enterprise)\n  architecture.md     runtime architecture (AI, diffing, git)\n  YC.md               the north star (RFS mapping, pitch)\n```\n\n## The three surfaces (see docs/USAGE.md)\n\n- **Free** — `npm run demo` / `npx @apidrift/cli run .` (LocalGitHost, code stays local).\n- **Enterprise** — add `examples/enterprise-workflow.yml` to a repo; the engine\n  runs in the client CI via `action.yml`, code never leaves.\n- **Pro** — `src/service/job.ts` is the per-repo job our backend runs; `poller.ts`\n  outlines the upstream (poll + diff + fan-out).\n\n## Adding a supported change\n\nA change ships as all four, or it doesn't ship:\n\n1. a `Change` + `Codemod` in `src/changes/`,\n2. registered in `src/changes/index.ts`,\n3. a before/after case in `fixtures/`,\n4. a test in `tests/`.\n\n## Roadmap (see `docs/backlog.md`)\n\n- AI fixer (tier 2) for changes with no deterministic codemod yet.\n- Automated change detection: poll OpenAPI specs (oasdiff) + SDK releases.\n- `GitHubHost` (Octokit) and `GitLabHost` behind the existing interface.\n- Self-hosted runner (GitHub Action / GitLab CI component).\n\n## Contributing\n\nBug reports, new `Change`/`Codemod` pairs (see \"Adding a supported change\"\nabove), and fixes are welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md) for\nthe workflow, coding conventions (`docs/conventions.md`), and the DoD each PR\nmust clear (`npx tsc --noEmit` + `npm test`). Please read the\n[Code of Conduct](./CODE_OF_CONDUCT.md) before participating.\n\nFound a security issue? Please **do not** open a public issue — see\n[SECURITY.md](./SECURITY.md) for how to report it privately.\n\n## License\n\nAPIdrift (the engine and the Free CLI) is open source under the\n**[Apache License 2.0](./LICENSE)** — use it, self-host it, modify it,\nredistribute it, including inside a commercial organization, with no\nfield-of-use restriction. See [`LICENSE`](./LICENSE) for the full text and\n[`NOTICE`](./NOTICE) for attribution. Pro and Enterprise are separate,\nclosed-source offerings built on top of this same engine (hosting,\nsupport, SLAs) — they don't change the license of what's in this repo.\n\nSee [CHANGELOG.md](./CHANGELOG.md) for release history.\n","readmeFilename":"README.md"}