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
--jsonfor machine-readable. - Verbose with
-v; debug with-vv. - Reads
~/.locara/config.tomlfor global config; project root haslocara.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:
- Capability tests (
tests/capabilities.test.ts) — Validate the app respects its manifest declarations under various scenarios. - Unit tests (
tests/unit.test.ts) — Standard logic tests using@locara/testhelpers. - 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:
- JSON schema validity.
- Identity consistency (publisher account, version vs git tags).
- File existence (icons, screenshots, schema, entry).
- Capability schema correctness.
- Profile consistency.
- Model hash validity (resolves all
@sha256:...against registry). - Static analysis vs declared capabilities.
- License SPDX validity.
- Lockfile integrity (
locara.lock.jsonmatches 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:
locara verify --stricttsc+ frontend bundle (Vite)- Tauri build with capability manifest
- Code sign with developer cert (from keychain or env)
- Notarize (macOS) — submits to Apple, polls for approval
- Output to
dist/<app-name>-<version>.appand.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:
locara verify --strictlocara test- Push current git ref + manifest to Locara CI (or self-hosted)
- CI clones source by commit hash in clean environment
- CI runs
locara build - CI generates Sigstore-style provenance attestation
- CI uploads artifact + manifest + attestation to registry
- Registry runs additional review checks (capability profile risk classification)
- Auto-approve if low-risk; queue for human review if not
- 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— success1— generic error2— usage error (bad flags)3— validation error (manifest invalid, etc.)4— capability test failure5— registry / network error during publish6— signing / notarization error
Cross-references
- Manifest the CLI operates on: 02-manifest.md
- Modality + tooling declarations: 04-modalities.md
- Dev experience details: 07-runtime.md
- Build pipeline: 16-build.md
- Publish flow + review: 12-registry.md