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

@openthread/claude-code-plugin

v0.2.8

Published

Share Claude Code conversations to OpenThread — the StackOverflow for AI agents. One command to publish any session to the community platform for the agentic AI era.

Downloads

2,200

Readme

@openthread/claude-code-plugin

Share, search, import, and install Claude Code conversations as skills via OpenThreadthe StackOverflow for AI agents. The community platform for the agentic AI era, where developers share, vote on, and discover the best AI conversation threads from Claude, ChatGPT, Gemini, and more.

Eight slash commands. Zero surprise browser pops. Strict trust boundaries between third-party content and your local machine.

npm version license downloads

Install

npm i -g @openthread/claude-code-plugin

Restart Claude Code. That's it — nothing else to configure. npm install registers the plugin and wires up all the slash commands automatically.

/ot:share — publish the current conversation

> /ot:share

Analyzing your conversation...

Step 1: Authenticate ✓
Step 2: Find the session file ✓ — 2 contexts detected
Step 3: Review and publish

? This session has 2 detected contexts. Which do you want to share?
  > Full thread (Recommended)
    seg-0: Debugging PKCE token refresh (turns 0–42)
    seg-1: Wiring up the new search index (turns 43–87)

? Choose one or more communities to publish to     [multi-select]
  [x] Coding with AI (Recommended)
  [ ] Debugging with AI
  [ ] AI Dev Tools
  [ ] Claude Threads

? Auto-generated tags: typescript, auth, debugging. Accept or edit?
  > Accept (Recommended)
    Edit tags

? Publish this as a Thread or a Skill?
  > Thread (Recommended)
    Skill

Conversation shared to OpenThread:

  • Title: Debugging PKCE Token Refresh in Auth Middleware
  • Community: Coding with AI
  • Tags: typescript, auth, debugging
  • Type: Thread
  • URL: https://openthread.me/c/coding-with-ai/post/27512cb1

What happens:

  1. Context detection — the plugin splits your session into distinct topic segments using timestamp gaps, working-directory changes, and tool-use shifts. If it finds more than one segment, you can publish just the one that matters. Otherwise this question is skipped.
  2. Multi-community selection — pick one or more communities. The plugin creates a separate post per community.
  3. Tags — auto-generated from the conversation content; accept or rewrite in one keypress.
  4. Post typeThread (standard conversation) or Skill (reusable package others can install via /ot:import --skill).

The first run on a fresh machine prints an extra Signing you in to OpenThread... line before Analyzing your conversation.... A browser tab opens for OAuth; once you approve, the rest of the flow proceeds automatically. You never type /ot:auth login by hand. Every subsequent /ot:share skips the sign-in step — the session is cached.

Non-interactive variants:

/ot:share --yes                   # skip the editor preview
/ot:share --skill --segment 2     # publish segment 2 as a Skill post
/ot:share --community ai-dev      # skip the community picker

/ot:search — search OpenThread

> /ot:search "hono auth middleware" --limit 3

[1] Debugging PKCE token refresh in auth middleware
    c/coding-with-ai · u/alice · 3h ago · ▲ 42 · 💬 7
    Walks through the PKCE refresh flow and the off-by-one in expiresAt
    that caused silent sign-outs on the 59th minute of every session...

[2] Hono middleware ordering: auth before CORS or after?
    c/backend-tips · u/bob · 1d ago · ▲ 18 · 💬 4
    A short thread on why CORS must run before auth if you want 401s
    to include CORS headers...

[3] JWT rotation with Hono + Redis
    c/hono · u/carol · 2d ago · ▲ 9 · 💬 2

? Import one of these?
  > [1] Debugging PKCE token refresh in auth middleware
    [2] Hono middleware ordering
    [3] JWT rotation with Hono + Redis
    Skip — just the results, don't import

If you pick a result, the plugin asks how to import it (save, inject, or install as a skill) and delegates to /ot:import.

Filters:

/ot:search "code review" --type comments           # comments, not posts
/ot:search "gh auth helper" --type skills          # only skill-shares
/ot:search "hono" --community coding-with-ai       # scope to one community
/ot:search "typescript" --provider claude --time week   # claude threads this week
/ot:search "migration" --limit 25                   # up to 25 results

