Adds a Copy Session ID button to the band above the prompt

A Claude Code mod that adds a Copy Session ID button to the band above the prompt. One click copies the current session's ID to the clipboard, the same ID that claude --resume <id> takes, and shows it in a toast.

In a Claude Code session:
/plugin install copy-session-id --marketplace aquarius-wing/copy-session-id
Or from your shell:
claude plugin marketplace add aquarius-wing/copy-session-id
claude plugin install copy-session-id@copy-session-id --scope user
If a session is already open, run /reload-plugins in it.
Requirements: Claude Code 2.1.287 or later, where mods load by default. The button shows in the terminal and in the Code tab of the Desktop app. Tested in the Desktop app's Code tab with Claude Code 2.1.295.
The mod is one hook, on ui.render for the AbovePrompt site:
next(e) first and keeps what the mods after it draw, then adds the button beside that.e.props.hasSurvey), it passes the band on untouched.$.session.id(), writes it to the clipboard of the app you pressed it in with $.ui.copy, and shows it with $.ui.toast. If the clipboard write fails, the toast still shows the ID, with the reason.It reads no files, starts no processes and makes no network requests. claude plugin validate lists everything it calls:
hooks: ui.render{component=AbovePrompt}
calls: $.session.id, $.ui.copy, $.ui.resolve, $.ui.toast
The band above the prompt is one site that every mod drawing there shares. Mods run as a chain, and the first one decides what the band shows. This mod keeps whatever the mods after it draw, so it never hides them. A mod that runs before it and returns its own line without calling next(e) hides this button, along with every other band mod after it.
If the button doesn't show while another band mod is installed:
next(e). The mods docs describe this: put the result of await next(e) in your own tree to keep what the others draw. For example, the Token Weather sample mod hides other band mods; anthropics/claude-code-playground#7 changes that.prependPlugins in ~/.claude/settings.json to run them before the other mods you install (see the mods admin docs): {
"prependPlugins": ["copy-session-id@copy-session-id"]
}
Then run /reload-plugins in each open session. To check it took, start claude --debug-file debug.log and look for hooks module copy-session-id@copy-session-id loaded (..., tier prepend). Tested with Claude Code 2.1.295 on a personal Max plan.
claude plugin validate .
claude plugin test .
The tests in hooks/register.test.ts mount the band on the terminal and Desktop surfaces with a stand-in for another band mod, press the button, and check what reaches the clipboard and the toast.
hooks/register.tsx 35 lines1import type { EngineInterface, Register, RenderSurface } from 'claude-code'
2
3async function copyId($: EngineInterface, surface: RenderSurface) {
4 const id = await $.session.id()
5 const copied = await $.ui.copy({ text: id, surface })
6 $.ui.toast(copied.isCopied ? `Copied session ID: ${id}` : `Session ID: ${id} (not copied: ${copied.reason})`)
7}
8
9export const register: Register = on => {
10 // The band above the prompt is shared by every mod that draws there. Keep what
11 // the mods after this one draw, then add the button beside it.
12 on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
13 // A survey holds the band: leave it alone.
14 if (e.props.hasSurvey) {
15 return next(e)
16 }
17
18 const { Box, Button } = $.ui.resolve(e)
19 const theirs = await next(e)
20
21 return (
22 <Box flexDirection="row" columnGap={2} alignItems="center">
23 {theirs}
24 <Button
25 key="copy-session-id-band"
26 label="Copy Session ID"
27 plain
28 dimColor
29 onPress={press => copyId($, press.surface)}
30 />
31 </Box>
32 )
33 })
34}
35