[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C5M75383P9AT30MSPJYJYA":3,"skill-same:01M6C5M75383P9AT30MSPJYJYA":72},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":47,"ownerHtmlUrl":48,"ownerBlogUrl":49,"ownerDescription":50,"updatedAt":51,"install":52,"resources":65},"01M6C5M75383P9AT30MSPJYJYA","provider-rpc",null,"Talk to a caldir provider binary directly via its JSON protocol to debug sync issues. Use when investigating \"Provider error\" messages, suspected wrong\u002Fmissing event data from a provider, or when you need to see exactly what a provider returns before it goes through caldir-core. Triggers: \"what does the provider return for X\", \"why is X showing up in status\", \"is this a parsing bug or a Google\u002FiCloud\u002FOutlook bug\", investigating any provider-emitted error.","t4t5\u002Fcaldir","t4t5","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2598660?v=4","01M6C5M35YXZEN3AM6F8VSZGX4","Tristan \u002F T4T5","01M6C5M39NFCY8QC4CHF2NAQXW",87,"MIT","https:\u002F\u002Fgithub.com\u002Ft4t5\u002Fcaldir\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fprovider-rpc\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"provider rpc","rpc","data","up","use","returns","json","why","parsing","outlook","google","messages","issues","protocol","core","debug","status","sync","2026-11-10 10:12:30",false,"---\nname: provider-rpc\ndescription: >-\n  Talk to a caldir provider binary directly via its JSON protocol to debug sync issues.\n  Use when investigating \"Provider error\" messages, suspected wrong\u002Fmissing event data from a provider,\n  or when you need to see exactly what a provider returns before it goes through caldir-core.\n  Triggers: \"what does the provider return for X\", \"why is X showing up in status\",\n  \"is this a parsing bug or a Google\u002FiCloud\u002FOutlook bug\", investigating any provider-emitted error.\nuser_invocable: false\n---\n\n# Talking to providers directly\n\nProviders are standalone binaries that speak JSON over stdin\u002Fstdout. When something looks wrong in `caldir status` \u002F `caldir pull`, you can usually narrow the bug to \"wrong on the wire\" vs. \"wrong after parsing\" in one shot by invoking the provider directly.\n\nThis bypasses caldir-cli, caldir-core, the diff engine, and the renderer — you see exactly what came back from the remote.\n\n## Protocol shape\n\nOne JSON line in, one JSON line out. The protocol is defined in `caldir-core\u002Fsrc\u002Fremote\u002Fprotocol.rs` — that file is the source of truth, check it if a command argument shape isn't obvious.\n\nRequest:\n```json\n{\"command\":\"\u003Ccommand>\",\"params\":{...}}\n```\n\nResponse (success):\n```json\n{\"status\":\"success\",\"data\":\u003Ccommand-specific>}\n```\n\nResponse (error):\n```json\n{\"status\":\"error\",\"error\":\"\u003Cmessage>\"}\n```\n\n## Critical: params is FLAT\n\n`remote_config` is `#[serde(flatten)]` in protocol structs. Pass its fields at the top level of `params`, not nested under `remote_config`. If you nest, you'll get `Missing required field: \u003Cname>`.\n\n```jsonc\n\u002F\u002F CORRECT\n{\"command\":\"list_events\",\"params\":{\n  \"google_account\":\"me@gmail.com\",\n  \"google_calendar_id\":\"primary\",\n  \"from\":\"2026-01-01T00:00:00Z\",\n  \"to\":\"2026-02-01T00:00:00Z\"\n}}\n\n\u002F\u002F WRONG — provider rejects with \"Missing required field: google_account\"\n{\"command\":\"list_events\",\"params\":{\n  \"remote_config\":{\"google_account\":\"me@gmail.com\", ...},\n  ...\n}}\n```\n\n## Commands\n\nAll providers implement: `connect`, `list_calendars`, `list_events`, `create_event`, `update_event`, `delete_event`. See `caldir-core\u002Fsrc\u002Fremote\u002Fprotocol.rs` for exact field names per command.\n\n`list_events` is the workhorse for debugging — it takes `from` \u002F `to` as RFC3339 strings.\n\n## Finding the right config\n\nPer-calendar config lives at `~\u002F\u003Ccalendar_dir>\u002F\u003Cslug>\u002F.caldir\u002Fconfig.toml`. The `[remote]` block has the provider name and provider-prefixed account\u002Fcalendar fields. Read it with `cat` and pass the same fields (minus `provider`) into `params`.\n\nThe user's `calendar_dir` comes from `~\u002F.config\u002Fcaldir\u002Fconfig.toml`.\n\n## Use the dev build, not the installed binary\n\nAfter editing a provider, rebuild it and invoke the dev binary by absolute path — don't rely on `which caldir-provider-google`, that finds the installed copy in `~\u002F.cargo\u002Fbin`.\n\n```bash\ncargo build -p caldir-provider-google\nPROVIDER=\"$(pwd)\u002Ftarget\u002Fdebug\u002Fcaldir-provider-google\"  # run from repo root\n```\n\nIf you want the whole CLI to use the dev build (e.g. to confirm a fix end-to-end via `caldir status`), prepend `target\u002Fdebug` to PATH:\n\n```bash\nPATH=\"$(pwd)\u002Ftarget\u002Fdebug:$PATH\" caldir status\n```\n\n## Pretty-printing output\n\n`jq` is fine for shape inspection. For Google-specific filtering (e.g. \"find every event referencing this UID\"), Python with `json.load(sys.stdin)` and a list comprehension is faster to write than the jq equivalent:\n\n```bash\necho '{\"command\":\"list_events\",\"params\":{...}}' | \"$PROVIDER\" | python3 -c \"\nimport json, sys\nr = json.loads(sys.stdin.read())\nprint('status:', r.get('status'))\nevents = r.get('data', [])\nprint('total:', len(events))\nfor e in events:\n    if 'lars' in (e.get('summary') or '').lower():\n        print(json.dumps(e, indent=2))\n\"\n```\n\n## Going below the provider\n\nWhen you suspect the provider itself is misinterpreting what the upstream API returned, hit the upstream directly.\n\nComparing the upstream response to what the provider emits is the fastest way to localize a bug to \"upstream is weird\" vs. \"we're parsing it wrong\".\n\n### Google Calendar API\n\n```bash\nTOKEN=$(grep \"^access_token\" ~\u002F.config\u002Fcaldir\u002Fproviders\u002Fgoogle\u002Fsession\u002F\u003Caccount>.toml | cut -d'\"' -f2)\ncurl -s -H \"Authorization: Bearer $TOKEN\" \\\n  \"https:\u002F\u002Fwww.googleapis.com\u002Fcalendar\u002Fv3\u002Fcalendars\u002F\u003Cid>\u002Fevents?timeMin=...&timeMax=...&singleEvents=true&showDeleted=true\" \\\n  | jq '.items[] | select(.summary | test(\"foo\"; \"i\"))'\n```\n\nUseful Google flags:\n- `singleEvents=true` — expand recurrences into instances; cancelled instances are omitted\n- `showDeleted=true` — include cancelled instances\u002Fevents (returns full data when used with `singleEvents=true`)\n- Default (`singleEvents=false`, `showDeleted=false`) returns master events plus bare cancellation tombstones\n\n### Microsoft Graph (Outlook)\n\n```bash\nTOKEN=$(grep \"^access_token\" ~\u002F.config\u002Fcaldir\u002Fproviders\u002Foutlook\u002Fsession\u002F\u003Caccount>.toml | cut -d'\"' -f2)\ncurl -s -H \"Authorization: Bearer $TOKEN\" \\\n  \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002Fme\u002Fcalendars\u002F\u003Cid>\u002Fevents?\\$select=id,iCalUId,subject,start,recurrence,type\" \\\n  | jq '.value[] | select(.subject | test(\"foo\"; \"i\"))'\n```\n\nPicking the right endpoint matters — Graph has three with very different semantics:\n\n- `\u002Fme\u002Fcalendars\u002F{id}\u002Fevents` — series **masters** and **standalones** only. Does NOT include exceptions or expanded occurrences. Best for \"what discrete events does this calendar contain\".\n- `\u002Fme\u002Fevents\u002F{master_id}\u002Finstances?startDateTime=...&endDateTime=...` — every occurrence of one series in the window, including overrides. Each item carries a `type` field: `occurrence` (auto-expanded, identical to master) or `exception` (overridden). caldir's `list_events` calls this for masters represented in `calendarView` and keeps only `type=exception`.\n- `\u002Fme\u002FcalendarView?startDateTime=...&endDateTime=...` — every occurrence of every series, fully expanded. Convenient for \"show me the calendar\" but a long-running weekly meeting becomes ~50 indistinguishable rows, so caldir avoids it.\n\nURL gotcha: Graph rejects RFC3339 timestamps containing `+` (e.g. `2026-05-01T16:00:00+00:00`) because URL-decoders read `+` as a space. Use the `Z` form (`2026-05-01T16:00:00Z`).\n\nOData syntax for the curl shell: prefix `$select`, `$top`, `$filter` etc. with a backslash so the shell doesn't try to expand them. Inside `jq`, the `@odata.nextLink` field is the pagination cursor.\n\nUseful fields on a Graph event:\n- `type` — `singleInstance` | `seriesMaster` | `occurrence` | `exception`\n- `iCalUId` — RFC 5545 UID. Microsoft mints a **fresh** one per exception (RFC violation), so caldir rewrites exceptions to share their master's UID\n- `originalStart` — UTC ISO-8601, the scheduled start of the recurring slot this exception overrides; this is what caldir matches against `recurrence_id`\n\n## When NOT to use this\n\n- For testing pure conversion logic (e.g. `from_google` mapping fields), prefer a unit test with a fake `google_calendar::types::Event` — see `caldir-provider-google\u002Fsrc\u002Fcommands\u002Flist_events.rs` tests for the empty-event-via-serde pattern.\n- For end-to-end behavior (status output, file writes), just run `caldir status` \u002F `caldir pull` with the dev provider on PATH.\n\nThe direct-RPC trick is for the gap between those two: \"what's actually on the wire?\"\n","# Talking to providers directly\n\nProviders are standalone binaries that speak JSON over stdin\u002Fstdout. When something looks wrong in `caldir status` \u002F `caldir pull`, you can usually narrow the bug to \"wrong on the wire\" vs. \"wrong after parsing\" in one shot by invoking the provider directly.\n\nThis bypasses caldir-cli, caldir-core, the diff engine, and the renderer — you see exactly what came back from the remote.\n\n## Protocol shape\n\nOne JSON line in, one JSON line out. The protocol is defined in `caldir-core\u002Fsrc\u002Fremote\u002Fprotocol.rs` — that file is the source of truth, check it if a command argument shape isn't obvious.\n\nRequest:\n```json\n{\"command\":\"\u003Ccommand>\",\"params\":{...}}\n```\n\nResponse (success):\n```json\n{\"status\":\"success\",\"data\":\u003Ccommand-specific>}\n```\n\nResponse (error):\n```json\n{\"status\":\"error\",\"error\":\"\u003Cmessage>\"}\n```\n\n## Critical: params is FLAT\n\n`remote_config` is `#[serde(flatten)]` in protocol structs. Pass its fields at the top level of `params`, not nested under `remote_config`. If you nest, you'll get `Missing required field: \u003Cname>`.\n\n```jsonc\n\u002F\u002F CORRECT\n{\"command\":\"list_events\",\"params\":{\n  \"google_account\":\"me@gmail.com\",\n  \"google_calendar_id\":\"primary\",\n  \"from\":\"2026-01-01T00:00:00Z\",\n  \"to\":\"2026-02-01T00:00:00Z\"\n}}\n\n\u002F\u002F WRONG — provider rejects with \"Missing required field: google_account\"\n{\"command\":\"list_events\",\"params\":{\n  \"remote_config\":{\"google_account\":\"me@gmail.com\", ...},\n  ...\n}}\n```\n\n## Commands\n\nAll providers implement: `connect`, `list_calendars`, `list_events`, `create_event`, `update_event`, `delete_event`. See `caldir-core\u002Fsrc\u002Fremote\u002Fprotocol.rs` for exact field names per command.\n\n`list_events` is the workhorse for debugging — it takes `from` \u002F `to` as RFC3339 strings.\n\n## Finding the right config\n\nPer-calendar config lives at `~\u002F\u003Ccalendar_dir>\u002F\u003Cslug>\u002F.caldir\u002Fconfig.toml`. The `[remote]` block has the provider name and provider-prefixed account\u002Fcalendar fields. Read it with `cat` and pass the same fields (minus `provider`) into `params`.\n\nThe user's `calendar_dir` comes from `~\u002F.config\u002Fcaldir\u002Fconfig.toml`.\n\n## Use the dev build, not the installed binary\n\nAfter editing a provider, rebuild it and invoke the dev binary by absolute path — don't rely on `which caldir-provider-google`, that finds the installed copy in `~\u002F.cargo\u002Fbin`.\n\n```bash\ncargo build -p caldir-provider-google\nPROVIDER=\"$(pwd)\u002Ftarget\u002Fdebug\u002Fcaldir-provider-google\"  # run from repo root\n```\n\nIf you want the whole CLI to use the dev build (e.g. to confirm a fix end-to-end via `caldir status`), prepend `target\u002Fdebug` to PATH:\n\n```bash\nPATH=\"$(pwd)\u002Ftarget\u002Fdebug:$PATH\" caldir status\n```\n\n## Pretty-printing output\n\n`jq` is fine for shape inspection. For Google-specific filtering (e.g. \"find every event referencing this UID\"), Python with `json.load(sys.stdin)` and a list comprehension is faster to write than the jq equivalent:\n\n```bash\necho '{\"command\":\"list_events\",\"params\":{...}}' | \"$PROVIDER\" | python3 -c \"\nimport json, sys\nr = json.loads(sys.stdin.read())\nprint('status:', r.get('status'))\nevents = r.get('data', [])\nprint('total:', len(events))\nfor e in events:\n    if 'lars' in (e.get('summary') or '').lower():\n        print(json.dumps(e, indent=2))\n\"\n```\n\n## Going below the provider\n\nWhen you suspect the provider itself is misinterpreting what the upstream API returned, hit the upstream directly.\n\nComparing the upstream response to what the provider emits is the fastest way to localize a bug to \"upstream is weird\" vs. \"we're parsing it wrong\".\n\n### Google Calendar API\n\n```bash\nTOKEN=$(grep \"^access_token\" ~\u002F.config\u002Fcaldir\u002Fproviders\u002Fgoogle\u002Fsession\u002F\u003Caccount>.toml | cut -d'\"' -f2)\ncurl -s -H \"Authorization: Bearer $TOKEN\" \\\n  \"https:\u002F\u002Fwww.googleapis.com\u002Fcalendar\u002Fv3\u002Fcalendars\u002F\u003Cid>\u002Fevents?timeMin=...&timeMax=...&singleEvents=true&showDeleted=true\" \\\n  | jq '.items[] | select(.summary | test(\"foo\"; \"i\"))'\n```\n\nUseful Google flags:\n- `singleEvents=true` — expand recurrences into instances; cancelled instances are omitted\n- `showDeleted=true` — include cancelled instances\u002Fevents (returns full data when used with `singleEvents=true`)\n- Default (`singleEvents=false`, `showDeleted=false`) returns master events plus bare cancellation tombstones\n\n### Microsoft Graph (Outlook)\n\n```bash\nTOKEN=$(grep \"^access_token\" ~\u002F.config\u002Fcaldir\u002Fproviders\u002Foutlook\u002Fsession\u002F\u003Caccount>.toml | cut -d'\"' -f2)\ncurl -s -H \"Authorization: Bearer $TOKEN\" \\\n  \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002Fme\u002Fcalendars\u002F\u003Cid>\u002Fevents?\\$select=id,iCalUId,subject,start,recurrence,type\" \\\n  | jq '.value[] | select(.subject | test(\"foo\"; \"i\"))'\n```\n\nPicking the right endpoint matters — Graph has three with very different semantics:\n\n- `\u002Fme\u002Fcalendars\u002F{id}\u002Fevents` — series **masters** and **standalones** only. Does NOT include exceptions or expanded occurrences. Best for \"what discrete events does this calendar contain\".\n- `\u002Fme\u002Fevents\u002F{master_id}\u002Finstances?startDateTime=...&endDateTime=...` — every occurrence of one series in the window, including overrides. Each item carries a `type` field: `occurrence` (auto-expanded, identical to master) or `exception` (overridden). caldir's `list_events` calls this for masters represented in `calendarView` and keeps only `type=exception`.\n- `\u002Fme\u002FcalendarView?startDateTime=...&endDateTime=...` — every occurrence of every series, fully expanded. Convenient for \"show me the calendar\" but a long-running weekly meeting becomes ~50 indistinguishable rows, so caldir avoids it.\n\nURL gotcha: Graph rejects RFC3339 timestamps containing `+` (e.g. `2026-05-01T16:00:00+00:00`) because URL-decoders read `+` as a space. Use the `Z` form (`2026-05-01T16:00:00Z`).\n\nOData syntax for the curl shell: prefix `$select`, `$top`, `$filter` etc. with a backslash so the shell doesn't try to expand them. Inside `jq`, the `@odata.nextLink` field is the pagination cursor.\n\nUseful fields on a Graph event:\n- `type` — `singleInstance` | `seriesMaster` | `occurrence` | `exception`\n- `iCalUId` — RFC 5545 UID. Microsoft mints a **fresh** one per exception (RFC violation), so caldir rewrites exceptions to share their master's UID\n- `originalStart` — UTC ISO-8601, the scheduled start of the recurring slot this exception overrides; this is what caldir matches against `recurrence_id`\n\n## When NOT to use this\n\n- For testing pure conversion logic (e.g. `from_google` mapping fields), prefer a unit test with a fake `google_calendar::types::Event` — see `caldir-provider-google\u002Fsrc\u002Fcommands\u002Flist_events.rs` tests for the empty-event-via-serde pattern.\n- For end-to-end behavior (status output, file writes), just run `caldir status` \u002F `caldir pull` with the dev provider on PATH.\n\nThe direct-RPC trick is for the gap between those two: \"what's actually on the wire?\"\n",{"name":5,"description":7,"user_invocable":38},"main","16b1db7e9ed1218c9fd3dc80ccb40ac84d43b4aa",".agents\u002Fskills\u002Fprovider-rpc",16,"https:\u002F\u002Fgithub.com\u002Ft4t5\u002Fcaldir","https:\u002F\u002Fcaldir.org","https:\u002F\u002Fgithub.com\u002Ft4t5","https:\u002F\u002Ft4t5.com","open sorcerer and plaintext enthusiast","2026-11-06 23:20:25",{"source":8,"skillName":5,"commands":53,"prompt":63,"zipAvailable":64},[54,57,60],{"tool":55,"command":56},"npx","npx skills add t4t5\u002Fcaldir --skill provider-rpc",{"tool":58,"command":59},"bunx","bunx skills add t4t5\u002Fcaldir --skill provider-rpc",{"tool":61,"command":62},"pnpm","pnpm dlx skills add t4t5\u002Fcaldir --skill provider-rpc","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ft4t5\u002Fcaldir\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fprovider-rpc\u002FSKILL.md",true,[66],{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"README.md","REFERENCE","参考文档",3799,"https:\u002F\u002Fgithub.com\u002Fdmlguq456\u002Fhearting\u002Fblob\u002Fmain\u002Fadapters\u002Fclaude\u002Fskills\u002Fcode-refine\u002FREADME.md",[73,88],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":79,"publishedAt":37},"01M6C5M9VA7T2G4RSNT8X7A1MA","caldir","Read, create, edit, and sync calendar events as plaintext .ics files using the caldir CLI. Use whenever the user wants to query, add, modify, or sync calendar events — e.g. \"what's on my calendar this week\", \"add a meeting tomorrow at 3\", \"cancel my Friday standup\", \"sync my Google calendar\". Requires the `caldir` CLI.","https:\u002F\u002Fgithub.com\u002Ft4t5\u002Fcaldir\u002Fblob\u002Fmain\u002Fwebsite\u002Fsrc\u002Fdata\u002Fskill.md",[],[75,29,80,36,81,82,83,84,85,86,23,87],"cli","create","ics","standup","read","edit","user","calendar",{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":37},"01M6C5M55A27Q1YA7J71PNNCKC","bump","Analyze changes since last release and bump crate versions","https:\u002F\u002Fgithub.com\u002Ft4t5\u002Fcaldir\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fbump\u002FSKILL.md",[],[90,95,96],"release","analyze"]