Skip to content

Release v1.15.0#271

Merged
TemujinCalidius merged 6 commits into
mainfrom
dev
Jul 17, 2026
Merged

Release v1.15.0#271
TemujinCalidius merged 6 commits into
mainfrom
dev

Conversation

@TemujinCalidius

Copy link
Copy Markdown
Owner

Cuts v1.15.0devmain.

🚀 What's shipping

Added

Fixed

MINOR: two backward-compatible features, no breaking changes. Default instances render identically.

Merge with a merge commit — not squash.

🤖 Generated with Claude Code

TemujinCalidius and others added 6 commits July 16, 2026 19:28
)

GET /api/posts (My Posts) returned title/excerpt but not the body, so a
title-less microblog note (excerpt is null for notes) had nothing to display →
clients showed "Untitled note". Add a short markup-stripped `preview` per post
via postOgDescription() — excerpt, else body text (~200 chars), else "" (empty
stays empty, not the site tagline, so the client keeps its own placeholder).
content/contentHtml are selected only to derive the preview, not shipped whole.
Documented GET /api/posts in docs/app-api.md.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
) (#264)

Add an "Generate app token" action to the connected-apps admin panel so the
owner can mint a scoped bearer token out of band — for clients that accept a
pasted token (headless/CI, App Store review, read-only readers) without the
OAuth round-trip or sharing ADMIN_SECRET.

- POST /api/admin/apps { action: "create", label, scope }: validates the
  label (≤100 chars, no newlines) and sanitizes the scope (rejects empty),
  mints via the existing generateToken reveal-once primitive with
  createdVia "manual", and returns the RAW token exactly once. Only the
  sha256 hash is stored, so a lost token is revoked + reissued.
- AppsClient: a label + scope-checkbox form, and a one-time reveal box
  (copyable token + "shown once" warning). "Generated token" source label.
- Long-lived + revocable from the same screen (reuses revoke/edit_scopes).
- Documented alongside the OAuth flow in docs/app-api.md; CHANGELOG entry.
- Tests: CSRF/admin gating, mints once + sanitized scope + manual source,
  rejects empty/unknown scope and oversized label, defaults the label.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…+ list (#250 Phase 3) (#265)

Start themeable *layout* (not just colour): the home/blog feed now renders
through a region dispatcher, with the current look extracted verbatim as the
default `cards` variant (pixel-identical) and a new compact `list` variant.

- src/lib/themes: a region×variant layout contract. `Theme.layout` gives each
  theme a per-region preset (default → feed: "cards"); `resolveLayout(themeId,
  overrides)` composes the theme preset with per-region overrides, honouring an
  override only when it's a known variant (empty/stale → theme default).
  `LAYOUT_REGIONS` catalogues the variants for validation + the future admin UI.
  Extracted the theme registry into registry.ts so layout.ts can resolve a
  theme without a barrel-import cycle.
- Config plumbing (#59 pattern): `layout.feed` key (env `LAYOUT_FEED`, empty =
  inherit theme), `RuntimeSiteConfig.layout`, overlay + validation (known
  variant or "").
- Components: `PostFeed` dispatcher → `cards` (reuses PostCard, verbatim) or
  `FeedList` (a date-led, image-free, reading-first index). Home page resolves
  the variant and renders through it.
- Tests: resolveLayout/isFeedVariant (defaults, override wins, empty/bad →
  default), layout.feed overlay + validation. 478 pass.

Foundation for the header/shell/post variants and the "Classic Blog" theme,
which plug into the same dispatch pattern. A default instance is unchanged.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… (#266)

Surface the now-wired `layout.feed` region variant in Admin → Site settings →
Appearance, so an owner can switch the homepage/blog feed between "Cards" and
"List" from the panel (no env editing, no restart) — the same save/clear +
60s-cache path as every other #59 setting. Adds a reusable `<select>` field
helper. Config plumbing + validation already shipped in Phase 3; this makes it
usable in-app.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…homepage (#267) (#268)

Phase 3's `layout.feed` (cards/list) was only wired into the homepage; every
other post-list surface still hard-coded the old cards rendering, so switching
to List had no effect on them.

- journal + articles: render own posts through the existing PostFeed dispatcher
  (resolve layout.feed, same as the homepage) instead of a hard-coded
  `space-y-12` + PostCard block.
- fediverse (public feed): extract the inline FediCard into a component
  (verbatim → the `cards` variant), add a compact FediList (`list` variant),
  and a FediFeed dispatcher — the FediPost analogue of PostFeed — honouring the
  same layout.feed key. Matters for the demo site.
- admin timeline (/timeline) intentionally left out for now — a private,
  interactive client view; tracked as a follow-up in #267.

Also: htmlToText now decodes HTML entities (single pass, tags-stripped-first so
a decoded `<` is never re-parsed as markup). Surfaced by the new FediList
snippet, but fixes every plain-text preview — search results, OG/link-card
descriptions, notification bodies — which showed `&#39;`/`&amp;` literally.

Default `cards` stays pixel-identical everywhere (verbatim extractions);
adversarial review confirmed no rendering/XSS/type regression. 482 tests.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Roll the Unreleased block into a dated 1.15.0 section and bump
package.json + lockfile 1.14.0 → 1.15.0.

MINOR: two backward-compatible features (swappable feed layouts across all
feeds #250/#267; scoped reveal-once app tokens #255), the /api/posts body
preview #253, and the entity-decode preview fix. No breaking changes.

Co-authored-by: Samuel Lison <samuel@slcolonies.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@TemujinCalidius
TemujinCalidius merged commit 4d263a6 into main Jul 17, 2026
9 checks passed
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.

1 participant