Кнопка в футере поля ввода Claude Code Desktop, копирующая в буфер обмена ссылку на текущую сессию

Marketplace модов Claude Code.
| Мод | Что делает |
|---|---|
turn-stats | Полоса над полем ввода: время работы сессии, токены (включая субагентов), квота |
pr-merge | Полоса с PR текущей ветки и кнопкой Merge через gh (настройки: mergeMethod, deleteBranch) |
session-progress | Прогресс-бар задачи сессии по todo-списку и плану модели (настройка: language) |
copy-session-link | Кнопка «🔗 Ссылка» в футере поля ввода Claude Code Desktop: копирует ссылку claude:// на текущую сессию |
visual-answer-improve | Итоговые секции ответа в цветных рамках с вкладкой-меткой: «Требуется решение» (оранжевая), «Сделано» (зелёная), «Не сделано» (мягкая красная). Правило про секции прикладывается к промптам пользователя (настройки: decisionColor, doneColor, notDoneColor) |
image-library | Панель «Библиотека» — галерея изображений (png/jpg/webp/gif/svg) из папки проекта (без папок сборки и зависимостей: node_modules, .git, Library, bin, dist, build и т. п.), папок сессий Claude Code этого проекта и Codex (~/.codex/generated_images): миниатюры, фильтр по источнику и сессии, сортировка по дате, постраничная навигация; «🔍» или имя — просмотр на всю панель с листанием, «📋 путь» — полный путь к файлу в буфер обмена, «↗» — открыть в системном приложении. Открывается кнопкой «🖼 Библиотека» в футере поля ввода или командой /library. Только Windows: сканирование и миниатюры через PowerShell и System.Drawing, кэш в %LOCALAPPDATA%\claude-image-library (настройки: includeCodex, scanLimit) |
/plugin marketplace add nerevar48/nerevar-mods
/plugin install turn-stats@nerevar-mods
/plugin install pr-merge@nerevar-mods
/plugin install session-progress@nerevar-mods
/plugin install copy-session-link@nerevar-mods
/plugin install visual-answer-improve@nerevar-mods
/plugin install image-library@nerevar-mods
Или в ~/.claude/settings.json:
"extraKnownMarketplaces": {
"nerevar-mods": { "source": { "source": "github", "repo": "nerevar48/nerevar-mods" } }
},
"enabledPlugins": {
"turn-stats@nerevar-mods": true,
"pr-merge@nerevar-mods": true,
"session-progress@nerevar-mods": true,
"copy-session-link@nerevar-mods": true,
"visual-answer-improve@nerevar-mods": true,
"image-library@nerevar-mods": true
}hooks/register.tsx 66 lines1import type { EngineInterface, Register, RenderSurface, UiPressArgument } from 'claude-code'
2
3// Ссылка, которой Claude Code Desktop открывает свою сессию по её id.
4const LINK_PREFIX = 'claude://claude.ai/epitaxy/'
5
6// Буфер обмена машины, где запущен Desktop (Windows или macOS): $.ui.copy на
7// удалённой поверхности (desktop) в буфер не пишет.
8const CLIPBOARD_COMMANDS: readonly (readonly string[])[] = [['clip.exe'], ['pbcopy']]
9
10async function copyWithSystemTool($: EngineInterface, text: string): Promise<boolean> {
11 for (const argv of CLIPBOARD_COMMANDS) {
12 try {
13 const { exitCode } = await $.process.run(argv, { stdin: text, timeoutMs: 5000 })
14
15 if (exitCode === 0) {
16 return true
17 }
18 } catch {
19 // Утилиты нет на этой платформе: пробуем следующую.
20 }
21 }
22
23 return false
24}
25
26async function copyLink($: EngineInterface, link: string, surface: RenderSurface): Promise<void> {
27 const isCopied =
28 (await copyWithSystemTool($, link)) ||
29 (await $.ui.copy({ text: link, surface }).then(copied => copied.isCopied, () => false))
30
31 if (isCopied) {
32 $.ui.toast('Ссылка на сессию скопирована')
33 } else {
34 $.ui.toast(`Не удалось скопировать: ${link}`)
35 }
36}
37
38export const register: Register = on => {
39 // Метки режимов в футере поля ввода: на десктопе это строка рядом с выбором модели.
40 on('ui.render', { component: 'SessionMode' }, async ($, e, next) => {
41 // Id сессии приложения; вне Claude Code Desktop его нет, и ссылки тоже.
42 const hostSessionId = await $.env.get('CLAUDE_CODE_HOST_SESSION_ID')
43
44 if (!hostSessionId) {
45 return next(e)
46 }
47
48 const link = LINK_PREFIX + hostSessionId
49 // То, что рисуют хуки ниже (метки режимов, кнопки других модов), остаётся рядом.
50 const below = await next(e)
51 const { Box, Button } = $.ui.resolve(e)
52
53 return (
54 <Box flexDirection="row" alignItems="center" gap={1}>
55 <Button
56 key="copy-session-link"
57 plain
58 label="🔗 Ссылка"
59 onPress={(press: UiPressArgument) => copyLink($, link, press.surface)}
60 />
61 {below}
62 </Box>
63 )
64 })
65}
66