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

codesky

v1.0.0

Published

Orchestrator bridging Gemini CLI and BlueSky for public vibecoding

Readme

CodeSKY: A Gemini-Powered BlueSky Bot MVP

This minimalist plan focuses on building the Social State Machine first. We will implement the OAuth + Keyring authentication and the binary thread-tip logic while keeping the agent in a "Read-Only" mode.


Phase 1: Minimalist Bot Architecture

The bot is written in pure JavaScript and node.js (no TypeScript or complex build steps).

1. Secure Authentication Layer

The bot will use OAuth 2.0 with PKCE. This ensures the orchestrator never touches your master password.

  • Storage: We will use keytar (or a similar library) to interface with the system keyring.
  • Flow: 1. Orchestrator checks keyring for a Refresh Token.
  1. If missing, it prints a login URL.
  2. User authorizes in browser; Orchestrator receives tokens and saves the Refresh Token to the keyring.
  3. Access Tokens are kept strictly in-memory.

2. The Polling & Dispatch Logic

The orchestrator will poll the BlueSky notification timeline. For every notification, it fetches the thread context to perform the Binary State Evaluation:

  • State A (Ignore): The thread tip is a post by the Bot. The turn belongs to the user.
  • State B (Process): The thread tip is a post by an Authorized User.
  • Action: 1. Post ephemeral Processing... message.
  1. Call Gemini (Read-Only mode).
  2. Post genuine reply.
  3. Delete the ephemeral Processing... message.

3. Environment & Constraints

To keep this phase truly minimalist and "safe," we apply these restrictions:

  • No File Access: The agent is not provided with tools to read or write to the local disk.
  • No Isolation: Since there is no filesystem risk, we skip PRoot for this phase.
  • System Prompt: Gemini is instructed: "You are a dialogue-only agent. Do not suggest code changes or file edits. Focus only on conversation and logic analysis."

4. Tech Stack for the MVP

| Component | Library/Tool | | --- | --- | | Language | Node.js (Latest LTS) | | BlueSky API | @atcute set of packages | | Keyring | keytar | | Inference | Google Generative AI SDK (Gemini 2.0/1.5) |


5. Verification Goals

  1. Persistence: Reboot the computer and see if the bot resumes polling without asking for a login.
  2. Cleanliness: Confirm the Processing... messages are deleted successfully after every turn.
  3. Concurrency: Send messages in two different threads simultaneously and ensure replies stay in their respective lanes.

Keytar fallback

The keytar fallback logic is a resilient storage pattern that prioritizes security but ensures functionality across different environments like WSL2 or Termux. It operates on a "Best-Effort Encryption" principle.

1. Runtime Detection (The Probe)

The Orchestrator does not assume the environment is compatible with native system APIs. At startup, it performs a guarded attempt to load the keytar module. If the module is missing or the underlying system service (like D-Bus or libsecret) is unresponsive, the Orchestrator catches the failure immediately rather than crashing.

2. Tiered Storage Selection

Based on the result of the probe, the system branches into one of two persistence paths:

  • Tier 1: System Keyring (Secure Path)

  • Used when keytar is successfully initialized.

  • Tokens are handed off to the OS (macOS Keychain, Windows Credential Vault, or Linux Secret Service).

  • The data is encrypted at rest by the operating system, protecting it from unauthorized file-system access.

  • Tier 2: Home-Directory JSON (Compatibility Path)

  • Used as the fail-safe for Termux, headless servers, or restricted sandboxes.

  • The tokens are stored in a hidden configuration file located in the user's home directory.

  • While this skips the system-level encryption, it ensures the bot remains stateless and portable, as the session can be recovered even without specialized system libraries.

3. Abstracted Access (The Facade)

To the rest of the bot's code, the storage method is invisible. The Orchestrator interacts with a unified "Token Manager" interface. Whether the token is pulled from an encrypted hardware enclave or a local text file, the internal logic only cares that a valid token is returned for the BlueSky session.

4. Installation Resilience

By marking keytar as an optional dependency in the project configuration, the bot remains installable on systems where native C++ compilation would normally fail. The installation process simply skips the "fucky" parts, allowing the pure-JavaScript fallback logic to take over automatically.

App password fallback

This adds a "Power User" override to the system. By introducing environment variables as the top-priority check, you allow the Orchestrator to skip the complex OAuth handshake entirely for local testing or CI/CD pipelines.

The Orchestrator will evaluate credentials in a strict Top-Down order. The moment it finds a valid set of credentials, it stops searching and initializes the session.

1. Tier 1: The Environment Override (Highest Priority)

This is the "Manual Override." If the user provides CODESKY_HANDLE and CODESKY_APP_PASSWORD in the shell environment (or a .env file), the bot immediately uses the App Password flow.

  • Why: This is perfect for Termux or quick local tests where you don't want to deal with browser redirects or keyring permissions.
  • Flow: 1. Checks for both variables.
  1. If present, calls agent.login() directly.
  2. Skips the Keyring and OAuth checks entirely.

2. Tier 2: The Secure Keyring (Default Stable)

If the environment variables are missing, the bot looks for a persistent OAuth session in the system keyring (e.g., keytar).

  • Why: This is the most "set-and-forget" stable method for a desktop/WSL2 environment.
  • Flow:
  1. Attempts to retrieve a refresh_token from the keyring.
  2. If found, it silently refreshes the session.

3. Tier 3: The Plain-Text Fallback (Portability)

If keytar is not available (like on Termux) and no environment variables are set, it checks the local home directory for a hidden session file.

  • Why: Ensures the bot can still be "stable" (survive reboots) on platforms that lack a system keyring.

4. Tier 4: Interactive OAuth Prompt (The Last Resort)

If all of the above fail, the bot assumes it is a fresh install.

  • Action: It prints the OAuth login URL and waits for the user to complete the browser handshake. Once finished, it saves the result to whichever Tier (2 or 3) is available.

The Logical Flow Visualized

| Priority | Method | Trigger | Storage | | --- | --- | --- | --- | | 1 | App Password | CODESKY_... Env Vars | None (Process only) | | 2 | OAuth (Refresh) | No Env Vars + Keyring Present | System Keyring | | 3 | OAuth (Refresh) | No Env Vars + Keyring Missing | ~/.bsky-session.json | | 4 | OAuth (Login) | No previous session found | Starts new Handshake |


Summary of the Env/App Password Fallback

By adding this, you've created a "Universal" bot.

  • On Windows/Linux, you'll likely use the OAuth/Keyring (Tier 2).
  • In a Termux environment, you can simply run export CODESKY_PASSWORD=... (Tier 1) and the bot will spring to life without needing a D-Bus or a browser.