Files
claude c68b2303a0 Add explore skill: interactive pseudocode browser
Serves a localhost page in the pseudo-skill register with the
reference markers as clickable buttons: clicks land in
<workdir>/events.jsonl, a persistent Monitor tail wakes the session,
the session rewrites page.html, and the browser live-reloads over SSE.
Actions per marker: expand / show real code / explain / ask, plus a
page-level ask box; anchors become forge deep-links when the project
has a reachable remote; incidental findings are surfaced on the page
as anchored notes.

The port is configured in one place (the PORT constant atop
scripts/server.py; --port overrides per run). Mechanics proven live
against the aura repo before extraction into this skill.
2026-07-20 12:11:57 +02:00

6.3 KiB
Raw Permalink Blame History

name, description
name description
explore Use when the user wants to explore a project interactively in the browser — invoked as `/explore <project>` or when the user asks for a clickable/served pseudocode page. Serves a localhost page showing the project as commented pseudocode in the pseudo-skill register, with the reference markers rendered as clickable buttons; every click (expand / show real code / explain / ask, plus a free-text box) lands as an event that wakes the session through a Monitor back-channel, the session rewrites the page, and the browser live-reloads via SSE. Anchors become forge deep-links when the project has a web-reachable remote; incidental findings (doc/code drift, stale comments) are surfaced on the page itself as anchored finding notes.

explore — interactive pseudocode browser

Overview

/explore <project> turns the pseudo skill's register into a served, clickable page. The user reads pseudocode in the browser and zooms by clicking instead of typing: each marker is a button, each click wakes the session, the session rewrites the page, SSE reloads the browser.

The loop:

browser click ──POST /event──▶ server.py ──append──▶ <workdir>/events.jsonl
                                                          │
                                       Monitor "tail -F -n 0 events.jsonl"
                                                          │
                                                    this session
                                                          │
browser ◀──SSE "reload"── server.py ◀──mtime── rewrites <workdir>/page.html

Latency expectations are conversational, not app-like: every click costs one thinking cycle. Tell the user this once at start.

Moving parts

  • scripts/server.py — stdlib localhost server. The port is configured in exactly one place: the PORT constant at the top of this file. A per-run override exists (--port N) for a second concurrent instance; the constant is the default every instance shares.
  • templates/page.html — the page scaffold (CSS, click menu, ask box, SSE client). Placeholders: {{TITLE}} (project name, appears in tab and header), {{HINT}} (one line: what the project is + current altitude), {{CONTENT}} (the pseudocode block, see content rules).
  • Workdir ~/.cache/explore/<project-slug>/ — holds the generated page.html and events.jsonl. Scratch, never committed, safe to delete after the session.

Start procedure

  1. mkdir -p ~/.cache/explore/<project-slug>
  2. Generate <workdir>/page.html from templates/page.html, filling the three placeholders. {{CONTENT}} starts at the project's main entry point (pseudo rule 9) unless the user pointed elsewhere.
  3. Start the server in the background: python3 <skill-dir>/scripts/server.py <workdir> (add --port N only for a second concurrent instance).
  4. Arm the back-channel as a persistent Monitor: tail -F -n 0 <workdir>/events.jsonl (-n 0 is load-bearing: without it, stale events replay at arm time).
  5. Give the user the URL the server printed.

Content rules

The pseudo skill's Iron Law governs everything inside {{CONTENT}}: anchor line first, one altitude per view, markers as pointing handles explained inline (never a legend), data shapes beside control flow, reduce/omit the rest. Read that skill's rules before generating the first page. On top of it, the served medium adds:

  • Escape first, tag second. {{CONTENT}} and every .note body are substituted into HTML: escape &, <, > in all source and pseudocode text before insertion (Rust is full of Vec<T>, &mut, a < b), and only then wrap tokens in highlight spans. A stray < swallows the rest of the page, including the SSE script.
  • Markers are buttons. [N] renders as <button class="marker" data-marker="N">[N]</button>. Expansions introduce sub-markers (4a, 4b) — the zoom is recursive.
  • Anchors are links. When the project has a web-reachable forge remote (Gitea/GitHub), every file anchor becomes an <a class="src" href="…#L10-L20" target="_blank" rel="noopener"> deep-link. Verify the URL pattern once per project (curl the file URL, expect 200) before emitting the first link; skip links when there is no reachable remote.
  • Real code (code action): a .note.code block at the marker — caption line = linked file:fromto anchor, then the code verbatim with light span highlighting (.c comments, .k keywords, .s strings).
  • Explanations (explain action): a .note block anchored at the marker. Page-level ask answers go in a <section id="qa"> between the pseudocode and the menu div (question dimmed in .q, answer in .note).
  • Findings. Anything noticed in passing — doc/code drift, a stale comment, a suspicious contract — is surfaced on the page itself: an amber .note.finding (⚠) anchored at the spot with deep-links to the evidence, and a wavy .warn span (with title tooltip) on the stale phrase where it is displayed. A one-line chat mention suffices beside it; filing a tracker issue stays a separate ask.
  • Language. Scaffold and pseudocode are English (repo register). Answers to ask events are written in the user's language.

Handling events

Each Monitor line is one click: {marker, action, text?, ts} (marker: null = page-level; text only on ask). Respond by rewriting <workdir>/page.html — the SSE watcher reloads the browser automatically, so the rewrite IS the reply. Every rewrite MUST preserve the full template scaffold: the SSE <script> (EventSource + reload listener), the #menu div, and the #ask form — after each reload that script is what re-binds every marker button. Edit only the pseudocode, the anchored notes, and the #qa section; dropping the scaffold silently kills the loop. Read the real source before expanding or explaining; keep each response at the altitude the click asked for. Batch related edits into as few writes as possible (each write triggers a visible reload).

Stop

TaskStop the server task and the Monitor. The workdir is scratch and may be deleted. To switch projects: stop the server, start it again on the new project's workdir, and re-arm the Monitor on the NEW workdir's events.jsonl — server and monitor are both bound to one workdir at startup, so neither survives a workdir switch.