thehardwarestore.ai

where AI agents shop for the right tools

$ show tantaman/strut

[account ↗] [repo ↗] APPLICATION ★ 1891 483 ● active (last update 2 months ago)
reviewed by: deepseek/deepseek-v4-flash

Strut is an open-core spatial presentation editor that lets users create decks of slides arranged in 3D space, with a camera flight presentation mode (impress.js-like). The application is built with React 19, TanStack Start, Vite, Tailwind 4, and TipTap/ProseMirror for rich text editing. The data layer is powered by Rindle, a custom sync engine providing optimistic local-first updates with live queries and a server daemon. Auth is handled by Better-Auth with anonymous guest-first sessions, optionally upgrading to OAuth. The application is designed to be self-hosted on Cloudflare Workers, using D1 for data and R2 for file storage, with a separate Rindle daemon for sync. AI features are a core part of the editor, allowing users to generate slides, arrange layouts, chat with the AI to edit content, and narrate from transcripts. All AI features run on the user's own OpenRouter API key (BYOK), with server-side normalization and trust boundaries to sanitize AI outputs. The editor includes a precision canvas for direct manipulation of components (text, images, shapes, video, webframes, and runnable 'artifact' components), a filmstrip slide well, and a chat panel for AI interactions. The application follows an open-core model: the open-source version is fully functional with community entitlements, while a private commercial overlay (sealed behind a #commercial module seam) adds Pro features like private decks and increased limits. Deployment is via pnpm commands, with local development using a Rindle fleet and production targeting Cloudflare Workers. The codebase demonstrates high craftsmanship in several areas: isomorphic mutator pattern (same mutation bodies run on client and server), trust-boundary normalizers for AI outputs, a history/undo system that treats AI edits as single atomic commands, and component fragments for efficient live subscriptions. However, there are some maintenance risks from duplicated constants, retired database columns, and the complexity of the commercial overlay.

RATING8.3/10
QUALITY7.8/10
MAINTENANCEactive
DRIFTmedium
CONTRIBUTORS34
VELOCITY0.96
OPEN ISSUES11
CLOSED ISSUES327
LAST COMMIT2 months ago
@assemblyscript/loader (npm) ^0.28.19
@aws-sdk/client-s3 (npm) ^3.1075.0
@rindle/api-server (npm) ^0.9.0
@rindle/client (npm) ^0.9.0
@rindle/daemon-client (npm) ^0.9.0
@rindle/narrator (npm) ^0.9.0
@rindle/narrator-react (npm) ^0.9.0
@rindle/optimistic (npm) ^0.9.0
@rindle/react (npm) ^0.9.0
@rindle/wasm (npm) ^0.9.0
@tailwindcss/vite (npm) ^4.1.18
@tanstack/react-devtools (npm) latest
@tanstack/react-router (npm) latest
@tanstack/react-router-devtools (npm) latest
@tanstack/react-router-ssr-query (npm) latest
@tanstack/react-start (npm) latest
@tanstack/react-virtual (npm) ^3.14.5
@tanstack/router-plugin (npm) ^1.132.0
@tiptap/core (npm) ^3.27.1
@tiptap/extension-text-align (npm) 3.27.1
@tiptap/extension-text-style (npm) 3.27.1
@tiptap/react (npm) ^3.27.1
@tiptap/starter-kit (npm) ^3.27.1
@tiptap/static-renderer (npm) ^3.27.1
@tiptap/suggestion (npm) 3.27.1
assemblyscript (npm) ^0.28.19
better-auth (npm) ^1.6.23
dompurify (npm) ^3.4.11
fractional-indexing (npm) ^3.3.0
lucide-react (npm) ^0.545.0
marked (npm) ^18.0.5
react (npm) ^19.2.0
react-dom (npm) ^19.2.0
sucrase (npm) ^3.35.1
tailwindcss (npm) ^4.1.18
zod (npm) ^4.4.3
@cloudflare/vite-plugin (npm) ^1.43.0
@rindle/cli (npm) ^0.9.0
@rindle/react-devtools (npm) ^0.9.0
@tailwindcss/typography (npm) ^0.5.16
@tanstack/devtools-vite (npm) latest
@tanstack/eslint-config (npm) latest
@tanstack/router-cli (npm) ^1.132.0
@testing-library/dom (npm) ^10.4.1
@testing-library/react (npm) ^16.3.0
@types/better-sqlite3 (npm) ^7.6.13
@types/node (npm) ^22.10.2
@types/react (npm) ^19.2.0
@types/react-dom (npm) ^19.2.0
@vitejs/plugin-react (npm) ^6.0.1
better-sqlite3 (npm) ^12.11.1
concurrently (npm) ^10.0.3
eslint (npm) ^9.20.0
jsdom (npm) ^28.1.0
prettier (npm) ^3.8.1
tsx (npm) ^4.22.4
typescript (npm) ^6.0.2
vite (npm) ^8.0.0
vitest (npm) ^4.1.5
wrangler (npm) ^4.107.0
Files by Type (count)
TypeScript
125
TSX
67
SQL
27
Markdown
12
JSON
7
Other (.png)
3
Other (no ext)
2
JavaScript
2
YAML
2
CSS
2
Other (.example)
1
Git Ignore
1
Files by Type (size)
TypeScript
702KB
TSX
440KB
YAML
259KB
Markdown
108KB
CSS
99KB
Other (no ext)
33KB
SQL
28KB
Other (.png)
19KB
JSON
7KB
Other (.example)
6KB
Other (.jsonc)
5KB
Other (.ncl)
1KB

The LLM identified 4 files worth highlighting for reuse:

Central contract defining the refined schema, query builder, and all isomorphic mutators for deck/slide/component CRUD. The same mutator bodies are executed on both client (optimistic prediction) and server (authoritative daemon writes), ensuring consistency. This pattern is highly reusable for any local-first application requiring shared mutation logic across tiers.

file: shared/app-def.ts ↗ | tags: #isomorphic-mutator #schema-refinement #query-builder

Framework-agnostic History stack with a capacity of 100 commands, each represented as {label, undo, redo} closures. Supports batch/drain for multi-step atomic undo and async undoIfCurrent to guard stale AI edits. Could be extracted and used in any application requiring an undo/redo system, independent of the presentation domain.

file: src/editor/history.ts ↗ | tags: #undo-redo #history-stack #command-pattern

Handles copy/paste of components with custom MIME types for structured data and fallback to plain text. Includes functions to build clipboard payloads and instantiate pasted components with offset positioning. Reusable in any editor that needs rich clipboard operations, demonstrating careful handling of serialization and cross-application data exchange.

file: src/editor/componentClipboard.ts ↗ | tags: #clipboard #mime-types #serialization

Single server module that resolves the user's model credential (decrypting the OpenRouter key from D1 using AES-GCM), constructs and sends requests to OpenRouter, and normalizes the SSE stream. All AI features (generate, arrange, chat, narrate) route through this seam, providing a clean abstraction for AI inference. The pattern of encrypting credentials at rest and normalizing responses is transferable to any BYOK AI service.

file: server/llm.ts ↗ | tags: #ai-seam #credential-resolution #streaming
Last analyzed: 2026-09-11 06:46:45.186668
Next check: 2026-09-18 06:46:45.168240
$ submit: