Edit a persistent custom system instruction in a panel; it is given to the model at every session start, including /clear.

Claude Code plugins by @josselinonduty.
| Plugin | Description |
|---|---|
commit-changes | Band above the prompt that splits uncommitted changes into logical sections and commits them one by one or automatically, with clean canonical messages. |
secret-guard | Detects secrets in prompts and conversation rows, moves them to the project's .env file and redacts them from the history. |
prompt-library | Save past prompts to a searchable library; fuzzy search, then Copy or Apply to the prompt field. |
system-instruction | Panel (/instructions) to edit a persistent custom system instruction, given to the model at every session start, /clear included. |
/plugin marketplace add josselinonduty/claude-plugins
/plugin install commit-changes@josselinonduty-plugins
/plugin install secret-guard@josselinonduty-plugins
/plugin install prompt-library@josselinonduty-plugins
/plugin install system-instruction@josselinonduty-pluginshooks/register.tsx 104 lines1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const PANE = 'system-instruction'
5const text = atom({ plugin: 'system-instruction', key: 'text' } as const, '')
6const isEditing = atom({ plugin: 'system-instruction', key: 'isEditing' } as const, false)
7
8async function load($: any): Promise<string> {
9 const saved = await $.store.get('text')
10
11 if (typeof saved === 'string') {
12 return saved
13 }
14
15 const legacy = await $.store.get('lines')
16
17 return Array.isArray(legacy) ? legacy.map(String).join('\n') : ''
18}
19
20export const register: Register = on => {
21 on('session.start', async ($, e, next) => {
22 const saved = await load($)
23 await update($, text, () => saved)
24 await $.command.register({
25 name: 'instructions',
26 description: 'Edit the custom system instruction given to the model at every session start',
27 })
28
29 return next(e)
30 })
31
32 on('command.run', { command: 'instructions' }, async $ => {
33 const saved = await load($)
34 await update($, text, () => saved)
35 await $.ui.open({ id: PANE, title: 'Instructions', focus: true })
36
37 return { text: 'System instruction panel opened.' }
38 })
39
40 on('prompt.compose', async ($, e, next) => {
41 const result = await next(e)
42 const instruction = (await load($)).trim()
43
44 if (!instruction) {
45 return result
46 }
47
48 return {
49 sections: [
50 ...result.sections,
51 { id: 'system-instruction:text', text: instruction, scope: 'session' as const },
52 ],
53 }
54 })
55
56 on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
57 const { Box, Text, Button } = $.ui.resolve(e)
58 const current = await read($, text)
59 const editing = await read($, isEditing)
60
61 const edit = async () => {
62 const saved = await load($)
63 await $.prompt.fill({ text: saved, mode: 'replace' })
64 await update($, isEditing, () => true)
65 }
66
67 const save = async () => {
68 const box = await $.prompt.read()
69 const value = box.text.trim()
70 await $.store.set('text', value)
71 await update($, text, () => value)
72 await $.prompt.fill({ text: '', mode: 'replace' })
73 await update($, isEditing, () => false)
74 $.ui.toast('System instruction saved')
75 }
76
77 const cancel = async () => {
78 await $.prompt.fill({ text: '', mode: 'replace' })
79 await update($, isEditing, () => false)
80 }
81
82 return (
83 <Box flexDirection="column">
84 <Text bold>Initial instructions</Text>
85 {current ? <Text>{current}</Text> : <Text dimColor>Nothing set yet.</Text>}
86 {editing ? (
87 <Box flexDirection="column">
88 <Text dimColor>
89 Editing in the prompt box below (Shift+Enter for a new line). Do not press Enter to
90 send; press Save.
91 </Text>
92 <Box>
93 <Button key="save" label="Save" hotkey="s" onPress={save} />
94 <Button key="cancel" label="Cancel" hotkey="c" onPress={cancel} />
95 </Box>
96 </Box>
97 ) : (
98 <Button key="edit" label="Edit" hotkey="e" onPress={edit} />
99 )}
100 </Box>
101 )
102 })
103}
104types/index.d.ts 6 lines1declare module 'claude-code' {
2 interface PluginState {
3 'system-instruction': { text: string; isEditing: boolean }
4 }
5}
6