SLOPSHOPPER

matrix

Jack Claude Code into the Matrix: digital rain above the prompt, phosphor-green transcript, and messages from Zion.

bandspinnerrowscommandstatustimer
v0.1.0no licenseupdated 2026-10-18Mulbrix/claude-mods/plugins/matrix
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · matrix
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /matrix ⎿ matrix: You took the blue pill. The story ends. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

token-dashboard

A Claude Code mod: a live pane showing the session's token usage — totals, cache hit rate, cost, context window fill, rate limits, a per-request sparkline and a per-model breakdown.

Open it with /tokens.

Install

The repository is private: you need access to it on GitHub, and GitHub set up on your computer.

/plugin install token-dashboard --marketplace mulbrix/claude-mods

Answer y to add the marketplace, then pick a scope.

Source 2 files
hooks/register.tsx 278 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const isOn = atom({ plugin: 'matrix', key: 'isOn' } as const, true)
5
6const GREEN = '#00ff41'
7const DIM_GREEN = '#008f11'
8const BLACK = 0x000000
9const HEAD = 0xd8ffd8
10const DEFAULT = 0x01000000
11
12// Halfwidth katakana, digits and a few symbols: every one a single cell wide.
13const GLYPHS: number[] = []
14for (let c = 0xff66; c <= 0xff9d; c++) GLYPHS.push(c)
15for (const ch of '0123456789Z:."=*+-<>|') GLYPHS.push(ch.charCodeAt(0))
16
17const INTRO = [
18  'Wake up, Neo...',
19  'The Matrix has you...',
20  'Follow the white rabbit.',
21  'Knock, knock, Neo.',
22]
23
24const SPINNER_WORDS = [
25  'Following the white rabbit',
26  'Jacking in',
27  'Bending the spoon',
28  'Dodging bullets',
29  'Downloading kung fu',
30  'Decoding the Matrix',
31  'Tracing the call',
32  'Hacking the mainframe',
33  'Searching for the Oracle',
34  'Taking the red pill',
35  'Rewriting the code',
36  'Evading Agents',
37]
38
39const DONE_WORDS = [
40  'Jacked out after',
41  'Decoded in',
42  'Escaped the Agents in',
43  'Bent the spoon in',
44  'Rebooted reality in',
45  'Freed your mind in',
46]
47
48const pick = (list: string[], seed: string) => {
49  let hash = 0
50  for (let i = 0; i < seed.length; i++) hash = (hash * 31 + seed.charCodeAt(i)) | 0
51  return list[Math.abs(hash) % list.length]!
52}
53
54const randomGlyph = () => GLYPHS[Math.floor(Math.random() * GLYPHS.length)]!
55
56const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
57const toBase64 = (bytes: Uint8Array) => {
58  let out = ''
59  for (let i = 0; i < bytes.length; i += 3) {
60    const n = (bytes[i]! << 16) | ((bytes[i + 1] ?? 0) << 8) | (bytes[i + 2] ?? 0)
61    out += B64[(n >> 18) & 63]! + B64[(n >> 12) & 63]!
62    out += i + 1 < bytes.length ? B64[(n >> 6) & 63]! : '='
63    out += i + 2 < bytes.length ? B64[n & 63]! : '='
64  }
65  return out
66}
67
68const fade = (t: number) => {
69  // t: 0 at the head, 1 at the tail's end.
70  const g = Math.round(255 - t * 210)
71  const r = Math.round(Math.max(0, 40 - t * 60))
72
73  return (r << 16) | (g << 8) | Math.round(Math.max(0, 65 - t * 80))
74}
75
76type Drop = { head: number; speed: number; length: number }
77
78/** The digital rain: a grid of glyphs and one falling drop per column. */
79class Rain {
80  columns = 0
81  rows = 0
82  glyphs = new Uint32Array(0)
83  drops: Drop[] = []
84  frame = 0
85
86  resize(columns: number, rows: number) {
87    if (columns === this.columns && rows === this.rows) return
88    this.columns = columns
89    this.rows = rows
90    this.glyphs = Uint32Array.from({ length: columns * rows }, randomGlyph)
91    this.drops = Array.from({ length: columns }, () => this.newDrop(true))
92  }
93
94  newDrop(anywhere: boolean): Drop {
95    const length = 3 + Math.floor(Math.random() * Math.max(4, this.rows * 1.5))
96
97    return {
98      head: anywhere ? Math.random() * (this.rows + length) : -Math.random() * this.rows * 2,
99      speed: 0.15 + Math.random() * 0.45,
100      length,
101    }
102  }
103
104  step() {
105    this.frame += 1
106    for (let c = 0; c < this.columns; c++) {
107      const drop = this.drops[c]!
108      drop.head += drop.speed
109      if (drop.head - drop.length > this.rows) this.drops[c] = this.newDrop(false)
110    }
111    for (let i = 0; i < this.glyphs.length; i++) {
112      if (Math.random() < 0.03) this.glyphs[i] = randomGlyph()
113    }
114  }
115
116  /** The current frame as Raster cells, with an optional line of text overlaid. */
117  cells(message?: string) {
118    const words = new Uint32Array(this.columns * this.rows * 3)
119    for (let r = 0; r < this.rows; r++) {
120      for (let c = 0; c < this.columns; c++) {
121        const i = r * this.columns + c
122        const drop = this.drops[c]!
123        const d = drop.head - r
124        let glyph = 0x20
125        let fg = DEFAULT
126        if (d >= 0 && d < 1) {
127          glyph = this.glyphs[i]!
128          fg = HEAD
129        } else if (d >= 1 && d < drop.length) {
130          glyph = this.glyphs[i]!
131          fg = fade(d / drop.length)
132        }
133        words[i * 3] = glyph
134        words[i * 3 + 1] = fg
135        words[i * 3 + 2] = BLACK
136      }
137    }
138    if (message) {
139      const row = Math.floor((this.rows - 1) / 2)
140      const start = Math.max(0, Math.floor((this.columns - message.length) / 2) - 1)
141      const padded = ` ${message} `.slice(0, this.columns)
142      for (let k = 0; k < padded.length; k++) {
143        const i = row * this.columns + start + k
144        words[i * 3] = padded.charCodeAt(k)
145        words[i * 3 + 1] = 0x00ff41
146        words[i * 3 + 2] = BLACK
147      }
148    }
149
150    return toBase64(new Uint8Array(words.buffer))
151  }
152}
153
154/** Light markdown flattening so prose can be drawn as one green Text. */
155const flatten = (text: string) =>
156  text
157    .replace(/^#{1,6}\s+/gm, '')
158    .replace(/\*\*(.+?)\*\*/g, '$1')
159    .replace(/__(.+?)__/g, '$1')
160    .replace(/`([^`]+)`/g, '$1')
161    .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1 <$2>')
162
163const isPlainProse = (text: string) => !/^\s*(```|~~~|\||>|\d+\.\s|[-*]\s\[)/m.test(text)
164
165export const register: Register = on => {
166  const rain = new Rain()
167  let bandId: string | null = null
168  let isEnabled = true
169  let introStartedAt = 0
170  let now = 0
171
172  const introText = () => {
173    const elapsed = now - introStartedAt
174    let at = 0
175    for (const line of INTRO) {
176      const typing = line.length * 90
177      const hold = 1400
178      if (elapsed < at + typing) return line.slice(0, Math.floor((elapsed - at) / 90) + 1) + '█'
179      if (elapsed < at + typing + hold) return line
180      at += typing + hold
181    }
182
183    return undefined
184  }
185
186  on('session.start', async ($, e, next) => {
187    await $.command.register({
188      name: 'matrix',
189      description: 'Toggle the Matrix look (digital rain, green transcript)',
190    })
191    isEnabled = await read($, isOn)
192    introStartedAt = now = await $.clock.now()
193    if (isEnabled) $.ui.status('◉ connected to the Matrix')
194
195    $.clock.every(70, () => {
196      now += 70
197      if (!isEnabled || bandId === null || rain.columns === 0) return
198      rain.step()
199      void $.ui.blit({ requestId: bandId, key: 'rain', cells: rain.cells(introText()) })
200    })
201
202    return next(e)
203  })
204
205  on('command.run', { command: 'matrix' }, async $ => {
206    const value = await update($, isOn, was => !was)
207    isEnabled = value
208    $.ui.status(value ? '◉ connected to the Matrix' : undefined)
209    if (value) introStartedAt = now
210
211    return { text: value ? 'Welcome back to the Matrix.' : 'You took the blue pill. The story ends.' }
212  })
213
214  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
215    if (e.props.hasSurvey || !(await read($, isOn)) || e.surface !== 'terminal') {
216      bandId = null
217      return next(e)
218    }
219    const { Raster } = $.ui.resolve(e)
220    const columns = Math.max(1, Math.min(512, e.props.bodyColumns))
221    const rows = Math.max(1, Math.min(e.props.maxRows - 1, e.props.isWorking ? 6 : 3))
222    rain.resize(columns, rows)
223    bandId = e.requestId
224
225    return <Raster key="rain" columns={columns} rows={rows} cells={rain.cells(introText())} />
226  })
227
228  on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
229    if (!(await read($, isOn)) || e.props.message !== null) return next(e)
230
231    return next({ ...e, props: { ...e.props, word: pick(SPINNER_WORDS, e.props.word) } })
232  })
233
234  on('ui.render', { component: 'TurnDuration' }, async ($, e, next) => {
235    if (!(await read($, isOn))) return next(e)
236    const { Text } = $.ui.resolve(e)
237    const seconds = Math.max(1, Math.round(e.props.durationMs / 1000))
238    const time = seconds >= 60 ? `${Math.floor(seconds / 60)}m ${seconds % 60}s` : `${seconds}s`
239
240    return (
241      <Text color={DIM_GREEN}>
242        ⌁ {pick(DONE_WORDS, e.props.word)} {time}
243      </Text>
244    )
245  })
246
247  on('ui.render', { component: 'UserMessage' }, async ($, e, next) => {
248    if (!(await read($, isOn)) || e.props.isExpanded || e.props.origin.kind !== 'composer') {
249      return next(e)
250    }
251    const { Text } = $.ui.resolve(e)
252
253    return (
254      <Text color={GREEN}>
255        <Text bold>neo@nebuchadnezzar</Text>
256        <Text color={DIM_GREEN}>:~$ </Text>
257        {e.props.text}
258      </Text>
259    )
260  })
261
262  on('ui.render', { component: 'AssistantMessage' }, async ($, e, next) => {
263    if (!(await read($, isOn)) || e.props.isSummary || !isPlainProse(e.props.text)) {
264      return next(e)
265    }
266    const { Box, Text } = $.ui.resolve(e)
267
268    return (
269      <Box flexDirection="row">
270        <Text color={GREEN}>{e.props.isFirstOfReply ? '▸ ' : '  '}</Text>
271        <Box flexDirection="column" flexShrink={1}>
272          <Text color={GREEN}>{flatten(e.props.text.trim())}</Text>
273        </Box>
274      </Box>
275    )
276  })
277}
278
types/index.d.ts 8 lines
1export type Toggle = boolean
2
3declare module 'claude-code' {
4  interface PluginState {
5    matrix: { isOn: Toggle }
6  }
7}
8