airplan

command module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 2 Imported by: 0

README

Logo

airplan

Turn local documents and artifacts into shareable links.

GitHub Release Go Reference GitHub Issues GitHub Pull Requests License

airplan uploads documents and file collections to S3-compatible storage and prints unguessable URLs:

$ airplan plan.md
https://plans.example.com/vq3nhk2p7r4wzt5c6ydjm3xhqd/plan.html

It is especially useful with coding agents: an agent can turn a local plan into a link you can open from any device. That makes reviewing plans from a mobile app practical even when the agent is running elsewhere and its local files are hard to reach.

It also works whenever you want to share a local document without running a server or using a paste service.

Collections make screenshots, browser recordings, PDFs, archives, and other artifacts easy to attach to a pull request or issue. Airplan uploads the original files together, generates an overview page with media previews and copyable direct links, and treats the directory as one cleanup unit.

  • Markdown becomes a polished page with light and dark themes. Authored HTML and link destinations are preserved, so treat it as trusted content.
  • Source and plain-text files become highlighted, gist-like pages.
  • HTML stays HTML, with no rendering step. Treat HTML input as trusted code: it may execute scripts when someone opens the link.
  • Images, video, and audio render on a responsive collection overview. Generic files remain available through direct open and download links.
  • Files live in a bucket you own. Use S3 directly or run one single-user Airplan server that keeps storage credentials off client machines.
  • The command has a predictable output contract for scripts and agents.

Live examples

  • Zero-downtime token migration is a realistic Markdown implementation plan with a diagram, responsive columns, alerts, tables, task lists, highlighted code, and automatic GitHub issue and pull-request links.
  • How airplan works is a concise architecture overview showing the CLI and library workflows.
  • Upload with airplan's Go API is a runnable Go example presented as a highlighted, gist-like page.
  • Release verification evidence is a file collection with an image preview and direct links to every original artifact.

The exact behavior is defined in SPEC.md.

Install

With Homebrew:

brew install --cask jimeh/tap/airplan

With mise:

mise use -g github:jimeh/airplan

With Go:

go install github.com/jimeh/airplan@latest

Prebuilt binaries are available from GitHub Releases. The macOS release archives contain Developer ID-signed, hardened-runtime, Apple-notarized binaries. Because a raw executable cannot carry a stapled notarization ticket, its first Gatekeeper assessment may require internet access. Binaries built locally with go install are not project-signed.

Install the agent skill

This repository includes an airplan agent skill for compatible coding agents. It teaches an agent to upload a requested document or file set, including visual evidence captured during authorized pull-request or issue work, then return direct and overview links.

Install it globally with the Skills CLI:

npx skills add jimeh/airplan --skill airplan --global

The installed binary also contains the canonical skill. An agent that only has the CLI can read it directly with:

airplan skill

Or install that exact embedded copy without checking out the repository:

mkdir -p ~/.agents/skills/airplan
airplan skill > ~/.agents/skills/airplan/SKILL.md

The airplan CLI must also be installed and configured on the machine where the agent runs. Once it is, ask the agent to share a plan, screenshot, or recording as a link and open the result from any browser.

Release assets include separate SPDX JSON SBOMs, and the archives are covered by GitHub artifact attestations. After downloading the release assets, verify them:

# Linux
sha256sum --ignore-missing --check checksums.txt
# macOS
shasum --ignore-missing --algorithm 256 --check checksums.txt

gh release verify v0.5.0 --repo jimeh/airplan

gh attestation verify airplan_0.5.0_darwin_arm64.tar.gz \
  --repo jimeh/airplan

Use the matching .zip name on Windows. Release verification checks GitHub's immutable release attestation; artifact verification confirms that the archive was produced by this repository's release workflow.

Configure storage

airplan works with any S3-compatible object store. You need a bucket, a public base URL, and API credentials with the permissions required by the commands you use. Uploads need object-write access. Remote listing and all delete or purge operations need bucket-list access; deletion also needs object-delete access. Object-read access powers show, get, remote purge inspection, and sync.

Create ~/.config/airplan/config.toml:

#:schema https://github.com/jimeh/airplan/releases/latest/download/airplan.schema.json
backend           = "s3"
endpoint          = "https://<account-id>.r2.cloudflarestorage.com"
bucket            = "plans"
region            = "auto"
public_base_url   = "https://plans.example.com"
access_key_id     = "..." # or AIRPLAN_ACCESS_KEY_ID
secret_access_key = "..." # or AIRPLAN_SECRET_ACCESS_KEY
# repo = "auto"           # infer GitHub origin for Markdown links
# collection_template = "~/.config/airplan/collection.html"

Explicit access and secret keys must be configured as a pair. Omit both to use the standard AWS credential chain. Endpoint and public base URLs must be absolute HTTP(S) URLs.

If the file contains credentials, protect it with chmod 600. airplan warns when its permissions are too broad. The #:schema comment enables validation and completion in editors with Taplo or the Even Better TOML extension.

Run airplan config schema to inspect every available file setting. See the configuration reference for profiles, environment-only setup, precedence, and diagnostic commands.

Run a single-user Airplan server

The default s3 backend keeps today's self-contained behavior: the CLI owns S3 credentials and calls storage directly. To configure S3 once for clients on other machines, run the built-in REST and MCP server:

openssl rand -base64 32 > /run/secrets/airplan-token
chmod 600 /run/secrets/airplan-token

airplan --profile storage \
  --manifest /var/lib/airplan/manifest.jsonl \
  serve --token-file /run/secrets/airplan-token

serve defaults to 127.0.0.1:8080 and requires an s3 profile. It checks storage before listening and exposes:

  • the authenticated REST API under /api/v1;
  • authenticated MCP Streamable HTTP at /mcp;
  • unauthenticated liveness at /healthz; and
  • the authoritative OpenAPI 3.0.3 schema at /openapi.yaml.

The default info log level keeps stderr quiet apart from the listening line and server failures. warn and error suppress the listening line. Use --log-level debug to diagnose request completion, safe authentication rejection reasons, Origin and size-limit failures, and MCP tool outcomes. --log-level trace additionally shows sanitized request, MCP method, and SDK lifecycle events:

airplan --profile storage serve \
  --token-file /run/secrets/airplan-token \
  --log-level debug

AIRPLAN_SERVER_LOG_LEVEL is the environment fallback; an explicit flag wins. Logs never include Authorization values, request or MCP bodies, tool arguments or results, uploaded content, capability URLs, storage identity, credentials, or filesystem paths.

Configure a client profile with only the server URL and bearer token:

[profiles.shared]
backend   = "airplan"
api_url   = "https://airplan.example.com"
api_token = "..." # or AIRPLAN_API_TOKEN

Normal commands then use the server without local S3 credentials:

airplan --profile shared plan.md
airplan --profile shared list
airplan --profile shared list --remote
airplan --profile shared sync
airplan --profile shared purge --older-than 30d

Terminate TLS at a trusted reverse proxy. HTTPS is required for non-loopback client URLs, and a non-loopback listen address requires --allow-non-loopback. Configure proxy body limits, buffering, and timeouts for large streaming uploads and downloads. Airplan v1 server authentication is one static bearer token: there are no accounts, roles, OAuth flow, or token issuance.

Run only one server process for a manifest. The file must be on persistent storage. A same-user local CLI and serve share the normal platform manifest by default, so airplan --profile storage list on the server machine includes uploads received through the API. Containers and services usually run with a different state directory; mount a persistent directory and pass the same explicit --manifest path when shared local history is desired. The server API scopes manifest results to its configured profile, bucket, and key prefix and does not expose unrelated records from a shared local file.

Cloudflare R2 setup

