Locara

06 — CLI (locara)

The single binary every developer interacts with. Eight commands, designed to be predictable, pipeable, and AI-friendly.

Command surface

locara init [template] [name] [--from-prompt <text>]
locara dev [--profile=<low|mid|high>] [--port=<n>]
locara test [--filter=<pattern>] [--watch]
locara simulate --profile=<low|mid|high> [--ram-cap=<n>]
locara verify [--strict] [--skip-static-analysis]
locara build [--target=<universal|aarch64|x86_64>]
locara publish [--registry=<url>] [--dry-run]
locara doctor

Plus utilities:

locara db generate-types
locara db migrate
locara db diff
locara model add <model-id>
locara model list
locara model verify

Conventions:

  • All commands return non-zero on error.
  • Output respects --json for machine-readable.
  • Verbose with -v; debug with -vv.
  • Reads ~/.locara/config.toml for global config; project root has locara.json.

locara init

Scaffold a new app.

locara init transcribe my-transcribe
# Creates ./my-transcribe/ from the "transcribe" template

locara init --from-prompt "an app that organizes screenshots by content"
# Uses LLM (Claude/OpenAI via env keys) to pick template + draft manifest

locara init blank my-app
# Generic minimal template

Templates (v1):

  • blank — minimal app with chat UI.
  • transcribe — audio → text scaffold.
  • docvault — document → search scaffold.
  • chat — pure conversational.

After scaffolding:

my-transcribe/
├── locara.json
├── package.json
├── src/
├── db/schema.sql
├── tests/
├── .gitignore
└── README.md

Then cd my-transcribe && locara dev.

--from-prompt is the agent-friendly path. Uses ANTHROPIC_API_KEY or OPENAI_API_KEY from env. Outputs the same scaffold structure but with prompted customizations.


locara dev

Hot-reload dev server. Opens a Tauri window with two halves: app on left, dev panel on right.

locara dev
locara dev --profile=low      # Simulate 8GB Mac
locara dev --port=3001        # Override frontend dev port

Dev panel shows:

  • Capability log — every model load, fs access, IPC call. Green ✓ for declared, red ✗ for undeclared.
  • Profile simulator — Low/Mid/High toggle.
  • Resource monitor — RAM, model size, disk, sqlite query latency.
  • Capability suggester — when code attempts an undeclared capability, offers one-click “add to manifest.”
  • Type-gen status — shows when schema → types regeneration runs.

The dev runtime is the same Locara runtime that ships to users, plus the dev panel. Bugs fixable in dev are bugs fixable in production.

Frontend changes hot-reload via Vite. Manifest changes restart the runtime. Schema changes trigger migration generation.


locara test

Run tests. Three layers:

locara test                        # all tests
locara test --filter=capabilities  # only matching files
locara test --watch                # rerun on change

Test categories:

  1. Capability tests (tests/capabilities.test.ts) — Validate the app respects its manifest declarations under various scenarios.
  2. Unit tests (tests/unit.test.ts) — Standard logic tests using @locara/test helpers.
  3. Integration tests (tests/integration.test.ts) — Run the app end-to-end in headless mode.

Example capability test:

import { test, expect, runApp } from '@locara/test'

test('does not attempt network', async () => {
  const app = await runApp()
  await app.simulate('user-loads-audio-file', './fixtures/sample.wav')
  expect(app.networkAttempts).toEqual([])
})

