尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證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 |