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

@everme/workbuddy

v0.7.10

Published

Native EverMe memory hooks for WorkBuddy.

Readme

@everme/workbuddy

Native EverMe memory hooks for WorkBuddy.

Installed by evercli plugin install workbuddy; you do not add it to WorkBuddy by hand.

evercli plugin install workbuddy
# then quit WorkBuddy completely (Cmd+Q) and reopen it

What it does

| Event | Mode | Behaviour | |---|---|---| | SessionStart | sync | injects the durable Profile into the new session | | UserPromptSubmit | sync | injects memories relevant to the prompt | | Stop | detached | uploads the turn that just finished |

Stop detaches itself so a per-turn upload never sits on a turn's critical path. Detaching is a stdout protocol, not a settings flag: the host parses the leading JSON object off the hook's stdout and detaches only on {"async":true,"asyncTimeout":N}. Its config validator accepts just type/command/timeout/matcher, so a definition-level async key is silently ignored — a hook relying on one stays synchronous for the whole upload.

SessionStart and UserPromptSubmit must NOT detach: their stdout is the context the host injects.

Why the desktop app runs hooks

The app is a shell around the bundled CodeBuddy engine, not an agent runtime of its own. It resolves cli/bin/codebuddy, speaks the agent-client protocol to it, and injects CODEBUDDY_CONFIG_DIR=~/.workbuddy. The engine's hook manager is Claude Code-shaped, so hooks registered in ~/.workbuddy/settings.json apply to app chat sessions.

~/.workbuddy/settings.json is the file to write — not the vendor-documented ~/.codebuddy/settings.json, which is the standalone terminal CLI's home and has its own session store.

Event census

Measured against WORKBUDDY_APP_VERSION 5.5.4 on 2026-09-10, with a probe on nine events across two sessions:

SessionStart 2 · UserPromptSubmit 2 · PreToolUse 15 · PostToolUse 14
Stop 2 · SubagentStart 0 · SubagentStop 0 · PreCompact 0 · SessionEnd 0
  • Stop fires once per turn (1:1 with UserPromptSubmit), which makes it the capture boundary.
  • SubagentStart / SubagentStop never fire: the app sets CODEBUDDY_DISABLE_FORK_SUBAGENT=1.
  • PreToolUse / PostToolUse are deliberately not registered. They would spawn a process per tool call to carry data the transcript already holds verbatim, and one PostToolUse payload reached 52 KB.

Host contract

  • stdin carries the hook input as JSON: session_id, transcript_path, cwd, hook_event_name, plus prompt on UserPromptSubmit and source on SessionStart.
  • stdout is parsed as hook output; the two context events return hookSpecificOutput.additionalContext.
  • exit 2 would block the operation and erase the user's prompt. Never used: every failure path exits 0 with one line on stderr.
  • command is a shell string, not an argv array, so the installer single-quotes every path. Only type: "command" handlers are accepted — the app sets CODEBUDDY_DISABLE_EXTENDED_PLUGIN_HOOKS=1, which makes the engine reject prompt / agent / http handlers.
  • The engine snapshots its hook config at startup, so changes need a full quit and reopen. Closing the window leaves the daemon running.

Transcripts

transcript_path points into ~/.workbuddy/projects/<cwd-slug>/<session-uuid>.jsonl, which the host appends to during the turn. Capture reads that file rather than reassembling a turn from event fields.

Session history there is a tree: resending or editing a prompt forks a new child off the same parent instead of rewriting the old record, so the file holds abandoned branches next to the live one. src/history.js walks back from the active leaf, which is the same reconstruction the Go cold-start scanner performs.

Both implementations are pinned to tests/fixtures/workbuddy-contract.expected.json — the Go test TestWorkBuddyGoldenMatchesRealtimeContract reads the fixtures in this directory — so a change to one that is not ported to the other fails on both sides.

One divergence is deliberate: the Go path runs content through Redact() and this one does not, matching the shipped @everme/qwenwork hook. Keep credential-shaped strings out of the shared fixture.

The native id is not a row id

WorkBuddy reuses one native id across sibling rows: an assistant message and the function_call rows it produced share it, and a single id can cover several calls. On one real machine that was 61 ids spanning more than one record type and 10 covering multiple calls.

A checkpoint keyed on the id alone therefore collapses siblings onto one entry. Since a tool-call message carries no top-level toolCallId, the first version of this adapter dropped 103 of 194 real tool calls from the upload while still sending all 193 results, leaving orphaned results the extractor cannot pair. The identity is [id, type, callId, role] — zero collisions across 557 real records — and adapter.checkpointKey() exposes it so the contract can be asserted directly.

Array-shaped tool results matter for the same reason: the built-in tools (present_files, show_widget, read_me, …) return an array of content blocks, which an object-or-string check silently turns into an empty string. That was 13 of 193 real results.

Files the installer writes

~/.workbuddy/settings.json   hooks.{SessionStart,UserPromptSubmit,Stop}
~/.workbuddy/everme.env      credentials (0600)
~/.workbuddy/mcp.json        mcpServers.everme-memory (on-demand recall)
~/.workbuddy/everme/         this bundle, staged

The MCP entry is the on-demand half: mem_search / mem_context as tools the model can call mid-turn. It is read-only, so it cannot double-write against the hook channel.

Uninstall

evercli plugin uninstall workbuddy

Manually: drop the everme-named handlers from hooks in ~/.workbuddy/settings.json (keep every other hook; remove an event key only if it becomes empty), drop mcpServers["everme-memory"] from ~/.workbuddy/mcp.json (keep every other server), then rm -rf ~/.workbuddy/everme ~/.workbuddy/everme.env and restart WorkBuddy.

Tests

npm test --workspace @everme/workbuddy

License

Apache-2.0