Skip to content

Weekendsuperhero-io/cadence

Repository files navigation

Cadence — a Co-Pilot for Co-Parents

Paste the week's chaos. Get a clean schedule, a fair settle-up, and a neutral message you can actually send. Chaos in → structure out.

Cadence organizes logistics. It is not legal, financial, mental-health, or relationship advice. It turns messages into a schedule, an expense ledger, and a neutral draft you review and send yourself. Always confirm details directly with the other parent. Cadence does not make decisions or store your data.

One engine, two surfaces: a Claude MCP that renders its result inline in the chat, and a standalone web app. Built at Claude Build Day with Claude Code + Opus 4.8 (claude-opus-4-8).


Demo

Watch the demo — Cadence untangling a real week of co-parenting logistics, inline in Claude.


What you get

Paste a messy week of texts, emails, and notes → four structured artifacts:

Artifact What you get
🗓 Schedule Week-at-a-glance custody/handoff events (+ .ics in the web app)
💸 Settle-Up A minimal "X owes Y $Z" ledger, itemized, reconciled to the cent — computed in code, never by the model
✉️ Message One neutral, ready-to-send BIFF message — disputed items are left out and asked about, never assumed
⚠️ Conflicts Double-bookings, math mismatches, ambiguous dates — found by a validation agent and an independent deterministic backstop

Every extracted item shows the exact source line it came from — nothing is invented.


Surface 1 — Cadence as an MCP (inline in Claude) ⭐

cadence-mcp/ is a TypeScript MCP server that wraps the same engine and renders the four cards inline inside Claude, as a sibling to your email / calendar / iMessage MCPs. This is the strategic shape: untangle your logistics without leaving the conversation.

  • Tool untangle({ blob }) → returns the structured ProcessResult and an inline ui://cadence/result widget — a self-contained text/html;profile=mcp-app document (MCP-UI / MCP Apps) that paints the four cards right in the chat.
  • Same engine, zero reimplementation — it imports lib/orchestrator.ts's runPipeline; run via tsx (no build step).
  • Proven live on real data: calendar + email + iMessage pulled from sibling MCPs → untangle → inline widget, with a real conflict caught and a sendable message drafted.
# Register it with Claude (absolute paths; runs the live TS source via tsx):
claude mcp add cadence -- \
  /ABS/PATH/cadence/node_modules/.bin/tsx \
  --tsconfig /ABS/PATH/cadence/cadence-mcp/tsconfig.json \
  /ABS/PATH/cadence/cadence-mcp/src/index.ts
npm run mcp:smoke     # offline contract test — 13 checks, zero API calls
npm run mcp:inspect   # open the MCP Inspector and see the widget render

Details, the rawHtml-vs-MCP-Apps decision log, and verification live in cadence-mcp/README.md.

Agent timeout knob — one env var, CADENCE_AGENT_TIMEOUT_MS, raises the per-agent ceiling for every agent + the orchestrator guard. The web app leaves it unset (28s, safe under Vercel's 60s limit); cadence-mcp (a local stdio server with no such limit) defaults it to 90s so larger real-world inputs aren't cut off.


Surface 2 — Cadence as a web app

npm install
cp .env.local.example .env.local   # add your ANTHROPIC_API_KEY (server-side only)
npm run dev                        # http://localhost:3000

Click "Load demo blob"Untangle. The demo runs offline from a committed snapshot (Safe Mode), so it works with or without a key; anything you type runs live on Opus 4.8. The UI ships a frosted glass / crystal theme with a 🌙 dark mode toggle.

Note: if your shell forces global npm installs, run installs as env npm_config_global=false npm_config_location=project npm install. Running scripts is unaffected.


Architecture — both surfaces, one engine

untangle({ blob })   ·or·   POST /api/process { blob }      (key stays server-side)
   │
   └─► runPipeline()  (lib/orchestrator.ts)
        ├─ Stage A  PARALLEL   schedule agent ‖ expense agent      [Opus 4.8, structured output]
        ├─ Stage B  OUR CODE   settle() → ledger ; overlap() → flags   (deterministic, unit-tested)
        ├─ Stage C  PARALLEL   comms agent ‖ validation agent
        └─ Stage D  assemble + merge model & deterministic conflicts → ProcessResult
                                  │                         │
                        web: 4 React cards        mcp: ui://cadence/result widget
  • Opus 4.8 via messages.parse() + zodOutputFormat — structured output validated against Zod (the single source of truth in lib/schemas.ts). Adaptive thinking; no sampling params.
  • The ledger is computed by code, not the model — agents emit line items; lib/settle.ts nets them, so the money is always correct.
  • Safe Mode — a blob matching a golden returns a committed snapshot with zero API calls (offline-safe; demo-proof). Add ?live=1 (web) / live:true (MCP) to force the real pipeline.
  • Never a raw failure — always a { ok, result?, error? } envelope; per-agent failures degrade gracefully.

Repo layout

cadence-mcp/    src/{index,render,ui-resource,env}.ts · scripts/smoke.ts · README.md   ← the MCP surface
app/            page.tsx + api/process + api/health
components/     InputPanel · {Schedule,SettleUp,Message}Card · ConflictBanner · ThemeToggle · ui/
lib/            schemas.ts · settle.ts · ics.ts · overlap.ts (pure, tested)
                anthropic.ts · agents/* · prompts/* · orchestrator.ts · grader.ts · fixtures.ts
tests/          settle · ics · overlap · schemas · golden (deterministic) + rubric.llm (graded)
brief.md  rubric.md  workflow.mjs        # the verifiable-done harness

Stack: Next.js 16 (App Router) · TypeScript · Tailwind v4 · @anthropic-ai/sdk + Opus 4.8 · @modelcontextprotocol/sdk + @mcp-ui/server · tsx · Vitest · Vercel.


"Done" is verifiable by the model — no human

npm test                 # deterministic: schema + ledger math + .ics + overlap + golden snapshots
npm run mcp:smoke        # the MCP contract: tools/list + untangle + a non-empty ui:// widget (offline)
npm run test:rubric      # Opus grades the output against rubric.md (needs ANTHROPIC_API_KEY)
node workflow.mjs verify # tests + a 200 from the live URL + the demo blob flags its planted conflict

Several rubric criteria (schema validity, calendar correctness, ledger reconciliation) are computed in code, and the Opus grader is told to defer to those verdicts — so a hallucinating grader can't pass genuinely broken math.

The harness is generic: swap brief.md + rubric.md + fixtures/*_input.txt and node workflow.mjs all re-runs scaffold → generate → test → grade → verify on a new problem, no code change.


Deploy (web, Vercel)

npx vercel                                  # preview
npx vercel env add ANTHROPIC_API_KEY production
npx vercel --prod                           # live URL

The key is read only inside app/api/** and is never prefixed NEXT_PUBLIC_.

License

MIT. See docs/build-narrative.md for how it was directed and where it caught itself.

About

Stay Up to date without the chaos

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages