MyGo 云音乐
用 Go 与 MyGo 写成的第三方网易云音乐桌面客户端。原生界面,没有 WebView;边下边播,无损与 Hi-Res,逐字歌词与「律动」,刘海播放器。
Translation pending
A daily almanac — news briefs, weather, markets, and stories worth knowing. Gathered each morning at marktan.ai.
Translation pending
MediaHTML · JavaScriptGitHub @markt1600OnlineOwner 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
Loading the full README. The saved excerpt is shown below.
A single-page daily dashboard in an editorial / broadsheet style: weather for Singapore, Tokyo, Vancouver, and Whistler, live market quotes, AI-written tech & lifestyle news with links to the original articles, Strava mileage, and a quote of the day — gathered fresh each morning. Built as one static page plus a few Vercel serverless functions. No framework, no build step. [README 설치·사용 부분 발췌] Setup (one-time): in Google Cloud Console → APIs & Services → Credentials, create an OAuth client ID (Web application) with https://marktan.ai as an authorized JavaScript origin, then set `GOOGLRead the full README ↗
A single-page daily dashboard in an editorial / broadsheet style: weather for Singapore, Tokyo, Vancouver, and Whistler, live market quotes, AI-written tech & lifestyle news with links to the original articles, Strava mileage, and a quote of the day — gathered fresh each morning.
Built as one static page plus a few Vercel serverless functions. No framework, no build step.
| Section | Source | Needs a key? |
|---|---|---|
| Projects bar | PROJECTS array in index.html | No |
| Markets (8 quotes, 5-day sparklines with date spans; gold also in S$/kg) | Yahoo Finance chart API | No |
| Exchange rates (USD→SGD, USD→JPY, SGD→JPY, SGD→CAD, USD→CAD) | Yahoo Finance chart API | No |
| Weather (Singapore, Tokyo, Vancouver, Whistler — incl. rain chance & US AQI; Whistler adds a Nov–Apr snow report) | Open-Meteo forecast + air-quality APIs | No |
| Stories & Briefs (deep-linked to the desk) | The day's MERIDIAN edition — feed.json from github.com/markt1600/dailymag (dailymag.marktan.ai). No web search here. | No |
| Quote of the Day + edition provenance line | MERIDIAN's "From the Desk" quote (same feed.json) | No |
| MERIDIAN pipeline tile (header) — green "No. N · built 06:47 · 24pp · QA clean", red past 07:15 SGT if today's issue hasn't landed, grey before that | status.json from github.com/markt1600/dailymag, committed by each build after its QA gate; re-checked every 10 min | No |
| Sports · Last 24 Hours (only while a major event is on — World Cup, Grand Slams, Tour de France, Olympics, late playoff rounds, F1…) | Claude + web search (/api/sports) | ANTHROPIC_API_KEY |
| Fitness (24h / 7d / 30d distance & run pace) | Strava API | Strava env vars |
| COE premiums (latest bidding exercise, all 5 categories) | LTA dataset via data.gov.sg API | No |
| Account balances (ElevenLabs credits, Claude API 30-day spend) — inside the owner-only For Mark · Private section | ElevenLabs + Anthropic Admin APIs | See below |
| Happy Day counter (relationship day count, ticks over at midnight SGT) | HAPPY_DAY config in index.html | No |
| Birthdays (owner-only, shown 7 days before → 3 days after in the For Mark section) | encrypted store data/birthdays.enc.json — edit at /admin | Login |
| Events watchlist (concerts, races, fitness, motorsport — finished events drop off) | data/events.json — edit at /admin (inline EVENTS array in index.html is the fallback) | No |
| Personal calendar (owner-only): Outlook-style month/week views, Sunday-first, multi-day events as continuous bars, recurring events (weekly/monthly/yearly), birthdays as annual dots; click any entry to edit every field or delete it (saves through the admin APIs with a fresh-sha conflict guard) | Public events + birthdays + the encrypted private list (/api/private-events) | Login |
Statement filing + recurring to-dos (owner-only): on schedule the daily cron adds items to the to-do list — statement-filing days and monthly bills are built in, and any item can be made recurring (monthly/yearly on a chosen date) from the To-dos panel in /admin | STATEMENTS / MONTHLY_TODOS configs in api/notify.js; user rules stored encrypted with the list | Login |
| Public holidays (next per region: Singapore, Japan, Vancouver/BC, Hong Kong, Shanghai) | Nager.Date API | No |
| 🔔 Morning digest push (07:20 SGT: build status, birthdays, event starts) | Web Push via /api/notify cron — see Notifications below | VAPID keys |
Sections whose keys aren't configured simply hide themselves — the page is never empty.
Account balances live inside the owner-only For Mark · Private section and appear only while logged in (below).
Owner login (Google Sign-In): the footer has a small login link that swaps itself for Google's sign-in button. api/login.js verifies the Google ID token (signature/expiry via Google's tokeninfo endpoint, audience must match GOOGLE_CLIENT_ID, and the verified email must be the owner's — any other Google account gets 403) and mints a 90-day HMAC session (api/_session.js, keyed off SESSION_SECRET → ADMIN_SECRET → DASHBOARD_SECRET). The session lives in localStorage and is re-verified server-side on every load. While logged in, the body gets the owner class, any element with class owner-only becomes visible (there's a "For Mark · Private" placeholder section wired up), the balances inside it are fetched with the session token, and /admin opens automatically. logout clears the session. Logged-out visitors see the page exactly as before.
Setup (one-time): in Google Cloud Console → APIs & Services → Credentials, create an OAuth client ID (Web application) with https://marktan.ai as an authorized JavaScript origin, then set GOOGLE_CLIENT_ID in Vercel. Until it's set, the login link explains it isn't configured yet.
index.html — the whole frontend. Fetches /api/dashboard, /api/fitness, and /api/balances and renders them. If the dashboard call fails (e.g. opening the file locally), it falls back to a sample edition instead of breaking.api/dashboard.js — weather, markets, FX, holidays, and the day's edition. The Stories & Briefs come from MERIDIAN: it fetches feed.json from github.com/markt1600/dailymag (published each morning ~7am SGT), maps the desk leads into features (MERIDIAN's cover-teaser top picks) + briefs, and deep-links each back to its desk at dailymag.marktan.ai. No web search runs here — the research is MERIDIAN's. If today's feed hasn't published yet, the raw file is simply the most recent edition (the "last good" stories, dated in the provenance line).api/sports.js — major-event sports results. Its own endpoint (and a cron an hour after the news one) so the two web-search Claude calls never share a rate-limit minute; returns an empty list when nothing major is on, and the section hides itself.api/fitness.js — Strava summary. Exchanges a long-lived refresh token for an access token on each run; cached ~1h.api/balances.js — ElevenLabs credits + Claude API 30-day spend. Never cached. Gated: with DASHBOARD_SECRET set, requests need a valid owner login session (Google Sign-In); without the secret set, it's public.api/admin.js — backend for the admin editor. Auth: the owner's Google-login session, or the shared automation secret (ADMIN_SECRET / DASHBOARD_SECRET) for scripted access. GET returns the current lists; POST commits an edited list to data/*.json via the GitHub Contents API (needs GITHUB_TOKEN). Each save is a commit, so git history is the audit trail; the current blob sha is round-tripped so a concurrent edit 409s instead of silently clobbering.data/events.json — the authoritative Events list the dashboard fetches. Edited through /admin; the inline array in index.html remains as an offline/local-preview fallback. Birthdays live in the encrypted data/birthdays.enc.json (personal info — owner-only, served via /api/private-events).api/assist.js — the admin page's Claude calendar assistant: takes free-form text, a pasted screenshot, or an uploaded file (image, PDF sent as a native document block, or .docx/.txt/.csv/.ics/.md/.eml — Word text is extracted in the browser, no libraries) plus both event lists, returns proposed adds (routed public/private) and deletions for review. Nothing commits until the owner confirms — confirming saves the ticked changes straight to the relevant list(s); the manual Save buttons are only for edits made directly in the tables. Uses .The site is an installable PWA (manifest.json + sw.js) that can deliver a 07:20 SGT morning digest to your lock screen with the browser closed: MERIDIAN build status (or a ⚠ if it hasn't published), birthdays today/tomorrow/in a week, and watchlist events starting today or tomorrow.
api/push.js (GET = VAPID public key; POST = register/remove a device), api/notify.js (composes + sends the digest; cron 20 23 * * * UTC = 07:20 SGT; ?token=<ADMIN_SECRET>&dry=1 previews without sending), sw.js (receives pushes; the tag field means re-sends replace rather than stack).data/push-subs.enc.json — committed to this public repo, so they're AES-256-GCM encrypted at rest (key derived from PUSH_STORE_KEY, falling back to VAPID_PRIVATE_KEY); endpoints are private capability URLs and never appear in plaintext./api/notify additionally rejects callers without CRON_SECRET (sent automatically by Vercel's cron) or the admin token./admin)Editing Birthdays and Events no longer means touching index.html. Visit /admin — it opens only for the owner's Google login (sign in on the dashboard first); there is no password. Edit both lists in a table UI. There's also a direct link in the For Mark · Private section. Saving commits to GitHub (data/events.json in plaintext; birthdays into the encrypted data/birthdays.enc.json) — which is the version history — and the change goes live once Vercel finishes the redeploy triggered by that commit (~a minute). The dashboard fetches events at load (inline-array fallback); birthdays arrive only with the owner login.
Requires two env vars (below): ADMIN_SECRET (the API automation secret) and GITHUB_TOKEN (fine-grained, Contents: Read & Write on markt1600/mainpage) so the function can read and commit. If neither ADMIN_SECRET nor DASHBOARD_SECRET is set, the admin APIs refuse to run — nothing ever opens unprotected.
/api/dashboard is edge-cached for ~24 hours (s-maxage=86400). The Stories & Briefs no longer run a paid web search — they're a cheap fetch of MERIDIAN's feed.json — so the daily cost is essentially just the sports call. The cron (15 23 * * * UTC = 07:15 SGT) warms the cache after MERIDIAN publishes (it builds ~06:00–07:00 SGT), so the morning edition reflects that day's MERIDIAN. The "↻ new stories" link in the footer forces a fresh, uncached fetch on demand.
Set these in Vercel → Settings → Environment Variables:
| Variable | Used by | Notes |
|---|---|---|
ANTHROPIC_API_KEY | sports.js | From https://console.anthropic.com. Now used only by the sports function; the dashboard's Stories & Briefs come from MERIDIAN and need no key. |
STRAVA_CLIENT_ID, STRAVA_CLIENT_SECRET, STRAVA_REFRESH_TOKEN | fitness.js | Refresh token from a one-time OAuth authorization with scope activity:read_all. |
ELEVENLABS_API_KEY | balances.js | elevenlabs.io → Profile → API key. |
ANTHROPIC_ADMIN_KEY | balances.js | Admin key (sk-ant-admin…) from console → Settings → Organization → Admin keys. Not the same as ANTHROPIC_API_KEY. |
DASHBOARD_SECRET | balances.js, admin.js | Optional. If set, balances are gated behind the owner login; also the fallback for ADMIN_SECRET as the API automation credential (shortcuts); /admin itself is Google-login only. |
ADMIN_SECRET | admin.js | Shared automation secret for API access from scripts/shortcuts (never a way into the /admin page, which is Google-login only). Falls back to DASHBOARD_SECRET; if neither is set, the admin APIs refuse to run. |
GITHUB_TOKEN | admin.js, push.js, notify.js | Fine-grained personal access token with Contents: Read & Write on markt1600/mainpage. Lets /admin and the push endpoints read and commit data/*.json. Server-only. Optional: GITHUB_REPO / GITHUB_BRANCH override the defaults markt1600/mainpage / main. |
MERIDIAN_DELIVER_TOKEN | deliver.js | Fine-grained personal access token with Actions: Read & Write on markt1600/dailymag. Lets the magazine's "⇥ reMarkable" menu item fire the delivery workflows ( / ) on demand. Until it's set the endpoint 502s and the menu item falls back to opening the GitHub Actions page. Optional: / override / . |
Keys live only in the serverless functions and are never sent to the browser.
Option A — GitHub + Vercel dashboard (easiest)
ANTHROPIC_API_KEY).Option B — Vercel CLI
npm i -g vercel
vercel # first deploy (preview)
vercel env add ANTHROPIC_API_KEY production
vercel --prod # deploy to production
In index.html:
PROJECTS array near the top of the <script>; each entry is { name, url }./admin (writes the encrypted data/birthdays.enc.json; owner-only on the site). Each entry is { name, month, day }. They appear in the For Mark section and in the personal calendar as small annual dot items./admin (writes data/events.json). Each entry is { act, kind, date, endDate, time, repeat, venue, status, note, url } where kind is a short type label ("Concert", "Race", "Fitness", "Motorsport", …) shown on the card, time is an optional HH:MM (24h) shown on the card and used for the timed calendar download, repeat is an optional "weekly" | "monthly" | "yearly" that makes the entry recur in the personal calendar (occurrences keep the original's duration; dates that don't exist — the 31st in a short month, Feb 29 — are skipped) and adds an RRULE to the calendar download, and date: null marks it TBA. Past events disappear automatically. The inline EVENTS array here is only the offline fallback.COST_BASIS map (Yahoo symbol → average buy-in price) draws a green border around a market tile when the live price is at/above your average and a red border when below.HAPPY_DAY constant holds the anniversary (month, day) and firstYear. The display reads <completed years × 365>.<day of the current relationship year>, with day 1 on the anniversary, resetting each year at midnight Singapore time.In api/dashboard.js:
MODEL defaults to claude-haiku-4-5-20251001 (fast, cheap). Swap for a Sonnet model for richer prose.CITIES array (name, lat/lon, timezone). Panels render top-to-bottom in array order.MARKETS array (display label + Yahoo Finance symbol).FX_PAIRS array (Yahoo symbols like SGDJPY=X).HOLIDAY_REGIONS (Nager.Date country codes; optional subdivision like CA-BC).allowed_domains list; the prompt (SCHEMA_PROMPT) asks for 5 briefs + 3 features.s-maxage=86400 in the Cache-Control header and the cron schedule in vercel.json.Opening index.html directly (or serving it statically) works — it shows the sample edition since /api/* isn't running. To exercise the real functions locally, run vercel dev with your env vars available.
maxDuration is 60s to allow for it. Thanks to stale-while-revalidate, visitors almost always get the instant cached copy.http(s) URLs on both the server and the client; a story without a usable URL renders unlinked rather than guessing.ANTHROPIC_API_KEYapi/special.js — serves MERIDIAN's owner-only special editions. Specials live encrypted at rest in the public dailymag repo (X25519 sealed-box .enc blobs); this endpoint fetches a blob from raw.githubusercontent, decrypts it with MERIDIAN_SPECIALS_KEY, and serves it only to a valid owner session (the .marktan.ai mt_owner cookie or ?token=). Everyone else gets a plain 404 — never a 401 — so the specials don't observably exist. PDFs over ~4.4 MB get a "delivered to your reMarkable" note instead (Vercel response cap).api/todos.js — Mark's private to-do list, encrypted at rest exactly like the private calendar (data/todos.enc.json, AES-256-GCM). GET returns the list + sha; POST {todos, sha} saves with a conflict guard; POST {add: "text"} is a sha-free server-side append used by the dashboard's quick-add box, the /todo voice page, and phone/watch shortcuts. Auth: owner session or admin secret. Shortcuts must call https://www.marktan.ai/... — the apex domain redirects to www, and Apple Shortcuts drops the POST body when following that redirect (the request degrades to a harmless GET).api/transcribe.js — voice → text for /todo's hold-to-record button, via ElevenLabs Speech-to-Text (Scribe; reuses ELEVENLABS_API_KEY). The browser records a clip and POSTs it; the transcript comes back and is added via /api/todos.api/private-events.js — the private calendar list (travel, personal items). Committed as data/private-events.enc.json, AES-256-GCM encrypted (key: PRIVATE_STORE_KEY → PUSH_STORE_KEY → VAPID_PRIVATE_KEY) since the repo is public; GET/POST gated by the owner session or admin secret, with sha-guarded writes.admin.html (served at /admin) — a self-contained CRUD editor: add/edit/delete rows in tables, then Save. Opens only for the owner's Google login (no password UI, no token deep-links). noindex.vercel.json — 60s maxDuration for the dashboard/sports functions, 15s for admin, a /admin → /admin.html rewrite, and the daily crons that warm the cache.deliver-remarkable.ymldeliver-special.ymlMERIDIAN_REPOMERIDIAN_BRANCHmarkt1600/dailymagmainVAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY | push.js, notify.js | Web Push signing keypair (npx web-push generate-vapid-keys). The public key goes to the browser; the private key signs every send — without it nobody can push to your devices. |
CRON_SECRET | notify.js | Recommended. Vercel sends it as a Bearer header on cron invocations; when set, manual /api/notify hits need ?token=<ADMIN_SECRET> instead. |
GOOGLE_CLIENT_ID | login.js | OAuth client ID (Web application) from Google Cloud Console with https://marktan.ai as an authorized JavaScript origin. Enables the footer's Google Sign-In owner login. |
MERIDIAN_SPECIALS_KEY | special.js | Base64 PKCS8 DER X25519 private key that decrypts MERIDIAN's special editions. The matching public key is committed in the dailymag repo (state/specials-pubkey.b64); the same value also lives as a GitHub Actions secret on dailymag for the reMarkable delivery workflow. |
SESSION_SECRET | _session.js | Optional. Dedicated HMAC key for owner login sessions; defaults to ADMIN_SECRET, then DASHBOARD_SECRET. |
PRIVATE_STORE_KEY | private-events.js | Optional. Dedicated encryption key for the private calendar file; defaults to PUSH_STORE_KEY, then VAPID_PRIVATE_KEY. |
PUSH_STORE_KEY | _pushstore.js | Optional. Separate encryption key for the committed subscription file; defaults to VAPID_PRIVATE_KEY. |