Home/Features/Session mods
2 plugins · mods

Session mods

test-board and session-compass: two lines above the prompt that show your last test run and where each session stands.

Install → test-board source ↗ session-compass source ↗
2
mods
10
runs kept per suite
50
sessions kept for /compass
0
background model calls

01 Overview

A mod is a Claude Code plugin made of TypeScript function hooks that wrap Claude Code's own behavior. Each hook has the shape ($, e, next). These two mods each draw one line above the prompt, and they stack over any other mod's band. test-board shows the result of your last test run. session-compass shows what a session is building when you come back to it.

Final frame, all three scenes: a test run, the compass band above it, then the /compass pane. Sample values.

02 Problem & why it's needed

Test counts are buried (test-board)

The pass and fail counts sit deep in tool output that nobody scrolls through. test-board lifts them into one line above the prompt, next to the previous run of the same suite, so you see at once whether failures went up or down.

You lose track of sessions (session-compass)

With several sessions across repos and worktrees, it is hard to remember what each one was doing. session-compass records the goal, the phase and everything the session produced, and shows it when you come back, without scrolling.

03 Install

Add the marketplace, then install the mods you want

/plugin marketplace add abhijitbansal/claude-skills
/plugin install test-board@claude-skills
/plugin install session-compass@claude-skills

Both run immediately after install; no restart.

Optional: try them from a checkout

claude --plugin-dir plugins/test-board --plugin-dir plugins/session-compass

04 Usability guide

test-board

What counts as a test run

These commands count, alone or after a leading cd or env vars, behind npx, bunx, uv run, uv tool run, uvx, poetry run, python -m, pnpm exec, pnpm dlx or yarn: xcodebuild … test (or test-without-building), swift test, pytest, jest, vitest, bun test, npm|pnpm|yarn [run] test, cargo test, go test, fastlane scan|test. cat pytest.log is not one. It reads cartoon's test summary first, then raw xcodebuild, swift test, pytest, jest/vitest and bun output.

Anatomy of the band line

One line per recent run, up to 3, in this order: label, counts, trend, duration, time it finished, previous run, subagent. Runs in the same turn stack; the first run after you submit a prompt replaces the previous turn's lines.

Cubby · xcodebuild test -scheme Cubby 412 ✓ 3 ✗ 2 skip ▲3 ✗ 1m12s done 14:32 prev 415 ✓ 0 ✗ · 2h ago via ios-fixer ✕ └ repo · suite └ counts │ └ took │ │ └ subagent │ └ trend └ done at └ previous run └ close

▲ and ▼

An arrow shows the change in failures against the previous run of the suite: ▲ means more failures, ▼ fewer. A suite with no earlier run shows first run in place of prev.

Press to expand failures

Press the line to list up to 10 failing tests with their locations.

Closing the band

Each line leaves the band 60 minutes after its run finished; the band closes with the last one. Press ✕ at the end of the first line to close it sooner. It stays closed through a plugin reload, and the next test run brings back a band holding only that run. session-compass's tests segment reads the same runs, so it also clears at 60 minutes; ✕ leaves it up.

When counts can't be read

A recognised test command whose output it cannot read shows ran · exit N · counts unavailable (the run is stored with parsed: false).

Narrow terminals and subagents

Narrow terminals drop via, then prev, then the duration, then the finish time. Runs from a subagent are tagged via <the agent's description>; workflow agents are tagged via workflow. When a session starts, the newest stored run of the current worktree appears dimmed until a new run replaces it, if it ran within the last 60 minutes. The band stays hidden while a survey is on screen.

session-compass

compass_status — the model sets the goal

The model sees the tool as mcp__session-compass__compass_status, with optional goal (80 characters), step and next (60 each). A short standing reminder asks Claude to call it when the goal is first clear and whenever the phase changes (spec, plan, implement, review, PR, done), not every turn. A call with no non-empty field is refused.

The compass band