Cloudflare R2 is a good default when you want S3 compatibility and a custom domain for public links.

  1. Create a bucket, such as plans, in R2 → Create bucket.
  2. Under Bucket → Settings → Custom Domains, connect a domain such as plans.example.com.
  3. Under R2 → Manage API Tokens, create an Object Read & Write token scoped to this bucket. Do not use account-level or admin credentials.
  4. Put the endpoint, bucket, custom domain, and token credentials in the config file shown above.

The custom domain should serve uploaded objects without exposing a public bucket listing. As a quick check, its root URL should return an error while a known object URL loads normally.

Share documents and files

Pass airplan a file and use the URL it prints:

airplan plan.md                   # Markdown → rendered page
airplan report.html               # HTML → uploaded page
airplan pkg/server/handler.go     # source → highlighted page
airplan --open plan.md            # upload and open in a browser
airplan --json plan.md            # structured result for scripts

Pass multiple files to create one collection. Airplan prints each direct file URL in argument order, then the overview URL:

$ airplan login.png settings.png demo.webm
https://plans.example.com/vq3n.../login.png
https://plans.example.com/vq3n.../settings.png
https://plans.example.com/vq3n.../demo.webm
https://plans.example.com/vq3n.../index.html

A single recognized media or binary file also becomes a collection. Use --files when one text-like input should be uploaded unchanged instead of rendered as a document:

airplan screenshot.png
airplan --files README.md
airplan --json screenshot.png recording.webm

Collection JSON retains .url for the overview and puts the ordered direct links in .files[].url. The original file bytes are unchanged. Duplicate basenames, directories, and reserved names are rejected before upload.

Standard input works too. It defaults to Markdown when no format can be inferred:

cat plan.md | airplan --slug my-plan -
cat main.go | airplan --format txt --lang go -
Preview without uploading

preview uses the same renderer locally. It does not need storage credentials, contact S3, or update the upload history.

airplan preview plan.md > plan.html
airplan preview -o plan.html plan.md
airplan preview --files screenshot.png demo.webm -o index.html

Use --collection-template custom.html to replace the collection overview without affecting document templates. airplan template collection prints the built-in starting point; airplan template continues to print the document template. Collection preview does not copy large members, so save the overview beside staged input files when its local media links need to work.

Manage uploads
airplan list                     # uploads known to the local manifest
airplan ls -r                    # airplan uploads currently in the bucket
airplan show <url-or-key>         # validate and inspect one remote upload
airplan get [--source] <url-or-key>  # raw page or source bytes
airplan delete <url-or-key>      # delete one upload
airplan purge --older-than 30d   # review and delete older uploads
airplan sync                     # reconcile remote uploads into local history

Each successful upload is recorded in ~/.local/state/airplan/manifest.jsonl. Local commands use that history by default. Override it globally with --manifest PATH or AIRPLAN_MANIFEST; relative paths resolve from the current working directory. The option applies to direct S3 commands, serve, and stdio MCP using S3. An HTTP client rejects an explicit --manifest because only the server may choose its filesystem path, and ignores AIRPLAN_MANIFEST.

ls aliases list, and -r aliases --remote for list and purge. An explicit list --profile NAME filters local history by its recorded profile; --profile= selects root-level history. Without that flag, local list shows every profile. Without resolvable configuration, local list assumes the s3 backend and remains config-free. A config can also select an airplan profile, in which case list reads the server manifest and --config is useful without --remote.

--remote reads storage through the selected backend instead, so it can find uploads from other machines. Remote discovery recognizes document .airplan.json and collection .airplan-collection.json ownership markers with one bucket listing; it does not fetch each marker. The marker name supplies an untrusted kind hint, letting collection rows select exact index.html even beside other HTML files. A directory containing both names is a conflict with no inferred URL and cannot be managed through Airplan. Markerless directories are invisible. Use airplan show for validated kind, declared files, and completeness.

preview and get accept -o as shorthand for --output. When show, get, or delete uniquely matches marker-managed local history, its recorded profile is selected automatically unless --profile or AIRPLAN_PROFILE is explicit. The remote ownership marker is still authoritative.

