SLOPSHOPPER

droid-console

Restyles Claude Code as a Star Wars droid console: personality palettes, transmission headers, droid spinner words and a status band. /droid switches…

newbandspinnerrowscommandtoast
v0.1.0no licenseupdated 2026-10-25ikentrock/starwars-claude-mods/droid-console
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · droid-console
▶ OPERATOR fix the failing auth test and add an audit log call ╭──────────────────────────────────╮ │ droid-console │ ⏺ Read(src/auth.ts) │ Droid console online. Beep boop. │ ⎿ Read 6 lines ╰──────────────────────────────────╯ ⚙ ⟨Claude Code's own drawing⟩ ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Computed for 42s · done 4:20 PM › /droid ⎿ droid-console: Personality set to C-3PO. ✻ Computing ◉… ◉ C-3PO ░▒▓ SYSTEMS NOMINAL ▓▒░ /droid to swap personality ⟨Claude Code's own drawing⟩ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Band
◉ C-3PO ░▒▓ SYSTEMS NOMINAL ▓▒░ /droid to swap personality ⟨Claude Code's own drawing⟩
Your message
▶ OPERATOR fix the failing auth test and add an audit log call
Tool row
⚙ ⟨Claude Code's own drawing⟩
README

starwars-claude-mods

Nine local Claude Code mods (UI and hook plugins) with a light Star Wars flavor.

ModWhat it does
brain-dumpIntercepts long, unstructured prompts, asks clarifying questions, rewrites them into a structured prompt. !raw prefix skips it.
helper-deskProgress bar from the to-do list, plus a side panel for sub-agents (/helper-desk).
cache-clockPrompt-cache countdown, Keep Warm button, /keep-warm.
handoffGenerates a handoff prompt at 250k tokens, on cold cache, or on /handoff.
reflectOffers to save rules/preferences to memory, CLAUDE.md, or a second brain.
chat-inventoryZero-token "In This Chat" panel (/inventory).
switchboard/mods panel to toggle mods and hide panels.
power-cellsGauges above the prompt for context, the 5-hour limit, and a weekly pacing plan: a daily ration, work-day weighting, over/under-plan warnings. /power plan shows the week.
droid-consoleRestyles the whole UI as a droid console: personality palettes, transmission headers, droid spinner words, status band. /droid switches personality.

Status: experimental. They pass claude plugin validate and tsc, but have not been tested at runtime. Expect rough edges.

Install

Add the marketplace once, then install the mods you want (user scope makes them load in every session):

claude plugin marketplace add ikentrock/starwars-claude-mods
claude plugin install brain-dump@starwars-claude-mods --scope user
claude plugin install cache-clock@starwars-claude-mods --scope user
claude plugin install chat-inventory@starwars-claude-mods --scope user
claude plugin install droid-console@starwars-claude-mods --scope user
claude plugin install handoff@starwars-claude-mods --scope user
claude plugin install helper-desk@starwars-claude-mods --scope user
claude plugin install power-cells@starwars-claude-mods --scope user
claude plugin install reflect@starwars-claude-mods --scope user
claude plugin install switchboard@starwars-claude-mods --scope user

Or one at a time from a session prompt:

/plugin install <mod> --marketplace ikentrock/starwars-claude-mods

Update later with claude plugin marketplace update starwars-claude-mods.

