Pinning a session turns on its Remote Control once machine-tag has put the machine icon in the title, so it shows by name and icon on every other computer and…

Private Claude Code marketplace for Tuncer's mods: function-hook plugins that run inside every Claude Code session on his machines (MacBook Pro, MacBook Air, therig, the 5090 PC, the 4090 work PC).
| Plugin | What it does |
|---|---|
memory-guards | Refuses the footgun commands Claude's memory notes warn about (for example impeccable update --help, routing shiftyeyegames.com DNS through cloudflared, /logout before cswap add) and says why, with the safe alternative. |
kb-health | Shows KB health in the status line on the machine that runs the KB. It stays quiet on machines without the KB snapshot job. |
machine-tag | Prefixes session titles with the machine's emoji tag (💻 MBP, 🪶 Air, 🎮 Rig, 🔥 5090, ⚡ 4090), so pinned sessions show which computer they run on. /machine-tag <emoji> <word> overrides it per machine. |
pin-everywhere | Pinning a session turns on its Remote Control once machine-tag has put the machine icon in the title, so the session shows by name and icon on every other computer and the phone. Unpinning turns it back off when this mod turned it on. A title is published when Remote Control connects, so after renaming a pinned session, unpin and pin it again to publish the new name. |
claude plugin marketplace add Shifty-Eye-Games/claude-mods
claude plugin install memory-guards@claude-mods
claude plugin install kb-health@claude-mods
claude plugin install machine-tag@claude-mods
claude plugin install pin-everywhere@claude-mods
Then turn on auto-update: in /plugin, open Marketplaces, pick claude-mods and enable auto-update, or set it in ~/.claude/settings.json:
"extraKnownMarketplaces": {
"claude-mods": {
"source": { "source": "github", "repo": "Shifty-Eye-Games/claude-mods" },
"autoUpdate": true
}
}
Each session start then pulls main. No versions are set, so every commit is an update.
The repo is private, so each machine needs GitHub access without a prompt: an SSH key GitHub knows (Claude Code tries ssh -T git@github.com first), or stored HTTPS credentials (gh auth login then gh auth setup-git, or Git Credential Manager on Windows). Without them the clone and the updates fail silently and the machine keeps its last copy.
Machines that loaded these mods from local folders before must drop those folders from CLAUDE_CODE_PLUGIN_DIRS in ~/.claude/settings.json, or each mod loads twice.
plugins/<name>/.claude plugin validate plugins/<name> and claude plugin test plugins/<name>.main. Versions are left unset on purpose, so each commit reaches every machine at its next session start.How mods work, and the engine rules that bite, are in Claude's memory note on Claude Code mods.
Auto-update is on, so whatever lands on main runs in every session on all four machines. Only org admins can push here (the org's default member permission is read). Keep it that way: never give anyone else write access.
hooks/register.ts 140 lines1import type { EngineInterface, Register } from 'claude-code'
2
3// Pinning a session in the desktop app turns on its Remote Control, so the session shows on every other
4// computer signed in to the same account (and the phone) with its title, machine icon included. Remote Control
5// fixes the title it publishes when it connects, so the mod waits until machine-tag has put the machine's tag
6// in the title before connecting. Unpinning turns Remote Control off again, but only when this mod turned it on.
7//
8// It acts on changes only (a pin or an unpin it has not seen yet), so turning Remote Control off by hand on a
9// pinned session is left alone. To publish a later rename, unpin and pin again.
10const PLUGIN = 'pin-everywhere'
11const GET = 'mcp__ccd_session_mgmt__get_session'
12const SET_RC = 'mcp__ccd_session_mgmt__set_remote_control'
13const TICK_MS = 2 * 60_000
14const TAGGED = /^\p{Extended_Pictographic}(?:️|\p{Extended_Pictographic}|[\u{1F3FB}-\u{1F3FF}])* \S+ · /u
15
16type Info = { id: string; title: string; pinned: boolean; rc: string; fromRemote: boolean }
17// One store key per app session ("rc:<id>"), written only for pinned sessions: what the mod last saw and
18// whether it was the one that turned Remote Control on.
19type Seen = { pinned: boolean; owned: boolean }
20
21const state = { busy: false, warned: false, timer: undefined as { cancel: () => void } | undefined }
22
23function parse(text: string | undefined): Record<string, unknown> | undefined {
24 try {
25 const value = JSON.parse(text ?? '')
26 return value && typeof value === 'object' ? (value as Record<string, unknown>) : undefined
27 } catch {
28 return undefined
29 }
30}
31
32async function readSelf($: EngineInterface): Promise<Info | undefined> {
33 const verdict = await $.tool.check({ tool: GET, input: { session_id: 'self' } } as never).catch(() => undefined)
34 if (verdict?.decision !== 'allow') {
35 return undefined
36 }
37 const got = await $.tool.call({ tool: GET, session_id: 'self' } as never).catch(() => undefined)
38 const row = parse(got?.text)
39 if (!row || typeof row.sessionId !== 'string') {
40 return undefined
41 }
42
43 return {
44 id: row.sessionId,
45 title: typeof row.title === 'string' ? row.title : '',
46 pinned: row.pinned === true,
47 rc: typeof row.remoteControlState === 'string' ? row.remoteControlState : '',
48 fromRemote: row.startedViaRemoteControl === true,
49 }
50}
51
52// Resolves to the state the app reports afterwards, or undefined when the call was refused or failed.
53async function setRemoteControl($: EngineInterface, enabled: boolean): Promise<string | undefined> {
54 const done = await $.tool.call({ tool: SET_RC, session_id: 'self', enabled } as never).catch(() => undefined)
55 const row = parse(done?.text)
56
57 return typeof row?.remoteControlState === 'string' ? row.remoteControlState : undefined
58}
59
60async function sync($: EngineInterface): Promise<void> {
61 if (state.busy) {
62 return
63 }
64 state.busy = true
65 try {
66 const me = await readSelf($)
67 // Only explicit states: 'connecting' means wait; 'unavailable' or a missing field means this app can't.
68 if (!me || me.fromRemote || (me.rc !== 'on' && me.rc !== 'off')) {
69 return
70 }
71 const key = `rc:${me.id}`
72 const raw = await $.store.get(key)
73 const seen: Seen | undefined = raw && typeof raw === 'object' ? (raw as Seen) : undefined
74 const wasPinned = seen?.pinned === true
75
76 if (me.pinned && !wasPinned) {
77 if (me.rc === 'on') {
78 await $.store.set(key, { pinned: true, owned: false })
79 } else if (TAGGED.test(me.title)) {
80 const after = await setRemoteControl($, true)
81 const ok = after === 'on' || after === 'connecting'
82 await $.store.set(key, { pinned: true, owned: ok })
83 if (!ok && !state.warned) {
84 state.warned = true
85 $.ui.toast('pin-everywhere: Remote Control could not be turned on for this pinned session.')
86 }
87 }
88 // Not tagged yet: wait, so the title Remote Control publishes already carries the machine icon.
89 return
90 }
91 if (!me.pinned && wasPinned) {
92 if (seen?.owned && me.rc === 'on') {
93 await setRemoteControl($, false)
94 }
95 await $.store.delete(key)
96 return
97 }
98 // Still pinned, and the person turned Remote Control off by hand: stop owning it, never turn it back on.
99 if (me.pinned && seen?.owned && me.rc === 'off') {
100 await $.store.set(key, { pinned: true, owned: false })
101 }
102 } finally {
103 state.busy = false
104 }
105}
106
107function startTicking($: EngineInterface) {
108 state.timer?.cancel()
109 state.timer = $.clock.every(TICK_MS, () => void sync($))
110}
111
112export const register: Register = on => {
113 // The mod's own Remote Control calls on this session need no prompt; anything else (the model's calls,
114 // another session's id) goes to the normal permission decision.
115 on('tool.check', { tool: SET_RC }, async ($, e, next) => {
116 const input = (e.input ?? {}) as { session_id?: unknown }
117 const mine = next.origin.plugin === PLUGIN || next.origin.plugin.startsWith(`${PLUGIN}@`)
118 if (mine && input.session_id === 'self') {
119 return { decision: 'allow', reason: 'pin-everywhere: Remote Control for this pinned session' }
120 }
121
122 return next(e)
123 })
124
125 on('session.start', async ($, e, next) => {
126 const ran = await next(e)
127 startTicking($)
128
129 return ran
130 })
131
132 // After each turn, outside the prompt's dispatch.
133 on('turn.complete', async ($, e, next) => {
134 const ran = await next(e)
135 $.clock.after(0, () => void sync($))
136
137 return ran
138 })
139}
140