SLOPSHOPPER

session-pane

/session-pane: files changed this session as a tree, plus the latest tool calls

newpaneguardcommand
v0.1.0MITupdated 2026-10-10michaelezehi/nw-skills/mods/session-pane
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · session-pane
│ ┃ Session ✕ › fix the failing auth test and add an audit log call │ ┃ Changed (3) │ ┃ src/ ⏺ Read(src/auth.ts) │ ┃ audit.ts ⎿ Read 6 lines │ ┃ auth.ts ⏺ Update(src/auth.ts) │ ┃ cache.ts ⎿ Added 2 lines, removed 1 line │ ┃ ⏺ Bash(bun test) │ ┃ Latest tool calls ⎿ 3 pass, 1 fail │ ┃ Read /work/app/src/auth.ts │ ┃ Grep refresh\( ● Done. refresh now rejects expired claims and logs an audit event. │ ┃ Edit /work/app/src/auth.ts │ ┃ Write /work/app/src/audit.ts ✻ Worked for 42s · done 4:20 PM │ ┃ Write /work/app/src/cache.ts │ ┃ Bash bun test › /session-pane │ ┃ Bash git status --porcelain ⎿ session-pane: Session pane opened. │ ┃ Bash rm -rf build && git push --force origin │ ┃ main │ ┃ Bash cat .env │ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Pane · Session
Changed (3) src/ audit.ts auth.ts cache.ts Latest tool calls Read /work/app/src/auth.ts Grep refresh\( Edit /work/app/src/auth.ts Write /work/app/src/audit.ts Write /work/app/src/cache.ts Bash bun test Bash git status --porcelain Bash rm -rf build && git push --force origin main Bash cat .env
README

NW skills

New Ward skills: agent skills and slash commands for Claude Code that I use on every project.

Most are my own. Some started as other people's skills and now carry my changes, mostly an unlazy completion gate and plain-writing rules wired in. Each one is marked in the tables below.

Install

Claude Code plugin

claude plugin marketplace add michaelezehi/nw-skills
claude plugin install nw-skills@nw-skills

Plugin skills and commands are namespaced, so /research becomes /nw-skills:research.

skills.sh

npx skills@latest add michaelezehi/nw-skills

This copies editable skill folders into your project or ~/.claude/skills.

By hand

Copy any folder under skills/<category>/ into ~/.claude/skills/, and any file under commands/ into ~/.claude/commands/.

Several skills point at ~/.claude/skills/unlazy/scripts/gate-check.mjs and ~/.claude/skills/unslop/SKILL.md. Install unlazy and unslop first if you take only a few.

Skills (38)

Engineering

SkillWhat it doesOrigin
app-user-journeyScan a codebase for every user role and map each one's real journey, registration, onboarding, the day-one surface, and a proposed leaner path, then ship it as an...Original
build-speedAudit and fix any project's build + deploy pipeline for speed, kill cache-busting, move builds off the deploy box into CI, wire registry pull mode, and prove every...Original
convex-backup-cronInstall a 4x-daily production backup cron for Convex + DigitalOcean Spaces projects.Original
ogInstall a dynamic Open Graph / Twitter social card route into a Next.js project.Original
own-goalRun a goal or a whole PRD to completion: a verifiable completion condition worked in a loop until met, with an accountability record and a /reviewer gate.Original
project-optimisationFind and fix why a JS/TS monorepo is slow, from dev server memory to first-load JS per route: measure, fan out by cause, fix in parallel, re-measure, ship through staging.Original
qa-casesGenerate a shareable QA test case .md document for the current project.Original
terminal-upgradeTurn pnpm dev / npm run dev / yarn dev / bun dev in every repo on the machine into Devdeck, a calm live terminal dashboard.Original
ts-upgradeMove a repo's type checking to TypeScript 7, the native compiler, without breaking ESLint, tsup, Next, Expo, Remotion, Convex, CI or Docker builds, and measure before and after.Original
unlazyAnti-laziness execution discipline, required on every task sized L or XL (the /prd-ch scale) and run on request for anything smaller.Modified from Leonxlnx/unlazy
vercel-react-best-practicesReact and Next.js performance optimization guidelines from Vercel Engineering.Modified from vercel-labs/agent-skills
walkthroughAdd a guided walkthrough to any web app, one story per user role: a story bar with arrow keys, a journey reader with "show me how to get there", split prompt cards, and an optional demo tier...Original

Design and frontend

SkillWhat it doesOrigin
apple-designApple's approach to interface design and fluid, physical motion, translated for the web.Modified from emilkowalski/skill
brandkitPremium brand-kit image generation skill for creating high-end brand-guidelines boards, logo systems, identity decks, and visual-world presentations.Modified from Leonxlnx/taste-skill
click-burstAdds a performant click-triggered full-viewport color burst transition (scale + opacity only, no animated blur).Original
design-taste-frontendAnti-slop frontend rules for LANDING PAGES, PORTFOLIOS, and MARKETING REDESIGNS: reads the brief, infers direction, ships interfaces that do not look templated, with...Modified from Leonxlnx/taste-skill
emil-design-engEmil Kowalski's design-engineering philosophy, animation decisions, springs, gestures, component feel, and the invisible details that make software feel great.Modified from emilkowalski/skill
fedAlias for frontend-design.Original
find-animation-opportunitiesSearch a codebase or UI for places that don't animate but should, and reject everything that shouldn't.Modified from emilkowalski/skill
frontend-designThe main frontend skill. Distinctive, production-grade UI with high craft in typography, layout, colour and motion.Original
iconizeExtract individual icons from sprite sheets into named, square PNG files organized by category.Original
image-to-codeAlias for imagegen-frontend-web (image-first web flow: generate section images, then code them).Modified from Leonxlnx/taste-skill
imagegen-frontend-mobilePremium mobile app screen concept images, iOS, Android, and cross-platform screens and multi-screen flows (onboarding, auth, home, profile, settings, chat, commerce,...Modified from Leonxlnx/taste-skill
imagegen-frontend-webThe image-first WEB flow, generate one premium horizontal reference image per section (hero, landing page, marketing site, product page, portfolio), deeply analyze...Modified from Leonxlnx/taste-skill
impeccableUse when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise...Modified from pbakaus/impeccable
improve-animationsSurvey a codebase's animation and motion code as a senior motion advisor, then produce a prioritized audit and self-contained implementation plans for other agents...Modified from emilkowalski/skill
industrial-brutalist-uiOPT-IN STYLE PRESET, use ONLY when the user explicitly asks for brutalist / industrial / Swiss-print / terminal aesthetics, or names this skill.Modified from Leonxlnx/taste-skill
minimalist-uiOPT-IN STYLE PRESET, use ONLY when the user explicitly asks for a minimalist / Notion-like / warm-monochrome editorial look, or names this skill.Modified from Leonxlnx/taste-skill
pick-ui-libraryPick the right library for a given frontend task from a curated, opinionated list, numbers, OTP inputs, charts, command menus, virtualization, drag and drop, toasts,...Modified from emilkowalski/skill
prototypeBuild multiple genuinely different versions of a UI piece you describe, rendered behind a visual picker so you can flip through them live and promote the one that...Modified from emilkowalski/skill
redesign-existing-projectsUpgrades existing websites and apps to premium quality.Modified from Leonxlnx/taste-skill
review-animationsReviews animation and motion code against a high craft bar derived from Emil Kowalski's design engineering philosophy.Modified from emilkowalski/skill
sketchesHand-drawn SVG sketch/doodle system with a growing, brand-themeable repertoire.Original
stitch-design-tasteSemantic Design System Skill for Google Stitch.Modified from Leonxlnx/taste-skill
the-broadsideInstall the broadside editorial slide-deck design system into the current React/Next.js project.Original
the-stripe-modalInstall the editorial-press design system (surface card + slide-in modal flow + hero empty state) into the current React/Next.js project.Original
ui-ux-pro-maxUI/UX design intelligence for web and mobile.Modified from nextlevelbuilder/ui-ux-pro-max-skill

Writing

SkillWhat it doesOrigin
humanizerRewrite AI-sounding text so it reads like the writer without changing what it says.Modified from blader/humanizer
rndCreate a shareable internal R&D page from a team brief, a votable consensus spec with a participant intro gate (--consensus), a screen-by-screen product build deck...Original
unslopCut AI tells from any writing.Original
writing-clearly-and-conciselyStrunk companion for prose humans will read.Modified from softaworks/agent-toolkit

Commands

CommandWhat it does
/cfForce-continue a context-exhausted session.
/chHandoff continuity mode: numbered task list, accountability record with every question and decision, optional HTML summary.
/fd-chFrontend design run with reconnaissance, a quality gate and an accountability record, built on the frontend-design skill.
/prRead every PR review comment, fix what is actionable, and reply to each one.
/prd-chCreate a PRD fast and well.
/researchDeep research on any topic.
/reviewerFull audit and fix pass on the current task's changes, using any review skills installed on your machine (never Greptile or CodeRabbit).

Mods

Claude Code mods (plugins with function hooks) in mods/. Each one installs on its own from this marketplace:

claude plugin marketplace add michaelezehi/nw-skills
claude plugin install savvy-progress@nw-skills
ModWhat it doesOrigin
savvy-progressProgress bar above the prompt and an agents panel (/agents-info) with each subagent's model, context, cost and time. Draws in 24-bit colour in any truecolor terminal (Warp, iTerm2, Ghostty, WezTerm, kitty) as well as on the desktop.Modified from johnnyvizz/claude-kit
agent-barTurns the savvy-progress bar on for every task: todos, tasks and subagent launches become its rows. Steps aside when a skill reports its own plan. Needs savvy-progress.Original
guard-railsDenies git commands that sweep other agents' work (git add -A, commit -a, stash, reset, clean, restore, checkout) and dashes in commit or PR text.Original
session-pane/session-pane opens a pane with the files changed this session as a tree and the latest 50 tool calls.Original
turn-chimeA toast and a chime when a turn that ran a minute or longer finishes.Original

The skills and commands report to the progress panel by the rules in references/progress-panel.md. Copy it to ~/.claude/references/. Without savvy-progress installed they skip it.

Handoff hooks (optional)

/ch, /fd-ch and /prd-ch hand work over to a fresh session when context runs low. That needs three hooks in hooks/:

  • context-monitor.sh warns at about 70 and 90 percent context use.
  • precompact.sh writes .claude/handoffs/current.md (todos and modified files) before compaction.
  • session-start.sh feeds that handoff back in when the next session starts.

They are not switched on by installing the plugin. To use them, copy the scripts to ~/.claude/hooks/ and add this to ~/.claude/settings.json:

{
  "hooks": {
    "PostToolUse": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/context-monitor.sh" }] }],
    "PreCompact": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/precompact.sh" }] }],
    "SessionStart": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/session-start.sh" }] }]
  }
}

Without them the commands still run; you just lose the automatic handoff.

Licence

My own skills and commands are MIT, see LICENSE. Modified skills keep their upstream licence and credit; see NOTICE.md.

Source 2 files
hooks/register.tsx 106 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { Call } from '../types'
5
6const PANE = 'session-pane'
7const files = atom({ plugin: 'session-pane', key: 'files' } as const, [])
8const calls = atom({ plugin: 'session-pane', key: 'calls' } as const, [])
9
10const WRITERS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit'])
11
12function labelOf(input: Record<string, unknown>): string {
13  const raw = input.file_path ?? input.notebook_path ?? input.command ?? input.pattern ?? input.description ?? ''
14  return String(raw).replace(/\s+/g, ' ').slice(0, 60)
15}
16
17function relative(path: string, cwd: string): string {
18  return path.startsWith(cwd + '/') ? path.slice(cwd.length + 1) : path
19}
20
21// Groups paths by folder so the pane reads as a tree, folders sorted.
22function treeRows(paths: string[]): Array<{ text: string; isFolder: boolean }> {
23  const byFolder = new Map<string, string[]>()
24
25  for (const path of paths) {
26    const cut = path.lastIndexOf('/')
27    const folder = cut === -1 ? '.' : path.slice(0, cut)
28    byFolder.set(folder, [...(byFolder.get(folder) ?? []), path.slice(cut + 1)])
29  }
30
31  return [...byFolder.keys()].sort().flatMap(folder => [
32    { text: `${folder}/`, isFolder: true },
33    ...byFolder.get(folder)!.sort().map(name => ({ text: `  ${name}`, isFolder: false })),
34  ])
35}
36
37export const register: Register = on => {
38  let cwd = ''
39
40  on('session.start', async ($, e, next) => {
41    cwd = e.cwd
42    await $.command.register({
43      name: 'session-pane',
44      description: 'Show files changed this session and the latest tool calls',
45    })
46
47    return next(e)
48  })
49
50  on('command.run', { command: 'session-pane' }, async $ => {
51    await $.ui.open({ id: PANE, title: 'Session' })
52
53    return { text: 'Session pane opened.' }
54  })
55
56  on('tool.call', async ($, e, next) => {
57    const input = e as unknown as Record<string, unknown>
58    const call: Call = { id: e.tool_use_id, tool: e.tool, label: labelOf(input), isDone: false, isError: false }
59    await update($, calls, list => [...list, call].slice(-50))
60
61    const ran = await next(e)
62    const isError = ran.deny !== undefined || ran.isError === true
63    await update($, calls, list =>
64      list.map(one => (one.id === call.id ? { ...one, isDone: true, isError } : one)),
65    )
66
67    const path = input.file_path ?? input.notebook_path
68
69    if (WRITERS.has(e.tool) && !isError && typeof path === 'string') {
70      const shown = relative(path, cwd)
71      await update($, files, list => (list.includes(shown) ? list : [...list, shown]))
72    }
73
74    return ran
75  }).catch(($, e, next) => next(e))
76
77  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
78    const { Box, Text } = $.ui.resolve(e)
79    const changed = await read($, files)
80    const recent = await read($, calls)
81    const rows = Math.max(6, (e.viewport?.rows ?? 24) - 6)
82    const callRoom = Math.min(10, Math.floor(rows / 2))
83    const fileRows = treeRows(changed).slice(0, rows - callRoom)
84
85    return (
86      <Box flexDirection="column">
87        <Text bold>Changed ({changed.length})</Text>
88        {changed.length === 0 && <Text dimColor>No edits yet.</Text>}
89        {fileRows.map(row => (
90          <Text color={row.isFolder ? 'cyan' : undefined} dimColor={row.isFolder}>
91            {row.text}
92          </Text>
93        ))}
94        <Text> </Text>
95        <Text bold>Latest tool calls</Text>
96        {recent.length === 0 && <Text dimColor>None yet.</Text>}
97        {recent.slice(-callRoom).map(call => (
98          <Text color={call.isError ? 'red' : call.isDone ? undefined : 'yellow'} dimColor={call.isDone && !call.isError}>
99            {call.tool} {call.label}
100          </Text>
101        ))}
102      </Box>
103    )
104  })
105}
106
types/index.d.ts 8 lines
1export type Call = { id: string; tool: string; label: string; isDone: boolean; isError: boolean }
2
3declare module 'claude-code' {
4  interface PluginState {
5    'session-pane': { files: string[]; calls: Call[] }
6  }
7}
8