Transform your work activity into short-form video scripts. Reads Claude Code sessions, Slack messages, and Granola meeting notes to create a weekly brief, then powers a chat interface to generate video content.
- Node.js 18+
- Python 3.8+
- xAI API key (for Grok summarization and video script generation)
Copy .env.example to .env.local and fill in your API keys:
cp .env.example .env.localRequired:
XAI_API_KEY— for Grok summarization and video script generationCLAUDE_PROJECTS_DIR— path to your Claude Code projects (usually~/.claude/projects)CONTEXT_DIR— where to store aggregated data (default:./context)
Optional:
XAI_MODEL— defaults togrok-4-fast-non-reasoningNEXT_PUBLIC_SUPABASE_URL,SUPABASE_SECRET_KEY— enables private Supabase Storage snapshots of Grok outputsSUPABASE_LLM_OUTPUTS_BUCKET— storage bucket for LLM output JSON (defaults tollm-outputs)SLACK_BOT_TOKEN— Slack bot token (install MCP server first)SLACK_TEAM_ID— Slack workspace team ID
npm installTo enable Slack data ingestion:
npm install -g @anthropic-ai/mcp-server-slackThen set SLACK_BOT_TOKEN and SLACK_TEAM_ID in .env.local.
npm run devNavigate to http://localhost:3000/studio.
Click the Sync button to:
- Read Claude Code session logs from
~/.claude/projects/ - Fetch recent Slack messages (if configured)
- Process Granola exports (if dropped in
context/granola/) - Summarize everything with xAI Grok →
context/weekly_brief.json - If Supabase is configured, upload the raw Grok response and normalized brief to Storage
- Pick a theme from the brief
- Chat interface generates Hook / Middle / CTA sections
- Storyboard shows live word counts and estimated spoken duration
- Copy the script or edit it inline ("make the hook punchier")
EF/
├── app/
│ ├── api/
│ │ ├── sync/ → Aggregation pipeline (Claude Code + Slack + Granola)
│ │ ├── brief/ → Returns weekly_brief.json
│ │ └── generate/ → Grok SSE streaming for video scripts
│ ├── studio/ → Main UI (chat + storyboard split panel)
│ └── layout.tsx → Root layout
├── components/
│ ├── ChatPanel.tsx → Theme selection + chat interface
│ ├── StoryboardPanel.tsx → Hook/Middle/CTA card display
│ ├── ThemeChip.tsx → Clickable theme pill
│ └── CopyButton.tsx → Copy to clipboard
├── lib/
│ ├── types.ts → Shared TypeScript interfaces
│ └── utils.ts → wordCount, spokenSeconds helpers
├── backend/
│ ├── aggregator/
│ │ ├── claude_code.py → JSONL parser for Claude Code sessions
│ │ ├── slack.py → Slack MCP client
│ │ └── granola.py → Watched folder processor
│ └── summarizer.py → Grok via xAI
└── context/
├── sessions/ → Claude Code session markdown files
├── slack/ → Slack channel summaries
├── granola/ → User-dropped Granola markdown files
├── uploads/ → User-provided context files
└── weekly_brief.json → Synthesized weekly brief
~/.claude/projects/*.jsonl
↓ (claude_code.py)
context/sessions/*.md
Slack (#channels)
↓ (slack.py via MCP)
context/slack/*.md
context/granola/*.md (user drops files here)
All ↓ (summarizer.py)
context/weekly_brief.json
↓ (UI loads /api/brief)
ChatPanel shows theme chips
↓ (user selects theme)
/api/generate → Grok SSE
↓
StoryboardPanel renders Hook/Middle/CTA
↓
Supabase Storage stores the raw and parsed script generation response
- The directory name at
~/.claude/projects/encodes the absolute path (lossy encoding). We readcwdfield from records instead. - Active sessions may have partial JSON on the last line — we safely skip malformed lines.
ai-titleis often absent (~70% of sessions); we fall back to first user message.
- Summarization and script generation both use the xAI API.
- Set
XAI_API_KEYand optionallyXAI_MODELin.env.local. - The default model is
grok-4-fast-non-reasoning.
- Requires installing
@anthropic-ai/mcp-server-slackglobally - Bot must be invited to channels to read them
- Pulls messages from past 7 days
- v1 (current): Drop exported
.mdfiles intocontext/granola/ - v2 (future): Custom MCP server for direct API integration
- Test the data pipeline end-to-end
- Add Slack bot setup instructions
- Implement remaining content formats (Twitter thread, carousel, etc.)
- Add exports: PDF, Notion, scheduled posting
- Build custom Granola MCP server
npx tsc --noEmitnpm run build
npm startCONTEXT_DIR=./context python3 backend/aggregator/claude_code.py
CONTEXT_DIR=./context python3 backend/summarizer.py