Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Rusty link thing.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A link aggregator for threaded.at: tagged stories, threaded comments, flags with reasons, user levels, AI-assisted triage, and a public moderation log. Sign-in is atproto OAuth. Submissions and comments are records in the author's own repo.
Working today:
THREADED_HYDRANT_SOCKET is set.Next: M5, reader features: an inbox for replies, "new" markers on threads, saved and hidden stories, tag filters, Atom feeds, posting to Bluesky, archive links, comment folding, and keyboard shortcuts. It is built and waits on a deploy and the checks done by hand. Its plan is docs/0008-m5.md. The milestone table is in the design doc, section 16.
Requires a stable Rust toolchain, from rustup.
make seed # demo tags and stories into threaded.db
make run # serve on http://127.0.0.1:8080
make check # fmt-check, clippy, test, audit, markdown lint, lexicon lint and validation
make a11y # axe-core audit of every page, light and dark, and the page scripts in Chrome
make hydrant # a local hydrant indexing at.threaded.dev.* records
make help lists every target. Some need tools beyond Rust:
| Target | Needs |
|---|---|
make audit | cargo-audit |
make md-lint | markdownlint-cli2 |
make lex-lint, make lex-validate | goat |
make a11y | Node and Chrome or Chromium (set CHROME if it is not in its default place); it installs puppeteer-core and axe-core itself |
make hooks | pre-commit |
make hydrant | a hydrant build at ../hydrant/target/release/hydrant (set HYDRANT for another path; building it is in docs/0006-m4.md). It keeps its database in ./hydrant.db and serves its API on ./hydrant.sock |
| Variable | Default |
|---|---|
THREADED_DB | sqlite:threaded.db |
THREADED_ADDR | 127.0.0.1:8080 |
THREADED_BLOG_DIR | blog |
THREADED_PUBLIC_URL | The public origin, such as https://threaded.at: the OAuth client ID and the absolute URLs in link previews. Unset: the localhost development OAuth client, and http://127.0.0.1: with the THREADED_ADDR port |
THREADED_OAUTH_KEY | required with THREADED_PUBLIC_URL |
THREADED_COOKIE_KEY | required with THREADED_PUBLIC_URL; unset in development means sessions end on restart |
THREADED_ANTHROPIC_KEY | a file holding an Anthropic API key; unset turns AI triage off |
THREADED_HYDRANT_SOCKET | hydrant's API socket, such as ./hydrant.sock from make hydrant; unset reads no records from the network |
THREADED_PLC_URL | https://plc.directory: where user review reads an account's creation time |
THREADED_TYPEAHEAD_URL | https://public.api.bsky.app: the AppView the sign-in typeahead asks |
RUST_LOG | info |
make run
Open http://127.0.0.1:8080, not localhost: atproto's development client
returns to 127.0.0.1. Sign in with any atproto account. threaded keygen DIR
writes the production key files.
A local build writes at.threaded.dev.submission, .comment, and .vote
records to your real repo; production writes at.threaded.*. Sign-in asks to
write submissions and comments. Publishing upvotes asks again, on
/settings, for vote records.
threaded tag add rust --description "The Rust language and its ecosystem"
threaded tag add meta --description "About Threaded itself" --boost -0.5
threaded tag list
tag add on an existing tag updates it. --boost is the tag's rank boost,
from -10 to 10. Both commands use THREADED_DB.
threaded role grant did:plc:... admin # or moderator; the account signs in once first
threaded role revoke did:plc:...
threaded triage check # one test item through the triage model
Roles take a DID, never a handle: a handle can pass to someone else. Admins
then work from /admin: tags, people, settings, and the site rules that AI
triage reads. AI triage runs only with THREADED_ANTHROPIC_KEY set and a
rules version saved; without either, moderation runs on flags and moderators.
Drop a Markdown file with YAML front matter into THREADED_BLOG_DIR and it is
live within a second, no restart. Editing or deleting it works the same way.
---
title: Sign-in is live
date: 2026-11-02
summary: Any atproto account can now sign in.
---
Body in CommonMark.
title and date (YYYY-MM-DD) are required. slug defaults to the file
name and cannot be feed, and draft: true hides a post. The full rules are in the design doc,
section 12. A file that fails to parse is skipped and the reason is logged.
| Route | Page |
|---|---|
/ | Front page |
/newest, /active | Newest, most recent discussion |
/top?t=day|week|month|year|all | Top by score |
/t/{tag} | Ranked within a tag |
/domain/{domain} | Newest from a domain and its subdomains |
/s/{short_id} | A story and its comments |
/s/{short_id}/edit, /s/{short_id}/delete | Edit or delete your story |
/s/{short_id}/bsky | Form target: post your story to Bluesky again after a failed try |
/c/{short_id}/reply, /c/{short_id}/edit, /c/{short_id}/delete | Reply to a comment; edit or delete yours |
/submit | Submit a story |
/comment, /vote, /flag | Form targets for comments, upvotes, and flags |
/u/{handle} | A user's stories, comments, and public upvotes; a DID works too |
/settings | Public upvotes, cross-posting to Bluesky, tag filters, keyboard shortcuts, and keeping your posts out of AI triage (form targets /settings/bsky, /settings/tags, /settings/keys, /settings/triage) |
/inbox | Comments on your stories and replies to your comments; the header shows the unread count |
/saved, /hidden | Your saved stories and the stories you hid; form targets /s/{short_id}/save and /s/{short_id}/hide |
/s/{short_id}/suggest | Suggest a story's title and tags |
/mod | Moderation queue: Holds, Flagged, Suggestions, Edits, Detached; form targets /mod/verdicts/{id} and /mod/suggestions/{id} |
/mod/s/{short_id}, /mod/c/{short_id}, |
src/main.rs CLI: serve, seed, keygen, tag, role, triage check
crates/core/ ranking, levels, policy and settings, search parser, links, tags
crates/auth/ atproto OAuth: keys, SQLite session store, sign-in flow, record writes
crates/store/ SQLite via sqlx; migrations/ at the repo root
crates/triage/ AI triage: the model request, verdicts, the worker
crates/indexer/ reading records from hydrant: the client for its socket API
crates/web/ axum router, askama templates, CSS
migrations/ forward-only SQL migrations
tests/ tests of the threaded command line
lexicons/ at.threaded.* lexicon schemas
scripts/a11y/ axe-core page audit and browser checks of the page scripts
blog/ blog posts, served from ./blog
deploy/ systemd units, nginx config, backup, update, and hydrant build scripts
docs/ design doc, deploy doc, milestone plans, and deck
third_party/ jacquard crates patched onto fixed crypto; see its README
Built on axum, askama, sqlx with SQLite, jacquard for atproto and OAuth, pulldown-cmark and ammonia for Markdown, and hydrant for reading records from the network.
MIT.
/mod/u/{did}Review a story, comment, or user, and act on it; a handle in /mod/u/ redirects to the DID |
/moderations | The public moderation log |
/moderations/stats | How often moderators agreed with AI triage |
/admin, /admin/rules, /admin/tags, /admin/people, /admin/settings | Health, site rules, tags, roles, and settings; form target /admin/breaker |
/search?q= | Search; syntax in the design doc, section 7 |
/tags | Tag list |
/blog | Blog index, newest first; ?page=2 and on |
/blog/{slug} | A blog post |
/login | Sign in with an atproto account |
/oauth-client-metadata.json, /oauth/jwks.json | OAuth client metadata and public key |
/feed, /newest/feed, /t/{tag}/feed, /domain/{domain}/feed, /u/{did}/feed, /blog/feed | Atom feeds, 30 entries each; a handle in /u/ redirects to the DID |
/healthz | Liveness |