尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A realtime social network built by AI agents with the Heliostack skills — Next.js 16, React 19.3, Postgres, zero UI/ORM/auth libraries.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A realtime social network, built by AI agents with the Heliostack skills.
Live demo → heliostack-halo.vercel.app · browse signed-out, or sign in as demo / halo-demo
Halo tests one claim: an agent that follows a small set of well-made skills can build a product-grade app on the platform alone. Timelines, threads, reposts and quotes, follows, grouped notifications, direct messages, search, trends and seven themes — in ~5,400 lines of TypeScript with five runtime dependencies.檢視完整 README ↗A realtime social network, built by AI agents with the Heliostack skills.
Live demo → heliostack-halo.vercel.app · browse signed-out, or sign in as demo / halo-demo
Halo tests one claim: an agent that follows a small set of well-made skills can build a product-grade app on the platform alone. Timelines, threads, reposts and quotes, follows, grouped notifications, direct messages, search, trends and seven themes — in ~5,400 lines of TypeScript with five runtime dependencies.
cacheComponents: true + partialPrefetching: true. Every page is partially prerendered (◐ in the build output): the shell — sidebar, header, tabs, trends — is static HTML from the CDN, and per-user parts stream in behind <Suspense>.
| Data | Treatment | Example |
|---|---|---|
| Same for everyone, minutes-stale OK | 'use cache' + cacheLife('minutes') + cacheTag(...) | trends, profile headers, hashtag counts |
| Personalised or must be fresh | uncached, <Suspense> as deep as possible | feeds (viewer's liked state), unread badges, composer |
| URL-dependent | params / searchParams promises passed down, awaited inside a boundary | /login?next=, /explore?q= |
Layouts never await request data, so navigating between pages is instant. Cache tags are built in one place (src/server/cache-tags.ts) so writers and readers can't drift.
src/features/*/server/repo.ts) are pure (db, …args) functions with no Next.js imports, which is what makes them testable against a real database.hydrate() turns them into full cards — author, counts, the viewer's like/repost/bookmark state, reply target, reposter — in a single statement ordered by unnest(...) with ordinality, plus one batched query for quoted posts. No N+1.repost_of_id), so the home timeline is one id-cursor query. A post reposted by several people you follow appears once (distinct on (coalesce(repost_of_id, id))).(1 + likes + 2·reposts + replies + 2·quotes) / (hours + 2)^1.4 with an offset cursor; the client dedupes across pages.db/migrations/0001_init.sql) — likes, reposts, replies and followers can never drift from the rows.tsvector with the simple config, so Korean and code work) plus prefix search on handles and names.Every Server Action follows the same steps — createPostAction is the reference:
requireViewer() → zod parse → repo (authorisation inside the SQL) → updateTag / refresh() → publish realtime event → ActionState
Likes, reposts, bookmarks and follows are optimistic: useOptimistic layered over locally confirmed state, so the UI flips instantly and rolls back on failure (post-actions.tsx). Every mutation is idempotent (on conflict do nothing), so double clicks are harmless.
flowchart LR
A["Server Action"] -->|"pg_notify · ids only"| DB[("Postgres")]
DB -->|"LISTEN · one per instance"| S["/api/events · SSE"]
S -->|"routed per viewer"| B["EventSource"]
B --> U["badge +1 · Show N posts · chat refresh"]
src/server/realtime)./api/events filters per viewer (posts from people you follow, your notifications, your conversations), sends a heartbeat every 20 s and closes itself before the serverless time limit; EventSource reconnects. Signed-out visitors get 204, which tells EventSource to stop.NOTIFY can't fire.scrypt from node:crypto for passwords; 256-bit random session tokens in an httpOnly cookie, stored in the database only as HMAC(SESSION_SECRET, token); sliding 30-day expiry (src/server/auth). proxy.ts does optimistic redirects from cookie presence only — real checks happen next to the data. The timeline, profiles, posts and search are public; there's no landing page.
design-system.json by the ds-init theme engine: OKLCH colours with light-dark(), 7 WCAG-checked themes, a 12/14/16 px type scale.src/ui built on the platform: <dialog> modals, Popover API menus positioned with CSS anchor positioning, @starting-style animations, and content-visibility: auto instead of a virtualization library./compose/post is intercepted by @modal/(.)compose/post and opens as a dialog over the current page; a direct visit still works.design/check-tokens.mjs) fails any raw colour or spacing value, and any CSS file that doesn't declare the cascade-layer order on line 1.node:test runs the TypeScript sources directly. useTestDb() boots a fresh in-memory Postgres (PGlite, WASM) per test file behind the wire protocol, so tests use the same driver and migrations as production — no mocks, no Docker. 26 tests cover threads, idempotent toggles, pagination edges, repost dedupe, authorisation, notification grouping and text parsing.
| Feature | Notes | Code |
|---|---|---|
| Timelines | ranked For you, chronological Following, infinite scroll via a Server Function, live "Show N new posts" | posts/ |
| Threads | ancestors via a recursive CTE, focused post, replies ranked by likes | status/[postId] |
| Profiles | cached header per handle, relationship streamed separately, posts / replies / likes tabs | profiles/ |
| Notifications | likes, reposts and follows grouped per post ("Sam and 10 others…"), read state synced across tabs | notifications/group.ts |
| Messages | 1:1 DMs, membership checked in SQL, optimistic send, IME-safe Enter to send | messages/ |
| Explore | full-text posts, people search, trends, hashtag pages | explore/ |
| Settings | theme + light / dark / system switcher (applied pre-paint, no flash), profile editing | settings/ |
Requires Node 24+ and pnpm. No Docker — local Postgres runs as WASM.
pnpm install
cp .env.example .env.local # set SESSION_SECRET (command in the file)
pnpm dev:db # Postgres (PGlite) on :5432 — keep it running
pnpm db:migrate && pnpm db:seed # 40 users, ~660 posts, likes, follows, DMs
pnpm dev # http://localhost:3000
pnpm verify # typecheck (typed routes) → ds:check → test → build
runtime next · react · react-dom · postgres · zod
dev typescript · @types/* · @electric-sql/pglite · @electric-sql/pglite-socket
Vercel + Neon (Vercel Marketplace). The vercel-build script runs migrations over the direct connection before next build.
| Variable | Purpose |
|---|---|
DATABASE_URL | pooled connection for queries (set by the Neon integration) |
DATABASE_URL_UNPOOLED | direct connection — migrations and cross-instance realtime (LISTEN) |
SESSION_SECRET | 32+ random bytes; rotating it signs everyone out |
Full walkthrough: the deploy-vercel skill.