@openviking/opencode-plugin 2026.9.10 → 2026.9.21-1

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.
package/INSTALL-ZH.md CHANGED
@@ -49,6 +49,7 @@ curl http://localhost:1933/health
49
49
  在仓库根目录执行:
50
50
 
51
51
  ```bash
52
+ node examples/memory-plugin-shared/sync.mjs
52
53
  mkdir -p ~/.config/opencode/plugins/openviking
53
54
  cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
54
55
  cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
@@ -56,6 +57,8 @@ cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
56
57
  cp -r examples/opencode-plugin/servers ~/.config/opencode/plugins/openviking/
57
58
  ```
58
59
 
60
+ `sync.mjs` 会生成 `lib/shared/`,插件和 MCP 代理都从这里 import 共享模块。这个目录不在 git 里,所以复制前要先运行;之后每次 `git pull` 也要重新运行再复制。
61
+
59
62
  安装后结构应类似:
60
63
 
61
64
  ```text
@@ -81,37 +84,44 @@ export { OpenVikingPlugin, default } from "./openviking/index.mjs"
81
84
 
82
85
  ## 配置
83
86
 
84
- 创建用户级配置文件:
87
+ 行为旋钮写在共享的客户端配置文件里:
85
88
 
86
89
  ```bash
87
- ~/.config/opencode/openviking-config.json
90
+ ~/.openviking/ovcli.conf
88
91
  ```
89
92
 
90
93
  示例配置:
91
94
 
92
95
  ```json
93
96
  {
94
- "enabled": true,
95
- "mcp": { "enabled": true },
96
- "timeoutMs": 30000,
97
- "repoContext": { "enabled": true, "cacheTtlMs": 60000 },
98
- "autoRecall": {
99
- "enabled": true,
100
- "limit": 6,
101
- "scoreThreshold": 0.35,
102
- "maxContentChars": 500,
103
- "preferAbstract": true,
104
- "tokenBudget": 2000,
105
- "minQueryLength": 3
106
- },
107
- "commitTokenThreshold": 20000,
108
- "commitKeepRecentCount": 10,
109
- "profileTokenBudget": 10000,
110
- "resumeContextBudget": 32000
97
+ "url": "http://127.0.0.1:1933",
98
+ "api_key": "your-api-key-here",
99
+ "plugin": {
100
+ "recallLimit": 6,
101
+ "opencode": {
102
+ "enabled": true,
103
+ "mcpEnabled": true,
104
+ "timeoutMs": 30000,
105
+ "repoContext": true,
106
+ "repoContextCacheTtlMs": 60000,
107
+ "autoRecall": true,
108
+ "scoreThreshold": 0.35,
109
+ "recallMaxContentChars": 500,
110
+ "recallPreferAbstract": true,
111
+ "recallTokenBudget": 2000,
112
+ "minQueryLength": 3,
113
+ "commitTokenThreshold": 20000,
114
+ "commitKeepRecentCount": 10,
115
+ "profileTokenBudget": 10000,
116
+ "resumeContextBudget": 32000
117
+ }
118
+ }
111
119
  }
112
120
  ```
113
121
 
114
- `autoRecall.limit` 是遗留的配额缩放输入,不是最终结果上限。显式设置为
122
+ `plugin` 里的键对所有 harness 生效;`plugin.opencode` 里的键只对本插件生效,并覆盖前者。解析顺序是 `OPENVIKING_*` 环境变量 → 工作区的 `.openviking/config.json`、`.openviking/config.local.json` 和本机 registry 条目 → `plugin.opencode` → `plugin` → 内置默认值。每个旋钮的类型、默认值、取值范围、环境变量名和兼容的旧拼写都声明在 [`examples/memory-plugin-shared/lib/config-schema.mjs`](../memory-plugin-shared/lib/config-schema.mjs)。
123
+
124
+ `recallLimit` 是遗留的配额缩放输入,不是最终结果上限。显式设置为
115
125
  1 到 5 时,有效总配额仍为 6,因为六个 coding 分类会各保留一个检索槽位。
116
126
 
117
127
  推荐通过环境变量提供 API Key,而不是写入配置文件:
@@ -121,15 +131,15 @@ export OPENVIKING_API_KEY="your-api-key-here"
121
131
  ```
