autotel-cli
v0.21.0
Published
CLI for autotel - setup wizard, diagnostics, and incremental features
Maintainers
Readme
autotel-cli
CLI for autotel. Setup wizard, diagnostics, and incremental features.
Designed for both humans and AI agents: every command supports --json,
errors are returned as a structured envelope with stable AUTOTEL_E_* codes,
and the binary describes itself via autotel schema.
For agents: see SKILL.md for the one-command bootstrap.
Installation
npm install -g autotel-cli
# or
npx autotel-cli <command>Commands
autotel init
Interactive setup wizard to initialize autotel in your project.
# Interactive mode
npx autotel-cli init
# Use defaults (local backend, all auto-instrumentations)
npx autotel-cli init --yes
# Use a quick preset
npx autotel-cli init --preset node-datadog-pino
# Dry run - see what would be created
npx autotel-cli init --dry-runBy default autotel init scans your package.json (and the workspace root
if you're in a monorepo) and proposes a plan: which presets to wire, which
packages to install, which env vars you'll need. Detected loggers, web
frameworks, MCP servers, Sentry, Cloudflare, etc. are wired automatically;
deps covered by @opentelemetry/auto-instrumentations-node (Express,
Fastify, NestJS, Next.js, pg, redis, …) are listed but not wired
individually.
Options:
| Flag | What it does |
| ------------------------------ | ---------------------------------------------------------------- |
| --yes, -y | Auto-apply detected items; no prompts |
| --preset <name> | Use a named quick preset (skips detection) |
| --dry-run | Print plan; write nothing |
| --no-install | Generate files only; print install command |
| --force | Overwrite a hand-edited instrumentation file (backup written) |
| --no-detect | Skip auto-detection; requires --plan, --input, or --preset |
| --detect-only | Print the detected plan and exit |
| --plan <path> | Apply a pre-built InitPlan JSON file |
| --input - / --input <path> | Read InitPlan JSON from stdin or a file |
| --scan-env | Consent to reading .env / .env.local for backend detection |
| --json | Machine-readable JSON instead of human output |
| --output-file <path> | Persist JSON output to a file |
| --no-secrets-in-output | Redact secret-shaped values (*KEY*, *TOKEN*, etc.) |
| --no-interactive | Fail fast instead of prompting |
Detection coverage:
- Frameworks (auto-wired): Hono, MCP servers/clients, TanStack Start
- Frameworks (via
auto-instrumentations-node): Express, Fastify, NestJS, Next.js, pg, mysql/2, redis, ioredis, GraphQL, AWS SDK - Loggers: Pino (first-class:
init({ logger })), Winston/Bunyan (auto-instrumented) - Subscribers: PostHog, Mixpanel, Amplitude, Segment, Slack
- Plugins: Mongoose, Drizzle, Sentry
- Platforms: Cloudflare (from
wrangler.toml), AWS Lambda, Edge - Backends from env vars:
DD_API_KEY→ Datadog,HONEYCOMB_API_KEY→ Honeycomb,OTEL_EXPORTER_OTLP_ENDPOINT→ OTLP
Quick presets:
node-datadog-pino- Node.js + Datadog + Pino loggingnode-datadog-agent- Node.js + Datadog Agent (local development)node-honeycomb- Node.js + Honeycombnode-otlp- Node.js + Generic OTLP endpoint
Agent-native discovery
autotel schema # Full command manifest with side-effect metadata
autotel schema errors # Error envelope shape + AUTOTEL_E_* codes
autotel schema outputs # JSON output shapes per command
autotel commands # Compact one-line-per-command listing
autotel examples [name] # Copy-pasteable examples
autotel version # Version + runtime info as JSONAll output is JSON. Errors are returned as:
{
"ok": false,
"command": "autotel init",
"error": {
"type": "validation",
"code": "AUTOTEL_E_NO_PACKAGE_JSON",
"message": "No package.json found at ...",
"retryable": false,
"fix": "cd into a directory with a package.json, or pass --cwd <path>",
"expected": { "file": "package.json" }
}
}Exit codes: 0 success, 1 runtime failure, 2 validation/conflict.
autotel doctor
Run diagnostics on your autotel setup.
# Run all checks
npx autotel-cli doctor
# Output as JSON
npx autotel-cli doctor --json
# Auto-fix resolvable issues
npx autotel-cli doctor --fix
# List available checks
npx autotel-cli doctor --list-checksOptions:
--json- Output machine-readable JSON--fix- Auto-fix resolvable issues--list-checks- List all available checks--env-file <path>- Specify env file to check
Exit codes:
0- All checks passed1- Warnings found2- Errors found
autotel add <type> <name>
Add a backend, subscriber, plugin, or platform incrementally.
# Add Datadog backend
npx autotel-cli add backend datadog
# Add PostHog event subscriber
npx autotel-cli add subscriber posthog
# Add Mongoose plugin
npx autotel-cli add plugin mongoose
# List all available presets
npx autotel-cli add --list
# List backends only
npx autotel-cli add backend --list
# Show help for a specific preset
npx autotel-cli add backend datadog --helpTypes:
backend- Telemetry backends (Datadog, Honeycomb, OTLP, etc.)subscriber- Event subscribers (PostHog, Mixpanel, Segment, Slack, etc.)plugin- Database/ORM plugins (Mongoose, Drizzle, etc.)platform- Platform support (AWS Lambda, Cloudflare Workers, etc.)
Options:
--list- List available presets--dry-run- Skip installation and print what would be done--force- Overwrite non-CLI-owned config (creates backup first)
autotel map
Reads your source, finds every entry point, and scores what context you would have when each one breaks. Static analysis only — nothing runs, nothing is sent anywhere.
# Score the project and write autotel.map.json
npx autotel-cli map
# Every entry point as a check matrix
npx autotel-cli map --all
# Explain one entry point and how to fix it
npx autotel-cli map app/api/checkout/route.ts
npx autotel-cli map /api/checkout
# Machine-readable, for agents and CI
npx autotel-cli map --json
# Fail CI below a threshold
npx autotel-cli map --min-score 70
# Fail CI when a check that used to pass now fails
npx autotel-cli map --baseline git:origin/main
# Annotate the pull request diff in GitHub Actions
npx autotel-cli map --format github --baseline git:origin/main --no-writeDetected frameworks: next, nitro (Nuxt), tanstack-start, sveltekit, hono, express, fastify, elysia, cloudflare. Override with --framework <name>.
Checks:
| Check | Weight | Question |
| --------------------- | ------ | --------------------------------------------------------------------- |
| trace | 40 | Does this entry point produce a span? |
| context | 25 | Does the span carry business context, or only method and status? |
| audit | 25 | Does this money or auth path leave an audit trail? (sensitive routes) |
| structured-errors | 15 | Do thrown errors explain why they failed and how to fix them? |
| error-handling | 10 | Does every catch block record the failure? |
| page-error-handling | 20 | Does a data-loading page handle its request failing? |
Suggestions never cost points. They cover untraced GenAI calls, validation without telemetry, missing redaction, repeated inline errors that can use an existing error catalog, and uncovered writes in a project that already records security events.
Health checks, probes, and telemetry endpoints are exempt. Anything else can be waived in code:
// autotel-map-disable error-handling -- returns a safe fallback on purpose
// autotel-map-disable-next-line audit, context -- internal-only route
handler(); // autotel-map-disable-line structured-errors -- delegated upstreamOmit the check id to waive every finding in the selected scope. A waived check
costs no score and is never counted as coverage;
summary.suppressedChecks reports how many there are.
autotel.map.json is written next to package.json and is meant to be committed: --baseline compares against it per check, so a refactor that instruments one route and breaks another still fails. A run that detects a regression does not overwrite the file it compared against.
Options:
--all- Show every entry point as a check matrix--framework <name>- Override framework detection--min-score <n>- Exit 1 when the global score is below this threshold--baseline [source]- Compare against a committed map (path, orgit:<ref>); exit 1 on regression--no-write- Skip writingautotel.map.json--json/--output-file <path>- Machine-readable output (--jsonis the same as--format json)--format github- GitHub Actions workflow annotations on stdout; the report goes to stderr and the exit code is unchanged--limit <n>- Most annotations--format githubemits (default 10, how many GitHub keeps per step)
Annotating pull requests: with --baseline, --format github emits the regressions as errors: the checks this pull request broke, nothing already on the map. Without one, it emits the "Fix these first" list, worst entry point first, as warnings. The first line carries the score, as an error when --min-score or the baseline failed the run, and says how many findings --limit left out. Paths are rebased on GITHUB_WORKSPACE, so a package scanned with --cwd inside a monorepo still annotates the right file.
::warning file=src/index.ts,line=6,title=autotel map%3A trace::no trace() or span() — this handler is invisible when it breaks
::warning file=src/index.ts,line=6,title=autotel map%3A audit::no audit trail (money: path says "payment") — withAudit() survives tail sampling
::notice title=autotel map::score 15/100 (at-risk): 0 instrumented, 0 partial, 3 dark; 6 more findings not shownautotel codemod trace <path>
Wrap functions in trace() with a span name derived from the function/variable/method name. Use this to adopt autotel on existing code without changing function bodies.
Supported file types: .ts, .tsx, .js, .jsx
# Single file (TypeScript or JavaScript)
npx autotel-cli codemod trace src/index.ts
npx autotel-cli codemod trace src/utils.js
# Glob pattern - TypeScript only
npx autotel-cli codemod trace "src/**/*.ts"
# Glob pattern - all supported files
npx autotel-cli codemod trace "src/**/*.{ts,tsx,js,jsx}"
# Dry run - print what would change without writing
npx autotel-cli codemod trace "src/**/*.ts" --dry-run
# Custom span name template: {name}, {file} (basename), {path} (relative)
npx autotel-cli codemod trace "src/**/*.ts" --name-pattern "{file}.{name}"
# Skip functions whose name matches a regex (repeatable)
npx autotel-cli codemod trace "src/**/*.ts" --skip "^_" --skip "test|mock"
# Print per-file summary (wrapped count, skipped)
npx autotel-cli codemod trace "src/**/*.ts" --print-filesOptions:
--dry-run- Print changes without writing files--name-pattern <pattern>- Span name template. Placeholders:{name},{file},{path}. Default:{name}only.--skip <regex>...- Skip functions whose name matches (repeatable; combined as OR).--print-files- Print per-file summary (e.g.✔ path (N wrapped),↷ path (skipped: reason)).
Supported patterns: Function declarations, arrow/function expressions in const/let/var, class and static methods (body wrap), object method shorthand, named default export function. Works with both TypeScript and JavaScript files. Span name defaults to function/variable/method name (or ClassName.methodName for methods).
Exclusions: Generator functions (function*, async function*); getters/setters; constructors; CJS (require('autotel')); anonymous default export; class/object methods that use super in the body; .d.ts files; node_modules/. The codemod does not modify files when no eligible functions are found (no unused trace import added). The {path} placeholder uses the relative path from --cwd with forward slashes; moving files will change span names.
Global Options
All commands support these options:
--cwd <path>- Target directory (default: current working directory)--verbose- Show detailed output--quiet- Only show warnings and errors
Package Manager Detection
The CLI automatically detects your package manager from the nearest lockfile:
pnpm-lock.yaml→ pnpmbun.lockb→ bunyarn.lock→ yarnpackage-lock.json→ npm
Fallback: npm if no lockfile found.
Monorepo Support
The CLI detects workspace roots and handles installation correctly:
# Install at package root (default)
npx autotel-cli init --cwd ./packages/my-app
# Install at workspace root
npx autotel-cli init --cwd ./packages/my-app --workspace-rootGenerated Files
src/instrumentation.mts
The CLI generates an instrumentation file with clear section markers:
/**
* autotel instrumentation - managed by autotel-cli
* Run `autotel add <feature>` to update this file
*/
import 'autotel/register';
import { init } from 'autotel';
// --- AUTOTEL:BACKEND ---
import { createDatadogConfig } from 'autotel-backends/datadog';
init({
// --- AUTOTEL:BACKEND_CONFIG ---
...createDatadogConfig({
apiKey: process.env.DATADOG_API_KEY,
}),
});.env.example
Environment variable template based on selected presets:
# Autotel configuration
# Copy to .env and fill in values
# Datadog API key for authentication
# ⚠️ SENSITIVE: Do not commit this value
DATADOG_API_KEY=your-api-keyStarting Your App
After running autotel init, start your app with the --import flag:
# Node.js ESM
node --import ./src/instrumentation.mts dist/index.js
# With tsx (development)
tsx --import ./src/instrumentation.mts src/index.tsOr add it to your package.json scripts:
{
"scripts": {
"start": "node --import ./src/instrumentation.mjs dist/index.js",
"dev": "tsx --import ./src/instrumentation.mts src/index.ts"
}
}Development
# Install dependencies
pnpm install
# Build
pnpm build
# Run tests
pnpm test
# Type check
pnpm type-checkLicense
Apache-2.0
