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

spiracha

v2.5.0

Published

Browse and expose local Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, MiniMax Code, and OpenCode conversation history through a local UI and stable data API.

Downloads

564

Readme

spiracha

license runtime

Spiracha is a Bun package with a local TanStack Start UI and a direct data client for browsing and exporting agent conversation history from Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, MiniMax Code, and OpenCode.

The legacy CLI, MCP server, and Codex plugin surfaces have been removed in the 2.0 hard cut. Spiracha now exposes the UI and a stable local data API; client-specific workflows such as review collection belong in the client that calls the API.

Quick Start

To run the packaged app:

bunx spiracha

Spiracha asks Vite for port 3000 and automatically uses the next available port when 3000 is occupied.

For repository development:

bun install
bun start

Open the local URL printed by Vite.

Spiracha requires Bun 1.3.14 or newer. Set PORT to request a different starting port, for example PORT=4100 bunx spiracha; the launcher uses the next available port if that one is occupied.

What It Does

  • Browse local conversations across Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, MiniMax Code, and OpenCode.
  • Search Codex projects from the app shell, with results delegated to the shareable /codex?q=... inventory filter.
  • Inspect source-specific detail pages with transcript, tool, reasoning, metadata, raw event, export, and delete flows where supported by the source. Codex thread detail includes optional live updates isolated from page-loading connections, a tool-focused activity view, recorded goals, and sandbox policy.
  • Export transcripts from the UI as Markdown, text, or zip bundles with source-specific commentary/final-answer filtering. The last submitted export choices persist across dialog openings; canceled drafts do not.
  • Export source-independent focused evidence: bounded failure/retry/tool episodes selected by a reusable JSON lens, with trace IDs and an omission ledger.
  • Expose a stable API for local clients that need normalized conversation metadata and message payloads.
  • Resolve Spiracha UI links and native source links into normalized { source, id } references for cross-thread context lookup.

Stable Data API

The API is served by the local UI server under /api/v1.

bunx spiracha

Common read endpoints:

GET  /api/v1/sources
GET  /api/v1/conversations?cwd=/absolute/project&include_messages=true
POST /api/v1/conversation-query
GET  /api/v1/conversations/:source/:id
GET  /api/v1/conversations/:source/:id/export
POST /api/v1/conversations/:source/:id/evidence
DELETE /api/v1/conversations/:source/:id
POST /api/v1/conversations/delete
POST /api/v1/conversations/export
GET  /api/v1/resolve?ref=<url-or-deeplink>

The default list selector is last_final_answer, which keeps fgh --collect style clients fast and small. Use message_selector=all when a client needs the full normalized thread. Claude Code and Kiro lists coalesce recognized compacted continuations under the parent conversation ID. Reading, exporting, generating focused evidence for, or deleting that parent operates on the complete lineage. A direct child-segment ID remains available as a physical-session lookup and affects only that segment.

Conversation lists use opaque keyset cursors ordered by update time, source, and conversation ID. Pass meta.next_cursor unchanged with the same filters to request the next page. The 2.0 offset cursor format is intentionally unsupported; clients must begin a fresh traversal after upgrading.

Workspace matching is lexical and performs no filesystem reads, so missing and network-mounted transcript paths cannot delay collection. Symlink aliases are intentionally not resolved; callers that require alias equivalence should pass the canonical workspace path recorded by the source.

Batch delete requires an explicit source and ID list. It returns deletedIds, missingIds, and a result for each requested ID, so partial success is represented in a 200 response body. Batch export also requires an explicit source and ID list, but is atomic: any missing ID returns an error instead of a partial archive.

Example:

curl 'http://localhost:3000/api/v1/conversations?cwd=/Users/me/workspace/fgh&include_messages=true'

Response envelope:

{
  "data": [
    {
      "source": "codex",
      "id": "019ecbfc-8a84-7421-ab3b-35653feb7896",
      "title": "Review thread",
      "workspacePath": "/Users/me/workspace/fgh",
      "messages": [
        {
          "role": "assistant",
          "phase": "final_answer",
          "text": "Final review result..."
        }
      ],
      "deepLinks": {
        "ui": "/threads/019ecbfc-8a84-7421-ab3b-35653feb7896",
        "native": "codex://threads/019ecbfc-8a84-7421-ab3b-35653feb7896",
        "spiracha": "spiracha://conversation/codex/019ecbfc-8a84-7421-ab3b-35653feb7896"
      }
    }
  ],
  "meta": {
    "has_next": false,
    "next_cursor": null
  }
}

