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

@genspark/opencode-conversation-archiver

v0.3.2

Published

Archive OpenCode conversations as readable Markdown in a git repository

Readme

OpenCode conversation archiver

An OpenCode server plugin that archives every top-level conversation after each completed turn. It keeps one Markdown file per session in a git repository and records only user-visible text:

  • user text parts;
  • assistant text parts;
  • context-compaction boundaries.

Reasoning, tool calls, tool outputs, file URLs, synthetic text, ignored text, and child/subagent sessions are excluded.

Install

opencode plugin -g @genspark/[email protected]

Completely quit and restart OpenCode after installation. The first completed turn is archived locally under ~/opencode-conversations with no additional setup.

See the User Guide for Second Brain connection, sharing one remote repository with Claude Code, management commands, privacy details, upgrades, troubleshooting, and removal.

Install From Source

Build the package:

cd toolkits/opencode-conversation-archiver
npm install
npm run build

Register the built server entry in opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "./toolkits/opencode-conversation-archiver/dist/server.js"
  ]
}

The path is relative to the config file. Quit and restart OpenCode after adding or updating a plugin because configuration is loaded only at startup. To get the immediate /new title reset when installing from source, also register ./toolkits/opencode-conversation-archiver/dist/tui.js in the plugin array of tui.json. The opencode plugin installer registers both npm entry points automatically.

For package distribution, the package exposes OpenCode's native ./server entry and declares compatibility with OpenCode 1.17.18 through <2.

Default Behavior

  • Archive repo: ~/opencode-conversations
  • Runtime state: ~/.config/opencode/conversation-archiver/
  • Mode: auto
  • Trigger: canonical session.status event with status.type === "idle"
  • Auto mode: write, commit, and launch a detached push after every changed turn
  • Manual mode: write locally without commit or push
  • No remote: commits remain local and push failure never interrupts OpenCode

Terminal Notifications

The plugin emits OSC 9999 genterm-notify sequences (base64 JSON) to the controlling terminal, wrapped in tmux passthrough under tmux. Each payload carries the pane's tmux coordinates (tmux.{socket,session,windowId,windowIndex,windowName}) so GenTerminal can join tmux.session against its managed session record. Since 0.3.2 the TUI plugin owns title-changing notifications: it reports each distinct non-placeholder session.updated title and observes the native session.new command to immediately report the directory basename (body: "New conversation"), mirroring the cc plugin's /clear reset, while returning control to OpenCode's native handler. The server still reports each archived turn for inbox, activity, and unread tracking, but uses a dedicated <session-id>:idle source ID and the non-renaming OpenCode placeholder so a delayed old archive cannot restore an old title after /new. The command keeps OpenCode's native command-palette and /new//clear slash metadata. OPENCODE_ARCHIVE_NO_NOTIFY=1 disables all notifications; OPENCODE_ARCHIVE_NOTIFY_TTY=<file> redirects the raw sequences to a file (the seam the tests use).

The server event hook owns a per-session archive queue because OpenCode intentionally does not await plugin event callbacks. The TUI owns one ordered notification queue so /new and subsequent model titles cannot reorder. Both entry points drain their pending work during a clean shutdown. Git and tmux commands use asynchronous child processes so archive work does not block OpenCode's event loop.

Management Tools

The plugin exposes these native tools:

| Tool | Purpose | | --- | --- | | conversation_archive_status | Mode, repo, redacted remote, commits, pending changes | | conversation_archive_doctor | Read-only dependency, repo, remote-auth, and activity diagnosis | | conversation_archive_current | Archive the current live session immediately | | conversation_archive_backfill | Archive all top-level sessions visible in the current OpenCode project |

Users can ask OpenCode to invoke these tools naturally, for example: "diagnose my conversation archive". The two write tools request explicit permission. Credential-bearing and repository-management operations are CLI-only so their arguments never enter an LLM-visible conversation or tool call.

OpenCode 1.17.18 does not expose a direct, no-LLM server slash-command handler. Markdown commands always enter the prompt pipeline and command.execute.before cannot short-circuit it. For deterministic automation, use the bundled CLI:

opencode-conversation-archiver status
opencode-conversation-archiver doctor
opencode-conversation-archiver manual
opencode-conversation-archiver auto
opencode-conversation-archiver upload
opencode-conversation-archiver repo ~/Documents/opencode-conversations
opencode-conversation-archiver connect '<sb-connect-link>'

backfill and current remain live tools because they require the injected OpenCode SDK and current session identity.

Second Brain

The CLI connect supports:

  1. A one-time .../sb-connect/<code> URL.
  2. No arguments, using GSK_API_KEY or the credential created by gsk login.
  3. An explicit HTTP(S) git remote and token.

The git credential is stored at ~/.config/opencode/conversation-archiver/git-credentials with mode 0600, outside the archive repository. The remote URL shown by status, doctor, and logs is credential-redacted. Connected archives are confined to the opencode/ subdirectory by default with sparse checkout.

Configuration

Runtime configuration:

{
  "mode": "auto",
  "repo": "/home/you/opencode-conversations",
  "subdir": "opencode"
}

Environment overrides:

  • OPENCODE_ARCHIVE_MODE
  • OPENCODE_ARCHIVE_REPO
  • OPENCODE_ARCHIVE_NO_NOTIFY

For isolated tests or embedded installations, pass appDir as plugin options:

{
  "plugin": [
    [
      "@genspark/opencode-conversation-archiver",
      { "appDir": "/custom/runtime-state" }
    ]
  ]
}

Preservation Guarantees

  • Message and compaction part IDs make overlapping/repeated idle events idempotent.
  • Cumulative text for an existing message ID can grow without duplicating a turn.
  • Session state is append-only and outside the git repo.
  • Title changes rename the archive while preserving git history where possible.
  • A collision index prevents one session from overwriting another.
  • A never-shrink guard diverts to a suffixed file if disk content is richer than local state, preserving both copies instead of dropping turns.
  • Archive and push operations use cross-process lock directories.
  • Remote pushes serialize, pull with rebase, and abort a failed in-progress rebase.

Development

npm test
npm run typecheck
npm run build
npm pack --dry-run

Local End-to-End Verification

The release was verified against a real local OpenCode 1.17.18 process, not only mocked SDK tests. An isolated opencode run session using Claude Haiku completed with ARCHIVER_E2E_OK; the plugin then created a titled Markdown archive containing one user and one assistant turn and committed it to the isolated archive git repository. The temporary plugin config and archive paths were supplied through OPENCODE_CONFIG_CONTENT, appDir, and OPENCODE_ARCHIVE_REPO, so the normal OpenCode configuration and archive were not modified.