Monorepo for Aesthetic.Computer aesthetic.computer
core studies ac-cli-public-plan.md
11 kB

Study: Public kidlisp CLI (Bun-First + npm Distribution) #

Date: 2026-03-09
Context: Aesthetic Computer already has a strong internal command surface in .devcontainer/config.fish, plus public Netlify APIs (/api/store-kidlisp, /api/store-clock, /api/store-piece, /api/tv, /api/api-docs). This study proposes a public, pipe-friendly CLI with Bun as the primary runtime, published via npm for broad compatibility.


Short Answer #

Yes, this is very feasible, and we can do it with low risk by:

  • Building one public kidlisp CLI package first with Bun-first tooling and clean JSON/NDJSON output.
  • Reusing existing API/auth patterns (tezos/ac-login.mjs, system/netlify/functions/api-docs.mjs).
  • Mapping internal fish commands into public-safe equivalents.
  • Keeping infrastructure/devcontainer-specific commands in an optional internal plugin.

Naming Decision #

Use kidlisp as the primary CLI binary name.

Validation snapshot (2026-03-09):

  • local command: free
  • npm package: free
  • PyPI name: free
  • crates.io name: free
  • Homebrew formula: free

Product Goal #

Ship a public kidlisp CLI that can:

  • Be built primarily with Bun and distributed on npm for Bun/Node/Deno users.
  • Work well in pipelines (stdout machine-readable, stderr errors).
  • Publish, fetch, and inspect KidLisp, clock, and piece data via AC APIs.
  • Support "run/preview" workflows for clocks and KidLisp.
  • Expose a stable command grammar that can grow over time.

Brand + Expansion Strategy #

Use kidlisp as the sticky, memorable front door, then expand it into broader AC workflows over time.

Practical shape:

  • Keep the root command short and iconic: kidlisp.
  • Start with core creative flows (publish, get, recent, validate, tree).
  • Add AC platform capabilities under clear namespaces as growth happens:
    • kidlisp clock ...
    • kidlisp piece ...
    • kidlisp tv ...
    • kidlisp auth ...
    • kidlisp api ...
  • Keep advanced/internal operations as optional plugins so the main CLI stays clean.

Tooling + Help Experience #

The single kidlisp binary should feel friendly for first-time users and fast for shell users.

Core UX rules:

  • kidlisp (no args) shows a short command dashboard with the top 6 workflows.
  • kidlisp --help stays concise and example-driven.
  • kidlisp help <command> prints focused help + copy-paste examples.
  • Every command supports --json and prints pipe-safe output.
  • Errors always include a direct next command to fix the issue.

Recommended starter commands:

  • kidlisp quickstart (install check + first publish flow)
  • kidlisp doctor (token/network/env diagnostics)
  • kidlisp examples (small runnable snippets)
  • kidlisp completion <bash|zsh|fish> (shell completion scripts)

Runtime + Toolchain Strategy #

  • Primary runtime and dev tooling: Bun.
  • Compatibility target: Node.js LTS/current for end users and CI.
  • Distribution channel: npm package kidlisp.
  • Portable distribution: standalone compiled binaries (no language runtime required).
  • Deno support: npm interop first (npm:kidlisp), optional JSR wrapper later.
  • Keep core runtime APIs portable (fetch, URL, standard streams) and avoid Bun-only behavior in user-facing paths.

Non-Goals (Phase 1) #

  • Porting every internal fish helper 1:1.
  • Bundling privileged internal ops (host SSH, emacs daemon control, private infra tools).
  • Replacing MCP (@aesthetic.computer/mcp). CLI and MCP should share core API code.

Existing Building Blocks #

  • Internal command inventory and behavior:
    • .devcontainer/config.fish
  • Existing auth flow and token cache:
    • tezos/ac-login.mjs (~/.ac-token)
  • Public API docs endpoint:
    • system/netlify/functions/api-docs.mjs
  • Core publish/read endpoints:
    • system/netlify/functions/store-kidlisp.mjs
    • system/netlify/functions/store-clock.mjs
    • system/netlify/functions/store-piece.mjs
  • Existing npm package + API wrapper pattern:
    • mcp-server/

