a64ea2acb3
A durable memory layer for OpenCode. Structure:
ROOT.md total plan: goals, hard rules, directory registry,
and a scenario -> file routing table
<category>/
index.md one line per file, COMPILED from frontmatter
<slug>.md the memory itself
Two roots, same shape: <config>/memory/ (global) and
<project canonical>/.memory/ (project). Project wins on conflict; global
hard rules stay resident everywhere.
Why a plugin rather than a skill that tells the model to read a folder:
model-driven retrieval is unreliable — the model forgets, reads half the
files, or reads the wrong ones. Markdown is the human-facing format; the
plugin is the engine that parses, scores, and injects.
Measured, not assumed: FTS5's two built-in tokenizers both fail on this
corpus. On SQLite 3.53.4 with "部署脚本用 pnpm 而不是 npm...": unicode61
emits 7 terms for the whole sentence and matches 0 hits for "部署";
trigram needs >= 3 characters and also returns 0 for that two-character
word. So tokenization happens in the plugin (CJK bigrams, latin words)
and no SQL index is used — a thousand memories are fine to scan.
index.md and ROOT's two tables are compiled, never hand-edited: a
hand-maintained index drifts, a generated one cannot. Hit counters live
in .state.json so cross-device sync does not conflict on every recall.
Tools are named recall/remember/forget/inspect rather than
write/read/status: generic names were observed shadowing the harness's
own built-in tools.
44 lines
1.6 KiB
Plaintext
44 lines
1.6 KiB
Plaintext
# Version only the skills and plugins trees.
|
|
#
|
|
# This directory is the OpenCode config root. OpenCode scans exactly two
|
|
# subdirectories for content:
|
|
#
|
|
# ~/.config/opencode/skills/ -> agent skills
|
|
# ~/.config/opencode/plugins/ -> server plugins (auto-discovered)
|
|
# ~/.config/opencode/memory/ -> memory store written by the memory plugin
|
|
#
|
|
# A .git directory inside either of those gets picked up as a plugin and fails
|
|
# to load, so the repository lives one level up, here, and everything that is
|
|
# not skills/ or plugins/ is ignored.
|
|
#
|
|
# Ignore every top-level entry, then re-admit only the two content trees and
|
|
# this file. A bare /* is not enough: git will not descend into an ignored
|
|
# directory, so the un-ignore rules are required.
|
|
|
|
/*
|
|
!/skills/
|
|
!/plugins/
|
|
!/memory/
|
|
!/.gitignore
|
|
|
|
# Per-memory hit counters. Derived data: regenerating it costs one recall, and
|
|
# committing it would rewrite the file on every retrieval and create merge
|
|
# conflicts across devices.
|
|
memory/**/.state.json
|
|
|
|
# UTF-8 shell launcher (see https://www.xsinfo.vip/windows/01-opencode-utf8.html).
|
|
# Portable: it only calls chcp and pwsh.exe from PATH, so it is safe to share.
|
|
!/pwsh.cmd
|
|
|
|
# opencode.json is intentionally NOT tracked: its "shell" field holds an absolute
|
|
# per-user Windows path (C:\Users\<name>\...), which breaks OpenCode on Linux/macOS.
|
|
# Each machine keeps its own opencode.json and points "shell" at its own pwsh.cmd.
|
|
|
|
# npm manifest for the sqlite plugin's better-sqlite3 dependency; without it the
|
|
# plugin fails to load with "Cannot find package 'better-sqlite3'".
|
|
!/package.json
|
|
|
|
# Belt and braces, in case a path is ever added from the parent side.
|
|
node_modules/
|
|
*.log
|