Skip to content

CLI Reference

ulis <command> [options]

Running ulis with no command prints help. All commands exit non-zero on error with a message on stderr.


ulis init

Scaffold a new .ulis/ source tree with empty folders, template YAML files, and schema-backed headers.

ulis init [-g | --global]
FlagEffect
-g, --globalScaffold ~/.ulis/ instead of ./.ulis/. No .gitignore is written in this mode.

Project mode:

  1. Creates ./.ulis/ with config.yaml, mcp.yaml, permissions.yaml, plugins.yaml, skills.yaml, and empty agents/, skills/, commands/, raw/ subfolders.
  2. Reads the project name from ./package.json (falls back to the directory name).
  3. Appends /.ulis/generated/ to .gitignore (creating the file if missing).
  4. Prints a hint suggesting you also gitignore ./.claude/, ./.cursor/, ./.codex/, ./.opencode/, and ./.forge/ if you don't want to commit generated configs.

Fails if .ulis/ (or ~/.ulis/ in global mode) already exists.


ulis build

Parse, validate, and generate configs into <source>/generated/<platform>/ without installing anything.

ulis build [-g | --global] [--source <path>] [--target <platforms>]
FlagEffect
-g, --globalRead from ~/.ulis/ instead of ./.ulis/.
--source <path>Explicit source path. Takes precedence over --global.
--target <platforms>Comma-separated subset of claude,codex,cursor,opencode,forgecode. Default: all.

Output is always written under <source>/generated/<platform>/. Existing contents there are cleared before each build.


ulis install

Run build and then deploy the generated configs onto the target platform directories.

ulis install [-g | --global] [--source <path>] [--target <platforms>]
             [-y | --yes] [--no-rebuild] [--backup]
FlagEffect
-g, --globalRead ~/.ulis/ and write to ~/.claude/, ~/.codex/, ~/.cursor/, ~/.opencode/, ~/forge/, and ~/.mcp.json.
--source <path>Override source (still writes to CWD or home depending on --global).
--target <platforms>Only build/install the listed platforms.
-y, --yesSkip the "about to overwrite" confirmation prompt.
--no-rebuildDon't rebuild — install whatever is already under <source>/generated/.
--backupCopy each existing platform dir to <dir>.backup.YYYYMMDD_HHMMSS before writing.

Install strategy per platform:

PlatformManaged dirs (replaced)Merged files
Claudeagents/, commands/, rules/, hooks/, …settings.json, .claude.json keys
OpenCodetarget dir contentsnone
Codextarget dir contentsnone
Cursoragents/ (.mdc files)mcp.json
ForgeCode.forge/agents, .forge/skills.mcp.json

Deep-merge preserves user-owned keys in settings.json / mcp.json / .mcp.json only.


ulis tui

Launch the interactive terminal UI. Useful when you want to pick generation and install targets separately, toggle backups, and stream progress in the same screen.

ulis tui

The TUI reads from ~/.ulis/ and writes to the corresponding home directories. It's the equivalent of ulis install --global with a point-and-click selection.


Exit codes

CodeMeaning
0Success.
1Source missing, validation error, user declined prompt, or I/O failure.

All errors print a single human-readable line on stderr before exiting.


Examples

Scaffold a project and install for Claude + Cursor only:

bash
ulis init
# edit .ulis/agents/*.md, .ulis/mcp.yaml, etc.
ulis install --target claude,cursor --yes

Rebuild global configs after editing ~/.ulis/:

bash
ulis install --global --yes --backup

Dry-run against a fixture without touching home:

bash
ulis build --source ./example

Reinstall from an existing build without regenerating:

bash
ulis install --no-rebuild --yes

Released under the ISC License.