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

@m8t-stack/cli

v0.2.5

Published

CLI for managing m8t-stack deployments on Azure / Microsoft Agent Foundry

Readme

@m8t-stack/cli — the m8t CLI

📖 Reference for the m8t command-line tool that manages m8t-stack deployments.

What it is

The m8t CLI manages a deployed m8t-stack platform: identity (whoami, status, doctor), config (config, switch), team membership (team), channel bindings (bind), the gateway stack (deploy), hosted coders (coder), and brains (brain). It's published to npm, Homebrew, and Scoop.

Why / how it fits

It's the operator's day-2 tool for the cloud platform — the successor to the old deploy/setup.mjs. It shares @m8t-stack/api-contract types with the gateway at build time and authenticates with your az session (DefaultAzureCredential).

Install

# npm (any OS with Node 20+)
npm install -g @m8t-stack/cli

# Homebrew (macOS / Linux)
brew install m8t-run/tap/m8t

# Scoop (Windows)
scoop bucket add m8t https://github.com/m8t-run/scoop-bucket
scoop install m8t

# Verify
m8t version

The CLI bundles the shared workspace types into a single dist/cli.js, so the npm install is self-contained (only the external runtime deps resolve from npm). Publishing is automated by .github/workflows/release-cli.yml (OIDC trusted publishing); see publish/npm-trusted-publishing-setup.md.

Build from source (contributors)

pnpm --filter "@m8t-stack/cli" build   # produces dist/cli.js with shebang
cd apps/cli && pnpm pack               # produces m8t-stack-cli-<version>.tgz
npm install -g ./m8t-stack-cli-*.tgz

Usage

m8t version                 # CLI version
m8t whoami                  # Identity + which gateway you're talking to (probes the backend)
m8t status                  # Full local snapshot: az identity, config.yaml, gateway cache, azd mode
m8t doctor                  # Health checks (az · config · tenant align · gateway · Foundry data-plane · model-quota) + fixes
m8t doctor --agent <name>   # + delivery-grant check: verifies the agent's MI holds Key Vault Secrets User
m8t open [webapp|foundry|portal]   # Open the deployed app / Foundry portal / resource group in a browser

# Local config (~/.m8t-stack)
m8t config show                       # config.yaml (tenant/client/project) + the cached gateway
m8t config set <key> <value>          # set tenantId | clientId | projectEndpoint
m8t config reset                      # clear the gateway discovery cache
m8t switch --subscription <id|name>   # re-point local config at another deployment (snapshots first)
m8t switch <profile>                  # restore a saved profile;  m8t switch --list

# Team management
m8t team add <handle> --display "<name>" [--telegram <id>] [--slack <id>] [--teams <upn>]
m8t team list
m8t team show <handle>
m8t team add-identity <handle> [--telegram <id>] [--slack <id>] [--teams <upn>]
m8t team remove-identity <handle> --telegram|--slack|--teams
m8t team remove <handle>

# Deploy / update the gateway stack (replaces the old deploy/setup.mjs)
m8t deploy [--client-id <appId>] [--image-ref <ref>] [--location <region>] [--resource-group <name>]

# Brain management
m8t brain link <name> --repo <owner>/<repo> [--persona <path>] [--allow-non-reasoning]
# --persona: override the recorded persona file (or use when no local agent yaml exists)
# --allow-non-reasoning: suppress the reasoning-model warning

--subscription <id> flag

Available on all gateway-using commands (whoami, config show, config reset, team add, team list, team show, team add-identity, team remove-identity, team remove, bind add, bind list, bind show, bind remove, bind cleanup). Pins gateway discovery to the named subscription, bypassing the active az subscription. Useful when you manage multiple m8t-stack deployments across subscriptions or when your shell's active subscription differs from the deployment target.

m8t team list --subscription <subscription-id-or-name>

Local context & config — status / doctor / switch

The CLI reads two local files under ~/.m8t-stack/: config.yaml (your tenantId, clientId, and Foundry projectEndpoint — used by the web app + architect) and cli-config.yaml (the auto-discovered gateway URL cache).

  • m8t status — a read-only snapshot of everything local: your signed-in az identity + active subscription/tenant, config.yaml (tenant / client / project), the gateway cache, the azd auth mode, and whether your az tenant matches config.yaml (tenant alignment). --output json for scripting.
  • m8t doctor — runs health checks and prints a fix for each failure; exits non-zero if any check FAILs. Checks: az signed in · config.yaml valid · tenant alignment · gateway reachable (/api/me) · Foundry data-plane reachable (a 401/403 prints the exact az role assignment create … "Cognitive Services User" command) · model-quota check (warns for any deployed model with 0 TPM quota in the region). Results stream as each check runs. Pass --agent <name> to add a targeted delivery-grant check: reads the agent's deployed env and verifies its managed identity holds Key Vault Secrets User on the configured vault.
  • m8t config set <key> <value> — write tenantId, clientId, or projectEndpoint into config.yaml (validated). m8t config show now displays config.yaml alongside the gateway cache.
  • m8t switch — re-point your local config at another deployment in one step. --subscription <id|name> discovers the gateway there and derives every config.yaml value from its container env (zero manual IDs); <profile> restores a saved profile; --list lists profiles. Every switch snapshots the outgoing config to a profile first (label it with --as <name>), so it's reversible — e.g. m8t switch --subscription <new> --as work, then later m8t switch personal.