airplan sync imports complete marker-managed uploads made from other machines into the receiving machine's manifest. It also tombstones local records whose markers are confirmed absent remotely; --no-prune makes the operation additive-only and --dry-run previews it. Sync verifies apparent absences with a targeted request instead of trusting a bucket listing alone. --concurrency controls concurrent marker requests (default 8, range 1-64). It converges the active remote inventory, not the historical JSONL event stream; deletion history is not uploaded.

Every new upload uses ownership marker version 3 with one declared-object model for pages, document sources, and collection files. Documents require a slug; collections have no slug and always use index.html. Current Airplan releases still manage marker versions 1 and 2. Older clients must be upgraded before they can manage any new v3 upload. Repository metadata is stored remotely for every input mode when --repo supplies or discovers a repository.

Pages airplan creates

Markdown pages include syntax highlighting, Mermaid diagrams from exact mermaid fences, a responsive table of contents, GitHub-style alerts, definition lists, YAML/TOML frontmatter, responsive Pandoc columns, rendered/source views, copy buttons, and links to the original Markdown. Frontmatter is shown collapsed at the top, and its string title sets the page title unless --title is given. Use --no-source if the original should not be uploaded.

By default, Markdown references such as #123, owner/repo#456, and full commit IDs link against a locally discovered GitHub origin. File repository context wins; a file outside Git falls back to the current working directory, which supports plans written to temporary directories. Use --repo none to disable this or --repo https://github.example/owner/repo to supply explicit GitHub Enterprise-compatible context. Discovery is local and never contacts the remote.

Pandoc columns use an outer {.columns} fenced div containing two or more {.column} children; optional validated width="40%" attributes weight them. Columns stack on narrow screens and when printed.

Plain-text and source files use the same standalone page shell and infer their highlight language from the filename. Use --lang to override it, especially for input piped through stdin.

Everything except the conditionally loaded Mermaid runtime is embedded in the HTML. Use --no-external-assets to keep airplan-managed features offline, or --mermaid-url to select another HTTPS CDN or self-hosted module. This policy does not block external content authored in trusted Markdown, HTML, or custom templates. The original Markdown remains exact in source view and the optional source object.

Collection overview pages render images inline, video and audio with controls, and arbitrary files as linked cards. Every member has Open, Download, and Copy URL actions, and the page can copy its own overview URL. Media never autoplays; images lazy-load; links remain usable without JavaScript. The page is self-contained, responsive, light/dark aware, and noindexed by default.

Collections accept at most 100 files. Defaults are 1 GiB per member and 2 GiB total; use --max-size and --max-total-size to adjust them per invocation, with 0 meaning unlimited. Increase --timeout explicitly for a substantial recording. Members stream from disk and downloads stream to their destination rather than buffering whole recordings in memory.

Automation and agents

For upload invocations, the command-line contract is intentionally simple:

  • A successful document prints its page URL and nothing else.
  • A successful collection prints ordered direct URLs followed by its overview.
  • With --json, stdout contains one JSON object instead.
  • Logs, warnings, progress, and errors go to stderr.
  • A non-zero exit means no upload URL was produced.

That makes direct capture safe:

url=$(airplan plan.md)
url=$(airplan --json plan.md | jq -r .url)
overview=$(airplan --json screenshot.png demo.webm | jq -r .url)
image=$(airplan --json screenshot.png | jq -r '.files[0].url')

Do not invent or reuse a URL after a failed command. For the complete CLI, config, key, and manifest contracts, use SPEC.md.

The same operation set is available to MCP clients. For a local agent, add airplan mcp as a stdio server; it follows the selected s3 or airplan profile exactly like the CLI. For remote agents, connect to the server's Streamable HTTP endpoint at https://airplan.example.com/mcp and configure Authorization: Bearer <token>. Clients that cannot attach a custom Authorization header are not supported by the initial single-user server.

The MCP server intentionally exposes only upload, list, inspect, delete, sync, and two-phase purge tools. Local stdio also supports collection upload from local paths. Hosted MCP does not accept server-local paths and therefore omits that tool. Template dumping, config inspection, arbitrary object access, and filesystem browsing are not exposed.

