SLOPSHOPPER

frame

Adds your own operating frame (a markdown file) to the system prompt in sessions that were not launched with it.

newprompt
★ 9v0.1.0MITupdated 2026-10-09nekyialabs/claude-code-toolkit/mods/frame
A shopper browsing a rack in a slop shop
README

frame

Adds your own operating frame to the system prompt. Write the frame once as a markdown file (who the agent is, how it should work, house rules) and this mod appends it to the system prompt of every session that was not already launched with it, for example a session opened from a desktop app or a plain claude in a terminal.

The file is read once per session start and added as a session-scoped system prompt section.

Install

  1. Copy this folder somewhere permanent, for example ~/.claude/mods/frame.
  2. Load it: set CLAUDE_CODE_PLUGIN_DIRS=/path/to/frame (colon-separate several) in the environment that starts Claude Code, or pass --plugin-dir /path/to/frame.
  3. Restart Claude Code.

Configure

  • Write your frame to ~/.claude/frame.md (see frame.example.md for a starting shape), or point FRAME_FILE at another path.
  • FRAME_SKIP=1: set this in a launcher that already passes the same file with --system-prompt-file, so the frame is not added twice.

If the file is missing or empty the mod does nothing.

Validate

claude plugin validate .

Caveats

Mods (function hooks) are an early-access feature of Claude Code and may change between releases without notice. Claude Code writes the type declarations into .claude-plugin/types/ itself when it loads the mod, so they are not included here. A long frame costs tokens in every session; keep it tight.

Source 1 files
hooks/register.ts 24 lines
1import type { Register } from 'claude-code'
2
3// frame: appends a markdown file to the system prompt of sessions that were not launched with it.
4// FRAME_FILE: path to the file (default: ~/.claude/frame.md).
5// FRAME_SKIP=1: do nothing in this session (use it in a launcher that already passes the file with --system-prompt-file).
6
7let frame: string | undefined
8
9export const register: Register = on => {
10  on('prompt.compose', async ($, e, next) => {
11    const composed = await next(e)
12    if ((await $.env.get('FRAME_SKIP')) === '1') return composed
13    if (frame === undefined) {
14      try {
15        let file = await $.env.get('FRAME_FILE')
16        if (!file) file = `${(await $.env.get('HOME')) ?? ''}/.claude/frame.md`
17        frame = await $.fs.read(file)
18      } catch { frame = '' }
19    }
20    if (!frame) return composed
21    return { sections: [...composed.sections, { id: 'frame:frame', text: frame, scope: 'session' as const }] }
22  })
23}
24