Claude
Skills
Sign in
Back

pp-airframe

Included with Lifetime
$97 forever

Aircraft forensics from open public records — tail-number dossiers, fleet research, model-level safety, and NTSB event archaeology. Trigger phrases: `look up tail number`, `who owns this plane N…`, `what aircraft does <company> own`, `safety record of <aircraft model>`, `accident history for`, `crash history for <aircraft model>`, `find aircraft registered to`, `NTSB event ERA…`, `use airframe`, `run airframe`. Secondary (day-of only, requires flight-goat + within 72hr of departure): `is UA<flight> safe`, `what plane is <flight>`.

General

What this skill does

<!-- GENERATED FILE — DO NOT EDIT.
     This file is a verbatim mirror of library/developer-tools/airframe/SKILL.md,
     regenerated post-merge by tools/generate-skills/. Hand-edits here are
     silently overwritten on the next regen. Edit the library/ source instead.
     See the repository agent guide, section "Generated artifacts: registry.json, cli-skills/". -->

# airframe — Printing Press CLI

## Prerequisites: Install the CLI

This skill drives the `airframe-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:

1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
   ```bash
   npx -y @mvanhorn/printing-press-library install airframe --cli-only
   ```
2. Verify: `airframe-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.

If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.3 or newer):

```bash
go install github.com/mvanhorn/printing-press-library/library/developer-tools/airframe/cmd/airframe-pp-cli@latest
```

If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.

## The two-tier model (read this first, every invocation)

| Tier | Dataset | Install requirement | Answers questions like |
|------|---------|---------------------|------------------------|
| **1** | FAA Aircraft Registry | **none** — just `airframe-pp-cli` | "Who owns N12345?" • "How old is this plane?" • "What aircraft does Berkshire Hathaway own?" • "What type is this Mode-S code?" |
| **2** | NTSB CAROL accident database | **`mdbtools` package** | "How safe is a Cessna 172?" • "Crash history for the Boeing 737 MAX 8" • "Has tail N12345 ever been in an incident?" • "Probable cause of event ERA22LA001" |

`airframe flight <ident>` additionally requires `flight-goat-pp-cli` installed + `FLIGHT_GOAT_API_KEY_AUTH` set, **and only works within ~72 hours of departure** (airlines don't assign a specific tail to a flight before then). For pre-purchase or pre-booking "is my flight safe" questions, use a Tier 2 model-level lookup with the equipment type from the booking site.

## Step 0 — Always run doctor first

Before answering any user question, run:

```bash
airframe-pp-cli doctor --json
```

Parse the JSON to determine:

- `db_exists` — has the user ever synced?
- `sync_meta` — which sources (faa_master, ntsb_avall) are present and how fresh?
- `mdbtools.detected` — can we serve Tier 2 questions?
- `flight_goat.detected` — can we serve `flight <ident>` questions?

**Branch from here** based on what the user actually asked.

## Decision tree (use this to drive every user interaction)

### A) User asks a Tier 1 question and Tier 1 is missing
*Example: "Who owns N628TS?" but `airframe-pp-cli doctor` shows db_exists=false or sync_meta is empty.*

1. Tell the user: "I need to download the FAA registry first (~80 MB, ~30 seconds, no setup needed)."
2. Offer to run `airframe-pp-cli sync` for them.
3. After sync completes, answer their original question.

### B) User asks a Tier 1 question and Tier 1 is ready
Just answer it directly:
```bash
airframe-pp-cli tail N628TS
airframe-pp-cli owner "Berkshire" --limit 20
```

### C) User asks a Tier 2 question (safety / accident / NTSB) and **`mdbtools` is missing**
*This is the most important branch — handle it with care.*

Surface a clear explanation:

> "To answer that, I need NTSB accident data, which requires the `mdbtools` package (NTSB ships their data in Microsoft Access format). It's a one-time install — would you like me to install it for you?"

If the user says yes, detect their OS and run the right command:

```bash
# Detect OS
uname -s   # → "Darwin" for macOS, "Linux" for Linux
# Detect Linux distribution if Linux
cat /etc/os-release 2>/dev/null | grep -E '^ID='
```

Then propose **before running**:

| OS detected | Command to run |
|---|---|
| macOS (`Darwin`) | `brew install mdbtools` |
| Ubuntu / Debian (`ID=ubuntu`, `ID=debian`) | `sudo apt update && sudo apt install -y mdbtools` |
| Fedora (`ID=fedora`) | `sudo dnf install -y mdbtools` |
| RHEL / Rocky / Alma (`ID=rhel`/`ID=rocky`/`ID=almalinux`) | `sudo dnf install -y mdbtools` |
| Arch (`ID=arch`) | `yay -S --noconfirm mdbtools` *(AUR — needs `yay` or `paru`; if neither is present, tell the user to install one first)* |

**Important:** never run `sudo` commands without first showing the user what you plan to run and confirming. The `--noconfirm` for `yay` is OK because the user has already opted in once.

After `mdbtools` installs, run:

```bash
airframe-pp-cli sync --source all
```

Then answer the original question.

### D) User asks a Tier 2 question and `mdbtools` is present but NTSB hasn't been synced
*`doctor` shows `mdbtools.detected=true`, but `sync_meta` has no `ntsb_avall` row.*

Tell the user: "I have the NTSB ingest tool installed but haven't synced the data yet. Would you like me to run that now? It's ~90 MB and takes about a minute."

If yes:
```bash
airframe-pp-cli sync --source ntsb
```

### E) User asks a flight-ident question — **first, check the 72-hour gate**
*Examples: "Is UA1234 safe?", "What plane will I be on for AA200?", "Is my flight on DL5678 tomorrow OK?"*

**Critical context:** Airlines don't assign a specific tail to a flight until ~48–72 hours before departure. If the user is more than 72 hours from their flight (or shopping a ticket they haven't booked yet), looking up the specific tail is **impossible** — there is no tail yet. Don't burn a flight-goat call on it.