122
132
 
123
133
  API key 会从环境变量或 `~/.openviking/ovcli.conf` 读取,并由 hooks 和 MCP proxy 作为 `Authorization: Bearer ...` 发送。`account` 和 `user` 是 trusted mode
124
- 身份头,会作为 `X-OpenViking-Account`、`X-OpenViking-User` 发送;使用
125
- user/admin API key 的 API_KEY mode 时应留空。
134
+ 身份头,会作为 `X-OpenViking-Account`、`X-OpenViking-User` 发送;`api_key`
135
+ 模式的服务端从 key 里取身份,插件在那里不发这两个头。
126
136
  `peerId` 会作为 `X-OpenViking-Actor-Peer` 用于数据面的 memory/resource 请求;捕获 session message 时仍写入 body `peer_id`。需要 peer 维度路由时请显式配置。
127
137
 
128
138
  `OPENVIKING_API_KEY`、`OPENVIKING_ACCOUNT`、`OPENVIKING_USER`、
129
139
  `OPENVIKING_PEER_ID`
130
- 优先级高于 `openviking-config.json` 里的同名配置。
140
+ 优先级高于 `ovcli.conf` 里的同名配置。
131
141
 
132
- 高级场景可以用 `OPENVIKING_PLUGIN_CONFIG` 指向其他配置文件路径。
142
+ 高级场景可以用 `OPENVIKING_CLI_CONFIG_FILE` 指向其他路径的 `ovcli.conf`。
133
143
 
134
144
  ### 仅 Hooks 模式
135
145
 
@@ -137,7 +147,9 @@ user/admin API key 的 API_KEY mode 时应留空。
137
147
 
138
148
  ```json
139
149
  {
140
- "mcp": { "enabled": false }
150
+ "plugin": {
151
+ "opencode": { "mcpEnabled": false }
152
+ }
141
153
  }
142
154
  ```
143
155
 
@@ -197,6 +209,7 @@ curl http://localhost:1933/health
197
209
  - 探索目录结构用 `openviking_list`
198
210
  - 删除前必须先获得用户明确确认,再调用 `openviking_forget`
199
211
  - 如果 agent 误用 OpenCode 本地 `read`、`glob`、`grep` 工具访问 `viking://` URI,插件会阻止这次本地文件系统调用,并提示改用 MCP 工具。
212
+ - `bash` 命令里带 `viking://` URI 时照常执行,插件会在输出末尾附一段提示,建议改用 MCP 工具;URI 本来就是命令参数时,agent 可以忽略这段提示。
200
213
 
201
214
  ## `openviking_add_resource` 本地文件
202
215
 
