# Project export: Snappier

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2026
- Tagline: Show Snappier your workflow once by recording your screen. AI figures out what you did and why, then automates it across any connected app. That's it.
- Devpost: https://devpost.com/software/snappier
- GitHub: https://github.com/nintang/snappier-treehacks
- Demo: https://snappier-thh.vercel.app/
- Video: https://www.youtube.com/embed/Mi4oWY_EkYc?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner ([Graphite] Most Likely to get Acquired by a Sponsor (OB–4 black bluetooth speaker); [Vercel] Best Use of Vercel/Best Deployed on Vercel (2k cash prize + $2.4k in Pro-level access credits ($100/month for 4 winners, access for 6 months.))
- Team: 3 GitHub contributor(s) — David Nintang (85 commits), Claude Opus 4.6 (68 commits), akinolaepaphras (6 commits)

## Devpost submission (written by the team)

### Inspiration

Most people can't automate their work because automation tools require programming skills. You need to understand APIs, data mapping, and conditional logic. Meanwhile, those same people teach their coworkers how to do things all the time by just showing them. We wanted to make automation work the way humans naturally teach: by demonstration, not configuration.

### What it does

Snappier turns screen recordings into automated workflows in 3 steps: Record — Perform your workflow once in the browser. Our Chrome extension captures everything (e.g., scrape LinkedIn → add to Google Sheets → send Slack message) Record — Perform your workflow once in the browser. Our Chrome extension captures everything (e.g., scrape LinkedIn → add to Google Sheets → send Slack message) Generate — AI watches the video and builds the automation. Gemini extracts what you did, Claude figures out the API calls, and we map it to 100+ SaaS tools via Composio Generate — AI watches the video and builds the automation. Gemini extracts what you did, Claude figures out the API calls, and we map it to 100+ SaaS tools via Composio Run — One click executes the entire workflow across your connected apps. Run it again anytime, or schedule it automatically Run — One click executes the entire workflow across your connected apps. Run it again anytime, or schedule it automatically No drag-and-drop builders. No field mapping. Just show us once and we automate it forever.

### How we built it

Frontend: Next.js 15 + React 19 + TypeScript + Tailwind CSS + React Flow (interactive workflow graphs) AI Pipeline: Google Gemini (gemini-3-pro-preview) for multimodal video understanding. Analyzes recordings frame-by-frame to extract structured steps with intent, confidence scores, and timestamps Claude Haiku for fast intent summarization and noise filtering to remove accidental clicks Claude Sonnet for workflow execution reasoning with tool-use calling OpenAI Whisper for audio transcription for narrated workflows Vercel AI SDK as unified interface for all LLMs with structured output (Zod schemas) Integrations: Composio provides 100+ pre-built SaaS tool integrations with OAuth and tool-calling APIs Cloudflare R2 for scalable video storage Clerk for user authentication Chrome Extension: Manifest V3 extension that captures screen video (WebM) + granular DOM events (clicks, keyboard, navigation) Architecture: Multi-modal step extraction (AI vision + DOM events + audio) → Intent summarization → Tool detection via URL pattern matching → Workflow generation → Composio execution with full audit logs

### Challenges we ran into

Video understanding reliability – Getting Gemini to consistently extract structured steps from noisy screen recordings took extensive prompt engineering and low-temperature sampling (0.2) Video understanding reliability – Getting Gemini to consistently extract structured steps from noisy screen recordings took extensive prompt engineering and low-temperature sampling (0.2) Intent vs. action gap – Users click buttons in the browser, but workflows need to call APIs. Bridging "clicked the blue button" to "send_email via Gmail API" required semantic reasoning with Claude Intent vs. action gap – Users click buttons in the browser, but workflows need to call APIs. Bridging "clicked the blue button" to "send_email via Gmail API" required semantic reasoning with Claude Noise filtering – We didn't realize how many accidental clicks, scrolls, and micro-adjustments users make. Our AI had to learn to ignore 80% of recorded actions Noise filtering – We didn't realize how many accidental clicks, scrolls, and micro-adjustments users make. Our AI had to learn to ignore 80% of recorded actions OAuth at scale – Managing connections across 100+ SaaS tools (each with different auth flows) was only feasible thanks to Composio's abstraction layer OAuth at scale – Managing connections across 100+ SaaS tools (each with different auth flows) was only feasible thanks to Composio's abstraction layer Real-time workflow editing – Keeping the React Flow graph, step list, and video player synchronized while the user edits was a complex state management challenge Real-time workflow editing – Keeping the React Flow graph, step list, and video player synchronized while the user edits was a complex state management challenge

### Accomplishments we're proud of

Multi-modal AI fusion – We combined video, DOM events, and audio into a single coherent understanding. Each modality validates the others (if Gemini sees a click AND the DOM recorded a click, high confidence) Multi-modal AI fusion – We combined video, DOM events, and audio into a single coherent understanding. Each modality validates the others (if Gemini sees a click AND the DOM recorded a click, high confidence) End-to-end working demo – From recording to execution, the full pipeline works. You can actually record a workflow and run it against real SaaS APIs End-to-end working demo – From recording to execution, the full pipeline works. You can actually record a workflow and run it against real SaaS APIs Intent-aware automation – We don't just replay mechanical actions. Snappier understands what you were trying to accomplish and finds the best API-level way to do it Intent-aware automation – We don't just replay mechanical actions. Snappier understands what you were trying to accomplish and finds the best API-level way to do it Control flow detection – Our AI detects loops ("for each row in this spreadsheet...") and conditionals, not just linear sequences Control flow detection – Our AI detects loops ("for each row in this spreadsheet...") and conditionals, not just linear sequences Production-ready architecture – Cloudflare R2 storage, Clerk auth, comprehensive test suite (Vitest), type-safe throughout Production-ready architecture – Cloudflare R2 storage, Clerk auth, comprehensive test suite (Vitest), type-safe throughout

### What we learned

Multimodal > unimodal – Video analysis alone misses context. DOM events alone can't infer intent. Audio alone is ambiguous. Together, they're powerful. Multimodal > unimodal – Video analysis alone misses context. DOM events alone can't infer intent. Audio alone is ambiguous. Together, they're powerful. Low-temperature LLMs are essential – For structured extraction, we needed temperature=0.2 or lower. Creativity kills reliability here. Low-temperature LLMs are essential – For structured extraction, we needed temperature=0.2 or lower. Creativity kills reliability here. Tool abstractions unlock scale – Building 100+ integrations from scratch would've been impossible. Composio's tool-calling abstraction made it feasible. Tool abstractions unlock scale – Building 100+ integrations from scratch would've been impossible. Composio's tool-calling abstraction made it feasible. Users are noisy – Humans don't realize how many random clicks, back-buttons, and scrolls they do. Filtering signal from noise is 80% of the challenge. Users are noisy – Humans don't realize how many random clicks, back-buttons, and scrolls they do. Filtering signal from noise is 80% of the challenge. Video-first is fundamentally different – Teaching by demonstration feels more natural than form-based builders. It's how we teach humans; why not computers? Video-first is fundamentally different – Teaching by demonstration feels more natural than form-based builders. It's how we teach humans; why not computers?

### What's next

Runtime control flow – Execute loops and conditionals, not just detect them Scheduled workflows – Cron-style automation (run every morning, every week, etc.) Team collaboration – Share workflow libraries across organizations Workflow marketplace – Discover and remix workflows from the community Mobile recording – iOS/Android screen recording support Advanced parameter inference – Better extraction of dynamic values (names, emails, dates) from recordings Multi-step editing – Visual graph editor to rearrange, add, or remove steps post-recording

## README (from the GitHub repository)

# Snappier

## Inspiration

Most people can't automate their work because automation tools require programming skills. You need to understand APIs, data mapping, and conditional logic. Meanwhile, those same people teach their coworkers how to do things all the time by just showing them. We wanted to make automation work the way humans naturally teach: by demonstration, not configuration.

## What it does

Snappier turns screen recordings into automated workflows in 3 steps:

1. **Record** — Perform your workflow once in the browser. Our Chrome extension captures everything (e.g., scrape LinkedIn → add to Google Sheets → send Slack message)
2. **Generate** — AI watches the video and builds the automation. Gemini extracts what you did, Claude figures out the API calls, and we map it to 100+ SaaS tools via Composio
3. **Run** — One click executes the entire workflow across your connected apps. Run it again anytime, or schedule it automatically

No drag-and-drop builders. No field mapping. Just show us once and we automate it forever.

