@tudovu/cli
v0.3.2
Published
Tudovu Architect CLI — interactive shell, ask, apply, status, and review from the terminal.
Readme
Tudovu Architect CLI
Terminal surface for Tudovu Architect: plan CloudFormation, open reviewable PRs, inspect status and security posture. Same PR-first contract as the MCP server — never merges PRs and never applies to AWS.
Primary entry: bare tudovu opens the branded interactive shell.
Subcommands: authenticate · whoami · ask · apply · status · review · exception add · help
Install
Local (monorepo) — put tudovu on your PATH
# from repo root
npm install
npm run cli:build
npm link -w @tudovu/cli
tudovu authenticate # saves ~/.tudovu/config.json (preferred)
# or: export TUDOVU_BASE_URL=… / TUDOVU_API_KEY=…
tudovu # interactive shell
tudovu help
tudovu whoami
tudovu ask "Spin up a staging Redis cluster, internal only"Re-run npm run cli:build after CLI source changes (link already points at dist/).
Dev without linking / build (tsx):
npm run cli:dev -- whoami
npm run cli:dev -- helpAfter publish (npm)
npm i -g @tudovu/cli
tudovu authenticate
tudovu
tudovu whoami
tudovu ask "…"Or one-shot: npx -y @tudovu/cli whoami (uses config file or env).
Windows (PATH)
npm i -g @tudovu/cli installs a tudovu.cmd shim into the npm global prefix. That directory is often missing from PATH (especially with some Node / nvm-windows installs), so tudovu may not resolve even though the package installed.
npm i -g @tudovu/cli
npm prefix -g
# Add that folder to your user PATH (commonly %APPDATA%\npm), then open a new terminal.
tudovu authenticate
# or: $env:TUDOVU_BASE_URL="https://app.tudovu.com"; $env:TUDOVU_API_KEY="…"
where.exe tudovu
tudovu whoamiTo append the global prefix to your user PATH for this session and permanently:
$npmBin = npm prefix -g
$env:Path = "$npmBin;$env:Path"
[Environment]::SetEnvironmentVariable(
"Path",
([Environment]::GetEnvironmentVariable("Path", "User") + ";" + $npmBin).Trim(';'),
"User"
)One-shot without relying on PATH: npx -y @tudovu/cli whoami.
Interactive shell
tudovuOpens a branded REPL (tudovu>). Welcome shows a short whoami snapshot
(firstName / account / awsConnected / githubRepo).
| Input | Behavior |
|---|---|
| Natural language | Architect ask with in-session conversation history |
| /authenticate | Save Base URL + API key to ~/.tudovu/config.json |
| /whoami | Identity snapshot |
| /status [--repo name] … | PR list/detail + deploy runs (prompts with known repos if omitted) |
| /review [--include-checks] … | Posture snapshot |
| /apply [--repo name] --template PATH … | Opens/updates a PR after y/N confirmation (prompts with known repos; never merges) |
| /exception --id … --reason "…" --expires … [--kind check] | Accepted-risk exception (default kind=finding; prompts for missing fields) |
| /thread [id] | Show current thread id, or load/switch to another |
| /clear | Reset conversation history |
| /help | Same branded help as tudovu help |
| /exit · exit · quit · empty-line Ctrl+C | Leave the shell (prints a resume hint) |
Ctrl+C at the prompt: if the input line has text, it is cleared (bash-like) and the shell stays open; if the line is empty, the shell exits.
On exit, the CLI prints Continue: tudovu --thread <id>. Threads are stored locally under ~/.tudovu/threads/<id>.json (resume with --thread or TUDOVU_THREAD).
When a CloudFormation block has validation.ok, an apply hint is printed.
--json is not supported for interactive mode (use subcommands with --json).
Auth & environment
Credentials resolve in this order (highest wins): CLI flags → env vars → ~/.tudovu/config.json → default base URL https://app.tudovu.com.
| Source | Notes |
|---|---|
| tudovu authenticate | Guided flow; saves baseUrl + apiKey to ~/.tudovu/config.json |
| TUDOVU_API_KEY | Org API key (Bearer). Required when auth is on. Alias: INFRANITUM_API_KEY |
| TUDOVU_BASE_URL | App origin. Alias: INFRANITUM_BASE_URL |
| --base-url / --api-key | Override env and config for one invocation |
Need an account? Create one at https://app.tudovu.com, mint a key under Config → Connect Agents, then:
tudovu authenticate
# or inside the shell: /authenticateDemo / auth-off hosts work without a key. Live Architect model replies need the app server live-architect flag enabled (not the CLI).
Global flags
tudovu [--json] [--base-url URL] [--api-key KEY] [--thread ID] [<command> …]- No command → interactive shell (refuse
--json). --thread <id>(orTUDOVU_THREAD) resumes a local shell conversation.- Default subcommand output is human-readable.
--jsonprints the same payload MCP tools return (scripting / CI).
Commands
help
tudovu helpBranded help: shell entry, subcommands, slash commands, env, examples.
(Commander --help still works on individual commands.)
authenticate
tudovu authenticate
tudovu authenticate --base-url https://app.tudovu.com --api-key inf_live_…Prompts for Base URL + API key (or uses flags), verifies with whoami, and writes
~/.tudovu/config.json so new terminals load credentials automatically.
Create an account at https://app.tudovu.com if you do not have one yet.
whoami
tudovu whoami
tudovu --json whoamiSlim identity: firstName, githubRepo, awsConnected, accountName
(no email, ids, ARNs, or launch commands).
ask — plan only
tudovu ask "Spin up a staging Redis cluster, internal only, Multi-AZ" \
--repo acme/infra \
--region us-east-1 \
--out ./redis-staging.yamlDoes not open a PR. Use apply after validation passes.
apply — open / update a PR
tudovu apply \
--repo acme/infra \
--template ./redis-staging.yaml \
--title "Staging Redis (internal, Multi-AZ)"
# omit --repo to be prompted (TTY): lists setup + GitHub App repos; Enter = default
tudovu apply --template ./redis-staging.yaml
# update an existing open PR
tudovu apply --repo acme/infra --template ./revised.yaml --pr 503
# confirmed overridable guardrails
tudovu apply --repo acme/infra --template … --override iam-full-adminNever merges. Deploy stays in the org’s CI.
status — PR + deploy runs
Paginated list (default 5 PRs per page; response includes page / perPage / hasMore).
Omit --repo to be prompted (TTY) with setup + installation repos:
tudovu status --repo acme/infra --pull-state open
tudovu status --repo acme/infra --page 2 --per-page 5
tudovu status --repo acme/infra --pr 503
tudovu status --pull-state openTerminal tables
Architect answers sometimes include GitHub-flavored markdown pipe tables
(| Resource | Type | Notes |). Those do not align in a terminal, and
tabs will not fix it (tab stops are fixed-width and depend on where each
cell starts). The CLI detects table blocks and re-renders them with
space-padded columns sized to content / terminal width (long cells truncate
with …). tudovu review uses the same helper for severity counts and
Critical/High findings (grouped by title + severity, with Resource and Id
under each group — not full ARN). The Id column is a short stable id
(UUID after /finding/ when present) for exception add --id.
review — posture snapshot
Findings are pulled live. --include-checks attaches the latest stored
check run (written by the app Evaluate button or scheduled cron) — it does
not re-run checks against AWS. Critical/High findings that share a title
are grouped into one section with a resource count; each resource line shows
its short Id (use that with exception add --id). --json keeps the
flat criticalHigh list (id full + shortId) and adds findings.grouped
for convenience.
tudovu review --region us-east-1
tudovu review --region us-east-1 --include-checks --findings-limit 50If no check run has been stored yet, --include-checks returns a clear
missing state with a hint to run checks in the app or wait for cron.
exception add — accepted risk (finding or check)
Records a temporary exception (disposition type exception) via
PUT /api/org/dispositions — the same API the UI uses. Requires a reason
and an expiry. Does not delete the finding/check and never applies to AWS.
--kind defaults to finding (--kind check for checks). For findings,
--id can be the short Id from tudovu review (preferred — exact match
on short id or full id), a title, or a subject key. Titles that hit multiple
resources need --resource or the review Id.
# Prefer short Id from `tudovu review` (no title collision; kind defaults to finding)
tudovu exception add --id 326feeff-73f6-4b2f-8540-b454bea58ea9 \
--reason "Marketing assets bucket must be publicly readable" \
--expires 2026-12-31
# Or match by title + resource when disambiguating
tudovu exception add --id "S3 buckets should block public" \
--resource marketing-assets \
--reason "Marketing assets bucket must be publicly readable" \
--expires 2026-12-31
# Same justification on the Tudovu check (check-scoped; subjectKey = check id)
tudovu exception add --kind check --id AC-S3-001 \
--reason "Marketing assets bucket must be publicly readable" \
--expires 2026-12-31Omit --reason / --expires in a TTY to be prompted (reason hint uses the
marketing-assets example). Shell: /exception (alias /exceptions).
Typical loop
tudovu(shell) ortudovu whoami- Ask in the shell, or
tudovu ask "…" --out ./plan.yaml /apply …in the shell (with confirmation), ortudovu apply --repo … --template ./plan.yamltudovu status --repo … --pr <n>- Merge in GitHub when ready — not via the CLI
Releasing to npm
Bump versions in apps/cli/package.json and packages/api-client/package.json,
commit, then tag and push:
git tag cli-vX.Y.Z
git push origin cli-vX.Y.ZThat runs .github/workflows/publish-cli.yml, which publishes @tudovu/api-client
then @tudovu/cli to npm. You can also trigger the workflow manually via
Actions → Publish CLI → Run workflow.
Development
Shared HTTP client: @tudovu/api-client (also used by MCP).
npm run cli:build
npm link -w @tudovu/cli # once, if not already linked
npm run cli:typecheck