Post-notebook polish: admin overhaul + public-site pass#37
Merged
AdaInTheLab merged 6 commits intomasterfrom Apr 20, 2026
Merged
Post-notebook polish: admin overhaul + public-site pass#37AdaInTheLab merged 6 commits intomasterfrom
AdaInTheLab merged 6 commits intomasterfrom
Conversation
Cosmetic update to match the terminology pass the rest of the stack already went through (lab-api + RELAY_IMPLEMENTATION.md). The single-use relay URL system is now consistently called the Liminal Bridge everywhere. - "🏛️ About Relay URLs" → "🌉 About Liminal Bridge" Co-authored-by: Sage <sage@thehumanpatternlab.com>
Long-form lab notes now live at notebook.thehumanpatternlab.com. The public marketing site no longer needs a local lab-notes surface — everything redirects to the subdomain and the dead code is removed. Changes: - Router: all four /lab-notes routes (en/ko × list/detail) now render a NotebookRedirect component that window.location.replaces to the subdomain - Nav: Header "Lab Notes" pill → "Notebook" external + ExternalLink icon (same pattern for the existing "Docs" external item so external linking is visually consistent) - Footer "Lab Notes" link → external "Notebook" with icon - Hero CTA "View Lab Notes" → external "Read the Notebook" - Home: drop RecentLabNotesPreview section entirely - Delete 14 dead files: LabNotesPage, LabNoteDetailPage, LabNoteCard + skeletons, RecentLabNotesPreview + css + skeleton, labNotes/notesIndex libs, labNotesClient, data/labNotes, data/labNote - Delete now-empty src/components/labnotes/ directory - i18n: drop labNotesPage namespace wiring, delete both pages.labNotes.json locale files, rename nav.lab-notes → nav.notebook (en + ko), remove sections.labNotes from pages.home (en + ko) - .gitignore: add .claude/ (Claude memory scratch dir) - Tests updated for the new nav + CTA labels Co-authored-by: Sage <sage@thehumanpatternlab.com>
Two Home-page placeholders — the Emotional Weather card and the video grid — now read from real sources instead of hand-authored stubs. YouTube integration: - fetchYouTube.js (run via `npm run fetch:youtube`) now fetches channel + uploads playlist, then makes a second contentDetails call to resolve ISO-8601 durations into "H:MM:SS" / "M:SS" strings - Writes src/data/youtube.json (committed so deploys don't require the API key — just re-run the script when publishing a new video) - src/data/videos.ts replaces hand-authored stubs with a shaper over youtube.json; first upload is marked isFeatured - VideoCategory now optional (YouTube doesn't give us series metadata); dropped fake categories (Carmel's Judgment Logs, Orbson Reports) - VideoArchivePage drops the category filter UI (each filter had one matching video anyway) and sorts newest-first - VideoDetailPage + FeaturedVideo conditionally render category / duration / publish-date only when present - tsconfig: enable resolveJsonModule for the youtube.json import Emotional Weather: - src/lib/weatherReportLoader.ts loads all src/weather-report/*.md via import.meta.glob, parses frontmatter + body (Summary / Temperature / Pressure / Wind / Precipitation / Advisory), picks the lexicographically latest filename and converts to an EmotionalWeatherSignal - EmotionalWeatherCard now defaults to EMOTIONAL_WEATHER_LATEST with EMOTIONAL_WEATHER_STATIC as the fallback when no report parses Result: the Home page widgets update when Ada publishes a new video (+ runs the fetch) or drops a new weather-report markdown file, instead of requiring a code change. Co-authored-by: Sage <sage@thehumanpatternlab.com>
… revisions, revoke Shift the admin from a single generic /admin/notes form into surfaces that match where the content actually lives (notebook.thehumanpatternlab.com and ironkitsune.tech/tails), and turn the editor from a schema-dump form into something that feels like a tool. Type-scoped workspaces: - AdminNotesPage now accepts optional fixedType / heading / eyebrow props — filters the list client-side, locks the form's type field, customizes header copy - New AdminNotebookPage at /admin/notebook: thin wrapper rendering AdminNotesPage with fixedType="labnote" - New AdminTailsPage at /admin/tails: purpose-built lean form for short-form tail entries. author_name is required (matches the lab-api validation); drops department/shadow_density/card_style; form body + list both live inside the same drawer pattern as notebook - /admin/notes stays as the "everything" power-user view - AdminNav adds Notebook + Tails; "Lab Notes" renamed to "All Notes" Drawer editor instead of always-on form: - New Drawer component: right-side slide-in portal with sticky header + footer, Esc/backdrop/close routed through onRequestClose so pages can veto closing when the form is dirty; body scroll locked; focus restored on close - AdminSystemRail removed from AdminLayout (disabled placeholders weren't earning their slot; drawer takes over the right side) - Cards list replaces the DB-table list view; NoteCard shows status pill, type/dept/locale badges, title/slug, line-clamped excerpt, author + tags + last-edited; hover-reveal Edit/Delete with inline confirm (no more blocking confirm() dialog) - "+ New Notebook" / "+ New Tail" buttons in the page header open the drawer with a blank form; cards open with the record loaded; successful save closes the drawer and refreshes the list Real markdown editor: - New MarkdownEditor component backed by @uiw/react-codemirror with markdown language support + one-dark theme tinted to the zinc/cyan palette; live-rendered preview uses react-markdown + remark-gfm - Toolbar dispatches CM6 transactions so Bold/Italic/Link/Code/ Heading/Quote/Bullet/Numbered list respect the current selection - Keymap at Prec.highest: Mod-B, Mod-I, Mod-K (link), Mod-E (code) - Tab-based Write / Preview switcher; Esc from preview returns to Write - MarkdownEditor.lazy.tsx wraps the real editor in React.lazy + Suspense so non-admin users don't pay the ~258 KB gzipped cost - vite.config.js: new "markdown" manualChunk bundles @uiw/react-codemirror + @codemirror/* + react-markdown + remark-gfm together so the chunk is cacheable independently of the main bundle Editor ergonomics: - Toast system (Toast.tsx + useToast hook) with success/error/info variants, mounted at AdminLayout; replaces all alert() calls - slugify util auto-generates slug from title while the slug hasn't been manually edited and the note is new - Cmd/Ctrl+S inside the drawer requestSubmit()s the form - Dirty-state tracking (form vs baseline snapshot) surfaces an "Unsaved" chip in the drawer header + blocks accidental closes via beforeunload + an explicit confirm() Revision history viewer: - New RevisionHistory component inside the editor drawer (only when editing an existing record) — collapsible panel, lazy-loads revision list + per-revision detail via the lab-api endpoints - Source-colored badges (web / cli / api / import), current + published pills, timestamp, byte size; click a revision to expand the full content (cached per-id) - refreshKey bumps on successful save to reload history inline Tokens revoke UI: - AdminTokensPage got a proper Revoke action per active row — inline confirm (Confirm / Cancel), disabled state while revoking, toast on success. Scopes rendered as chips; status shown as pill (active / revoked with strikethrough label) - Uses the existing POST /admin/tokens/:id/revoke endpoint (soft revoke — preserves audit trail) New deps: - @uiw/react-codemirror, @codemirror/lang-markdown, @codemirror/theme-one-dark Co-authored-by: Sage <sage@thehumanpatternlab.com>
Three long-standing TS errors were blocking a clean typecheck. While fixing them, consolidate the mascot display data that was drifting between DepartmentCard and DepartmentDetailPage into one shared module — which the Departments + About + LabMember detail work builds on. Changes: - New src/data/mascotMeta.ts — single source of truth for mascot emoji, display name, avatar image path, and labteam profile slug keyed by MascotId. Previously the emoji+name maps were duplicated (and drifting) between DepartmentCard and DepartmentDetailPage - LabTeamPage: drop invalid onClick prop + unused useNavigate import (LabMemberCard already has its own "View profile →" Link internally, so the duplicate onClick was both a TS error and redundant nav) (DepartmentDetailPage + LabMemberDetailPage prop-name fixes and the DepartmentCard consumption of mascotMeta land alongside the rest of the polish rewrites in the next commit.) Co-authored-by: Sage <sage@thehumanpatternlab.com>
…legal) Full pass over the public surfaces now that the notebook migration is done. Goal was coherence: every page uses LayoutShell, mascot visuals come from the shared labTeam data, dark-theme tokens apply everywhere, and dead-end flows get a real outbound link. About: - Founders section now pulls from labTeam (by id: ada, orbson, carmel, mcchonk) with real avatars + aura glow, each card a Link to the member's profile - "Lead Human Pattern Analyst" anonymization → Cognitive Fox Ada - "See the full team →" link under the grid; "Meet the Lab Team" added to the bottom CTA - Philosophy grid items got lucide icons (Waves / Compass / Smile / PawPrint / Bot / Feather) in tinted cyan squares - 7 stacked text sections → 5: Mission + "Where science meets creatures" + "Why chaos is data" collapsed into one "Why chaos is data" beat; the Lab mantra got promoted to a sticky aside next to the Philosophy grid Departments: - DepartmentCard: whole header + body is now a Link to /departments/:id; emoji gradient circle replaced with the real mascot avatar from mascotMeta; "Mascot: Name" in the footer is a Link to /labteam/:slug - DepartmentsPage: dropped the filter bar (each mascot owned exactly one department — filter was really "pick one of 10 to see 1") - DepartmentCard.test.tsx updated: wraps in MemoryRouter, asserts on avatar alt-text + link destinations (was checking emoji text) Department detail: - Was rendering outside LayoutShell — content ran flush-left past the centered container. Wrapped properly now - Big mascot callout with aura glow (pulled from labTeam member's aura), links to the mascot's /labteam profile - Dropped the "This department works closely with..." filler paragraph that appeared on every detail page - "Related work" section tightened: no more "in the future, this section can..." placeholder, direct pointers to Notebook + Video Archive Lab member detail: - Dropped the duplicated header (LayoutShell was rendering name + title up top, card below was re-rendering the same) - Big aura avatar (avatarSrc + radial glow in the member's primary aura color) instead of the small emoji-in-tile - New "Home department" callout: if the mascot leads a department, linked card to /departments/:id (reverse-lookup via mascotProfileSlug) - Lore & Documentation links get the consistent ExternalLink icon Contact: - Required fields marked with red * + required/aria-required attributes + autoComplete hints so browsers validate before submit and offer autofill - Labels wired to inputs via id/htmlFor (was fully missing) - Status is now a discriminated union; validation errors list the specific missing field(s); send-errors are separate and mention the direct-email fallback - New "Notebook entry" topic option; right-rail "Lab Notes" bullet updated to "notebook entries" - Send button gets a lucide Send icon Privacy Policy: - Was rendering its own <main> with text-gray-* tokens on a dark site — body text was nearly invisible. Now inside LayoutShell using slate-* / cyan-* tokens consistent with the rest of the site - Dropped the H2 emojis (ContentUsePolicy has none — was jarring) - Replaced "upcoming Analytics Opt-Out Toggle" promise (a TODO shipped live) with a real alternative: browser tracking protection / "Do Not Track" Content Use Policy: three stale "Lab Notes" references → "notebook entries". Co-authored-by: Sage <sage@thehumanpatternlab.com>
😼📘 Carmel Epistemic Stamp™📘 Carmel Epistemic Stamp™
This automated judgment has been issued by the Chief Judgment Office (CJO). |
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A broad post-notebook-migration pass across the frontend. Three threads, all tied together:
Companion API work: AdaInTheLab/lab-api#28 adds the
author_name/author_kind/tagspersistence and revision history endpoints this PR consumes.Changes by commit
🌉 ui: rename relay info box to "Liminal Bridge" (8a3ba5b)
Terminology consistency — the relay system is now called the Liminal Bridge everywhere.
📝 content: retire /lab-notes, redirect to notebook subdomain (d5972f9)
/lab-notesroutes (en/ko × list/detail) redirect tonotebook.thehumanpatternlab.comExternalLinkicon (Docs pill gets the icon too for consistency)RecentLabNotesPreviewsectionpackage.jsondrops stalesync:labnotesscript.gitignoreadds.claude/⚙️ feat: wire Home widgets to live data (YouTube + Emotional Weather) (f08fde7)
fetchYouTube.jsnow pulls durations via a secondvideos?part=contentDetailscall; ISO-8601 →H:MM:SS/M:SSdata/videos.tsreads from the generatedyoutube.json(committed; deploys don't need the API key)weatherReportLoader.tsparses the latestsrc/weather-report/*.mdinto anEmotionalWeatherSignal;EmotionalWeatherCardnow defaults to the latest parsed reporttsconfig.jsongetsresolveJsonModule: true⚙️ feat: admin overhaul (1cc86e2)
The big one. Details in the commit body, but the shape:
/admin/notebook(scopedAdminNotesPagewrapper) + new/admin/tailswith its own lean form requiringauthor_nameDrawercomponent (right-side slide-in portal, Esc/backdrop close with optional dirty-check veto). Replaces the always-on form.AdminSystemRailremoved fromAdminLayoutNoteCardreplaces the DB-table list view; status pills, type/dept/locale badges, excerpt, author + tags footer, inline delete confirmMarkdownEditorbacked by CodeMirror 6 (@uiw/react-codemirror+@codemirror/lang-markdown+@codemirror/theme-one-dark). Toolbar dispatches CM6 transactions; Write/Preview tabs;Mod-B/I/K/Eshortcuts. Lazy-loaded viaMarkdownEditor.lazy.tsxso non-admin users don't pay the ~258 KB gzipped cost.vite.config.jsgets amarkdownmanualChunkToastsystem replaces everyalert();slugifyauto-generates slug from title (until manually edited); Cmd/Ctrl+S submits the drawer form; dirty-state tracking surfaces an "Unsaved" chip + blocks close viabeforeunload+window.confirm()RevisionHistorycomponent inside the editor drawer; reads the two new lab-api endpoints; source-colored badges, current/published pills, lazy per-revision content fetch with cacheAdminTokensPagegets a proper Revoke action with inline confirm + toast + status pill🔧 refactor: fix pre-existing TS errors + extract mascot metadata (e4aac6d)
src/data/mascotMeta.ts— single source of truth for mascot emoji, name, avatar path, and labteam profile slug (emoji + name were previously duplicated and drifting betweenDepartmentCardandDepartmentDetailPage)LabTeamPagedrops an invalidonClickprop onLabMemberCard(LabMemberCardalready has its own internal "View profile →" Link)🎨 style: public-site polish pass (48fc59e)
labTeam(real avatars + aura glow + link to profile); "Lead Human Pattern Analyst" → Cognitive Fox Ada; "See the full team →"; Philosophy grid gets lucide icons (Waves / Compass / Smile / PawPrint / Bot / Feather); 7 stacked text sections → 5; Lab mantra promoted to sticky asideDepartmentCardis now a Link to the detail page with real mascot avatar; mascot name is a Link to/labteam/:slug; filter bar dropped (each mascot had exactly one department — the filter was pick-10-see-1); test updated for new structureLayoutShell(was rendering outside, content ran flush-left); big mascot callout with aura glow linking to the profile; filler paragraph dropped; related-work section tightenedmascotProfileSlug)*+required/aria-required+autoComplete; labels wired viaid/htmlFor(were unlinked); validation vs send-error messages split; "Notebook entry" topic added; stale "Lab Notes" bullet updated<main>withtext-gray-*tokens (body text nearly invisible on the dark theme). Now inLayoutShellwithslate-*tokens; H2 emojis dropped for consistency with the Content Use page; "upcoming Analytics Opt-Out Toggle" TODO replaced with a real alternativeTesting
npx tsc --noEmit— cleannpx vitest run— 38/38 tests passnpx vite build— green; bundle hygiene: mainindex.jsstays ~132 KB gzipped, CodeMirror + preview live in a separate 258 KB chunk that only loads when the editor is renderedBreaking changes
None for site users. For admin users:
/admin/notesstill works as before (now relabeled "All Notes" in the nav) — the new/admin/notebookand/admin/tailsare additive.Related
Co-authored-by: Sage sage@thehumanpatternlab.com