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

@qltk/mnemo

v0.5.9

Published

Persistent memory layer for opencode — auto recall/extract/dream, modeled on Claude Code's memory system. File-based, four types, MEMORY.md index + topic files. TypeScript.

Readme

@qltk/mnemo

Persistent memory layer for opencode — auto recall / extract / dream, modeled on Claude Code's memory system. File-based (Markdown), four types, project-scoped. Runs as a self-contained opencode plugin (fork-based, no external scheduler).

How it works

| Function | Mechanism | |---|---| | Recall | plugin experimental.chat.system.transform hook injects inject.md + global/project MEMORY.md indexes into the system prompt each session | | Extract (proactively record) | main session session.idle → fork a background agent running extract.md (scans transcript, writes topic files). Throttled: min 5 new messages + 30min interval | | Dream (consolidate) | per-slug 24h throttle → fork dream.md (merge / dedupe / prune drift / fix index). Night window (default 18:30–08:30) + backlog catches small projects that rarely idle | | Usage tracking (0.5.0+) | on each main-session idle, plugin observes assistant Read-tool calls (hard observation) → bumps usage_count / last_used on read topics. Dream prunes low-usage stale topics after a cold-start period | | Fork cleanup | fork sessions tagged via session.update(title); on their own session.idle they are auto-session.deleted. Tracked in-memory (runtime) + by title (survives restart, cleans orphans) | | Per-project scope | each session looks up its directory via session.get → derives a slug → memory isolated under projects/<slug>/ | | Auto permission | on load, detects if permission: allow is missing and auto-injects it into opencode.jsonc (backs up to .mnemo-backup). Restart once to activate |

Extract/Dream run on a free model by default (opencode/big-pickle); the main session's model is untouched.

Install

From npm (recommended for other machines)

// ~/.config/opencode/opencode.jsonc
{
  "plugin": ["@qltk/mnemo@^0.5.7"]
}

On first load, the plugin auto-injects "permission": "allow" into your global opencode.jsonc (with backup). Restart once to activate. No manual config editing needed.