## How we built it

**Frontend**: Next.js 15 + React 19 + TypeScript + Tailwind CSS + React Flow (interactive workflow graphs)

**AI Pipeline**:
- Google Gemini (gemini-3-pro-preview) for multimodal video understanding. Analyzes recordings frame-by-frame to extract structured steps with intent, confidence scores, and timestamps
- Claude Haiku for fast intent summarization and noise filtering to remove accidental clicks
- Claude Sonnet for workflow execution reasoning with tool-use calling
- OpenAI Whisper for audio transcription for narrated workflows
- Vercel AI SDK as unified interface for all LLMs with structured output (Zod schemas)

**Integrations**:
- Composio provides 100+ pre-built SaaS tool integrations with OAuth and tool-calling APIs
- Cloudflare R2 for scalable video storage
- Clerk for user authentication
- Chrome Extension: Manifest V3 extension that captures screen video (WebM) + granular DOM events (clicks, keyboard, navigation)

**Architecture**: Multi-modal step extraction (AI vision + DOM events + audio) → Intent summarization → Tool detection via URL pattern matching → Workflow generation → Composio execution with full audit logs

## Challenges we ran into

- **Video understanding reliability** – Getting Gemini to consistently extract structured steps from noisy screen recordings took extensive prompt engineering and low-temperature sampling (0.2)
- **Intent vs. action gap** – Users click buttons in the browser, but workflows need to call APIs. Bridging "clicked the blue button" to "send_email via Gmail API" required semantic reasoning with Claude
- **Noise filtering** – We didn't realize how many accidental clicks, scrolls, and micro-adjustments users make. Our AI had to learn to ignore 80% of recorded actions
- **OAuth at scale** – Managing connections across 100+ SaaS tools (each with different auth flows) was only feasible thanks to Composio's abstraction layer
- **Real-time workflow editing** – Keeping the React Flow graph, step list, and video player synchronized while the user edits was a complex state management challenge

## Accomplishments that we're proud of

- **Multi-modal AI fusion** – We combined video, DOM events, and audio into a single coherent understanding. Each modality validates the others (if Gemini sees a click AND the DOM recorded a click, high confidence)
- **End-to-end working demo** – From recording to execution, the full pipeline works. You can actually record a workflow and run it against real SaaS APIs
- **Intent-aware automation** – We don't just replay mechanical actions. Snappier understands what you were trying to accomplish and finds the best API-level way to do it
- **Control flow detection** – Our AI detects loops ("for each row in this spreadsheet...") and conditionals, not just linear sequences
- **Production-ready architecture** – Cloudflare R2 storage, Clerk auth, comprehensive test suite (Vitest), type-safe throughout

## What we learned

- **Multimodal > unimodal** – Video analysis alone misses context. DOM events alone can't infer intent. Audio alone is ambiguous. Together, they're powerful.
- **Low-temperature LLMs are essential** – For structured extraction, we needed temperature=0.2 or lower. Creativity kills reliability here.
- **Tool abstractions unlock scale** – Building 100+ integrations from scratch would've been impossible. Composio's tool-calling abstraction made it feasible.
- **Users are noisy** – Humans don't realize how many random clicks, back-buttons, and scrolls they do. Filtering signal from noise is 80% of the challenge.
- **Video-first is fundamentally different** – Teaching by demonstration feels more natural than form-based builders. It's how we teach humans; why not computers?

## What's next for Snappier

- **Runtime control flow** – Execute loops and conditionals, not just detect them
- **Scheduled workflows** – Cron-style automation (run every morning, every week, etc.)
- **Team collaboration** – Share workflow libraries across organizations
- **Workflow marketplace** – Discover and remix workflows from the community
- **Mobile recording** – iOS/Android screen recording support
- **Advanced parameter inference** – Better extraction of dynamic values (names, emails, dates) from recordings
- **Multi-step editing** – Visual graph editor to rearrange, add, or remove steps post-recording

## Built With

- ai
- anthropic-claude-(workflow-planning-&-execution)
- api
- chrome
- clerk
- cloudflare
- composio
- extensions
- framer-motion-ai/llm:-google-gemini-(video-understanding)
- gemini
- openai-whisper-(transcription)
- r2
- react-19
- react-flow
- saas
- sdk
- tailwind-css
- typescript
- vercel
- vitest
- zod

