MyGo 云音乐
用 Go 与 MyGo 写成的第三方网易云音乐桌面客户端。原生界面,没有 WebView;边下边播,无损与 Hi-Res,逐字歌词与「律动」,刘海播放器。
Translation pending
One inbox. One PDF. The news, a fresh write-in crossword, Kanji practice and your Home Assistant briefing, bound into one edition and emailed to your Kindle Scribe, any e-reader, or plain inbox every
MediaTypeScript · JavaScriptGitHub @RonanODOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Online Services for Kindle Scribe and other devices
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
dailyscribe.ca — pick from a catalogue of daily
"services" (the news, a write-in crossword, Kanji practice, a Home Assistant
briefing), and Daily Scribe binds them into one PDF and emails it to your Kindle
Scribe, any other e-reader, or a plain inbox — one edition a day, timed to your
morning. The Kindle Scribe is locked down by Amazon but accepts PDFs by email —
this turns that one open channel into a personalised daily edition. Some services
also read back: write your answers on the device by hand, mail the page to
[email protected], and it is graded automatically.Read the full README ↗dailyscribe.ca — pick from a catalogue of daily
"services" (the news, a write-in crossword, Kanji practice, a Home Assistant
briefing), and Daily Scribe binds them into one PDF and emails it to your Kindle
Scribe, any other e-reader, or a plain inbox — one edition a day, timed to your
morning. The Kindle Scribe is locked down by Amazon but accepts PDFs by email —
this turns that one open channel into a personalised daily edition. Some services
also read back: write your answers on the device by hand, mail the page to
[email protected], and it is graded automatically.
▶ Watch the 2-minute demo — a real edition opened on a Kindle Scribe: the news sections, the Home Assistant briefing, Kanji practice, and the write-in crossword.
Private beta, invite-only (ALLOW_NEW_SIGNUPS=false; the Auth.js signIn
callback rejects any address not already in users). The public site runs a
waitlist form; apps/web/scripts/approve-waitlist.mjs seeds approved emails into
users in small batches and sends the invite. See the roadmap in
CLAUDE.md.
GNU AGPLv3. The source is open — read it, self-host it, send patches. The AGPL's one added condition versus a permissive license: if you run a modified version of this code as a network service for others, you need to make your modified source available to them too.
flowchart TD
subgraph signup["Sign-up · invite-only"]
WL["Waitlist form<br/>(dailyscribe.ca)"] -->|"POST /api/waitlist"| WLDB[("waitlist")]
WLDB --> APV["approve-waitlist.mjs"]
APV --> USERS[("users")]
APV --> INV(["Resend invite"])
LOGIN["Sign in<br/>(my.dailyscribe.ca)"] -->|"Auth.js v5:<br/>Google · GitHub · magic-link"| USERS
LOGIN --> CFG[("subscriptions +<br/>userSecrets (AES-256-GCM)")]
end
subgraph delivery["Daily delivery"]
CRON["GitHub Actions<br/>every ~10 min<br/>(daily Vercel Cron fallback)"] -->|"GET /api/cron/dispatch"| DISP["dispatchDue()"]
CFG --> DISP
DISP --> RUN["runSubscription()<br/>timezone-aware · idempotent per day"]
RUN --> PLUG["ServicePlugin.run(ctx)"]
PLUG -->|"fetch"| SRC["RSS feeds · Home Assistant REST<br/>Kanji curriculum · Universal Crossword feed"]
PLUG -->|"render"| PDF["PDF (@react-pdf/renderer)"]
PDF --> ASM["Digest assembly<br/>(pdf-lib: branded cover + linked TOC)"]
ASM --> DLV["Deliverer / Resend"]
DLV --> AMZ["Amazon<br/>Approved Personal Document e-mail"]
AMZ --> DEV["Kindle Scribe /<br/>e-reader / inbox"]
end
subgraph back["Handwriting return path"]
DEV -->|"mail the page back"| RIN["POST /api/webhooks/resend-inbound"]
RIN -->|"pdfjs finds dailyscribe:service:token"| GEM["Gemini grading"]
GEM --> KP[("kanjiSubmissions +<br/>kanjiProgress")]
end
subgraph health["Delivery health"]
DLV -.->|"status webhook"| REV["POST /api/webhooks/resend-events"]
REV --> EVT[("deliveryEvents")]
REV -->|"hard bounce / complaint"| OFF["auto-disable subscription"]
end
classDef ext fill:#f4e9d6,stroke:#b0402e,color:#23201a;
class CRON,AMZ,GEM ext;
classDef store fill:#eef1f4,stroke:#5b6470,color:#23201a;
class WLDB,USERS,CFG,KP,EVT store;
Every [( … )] node is a collection in a single MongoDB Atlas database
(dailyscribe); the app has no other datastore. Cloudflare hosts DNS only —
DKIM/SPF/DMARC for the sending domain, the MX record that points inbound mail at
Resend, and the CNAMEs for both Vercel projects.
There is no job queue and no per-user cron. A GitHub Actions workflow
(.github/workflows/dispatch.yml) polls GET /api/cron/dispatch every ~10 minutes,
with a once-daily Vercel Cron as a fallback. Each subscription carries a delivery
time and an IANA timezone, and dispatchDue() sends a subscriber's edition on the
first poll at or past that local time — exactly once per day, enforced by a
deliveries marker row keyed by (userId, service, localDate). (Vercel Hobby cron
alone only fires daily, which can't honour a per-subscriber time across timezones;
native hourly Vercel Cron on Pro is the eventual replacement — see CLAUDE.md
Phase 3.)
pnpm + Turborepo. pnpm-workspace.yaml → apps/*, packages/*.
| Workspace | Package | What it owns |
|---|---|---|
apps/web | @dailyscribe/web | The dashboard, Auth.js, every API route, the cron dispatcher (lib/runner.ts), and all service plugins + PDF renderers (lib/plugins/*.tsx). Deploys to my.dailyscribe.ca. |
apps/marketing | @dailyscribe/marketing | The public site at dailyscribe.ca + www, the cross-origin waitlist form, and a git-based Decap CMS at /admin for the landing copy. No database, no auth. |
packages/core | @dailyscribe/core | Framework-free TS: Mongo client + collections() / ensureIndexes(), AES-256-GCM secret crypto, the ServicePlugin interface + registry, the Deliverer abstraction, pdf-lib merge/split, an SSRF guard, and the Gemini kanji-grading client. Ships raw .ts, consumed directly. |
packages/theme | @dailyscribe/theme | Shared design tokens (an oklch newsprint palette) and next/font config (Playfair Display + PT Serif), imported by both apps so product and marketing read as one brand. |
signIn gate.Daily Scribe <[email protected]>), one app-wide API key, no per-user
credentials. Handles outbound editions, magic links, invites, and both the
inbound-mail and delivery-status webhooks.GET /api/cron/dispatch (guarded
by CRON_SECRET) every ~10 min; a daily Vercel Cron is the fallback.@react-pdf/renderer for every rendered service; pdf-lib for stitching
a digest and drawing its cover/TOC links; pdfjs-serverless to read mailed-back
pages.@google/genai) — used only to grade a mailed-back Kanji
practice page./api/cron/dispatch every ~10
minutes (a daily Vercel Cron is the fallback). dispatchDue() loads every
enabled subscription and sends to each subscriber whose chosen delivery time has
already passed in their own timezone and whose edition hasn't gone out yet today;
it skips a user's standalone services if they have the Digest enabled.runSubscription() decrypts any needed secrets and calls
getPlugin(service).run(ctx). A plugin fetches its source (an RSS feed, the
user's Home Assistant REST API, the Kanji curriculum, the Universal Crossword
feed) and returns one or more PDF Assets. A successful send writes a
deliveries row; a failure writes one too, and never throws.collectDigestSections() runs each member service
with per-member failure isolation, then assembleDigestPdf() (pdf-lib) prepends
a branded cover + a linked table of contents and draws a back-to-contents link
on every page.createResendDeliverer().deliver() sends the PDF from the single
verified address. The user has whitelisted [email protected] once in Amazon's
Approved Personal Document E-mail List, so Amazon forwards it to the device./api/webhooks/resend-inbound. pdfjs-serverless scans the pages for the
embedded dailyscribe:<service>:<token> routing ref, trims the PDF to that
service's pages, and (for Kanji) sends it to Gemini for a per-character verdict
that updates kanjiProgress./api/webhooks/resend-events)
records deliveries, bounces, and complaints in deliveryEvents and
auto-disables any subscription whose address hard-bounced or filed a complaint;
the dashboard shows why.A service is a ServicePlugin — { id, label, run(ctx): Promise<Asset[]> }
(packages/core/src/plugins/index.ts). Plugins are registered once at the top of
apps/web/lib/runner.ts; their implementations live in
apps/web/lib/plugins/*.tsx. apps/web/lib/service-catalog.ts is the single source
of truth for a service's identity (label, icon, blurb, whether it needs a stored
secret, whether it appears in onboarding) and drives the dashboard tabs, the
onboarding picker, and the digest's member list.
Live: RTÉ / CBC / BBC news, Home Assistant summary, Kanji-a-day, the write-in (Universal) crossword, a solo DnD 5e campaign (mail-back moves, like Kanji), plus the Digest bundle. Coming: serialized classic novels, an eating/drinking tracker. Paused: the NYT crossword plugin still exists but is excluded from the catalogue (it needs the subscriber's own cookies).
pnpm install
pnpm dev # both apps via Turborepo
pnpm test # vitest in packages/core
pnpm typecheck
pnpm build
Requires Node ≥ 20 and pnpm 9. The apps need environment variables and a handful of
external accounts (MongoDB Atlas, Resend, OAuth apps, a Gemini key) to do anything
real — SETUP.md walks through every variable and the one-time
service setup, and finishes with an end-to-end "you as customer #1" checklist.