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

recess-cli

v3.11.0

Published

Safe Recess administration and family AI tools from the command line.

Downloads

3,968

Readme

Recess CLI

recess-cli is the typed, agent-friendly command layer for Recess operations. ADMIN accounts receive the full staff surface; GUARDIAN accounts with access:ai receive family-scoped class schedules, progress, goals, todos, memories, Rocky configuration, learning research, GoalTemplate, and goal-content commands; GUIDE accounts receive that same student surface for the students they hold an ACTIVE tutor assignment to—not their wider class roster. KID accounts receive only authenticated Village home building. It uses the web-server OpenAPI document, authenticates through Recess SSO, emits stable JSON, and refuses live writes until the exact command is rerun with --confirm plus the preview's operation key after human approval.

Version 3 changes

goals list now shows ACTIVE and PAUSED goals by default. Add --include-archived to include COMPLETED goals (both archived and rewarded completions), and --query to search. Staff gain cohorts schedule and versioned memories file commands. Deploy their backend and database support before publishing this CLI; writes require a server preview.

Install (no checkout needed)

Published to npm as recess-cli. On any machine with Node 20+:

npm install -g recess-cli
recess setup --reason "Install and update the Recess agent skill"

setup installs the bundled skill in the Codex and Claude Code user directories, which Cursor also discovers for compatibility, and then opens Recess SSO in your browser (skip the browser step with --skill-only; it is also skipped when a live session already exists). Restart your agent afterwards so it discovers the skill. npx -y recess-cli setup works too, but leaves no recess on your PATH — which is the command the installed skill tells the agent to run — so setup warns when it detects it is running from an npx cache.

Publishing rides the production deploy (.github/workflows/admin-cli-publish.yml): bump version in apps/admin-cli/package.json in a normal PR to staging, and it publishes when staging promotes to production. A production deploy that did not bump the version is a no-op — a gate job checks the version against npm first. The same workflow is still dispatchable by hand for out-of-band releases. pnpm packs the CLI so the workspace catalog: dependency becomes a real range; npm then publishes that tarball through the workflow's OIDC trusted-publishing path. The registry-side publisher must be configured as described in docs/codebase/admin-cli.md.

Building Studio apps with your agent

recess apps init my-applet --reason "New applet"      # scaffold + AGENTS.md (the contract your agent follows)
# build it in your editor with Claude Code / Codex / Cursor, then:
recess --json apps validate my-applet --reason "Check it"   # Studio's validation, nothing published
recess --json apps publish my-applet --reason "Ship it"     # validation + independent review → live at appUrl
recess --json apps list --reason "See my apps"
recess apps pull <project-id> my-applet --reason "Keep editing"

Guides and staff only. The app folder keeps its project id in .recess/app.json, so publishing again updates the same app.

For a specific kid, start from their session instead of a blank description:

recess --json students todos --student <kid-id> --analyzed --reason "What did they struggle with"
recess --json students analysis --todo <todo-id> --reason "Read the analysis"
recess apps init fix-it --for-todo <todo-id> --reason "Build for this gap"   # scaffold + brief.md
recess --json apps publish fix-it --assign <kid-id> --due 2026-09-01 --reason "Ship it to the kid"
recess --json apps standards "grade 4 adding fractions" --reason "Find the code"

Install (from a checkout — CLI development)

From the monolith root:

pnpm install
pnpm --dir apps/admin-cli run client:generate
pnpm --dir apps/admin-cli run install-persistent

install-persistent copies a self-contained build (non-test dist/ JS + the openapi-fetch runtime dep) to ~/.recess-cli/cli/ and points ~/.local/bin/recess at it — the install keeps working after the checkout or worktree it was built from is deleted. Use it on any machine that operates on production. install-local instead symlinks ~/.local/bin/recess straight to this checkout's dist/index.js so rebuilds are picked up live — use it only while actively developing the CLI, and expect the link to die with the worktree. Both targets install the small shared router at ${CODEX_HOME:-~/.codex}/skills/recess-cli and ${CLAUDE_CONFIG_DIR:-~/.claude}/skills/recess-cli. That public npm bundle contains only authentication, JSON, confirmation, and audience-routing guidance. Guardian learning skills and staff-only operational skills/gotchas are fetched after login from separate permission-checked catalogs; they are not shipped in the package.