For direct access from Bun scripts and CLIs, use the public client export. Local mode reads the source data without starting the TanStack server:

import { createConversationClient } from "spiracha/client";

const client = createConversationClient({ mode: "local" });
const page = await client.listConversations({
  cwd: process.cwd(),
  includeMessages: true,
  messageSelector: "last_final_answer",
});

Library and CLI use is quiet by default. Set SPIRACHA_TRANSCRIPT_LOAD_LOGS=1 or SPIRACHA_OPENCODE_DB_LOGS=1 only when diagnosing loader or OpenCode database timing.

Focused evidence is a deterministic, lossy Markdown export for qualitative DX analysis. It does not change full-transcript exports. See Focused evidence lenses for the complete lens schema, bounds, local and HTTP examples, UI workflow, privacy behavior, omission accounting, and performance limits.

Source Locations

| Source | Default location | Primary override | | --- | --- | --- | | Codex | shared Codex DB probe list | SPIRACHA_CODEX_DB | | Claude Code | ~/.claude/projects | SPIRACHA_CLAUDE_CODE_PROJECTS_DIR | | Cline | ~/.cline/data/sessions | SPIRACHA_CLINE_DATA_DIR | | Grok | ~/.grok/sessions | SPIRACHA_GROK_SESSIONS_DIR | | Kiro | ~/Library/Application Support/Kiro/User/globalStorage/kiro.kiroagent/workspace-sessions | SPIRACHA_KIRO_WORKSPACE_SESSIONS_DIR | | Qoder | ~/Library/Application Support/Qoder/User/globalStorage/state.vscdb and ~/Library/Application Support/Qoder/User/workspaceStorage | SPIRACHA_QODER_GLOBAL_STATE_DB, SPIRACHA_QODER_WORKSPACE_STORAGE_DIR | | Cursor | ~/Library/Application Support/Cursor/User on macOS | SPIRACHA_CURSOR_USER_DIR, SPIRACHA_CURSOR_PROJECTS_DIR | | Antigravity | ~/.gemini/antigravity-ide, ~/.gemini/antigravity-cli, and ~/.gemini/antigravity | SPIRACHA_ANTIGRAVITY_DIRS, SPIRACHA_ANTIGRAVITY_DIR | | MiniMax Code | ~/.minimax/v2/sessions and ~/.minimax/v2/sqlite/runtime-state.sqlite | SPIRACHA_MINIMAX_CODE_SESSIONS_DIR, SPIRACHA_MINIMAX_CODE_RUNTIME_DB_PATH | | OpenCode | ${XDG_DATA_HOME:-~/.local/share}/opencode/opencode.db | SPIRACHA_OPENCODE_DB | | UI exports | OS temp directory under spiracha-ui-exports | SPIRACHA_UI_EXPORT_DIR |

Qoder live ACP hydration

Qoder detail/export reads first use persisted state and CLI transcript files. When those do not contain assistant messages and Qoder is running, Spiracha can connect to Qoder's local JSON-RPC ACP Unix socket, issue initialize and session/load, and collect the streamed session updates. The default socket is the Qoder SharedClientCache/qoder.sock; override it with SPIRACHA_QODER_SOCKET_PATH (or the legacy environment spelling SPIRACHA_QODER_SOCKET). Connection failures and timeouts fall back to the persisted transcript rather than preventing the session from loading.

Antigravity transcript contract

When an Antigravity conversation has a live trajectory database, Spiracha treats it as the authoritative transcript and merges any generated JSONL-only events by step index. This preserves early reasoning plus paired command inputs, call IDs, working directories, exit codes, and complete outputs that may be absent from generated logs. The same merged data powers the detail page, stable API, and Markdown/text exports.

Markdown transcript exports identify this parser contract with transcript_schema: antigravity-transcript/v2. The UI parser retains complete tool output in its event data and export, but bounds the rendered preview to 20,000 characters so a single large operation result cannot dominate the detail page.

Encrypted Antigravity transcripts use the macOS Keychain item Antigravity Safe Storage / Antigravity Key and the Electron-compatible saltysalt PBKDF2 derivation. Keychain access is reacquired for each protected server request; the raw secret is not stored in process-global state or returned to the browser. Non-encrypted transcripts do not require Keychain access, and other platforms report decryption as unsupported.