**Step 1 — establish when the flight is.** Ask the user (or infer from context):

> "When is the flight? Tail assignments are made 48–72 hours before departure — if you're shopping or it's further out than that, I'll point you at the model-level safety lookup instead, which is more reliable for that horizon."

**Step 2 — branch:**

- **Flight is >72 hours away or hypothetical** → recommend the model-level fallback. Most airline booking sites tell you the equipment type (e.g. "Boeing 737 MAX 8" or "Airbus A321neo"). Run:
  ```bash
  airframe-pp-cli model "Boeing 737 MAX 8"
  ```
  This answers the user's underlying question ("is the type of plane I'll be on safe?") and needs no flight-goat at all. (It still needs Tier 2 / mdbtools for safety data — fall through to branch C if missing.)

- **Flight is ≤72 hours away OR the user is asking about a flight that already happened (post-incident research)** → proceed with flight-goat resolution. Continue to step 3.

**Step 3 — flight-goat present? If not, install it.**

If `flight_goat.detected=false`, tell the user:

> "To resolve a specific flight ident (like UA1234) to a tail number, I need `flight-goat-pp-cli`. Would you like me to install it? It also requires a FlightAware AeroAPI key — that part you'll need to provide."

If yes:
```bash
go install github.com/mvanhorn/printing-press-library/library/travel/flight-goat/cmd/flight-goat-pp-cli@latest
```

**Step 4 — `FLIGHT_GOAT_API_KEY_AUTH` set? If not, explain the cost.**

If the env var is unset, tell the user that flight-goat routes through FlightAware's AeroAPI (paid service) and they'll need to sign up at flightaware.com/aeroapi to get a key. Don't push past without explicit direction.

**Step 5 — run the lookup.**

```bash
airframe-pp-cli flight UA1234
```

Note that the result may include **multiple recent tails** that have flown the same ident over the past 14 days — flight-goat returns the history, not just the next scheduled flight. For post-incident research, look at the date-aligned tail; for pre-departure curiosity, look at the most recent one.

## Commands

| Command | Tier | What it does |
|---|---|---|
| `sync [flags]` | both | Download 

Related in General