Skip to content
Resource
DocsTourSlicesBest PracticeAgentsInstall

Command Palette

Search for a command to run...

New
  • Changelog

Changelog

Release notes

Changelog

What changed in each rr release — page 18 of 25. Full prose history in CHANGELOG.md.

MAY312026
FeatureCK-1PMay 31, 2026

appshell — manifest-driven desktop + mobile OS shell, lifted from os-vps

New tier-3 slice: a generic, brand-free OS-style shell framework. One <AppShell manifest> wrapper provider gives any project a macOS-style window manager (drag/snap/maximize, dock with macOS click-to-focus + hover window switcher, menu bar, ⌘K Spotlight) AND an iOS-style mobile surface (home pager, app library, control center, widgets). Everything project-specific arrives through the manifest: brand, apps, features, surface regions, capabilities (data/auth/AI injection seam), persistence, keymap. The five shell features (search, inspector, notifications, control-center, widgets) ship bundled inside the slice as defineFeature() contributions that mount into named <Slot>s — `rr add appshell` installs the whole shell as one unit. Responsiveness is a single ResponsiveProvider + 4 DRY primitives (AppFrame, MasterDetail, ResponsiveToolbar, TouchList). Lift hardening: the slice was made fully self-contained (imports nothing but @/components/ui/* + @/lib/utils — ResponsiveDialog and a graceful useIsMobile were pulled in-slice), and four oversized files were split under the 200-LOC cap (store, responsive-dialog, menu-bar, mobile-app-library). Source: os-vps (Topside).

Slices touched

  • appshell — lifted from os-vps; desktop+mobile shell, 5 features bundled (new, 0.1.0)
MAY302026
Featurelibrary@0.1.0May 30, 2026

library slice — resource hub (prompts · visuals · snippets · links), lifted from rahmanef.com

Backfilled entry for lift commit 2c3b745 (2026-05-30) — the slice landed in the catalog but skipped its changelog entry, so RecentlyUpdatedBadge never fired. One polymorphic libraryItems table holds six kinds (prompt, image, video, link, download, snippet) with per-kind payload fields switched on kind — no joins. Attribution-first (source/license/tools on every item), collections, Convex-backed with index-bounded queries (no bare .collect()). Public surface: filterable card grid + per-item detail with copy-to-clipboard for prompts/snippets and an opt-in upvote control (consumer-owned backend). Brought to project bar before landing: six raw <button> converted to shadcn <Button>, className branches cn-merged, 200-LOC cap splits on mutations + detail view. Peers the seo slice for override fields.

Slices (new)

  • library 0.1.0 — polymorphic 6-kind resource hub: Convex schema + queries/mutations, filterable grid, detail + copy + upvote
MAY282026
FixCK-1OMay 28, 2026

Empties the CK-1L deferred list: newsletter rate-limit + orphaned checkEmail removed

Closes the last two CK-1L (Lane A) deferrals. (1) newsletter.subscribe — the lite subscribe mutation had no abuse defense beyond an email-shape check, so it now mirrors the hardened `subscribers` slice: a honeypot field (`website`), a per-email windowed rate-limit (new `newsletterSubscribeAttempts` table + `by_email_time` index, 3 attempts/hour), and an explicit `returns` validator. Idempotency + status flow unchanged; the new optional `website` arg is non-breaking. resend-newsletter 0.1.1 -> 0.1.2 (its slice.manifest.json was also stale at 0.1.0 and is corrected). (2) convex-auth — removed `convex/features/auth/checkEmail.ts`, an orphaned httpAction port (anti-enumeration email check + signin-attempt throttle) that imported non-existent `_shared/clientIp` + `_shared/origin` and queried a `loginCheckIpEvents` table defined in no schema. It was wired into no http router and called by no frontend, yet shipped to every consumer through the convex-auth `convexFiles` glob — breaking their `convex dev`. Removed rather than restored: nothing consumes it, and restoring would build an unused speculative feature (the design survives in git history if ever wanted). convex-auth 0.2.0 -> 0.2.1. Note: true per-IP rate-limiting would need an httpAction (Convex mutations can't read request headers); per-email + honeypot matches the production-grade subscribers pattern. convex/** is outside the root typecheck, so the new table's _generated types land on the next `convex dev` — code mirrors deployed slice patterns to stay correct-by-construction.

Slices touched

  • resend-newsletter — honeypot + per-email rate-limit + returns validator on subscribe (0.1.1 -> 0.1.2)
  • convex-auth — removed orphaned/broken checkEmail.ts (0.2.0 -> 0.2.1)

CK-1L deferred list

  • All three CK-1L follow-ups now closed — admin.stats gate (CK-1N), newsletter rate-limit + checkEmail (here).
MAY282026
FixCK-1NMay 28, 2026

Closes CK-1L deferral: admin.stats now requireAdmin-gated

Follow-up to CK-1L (Lane A) closing the highest-severity deferred item: `convex/features/admin/query.ts:stats` was a public, unauthenticated `query` returning dashboard counts plus the 12 most-recent activity rows across every table — including contact-submission names/emails — so any caller could read it over WebSocket. The `admin` slice already advertised "Gated by requireAdmin on Convex side" in its slice.json, README, agent recipe, and catalog entry, so this is a documented-contract drift rather than a behaviour change: the handler now calls `await requireAdmin(ctx)` first (the same gate used by services/subscribers/testimonials/create-your-mcp, honouring the `SUPER_ADMIN_EMAIL` bypass). No call site in this repo is affected — the rr site's own /admin is cookie-gated and reads a local filesystem loader, never the Convex query; only consumer projects that `rr add admin` and wire `api.admin.stats` were exposed. admin slice patch bump 0.2.0 → 0.2.1. The two remaining CK-1L deferrals (newsletter per-IP rate-limit table; auth/checkEmail.ts missing `_shared` siblings) need a Convex dev loop to verify and are left for a focused pass.

Slices touched

  • admin — stats query now requireAdmin-gated, matching its documented contract (0.2.0 → 0.2.1)

Follow-ups (deferred)

  • newsletter/subscribe per-IP rate-limit still needs a schema table (CK-1L item 1)
  • auth/checkEmail.ts missing `_shared/clientIp` + `_shared/origin` + `loginCheckIpEvents` schema — restore-or-delete needs Convex verification (CK-1L item 2)
MAY282026
ImprovementCK-1MMay 28, 2026

Lane B+C: catalog→install UX + responsive + a11y P0 fixes

Eight P0 findings from the post-Phase-6 UI/UX + user-flow audit, shipped as one site wave (no consumer-slice API change beyond two preview pages). Flow: (1) catalog grid cards now carry a `RecentlyUpdatedBadge` corner overlay so freshness is scannable from /slices without opening each detail page — added a generic `cornerBadge` slot to `CatalogCard` (reusable by templates/layouts/recipes). (2) slice-detail HeroStrip gained a `CopyButton` next to the install command (was a truncated, un-copyable code chip — the page's primary CTA) plus an 'Already installed?' secondary line showing `npx rahman-resources update <slug>` so returning users find the update verb. (3) Branded `not-found.tsx` + `error.tsx` under `app/(docs)/` — typos/deleted-slice links + uncaught route errors now land on on-brand pages with recovery CTAs instead of the raw Next default (covers 60+ routes). Responsive + a11y: (4) slice-detail header strip stacks `flex-col` on mobile (was overflowing the action cluster below the h1 at ≤480px). (5) KIND_CLASS badge colors switched to dual-mode `text-{c}-700 dark:text-{c}-300` (were dark-only 300-level = WCAG contrast fail on light bg). Hard-rule compliance: (6) contact-form-resend preview raw `<input>/<select>/<textarea>` → shadcn `Input`/`Select`/`Textarea`/`Label` (this is the canonical contact slice consumers copy). (7) ai-router preview raw `<textarea>` → shadcn `Textarea`. (8) image-gallery block-renderer raw `<img>` (w/ eslint-disable) → `next/image` (unoptimized, since URLs are consumer-supplied). Deferred to a focused pass: /build mobile collapse (needs ThreeColumn→Tabs refactor + browser verification).

Site

  • CatalogCard — new `cornerBadge` slot; /slices grid shows RecentlyUpdatedBadge per card
  • HeroStrip — CopyButton on install command + 'Already installed?' update-command line
  • app/(docs)/not-found.tsx + error.tsx — branded 404 + error boundary with recovery CTAs
  • slice-detail-header — flex-col mobile stack + dual-mode KIND_CLASS badge colors (WCAG)

Slices touched

  • contact-form-resend — preview page raw form inputs → shadcn primitives
  • ai-router — preview page raw textarea → shadcn Textarea

Follow-ups (deferred)

  • /build mobile: collapse nested ThreeColumnLayoutAdvanced to Tabs at <md (needs browser verification)
  • version-pin selector on install command (--ref vX.Y.Z)
MAY282026
FixCK-1LMay 28, 2026

Lane A: P0 security patch — 7 fixes across 8 backend slices

Cross-slice security batch from the post-Phase-6 audit. Zero P0 surfaced, but seven P1 findings warranted same-day patches before more slices accreted around the same patterns. Per-slice changes: (1) `payment.markPaid` now verifies `order.userId === requireUser(ctx)` so a logged-in user can no longer flip another user's order to paid by guessing the (string) orderId. (2) `payment.get` and `payment.getOrderByOrderId` are now owner-only — anon callers + non-owner authenticated callers get null instead of full order detail (amount, channel, instructions). (3) `comments.listForTarget` flipped from public `query` to `_listForTarget` `internalQuery` with default-deny semantics — consumers MUST wrap with their own target-visibility gate; ships with doc-comment example. (4) `newsletter.broadcastPublic` admin gate is now enforced (`isAdminUser` internalQuery checks `userProfiles.role==='admin'` or `SUPER_ADMIN_EMAIL`) instead of the TODO comment that any-logged-in could bypass. (5) `newsletter.subscribe` validates email shape (`^[^\s@]+@[^\s@]+\.[^\s@]+$`) + length cap (200 chars) + normalises before insert — partial defense; per-IP rate-limit table deferred to follow-up since it needs schema migration. The canonical `subscribers` slice already has the full hardened pattern (honeypot + windowed rate-limit + unsubscribe token); recommended for production. (6) Unbounded `.collect()` on public/internal queries replaced with explicit caps: `services.listAll` 500, `socials.listAll/listVisible` 200, `testimonials.listAll` 500, `seo.callsInWindow` 1000, `newsletter.activeSubscribers` 10000. Defense-in-depth — these tables would otherwise grow unboundedly on adopted projects with no read-time guard. Eight slice patch bumps: doku-payment 0.1.1, midtrans-payment 0.1.1, resend-newsletter 0.1.1, comments 0.2.1, services 0.1.1, socials 0.1.1, testimonials 0.1.1, seo 0.2.1.

Slices touched

  • doku-payment + midtrans-payment — markPaid owner-check + get/getOrderByOrderId owner-only (0.1.0 → 0.1.1)
  • resend-newsletter — broadcastPublic admin gate + subscribe email validation (0.1.0 → 0.1.1)
  • comments — listForTarget flipped to internalQuery default-deny (0.2.0 → 0.2.1)
  • services — listAll bounded to 500 (0.1.0 → 0.1.1)
  • socials — listAll/listVisible bounded to 200 (0.1.0 → 0.1.1)
  • testimonials — listAll bounded to 500 (0.1.0 → 0.1.1)
  • seo — callsInWindow .collect() bounded to 1000 (0.2.0 → 0.2.1)

Follow-ups (deferred)

  • newsletter/subscribe needs a `newsletterSubscribeAttempts` schema table for per-IP rate-limit on par with subscribers/mutation.ts
  • auth/checkEmail.ts references missing `_shared/clientIp` + `_shared/origin` — restore or delete (file is functional, just unwired)
  • convex/features/admin/query.ts:stats unauthenticated — gate for production-grade deployments
MAY272026
ImprovementCK-1KMay 27, 2026

notion-database 0.13.0 — typed AST formula engine (CK-1D Phase 6)

Last big CK-1D phase. Replaces the flat single-file regex evaluator (`lib/formula.ts`) with a typed AST engine under `lib/formulaEngine/` ported from notion-page-clone. Eight focused submodules, each ≤200 LOC: `types` (FormulaValue union + AST node shapes + FormulaError), `coerce` (toString/toNumber/toBoolean/toDate/isEmpty), `dateUtils` (UTC addUnit/diffUnit/formatDate), `ParserClass` (Pratt-style recursive-descent w/ source positions), `parser` (top-level dispatch — template / `=math` / bare call), `functions` (29-fn dispatch w/ arity throws), `evaluator` (AST walker w/ circular-ref guard + memoisation cache), `deps` (static `collectDeps` walker). New typed FormulaValue (string/number/boolean/date/null/list) replaces string-only returns — host gets exact runtime types. Circular-reference detection via visited-set throws FormulaError before infinite recursion. Per-call memoisation cache reuses evaluated formula values across an eval tree. New fn surface: `substring`, `dateAdd`, `dateSubtract`, `dateBetween`, `formatDate`, `count`, `sum`, `join` — on top of every existing fn (concat/lower/upper/length/contains/replace/if/and/or/not/empty/round/floor/ceil/abs/min/max/now/today). Relation refs (`{{Tasks}}`) now resolve to a `list` of target-page titles when `pages` is passed through NotionDatabase. FormulaCell upgraded — popover surfaces parse-error message + source position; cell display flips to destructive style + tooltip on invalid expression; preview line updates live as the user types. Legacy `evaluateFormula()` string wrapper preserved (back-compat) but routes through the new engine. New imports: `evalFormula`, `formatFormulaValue`, `collectDeps`, `parseFormula`, plus typed exports `FormulaValue`, `EvalContext`, `EvalResult`, `FormulaError`, `Node`, `ExprNode` from `@/features/notion-database`. Parity tracker: rr ↔ open-silong now ~88% (Phase 6 closes the formula gap; remaining deferred: SubItemsPicker, table-dnd column/row reorder, PropertyFormInput, RowActionsMenu keyboard nav).

Slices touched

  • notion-database — typed AST formula engine + 8 new fns + circular-ref guard (0.12.0 → 0.13.0)

New files

  • frontend/slices/notion-database/lib/formulaEngine/{types,coerce,dateUtils,ParserClass,parser,functions,evaluator,deps,index}.ts — 9-file typed AST engine

Touched files

  • lib/formula.ts — slimmed to barrel + legacy evaluateFormula() wrapper
  • components/cells/FormulaCell.tsx — inline parse-error + live preview + relation-pages prop
  • components/property-cells.tsx — passes `pages` through to FormulaCell
MAY272026
FeatureCK-1JMay 27, 2026

activity 0.1.0 — public productivity log + MCP-friendly Convex backend, lifted from rahmanef.com

First 'now-page' / productivity-log slice in the catalog. Public-facing weekly activity log grouped by ISO week with schema.org-friendly markup, designed to maximise SEO so the question 'what is <person> working on this week?' lands here. Convex-backed: schema (`activities` table + `by_visibility_occurredAt` index), queries (`listAll`, `listPublic`, `get`, `statsThisWeek`), unauthenticated mutations (`create`, `update`, `remove`, `seed`) the consumer wraps. MCP-friendly — designed so AI workflows (Claude / GPT / custom agents) can append entries via the consumer's MCP server. ActivityFeed view split from a 225-LOC monolith into 1 view + 2 sub-components (`StatsPanel`, `ActivityItem`) + 4 lib helpers (`grouping`, `format`, `types`, `defaults`) for the 200-LOC cap. All user-facing copy + per-category labels + date/time locale are prop-driven with English defaults — original Indonesian strings + project-specific MCP-integration copy lifted out. Custom `<Section>`/`<Heading>` primitives + brutalist Tailwind utilities (`tracking-brutal-sm`, `border-foreground`) stripped — replaced with raw semantic elements + stock utilities (`tracking-wider`, `border-2`). Project-specific `seedDefaults` mutation (3 hardcoded rahmanef.com seed rows) dropped in favour of generic `seed`. Cross-slice `requireAdmin` import dropped — mutations ship as `internalMutation` and the consumer wraps them.

Slices touched

  • activity — first release, lifted from rahmanef.com (0.0.0 → 0.1.0)

New files

  • convex/features/activity/{_schema,queries,mutations,index}.ts — Convex backend
  • frontend/slices/activity/views/ActivityFeed.tsx — top-level view (~90 LOC)
  • frontend/slices/activity/components/{StatsPanel,ActivityItem}.tsx — view sub-components
  • frontend/slices/activity/lib/{types,defaults,grouping,format}.ts — helpers + prop types + English copy defaults
  • frontend/slices/activity/{slice.json,slice.contract.ts,slice.manifest.json,README.md,config.ts,index.ts}

Dependencies

  • convex ^1.17 (schema + queries + mutations)
  • lucide-react ^0.400.0 (ArrowUpRight, Clock, Tag icons in ActivityItem)
  • next ^15 (next/link in ActivityItem)
  • react ^18
MAY272026
FeatureCK-1IMay 27, 2026

i18n-translate 0.1.0 — Google Translate widget, lifted from rahmanef.com

First on-the-fly localization slice in the catalog. Drop `<GoogleTranslate />` anywhere — no API key, no Google Cloud billing, no hand-maintained dictionaries. Auto-detect browser language on first visit (cookie set BEFORE Google's script loads so first paint is already translated), persist user choice via localStorage, click-to-reload language switching with router-refresh + best-effort-in-place fallback strategies. Source was a 510-LOC monolith at rahmanef.com `slices/i18n-translate/components/GoogleTranslate.tsx`; split during lift into 8 sub-files (`components/GoogleTranslate.tsx`, `hooks/useGoogleTranslate.ts`, `lib/{widget,cookie,storage,styles,defaults,types}.ts`) for the 200-LOC cap. Project-specific Tailwind utilities (`tracking-brutal-sm`, `border-[length:var(--border-width,2px)]`) stripped from defaults — replaced with stock `tracking-wider` + `border-2` so the slice renders cleanly without a brutalism preset. Consumer must add the CSP allowlist in README.md to their middleware/proxy for Google's script to load.

Slices touched

  • i18n-translate — first release, lifted from rahmanef.com (0.0.0 → 0.1.0)

New files

  • frontend/slices/i18n-translate/components/GoogleTranslate.tsx — dropdown UI (110 LOC)
  • frontend/slices/i18n-translate/hooks/useGoogleTranslate.ts — stateful hook (87 LOC)
  • frontend/slices/i18n-translate/lib/widget.ts — Google widget plumbing (script + combo dispatch) (102 LOC)
  • frontend/slices/i18n-translate/lib/{cookie,storage,styles,defaults,types}.ts — sub-module split for 200-LOC cap
  • frontend/slices/i18n-translate/{slice.json,slice.contract.ts,slice.manifest.json,README.md,config.ts,index.ts}

Dependencies

  • lucide-react ^0.400.0 (ChevronDown icon in trigger button)
  • next ^15 (useRouter for the "router" refresh strategy)
  • react ^18
MAY252026
FeatureCK-1HMay 25, 2026

icon-picker 0.3.0 — Phosphor fill variant + smart positioning + dialog fallback

Lifted from open-silong. The picker gains a second icon variant (Phosphor fill, color-aware) parallel to Lucide outline, surfaced via a two-tab layout (Emoji | Icon) with sub-variant pills (Native | Twemoji / Lucide | Phosphor). Storage adds a new `phosphor:Name?c=hex` form parallel to `lucide:Name?c=hex` — back-compat with every existing emoji + lucide value. Smart positioning: PopoverContent now caps height to Radix's `--radix-popover-content-available-height` CSS var and falls back to a centered Dialog when neither side fits ≥340px usable vertical (or viewport <360px wide) — fixes off-screen clipping on tight viewports + small mobile screens. Inline picker restructured to flex column with `min-h-0` so it adapts to either container. `style-pref.ts` renamed its localStorage key `nosion:iconStyle` → `icon-picker:style` with one-shot legacy migration so existing consumers keep their Twemoji/native preference.

Slices touched

  • icon-picker — phosphor variant, smart popover positioning, flex-resizable inline body (0.2.0 → 0.3.0)

New files

  • frontend/slices/icon-picker/lib/phosphor-catalog.ts — 190 phosphor names grouped by category
  • frontend/slices/icon-picker/lib/phosphor-icons.ts — curated named-import surface for @phosphor-icons/react (tree-shake-safe)
  • frontend/slices/icon-picker/components/picker-parts/IconTab.tsx — combined Lucide+Phosphor tab (replaces LucideTab.tsx)

Dependencies

  • @phosphor-icons/react@^2.1.10 added to dependencies
  • deps.shadcn += dialog (smart fallback uses it)
NewerPage 18 / 25Older