@@ -229,7 +242,7 @@ openviking_add_resource(path="file:///home/alice/project/notes.md", description=
229
242
  - `openviking-memory.log`
230
243
  - `openviking-session-state.json`
231
244
 
232
- 可以通过配置里的 `runtime.dataDir` 修改这个目录。
245
+ 可以通过 `plugin.opencode` 里的 `dataDir` 修改这个目录。
233
246
 
234
247
  这些是本地运行时文件,不建议提交到版本库。
235
248
 
@@ -238,7 +251,8 @@ openviking_add_resource(path="file:///home/alice/project/notes.md", description=
238
251
  | 问题 | 排查方向 |
239
252
  |------|----------|
240
253
  | 插件没有加载 | package 安装检查 `~/.config/opencode/opencode.json` 是否包含 `@openviking/opencode-plugin`;源码安装检查 `~/.config/opencode/plugins/openviking.js` 是否存在 |
241
- | MCP tools 连到了错误的 server | 检查 `~/.openviking/ovcli.conf`,或用 `OPENVIKING_*` 环境变量 / `OPENVIKING_PLUGIN_CONFIG` 指向正确配置 |
254
+ | 加载时报找不到 `lib/shared/*.mjs` | 源码复制前没有运行 `sync.mjs`。在仓库根目录运行 `node examples/memory-plugin-shared/sync.mjs` 后重新复制 `lib/` |
255
+ | MCP tools 连到了错误的 server | 检查 `~/.openviking/ovcli.conf`,或用 `OPENVIKING_*` 环境变量 / `OPENVIKING_CLI_CONFIG_FILE` 指向正确配置 |
242
256
  | OpenViking 返回 401 / 403 | 检查 `OPENVIKING_API_KEY`;trusted-mode 部署还要检查 `OPENVIKING_ACCOUNT` 和 `OPENVIKING_USER` |
243
- | recall 为空 | 确认 OpenViking 中已有 memories/resources,并且 `autoRecall.enabled` 为 `true` |
257
+ | recall 为空 | 确认 OpenViking 中已有 memories/resources,并且 `autoRecall` 为 `true` |
244
258
  | 本地 `openviking_add_resource` 失败 | 传入文件路径而不是目录;目前还不支持自动上传本地目录 |
package/INSTALL.md CHANGED
@@ -49,6 +49,7 @@ Use this method for development, debugging, or PR testing. OpenCode's recommende
49
49
  Run the following commands from the repository root:
50
50
 
51
51
  ```bash
52
+ node examples/memory-plugin-shared/sync.mjs
52
53
  mkdir -p ~/.config/opencode/plugins/openviking
53
54
  cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
54
55
  cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
@@ -56,6 +57,8 @@ cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
56
57
  cp -r examples/opencode-plugin/servers ~/.config/opencode/plugins/openviking/
57
58
  ```
58
59
 
60
+ `sync.mjs` generates `lib/shared/`, the shared modules the plugin and its MCP proxy import. That directory is not in git, so run it before copying, and again after every `git pull`.
61
+
59
62
  After installation, the layout should look like this:
60
63
 
61
64
  ```text
@@ -81,37 +84,44 @@ If you install through an npm package, you can also use `examples/opencode-plugi
81
84
 
82
85
  ## Configuration
83
86
 
84
- Create the user-level configuration file:
87
+ Behaviour knobs live in the shared client configuration file:
85
88
 
86
89
  ```bash
87
- ~/.config/opencode/openviking-config.json
90
+ ~/.openviking/ovcli.conf
88
91
  ```
89
92
 
90
93
  Example configuration:
91
94
 
92
95
  ```json
93
96
  {
94
- "enabled": true,
95
- "mcp": { "enabled": true },
96
- "timeoutMs": 30000,
97
- "repoContext": { "enabled": true, "cacheTtlMs": 60000 },
98
- "autoRecall": {
99
- "enabled": true,
100
- "limit": 6,
101
- "scoreThreshold": 0.35,
102
- "maxContentChars": 500,
103
- "preferAbstract": true,
104
- "tokenBudget": 2000,
105
- "minQueryLength": 3
106
- },
107
- "commitTokenThreshold": 20000,
108
- "commitKeepRecentCount": 10,
109
- "profileTokenBudget": 10000,
110
- "resumeContextBudget": 32000
97
+ "url": "http://127.0.0.1:1933",
98
+ "api_key": "your-api-key-here",
99
+ "plugin": {
100
+ "recallLimit": 6,
101
+ "opencode": {
102
+ "enabled": true,
103
+ "mcpEnabled": true,
104
+ "timeoutMs": 30000,
105
+ "repoContext": true,
106
+ "repoContextCacheTtlMs": 60000,
107
+ "autoRecall": true,
108
+ "scoreThreshold": 0.35,
109
+ "recallMaxContentChars": 500,
110
+ "recallPreferAbstract": true,
111
+ "recallTokenBudget": 2000,
112
+ "minQueryLength": 3,
113
+ "commitTokenThreshold": 20000,
114
+ "commitKeepRecentCount": 10,
115
+ "profileTokenBudget": 10000,
116
+ "resumeContextBudget": 32000
117
+ }
118
+ }
111
119
  }
112
120
  ```
113
121
 
114
- `autoRecall.limit` is a legacy quota-scaling input, not a final result cap.
122
+ Keys in `plugin` apply to every harness; keys in `plugin.opencode` apply to this one and override them. Resolution is `OPENVIKING_*` environment variables → the workspace's `.openviking/config.json`, `.openviking/config.local.json` and machine registry entry → `plugin.opencode` → `plugin` → built-in defaults. Every knob, with its type, default, range, environment variable and accepted older spellings, is declared in [`examples/memory-plugin-shared/lib/config-schema.mjs`](../memory-plugin-shared/lib/config-schema.mjs).
123
+
124
+ `recallLimit` is a legacy quota-scaling input, not a final result cap.
115
125
  Explicit values from 1 through 5 produce an effective total quota of 6 because
116
126
  each coding category keeps one retrieval slot.
117
127
 
@@ -121,11 +131,11 @@ It is recommended to provide the API key through an environment variable instead
121
131
  export OPENVIKING_API_KEY="your-api-key-here"
122
132
  ```
123
133
 
124
- API keys are resolved from environment variables or `~/.openviking/ovcli.conf` and sent as `Authorization: Bearer ...` by both hooks and the MCP proxy. `account` and `user` are trusted-mode identity headers sent as `X-OpenViking-Account` and `X-OpenViking-User`; leave them empty when using API-key mode with user/admin API keys. `peerId` is sent as `X-OpenViking-Actor-Peer` on data-plane memory/resource requests; captured session messages store it as body `peer_id`.
134
+ API keys are resolved from environment variables or `~/.openviking/ovcli.conf` and sent as `Authorization: Bearer ...` by both hooks and the MCP proxy. `account` and `user` are trusted-mode identity headers sent as `X-OpenViking-Account` and `X-OpenViking-User`; an `api_key` server reads both out of the key, so the plugin withholds them there. `peerId` is sent as `X-OpenViking-Actor-Peer` on data-plane memory/resource requests; captured session messages store it as body `peer_id`.
125
135
 
126
- `OPENVIKING_API_KEY`, `OPENVIKING_ACCOUNT`, `OPENVIKING_USER`, and `OPENVIKING_PEER_ID` take precedence over the corresponding values in `openviking-config.json`.
136
+ `OPENVIKING_API_KEY`, `OPENVIKING_ACCOUNT`, `OPENVIKING_USER`, and `OPENVIKING_PEER_ID` take precedence over the corresponding values in `ovcli.conf`.
127
137
 
128
- For advanced setups, use `OPENVIKING_PLUGIN_CONFIG` to point to another configuration file path.
138
+ For advanced setups, use `OPENVIKING_CLI_CONFIG_FILE` to point to an `ovcli.conf` at another path.
129
139
 
130
140
  ### Hook-only mode
131
141
 
@@ -134,7 +144,9 @@ keeping this plugin's lifecycle hooks active:
134
144
 
135
145
  ```json
136
146
  {
137
- "mcp": { "enabled": false }
147
+ "plugin": {
148
+ "opencode": { "mcpEnabled": false }
149
+ }
138
150
  }
139
151
  ```
140
152
 
@@ -194,6 +206,7 @@ Usage guidance:
194
206
  - Use `openviking_list` to explore directory structure.
195
207
  - Before deleting anything, obtain explicit user confirmation first; then call `openviking_forget`.
196
208
  - If an agent tries to use OpenCode's local `read`, `glob`, or `grep` tools on a `viking://` URI, the plugin blocks that call and points it to the MCP tools.
209
+ - A `bash` command that contains a `viking://` URI still runs; the plugin appends a notice pointing to the MCP tools to its output, which the agent can ignore when the URI is intentional.
197
210
 
198
211
  ## Local Files with `openviking_add_resource`
199
212
 
@@ -226,7 +239,7 @@ Possible files include:
226
239
  - `openviking-memory.log`
227
240
  - `openviking-session-state.json`
228
241
 
229
- You can change this directory with `runtime.dataDir` in the configuration.
242
+ You can change this directory with `dataDir` in `plugin.opencode`.
230
243
 
231
244
  These are local runtime files and should not be committed to the repository.
232
245
 
@@ -235,7 +248,8 @@ These are local runtime files and should not be committed to the repository.
235
248
  | Issue | What to check |
236
249
  |-------|---------------|
237
250
  | Plugin does not load | For package installs, confirm `~/.config/opencode/opencode.json` contains `@openviking/opencode-plugin`; for source installs, confirm `~/.config/opencode/plugins/openviking.js` exists |
238
- | MCP tools call the wrong server | Check `~/.openviking/ovcli.conf`, or set `OPENVIKING_*` env vars / `OPENVIKING_PLUGIN_CONFIG` to the intended config path |
251
+ | Load fails with a missing `lib/shared/*.mjs` module | The source copy was made without running `sync.mjs` first. Run `node examples/memory-plugin-shared/sync.mjs` from the repository root and copy `lib/` again |
252
+ | MCP tools call the wrong server | Check `~/.openviking/ovcli.conf`, or set `OPENVIKING_*` env vars / `OPENVIKING_CLI_CONFIG_FILE` to the intended config path |
239
253
  | 401 / 403 from OpenViking | Verify `OPENVIKING_API_KEY`; for trusted-mode deployments, also verify `OPENVIKING_ACCOUNT` and `OPENVIKING_USER` |
240
- | Recall is empty | Confirm OpenViking has indexed memories/resources and `autoRecall.enabled` is `true` |
254
+ | Recall is empty | Confirm OpenViking has indexed memories/resources and `autoRecall` is `true` |
241
255
  | Local `openviking_add_resource` fails | Pass a file path, not a directory; local directories are not uploaded automatically yet |
package/README.md CHANGED
@@ -18,7 +18,7 @@ The plugin uses OpenCode hooks for lifecycle behavior and registers OpenViking's
18
18
  - Captures user and assistant text messages into OpenViking.
19
19
  - Commits sessions at lifecycle boundaries for memory extraction.
20
20
  - Automatically recalls relevant memories and injects them as hidden synthetic context for the current user message.
21
- - Blocks accidental local filesystem reads of `viking://` URIs and points the agent back to `openviking_read`, `openviking_glob`, or `openviking_search`.
21
+ - Blocks accidental local filesystem reads of `viking://` URIs and points the agent back to `openviking_read`, `openviking_glob`, or `openviking_search`. Shell commands that carry a `viking://` URI still run, with a notice appended to their output.
22
22
 
23
23
  ## Files
24
24
 
@@ -83,6 +83,7 @@ npm view @openviking/opencode-plugin version
83
83
  For development or PR testing, copy the package into OpenCode's plugin directory with a top-level wrapper:
84
84
 
85
85
  ```bash
86
+ node examples/memory-plugin-shared/sync.mjs
86
87
  mkdir -p ~/.config/opencode/plugins/openviking
87
88
  cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
88
89
  cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
@@ -90,6 +91,8 @@ cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
90
91
  cp -r examples/opencode-plugin/servers ~/.config/opencode/plugins/openviking/
91
92
  ```
92
93
 
94
+ `sync.mjs` generates `lib/shared/`, the shared modules the plugin and its MCP proxy import. That directory is not in git, so run it before copying, and again after every `git pull`.
95
+
93
96
  This creates a stable OpenCode plugin layout:
94
97
 
95
98
  ```text
@@ -113,39 +116,46 @@ Use the `.js` wrapper for source installs; OpenCode's local plugin scanner disco
113
116
 
114
117
  ## Configuration
115
118
 
116
- Create `~/.config/opencode/openviking-config.json`:
119
+ Behaviour knobs live in `~/.openviking/ovcli.conf` beside the connection fields, in the shared `plugin` section or in the `plugin.opencode` override:
117
120
 
118
121
  ```json
119
122
  {
120
- "enabled": true,
121
- "mcp": { "enabled": true },
122
- "timeoutMs": 30000,
123
- "repoContext": { "enabled": true, "cacheTtlMs": 60000 },
124
- "autoRecall": {
125
- "enabled": true,
126
- "limit": 6,
127
- "scoreThreshold": 0.35,
128
- "maxContentChars": 500,
129
- "preferAbstract": true,
130
- "tokenBudget": 2000,
131
- "minQueryLength": 3
132
- },
133
- "commitTokenThreshold": 20000,
134
- "commitKeepRecentCount": 10,
135
- "profileTokenBudget": 10000,
136
- "resumeContextBudget": 32000
123
+ "url": "http://127.0.0.1:1933",
124
+ "api_key": "your-api-key-here",
125
+ "plugin": {
126
+ "recallLimit": 6,
127
+ "opencode": {
128
+ "enabled": true,
129
+ "mcpEnabled": true,
130
+ "timeoutMs": 30000,
131
+ "repoContext": true,
132
+ "repoContextCacheTtlMs": 60000,
133
+ "autoRecall": true,
134
+ "scoreThreshold": 0.35,
135
+ "recallMaxContentChars": 500,
136
+ "recallPreferAbstract": true,
137
+ "recallTokenBudget": 2000,
138
+ "minQueryLength": 3,
139
+ "commitTokenThreshold": 20000,
140
+ "commitKeepRecentCount": 10,
141
+ "profileTokenBudget": 10000,
142
+ "resumeContextBudget": 32000
143
+ }
144
+ }
137
145
  }
138
146
  ```
139
147
 
140
- `autoRecall.limit` is a legacy quota-scaling input, not a final result cap.
148
+ Keys in `plugin` apply to every harness; keys in `plugin.opencode` apply to this one and override them. Resolution is `OPENVIKING_*` environment variables → the workspace's `.openviking/config.json`, `.openviking/config.local.json` and machine registry entry → `plugin.opencode` → `plugin` → built-in defaults. Every knob, with its type, default, range, environment variable and accepted older spellings, is declared in [`examples/memory-plugin-shared/lib/config-schema.mjs`](../memory-plugin-shared/lib/config-schema.mjs).
149
+
150
+ `recallLimit` is a legacy quota-scaling input, not a final result cap.
141
151
  Explicit values from 1 through 5 produce an effective total quota of 6 because
142
152
  each coding category keeps one retrieval slot. Use Context `quotas` directly
143
153
  when exact category ceilings are required.
144
154
 
145
155
  API keys are resolved from environment variables or `~/.openviking/ovcli.conf` and sent as `Authorization: Bearer ...` by both hooks and the MCP proxy. Recall goes through the server-side context face (`POST /api/v1/search/search` with `mode="context"`), falling back to the deprecated `/api/v1/search/recall` on older deployments. `account` and `user` are trusted-mode identity
146
- headers sent as `X-OpenViking-Account` and `X-OpenViking-User`; leave them empty
147
- when using API-key mode with user/admin API keys.
148
- By default the plugin derives a peer from the git identity of the project directory: the normalized `origin` URL, else the repository root path. Outside a git repository no peer is sent at all, and what is remembered there goes to the user-level space `viking://user/<you>/memories`. `git@github.com:volcengine/OpenViking.git` becomes `github.com-volcengine-openviking`; the path fallback keeps the older naming rule where every non-letter-or-digit character becomes `-`, so `/Users/x/Dev/OpenViking` becomes `-Users-x-Dev-OpenViking`. One repository therefore keeps one peer across subdirectories, worktrees, clones and machines, while a fork's different origin keeps it separate. Derivation reads `.git` directly, so no `git` binary is needed. The plugin does not read workspace `.openviking/config.json` files, so a `peer.id` written there has no effect. Data-plane memory/resource requests send the effective peer as `X-OpenViking-Actor-Peer`; captured session messages store it as body `peer_id`. Configure `peerId` or `OPENVIKING_PEER_ID` to override the derived peer, or set `workspacePeer=false` / `OPENVIKING_WORKSPACE_PEER=0` to send no peer at all. Memories written under the older directory-derived peer stay reachable: the default broad recall sweeps every peer under the user, and `recallPeerScope="actor"` asks that previous peer separately.
156
+ headers sent as `X-OpenViking-Account` and `X-OpenViking-User`; an `api_key`
157
+ server reads both out of the key, so the plugin withholds them there.
158
+ By default the plugin derives a peer from the git identity of the project directory: the normalized `origin` URL, else the repository root path. Outside a git repository no peer is sent at all, and what is remembered there goes to the user-level space `viking://user/<you>/memories`. `git@github.com:volcengine/OpenViking.git` becomes `github.com-volcengine-openviking`; the path fallback keeps the older naming rule where every non-letter-or-digit character becomes `-`, so `/Users/x/Dev/OpenViking` becomes `-Users-x-Dev-OpenViking`. One repository therefore keeps one peer across subdirectories, worktrees, clones and machines, while a fork's different origin keeps it separate. Derivation reads `.git` directly, so no `git` binary is needed. The plugin reads the workspace's `.openviking/config.json`, so a `peer.id` or `peer.source` written there applies. Data-plane memory/resource requests send the effective peer as `X-OpenViking-Actor-Peer`; captured session messages store it as body `peer_id`. Configure `peerId` in the `plugin` section or `OPENVIKING_PEER_ID` to override the derived peer, or set `workspacePeer` to `false` / `OPENVIKING_WORKSPACE_PEER=0` to send no peer at all. Memories written under the older directory-derived peer stay reachable: the default broad recall sweeps every peer under the user, and `recallPeerScope="actor"` asks that previous peer separately.
149
159
 
150
160
  Recall defaults to the broad mode: global memory, the current workspace, and
151
161
  other workspace memories can all be recalled, with other workspaces penalized
@@ -157,13 +167,12 @@ with an explicit actor peer so one person's memories are not recalled into
157
167
  another person's session.
158
168
 
159
169
  `OPENVIKING_API_KEY`, `OPENVIKING_ACCOUNT`, `OPENVIKING_USER`,
160
- and `OPENVIKING_PEER_ID` take precedence over values in this file. The config
161
- file's `peerId` still applies whenever shared credentials (ovcli.conf or
162
- environment variables) do not carry a peer of their own, so an authenticated
163
- setup keeps writing peer-scoped data instead of dropping into the shared user
164
- tree.
170
+ and `OPENVIKING_PEER_ID` take precedence over `ovcli.conf`. Below the
171
+ environment, the `plugin` section's `peerId` takes precedence over
172
+ `ovcli.conf`'s `actor_peer_id`: a peer written for this harness is the more
173
+ specific answer, and this is the order every memory plugin follows.
165
174
 
166
- For advanced setups, `OPENVIKING_PLUGIN_CONFIG` can point to another config file path.
175
+ `OPENVIKING_CLI_CONFIG_FILE` points the plugin at an `ovcli.conf` somewhere other than `~/.openviking/ovcli.conf`.
167
176
 
168
177
  ### Hook-only mode
169
178
 
@@ -172,7 +181,9 @@ skipping this plugin's bundled MCP registration:
172
181
 
173
182
  ```json
174
183
  {
175
- "mcp": { "enabled": false }
184
+ "plugin": {
185
+ "opencode": { "mcpEnabled": false }
186
+ }
176
187
  }
177
188
  ```
178
189
 
@@ -181,7 +192,10 @@ It does not add or overwrite OpenCode's `mcp.openviking` entry.
181
192
 
182
193
  OpenCode's local `read`, `glob`, and `grep` tools cannot read `viking://` URIs.
183
194
  When the agent accidentally tries that, the plugin blocks the filesystem tool
184
- call and points it to the OpenViking MCP tools.
195
+ call and points it to the OpenViking MCP tools. A `bash` command that contains a
196
+ `viking://` URI is not blocked, because the URI is often data (an `ov` argument,
197
+ an HTTP payload); the command runs and the plugin appends a notice naming the
198
+ MCP tools to its output.
185
199
 
186
200
  ## MCP Tools
187
201
 
@@ -211,12 +225,12 @@ The plugin writes runtime files to `~/.config/opencode/openviking/` by default:
211
225
  - `openviking-memory.log`
212
226
  - `openviking-session-state.json`
213
227
 
214
- Set `runtime.dataDir` in config to override this directory.
228
+ Set `dataDir` in `plugin.opencode` to override this directory.
215
229
 
216
230
  ## Automated npm releases
217
231
 
218
232
  Changes merged into upstream `main` under `examples/opencode-plugin/` trigger
219
- `.github/workflows/opencode-plugin-release.yml`. Releases use the same calendar
233
+ `.github/workflows/plugin-npm-release.yml`. Releases use the same calendar
220
234
  version convention as the OpenClaw plugin: `YYYY.M.D`, then `YYYY.M.D-N` for
221
235
  subsequent releases on that date (Asia/Shanghai). No manual source version bump
222
236
  is required. The workflow changes the version only in the package being published;
package/index.mjs CHANGED
@@ -5,9 +5,10 @@ import { createRepoContext } from "./lib/repo-context.mjs"
5
5
  import { createMemorySessionManager } from "./lib/memory-session.mjs"
6
6
  import { createMemoryRecall } from "./lib/memory-recall.mjs"
7
7
  import { createSessionInject } from "./lib/session-inject.mjs"
8
- import { createVikingUriGuard } from "./lib/viking-uri-guard.mjs"
8
+ import { createVikingUriGuard, createVikingUriNotice } from "./lib/viking-uri-guard.mjs"
9
9
  import { injectOpenVikingMcpConfig } from "./lib/mcp-config.mjs"
10
10
  import { loadConfig, resolveDataDir } from "./lib/config.mjs"
11
+ import { isRecallEnabled } from "./lib/shared/recall-core.mjs"
11
12
  import { initLogger, log, makeToast } from "./lib/utils.mjs"
12
13
 
13
14
  const pluginRoot = dirname(fileURLToPath(import.meta.url))
@@ -27,16 +28,10 @@ export async function OpenVikingPlugin({ client, directory }) {
27
28
  const recall = createMemoryRecall({ config, sessionManager })
28
29
  const sessionInject = createSessionInject({ config, sessionManager })
29
30
  const vikingUriGuard = createVikingUriGuard()
31
+ const vikingUriNotice = createVikingUriNotice()
30
32
 
31
33
  await sessionManager.init()
32
34
  const toast = makeToast(client)
33
- if (config.legacyCredentialsUsed) {
34
- log("WARN", "config", "Legacy OpenCode credential fields are still in use; run node scripts/setup.mjs to migrate to ovcli.conf", {
35
- configPath: config.configPath,
36
- })
37
- await toast("OpenViking credentials in openviking-config.json are deprecated. Run node scripts/setup.mjs to migrate.", "warning")
38
- }
39
-
40
35
  Promise.resolve().then(async () => {
41
36
  const ready = await initializeRuntime(config, client)
42
37
  if (ready) await repoContext.refreshRepos({ force: true })
@@ -63,6 +58,7 @@ export async function OpenVikingPlugin({ client, directory }) {
63
58
  },
64
59
 
65
60
  "tool.execute.before": vikingUriGuard,
61
+ "tool.execute.after": vikingUriNotice,
66
62
 
67
63
  "experimental.chat.system.transform": (_input, output) => {
68
64
  const prompt = repoContext.getRepoSystemPrompt()
@@ -72,7 +68,7 @@ export async function OpenVikingPlugin({ client, directory }) {
72
68
  "chat.message": async (input, output) => {
73
69
  try {
74
70
  await sessionInject.injectSessionContext(input, output)
75
- if (!config.autoRecall?.enabled) return
71
+ if (!isRecallEnabled(config)) return
76
72
  await recall.injectRelevantMemories(input, output)
77
73
  } catch (error) {
78
74
  log("WARN", "recall", "Auto recall failed", { error: error?.message ?? String(error) })