jam-skill-cli
v0.2.0
Published
Talk to an agent in a browser where its replies render as rich, typeset HTML instead of terminal markdown. The CLI backend for the jam skill.
Maintainers
Readme
jam
Talk to your coding agent in a browser, where its replies render as rich, typeset HTML instead of flat terminal markdown.
jam is a skill for Claude Code and other agents that support the Agent Skills format. When a reply would read better with layout the terminal can't carry — a comparison table, a diagram, code with callouts, math — the agent opens a browser window and answers there. You type back in the browser; the agent replies in a scrolling transcript. The conversation is the artifact; there's no document to review.
Under the hood it's a tiny two-process CLI: open hosts a local, loopback-only
HTTP server and opens your browser; poll long-polls for your next message and
posts the agent's reply. Replies compose against a small design language — a
documented set of tokens and component classes — so turns look coherent instead of
freehanded.
Install
Add the skill with the skills CLI:
npx -y skills add youssefm/jam --skill jam -g -yThat installs SKILL.md user-globally (~/.claude/skills/jam/) into every detected
agent, with no prompts — -g pins the user scope, and omitting --agent lets the
CLI target the agents it detects on your machine (pass --agent '*' instead to hit
every supported agent, installed or not), -y skips confirmations. On
first use the skill installs the CLI globally (npm install -g jam-skill-cli) so the
jam command is on PATH — or falls back to npx -y jam-skill-cli where a global
install isn't available.
Requirements: Node ≥ 18.
Use
Once the skill is installed, just ask the agent to move into the browser:
"let's jam" · "chat about this in the browser"
…or let it decide on its own when a reply needs real layout. A window opens, and you talk. Click End chat in the header when you're done — control returns to the terminal.
You can also drive the CLI directly (after npm install -g jam-skill-cli, or via
npx -y jam-skill-cli without installing):
jam open # host the chat; prints { session, url }
jam poll <session> # wait for the next message
jam poll <session> --html # post an HTML reply (on stdin), then wait
jam poll <session> --text # post a plain-text reply, then waitHow it works
- Two processes.
openis the server — it mints a memorable two-word session id (e.g.brave-otter), binds an ephemeral loopback port, prints one JSON line{ session, url }, opens the browser, and blocks.pollis a short-lived process that finds the running server and long-polls for the next message; with a--html/--textflag it posts the agent's reply (read from stdin) first, so one command posts-and-waits per turn. - Zero runtime dependencies. The backend (
src/*.ts) uses only Node built-ins. The browser app (React + Vite) is prebuilt intoapp/distand shipped in the package, so installingjam-skill-clipulls in nothing transitive. - Rich, safe rendering. Agent HTML is sanitized with DOMPurify, then rendered full-width with client-side syntax highlighting (highlight.js) and math (KaTeX) loaded lazily only when a turn uses them. Sanitization is hygiene, not a sandbox — jam is a personal, single-user, loopback-bound tool.
- The design language. Agent replies compose against
--jam-*tokens and.jam-card/.jam-callout/.jam-grid/.jam-metric/.jam-badge/.jam-dividerclasses defined once in the app's CSS, so turns stay visually coherent.skills/jam/SKILL.mdis how that vocabulary reaches the agent.
Development
npm install # installs devDeps and builds dist/ + app/dist (via prepare)
npm run dev # Vite dev server for the browser app
npm run build # bundle the CLI (dist/cli.mjs) and build the browser app (app/dist)
npm run typecheck # tsc over the backend and the app (no emit)
npm run lint # eslint (strict, type-checked)
npm run test # vitest over src/**/*.test.ts and app/src/**/*.test.ts
npm run check # typecheck + lint + test + buildTo run the CLI: npm run build once, then node dist/cli.mjs open /
node dist/cli.mjs poll <session>. On Node ≥ 22.18 you can also run the source
directly during development — node src/cli.ts open — via Node's type stripping.
Repository layout
src/ # the CLI backend source — Node ESM, zero npm deps (TypeScript)
cli.ts # the agent's surface: open / poll, discovery files, browser open
server.ts # one HTTP server per chat: routes, long-poll, SSE, static serving
store.ts # in-memory session state and the long-poll handoff
words.ts # the two-word session-id vocabulary
types.ts # the chat wire contract
dist/ # bundled CLI (dist/cli.mjs) — generated by esbuild, shipped in the package
app/ # the browser app — Vite + React 19 + TypeScript
src/ # transcript, composer, sanitize/highlight/math, the design language
dist/ # built output the server serves (generated; shipped in the package)
skills/jam/ # SKILL.md — the installable skill that teaches the agent to use the CLI