## Detected evidence (automated analysis)

Indexed codebase: 127 recognized source files, 661 KB.
- CSS (language) — detected in the code
- Google Gemini (technology) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code
- Vercel AI SDK (technology) — detected in the code
- Tailwind CSS (technology) — claimed on Devpost, not found in the code
- Vercel (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 131)

```
.eslintrc.json
.gitignore
ANALYSIS_CARD_REDESIGN.md
app/api/chat/route.ts
app/api/connections/all/route.ts
app/api/connections/callback/route.ts
app/api/connections/disconnect/route.ts
app/api/connections/initiate/route.ts
app/api/connections/status/route.ts
app/api/process/[id]/analysis/route.ts
app/api/process/[id]/detected-tools/route.ts
app/api/process/[id]/route.ts
app/api/process/[id]/video/route.ts
app/api/process/[id]/workflow-model/route.ts
app/api/process/complete/route.ts
app/api/process/route.ts
app/api/process/upload-url/route.ts
app/api/run-workflow/route.ts
app/api/runs/[id]/route.ts
app/api/runs/route.ts
app/api/toolkits/route.ts
app/api/video-understanding/route.ts
app/connect/[id]/page.tsx
app/connections/page.tsx
app/globals.css
app/layout.tsx
app/page.tsx
app/process-completed/page.tsx
app/recording-complete/page.tsx
app/runs/page.tsx
app/sign-in/[[...sign-in]]/page.tsx
app/sign-up/[[...sign-up]]/page.tsx
app/start/page.tsx
app/studio/[id]/page.tsx
app/video-understanding-demo/page.tsx
components/connect/ConnectionGate.module.css
components/connect/ConnectionGate.tsx
components/connect/ToolCard.module.css
components/connect/ToolCard.tsx
components/dashboard/ConnectedApps.module.css
components/dashboard/ConnectedApps.tsx
components/dashboard/Dashboard.module.css
components/dashboard/Dashboard.tsx
components/dashboard/RecordingItem.tsx
components/dashboard/WorkflowCard.tsx
components/demo/VideoUnderstandingDemo.module.css
components/demo/VideoUnderstandingDemo.tsx
components/recording-complete/RecordingComplete.module.css
components/recording-complete/RecordingComplete.tsx
components/runs/RunDetailPanel.module.css
components/runs/RunDetailPanel.tsx
components/runs/RunsPage.module.css
components/runs/RunsPage.tsx
components/runs/RunsTable.module.css
components/runs/RunsTable.tsx
components/studio/ChatPanel.module.css
components/studio/ChatPanel.tsx
components/studio/nodes/nodeTypes.ts
components/studio/nodes/WorkflowNode.module.css
components/studio/nodes/WorkflowNode.tsx
components/studio/RecordingPanel.module.css
components/studio/RecordingPanel.tsx
components/studio/StepCard.module.css
components/studio/StepCard.tsx
components/studio/StepsPanel.module.css
components/studio/StepsPanel.tsx
components/studio/VariableDrawer.module.css
components/studio/VariableDrawer.tsx
components/studio/WorkflowGraph.tsx
components/studio/WorkflowStudio.module.css
components/studio/WorkflowStudio.tsx
components/ui/AppHeader.module.css
components/ui/AppHeader.tsx
components/ui/OverflowMarquee.tsx
components/ui/StudioHeader.module.css
components/ui/StudioHeader.tsx
docs/workflow-migration/CHANGELOG.md
docs/workflow-migration/OUTPUT-SCHEMA.md
docs/workflow-migration/PHASES.md
docs/workflow-migration/README.md
docs/workflow-migration/USE-CASES.md
lib/__tests__/connections-all-route.test.ts
lib/__tests__/connections-callback-route.test.ts
lib/__tests__/connections-disconnect-route.test.ts
lib/__tests__/connections-initiate-route.test.ts
lib/__tests__/connections-status-route.test.ts
lib/__tests__/deterministic-plan.test.ts
lib/__tests__/fixtures/linkedin-to-sheets-recording.fixture.ts
lib/__tests__/fixtures/recorded-screen-output.fixture.ts
lib/__tests__/process-analysis-route.test.ts
lib/__tests__/process-analysis.test.ts
lib/__tests__/process-presenter.test.ts
lib/__tests__/process-route.test.ts
lib/__tests__/process-store.test.ts
lib/__tests__/run-store.test.ts
lib/__tests__/run-workflow-route.test.ts
lib/__tests__/trace-quality.test.ts
lib/__tests__/trace-semantics.test.ts
lib/__tests__/workflow-model-route-auth.test.ts
lib/__tests__/workflow-model.test.ts
lib/__tests__/workflow-planner-linkedin.test.ts
lib/__tests__/workflow-planner.test.ts
lib/composio.ts
lib/connection-return.ts
lib/deterministic-plan.ts
lib/generated-workflow-store.ts
lib/logo-dev.ts
lib/process-analysis.ts
lib/process-presenter.ts
lib/process-store-dir.ts
lib/process-store.ts
lib/process-types.ts
lib/recording.ts
lib/run-store.ts
lib/storage-backend.ts
lib/tools.ts
lib/trace-quality.ts
lib/trace-semantics.ts
lib/use-workflow-draft.ts
lib/video-understanding.ts
[11 more files omitted for size]
```