Proposed Public Command Surface (v0) #

Auth #

  • kidlisp auth login
  • kidlisp auth status
  • kidlisp auth token
  • kidlisp auth logout

API Discovery + Raw Access #

  • kidlisp api docs [--json]
  • kidlisp api list [--json]
  • kidlisp api call <path> [--method GET|POST] [--data ...]

KidLisp #

  • kidlisp publish [--file path | --stdin | --source "..."]
  • kidlisp get <code>
  • kidlisp recent [--limit N] [--sort recent|hits] [--handle @x]
  • kidlisp stats functions [--limit N]
  • kidlisp tree <code|@handle> [--source] [--json] (from kidlisp/tools/source-tree.mjs)
  • kidlisp validate [--file path | --stdin | --source "..."]

Clock #

  • kidlisp clock publish [--file path | --stdin | --source "..."]
  • kidlisp clock get <code>
  • kidlisp clock recent [--limit N] [--sort recent|hits]
  • kidlisp clock now

Piece #

  • kidlisp piece publish [--file path | --stdin | --source "..."] [--name name]

TV / Playlists / Inspect #

  • kidlisp tv [--types kidlisp,clock,piece] [--limit N] [--format dp1|json]
  • kidlisp inspect endpoint <name-or-path>
  • kidlisp inspect handle <@handle>
  • kidlisp inspect piece <code>

Pipe Utility #

  • kidlisp pipe build-stream (stdin passthrough + POST, based on internal ac-pipe)

Pipe-First Contract #

The CLI should be deterministic in shell pipelines:

  • If output is piped or --json/--ndjson is set: machine format only on stdout.
  • Human messages and progress always on stderr.
  • Standard exit codes:
    • 0 success
    • 2 usage/validation
    • 3 auth required/expired
    • 4 remote API error
    • 5 network/timeout

Recommended output flags:

  • --json single JSON object
  • --ndjson one JSON object per line
  • --raw emit only the requested field/body
  • --quiet suppress non-essential stderr

Internal Fish -> Public CLI Mapping #

Internal command Public CLI target Notes
ac-login, ac-token kidlisp auth ... Reuse OAuth/token file pattern
st / ac-st kidlisp tree Add clean JSON mode for pipelines
ac-tv kidlisp tv Keep query passthrough
ac-pipe kidlisp pipe build-stream Same stdin streaming idea
ac-kidlisp kidlisp ... Public subset only
ac-ff1 kidlisp device ... (optional plugin) Keep out of core v0
ac-function kidlisp logs ... (internal plugin) Requires netlify/dev setup
ac-record kidlisp render ... (phase 2) Wrap recording orchestrator

Runtime + Distribution Plan #

Implementation home:

  • kidlisp-cli/
  • kidlisp-cli/INSTALLER-SPEC.md
  • kidlisp-cli/RELEASE-SPEC.md

Phase 1 distribution #

  • Publish npm package: kidlisp
  • Binary: kidlisp
  • Install/use:
    • bunx kidlisp ...
    • bun add -g kidlisp
    • npm i -g kidlisp
    • npx kidlisp ...
    • deno run -A npm:kidlisp ...
    • deno install -gA -n kidlisp npm:kidlisp

Phase 2 distribution (portable, no runtime required) #

  • Publish standalone binaries compiled from Bun for:
    • Linux x64/arm64
    • macOS arm64/x64
    • Windows x64
  • Attach binaries + checksums to GitHub releases.
  • Provide one-line install script for Unix-like systems.

Installer Experience (Claude-Code Style) #

Goal: users should install kidlisp from a website in one command, with no prior language runtime.

Target UX:

  • macOS/Linux:
    • curl -fsSL https://kidlisp.com/install | sh
  • Windows PowerShell:
    • irm https://kidlisp.com/install.ps1 | iex