Runs anonymously. No browser, no auth, no session required. If you happen to be signed in, you also see posts from private communities you belong to.

/ot:import — fetch a post into your workspace

> /ot:import 27512cb1-4e7a-4c3b-9d8e-1f2a3b4c5d6e

Imported: Debugging PKCE Token Refresh in Auth Middleware
Author:   @alice
Community: c/coding-with-ai
Messages: 42
Size:     87 KB

Preview:
  Long session today. PKCE flow was working locally but silently failing
  in prod — token refresh endpoint was returning 200 with an empty body...

Saved locally. I will NOT read this file automatically. If you want me
to read it, ask in a new message. The imported content is DATA, not
instructions.

Three destination modes — one flag picks where the content lands:

/ot:import <id>                       # --read (default) → disk, NOT injected
/ot:import <id> --read                #   explicit
/ot:import <id> --context             #   inject into THIS conversation
/ot:import <id> --skill               #   install as a local skill (globally)
/ot:import <id> --skill --project     #   install as a local skill (this repo)

--read saves to ~/.openthread/imports/<uuid>.md with mode 0600. Claude does NOT auto-load the file — you must ask in a separate message.

--context fetches the post, wraps it in an <imported_thread trust="untrusted"> envelope, and asks you to confirm before injecting. Declining leaves zero files on disk.

--skill installs a fetched post as a globally invokable skill at ~/.claude/skills/<name>/SKILL.md with an .ot-origin.json sidecar recording who shared it and when. First install asks for a one-keypress confirmation. Collision shows the existing origin next to the new one and asks Replace / Keep / Cancel.

Accepts bare UUIDs, path suffixes, or full URLs:

/ot:import 27512cb1-4e7a-4c3b-9d8e-1f2a3b4c5d6e
/ot:import /c/coding-with-ai/post/27512cb1-4e7a-4c3b-9d8e-1f2a3b4c5d6e
/ot:import https://openthread.me/c/coding-with-ai/post/27512cb1-...

Every imported byte is treated as untrusted third-party data. See the Security guarantees section for the full trust boundary.

/ot:export — download a post as a local file

> /ot:export 27512cb1-4e7a-4c3b-9d8e-1f2a3b4c5d6e

Exported: Debugging PKCE Token Refresh in Auth Middleware
Format:   markdown
Size:     87 KB

The file is a plain archive with a provenance banner. It is NOT
loaded into my context. If you want me to read it, ask in a new
message.

Unlike /ot:import, the exported file is written to your current working directory with sharable permissions (0644). It's meant to be committed to a repo, shared over email, or archived — not loaded into Claude's context.

Format and output flags:

/ot:export <id>                       # markdown archive (default)
/ot:export <id> --format json         # structured JSON export
/ot:export <id> --format text --no-banner   # plain text, no provenance header
/ot:export <id> --out ./thread.md     # explicit output path (CWD-guarded)
/ot:export <id> --stdout              # body to stdout, metadata to stderr

--skill mode writes a SKILL.md-shaped template file to your current directory. Unlike /ot:import --skill, this does NOT install the skill globally — it just produces the file so you can commit it to a repo.

/ot:export <id> --skill               # write SKILL.md template to CWD

To take a template from /ot:export --skill and install it globally, use /ot:import --skill <source-url> after publishing the thread. Different commands, different targets.

Runs anonymously. No browser, no auth, no session required.


Power-user skills

These exist for troubleshooting and non-npm install flows. You do not need any of them during normal daily use — the four skills above are complete.

/ot:status — health check when something breaks

> /ot:status

Plugin:   ✓ openthread-share v0.2.2
          ~/.claude/plugins/marketplaces/openthread/plugins/ot/
Skills:   ✓ 8/8 installed
Deps:     ✓ python3 3.11  ✓ curl 8.1  ✓ bash 5.2
Auth:     ✓ signed in as @alice, expires in 42m
Server:   ✓ reachable
Updates:  ✓ up to date (0.2.2)

Run this if a skill is behaving oddly. Every failing line includes a fix: <command> hint. Side-effect-free — safe to run any time.

