moda CLI.
Prerequisites
@moda-ai/cliinstalled:npm install -g @moda-ai/cli(Node.js >= 18).- An API key for
syncandpromote: setMODA_API_KEY, or runmoda initonce to provision and store one.init,status, anddiffwork offline.
1
Create the manifest
.moda/prompts.yml if it does not exist (it never overwrites an existing manifest):.moda/prompts.yml
moda init (the full onboarding wizard) also creates this manifest and runs a first sync.The CLI discovers files by walking the directory before the first glob character and matching the .prompt.<ext> suffix. node_modules, .git, dist, and build are skipped, and symlinks are never followed.Although the default manifest lists
.prompt.yaml and .prompt.yml patterns, the CLI parses those files with the same frontmatter parser as .prompt.md. Write prompts as .prompt.md or .prompt.json.2
Write prompt files
Markdown format — optional frontmatter, then the prompt content as the body:Recognized frontmatter keys:Supported JSON fields:
prompts/support/triage.prompt.md
Frontmatter is parsed line by line as flat
key: value pairs — nested YAML structures and lists are not supported, and .prompt.md files cannot declare variables. Use .prompt.json for structured prompts.JSON format — supports the full schema, including messages, variables, and tool references:prompts/support/answer.prompt.json
key, name, description, category, content (defaults to the pretty-printed messages array when omitted), messages, systemPrompt, variables, variablesSchema, modelConfig, toolRefs, responseSchema. variables and variablesSchema are stored as declared metadata with each version; the CLI and registry do not render or substitute variables.Key derivation. When no explicit key is set, the key comes from the file path: strip a leading prompts/, strip the .prompt.<ext> extension, and replace slashes with dots. prompts/support/triage.prompt.md becomes support.triage.3
Check local state
status is local-only — no network call. It compares discovered files against .moda/prompts.lock.json:state is one of new (not in the lockfile), unchanged (hash matches), changed (hash differs), or deleted (in the lockfile but no longer on disk).moda prompts diff runs the same comparison and prints the same output — it is an alias for status, not a textual diff of prompt content.4
Sync versions
.moda/prompts.lock.json:.moda/prompts.lock.json
promote. It is rewritten wholesale on each sync; commit it alongside your prompt files.Every sync also moves the dev label to the just-synced version of each prompt.Options:--dry-run— the server computes and returns the IDs without writing anything; the lockfile is not updated.--watch— re-check local files on an interval and re-sync when hashes change.--interval=<ms>sets the poll interval (default 2500, minimum 1000).
moda sync prompts is an alias for moda prompts sync.5
Promote a release label
--label accepts dev, staging, or prod; --version (alias --version-id) takes the version ID from the lockfile or from moda prompts status. The label moves atomically from whichever version held it to the target version.Promote to staging before prod if you validate releases in a pre-production environment. You can also promote from the dashboard: each version on the prompt’s Versions tab has staging and prod promote buttons.Verify in the dashboard
After the first sync, open Dashboard → Prompts. You should see each discovered prompt with one version, thedev label on that version, and the source path and commit you synced from. After a promote, the label badge moves to the target version on the prompt’s Versions tab.
Optional: sync automatically from CI
.github/workflows/moda-autosync.yml, a GitHub Actions workflow that runs moda prompts sync (and moda skills sync) on every push to main — and only main, so unmerged versions are never published. It needs two repository secrets: MODA_API_KEY and MODA_TENANT_ID.
.github/workflows/moda-autosync.yml
<version> is the exact version of the CLI that wrote it — the pin makes CLI upgrades explicit, reviewable diffs. Rerunning moda init --autosync after upgrading the CLI bumps the pin.
Deleting a prompt
Delete the file from your repo.moda prompts status reports it as deleted, and the next sync drops it from the lockfile. The prompt and its versions remain in the registry — there is no delete or archive API — but they stop receiving new versions.
Troubleshooting
Next steps
- Prompt attribution — stamp the lockfile IDs on runtime calls so usage shows up per version.
- Prompt experiments — A/B a candidate against the current prompt before promoting.
- Prompt management overview — the versioning and label model in one page.
- CLI reference — output modes, exit codes, and environment variables shared by all CLI commands.