Skip to content

feat: Linear and Notion live-sync recipes + fix embedding config key lookup#192

Open
mishanefedov wants to merge 1 commit intogarrytan:masterfrom
mishanefedov:feat/linear-notion-recipes
Open

feat: Linear and Notion live-sync recipes + fix embedding config key lookup#192
mishanefedov wants to merge 1 commit intogarrytan:masterfrom
mishanefedov:feat/linear-notion-recipes

Conversation

@mishanefedov
Copy link
Copy Markdown

What this adds

Two new integration recipes following the existing deterministic-collector pattern (code for data, LLMs for judgment), plus a bug fix.

recipes/linear-to-brain.md

Live sync of Linear issues, projects, and cycles into brain pages for offline semantic search. Complements MCP real-time access — gbrain query works without an active session or network connection.

  • GraphQL-based collector with full pagination (pageInfo.hasNextPage + endCursor)
  • Incremental sync via updatedAt filter (only changed issues re-fetched)
  • Priority mapping (0–4 → human labels) for searchable frontmatter
  • Month-partitioned output: brain/linear/issues/{YYYY-MM}/{id}.md
  • Single credential: LINEAR_API_KEY (read-only, no OAuth)
  • Daily launchd/cron sync recipe included

recipes/notion-to-brain.md

Live Notion API sync as a complement to the existing one-shot migrate skill. Handles the ongoing case: new pages appear in the brain automatically on a schedule.

  • Search-based discovery (POST /v1/search) — no hardcoded page IDs
  • Full block-to-markdown renderer (paragraph, headings, lists, to_do, code, divider, child_page)
  • Database row support: properties rendered as typed frontmatter
  • Incremental sync via last_edited_time
  • 350ms request throttle to respect Notion's 3 req/s limit
  • Documents the sharing-required constraint (Notion API security model)

skills/RESOLVER.md

Added routing entries for both recipes, disambiguating the new live-sync paths from the existing one-shot Notion migration skill.

src/core/embedding.ts (bug fix)

new OpenAI() reads only from OPENAI_API_KEY env var. If the key is stored in ~/.gbrain/config.json (the openai_api_key field that loadConfig() already defines), the embedding step silently fails. Fix: fall back to loadConfig()?.openai_api_key when the env var is absent. Env var still takes precedence.

Tests

bun test → 1191 pass, 0 fail (including test/integrations.test.ts which validates recipe frontmatter schema)

E2E tests skipped (no DATABASE_URL) — new recipes don't touch the engine layer, covered by the integration frontmatter tests.

Fits the welcome PRs list

PRs welcome for: new enrichment API integrations

Both recipes fall squarely in this category.

Two new integration recipes following the existing deterministic-collector
pattern (code for data, LLMs for judgment):

- recipes/linear-to-brain.md — GraphQL-based Linear sync (issues, projects,
  cycles) with incremental updates, priority mapping, and assignee enrichment.
  Single API key credential, no OAuth dance.

- recipes/notion-to-brain.md — Notion API live sync (pages + database rows)
  as a complement to the existing one-shot migrate skill. Handles block
  rendering, incremental sync via last_edited_time, and the sharing-required
  constraint.

- skills/RESOLVER.md — add routing entries for both recipes, disambiguating
  the new live-sync paths from the existing one-shot Notion migration skill.

- src/core/embedding.ts — fix: read OPENAI_API_KEY from config.json when
  env var is not set. Prevents embed failures when the key is stored in
  ~/.gbrain/config.json (the recommended local install path) but not exported
  as an environment variable.

All 1191 unit tests pass. 0 failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant