Inspiration

I was staring at my inbox at midnight, 847 unread, knowing there was a Slack DM from earlier I'd forgotten to answer and a PR sitting untouched for over a week. The problem wasn't any single tool. It was that no single tool sees all of it together and tells you what you're dropping. I wanted an agent that could look across Gmail, Calendar, GitHub, and Slack and actually do something about it, not just show me another notification.

What it does

Loose Ends scans your connected services for dropped threads, ranks them by urgency, and suggests actions. It reads an email and books the calendar event. Posts a comment on a stale PR and pings the reviewer on Slack. Sends a reply in your voice. Every action requires phone approval through Auth0 CIBA, so the agent never acts without you saying yes.

How I built it

I started with the spec-driven development process. Before writing code, I wrote a scope document defining what was in and out of bounds, a PRD with 8 user stories and acceptance criteria, a technical spec with architecture diagrams and data flow maps, and a build checklist breaking the project into tasks with checkboxes. These are all in the docs/ folder.

The stack is Next.js 16 on Vercel, Auth0 for authentication and token management (Token Vault, FGA, CIBA), Claude via Vercel AI SDK for the AI layer, and Neon Postgres for persistence. The agent uses tool calling with inputSchema and stepCountIs from AI SDK v6 to scan services and reason about what to do.

The specs shaped the build. The scope doc kept me from adding features that didn't matter. The PRD's acceptance criteria told me when a feature was actually done. The technical spec's architecture diagram caught a design mistake early, I was about to put token handling on the client side before the spec made me think through the security model.

Challenges I faced

The Auth0 Next.js SDK had just moved to v4 and every tutorial online was written for v3. I burned most of a day fighting middleware issues. My redirect was pointing to /auth/login when Token Vault needed /auth/connect, which produced unhelpful 404s.

The Vercel AI SDK v6 migration was rough. Tool calling had changed to a new format and my chat panel was crashing silently. I spent hours stripping out abstractions until I found the real problem: a compatibility issue between the AI SDK and the Anthropic provider (GitHub issue #12020).

Wiring four OAuth providers through Token Vault meant four different API quirks. Slack uses oauth.v2.user.access instead of the standard token endpoint. Each provider was a small paper cut, together they ate a full day.

When scope crept (Slack wasn't in the original plan), I went back to the scope doc, updated it, and adjusted the downstream specs before writing code. That discipline came directly from the spec-driven process.

What I learned

The biggest lesson was that specs aren't just documentation. They're a conversation with yourself about what you're actually building. When I was debugging at 3am, the PRD kept me from rabbit-holing into features that didn't matter. When I wanted to add a fifth integration, the scope doc made me ask whether it was worth the time.

I'd also do the technical spec's security model first next time. The trust layer (Token Vault for credentials, FGA for permissions, CIBA for phone approval) ended up being the core of the product, but I originally spec'd it as a sub-section. It deserved to be the organizing principle of the whole document.

Accomplishments that I'm proud of

The CIBA flow. Getting the full loop working where the agent reads an email, checks your calendar, drafts a reply, sends a push notification to your phone, and then only acts after you approve with Face ID. That moment where you tap once and the calendar event appears on your laptop while the reply lands in the sender's inbox, that felt like the future. Two services, one tap, no tab switching.

Also the FGA permission toggles. You flip a switch on the settings page and the agent's behavior changes immediately on the next scan. That instant feedback loop where the user feels in control wasn't something I expected to care about, but it ended up being one of the best parts of the UX.

And honestly just shipping a working app across four real OAuth providers. Mock data is easy. Getting Gmail, Calendar, GitHub, and Slack all talking through Token Vault with real tokens and real API calls was a grind, but it works.

What's next for Loose Ends

I want the agent to explain its reasoning better. Right now it tells you what it wants to do but not always why. "I'm suggesting you reply because this email is 3 days old and you've replied to this person within 24 hours historically" is way more useful than just "Reply to this email?"

I also want to add proactive nudges where the agent notices patterns over time. Like "your PM hasn't updated the Q2 doc in a week, want me to ping them?" or "you have three back-to-back meetings Thursday, want me to propose moving standup?"

And better cross-service reasoning. Right now the agent handles each service mostly independently. I want it to connect dots, like noticing a PR reviewer is the same person who emailed you about something related.

Built With

  • anthropic-claude
  • auth0
  • auth0-ciba
  • auth0-guardian
  • framer-motion
  • github-api
  • gmail-api
  • google-calendar-api
  • neon-postgres
  • next.js
  • openfga
  • react
  • slack-api
  • tailwind-css
  • typescript
  • vercel-ai-sdk
  • zod
Share this project:

Updates