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

opencode-obsidian-export

v1.1.0

Published

Auto-save opencode sessions to Obsidian vault as markdown, with an agent-context summary (goal, highlights, files touched) and a manual export tool.

Readme

opencode-obsidian-export

npm version MIT License

Auto-save your opencode chat sessions as readable Markdown notes in your Obsidian vault — every time a session goes idle, it's synced automatically. Each note leads with an agent-readable summary (goal, highlights, files touched) so future agents can resume work without starting from scratch. Manual export on demand is supported too.

Why

opencode already lets you resume a session with opencode -s <session-id>, but there's no easy way to browse or search your past conversations alongside your other notes. This plugin writes each session to your Obsidian vault as a normal .md file, so it shows up in Obsidian's native search, graph view, etc.

Agent context (for resuming work)

On top of the raw transcript, each note now starts with an Agent Context block plus YAML frontmatter, so a future agent can @-load the note and pick up where the last one left off — without re-deriving everything from scratch:

  • Frontmatter: session_id, title, created/updated, agent, model, directory, a ready-to-run resume_cmd (opencode -s <id>), and tags: [opencode-session, agent-context].
  • Goal: the first substantive user message (the intent of the session).
  • 📝 Summary: an optional agent-written narrative (goal, what was done, decisions/gotchas, current state, next steps). See below.
  • Highlights: heuristically extracted lines tagged decision / gotcha / todo / fix.
  • Files touched: every file path referenced by read/edit/write tool calls.
  • Tools used and diff stat (+adds / -dels across N files).

The frontmatter, highlights, files, and tools are deterministic — no LLM call. The Summary is different: OpenCode has no built-in prose summary, so it's supplied by the agent (see next section).

The summary (agent-written)

export_to_obsidian takes an optional summary argument. When an agent runs the export, it writes a concise narrative — goal, what was done, key decisions/gotchas, current state, next steps — and passes it in; the plugin injects it as a ### 📝 Summary section at the top of the note. This is the part a future agent reads first to resume without re-reading the whole transcript.

On automatic session.idle exports (no agent authoring one) the summary is simply omitted and the deterministic block still applies. There's no hidden LLM call and no extra cost — the summary comes from whichever agent is already running the export.

Manual export

Exports still happen automatically on session.idle, but the plugin also registers a tool so you (or the agent) can export on demand.

It's not a slash-command or CLI keyword — it's a tool the agent calls. Just say something like:

"export this session to obsidian" "save this session to my vault" "sync this chat to obsidian"

The agent recognizes the intent and invokes the export_to_obsidian tool. It takes an optional sessionId (defaults to the current session), so you can also export another session by id.

You can confirm the tool is loaded by asking the agent to "list your available tools" — export_to_obsidian should appear alongside the built-ins.

Slash commands (recommended)

Plain English works, but commands are more reliable and repeatable than a prompt — they always tell the agent to write a summary first and then call the tool the same way. Two are provided:

| Command | What it writes | |---|---| | /export2obsidian-summary | A summary-only note (Agent Context block, no message dump) → <hostname> - <title> Summary.md | | /export2obsidian-transcript | The full transcript note (context + every message) → <hostname> - <title> Transcript.md |

Both make the agent author the narrative summary, and both accept an optional custom filename typed after the command (e.g. /export2obsidian-summary {date} - {title}; tokens {date} {hostname} {title} {sessionId} are expanded).

Install — one line each into ~/.config/opencode/commands/, then restart opencode:

curl -fsSL https://raw.githubusercontent.com/aditrachman/Opencode-Obsidian-Export/main/examples/commands/export2obsidian-summary.md    -o ~/.config/opencode/commands/export2obsidian-summary.md
curl -fsSL https://raw.githubusercontent.com/aditrachman/Opencode-Obsidian-Export/main/examples/commands/export2obsidian-transcript.md -o ~/.config/opencode/commands/export2obsidian-transcript.md

Restart opencode after adding command files — they're only picked up at startup.

Then type /export2obsidian-summary or /export2obsidian-transcript in the TUI. Under the hood each just invokes the export_to_obsidian tool — the tool stays the source of truth; the commands are convenience shortcuts.

Setup

1. Install (npm — recommended)

Add to your opencode.json (project root or ~/.config/opencode/opencode.json):

{
  "plugin": ["opencode-obsidian-export"]
}

Opencode auto-installs it with Bun. No manual npm install needed.

2. Set vault path

Tell the plugin where your Obsidian vault is:

Linux / macOS — tambah ke ~/.bashrc atau ~/.zshrc:

export OBSIDIAN_VAULT_PATH="/home/username/MyVault"

Windows (PowerShell) — tambah ke $PROFILE:

$env:OBSIDIAN_VAULT_PATH = "C:\Users\Username\MyVault"

3. Restart opencode

Done. Sessions will auto-save to <vault>/OpenCode-Logs/.


Manual install (no npm)

Alternatively, download index.js and place it in:

  • Linux / macOS: ~/.config/opencode/plugin/index.js
  • Windows: %APPDATA%\opencode\plugin\index.js or %USERPROFILE%\.config\opencode\plugin\index.js

Then install the optional dependency (for auto-fixing malformed JSON):

cd ~/.config/opencode/plugin
npm install jsonrepair

Custom labels

Set these env vars to customize the labels used in the generated markdown:

export OPENCODE_USER_NAME="You"            # 👤 user label (default: "You")
export OPENCODE_ASSISTANT_NAME="Assistant" # 🤖 assistant label (default: "Assistant")
export OPENCODE_SESSION_PREFIX="Session"   # 📝 title prefix (default: "Session")
export OPENCODE_LOG_SUBDIR="OpenCode-Logs" # 📁 subfolder in vault (default: "OpenCode-Logs")

Filename format

By default notes are named YYYY-MM-DD - <title>.md. Customize it with a token template:

# Tokens: {date} {hostname} {title} {sessionId}
export OPENCODE_FILENAME_FORMAT="{hostname} - {title}"   # e.g. "Rvs-Mac-Mini - Fix auth bug.md"

Empty tokens and their leftover separators are cleaned up automatically, and .md is always appended.

OPENCODE_FILENAME_FORMAT sets the base name. The plugin then appends a Summary or Transcript suffix depending on which kind of note is written, so both can live side by side for the same session — e.g. Rvs-Mac-Mini - Fix auth bug Summary.md and Rvs-Mac-Mini - Fix auth bug Transcript.md. To override the whole name for a one-off, pass a filename to the export_to_obsidian tool (or type it after a slash command).

{hostname} is your machine's short hostname (os.hostname() with the domain stripped) — handy when several machines sync into the same vault, so you can tell at a glance which box a session came from.

Multi-machine setup (~/.zshrc / ~/.bashrc)

If you sync one Obsidian vault across machines (e.g. via Obsidian Sync, iCloud, Syncthing, or LiveSync) and want each machine's sessions grouped and labelled by host, add this block to your shell rc file:

# opencode → Obsidian session export
export OBSIDIAN_VAULT_PATH="$HOME/Brain"                 # path to your vault
export OPENCODE_LOG_SUBDIR="_Shared_Systems/Opencode"    # subfolder inside the vault
export OPENCODE_FILENAME_FORMAT="{hostname} - {title}"   # prefix notes with the machine name

Then reload and restart opencode:

source ~/.zshrc   # or: source ~/.bashrc

Every machine writes into the same _Shared_Systems/Opencode/ folder, with filenames like Rvs-Mac-Mini - Fix auth bug.md and Work-Laptop - Deploy pipeline.md, so they never collide and are easy to filter in Obsidian search.

Tip: check your machine's hostname first with hostname -s (macOS/Linux) so you know what the {hostname} token will resolve to.

Example — for a Raya-chan character setup:

export OPENCODE_USER_NAME="Tuan Adit"
export OPENCODE_ASSISTANT_NAME="Raya-chan"
export OPENCODE_SESSION_PREFIX="Raya-chan session"
export OPENCODE_LOG_SUBDIR="RayaChan-Logs"

How it works

opencode's plugin system exposes a session.idle event, which fires whenever a session finishes responding and is waiting for the next input. This plugin listens for that event and:

  1. Runs opencode export <sessionID> to get the session as JSON
  2. Builds an Agent Context block (goal, highlights, files touched, tools, diff stat) + YAML frontmatter
  3. Extracts the actual conversation text (skips internal step/reasoning metadata)
  4. Writes it to your vault as YYYY-MM-DD - <title>.md

You can also trigger step 1–4 manually anytime via the export_to_obsidian tool.

Because the file is keyed by session ID (tracked via .session-index.json), re-syncing an ongoing conversation updates the same file instead of creating duplicates. Old files with different titles for the same session are cleaned up automatically.

Important notes

  • Security: Sessions are saved in plaintext. Don't paste secrets (API keys, passwords) into chats you plan to sync, or exclude the log folder from any cloud sync / git repo.
  • No TUI noise: Plugin logs go to .plugin.log inside the log folder, not to the terminal — won't interfere with opencode's UI or opencode export stdout.
  • Large sessions safe: maxBuffer is set to 100MB. Sessions with massive tool call outputs won't get truncated.
  • JSON repair: If the export JSON is malformed (edge case), the plugin tries to auto-fix it using jsonrepair before giving up and dumping a debug file.
  • This is plain-text history, not semantic search. If you want to ask your notes questions, that's a separate project (RAG over your vault) — out of scope here.

File structure

<vault>/
└── OpenCode-Logs/
    ├── YYYY-MM-DD - Session Title.md   ← session notes
    ├── .session-index.json             ← tracks session → file mapping
    └── .plugin.log                     ← internal plugin logs

Compatibility

  • ✅ Linux
  • ✅ macOS
  • ✅ Windows
  • ✅ opencode ≥ 0.x (plugin API)
  • ✅ Node ≥ 18

License

MIT — see LICENSE.