One-time SSO setup

Create an approved OAuthClient row in each Recess environment. This remains a manual security operation. Configure:

  • name: Recess Admin CLI
  • approved: true
  • adminCliEnabled: true
  • jwtSecret: a new secret
  • redirectUris: exactly http://127.0.0.1:8765/callback
  • defaultlaunchUrl: leave null; the CLI constructs and opens the Recess OAuth URL itself

The production row ID (c7e34138-18f9-45b1-a2fb-26a4e3a6d739) is the CLI's built-in default, so production login needs no client-ID setup. --client-id, RECESS_CLI_OAUTH_CLIENT_ID, and a stored client ID remain overrides for local/staging clients. The web-server decodes the assertion audience, loads that exact OAuthClient, and requires both approved and adminCliEnabled; there is no separate server environment allowlist. Production redirect validation is exact, so a different callback port must also be explicitly registered.

The browser SSO assertion is exchanged once and discarded. The CLI stores a separate signed Recess session (12 hours by default) at ~/.recess-cli/config.json with mode 0600. A guardian must hold the live access:ai permission; removing it immediately invalidates session checks. Guardian sessions cannot call /admin routes and every target is independently restricted to their family. A KID session has village_home scope: application-level and shared-auth fences permit only session inspection and Village assertion minting, denying every other backend route.

recess --json auth login
recess --json doctor --reason "Verify CLI connectivity, identity, and scope"

Sessions default to 12 hours. Admins can request 30 days locally with recess --json auth login --duration 30d, or remotely with recess --json auth request --duration 30d --label "remote agent", approve the link as an admin, then run recess --json auth poll. The approval page shows the requested duration; the link still expires after 10 minutes. Non-admins cannot authorize 30-day sessions.

Testing against a local server

auth login opens production SSO, so local iteration uses the env-cookie hatch instead:

export RECESS_CLI_API_ORIGIN=http://localhost:5068
export RECESS_CLI_COOKIE='recess.auth-token=<signed-value>'
recess --json doctor --reason "Verify the local Recess API connection"

To mint <signed-value>: sign {sub, role, cliScope} with the server's JWT_SECRET (audience = CLIENT_ORIGIN), then sign THAT string with cookie.signerFactory(COOKIE_SECRET) from @fastify/cookie. Two traps, both silent:

  • @fastify/jwt reads the auth cookie with signed: true, so a bare JWT is rejected as "missing token" before it is ever verified — the @fastify/cookie signature is not optional.
  • A stored identity from a previous auth login does not describe an env-cookie session (it may even be a different person on a different environment). Commands that branch on role ask the server whenever authSource !== "config".

Real SSO against a local server instead needs an OAuthClient row in the local database with approved && adminCliEnabled and redirect http://127.0.0.1:8765/callback, passed via RECESS_CLI_OAUTH_CLIENT_ID.

Interactive console (recess ui)

recess ui

