π Language / θ―θ¨: English Β· δΈζ
Prefer to configure everything by hand? This page walks through every step. If you'd rather use the interactive wizard, use the upstream setup wizard instead.
Prefer Use this template β Create a new repository on the GitHub page. That gives you your own copy with all the automation included, without the extra Actions friction that forks often add.
If you intentionally need an upstream-linked development copy, you can still use Fork, but this manual guide assumes you are creating your own standalone digest repo.
The recommended one-click path no longer uses a PAT. Instead:
- install the Linnet Bridge GitHub App on your target repo
- open the upstream setup wizard at https://yuyangxueed.github.io/Linnet/setup/
- click Install GitHub App / Authorize GitHub
- deploy from Step 5
This manual guide remains the fallback path when you want to keep every config change explicit, or when org / repo policy blocks the GitHub App flow.
In your repo go to: Settings β Secrets and variables β Actions β New repository secret
| Name | Value |
|---|---|
OPENROUTER_API_KEY |
Your key from openrouter.ai/keys β free tier works, starts with sk-or-... |
This is the default fast-path credential. OpenRouter lets you call many AI models (Gemini, GPT, Claude) with one key and switch between them any time.
π° Cost estimate: With the default model (
google/gemini-2.5-flash-lite), one full daily digest run costs roughly $0.1 USD. At one run per day, that's under $3 USD / month. Actual spend varies with the sources you enable, how many papers get fetched, and the summary language β you can watch per-call costs live on the OpenRouter dashboard. If you want to spend less, swapscoring_model/summarization_modelinconfig/sources.yamlfor a cheaper model, or lower the daily paper cap inconfig/extensions/arxiv.yaml.
If you prefer a different OpenAI-compatible provider, set these fields in config/sources.yaml:
llm:
provider: "openai"
base_url: "https://api.openai.com/v1"
api_key_env: "OPENAI_API_KEY"
scoring_model: "gpt-5-mini"
summarization_model: "gpt-5-mini"Then export or store the matching secret name instead:
export OPENAI_API_KEY=sk-...Go to: Settings β Pages β Source: GitHub Actions
Click Save. Your site URL will appear there β it looks like https://YOUR-USERNAME.github.io/Linnet.
Open config/extensions/arxiv.yaml. It has four ready-made profiles β
uncomment the one closest to your work and edit the keywords freely:
# PROFILE A: AI / ML / LLM (general)
# categories: [cs.AI, cs.LG, cs.CL, cs.CV, stat.ML]
# must_include:
# - large language model
# - foundation model
# PROFILE B: Astrophysics / Space Science
# PROFILE C: Chemistry / Materials Science
# PROFILE D: Computational Biology / BioinformaticsWant summaries in a different language? Open config/sources.yaml and
change language: "en" to "zh", "fr", "de", "ja", "ko", "es", or any other language code.
If GitHub Actions / workflows are currently disabled in the repo, enable them manually first unless you already used the Setup Wizardβs Step 5 auto-enable option successfully. This is most common on forks.
Clean start for older forks: delete any inherited generated snapshots under docs/data/daily/*.json, docs/data/weekly/*.json, and docs/data/monthly/*.json, but keep the .gitkeep files. The next Daily Digest run will create fresh data for your repo.
You need to manually trigger two workflows in order:
- Generate the digest content: Go to Actions β Daily Digest β Run workflow β Run workflow and wait for it to finish (about 3β5 minutes). This calls the LLM, builds today's digest, and commits it into
docs/. - Deploy the site to GitHub Pages: Go to Actions β Deploy Astro Site to GitHub Pages β Run workflow β Run workflow and wait for it to finish (about 1β2 minutes). This builds the Astro site and publishes it.
π‘ From then on,
Daily Digestruns automatically every day and auto-triggers the deploy on success β so you only need to click these two buttons the first time.
Once both are green, your site is live at https://<your-username>.github.io/<repo-name>/.
Optional but recommended: paste that URL into the repository's About -> Website field so the site link also appears on the GitHub repo home page.
Open config/sources.yaml and set enabled: true or enabled: false
for each source:
arxiv:
enabled: true # arXiv papers β the main event
hacker_news:
enabled: true # top Hacker News stories
github_trending:
enabled: true # today's trending GitHub repos
max_repos: 15
weather:
enabled: true
city: "Edinburgh" # change to your city
postdoc_jobs:
enabled: false # academic job listings β turn on if you want these
supervisor_updates:
enabled: false # professor/lab page monitor β turn on if you want these
quote_of_day:
enabled: false # daily quote as briefing tagline (English, requires API_NINJAS_KEY)
hitokoto:
enabled: false # δΈθ¨ daily quote as briefing tagline (Chinese, no key needed)You can also switch AI models here, set llm.provider, point llm.base_url at another OpenAI-compatible provider, change llm.api_key_env, or cap how many papers get fetched per day.
Every summarisation and scoring prompt can be overridden in config/sources.yaml under the llm.prompts: block.
The commented-out defaults are already in that file β uncomment and edit any you want to change:
llm:
summarization_model: "google/gemini-2.5-flash-lite"
# prompts:
# arxiv_summary: |
# Summarize the core method and contribution of the following paper
# {lang}, in 2-3 sentences (β€100 words):
# Title: {title}
# Abstract: {abstract}
# hacker_news_summary: |
# Summarize the core content of the following tech news story
# {lang}, in one sentence (β€50 words):
# Title: {title}
# URL: {url}Available placeholders per prompt:
| Prompt key | Placeholders |
|---|---|
arxiv_score |
{title}, {abstract} |
arxiv_summary |
{title}, {abstract}, {lang} |
hacker_news_summary |
{title}, {url}, {lang} |
github_summary |
{full_name}, {description}, {lang} |
If you want a lighter notification path, especially for Chinese-language workflows, ServerChan is a good fit:
- Open sct.ftqq.com/sendkey
- Copy your SendKey
- Add it as a secret: Settings β Secrets and variables β Actions β New repository secret, name it
SERVERCHAN_SENDKEY - Enable it in
config/sources.yaml:
sinks:
serverchan:
enabled: true
max_papers: 5
max_hn: 3
max_github: 3
max_jobs: 3This keeps the key out of YAML and out of version control.
In addition to the website, you can receive a daily Slack message:
- Go to api.slack.com/apps β Create New App β From scratch
- Left sidebar β Features β Incoming Webhooks β toggle On
- Scroll down β Add New Webhook to Workspace β choose your channel β Allow
- Copy the webhook URL (looks like
https://hooks.slack.com/services/T.../B.../...) - Add it as a secret: Settings β Secrets and variables β Actions β New repository secret, name it
SLACK_WEBHOOK_URL - Enable it in
config/sources.yaml:
sinks:
slack:
enabled: true
max_papers: 5 # how many papers to include
max_hn: 3 # how many HN stories to include
max_github: 3 # how many trending repos to includeIf you skip this step, nothing breaks β the website still updates as normal.
| When | What happens |
|---|---|
| Weekdays at 09:30 UTC by default | Full digest β papers, HN, GitHub trending, weather, US pre-market stocks, any extras you enabled |
| Every Monday at 00:00 UTC | Weekly summary of the past week |
| 1st of every month at 00:00 UTC | Monthly overview |
The setup wizard can generate a custom daily schedule in .github/workflows/daily.yml from your local time and UTC offset. You can also edit the cron lines manually, or trigger any workflow by hand: Actions -> [workflow name] -> Run workflow.