DeepSeek Harness Remote
DeepSeek Harness Remote 可将手机或另一台电脑与你运行 DeepSeek Harness 的电脑安全连接,随时随地继续你的工作,方便随时查看进度并继续工作。
AI 翻译
尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Sunsama-style daily planning PWA — time-blocking, planning rituals & two-way Google Calendar sync. Next.js 16, React 19, Supabase (RLS), offline-first.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A Sunsama-inspired daily planning PWA — plan your day with intention, time-block it, and close it out. Built as a shared workspace for two people.
Live app: https://productivity-app-three-pink.vercel.app
Morchitask is a calm, opinionated productivity app built around a daily ritual: a morning plan, a day spent time-blocking against your real capacity, and an evening shutdown. It's a real product used every day by two people who share one household workspace, with each task, category, and goal scoped to its owner. Installable as a PWA on iPhone, available in Spanish and English, and syncs both ways with Google Calendar.
A few things worth a closer look from an engineering standpoint:
householdId through from the session. That works right up until one query forgets — and a forgotten scope is invisible in review, in types, and in every other test here, because they all run against a single tenant. So lib/db/queries/isolation.test.ts boots a real Postgres (pglite, WASM), replays every migration into it, seeds two households, and asserts that asking as A never returns a row belonging to B.lib/google.ts.date-fns-tz and are covered by tests, so a 9pm task never silently lands on the wrong day.messages/{es,en}.json. i18n breaks by omission, so two lint rules reject a new hardcoded string, a script (npm run i18n:scan) reads the JSX for the shapes lint can't see, and a test parses both catalogs with the ICU parser to check they agree on placeholders — a {planned} in one language and a {amount} in the other renders a literal curly brace on screen with no error at all.Planning rituals
/plan/[date]) — set the day's focus, pull in what rolled over from yesterday or the backlog, and adjust estimates while a sticky panel shows what it costs./shutdown/[date]) — three steps: what got done (estimated vs. actually tracked), a mood and a note, and where each leftover goes. Confetti when everything's closed.Views
/metas) — weekly and monthly objectives; tasks link to one and each shows progress./routines) — tasks that create themselves daily or on chosen weekdays./resumen) — completion, estimate-vs-actual and time per category over a week or a month.Focus & time
Quality-of-life
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router, React Server Components, Server Actions) |
| UI | React 19, TypeScript, Tailwind CSS v4 |
| State / data | TanStack Query (optimistic updates), Zustand |
| Database | Neon Postgres + Drizzle ORM (typed schema and migrations) |
| Auth | Auth.js v5 (next-auth) + Drizzle adapter, Google OAuth, DB sessions |
| Storage | Vercel Blob (task attachments, avatars) |
| i18n | next-intl — cookie for rendering, profiles.locale as source of truth |
| Interactions | dnd-kit (drag & drop), Framer Motion (animation) |
| PWA / push | Serwist (service worker), web-push (VAPID) |
| Dates | date-fns / date-fns-tz |
| Tooling | Vitest, pglite, ESLint, Prettier, Husky + lint-staged |
app/
├── (auth)/login/ # Google sign-in
├── (app)/ # Authenticated app shell
│ ├── today, day/[date] # Day view (List + Agenda)
│ ├── plan/[date] # Morning planning ritual
│ ├── shutdown/[date] # Evening shutdown ritual
│ ├── week, month # Calendar views
│ ├── backlog, metas # Backlog & goals
│ ├── routines, resumen # Recurring tasks & stats
│ ├── focus # Focus / Pomodoro
│ └── settings
└── api/
├── auth/[...nextauth] # Auth.js
├── calendar/ # Google Calendar read + block writes
├── cron/ # Daily plan push, task reminders
├── tasks/ # Search, counts, ranges
└── attachments/ # Blob upload + fetch
components/ # Feature-grouped UI (day/, week/, tasks/, plan/, ui/ …)
lib/
├── actions/ # Server Actions — every mutation, session-scoped
├── db/ # Drizzle schema + queries (all take householdId)
├── queries/ # TanStack Query hooks wrapping the actions
├── stores/ # Zustand (running timers, task detail, palette)
└── *.ts (+ *.test.ts) # Pure logic: dates, ordering, capacity, i18n keys
messages/ # es.json / en.json — every user-visible string
drizzle/migrations/ # Schema migrations
Data flow: components read and mutate through lib/queries/*, which wrap Server Actions from lib/actions/* in TanStack Query with optimistic updates. Every action starts with requireSession() and every database query takes a householdId — that is the authorization boundary, so it lives in one reviewable place rather than being sprinkled through the UI. Secrets (Google token refresh, calendar writes, push delivery) never reach the client.
A note on the crons. daily-plan is declared in vercel.json and runs at 11:00 UTC (08:00 in Buenos Aires). task-reminders is not: it needs to run every few minutes, so an external Upstash QStash schedule calls it. That means nothing in this repo will tell you if that schedule stops — and that adding it to vercel.json without removing the QStash one would send every reminder twice. Both routes reject requests when CRON_SECRET is unset; they fail closed on purpose.
A note on offline. The app installs as a PWA and its shell is precached, but there is no offline data layer: API traffic is NetworkOnly in the service worker on purpose, because caching one person's tasks and serving them to whoever opens the app next is worse than an empty list. Persisting the query cache to IndexedDB (offline reads) is a modest change; offline mutations with replay on reconnect is a much bigger one. Neither is built — this section will say so until one of them is.
# 1. Install
npm install
# 2. Configure environment
cp .env.example .env.local
# Fill in DATABASE_URL, AUTH_SECRET and the Google OAuth pair at minimum.
# 3. Apply the schema
npm run db:migrate
# 4. Run
npm run dev # http://localhost:3000
You'll need a Postgres database (Neon's free tier is what this runs on) and Google OAuth credentials — sign-in won't work without them, since Google is currently the only provider. Every variable is documented in .env.example, and the Google setup is walked through in docs/GOOGLE_SETUP.md.
| Command | What it does |
|---|---|
npm run dev | Start the dev server |
npm run build | Production build |
npm run typecheck | TypeScript, no emit |
npm run lint | ESLint |
npm test | Vitest (399 tests, some against a real Postgres) |
npm run i18n:scan | Find user-visible text that isn't in a message catalog |
npm run db:migrate | Apply Drizzle migrations |
npm run e2e | Playwright against a real build (it starts it itself) |
npm run format | Prettier |
npm run e2e runs Playwright against a real production build that the config starts itself. It covers what a logged-out visitor gets: route protection, that data endpoints serve nothing, that the interface really does render in English when the locale cookie says so, the security headers, and the PWA manifest. Anything needing a session is not covered — that needs a real Postgres and Neon's HTTP proxy in front of it, since lib/db/client.ts speaks Neon's wire protocol rather than plain pg.
Actively used and maintained. The planning rituals, calendar sync, focus timer, routines and goals are all shipped, and the interface is fully translated. Next up: rate limiting, error tracking, and an end-to-end suite.
Built by @lucasfmujica.