A terminal console for the human half of the job: roster on the left (live-session dot, today's todo bar, XP, active goals), detail on the right (today's numbers, what they're working on right now, recent daily summaries). Refreshes every 30s. Keys: ↑↓/jk move, / filter, r refresh, q quit. It is scope-aware — an ADMIN sees every student, a GUIDE sees the students they are actively assigned to.

ui deliberately never touches the --json path: agents parse stdout, so the TUI runs before the JSON envelope and writes only to the terminal.

JSON contract

With --json, stdout contains only one JSON object.

Success:

{ "ok": true, "data": { "results": [] } }

Error or write preview:

{
  "ok": false,
  "error": {
    "code": "confirmation_required",
    "message": "...",
    "details": { "preview": { "details": { "operationKey": "..." } } }
  }
}

Exit code 0 means success, 1 means an input/auth/API failure, and 2 means a write is awaiting explicit human confirmation.

recess --json agent-context returns the canonical command/flag/positional schema filtered to the scope claim already stored in the current CLI session. Bare help, scoped help, and agent-context make no API request; real commands still go through server authorization, while auth status and doctor perform live session checks. recess --json help payout recipients returns scoped help, and human help marks exact-admin commands with ◆. Unknown flags, duplicate non-repeatable flags, missing values, and extra positionals are errors instead of being silently ignored.

Every command-driven request to the Recess API except auth requires --reason "...": a non-empty, human-readable purpose of at most 1024 characters. The CLI sends it as x-recess-reason; the server rejects missing reasons before route execution and stores one audit row per request. The human-only recess ui console is explicitly exempt and identifies itself as x-recess-client: cli-ui instead.

Common flow

School-onboarding work is family-first: one composite view, then a loop of "what's next" → the suggested command → "what's next" again, with doctor as the gate-observability instrument when something is unexpectedly dark:

recess --json onboarding family <family-id> --reason "One-screen view of this school family"
recess --json onboarding next <family-id> --reason "What should happen next for this family"
recess --json onboarding doctor --family <family-id> --reason "Why is the school surface dark for them"
recess --json onboarding starter-coverage --reason "Run the pre-flip coverage gate"
recess --json onboarding backfill-trackers --reason "Census the WS-H guardian trackers"

next returns the mission-control queue's current action plus suggestedCommands with real ids substituted; every suggested write still previews and requires its own --confirm. doctor reports the env kill-switches, comms mode, and per-guardian/per-kid flag + capability-lock + cohort-gate state — its env values are the answering service's only (the Worker can differ).

recess --json users search "Morgan Rivera" --reason "Find the exact student record"
recess --json users tier get <kid-id> --reason "Inspect the student's current tier"
recess --json users tier preview <kid-id> --tier lite --slots 1 --reason "Preview a tier change"
recess --json students upload-map-scores --student <kid-id> --file /path/to/map-report.pdf --reason "Import this student's MAP scores"
recess --json enrollments list --user <kid-id> --reason "Inspect the student's enrollments"
recess --json subscriptions list --family <family-id> --kid <kid-id> --reason "Inspect family subscriptions"
recess --json invoices list --subscription <subscription-id> --reason "Inspect subscription invoices"

Preview a write by omitting --confirm:

recess --json billing pause --subscription <subscription-id> --until 2026-09-01 --reason "Pause billing through September 1"

After a human approves that exact preview, rerun the unchanged command with --confirm --operation-key <operationKey>. File-backed family edits, deterministic template apply, and goal-content writes also return details.approvalToken; echo it with --approval-token TOKEN. The token covers the local bytes plus the server preflight/CAS state, so a changed file or goal produces a new preview instead of consuming stale approval. Confirmed requests are fenced server-side per actor, operation, route/body, and preview fingerprint; retry an interrupted command with the same operation key to replay a completed response rather than duplicate the write. jobs list|get reads the protected local recovery ledger.

Named profile save|use|list configurations keep environment selection explicit, with global --profile as a one-command override. --deliver file:<path> atomically writes the JSON envelope with mode 0600; webhook delivery is intentionally unavailable for authenticated Recess data. feedback submit stores deduplicated CLI friction locally and can forward it to RECESS_CLI_FEEDBACK_ENDPOINT.

School tier writes require the updatedAt token from users tier get. Their read-only preflight shows capabilitiesLockedNow/capabilitiesLockedAfter, the resolved class allowance, current slotsUsed, and whether the change would strand registrations. Stranding is refused unless the human explicitly approves the exceptional --allow-strand override.

MAP uploads accept one PDF up to 15 MB. The preview includes the resolved path, byte count, and SHA-256 without contacting the API; the confirmed command sends the report to the existing tutor-dashboard extraction route.

Store catalog and Village

Village store goods are main-Recess StoreItem rows, not Village-island database rows. List them and preview an availability change with:

recess --json store-items list --item-type VILLAGE_ITEM --reason "Inspect the Village item catalog"
recess --json store-items set-status <store-item-id> --status INACTIVE --reason "Deactivate this Village item"

The status command resolves the exact VILLAGE_ITEM first and includes its name, catalog metadata, current status, purchase count, and lack of feed-publication side effects in the approval preview; it refuses non-Village item IDs. After approval, rerun the unchanged command with --confirm and the preview's --operation-key. The separate village models commands edit the Village island's reusable models and placements. village build cmd sends one confirmed command through Village's ordinary authenticated command dispatcher. village library search|get, village objects list|get, and village render use the same scoped Village identity and are own-home-only outside ADMIN. village worlds export|import|promote moves or promotes data-built worlds through the fixed admin bridge.

Authoring learning content

recess --json skills guardian get recess-goal-authoring --all-references --reason "Load goal authoring guidance"
recess --json content-library search "fractions through visual puzzles" --limit 8 --reason "Find visual fraction resources"
recess --json content-library status <gem-id-or-url> --reason "Inspect this gem's pipeline status"
recess --json content-library set-stage <gem-id-or-url...> --stage archived --reason "Archive these gems"
recess --json goal-templates validate-spec --file ./template.json --reason "Validate this template draft"
recess --json goal-templates create --file ./template.json --reason "Create this reusable goal template"
recess --json goal-templates create --file ./template.json --confirm \
  --operation-key <preview-operation-key> --reason "Create this reusable goal template"
recess --json goal-templates patch-spec <id-or-slug> --expected-version 7 --patches-file ./patches.json --reason "Update this template specification"
recess --json goals files init --student <kid-id> --draft <draft-slug> \
  --output-dir ./goal-content --reason "Start this goal draft"
git -C ./goal-content add -A
git -C ./goal-content commit -m "Author the learning path"
recess --json goals files push --source-dir ./goal-content --reason "Publish this goal draft"
recess --json goals pdf upload --student <kid-id> --draft <draft-slug> --source-file ./textbook.pdf --reason "Attach this textbook to the goal draft"
recess --json goal-templates capture-snapshot <id-or-slug> --source-dir ./goal-content --dry-run --reason "Preview a template snapshot"
recess --json goal-templates apply <id-or-slug> --answers-file ./answers.json --dry-run --reason "Preview applying this template"
recess --json goals create --student <kid-id> --title "..." --description-file ./goal.md --reason "Create this student goal"
recess --json goals create --source-dir ./goal-content --title "..." \
  --description-file ./goal.md --enable-applet-follow-ups --reason "Create this student goal draft"
recess --json goals files list --student <kid-id> --goal <goal-id> --reason "Inspect the goal workspace files"
recess --json goals files checkout --student <kid-id> --goal <goal-id> \
  --output-dir ./goal-content --reason "Check out this goal for editing"
git -C ./goal-content add -A
git -C ./goal-content commit -m "Revise module 3"
recess --json goals files push --source-dir ./goal-content --reason "Publish the module revision"

ADMIN discovery batches use the same Content Library admission door as the dashboard. Omit --confirm to preview the exact payload first. An interactive run asks for Review or polish with Review preselected; JSON/non-interactive runs safely default to Review. Use --stage polish to start automatic decoration immediately:

recess --json content-library submit https://example.org/activity --stage review --reason "Submit this activity for review"
recess --json content-library submit --file ./gems.json --reason "Submit this resource batch for review"
recess --json content-library submit --file ./urls.txt --stage polish --confirm \
  --operation-key <preview-operation-key> --reason "Submit this batch for polishing"

JSON files are arrays of URL strings or { "url", "title"?, "summary"?, "lane"? } objects; plain-text files contain one URL per line. The server checks that the deployed island understands the review/polish lifecycle before sending any item, and then writes with concurrency three. content-library status accepts an exact gem ID (including one returned by search) or URL and reports its Review/Polishing/Live/Archived stage plus metadata, cover, and search-index progress. content-library set-stage accepts one or many IDs/URLs (or a newline/JSON-string-array --file), previews every resolved current stage, and requires --confirm. It uses the same lifecycle as Manage: direct-to-Live routes unfinished gems through Polishing, and moving out of Polishing cancels that exact run first. Add --wait --timeout 900 when promoting to Live (or submitting to polish) to poll the durable island status with bounded concurrency and exponential backoff.

Family AI operations

recess --json students list --reason "List the students I can support"
recess --json students today --student <kid-id> --reason "Review today's learning plan"
recess --json students schedule --student <kid-id> --days 30 --reason "Review the student's upcoming schedule"
recess --json students xp-history --student <kid-id> --range month --reason "Review recent XP history"
recess --json goals list --student <kid-id> --reason "Review the student's goals"
recess --json todos create --student <kid-id> --title "Read chapter 4" --reason "Add the assigned reading"
recess --json todos complete <todo-id> --xp 35 --reason "Complete the todo with a 35 XP total reward"
recess --json goals delete <goal-id> --student <kid-id> --reason "Remove this obsolete goal"
recess --json goals restore <goal-id> --student <kid-id> --reason "Restore this goal"
recess --json todos delete <todo-id> --reason "Remove this disposable todo"
recess --json todos restore <todo-id> --reason "Restore this todo"
recess --json todos generate-learning-analysis <todo-id> --reason "Backfill this todo's missing learning analysis"
recess --json todos generate-applet <todo-id> --student <kid-id> --reason "Generate this todo's applet"
recess --json memories context --student <kid-id> --reason "Review durable tutor context"
recess --json memories log --student <kid-id> --date 2026-08-12 --reason "Review the learning log for this date"
recess --json rocky get --student <kid-id> --reason "Inspect the student's Rocky configuration"

All family writes still preview first. Goal/todo/Rocky edits also carry the current server version into the confirmed request. todos complete is staff-only; --xp is the target total XP for the todo, so its preview reports prior credit and the new delta before the normal completion and reward side effects run. Applet generation is also staff-only: it resolves the todo's latest learning analysis, defaults the generated todo to tomorrow in the student's timezone, and lets the server select v1 or v2 for that student. Learning-analysis generation is ADMIN-only and queues the idempotent forensic pipeline from the latest completed Gemini analysis without rerunning completion or rewards. Goal and todo deletion is soft-only. Restoring a goal retains its Mesa workspace, rechecks open-goal capacity, and restores only linked todos sharing that deletion's tombstone; standalone todo restore uses the same preview-bound tombstone check. A guardian cannot target another family, inspect frozen/deleted template history, choose todo rewards/completion/internal fields, or use the ADMIN-only device-authorization flow. memories context and memories log read only the tutor repository's spine, rules, reminders, and session logs; private guide remarks are never returned. The CLI does not expose Postgres UserMemory.

Keeping the agent skill current

recess --json --version          # {cliVersion, skillVersion}
recess --json doctor --reason "Check CLI health" # .skill reports whether a newer bundle exists
recess --json setup --skill-only --reason "Update the installed Recess skill"

The CLI's small shared router skill is both bundled in this package and served from GET /auth/admin-cli/skill/. The bundled copy is the floor — it works offline, before a session exists, and always matches the installed binary; postinstall refreshes it on every npm install -g. The served copy is the upgrade: shared wording changes reach installed CLIs on the next deploy instead of the next npm release, fenced by the bundle manifest's minCliVersion so an older binary keeps its bundled copy rather than reading a skill written for a newer one. An unreachable server is never an error.

skills guardian list|get serves family and goal-authoring guidance to family_ai and full_admin sessions. skills admin list|get serves the staff operational skill plus the live private tutor-skill registry and requires full_admin. The explicit audience is part of the command contract; skills get by itself is not valid. Responses cache under ~/.recess-cli/skills-cache/ (--refresh re-fetches).

Every template created here is setupMode: DETERMINISTIC_WORKFLOW and cannot be converted back, so the confirmation gate is load-bearing. create runs a real server-side validation before the gate, so preview.details carries the handler, goal shape, wizard step keys, and spec inventory the server resolved rather than a client-side guess; apply runs the backend's own dryRun and previews the per-student outcome. set-metadata and delete require --expected-version from get; a stale value 409s STALE_WRITE without writing. set-metadata cannot send a setupWorkflowSpec at all. Use patch-spec with a JSON array of bounded JSON-Pointer operations; it always runs the backend's guarded preview first and requires the preview's exact loss token in addition to --confirm when protected template data would be removed.

Module-backed content starts with goals files init --draft, which creates a normal local Git repository pinned to the student's Mesa revision. Edit, rename, delete, inspect, and commit with ordinary Git, then use goals files push. The same checkout can become a personal goal through goals create --source-dir or a reusable BLUEPRINT snapshot through goal-templates capture-snapshot --source-dir; successful goal creation retargets its metadata to the new live goal for continued pushes. Existing live goals use checkout --goal. Every push previews the committed range as one Mesa change and refuses a stale remote tip. The direct goals files write upsert remains available for small or automated writes.

See recess --help for the complete command surface. The raw escape hatch is intentionally read-only: recess --json request get /path.