npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

usrcp-google-calendar

v0.1.8

Published

Google Calendar capture adapter for USRCP - polls the configured user's primary calendar for past events they attended and appends them to the local ledger

Readme

usrcp-google-calendar

Capture-only Google Calendar adapter for USRCP. Polls the configured user's primary calendar for past events they attended and appends them to the local ledger as event_attended entries.

The cloud sees nothing from this adapter; it writes only to the local ledger (which encrypts at rest under the same master key as the rest of USRCP).

What it captures

  • Events on the primary calendar with both a start.dateTime and an end.dateTime (i.e., timed events; all-day entries are skipped).
  • Only after the event has ended - we capture meetings the user actually attended, not future appointments.
  • Skipped: cancelled events; events the user RSVP'd declined.

Each ledger entry has:

  • domain: configurable (default calendar)
  • intent: event_attended
  • outcome: success
  • detail: full event metadata - id, summary, description, location, url, start, end, organizer email, attendee emails, created/updated.
  • tags: ["google-calendar", "event"]
  • channel_id: the Google event id (for getRecentEventsByChannel).
  • Idempotency key: gcal:event:<id> (re-running the poller is safe).

Setup

Google requires a real OAuth client; there is no "personal API key" shortcut for user calendar data. Setup is a one-time three-secret prompt.

1. Create the OAuth client (one-time)

  1. Go to console.cloud.google.com, create a project (or reuse one).
  2. APIs & Services > Library: enable Google Calendar API.
  3. APIs & Services > OAuth consent screen: set up the consent screen (External, fill the required fields, add your email as a test user).
  4. APIs & Services > Credentials > Create credentials > OAuth client ID: choose Desktop app. Copy the resulting client ID and client secret.

2. Run the wizard

cd packages/usrcp-google-calendar
npm install
npm run build

usrcp setup --adapter=google-calendar

The wizard prompts for client_id + client_secret and then asks whether to authorise via browser (default Yes). The browser flow opens a localhost listener, prints the Google sign-in URL, captures the redirect, and persists the refresh token automatically; no copy / paste from the OAuth Playground.

If you can't open a browser from this machine (remote shell, CI, etc.), answer "no" and the wizard falls back to the manual OAuth-Playground path:

  1. Visit developers.google.com/oauthplayground.
  2. Click the gear icon (top right). Tick Use your own OAuth credentials and paste your client ID + secret.
  3. In the left panel, scroll to Google Calendar API v3 and tick https://www.googleapis.com/auth/calendar.readonly.
  4. Click Authorize APIs, complete the Google sign-in, then Exchange authorization code for tokens.
  5. Copy the refresh_token from the response and paste it into the wizard.

The wizard validates the credentials against the Calendar API before persisting, so a wrong value fails fast.

Run

usrcp-google-calendar
# or: USRCP_PASSPHRASE=<pp> usrcp-google-calendar

The poller logs each tick that captured or skipped any events.

Config

Stored at ~/.usrcp/google-calendar-config.json (mode 0600):

| Field | Type | Notes | |---|---|---| | oauth_client_id | string | From step 1. Plaintext (not sensitive). | | oauth_client_secret | string | Encrypted at rest as enc:<base64> under the USRCP global key (HKDF-derived from the master key). | | refresh_token | string | Encrypted at rest as enc:<base64> under the USRCP global key. Grants long-lived Calendar read access; the master-key wrap means an attacker who reads disk without unlocking the passphrase cannot use it. | | domain | string | USRCP domain to write events under. | | poll_interval_s | number | Seconds; 60-3600. Default 300 (5 min). | | last_synced_at | string | ISO; managed by the poller. |

Pre-#54 configs with plaintext secrets are still readable; the first save (e.g. when the poller advances the cursor) auto-migrates them into the encrypted envelope.

What's out of scope (v0)

  • Secondary calendars (only primary).
  • Stream sync (no stream_events entries; ledger only).
  • Capturing future events (no "I scheduled X" entries).
  • Recurring-event masters (we capture each instance individually via singleEvents=true).
  • Webhook push (we poll - works behind NAT on a laptop).
  • Storing event bodies encrypted-at-rest with the USRCP master key (matches Linear's posture: config is plaintext-on-disk, mode 0600, same as ~/.ssh/id_rsa).