opencode-diane 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/LICENSE +21 -0
  3. package/README.md +206 -0
  4. package/WIKI.md +1430 -0
  5. package/dist/index.d.ts +28 -0
  6. package/dist/index.js +1632 -0
  7. package/dist/ingest/adaptive.d.ts +47 -0
  8. package/dist/ingest/adaptive.js +182 -0
  9. package/dist/ingest/code-health.d.ts +58 -0
  10. package/dist/ingest/code-health.js +202 -0
  11. package/dist/ingest/code-map.d.ts +71 -0
  12. package/dist/ingest/code-map.js +670 -0
  13. package/dist/ingest/cross-refs.d.ts +59 -0
  14. package/dist/ingest/cross-refs.js +1207 -0
  15. package/dist/ingest/docs.d.ts +49 -0
  16. package/dist/ingest/docs.js +325 -0
  17. package/dist/ingest/git.d.ts +77 -0
  18. package/dist/ingest/git.js +390 -0
  19. package/dist/ingest/live-session.d.ts +101 -0
  20. package/dist/ingest/live-session.js +173 -0
  21. package/dist/ingest/project-notes.d.ts +28 -0
  22. package/dist/ingest/project-notes.js +102 -0
  23. package/dist/ingest/project.d.ts +35 -0
  24. package/dist/ingest/project.js +430 -0
  25. package/dist/ingest/session-snapshot.d.ts +63 -0
  26. package/dist/ingest/session-snapshot.js +94 -0
  27. package/dist/ingest/sessions.d.ts +29 -0
  28. package/dist/ingest/sessions.js +164 -0
  29. package/dist/ingest/tables.d.ts +52 -0
  30. package/dist/ingest/tables.js +360 -0
  31. package/dist/mining/skill-miner.d.ts +53 -0
  32. package/dist/mining/skill-miner.js +234 -0
  33. package/dist/search/bm25.d.ts +81 -0
  34. package/dist/search/bm25.js +334 -0
  35. package/dist/search/e5-embedder.d.ts +30 -0
  36. package/dist/search/e5-embedder.js +91 -0
  37. package/dist/search/embed-pass.d.ts +26 -0
  38. package/dist/search/embed-pass.js +43 -0
  39. package/dist/search/embedder.d.ts +58 -0
  40. package/dist/search/embedder.js +85 -0
  41. package/dist/search/inverted-index.d.ts +51 -0
  42. package/dist/search/inverted-index.js +139 -0
  43. package/dist/search/ppr.d.ts +44 -0
  44. package/dist/search/ppr.js +118 -0
  45. package/dist/search/tokenize.d.ts +26 -0
  46. package/dist/search/tokenize.js +98 -0
  47. package/dist/store/eviction.d.ts +16 -0
  48. package/dist/store/eviction.js +37 -0
  49. package/dist/store/repository.d.ts +222 -0
  50. package/dist/store/repository.js +420 -0
  51. package/dist/store/sqlite-store.d.ts +89 -0
  52. package/dist/store/sqlite-store.js +252 -0
  53. package/dist/store/vector-store.d.ts +66 -0
  54. package/dist/store/vector-store.js +160 -0
  55. package/dist/types.d.ts +385 -0
  56. package/dist/types.js +9 -0
  57. package/dist/utils/file-log.d.ts +87 -0
  58. package/dist/utils/file-log.js +215 -0
  59. package/dist/utils/peer-detection.d.ts +45 -0
  60. package/dist/utils/peer-detection.js +90 -0
  61. package/dist/utils/shell.d.ts +43 -0
  62. package/dist/utils/shell.js +110 -0
  63. package/dist/utils/usage-skill.d.ts +42 -0
  64. package/dist/utils/usage-skill.js +129 -0
  65. package/dist/utils/xlsx.d.ts +36 -0
  66. package/dist/utils/xlsx.js +270 -0
  67. package/grammars/tree-sitter-c.wasm +0 -0
  68. package/grammars/tree-sitter-c_sharp.wasm +0 -0
  69. package/grammars/tree-sitter-cpp.wasm +0 -0
  70. package/grammars/tree-sitter-css.wasm +0 -0
  71. package/grammars/tree-sitter-go.wasm +0 -0
  72. package/grammars/tree-sitter-html.wasm +0 -0
  73. package/grammars/tree-sitter-java.wasm +0 -0
  74. package/grammars/tree-sitter-javascript.wasm +0 -0
  75. package/grammars/tree-sitter-json.wasm +0 -0
  76. package/grammars/tree-sitter-php.wasm +0 -0
  77. package/grammars/tree-sitter-python.wasm +0 -0
  78. package/grammars/tree-sitter-rust.wasm +0 -0
  79. package/grammars/tree-sitter-typescript.wasm +0 -0
  80. package/package.json +80 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,180 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
