Skip to content

Add blog, cached GitHub author registry, feeds, and page edit links - #5

Merged
bcomnes merged 14 commits into
refactor/domstack-improvementsfrom
feat/blog-and-page-edit-links
Sep 19, 2026
Merged

bcomnes merged 14 commits into
refactor/domstack-improvementsfrom
feat/blog-and-page-edit-links

Conversation

@bcomnes

@bcomnes bcomnes commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Stack: 3 of 3 — depends on #3

Base: refactor/domstack-improvements. Review against #3, not master. Managed through gh stack: #2 → #3 → #5. Merge in that order. #2 isolates the Python-to-TypeScript tooling port; #3 owns DOMStack/data/output improvements; this PR owns the blog, author system, edit links, and shared visual follow-ups.

Screenshots

Captured with Playwright from the built site: 1440 × 1000 desktop and 390 × 844 mobile viewports, full-page screenshots. Screenshots are uploaded as GitHub attachments; no image files are included in the final PR diff or published site.

Blog index

Blog index — desktop

Year archive

2026 blog archive — desktop

Article

Hello world article — desktop

Mobile

Blog index Year archive Article
Blog index — mobile 2026 archive — mobile Hello world article — mobile

Blog and authoring

  • Replace the placeholder with a newest-first blog, generated /blog/<year>/ archives, breadcrumbs, archive navigation, and sitemap entries. Archive membership follows source directories; empty archives are removed during watch.
  • Use blog for articles and blog-index for listings, both inheriting the full root layout.
  • Publish /blog/2026/hello-world/, credited to jwerle.
  • Blog titles live in frontmatter and render as a layout-owned H1. The layout requires a nonempty title; the generator no longer duplicates it in the Markdown body. Documentation retains its existing H1-driven authoring convention.
  • npm run new-blogpost -- --author jwerle --author bcomnes "Post title" creates a dated page.draft.md and img/ directory. The generator defaults to oro-computer when no author is supplied.
  • npm run publish-draft -- [year/]slug sets the publication date and installs page.md without clobbering an existing post. Article bodies and metadata values are preserved; YAML formatting/comments may normalize.
  • Native drafts appear in preview but never in feeds. Draft assets are not private. Future publication dates control ordering, not scheduling.

Local GitHub author registry and cache

  • Store authors in src/authors/<github-username>/author-meta.json with a colocated avatar. Include downloaded profiles for bcomnes, jwerle, and oro-computer.
  • npm run import-author -- username explicitly fetches the public GitHub username/display name, website, social links, current avatar, SSH public keys, and GPG public keys. No private key material is stored.
  • Imports validate paths, URLs, response types, and payload limits; requests have deadlines. Staged replacement protects prior registry data on failure. Optional GITHUB_TOKEN is sent only to the GitHub API and never stored.
  • Posts require a nonempty authors array of registered usernames. Preserve order, reject duplicates/unknown names, and render linked names and local avatars on posts and indexes. Legacy joe/bret/oro aliases are replaced by GitHub usernames.
  • AuthorRegistry lazily reads requested authors using async I/O. Per-author promises cache successful reads and deduplicate concurrent requests. Failures are evicted for retry; clear(username?) explicitly invalidates entries. Cached author objects are frozen and returned arrays are independent.
  • Cache scope is one module instance; workers/processes have separate caches. This is an I/O cache, not another downstream fingerprint/invalidation mechanism.
  • Builds and post creation never fetch GitHub author data. Restart watch after registry edits/imports: filesystem reads do not establish DOMStack static-import dependencies.

Feeds and incremental data

  • JSON Feed 1.1 at /feed.json and Atom at /feed.xml; correct rel="alternate" autodiscovery lives in the root layout.
  • Use the small JSON Feed and RSS/Atom SVG icons from bret.io for visible subscription links, with accessible labels and titles.
  • Include the latest 20 published posts with full HTML, stable canonical IDs, all authors, and publication/update dates. JSON Feed includes absolute avatar URLs; Atom emits each author’s name and URI.
  • Absolutize content links, images, posters, and srcset; escape Atom XML.
  • Extend the existing stateful global-data index with cached blog projections and separate summary/archive versus feed-body dependencies. Body-only changes leave summary consumers unchanged; existing DOMStack fingerprints remain authoritative.