Source 2 files
hooks/register.tsx 147 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { Personality } from '../types'
5
6const personality = atom(
7  { plugin: 'droid-console', key: 'personality' } as const,
8  'r2d2',
9  { shape: 'personality-1' },
10)
11
12type Look = { name: string; accent: string; user: string; ok: string; alert: string }
13
14const LOOKS: Record<Personality, Look> = {
15  r2d2: { name: 'R2-D2', accent: 'cyan', user: 'blue', ok: 'green', alert: 'red' },
16  c3po: { name: 'C-3PO', accent: 'yellow', user: 'white', ok: 'green', alert: 'red' },
17  bb8: { name: 'BB-8', accent: 'magenta', user: 'yellow', ok: 'green', alert: 'red' },
18  imperial: { name: 'IG-11', accent: 'red', user: 'white', ok: 'gray', alert: 'yellow' },
19}
20const ORDER: Personality[] = ['r2d2', 'c3po', 'bb8', 'imperial']
21
22const WORDS = {
23  requesting: 'Transmitting',
24  thinking: 'Computing',
25  responding: 'Broadcasting',
26  'tool-input': 'Calibrating',
27  'tool-use': 'Actuating',
28} as const
29
30const look = async ($: Parameters<typeof read>[0]): Promise<Look> =>
31  LOOKS[await read($, personality)]
32
33export const register: Register = on => {
34  on('session.start', async ($, e, next) => {
35    await $.command.register({
36      name: 'droid',
37      description: 'Switch the droid console personality (r2d2, c3po, bb8, imperial)',
38    })
39    $.ui.toast('Droid console online. Beep boop.')
40
41    return next(e)
42  })
43
44  on('command.run', { command: 'droid' }, async ($, e) => {
45    const wanted = String(e.args ?? '').trim().toLowerCase().replace(/[^a-z0-9]/g, '')
46    const current = await read($, personality)
47    const next = (ORDER as string[]).includes(wanted)
48      ? (wanted as Personality)
49      : (ORDER[(ORDER.indexOf(current) + 1) % ORDER.length] ?? 'r2d2')
50    await update($, personality, () => next)
51
52    return { text: `Personality set to ${LOOKS[next].name}.` }
53  })
54
55  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
56    const below = await next(e)
57
58    if (e.props.hasSurvey) {
59      return below
60    }
61
62    const { Box, Text } = $.ui.resolve(e)
63    const l = await look($)
64    const state = e.props.isWorking ? 'PROCESSING' : 'SYSTEMS NOMINAL'
65
66    return (
67      <Box flexDirection="column">
68        <Box>
69          <Text color={l.accent} bold>
70            ◉ {l.name}{' '}
71          </Text>
72          <Text color={e.props.isWorking ? l.alert : l.ok}>░▒▓ {state} ▓▒░</Text>
73          <Text dimColor> /droid to swap personality</Text>
74        </Box>
75        {below}
76      </Box>
77    )
78  })
79
80  on('ui.render', { component: 'UserMessage' }, async ($, e, next) => {
81    if (e.props.origin.kind !== 'composer') {
82      return next(e)
83    }
84
85    const { Box, Text } = $.ui.resolve(e)
86    const l = await look($)
87
88    return (
89      <Box>
90        <Text color={l.user} bold>
91          ▶ OPERATOR{' '}
92        </Text>
93        <Text>{e.props.text}</Text>
94      </Box>
95    )
96  })
97
98  on('ui.render', { component: 'AssistantMessage' }, async ($, e, next) => {
99    const drawn = await next(e)
100
101    if (!e.props.isFirstOfReply) {
102      return drawn
103    }
104
105    const { Box, Text } = $.ui.resolve(e)
106    const l = await look($)
107
108    return (
109      <Box flexDirection="column">
110        <Text color={l.accent} bold>
111          ◉ {l.name} // TRANSMISSION INCOMING
112        </Text>
113        {drawn}
114      </Box>
115    )
116  })
117
118  on('ui.render', { component: 'ToolUse' }, async ($, e, next) => {
119    const drawn = await next(e)
120    const { Box, Text } = $.ui.resolve(e)
121    const l = await look($)
122    const color = e.props.isErrored ? l.alert : e.props.isRunning ? l.accent : l.ok
123
124    return (
125      <Box>
126        <Text color={color}>⚙ </Text>
127        {drawn}
128      </Box>
129    )
130  })
131
132  on('ui.render', { component: 'Spinner' }, async ($, e, next) =>
133    next({
134      ...e,
135      props: { ...e.props, word: WORDS[e.props.mode], suffix: ' ◉' },
136    }),
137  )
138
139  on('ui.render', { component: 'TurnDuration' }, async ($, e, next) =>
140    next({ ...e, props: { ...e.props, word: 'Computed' } }),
141  )
142
143  on('ui.render', { component: 'PromptHint' }, async ($, e, next) =>
144    next({ ...e, props: { ...e.props, tail: `◉ ${(await look($)).name} console` } }),
145  )
146}
147
types/index.d.ts 8 lines
1export type Personality = 'r2d2' | 'c3po' | 'bb8' | 'imperial'
2
3declare module 'claude-code' {
4  interface PluginState {
5    'droid-console': { personality: { shape: string; value: Personality } }
6  }
7}
8