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

@learnaltitude/cli

v0.9.0

Published

Agent-neutral Altitude workshop client for Claude Code and Codex.

Readme

Altitude CLI

The Altitude CLI is the workshop client that connects supported coding agents to the Altitude service.

Install

npm install -g @learnaltitude/cli

Pair the CLI with your account at app.learnaltitude.com. Supported agents are Claude Code and Codex.

Connect, bind, and inspect a project

From a terminal, name the agent this computer will use and complete the browser device flow:

altitude connect --agent claude-code
altitude connect --agent codex

Use one command, not both. Codex must meet the current compatibility floor documented on the W2 card. Adapter-native connect declares the detected version; the server refuses a parseable version below its floor with server-authored remediation. The raw terminal command stamps the version as "unknown", which deliberately remains pairable. Other JSON connection failures likewise print the server's message; non-JSON failures retain the HTTP status line. Connecting stores a scoped bearer token in the CLI data directory (by default, ~/.altitude/token.json) with owner-only permissions; it does not activate hooks in every directory.

A directory declares WHICH journey it works. From the root of the project, pick from your journey list:

altitude bind --list            # show your journeys and their statuses
altitude bind --journey <id>    # bind this directory to one of them
altitude bind                   # binds directly when exactly one journey is bindable

Binding writes a .altitude marker in that directory. Hooks discover the nearest marker while walking upward, so the project and its subdirectories are active. Without a valid marker, hooks remain dormant for capture, context, gates, and session registration. They still recover writes left in the temporary spool, and a paired device's session-start and learner-turn hooks refresh the account-level caches at most once per 10-minute attempt window so sandboxed CLI commands can read them. Binding during a running agent session takes effect on its next learner turn or tool lifecycle; you do not need to restart the agent. That first bound lifecycle refreshes the journey before it registers the adopted session, so the session is attributed to the current task when available. Gate failures in a bound project still fail open. Several directories may bind the same journey (git worktrees are the normal case); each directory holds exactly one journey, and its down-synced working set is cached per journey in an owner-only file for offline sessions. An abandoned journey stays visible in the list but cannot be bound; a paused journey can. When the refreshed or cached journey list marks it paused, session start prints the server's paused notice when present and keeps gates dormant until a later list refresh observes that you resumed it on Altitude (never automatically from the terminal). Older responses without a notice stay silent. When the server refuses a binding's journey (deleted, abandoned, or not entitled), the session prints the server's explanation instead of silently substituting another project. altitude diagnostics records these misses and stale bindings; the precise hook behavior is defined in the workshop/server protocol. If the project is already bound to another journey, inspect the IDs before deliberately replacing the marker with altitude bind --force.

Use altitude task --json --session <actual-session-id> for a network-first snapshot of the BOUND journey with local-cache fallback; its source field says which was used, journey_status carries the journey's last-known status, and journey_miss carries the server's refusal when the bound journey was not served. After a failed live read, reason distinguishes a host-blocked network, an offline host, rejected authorization, and a bad server response; transport carries the support-safe cause and elapsed time. For session identity and recovery, see Versioned paid lessons. Its full shape is the taskEnvelopeSchema contract. altitude status is a local snapshot that includes the nearest binding, the bound journey's cached working-set summaries, queued and spooled event counts, and any host-published network-sandbox marker. altitude diagnostics reports the primary log's path, existence, line count, malformed-line count, and valid records, plus the spool path and its line count. Malformed lines do not prevent valid records from being shown. Binding requires a connected device token; the command tells unconnected users to connect and directs users without a bindable journey back to Altitude.

Queue, diagnostic, and flusher-wake writes refused because the CLI data directory is read-only are preserved under the operating system's temporary directory. The next hook or flusher drain moves them into the normal owner-only data directory. As a result, altitude emit still succeeds when a supported host sandbox makes the home directory unwritable. Spool fallback is limited to permission and read-only-filesystem failures; diagnostics and wake nudges remain best-effort.

The envelope also carries two update signals, both derived from the server's client_releases answer on the settings down-sync (the server owns "what's current"; there is no npm registry check). update_available is true when the CLI is behind the server's latest — its meaning is unchanged for older plugin markdown. update_notices is the successor surface: zero, one, or two server-authored lines (CLI and/or plugin), compared live against the installed versions on every read. Hooks stamp routine notices once per session; urgent notices repeat within the session. Task reads return current notices without consulting or updating those stamps. altitude task adds no version request of its own — a lesson never waits on one. Skills update separately through the agent's plugin system.

Tutor flows can attach the learner's verbatim answer to its canonical concepts. The tutor does not grade the answer; grading and any resulting mastery update are server-side:

altitude emit quiz-moment --session <id> --question <q> --answer <a> \
  --concepts <id,...>

--concepts accepts comma-separated IDs or repeated flags. The CLI trims empty entries, removes duplicates in first-seen order, and omits concept_ids when no non-empty ID is supplied.

Teaching preferences and check-ins

Change the bound journey's teaching preferences with one or more assignments:

altitude teaching set drills=1 step_size=line --session <id>
altitude teaching set check_density=every_run --json

Valid values are drills=0|1|2|3, step_size=line|function|feature, and check_density=teach_runs|every_run. The server's teaching read policy determines how preferences apply to each lesson's learning level. The command requires a connected device and discovers the same project binding as altitude task. It uses the device bearer token to PATCH /api/journeys/{journeyId}/teaching with the usual HTTP timeout. Success prints all three preferences; --json prints the server's { journey_id, teaching_knobs } response.

When network access fails or the server returns 5xx, the command queues a teaching_knobs_set event with source: "cli" and reports that the change applies on the next sync. An unwritable data directory uses the existing temporary spool. With --json, this returns { status: "queued", journey_id, knobs, message }, not a confirmation that the server applied the change. Server 4xx responses print the server message, exit 1, and are neither retried nor queued. Invalid input also exits 1. These commands never exit 2.

If an earlier teaching update or accepted check-in for this journey is still in the queue or temporary spool, the command exits 1 before PATCH. Run altitude flush --force, then retry the command once syncing succeeds. This keeps an older claim from overwriting a newer confirmed preference. Declined check-ins and other journeys do not delay the update. Concurrent teaching set commands share an atomic directory lock in the temporary spool; a second command exits 1 with a retry message until the first finishes its PATCH or queues its fallback. The lock is released on both success and errors. After a forcibly terminated process, stop any remaining teaching set commands before removing the empty teaching-update.lock directory under the data directory's temporary spool. Locks are never stolen on a timer, so a slow request cannot be overtaken.

Record a lesson-close proposal and the learner's explicit answer:

altitude emit teaching-checkin --session <id> --knob drills --value 1 \
  --signal hints_heavy --answer yes \
  --observation 'You needed three hints while writing the loop.'

Signals are hints_heavy, drills_skipped, no_learner_lines, impatience, or floor. --answer yes|no becomes the event's accepted boolean. Both answers queue a teaching_checkin; the server owns applying accepted proposals and checking authorization. This command makes no direct settings request. Both commands use the existing session registry fallback when --session is omitted; pass the actual session ID when available. Optional --task <uuid> --plan-revision <positive integer> flags are validated consistently with other emitters, but the current shared check-in contract is journey-scoped and has no fields to transmit that task/revision provenance. These are preference claims, not mastery evidence.

altitude task --json preserves the server's optional journey.teaching_knobs, journey.current_task.due_review, and journey.current_task.method_checkin on both live and cached reads. The client does not select review concepts or schedule check-ins.

Versioned paid lessons

Compatible client artifacts and release prerequisites are tracked in the learning-level rollout specification.

current_task.learning_requirements carries the server-authored instructions, level, lesson mode, concept capabilities, and immutable plan revision. Paid executors retain that task and revision for the whole lesson, including a completion queued after the journey changes. Pass --task <id> --plan-revision <n> with both emit task-completed and emit quiz-moment for every versioned task, including Beginner. Quiz text must preserve the actual question and the learner's answer verbatim. These events are claims; server judgment owns capability credit.

learning_runtime contains server-authored update copy and compatible version minima. The CLI compares its running version and the exact session marker’s hook-observed plugin version against those minima even when reading a warm cache.

Use the exact reload command supplied by the current agent's Altitude hook. An omitted or empty --session uses an unambiguous CLAUDE_CODE_SESSION_ID or CODEX_THREAD_ID; if both are nonblank they must agree. An explicit ID must match the current host identity. An ordinary terminal without either variable can provide an exact existing session ID. Reads never select the newest session, borrow another session's plugin observation, or create or modify session markers. The optional learning_runtime.session_id identifies an existing plugin observation, not a replacement ID to invent.

The local task envelope distinguishes these runtime outcomes (the HTTP settings contract is unchanged):

  • supported: the lesson can proceed.
  • update_required: a known installed version is below the server's compatibility minimum. Follow the update instructions and restart the agent after a plugin update.
  • session_required: the CLI version or this session's plugin observation is unusable. Follow recovery_message. For a missing plugin observation, send the next normal learner prompt so the installed hook can refresh it, then reload using the hook's exact session command. Reopen the agent if hooks are not running. Do not invoke hooks manually, edit session records, or repeatedly update software to repair a missing observation.
  • requirements_unavailable: an Intermediate task is missing its server-authored requirements. Reload online with the current session ID; contact [email protected] if they remain unavailable. Do not fabricate requirements or treat this as an update request. This outcome takes precedence over version checks.

Normal bound prompt hooks refresh existing plugin observations and clear stale observations when the installed version is missing or blank. After recovery, require a fresh supported result before teaching or reporting lesson completion. A bound cold cache cannot authorize lesson evidence. An unsupported paid lesson waits for a supported read and never silently adopts the free method; editor hooks remain fail open. When the subscription is paused, bound paid journey lessons wait for renewed access; standalone unbound free projects remain available. Intermediate does not mint automatic legacy gate credit. Its demonstrated evidence is captured through the paid executor, with task and revision provenance.

Manual verification with a real Claude Code subscription and a local plugin checkout:

pnpm -F @learnaltitude/cli build
node packages/workshop-core/scripts/verify-learning-session.mjs /path/to/altitude-skills

The harness uses a loopback fixture backend, an isolated scratch git repository, and the actual CLI/plugin hooks. Enter learner messages one line at a time and /exit when finished. It removes provider API-key environment variables and uses the installed agent's account. It retains the scratch code, HTTP requests, emitted claims, and turn outputs in the printed temporary directory. Fixture acceptance verifies transport and attribution, not real production grading or mastery.

Plugin marketplace installs and updates

Install the Altitude plugin exclusively through the marketplace built into your coding agent. For Claude Code, open a terminal and start Claude Code:

claude

Then run these commands inside that terminal session:

/plugin marketplace add jasonku09/altitude-skills
/plugin install altitude@altitude

When the installer asks for a scope, choose the user scope so the plugin is available across all projects, including the new project folder created by your first lesson. If the install summary asks you to run /reload-plugins, run it; newer Claude Code versions activate the plugin in place. The VS Code built-in terminal works for this flow. The extension chat panel uses its separate /plugins manager instead.

Start the lesson from a terminal with claude --permission-mode auto, then enter /altitude:begin. Auto mode clears routine approval prompts while Claude Code's separate safety checks screen every action and block risky ones; it is a safeguard, not a guarantee.

For Codex, update Codex to the latest version first, then run these commands in a terminal. Older Codex CLI releases do not recognize the plugin commands.

codex plugin marketplace add jasonku09/altitude-skills
codex plugin add altitude@altitude

On the first Codex launch after installation, accept the one-time Hooks need review -> Trust all and continue prompt. To start the first lesson, type $begin and press Enter twice; the second press expands the command in Codex's composer. Skills update with the agent's plugin system.

Neither half updates on its own by default. Claude Code enables marketplace auto-update only for official Anthropic marketplaces; altitude is third-party, so its auto-update starts off. Turn it on once — run /plugin in Claude Code, open Marketplaces → altitude, enable auto-update — and the plugin then follows releases without further prompting.

The globally installed Altitude CLI never updates itself. To move it:

altitude update

The command prints a one-line reminder that skills update with the agent, then asks the detected global package manager to update @learnaltitude/cli. If detection or execution fails, it prints the exact manual command instead.

Because nothing forces either update, the server enforces a minimum CLI version at the device connect handshake. altitude connect is refused when the CLI does not report a readable version or is older than the floor; the refusal names the update command and, for Claude Code, the auto-update toggle. The floor is server-owned — raising it needs no client release.

Network disclosure

The distributed client uses the user's own agent subscription and no Altitude-held API key. The CLI makes no third-party requests: the old anonymous registry.npmjs.org version check is gone. Freshness now rides the existing authenticated settings down-sync — the request reports the installed CLI and plugin versions as query parameters, and the response's client_releases block carries the server's latest versions plus the notice copy. Lesson reads follow the exact-session usage above, with network-first reads and cache fallback. Bound session-start hooks refresh the journey and journey list; learner-turn hooks also refresh stale bound caches, and refresh immediately after delivering a task completion that can change the snapshot. On paired devices, unbound session-start and learner-turn hooks silently warm the account-level caches for sandboxed commands. Failed attempts are rate-limited as well as successful reads: the defaults are 10 minutes for unbound warming and 60 seconds per bound journey, configurable with ALTITUDE_DOWNSYNC_TTL_MS and ALTITUDE_BOUND_REFRESH_TTL_MS. connect performs only its device flow, while diagnostics, status, and update-notice checks use cached down-sync data. Gates perform no version or network work. Hook refresh and comparison failures remain silent and cannot change a hook's exit code.