Configuration reference

airplan resolves settings in this order, from highest to lowest priority:

  1. Command-line flags
  2. AIRPLAN_* environment variables
  3. The selected named profile
  4. Root-level config file values
  5. Built-in defaults

The default config path is $XDG_CONFIG_HOME/airplan/config.toml, normally ~/.config/airplan/config.toml on Linux and macOS, with the corresponding platform config directory used on Windows. Select another file with --config PATH or AIRPLAN_CONFIG. An explicitly selected file must exist; only the platform-default file is optional.

Config files and profiles

Root-level values are shared defaults. Named profiles inherit them and override only what differs:

# Root-level keys must appear before the first [profiles.*] table.
backend = "s3"
endpoint = "https://<account-id>.r2.cloudflarestorage.com"
region = "auto"
key_prefix = "jimeh"
default_profile = "work"

[profiles.work]
bucket = "work-plans"
public_base_url = "https://plans.work.example.com"

[profiles.personal]
bucket = "personal-plans"
public_base_url = "https://plans.example.com"

[profiles.shared]
backend = "airplan"
api_url = "https://airplan.example.com"
api_token = "..."

backend defaults to s3, so existing configuration is unchanged. An airplan profile needs only api_url and api_token; it does not load the AWS credential chain. S3 values inherited from a root configuration are inactive for that profile. Conversely, API settings are inactive for an s3 profile.

Select a profile for one command with --profile / -p, or for profile-aware commands in a project-specific shell environment with AIRPLAN_PROFILE:

# For example, in a project shell setup, task runner, or .envrc:
export AIRPLAN_PROFILE="work"

airplan does not load .env files itself; the variable must be exported by your shell or another environment manager. An explicitly selected profile must exist in the config file. Without an explicit selection, airplan uses default_profile, the only named profile, or complete root-level values, in that order.

For a shared bucket, give each person a distinct key_prefix. The prefix also scopes remote list and purge operations.

Environment variables

A config file is not required. You can provide a complete backend setup through environment variables instead. For direct S3:

export AIRPLAN_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"
export AIRPLAN_BUCKET="plans"
export AIRPLAN_REGION="auto"
export AIRPLAN_PUBLIC_BASE_URL="https://plans.example.com"
export AIRPLAN_ACCESS_KEY_ID="..."
export AIRPLAN_SECRET_ACCESS_KEY="..."

airplan plan.md

For a server-backed client:

export AIRPLAN_BACKEND="airplan"
export AIRPLAN_API_URL="https://airplan.example.com"
export AIRPLAN_API_TOKEN="..."

airplan plan.md

Avoid committing credential values in project environment files. Explicit access and secret keys must be set as a pair. If neither is set through AIRPLAN_* variables or the config file, airplan uses the standard AWS credential chain, including AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and the shared credentials file.

Variable Purpose
AIRPLAN_CONFIG Select an alternate config file
AIRPLAN_PROFILE Select a named [profiles.*] profile
AIRPLAN_BACKEND Select s3 or airplan
AIRPLAN_API_URL Set an Airplan server base URL
AIRPLAN_API_TOKEN Set its bearer token
AIRPLAN_SERVER_LOG_LEVEL Set serve logging from error to trace
AIRPLAN_MANIFEST Select a local S3/service manifest
AIRPLAN_ENDPOINT Set the S3-compatible API endpoint
AIRPLAN_BUCKET Set the destination bucket
AIRPLAN_REGION Set the S3 signing region
AIRPLAN_ACCESS_KEY_ID Set the explicit access key ID
AIRPLAN_SECRET_ACCESS_KEY Set the matching secret access key
AIRPLAN_PUBLIC_BASE_URL Set the base URL used for public links
AIRPLAN_KEY_PREFIX Prefix and scope uploaded object keys
AIRPLAN_TEMPLATE Select a custom HTML page template
AIRPLAN_COLLECTION_TEMPLATE Select a collection overview template
AIRPLAN_NO_EXTERNAL_ASSETS Disable airplan-managed external loads
AIRPLAN_MERMAID_URL Set an alternate HTTPS Mermaid module URL
AIRPLAN_REPO Set auto, none, or a repository URL
AIRPLAN_TIMEOUT Set a duration such as 30s; 0 disables it

