1
TOOLS#e85c04aa
Claude Code Cache Prompt Management Playbook
@Owner·deposited 3w ago·updated 2w ago·161 views
TOOLS#e85c04aa
Claude Code Cache Prompt Management Playbook
OW
@Owner
161Views
0Comments
2Forks
0Saves
SHARE · REMIX
Claude Code Cache Prompt Management Playbook — a HTML Tools widget by @Owner.
CONTROLS
No comments yet. Be the first!
✦ Remix with AI
SDK in this widget
vibes.onReadyvibes.savevibes.load
- localStorage: localStorage detected. Prefer vibes.save/load for per-user persistence.
Generated prompt
You are helping me modify a vibe-coded widget from itjustvibes.com.
[VIBE CODE: "Claude Code Cache Prompt Management Playbook" by @Owner]
Source: https://itjustvibes.com/Owner/claude-code-cache-prompt-management-playbook
Type: HTML
--- SOURCE CODE ---
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Claude Code Cache Prompt Management Playbook</title>
<style>
:root{
--bg:#0b0f17;--panel:#151c29;--panel2:#1d2636;--ink:#eef4ff;--muted:#aab6cc;
--line:#2c3850;--good:#40d493;--warn:#ffd166;--bad:#ff6b6b;--blue:#7aa2ff;--purple:#c9a0ff;
--shadow:0 18px 55px rgba(0,0,0,.35);--radius:18px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:
radial-gradient(circle at 5% 0%,rgba(122,162,255,.22),transparent 30%),
radial-gradient(circle at 95% 0%,rgba(201,160,255,.16),transparent 34%),
linear-gradient(180deg,#090c12,#0d1119 45%,#07090e);color:var(--ink);line-height:1.45}
a{color:#a8c0ff}
code{background:#070a10;border:1px solid #29354a;padding:1px 5px;border-radius:7px}
.wrap{max-width:1180px;margin:auto;padding:22px}
.hero{display:grid;grid-template-columns:1.25fr .75fr;gap:18px}
.card{background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.02));border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
.heroMain{padding:28px;overflow:hidden}
.badge{display:inline-flex;gap:8px;align-items:center;border:1px solid rgba(122,162,255,.35);background:rgba(122,162,255,.1);color:#d5e2ff;border-radius:999px;padding:7px 11px;font-size:13px}
h1{font-size:clamp(34px,5vw,62px);line-height:.96;margin:18px 0 12px;letter-spacing:-.055em}
h2{font-size:30px;margin:6px 0 12px;letter-spacing:-.03em}
h3{font-size:20px;margin:8px 0 8px}
p{color:var(--muted)}
.lead{font-size:18px;max-width:780px}
.small{font-size:13px;color:var(--muted)}
.heroSide{padding:20px;display:flex;flex-direction:column;gap:12px}
.metric{padding:15px;border-radius:15px;background:rgba(255,255,255,.035);border:1px solid var(--line)}
.metric b{display:block;font-size:25px}.metric span{color:var(--muted);font-size:13px}
.nav{position:sticky;top:0;z-index:5;margin:18px 0;padding:10px;display:flex;gap:8px;flex-wrap:wrap;background:rgba(11,15,23,.84);backdrop-filter:blur(16px);border:1px solid var(--line);border-radius:22px}
.nav a{border:0;border-radius:999px;padding:10px 14px;background:transparent;color:var(--muted);cursor:pointer;text-decoration:none;display:inline-flex}
.nav a.active,.nav a:hover{background:var(--panel2);color:var(--ink)}
.section{scroll-margin-top:92px;margin-bottom:16px}
.js .section{display:none}
.js .section.active{display:block}
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}
.span4{grid-column:span 4}.span5{grid-column:span 5}.span6{grid-column:span 6}.span7{grid-column:span 7}.span8{grid-column:span 8}.span12{grid-column:span 12}
.box{padding:20px}
.pill{display:inline-flex;padding:5px 9px;border-radius:999px;border:1px solid var(--line);font-size:12px;color:#c9d5ea;margin:3px;background:rgba(255,255,255,.03)}
.good{color:var(--good)}.warn{color:var(--warn)}.bad{color:var(--bad)}.blue{color:var(--blue)}
.rule{border-left:4px solid var(--blue);padding:12px 14px;background:rgba(122,162,255,.08);border-radius:12px;margin:10px 0}
.goodline{border-left-color:var(--good);background:rgba(64,212,147,.08)}
.warnline{border-left-color:var(--warn);background:rgba(255,209,102,.08)}
.badline{border-left-color:var(--bad);background:rgba(255,107,107,.08)}
.layer{display:grid;grid-template-columns:150px 1fr 150px;gap:10px;align-items:center;margin:10px 0;padding:13px;border-radius:14px;background:rgba(255,255,255,.035);border:1px solid var(--line)}
.layer .tag{font-weight:800}.bar{height:18px;border-radius:999px;background:linear-gradient(90deg,var(--blue),var(--purple));opacity:.95}.bar.b2{width:82%}.bar.b3{width:62%}.status{text-align:right;font-size:13px}
.codeWrap{position:relative}
.code{background:#070a0f;border:1px solid #283246;border-radius:14px;padding:44px 14px 14px;white-space:pre-wrap;color:#dfe8ff;overflow:auto;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;min-height:110px}
.copy{position:absolute;right:9px;top:9px;border:1px solid var(--line);background:#192236;color:#dfe8ff;border-radius:10px;padding:7px 10px;cursor:pointer;font-size:12px}
.copy:hover{background:#24314a}
.example{display:none}.example.active{display:block}
.tabbar{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0 14px}
.tabbar button,.btn{border:1px solid var(--line);background:rgba(255,255,255,.025);color:var(--muted);border-radius:999px;padding:9px 12px;cursor:pointer}
.tabbar button.active,.btn:hover{background:rgba(122,162,255,.18);color:white;border-color:rgba(122,162,255,.5)}
.choice{display:flex;gap:10px;align-items:flex-start;padding:12px;border:1px solid var(--line);border-radius:14px;margin:8px 0;background:rgba(255,255,255,.025);cursor:pointer}
.choice input{margin-top:3px}.score{font-size:48px;font-weight:900;letter-spacing:-.055em}
textarea{width:100%;min-height:130px;border-radius:14px;border:1px solid var(--line);background:#090d14;color:var(--ink);padding:12px}
.table{width:100%;border-collapse:collapse;overflow:hidden;border-radius:14px}
.table th,.table td{border-bottom:1px solid var(--line);padding:12px;text-align:left;vertical-align:top}
.table th{color:#dce6ff;background:rgba(255,255,255,.04)}
.table td{color:var(--muted)}
.ref{padding:12px;border:1px solid var(--line);border-radius:14px;margin:10px 0;background:rgba(255,255,255,.025)}
.notice{display:none;margin:12px 0;padding:10px 12px;border-radius:12px;border:1px solid rgba(255,209,102,.45);background:rgba(255,209,102,.08);color:#ffe1a0;font-size:13px}
.no-js{margin:12px 0;padding:10px 12px;border-radius:12px;border:1px solid rgba(255,209,102,.45);background:rgba(255,209,102,.08);color:#ffe1a0;font-size:13px}
.js .no-js{display:none}
.footer{margin:24px 0;color:var(--muted);font-size:13px}
@media(max-width:850px){
.hero{grid-template-columns:1fr}.grid{display:block}.card{margin-bottom:14px}.layer{grid-template-columns:1fr}.status{text-align:left}
}
</style>
<script>
document.documentElement.className += " js";
</script>
</head>
<body>
<div class="wrap">
<div class="hero">
<div class="card heroMain">
<span class="badge">⚡ Claude Code cache prompt management • beginner mode</span>
<h1>Keep Claude Code fast, cheap, and focused.</h1>
<p class="lead">This app explains prompt caching like you have no development background. It gives you a practical workflow, copy-paste prompts, constraints, and edge cases for Claude Code.</p>
<p class="small">This version uses anchor navigation as a fallback. If JavaScript is blocked, every section remains visible instead of becoming unusable.</p>
<div id="scriptNotice" class="notice"></div>
<noscript><div class="no-js">JavaScript is disabled. The app is still readable, but tab switching, copy buttons, notes, and the simulator require JavaScript.</div></noscript>
</div>
<div class="card heroSide">
<div class="metric"><b>Prefix</b><span>The exact beginning of the request Claude already processed.</span></div>
<div class="metric"><b>Cache hit</b><span>Claude reuses that prefix instead of reading it from scratch.</span></div>
<div class="metric"><b>Cache miss</b><span>Something changed early enough that Claude must rebuild.</span></div>
</div>
</div>
<nav class="nav" aria-label="App sections">
<a class="active" href="#learn" data-section="learn">1. Learn</a>
<a href="#workflow" data-section="workflow">2. Workflow</a>
<a href="#examples" data-section="examples">3. Copy prompts</a>
<a href="#simulator" data-section="simulator">4. Simulator</a>
<a href="#edgecases" data-section="edgecases">5. Edge cases</a>
<a href="#notes" data-section="notes">6. Notes</a>
<a href="#refs" data-section="refs">References</a>
</nav>
<main>
<section id="learn" class="section active">
<div class="grid">
<div class="card box span7">
<h2>The no-dev explanation</h2>
<p>Imagine Claude Code has to reread a giant binder every time you ask a question: system instructions, tool list, project rules, files it already read, chat history, and your new request. Prompt caching is like saying, "The first part of this binder is identical to last time, so reuse it."</p>
<div class="rule goodline"><b class="good">Good:</b> Keep the beginning of the session stable. Pick your model, connect MCP servers, choose output style, and load project rules at the start.</div>
<div class="rule warnline"><b class="warn">Careful:</b> New messages are fine because they are added at the end. Cache usually breaks when something changes near the beginning, like model, tools, or system prompt.</div>
<div class="rule badline"><b class="bad">Bad:</b> Switching models, changing MCP tool availability, or compacting mid-task can cause slower or more expensive turns while the cache rebuilds.</div>
</div>
<div class="card box span5">
<h2>One sentence rule</h2>
<p><b>Cache loves boring consistency.</b> Set up the session once, then keep working in the same lane until a natural break.</p>
<span class="pill">Start stable</span><span class="pill">Work in one task lane</span><span class="pill">Compact at breaks</span><span class="pill">Use subagents for side quests</span><span class="pill">Clear between unrelated tasks</span>
</div>
<div class="card box span12">
<h2>The request stack Claude Code sends</h2>
<p>Claude Code sends context every turn. The cache works by exact prefix matching, so earlier layers are more sensitive than later layers.</p>
<div class="layer"><div class="tag">System prompt</div><div class="bar"></div><div class="status bad">Most sensitive</div></div>
<div class="layer"><div class="tag">Project context</div><div class="bar b2"></div><div class="status warn">Loaded at start</div></div>
<div class="layer"><div class="tag">Conversation</div><div class="bar b3"></div><div class="status good">Appends normally</div></div>
<p class="small">Plain English: changing "rules of the game" is expensive. Adding another normal message is expected.</p>
</div>
</div>
</section>
<section id="workflow" class="section">
<div class="grid">
<div class="card box span6">
<h2>Before you start Claude Code</h2>
<table class="table">
<tr><th>Do this</th><th>Why it helps cache/context</th></tr>
<tr><td>Open the correct repo folder first.</td><td>Starting in the right place avoids rebuilding around a different project context.</td></tr>
<tr><td>Pick the model once.</td><td>Each model has its own cache. Switching models forces a fresh read.</td></tr>
<tr><td>Connect MCP servers before serious work.</td><td>Tool definitions affect the system prompt. Changing tool availability mid-session can invalidate cache.</td></tr>
<tr><td>Check <code>CLAUDE.md</code> and auto memory.</td><td>Project rules and memories load at session start. Stable, concise memory reduces repeated explanations.</td></tr>
<tr><td>Choose output style before the session matters.</td><td>Output style is part of the system prompt and loads at session start.</td></tr>
</table>
</div>
<div class="card box span6">
<h2>While working</h2>
<table class="table">
<tr><th>Habit</th><th>Use it when</th></tr>
<tr><td><code>/usage</code> or a status line</td><td>You want to know whether cache reads are high and creation tokens are low.</td></tr>
<tr><td><code>/recap</code></td><td>You want a session summary without replacing history.</td></tr>
<tr><td><code>/compact Focus on...</code></td><td>You reached a natural break and want a smaller conversation going forward.</td></tr>
<tr><td><code>/clear</code></td><td>You are switching to an unrelated task and stale context would confuse Claude.</td></tr>
<tr><td>Subagents</td><td>You need research, logs, or file digging that would pollute your main conversation.</td></tr>
</table>
</div>
<div class="card box span12">
<h2>The simple decision tree</h2>
<div class="rule goodline"><b>Same task?</b> Keep going. Do not switch model or MCP tools.</div>
<div class="rule warnline"><b>Side investigation?</b> Use a subagent so the main context stays clean.</div>
<div class="rule warnline"><b>Long conversation but still same project?</b> Use <code>/compact</code> at a clean checkpoint and tell Claude what to preserve.</div>
<div class="rule badline"><b>Completely different task?</b> Use <code>/rename</code>, then <code>/clear</code>, then start clean.</div>
</div>
</div>
</section>
<section id="examples" class="section">
<div class="card box">
<h2>Copy-paste prompt library</h2>
<p>Use these directly in Claude Code. They are written for someone who does not want to think about cache mechanics every time.</p>
<div class="tabbar" aria-label="Prompt examples">
<button type="button" class="active" data-ex="ex1">Session start</button>
<button type="button" data-ex="ex2">CLAUDE.md</button>
<button type="button" data-ex="ex3">Compact</button>
<button type="button" data-ex="ex4">Cache debug</button>
<button type="button" data-ex="ex5">Subagent</button>
<button type="button" data-ex="ex6">MCP check</button>
</div>
<div id="ex1" class="example active">
<h3>Stable session start prompt</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex1">Copy</button><div class="code" id="copy-ex1">Before changing files, orient yourself to this repo.
1. Read the top-level README, package/config files, and CLAUDE.md if present.
2. Summarize the project in beginner-friendly language.
3. Identify the main folders and how the app runs.
4. Tell me what assumptions you are making.
5. Do not switch models, change MCP tools, or compact unless I ask.</div></div>
</div>
<div id="ex2" class="example">
<h3>Add durable project rules to CLAUDE.md</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex2">Copy</button><div class="code" id="copy-ex2">Add a concise section to CLAUDE.md called "Context management rules".
Include:
- Start by reading this file before making major changes.
- Prefer targeted file reads over scanning huge folders.
- Use subagents for broad research or log digging.
- Ask before changing MCP configuration, model, or output style.
- When compacting, preserve architecture decisions, commands that worked, unresolved blockers, and file paths changed.
Keep it short and specific.</div></div>
</div>
<div id="ex3" class="example">
<h3>Safe compaction prompt</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex3">Copy</button><div class="code" id="copy-ex3">/compact Preserve only the information needed to continue this implementation:
- Current goal and acceptance criteria
- Files changed and why
- Commands that worked or failed
- Important design decisions
- Known bugs, blockers, and next steps
- Any user preferences or constraints I explicitly gave you
Discard dead-end exploration, repeated logs, and irrelevant discussion.</div></div>
</div>
<div id="ex4" class="example">
<h3>Cache performance troubleshooting</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex4">Copy</button><div class="code" id="copy-ex4">Help me diagnose whether this Claude Code session is wasting context or breaking cache.
Check for:
- Recent model switches
- MCP server connect/disconnect events
- broad deny rules like Bash or WebFetch
- unnecessary compaction
- repeated large file reads
- stale or oversized CLAUDE.md content
- unrelated tasks mixed into this session
Give me a simple "keep / compact / clear / restart" recommendation.</div></div>
</div>
<div id="ex5" class="example">
<h3>Subagent prompt for a side quest</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex5">Copy</button><div class="code" id="copy-ex5">Use a subagent for this research so the main conversation stays clean.
Task:
Find the files and code paths related to [FEATURE].
Return only:
- 5-10 most relevant files
- short explanation of how they connect
- risks or confusing parts
- recommended next implementation step
Do not dump long file contents into the main conversation.</div></div>
</div>
<div id="ex6" class="example">
<h3>MCP stability checklist prompt</h3>
<div class="codeWrap"><button type="button" class="copy" data-copy="copy-ex6">Copy</button><div class="code" id="copy-ex6">Before we continue, check whether my MCP setup is stable for this task.
Tell me:
- Which MCP tools you can currently see
- Which ones are actually needed
- Whether any tool/server changes would likely disrupt cache
- Whether I should restart now or leave everything alone
Do not modify MCP settings unless I explicitly approve.</div></div>
</div>
</div>
</section>
<section id="simulator" class="section">
<div class="grid">
<div class="card box span7">
<h2>Cache warmth simulator</h2>
<p>Select actions you plan to take during a Claude Code session. The app estimates whether your next turn stays warm or likely rebuilds cache.</p>
<label class="choice"><input type="checkbox" data-impact="10"><span>Continue same task and ask another targeted question.</span></label>
<label class="choice"><input type="checkbox" data-impact="-35"><span>Switch models with <code>/model</code> mid-session.</span></label>
<label class="choice"><input type="checkbox" data-impact="-30"><span>Connect/disconnect an MCP server while working.</span></label>
<label class="choice"><input type="checkbox" data-impact="-20"><span>Run <code>/compact</code> in the middle of a task.</span></label>
<label class="choice"><input type="checkbox" data-impact="8"><span>Use <code>/recap</code> for a summary.</span></label>
<label class="choice"><input type="checkbox" data-impact="10"><span>Use a subagent for broad research.</span></label>
<label class="choice"><input type="checkbox" data-impact="-12"><span>Edit CLAUDE.md and expect it to apply immediately.</span></label>
<label class="choice"><input type="checkbox" data-impact="5"><span>Edit source files normally and let Claude reread only what it needs.</span></label>
</div>
<div class="card box span5">
<h2>Result</h2>
<div id="score" class="score">100</div>
<div id="scoreLabel" class="pill good">Warm</div>
<p id="scoreText">Your session is stable. Keep going in the same lane.</p>
<button type="button" class="btn" id="resetSim">Reset</button>
</div>
</div>
</section>
<section id="edgecases" class="section">
<div class="card box">
<h2>Constraints and edge cases</h2>
<table class="table">
<tr><th>Situation</th><th>What actually happens</th><th>Beginner takeaway</th></tr>
<tr><td>Editing <code>CLAUDE.md</code> mid-session</td><td>Does not usually invalidate cache, but the new content also does not apply until <code>/clear</code>, <code>/compact</code>, or restart.</td><td>Edit it before the session matters, or restart after major changes.</td></tr>
<tr><td>Changing output style</td><td>It is part of the system prompt and is read at session start; a change applies after <code>/clear</code> or a new session.</td><td>Pick your style up front.</td></tr>
<tr><td>Switching models</td><td>Each model has its own cache.</td><td>Do not bounce between models unless the cold turn is worth it.</td></tr>
<tr><td>MCP server changes</td><td>Tool definitions affect the system prompt layer.</td><td>Connect needed servers first; avoid unstable tool lists mid-task.</td></tr>
<tr><td>File edits</td><td>Editing a file does not rewrite old conversation history. Claude rereads changed files when needed.</td><td>Normal coding is fine. The issue is changing session structure, not editing code.</td></tr>
<tr><td><code>/compact</code></td><td>Replaces history with a summary, so the old conversation prefix changes.</td><td>Compact at natural breaks and tell Claude what to preserve.</td></tr>
<tr><td><code>/recap</code></td><td>Generates a displayed summary without replacing the conversation history.</td><td>Use it when you just need a status summary.</td></tr>
<tr><td>Subagents</td><td>They run in their own context/cache and return summaries to the parent session.</td><td>Great for research that would clutter the main thread.</td></tr>
<tr><td>Subscription vs API key</td><td>Claude subscription sessions can use one-hour TTL automatically; API/third-party defaults are usually five minutes unless configured.</td><td>On API usage, long breaks can cool the cache faster.</td></tr>
<tr><td>Privacy/local transcripts</td><td>Claude Code can store local session transcripts in plaintext under <code>~/.claude/projects/</code> by default for resumption.</td><td>Be careful with sensitive projects and retention settings.</td></tr>
</table>
</div>
</section>
<section id="notes" class="section">
<div class="grid">
<div class="card box span6">
<h2>Your project cache notes</h2>
<p>This scratchpad saves in this browser. If hosted in an environment with <code>window.vibes.save/load</code>, it uses that; otherwise it falls back to localStorage.</p>
<textarea id="notesBox" placeholder="Example: Start in repo root, use Sonnet, keep MCP stable, compact after feature phases..."></textarea>
<p><button type="button" class="btn" id="saveNotes">Save notes</button> <button type="button" class="btn" id="clearNotes">Clear</button></p>
<p id="saveStatus" class="small"></p>
</div>
<div class="card box span6">
<h2>Personal checklist</h2>
<div class="rule goodline">□ I picked the correct repo folder.</div>
<div class="rule goodline">□ I chose the model I plan to use for this session.</div>
<div class="rule goodline">□ MCP servers are connected and stable.</div>
<div class="rule goodline">□ CLAUDE.md is short, specific, and current.</div>
<div class="rule goodline">□ I know when I will compact: after the feature phase, not randomly.</div>
<div class="rule goodline">□ I will use subagents for side research.</div>
</div>
</div>
</section>
<section id="refs" class="section">
<div class="card box">
<h2>References and where this app's guidance came from</h2>
<p>This app paraphrases these official Anthropic / Claude sources and turns them into beginner workflows. It does not call the Claude API or any external service.</p>
<div class="ref"><b>[1] Anthropic API Docs -- Prompt caching</b><br>Used for cache prefixes, cache hit vs creation behavior, TTL behavior, and repetitive long-prompt guidance.<br><a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching" target="_blank" rel="noopener">platform.claude.com/docs/en/build-with-claude/prompt-caching</a></div>
<div class="ref"><b>[2] Claude Code Docs -- Prompt caching</b><br>Used for Claude Code-specific automatic caching, exact prefix matching, invalidators, cache scope, TTL by authentication method, and subagent cache behavior.<br><a href="https://code.claude.com/docs/en/prompt-caching" target="_blank" rel="noopener">code.claude.com/docs/en/prompt-caching</a></div>
<div class="ref"><b>[3] Claude Code Docs -- Memory</b><br>Used for CLAUDE.md, auto memory, /memory, and memory loading behavior.<br><a href="https://code.claude.com/docs/en/memory" target="_blank" rel="noopener">code.claude.com/docs/en/memory</a></div>
<div class="ref"><b>[4] Claude Code Docs -- Manage costs effectively</b><br>Used for context-size cost guidance, /usage, /clear, /rename, /resume, and custom compaction instructions.<br><a href="https://code.claude.com/docs/en/costs" target="_blank" rel="noopener">code.claude.com/docs/en/costs</a></div>
<div class="ref"><b>[5] Claude Code Docs -- Output styles</b><br>Used for output-style behavior and system-prompt impact.<br><a href="https://code.claude.com/docs/en/output-styles" target="_blank" rel="noopener">code.claude.com/docs/en/output-styles</a></div>
<div class="ref"><b>[6] Claude Code Docs -- Common workflows</b><br>Used for beginner prompt patterns: overview, finding relevant code, planning before editing, resuming, worktrees, and delegating research.<br><a href="https://code.claude.com/docs/en/common-workflows" target="_blank" rel="noopener">code.claude.com/docs/en/common-workflows</a></div>
<div class="ref"><b>[7] Claude Code Docs -- Subagents</b><br>Used for the recommendation to isolate broad research/log digging into subagents to preserve main context.<br><a href="https://code.claude.com/docs/en/sub-agents" target="_blank" rel="noopener">code.claude.com/docs/en/sub-agents</a></div>
<div class="ref"><b>[8] Claude Code Docs -- Data usage</b><br>Used for the note that local Claude Code transcripts can be stored in plaintext under <code>~/.claude/projects/</code> by default for session resumption.<br><a href="https://code.claude.com/docs/en/data-usage" target="_blank" rel="noopener">code.claude.com/docs/en/data-usage</a></div>
</div>
</section>
</main>
<div class="footer">Built as a single-file HTML app. No external network calls, libraries, tracking, or build step.</div>
</div>
<script>
(function(){
"use strict";
function one(sel, root){ return (root || document).querySelector(sel); }
function all(sel, root){ return Array.prototype.slice.call((root || document).querySelectorAll(sel)); }
function showNotice(message){
var box = one("#scriptNotice");
if(!box) return;
box.style.display = "block";
box.textContent = message;
}
window.addEventListener("error", function(evt){
showNotice("A script error occurred: " + (evt.message || "unknown error"));
});
function setSection(id, updateHash){
var target = document.getElementById(id);
if(!target) return;
all(".section").forEach(function(section){
section.classList.toggle("active", section.id === id);
});
all(".nav a").forEach(function(link){
link.classList.toggle("active", link.getAttribute("data-section") === id);
});
if(updateHash && window.history && window.history.replaceState){
window.history.replaceState(null, "", "#" + id);
}
}
function setExample(id){
all(".example").forEach(function(ex){
ex.classList.toggle("active", ex.id === id);
});
all(".tabbar button").forEach(function(btn){
btn.classList.toggle("active", btn.getAttribute("data-ex") === id);
});
}
async function copyText(text, button){
var original = button.textContent;
try{
if(navigator.clipboard && window.isSecureContext){
await navigator.clipboard.writeText(text);
} else {
var ta = document.createElement("textarea");
ta.value = text;
ta.setAttribute("readonly", "");
ta.style.position = "fixed";
ta.style.left = "-9999px";
document.body.appendChild(ta);
ta.focus();
ta.select();
var ok = document.execCommand("copy");
document.body.removeChild(ta);
if(!ok) throw new Error("copy command unavailable");
}
button.textContent = "Copied";
}catch(err){
button.textContent = "Select text";
var copyId = button.getAttribute("data-copy");
var block = copyId ? document.getElementById(copyId) : null;
if(block && window.getSelection){
var range = document.createRange();
range.selectNodeContents(block);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
}
setTimeout(function(){ button.textContent = original; }, 1200);
}
function updateScore(){
var score = 100;
all("input[data-impact]:checked").forEach(function(input){
score += Number(input.getAttribute("data-impact") || 0);
});
score = Math.max(0, Math.min(100, score));
var scoreBox = one("#score");
var label = one("#scoreLabel");
var text = one("#scoreText");
if(!scoreBox || !label || !text) return;
scoreBox.textContent = String(score);
label.className = "pill ";
if(score >= 80){
label.className += "good";
label.textContent = "Warm";
text.textContent = "Your session is stable. Keep working in the same lane.";
} else if(score >= 55){
label.className += "warn";
label.textContent = "Mixed";
text.textContent = "Some choices may cool the cache. Delay model/MCP/compact changes until a checkpoint.";
} else {
label.className += "bad";
label.textContent = "Likely cold";
text.textContent = "You are doing things that often rebuild cache. Consider /rename, /clear, or restart clean after setup.";
}
}
var KEY = "claude-cache-playbook-notes-v2";
async function loadNotes(){
var box = one("#notesBox");
if(!box) return;
try{
if(window.vibes && typeof window.vibes.onReady === "function"){
window.vibes.onReady(async function(){
try{
var saved = await window.vibes.load(KEY);
if(saved) box.value = saved;
}catch(e){
box.value = localStorage.getItem(KEY) || "";
}
});
} else {
box.value = localStorage.getItem(KEY) || "";
}
}catch(e){
try{ box.value = localStorage.getItem(KEY) || ""; }catch(ignore){}
}
}
async function saveNotes(value){
try{
if(window.vibes && typeof window.vibes.save === "function"){
await window.vibes.save(KEY, value);
} else {
localStorage.setItem(KEY, value);
}
}catch(e){
try{ localStorage.setItem(KEY, value); }catch(ignore){}
}
}
function bindEvents(){
document.addEventListener("click", function(evt){
var nav = evt.target.closest ? evt.target.closest(".nav a") : null;
if(nav){
evt.preventDefault();
setSection(nav.getAttribute("data-section"), true);
return;
}
var tab = evt.target.closest ? evt.target.closest(".tabbar button") : null;
if(tab){
setExample(tab.getAttribute("data-ex"));
return;
}
var copy = evt.target.closest ? evt.target.closest(".copy") : null;
if(copy){
var id = copy.getAttribute("data-copy");
var block = id ? document.getElementById(id) : null;
if(block) copyText(block.innerText || block.textContent || "", copy);
return;
}
if(evt.target && evt.target.id === "resetSim"){
all("input[data-impact]").forEach(function(input){ input.checked = false; });
updateScore();
return;
}
if(evt.target && evt.target.id === "saveNotes"){
var notes = one("#notesBox");
saveNotes(notes ? notes.value : "");
var status = one("#saveStatus");
if(status){
status.textContent = "Saved.";
setTimeout(function(){ status.textContent = ""; }, 1200);
}
return;
}
if(evt.target && evt.target.id === "clearNotes"){
var notesBox = one("#notesBox");
if(notesBox) notesBox.value = "";
saveNotes("");
var clearStatus = one("#saveStatus");
if(clearStatus){
clearStatus.textContent = "Cleared.";
setTimeout(function(){ clearStatus.textContent = ""; }, 1200);
}
return;
}
});
document.addEventListener("change", function(evt){
if(evt.target && evt.target.matches && evt.target.matches("input[data-impact]")){
updateScore();
}
});
window.addEventListener("hashchange", function(){
var id = (location.hash || "#learn").replace("#", "");
setSection(id, false);
});
}
function init(){
bindEvents();
var initial = (location.hash || "#learn").replace("#", "");
if(!document.getElementById(initial)) initial = "learn";
setSection(initial, false);
setExample("ex1");
updateScore();
loadNotes();
var notice = one("#scriptNotice");
if(notice){
notice.style.display = "block";
notice.textContent = "Interactive mode loaded. Tabs, copy buttons, notes, and simulator are active.";
setTimeout(function(){ notice.style.display = "none"; }, 1600);
}
}
if(document.readyState === "loading"){
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
</script>
</body>
</html>
```
[REQUESTED CHANGES]
(no specific request — apply your best judgment)
--- HOW TO RESPOND (READ FIRST) ---
Before writing any code, follow this exact process:
1. **ANALYZE** the widget source code provided above and identify:
a. Which Vibes SDK features it already uses (vibes.save, vibes.load, vibes.shared.join, etc.)
b. Which SDK features would genuinely benefit THIS specific widget — tailored to what it does, not a dump of everything available.
2. **PRESENT A NUMBERED LIST** covering:
- SDK features currently active in this widget
- New SDK features that would concretely improve this widget (be specific: why this widget, what it enables)
3. **WAIT** — do not write any code yet. Reply with your analysis and numbered list, then stop and ask the user which numbered items they want.
4. **IMPLEMENT ONLY** the items the user confirms, plus any explicit change they requested. Do not add unrequested features.
**IMPORTANT — Shared state room names:**
If you add vibes.shared.join(), do NOT use a hardcoded string literal as the room name (e.g. vibes.shared.join("lobby")) unless the user explicitly wants ALL viewers to share one single global state. A hardcoded room name means every person who visits this widget reads and writes the same shared state — it is a global room. For per-user or per-session isolation, derive the room name from a variable (e.g. a user ID, session token, or random value). When in doubt, use vibes.save/vibes.load for per-user persistence instead.
--- VIBES SDK CONTEXT ---
## Vibes SDK Reference
You are building an HTML widget for It Just Vibes (itjustvibes.com). The Vibes SDK is auto-injected — do NOT add a script tag. Just use `window.vibes` (or just `vibes`).
### Setup
Wrap your startup code in `vibes.onReady`:
```js
vibes.onReady(async () => {
const saved = await vibes.load("myKey");
// your widget logic here
});
```
### State (Per-User Persistence)
Every user gets their own isolated state per widget. All methods return Promises.
| Method | Description |
|--------|-------------|
| `await vibes.save(key, value)` | Save JSON-serializable data |
| `await vibes.load(key)` | Load saved data (returns `null` if not found) |
| `await vibes.delete(key)` | Delete a saved key |
| `await vibes.listKeys()` | Get array of all saved key names |
**Key rules:**
- Keys are strings, max 64 characters, alphanumeric + dashes/underscores
- Values must be JSON-serializable (objects, arrays, strings, numbers, booleans)
- Max 100KB per value, 500KB per widget per user, 5MB per user total
- Max 100 keys per widget per user
### Fetch Proxy
Use direct `fetch()` for APIs with permissive CORS headers (`Access-Control-Allow-Origin: *`). Use `vibes.fetch` for APIs without CORS headers (the proxy handles cross-origin requests):
```js
const resp = await vibes.fetch("https://api.example.com/data", {
method: "GET", // GET, POST, PUT, DELETE
headers: {}, // optional headers
body: null, // optional body (string)
timeout: null // optional timeout in ms
});
const data = await resp.json(); // or resp.text()
console.log(resp.status, resp.ok);
```
### Multiplayer (Shared State)
Real-time shared state across all users viewing the same widget.
```js
// Join a room (call once at startup)
await vibes.shared.join("lobby", { persistent: true });
// Set shared state (broadcasts to all users)
await vibes.shared.set("score", { player1: 10, player2: 7 });
// Read shared state (synchronous, returns last known value)
const score = vibes.shared.get("score");
// Listen for changes to a specific key
vibes.shared.onChange("score", (newValue) => {
console.log("Score updated:", newValue);
});
// Listen for any shared state change
vibes.shared.onAny((key, value) => {
console.log(key, "changed to", value);
});
// Get number of connected users
const count = await vibes.shared.getUserCount();
// Leave room
vibes.shared.leave();
// Clear all shared state for this room
await vibes.shared.clear();
```
**Shared state options:**
- `{ persistent: true }` — state survives page reloads (stored server-side)
- Default room name is "__default__" if omitted
### Rules
1. **Do NOT use localStorage, sessionStorage, or window.storage** — they are blocked or undefined in the sandbox. Use `vibes.save`/`vibes.load` instead.
2. **Do NOT add a script tag to import the SDK** — it is auto-injected.
3. **Wrap startup code in `vibes.onReady()`** — the SDK may not be ready immediately.
4. **Await all SDK calls** — every method (except `vibes.shared.get`) returns a Promise.
5. **Do NOT import external JS libraries via script tags** — they will be blocked. Include library code inline or use a CDN link in a `<link>` tag for CSS only.
6. **Keep total code under 80KB** — that is the default widget size limit (your account limit may be higher).
### Rate Limits
| Operation | Limit |
|-----------|-------|
| Writes (save + delete combined) | 30/min |
| Reads (load) | 60/min |
| List keys | 30/min |
| Fetch proxy | Rate limited per widget |
### Error Handling
All SDK methods can reject. Wrap in try/catch:
```js
try {
await vibes.save("key", value);
} catch (err) {
console.error("Save failed:", err.message);
}
```
Fetch proxy errors include `err.code`: `"RATE_LIMITED"`, `"BLOCKED"`, `"FETCH_ERROR"`.
### Data Export
Export rows of data as CSV or Excel directly from your widget.
```js
// Register dataset for the platform's "Export data" button
// AND optionally trigger an immediate download
vibes.exportData(rows, { filename: 'results.csv' })
// rows: Array of arrays (each inner array is one row; first row = headers)
// options.filename: sets the download filename and format (csv or xlsx)
// options.directDownload: false to only register without downloading (default: true)
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `filename` | string | `'data.csv'` | Download filename; extension determines format (`.csv` or `.xlsx`) |
| `directDownload` | boolean | `true` | Trigger immediate browser download in addition to registering the dataset |
**Notes:**
- First call registers the dataset so the widget chrome shows an "Export data" button
- Use `.csv` extension for CSV, `.xlsx` for Excel
- CSV injection safety is automatic (formula-starting cells prefixed with `'`)
- Data stays in the browser — no server round-trip
--- FORK & RESUBMIT INSTRUCTION ---
Return the complete, self-contained HTML file with all changes applied.
It should be ready to paste into itjustvibes.com/submit to create a new fork.
Include this comment at the top of the output:
/* Forked from: https://itjustvibes.com/Owner/claude-code-cache-prompt-management-playbook */