Fix empty code blocks: rename ~docs/code param, fix batched IO dispatch
Two bugs caused code blocks to render empty across the site: 1. ~docs/code component had parameter named `code` which collided with the HTML <code> tag name. Renamed to `src` and updated all 57 callers. Added font-mono class for explicit monospace. 2. Batched IO dispatch in ocaml_bridge.py only skipped one leading number (batch ID) but the format has two (epoch + ID): (io-request EPOCH ID "name" args...). Changed to skip all leading numbers so the string name is correctly found. This fixes highlight and other batchable helpers returning empty results. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,14 +18,14 @@
|
||||
;; -----------------------------------------------------------------
|
||||
(~docs/section :title "Why raw text fails" :id "why-text-fails"
|
||||
(p "Claude Code reads " (code ".sx") " files as raw text and mentally reconstructs the tree structure by tracking bracket nesting. It does this imperfectly — especially in deep or wide trees where closing parentheses pile up and their correspondence to openers is lost. Consider the end of a complex island:")
|
||||
(~docs/code :code "(set-cookie \"sx-home-stepper\" (freeze-to-sx \"home-stepper\"))))))))")
|
||||
(~docs/code :src "(set-cookie \"sx-home-stepper\" (freeze-to-sx \"home-stepper\"))))))))")
|
||||
(p "Eight closing parentheses. Which one closes " (code "set-cookie") "? Which closes the " (code "fn") "? Which closes the binding pair? Which closes the letrec bindings list? Answering this requires counting backward through hundreds of lines. Counting is not what language models do well.")
|
||||
(p "The same problem compounds when writing. Claude generates plausible-looking s-expression fragments that are structurally wrong — a paren added, a paren dropped, a level of nesting off. The " (code "str_replace") " tool makes this worse: replacing a string inside a deeply nested form can silently unbalance the surrounding structure in ways that are not visible until the file fails to parse — or worse, parses into a different tree."))
|
||||
|
||||
;; -----------------------------------------------------------------
|
||||
(~docs/section :title "The fix: structural tools" :id "structural-tools"
|
||||
(p "If Claude sees trees when the underlying thing is a tree, both the reading and writing problems disappear. Instead of raw text, Claude gets an annotated tree view with explicit paths:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str "[0] (defisland ~home/stepper\n"
|
||||
" [0,0] ~home/stepper\n"
|
||||
" [0,1] ()\n"
|
||||
@@ -41,7 +41,7 @@
|
||||
" [0,2,2,5] (let ((_eff ...)) (div ...)))))"))
|
||||
(p "The structural correspondence that is invisible in raw text is explicit here. Every node has a path. If " (code "rebuild-preview") " appears at " (code "[0,2,2,2]") " instead of " (code "[0,2,2,1,12]") ", it is immediately obvious that it is a body expression, not a letrec binding. The bug that took an hour to find would be visible on inspection.")
|
||||
(p "For editing, Claude specifies tree operations rather than text replacements:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str ";; Replace a node by path — the fragment is parsed before\n"
|
||||
";; the file is touched. Bracket errors are impossible.\n"
|
||||
"(replace-node \"home-stepper.sx\" [0,2,2,1,12]\n"
|
||||
@@ -58,7 +58,7 @@
|
||||
;; -----------------------------------------------------------------
|
||||
(~docs/section :title "Architecture" :id "architecture"
|
||||
(p "SX Tools is an SX application. The comprehension and editing logic is written in SX, runs on the OCaml evaluator, and is exposed through two interfaces: an MCP server for Claude Code, and an interactive web application for the developer.")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str " ┌─────────────────┐\n"
|
||||
" Claude Code ──▶ │ MCP Server │\n"
|
||||
" │ (OCaml stdio) │\n"
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Annotated tree view")
|
||||
(p "The primary comprehension tool. Every node gets its path label inline, making tree structure explicit. The structural correspondence that is invisible in raw text is readable by inspection, with no need to count brackets:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str "[0] (defcomp ~card\n"
|
||||
" [0,1] (&key title subtitle &rest children)\n"
|
||||
" [0,2] (div :class \"card\"\n"
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Structural summary")
|
||||
(p "A folded view for large files, showing shape without detail. Claude orients itself in a 300-line island, identifies the region it needs, then calls " (code "read-subtree") " on just that part:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str "(defisland ~home/stepper [0]\n"
|
||||
" (let [0,2]\n"
|
||||
" ((source ...) (code-tokens ...)) [0,2,1]\n"
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Context view")
|
||||
(p "Given a deep path, shows the enclosing chain back to the root. Essential for working deep in a tree without loading the entire file:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str "Context for [0,2,2,1,12]:\n"
|
||||
" [0] defisland ~home/stepper\n"
|
||||
" [0,2] let ((source ...) ... (code-tokens ...))\n"
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
(h4 :class "font-semibold text-stone-700 mt-6 mb-2" "Bracket-paired view")
|
||||
(p "The raw source annotated with matched pair labels, for cases where Claude needs to see the actual syntax and verify bracket correspondence:")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str "(₁defcomp ~card (₂&key title subtitle &rest children)₂\n"
|
||||
" (₃div :class \"card\"\n"
|
||||
" (₄h2 title)₄\n"
|
||||
@@ -149,7 +149,7 @@
|
||||
;; -----------------------------------------------------------------
|
||||
(~docs/section :title "The protocol" :id "protocol"
|
||||
(p "The tools only work if they are actually used. The MCP server must be accompanied by a protocol — enforced via " (code "CLAUDE.md") " — that prevents fallback to raw text editing.")
|
||||
(~docs/code :code
|
||||
(~docs/code :src
|
||||
(str ";; Before doing anything in an .sx file:\n"
|
||||
";; 1. summarise → structural overview of the whole file\n"
|
||||
";; 2. read-subtree → expand the region you intend to work in\n"
|
||||
|
||||
Reference in New Issue
Block a user