尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A shared to-do list and budget planner for a new house, for two people. Log every job and every thing to buy, room by room, and the app tells you what to do next, what the money covers right now, and roughly when the rest becomes affordable.
Fix bathroom tap £40 tomorrow !must @Sam and it's filed: cost, due date, priority, who and room are pulled out of the sentence. #kitchen names a room explicitly; £100-150 is a range.!must #kitchen and the rest) and it's filed as something to buy, with the product's name, price and the link filled in from the page, and a room guessed from the name ("shower" → bathroom). No AI: it reads the page's own product data. Works with Screwfix, B&Q, IKEA, Wickes, Toolstation, and Amazon with Amazon prices on; shops that turn servers away (Argos) still get added straight away, named from the link. Adding a link in the detail sheet, or as a step, offers "Use £X from Screwfix" with one tap.Boiler service every year works in quick add).src/lib/house.ts: correct them there if you measure.AUTH_SECRET revokes it.N to add on desktop.You'll need Node.js 20 or later installed.
Copy the example file — the defaults already work for local development, no editing required to get started:
cp .env.example .env
| Variable | Required | What it is |
|---|---|---|
DATABASE_URL | Yes | Postgres connection string. The example file's default points at a local database that gets created automatically — see below. |
HOUSE_PIN | Yes | The shared PIN the two of you type in to unlock the app. The example ships with changeme; pick your own before sharing the app with anyone. |
AUTH_SECRET | Yes | A long random string used to sign the login cookie. Generate one with node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" and paste the output in — the shipped placeholder is fine for local dev only. |
DATABASE_POOL_MAX | No (local dev only) | Leave at 1 locally — see the note below. Omit this variable entirely in production. |
RAINFOREST_API_KEY | No | Turns on Amazon prices: a key from rainforestapi.com. Without it, Amazon links work as before. |
HOUSE_LIST_URL | Worker only | Where the Ask Claude worker finds the app. Defaults to http://localhost:3000. |
HOUSE_LIST_WORKER_TOKEN | Worker only | The worker's key, from Settings → Ask Claude. Locally it can be left out (it's derived from AUTH_SECRET). |
HOUSE_LIST_CLAUDE_MODEL | No | Model alias the worker asks claude for. Defaults to sonnet. |
HOUSE_LIST_CLAUDE_BIN | No | Path to the claude executable, if the worker can't find it on your PATH. |
HOUSE_LIST_WORKER_MAX_IDLE | No | Longest wait between checks when nothing's happening, in seconds. Defaults to 60. |
npm test runs the unit tests for the quick-add parser, the product-link reader (against saved shop-page shapes, no network), the budget planner, the pot rules, the Claude connector and the Ask Claude worker (prompt, claude arguments, answer checking).
npm install
npm run dev
That's genuinely it. Behind the scenes, npm run dev first starts (or reuses) Prisma's own local Postgres server — a real Postgres-compatible database that runs on your machine with no signup, no Docker, and no separate install — then applies the database schema, then starts the app. Your data persists across restarts.
Open http://localhost:3000.
Why
DATABASE_POOL_MAX=1locally? Prisma's local dev Postgres server has a known issue returning "prepared statement" errors under more than one concurrent database connection. Capping the pool at 1 works around it. This is a local-only quirk — production Postgres (Neon) doesn't need it, so that variable should be left unset on Vercel.
If you ever want to inspect the local database directly, npx prisma studio opens a browser-based data viewer.
This assumes you've never deployed anything before. It takes about 15 minutes.
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git
git push -u origin main
-pooler), once with it off. You will need both in Step 4.Still on the import screen (or afterwards under Project Settings → Environment Variables), add:
| Name | Value |
|---|---|
DATABASE_URL | The pooled Neon connection string from Step 2 |
DATABASE_URL_UNPOOLED | The direct (non-pooled) Neon connection string — used only to apply database migrations |
HOUSE_PIN | Whatever PIN you and your partner want to use |
AUTH_SECRET | A long random string — generate one locally with node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
RAINFOREST_API_KEY | Optional: turns on Amazon prices. |
Do not add DATABASE_POOL_MAX — leave it unset in production. The worker's own variables don't go on Vercel either: they live on the computer that runs the worker. (RAINFOREST_API_KEY is the exception that belongs here: the worker borrows the app's Amazon lookups rather than holding the key.)
Click Deploy. Vercel runs the vercel-build script, which applies any pending database migrations (creating the tables on the first deploy) and then builds the app. Schema changes in later pushes are applied the same way, so there is nothing to run by hand.
Vercel gives you a URL like your-project.vercel.app. Share that link and the PIN with your partner — that's the whole rollout. Every time you push to the main branch on GitHub, Vercel redeploys automatically.
The app is also a remote MCP server, so Claude can read and edit the list on your Claude plan (no API key).
localhost won't work.claude mcp add --transport http house-list <link>).Claude can see the overview and budget plan, preview what a change would do to the plan without making it (a new priority, a pin, dropping something, a big new cost: what it moves forward and what it pushes back), pull together the shopping list (things to buy plus the supplies inside jobs, by shop, or just what the pot covers), find and read items, add and update them (steps, costs, links, notes, due dates, status), log and choose quotes, post updates and delete items when asked. Its changes go through the same rules as the app (finishing something costed spends from the pot, repeating jobs reschedule) and show up on both phones, attributed to "Claude" and in Since you last looked. Claude isn't added to your household.
The link carries its own key, like the calendar link, so keep it private. Rotating AUTH_SECRET changes it (and the calendar link); you'd then re-add the connector with the new link.
The app never calls Claude itself. Pressing Ask Claude queues the question; a small worker script, running on a computer that's signed in to Claude Code, picks it up, runs claude -p (Claude Code's headless mode) with your own Claude Pro/Max subscription, and sends the answer back. No API key, nothing to pay beyond the subscription. While no worker is running, the app says so honestly ("Waiting for Claude… It runs when the worker's computer is on"), and Settings shows when the worker last checked in.
Set it up once, on your computer:
claude and follow the login). claude auth status should say "loggedIn": true..env on that computer, add:
HOUSE_LIST_URL="https://your-project.vercel.app"
HOUSE_LIST_WORKER_TOKEN="paste from Settings → Ask Claude → Copy token"
npm run ai-worker
It checks for questions every 20 seconds or so (easing off to once a minute when it's quiet), answers them one at a time, and stops with Ctrl+C. An answer usually takes under a minute and uses a little of your subscription's usage.Against your local copy (npm run dev), step 2's variables aren't needed: the worker defaults to http://localhost:3000 and derives the token from AUTH_SECRET in .env.
Start it with Windows. Task Scheduler → Create Task… → Triggers: At log on; Actions: Start a program, Program node, Arguments scripts/ai-worker.mjs, Start in: this project's folder. Leave Run only when user is logged on ticked (Claude Code needs your login). On a Mac, a login item or launchd agent running the same command does the same job.
Or don't keep a computer on. A scheduled Claude Code cloud routine on this repository, with HOUSE_LIST_URL and HOUSE_LIST_WORKER_TOKEN set, can run node scripts/ai-worker.mjs --once every so often: --once answers whatever is waiting and exits. Answers then arrive on the routine's schedule rather than within a minute.
What Claude can do from the worker: web search and web fetch, plus the app's two Amazon price tools when Amazon prices are on, nothing else. It runs in an empty temporary folder with no shell, no file editing and none of your MCP servers, hooks, plugins, skills or CLAUDE.md files (--tools WebSearch,WebFetch, --permission-mode dontAsk, --strict-mcp-config, and --safe-mode; with the price tools, whose server --safe-mode would drop, --setting-sources project --disable-slash-commands and CLAUDE_CODE_DISABLE_CLAUDE_MDS instead). The price tools come from the app's /api/worker/mcp, signed in with the worker token, and can only read Amazon prices: nothing there can change the list. The household's text is passed in as data, not instructions, the prompt goes in on stdin rather than the command line, and each job is stopped after five minutes. Answers are checked against a schema when they arrive, and links that aren't plain web addresses are refused.
Neon note: every check is a tiny database query, so while the worker runs, a Neon free-tier database doesn't get to sleep. That's fine for a computer that's on during the day; for round-the-clock use, raise
HOUSE_LIST_WORKER_MAX_IDLEor use the scheduled--onceoption.
Rotating AUTH_SECRET revokes the worker token along with the calendar link; copy the new one from Settings.
Amazon turns servers away, so neither a pasted link nor Claude's web fetch can read its prices. With RAINFOREST_API_KEY set (on Vercel, and in .env locally), Rainforest API reads them instead:
amzn.eu/d/… share links) fills in the real name and current price, and tidies the link to amazon.co.uk/dp/….Every lookup spends one Rainforest credit. Answers are kept for six hours, and Claude is asked to keep to a few lookups per question. If a lookup fails (no credits left, say), a pasted link falls back to reading the page as before.
Push notifications need a key pair, set once on Vercel (and in .env to try them locally):
npx web-push generate-vapid-keys.NEXT_PUBLIC_VAPID_PUBLIC_KEY (the public key) and VAPID_PRIVATE_KEY (the private one). Keep the private one private. Changing the pair later stops every phone's notifications until it's turned on again.CRON_SECRET, any long random string. Vercel sends it to the daily reminder (/api/cron/due, scheduled in vercel.json), which turns away anyone without it.Without the keys the Settings switch says the browser can't show notifications and nothing else changes.
Photos are kept in a Vercel Blob store, which is free on the Hobby plan (about 1 GB, and photos are shrunk to a few hundred KB each, so a few thousand fit). Set it up once:
BLOB_READ_WRITE_TOKEN for you.Until then, adding a photo on the live app says photos aren't set up yet. Locally, without the token, photos are saved in .photos/. Over the free allowance, Vercel doesn't charge on Hobby; it stops Blob until the month is out.
src/
app/
page.tsx # server component: fetches initial data
login/page.tsx # PIN entry
api/ # state, items, settings, export (CSV), unfurl (product links), auth, calendar feed, mcp (Claude connector), ai-jobs, worker routes
components/ # HouseListApp (shell), views/ (Home, List, Rooms, Money), ItemRow, QuickAdd, ItemSheet, …
lib/ # store (shared state + sync), items-service (write rules), plan (budget maths), parse (quick add), mcp + mcp-tools (connector), rooms (paints), …
proxy.ts # PIN-gate middleware (Next.js 16's middleware convention)
prisma/
schema.prisma # Item, Step, Quote, Comment, AiJob, Settings models
scripts/
ai-worker.mjs # the Ask Claude worker (runs claude -p on your computer)