@openviking/opencode-plugin 0.1.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.
- package/INSTALL-ZH.md +225 -0
- package/INSTALL.md +220 -0
- package/README.md +261 -0
- package/index.mjs +84 -0
- package/lib/code-tools.mjs +134 -0
- package/lib/memadd-local.mjs +118 -0
- package/lib/memory-recall.mjs +214 -0
- package/lib/memory-session.mjs +651 -0
- package/lib/memory-tools.mjs +410 -0
- package/lib/repo-context.mjs +68 -0
- package/lib/runtime.mjs +33 -0
- package/lib/utils.mjs +341 -0
- package/lib/viking-uri-guard.mjs +52 -0
- package/package.json +42 -0
package/INSTALL-ZH.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# 安装 OpenViking OpenCode 统一插件
|
|
2
|
+
|
|
3
|
+
这个插件新增了一个面向 OpenCode 的统一 OpenViking 插件:
|
|
4
|
+
|
|
5
|
+
- 外部仓库语义检索
|
|
6
|
+
- 长期记忆、session 同步、生命周期边界 commit、自动 recall
|
|
7
|
+
|
|
8
|
+
这是仓库中唯一继续维护的 OpenCode 插件示例。这个插件不再安装 `skills/openviking/SKILL.md`,也不要求 agent 使用 `ov` 命令。原 skill 风格的能力会通过 OpenCode tools 暴露。
|
|
9
|
+
|
|
10
|
+
## 前置条件
|
|
11
|
+
|
|
12
|
+
需要先准备:
|
|
13
|
+
|
|
14
|
+
- OpenCode
|
|
15
|
+
- OpenViking HTTP Server
|
|
16
|
+
- Node.js / npm,用于安装插件依赖
|
|
17
|
+
- 如果服务端启用了认证,需要可用的 OpenViking API Key
|
|
18
|
+
|
|
19
|
+
建议先启动 OpenViking:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
openviking-server --config ~/.openviking/ov.conf
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
检查服务:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
curl http://localhost:1933/health
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 安装方式一:发布包安装
|
|
32
|
+
|
|
33
|
+
普通用户推荐通过 OpenCode 的 package plugin 机制启用:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"plugin": ["@openviking/opencode-plugin"]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 安装方式二:源码安装
|
|
42
|
+
|
|
43
|
+
用于开发调试或 PR 测试。OpenCode 推荐插件目录:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
~/.config/opencode/plugins
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
在仓库根目录执行:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mkdir -p ~/.config/opencode/plugins/openviking
|
|
53
|
+
cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
|
|
54
|
+
cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
|
|
55
|
+
cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
|
|
56
|
+
cd ~/.config/opencode/plugins/openviking
|
|
57
|
+
npm install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
安装后结构应类似:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
~/.config/opencode/plugins/
|
|
64
|
+
├── openviking.js
|
|
65
|
+
└── openviking/
|
|
66
|
+
├── index.mjs
|
|
67
|
+
├── package.json
|
|
68
|
+
├── lib/
|
|
69
|
+
└── node_modules/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
顶层 `openviking.js` 只负责把 OpenCode 能发现的一级 `.js` 入口转发到插件目录:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
export { OpenVikingPlugin, default } from "./openviking/index.mjs"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
这个 wrapper 只用于上面这种源码安装目录结构。npm 包安装会通过 `package.json` 直接加载 `index.mjs`。
|
|
79
|
+
源码安装请使用 `.js` wrapper;OpenCode 的本地插件扫描器会发现 JavaScript/TypeScript 插件文件。
|
|
80
|
+
|
|
81
|
+
如果你使用 npm 包方式安装,也可以将 `examples/opencode-plugin` 作为一个普通 OpenCode 插件包使用。
|
|
82
|
+
|
|
83
|
+
## 配置
|
|
84
|
+
|
|
85
|
+
创建用户级配置文件:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
~/.config/opencode/openviking-config.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
示例配置:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"endpoint": "http://localhost:1933",
|
|
96
|
+
"apiKey": "",
|
|
97
|
+
"account": "",
|
|
98
|
+
"user": "",
|
|
99
|
+
"peerId": "",
|
|
100
|
+
"enabled": true,
|
|
101
|
+
"timeoutMs": 30000,
|
|
102
|
+
"repoContext": { "enabled": true, "cacheTtlMs": 60000 },
|
|
103
|
+
"autoRecall": {
|
|
104
|
+
"enabled": true,
|
|
105
|
+
"limit": 6,
|
|
106
|
+
"scoreThreshold": 0.15,
|
|
107
|
+
"maxContentChars": 500,
|
|
108
|
+
"preferAbstract": true,
|
|
109
|
+
"tokenBudget": 2000
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
推荐通过环境变量提供 API Key,而不是写入配置文件:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
export OPENVIKING_API_KEY="your-api-key-here"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`apiKey` 会作为 `X-API-Key` 发送。`account` 和 `user` 是 trusted mode
|
|
121
|
+
身份头,会作为 `X-OpenViking-Account`、`X-OpenViking-User` 发送;使用
|
|
122
|
+
user/admin API key 的 API_KEY mode 时应留空。
|
|
123
|
+
`peerId` 会作为 `X-OpenViking-Actor-Peer` 用于数据面的 memory/resource 请求;捕获 session message 时仍写入 body `peer_id`。需要 peer 维度路由时请显式配置。
|
|
124
|
+
|
|
125
|
+
`OPENVIKING_API_KEY`、`OPENVIKING_ACCOUNT`、`OPENVIKING_USER`、
|
|
126
|
+
`OPENVIKING_PEER_ID`
|
|
127
|
+
优先级高于 `openviking-config.json` 里的同名配置。
|
|
128
|
+
|
|
129
|
+
高级场景可以用 `OPENVIKING_PLUGIN_CONFIG` 指向其他配置文件路径。
|
|
130
|
+
|
|
131
|
+
## 验证
|
|
132
|
+
|
|
133
|
+
修改插件或 OpenViking 配置后,需要重启 OpenCode。
|
|
134
|
+
|
|
135
|
+
进入新的 OpenCode session 后,可以让 agent 浏览 OpenViking memory,或搜索一个已索引的资源。插件应暴露这些 tools:
|
|
136
|
+
|
|
137
|
+
- `memsearch`、`memread`、`membrowse`
|
|
138
|
+
- `memgrep`、`memglob`
|
|
139
|
+
- `memadd`、`memwrite`、`memremove`、`memqueue`
|
|
140
|
+
- `memcommit`
|
|
141
|
+
- `codesearch`、`codeoutline`、`codeexpand`
|
|
142
|
+
|
|
143
|
+
如果行为异常,先查看运行时文件:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
ls ~/.config/opencode/openviking/
|
|
147
|
+
tail -n 100 ~/.config/opencode/openviking/openviking-memory.log
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
如果使用本地 server,也确认 OpenViking 可访问:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
curl http://localhost:1933/health
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 可用工具
|
|
157
|
+
|
|
158
|
+
插件会通过 OpenCode `tool` hook 暴露这些工具:
|
|
159
|
+
|
|
160
|
+
- `memsearch`:语义检索 memories/resources/skills
|
|
161
|
+
- `memread`:读取具体 `viking://` URI
|
|
162
|
+
- `membrowse`:浏览 OpenViking 文件系统
|
|
163
|
+
- `memcommit`:提交当前 session 并触发记忆提取
|
|
164
|
+
- `memgrep`:精确文本或模式搜索,替代原 `ov grep`
|
|
165
|
+
- `memglob`:文件 glob 枚举,替代原 `ov glob`
|
|
166
|
+
- `memadd`:添加远端 URL 或本地文件资源,替代常见 `ov add-resource` 场景
|
|
167
|
+
- `memwrite`:通过 `/api/v1/content/write` 直接写入 `viking://` 文本文件
|
|
168
|
+
- `memremove`:删除资源,替代 `ov rm`
|
|
169
|
+
- `memqueue`:查看处理队列,替代 `ov observer queue`
|
|
170
|
+
|
|
171
|
+
使用建议:
|
|
172
|
+
|
|
173
|
+
- 概念性问题用 `memsearch`
|
|
174
|
+
- 精确符号、函数名、类名、报错字符串用 `memgrep`
|
|
175
|
+
- 枚举文件用 `memglob`
|
|
176
|
+
- 读取内容用 `memread`
|
|
177
|
+
- 探索目录结构用 `membrowse`
|
|
178
|
+
- 持久化笔记或小型文本更新用 `memwrite`;默认是 `create`,避免误覆盖
|
|
179
|
+
- 删除前必须先获得用户明确确认,再调用 `memremove` 且传入 `confirm: true`
|
|
180
|
+
- 如果 agent 误用 OpenCode 本地 `read`、`glob`、`grep` 工具访问 `viking://` URI,插件会阻止这次本地文件系统调用,并提示改用 `memread`、`membrowse` 或 `memsearch`。
|
|
181
|
+
|
|
182
|
+
## `memadd` 本地文件
|
|
183
|
+
|
|
184
|
+
`memadd` 支持三类输入:
|
|
185
|
+
|
|
186
|
+
- 远端 `http(s)` URL:直接调用 `/api/v1/resources`
|
|
187
|
+
- 本地文件路径:先调用 `/api/v1/resources/temp_upload`,再用返回的 `temp_file_id` 添加资源
|
|
188
|
+
- `file://` URL:按本地文件处理
|
|
189
|
+
|
|
190
|
+
相对路径会按 OpenCode 当前项目目录解析。示例:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
memadd path="https://example.com/spec.md" to="viking://resources/spec"
|
|
194
|
+
memadd path="./docs/notes.md" parent="viking://resources/"
|
|
195
|
+
memadd path="file:///home/alice/project/notes.md" reason="project notes"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
当前仍不支持本地目录自动打 zip 上传;传入目录时会返回明确错误。
|
|
199
|
+
|
|
200
|
+
## 运行时文件
|
|
201
|
+
|
|
202
|
+
插件默认会把运行时文件写入:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
~/.config/opencode/openviking/
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
可能包含:
|
|
209
|
+
|
|
210
|
+
- `openviking-memory.log`
|
|
211
|
+
- `openviking-session-map.json`
|
|
212
|
+
|
|
213
|
+
可以通过配置里的 `runtime.dataDir` 修改这个目录。
|
|
214
|
+
|
|
215
|
+
这些是本地运行时文件,不建议提交到版本库。
|
|
216
|
+
|
|
217
|
+
## 故障排查
|
|
218
|
+
|
|
219
|
+
| 问题 | 排查方向 |
|
|
220
|
+
|------|----------|
|
|
221
|
+
| 插件没有加载 | package 安装检查 `~/.config/opencode/opencode.json` 是否包含 `@openviking/opencode-plugin`;源码安装检查 `~/.config/opencode/plugins/openviking.js` 是否存在 |
|
|
222
|
+
| Tools 连到了错误的 server | 检查 `~/.config/opencode/openviking-config.json` 里的 `endpoint`,或用 `OPENVIKING_PLUGIN_CONFIG` 指向正确配置文件 |
|
|
223
|
+
| OpenViking 返回 401 / 403 | 检查 `OPENVIKING_API_KEY`;trusted-mode 部署还要检查 `OPENVIKING_ACCOUNT` 和 `OPENVIKING_USER` |
|
|
224
|
+
| recall 为空 | 确认 OpenViking 中已有 memories/resources,并且 `autoRecall.enabled` 为 `true` |
|
|
225
|
+
| 本地 `memadd` 失败 | 传入文件路径而不是目录;目前还不支持自动上传本地目录 |
|
package/INSTALL.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Install the Unified OpenViking OpenCode Plugin
|
|
2
|
+
|
|
3
|
+
This plugin adds one unified OpenViking plugin for OpenCode:
|
|
4
|
+
|
|
5
|
+
- Semantic retrieval for external repositories
|
|
6
|
+
- Long-term memory, session synchronization, lifecycle commit, and automatic recall
|
|
7
|
+
|
|
8
|
+
This is the only OpenCode plugin example maintained in this repository. It does not install `skills/openviking/SKILL.md`, and it does not require the agent to use the `ov` command. The former skill-style capabilities are exposed as OpenCode tools here.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
Prepare the following first:
|
|
13
|
+
|
|
14
|
+
- OpenCode
|
|
15
|
+
- OpenViking HTTP Server
|
|
16
|
+
- Node.js / npm, used to install plugin dependencies
|
|
17
|
+
- A valid OpenViking API key if authentication is enabled on the server
|
|
18
|
+
|
|
19
|
+
Start OpenViking first:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
openviking-server --config ~/.openviking/ov.conf
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Check the service:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
curl http://localhost:1933/health
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Installation Method 1: Published Package
|
|
32
|
+
|
|
33
|
+
Normal users are recommended to enable it through OpenCode's package plugin mechanism:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"plugin": ["@openviking/opencode-plugin"]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Installation Method 2: Source Install
|
|
42
|
+
|
|
43
|
+
Use this method for development, debugging, or PR testing. OpenCode's recommended plugin directory is:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
~/.config/opencode/plugins
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Run the following commands from the repository root:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mkdir -p ~/.config/opencode/plugins/openviking
|
|
53
|
+
cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
|
|
54
|
+
cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
|
|
55
|
+
cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
|
|
56
|
+
cd ~/.config/opencode/plugins/openviking
|
|
57
|
+
npm install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
After installation, the layout should look like this:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
~/.config/opencode/plugins/
|
|
64
|
+
├── openviking.js
|
|
65
|
+
└── openviking/
|
|
66
|
+
├── index.mjs
|
|
67
|
+
├── package.json
|
|
68
|
+
├── lib/
|
|
69
|
+
└── node_modules/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The top-level `openviking.js` forwards the first-level `.js` entry that OpenCode can discover to the actual plugin directory:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
export { OpenVikingPlugin, default } from "./openviking/index.mjs"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This wrapper is only for source installs with the directory layout shown above. npm package installs load `index.mjs` directly through `package.json`.
|
|
79
|
+
Use the `.js` wrapper for source installs; OpenCode's local plugin scanner discovers JavaScript/TypeScript plugin files.
|
|
80
|
+
|
|
81
|
+
If you install through an npm package, you can also use `examples/opencode-plugin` as a normal OpenCode plugin package.
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
Create the user-level configuration file:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
~/.config/opencode/openviking-config.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Example configuration:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"endpoint": "http://localhost:1933",
|
|
96
|
+
"apiKey": "",
|
|
97
|
+
"account": "",
|
|
98
|
+
"user": "",
|
|
99
|
+
"peerId": "",
|
|
100
|
+
"enabled": true,
|
|
101
|
+
"timeoutMs": 30000,
|
|
102
|
+
"repoContext": { "enabled": true, "cacheTtlMs": 60000 },
|
|
103
|
+
"autoRecall": {
|
|
104
|
+
"enabled": true,
|
|
105
|
+
"limit": 6,
|
|
106
|
+
"scoreThreshold": 0.15,
|
|
107
|
+
"maxContentChars": 500,
|
|
108
|
+
"preferAbstract": true,
|
|
109
|
+
"tokenBudget": 2000
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
It is recommended to provide the API key through an environment variable instead of writing it into the configuration file:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
export OPENVIKING_API_KEY="your-api-key-here"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`apiKey` is sent as `X-API-Key`. `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`.
|
|
121
|
+
|
|
122
|
+
`OPENVIKING_API_KEY`, `OPENVIKING_ACCOUNT`, `OPENVIKING_USER`, and `OPENVIKING_PEER_ID` take precedence over the corresponding values in `openviking-config.json`.
|
|
123
|
+
|
|
124
|
+
For advanced setups, use `OPENVIKING_PLUGIN_CONFIG` to point to another configuration file path.
|
|
125
|
+
|
|
126
|
+
## Verify
|
|
127
|
+
|
|
128
|
+
Restart OpenCode after changing plugin or OpenViking configuration.
|
|
129
|
+
|
|
130
|
+
In a new OpenCode session, ask the agent to browse OpenViking memory or search for a known indexed resource. The plugin should expose these tools:
|
|
131
|
+
|
|
132
|
+
- `memsearch`, `memread`, `membrowse`
|
|
133
|
+
- `memgrep`, `memglob`
|
|
134
|
+
- `memadd`, `memwrite`, `memremove`, `memqueue`
|
|
135
|
+
- `memcommit`
|
|
136
|
+
- `codesearch`, `codeoutline`, `codeexpand`
|
|
137
|
+
|
|
138
|
+
If anything looks wrong, check the runtime files:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
ls ~/.config/opencode/openviking/
|
|
142
|
+
tail -n 100 ~/.config/opencode/openviking/openviking-memory.log
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
For a local server, also confirm OpenViking is reachable:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
curl http://localhost:1933/health
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Available Tools
|
|
152
|
+
|
|
153
|
+
The plugin exposes the following tools through the OpenCode `tool` hook:
|
|
154
|
+
|
|
155
|
+
- `memsearch`: semantic retrieval across memories, resources, and skills
|
|
156
|
+
- `memread`: read a specific `viking://` URI
|
|
157
|
+
- `membrowse`: browse the OpenViking filesystem
|
|
158
|
+
- `memcommit`: commit the current session and trigger memory extraction
|
|
159
|
+
- `memgrep`: exact text or pattern search, replacing the former `ov grep` use case
|
|
160
|
+
- `memglob`: file glob enumeration, replacing the former `ov glob` use case
|
|
161
|
+
- `memadd`: add a remote URL or local file resource, replacing common `ov add-resource` scenarios
|
|
162
|
+
- `memwrite`: write text to a `viking://` file through `/api/v1/content/write`
|
|
163
|
+
- `memremove`: remove resources, replacing `ov rm`
|
|
164
|
+
- `memqueue`: inspect the processing queue, replacing `ov observer queue`
|
|
165
|
+
|
|
166
|
+
Usage guidance:
|
|
167
|
+
|
|
168
|
+
- Use `memsearch` for conceptual questions.
|
|
169
|
+
- Use `memgrep` for exact symbols, function names, class names, or error strings.
|
|
170
|
+
- Use `memglob` to enumerate files.
|
|
171
|
+
- Use `memread` to read content.
|
|
172
|
+
- Use `membrowse` to explore directory structure.
|
|
173
|
+
- Use `memwrite` for durable notes or small direct text updates; default mode is `create`.
|
|
174
|
+
- Before deleting anything, obtain explicit user confirmation first; then call `memremove` with `confirm: true`.
|
|
175
|
+
- 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 `memread`, `membrowse`, or `memsearch`.
|
|
176
|
+
|
|
177
|
+
## Local Files with `memadd`
|
|
178
|
+
|
|
179
|
+
`memadd` supports three input types:
|
|
180
|
+
|
|
181
|
+
- Remote `http(s)` URL: directly calls `/api/v1/resources`
|
|
182
|
+
- Local file path: first calls `/api/v1/resources/temp_upload`, then adds the resource using the returned `temp_file_id`
|
|
183
|
+
- `file://` URL: handled as a local file
|
|
184
|
+
|
|
185
|
+
Relative paths are resolved against the current OpenCode project directory. Examples:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
memadd path="https://example.com/spec.md" to="viking://resources/spec"
|
|
189
|
+
memadd path="./docs/notes.md" parent="viking://resources/"
|
|
190
|
+
memadd path="file:///home/alice/project/notes.md" reason="project notes"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Automatic zip upload for local directories is not supported yet. Passing a directory will return a clear error.
|
|
194
|
+
|
|
195
|
+
## Runtime Files
|
|
196
|
+
|
|
197
|
+
By default, the plugin writes runtime files to:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
~/.config/opencode/openviking/
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Possible files include:
|
|
204
|
+
|
|
205
|
+
- `openviking-memory.log`
|
|
206
|
+
- `openviking-session-map.json`
|
|
207
|
+
|
|
208
|
+
You can change this directory with `runtime.dataDir` in the configuration.
|
|
209
|
+
|
|
210
|
+
These are local runtime files and should not be committed to the repository.
|
|
211
|
+
|
|
212
|
+
## Troubleshooting
|
|
213
|
+
|
|
214
|
+
| Issue | What to check |
|
|
215
|
+
|-------|---------------|
|
|
216
|
+
| 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 |
|
|
217
|
+
| Tools call the wrong server | Check `endpoint` in `~/.config/opencode/openviking-config.json`, or set `OPENVIKING_PLUGIN_CONFIG` to the intended config path |
|
|
218
|
+
| 401 / 403 from OpenViking | Verify `OPENVIKING_API_KEY`; for trusted-mode deployments, also verify `OPENVIKING_ACCOUNT` and `OPENVIKING_USER` |
|
|
219
|
+
| Recall is empty | Confirm OpenViking has indexed memories/resources and `autoRecall.enabled` is `true` |
|
|
220
|
+
| Local `memadd` fails | Pass a file path, not a directory; local directories are not uploaded automatically yet |
|
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# OpenViking OpenCode Plugin
|
|
2
|
+
|
|
3
|
+
A unified OpenCode plugin for OpenViking repository retrieval and long-term memory.
|
|
4
|
+
|
|
5
|
+
This is the only OpenCode plugin example maintained in this repository. It supersedes the former split examples for indexed repository prompt injection and long-term memory.
|
|
6
|
+
|
|
7
|
+
The new plugin exposes everything through OpenCode tool hooks and talks to OpenViking through HTTP APIs. It does not install or require an OpenCode skill, and agents do not need to run `ov` shell commands.
|
|
8
|
+
|
|
9
|
+
## What It Does
|
|
10
|
+
|
|
11
|
+
- Injects indexed `viking://resources/` repositories into the system prompt.
|
|
12
|
+
- Exposes repository search, grep, glob, read, browse, add, write, remove, and queue status as tools.
|
|
13
|
+
- Maps each OpenCode session to an OpenViking session.
|
|
14
|
+
- Captures user and assistant text messages into OpenViking.
|
|
15
|
+
- Commits sessions at lifecycle boundaries for memory extraction.
|
|
16
|
+
- Automatically recalls relevant memories and injects them as hidden synthetic context for the current user message.
|
|
17
|
+
- Blocks accidental local filesystem reads of `viking://` URIs and points the agent back to `memread`, `membrowse`, or `memsearch`.
|
|
18
|
+
|
|
19
|
+
## Files
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
examples/opencode-plugin/
|
|
23
|
+
├── index.mjs
|
|
24
|
+
├── package.json
|
|
25
|
+
├── README.md
|
|
26
|
+
├── INSTALL-ZH.md
|
|
27
|
+
├── lib/
|
|
28
|
+
│ ├── runtime.mjs
|
|
29
|
+
│ ├── repo-context.mjs
|
|
30
|
+
│ ├── memory-session.mjs
|
|
31
|
+
│ ├── memadd-local.mjs
|
|
32
|
+
│ ├── memory-tools.mjs
|
|
33
|
+
│ ├── memory-recall.mjs
|
|
34
|
+
│ ├── viking-uri-guard.mjs
|
|
35
|
+
│ └── utils.mjs
|
|
36
|
+
├── tests/
|
|
37
|
+
└── wrappers/
|
|
38
|
+
└── openviking.js
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
There is intentionally no `skills/openviking/SKILL.md`. The former skill behavior is implemented as tools.
|
|
42
|
+
|
|
43
|
+
## Requirements
|
|
44
|
+
|
|
45
|
+
- OpenCode
|
|
46
|
+
- OpenViking HTTP server
|
|
47
|
+
- Node.js / npm for installing the plugin dependency
|
|
48
|
+
- An OpenViking API key if your server requires authentication
|
|
49
|
+
|
|
50
|
+
Start OpenViking first:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
openviking-server --config ~/.openviking/ov.conf
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
### Published Package
|
|
59
|
+
|
|
60
|
+
Normal users should enable it through OpenCode's package plugin mechanism:
|
|
61
|
+
|
|
62
|
+
The published npm package is `@openviking/opencode-plugin`; verify availability with:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm view @openviking/opencode-plugin version
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"plugin": ["@openviking/opencode-plugin"]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Source Install
|
|
75
|
+
|
|
76
|
+
For development or PR testing, copy the package into OpenCode's plugin directory with a top-level wrapper:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mkdir -p ~/.config/opencode/plugins/openviking
|
|
80
|
+
cp examples/opencode-plugin/wrappers/openviking.js ~/.config/opencode/plugins/openviking.js
|
|
81
|
+
cp examples/opencode-plugin/index.mjs examples/opencode-plugin/package.json ~/.config/opencode/plugins/openviking/
|
|
82
|
+
cp -r examples/opencode-plugin/lib ~/.config/opencode/plugins/openviking/
|
|
83
|
+
cd ~/.config/opencode/plugins/openviking
|
|
84
|
+
npm install
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This creates a stable OpenCode plugin layout:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
~/.config/opencode/plugins/
|
|
91
|
+
├── openviking.js
|
|
92
|
+
└── openviking/
|
|
93
|
+
├── index.mjs
|
|
94
|
+
├── package.json
|
|
95
|
+
├── lib/
|
|
96
|
+
└── node_modules/
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The top-level `openviking.js` is only a wrapper:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
export { OpenVikingPlugin, default } from "./openviking/index.mjs"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This wrapper is only for source installs with the directory layout shown above. npm package installs load `index.mjs` directly through `package.json`.
|
|
106
|
+
Use the `.js` wrapper for source installs; OpenCode's local plugin scanner discovers JavaScript/TypeScript plugin files.
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
Create `~/.config/opencode/openviking-config.json`:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"endpoint": "http://localhost:1933",
|
|
115
|
+
"apiKey": "",
|
|
116
|
+
"account": "",
|
|
117
|
+
"user": "",
|
|
118
|
+
"peerId": "",
|
|
119
|
+
"enabled": true,
|
|
120
|
+
"timeoutMs": 30000,
|
|
121
|
+
"repoContext": { "enabled": true, "cacheTtlMs": 60000 },
|
|
122
|
+
"autoRecall": {
|
|
123
|
+
"enabled": true,
|
|
124
|
+
"limit": 6,
|
|
125
|
+
"scoreThreshold": 0.15,
|
|
126
|
+
"maxContentChars": 500,
|
|
127
|
+
"preferAbstract": true,
|
|
128
|
+
"tokenBudget": 2000
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`apiKey` is sent as `X-API-Key`. `account` and `user` are trusted-mode identity
|
|
134
|
+
headers sent as `X-OpenViking-Account` and `X-OpenViking-User`; leave them empty
|
|
135
|
+
when using API-key mode with user/admin API keys.
|
|
136
|
+
`peerId` is sent as `X-OpenViking-Actor-Peer` on data-plane memory/resource
|
|
137
|
+
requests; captured session messages store it as body `peer_id`. Configure
|
|
138
|
+
`peerId` explicitly when peer-scoped memory routing is needed.
|
|
139
|
+
|
|
140
|
+
`OPENVIKING_API_KEY`, `OPENVIKING_ACCOUNT`, `OPENVIKING_USER`,
|
|
141
|
+
and `OPENVIKING_PEER_ID` take
|
|
142
|
+
precedence over values in this file.
|
|
143
|
+
|
|
144
|
+
For advanced setups, `OPENVIKING_PLUGIN_CONFIG` can point to another config file path.
|
|
145
|
+
|
|
146
|
+
OpenCode's local `read`, `glob`, and `grep` tools cannot read `viking://` URIs.
|
|
147
|
+
When the agent accidentally tries that, the plugin blocks the filesystem tool
|
|
148
|
+
call and points it to `memread`, `membrowse`, or `memsearch`.
|
|
149
|
+
|
|
150
|
+
## Tools
|
|
151
|
+
|
|
152
|
+
### `memsearch`
|
|
153
|
+
|
|
154
|
+
Semantic search across memories, resources, and skills.
|
|
155
|
+
|
|
156
|
+
Use for conceptual questions, repository internals, user preferences, and context-aware retrieval. Use `target_uri` to narrow scope, for example `viking://resources/fastapi/`.
|
|
157
|
+
|
|
158
|
+
### `memread`
|
|
159
|
+
|
|
160
|
+
Read a specific `viking://` URI using `abstract`, `overview`, `read`, or `auto`.
|
|
161
|
+
|
|
162
|
+
Use after `memsearch`, `memgrep`, `memglob`, or `membrowse` returns a URI.
|
|
163
|
+
|
|
164
|
+
### `membrowse`
|
|
165
|
+
|
|
166
|
+
Browse OpenViking filesystem structure with `list`, `tree`, or `stat`.
|
|
167
|
+
|
|
168
|
+
Use to discover exact URIs before reading content.
|
|
169
|
+
|
|
170
|
+
### `memcommit`
|
|
171
|
+
|
|
172
|
+
Commit the current OpenCode session to OpenViking and trigger memory extraction.
|
|
173
|
+
|
|
174
|
+
The plugin also commits at session deletion, session error, compaction, and plugin shutdown boundaries.
|
|
175
|
+
|
|
176
|
+
### `memgrep`
|
|
177
|
+
|
|
178
|
+
Pattern search through OpenViking content.
|
|
179
|
+
|
|
180
|
+
Use for exact symbols, class names, function names, error strings, or known keywords.
|
|
181
|
+
|
|
182
|
+
### `memglob`
|
|
183
|
+
|
|
184
|
+
Glob file matching through OpenViking content.
|
|
185
|
+
|
|
186
|
+
Use to enumerate files such as `**/*.py`, `**/test_*.ts`, or `**/*.md`.
|
|
187
|
+
|
|
188
|
+
### `memadd`
|
|
189
|
+
|
|
190
|
+
Add a remote URL or local file resource to OpenViking.
|
|
191
|
+
|
|
192
|
+
Remote `http(s)` URLs go directly through `POST /api/v1/resources`.
|
|
193
|
+
Local files use the safer two-step server flow: upload the file to
|
|
194
|
+
`POST /api/v1/resources/temp_upload`, then add it through
|
|
195
|
+
`POST /api/v1/resources` with the returned `temp_file_id`.
|
|
196
|
+
|
|
197
|
+
Local paths may be absolute, relative to the OpenCode project directory, or
|
|
198
|
+
`file://` URLs. Local directory upload is not supported yet.
|
|
199
|
+
|
|
200
|
+
Examples:
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
memadd path="https://example.com/spec.md" to="viking://resources/spec"
|
|
204
|
+
memadd path="./docs/notes.md" parent="viking://resources/"
|
|
205
|
+
memadd path="file:///home/alice/project/notes.md" reason="project notes"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
After adding a resource, the tool also returns `GET /api/v1/observer/queue` status.
|
|
209
|
+
|
|
210
|
+
### `memwrite`
|
|
211
|
+
|
|
212
|
+
Write text content to a `viking://` file through `POST /api/v1/content/write`.
|
|
213
|
+
|
|
214
|
+
Use this for durable notes, small project memory files, or resource text that
|
|
215
|
+
should be updated directly. The default mode is `create` to avoid accidental
|
|
216
|
+
overwrites. Use `append` to extend an existing file and `replace` only when the
|
|
217
|
+
user explicitly wants to overwrite the file.
|
|
218
|
+
|
|
219
|
+
Examples:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
memwrite uri="viking://user/memories/project-notes.md" content="# Decision\n\nUse PostgreSQL." wait=true
|
|
223
|
+
memwrite uri="viking://resources/docs/api.md" content="\n\n## New endpoint" mode="append"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### `memremove`
|
|
227
|
+
|
|
228
|
+
Remove a `viking://` URI through `DELETE /api/v1/fs`.
|
|
229
|
+
|
|
230
|
+
This tool requires `confirm: true`. The user must explicitly confirm deletion before the agent calls it.
|
|
231
|
+
|
|
232
|
+
### `memqueue`
|
|
233
|
+
|
|
234
|
+
Return OpenViking observer queue status for embedding and semantic processing.
|
|
235
|
+
|
|
236
|
+
### `codesearch`
|
|
237
|
+
|
|
238
|
+
Search AST-supported symbol names across a confirmed ingested code repository or source subtree.
|
|
239
|
+
|
|
240
|
+
Use this after you have evidence that a `viking://` URI contains supported source files.
|
|
241
|
+
|
|
242
|
+
### `codeoutline`
|
|
243
|
+
|
|
244
|
+
Show symbol structure for a confirmed `viking://` source file.
|
|
245
|
+
|
|
246
|
+
Use this after `memglob`, `membrowse`, or `codesearch` finds an exact source file URI.
|
|
247
|
+
|
|
248
|
+
### `codeexpand`
|
|
249
|
+
|
|
250
|
+
Return the full source for one named symbol from a confirmed `viking://` source file.
|
|
251
|
+
|
|
252
|
+
Use this after `codeoutline` or other evidence shows the symbol exists in that file.
|
|
253
|
+
|
|
254
|
+
## Runtime Files
|
|
255
|
+
|
|
256
|
+
The plugin writes runtime files to `~/.config/opencode/openviking/` by default:
|
|
257
|
+
|
|
258
|
+
- `openviking-memory.log`
|
|
259
|
+
- `openviking-session-map.json`
|
|
260
|
+
|
|
261
|
+
Set `runtime.dataDir` in config to override this directory.
|