尚未检测到更新。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 |