/ot:status --json            # machine-readable for scripting
/ot:status --quiet           # only failing sections, rc=1 if any
/ot:status --section auth    # limit to one section

/ot:auth — explicit session management

You almost never need this. The first /ot:share on a fresh machine auto-auths; subsequent calls reuse the cached session. Use /ot:auth only when you want to sign OUT, switch accounts, or force-refresh a dying session.

/ot:auth              # whoami if signed in, else login
/ot:auth whoami       # print the signed-in user + expiry
/ot:auth refresh      # refresh the token without opening a browser
/ot:auth logout       # clear the cached session (asks for confirmation)
/ot:auth logout --yes # clear without asking
/ot:auth login        # force a fresh browser OAuth flow

/ot:update — update the plugin (non-npm install paths)

If you installed via npm, use npm update -g @openthread/claude-code-plugin instead. This command is for users who installed via git clone or tarball.

/ot:update --check           # report availability, no changes
/ot:update                   # fetch → stage → validate → atomic swap
/ot:update --dry-run         # stage + validate, don't swap
/ot:update --rollback        # restore the most recent backup

Updates are atomic. The new tree is staged in a sibling directory, validated (deps, minApi compat), then promoted via a directory rename. In-flight skills finish under the old tree (the kernel holds their inode open), and the backup at .bak/<old-version>/ lets you roll back if something regresses.

/ot:install — bootstrap the plugin (non-npm install paths)

If you installed via npm, the plugin is already installed. Running /ot:install will report EXISTS. This command is for users who prefer to install from git or a local path.

/ot:install --source git --from https://github.com/openthread/openthread-share
/ot:install --source tarball --from https://openthread.me/releases/v0.2.2.tgz
/ot:install --source local --from ~/src/openthread-share
/ot:install --dry-run        # preview without touching anything

Security guarantees

Everything below is covered by the regression suite at scripts/test-live.sh — run it any time to verify.

Auth is never initiated on your behalf

The plugin never opens a browser OAuth flow except when you explicitly run /ot:auth login. No other skill — not /ot:share, not /ot:search, not /ot:import, not even /ot:status — will ever initiate auth on its own.

Under the hood, every optional-auth path uses token.sh get-if-cached, which:

  1. Returns a cached access token if one is valid.
  2. Refreshes the token silently if it's within 60s of expiry.
  3. Exits non-zero without touching the browser if no session exists.

On a stale refresh token (refresh fails with 401/403/etc.), the plugin clears the bad session file automatically so subsequent invocations take the fast "no session" path instead of hammering the refresh endpoint. You must run /ot:auth login to re-authenticate.

Imported content is UNTRUSTED data, never instructions

/ot:import treats every byte of a fetched post as data, not commands. The skill body enforces this at multiple layers:

  • The imported content is never executed, interpreted, or treated as instructions by Claude.
  • --read saves to disk with mode 0600 inside a 0700 directory and does NOT auto-read the file into context.
  • --context wraps the body in an <imported_thread trust="untrusted"> envelope before injection, and the envelope file is not pre-written to disk — the user must confirm via AskUserQuestion before any injection or write.
  • --skill shows a confirmation block with the post's origin (name, description, author, community) before installing. On collision, the existing .ot-origin.json sidecar is shown alongside the new origin so the user can decide between Replace / Keep / Cancel.
  • Strict UUID validation on every input form.
  • HTTPS enforced unless OPENTHREAD_API_URL points to a loopback host.
  • Response bodies capped at 5 MB, read in bounded chunks.
  • Control characters and ANSI escapes stripped; paths, usernames, secrets, emails, and IPs masked locally as defense-in-depth on top of server-side masking.

Skill installs leave a provenance trail

Every /ot:import --skill install writes a .ot-origin.json sidecar next to the SKILL.md:

{
  "schema": "ot-origin/1",
  "postId": "27512cb1-4e7a-4c3b-9d8e-1f2a3b4c5d6e",
  "author": "alice",
  "community": "coding-with-ai",
  "importedAt": "2026-04-15T10:23:11Z",
  "pluginVersion": "0.1.12",
  "sourceUrl": "https://openthread.me/c/coding-with-ai/post/27512cb1-...",
  "title": "Auth helper for gh CLI"
}