### Dependencies

- package.json: @ai-sdk/gateway@^3.0.46, @ai-sdk/react@^3.0.88, @aws-sdk/client-s3@^3.990.0, @aws-sdk/s3-request-presigner@^3.990.0, @clerk/nextjs@^6.37.4, @composio/core@^0.6.3, @composio/vercel@^0.6.3, @google/genai@^1.41.0, @google/generative-ai@^0.24.1, @types/node@22.10.2, @types/react@^19.0.4, @types/react-dom@^19.0.4, @xyflow/react@^12.10.0, ai@^6.0.86, dotenv@^17.3.1, eslint@8.57.1, eslint-config-next@15.5.12, framer-motion@^12.34.0, lucide-react@^0.564.0, next@15.5.12, openai@^6.22.0, react@^19.0.4, react-dom@^19.0.4, react-markdown@^10.1.0, typescript@5.7.2, vitest@^3.2.4, workflow@^4.1.0-beta.57, zod@^4.3.6

### Recent commits (newest first)

- Update README.md with new content
- Fix ENOENT mkdir .process-store
- Fix serverless process-store dir (use /tmp)
- chore(deps): update package-lock
- feat(planner): improve inference and add output bindings
- feat(run): start workflow orchestration via workflow/api
- chore(workflow): wire workflow next integration
- chore(gitignore): ignore next build backups
- chore(dev): default dev to webpack, add dev:turbo
- fix(studio): keep no-op run status setter type-compatible
- feat(ui): add resizable recording panel and simplify connections header
- feat(studio): add workflow chat assistant panel
- feat(workflow): support node patch updates and toolkit logos
- test: add workflow planner test script for NYT scenario
- feat: add toolkit catalog export and update connection gate
- refactor: update workflow executor for improved tool handling
- feat: add LLM-based toolkit selection for workflow planning
- feat: add createToolRouterSession for managed tool connections
- feat: implement custom auth pages with OAuth integration
- refactor: rebrand to Snappier across all pages

## Key source files (fetched from GitHub, selected and truncated for size)

### ANALYSIS_CARD_REDESIGN.md

```markdown
# Analysis Status Card Redesign

## Problem
The original analysis status card felt too technical and exposed internal system state:
- Showed "Analysis status: Completed" with explicit status labels
- Used technical progress bars and system messages
- Felt like a debug panel rather than part of the natural workflow

## Solution
Transformed the card into a contextual, conversational helper that guides users naturally:

### Design States

1. **Ready to Analyze** (`promptCard`)
   - Warm gradient background (orange to white)
   - Friendly, conversational copy: "Your recording is ready. Let's analyze it..."
   - Clear call-to-action button
   - Feels inviting rather than technical

2. **Analyzing** (`analysisProgress`)
   - Minimal, integrated progress indicator
   - Subtle 3px progress bar with shimmer animation
   - Friendly label with spinner: "Analyzing your recording... X%"
   - Clean white background, less prominent than the prompt

3. **Error State** (`errorCard`)
   - Soft red background (not alarming)
   - Conversational error message
   - "Try again" button instead of technical "Retry"
   - Feels helpful rather than critical

## Aesthetic Approach

**Tone**: Collaborative assistant, not system monitor
**Visual**: Soft, integrated, warm
**Language**: Conversational, user-focused

### Key Changes

- ❌ Removed: "Analysis status: Completed"
- ❌ Removed: Technical status labels (Queued, Processing, etc.)
- ❌ Removed: Thick progress bars
- ✅ Added: Contextual prompts that speak to user intent
- ✅ Added: Subtle animations (shimmer, hover transforms)
- ✅ Added: Warm gradient backgrounds for key actions

### Visual Details

- **Prompt card**: Gradient from `#FFF3EC` to white with orange border
- **Progress bar**: 3px height (vs 6px), subtle shimmer animation
- **Buttons**: Micro-interactions (translateY on hover)
- **Typography**: Friendly, complete sentences vs. status codes