test('only reads user-selected files', async () => {
  const app = await runApp()
  await app.simulate('user-picks-files', ['./fixtures/a.wav'])
  for (const path of app.fsReads) {
    expect(path).toMatch(/^\/user-selected\//)
  }
})

Required to pass before locara publish will submit.


locara simulate

Run the app under a forced device profile.

locara simulate --profile=low --ram-cap=6
# Run as if on an 8GB Mac with 6GB available RAM

Different from dev — no hot reload, headless option available, behaves like a real install.

Useful for: validating low-tier UX, reproducing user-reported issues, performance testing.


locara verify

Validate manifest + capabilities + signatures + dependencies. Run automatically before publish.

locara verify

Checks:

  1. JSON schema validity.
  2. Identity consistency (publisher account, version vs git tags).
  3. File existence (icons, screenshots, schema, entry).
  4. Capability schema correctness.
  5. Profile consistency.
  6. Model hash validity (resolves all @sha256:... against registry).
  7. Static analysis vs declared capabilities.
  8. License SPDX validity.
  9. Lockfile integrity (locara.lock.json matches resolved deps).

Output:

✓ Manifest schema valid
✓ Identity matches local git
✓ Files present (3 screenshots, icon, schema)
✓ Capabilities well-formed
✓ Profiles ordered correctly
✓ All model hashes resolved (2 models, 1.4 GB total)
⚠ Static analysis: src/lib/transcribe.ts:47 uses fetch() but net=false
✗ License "Apache 2" is not a valid SPDX identifier (try "Apache-2.0")

1 warning, 1 error.

Strict mode (--strict) treats warnings as errors. CI uses --strict.


locara build

Production build. Outputs a signed .app bundle.

locara build
locara build --target=universal   # Apple Silicon + Intel
locara build --target=aarch64     # Apple Silicon only (default)

Steps:

  1. locara verify --strict
  2. tsc + frontend bundle (Vite)
  3. Tauri build with capability manifest
  4. Code sign with developer cert (from keychain or env)
  5. Notarize (macOS) — submits to Apple, polls for approval
  6. Output to dist/<app-name>-<version>.app and .dmg

Build is reproducible given locara.lock.json. CI builds on every publish.


locara publish

Submit to registry.

locara publish
locara publish --dry-run         # Validate only, no submission
locara publish --registry=https://my-org.locara.app

Steps:

  1. locara verify --strict
  2. locara test
  3. Push current git ref + manifest to Locara CI (or self-hosted)
  4. CI clones source by commit hash in clean environment
  5. CI runs locara build
  6. CI generates Sigstore-style provenance attestation
  7. CI uploads artifact + manifest + attestation to registry
  8. Registry runs additional review checks (capability profile risk classification)
  9. Auto-approve if low-risk; queue for human review if not
  10. Output: registry URL, expected approval timeline

Developer never uploads a binary. CI builds from source.


locara doctor

Diagnose local environment.

locara doctor

Output:

locara doctor — running diagnostics

System:
  ✓ macOS 14.5 (Apple Silicon, M2 Pro, 32GB RAM)
  ✓ Xcode Command Line Tools installed
  ✓ Apple Developer signing identity present

Locara:
  ✓ locara CLI v0.1.4
  ✓ @locara/sdk v0.1.4 (compatible)
  ✓ Tauri 2.1.0
  ✓ Rust 1.81 (rustup)
  ✓ Bun 1.2.10
  ✓ bun 1.2.0
  
Project:
  ✓ locara.json valid
  ✓ Models cached: 2/2 (whisper-large-v3-q4, qwen2.5-3b-q4)
  ✓ Database schema parses
  ⚠ Tests not run yet — run `locara test`

Suggestions:
  → Run `locara test` before publishing.

Subcommands: locara db

locara db generate-types     # Regenerate TS types from schema.sql
locara db migrate            # Apply pending migrations to dev DB
locara db diff               # Show schema changes vs last published version

Used during dev; rarely needed manually because locara dev does this automatically.

Subcommands: locara model

locara model add qwen2.5-3b-instruct-q4
# Adds to manifest, downloads to cache, pins hash in lockfile

locara model list
# Show all models in app's manifest with sizes

locara model verify
# Re-verify all model hashes against cache + registry

Configuration

User-level: ~/.locara/config.toml

[publisher]
account = "kingtongchoo"
github_token = "..." # for verification

[signing]
identity = "Developer ID Application: King Tong Choo (XXXXXXXXXX)"

[registry]
default = "https://locara.app"

[telemetry]
enabled = false  # Always default false. User opt-in only.

[ai]
provider = "anthropic"  # for --from-prompt
api_key_env = "ANTHROPIC_API_KEY"

Project-level: locara.json (the manifest itself).

Exit codes

  • 0 — success
  • 1 — generic error
  • 2 — usage error (bad flags)
  • 3 — validation error (manifest invalid, etc.)
  • 4 — capability test failure
  • 5 — registry / network error during publish
  • 6 — signing / notarization error

Cross-references