--- name: explore description: Use when the user wants to explore a project interactively in the browser — invoked as `/explore ` 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 ` 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──▶ /events.jsonl │ Monitor "tail -F -n 0 events.jsonl" │ this session │ browser ◀──SSE "reload"── server.py ◀──mtime── rewrites /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//` — holds the generated `page.html` and `events.jsonl`. Scratch, never committed, safe to delete after the session. ## Start procedure 1. `mkdir -p ~/.cache/explore/` 2. Generate `/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 /scripts/server.py ` (add `--port N` only for a second concurrent instance). 4. Arm the back-channel as a persistent Monitor: `tail -F -n 0 /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`, `&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 ``. 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 `` 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:from–to` 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 `
` 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 `/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 `