Public: anyone can read this; the crew can change it.
Each week, get a seller update email to approve: what went out for their listing, what is scheduled next, and the property page link #86
Check · Review · Land · Live done — Landed and live in production.
Each listing now has a drafted weekly seller update on its own **Seller update** tab. It goes through the same Approve / Withdraw flow as every other asset. `bun test` passes (319 tests) and `bun run lint:design` is clean. `bun x tsc --noEmit` printed only its help text and checked nothing, because the repo has no `tsconfig.json`. There is no `scripts/gate.ts`.
shipped production is serving it deploy 957b843
Each listing now has a drafted weekly seller update on its own Seller update tab. It goes through the same Approve / Withdraw flow as every other asset. bun test passes (319 tests) and bun run lint:design is clean. bun x tsc --noEmit printed only its help text and checked nothing, because the repo has no tsconfig.json. There is no scripts/gate.ts.
What changed
- New module:
src/update.tshassellerUpdate(listing, now), plain data in and plain text out. It's addressed "Hello," and signed with the agent's name, brokerage, license, phone and email. It states:
- the address, status and price;
- every asset approved in the last 7 days, as "Approved by … on …";
- the launch-week rows for the next 7 days (read from schedule.ts, not changed);
- all upcoming open houses;
- the property page link.
- Stored as an asset: the update is a new asset kind,
email_update, labelled "Seller update". That is what gives it the Fair Housing check, editing, the "Draft — not approved" band and the usual Copy button. No new approval path and nocontract.jsonchange. The README,AGENTS.mdandcontract/openapi.jsonare updated. - Following approvals: an update nobody has edited or approved is rewritten whenever another asset is approved or withdrawn, so it lists what was approved. Once edited, it stays as written.
- Clearing approval: editing facts, changing the tone, or changing the status clears its approval. A status change on a hand-edited update clears the approval but keeps the words.
- Existing listings: on boot, any listing without an update gets a draft. The Alder Lane sample gets its update signed by the sample agent, and a fresh sample opens with it approved.
- Off-market listings: the update lists no open houses, matching the launch week, which is empty for them.
- Tests:
src/update.test.tscovers:
- only this week's approvals appear; - the next seven days of schedule and the open house dates; - the update clears on facts or status changes; - it can't be approved over the API or MCP; - the page section; - escaping; - the sample.
The hostile-listing test now edits the update too.
- README and
AGENTS.md: the meeting walkthrough gains one line (step 15), andAGENTS.mdlists the new module.
To look at
- The issue says the sample "lists six assets", but Alder Lane has seven others because the open house adds a follow-up email. The sample update lists seven.
- Because there is one more asset, I raised the expected counts in about a dozen existing tests, and the matching numbers in the README, by one ("0 of 6 approved" is now "0 of 7"). I checked each against the running app. I also changed the report test's "Approved by" count from 8 to 8 + 7, since the update repeats the seven approvals.
- A few tests that approve every asset now approve the update last, because it moves as the others are approved.
- A draft is only refreshed when something is approved or edited. The "this week" window won't advance on its own, so open the tab and approve to re-read it. I did not add a "Redraft" button.
- No
contract.jsoncell changed and no dependency was added.
How to try it: open Alder Lane, then Seller update, or launch a listing, approve a few assets and watch the update list them.
🤖 Generated with Claude Code
Good shape overall (no contract cell loosened, a person-only approval, escaped output, a single new module). Changes needed, in one round:
- FIRST: the draft goes stale when an asset is edited. redraftUpdate runs only from approve(). Editing an approved asset, restoring an earlier version, or any other path that clears an asset approval leaves the seller update still saying Approved by X on Y for words no longer approved, and an email to a seller that claims something went out is wrong. Call redraftUpdate (emit once) from every path that sets or clears another asset approval (editAsset, restore, tone/facts rewrite already rewrites), and add a test that edits an approved asset and sees it drop from the unedited draft. Your own note says it refreshes on edit; the code does not.
- Tests: the MCP check in update.test.ts ("only a person approves") asserts only a loose regex /person|isError|refus|cannot/i on the serialised body, which can pass when the call succeeds (isError:false matches). Assert the specific person_required error and that update approval stays null (it does check null, but the assertion on the refusal must be exact).
- Both doors: nothing tests the terminal for the Seller update (show it, approve with a, copy). Add a tty test that the asset appears and that a approves it, and one line in the README terminal section saying so.
- Clean: the markStatus change in actions.ts is a single very long line mixing a query, a ternary and a call; split it into named steps. The report test now counts 8 + 7 Approved by lines because the seller report repeats the update; confirm the seller report should list the internal update asset at all, or exclude email_update from it.
Boxes ticked below; the rest left with reasons.
All four review points are fixed and pushed. bun test passes (321 tests) and bun run lint:design is clean. I did not run bun x tsc --noEmit this round: the repo has no tsconfig.json, so the first-round run printed only the compiler's help text. scripts/gate.ts does not exist either.
- Stale draft: the seller update is now written again whenever another asset's approval is cleared.
- Editing an asset does it. Restoring an earlier version and "use suggested wording" go through that same edit, so they do it too. - A photo reorder or removal does it as well, because it clears the flyer's and email's approvals. I did not write a test for this path. - A new test edits and restores an approved asset and checks it drops out of the update, while another approval stays listed. - An update a person has edited, or one already approved, is still left as it is. An approved update therefore keeps its words even if an asset it listed is later edited. Tell me if you want that approval cleared as well.
- MCP test: it now checks that the result is an error and that its text starts with
person_required:. The update's approval still stays null. - Terminal: a new tty test moves to the Seller update, which is the last asset. It checks the draft shows, that
aapproves it, and that a secondawithdraws it. The README's walkthrough step now says so. The terminal has no Copy for any asset, so there is nothing to test there. - Clean-up:
- markStatus: the long line is split into named steps (updateDrafted, written).
- Seller report: I excluded the update from it, since it's the agent's note to the seller and not something that goes out. The report test counts are back to 7, and the terminal test string for the report is back to "1 of 6 assets approved". The launch kit still includes it.
contract.json is unchanged.
🤖 Generated with Claude Code
I merged main into the branch, resolved the six conflicts, and pushed. bun test passes (330 tests) and bun run lint:design is clean.
src/generate.tsandcontract/openapi.json:main'ssocial_reminderandemail_reminderkinds and myemail_updateare all kept. I regeneratedopenapi.jsonwithcontract:emitinstead of hand-merging it.src/pages/listing.ts:
- The Social and Email tabs include the reminder assets and the "Preview reminder" link.
- The Seller update tab and its draft band are kept.
- draftBand accepts email_reminder and email_update.
src/tty.test.ts: both tests are kept,main's reminder preview and my seller update approve/withdraw.- Counts: with
main's two new assets, a listing has one more asset than either side counted alone. I raised the expected totals insample.test.ts,walkthrough.test.tsandreminder.test.ts. Inupdate.test.ts, the Alder Lane sample's update now lists nine assets.
The earlier asks are met: the update now redrafts when another asset's approval clears (edit, restore, photo changes), the MCP test checks the person_required error, the terminal has a test for approving and withdrawing it, and the markStatus line is split. The report leaves the update out. No contract.json cell changed and there is no new dependency.
Non-blocking: an already-approved update keeps its words if a listed asset is edited afterwards, so it can name an asset that is no longer approved. Consider clearing its approval then. The photo-reorder redraft path has no test. There is a stray blank line at the end of the last test in update.test.ts.
I could not run git diff against the previous head because the clone does not have that commit, so I read the diff in full as given.
Each listing now has a drafted weekly seller update on its own Seller update tab. It goes through the same Approve / Withdraw flow as every other asset.
bun testpasses (319 tests) andbun run lint:designis clean.bun x tsc --noEmitprinted only its help text and checked nothing, because the repo has notsconfig.json. There is noscripts/gate.ts.What changed
src/update.tshassellerUpdate(listing, now), plain data in and plain text out. It's addressed "Hello," and signed with the agent's name, brokerage, license, phone and email. It states:- the address, status and price; - every asset approved in the last 7 days, as "Approved by … on …"; - the launch-week rows for the next 7 days (read from
schedule.ts, not changed); - all upcoming open houses; - the property page link.email_update, labelled "Seller update". That is what gives it the Fair Housing check, editing, the "Draft — not approved" band and the usual Copy button. No new approval path and nocontract.jsonchange. The README,AGENTS.mdandcontract/openapi.jsonare updated.src/update.test.tscovers:- only this week's approvals appear; - the next seven days of schedule and the open house dates; - the update clears on facts or status changes; - it can't be approved over the API or MCP; - the page section; - escaping; - the sample.
The hostile-listing test now edits the update too.
AGENTS.md: the meeting walkthrough gains one line (step 15), andAGENTS.mdlists the new module.To look at
contract.jsoncell changed and no dependency was added.How to try it: open Alder Lane, then Seller update, or launch a listing, approve a few assets and watch the update list them.
🤖 Generated with Claude Code
Closes #75