Skip to content

SOPs

Browser Guide Overlays

A browser guide overlay is a floating, draggable panel injected into the active Chrome tab — numbered checklist, one step highlighted as the current action, close button included. Data is baked into the DOM (no fetch, no server), so it works on HTTPS pages without mixed-content warnings.

Use it when a task cannot be fully automated: OAuth consent flows, Cloudflare Zero Trust challenges, support chat widgets, native OS pickers, Google login walls.

Just ask Claude. Any natural phrasing works:

  • “Walk me through this with an overlay.”
  • “Give me an overlay for the steps.”
  • “Pop up a checklist — I do not know what to do next.”
  • “Inject a guide for this task.”

Claude will recognize the intent and call the overlay script with the relevant steps. If the page is not already focused in Chrome, Claude will open or focus it first, then inject.

Ask for an overlay any time you hit a browser task that is more than two clicks and you would otherwise have to memorize or screen-swap back to read. Examples:

  • Filing a support ticket with a vendor (Hostinger, Cloudflare, GHL)
  • OAuth consent flows Claude cannot complete for you
  • Multi-step config wizards (Stripe, Google Search Console, DNS provider UIs)
  • Form filling where Claude drafted the field values
  • Any “do these five things in order” workflow

The overlay system lives in ~/apps/cc/overlay/:

  • inject-guide.sh — entry point, takes a JSON payload
  • inject.js — the JavaScript that builds the overlay DOM
  • floating-guide.py — Python helper (unused by the primary flow; kept for reference)

Flow:

  1. Claude composes a JSON payload describing the title and steps.
  2. inject-guide.sh reads inject.js, substitutes the JSON into the template, and escapes it for AppleScript.
  3. AppleScript (osascript) tells Chrome to execute the JavaScript inside the active tab of the front window.
  4. The JS removes any previous overlay, injects new CSS and HTML, and makes the panel draggable.

Re-injecting simply replaces the previous overlay — so Claude can update step statuses as you progress.

{
"title": "Short Task Name",
"steps": [
{ "text": "First step description", "status": "completed" },
{ "text": "Second step description", "status": "active" },
{ "text": "Third step description", "status": "pending" }
]
}
FieldRequiredDescription
titleYesShown at the top of the overlay. Keep it short — 3-5 words.
stepsYesArray of step objects. No fixed limit, but keep it under ~7 for readability.
steps[].textYesThe step instruction. Plain English. No markdown rendering.
steps[].statusYesOne of pending, active, completed.
  • completed — already done, rendered with a strikethrough/check style.
  • active — the current step, rendered highlighted. There should be exactly one active step at a time.
  • pending — upcoming step, rendered dim.
Terminal window
bash ~/apps/cc/overlay/inject-guide.sh '{"title":"Deploy Website","steps":[
{"text":"Run build","status":"completed"},
{"text":"Push to GitHub","status":"active"},
{"text":"Verify deploy","status":"pending"}
]}'

Output on success:

Overlay injected: 3 steps
Active: Push to GitHub

Re-run the command with a new JSON payload. The previous overlay is removed before the new one is drawn.

Terminal window
bash ~/apps/cc/overlay/inject-guide.sh close

Or click the close button (×) in the overlay itself.

Writing JSON Safely (For Claude’s Reference)

Section titled “Writing JSON Safely (For Claude’s Reference)”

The biggest foot-gun is JSON encoding. If the steps array contains characters that need escaping (apostrophes, em dashes, quotes), building the JSON string by hand in bash will fail. The reliable pattern:

python3 -c "
import json, subprocess
data = {
'title': 'Task Name',
'steps': [
{ 'text': 'Step one with apostrophes and dashes', 'status': 'active' },
{ 'text': 'Step two', 'status': 'pending' }
]
}
subprocess.run(['bash', '/Users/ojhurst/apps/cc/overlay/inject-guide.sh', json.dumps(data)], check=True)
"

json.dumps handles the escaping. Passing the result through the shell as a single argument avoids quoting issues.

  • Chrome only. The AppleScript dispatch is specific to Google Chrome. Safari, Firefox, Arc are not wired up.
  • Active tab only. The overlay lands in whatever tab is front-most at the moment of injection. If the wrong tab is focused, Claude will open/refocus the right page first.
  • Local machines only. Claude injects overlays from the local machine it is running on. Overlays cannot be injected into another machine’s browser remotely.
  • No two-way signal. The overlay cannot tell Claude when a step is finished. James reports back in chat (“done with step 2” or “ticket filed”), and Claude re-injects with the updated statuses.
  • Script: ~/apps/cc/overlay/inject-guide.sh
  • CLAUDE.md reference: search “Browser Guide Overlay” in the super CLAUDE.md