feat(desktop): what waits in the Inbox carries each item's agent and question
Merged
DA
6d ago+90+90+01234567890123456789-14-14-01234567890123456789
Summary
- Factory v1, PR 1 of 3. Main's account-wide Inbox read already holds each open item's agent, title, and posting instant (
account-inbox-wire.ts); the app-state slice it writes (inbox.waiting) kept only each item's id. Each waiting item now carries{ id, agentId, title, postedAt }, so the Factory tab (PR 3) can name each question and the agent stalled on it from main's one read, with no read per plan and no server work. - The toast's withdrawal reads the ids off the items; the sidebar count is unchanged.
waitingOfjoins#testing/plans-controlas the shared builder for a waiting item (two callers here, the Factory model's tests next).- Builds on the Inbox, which stays; Chat is separate.
Evidence
- Platform-independent checks:
pnpm check:affectedexit 0 (typecheck, lint, 470 desktop tests);./scripts/check.shexit 0. - New test
what waits carries each open item's agent, what it asks, and when it was posted…inagent-notices.test.ts; it fails on main'sagent-notices.tsand passes here. - macOS Electron verification (
./scripts/verify.sh):not run— no UI changes; nothing drawn differs.
Visual evidence
- Fixture screenshots inspected:
not attached(no UI change).
Physical-device evidence
- Screenshot or screen recording:
not attached - Device/display configuration:
not recorded
Invariants
-
./scripts/check.shgreen; renderer/UI PRs also./scripts/verify.shwith evidence inspected. (CI) — not a UI change. - JSON Schema goldens unchanged (
LUKE_UPDATE_FIXTURESnot run, or diff explained line by line). (CI) - Every behavior change has, in this PR, the test that fails without it; no change-detector test added. (manual; root
AGENTS.md"Testing") - Gateway envelope goldens unchanged. (CI)
- No new
astype assertion outside the allowlisted files. (CI via anti-slop) - No
Effect.runPromise/runSync/runForkoutside the runtime edges and the shimstools/oxlint/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-run-promise-outside-edges) - No new
setTimeout/setInterval/new Promise/AbortController/fs.watchoutside the filestools/oxlint/anti-slop/effect-edges.jsonrecords. (CI viaanti-slop/no-raw-async-primitives) - No Effect, Stream, or Layer written as a statement and dropped; a description a caller walks past runs nothing. (CI via
pnpm discarded-effect) - Test count equals the pre-PR count or the delta is listed. (manual:
vitest run --reporter=json) — +1 desktop test. - Each hand-rolled file the PR replaces is deleted, or the part that remains is a permanent adaptor named in root
AGENTS.md's "The permanent adaptors" with the reason it stays. - Every
CLAUDE.md/AGENTS.mdsentence naming a changed part is edited; root pair stays byte-identical. (CI for pair existence; manual for wording) — none names the slice. -
PRIVACY.mdunchanged, or the change is a product decision called out in the PR body. - Package
package.jsondeps match what the sources import by bare specifier;effectviacatalog:. (CI) - Barrel/door rule: no Node-reaching Effect module (
@effect/platform-node,effect/sql) behind a barrel the renderer or a web function opens. (CI: existing renderernode:grep plus a new grep for those specifiers in renderer bundles)
Notes
- Blockers or follow-up verification: None. Next: the Factory model (stacked on this), then the view, which ships behind the Experimental flag.
🤖 Generated with Claude Code
Summary by cubic
The Inbox waiting slice now carries each item's agent, question, and posting time alongside its id, so the Factory tab can name what each agent is stalled on from main's single account-wide read without per-plan reads.
inbox.waitingitems are now{ id, agentId, title, postedAt }instead of bare ids; the sidebar count and toast withdrawal behavior are unchanged.waitingOfin#testing/plans-controlis the shared test builder for a waiting item.- Adds a test asserting one account-wide read groups waiting items by plan with each item's full detail.