6
+ this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
7
+ on the understanding that the public surface for SemVer purposes is the
8
+ tool list (`memory_*`) and the documented `UserConfig` options.
9
+
10
+ ## [0.0.5] — 2026-05-22
11
+
12
+ ### Added
13
+ - **Live-session activity recording (`recordSessionActivity`, default
14
+ `true`).** The current session's file edits and bash commands are
15
+ now rolled up into a single memory under `session-trace` →
16
+ `live:${sessionId}`, upserted in place after each event. Lets the
17
+ current session recall what it has already touched without scanning
18
+ the OpenCode SDK, and pre-seeds the trace for the moment this
19
+ session becomes "past" to a successor. The memory is not pinned —
20
+ transient state should be evictable. JSONL logs are unchanged; this
21
+ is a recall surface, not an audit log. New module
22
+ `src/ingest/live-session.ts` (~160 lines), bounded by
23
+ `MAX_CONTENT_BYTES` and per-buffer caps so a long session can't
24
+ swell the store.
25
+ - **Bash file-change tracking (`bashFileTrackingMaxFiles`,
26
+ default `20`).** After every `bash` tool call the plugin runs
27
+ `git status --porcelain` and refreshes the code-map for each
28
+ touched file (modified or untracked, deletions skipped). Closes the
29
+ long-standing "bash-driven changes are a known gap" caveat —
30
+ `git checkout other-branch`, `npm run format`, `cargo fmt --all`,
31
+ and similar now keep the code map fresh. Capped to bound post-hook
32
+ latency on mass-checkout situations; raise or set to `0` to
33
+ disable.
34
+ - **Auto git re-ingest on HEAD movement (`autoReingestGitOnHeadChange`,
35
+ default `true`).** After every `bash` call the plugin polls
36
+ `git rev-parse HEAD`; if HEAD moved (pull / merge / rebase /
37
+ checkout / reset), it queues a background re-ingest of git
38
+ history. Idempotent — already-known commits are skipped via
39
+ `insertIfMissing`. Concurrent triggers coalesce (one re-ingest at a
40
+ time; further detections re-arm the flag for the next poll). Closes
41
+ the post-merge invisibility gap surfaced by the v0.0.4 verdict.
42
+ - **`memory_ingest_git` tool (the 10th).** Explicit on-demand
43
+ re-ingest of git history for cases the auto-detect can't cover
44
+ (a `git fetch` without merge that nonetheless brings new commits
45
+ via another mechanism). Returns a human-readable summary of new
46
+ commit / co-change / churn / recency memories added.
47
+ - New helpers in `src/utils/shell.ts`: `currentHead(cwd)` (returns
48
+ the HEAD SHA or null) and `changedFilesInWorktree(cwd)` (parses
49
+ `git status --porcelain` into a file list, handling renames,
50
+ deletions, and C-quoted paths). Both are non-throwing — they
51
+ return safe empty values on non-git directories or git failures.
52
+
53
+ ### Changed
54
+ - The tool count is now **ten** (was nine in v0.0.4). The new tool is
55
+ additive — existing tool semantics are unchanged.
56
+ - Live-session memories share the `session-trace` category with past
57
+ sessions, distinguished by subject prefix: `task:` / `trace:` for
58
+ past, `live:` for current.
59
+
60
+ ### Notes
61
+ - All three new behaviours default ON. Set the corresponding config
62
+ to `false` (or `0` for `bashFileTrackingMaxFiles`) to opt out. The
63
+ JSONL audit log captures the same events regardless.
64
+ - Test count: **674 assertions across 24 test suites** (up from
65
+ 641/23 in v0.0.4). New suite `tests/live-session.test.ts` adds
66
+ 33 assertions; two pre-existing plugin-test assertions and one
67
+ smoke-script assertion were updated from "nine tools" to "ten".
68
+
69
+ ## [0.0.4] — 2026-05-22
70
+
71
+ ### Added
72
+ - **Grammar-agnostic cross-reference ingester (`ingestCrossRefs`,
73
+ default `true`).** Discovers file→file edges for languages
74
+ tree-sitter doesn't cover (Pascal, Ruby, Perl, Elixir, Lua, R,
75
+ Haskell, Scala, Kotlin, Swift, Crystal, Nim, Tcl, OCaml, F#, Dart,
76
+ Erlang, Clojure, Elm, Zig, Ada, **plus Verilog, SystemVerilog,
77
+ VHDL, COBOL, Fortran (modern, .f90+), Solidity, D, Vim script,
78
+ Smalltalk, Racket/Scheme, Common Lisp, Modula-2**) and for
79
+ low-code DSLs (GitHub Actions, Docker Compose, k8s kustomize,
80
+ Terraform, Ansible, n8n-shaped JSON workflows, OpenAPI, Protocol
81
+ Buffers, Thrift, GraphQL). Uses **multi-signal corroboration** to
82
+ keep FP low: path-resolvable strings (filesystem-grounded; single
83
+ signal sufficient) and rare identifier references corroborated by
84
+ import-line context OR filename↔identifier coupling (lexical
85
+ matches alone are deliberately rejected). Three new import-line
86
+ patterns: Verilog backtick-include (`` `include "file.v" ``),
87
+ COBOL `COPY copybook.cpy.`, Vim `runtime path/file.vim`.
88
+ Per-extension comment-line skipping prevents Lisp `; alu` in
89
+ comments from spuriously coupling to `alu.v`. Each edge becomes a
90
+ memory under `xref:<from>→<to>`. 52 assertions in
91
+ `tests/cross-refs.test.ts` exercise the language + DSL matrix
92
+ including FP-control negatives.
93
+ - **Generic markdown ingestion (`ingestDocs`, default `true`).** Walks
94
+ `<root>/docs/` recursively and a fixed set of conventional root
95
+ docs (CHANGELOG, CONTRIBUTING, ARCHITECTURE, ROADMAP, TODO, NOTES,
96
+ SECURITY, HISTORY, GOVERNANCE, MAINTAINERS, AUTHORS,
97
+ CODE_OF_CONDUCT). Each H1/H2/H3 heading becomes a recallable
98
+ section pointer: `memory_recall { query: "installation" }` now
99
+ returns `docs/install.md:15 ## Installation` + first paragraph —
100
+ the agent gets a precise pointer it can hand to `read` without
101
+ grepping the docs tree. Headings inside fenced code blocks are
102
+ correctly ignored. Bounded walk (200 files, 50 headings/file,
103
+ 256 KB/file). Tests in `tests/docs-ingest.test.ts`.
104
+ - **Project-notes ingestion (`ingestProjectNotes`, default `true`).**
105
+ Indexes root-level agent-instruction files as project facts:
106
+ `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `COPILOT.md`,
107
+ `CONVENTIONS.md`, `.cursorrules`, `.windsurfrules`, `.clinerules`.
108
+ One memory per file (truncated to 6 KB) plus a directory-summary
109
+ memory listing what was found, so the agent learns the repo's
110
+ house rules in the first recall. Tests in
111
+ `tests/extra-ingesters.test.ts`.
112
+ - **Table-header ingestion (`ingestTableHeaders`, default `true`).**
113
+ Walks for `.csv`, `.tsv`, `.xlsx`, `.xls`, `.xlsm` files and
114
+ indexes *only the column headers* — `users.csv (CSV, 4 columns):
115
+ id, email, signup_date, plan_tier`; for spreadsheets, each sheet
116
+ becomes its own memory (`table:budget.xlsx#users`,
117
+ `table:budget.xlsx#events`). Row data is never loaded; even a 10 GB
118
+ CSV or a workbook with 1 M rows costs the same as a 10-row file.
119
+ RFC-4180-ish CSV parsing handles quoted fields with embedded
120
+ commas; single-column files / sheets and binary files are
121
+ rejected. XLSX support uses SheetJS, **lazy-imported only when a
122
+ spreadsheet is actually encountered** — projects with no
123
+ spreadsheets pay no module-load cost. SheetJS is invoked with
124
+ macros, formulas, and styles disabled (minimum surface). Tests
125
+ in `tests/extra-ingesters.test.ts`.
126
+
127
+ ### Changed
128
+ - **`enableCodeMap` now defaults to `true`.** The tree-sitter
129
+ signature map is built on first startup so the agent has the
130
+ structural shape of the codebase from the first session. Set to
131
+ `false` to disable (the ~10 MB grammars ship in the package
132
+ regardless).
133
+ - **Soft-force adoption.** A new `installUsageSkill` option (default
134
+ `true`) writes `<skillsOutputDir>/<prefix>using-memory/SKILL.md` on
135
+ first startup so OpenCode surfaces a "call `memory_recall` first"
136
+ instruction to the agent at session start. Written only when the
137
+ file does not already exist — user edits and user deletions both
138
+ survive every subsequent startup. Set `installUsageSkill: false` to
139
+ never write it.
140
+
141
+ ## [0.0.3] — Unreleased
142
+
143
+ First public preview release.
144
+
145
+ ### Added
146
+ - Nine `memory_*` tools (`recall`, `remember`, `snapshot`, `status`,
147
+ `code_map`, `outline`, `ingest_sessions`, `mine_skills`, `skill`).
148
+ - BM25 lexical recall with one-hop co-change boosting; opt-in
149
+ Personalized PageRank for multi-hop recall (`personalizedPageRank`).
150
+ - Tree-sitter code-map across 10 languages plus JSON/CSS/HTML
151
+ (`enableCodeMap`).
152
+ - Cross-lingual semantic search via a small multilingual e5 model
153
+ (`enableSemanticSearch`, optional `@huggingface/transformers`).
154
+ - Skill mining: cluster-derived `SKILL.md` files from past sessions.
155
+ - Structured JSONL logs under `$OPENCODE_DIANE_LOG_DIR` (or
156
+ `os.tmpdir()/opencode-diane/`) with `analyze-logs.py` reader.
157
+ - Plugin version flows from `package.json#version` to the
158
+ `plugin.active` event and `memory_status` output — single source of
159
+ truth, no second place to update.
160
+ - Defensive legacy-JSON → SQLite migration that never crashes plugin
161
+ startup even when another plugin is contending for the database.
162
+
163
+ ### Reliability
164
+ - `MemoryRepository.load` accepts an `onMigrationError` callback so a
165
+ failed legacy migration logs cleanly and the plugin continues with
166
+ an empty database rather than failing to start. Regression test in
167
+ `tests/store.test.ts`.
168
+ - Auto-detects coexisting plugins (`oh-my-opencode`/`oh-my-openagent`/
169
+ `oh-my-opencode-slim`, and any `caveman` packaging) by reading the
170
+ `plugin` array in `opencode.json`. When a peer is present and the
171
+ user hasn't overridden the relevant option, disables the
172
+ tool-output nudge hook (oh-my-opencode also rewrites tool output)
173
+ and prefixes mined-skill subdirectories with `diane-` (so skills
174
+ in the shared `.opencode/skills/` directory don't collide with the
175
+ peer's slugs). Standalone behaviour is unchanged. Tests in
176
+ `tests/peer-compat.test.ts`.
177
+
178
+ ### Coverage
179
+ - 460+ assertions across 16 suites; 91%+ line coverage; size ceiling
180
+ enforced in CI.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 opencode-diane contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,206 @@
1
+ # opencode-diane
2
+
3
+ [![npm](https://img.shields.io/npm/v/opencode-diane.svg)](https://www.npmjs.com/package/opencode-diane)
4
+ [![CI](https://github.com/two-coats-guaranteed/opencode-diane/actions/workflows/ci.yml/badge.svg)](https://github.com/two-coats-guaranteed/opencode-diane/actions/workflows/ci.yml)
5
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
6
+
7
+ A memory layer for [OpenCode](https://opencode.ai). It gives the
8
+ coding agent a persistent, searchable store of structural facts about
9
+ a repository, so it stops re-discovering the same things — with raw
10
+ `git log`, `grep`, and file reads — every single session.
11
+
12
+ Named for Diane in *Twin Peaks* — the recipient of Dale Cooper's
13
+ recorded case notes. The plugin works the same way: it keeps the
14
+ record of what your coding agent learns about a codebase.
15
+
16
+ ## TL;DR for a decision-maker
17
+
18
+ - **What it is.** A hierarchical, BM25-ranked memory layer for any git
19
+ repository. It pre-fills itself from git history, project files,
20
+ docs, agent-instruction files (AGENTS.md, CLAUDE.md, .cursorrules),
21
+ table column headers, and grammar-agnostic cross-file edges; the
22
+ agent reaches it through ten `memory_*` tools.
23
+ - **The problem it solves.** An agent re-greps and re-reads the same
24
+ files every session. One bounded `memory_recall` replaces many raw
25
+ discovery calls.
26
+ - **Token reduction.** 80–89 % measured *when a recall covers the
27
+ task* — a ceiling, not a promise; lower on terse-history, mature, or
28
+ tiny repos. The bundled `dry-run.mjs` gives *your* repo a GOOD /
29
+ MODERATE / LOW verdict before you rely on it.
30
+ - **Deterministic.** BM25 over a hand-built index — no embeddings, no
31
+ model, no API key, no GPU, no network. Reproducible and debuggable.
32
+ (One opt-in exception: semantic search — off by default — adds an
33
+ embedding model for cross-lingual recall. See below.)
34
+ - **Convention-free.** It never parses commit messages for meaning;
35
+ every signal is a physical fact (files touched, lines ±, co-change).
36
+ It behaves identically on a `wip` / `.` / `更新` history and a
37
+ pristine one.
38
+ - **Languages.** Code map covers 13 tree-sitter grammars. The
39
+ grammar-agnostic cross-reference ingester extends this to 30+
40
+ languages (Pascal, Ruby, Perl, Elixir, Verilog, VHDL, COBOL,
41
+ Fortran, Solidity, Smalltalk, Racket, Common Lisp, Vim script, and
42
+ more) plus low-code DSLs (GitHub Actions, k8s, Terraform, n8n).
43
+ - **What it costs.** ~1.6 MB packed, ~17 MB unpacked (includes
44
+ tree-sitter grammar `.wasm` files and SheetJS for spreadsheet
45
+ headers). A few hundred MB RAM for a large store. Dependencies:
46
+ `@opencode-ai/plugin`, `web-tree-sitter`, `xlsx`.
47
+ - **What it is not.** Not an LLM, not an unbounded archive (a
48
+ configurable disk budget, 50 MB by default, ages out least-used
49
+ facts), not a replacement for `AGENTS.md` (though we *read*
50
+ AGENTS.md and index its contents). Not a vector store by default —
51
+ lexical BM25 — though cross-lingual semantic search is available as
52
+ an explicit opt-in.
53
+ - **Maturity.** 674 assertions across 24 test suites, ~90 % line
54
+ coverage; verified against the documented plugin contract in 30+
55
+ languages and against live builds with oh-my-opencode and caveman
56
+ as coexisting plugins. Not yet run end-to-end inside a live OpenCode
57
+ *server* — see the WIKI.
58
+
59
+ **The full design — how the memory is structured, how retrieval works,
60
+ what happens without git, scaling numbers, how it compares to other
61
+ approaches, and every honest limitation — is in
62
+ [WIKI.md](./WIKI.md).** Start there with *Straight answers for a
63
+ decision-maker*.
64
+
65
+ ## The tools
66
+
67
+ | Tool | What it does |
68
+ |---|---|
69
+ | `memory_recall` | BM25 search over the store — co-change-boosted, token-budgeted, with optional `category` / `subject` filters. The recall-first entry point. |
70
+ | `memory_code_map` | Aider-style structural map: per-file signatures of functions/classes/types, ranked and budgeted. Needs `enableCodeMap`. |
71
+ | `memory_remember` | Store an explicit note for future turns. |
72
+ | `memory_snapshot` | Record this session's *understanding* — mental model, decisions, conventions — for a later or parallel session to resume from. |
73
+ | `memory_outline` | Counts per category — token-cheap orientation. |
74
+ | `memory_status` | Size, byte usage vs budget, last-ingest timestamps. |
75
+ | `memory_ingest_sessions` | Pull task + tool-trace summaries from past OpenCode sessions. |
76
+ | `memory_ingest_git` | Re-scan git history for new commits after a pull / merge / rebase. Idempotent — already-known commits are skipped. The plugin also auto-runs this in the background when it detects HEAD moved as a side effect of a `bash` call. |
77
+ | `memory_mine_skills` | Cluster memories by subject into `SKILL.md` files. Runs in the background. |
78
+ | `memory_skill` | List the mined skill files, or load one into the conversation — so a skill mined this session is usable now, no restart. |
79
+
80
+ ## Install
81
+
82
+ ```bash
83
+ npm install opencode-diane
84
+ ```
85
+
86
+ Then in `opencode.json`:
87
+
88
+ ```json
89
+ {
90
+ "$schema": "https://opencode.ai/config.json",
91
+ "plugin": ["opencode-diane"]
92
+ }
93
+ ```
94
+
95
+ Open OpenCode in any git repository, in any language. The plugin
96
+ loads, runs prefill in the background, registers all ten tools, and
97
+ the agent can use them immediately. If the directory is neither a git
98
+ repo nor has a recognised manifest, the plugin logs one idle line and
99
+ does nothing.
100
+
101
+ The optional Aider-style code map is **off by default** because its
102
+ tree-sitter grammars add ~16 MB to the install. To enable it, use the
103
+ `[name, options]` tuple form and restart OpenCode:
104
+
105
+ ```json
106
+ {
107
+ "plugin": [["opencode-diane", { "enableCodeMap": true }]]
108
+ }
109
+ ```
110
+
111
+ ### Install from a local clone
112
+
113
+ ```bash
114
+ git clone <repo-url> opencode-diane
115
+ cd opencode-diane
116
+ bun install # fetches @opencode-ai/plugin into ./node_modules
117
+ bun run build # compiles src/ -> dist/
118
+ ```
119
+
120
+ Then point `opencode.json` at the built file:
121
+
122
+ ```json
123
+ {
124
+ "plugin": ["file:///absolute/path/to/opencode-diane/dist/index.js"]
125
+ }
126
+ ```
127
+
128
+ `bun install` is required for the local form — OpenCode resolves
129
+ plugin imports through the module resolver, so
130
+ `node_modules/@opencode-ai/plugin` must sit next to `dist/`.
131
+
132
+ ## Configuration
133
+
134
+ Every setting is optional with a sensible default. To override, list
135
+ the plugin as a `[name, options]` tuple — OpenCode passes the options
136
+ object straight through, and bad or unknown keys are ignored so a
137
+ malformed config never breaks the plugin.
138
+
139
+ ```ts
140
+ interface UserConfig {
141
+ maxMemoryDiskMB?: number // default 50
142
+ autoIngestOnStartup?: boolean // default true
143
+ gitHistoryDepth?: number // default 500
144
+ forceActive?: boolean // default false
145
+ skillsOutputDir?: string // default ".opencode/skills"
146
+ skillMiningMinCluster?: number // default 3
147
+ ingestSessions?: boolean // default true
148
+ enableCodeMap?: boolean // default true (see WIKI: Code map)
149
+ installUsageSkill?: boolean // default true — write a using-memory skill on first startup
150
+ ingestDocs?: boolean // default true — index docs/ headings as section pointers
151
+ ingestProjectNotes?: boolean // default true — index AGENTS.md, CLAUDE.md, .cursorrules, …
152
+ ingestTableHeaders?: boolean // default true — index CSV/TSV/XLSX column headers
153
+ ingestCrossRefs?: boolean // default true — grammar-agnostic cross-file edge discovery
154
+ crossRefsRarityThreshold?: number // default 3 — max files a symbol can appear in to count
155
+ enableNudgeHook?: boolean // default true (see WIKI: Compatibility)
156
+ adaptive?: boolean // default true (see WIKI: Adaptive sizing)
157
+ enableSemanticSearch?: boolean // default false (see WIKI: Semantic search)
158
+ embeddingModel?: string // default "Xenova/multilingual-e5-small"
159
+ personalizedPageRank?: boolean // default false (co-change ranking; see WIKI)
160
+ recordSessionActivity?: boolean // default true — record this session's edits + bash as a rolling memory
161
+ bashFileTrackingMaxFiles?: number // default 20 — refresh code-map for files a bash call touched (0 = off)
162
+ autoReingestGitOnHeadChange?: boolean // default true — re-ingest git when bash moves HEAD (pull/merge/rebase)
163
+ }
164
+ ```
165
+
166
+ With `adaptive` on (the default), prefill measures one cheap signal —
167
+ commit count, or file count when there is no git — and scales the
168
+ history depth and code-map file cap to the repo's size. An explicit
169
+ value in your config always wins.
170
+
171
+ `maxMemoryDiskMB` is the disk budget for the memory store: once it is
172
+ exceeded, least-used memories are evicted (pinned ones never). The
173
+ default is 50 MB — generous enough that a realistic store (even on a
174
+ large repo, ~4–6 MB) never hits it, so eviction acts as a safety valve
175
+ rather than a routine clip. Note it also bounds RAM: the search index
176
+ is held in memory at roughly 70 MB of heap per 1 MB of budget *if
177
+ filled*, so on an unusually large monorepo, lower it to cap memory or
178
+ raise it for a deeper store. See *Performance* in the WIKI.
179
+
180
+ `enableSemanticSearch` (default **off**) adds opt-in cross-lingual
181
+ recall: with it on, the plugin also embeds memories with a small
182
+ multilingual e5 model and fuses vector similarity with the BM25
183
+ ranking, so a query in one language (Russian, Chinese, …) can retrieve
184
+ code and comments written in another. It needs the optional
185
+ `@huggingface/transformers` dependency (`bun add @huggingface/transformers`);
186
+ the model downloads on first use. When off — the default — no model is
187
+ downloaded, the dependency is never loaded, and retrieval is the
188
+ unchanged lexical path. See *Semantic search* in the WIKI.
189
+
190
+ ## Learn more
191
+
192
+ [WIKI.md](./WIKI.md) covers everything else, including:
193
+
194
+ - *Straight answers for a decision-maker* — the questions above, in depth
195
+ - *How the memory is structured* — the record shape and the hierarchy, with diagrams
196
+ - *The pillars* — retrieval, prefill, code-health, and the rest, with diagrams
197
+ - *How it compares* — versus embeddings, aider's repo-map, and `AGENTS.md`
198
+ - *Without git history* — what works, what doesn't, and why
199
+ - *Semantic search* — the opt-in cross-lingual embedding feature
200
+ - *Token savings* — what reduction to expect, and how it is measured
201
+ - *Performance* & *Scaling* — measured numbers, and the honest heap caveat
202
+ - *Code map*, *Session snapshots*, *Skill mining*, *Rich logs*, *Tests & CI*
203
+
204
+ ## License
205
+
206
+ MIT.