JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q102493F
  • License MIT

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.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@openthread/claude-code-plugin) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    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