SLOPSHOPPER

restart-ultron-backend

A Restart backend button in a sidebar pane, active only in the ULTRON_cBrain folder.

newpanecommandprocess
★ 1v0.1.0no licenseupdated 2026-10-24erte-del/claude-mods/mods/restart-ultron-backend
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · restart-ultron-backend
│ ┃ restart-ultron-backend ✕ › fix the failing auth test and add an audit log call │ ┃ Only works in ULTRON_cBrain. │ ⏺ 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 │ │ │ │ ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Pane · restart-ultron-backend
Only works in ULTRON_cBrain.
README

claude-mods

<img width="391" height="379" alt="image" src="https://github.com/user-attachments/assets/6a3cb2d9-57cb-47e2-84c0-6cfc547499c3" />

Small mods for Claude Code: a live sidebar with one-click buttons for the things you do every session, and a repo picker. Works on Windows, macOS and Linux.

ModWhat you get
sidebarModel badge, context-window gauge, session cost, a 5-hour / weekly usage dial, and buttons for New chat, Commit & Push and Handoff
commit-pushOne click to stage, commit (with a Claude-written message) and push
handoffOne click to save a handoff.md, clear the chat, and continue from it
repoPick a GitHub repo, clone it if needed, and move the session into it
restart-ultron-backendA Restart backend button in a sidebar pane, active only in the ULTRON_cBrain folder

Install

In Claude Code:

/plugin marketplace add erte-del/claude-mods
/plugin install sidebar@claude-mods
/plugin install repo@claude-mods
/reload-plugins

Or from a terminal:

claude plugin marketplace add erte-del/claude-mods
claude plugin install sidebar@claude-mods --scope user
claude plugin install repo@claude-mods --scope user

Installing sidebar also installs commit-push and handoff, because its buttons call them. repo is separate, since it opens a picker when a session starts; skip it if you don't want that.

Start a new session or run /reload-plugins and the sidebar appears. It docks beside the transcript on terminals 110 columns or wider, and otherwise shows as a bar above the prompt.

Requirements: Claude Code and git. repo also uses the GitHub CLI (gh, signed in with gh auth login) to list your repos.

What each mod does

sidebar

Live status, redrawn after every turn:

  • the current model
  • how full the context window is
  • what the session has cost so far
  • how much of your 5-hour and weekly limits you've used, as a dial, with time until each resets

Buttons, top to bottom: + New chat runs /clear. ⇡ Commit & Push and ⇄ Handoff run the mods below. ↻ Reload plugins runs /reload-plugins.

commit-push

Click ⇡ Commit & Push, or type /commit-push.

  1. Checks the current repo. If nothing changed, it says so and stops.
  2. Stages everything (git add -A).
  3. Sends the staged diff to Claude (Haiku) for a one-line conventional-commit message such as fix: handle empty repo list in picker. If that fails it falls back to naming the changed files.
  4. Commits, then pushes. If the branch has no upstream yet, it runs git push -u origin <branch>.
  5. Shows the commit message and the result in the sidebar. A failed push shows git's own error text plus a hint (network, sign-in, rejected, protected branch).

It never force-pushes. It stops and leaves it to you when the branch is behind its upstream, there are unresolved merge conflicts, a merge or rebase is in progress, or HEAD is detached. Your files are only staged when it gets as far as committing.

It works on whatever folder the session is in, so it follows repo.

handoff

Click ⇄ Handoff, or type /handoff. Use it when your context is getting full.

  1. Asks Claude to write handoff.md in the project root: what you're doing, current state, the exact next step, decisions made, gotchas and open questions. An existing handoff.md is overwritten.
  2. Waits for the turn to finish and the file to appear.
  3. Runs /clear.
  4. Tells the fresh chat to read handoff.md and carry on from its next step.

If you interrupt, the turn errors, or Claude finishes without writing the file, it stops without clearing anything. The prompt is in mods/handoff/hooks/register.tsx if you want to change what goes in the file.

repo

Opens a picker when a session starts with no repo chosen, or type /repo.

  • Type part of a name to fuzzy-search your repos (matches on name, then description), list to see them all, then a number to pick.
  • Or type a full name, owner/repo, or a git URL.
  • It looks for an existing checkout in the usual places (~/repos, ~/Documents, ~/Desktop, ~/code, ~/projects, ~/dev, ~/src, ~/GitHub and a few more) and clones the repo if it can't find one.
  • Then it moves the session into that folder and tells Claude which repo is active.

Settings

Change these in /config (each mod's settings are listed under its name).

ModSettingDefaultWhat it does
sidebarbudgetUsd5The session cost that fills the cost bar
sidebarasciioffDraw bars with # and - and skip the dial, for terminals that can't show block characters
repoowneryour gh loginWhose repos to list: another user or an organization
repocloneDir~/reposWhere missing repos are cloned
repoopenOnStartonOpen the picker when a session starts with no active repo

Updating and removing

claude plugin marketplace update claude-mods
claude plugin uninstall sidebar@claude-mods

Each mod lives in its own folder under mods/ with its tests next to the code (claude plugin test mods/<name>).

Source 2 files
hooks/register.tsx 62 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const PANE = 'restart-ultron-backend'
5const FOLDER = 'ULTRON_cBrain'
6const status = atom({ plugin: 'restart-ultron-backend', key: 'status' } as const, 'Idle.')
7
8// Reload through launchd when autostart is on; else stop and start via the project's own scripts.
9const RESTART = `
10ROOT="$PWD"
11AGENT="gui/$(id -u)/com.ultron.backend"
12if launchctl print "$AGENT" >/dev/null 2>&1; then
13  launchctl kickstart -k "$AGENT" || exit 1
14else
15  "$ROOT/scripts/stop_ultron.sh"
16  sleep 1
17  "$ROOT/scripts/start_ultron.sh" --no-open || exit 1
18fi
19for _ in $(seq 1 60); do curl -s -m 1 http://127.0.0.1:8000/health >/dev/null 2>&1 && exit 0; sleep 0.5; done
20echo "backend did not come back on :8000" >&2; exit 1
21`
22
23const inUltron = async ($: { session: { root: () => Promise<string> } }) =>
24  (await $.session.root()).split('/').pop() === FOLDER
25
26export const register: Register = on => {
27  on('session.start', async ($, e, next) => {
28    if (await inUltron($)) {
29      await $.command.register({ name: 'restart-backend', description: 'Restart the Ultron backend' })
30      void $.ui.open({ id: PANE, title: 'Ultron' })
31    }
32    return next(e)
33  })
34
35  on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
36    const { Box, Text, Button } = $.ui.resolve(e)
37    if (!(await inUltron($))) return <Text dimColor>Only works in {FOLDER}.</Text>
38    const text = await read($, status)
39
40    return (
41      <Box flexDirection="column">
42        <Button
43          key="restart"
44          label="Restart backend"
45          onPress={async () => {
46            if (!(await inUltron($))) return
47            await update($, status, () => 'Restarting...')
48            const r = await $.process.run(['bash', '-c', RESTART], {
49              cwd: await $.session.root(),
50              timeoutMs: 90000,
51            })
52            await update($, status, () =>
53              r.exitCode === 0 ? 'Backend restarted.' : `Failed: ${r.stderr.trim().slice(-200) || r.exitCode}`,
54            )
55          }}
56        />
57        <Text dimColor>{text}</Text>
58      </Box>
59    )
60  })
61}
62
types/index.d.ts 8 lines
1export type RestartStatus = string
2
3declare module 'claude-code' {
4  interface PluginState {
5    'restart-ultron-backend': { status: RestartStatus }
6  }
7}
8