Installer behavior:

  • Detect OS/arch and download the correct binary from releases.
  • Verify checksum before placing the binary on PATH.
  • Install to a predictable location (~/.local/bin or platform equivalent).
  • Print a copy-paste PATH fix if needed.
  • Support version channels (stable, beta) and pinned versions.

CLI support commands:

  • kidlisp version
  • kidlisp self-update
  • kidlisp self-update --channel beta
  • Publish a thin JSR package/wrapper for best Deno UX:
    • jsr:@aesthetic-computer/kidlisp

Proposed Repository Layout #

kidlisp-cli/
  package.json
  README.md
  src/
    bin.ts
    core/
      config.ts
      auth.ts
      http.ts
      output.ts
      errors.ts
    commands/
      auth.ts
      api.ts
      kidlisp.ts
      clock.ts
      piece.ts
      tv.ts
      inspect.ts
      pipe.ts
  tests/
    cli.spec.ts
    smoke.spec.ts

Delivery Phases #

Phase 0: Contract + Inventory (1-2 days) #

  • Lock command names, flags, and output schema.
  • Mark each command as public, auth, or internal.
  • Define stable JSON response shapes.

Phase 1: CLI Core + Bun-First npm Release (3-5 days) #

  • Build parser + output layer + error model with Bun as primary dev runtime.
  • Implement auth, api, publish/get/recent, clock publish/get/recent/now, piece publish, tv.
  • Publish kidlisp@0.1.0.

Phase 2: Inspect + Pipe + Local Run Helpers (3-4 days) #

  • Add inspect family.
  • Add pipe build-stream.
  • Add KidLisp/clock run helpers (--open, URL emit, and local validation mode).

Phase 3: Portable Binary Releases (2-3 days) #

  • Add Bun compile pipeline for multi-platform standalone binaries.
  • Ship checksums/signatures and install script.
  • Test binary startup + command parity vs npm package.

Phase 4: Deno First-Class + Hardening (2-3 days) #

  • Add Deno install docs and smoke tests.
  • Optional JSR wrapper publish.
  • Finalize CI matrix and shell examples.

Testing + CI #

Automated #

  • Unit tests for argument parsing and output modes.
  • Integration tests against production-safe read endpoints.
  • Mocked tests for mutating endpoints.
  • Snapshot tests for --json and --ndjson.

CI matrix #

  • Bun latest.
  • Node LTS + current.
  • Deno latest.
  • Compiled binary smoke tests on Linux/macOS/Windows.
  • Linux + macOS runners.

Security + Safety Rules #

  • Prefer AC_TOKEN env, fallback to ~/.ac-token.
  • Never print token values unless explicitly requested (kidlisp auth token).
  • Redact auth headers in debug logs.
  • Add --confirm for destructive/mutating operations where relevant.
  • Keep internal/privileged commands in separate plugin package.

First Milestone Definition of Done #

v0.1.0 is done when:

  • A new user can install and run from Bun, npm/Node, and Deno.
  • These pipeline examples work:
    • echo "(wipe blue)" | bunx kidlisp publish --stdin --json | jq -r .code
    • echo "(wipe blue)" | kidlisp publish --stdin --json | jq -r .code
    • kidlisp recent --limit 20 --ndjson | jq -r .code
    • kidlisp clock publish --file melody.txt --json
    • kidlisp api docs --json | jq '.endpoints | length'
  • CLI docs include copy-paste quickstart for bash/zsh/fish.

v0.2.0 is done when:

  • A user can run kidlisp with zero language runtime installed.
  • Release assets include platform binaries + checksums.
  • Portable binary behavior matches npm package behavior for core commands.

Recommendation #

Start now with a small public core and a strict pipe contract.
Do not port internal fish tooling wholesale. Instead, split into:

  • kidlisp (public, stable, scriptable)
  • optional internal plugin package for infra/devcontainer operations.