Open in the browser — m8t open

m8t open            # the deployed webapp (gateway URL) — default
m8t open foundry    # the Microsoft Foundry portal (ai.azure.com)
m8t open portal     # the resource group in the Azure portal
m8t open --print    # print the URL instead of launching a browser (pipe-friendly)

Deploy / update the gateway — m8t deploy

Provisions (or updates) the gateway/webapp stack via Bicep — the successor to the old node deploy/setup.mjs. See deploy/README.md for the full flow.

# Bring-your-own app registration (required if you can't create Entra app regs, e.g. a directory guest):
m8t deploy --client-id <appId> --image-ref <acr-or-ghcr-ref> --location <region>

Key flags: --client-id <appId> (reuse an existing app reg + skip all Microsoft Graph writes), --image-ref <ref> (full image ref; default ghcr.io/m8t-run/m8t:latest — pass an *.azurecr.io/... ref for ACR images), --resource-group (default rg-m8t-stack), --location, --suffix, --foundry-endpoint, --foundry-resource-id.

⚠️ m8t deploy is declarative — it makes the live stack match the Bicep template. If a deployment was hand-modified after provisioning (e.g. switched to a private-ACR image with a UserAssigned pull identity), re-running the bicep can revert those changes. Preview with az deployment group create --what-if before applying against a live stack.

Binding management — m8t bind

Wire channel bots (Telegram, Slack, Teams) to Foundry workers. F4 ships the management API + CLI scaffolding; the actual adapters (which deliver inbound messages from each channel) ship in later features.

# Create a binding (requires the channel adapter — Telegram ships in F6)
m8t bind add telegram \
  --worker cmo \
  --bot-token <from-botfather> \
  --slug cmo-tg \
  --bot-username "@startup_cmo_bot"

# List all bindings, optionally filtered
m8t bind list
m8t bind list --channel telegram
m8t bind list --status orphaned

# Inspect one binding (token NEVER returned — only the KV URI)
m8t bind show cmo-tg

# Remove a binding (cascade: unregister webhook → KV → conversations → row)
m8t bind remove cmo-tg
m8t bind remove cmo-tg --yes      # skip confirm

# Orphan-only cleanup (refuses to act on active bindings)
m8t bind cleanup <bindingId>
m8t bind cleanup --all-orphaned

--worker is the case-sensitive, lowercase Foundry agent name as deployed (e.g. cmo). A wrong name isn't rejected at bind time — it surfaces later as an orphaned binding on the first message.

Pre-F6 behavior

m8t bind add telegram ... currently fails with:

error: no adapter for channel 'telegram'. This is expected for F4 alone;
       the channel-specific adapter ships in a later feature.

This is correct. F6 (Telegram adapter) will register the adapter at startup and unlock the create flow.

Cascade-delete idempotency

If m8t bind remove fails mid-cascade, it prints which steps completed and which step failed, and recommends re-running the command. Each step is independently idempotent — a re-run resumes safely from the failure point.

Output modes

Pretty table or key-value block by default; pipe or redirect, and the CLI auto-switches to JSON:

m8t team list                   # pretty
m8t team list | jq              # auto-JSON
m8t team list --output json     # explicit JSON
m8t team list --output pretty   # force pretty even on pipe

Exit codes

  • 0 success
  • 1 any failure (auth, network, validation, backend)
  • 2 user-cancelled

Granular error info in stderr's structured JSON envelope.

Prerequisites

  • Node 20+
  • az login against the customer's Azure tenant. CLI uses DefaultAzureCredential — no per-admin pre-registration.

Troubleshooting

error: You are not signed in to Azure.

Run az login first. The CLI uses your active az session to acquire a token for the gateway.

error: No m8t-stack deployment found in subscription <name>.

The deployment is in a different subscription. Switch with:

az account set --subscription <other-sub>
m8t config reset
m8t team list

error: Multiple m8t-stack deployments found ...

You have more than one gateway in this subscription. The CLI prompts you to pick one when running interactively (e.g. m8t whoami). The choice is cached at ~/.m8t-stack/cli-config.yaml. Or pass --subscription <id> to target a specific subscription and skip the picker entirely.

(gateway is starting up...)

The deployed gateway is configured with min-replicas=0 (scale-to-zero). First request after idle pays ~10–20s cold start. The CLI retries once on 502/503/504.

error: partial write — <channel-A> succeeded, <channel-B> failed.

A multi-identity m8t team add partially succeeded. Run m8t team show <handle> to verify the current state, then m8t team add-identity <handle> --<channel-B> <id> to fill in the missing identity.

CLI version vs gateway version drift

The CLI and the gateway share @m8t-stack/api-contract types at compile time (the CLI bundles them at build). If the gateway is on an older version and returns a response in an unknown shape, the CLI surfaces BAD_RESPONSE with a "this may be a gateway version mismatch" hint.