Layout and shared visual follow-ups

  • Refine index/archive/post layouts: narrower reading column, responsive heading hierarchy, author-first bylines below titles, compact feed links, and archive tabs integrated with the divider.
  • Use the shared .prose spacing for articles rather than a parallel paragraph/heading system.
  • Make default prose links graphite with subtle neutral underlines and gold hover/focus treatment; preserve specialized navigation/button styles.
  • Add source-aware “Edit this page” links to both footer variants, muted and aligned opposite copyright. Generated archives link to their factory; redirects link to the source declaring the alias.
  • Keep short-page footers at the viewport bottom and avoid the background seam. Set subnavigation headers’ top padding to 1rem without changing desktop homepage sidebar spacing.
  • Fix docs sidebar/TOC white-panel and partial-rounded-border conflicts. Desktop uses transparent surfaces and straight dividers; mobile retains complete bordered panels.
  • Fix /docs/ action-button spacing and remove stacked white group backgrounds. Individual link boxes retain opaque ivory surfaces with opaque hover/focus treatment.

Template and feed follow-ups

  • Expand layout/page/template markup into readable multiline HTML, including blog index loops and conditional sections.
  • Colocate each type-only LayoutRegistry declaration with its layout; remove the central registry file and update factory type imports.
  • Generate Atom with jsonfeed-to-atom@^1.2.5 from the shared JSON Feed data builder rather than handwritten XML. Its 1.0-only API needs a small compatibility adapter for multiple authors, stable feed identity, deterministic timestamps, and exact article HTML. Add a local TypeScript declaration.
  • Latest follow-up validation: typecheck and 26 focused blog/redirect/author-cache tests passed. The converter also passed all 75 unit tests and two isolated full builds with identical Atom output. No screenshot attachments were changed.

Layout cleanup and redirect fallback

  • Registry declarations now reference local renderer, parent, and vars bindings with typeof, rather than inline self-import types.
  • Move the listing renderer to src/layouts/blog-index.ts alongside its layout; update page/archive imports.
  • Keep redirects under the full root layout and provide a styled fallback with an H1, explanation, destination button, and docs/home links. Automatic redirect, canonical, and no-JavaScript behavior remain unchanged.
  • Validation: typecheck, blog/redirect tests, and temporary Playwright fallback checks at 1440, 390, and 320px passed.

CI fix and homepage colors

  • Use graphite for the homepage Technology label and muted text for product numbers instead of explicit purple. Verified computed colors with temporary Playwright checks at 1440px and 390px.
  • Trim surrounding template whitespace in the redirect watch test while preserving its exact destination-label assertion; fixes the failure in CI run 35459149679.
  • Validation for this follow-up: typecheck, all 75 unit tests (including redirect watch), and git diff --check passed. Full CI is pending on the updated commit.

Earlier full validation

An earlier revision passed in an isolated temporary copy, without overwriting the running site’s output:

  • Full npm run check: typecheck, build, 75 unit tests, 6 site tests, 18 desktop/mobile browser tests, 15 tooling tests, content/output audits, and reproducibility.
  • Separate node --test tools/authors/import.test.ts: 5 importer/cache tests, including in-flight deduplication, cached reads, invalidation, retry, and failed-refresh preservation.
  • Output audit: 609 HTML pages; 149,124 internal links/anchors. All seven content audits passed; repeated build output was identical.
  • Temporary Playwright design checks covered index/archive/article layouts, long titles, multiple authors, avatars, keyboard focus, and overflow at desktop/tablet/mobile widths; docs sidebar and landing-page styles were also checked.
  • Normal author-import CLI successfully downloaded all three included profiles using Node fetch.
  • Temporary fixtures, screenshots, scripts, and build outputs were removed. Focused permanent tests remain; no permanent visual-debugging suite was added.

Earlier incremental checks also verified that a body-only edit writes one article HTML page and both feeds without rewriting indexes, archives, or docs, and deleting the last post removes its year archive.

Local browsers used Brave via ORO_BROWSER_EXECUTABLE; CI status is separate. README and tools/authors/README.md document usage, cache behavior, watch limitations, drafts, archives, feeds, and source editing.

@bcomnes
bcomnes added this pull request to stack #4 September 19, 2026 01:07
@bcomnes bcomnes changed the title feat: add blog archives, feeds, authors and page edit links Add blog, year archives, authoring tools, feeds, and page edit links Sep 19, 2026
@bcomnes
bcomnes force-pushed the feat/blog-and-page-edit-links branch from f49d521 to db5d05e Compare September 19, 2026 03:59
@bcomnes bcomnes changed the title Add blog, year archives, authoring tools, feeds, and page edit links Add blog, cached GitHub author registry, feeds, and page edit links Sep 19, 2026
@bcomnes
bcomnes marked this pull request as ready for review September 19, 2026 17:10
@bcomnes
bcomnes requested review from jwerle and a lite review from Copilot September 19, 2026 17:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved archive-path, feed parsing, timestamp parsing, importer-locking, and test-coverage findings remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

This pull request adds a generated blog, cached GitHub author registry, JSON/Atom feeds, edit links, and related layout and styling updates.

Changes:

  • Added blog posts, archives, authoring tools, and publishing workflows.
  • Added cached author metadata, importer tooling, and author-aware rendering.
  • Added feed generation and incremental blog data projections.
  • Updated layouts, redirects, styling, documentation, scripts, and tests.
File Summary
tools/​blog/​shared.ts Shared blog tooling helpers.
tools/​blog/​publish.ts Draft publication workflow.
tools/​blog/​create.ts Blog post scaffolding CLI.
tools/​authors/​README.md Author registry documentation.
tools/​authors/​import.ts GitHub author importer.
tools/​authors/​import.test.ts Importer and cache tests.
tests/​tooling/​watch.test.ts Watch instrumentation updates.
tests/​redirects.test.ts Redirect source assertions.
tests/​redirects-watch.test.ts Redirect edit-link coverage.
tests/​docs-index.test.ts Redirect projection updates.
tests/​blog.test.ts Blog and feed tests.
tests/​blog-tools.test.ts Blog CLI tests.
src/​style.css Homepage and editorial styling.
src/​redirects.pages.ts Source-aware redirect pages.
src/​lib/​redirects.ts Redirect source metadata.
src/​lib/​page-vars.ts Layout registry import cleanup.
src/​lib/​navigation.ts Footer edit links.
src/​lib/​jsonfeed-to-atom.d.ts Atom converter types.
src/​lib/​blog.ts Blog validation and projections.
src/​lib/​blog-feeds.ts JSON and Atom feed generation.
src/​lib/​authors.ts Author registry and caching.
src/​layouts/​spec.layout.ts Local layout type registration.
src/​layouts/​root.layout.ts Root metadata and edit links.
src/​layouts/​registry.ts Removed centralized registry.
src/​layouts/​redirect.layout.ts Redirect fallback layout.
src/​layouts/​product.layout.ts Local type registration.
src/​layouts/​marketing.layout.ts Local type registration.
src/​layouts/​learn.layout.ts Local type registration.
src/​layouts/​docs.layout.ts Local type registration.
src/​layouts/​blog.layout.ts Article layout.
src/​layouts/​blog.layout.css Article styling.
src/​layouts/​blog-index.ts Blog listing renderer.
src/​layouts/​blog-index.layout.ts Blog listing layout.
src/​layouts/​blog-index.layout.css Blog listing styling.
src/​globals/​global.data.ts Incremental blog data indexing.
src/​globals/​global.css Shared layout and documentation styling.
src/​feed.xml.template.ts Atom feed template.
src/​feed.json.template.ts JSON Feed template.
src/​blog/​page.vars.ts Removed placeholder variables.
src/​blog/​page.ts Blog index page.
src/​blog/​page.html Removed placeholder markup.
src/​blog/​jsonfeed.svg JSON Feed icon.
src/​blog/​atom.svg Atom icon.
src/​blog/​archives.pages.ts Generated year archive pages.
src/​blog/​2026/​hello-world/​page.md Initial blog post.
src/​authors/​oro-computer/​author-meta.json Oro Computer author metadata.
src/​authors/​jwerle/​author-meta.json Joseph Werle author metadata.
src/​authors/​bcomnes/​author-meta.json Bret Comnes author metadata.
README.md Blog and authoring documentation.
package.json New scripts and feed dependency.
package-lock.json Dependency lockfile updates.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/blog/archives.pages.ts Resolved
Comment thread src/lib/blog-feeds.ts Resolved
@bcomnes
bcomnes merged commit f1d2737 into master Sep 19, 2026
1 check passed
@bcomnes
bcomnes deleted the feat/blog-and-page-edit-links branch September 19, 2026 21:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants