SLOPSHOPPER

context-handoff

Warns near context limits and builds a /handoff snippet for a fresh session.

newbandcommandtoast
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · context-handoff
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ Read 6 lines ⏺ Update(src/auth.ts) ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /handoff ⎿ context-handoff: HANDOFF SNIPPET ⎿ context-handoff: cwd: (session) ⎿ context-handoff: context: 49% ⎿ context-handoff: Continue from the current task. Prefer existing plans and open files. Do not re-read huge trees unless needed. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts
README

context-handoff

Warns near context limits and builds a /handoff snippet for a fresh session.

Install

claude plugin marketplace add kenhuangus/claude-code-mods-pack
claude plugin install context-handoff@kenhuang-mods
Source 2 files
hooks/context-handoff.mjs 44 lines
1const META = { plugin: "context-handoff", key: "meta" };
2const THRESHOLD = 80;
3export function register(on) {
4  on("session.start", async ($, e, next) => {
5    const r = await next(e);
6    await $.state.set(META, { percent: 0, warned: false });
7    await $.command.register({ name: "handoff", description: "Package a concise handoff snippet for a new chat" });
8    return r;
9  });
10  on("turn.complete", async ($, e, next) => {
11    const r = await next(e);
12    if (e.agentId) return r;
13    const usage = await $.session.usage();
14    const percent = usage?.context?.percent ?? 0;
15    const { value: meta } = await $.state.get(META);
16    const warned = percent >= THRESHOLD;
17    await $.state.set(META, { ...(meta || {}), percent, warned });
18    if (warned) {
19      try { await $.ui.toast(`Context ${percent}% — run /handoff soon`); } catch {}
20    }
21    return r;
22  });
23  on("command.run", { command: "handoff" }, async ($) => {
24    const usage = await $.session.usage();
25    const percent = usage?.context?.percent ?? 0;
26    const snippet = [
27      "HANDOFF SNIPPET",
28      "cwd: (session)",
29      `context: ${percent}%`,
30      "Continue from the current task. Prefer existing plans and open files. Do not re-read huge trees unless needed.",
31    ].join("\n");
32    const { value: meta } = await $.state.get(META);
33    await $.state.set(META, { ...(meta || { warned: false }), percent, handoff: snippet });
34    return { text: snippet };
35  });
36  on("ui.render", { component: "AbovePrompt" }, async ($, e, next) => {
37    if (e.props?.hasSurvey) return next(e);
38    const { value: meta } = await $.state.get(META);
39    if (!meta?.warned) return next(e);
40    const { Box, Text } = $.ui.resolve(e);
41    return Box({ paddingX: 1, children: [Text({ color: "magenta", bold: true, children: `CONTEXT ${meta.percent}% — /handoff` })] });
42  });
43}
44
types/index.d.ts 8 lines
1declare module "claude-code" {
2  interface PluginState {
3    "context-handoff": {
4      meta: { percent: number; warned: boolean; handoff?: string };
5    };
6  }
7}
8