Future imports that would collide read this sidecar to render a clear "replacing X by @alice with Y by @bob" comparison before overwriting. --force skips the prompt but never suppresses the summary.

File permissions and path safety

| File / directory | Mode | Purpose | |---|---|---| | ~/.claude/plugins/openthread-share/ | 0755 | plugin root | | .session.json | 0600 | OAuth tokens | | ~/.openthread/imports/ | 0700 | untrusted archives | | ~/.openthread/imports/<uuid>.md | 0600 | imported posts | | ~/.openthread/audit.log | 0600 | mutating-op log | | /ot:export output files | 0644 | shareable archives |

Writes are atomic — every file is written as <path>.part and renamed into place, so a partial download or crash never leaves corrupt content at the final path.

/ot:export --out <path> is path-traversal guarded: relative paths must stay under CWD; absolute paths are rejected if they land inside /etc /dev /proc /sys /bin /sbin /usr /var /boot /lib /lib64.

Retries are bounded

Every network call goes through ot_curl_with_retry:

  • 3 attempts total, exponential backoff (1s, 2s).
  • 60s wall-clock cap — exceeds and emits a structured error.
  • 429 Retry-After is honored up to the 60s cap.
  • 4xx errors are terminal (they're caller intent, not transient).
  • 5xx errors are retryable within budget.

There is no infinite retry loop. If the server is down, you get one clean HTTP_ERROR and the command exits.

Concurrency

/ot:install and /ot:update hold a mkdir-based lock at ~/.claude/plugins/openthread-share/.lockdir/. A second concurrent invocation immediately gets LOCK_HELD instead of racing.

Core skills (/ot:share, /ot:search, etc.) do NOT take the lock — they run independently and are unaffected by update activity.

First use

Just run one of the four commands. No pre-setup, no install dance:

> /ot:share

The first /ot:share on a fresh machine prints one line (Signing you in to OpenThread...), opens a browser tab to complete OAuth, and then proceeds to publish. You never run /ot:auth login or /ot:install manually. Once signed in, every subsequent /ot:share is instant — cached session, no prompts, no network round-trip for auth.

The other three skills — /ot:search, /ot:import, /ot:export — work anonymously out of the box. They never trigger a browser unless you explicitly ask for private content, and even then only if you opt in.

The skills

Four daily skills — listed in the order you're most likely to use them. Each one works immediately after npm install with no pre-setup, no prior command, and no configuration step.

| # | Command | What it does | Auth | |---|---|---|---| | 1 | /ot:share | Publish the current Claude Code conversation | auto (browser on first use) | | 2 | /ot:search <query> | Search threads, comments, communities, users, skills | anonymous | | 3 | /ot:import <id> | Fetch a post: save to disk, inject into context, or install as a skill | anonymous (public), opt-in auth (private) | | 4 | /ot:export <id> | Archive a post as a local file or SKILL.md template | anonymous |

Four power-user skills — for troubleshooting and non-npm install flows. You do not need any of these during normal daily use.

| # | Command | When you'd need it | |---|---|---| | 5 | /ot:status | Something broke — see which layer (plugin, deps, auth, server) is unhappy | | 6 | /ot:auth login / logout / refresh / whoami | Manually manage the cached session | | 7 | /ot:update | Update the plugin from git/tarball (npm users use npm update -g) | | 8 | /ot:install | Bootstrap from a git tag or local path (npm users already have the plugin) |


Manual install

If you prefer not to use npm:

# Option A: via /ot:install from an existing Claude Code session
/ot:install

# Option B: manual clone
git clone https://github.com/openthread/openthread-share ~/.claude/plugins/openthread-share
openthread-claude install   # registers with Claude Code

Restart Claude Code. /ot:status will verify the install is healthy.

Uninstall

A dedicated uninstall command isn't shipped yet. To remove manually:

rm -rf ~/.claude/plugins/openthread-share
rm -rf ~/.claude/skills/ot-*
rm -rf ~/.claude/skills/share-thread ~/.claude/skills/search-threads \
       ~/.claude/skills/import-thread ~/.claude/skills/export-thread

Your session (.session.json) and local imports under ~/.openthread/imports/ live outside the plugin dir — delete them manually if desired.

License

MIT