no_source and indexable do not have environment variables. Configure them in TOML or override them with --no-source and --indexable.

Inspect configuration
airplan config profiles        # list named profiles and the explicit default
airplan config show            # show resolved values and their winning source
airplan config show --json     # return the same diagnostics for scripts
airplan config schema          # print the complete config file JSON Schema

config show always redacts access keys, secret keys, and API tokens. It resolves the active configuration without contacting storage or resolving the standard AWS credential chain. config profiles --json provides a scriptable profile inventory without requiring each profile to be complete.

Shell completion

airplan generates completion scripts at runtime for Bash, Zsh, Fish, and PowerShell:

# Bash
source <(airplan completion bash)

# Zsh
source <(airplan completion zsh)

# Fish
airplan completion fish | source
# PowerShell
airplan completion powershell | Out-String | Invoke-Expression

These commands enable completion for the current session. Run airplan completion <shell> --help for persistent installation instructions specific to that shell and platform.

Privacy model

airplan links are capability URLs. Every path contains 128 random bits, and rendered pages include a noindex directive. The link is effectively private while it remains unknown, but it is not access-controlled:

  • Anyone with the link can open it and pass it on.
  • Chat tools may scan or prefetch links shared through them.
  • Objects remain in the bucket until they are deleted. airplan serves them with Cache-Control: no-store so browsers and shared caches should not retain a reusable response after deletion.
  • Bucket listing must remain private.

Collections broaden what can leak through a capability URL. Review screenshots and recordings for tokens, usernames, private messages, browser chrome, and unrelated desktop content before uploading. Filenames are public in direct URLs and on the overview. HTML and SVG members may execute active content when opened; Airplan uploads every member byte-for-byte and does not sanitize it.

Use airplan purge --older-than 30d --yes manually or from cron when uploads should expire. For large remote inventories, purge --remote --concurrency N changes only parallel marker inspection (default 8, range 1-64); destructive deletions stay sequential after confirmation. For defense in depth on Cloudflare, a Transform Rule can add an X-Robots-Tag: noindex response header to the custom domain.

Go library

The CLI is a thin shell over an importable Go package:

import (
    "context"
    "fmt"
    "io"
    "os"

    "github.com/jimeh/airplan/airplan"
)

func upload(ctx context.Context, f io.Reader) error {
    cfg, err := airplan.LoadConfig(airplan.ConfigOptions{})
    if err != nil {
        return err
    }
    client, err := airplan.New(ctx, cfg)
    if err != nil {
        return err
    }
    res, err := client.Upload(ctx, airplan.Input{
        Reader: f,
        Name:   "plan.md",
    })
    if err != nil {
        return err
    }
    fmt.Println(res.URL)
    return nil
}

Collections use seekable readers and declared sizes so large members can stream without whole-file buffering:

func uploadFiles(ctx context.Context, client *airplan.Client) error {
    image, err := os.Open("screenshot.png")
    if err != nil {
        return err
    }
    defer image.Close()

    info, err := image.Stat()
    if err != nil {
        return err
    }
    res, err := client.UploadFiles(ctx, airplan.FilesInput{
        Files: []airplan.FileInput{{
            Name:   "screenshot.png",
            Reader: image,
            Size:   info.Size(),
        }},
    })
    if err != nil {
        return err
    }
    fmt.Println(res.Files[0].URL, res.URL)
    return nil
}

The library exposes the same behavior as the CLI. See the Go reference for its API and IMPLEMENTATION.md for the repository architecture. Construct clients with airplan.New; nil contexts, nil configuration, and zero-value clients return errors. Canceling a context stops waiting for a blocked input reader, but callers that retain one must still unblock or close it because Go cannot interrupt an arbitrary io.Reader.