Local development (file://)

{
  "plugin": ["file:///path/to/mnemo/src/index.ts"]
}

opencode's bun runtime loads .ts directly — no build step needed during development. Edit src/*.ts → restart opencode → test.

推荐配置(dream 换大 window 模型,直接复制)

dream 整理 memory 时 context 会累积(多 topic 项目可达 40 万+ token),免费模型 big-pickle 的 window 可能不够。推荐 dream 单独用大 window 模型(如 opencode-go/deepseek-v4-flash 384k),extract 保持免费 big-pickle。

openchamber「选项(JSON)」框opencode.jsonc options 直接复制:

{
  "forkModelDream": { "providerID": "opencode-go", "modelID": "deepseek-v4-flash" }
}

或 opencode.jsonc 完整形式:

{
  "plugin": [{
    "id": "@qltk/mnemo@^0.5.6",
    "options": {
      "forkModelDream": { "providerID": "opencode-go", "modelID": "deepseek-v4-flash" }
    }
  }]
}

保存重载即生效。extract 还用默认 big-pickle(免费),dream 用 deepseek-v4-flash(384k window,付费但便宜)。

Plugin options(0.5.6+,动态配置,优先于 env)

opencode.jsonc 用对象形式配 plugin,可在 options 里动态配置 model——改 options 重载即生效,不用 env 不用发版:

{
  "plugin": [{
    "id": "file:///home/liubola/my-own-dist/mnemo/src/index.ts",
    "options": {
      "forkModel": { "providerID": "opencode", "modelID": "big-pickle" },              // extract(context 小,免费够)
      "forkModelDream": { "providerID": "opencode-go", "modelID": "deepseek-v4-flash" }, // dream(context 大,384k window)
      "forkModelFallback": ["deepseek-v4-flash-free"]                                   // 主模型 free_tier_limit 兜底
    }
  }]
}

| option | 类型 | 说明 | |---|---|---| | forkModel | {providerID, modelID} | extract 模型 | | forkModelDream | {providerID, modelID} | dream 专用(context 大,换大 window 如 opencode-go/deepseek-v4-flash;默认同 forkModel) | | forkModelFallback | string[] | 主模型 free_tier_limit 时 fallback 序列 |

options 优先于 env(env 优先于默认)。

Configuration (env overrides)

所有配置通过环境变量覆盖——opencode 启动前 export,或写进 systemd 服务的 Environment=

Memory 位置

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_ROOT | ~/.config/opencode/memory | 记忆根目录。所有 topic 文件、MEMORY.md、.plugin.log、.state.json 都在这下面 | | OPENCODE_MEMORY_PROMPTS_DIR | <plugin>/../prompts | prompt 模板目录(inject/extract/dream.md)。自定义时指向别处 |

Fork agent(extract/dream 后台 agent)

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_FORK_MODEL_PROVIDER | opencode | fork agent 的 provider ID | | OPENCODE_MEMORY_FORK_MODEL_ID | big-pickle | fork agent 的 model ID(0.5.3 改回 big-pickle——dream 工具更干练 + 0.5.2 extract 改 create 后不再爆配额) | | OPENCODE_MEMORY_FORK_MODEL_FALLBACK | deepseek-v4-flash-free | 0.5.1+ 主模型 free_tier_limit 时的 fallback 序列(逗号分隔,"provider/model" 或 modelID) | | OPENCODE_MEMORY_FORK_STUCK_TIMEOUT_MS | 600000(10min) | 0.5.1+ fork session 卡 retry/failed 不 idle 的超时阈值,超过则查 status + 清理 + 触发 fallback | | OPENCODE_MEMORY_FORK_MODEL_DREAM_PROVIDER | opencode | 0.5.6+ dream 专用 provider(dream context 大,可换大 window) | | OPENCODE_MEMORY_FORK_MODEL_DREAM | big-pickle | 0.5.6+ dream 专用 modelID(默认同 forkModel;如 deepseek-v4-flash) |

fork agent 默认工具权限:read/grep/glob/bash/edit/write(硬编码于 config.ts,需改源码调整)。fork session 写 memory 到项目外需要 permission: allow——plugin 首次加载会自动注入到 opencode.jsonc(备份原文件到 .mnemo-backup),重启生效,无需手动配。

Extract 节流

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_EXTRACT_MIN_NEW_MESSAGES | 5 | 触发 extract 至少需要的新消息数。低于此 skip(消息累积不丢) | | OPENCODE_MEMORY_EXTRACT_MIN_INTERVAL_MS | 1800000(30min) | 两次 extract 最小间隔(毫秒)。小于此 skip | | OPENCODE_MEMORY_EXTRACT_CONTEXT_BEFORE | 6 | 0.5.2+ extract create 模式下,cursor 前滑动窗口条数(消解指代) |

两个条件同时满足才 extract。skip 时不推进游标,消息累积到下次。

Dream 调度(夜间窗口)

⚠️ 0.4.0 起默认启用夜间窗口(breaking 调度变更):dream 只在 18:30–08:30(跨午夜,配置时区)触发,白天工作时间不打扰。中国机器零配置即对中国时间。

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_DREAM_INTERVAL_MS | 86400000(24h) | 两次 dream 最小间隔(毫秒) | | OPENCODE_MEMORY_DREAM_WINDOW_START | 18:30 | 窗口起点(含),HH:MM | | OPENCODE_MEMORY_DREAM_WINDOW_END | 08:30 | 窗口终点(不含,可跨午夜),HH:MM | | OPENCODE_MEMORY_DREAM_TZ | 进程本地时区 | IANA 时区名,如 Asia/Shanghai / UTC |

半开区间 [start, end):18:30 当刻触发、08:30:00 起算白天(skip)。 关闭窗口(全天可触发,回到 0.3.x 行为):OPENCODE_MEMORY_DREAM_WINDOW_START=""。 非法值(25:99 / Foo/Bar 时区)→ 关闭窗口或回退本地时区并 warn。 时间窗 skip 时不写 lastDream 游标,每个后续 idle 重新检查,直到落入夜间窗口才触发。

Dream backlog(0.5.0+ 小项目消化)

per-slug 节流后活跃项目不再独占 dream 配额。但小项目夜间无会话 idle → 仍可能长期不 dream。backlog 机制:主 session idle 触发当前 slug dream 后,串行补跑积压 slug(全局 lock 串行)。

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_DREAM_BACKLOG_DAYS | 2 | 距上次 dream 超过 N 天的 slug 视为积压,触发补跑 | | OPENCODE_MEMORY_DREAM_BACKLOG_PER_IDLE | 1 | 每次 idle 最多补跑的 backlog slug 数(全局 lock 串行,实际并发上限 1) |

Prune 与 cold start(0.5.0+)

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_PRUNE_AGE_DAYS | 30 | dream prune 年龄硬阈值:mtime 超过 N 天 + usage_count ≤ 1 → 强 prune 候选 | | OPENCODE_MEMORY_COLD_START_DAYS | 14 | read-tracking 冷启动期:P0 上线后 N 天内 dream 跳过 usage-based prune(防老 topic 假低 usage 被误删) |

Topic 大小 / Log rotation(0.5.0+)

| env | default | 说明 | |---|---|---| | OPENCODE_MEMORY_TOPIC_SOFT_MAX_KB | 8 | 单 topic 文件软上限(KB),extract 超出应只留结论/拆分 | | OPENCODE_MEMORY_LOG_MAX_BYTES | 1048576(1MB) | .plugin.log 大小阈值,超出滚动到 .plugin.log.1(单代备份) |

示例

# extract 更积极(3 条 + 10min)
export OPENCODE_MEMORY_EXTRACT_MIN_NEW_MESSAGES=3
export OPENCODE_MEMORY_EXTRACT_MIN_INTERVAL_MS=600000

# 换 fork 模型(付费,抽取质量更高)
export OPENCODE_MEMORY_FORK_MODEL_ID=deepseek-chat

# 自定义 memory 目录
export OPENCODE_MEMORY_ROOT=/data/my-memory

# dream:锁中国时间 + 收窄窗口(仅深夜 23:00-06:00)
export OPENCODE_MEMORY_DREAM_TZ=Asia/Shanghai
export OPENCODE_MEMORY_DREAM_WINDOW_START=23:00
export OPENCODE_MEMORY_DREAM_WINDOW_END=06:00

# dream:关闭夜间窗口,全天 24h 节流即可触发(回到 0.3.x 行为)
export OPENCODE_MEMORY_DREAM_WINDOW_START=

设好后重启 opencode 生效。

Structure

src/                        TypeScript source (bun loads .ts directly in file:// mode)
├── index.ts                entry: exports { id, server } PluginModule
├── plugin.ts               memoryPlugin: system.transform + event + permission.ask + config hook
├── fork-orchestrator.ts    fork/create/prompt/cleanup + extract/dream throttle
├── config.ts               config seam (env overrides)
├── io.ts  slug.ts  prompt.ts  log.ts  ...
prompts/                    prompt templates (inject.md / extract.md / dream.md)
dist/                       compiled output (npm publish), gitignored

Memory on disk (~/.config/opencode/memory/, outside this repo):

MEMORY.md                   global index (user type, cross-project)
<topic>.md                  user type topic
projects/<slug>/            per-project
  MEMORY.md                 project index
  <topic>.md                project/feedback/reference type
.plugin.log                 debug log
.state.json                 dream/extract throttle state

Four types → scope

| type | scope | records | |---|---|---| | user | global | user role, cross-project preferences | | feedback | project | collaboration corrections (rule + reason + scope) | | project | project | background not derivable from code/git | | reference | project | external system links |

Design references

  • Modeled on Claude Code's memory system (file-based, four types, MEMORY.md index + topic files, extract/dream fork agents)
  • Project scoping borrowed from EverOs (<app>/<project> path-encoded scope)
  • No RAG — relevance via LLM-judge (inject index → agent scans titles → reads topic on demand), per Claude Code / Codex

Development

See AGENTS.md for development rules and CONTEXT.md for domain vocabulary.

Publish: npm install && npm run build && npm publish.