## Integration

The cards now feel like natural parts of the workflow creation process:
- They appear contextually when needed
- Use the same warm aesthetic as the rest of the app
- Guide users forward rather than report system state
- Disappear gracefully when analysis completes (steps appear instead)

## Technical Notes

- Removed unused `toAnalysisStatusLabel` function
- Removed unused `analysisMessage` variable
- Simplified component logic to focus on user actions
- All state transitions are visually smooth with CSS transitions

```

### docs/workflow-migration/USE-CASES.md

```markdown
# Recording-to-Workflow Use Cases (Code-Driven)

These use cases are based on structures produced by code (`TraceEvent`, `SemanticAction`, `AiWorkflowStep`, `DeterministicPlan`) and not on any specific stored recording.

## Use Case 1: Lead Intake -> CRM Update -> Slack Notify

### Recording signal pattern
- `page.navigation` to lead source pages.
- `ui.input` / `ui.change` for lead fields (name, email, company).
- `ui.submit` for form save.
- `tab.activated` + `ui.click` into CRM-like app.

### Generated workflow mapping
1. Parse submitted lead values from semantic/form events.
2. Find CRM tool (Composio toolkit match: `salesforce` or fallback by host/tool search).
3. Execute CRM create/update action.
4. Send Slack confirmation message with created record details.

### Variable defaults
- `source_url`: default from most recent `page.navigation.details.toUrl`.
- `submitted_at`: default from `ui.submit.timestamp`.
- `lead_name`/`lead_email`: default from latest relevant `ui.input` values if present.

---

## Use Case 2: Search Results -> Save to Google Sheets

### Recording signal pattern
- `ui.input` and `ui.keydown` (Enter) on search field.
- `page.navigation` to results pages.
- `ui.click` on target links.
- optional `tab.activated` for review tabs.

### Generated workflow mapping
1. Capture search query and visited result URLs.
2. Find Sheets toolkit (`googlesheets`) via tool search + host detection.
3. Append rows: `query`, `url`, `title`, `captured_at`.

### Variable defaults
- `query`: default from last grouped search `form_edit/search` semantic action.
- `captured_at`: default `new Date().toISOString()` at execution.
- `sheet_name`: default from config (`Leads` or `Results`) if tool schema allows optional tab name.

---

## Use Case 3: Gmail Triage -> Notion Task Creation

### Recording signal pattern
- Navigation/clicks within Gmail-like inbox pages.
- `ui.click` on message rows.
- `ui.input` or `ui.submit` indicating categorization/tagging.
- switching to Notion-like workspace tab.

### Generated workflow mapping
1. Extract triage criteria from semantic actions (labels/keywords/context URL).
2. Find Gmail + Notion tools with Composio search.
3. Fetch matching emails.
4. Create Notion tasks/pages for each matched email.

### Variable defaults
- `time_window`: default `"last_24h"` unless recording indicates another interval.
- `priority`: default `"medium"`.
- `target_database`: default from stored user config; unresolved if required and not inferable.

---

## Defaulting Strategy (Phase 3)

For each selected Composio action:

1. Inspect tool input schema.
2. Fill defaults in this order:
   - inferred from recording (`semanticActions`, event details, URL context)
   - deterministic constants (`timestamp`, source host, run id)
   - safe static defaults for optional params
3. Mark unresolved required fields as `needsUserInput: true`.
4. Persist defaults and unresolved variables on generated workflow node.

