The source of truth for TooToo. The single-file index.html at the repo root is a
generated build — you edit the component sources under src/, assemble, test,
and promote. Never hand-edit a production index.html.
- Edit the components in
src/—js/,styles.css,components/,config.js. pwsh -File assemble.ps1→ buildstootoo-dev/index.html(the dev build); test it viafile://.promoteregenerates the canonical productionindex.htmlat the repo root (assemble.ps1 -Prod), thensync→ forks andpublish→ git. Full spec:../PIPELINE.md; rules:../AGENTS.md.
History. This began on 2026-06-21 as an isolated sandbox — a safe place to carve the single-file app into components and prove they reassemble byte-for-byte. It graduated to canonical source on 2026-06-23, when the assembled build replaced the hand-maintained
index.html. The design notes below date from that carve and are kept as background.
Split TooToo into standalone, runnable component files for easy experimentation,
then assemble them back into the single index.html (which must stay one file).
tootoo-lab/
tootoo-reference.html ← read-only copy of current canonical engine (carve from this)
src/
index.template.html ← skeleton with <!-- @include ... --> markers (later)
styles.css ← shared stylesheet (later)
components/ header.html sidebar.html content.html footer.html
js/ core.js header.js sidebar.js content.js footer.js main.js
mock/mock-data.js ← sample data so component pages run offline
index.html ← GENERATED by assembling src/ (the proof it round-trips)
Each components/*.html is both a standalone test page (open it, style it with
mock data, no GitHub needed) and a source fragment the assembler extracts.
- Prove the round-trip — carve the reference into parts, assemble back, confirm it behaves identically. Validates the machinery before changing any behavior.
- Shared CSS + HTML partials with mock harnesses — the fun playground, low risk.
- Carve JS incrementally —
main.jsas one blob first, then peel offcore.jsand one component at a time, re-assembling and testing each step.
- src/ARCHITECTURE.md — layers, the shared-global one-writer-per-field rule, and each component's contract.
- PARITY.md — graduation audit: what's closed vs canonical, verification log.
- lab-fixes.md — every spot the lab diverged from canonical + the fix (raw material for the graduation diff).
- 2026-08-09 — Review pass: five small fixes. (1) Branch menu keyboard support:
Escape closes and refocuses the chip, ArrowUp/Down (wrapping) + Home/End move through
options, the current branch is focused on open, and picking a branch returns focus to
the chip. (2) The first file open of a page load (auto-README/last-file) uses
history.replaceState, so Back no longer lands on a dead empty-hash entry. (3) A failed file load clearsstate.currentFilePath, so re-navigating to the same hash retries instead of being swallowed by the hashchange guard. (4).htm/.htmlshare one Rendered/Raw view preference. (5)selectFilehighlights the active row via the sidebar'scachedTreeItemsinstead of re-querying every.tree-item. - 2026-06-23 — PDF viewer fills the pane. PDFs now use the full height between the
file-header and the in-pane footer (a
:has()-driven flex fill on the PDF iframe) instead of a fixed 70vh; the HTML preview keeps 70vh, and it degrades to 70vh where:has()is unsupported. - 2026-06-23 — Blog mode (auto, by convention). A
blog/folder with NN-Month subfolders becomes a reverse-chronological logbook: newest post on top, newest month/year first, the latest month pre-expanded, and the latest post opens on the first expand ofblog/. Scoped to the blog subtree — the rest of the repo is unchanged. - 2026-06-23 — Private-repo file loading via the GitHub Contents API. With a token
set,
fetchFileResponsenow fetches file contents from the Contents API (Accept: application/vnd.github.raw+json) instead ofraw.githubusercontent.com, which only serves public files — so private forks (e.g. the agenda repo) open files, images, and media, not just the tree.resolveMediaUrlbecame async (token → ablob:URL via the Contents API); its three callers nowawait. Anonymous/public browsing is unchanged (still raw, no extra API quota). - 2026-06-23 — Header brand mark + favicon.ico auto-detection. The header's GitHub
octocat is now the app favicon (generated letter mark), and a real
favicon.iconext toindex.html(the fork's site root) is auto-preferred for the tab icon and the header/footer/sidebar marks when present (detectRealFavicon, image-probe with a graceful fallback). Plus a guard so the ?/⚙️ panels no-op instead of throwing on pages with no content area (e.g. the standalone header component). - 2026-06-21 — 🟧 list complete (batch 4): full self-test (§12b) — renders each visible file off-screen by type with a pass/fail/skip table + concurrency, replacing the fetch-only check. All 🟥 blockers + 🟧 important items are now closed. What remains is minor 🟨 polish + a manual verification pass before graduation.
- 2026-06-21 — 🟧 Keyboard navigation (batch 3): Ctrl/⌘ B, / (filter), \ (tree),
arrows/Home/End/PgUp/PgDn, Enter/Space, →/←, Esc-clears-filter — plus
toggleSidebarextracted + sidebar-hidden persistence.⚠️ needs a manual key test (not headless- verifiable). With this, the only remaining 🟧 is a fuller self-test (refinement). - 2026-06-21 — 🟧 Important items (batch 2): responsive + print + reduced-motion
CSS (responsive verified at 600px — file-header stacks), token panel auto-opens on
403/404, "Reset all data" button,
#printTitlefor print. Remaining 🟧: keyboard navigation, full self-test (real renderers). - 2026-06-21 — 🟧 Important items (batch 1): branch switcher (chip + dropdown + switch-in-place, verified), About panel + repo stats + About/Token toggle-return, dark-mode code theme + persistence, global error handlers, breadcrumb folder scroll, and a simplified self-test (fetch-check of text files). Remaining 🟧: keyboard navigation, responsive/print CSS, token auto-open on errors, full self-test.
- 2026-06-21 — 🟥 Graduation blockers closed (see PARITY.md): GitHub Pages
auto-detection + repo cache + manual-entry form, Markdown relative image/link
resolution, real New-Tab/Download URLs, and blob-URL revocation. Plus the
breadcrumb folder links now work.
detectRepois now async; regression-clean. Remaining for full parity: the 🟧 important items (About/self-test, keyboard nav, branch switcher, responsive/print CSS, …). - 2026-06-21 — Review fixes:
selectFilenow opens ancestor folders + scrolls the active row into view (deep-links into nested folders are now visible); refreshed a stalecore.jscomment;assemble.ps1reports char count (Get-Item read a stale cluster size right after write). WrotePARITY.md(graduation audit). - 2026-06-21 — Parity gaps closed.
- Renderers: added audio / video / PDF / spreadsheet (SheetJS, lazy-loaded). All file types now render. Verified live: CSV→table, PDF→inline iframe (plus md / code / svg / json / image from before). Audio/video share the PDF blob+MIME path.
- Token UI: ⚙️ opens a token panel (PAT → localStorage → used by
ghHeaders, Save/Clear reload + clear cache). Wired; not screenshot-verified (needs a click). - Request abort (
newAbort/AbortController on each tree/file load) + a capped in-memory file-text cache. - Local
file://mode (detectLocalModereads./.git/config, files fetched './path'-first then raw GitHub).⚠️ UNVERIFIED here — only activates inside a real checkout opened via file://; assumes the app sits at the repo root. Test by dropping the assembledindex.htmlinto a cloned repo and opening it. - Regression-checked: default live build still renders the real README fine.
- 2026-06-21 — Data layer carved — assembled build is LIVE.
core.jsnow owns CONFIG+state and the GitHub services (ghApi, raw-file fetch, detectRepo, hash routing, rate badge);sidebar.jsgotfetchTree+autoSelectReadme;content.jsselectFilefetches real files;main.jsdoes live init. Newconfig.js(real config) is included by the assembler instead ofmock-data.js, so the assembledindex.htmlfetches a real repo (defaultpushme-pullyou/tootoo, override with?owner=&repo=&branch=). Standalone component pages stay offline via atypeof mockFilesguard infetchFileText. Verified: live tree + README from GitHub, real rate badge. SIMPLIFIED vs canonical (parity TODO): no localfile://mode, no token UI, no abort/cache, and audio/video/pdf/spreadsheet renderers not ported. - 2026-06-21 — Round-trip proven. Added footer (
components/footer.html+js/footer.js, a new page-level footer), extracted header logic tojs/header.js, addedjs/main.js(init/wiring),src/index.template.html, andassemble.ps1. Running the assembler stitches all four components +styles.css+ the JS into a singletootoo-lab/index.html(~53 KB) that renders header+sidebar+content+footer together on mock data. CAVEAT: still mock data — the core data layer (fetch / detectRepo / hash routing) is not carved yet, so the assembled build isn't a live GitHub viewer. To rebuild:pwsh -File assemble.ps1. - 2026-06-21 — Content panel carved:
components/content.htmlruns the file-header (breadcrumbs + Copy/Print/New-Tab/view-toggle) and renderers (markdown via marked+DOMPurify, code via highlight.js, SVG, raw toggle) standalone onmock/mock-data.js(mockFiles). Logic injs/content.js;core.jsgrew the extension constants + view-pref helpers. Header/sidebar/content all carved. - 2026-06-21 — Sidebar carved:
components/sidebar.htmlruns the real tree (build/sort/render, filter, expand-all, resizer, selection hand-off) standalone onmock/mock-data.js, with logic injs/sidebar.jsand shared helpers injs/core.js. Verified the visibility rules (dotfolders +hiddenFoldershidden) and theContent.selectFile()hand-off.styles.cssnow holds base + header + sidebar. - 2026-06-21 — Wrote
src/ARCHITECTURE.md: shared-global model, state-ownership table, per-component contracts. - 2026-06-21 — First component proved:
src/components/header.htmlruns the real header bar standalone with mock data + live lab controls, styled bysrc/styles.css. The@part:headermarkers delimit the extractable fragment. - 2026-06-21 — Lab created; baseline
tootoo-reference.htmlcopied in. Emptysrc/.