* docs: break SKILLPACK into 17 individual guides The 1,281-line SKILLPACK monolith is now 17 individually linkable guides in docs/guides/, organized by category: core patterns, data pipelines, operations, search, and administration. GBRAIN_SKILLPACK.md becomes a structured index with categorized tables linking to each guide. The URL stays stable for backward compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add integration guides, architecture docs, and ethos New documentation directories: - docs/integrations/ — "Getting Data In" landing page, credential gateway, meeting webhooks. Includes recipe format documentation. - docs/architecture/ — Infrastructure layer doc (import, chunk, embed, search) - docs/ethos/ — "Thin Harness, Fat Skills" essay with agent decision guide - docs/designs/ — "Homebrew for Personal AI" 10-star vision document Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add gbrain integrations command + voice-to-brain recipe New CLI command: gbrain integrations (list/show/status/doctor/stats/test) - Standalone command, no database connection needed - Uses gray-matter directly for recipe parsing (not parseMarkdown) - --json flag on every subcommand for agent-parseable output - Bare command shows senses/reflexes dashboard - Health heartbeat via ~/.gbrain/integrations/<id>/heartbeat.jsonl First recipe: recipes/twilio-voice-brain.md - Phone calls create brain pages via Twilio + OpenAI Realtime - Opinionated defaults: caller screening, brain-first lookup, quiet hours - Outbound call smoke test (GBrain calls the user to prove it works) - Validate-as-you-go credential testing - Twilio signature validation for webhook security Migration file for v0.7.0 with agent-readable changelog. 13 unit tests covering parseRecipe, CLI routing, and recipe validation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add Getting Data In to README, update CLAUDE.md and manifest README: voice calls in intro bullet list, new "Getting Data In" section with integration table (voice, email, X, calendar) and recipe philosophy. CLAUDE.md: reference new files (integrations.ts, recipes/, docs/guides/, docs/integrations/, docs/architecture/, docs/ethos/). manifest.json: bump to v0.7.0, add recipes_dir field. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: v0.7.0 CHANGELOG, TODOS, VERSION bump CHANGELOG: v0.7.0 entry covering integration recipes, voice-to-brain, gbrain integrations command, SKILLPACK breakout, and new documentation. TODOS: 3 new items from CEO/DX reviews (constrained health_check DSL, community recipe submission, always-on deployment recipes). VERSION + package.json: bump to 0.7.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: rewrite voice recipe with agent instructions and verified links Major improvements to recipes/twilio-voice-brain.md: - Agent preamble: explains WHY sequential execution matters (each step depends on the previous), defines 4 stop points where the agent MUST pause and verify, tells agent to never say "something went wrong" but instead explain the exact error and fix - User actions are now specific: exact URLs for every credential (Twilio console, OpenAI API keys page, ngrok dashboard), what buttons to click, what fields to copy, common failure modes - All URLs verified via web search against current 2026 documentation: Twilio SID/token at twilio.com/console, OpenAI keys at platform.openai.com/api-keys, ngrok token at dashboard.ngrok.com/get-started/your-authtoken - Cost estimate corrected: OpenAI Realtime is $0.06/min input + $0.24/min output (was understated), total ~$20-22/mo for 100 min - Validate-as-you-go: each credential tested immediately with exact curl commands, failure messages explain what went wrong and how to fix - Smoke test flow: tells user exactly what to say, verifies ALL three outputs (messaging notification + brain page + search result) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add "Homebrew for Personal AI" essay (markdown is code) New essay at docs/ethos/MARKDOWN_SKILLS_AS_RECIPES.md — the distribution corollary to "Thin Harness, Fat Skills." Argues that markdown skill files are simultaneously documentation, specification, package, and source code. The agent is the package manager. The git repo is the app store. Referenced from SKILLPACK index and CLAUDE.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: rewrite agent instructions as command language, promote skills The OpenClaw/Hermes install block is now a drill sergeant, not a tour guide. Every step is an imperative command with exact verification criteria and explicit stop-on-failure behavior. No FYI, no suggestions, just rails. Key changes: - 11-step setup with STOP points after each step - Exact user instructions for Supabase connection string (what to click, what NOT to give the agent, what the string looks like) - "Verify: run X. You must see Y. If not: Z" after every step - Skills table now links to both skill files AND guide docs - Integration recipes table simplified (no "coming soon" placeholders) - Docs section reorganized: for agents / for humans / reference Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: 4 codex findings + add email-to-brain recipe Codex review found 4 issues, all fixed: 1. getStatus() returned "configured" if ANY secret was set (e.g. just OPENAI_API_KEY). Now requires ALL required secrets before marking configured. Prevents false "configured" status and spurious doctor runs. 2. Twilio health check hit unauthenticated endpoint (always 401). Now uses authenticated curl with SID:token, matching the setup validation. 3. README anchor docs/GBRAIN_SKILLPACK.md#the-dream-cycle broken after SKILLPACK rewrite. Updated to point to docs/guides/cron-schedule.md. 4. Compiled binary can't find recipes/ via import.meta.dir. Added GBRAIN_RECIPES_DIR env var override + global bun install path fallback. Also adds recipes/email-to-brain.md: Gmail deterministic collector pattern with ClawVisor credential gateway, validate-as-you-go, agent instructions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add email, X, calendar, and meeting sync recipes Four new integration recipes extracted from production wintermute patterns: - recipes/email-to-brain.md: Gmail via ClawVisor, deterministic collector pattern (code pulls emails with baked-in links, agent does judgment), noise filtering, signature detection, digest generation - recipes/x-to-brain.md: X API v2, timeline + mentions + keyword search, deletion detection (diffs previous run, verifies 404), engagement velocity tracking, rate limit awareness - recipes/calendar-to-brain.md: Google Calendar via ClawVisor, historical backfill (years of data), daily markdown files with attendees + locations, attendee enrichment for brain pages - recipes/meeting-sync.md: Circleback API, transcript import with speaker labels, attendee detection + filtering, entity propagation to people/ company pages, action item extraction, idempotent by source_id All recipes follow the same format: agent preamble with sequential execution rules, validate-as-you-go credentials, exact URLs for API key setup, stop-on-failure verification, and heartbeat logging. Updated README, SKILLPACK index, and integrations landing page with all 5 recipes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add Google OAuth as alternative to ClawVisor in email + calendar recipes Both recipes now offer two auth options: - Option A: ClawVisor (recommended, handles OAuth + token refresh) - Option B: Google OAuth2 directly (no extra service, you manage tokens) Option B includes step-by-step instructions for Google Cloud Console: exact URLs, which buttons to click, which scopes to add, how to enable the API, and the OAuth flow for token exchange. This removes ClawVisor as a hard dependency for getting started. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add implementation guides with pseudocode and test suggestions Every recipe now includes an "Implementation Guide" section with: - Production-tested pseudocode the agent can follow to build each collector - Edge cases and failure modes discovered in real deployment - Non-obvious implementation details (why the 48h staleness heuristic, why Gmail links need authuser, why SSE responses need double-parsing) - Test suggestions: what the agent should verify after setup email-to-brain: noise filtering algorithm, signature detection patterns, Gmail link generation (authuser is critical), sent-mail dedup x-to-brain: deletion detection with 3 heuristics (7-day, 48h staleness, API verification), engagement velocity thresholds (50 min for 2x, 100 absolute jump), atomic writes, stdout contract, rate limit handling calendar-to-brain: smart chunking (monthly for sparse years, weekly for dense), attendee filtering (rooms, groups, distros), merge-with-existing (only replace ## Calendar section), date/time parsing edge cases meeting-sync: SSE double-JSON parsing, idempotency double-check (grep + filename), auto-tagging from meeting names, git commit after sync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: 6 new guides from production patterns (wintermute extraction) New guides extracted and generalized from production deployment: - repo-architecture.md: Two-repo pattern (agent behavior vs world knowledge). Strict boundary rules, decision tree, hard rule: never write knowledge to the agent repo. - sub-agent-routing.md: Model routing table by task type. Signal detector pattern (spawn Sonnet on every message). Research pipeline pattern (Opus plans, DeepSeek executes, Opus synthesizes). Cost optimization. - skill-development.md: 5-step cycle (concept, prototype, evaluate, codify, cron). MECE discipline (no overlapping skills). Quality bar checklist. "If you ask twice, it should already be a skill." - idea-capture.md: Originality distribution rating (0-100 across 4 populations). Depth test ("could someone unfamiliar understand WHY?"). Deep cross-linking mandate. Notability filtering. - quiet-hours.md: Hold notifications 11pm-8am local time. Held messages directory pattern. Timezone-aware delivery. Morning briefing pickup. - diligence-ingestion.md: 9-step pipeline for data room materials. Detection patterns (PDF filenames, spreadsheet tabs, user language). Index.md template with bull/bear case. Company page enrichment. All PII scrubbed. Patterns generalized for any user. SKILLPACK index updated with 6 new entries. CLAUDE.md references added. All 37 SKILLPACK links verified. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: upgrade all guides to operational playbooks with pseudocode Every guide now follows the playbook structure: - Goal: one sentence, what this achieves - What the User Gets: without this / with this - Implementation: pseudocode with actual gbrain commands - Tricky Spots: production-tested gotchas - How to Verify: test steps the agent runs after setup Guides upgraded (15 files): - brain-agent-loop: on_message() loop with read/write/sync pseudocode - brain-first-lookup: 4-step lookup cascade with exact commands - brain-vs-memory: routing algorithm for 3 knowledge layers - compiled-truth: page structure + rewrite vs append rules - content-media: 3 ingest patterns (YouTube, social, PDFs) - cron-schedule: full schedule table + dream cycle pseudocode - enrichment-pipeline: 7-step protocol with tier classification - entity-detection: spawn pattern + detection prompt + notability filter - executive-assistant: 3 workflow algorithms (triage, prep, post-inbox) - meeting-ingestion: 6-step transcript-to-brain flow - operational-disciplines: 5 executable discipline blocks - originals-folder: detection + exact-phrasing capture + cross-linking - search-modes: decision tree for keyword vs hybrid vs direct - source-attribution: citation format + hierarchy + conflict resolution - Plus Goal/What User Gets headers on 6 newer guides Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add WebRTC to voice recipe + ngrok Hobby setup guide Voice recipe updates: - Added WebRTC endpoint (POST /session, GET /call, POST /tool) for browser-based calling with RNNoise noise suppression - WebRTC pseudocode with the 4 non-obvious gotchas from production (voice under audio.output.voice, no turn_detection, no session.update on connect, trigger greeting via data channel) - Recommend ngrok Hobby ($8/mo) for fixed domain instead of free tier - Fixed domain means URLs never change, Twilio never breaks New guide: docs/mcp/NGROK_SETUP.md - How to set up ngrok Hobby for both MCP and voice agent - Fixed domain setup, watchdog pattern, AI client configuration - Claude Desktop requires Settings > Integrations (not JSON config) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add dependency graph + ngrok-tunnel + credential-gateway recipes Recipes now have real dependencies via the `requires` field: - voice-to-brain requires ngrok-tunnel (needs public URL for Twilio) - email-to-brain requires credential-gateway (needs Gmail access) - calendar-to-brain requires credential-gateway (needs Calendar access) - x-to-brain and meeting-sync are standalone (direct API keys) Two new infrastructure recipes: - ngrok-tunnel: fixed public URL for MCP + voice. Recommends Hobby ($8/mo) for a domain that never changes. Includes watchdog pattern. - credential-gateway: secure Google service access via ClawVisor (recommended) or direct OAuth2. One setup, all Google recipes use it. Moved ngrok from docs/mcp/ to recipes/ — it's shared infrastructure, not MCP-specific. README and integrations landing page show dependency chains. When agent installs voice-to-brain, it sets up ngrok-tunnel first. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add infra category, fix dashboard alignment, show dependencies DX audit found two bugs in gbrain integrations dashboard: 1. Column alignment broken — IDs > 18 chars ran into descriptions with no space. Fixed: pad to 22 chars. 2. ngrok-tunnel and credential-gateway showed as SENSES but they're infrastructure. Added 'infra' category. Dashboard now shows three sections: INFRASTRUCTURE (set up first), SENSES, REFLEXES. 3. Dependencies now shown inline: "AVAILABLE (needs credential-gateway)" Also added 'requires' field to JSON output for agent consumption. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add frontier model requirement disclaimer to README GBrain's markdown-is-code approach requires models capable of interpreting intent and implementing from architecture descriptions. Tested with Claude Opus 4.6 and GPT-5.4 Thinking. Smaller models will struggle with the recipe format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add PGLite → Supabase upgrade path to README Clarify the database progression: start with PGLite (Postgres as WASM, zero infrastructure, pgvector built in, nothing to install). Graduate to Supabase or self-hosted Postgres when you need connection pooling, concurrency, and remote MCP access from Claude Desktop, Cowork, ChatGPT, Perplexity Computer, or any MCP-compatible agent. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: revert PGLite mention (coming in next branch) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: make all 23 guides consistent (Goal/Impl/Tricky/Verify) Every guide now has exactly these sections in this order: - ## Goal (one sentence) - ## What the User Gets (without this / with this) - ## Implementation (pseudocode with gbrain commands) - ## Tricky Spots (3-5 numbered gotchas) - ## How to Verify (3-5 numbered test steps) 11 guides restructured from non-standard headings: - deterministic-collectors, live-sync, upgrades-auto-update (full rewrites) - entity-detection, diligence-ingestion, idea-capture, quiet-hours, repo-architecture, skill-development, sub-agent-routing (restructured) 23/23 guides now pass consistency audit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: restructure README around the #1 blocker (getting data in) The README was leading with Postgres and database architecture. Most users are stuck at step zero: "I have an agent but it doesn't know anything about my life." New structure: 1. The Problem — your agent doesn't know your life 2. Getting Data In — integration recipes, front and center 3. The Compounding Thesis — why this matters 4. How this happened — credibility, origin story 5. When you need Postgres — scale, not starting point Postgres is de-emphasized from a full section to two paragraphs: "You don't need Postgres to start" and "When you need Postgres" (1,000+ files, remote MCP access, multiple AI clients). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: move Install to top of README, remove duplicate section Install now appears right after Getting Data In (line 38), not buried at line 295. The user sees: Problem → Getting Data In → Install. Removed the duplicate Install section (262 lines) that was lower in the README. The agent instructions block, CLI quickstart, and all content is now in the single Install section near the top. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: move agent install block to first thing in README "Start here: paste this into your agent" is now the first section, right after the one-line pitch. No scrolling, no context, no preamble. User opens the README, sees the paste block, copies it into OpenClaw or Hermes, and the agent takes over. Flow: pitch → paste block → Getting Data In → Compounding Thesis → origin story Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: compress install block from 11 steps to 5 The agent install block was 102 lines and 11 steps. Now it's 40 lines and 5 steps. Same coverage, half the text. Changes: - Merged "prove keyword search" + "embed" + "prove hybrid search" into one SEARCH step (the user doesn't care about the intermediate) - Merged skillpack, sync, auto-update, integrations, verification into one GO LIVE step with sub-items (post-install polish, not install) - Shortened database instructions (one line instead of 5 sub-steps) - Removed redundant preamble ("YOU MUST COMPLETE EVERY STEP" is now just "Do not skip steps. Verify each step.") The 5 steps: INSTALL → DATABASE → IMPORT → SEARCH → GO LIVE Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: gitignore all .env files, not just specific ones CSO audit found .gitignore covered .env.testing and .env.production but not bare .env. A user creating .env with database credentials could accidentally commit it. Fix: .env and .env.* are now gitignored. .env.*.example files are explicitly un-ignored so templates remain tracked. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: scrub PII from essay and recipe examples - 510-MY-GARRY phone mnemonic → "Your Phone Number" - "Garry → Authenticated Mode" → "Owner → Authenticated Mode" - "Telegram" → "secure channel" in auth example - @garrytan → @yourhandle in X recipe example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
381 lines
12 KiB
Markdown
381 lines
12 KiB
Markdown
---
|
|
id: meeting-sync
|
|
name: Meeting Sync
|
|
version: 0.7.0
|
|
description: Meeting transcripts from Circleback auto-import into brain pages with attendee detection and entity propagation.
|
|
category: sense
|
|
requires: []
|
|
secrets:
|
|
- name: CIRCLEBACK_TOKEN
|
|
description: Circleback API token for meeting data access
|
|
where: https://app.circleback.ai — Settings > API > generate token
|
|
health_checks:
|
|
- "curl -sf -H \"Authorization: Bearer $CIRCLEBACK_TOKEN\" \"https://app.circleback.ai/api/mcp\" -X POST -H \"Content-Type: application/json\" -d '{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"id\":1}' > /dev/null && echo 'Circleback: OK' || echo 'Circleback: FAIL'"
|
|
setup_time: 15 min
|
|
cost_estimate: "$0-17/mo (Circleback free for 10 meetings/mo, Pro $17/mo unlimited)"
|
|
---
|
|
|
|
# Meeting Sync: Transcripts That Become Brain Pages
|
|
|
|
Every meeting is automatically recorded, transcribed, and imported into your brain
|
|
with attendee detection, entity propagation, and action item extraction. You never
|
|
take notes again. The brain remembers what was said, who said it, and what needs
|
|
to happen next.
|
|
|
|
## IMPORTANT: Instructions for the Agent
|
|
|
|
**You are the installer.** Follow these steps precisely.
|
|
|
|
**Why this is high-value:** Meeting transcripts are the richest signal source.
|
|
A 30-minute meeting mentions 5-10 people, 3-5 companies, and generates 2-3 action
|
|
items. Each one should propagate to the relevant brain pages. Without this recipe,
|
|
meetings are black holes. With it, every meeting compounds the brain.
|
|
|
|
**The flow:**
|
|
1. Circleback records and transcribes the meeting (automatic, no user action)
|
|
2. The sync script pulls completed meetings from Circleback API
|
|
3. Each meeting becomes a brain page at `brain/meetings/{YYYY-MM-DD}-{slug}.md`
|
|
4. YOU (the agent) propagate entities to people/company pages
|
|
|
|
**Do not skip steps. Verify after each step.**
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Video Call (Zoom, Google Meet, Teams)
|
|
↓ Circleback bot joins automatically
|
|
Circleback (recording + transcription + AI summary)
|
|
↓ API (JSONRPC 2.0 over HTTP, SSE responses)
|
|
Meeting Sync Script (deterministic Node.js)
|
|
↓ Outputs:
|
|
└── brain/meetings/{YYYY-MM-DD}-{slug}.md
|
|
- Frontmatter: source_id, date, duration, attendees, location
|
|
- Transcript with speaker labels and timestamps
|
|
- Tags inferred from title
|
|
↓
|
|
Agent reads meeting page
|
|
↓ Judgment calls:
|
|
├── Entity detection (people, companies, topics)
|
|
├── Propagate to attendee brain pages (timeline entries)
|
|
├── Action item extraction
|
|
└── Cross-reference with calendar data
|
|
```
|
|
|
|
## Opinionated Defaults
|
|
|
|
**Meeting page format:**
|
|
```markdown
|
|
---
|
|
type: meeting
|
|
source_id: cb_abc123
|
|
source_type: circleback
|
|
title: Weekly Team Sync
|
|
date: 2026-04-10
|
|
duration: 32 min
|
|
attendees: [Alice Chen, Bob Park, Carol Wu]
|
|
location: Google Meet
|
|
tags: [team, weekly, sync]
|
|
---
|
|
|
|
## Key Points
|
|
- Discussed Q2 roadmap priorities
|
|
- Alice is blocked on the API migration
|
|
- Bob's prototype is ready for review
|
|
|
|
## Action Items
|
|
- [ ] Alice: unblock API migration by Friday
|
|
- [ ] Bob: share prototype link in Slack
|
|
- [ ] Carol: schedule design review for next week
|
|
|
|
---
|
|
|
|
## Transcript
|
|
|
|
**Alice Chen** (00:00): Let's start with the roadmap update...
|
|
**Bob Park** (02:15): The prototype is basically done...
|
|
**Carol Wu** (05:30): I have some design feedback on the new flow...
|
|
```
|
|
|
|
**Attendee filtering:**
|
|
- Skip calendar resources (e.g., "YC-SF Conference Room")
|
|
- Skip group addresses (e.g., "team@company.com")
|
|
- Extract display names, not email addresses
|
|
|
|
**Idempotent by source_id:** If a meeting with the same `source_id` already exists
|
|
in the brain, skip it. No duplicates.
|
|
|
|
## Prerequisites
|
|
|
|
1. **GBrain installed and configured** (`gbrain doctor` passes)
|
|
2. **Node.js 18+** (for the sync script)
|
|
3. **Circleback account** (https://circleback.ai) with meetings recorded
|
|
|
|
## Setup Flow
|
|
|
|
### Step 1: Get Circleback API Token
|
|
|
|
Tell the user:
|
|
"I need your Circleback API token. Here's where to find it:
|
|
|
|
1. Go to https://app.circleback.ai
|
|
2. Click your profile icon (top right) > Settings
|
|
3. Go to the API section
|
|
4. Generate a new API token (or copy existing)
|
|
5. Paste it to me
|
|
|
|
Note: Circleback's free tier records up to 10 meetings/month. Pro ($17/mo)
|
|
is unlimited. You need at least one recorded meeting for the sync to work."
|
|
|
|
Validate immediately:
|
|
```bash
|
|
curl -sf -H "Authorization: Bearer $CIRCLEBACK_TOKEN" \
|
|
"https://app.circleback.ai/api/mcp" \
|
|
-X POST -H "Content-Type: application/json" \
|
|
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}' \
|
|
| grep -q '"result"' \
|
|
&& echo "PASS: Circleback API connected" \
|
|
|| echo "FAIL: Circleback token invalid"
|
|
```
|
|
|
|
**If validation fails:** "That didn't work. Common issues: (1) make sure you copied
|
|
the full token, (2) tokens are long hex strings, (3) check that your Circleback
|
|
account is active."
|
|
|
|
**STOP until Circleback validates.**
|
|
|
|
### Step 2: Set Up the Meeting Sync Script
|
|
|
|
```bash
|
|
mkdir -p meeting-sync
|
|
cd meeting-sync
|
|
npm init -y
|
|
```
|
|
|
|
The sync script needs these capabilities:
|
|
|
|
1. **List meetings** — call Circleback API `list_meetings` with date range
|
|
(SSE response format, parse streaming events)
|
|
2. **Extract meeting data** — title, attendees, transcript, duration, date
|
|
3. **Slugify title** — "Weekly Team Sync" → `weekly-team-sync`
|
|
4. **Check for existing** — skip if `brain/meetings/{date}-{slug}.md` exists
|
|
5. **Format as markdown** — frontmatter + key points + action items + transcript
|
|
6. **Filter attendees** — remove calendar resources, groups, extract display names
|
|
7. **Infer tags** — from title keywords (e.g., "board" → board, "1:1" → 1-on-1)
|
|
|
|
### Step 3: Run First Sync
|
|
|
|
```bash
|
|
node meeting-sync.mjs --days 7
|
|
```
|
|
|
|
This syncs the last 7 days of meetings. For a full backfill:
|
|
```bash
|
|
node meeting-sync.mjs --start 2026-01-01 --end $(date +%Y-%m-%d)
|
|
```
|
|
|
|
Verify:
|
|
```bash
|
|
ls brain/meetings/ | head -10
|
|
```
|
|
|
|
Should show files like `2026-04-10-weekly-team-sync.md`.
|
|
|
|
Tell the user: "Found and synced N meetings. Here are the most recent: [list 3]."
|
|
|
|
### Step 4: Import to GBrain
|
|
|
|
```bash
|
|
gbrain import brain/meetings/ --no-embed
|
|
gbrain embed --stale
|
|
```
|
|
|
|
Verify:
|
|
```bash
|
|
gbrain search "meeting" --limit 3
|
|
```
|
|
|
|
### Step 5: Propagate to Entity Pages
|
|
|
|
This is YOUR job (the agent). For each meeting:
|
|
|
|
1. **Read the meeting page** — understand who attended and what was discussed
|
|
2. **For each attendee**, check brain: `gbrain search "attendee name"`
|
|
- If page exists: append timeline entry:
|
|
`- YYYY-MM-DD | Meeting: {title}. Discussed: {key points relevant to this person} [Source: Circleback]`
|
|
- If no page and person is notable: create a brain page
|
|
3. **For each company mentioned**: update company page timeline
|
|
4. **Action items**: if the meeting has action items, ensure they're tracked
|
|
5. **Cross-reference with calendar**: link meeting page to the calendar event
|
|
6. **Sync**: `gbrain sync --no-pull --no-embed`
|
|
|
|
### Step 6: Set Up Cron
|
|
|
|
Sync 3x daily on weekdays:
|
|
```bash
|
|
# 10 AM, 4 PM, 9 PM PT on weekdays
|
|
0 10,16,21 * * 1-5 cd /path/to/meeting-sync && node meeting-sync.mjs >> /tmp/meeting-sync.log 2>&1
|
|
```
|
|
|
|
Default (no flags): syncs yesterday and today.
|
|
|
|
### Step 7: Log Setup Completion
|
|
|
|
```bash
|
|
mkdir -p ~/.gbrain/integrations/meeting-sync
|
|
echo '{"ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","event":"setup_complete","source_version":"0.7.0","status":"ok"}' >> ~/.gbrain/integrations/meeting-sync/heartbeat.jsonl
|
|
```
|
|
|
|
Tell the user: "Meeting sync is set up. Every meeting recorded by Circleback
|
|
automatically becomes a searchable brain page. Attendee pages get updated with
|
|
meeting history. Action items are extracted. Sync runs 3x daily on weekdays."
|
|
|
|
## Implementation Guide
|
|
|
|
These are production-tested patterns from syncing 280+ meeting transcripts.
|
|
|
|
### SSE Response Parsing
|
|
|
|
Circleback returns JSONRPC 2.0 over SSE (Server-Sent Events):
|
|
```
|
|
call_circleback(tool_name, args):
|
|
body = {jsonrpc: '2.0', id: next_id(), method: 'tools/call',
|
|
params: {name: tool_name, arguments: args}}
|
|
|
|
res = POST CIRCLEBACK_ENDPOINT, body,
|
|
headers: {Authorization: Bearer TOKEN, Accept: 'application/json, text/event-stream'}
|
|
|
|
text = res.text()
|
|
for line in text.split('\n'):
|
|
if line.startsWith('data: '):
|
|
json = JSON.parse(line[6:]) // strip "data: "
|
|
if json.result?.content?.[0]?.text:
|
|
return JSON.parse(json.result.content[0].text) // double-parse
|
|
if json.error:
|
|
throw json.error
|
|
```
|
|
|
|
**Non-obvious:** The response is JSON inside SSE inside JSONRPC. You have to:
|
|
1. Strip `data: ` prefix
|
|
2. Parse the SSE line as JSON
|
|
3. Drill into `result.content[0].text`
|
|
4. Parse THAT as JSON again (it's a string containing JSON)
|
|
|
|
### Idempotency (Double-Check)
|
|
|
|
```
|
|
meeting_exists(source_id):
|
|
// Method 1: grep all meeting files for source_id
|
|
result = shell(f'grep -rl "source_id: {source_id}" {MEETINGS_DIR}/')
|
|
if result: return true
|
|
|
|
// Method 2: check filename (backup)
|
|
slug = slugify(meeting.name)
|
|
if file_exists(f'{MEETINGS_DIR}/{date}-{slug}.md'): return true
|
|
|
|
return false
|
|
```
|
|
|
|
**Why double-check:** grep catches source_id matches even if the filename changed.
|
|
File existence catches cases where grep fails (e.g., permission issues).
|
|
|
|
### Auto-Tagging from Meeting Name
|
|
|
|
```
|
|
auto_tag(meeting_name):
|
|
name = meeting_name.toLowerCase()
|
|
tags = []
|
|
if 'office hours' in name or ' oh ' in name: tags.push('oh')
|
|
if 'standup' in name or 'sync' in name: tags.push('sync')
|
|
if '1:1' in name or '1on1' in name: tags.push('1on1')
|
|
if 'board' in name: tags.push('board')
|
|
if 'policy' in name or 'civic' in name: tags.push('civic')
|
|
if not tags: tags.push('meeting')
|
|
return tags
|
|
```
|
|
|
|
### Meeting Page Structure
|
|
|
|
```
|
|
---
|
|
title: "Weekly Team Sync"
|
|
type: meeting
|
|
date: 2026-04-10
|
|
duration: 32 min
|
|
source: circleback
|
|
source_id: cb_abc123
|
|
attendees:
|
|
- {name: Alice Chen, email: alice@company.com}
|
|
- {name: Bob Park, email: bob@company.com}
|
|
tags: [sync]
|
|
---
|
|
|
|
# Weekly Team Sync
|
|
|
|
## Summary
|
|
[Circleback AI summary]
|
|
|
|
## Attendees
|
|
- Alice Chen
|
|
- Bob Park
|
|
|
|
## Action Items
|
|
- [ ] Alice: unblock API migration by Friday
|
|
|
|
---
|
|
|
|
## Transcript
|
|
|
|
**Alice Chen** (00:00): Let's start with the roadmap...
|
|
**Bob Park** (02:15): The prototype is basically done...
|
|
```
|
|
|
|
### Git Commit After Sync
|
|
|
|
```
|
|
if new_meetings_created > 0:
|
|
shell('git add -A', cwd=BRAIN_DIR)
|
|
msg = f'sync: {count} meeting(s) from Circleback ({start} to {end})'
|
|
shell(f'git commit -m "{msg}"', cwd=BRAIN_DIR)
|
|
shell('git push', cwd=BRAIN_DIR)
|
|
```
|
|
|
|
The sync script commits and pushes automatically. This triggers GBrain's
|
|
live sync to index the new pages.
|
|
|
|
### What the Agent Should Test After Setup
|
|
|
|
1. **SSE parsing:** Verify `SearchMeetings` returns parseable data (the double-JSON
|
|
parsing is the most common failure point).
|
|
2. **Idempotency:** Sync a meeting, add a note to the file manually, sync again.
|
|
Verify the meeting is skipped (not re-created or overwritten).
|
|
3. **Attendee filtering:** Sync a meeting that includes a conference room in attendees.
|
|
Verify the room doesn't appear in the attendee list.
|
|
4. **Auto-tagging:** Sync a meeting named "1:1 with Sarah". Verify tag is `1on1`.
|
|
5. **Transcript formatting:** Verify speaker names and timestamps are formatted
|
|
correctly (speaker bold, timestamp in parentheses).
|
|
6. **Git commit:** Sync 2+ meetings. Verify the git commit message includes the count.
|
|
|
|
## Cost Estimate
|
|
|
|
| Component | Monthly Cost |
|
|
|-----------|-------------|
|
|
| Circleback Free tier | $0 (10 meetings/mo) |
|
|
| Circleback Pro | $17/mo (unlimited) |
|
|
| **Recommended** | **$17/mo (Pro)** |
|
|
|
|
## Troubleshooting
|
|
|
|
**No meetings found:**
|
|
- Check that Circleback has recorded meetings (open the Circleback dashboard)
|
|
- The Circleback bot must join the meeting for recording to work
|
|
- Check the date range: `--days 30` to widen the search
|
|
|
|
**Transcript is empty:**
|
|
- Some meetings may not have transcripts (e.g., no audio, bot was removed)
|
|
- Check the Circleback dashboard for the specific meeting's status
|
|
|
|
**Duplicate meetings:**
|
|
- The sync script checks for existing files by source_id
|
|
- If duplicates appear, the idempotency check may be failing
|
|
- Delete duplicates manually and re-run sync
|