Development

The project uses mise for its task surface:

mise run treeboot           # bootstrap a new linked worktree
mise run setup              # install tools and Git hooks
mise run check              # lint, generated files, format, and unit tests
mise run check:spec-sync    # check contract changes update spec versions
mise run test:coverage      # statement summary + coverage.html report
mise run test-integration   # MinIO round trip; requires Docker
mise run test:browser       # Chromium page smoke tests; installs browser
mise run audit:deps         # audit Go modules and npm dependencies
mise run release:snapshot   # build release artifacts without publishing
mise run verify             # broad local validation
mise run update:mermaid     # update an eligible, 72-hour-old Mermaid pin

The browser suite requires Node.js and Chromium. The shared task installs the locked npm dependencies and matching Chromium build on demand. CI also installs Chromium's Linux system dependencies first. Failed CI runs retain the Playwright HTML report, traces, screenshots, and other test results for seven days. On a Linux development host missing those system libraries, run npm ci followed by npx playwright install-deps chromium once; the latter may require elevated privileges.

mise run check:spec-sync compares the branch with origin/main by default. Set SPEC_SYNC_BASE to check against another revision. It requires a SPEC.md version bump when main.go, non-test Go files in cli/ or airplan/, page assets, or the generated configuration schema are added, changed, moved, or removed. It also keeps the target version in IMPLEMENTATION.md aligned with a bumped spec. The PR job currently reports policy findings as warning annotations while the signal matures; operational failures still fail CI. Local policy findings fail the task.

See AGENTS.md for the repository map and contribution constraints. Releases are managed by release-please and GoReleaser from conventional commits.

License

MIT — see LICENSE.

Documentation

Overview

Command airplan renders and uploads AI/LLM plan documents, with a local preview path that does not require object storage. Behavior is defined by SPEC.md.

Directories

Path Synopsis
Package airplan is the core library behind the airplan CLI: config loading, input detection, markdown rendering, key generation, and uploads to S3-compatible storage.
Package airplan is the core library behind the airplan CLI: config loading, input detection, markdown rendering, key generation, and uploads to S3-compatible storage.
Package api exposes Airplan's authoritative REST wire contract.
Package api exposes Airplan's authoritative REST wire contract.
Package cli implements the airplan command-line interface.
Package cli implements the airplan command-line interface.
internal
cmd/checkopenapi command
Command checkopenapi verifies that the checked-in OpenAPI-generated Go client/server/models exactly match api/openapi.yaml.
Command checkopenapi verifies that the checked-in OpenAPI-generated Go client/server/models exactly match api/openapi.yaml.
cmd/checkspecsync command
Command checkspecsync detects contract changes that are missing the corresponding specification version updates.
Command checkspecsync detects contract changes that are missing the corresponding specification version updates.
cmd/genmermaid command
Command genmermaid generates the pinned Mermaid dependency constants.
Command genmermaid generates the pinned Mermaid dependency constants.
cmd/genschema command
cmd/updatedemos command
Command updatedemos refreshes README demo links when their origin storage bytes differ from the repository's upload-mode golden pages and source files.
Command updatedemos refreshes README demo links when their origin storage bytes differ from the repository's upload-mode golden pages and source files.
cmd/updatemermaid command
Command updatemermaid safely updates the repository's Mermaid pin.
Command updatemermaid safely updates the repository's Mermaid pin.
httpapi/generated
Package generated provides primitives to interact with the openapi HTTP API.
Package generated provides primitives to interact with the openapi HTTP API.
serverlog
Package serverlog provides the deliberately narrow logging surface used by the self-hosted HTTP server.
Package serverlog provides the deliberately narrow logging surface used by the self-hosted HTTP server.
Package skills embeds the canonical agent skills shipped with airplan.
Package skills embeds the canonical agent skills shipped with airplan.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL