[integrations] Limitless wearable capture - #50
Conversation
Poll-based adapter on wearable-capture-core for the Limitless Pendant. Pages the Limitless Developer API (X-API-Key) by cursor for lifelogs since a rolling window, and maps each to a `meeting` thought from Limitless's own title + section headings (source_type='limitless_lifelog') — no per-item LLM cost. The core handles dedup (on the lifelog id), embedding, and inserts. Includes README (setup + deploy + 5-min pg_cron schedule), metadata.json, deno.json. Requires the wearable-capture-core integration. Secrets via Deno.env.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c518321b41
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| url := 'https://YOUR_PROJECT_REF.supabase.co/functions/v1/wearable-limitless-capture', | ||
| headers := jsonb_build_object( | ||
| 'Content-Type', 'application/json', | ||
| 'Authorization', 'Bearer ' || current_setting('app.settings.service_role_key', true) |
There was a problem hiding this comment.
Use a stored token for scheduled Edge calls
When users follow the documented default supabase functions deploy and then install this cron job, the database session cannot read the Edge Function's auto-injected SUPABASE_SERVICE_ROLE_KEY; current_setting('app.settings.service_role_key', true) returns NULL unless they separately create that setting, so the Authorization header is NULL and Supabase's default JWT verification rejects the scheduled request before the function runs. Supabase documents JWT verification as the default and recommends Vault for scheduled function tokens (https://supabase.com/docs/guides/functions/function-configuration, https://supabase.com/docs/guides/functions/schedule-functions), so this step should either use Vault / a documented DB setting or explicitly deploy with JWT verification disabled.
Useful? React with 👍 / 👎.
| const params = new URLSearchParams({ | ||
| start: sinceISO, | ||
| timezone: "UTC", | ||
| limit: "50", |
There was a problem hiding this comment.
Keep the Limitless page size within the API cap
For live Limitless polling, this sends limit=50 on every /v1/lifelogs request, but the current Limitless developer docs cap the lifelog list limit at 10 and instruct callers to use cursor pagination for more results (https://www.limitless.ai/developers). If the API enforces that documented max, every scheduled run takes the !r.ok path and imports nothing; use a page size of 10 and continue following nextCursor.
Useful? React with 👍 / 👎.
A summary-per-lifelog capture collapsed a whole recording into one row, losing the per-topic detail. Atomize each lifelog with Limitless's own Markdown structure (no LLM): a title atom plus one section atom per `##` heading — the label with its rolled-up utterances — attributed to the section's speakers (self/other/mixed/unknown via a configurable, non-hardcoded self-label set). No cap on sections; they are the device's native unit. Drive it through the shared core's per-atom salted-fingerprint dedup + provenance, and route the lifelog list through the core's 429-aware fetch. Vendor the core engine in _shared/ so the function typechecks and deploys standalone (deno.json import map points the deploy path at it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The lint CI flagged a blank line between the two callout blockquotes (IMPORTANT then NOTE) as a blank line inside a blockquote. Separate them with an empty HTML comment so they render as two distinct callouts and the markdownlint check passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
A poll-based Limitless Pendant capture adapter built on [
wearable-capture-core]. Limitless lifelogs land in your brain automatically as searchable thoughts (source_type='limitless_lifelog').How
Implements the
WearableAdapterinterface:GET /v1/lifelogs?start=<ISO>&includeMarkdown=true,X-API-Key) by followingmeta.lifelogs.nextCursor.meetingthought from the lifelog title + Limitless's own##section headings (transcript-snippet fallback). No per-item LLM cost.The core handles dedup, OpenRouter embedding, and the
thoughtsinsert. An edge function (Deno.serve) runs one pass; the README shows a 5-minutepg_cron+net.http_postschedule.Prereq & guardrails
[integrations] Wearable capture corePR (deploy it first).thoughtsschema changes; secrets viaDeno.env;deno check/lintclean; no keys in the diff.🤖 Generated with Claude Code