npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tudovu/cli

v0.4.0

Published

Tudovu CLI — AIMEE (the harness) from the terminal: ask, propose, approve, close out checks and findings; Architect drafts the compliant CloudFormation.

Readme

Tudovu CLI

AIMEE, the Tudovu harness, from your terminal. The same commands the Slack bot answers (status, queue, propose …, run access review) work here, plus the things a terminal is better at: listing failing checks, picking one, and closing it out resource by resource. Architect is still in the box, as the tool AIMEE uses to draft compliant CloudFormation (tudovu iac …).

Same contract as always: every change is a pull request a person approves. The CLI never merges and never applies to AWS.

Primary entry: bare tudovu opens the shell.


Install

Local (monorepo)

npm install
npm run cli:build
npm link -w @tudovu/cli

tudovu authenticate    # saves ~/.tudovu/config.json
tudovu                 # the shell

Re-run npm run cli:build after CLI source changes. Without linking: npm run cli:dev -- queue.

From npm

npm i -g @tudovu/cli
tudovu authenticate
tudovu

One-shot: npx -y @tudovu/cli queue. Windows PATH notes are at the bottom.

Try the pre-release

The in-development build ships under the beta tag, so it never replaces the stable @tudovu/cli:

npm i -g @tudovu/cli@beta
tudovu --version        # a -beta version

Run it without installing

For a quick trial on a machine you don't want to install anything on, run the single-file bundle (Node 18+). Copy tudovu.mjs over and:

node tudovu.mjs help
node tudovu.mjs discover > discover.sh    # the read-only discovery script
TUDOVU_BASE_URL=https://your-app node tudovu.mjs status

No npm, no registry, no dependencies. Build it yourself from the monorepo with:

npm run cli:build
npx esbuild apps/cli/dist/index.js --bundle --platform=node --format=esm \
  --banner:js="import{createRequire as __cr}from'module';const require=__cr(import.meta.url);" \
  --outfile=tudovu.mjs

You need an org API key (app → Config → Connect Agents) and the harness switched on for the org (Config → Harness). Proposals need a connected GitHub repo, or there is nowhere to open the PR; tudovu whoami tells you.


The shell

aimee> what needs me?
aimee> is anything in this account public?
aimee> propose block public access on the uploads bucket

Plain sentences go to AIMEE. Ones it recognises are its own verbs (queue, brief, duties, run access review, propose …, control …, tune …, alert when …, monitor …, deploy …, score, never); anything else is a read-only question Architect answers from the live account. A proposal comes back with the plan, the cost line, the guardrail verdict, and a question:

Open this as a pull request?  (case 5f05eae8, decide by 2026-09-02 16:00 UTC)
  [y] Open the PR   [n] Drop it   [s] decide later  ›

y hands it to Architect and waits for the PR link. s leaves it in the queue; tudovu approve 5f05eae8 later does the same thing.

| Slash command | What it does | |---|---| | /queue · /case <id> | What is waiting; one case file (first 8 characters of an id are enough) | | /approve <id> · /decline <id> · /attest <id> [--note …] | Answer a case | | /checks [--status …] [--severity …] [--service …] [--search …] | Open checks from the latest run | | /check <id> · /check <id> close … | One check with its resources; walk the failing ones | | /findings [text] [--severity …] [--resource …] · /finding <id> close … | Security Hub, live | | /status /brief /duties /run <duty> /propose … /ask … | Any AIMEE verb | | /iac <request> · /pr · /expand | Architect conversation; open a PR from its last validated template | | /prs [repo] · /review · /exception … | PR list and deploy runs; posture snapshot; accepted-risk exception | | /whoami /authenticate /thread [id] /clear /help /exit | Housekeeping |

Ctrl+C clears a non-empty line; on an empty line it leaves. /iac threads are saved under ~/.tudovu/threads/<id>.json and resume with --thread.


Closing out a check

The case this was built for: a check fails on several resources and they do not all want the same answer. One bucket is public on purpose (a marketing site); the other is a mistake. Whole-check exceptions could not say that.

tudovu checks --service s3            # what's failing
tudovu check AC-S3-003                # the buckets it judged, one row each
tudovu check AC-S3-003 close          # walk them

close asks, per failing resource: [x] accept as an exception, [f] fix via a pull request, [s] leave it. Then, in this order:

  1. Exceptions are recorded first, resource-scoped: the disposition lands on AC-S3-003@<bucket>, not on the check. That bucket reads ACCEPTED; the check stays FAIL until every other failing resource is fixed or accepted.
  2. The fix goes to AIMEE as one proposal that names the excepted resources as off limits, so Architect drafts a change for the misconfigured bucket and leaves the accepted one alone. The plan, the cost, and the guardrail verdict (mapped to the checks the template would fail) come back. Approving commits exactly that template as the pull request. Only when the draft still has blocking guardrail issues does Architect get a second turn to clear them before the PR opens.
  3. --evaluate re-runs just that check afterwards so the register reflects the exception now. The check reads ACCEPTED once the PR merges, deploys and the check re-runs.

Non-interactive, for a script or a ticket:

tudovu check AC-S3-003 close \
  --except marketing-site-bucket --fix uploads-bucket \
  --reason "Marketing site must be publicly readable" --expires 2026-12-31 \
  --evaluate -y

Security Hub findings work the same way. A finding is one title across many resources; tudovu finding <id|title> close walks them with the same exception-then-PR order, keyed the way finding exceptions already are (source:control:resource).

tudovu findings --search "block public"
tudovu finding 326feeff close

Reclaimer: what nothing manages

tudovu reclaim                        # Reclaimer's inventory, sorted by what it can import today
tudovu adopt /app/my-log-group        # import one into CloudFormation as a PR

reclaim reads Reclaimer's own inventory (ownership from stack enumeration, deleted-stack history and repository evidence, never from a tag) and says what can happen to each row: ready to import, needs an owner to confirm no other tool manages it, stack-owned so fix the template instead, or owned by Terraform and friends. Reclaimer imports fourteen shapes in place today: log groups, standalone EC2 instances, security groups, S3 buckets, RDS instances, ECR repositories, container-image Lambda functions, DynamoDB tables, IAM roles, EFS file systems, ECS services, SNS topics, SQS queues, and the application load balancer trio (load balancer, listener, target group). Every plan carries CloudFormation's own change set, planned in your account before the merge; Lambda is the one shape that gets no pre-merge plan, and the pull request says why. Everything else is inventory-only and the CLI says so.

The same five calls the CLI makes are plain HTTP with the org API key as a Bearer token: POST /api/reclaimer/inventory, /resource-checks, /ownership-confirmations, /previews, /adoption-plans/draft-pr. adopt is an owner-only write (it opens a pull request), so a key minted by a non-owner gets the scan and the previews and is refused at the pull request, which is the same boundary the app draws.

adopt runs Reclaimer's own steps behind one approval: the focused checks, the ownership confirmation when machine evidence found no manager (recorded under the approver's name for 30 days), the retained-import preview, and the pull request. A resource that fails a check is refused, and an accepted exception on that check doesn't change that: the import keeps the live configuration exactly as it is, so an exception never counts as a pass here. Fix the setting first (the resource's page in the app builds that fix as its own plan), then run adopt again. An app owner has to approve, because that is Reclaimer's boundary too. Nothing in AWS is stopped, modified or recreated: a person merges, and the customer's own deploy role runs the import.


Deploying a repo

tudovu deploy acme/shop --via eks            # the plan: source, images, what the PR adds
tudovu deploy acme/shop --via eks --open     # open the pull request; merging it deploys
tudovu repos                                 # what runs from each repo, where, and its CI/CD

--via takes ecs, eks, ec2 or lambda, and the usual synonyms (kubernetes, k8s, helm, fargate, serverless). The repo has to be connected to the Tudovu GitHub App. For EKS the plan picks the repo's best Kubernetes source (Kustomize, Helm, plain manifests or Skaffold) and --source overrides it; a repo with only a Dockerfile gets a Deployment and Service scaffolded. --stage names the environment and --port overrides the port the plan read from the repo.

Nothing deploys until a person merges the pull request, and the security gate runs first. A repo has one deploy workflow, so pointing it at a different target replaces the old pipeline; the plan warns you before it does. The Repositories page in the app, the MCP pipeline tool and deploy owner/repo via eks to AIMEE all make the same plan.


Subcommands

tudovu [--json] [--base-url URL] [--api-key KEY] [--thread ID] [<command> …]

| Command | | |---|---| | aimee "…" (-y / -n; snippy still works) | One command to AIMEE, wait for the answer, approve or decline what it proposes | | status · brief · duties · run <duty> | AIMEE's status, the briefing, the calendar, a duty now | | queue · case <id> · approve · decline · attest | The inbox and decisions (--no-wait skips waiting for the PR) | | checks · check <id> [close] | Compliance checks and the closeout walk | | findings [text] · finding <id> [close] | Security Hub findings and their closeout | | iac draft "…" [--out f.yaml] · iac pr --template f.yaml | Architect as a tool: plan, then open a PR (never merges) | | deploy <repo> --via <target> [--open] · repos [search] | Deploy a repo to ECS, EKS, EC2 or Lambda; what's deployed where | | prs [repo] · review · exception add · preflight | PR list + deploy runs; posture; accepted risk; CI container smoke test | | authenticate · whoami · help | |

--json prints the same payloads the API returns, for scripting. ask and apply from 0.3 are now iac draft and iac pr; status now means AIMEE's status, the PR list is prs.


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 | | TUDOVU_API_KEY | Org API key (Bearer). Alias: INFRANITUM_API_KEY | | TUDOVU_BASE_URL | App origin. Alias: INFRANITUM_BASE_URL | | --base-url / --api-key | One invocation | | TUDOVU_NOTIFY=1 / --notify | OS notification when AIMEE or Architect finishes | | TUDOVU_BELL=0 | No terminal bell |

An API key acts as the user who minted it, in their org. Approving a case needs the harness approve.pr permission (or the app owner role when no roster is set up), same as in Slack.


Under the hood

  • POST /api/harness/command runs the same dispatcher the Slack bot uses with surface: "cli"; the ack and the outcome come back in the response instead of being posted. A proposal's decision lives on a case, approved through POST /api/harness/situations/{id}/decision.
  • A resource-scoped check exception is a disposition on check / AC-XXX-NNN@<resourceId>; /api/checks/latest?overlay=1 returns the run with those applied, the way the Checks tab shows it.
  • Shared HTTP client: @tudovu/api-client (also used by the MCP servers).

Terminal tables

Architect answers sometimes include GitHub-flavored markdown pipe tables. The CLI re-renders them with space-padded columns sized to content / terminal width (long cells truncate with …). review uses the same helper.

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.Z

That runs .github/workflows/publish-cli.yml. You can also trigger it via Actions → Publish CLI → Run workflow.

Windows (PATH)

npm i -g @tudovu/cli installs a tudovu.cmd shim into the npm global prefix, which is often missing from PATH.

npm i -g @tudovu/cli
npm prefix -g
# Add that folder to your user PATH (commonly %APPDATA%\npm), then open a new terminal.

One-shot without relying on PATH: npx -y @tudovu/cli whoami.

Development

npm run cli:build
npm link -w @tudovu/cli   # once
npm run cli:typecheck
npm run cli:test