```

### package.json

```
{
  "name": "snappier",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "dev:turbo": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "vitest run",
    "test:watch": "vitest"
  },
  "dependencies": {
    "@ai-sdk/gateway": "^3.0.46",
    "@ai-sdk/react": "^3.0.88",
    "@aws-sdk/client-s3": "^3.990.0",
    "@aws-sdk/s3-request-presigner": "^3.990.0",
    "@clerk/nextjs": "^6.37.4",
    "@composio/core": "^0.6.3",
    "@composio/vercel": "^0.6.3",
    "@google/genai": "^1.41.0",
    "@google/generative-ai": "^0.24.1",
    "@xyflow/react": "^12.10.0",
    "ai": "^6.0.86",
    "dotenv": "^17.3.1",
    "framer-motion": "^12.34.0",
    "lucide-react": "^0.564.0",
    "next": "15.5.12",
    "openai": "^6.22.0",
    "react": "^19.0.4",
    "react-dom": "^19.0.4",
    "react-markdown": "^10.1.0",
    "workflow": "^4.1.0-beta.57",
    "zod": "^4.3.6"
  },
  "devDependencies": {
    "@types/node": "22.10.2",
    "@types/react": "^19.0.4",
    "@types/react-dom": "^19.0.4",
    "eslint": "8.57.1",
    "eslint-config-next": "15.5.12",
    "typescript": "5.7.2",
    "vitest": "^3.2.4"
  }
}

```

### app/page.tsx

```typescript
import { redirect } from "next/navigation";

export default function HomePage() {
  redirect("/start");
}

```

### app/layout.tsx

```typescript
import type { Metadata } from "next";
import { ClerkProvider } from "@clerk/nextjs";
import { Fraunces, Manrope } from "next/font/google";
import "./globals.css";

const fraunces = Fraunces({
  subsets: ["latin"],
  variable: "--font-fraunces",
  display: "swap",
  weight: ["400", "500", "600", "700"],
});

const manrope = Manrope({
  subsets: ["latin"],
  variable: "--font-manrope",
  display: "swap",
  weight: ["400", "500", "600", "700"],
});

export const metadata: Metadata = {
  title: "Snappier",
  description: "Record, automate, and replay browser workflows — snappier than Zapier",
};

export default function RootLayout({
  children,
}: Readonly<{ children: React.ReactNode }>) {
  return (
    <ClerkProvider>
      <html lang="en" className={`${fraunces.variable} ${manrope.variable}`}>
        <body>{children}</body>
      </html>
    </ClerkProvider>
  );
}

```

### app/runs/page.tsx

```typescript
import type { Metadata } from "next";
import { RunsPage } from "@/components/runs/RunsPage";

export const metadata: Metadata = {
  title: "Workflow History — Snappier",
};

export default function RunsPageRoute() {
  return <RunsPage />;
}

```

### app/connections/page.tsx

```typescript
import type { Metadata } from "next";
import { ConnectionGate } from "@/components/connect/ConnectionGate";

export const metadata: Metadata = {
  title: "Connections — Snappier",
};

export default function ConnectionsPageRoute() {
  return <ConnectionGate workflowId="default" globalMode />;
}

```

### app/video-understanding-demo/page.tsx

```typescript
import type { Metadata } from "next";
import { VideoUnderstandingDemo } from "@/components/demo/VideoUnderstandingDemo";

export const metadata: Metadata = {
  title: "Video Understanding Demo — Snappier",
};

export default function VideoUnderstandingDemoPage() {
  return <VideoUnderstandingDemo />;
}

```

### app/process-completed/page.tsx

```typescript
import { redirect } from "next/navigation";

type Props = {
  searchParams: Promise<{ processId?: string }>;
};

export default async function ProcessCompletedPage({ searchParams }: Props) {
  const { processId } = await searchParams;
  const target = processId
    ? `/recording-complete?processId=${encodeURIComponent(processId)}`
    : "/start";
  redirect(target);
}

```

### app/start/page.tsx

```typescript
import type { Metadata } from "next";
import { Suspense } from "react";
import { Dashboard } from "@/components/dashboard/Dashboard";

export const metadata: Metadata = {
  title: "Start — Snappier",
};

export default function DashboardPage() {
  return (
    <Suspense
      fallback={
        <main style={{ minHeight: "100dvh", display: "grid", placeItems: "center", padding: 24 }}>
          Loading...
        </main>
      }
    >
      <Dashboard />
    </Suspense>
  );
}

```

[114 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]