Sno Station
Sno Station은 AI 에이전트를 하나의 팀으로 묶는 오픈소스 워크스테이션으로, 로컬 머신에서 에이전트 협업을 가능하게 함
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Turns the coding-agent tips you save from LinkedIn, X, Reddit and YouTube into briefs your agent can try. Scoring runs on Jev, TypeSafe's decision model, through your OpenRouter key. Sieve is independent and not made by TypeSafe.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A Chrome extension that tells you which LinkedIn, X, Reddit and YouTube posts are worth your attention. For
developers, it turns techniques worth trying into briefs your coding agent (Claude Code,
Codex, Cursor and others) can try in your repo. It never clicks, comments or posts for you, and never installs
or runs anything: a brief is text you copy.
A paid Sieve account is coming: no API keys to manage, and one library across Chrome and iPhone (Sieve for iPhone is
in App Review). Join the waitlist. The extension stays free and open source.README 전문 보기 ↗A Chrome extension for developers who build with coding agents. It turns techniques worth trying, from LinkedIn, X, Reddit and YouTube posts, into briefs your coding agent (Claude Code, Codex, Cursor and others) can try in your repo, and it scores those feeds so you see which posts are worth your attention. It never clicks, comments or posts for you, and never installs or runs anything: a brief is text you copy.
A paid Sieve account is coming: no API keys to manage, and one library across Chrome and iPhone (Sieve for iPhone is in App Review). Join the waitlist. The extension stays free and open source.
Scoring runs on Jev, TypeSafe's decision model, reached through your OpenRouter key (or directly, with a TypeSafe key, if you have one and no OpenRouter key). Sieve is an independent project, not made by TypeSafe. Jev doesn't generate text: it picks from answers you define and returns a probability. When OpenRouter can't reach Jev, a general model is asked the same questions through OpenRouter and answers in the same shape. Either way the scorer makes the narrow calls (is this worth reading? could I answer this?), plain code handles the rules, and you do the part that needs judgement.
LinkedIn feed
Reddit (www and old.reddit)
YouTube
X
Technique briefs
chrome:..., the id your agent sees once
Your agent is on and the item has been sent), it's the last line, so an agent with Sieve's tools can find
the brief and, if you agree, record how it went. A brief with a warning gets the id alone, with no offer to record anything.Daily learnings
Settings (right-click the icon → Options, or Settings in the popup). Since 1.5.0 the page follows Sieve for iPhone's design: Your agent comes first, and every change saves as you make it (a field when you leave it, a switch or choice at once), with a short "Saved" note. Keys save only through Check and save keys:
chrome://extensions → Developer mode → Load unpacked → this folder.deepseek/deepseek-v4-flash by default. Checked against the API before it's saved.
Start here's Connect OpenRouter gets one through OpenRouter's sign-in window (OAuth with PKCE): OpenRouter makes a key labelled "Sieve for Chrome" in your account, and it's checked and saved exactly like a pasted one. Paste a key instead goes to the field.Keys live only in chrome.storage.local in your browser profile. Sieve sends data to two services at most and
nowhere else, unless you turn on sending to your agent (see Your agent below). Scoring requests go to OpenRouter, which passes them to TypeSafe for Jev; when OpenRouter can't
reach Jev, the same request goes through OpenRouter to a fixed general model (DeepSeek V4 Flash) instead; with
only a TypeSafe key, they go straight to TypeSafe. Whoever receives a scoring request gets what is scored: a
post's text (for YouTube, the title, channel and length, the text YouTube shows with the tile, and for a tile
that shows none, the first 1,500 characters of the description), your role and topics, and on Reddit your
Reddit facts. OpenRouter gets a post's text when you ask for a brief (with your role and topics), your saved posts (except any Sieve left out) when you ask for a digest, and a
video's link, title and channel (with your role and topics) when you have it watched. OpenRouter passes each
request to the model you picked, except scoring, which goes to Jev (or, as the fallback, DeepSeek V4 Flash).
test/compare_scorers.mjs on 24
Sep 2026.Off by default, and for now only for people Sieve has invited. Settings > Your agent sends your Chrome library to Sieve's server, so a coding agent you connect there can read it next to your iPhone pins.
identity permission (for the sign-in window) and access to mcp.divergada.com are
optional. Chrome asks for them only when you click Turn on, and Sieve gives them back when you turn it off.
Connect OpenRouter asks for identity alone, for OpenRouter's sign-in window, and gives it back when
it's done unless sending to your agent is on or signing in.If usage stats are on (see below), the daily counts also say whether sending to your agent is on, as "on" or "off". They never carry your email or anything from your library.
Off by default. The popup asks once, and Settings > Usage stats turns it on or off. Consent can only be
changed from Sieve's own pages (the popup or settings), never from a script on a feed page. Only after a yes, once a day, the extension sends Google Analytics
counts for each finished day you used it: posts scored, saved, briefed, copied as a prompt, watched, put
in a digest and exported, per platform, with the extension version, which scorer answered, whether sending to your agent is on, and a random
install ID made in your browser. Never post text, links, names, titles, facts, keys or anything you type.
Turning it off deletes the ID and any unsent counts. All of it is in analytics.js, with a comment at the
top saying exactly this.
It's a plain POST to the GA4 Measurement Protocol from the service worker, so no Google script is loaded
and no permission is needed. The Measurement ID and API secret ship inside the store package, so they
aren't secret; the events are kept narrow so made-up ones can only inflate counts. A build from this repo
has empty values in analytics-config.js and sends nothing. The store package gets the real values from
an untracked analytics-config.local.js: node tools/store-zip.mjs refuses without that file, rebuilds
the config from its two checked lines (so nothing else in the file ships), and --no-analytics leaves
the values out.
The tests use invented posts (test/sample.json, test/hostile.json, test/reddit_test.mjs). Keys come from
TYPESAFE_API_KEY / OPENROUTER_API_KEY, or on macOS from Keychain items typesafe-api-key / openrouter-api-key.
The live scoring scripts (run_triage, reddit_test, compare_scorers) reach Jev through OpenRouter, as the
extension does, so they need only the OpenRouter key; score_latency also times Jev direct with the TypeSafe key.
node test/rules_test.mjs # the rules on top of the score (offline, no keys)
node test/youtube_text_test.mjs # what a YouTube tile says beyond its title, and asking YouTube for the description (offline)
node test/score_test.mjs # scoring through the real worker: which endpoint answers for each key, Jev's errors, the fallback to the chat scorer, cost, and the chat prompt and parser (offline)
node test/watch_parse_test.mjs # the video answer parser (offline)
node test/brief_parse_test.mjs # technique briefs: shape, safety header, prompt text (offline)
node test/brief_prompt_test.mjs # the post brief prompt and its parser (offline)
node test/linear_regex_test.mjs # the dash and bare-domain patterns: the same matches as before, linear on hostile text (offline)
node test/warned_filters_test.mjs # a warned brief: shells by path, look-alike pipes, missed links, every field rewritten (offline)
node test/digest_prompt_test.mjs # the digest prompt, which posts reach it, the Left out note (offline)
node test/digest_worker_test.mjs # the digest through the real worker: flagged posts never sent (offline)
node test/export_test.mjs # the library export (offline)
node test/brief_storage_test.mjs # briefs and saved posts kept apart per platform, a cross-post digested once, through the real worker (offline)
node test/linkedin_post_id_test.mjs # finding a LinkedIn post's id in the page's data (offline)
node test/watch_drawer_test.mjs # the "watched for you" drawer, built line by line like youtube.js used to (offline)
node test/video_platform_test.mjs # Watch it for me on a platform other than YouTube (offline)
node test/agent_sync_test.mjs # sending the library to your agent: sign-in URL and answers, the body, the hash, the words, and that Copy as prompt's Sieve id matches what is sent (offline)
node test/agent_sync_worker_test.mjs # the worker's sign-in, sends, retries, turning off and deleting, against a fake server (offline)
node test/agent_sync_options_test.mjs # the settings page's Your agent section (offline)
node test/openrouter_connect_test.mjs # Connect OpenRouter: the sign-in URL, the callback, the code-for-key exchange, and Start here's button (offline)
node test/options_autosave_test.mjs # the settings page saves each change as it's made, and on closing the tab (offline)
node test/analytics_test.mjs # opt-in usage stats: counting, consent, the daily send (offline)
node test/analytics_worker_test.mjs # the worker counts actions only after a yes (offline)
node test/store_zip_test.mjs # the store package: leaves out tests and tools, refuses forbidden words and missing loads (offline)
node test/fake_dom_test.mjs # the fake DOM test helper itself (offline)
node test/x_post_data_test.mjs # X's page data: full text, reply chain, pictures and video (offline)
node test/x_thread_test.mjs # X threads: checking page summaries, finding the thread, brief and watch requests (offline)
node test/x_brief_worker_test.mjs # X briefs through the real worker: pictures, the vision model, threads (offline)
node test/x_page_test.mjs # x.js on a fake X page: threads, pictures, Watch it for me (offline)
node test/recycled_tiles_test.mjs # a YouTube tile or X post element reused for another video or post: the old verdict goes, the new one is scored (offline)
node test/theme_contrast_test.mjs # the popup, settings and daily learnings pages' light and dark colours and their contrast (offline)
node test/popup_test.mjs # the popup: Add your key until a key is saved, and the rest of its states (offline)
node test/digest_page_test.mjs # the Daily learnings page (offline)
node test/welcome_test.mjs # a fresh install opens settings, where Start here shows until a key is saved (offline)
node test/brief_test.mjs # briefs for invented and hostile posts, checked (set RUNS=3 to repeat each post, at most 4), under 1 US cent
node test/run_triage.mjs # LinkedIn scoring with Jev through OpenRouter (PREFS=file.json to score as someone else)
node test/reddit_test.mjs # Reddit scoring with Jev through OpenRouter
node test/digest_test.mjs # a digest with three probes aimed at the summariser, checked (RUNS=3 to repeat), under 1 US cent
node test/watch_test.mjs # Watch it for me on one public video (VIDEO=url), about 1 cent
node test/x_live_test.mjs # an X picture brief on Flash-Lite and Flash, and an X video watched, under 1 US cent
node test/compare_scorers.mjs # the invented sets scored by Jev (through OpenRouter) and by OpenRouter chat models side by side, with cost; SET=reddit, youtube or hostile (live, a few cents); TITLE_ONLY=1 with SET=youtube scores the tiles as 1.3.0 did
node test/score_latency.mjs # times Jev direct, Jev through OpenRouter and chat models on five invented Reddit posts, a cent or so
On the invented set, Jev's LinkedIn scoring matched the intended tier on 7 of 8 (a "built a small tool" post scored high where it was labelled maybe) and Reddit on 5 of 6 (the shared-inbox question scored 0.52, maybe instead of high).
[role=listitem][componentkey^="update-card-"] and [data-testid="expandable-text-box"]. Reddit uses
<shreddit-post> attributes. If badges stop appearing, those changed. Reddit shows a note if it can't find posts.
A LinkedIn post's own link comes from the page's React data (linkedin-post-id.js); if briefs start linking
to the author's profile instead of the post, that changed.prefs.js: default settings, the questions the scorer is asked (built from each user's settings) and the rules applied after.jev.js: Jev, TypeSafe's decision model: which key scores (the OpenRouter key first, a TypeSafe key only without one) and one call to it, with each error and whether to fall back.score-prompt.js: the same questions as one OpenRouter chat prompt, and the answer back in Jev's shape, for the fallback when OpenRouter can't reach Jev.models.js: the default text model for briefs and digests, and the OpenRouter providers Sieve avoids.digest-prompt.js: which saved posts go into a digest (flagged ones left out), the digest prompt, the Left out note and the final text.content.js (LinkedIn), x.js (X), reddit.js (Reddit), youtube.js (YouTube), background.js (API calls, saving, reminder).
linkedin-post-id.js: runs in LinkedIn's own page and finds a feed post's id, so briefs link to the post. Reads only.
x-post-data.js: runs in X's own page and reads a post's full text, reply chain, pictures and video. Reads only.
x-thread.js: checks what x-post-data.js wrote, finds the author's thread, and builds the brief and watch requests.watch-prompt.js: the Watch it for me prompt, cost estimate and parser. json.js: tolerant parsing of model JSON.brief.js: the technique brief (shape, safety header, markdown, Copy as prompt, the rules for warned briefs).
brief-prompt.js: the prompt that briefs one post, and its parser.
brief-panel.js: shows a brief on LinkedIn, X and YouTube. export.js: the Export library file.youtube-text.js: what a YouTube tile says beyond its title (description lines, chapters, YouTube's summary),
and the start of a video's description from YouTube's player endpoint when the tile shows none.agent-sync.js: sending the library to your agent, the pure part (sign-in URL, the library body and its hash, the words). agent-sync-run.js: the worker's part (sign-in, tokens, sends, turning off).openrouter-connect.js: Connect OpenRouter, OpenRouter's sign-in window that gives Sieve a key: the URL, the callback, the exchange, the check, the words.watch-drawer.js: the "watched for you" drawer for Watch it for me, shared by every page that offers it.options.*: settings page. popup.*: toolbar popup. : daily learnings page. All three follow Chrome's light or dark setting: their colours are tokens on , with dark values under .node tools/store-zip.mjs writes ~/Downloads/sieve-store/sieve-<version>.zip from the current commit
(--ref main for another commit, --out <folder> for another output folder). It won't overwrite an
existing zip unless you pass --force. It packages committed files only, leaving out test/, tools/,
README.md and .gitignore. Before writing anything it checks the package and refuses, naming the
problem, when a packaged file's name or bytes mention a word it must never contain, when it loads a file
that's missing from the package, when a .gitattributes file exists anywhere the commit or the repo could
apply one, or when manifest.json uses a key store-zip doesn't check yet. The word check is a tripwire
against committing the owner's personal copy by mistake, not a guarantee. When the commit has analytics-config.js, the zip needs the untracked
analytics-config.local.js (see Usage stats), or --no-analytics to ship the empty one. A committed
*.local.* file is refused. Commit first, then build.
MIT
digest.*:rootprefers-color-scheme: dark