One line above the prompt: repo · worktree (branch) · Goal · Now · N artifacts · tests. It is always up, from the moment the session starts, and updates as the goal, step and artifacts change. Only a survey on screen takes its place. With no goal set it shows your first prompt dimmed and (no goal set). tests appears when test-board is installed and has parsed runs.

The /compass pane

This session shows repo, worktree and branch; goal; step and next; how long ago the status was set; test-board's tally; and every artifact. All sessions lists the other recorded sessions, most recently active first, up to 50. Press an entry to copy it: a URL, a path, a commit sha, a branch name, or claude --resume <id> for a session row.

What counts as an artifact

Captured automatically from successful tool calls:

SourceWhat is kept
Artifact publishThe claude.ai URL. Opens, reads and lists are ignored.
SendUserFileAttachments that uploaded without error.
Deliverable WriteAn .html, .md, .pdf, .png or .svg under .scratch/, docs/, reports/ or test-checklists/, or under a Claude scratchpad directory.
Git commits, pushes, PRsAs reported by the Bash tool. A checkout, switch, worktree, commit or push from the main session also refreshes the recorded worktree and branch.

05 How it works under the hood

The hook chain

A tool call goes down through the mods to the engine, and the result comes back up. Each mod wraps next(e), so it sees the command before it runs and the result after, without owning either. Neither mod alters or denies another tool's call.

MOD CHAIN · on('tool.call') Model session-compasscaptures artifacts · never alters test-boardrecords runs · never alters engine · Bash runs Bash call next(e) result · parse tests result · capture commits same result
The order of the two mods does not matter.

Band stacking

Each band hook draws its own line, then appends whatever next(e) drew below it. A band never replaces another, so the two mods and any other mod's band stack in one column above the prompt.

my line + next(e)session-compass my line + next(e)test-board engine / other mods ui.render · AbovePrompt claude-skills · claude-mods (feat/session-mods) · Goal: barcode fallback claude-skills · pytest -q 40 ✓ 3 ✗ 1 skip ▲3 ✗ 1s done 14:32 prev 43 ✓ 0 ✗ · 5m ago ✕ other band
Each hook draws its line and then appends whatever next(e) drew.

test-board internals

Pure modules (suite.ts, parse.ts, history.ts, format.ts) and one register.tsx that talks to the engine. History lives in the plugin store under runs:<key>, where the key is the worktree root plus the normalized command, so … | tail -30 and the bare command share one history. It keeps the last 10 runs per suite per worktree, plus an index of keys by last use. The latest runs are in the test-board.latest state value, which session-compass reads when test-board is installed.

session-compass internals

Pure modules (record.ts, capture.ts, git.ts, io.ts, band.tsx, pane.tsx) and one register.tsx. The store holds one session:<id> record per session and an index of ids. All store work runs on one serial queue, and the record changes only through compare-and-swap updates of the current state value, so concurrent events never interleave. compass_status is denied for subagents, so a subagent cannot rewrite the session goal; a subagent's artifacts still count. Atoms and every function that touches $ sit in register.tsx because the host does not follow $ into imported files.

06 What's inside

test-board

hooks/register.tsx, suite.ts, parse.ts, history.ts, format.ts, hooks.json
limits10 runs per suite per worktree · 20 failure IDs per run · 3 runs in the band · 2 MiB soft store cap (least recently used suites dropped first)
known limitA hot reload mid-session forgets which agent ids belong to which subagent, so their later runs show as via workflow.

session-compass

hooks/register.tsx, record.ts, capture.ts, git.ts, io.ts, band.tsx, pane.tsx, hooks.json
limitsGoal 80 characters, step and next 60 · 100 artifacts per session · 50 sessions
privacyRecords live in the plugin's local store. Nothing leaves the machine and the plugin makes no model calls. The store keeps the first 80 characters of a session's first prompt, worktree paths, commit subjects and artifact URLs until the session ages out of the 50-session cap; avoid pasting secrets into a first prompt.

Explore the other plugins

Browse the full skills & tools catalog →