Spanlens CLI

One command rewrites every new OpenAI(...), new Anthropic(...), and new GoogleGenerativeAI(...) in your codebase into the matching @spanlens/sdk factory. The wizard validates your key against the dashboard, picks up which providers are registered on your project, and runs tsc --noEmit before committing so you do not ship a broken build.

Two-line manual integration still works

If the wizard does not fit your stack, skip it and use the @spanlens/sdk factories directly. Same end result, same proxy, same dashboard.

Install & run

npx @spanlens/cli init
bash

No global install needed. npx fetches the latest release on each run, so the patch rules stay current with new framework releases. The wizard expects:

  • A Spanlens account with a project at /projects
  • At least one provider key (OpenAI / Anthropic / Gemini) registered on that project
  • A Spanlens API key issued for the project (sl_live_*)
  • Node.js 18 or newer in the project you are patching

Walkthrough

Here is a real run against a Next.js project with three direct provider SDK call sites:

Spanlens setup

  Detected Next.js (TypeScript)

  Before continuing, make sure you have:
    1. A Spanlens account at https://www.spanlens.io
    2. A Project at https://www.spanlens.io/projects
    3. Provider keys (OpenAI / Anthropic / Gemini) added to that project
    4. A Spanlens key issued for that project (sl_live_...)

  ? Paste your Spanlens key > sl_live_*************

  Key valid - project chatbot-prod - providers: openai, anthropic, gemini
  Updated SPANLENS_API_KEY in .env.local
  Installed @spanlens/sdk (pnpm add @spanlens/sdk)

  Found 3 patches to apply
    - [openai] app/api/chat/route.ts
        import: "OpenAI" from 'openai' -> { createOpenAI } from '@spanlens/sdk/openai'
        1 x new OpenAI(...) -> createOpenAI(...)
    - [anthropic] app/api/summary/route.ts
        1 x new Anthropic(...) -> createAnthropic(...)
    - [gemini] app/api/translate/route.ts
        1 x new GoogleGenerativeAI(...) -> createGemini(...)

  ? Apply these changes? > yes
  Patched 3 files
  TypeScript check passed

Spanlens setup complete
bash

The wizard never writes to disk until you answer yes on the confirmation prompt. The tsc --noEmit check after patching is mandatory; if any rewrite breaks a type, the wizard refuses to complete and reports which file failed.

Before / after

Each provider follows the same pattern: drop the import, drop the explicit apiKey, keep every other option (timeout, organization, defaultHeaders, etc.).

OpenAI

- import OpenAI from 'openai'
- const openai = new OpenAI({
-   apiKey: process.env.OPENAI_API_KEY,
-   timeout: 30_000,
- })
+ import { createOpenAI } from '@spanlens/sdk/openai'
+ const openai = createOpenAI({
+   timeout: 30_000,
+ })
diff

Anthropic

- import Anthropic from '@anthropic-ai/sdk'
- const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
+ import { createAnthropic } from '@spanlens/sdk/anthropic'
+ const anthropic = createAnthropic()
diff

Gemini

- import { GoogleGenerativeAI } from '@google/generative-ai'
- const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY ?? '')
+ import { createGemini } from '@spanlens/sdk/gemini'
+ const genAI = createGemini()
diff

What is supported today

AreaStatus
OpenAI / Anthropic / Gemini SDK rewritesStable. Auto-detected from your registered provider keys.
Next.js (TypeScript & JavaScript)Stable.
Vite / Express / Fastify / standalone NodeDetection-only today, full rewrite path is on the roadmap.
Python (FastAPI / Flask)Planned. Use the manual @spanlens/sdk for now.
Package managersnpm, pnpm, yarn, bun all detected automatically.
Env-file writesPreserves comments and surrounding keys; confirms before overwriting.

Flags

FlagUse it for
--dry-runPreview the patch list without writing or installing anything. Safe to run on a clean tree to see what the wizard would do.
npx @spanlens/cli init --dry-run
bash
--server-url <url>Point at a self-hosted Spanlens instance. Validation, dashboard links, and the generated SPANLENS_BASE_URL all use your URL instead of spanlens.io.
npx @spanlens/cli init --server-url https://spanlens.yourcompany.com
bash

Manual integration

Prefer to skip the wizard? The same factories work standalone. Add @spanlens/sdk as a dependency, replace your provider SDK constructor with the matching factory, and you are done:

import { createOpenAI }    from '@spanlens/sdk/openai'
import { createAnthropic } from '@spanlens/sdk/anthropic'
import { createGemini }    from '@spanlens/sdk/gemini'

// Each factory reads SPANLENS_API_KEY from env and routes the
// underlying provider SDK through the Spanlens proxy. The response
// types and method signatures are identical to the upstream SDKs.
ts

See the SDK reference for the full option list, streaming details, and agent-tracing primitives.

Troubleshooting

The wizard says my key is invalid

The CLI calls POST /api/v1/keys/validate on the Spanlens server before writing anything. Common causes:

  • The key is for a different project than the one you intended.
  • The key was revoked from /projects.
  • A self-hosted deployment without --server-url points at spanlens.io by default.

TypeScript check fails after patching

The wizard aborts with the file that failed. Almost always this is a custom field on the original constructor that we did not migrate (for example, a private adapter wrapping new OpenAI). Open the file, finish the migration by hand, and re-run with --dry-run to confirm there is nothing left to patch.

Wizard does not detect my framework

Today the rewrite path is Next.js only. For Vite, Express, Fastify, or standalone Node projects, run the manual integration shown above. Open an issue on spanlens/spanlens with the framework you would like detected.

I want to roll back what the wizard did

Every change is a regular file edit and an env write. git diff shows the rewrite; git restore . reverses it. The wizard never touches anything outside the patched source files and your env file, so a single revert is enough.

Source: packages/cli on GitHub. MIT licensed.