safeeyes
간단하고 아름다운 휴식 알림으로 눈 피로 보호
인스타그램 같은 앱이 열리기 전, 잉크가 번지는 모습을 보고 10초 숨을 쉬세요
Before an app like Instagram opens on an iPhone, watch a wash of ink and breathe for ten seconds, then decide whether to go in. “Today” holds the three things that matter most in the weeks ahead, one
건강TypeScript · JavaScriptGitHub @Defiabell온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
打开干扰类 App 前,先呼吸十秒。自建的 One Sec 替代品,跑在 Cloudflare 免费额度上。A self-hosted One Sec alternative: breathe before the app opens.
README 전체를 불러오는 중입니다.
README 전문 보기 ↗English | 简体中文
一息 does two things, sharing one account. Breathe (拦): before a distracting app opens, your phone shows a page that asks you to breathe for ten seconds, then offers 「算了」 first and 「继续打开」 second, and keeps the receipt. Today (引): your top few goals for the coming weeks — three by default, as many as nine if you want — on one page you open every morning, each with its sub-tasks for today, seven dots for the last seven days, and a button that jumps straight into the app where the work happens — B 站 for a workout, 微信读书 for a book. Either half is useful on its own.
One Cloudflare Worker and one D1 database, running entirely on Cloudflare's free tier. On the interception side it is a self-hosted stand-in for One Sec, built as a web page instead of an iPhone app.
「算了」 is a filled pill, 「继续打开」 a small underlined link — the asymmetry is deliberate.
Before a distracting app opens, the phone jumps to a page that counts ten seconds out, offers the way out first and the way in second, and keeps the receipt either way.
Three goals, the first one large. No streak number anywhere.
The few things that matter for the coming weeks on one page you open every morning — each with its sub-tasks for today, seven dots for the last seven days, and one button into the app where the work happens.
Who this is for: anyone who wants a nudge rather than a wall. It is friction, not enforcement — the automation is one toggle away from off, on purpose. A third face, Surf (渡): when an urge shows up, tap it, and it walks you through ten minutes.
The open instance is the quickest way in. If you would rather not keep a minute-by-minute log of your worst impulses on someone else's server, deploy your own in fifteen minutes; it is the same code either way.
Three that apply to the whole product. The per-face lists are in docs/breathe.md and docs/today.md, and both are worth reading before you deploy.
/account, or by adding ?lang=en / ?lang=zh to any page; Chinese is the default whenever nothing else says otherwise. Every page is translated, the long Shortcut walkthrough at /setup included; the iOS labels it quotes are the ones English iOS prints.pages.dev is a shared suffix and clean today is not clean forever — your own domain is the only durable answer.| Route | Who | What |
|---|---|---|
/ | anyone | landing page, links to register / sign in |
/gate?app=&k= | gate token | the decision endpoint the Shortcut calls; answers pass or a URL |
/b?s=<sid> | sid | the breathing page |
POST /resolve | sid | records proceed / abandon, opens the grace window |
/register /login /claim /recover | anyone | sign up, sign in, bind an old token, reset a password with a token |
/today | you | the one page to open every morning: your top goals, today's sub-tasks, a seven-day dot strip |
/today/goals | you | add, edit, reorder and archive goals — everything /today shows but does not let you change |
/today/review | you | looking back: today's ratio, a 30-day strip, every goal's own dot strip and check-in rate, this week's sub-task check-ins |
/today/setup | you | add /today to the home screen, a Shortcut, or a timed automation that opens it on its own |
/goals | you | kept as a 307 to /today/goals (preserves method/body), so old links and bookmarks still land somewhere useful |
/review | you | today, the last seven days, which app costs you most |
/settings | you | which apps to intercept, and how long |
GET /api/candidates | you | JSON: type an app name, get candidate URL schemes with sources. Fetched by the URL scheme field on /settings and /today/goals; not a page |
/lookup /probe | — | kept as 302s to /settings. Both were pages once; finding and testing a scheme is now part of the field that needs it, so old links and bookmarks still land somewhere useful |
Anything else is a 404. There is no detail endpoint under /admin to guess at — see SECURITY.md.
Each face carries its own nav — 「今日」 for /today and behind it, 「拦截」 for the breathing pages and behind them, 「渡」 for /surf and behind it — with a small link to each of the others, and all three share the same login.
One codebase, two Cloudflare deployments, sharing one D1 database:
| Deployment | Config | Job |
|---|---|---|
| Pages | pages/wrangler.toml | the hostname people actually open |
| Worker | wrangler.toml | one daily trigger — cleanup at noon Shanghai, the goal_days snapshot at 00:00 |
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗
/setup| you |
| the Shortcut walkthrough, with your own host and token filled in |
/surf | you | the Surf (渡) ten-minute flow: put the phone down, let it pass, then decide again. Nothing on it asks you anything |
/surf/review | you | Surf's 30-day look-back: urge counts, the passed/opened ratio, and what time of day they come. Also the entry point for the 渡 face |
/surf/setup | you | pick your scene, once |
/account | you | read your gate token back, change your password, sign out |
/mock?v=1|2 | anyone | the two candidate visual skins, side by side |
/admin | owner | mint a token for someone offline; see per-user attempt counts |
/manifest.webmanifest /icon.png | anyone | the home-screen files — public and cacheable, nothing per-user in either |
/robots.txt | anyone | crawl the front door, nothing else |