Codex browser database compatibility

Codex browser reads target the codex-state-5-thread-browse-v1 compatibility profile. The threads table and its browse columns are required; missing tables, missing columns, or invalid decoded row values produce an actionable compatibility error instead of a guessed result. The thread_dynamic_tools, thread_goals, and thread_spawn_edges tables are optional and are read when present, so older databases without those tables remain browseable.

Multi-table thread browse reads run inside one SQLite deferred read transaction. This gives each browse result a consistent database snapshot while allowing Codex's normal writers to continue; it does not claim crash-level atomicity across the main database, attached history databases, rollout files, or the session index. Destructive DB changes commit before optional session-file and session-index cleanup, and cleanup results identify what was removed.

UI batch Codex exports use one batch browse pass and include a versioned spiracha-manifest.json in every successful archive. The manifest preserves requested ID order and records exported, missing, unreadable, and unstable entries. A batch succeeds when at least one selected thread is exportable; a single-thread export remains fail-fast. Active rollout files are copied to an attempt-local snapshot, checked by size, inode, and high-resolution timestamps, and retried once when they mutate during the copy.

Cursor SQLite access

Cursor reads use a retry-aware synchronous callback that opens a fresh read handle for each attempt and closes it before retrying. Cursor mutations use a same-database BEGIN IMMEDIATE transaction with the shared bounded SQLite retry policy and no stacked long busy_timeout. Missing writable databases fail closed instead of being created. Recovery and deletion keep cross-database compensation and filesystem cleanup outside retry callbacks; destructive discovery uses strict readers so exhausted locks cannot be mistaken for empty data. UI mutation entrypoints still require Cursor to be closed before writing because Cursor can rewrite its history on exit.

UI Routes

  • /codex and /codex/$project for Codex inventory and project threads.
  • /threads/$threadId for Codex thread detail.
  • /claude-code, /cline, /grok, /kiro, /qoder, /cursor, /antigravity, /minimax-code, and /opencode for source inventories.
  • Source detail routes include /claude-code-sessions/$sessionId, /cline-tasks/$taskId, /grok-sessions/$sessionId, /kiro-sessions/$sessionId, /qoder-sessions/$sessionId, /cursor-threads/$composerId, /antigravity-conversations/$conversationId, /minimax-code-sessions/$sessionId, and /opencode-sessions/$sessionId.
  • MiniMax Code workspace and detail pages support single, selected, and workspace-wide deletion. Deletion removes finalized session directories and authoritative runtime database rows while preserving generated workspace files and append-only observability logs.
  • /analytics for project-scoped Codex token totals, average and median thread size, archive counts, tool usage, model tokens, client sources, and reasoning-effort breakdowns.
  • /settings for transcript path conversion and username redaction. Export dialogs remember their own last submitted options.

Codex Live mode opens an SSE connection from the thread page. While connected, the server shares one bounded rollout-file monitor across every tab viewing that thread and releases it after the final client disconnects. The browser does not poll.

Development

bun test
bun run lint
bun run typecheck
bun run build
bun run coverage
bun start
bun run test:ui

bun run coverage enforces at least 90% line coverage independently for the root Bun suite and the UI Vitest suite, and reports function coverage and per-file hotspots for follow-up.

Run one root test file with bun test src/lib/shared.test.ts. Run one UI test file with bun run test:ui --run src/ui/components/export-dialog.vitest.tsx.

Spiracha has one application boundary: the stable API, server functions, browser route tree, and UI all live under the root package and resolve through one manifest and one dependency graph. Vite runs from the repository root with Bun because TanStack server functions import Bun-only modules such as bun:sqlite; Vitest uses its normal Node runtime.

TanStack Router generates src/ui/routeTree.gen.ts during development/build. Do not edit it manually; after adding or renaming route files, run bun run build (or start the dev server) and include the generated update.

Breaking Consequences

  • The only published bin entry is spiracha, and it only launches the local UI server.
  • No codex-chats, codex-chats-claude, or legacy export command remains.
  • No repo-local CLI export flow remains.
  • No standalone Claude or Cursor export CLI remains.
  • No MCP server or local Codex plugin remains.
  • Programmatic consumers should call the stable local HTTP API or import spiracha/client from Bun.
  • Normalized conversation messages now always include toolEvidence (null for non-tool messages); consumers that construct these DTOs must provide that explicit field.