opencode-haimati 1.1.4 → 1.2.0

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/README.md CHANGED
@@ -1,253 +1,99 @@
1
- # opencode-haimati
2
-
3
- 海马体记忆系统插件 - 为 OpenCode 提供基于文件系统的长期记忆存储和检索功能。
4
-
5
- ## 功能特性
6
-
7
- - 🧠 类海马体记忆机制:模拟人脑记忆系统的分类存储
8
- - 📁 树形索引结构:通过 `.haimati/索引.md` 维护记忆索引
9
- - 📚 分组书页存储:记忆内容按序号分组存储于 `.haimati/书页/` 目录
10
- - 🔍 多模式搜索:支持序号精确查询和关键字模糊搜索
11
- - ✏️ 完整 CRUD:读取、写入、更新(部分替换)、删除、移动记忆
12
- - 🔄 版本并发控制:基于 version 的乐观锁,防止多会话并发冲突
13
- - ✨ 自动增强首条提示词:自动查询 `/start-work` 命令的 template 并添加到用户首条消息前
14
- - 📋 自动记录会话结束:会话空闲时自动注入 `/record-memory` 命令提示用户记录
15
- - 🚫 用户停止保护:用户主动停止会话时不会注入提示词
16
- - 📋 日志追踪:完整的操作日志记录(按天覆盖)
17
- - ⚡ 纯异步架构:所有文件操作非阻塞执行
18
- - 🔐 文件锁机制:支持网络共享挂载时的多用户协调
19
-
20
- ## 安装
21
-
22
- ```bash
23
- npm install -g opencode-haimati
24
- #
25
- bun add -g opencode-haimati
26
- ```
27
-
28
- ## 使用方法
29
-
30
- 将插件添加到你的 `opencode.json`:
31
-
32
- ```json
33
- {
34
- "$schema": "https://opencode.ai/config.json",
35
- "plugin": ["opencode-haimati"],
36
- }
37
- ```
38
-
39
- ## 配置文件
40
-
41
- 在项目根目录创建 `opencode-haimati.conf` 配置文件:
42
-
43
- ```ini
44
- # 海马体存储路径(可选,默认 .haimati)
45
- haimati-path: .haimati
46
- ```
47
-
48
- ## 海马体结构
49
-
50
- ```
51
- .haimati/
52
- ├── .lock # 序号分配锁(支持网络共享挂载时多用户协调)
53
- ├── 索引.md # 树形结构索引
54
- ├── next-id.txt # 下一个可用序号
55
- └── 书页/ # 存储各记忆内容(按序号分组)
56
- ├── 001-050/
57
- │ ├── 001.md
58
- │ └── 002.md
59
- └── 051-100/
60
- └── ...
61
- ```
62
-
63
- **序号分组规则**:每 50 个序号划为一个分组,如 `001-050`、`051-100`。
64
-
65
- ## 可用工具
66
-
67
- | 工具 | 说明 |
68
- |------|------|
69
- | `haimati_read` | 读取记忆内容(只支持序号查询,支持分页,返回带行号和版本号) |
70
- | `haimati_write` | 写入新记忆(如果已存在相同分类和标题的记忆则报错,不允许覆盖) |
71
- | `haimati_search` | 搜索记忆内容(标题、分类、序号、书页内容,match参数必填) |
72
- | `haimati_edit` | 修改记忆内容(部分替换,行号范围 [offsetBegin, offsetEnd],offsetEnd 包括,需传入 version 并发控制) |
73
- | `haimati_move` | 修改记忆的分类路径 |
74
- | `haimati_delete` | 删除记忆(支持序号或完整路径定位) |
75
- | `haimati_list` | 列出记忆索引(支持递归遍历) |
76
-
77
- ### 工具入参说明
78
-
79
- #### haimati_read
80
- - `query`: 序号(必填),如 "086"
81
- - `offset`: 起始行号(可选,默认 1)
82
- - `limit`: 最大读取行数(可选,默认 2000)
83
-
84
- #### haimati_write
85
- - `category`: 分类路径(必填),如 "xxx项目/签章" 或 "通用"
86
- - `title`: 记忆标题(必填)
87
- - `content`: 要写入的详细内容(必填)
88
- - 注意:标题不能以 " - 序号" 格式结尾,序号由系统自动分配
89
-
90
- #### haimati_search
91
- - `keyword`: 搜索关键词(必填),支持多关键字用空格分隔
92
- - `match`: 匹配模式(必填),`and`=所有关键字都匹配,`or`=任意关键字匹配
93
- - `limit`: 返回结果数量限制(可选,默认 10)
94
- - `offset`: 分页偏移量(可选,默认 0)
95
-
96
- #### haimati_edit
97
- - `query`: 序号(必填)
98
- - `offsetBegin`: 起始行号(包括)
99
- - `offsetEnd`: 结束行号(包括)
100
- - `content`: 替换内容
101
- - `version`: read 时返回的 version,用于并发控制(必填)
102
-
103
- #### haimati_delete
104
- - `query`: 序号或完整路径(必填)
105
-
106
- #### haimati_move
107
- - `query`: 序号或完整路径(必填)
108
- - `newCategory`: 新的分类路径(必填)
109
-
110
- #### haimati_list
111
- - `category`: 可选的分类路径
112
- - `recursive`: 是否递归遍历子分类(可选,默认 false)
113
-
114
- ## 海马体三大原则
115
-
116
- 1. **信息不丢失**: 完整保留所有有价值的信息
117
- 2. **错误信息修正**: 不再保留已被纠正的错误信息
118
- 3. **拒绝冗余**: 不要重复记录相同内容
119
-
120
- ## 使用示例
121
-
122
- ```typescript
123
- // 写入新记忆
124
- // 注意:title 不能以 " - 序号" 格式结尾(如 " - 001"),序号由系统自动分配
125
- haimati_write({
126
- category: "xxx项目/签章",
127
- title: "签章服务WS通信机制", // ✓ 正确
128
- // title: "签章服务WS通信机制 - 001", // ✗ 错误,会报错
129
- content: "WebSocket通信采用base64编码..."
130
- })
131
-
132
- // 读取记忆(只支持序号查询)
133
- haimati_read({ query: "086" })
134
-
135
- // 分页读取
136
- haimati_read({ query: "086", offset: 10, limit: 50 })
137
-
138
- // 搜索记忆
139
- haimati_search({ keyword: "WebSocket", match: "or", limit: 10 })
140
-
141
- // 部分修改记忆(注意:offsetEnd 不包括此行,[3, 5) 表示替换第 3、4 两行)
142
- // 先用 haimati_read 获取 version,然后传入进行并发控制
143
- haimati_edit({
144
- query: "086",
145
- offsetBegin: 3,
146
- offsetEnd: 5, // 不包括第 5 行
147
- content: "新的替换内容",
148
- version: 1 // 从 haimati_read 获取的 version
149
- })
150
-
151
- // 移动记忆到新分类
152
- haimati_move({
153
- query: "086",
154
- newCategory: "xxx项目/客户端"
155
- })
156
-
157
- // 删除记忆(支持序号或完整路径)
158
- haimati_delete({ query: "086" })
159
- // 或
160
- haimati_delete({ query: "xxx项目/签章/签章服务WS通信机制" })
161
-
162
- // 列出所有记忆
163
- haimati_list({})
164
-
165
- // 列出指定分类下的直接子分类和条目
166
- haimati_list({ category: "xxx项目" })
167
-
168
- // 递归列出指定分类下所有后代条目
169
- haimati_list({ category: "xxx项目", recursive: true })
170
- ```
171
-
172
- ### 并发控制示例
173
-
174
- haimati_edit 使用 version 进行并发控制,防止多会话同时修改导致数据丢失:
175
-
176
- ```
177
- 会话A: haimati_read({ query: "086" }) → version:1
178
- 会话B: haimati_read({ query: "086" }) → version:1
179
- 会话A: haimati_edit({ query: "086", ..., version:1 }) → 成功,version变为2
180
- 会话B: haimati_edit({ query: "086", ..., version:1 }) → 错误:版本冲突
181
- ```
182
-
183
- ## 索引格式示例
184
-
185
- ```
186
- xxx项目/
187
- ├── 签章/
188
- │ └── 签章服务WS通信机制 - 086
189
- └── 通用/
190
- └── 用户注册密码 - 033
191
- ```
192
-
193
- ## 书页文件格式
194
-
195
- ```
196
- 正文内容第一行
197
- 正文内容第二行
198
- 正文内容第三行
199
- ------system------
200
- 标题
201
- 创建时间 (ISO 8601)
202
- version:1
203
- ```
204
-
205
- 最后4行是系统行:分隔符、标题、创建时间、版本号。
206
-
207
- 系统会自动兼容旧格式书页文件(标题在正文之前或最旧格式)。
208
-
209
- ## 依赖要求
210
-
211
- - OpenCode v0.15.0 或更高版本
212
- - Node.js 或 Bun 运行时
213
- - 项目目录的文件系统写入权限
214
-
215
- ## 日志
216
-
217
- 日志文件位于:`{系统临时目录}/haimati_logs/haimati.log`
218
-
219
- 日志按天覆盖,新的一天开始时覆盖旧日志。日志内容超长时自动截断(保留前后各一部分)。
220
-
221
- **日志格式**:
222
- ```
223
- [时间戳] [级别] 消息
224
-
225
- 例如:
226
- [14:30:25] [INFO] [haimati_write] 入参: category="通用", title="测试记忆"
227
- [14:30:26] [INFO] [haimati_write] 出参:
228
- 已写入海马体 #001
229
- 路径: 通用/测试记忆
230
- 版本: 1
231
- ```
232
-
233
- **日志级别**:DEBUG、INFO、WARN、ERROR
234
-
235
- ## 自动增强与记录
236
-
237
- ### 首条提示词增强
238
-
239
- 插件会在会话开始时自动增强用户发送的第一条消息:
240
- - 查找 `/start-work` 命令的 template
241
- - 如果存在,将 template 添加到用户消息前面
242
- - 只增强首条消息,后续消息不受影响
243
-
244
- ### 会话结束记录
245
-
246
- 会话空闲时,插件会自动注入 `/record-memory` 命令提示用户记录:
247
- - 只有当 `/record-memory` 命令存在且有 template 时才会注入
248
- - 如果用户主动停止会话,不会注入提示词
249
- - 使用内存集合跟踪已注入的会话,防止重复注入
250
-
251
- ## 许可证
252
-
253
- MIT
1
+ # opencode-haimati
2
+
3
+ 为 OpenCode 提供基于文件系统的长期记忆存储和检索功能。
4
+
5
+ ## 功能特性
6
+
7
+ - 类海马体记忆机制:模拟人脑记忆系统的分类存储
8
+ - 树形索引结构 + 分组书页存储
9
+ - 多模式搜索:序号精确查询 + 关键字模糊搜索
10
+ - 完整 CRUD:读取、写入、更新、删除、移动
11
+ - 版本并发控制:基于 version 的乐观锁
12
+ - 自动增强首条提示词 + 会话空闲时自动提示记录
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install -g opencode-haimati
18
+ #
19
+ bun add -g opencode-haimati
20
+ ```
21
+
22
+ ## 配置
23
+
24
+ `opencode.json` 中添加插件:
25
+
26
+ ```json
27
+ {
28
+ "$schema": "https://opencode.ai/config.json",
29
+ "plugin": ["opencode-haimati"]
30
+ }
31
+ ```
32
+
33
+ 在项目根目录创建 `opencode-haimati.conf`(可选):
34
+
35
+ ```ini
36
+ haimati-path: .haimati
37
+ ```
38
+
39
+ ## 目录结构
40
+
41
+ ```
42
+ .haimati/
43
+ ├── .lock # 文件锁(支持网络共享挂载多用户协调)
44
+ ├── 索引.md # 树形索引
45
+ ├── next-id.txt # 下一个序号
46
+ └── 书页/ # 记忆内容(每50个序号一分组)
47
+ ```
48
+
49
+ ## 工具
50
+
51
+ | 工具 | 说明 |
52
+ |------|------|
53
+ | `haimati_read` | 读取记忆(序号查询,支持分页) |
54
+ | `haimati_write` | 写入记忆(不允许覆盖已存在) |
55
+ | `haimati_search` | 搜索(标题/分类/内容,match必填) |
56
+ | `haimati_edit` | 部分修改(需 version 并发控制) |
57
+ | `haimati_move` | 修改分类路径 |
58
+ | `haimati_delete` | 删除记忆 |
59
+ | `haimati_list` | 列出索引 |
60
+
61
+ ## 使用示例
62
+
63
+ ```typescript
64
+ // 写入(title 不能以 " - 序号" 结尾)
65
+ haimati_write({ category: "xxx项目/签章", title: "签章服务WS通信机制", content: "..." })
66
+
67
+ // 读取
68
+ haimati_read({ query: "086" })
69
+
70
+ // 搜索
71
+ haimati_search({ keyword: "WebSocket", match: "or" })
72
+
73
+ // 修改(先 read 获取 version)
74
+ haimati_edit({ query: "086", offsetBegin: 3, offsetEnd: 5, content: "新内容", version: 1 })
75
+
76
+ // 移动
77
+ haimati_move({ query: "086", newCategory: "xxx项目/客户端" })
78
+
79
+ // 删除
80
+ haimati_delete({ query: "086" })
81
+
82
+ // 列出
83
+ haimati_list({ category: "xxx项目", recursive: true })
84
+ ```
85
+
86
+ ## 海马体三大原则
87
+
88
+ 1. **信息不丢失**: 完整保留所有有价值的信息
89
+ 2. **错误信息修正**: 不再保留已被纠正的错误信息
90
+ 3. **拒绝冗余**: 不要重复记录相同内容
91
+
92
+ ## 日志
93
+
94
+ 日志位于:`{系统临时目录}/haimati_logs/haimati.log`(按天覆盖)
95
+
96
+ ## 依赖
97
+
98
+ - OpenCode v0.15.0+
99
+ - Node.js 或 Bun
package/dist/index.js CHANGED
@@ -1,90 +1,90 @@
1
- import{tool as I}from"@opencode-ai/plugin";import M from"path";import At from"os";import H from"fs";var B=".haimati",dt="\u7D22\u5F15.md";var ut="next-id.txt",mt="haimati.log";var gt="opencode-haimati.conf",ht="haimati-path";var O="/start-work";var G="/record-memory";function Ft(e){let o=M.join(e,gt);if(!H.existsSync(o))return null;try{let l=H.readFileSync(o,"utf-8").split(`
2
- `);for(let t of l){let i=t.trim();if(!i||i.startsWith("#"))continue;let c=i.match(/^([^:]+):\s*(.+)$/);if(c){let s=c[1].trim(),a=c[2].trim();if(s===ht&&a){let u=a.match(/^\$\{(\w+)\}$/);if(u){let f=process.env[u[1]];return f?M.resolve(e,f):(console.warn(`[haimati] \u73AF\u5883\u53D8\u91CF ${u[1]} \u672A\u5B9A\u4E49\u6216\u503C\u4E3A\u7A7A`),null)}return M.resolve(e,a)}}}}catch(n){console.error("[haimati] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:",n)}return null}function k(e){let o=Ft(e);return o||M.join(e,B)}function D(e){return M.join(k(e),dt)}function J(e){return M.join(k(e),ut)}function rt(e){return M.join(k(e),".lock")}function st(e){return M.join(k(e),"\u4E66\u9875")}function j(e,o){let n=parseInt(o,10),l=Math.floor((n-1)/50)*50+1,t=l+50-1,i=`${String(l).padStart(3,"0")}-${String(t).padStart(3,"0")}`;return M.join(st(e),i)}function K(e,o){let n=String(parseInt(o,10)).padStart(3,"0");return M.join(j(e,o),`${n}.md`)}function pt(){let e=At.tmpdir();return M.join(e,"haimati_logs",mt)}function L(e){return H.promises.mkdir(e,{recursive:!0}).then(()=>{})}function x(e){return H.promises.access(e).then(()=>!0).catch(()=>!1)}import wt from"fs";import Ot from"path";import{promisify as yt}from"util";var $t=yt(wt.readFile),jt=yt(wt.writeFile);function z(e){let o=0,n=0,l=e.length;for(;n<l;)if(e[n]==="\u2502"&&n+3<l&&e.slice(n+1,n+4)===" ")o++,n+=4;else if(e.slice(n,n+4)===" ")o++,n+=4;else{if((e[n]==="\u251C"||e[n]==="\u2514")&&n+3<l&&e.slice(n+1,n+4)==="\u2500\u2500 ")break;break}return o}function U(e){let n=e.trim().replace(/^[│├└─\s]+/,"").trim();return n==="/"?"/":!n.endsWith("/")||(n=n.slice(0,-1),!n)?null:n}function Rt(e){let o=[],n=e.split(`
3
- `),l=[];for(let t of n){if(!t.trim())continue;let i=z(t),c=t.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/);if(c){let s=c[1].trim(),a=String(parseInt(c[2],10)),f=l.slice(0,i).filter(d=>d!=="").join("/");o.push({id:a,category:f,title:s})}else{let s=U(t);if(s)if(s==="/"){l[i]="";for(let a=i+1;a<l.length;a++)delete l[a]}else{l[i]=s;for(let a=i+1;a<l.length;a++)delete l[a]}}}return o}function R(e,o){return e.find(n=>n.id===o)||null}function V(e,o,n){return e.find(l=>l.category===o&&l.title===n)||null}function xt(e,o){return e.filter(n=>n.id!==o)}function ot(e){if(e.length===0)return"";let o={name:"/",children:[],entry:null};for(let t of e){let i=t.category.split("/"),c=o;for(let a=0;a<i.length;a++){let u=i[a];if(!u)continue;let f=c.children.find(d=>d.name===u);f||(f={name:u,children:[],entry:null},c.children.push(f)),c=f}let s={name:t.id,children:[],entry:t};c.children.push(s)}function n(t){t.children.sort((i,c)=>i.name.localeCompare(c.name,void 0,{sensitivity:"base"}));for(let i of t.children)n(i)}n(o);function l(t,i,c){let s=[],a=i+(c?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 "),u=t.name==="/"?"/":t.name+"/";s.push(`${a}${u}`),i=i+(c?" ":"\u2502 ");let f=t.children.filter(m=>m.entry===null),d=t.children.filter(m=>m.entry!==null),h=[...f,...d];for(let m=0;m<h.length;m++){let g=h[m],w=m===h.length-1;if(g.entry){let p=g.entry.id.padStart(3,"0"),E=i+(w?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ");s.push(`${E}${g.entry.title} - ${p}`)}else s.push(...l(g,i,w))}return s}return l(o,"",!0).join(`
4
- `)}async function C(e){let o=D(e);if(!await x(o))return[];let n=await $t(o,"utf-8");return Rt(n)}async function W(e,o){let n=Ot.join(e,B);await x(n)||await L(n);let l=ot(o),t=D(e);await jt(t,l,"utf-8")}async function It(e){let o=D(e);return await x(o)?$t(o,"utf-8"):""}import Y from"fs";import{promisify as X}from"util";var Wt=X(Y.readFile),qt=X(Y.writeFile),Bt=X(Y.unlink),Et=X(Y.mkdir);async function N(e,o){let n=K(e,o);if(!await x(n))return null;let t=(await Wt(n,"utf-8")).split(`
5
- `);if(t.length<4)return null;let i="------system------",c=Math.max(0,t.length-5),s=-1;for(let m=t.length-1;m>=c;m--)if(t[m].trim()===i){s=m;break}if(s===-1){if(t.length>=3&&t[2].startsWith("version:")&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(t[1])){let p=t[0],E=t[1],y=parseInt(t[2].substring(8).trim(),10)||1,_=t.slice(3).join(`
6
- `);return{title:p,createdAt:E,content:_,version:y}}let g=t[0],w=t.join(`
7
- `);return{title:g,createdAt:"",content:w,version:1}}if(s+3>=t.length)return null;let a=t.slice(0,s).join(`
8
- `),u=t[s+1],f=t[s+2],d=t[s+3],h=parseInt(d.substring(8).trim(),10)||1;return{title:u,createdAt:f,content:a,version:h}}async function q(e,o,n,l,t,i=1){let c=st(e);await x(c)||await Et(c,{recursive:!0});let s=j(e,o);await x(s)||await Et(s,{recursive:!0});let a=K(e,o),f=`------system------
1
+ import{tool as x}from"@opencode-ai/plugin";import E from"path";import It from"os";import F from"fs";var U=".haimati",ht="\u7D22\u5F15.md";var pt="next-id.txt",wt="info.log";var yt="log.conf";var $t="opencode-haimati.conf",xt="haimati-path";var O="/start-work";var K="/record-memory";function zt(t){let r=E.join(t,$t);if(!F.existsSync(r))return null;try{let a=F.readFileSync(r,"utf-8").split(`
2
+ `);for(let e of a){let i=e.trim();if(!i||i.startsWith("#"))continue;let l=i.match(/^([^:]+):\s*(.+)$/);if(l){let s=l[1].trim(),c=l[2].trim();if(s===xt&&c){let g=c.match(/^\$\{(\w+)\}$/);if(g){let d=process.env[g[1]];return d?E.resolve(t,d):(console.warn(`[haimati] \u73AF\u5883\u53D8\u91CF ${g[1]} \u672A\u5B9A\u4E49\u6216\u503C\u4E3A\u7A7A`),null)}return E.resolve(t,c)}}}}catch(n){console.error("[haimati] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25:",n)}return null}function C(t){let r=zt(t);return r||E.join(t,U)}function _(t){return E.join(C(t),ht)}function V(t){return E.join(C(t),pt)}function ct(t){return E.join(C(t),".lock")}function lt(t){return E.join(C(t),"\u4E66\u9875")}function R(t,r){let n=parseInt(r,10),a=Math.floor((n-1)/50)*50+1,e=a+50-1,i=`${String(a).padStart(3,"0")}-${String(e).padStart(3,"0")}`;return E.join(lt(t),i)}function z(t,r){let n=String(parseInt(r,10)).padStart(3,"0");return E.join(R(t,r),`${n}.md`)}function q(){let t=It.homedir();return E.join(t,".opencode-haimati","log")}function Xt(){let t=It.homedir();return E.join(t,".opencode-haimati",yt)}function X(){return E.join(q(),wt)}function dt(){let t=Xt(),r={level:"info",logRetentionDays:180};if(!F.existsSync(t))return r;try{let a=F.readFileSync(t,"utf-8").split(`
3
+ `),e=r.level,i=r.logRetentionDays;for(let l of a){let s=l.trim();if(!s||s.startsWith("#"))continue;let c=s.match(/^([^:]+):\s*(.+)$/);if(c){let g=c[1].trim(),d=c[2].trim();if(g==="level")["debug","info","warn","error"].includes(d)&&(e=d);else if(g==="log_retention_days"){let f=parseInt(d,10);!isNaN(f)&&f>0&&(i=f)}}}return{level:e,logRetentionDays:i}}catch(n){return console.error("[haimati] \u8BFB\u53D6\u65E5\u5FD7\u914D\u7F6E\u5931\u8D25:",n),r}}function L(t){return F.promises.mkdir(t,{recursive:!0}).then(()=>{})}function w(t){return F.promises.access(t).then(()=>!0).catch(()=>!1)}import bt from"fs";import Qt from"path";import{promisify as St}from"util";var Et=St(bt.readFile),Zt=St(bt.writeFile);function Q(t){let r=0,n=0,a=t.length;for(;n<a;)if(t[n]==="\u2502"&&n+3<a&&t.slice(n+1,n+4)===" ")r++,n+=4;else if(t.slice(n,n+4)===" ")r++,n+=4;else{if((t[n]==="\u251C"||t[n]==="\u2514")&&n+3<a&&t.slice(n+1,n+4)==="\u2500\u2500 ")break;break}return r}function Z(t){let n=t.trim().replace(/^[│├└─\s]+/,"").trim();return n==="/"?"/":!n.endsWith("/")||(n=n.slice(0,-1),!n)?null:n}function te(t){let r=[],n=t.split(`
4
+ `),a=[];for(let e of n){if(!e.trim())continue;let i=Q(e),l=e.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/);if(l){let s=l[1].trim(),c=String(parseInt(l[2],10)),d=a.slice(0,i).filter(f=>f!=="").join("/");r.push({id:c,category:d,title:s})}else{let s=Z(e);if(s)if(s==="/"){a[i]="";for(let c=i+1;c<a.length;c++)delete a[c]}else{a[i]=s;for(let c=i+1;c<a.length;c++)delete a[c]}}}return r}function G(t,r){return t.find(n=>n.id===r)||null}function tt(t,r,n){return t.find(a=>a.category===r&&a.title===n)||null}function Pt(t,r){return t.filter(n=>n.id!==r)}function ft(t){if(t.length===0)return"";let r={name:"/",children:[],entry:null};for(let e of t){let i=e.category.split("/"),l=r;for(let c=0;c<i.length;c++){let g=i[c];if(!g)continue;let d=l.children.find(f=>f.name===g);d||(d={name:g,children:[],entry:null},l.children.push(d)),l=d}let s={name:e.id,children:[],entry:e};l.children.push(s)}function n(e){e.children.sort((i,l)=>i.name.localeCompare(l.name,void 0,{sensitivity:"base"}));for(let i of e.children)n(i)}n(r);function a(e,i,l){let s=[],c=i+(l?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 "),g=e.name==="/"?"/":e.name+"/";s.push(`${c}${g}`),i=i+(l?" ":"\u2502 ");let d=e.children.filter(u=>u.entry===null),f=e.children.filter(u=>u.entry!==null),p=[...d,...f];for(let u=0;u<p.length;u++){let m=p[u],y=u===p.length-1;if(m.entry){let h=m.entry.id.padStart(3,"0"),b=i+(y?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ");s.push(`${b}${m.entry.title} - ${h}`)}else s.push(...a(m,i,y))}return s}return a(r,"",!0).join(`
5
+ `)}async function D(t){let r=_(t);if(!await w(r))return[];let n=await Et(r,"utf-8");return te(n)}async function H(t,r){let n=Qt.join(t,U);await w(n)||await L(n);let a=ft(r),e=_(t);await Zt(e,a,"utf-8")}async function _t(t){let r=_(t);return await w(r)?Et(r,"utf-8"):""}import et from"fs";import{promisify as nt}from"util";var ee=nt(et.readFile),ne=nt(et.writeFile),re=nt(et.unlink),Dt=nt(et.mkdir);async function k(t,r){let n=z(t,r);if(!await w(n))return null;let e=(await ee(n,"utf-8")).split(`
6
+ `);if(e.length<4)return null;let i="------system------",l=Math.max(0,e.length-5),s=-1;for(let u=e.length-1;u>=l;u--)if(e[u].trim()===i){s=u;break}if(s===-1){if(e.length>=3&&e[2].startsWith("version:")&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e[1])){let h=e[0],b=e[1],$=parseInt(e[2].substring(8).trim(),10)||1,M=e.slice(3).join(`
7
+ `);return{title:h,createdAt:b,content:M,version:$}}let m=e[0],y=e.join(`
8
+ `);return{title:m,createdAt:"",content:y,version:1}}if(s+3>=e.length)return null;let c=e.slice(0,s).join(`
9
+ `),g=e[s+1],d=e[s+2],f=e[s+3],p=parseInt(f.substring(8).trim(),10)||1;return{title:g,createdAt:d,content:c,version:p}}async function B(t,r,n,a,e,i=1){let l=lt(t);await w(l)||await Dt(l,{recursive:!0});let s=R(t,r);await w(s)||await Dt(s,{recursive:!0});let c=z(t,r),d=`------system------
9
10
  ${n}
10
- ${l}
11
- version:${i}`,d=t?`${t}
12
- ${f}`:f;await qt(a,d,"utf-8")}async function St(e,o){let n=K(e,o);return await x(n)?(await Bt(n),!0):!1}async function Q(e,o,n,l,t=!1){let i=o.toLowerCase().split(/\s+/).filter(s=>s.length>0);if(i.length===0)return[];let c=[];for(let s of e){let a=s.title.toLowerCase(),u=s.category.toLowerCase(),f=s.id.toLowerCase(),d=0,h=0;for(let g of i)(a.includes(g)||u.includes(g)||f.includes(g))&&d++;if(t&&l){let g=await N(l,s.id);if(g&&g.content){let w=g.content.toLowerCase();for(let p of i)w.includes(p)&&h++}}let m=d+h;n==="and"?m>=i.length&&c.push({entry:s,score:m}):(d>0||t&&h>0)&&c.push({entry:s,score:m})}return c.sort((s,a)=>a.score-s.score),c.map(s=>s.entry)}import Dt from"fs";import{promisify as Ct}from"util";import Pt from"fs";import{promisify as bt}from"util";var Ht=bt(Pt.writeFile),Jt=bt(Pt.unlink);async function _t(e){let o=k(e);await x(o)||await L(o);let n=rt(e),l=Date.now(),t=50+Math.random()*20;for(;await x(n);){if(Date.now()-l>5e3)return!1;await new Promise(i=>setTimeout(i,t))}return await Ht(n,String(process.pid),"utf-8"),!0}async function Mt(e){let o=rt(e);await x(o)&&await Jt(o)}import ct from"fs";import Kt from"path";import{promisify as lt}from"util";var zt=lt(ct.appendFile),Ut=lt(ct.writeFile),Vt=lt(ct.stat);function $(e,o=5e3){if(e.length<=o)return e;let n=Math.floor((o-20)/2);return e.substring(0,n)+"...(\u7701\u7565"+(e.length-o)+"\u5B57\u7B26)..."+e.substring(e.length-n)}async function Yt(e){try{let o=new Date,n=o.toLocaleDateString("zh-CN"),l=o.toLocaleTimeString("zh-CN",{hour12:!1}),t=pt(),i=Kt.dirname(t);await x(i)||await L(i);let c=!1;await x(t)&&(await Vt(t)).mtime.toLocaleDateString("zh-CN")!==n&&(c=!0);let s=`[${l}] ${e}`;c?await Ut(t,s+`
13
- `,"utf-8"):await zt(t,s+`
14
- `,"utf-8")}catch(o){console.error("[haimati] \u5199\u5165\u65E5\u5FD7\u6587\u4EF6\u5931\u8D25:",o)}}async function r(e,o){await Yt(`[${e.toUpperCase()}] ${o}`)}var Xt=Ct(Dt.readFile),Qt=Ct(Dt.writeFile);async function Zt(e){let o=J(e);if(!await x(o))return 1;let l=(await Xt(o,"utf-8")).trim(),t=parseInt(l,10);return!isNaN(t)&&t>0?t:1}async function te(e){let o=J(e);if(await x(o))return;let n=await C(e),l=0;for(let t of n){let i=parseInt(t.id,10);i>l&&(l=i)}await kt(e,l+1)}async function kt(e,o){let n=k(e);await x(n)||await L(n);let l=J(e);await Qt(l,String(o),"utf-8")}async function Lt(e,o,n,l,t,i=!1){if(/ - \d{3}$/.test(n))throw await r("warn",`[allocateIdWithLock] title \u683C\u5F0F\u4E0D\u5408\u89C4: "${n}", \u629B\u51FA\u9519\u8BEF`),new Error('\u6807\u9898\u4E0D\u80FD\u4EE5 " - \u5E8F\u53F7" \u683C\u5F0F\u7ED3\u5C3E\uFF0C\u5E8F\u53F7\u7531\u7CFB\u7EDF\u81EA\u52A8\u5206\u914D\uFF0C\u8BF7\u4FEE\u6539\u6807\u9898');if(await r("info",`[allocateIdWithLock] \u5F00\u59CB\u5206\u914D\u5E8F\u53F7: category="${o}", title="${n}"`),!await _t(e))return await r("warn",`[allocateIdWithLock] \u83B7\u53D6\u9501\u5931\u8D25: category="${o}", title="${n}"`),null;await r("debug",`[allocateIdWithLock] \u83B7\u53D6\u9501\u6210\u529F: category="${o}", title="${n}"`);try{await te(e);let c=await C(e),s=c.find(d=>d.category===o&&d.title===n);if(s){if(!i)throw new Error(`\u8BB0\u5FC6\u5DF2\u5B58\u5728: ${o}/${n}\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u4F7F\u7528 haimati_edit \u5DE5\u5177`);let d=await N(e,s.id),h=d?d.createdAt:l,m=d?d.version+1:1;return await q(e,s.id,n,h,t,m),await r("info",`[allocateIdWithLock] \u66F4\u65B0\u5DF2\u6709\u6761\u76EE: #${s.id} ${o}/${n}, \u65B0\u7248\u672C: ${m}`),null}let a=await Zt(e),u=String(a).padStart(3,"0");await q(e,u,n,l,t,1);let f={id:u,category:o,title:n};return c.push(f),await W(e,c),await kt(e,a+1),await r("info",`[allocateIdWithLock] \u5206\u914D\u5E8F\u53F7\u6210\u529F: #${u} ${o}/${n}`),u}catch(c){let s=c instanceof Error?c.message:String(c);if(await r("error",`[allocateIdWithLock] \u5206\u914D\u5E8F\u53F7\u5931\u8D25: ${s}`),s.includes("\u8BB0\u5FC6\u5DF2\u5B58\u5728"))throw c;return null}finally{await Mt(e)}}function Nt(){return{haimati_read:I({description:"\u4ECE\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u8BFB\u53D6\u5185\u5BB9\u3002\u901A\u8FC7\u5E8F\u53F7\uFF08\u5982 '086'\uFF09\u6765\u5B9A\u4F4D\u5E76\u8BFB\u53D6\u8BB0\u5FC6\u5185\u5BB9\u3002\u652F\u6301\u5206\u9875\u8BFB\u53D6\uFF08offset/limit\uFF09\uFF0C\u8FD4\u56DE\u5185\u5BB9\u5E26\u884C\u53F7\u548C\u7248\u672C\u53F7\u3002",args:{query:I.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'"),offset:I.schema.number().optional().default(1).describe("\u8D77\u59CB\u884C\u53F7\uFF08\u9ED8\u8BA4 1\uFF09"),limit:I.schema.number().optional().default(2e3).describe("\u6700\u5927\u8BFB\u53D6\u884C\u6570\uFF08\u9ED8\u8BA4 2000\uFF09")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_read] \u5165\u53C2: query="${e.query}", offset=${e.offset||1}, limit=${e.limit||2e3}`),!await x(l)){let t=`\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728\u4E8E ${l}`;return await r("warn",`[haimati_read] \u51FA\u53C2:
15
- ${$(t)}`),t}try{let t=await C(n);await r("debug",`[haimati_read] \u8BFB\u53D6\u7D22\u5F15: \u5171 ${t.length} \u6761\u8BB0\u5F55`);let i=e.query.trim();if(!/^\d+$/.test(i)){let y="\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";return await r("warn",`[haimati_read] \u51FA\u53C2:
16
- ${$(y)}`),y}let c=String(parseInt(i,10)),s=R(t,c);if(await r("debug",`[haimati_read] \u5E8F\u53F7\u67E5\u8BE2 #${i}: ${s?"\u627E\u5230":"\u672A\u627E\u5230"}`),!s){let y=`\u672A\u627E\u5230\u8BB0\u5FC6: ${e.query}`;return await r("info",`[haimati_read] \u51FA\u53C2:
17
- ${$(y)}`),y}let a=await N(n,s.id);if(!a){let y=`\u672A\u627E\u5230\u4E66\u9875: #${s.id.padStart(3,"0")}`;return await r("error",`[haimati_read] \u51FA\u53C2:
18
- ${$(y)}`),y}let u=j(n,s.id);await r("debug",`[haimati_read] \u8BFB\u53D6\u4E66\u9875: \u4E66\u9875/${u.split(/[\\/]/).pop()}/${s.id}.md, version=${a.version}`);let f=a.content.split(`
19
- `),d=e.offset||1,h=e.limit||2e3,m=f.length,g=Math.max(0,d-1),w=Math.min(m,g+h),p=[];p.push(`version:${a.version}`);for(let y=g;y<w;y++)p.push(`${y+1}|${f[y]}`);let E=p.join(`
20
- `);return await r("info",`[haimati_read] \u51FA\u53C2:
21
- ${$(E)}`),E}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_read] \u51FA\u53C2: \u9519\u8BEF: ${i}
22
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}}),haimati_write:I({description:"\u5C06\u65B0\u4FE1\u606F\u5199\u5165\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u3002\u9700\u8981\u63D0\u4F9B\u5206\u7C7B\u8DEF\u5F84\uFF08\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0'\uFF09\u3001\u6807\u9898\u548C\u5185\u5BB9\u3002\u5982\u679C\u76F8\u540C\u5206\u7C7B\u548C\u6807\u9898\u7684\u8BB0\u5FC6\u5DF2\u5B58\u5728\uFF0C\u5219\u4F1A\u62A5\u9519\u3002",args:{category:I.schema.string().describe("\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0' \u6216 '\u901A\u7528'"),title:I.schema.string().describe("\u8BB0\u5FC6\u6807\u9898\uFF0C\u5982 '\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236'"),content:I.schema.string().describe("\u8981\u5199\u5165\u7684\u8BE6\u7EC6\u5185\u5BB9")},async execute(e,o){let{directory:n}=o;await r("info",`[haimati_write] \u5165\u53C2: category="${e.category}", title="${e.title}", content\u957F\u5EA6=${e.content.length}\u5B57\u7B26, content=
23
- ${$(e.content)}
24
- `);try{let l=new Date().toLocaleString("zh-CN",{hour12:!1}),t=null;for(let a=0;a<3;a++)try{if(t=await Lt(n,e.category,e.title,l,e.content,!1),t)break;await r("warn",`[haimati_write] \u9501\u83B7\u53D6\u5931\u8D25\uFF0C\u91CD\u8BD5\u7B2C ${a+1} \u6B21`)}catch(u){let f=u instanceof Error?u.message:String(u);if(f.includes("\u8BB0\u5FC6\u5DF2\u5B58\u5728"))throw u;await r("warn",`[haimati_write] \u83B7\u53D6\u9501\u5F02\u5E38: ${f}, \u91CD\u8BD5\u7B2C ${a+1} \u6B21`)}if(t){let a=j(n,t);await r("debug",`[haimati_write] \u5206\u914D\u65B0\u5E8F\u53F7: #${t}`),await r("debug",`[haimati_write] \u4E66\u9875\u548C\u7D22\u5F15\u5DF2\u66F4\u65B0: \u4E66\u9875/${a.split(/[\\/]/).pop()}/${t}.md`);let u=`\u5DF2\u5199\u5165\u6D77\u9A6C\u4F53 #${t}
25
- \u8DEF\u5F84: ${e.category}/${e.title}
26
- \u7248\u672C: 1`;return await r("info",`[haimati_write] \u51FA\u53C2:
27
- ${$(u)}`),u}let i=await C(n),c=V(i,e.category,e.title);if(c){let a=`\u9519\u8BEF\uFF1A\u8BB0\u5FC6\u5DF2\u5B58\u5728 #${c.id} (${e.category}/${e.title})\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u4F7F\u7528 haimati_edit \u5DE5\u5177`;return await r("error",`[haimati_write] \u51FA\u53C2:
28
- ${$(a)}`),a}let s="\u9519\u8BEF\uFF1A\u65E0\u6CD5\u5206\u914D\u5E8F\u53F7\uFF08\u9501\u7B49\u5F85\u8D85\u65F6\uFF09";return await r("error",`[haimati_write] \u51FA\u53C2:
29
- ${$(s)}`),s}catch(l){let t=l instanceof Error?l.message:String(l),i=l instanceof Error?l.stack:"";return await r("error",`[haimati_write] \u51FA\u53C2: \u9519\u8BEF: ${t}
30
- \u5806\u6808: ${i}`),`\u9519\u8BEF: ${t}`}}}),haimati_search:I({description:"\u641C\u7D22\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09\u3002\u641C\u7D22\u8303\u56F4\u5305\u62EC\uFF1A\u6807\u9898\u3001\u5206\u7C7B\u3001\u5E8F\u53F7\u3001\u4E66\u9875\u5185\u5BB9\u3002\u8F93\u5165\u5173\u952E\u8BCD\uFF0C\u8FD4\u56DE\u5339\u914D\u7684\u6761\u76EE\u5217\u8868\u548C\u5185\u5BB9\u7247\u6BB5\uFF0C\u652F\u6301\u5206\u9875\uFF08limit/offset\uFF09\u3002",args:{keyword:I.schema.string().describe("\u641C\u7D22\u5173\u952E\u8BCD\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09"),match:I.schema.string().describe("\u5339\u914D\u6A21\u5F0F\uFF1Aand=\u6240\u6709\u5173\u952E\u5B57\u90FD\u5339\u914D\uFF0Cor=\u4EFB\u610F\u5173\u952E\u5B57\u5339\u914D"),limit:I.schema.number().default(10).describe("\u8FD4\u56DE\u7ED3\u679C\u6570\u91CF\u9650\u5236"),offset:I.schema.number().default(0).describe("\u5206\u9875\u504F\u79FB\u91CF\uFF0C\u7528\u4E8E\u83B7\u53D6\u540E\u7EED\u9875\u9762")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_search] \u5165\u53C2: keyword="${e.keyword}", match="${e.match}", limit=${e.limit||10}, offset=${e.offset||0}`),!await x(l)){let t="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await r("warn",`[haimati_search] \u51FA\u53C2:
31
- ${$(t)}`),t}try{let t=await C(n),i=e.keyword.trim(),c=e.match,s=e.limit||10,a=e.offset||0,u=await Q(t,i,c,n,!0),f=u.length,d=u.slice(a,a+s);if(d.length===0){let p=`\u672A\u627E\u5230\u5305\u542B '${i}' \u7684\u8BB0\u5FC6`;return await r("info",`[haimati_search] \u51FA\u53C2:
32
- ${$(p)}`),p}let h=[],m=a+d.length<f,g=m?`${a+1}-${a+d.length}/${f}`:`${a+1}-${a+d.length}/${f}`;h.push(`\u627E\u5230 ${g} \u6761\u5339\u914D\uFF1A
33
- `),m&&h.push(`\uFF08\u5982\u9700\u83B7\u53D6\u66F4\u591A\uFF0C\u8BF7\u4F7F\u7528 offset=${a+s} \u7EE7\u7EED\u7FFB\u9875\uFF09
34
- `);for(let p of d){let E=await N(n,p.id),y=`${p.category}/${p.title}`,_="";E&&(_=E.content.split(`
35
- `).filter(tt=>tt.trim()).slice(0,3).join(" | ").substring(0,150),_.length===150&&(_+="...")),h.push(`## ${y} [${p.id}]`),_&&h.push(`> ${_}`),h.push("")}let w=h.join(`
36
- `);return await r("info",`[haimati_search] \u51FA\u53C2:
37
- ${$(w)}`),w}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_search] \u51FA\u53C2: \u9519\u8BEF: ${i}
38
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}}),haimati_edit:I({description:"\u4FEE\u6539\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7684\u90E8\u5206\u5185\u5BB9\u3002\u5C06\u6307\u5B9A\u884C\u53F7\u8303\u56F4 [offsetBegin, offsetEnd] \u7684\u5185\u5BB9\u66FF\u6362\u4E3A\u65B0 content\uFF0CoffsetEnd \u5305\u62EC\u6B64\u884C\u3002\u9700\u8981\u63D0\u4F9B read \u65F6\u8FD4\u56DE\u7684 version \u8FDB\u884C\u5E76\u53D1\u63A7\u5236\u3002",args:{query:I.schema.string().describe("\u5E8F\u53F7\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u66F4\u65B0\u7684\u8BB0\u5FC6"),offsetBegin:I.schema.number().describe("\u8D77\u59CB\u884C\u53F7\uFF08\u5305\u62EC\uFF09"),offsetEnd:I.schema.number().describe("\u7ED3\u675F\u884C\u53F7\uFF08\u5305\u62EC\u6B64\u884C\uFF09"),content:I.schema.string().describe("\u66FF\u6362\u5185\u5BB9"),version:I.schema.number().describe("read \u65F6\u8FD4\u56DE\u7684 version\uFF0C\u7528\u4E8E\u5E76\u53D1\u63A7\u5236")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_edit] \u5165\u53C2: query="${e.query}", offsetBegin=${e.offsetBegin}, offsetEnd=${e.offsetEnd}, content\u957F\u5EA6=${e.content.length}\u5B57\u7B26, version=${e.version}, content=
39
- ${$(e.content)}`),!await x(l)){let t="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await r("warn",`[haimati_edit] \u51FA\u53C2:
40
- ${$(t)}`),t}try{let t=await C(n),i=e.query.trim();if(!/^\d+$/.test(i)){let S="\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";return await r("warn",`[haimati_edit] \u51FA\u53C2:
41
- ${$(S)}`),S}let c=String(parseInt(i,10)),s=R(t,c);if(!s){let S=`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;return await r("info",`[haimati_edit] \u51FA\u53C2:
42
- ${$(S)}`),S}let a=await N(n,s.id);if(!a){let S=`\u672A\u627E\u5230\u4E66\u9875: #${s.id.padStart(3,"0")}`;return await r("error",`[haimati_edit] \u51FA\u53C2:
43
- ${$(S)}`),S}let u=e.offsetBegin,f=e.offsetEnd,d=a.content.split(`
44
- `).length;if(u<1||u>d||u>f||f>d){let S=`\u9519\u8BEF\uFF1Aoffset \u975E\u6CD5\uFF0CoffsetBegin=${u}, offsetEnd=${f}, \u6587\u4EF6\u603B\u884C\u6570=${d}\uFF0C\u6709\u6548\u8303\u56F4 offsetBegin=[1, ${d}], offsetEnd=[offsetBegin, ${d}]`;return await r("warn",`[haimati_edit] \u51FA\u53C2:
45
- ${$(S)}`),S}if(a.version!==e.version){let S=`\u9519\u8BEF\uFF1A\u7248\u672C\u51B2\u7A81\uFF0C\u5F53\u524D version=${a.version}\uFF0C\u4F20\u5165 version=${e.version}\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u518D\u64CD\u4F5C`;return await r("warn",`[haimati_edit] \u51FA\u53C2:
46
- ${$(S)}`),S}let h=(S,et)=>{if(et===0)return 0;let nt=1,F=0;for(;F<S.length;){if(S[F]===`
47
- `){if(nt===et)return F+1;nt++}F++}return F},m=u===1?0:h(a.content,u-1),g=h(a.content,f),w=a.content.substring(0,Math.min(100,a.content.length));await r("debug",`[haimati_edit] content\u957F\u5EA6=${a.content.length}, content\u524D100\u5B57\u7B26: ${JSON.stringify(w)}, offsetBegin=${u}, offsetEnd=${f}, beforeEndIndex=${m}, afterStartIndex=${g}`);let E=(g<a.content.length?a.content.substring(g):"").startsWith(`
48
- `),y=g<a.content.length&&!e.content.endsWith(`
49
- `)&&!E,_=a.content.substring(0,m)+e.content+(y?`
50
- `:"")+a.content.substring(g),A=a.version+1;await q(n,s.id,s.title,a.createdAt,_,A);let tt=`${s.category}/${s.title}`,ft=`\u5DF2\u66F4\u65B0\u6D77\u9A6C\u4F53 #${s.id.padStart(3,"0")}
51
- \u8DEF\u5F84: ${tt}
52
- \u65B0\u7248\u672C: ${A}`;return await r("info",`[haimati_edit] \u51FA\u53C2:
53
- ${$(ft)}`),ft}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_edit] \u51FA\u53C2: \u9519\u8BEF: ${i}
54
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}}),haimati_delete:I({description:"\u5220\u9664\u6D77\u9A6C\u4F53\u4E2D\u7684\u8BB0\u5FC6\u3002\u901A\u8FC7\u5E8F\u53F7\uFF08\u5982 '086'\uFF09\u6216\u5B8C\u6574\u8DEF\u5F84\uFF08\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0/\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236'\uFF09\u6765\u5B9A\u4F4D\u8981\u5220\u9664\u7684\u8BB0\u5FC6\u3002",args:{query:I.schema.string().describe("\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u5220\u9664\u7684\u8BB0\u5FC6")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_delete] \u5165\u53C2: query="${e.query}"`),!await x(l)){let t="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await r("warn",`[haimati_delete] \u51FA\u53C2:
55
- ${$(t)}`),t}try{let t=await C(n),i=e.query.trim(),c=null;if(/^\d+$/.test(i))c=R(t,String(parseInt(i,10)));else{let f=i.split("/").filter(Boolean);if(f.length>=2){let d=f.pop(),h=f.join("/");c=V(t,h,d)}else{let d=await Q(t,i,"or",n);if(d.length===1)c=d[0];else if(d.length>1)return`\u627E\u5230\u591A\u6761\u5339\u914D\uFF0C\u8BF7\u4F7F\u7528\u5E8F\u53F7\u7CBE\u786E\u6307\u5B9A\uFF1A
56
- ${d.slice(0,10).map(m=>` - ${m.category}/${m.title} [${m.id.padStart(3,"0")}]`).join(`
57
- `)}`}}if(!c){let f=`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;return await r("info",`[haimati_delete] \u51FA\u53C2:
58
- ${$(f)}`),f}await St(n,c.id);let s=xt(t,c.id);await W(n,s);let a=`${c.category}/${c.title}`,u=`\u5DF2\u5220\u9664\u6D77\u9A6C\u4F53 #${c.id.padStart(3,"0")}
59
- \u8DEF\u5F84: ${a}`;return await r("info",`[haimati_delete] \u51FA\u53C2:
60
- ${$(u)}`),u}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_delete] \u51FA\u53C2: \u9519\u8BEF: ${i}
61
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}}),haimati_move:I({description:"\u4FEE\u6539\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7684\u5206\u7C7B\u8DEF\u5F84\u3002\u901A\u8FC7\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\u5B9A\u4F4D\u8BB0\u5FC6\uFF0C\u7136\u540E\u5C06\u5176\u79FB\u52A8\u5230\u65B0\u7684\u5206\u7C7B\u3002",args:{query:I.schema.string().describe("\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u79FB\u52A8\u7684\u8BB0\u5FC6"),newCategory:I.schema.string().describe("\u65B0\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u5BA2\u6237\u7AEF' \u6216 '\u901A\u7528'")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_move] \u5165\u53C2: query="${e.query}", newCategory="${e.newCategory}"`),!await x(l)){let t="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await r("warn",`[haimati_move] \u51FA\u53C2:
62
- ${$(t)}`),t}try{let t=await C(n),i=e.query.trim(),c=null;if(/^\d+$/.test(i))c=R(t,String(parseInt(i,10)));else{let m=i.split("/").filter(Boolean);if(m.length>=2){let g=m.pop(),w=m.join("/");c=V(t,w,g)}else{let g=await Q(t,i,"or",n);if(g.length===1)c=g[0];else if(g.length>1)return`\u627E\u5230\u591A\u6761\u5339\u914D\uFF0C\u8BF7\u4F7F\u7528\u5E8F\u53F7\u7CBE\u786E\u6307\u5B9A\uFF1A
63
- ${g.slice(0,10).map(p=>` - ${p.category}/${p.title} [${p.id.padStart(3,"0")}]`).join(`
64
- `)}`}}if(!c){let m=`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;return await r("info",`[haimati_move] \u51FA\u53C2:
65
- ${$(m)}`),m}let a=`${c.category}/${c.title}`,u=e.newCategory,f=`${u}/${c.title}`,d=t.map(m=>m.id===c.id?{...m,category:u}:m);await W(n,d);let h=`\u5DF2\u79FB\u52A8\u6D77\u9A6C\u4F53 #${c.id}
66
- \u65E7\u8DEF\u5F84: ${a}
67
- \u65B0\u8DEF\u5F84: ${f}`;return await r("info",`[haimati_move] \u51FA\u53C2:
68
- ${$(h)}`),h}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_move] \u51FA\u53C2: \u9519\u8BEF: ${i}
69
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}}),haimati_list:I({description:"\u5217\u51FA\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u7684\u5B8C\u6574\u7D22\u5F15\u7ED3\u6784\u3002",args:{category:I.schema.string().optional().describe("\u53EF\u9009\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5217\u51FA\u8BE5\u5206\u7C7B\u4E0B\u7684\u6761\u76EE"),recursive:I.schema.boolean().optional().default(!1).describe("\u662F\u5426\u9012\u5F52\u904D\u5386\u5B50\u5206\u7C7B\uFF0C\u9ED8\u8BA4false")},async execute(e,o){let{directory:n}=o,l=D(n);if(await r("info",`[haimati_list] \u5165\u53C2: category="${e.category||"(\u65E0)"}, recursive=${e.recursive}"`),!await x(l)){let t="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await r("warn",`[haimati_list] \u51FA\u53C2:
70
- ${$(t)}`),t}try{let t=await C(n);if(e.category){let a=(await It(n)).split(`
71
- `),u=0,f=[];for(let g of a){if(!g.trim())continue;let w=z(g);if(g.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/))continue;let E=U(g);if(E&&(E==="/"?f[w]="":f[w]=E,f=f.slice(0,w+1),f.filter(Boolean).join("/")===e.category)){u=w;break}}let d=[],h=[];f=[];for(let g of a){if(!g.trim())continue;let w=z(g),p=g.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/);if(p){let y=p[1].trim(),_=p[2];if(w===u+1){let A=f.slice(1,w).filter(Boolean).join("/");A===e.category&&h.push({category:A,title:y,id:_})}continue}let E=U(g);E&&(E==="/"?f[w]="":f[w]=E,f=f.slice(0,w+1),w===u+1&&f.filter(Boolean).join("/")===e.category&&d.push(E))}let m=`## ${e.category}
11
+ ${a}
12
+ version:${i}`,f=e?`${e}
13
+ ${d}`:d;await ne(c,f,"utf-8")}async function Mt(t,r){let n=z(t,r);return await w(n)?(await re(n),!0):!1}function Lt(t,r){if(r===0)return 0;let n=1,a=0;for(;a<t.length;){if(t[a]===`
14
+ `){if(n===r)return a+1;n++}a++}return a}function vt(t,r,n,a){let e=r===1?0:Lt(t,r-1),i=Lt(t,n),s=(i<t.length?t.substring(i):"").startsWith(`
15
+ `),c=i<t.length&&!a.endsWith(`
16
+ `)&&!s;return t.substring(0,e)+a+(c?`
17
+ `:"")+t.substring(i)}async function rt(t,r,n,a,e=!1){let i=r.toLowerCase().split(/\s+/).filter(s=>s.length>0);if(i.length===0)return[];let l=[];for(let s of t){let c=s.title.toLowerCase(),g=s.category.toLowerCase(),d=s.id.toLowerCase(),f=0,p=0;for(let m of i)(c.includes(m)||g.includes(m)||d.includes(m))&&f++;if(e&&a){let m=await k(a,s.id);if(m&&m.content){let y=m.content.toLowerCase();for(let h of i)y.includes(h)&&p++}}let u=f+p;n==="and"?u>=i.length&&l.push({entry:s,score:u}):(f>0||e&&p>0)&&l.push({entry:s,score:u})}return l.sort((s,c)=>c.score-s.score),l.map(s=>s.entry)}import Gt from"fs";import{promisify as Ht}from"util";import Ct from"fs";import{promisify as kt}from"util";var se=kt(Ct.writeFile),oe=kt(Ct.unlink);async function Tt(t){let r=C(t);await w(r)||await L(r);let n=ct(t),a=Date.now(),e=50+Math.random()*20;for(;await w(n);){if(Date.now()-a>5e3)return!1;await new Promise(i=>setTimeout(i,e))}return await se(n,String(process.pid),"utf-8"),!0}async function Nt(t){let r=ct(t);await w(r)&&await oe(r)}import j from"fs";import N from"path";import{promisify as W}from"util";var Ot=W(j.appendFile),ae=W(j.readdir),ce=W(j.unlink),ut=W(j.stat),Ft=W(j.readFile),Rt=W(j.writeFile),At={debug:0,info:1,warn:2,error:3},v="",le=".log_state";function jt(){return N.join(q(),le)}async function mt(){let t=jt();try{if(await w(t)){let n=(await Ft(t,"utf-8")).match(/lastCheckedDate=(\d{4}-\d{2}-\d{2})/);if(n)return n[1]}}catch(r){console.error("[haimati] \u8BFB\u53D6\u65E5\u5FD7\u72B6\u6001\u6587\u4EF6\u5931\u8D25:",r)}return""}async function Y(t){let r=jt();try{let n=N.dirname(r);await w(n)||await L(n),await Rt(r,`lastCheckedDate=${t}`,"utf-8")}catch(n){console.error("[haimati] \u5199\u5165\u65E5\u5FD7\u72B6\u6001\u6587\u4EF6\u5931\u8D25:",n)}}function I(t,r=5e3){if(t.length<=r)return t;let n=Math.floor((r-20)/2);return t.substring(0,n)+"...(\u7701\u7565"+(t.length-r)+"\u5B57\u7B26)..."+t.substring(t.length-n)}function J(t){let r=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0");return`${r}-${n}-${a}`}function de(){let t=new Date;return t.setDate(t.getDate()-1),J(t)}function fe(t){let r=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),a=String(t.getDate()).padStart(2,"0"),e=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),l=String(t.getSeconds()).padStart(2,"0");return`${r}-${n}-${a} ${e}:${i}:${l}`}async function ge(t){try{let r=X();if(!await w(r)||(await ut(r)).size===0)return;let a=N.join(q(),"history");await w(a)||await L(a);let e=N.join(a,`${t}.log`),i=await Ft(r,"utf-8");await Ot(e,i,"utf-8"),await Rt(r,"","utf-8")}catch(r){console.error("[haimati] \u8F6E\u8F6C info.log \u5931\u8D25:",r)}}async function ue(){let t=J(new Date);if(await mt()===t){v=t;return}let n=de();await ge(n),v=t,await Y(t)}async function me(t,r){try{let n=N.dirname(t);await w(n)||await L(n),await Ot(t,r+`
18
+ `,"utf-8")}catch(n){console.error("[haimati] \u5199\u5165\u65E5\u5FD7\u6587\u4EF6\u5931\u8D25:",n)}}async function Wt(){let t=new Date,r=J(t);if(await mt()===r){v=r;return}try{let a=dt(),e=N.join(q(),"history");if(!await w(e)){v=r,await Y(r);return}let i=await ae(e),l=t.getTime()-a.logRetentionDays*24*60*60*1e3;for(let s of i){if(!s.match(/^\d{4}-\d{2}-\d{2}\.log$/))continue;let c=N.join(e,s);(await ut(c)).mtime.getTime()<l&&await ce(c)}v=r,await Y(r)}catch(a){console.error("[haimati] \u6E05\u7406\u5386\u53F2\u65E5\u5FD7\u5931\u8D25:",a)}}async function it(t,r,n){try{let e=dt().level;if(At[t]<At[e])return;let l=fe(new Date),s=n?`[${n}] `:"",c=`[${l}] [${t.toUpperCase()}] ${s}${r}`,g=c.length>5e3?I(c):c;await ue(),await me(X(),g),Wt().catch(d=>{console.error("[haimati] \u6E05\u7406\u5386\u53F2\u65E5\u5FD7\u5931\u8D25:",d)})}catch(a){console.error("[haimati] \u65E5\u5FD7\u8BB0\u5F55\u5931\u8D25:",a)}}var o={debug(t,r){return it("debug",t,r)},info(t,r){return it("info",t,r)},warn(t,r){return it("warn",t,r)},error(t,r){return it("error",t,r)}};async function qt(){let t=J(new Date),r=X();if(v=await mt(),v!==t){try{if(await w(r)){let n=await ut(r);if(J(n.mtime)===t){v=t,await Y(t);return}}}catch(n){console.error("[haimati] \u68C0\u67E5 info.log \u72B6\u6001\u5931\u8D25:",n)}v=t,await Y(t),await Wt()}}var he=Ht(Gt.readFile),pe=Ht(Gt.writeFile);async function we(t){let r=V(t);if(!await w(r))return 1;let a=(await he(r,"utf-8")).trim(),e=parseInt(a,10);return!isNaN(e)&&e>0?e:1}async function ye(t){let r=V(t);if(await w(r))return;let n=await D(t),a=0;for(let e of n){let i=parseInt(e.id,10);i>a&&(a=i)}await Bt(t,a+1)}async function Bt(t,r){let n=C(t);await w(n)||await L(n);let a=V(t);await pe(a,String(r),"utf-8")}async function Yt(t,r,n,a,e,i=!1){if(/ - \d{3}$/.test(n))throw await o.warn(`[allocateIdWithLock] title \u683C\u5F0F\u4E0D\u5408\u89C4: "${n}", \u629B\u51FA\u9519\u8BEF`),new Error('\u6807\u9898\u4E0D\u80FD\u4EE5 " - \u5E8F\u53F7" \u683C\u5F0F\u7ED3\u5C3E\uFF0C\u5E8F\u53F7\u7531\u7CFB\u7EDF\u81EA\u52A8\u5206\u914D\uFF0C\u8BF7\u4FEE\u6539\u6807\u9898');if(await o.info(`[allocateIdWithLock] \u5F00\u59CB\u5206\u914D\u5E8F\u53F7: category="${r}", title="${n}"`),!await Tt(t))return await o.warn(`[allocateIdWithLock] \u83B7\u53D6\u9501\u5931\u8D25: category="${r}", title="${n}"`),null;await o.debug(`[allocateIdWithLock] \u83B7\u53D6\u9501\u6210\u529F: category="${r}", title="${n}"`);try{await ye(t);let l=await D(t),s=l.find(f=>f.category===r&&f.title===n);if(s){if(!i)throw new Error(`\u8BB0\u5FC6\u5DF2\u5B58\u5728: ${r}/${n}\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u4F7F\u7528 haimati_edit \u5DE5\u5177`);let f=await k(t,s.id),p=f?f.createdAt:a,u=f?f.version+1:1;return await B(t,s.id,n,p,e,u),await o.info(`[allocateIdWithLock] \u66F4\u65B0\u5DF2\u6709\u6761\u76EE: #${s.id} ${r}/${n}, \u65B0\u7248\u672C: ${u}`),null}let c=await we(t),g=String(c).padStart(3,"0");await B(t,g,n,a,e,1);let d={id:g,category:r,title:n};return l.push(d),await H(t,l),await Bt(t,c+1),await o.info(`[allocateIdWithLock] \u5206\u914D\u5E8F\u53F7\u6210\u529F: #${g} ${r}/${n}`),g}catch(l){let s=l instanceof Error?l.message:String(l);if(await o.error(`[allocateIdWithLock] \u5206\u914D\u5E8F\u53F7\u5931\u8D25: ${s}`),s.includes("\u8BB0\u5FC6\u5DF2\u5B58\u5728"))throw l;return null}finally{await Nt(t)}}function Jt(){return{haimati_read:x({description:"\u4ECE\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u8BFB\u53D6\u5185\u5BB9\u3002\u901A\u8FC7\u5E8F\u53F7\uFF08\u5982 '086'\uFF09\u6765\u5B9A\u4F4D\u5E76\u8BFB\u53D6\u8BB0\u5FC6\u5185\u5BB9\u3002\u652F\u6301\u5206\u9875\u8BFB\u53D6\uFF08offset/limit\uFF09\uFF0C\u8FD4\u56DE\u5185\u5BB9\u5E26\u884C\u53F7\u548C\u7248\u672C\u53F7\u3002",args:{query:x.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'"),offset:x.schema.number().optional().default(1).describe("\u8D77\u59CB\u884C\u53F7\uFF08\u9ED8\u8BA4 1\uFF09"),limit:x.schema.number().optional().default(2e3).describe("\u6700\u5927\u8BFB\u53D6\u884C\u6570\uFF08\u9ED8\u8BA4 2000\uFF09")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_read] \u5165\u53C2: query="${t.query}", offset=${t.offset||1}, limit=${t.limit||2e3}`),!await w(a)){let e=`\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728\u4E8E ${a}`;return await o.warn(`[haimati_read] \u51FA\u53C2:
19
+ ${I(e)}`),e}try{let e=await D(n);await o.debug(`[haimati_read] \u8BFB\u53D6\u7D22\u5F15: \u5171 ${e.length} \u6761\u8BB0\u5F55`);let i=t.query.trim();if(!/^\d+$/.test(i)){let $="\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";return await o.warn(`[haimati_read] \u51FA\u53C2:
20
+ ${I($)}`),$}let l=String(parseInt(i,10)),s=G(e,l);if(await o.debug(`[haimati_read] \u5E8F\u53F7\u67E5\u8BE2 #${i}: ${s?"\u627E\u5230":"\u672A\u627E\u5230"}`),!s){let $=`\u672A\u627E\u5230\u8BB0\u5FC6: ${t.query}`;return await o.debug(`[haimati_read] \u51FA\u53C2:
21
+ ${I($)}`),$}let c=await k(n,s.id);if(!c){let $=`\u672A\u627E\u5230\u4E66\u9875: #${s.id.padStart(3,"0")}`;return await o.error(`[haimati_read] \u51FA\u53C2:
22
+ ${I($)}`),$}let g=R(n,s.id);await o.debug(`[haimati_read] \u8BFB\u53D6\u4E66\u9875: \u4E66\u9875/${g.split(/[\\/]/).pop()}/${s.id}.md, version=${c.version}`);let d=c.content.split(`
23
+ `),f=t.offset||1,p=t.limit||2e3,u=d.length,m=Math.max(0,f-1),y=Math.min(u,m+p),h=[];for(let $=m;$<y;$++)h.push(`${$+1}|${d[$]}`);h.push("------system------"),h.push(`\u6807\u9898:${s.title}`),h.push(`\u521B\u5EFA\u65F6\u95F4:${c.createdAt}`),h.push(`version:${c.version}`);let b=h.join(`
24
+ `);return await o.debug(`[haimati_read] \u51FA\u53C2:
25
+ ${I(b)}`),b}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_read] \u51FA\u53C2: \u9519\u8BEF: ${i}
26
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}}),haimati_write:x({description:"\u5C06\u65B0\u4FE1\u606F\u5199\u5165\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u3002\u9700\u8981\u63D0\u4F9B\u5206\u7C7B\u8DEF\u5F84\uFF08\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0'\uFF09\u3001\u6807\u9898\u548C\u5185\u5BB9\u3002\u5982\u679C\u76F8\u540C\u5206\u7C7B\u548C\u6807\u9898\u7684\u8BB0\u5FC6\u5DF2\u5B58\u5728\uFF0C\u5219\u4F1A\u62A5\u9519\u3002",args:{category:x.schema.string().describe("\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0' \u6216 '\u901A\u7528'"),title:x.schema.string().describe("\u8BB0\u5FC6\u6807\u9898\uFF0C\u5982 '\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236'"),content:x.schema.string().describe("\u8981\u5199\u5165\u7684\u8BE6\u7EC6\u5185\u5BB9")},async execute(t,r){let{directory:n}=r;await o.debug(`[haimati_write] \u5165\u53C2: category="${t.category}", title="${t.title}", content\u957F\u5EA6=${t.content.length}\u5B57\u7B26, content=
27
+ ${I(t.content)}
28
+ `);try{let a=new Date().toLocaleString("zh-CN",{hour12:!1}),e=null;for(let c=0;c<3;c++)try{if(e=await Yt(n,t.category,t.title,a,t.content,!1),e)break;await o.warn(`[haimati_write] \u9501\u83B7\u53D6\u5931\u8D25\uFF0C\u91CD\u8BD5\u7B2C ${c+1} \u6B21`)}catch(g){let d=g instanceof Error?g.message:String(g);if(d.includes("\u8BB0\u5FC6\u5DF2\u5B58\u5728"))throw g;await o.warn(`[haimati_write] \u83B7\u53D6\u9501\u5F02\u5E38: ${d}, \u91CD\u8BD5\u7B2C ${c+1} \u6B21`)}if(e){let c=R(n,e);await o.debug(`[haimati_write] \u5206\u914D\u65B0\u5E8F\u53F7: #${e}`),await o.debug(`[haimati_write] \u4E66\u9875\u548C\u7D22\u5F15\u5DF2\u66F4\u65B0: \u4E66\u9875/${c.split(/[\\/]/).pop()}/${e}.md`);let g=`\u5DF2\u5199\u5165\u6D77\u9A6C\u4F53 #${e}
29
+ \u8DEF\u5F84: ${t.category}/${t.title}
30
+ \u7248\u672C: 1`;return await o.debug(`[haimati_write] \u51FA\u53C2:
31
+ ${I(g)}`),g}let i=await D(n),l=tt(i,t.category,t.title);if(l){let c=`\u9519\u8BEF\uFF1A\u8BB0\u5FC6\u5DF2\u5B58\u5728 #${l.id} (${t.category}/${t.title})\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u4F7F\u7528 haimati_edit \u5DE5\u5177`;return await o.error(`[haimati_write] \u51FA\u53C2:
32
+ ${I(c)}`),c}let s="\u9519\u8BEF\uFF1A\u65E0\u6CD5\u5206\u914D\u5E8F\u53F7\uFF08\u9501\u7B49\u5F85\u8D85\u65F6\uFF09";return await o.error(`[haimati_write] \u51FA\u53C2:
33
+ ${I(s)}`),s}catch(a){let e=a instanceof Error?a.message:String(a),i=a instanceof Error?a.stack:"";return await o.error(`[haimati_write] \u51FA\u53C2: \u9519\u8BEF: ${e}
34
+ \u5806\u6808: ${i}`),`\u9519\u8BEF: ${e}`}}}),haimati_search:x({description:"\u641C\u7D22\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09\u3002\u641C\u7D22\u8303\u56F4\u5305\u62EC\uFF1A\u6807\u9898\u3001\u5206\u7C7B\u3001\u5E8F\u53F7\u3001\u4E66\u9875\u5185\u5BB9\u3002\u8F93\u5165\u5173\u952E\u8BCD\uFF0C\u8FD4\u56DE\u5339\u914D\u7684\u6761\u76EE\u5217\u8868\u548C\u5185\u5BB9\u7247\u6BB5\uFF0C\u652F\u6301\u5206\u9875\uFF08limit/offset\uFF09\u3002",args:{keyword:x.schema.string().describe("\u641C\u7D22\u5173\u952E\u8BCD\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09"),match:x.schema.string().describe("\u5339\u914D\u6A21\u5F0F\uFF1Aand=\u6240\u6709\u5173\u952E\u5B57\u90FD\u5339\u914D\uFF0Cor=\u4EFB\u610F\u5173\u952E\u5B57\u5339\u914D"),limit:x.schema.number().default(10).describe("\u8FD4\u56DE\u7ED3\u679C\u6570\u91CF\u9650\u5236"),offset:x.schema.number().default(0).describe("\u5206\u9875\u504F\u79FB\u91CF\uFF0C\u7528\u4E8E\u83B7\u53D6\u540E\u7EED\u9875\u9762")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_search] \u5165\u53C2: keyword="${t.keyword}", match="${t.match}", limit=${t.limit||10}, offset=${t.offset||0}`),!await w(a)){let e="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await o.warn(`[haimati_search] \u51FA\u53C2:
35
+ ${I(e)}`),e}try{let e=await D(n),i=t.keyword.trim(),l=t.match,s=t.limit||10,c=t.offset||0,g=await rt(e,i,l,n,!0),d=g.length,f=g.slice(c,c+s);if(f.length===0){let h=`\u672A\u627E\u5230\u5305\u542B '${i}' \u7684\u8BB0\u5FC6`;return await o.debug(`[haimati_search] \u51FA\u53C2:
36
+ ${I(h)}`),h}let p=[],u=c+f.length<d,m=u?`${c+1}-${c+f.length}/${d}`:`${c+1}-${c+f.length}/${d}`;p.push(`\u627E\u5230 ${m} \u6761\u5339\u914D\uFF1A
37
+ `),u&&p.push(`\uFF08\u5982\u9700\u83B7\u53D6\u66F4\u591A\uFF0C\u8BF7\u4F7F\u7528 offset=${c+s} \u7EE7\u7EED\u7FFB\u9875\uFF09
38
+ `);for(let h of f){let b=await k(n,h.id),$=`${h.category}/${h.title}`,M="";b&&(M=b.content.split(`
39
+ `).filter(Kt=>Kt.trim()).slice(0,3).join(" | ").substring(0,150),M.length===150&&(M+="...")),p.push(`## ${$} [${h.id}]`),M&&p.push(`> ${M}`),p.push("")}let y=p.join(`
40
+ `);return await o.debug(`[haimati_search] \u51FA\u53C2:
41
+ ${I(y)}`),y}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_search] \u51FA\u53C2: \u9519\u8BEF: ${i}
42
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}}),haimati_edit:x({description:"\u4FEE\u6539\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7684\u90E8\u5206\u5185\u5BB9\u3002\u5C06\u6307\u5B9A\u884C\u53F7\u8303\u56F4 [offsetBegin, offsetEnd] \u7684\u5185\u5BB9\u66FF\u6362\u4E3A\u65B0 content\uFF0CoffsetEnd \u5305\u62EC\u6B64\u884C\u3002\u9700\u8981\u63D0\u4F9B read \u65F6\u8FD4\u56DE\u7684 version \u8FDB\u884C\u5E76\u53D1\u63A7\u5236\u3002",args:{query:x.schema.string().describe("\u5E8F\u53F7\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u66F4\u65B0\u7684\u8BB0\u5FC6"),offsetBegin:x.schema.number().describe("\u8D77\u59CB\u884C\u53F7\uFF08\u5305\u62EC\uFF09"),offsetEnd:x.schema.number().describe("\u7ED3\u675F\u884C\u53F7\uFF08\u5305\u62EC\u6B64\u884C\uFF09"),content:x.schema.string().describe("\u66FF\u6362\u5185\u5BB9"),version:x.schema.number().describe("read \u65F6\u8FD4\u56DE\u7684 version\uFF0C\u7528\u4E8E\u5E76\u53D1\u63A7\u5236")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_edit] \u5165\u53C2: query="${t.query}", offsetBegin=${t.offsetBegin}, offsetEnd=${t.offsetEnd}, content\u957F\u5EA6=${t.content.length}\u5B57\u7B26, version=${t.version}`),!await w(a))return await o.warn(`[haimati_edit] \u51FA\u53C2:
43
+ \u7D22\u5F15\u6587\u4EF6\u4E0D\u5B58\u5728`),"\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";try{let e=await D(n),i=t.query.trim();if(!/^\d+$/.test(i))return await o.warn(`[haimati_edit] \u51FA\u53C2:
44
+ query\u65E0\u6548`),"\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";let l=String(parseInt(i,10)),s=G(e,l);if(!s)return await o.debug(`[haimati_edit] \u51FA\u53C2:
45
+ \u672A\u627E\u5230`),`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;let c=await k(n,s.id);if(!c)return await o.error(`[haimati_edit] \u51FA\u53C2:
46
+ \u4E66\u9875\u4E0D\u5B58\u5728`),`\u672A\u627E\u5230\u4E66\u9875: #${s.id.padStart(3,"0")}`;if(c.version!==t.version)return await o.warn(`[haimati_edit] \u51FA\u53C2:
47
+ \u7248\u672C\u51B2\u7A81`),`\u9519\u8BEF\uFF1A\u7248\u672C\u51B2\u7A81\uFF0C\u5F53\u524D version=${c.version}\uFF0C\u4F20\u5165 version=${t.version}\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u518D\u64CD\u4F5C`;let g=c.content.split(`
48
+ `).length,{offsetBegin:d,offsetEnd:f}=t;if(d<1||d>g||d>f||f>g)return await o.warn(`[haimati_edit] \u51FA\u53C2:
49
+ offset\u975E\u6CD5`),`\u9519\u8BEF\uFF1Aoffset \u975E\u6CD5\uFF0CoffsetBegin=${d}, offsetEnd=${f}, \u6587\u4EF6\u603B\u884C\u6570=${g}\uFF0C\u6709\u6548\u8303\u56F4 offsetBegin=[1, ${g}], offsetEnd=[offsetBegin, ${g}]`;let p=vt(c.content,d,f,t.content);await B(n,s.id,s.title,c.createdAt,p,c.version+1);let u=`${s.category}/${s.title}`,m=`\u5DF2\u66F4\u65B0\u6D77\u9A6C\u4F53 #${s.id.padStart(3,"0")}
50
+ \u8DEF\u5F84: ${u}
51
+ \u65B0\u7248\u672C: ${c.version+1}`;return await o.debug(`[haimati_edit] \u51FA\u53C2:
52
+ ${I(m)}`),m}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_edit] \u51FA\u53C2:
53
+ ${i}
54
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}}),haimati_delete:x({description:"\u5220\u9664\u6D77\u9A6C\u4F53\u4E2D\u7684\u8BB0\u5FC6\u3002\u901A\u8FC7\u5E8F\u53F7\uFF08\u5982 '086'\uFF09\u6216\u5B8C\u6574\u8DEF\u5F84\uFF08\u5982 'xxx\u9879\u76EE/\u7B7E\u7AE0/\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236'\uFF09\u6765\u5B9A\u4F4D\u8981\u5220\u9664\u7684\u8BB0\u5FC6\u3002",args:{query:x.schema.string().describe("\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u5220\u9664\u7684\u8BB0\u5FC6")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_delete] \u5165\u53C2: query="${t.query}"`),!await w(a)){let e="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await o.warn(`[haimati_delete] \u51FA\u53C2:
55
+ ${I(e)}`),e}try{let e=await D(n),i=t.query.trim(),l=null;if(/^\d+$/.test(i))l=G(e,String(parseInt(i,10)));else{let d=i.split("/").filter(Boolean);if(d.length>=2){let f=d.pop(),p=d.join("/");l=tt(e,p,f)}else{let f=await rt(e,i,"or",n);if(f.length===1)l=f[0];else if(f.length>1)return`\u627E\u5230\u591A\u6761\u5339\u914D\uFF0C\u8BF7\u4F7F\u7528\u5E8F\u53F7\u7CBE\u786E\u6307\u5B9A\uFF1A
56
+ ${f.slice(0,10).map(u=>` - ${u.category}/${u.title} [${u.id.padStart(3,"0")}]`).join(`
57
+ `)}`}}if(!l){let d=`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;return await o.debug(`[haimati_delete] \u51FA\u53C2:
58
+ ${I(d)}`),d}await Mt(n,l.id);let s=Pt(e,l.id);await H(n,s);let c=`${l.category}/${l.title}`,g=`\u5DF2\u5220\u9664\u6D77\u9A6C\u4F53 #${l.id.padStart(3,"0")}
59
+ \u8DEF\u5F84: ${c}`;return await o.debug(`[haimati_delete] \u51FA\u53C2:
60
+ ${I(g)}`),g}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_delete] \u51FA\u53C2: \u9519\u8BEF: ${i}
61
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}}),haimati_move:x({description:"\u4FEE\u6539\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7684\u5206\u7C7B\u8DEF\u5F84\u3002\u901A\u8FC7\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\u5B9A\u4F4D\u8BB0\u5FC6\uFF0C\u7136\u540E\u5C06\u5176\u79FB\u52A8\u5230\u65B0\u7684\u5206\u7C7B\u3002",args:{query:x.schema.string().describe("\u5E8F\u53F7\u6216\u5B8C\u6574\u8DEF\u5F84\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u79FB\u52A8\u7684\u8BB0\u5FC6"),newCategory:x.schema.string().describe("\u65B0\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u5BA2\u6237\u7AEF' \u6216 '\u901A\u7528'")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_move] \u5165\u53C2: query="${t.query}", newCategory="${t.newCategory}"`),!await w(a)){let e="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await o.warn(`[haimati_move] \u51FA\u53C2:
62
+ ${I(e)}`),e}try{let e=await D(n),i=t.query.trim(),l=null;if(/^\d+$/.test(i))l=G(e,String(parseInt(i,10)));else{let u=i.split("/").filter(Boolean);if(u.length>=2){let m=u.pop(),y=u.join("/");l=tt(e,y,m)}else{let m=await rt(e,i,"or",n);if(m.length===1)l=m[0];else if(m.length>1)return`\u627E\u5230\u591A\u6761\u5339\u914D\uFF0C\u8BF7\u4F7F\u7528\u5E8F\u53F7\u7CBE\u786E\u6307\u5B9A\uFF1A
63
+ ${m.slice(0,10).map(h=>` - ${h.category}/${h.title} [${h.id.padStart(3,"0")}]`).join(`
64
+ `)}`}}if(!l){let u=`\u672A\u627E\u5230\u4E0E '${i}' \u76F8\u5173\u7684\u8BB0\u5FC6`;return await o.debug(`[haimati_move] \u51FA\u53C2:
65
+ ${I(u)}`),u}let c=`${l.category}/${l.title}`,g=t.newCategory,d=`${g}/${l.title}`,f=e.map(u=>u.id===l.id?{...u,category:g}:u);await H(n,f);let p=`\u5DF2\u79FB\u52A8\u6D77\u9A6C\u4F53 #${l.id}
66
+ \u65E7\u8DEF\u5F84: ${c}
67
+ \u65B0\u8DEF\u5F84: ${d}`;return await o.debug(`[haimati_move] \u51FA\u53C2:
68
+ ${I(p)}`),p}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_move] \u51FA\u53C2: \u9519\u8BEF: ${i}
69
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}}),haimati_list:x({description:"\u5217\u51FA\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u7684\u5B8C\u6574\u7D22\u5F15\u7ED3\u6784\u3002",args:{category:x.schema.string().optional().describe("\u53EF\u9009\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5217\u51FA\u8BE5\u5206\u7C7B\u4E0B\u7684\u6761\u76EE"),recursive:x.schema.boolean().optional().default(!1).describe("\u662F\u5426\u9012\u5F52\u904D\u5386\u5B50\u5206\u7C7B\uFF0C\u9ED8\u8BA4false")},async execute(t,r){let{directory:n}=r,a=_(n);if(await o.debug(`[haimati_list] \u5165\u53C2: category="${t.category||"(\u65E0)"}, recursive=${t.recursive}"`),!await w(a)){let e="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await o.warn(`[haimati_list] \u51FA\u53C2:
70
+ ${I(e)}`),e}try{let e=await D(n);if(t.category){let c=(await _t(n)).split(`
71
+ `),g=0,d=[];for(let m of c){if(!m.trim())continue;let y=Q(m);if(m.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/))continue;let b=Z(m);if(b&&(b==="/"?d[y]="":d[y]=b,d=d.slice(0,y+1),d.filter(Boolean).join("/")===t.category)){g=y;break}}let f=[],p=[];d=[];for(let m of c){if(!m.trim())continue;let y=Q(m),h=m.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/);if(h){let $=h[1].trim(),M=h[2];if(y===g+1){let ot=d.slice(1,y).filter(Boolean).join("/");ot===t.category&&p.push({category:ot,title:$,id:M})}continue}let b=Z(m);b&&(b==="/"?d[y]="":d[y]=b,d=d.slice(0,y+1),y===g+1&&d.filter(Boolean).join("/")===t.category&&f.push(b))}let u=`## ${t.category}
72
72
 
73
- `;if(e.recursive){let g=t.filter(p=>p.category===e.category||p.category.startsWith(e.category+"/")),w=new Map;for(let p of g){let y=p.category.slice(e.category.length+1).split("/")[0]||"(\u76F4\u63A5)";w.has(y)||w.set(y,[]),w.get(y).push(p)}for(let[p,E]of w)m+=`### ${p}/
74
- `,m+=E.map(y=>`- ${y.title} - ${y.id.padStart(3,"0")}`).join(`
73
+ `;if(t.recursive){let m=e.filter(h=>h.category===t.category||h.category.startsWith(t.category+"/")),y=new Map;for(let h of m){let $=h.category.slice(t.category.length+1).split("/")[0]||"(\u76F4\u63A5)";y.has($)||y.set($,[]),y.get($).push(h)}for(let[h,b]of y)u+=`### ${h}/
74
+ `,u+=b.map($=>`- ${$.title} - ${$.id.padStart(3,"0")}`).join(`
75
75
  `)+`
76
76
 
77
- `}else d.length>0&&(m+=`**\u5B50\u5206\u7C7B\uFF1A**
78
- `+d.map(g=>`- ${g}/`).join(`
77
+ `}else f.length>0&&(u+=`**\u5B50\u5206\u7C7B\uFF1A**
78
+ `+f.map(m=>`- ${m}/`).join(`
79
79
  `)+`
80
80
 
81
- `),h.length>0&&(m+=`**\u76F4\u63A5\u6761\u76EE\uFF1A**
82
- `+h.map(g=>`- ${g.title} - ${g.id.padStart(3,"0")}`).join(`
83
- `));return await r("info",`[haimati_list] \u51FA\u53C2:
84
- ${$(m)}`),m}let c=`## \u6D77\u9A6C\u4F53\u7D22\u5F15
81
+ `),p.length>0&&(u+=`**\u76F4\u63A5\u6761\u76EE\uFF1A**
82
+ `+p.map(m=>`- ${m.title} - ${m.id.padStart(3,"0")}`).join(`
83
+ `));return await o.debug(`[haimati_list] \u51FA\u53C2:
84
+ ${I(u)}`),u}let l=`## \u6D77\u9A6C\u4F53\u7D22\u5F15
85
85
 
86
- ${ot(t)||"(\u7A7A)"}`;return await r("info",`[haimati_list] \u51FA\u53C2:
87
- ${$(c)}`),c}catch(t){let i=t instanceof Error?t.message:String(t),c=t instanceof Error?t.stack:"";return await r("error",`[haimati_list] \u51FA\u53C2: \u9519\u8BEF: ${i}
88
- \u5806\u6808: ${c}`),`\u9519\u8BEF: ${i}`}}})}}var v=new Map,Z=new Map,T=new Set,P=new Set,b=new Set,vt=new Map,tn=async e=>{await r("info","\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u63D2\u4EF6(\u6587\u4EF6\u7248)debug\u7248\u672C04091402\u5DF2\u52A0\u8F7D");let{client:o}=e;return{tool:Nt(),"chat.message":async(l,t)=>{let{message:i,parts:c}=t,s=i.sessionID,a=i.id;if(await r("debug","[chat.message] ====== \u5F00\u59CB\u5904\u7406 ======"),await r("debug",`[chat.message] sessionId=${s}, messageId=${a}`),await r("debug",`[chat.message] enhancedSessions: ${JSON.stringify([...v.entries()])}`),v.get(s)===a){await r("debug",`[chat.message] \u4F1A\u8BDD ${s} \u7684\u6D88\u606F ${a} \u5DF2\u589E\u5F3A\u8FC7\uFF0C\u8DF3\u8FC7`);return}let u=c.some(d=>d.type==="text"&&d.text);if(await r("debug",`[chat.message] hasUserContent=${u}`),!u){await r("debug",`[chat.message] \u6D88\u606F ${a} \u4E0D\u5305\u542B\u7528\u6237\u5185\u5BB9\uFF0C\u8DF3\u8FC7`);return}if(v.has(s)){await r("debug",`[chat.message] \u4F1A\u8BDD ${s} \u5DF2\u589E\u5F3A\u8FC7\uFF0C\u4E0D\u662F\u9996\u6761\u7528\u6237\u6D88\u606F\uFF0C\u8DF3\u8FC7 | enhancedSessions.get=${v.get(s)}`);return}let f=null;try{let d=await o.command.list({});if(d.data){let m=d.data.find(g=>g.name===O.replace(/^\//,""));m&&m.template?(f=m.template,await r("info",`[chat.message] \u627E\u5230 ${O} \u547D\u4EE4\u7684 template`)):await r("warn",`[chat.message] \u672A\u627E\u5230 ${O} \u547D\u4EE4\u7684 template`)}}catch(d){let h=d instanceof Error?d.message:String(d);await r("error",`[chat.message] \u67E5\u8BE2 ${O} \u547D\u4EE4 template \u5931\u8D25: ${h}`)}if(f===null){await r("info",`[chat.message] \u4F1A\u8BDD ${s} \u672A\u627E\u5230 ${O} \u547D\u4EE4\u7684 template\uFF0C\u6807\u8BB0\u5E76\u8DF3\u8FC7`),v.set(s,a),await r("debug",`[chat.message] \u6807\u8BB0\u540E enhancedSessions: ${JSON.stringify([...v.entries()])}`);return}await r("info",`[chat.message] \u589E\u5F3A\u4F1A\u8BDD ${s} \u7684\u9996\u6761\u7528\u6237\u6D88\u606F ${a}`);for(let d of c)d.type==="text"&&(d.text=f+`
86
+ ${ft(e)||"(\u7A7A)"}`;return await o.debug(`[haimati_list] \u51FA\u53C2:
87
+ ${I(l)}`),l}catch(e){let i=e instanceof Error?e.message:String(e),l=e instanceof Error?e.stack:"";return await o.error(`[haimati_list] \u51FA\u53C2: \u9519\u8BEF: ${i}
88
+ \u5806\u6808: ${l}`),`\u9519\u8BEF: ${i}`}}})}}var T=new Map,st=new Map,A=new Set,S=new Set,P=new Set,Ut=new Map,In=async t=>{await qt(),await o.debug("\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u7CFB\u7EDF\u63D2\u4EF6(\u6587\u4EF6\u7248)debug\u7248\u672C04091402\u5DF2\u52A0\u8F7D");let{client:r}=t;return{tool:Jt(),"chat.message":async(a,e)=>{let{message:i,parts:l}=e,s=i.sessionID,c=i.id;if(await o.debug("[chat.message] ====== \u5F00\u59CB\u5904\u7406 ======"),await o.debug(`[chat.message] sessionId=${s}, messageId=${c}`),await o.debug(`[chat.message] enhancedSessions: ${JSON.stringify([...T.entries()])}`),T.get(s)===c){await o.debug(`[chat.message] \u4F1A\u8BDD ${s} \u7684\u6D88\u606F ${c} \u5DF2\u589E\u5F3A\u8FC7\uFF0C\u8DF3\u8FC7`);return}let g=l.some(f=>f.type==="text"&&f.text);if(await o.debug(`[chat.message] hasUserContent=${g}`),!g){await o.debug(`[chat.message] \u6D88\u606F ${c} \u4E0D\u5305\u542B\u7528\u6237\u5185\u5BB9\uFF0C\u8DF3\u8FC7`);return}if(T.has(s)){await o.debug(`[chat.message] \u4F1A\u8BDD ${s} \u5DF2\u589E\u5F3A\u8FC7\uFF0C\u4E0D\u662F\u9996\u6761\u7528\u6237\u6D88\u606F\uFF0C\u8DF3\u8FC7 | enhancedSessions.get=${T.get(s)}`);return}let d=null;try{let f=await r.command.list({});if(f.data){let u=f.data.find(m=>m.name===O.replace(/^\//,""));u&&u.template?(d=u.template,await o.debug(`[chat.message] \u627E\u5230 ${O} \u547D\u4EE4\u7684 template`)):await o.warn(`[chat.message] \u672A\u627E\u5230 ${O} \u547D\u4EE4\u7684 template`)}}catch(f){let p=f instanceof Error?f.message:String(f);await o.error(`[chat.message] \u67E5\u8BE2 ${O} \u547D\u4EE4 template \u5931\u8D25: ${p}`)}if(d===null){await o.debug(`[chat.message] \u4F1A\u8BDD ${s} \u672A\u627E\u5230 ${O} \u547D\u4EE4\u7684 template\uFF0C\u6807\u8BB0\u5E76\u8DF3\u8FC7`),T.set(s,c),await o.debug(`[chat.message] \u6807\u8BB0\u540E enhancedSessions: ${JSON.stringify([...T.entries()])}`);return}await o.debug(`[chat.message] \u589E\u5F3A\u4F1A\u8BDD ${s} \u7684\u9996\u6761\u7528\u6237\u6D88\u606F ${c}`);for(let f of l)f.type==="text"&&(f.text=d+`
89
89
 
90
- `+d.text,await r("debug",`[chat.message] \u5DF2\u589E\u5F3A part ${d.id}\uFF0Ctemplate \u957F\u5EA6=${f.length}`));v.set(s,a),await r("info",`[chat.message] \u5B8C\u6210\u9996\u6761\u6D88\u606F\u589E\u5F3A (sessionID: ${s}, messageID: ${a})`),await r("debug",`[chat.message] \u6807\u8BB0\u540E enhancedSessions: ${JSON.stringify([...v.entries()])}`),await r("debug","[chat.message] ====== \u5904\u7406\u5B8C\u6210 ======")},event:async({event:l})=>{try{if(l.type==="session.created"){await r("debug",`[session.created] \u4E8B\u4EF6\u5C5E\u6027: ${JSON.stringify(l.properties)}`);let t=l.properties?.info?.id,i=l.properties?.info?.directory;if(await r("debug",`[session.created] \u5C1D\u8BD5\u4FDD\u5B58\u4F1A\u8BDD\u76EE\u5F55: (evt.properties as any).sessionID=${l.properties?.sessionID}, info.id=${t}, directory=${i}`),await r("debug",`[session.created] sessionDirectories.size=${Z.size}, \u73B0\u6709key: ${Array.from(Z.keys()).join(",")}`),i&&(Z.set(t,i),await r("debug",`[session.created] \u4FDD\u5B58\u4F1A\u8BDD\u76EE\u5F55\u5B8C\u6210: sessionID=${t}, directory=${i}`)),!t){await r("warn","[session.created] \u65E0\u6CD5\u83B7\u53D6 sessionID\uFF0C\u8DF3\u8FC7");return}return}if(l.type==="session.error"){let t=l.properties?.sessionID,i=l.properties?.error;await r("debug",`[session.error] \u4E8B\u4EF6\u5C5E\u6027: ${JSON.stringify(l.properties)}, sessionID=${t}, error=${JSON.stringify(i)}`),i&&i.name==="MessageAbortedError"&&t&&(b.add(t),await r("info",`[session.error] \u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\u4F1A\u8BDD ${t}`));return}if(l.type==="session.idle"){let t=l.properties?.sessionID,i=(vt.get(t)||0)+1;if(vt.set(t,i),i===1&&await r("info",`[session.idle] \u7B2C1\u6B21\u89E6\u53D1 | \u72B6\u6001: userStopped=${b.has(t)}, injected=${T.has(t)}, injecting=${P.has(t)}`),i>1&&(P.has(t)||T.has(t))){await r("debug",`[session.idle] \u7B2C${i}\u6B21\u89E6\u53D1\u91CD\u590D\uFF0C\u8DF3\u8FC7 | sessionId=${t}`);return}if(!t){await r("warn","[session.idle] \u65E0\u6CD5\u83B7\u53D6 sessionID\uFF0C\u8DF3\u8FC7");return}if(i===1&&await r("debug",`[session.idle] \u8BE6\u7EC6\u72B6\u6001: userStoppedSessions=${JSON.stringify([...b])}, injectedSessions=${JSON.stringify([...T])}, injectingSessions=${JSON.stringify([...P])}`),T.has(t)){await r("debug",`[session.idle] \u4F1A\u8BDD ${t} \u5DF2\u6CE8\u5165\u8FC7\u63D0\u793A\u8BCD\uFF0C\u8DF3\u8FC7`);return}if(P.has(t)){if(await r("debug",`[session.idle] \u4F1A\u8BDD ${t} \u6B63\u5728\u6CE8\u5165\u4E2D\uFF0C\u7B49\u5F85...`),await new Promise(s=>setTimeout(s,1e3)),b.has(t)){await r("info",`[session.idle] \u7B49\u5F85\u540E\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${t}`),b.delete(t),P.delete(t);return}if(T.has(t)){await r("debug",`[session.idle] \u7B49\u5F85\u540E\u786E\u8BA4\u5DF2\u6CE8\u5165\uFF0C\u8DF3\u8FC7 | sessionId=${t}`);return}if(!b.has(t)){await r("debug",`[session.idle] \u7B49\u5F85\u540E\u672A\u68C0\u6D4B\u5230\u7528\u6237\u505C\u6B62\uFF0C\u7531\u9996\u6B21\u89E6\u53D1\u5904\u7406 | sessionId=${t}`),P.delete(t);return}await r("warn",`[session.idle] \u4F1A\u8BDD ${t} \u7B49\u5F85\u540E\u4ECD\u672A\u6CE8\u5165\u4F46\u4ECD\u5728\u6CE8\u5165\u4E2D\uFF0C\u8DF3\u8FC7`);return}if(P.add(t),await r("debug",`[session.idle] \u4F1A\u8BDD ${t} \u5F00\u59CB\u6CE8\u5165\uFF0C\u6807\u8BB0\u4E3A\u6B63\u5728\u6CE8\u5165`),await new Promise(s=>setTimeout(s,500)),await r("debug",`[session.idle] \u7B49\u5F85500ms\u540E\u68C0\u67E5: userStopped=${b.has(t)}, sessionId=${t}`),b.has(t)){await r("info",`[session.idle] \u7B49\u5F85\u540E\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${t}`),b.delete(t),P.delete(t);return}let c=null;try{let s=await o.command.list({});if(s.data){let u=s.data.find(f=>f.name===G.replace(/^\//,""));u&&u.template?(c=u.template,await r("info",`[session.idle] \u627E\u5230 ${G} \u547D\u4EE4\u7684 template`)):await r("warn",`[session.idle] \u672A\u627E\u5230 ${G} \u547D\u4EE4\u7684 template`)}}catch(s){let a=s instanceof Error?s.message:String(s);await r("error",`[session.idle] \u67E5\u8BE2\u547D\u4EE4 template \u5931\u8D25: ${a}`)}if(c===null){await r("info",`[session.idle] \u4F1A\u8BDD ${t} \u672A\u627E\u5230 /record-memory \u547D\u4EE4\u7684 template\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F`),P.delete(t);return}if(b.has(t)){await r("info",`[session.idle] \u6CE8\u5165\u524D\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${t}`),b.delete(t),P.delete(t);return}await r("info",`[session.idle] \u5F00\u59CB\u6CE8\u5165\u63D0\u793A\u8BCD | sessionId=${t}, promptText=${c.substring(0,50)}...`);try{await o.session.prompt({path:{id:t},body:{parts:[{type:"text",text:c}],noReply:!1}}),await r("info",`[session.idle] \u2705 \u6210\u529F\u6CE8\u5165\u63D0\u793A\u8BCD\u5230\u4F1A\u8BDD ${t}`),T.add(t),P.delete(t),await r("debug",`[session.idle] \u6CE8\u5165\u5B8C\u6210\uFF0C\u6E05\u7406\u72B6\u6001: injectedSessions=${JSON.stringify([...T])}, injectingSessions=${JSON.stringify([...P])}, userStoppedSessions=${JSON.stringify([...b])}`),Z.delete(t)}catch(s){let a=s instanceof Error?s.message:String(s);await r("error",`[session.idle] \u274C \u6CE8\u5165\u63D0\u793A\u8BCD\u5931\u8D25: ${a}`),P.delete(t),await r("debug",`[session.idle] \u6CE8\u5165\u5931\u8D25\uFF0C\u6E05\u7406\u72B6\u6001: injectingSessions=${JSON.stringify([...P])}, userStoppedSessions=${JSON.stringify([...b])}`)}return}}catch(t){let i=t instanceof Error?t.message:String(t);await r("error",`[event] \u5904\u7406\u4E8B\u4EF6 ${l.type} \u5931\u8D25: ${i}`)}}}};export{tn as HaimatiPlugin};
90
+ `+f.text,await o.debug(`[chat.message] \u5DF2\u589E\u5F3A part ${f.id}\uFF0Ctemplate \u957F\u5EA6=${d.length}`));T.set(s,c),await o.debug(`[chat.message] \u5B8C\u6210\u9996\u6761\u6D88\u606F\u589E\u5F3A (sessionID: ${s}, messageID: ${c})`),await o.debug(`[chat.message] \u6807\u8BB0\u540E enhancedSessions: ${JSON.stringify([...T.entries()])}`),await o.debug("[chat.message] ====== \u5904\u7406\u5B8C\u6210 ======")},event:async({event:a})=>{try{if(a.type==="session.created"){await o.debug(`[session.created] \u4E8B\u4EF6\u5C5E\u6027: ${JSON.stringify(a.properties)}`);let e=a.properties?.info?.id,i=a.properties?.info?.directory;if(await o.debug(`[session.created] \u5C1D\u8BD5\u4FDD\u5B58\u4F1A\u8BDD\u76EE\u5F55: (evt.properties as any).sessionID=${a.properties?.sessionID}, info.id=${e}, directory=${i}`),await o.debug(`[session.created] sessionDirectories.size=${st.size}, \u73B0\u6709key: ${Array.from(st.keys()).join(",")}`),i&&(st.set(e,i),await o.debug(`[session.created] \u4FDD\u5B58\u4F1A\u8BDD\u76EE\u5F55\u5B8C\u6210: sessionID=${e}, directory=${i}`)),!e){await o.warn("[session.created] \u65E0\u6CD5\u83B7\u53D6 sessionID\uFF0C\u8DF3\u8FC7");return}return}if(a.type==="session.error"){let e=a.properties?.sessionID,i=a.properties?.error;await o.debug(`[session.error] \u4E8B\u4EF6\u5C5E\u6027: ${JSON.stringify(a.properties)}, sessionID=${e}, error=${JSON.stringify(i)}`),i&&i.name==="MessageAbortedError"&&e&&(P.add(e),await o.debug(`[session.error] \u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\u4F1A\u8BDD ${e}`));return}if(a.type==="session.idle"){let e=a.properties?.sessionID,i=(Ut.get(e)||0)+1;if(Ut.set(e,i),i===1&&await o.debug(`[session.idle] \u7B2C1\u6B21\u89E6\u53D1 | \u72B6\u6001: userStopped=${P.has(e)}, injected=${A.has(e)}, injecting=${S.has(e)}`),i>1&&(S.has(e)||A.has(e))){await o.debug(`[session.idle] \u7B2C${i}\u6B21\u89E6\u53D1\u91CD\u590D\uFF0C\u8DF3\u8FC7 | sessionId=${e}`);return}if(!e){await o.warn("[session.idle] \u65E0\u6CD5\u83B7\u53D6 sessionID\uFF0C\u8DF3\u8FC7");return}if(i===1&&await o.debug(`[session.idle] \u8BE6\u7EC6\u72B6\u6001: userStoppedSessions=${JSON.stringify([...P])}, injectedSessions=${JSON.stringify([...A])}, injectingSessions=${JSON.stringify([...S])}`),A.has(e)){await o.debug(`[session.idle] \u4F1A\u8BDD ${e} \u5DF2\u6CE8\u5165\u8FC7\u63D0\u793A\u8BCD\uFF0C\u8DF3\u8FC7`);return}if(S.has(e)){if(await o.debug(`[session.idle] \u4F1A\u8BDD ${e} \u6B63\u5728\u6CE8\u5165\u4E2D\uFF0C\u7B49\u5F85...`),await new Promise(s=>setTimeout(s,1e3)),P.has(e)){await o.debug(`[session.idle] \u7B49\u5F85\u540E\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${e}`),P.delete(e),S.delete(e);return}if(A.has(e)){await o.debug(`[session.idle] \u7B49\u5F85\u540E\u786E\u8BA4\u5DF2\u6CE8\u5165\uFF0C\u8DF3\u8FC7 | sessionId=${e}`);return}if(!P.has(e)){await o.debug(`[session.idle] \u7B49\u5F85\u540E\u672A\u68C0\u6D4B\u5230\u7528\u6237\u505C\u6B62\uFF0C\u7531\u9996\u6B21\u89E6\u53D1\u5904\u7406 | sessionId=${e}`),S.delete(e);return}await o.warn(`[session.idle] \u4F1A\u8BDD ${e} \u7B49\u5F85\u540E\u4ECD\u672A\u6CE8\u5165\u4F46\u4ECD\u5728\u6CE8\u5165\u4E2D\uFF0C\u8DF3\u8FC7`);return}if(S.add(e),await o.debug(`[session.idle] \u4F1A\u8BDD ${e} \u5F00\u59CB\u6CE8\u5165\uFF0C\u6807\u8BB0\u4E3A\u6B63\u5728\u6CE8\u5165`),await new Promise(s=>setTimeout(s,500)),await o.debug(`[session.idle] \u7B49\u5F85500ms\u540E\u68C0\u67E5: userStopped=${P.has(e)}, sessionId=${e}`),P.has(e)){await o.debug(`[session.idle] \u7B49\u5F85\u540E\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${e}`),P.delete(e),S.delete(e);return}let l=null;try{let s=await r.command.list({});if(s.data){let g=s.data.find(d=>d.name===K.replace(/^\//,""));g&&g.template?(l=g.template,await o.debug(`[session.idle] \u627E\u5230 ${K} \u547D\u4EE4\u7684 template`)):await o.warn(`[session.idle] \u672A\u627E\u5230 ${K} \u547D\u4EE4\u7684 template`)}}catch(s){let c=s instanceof Error?s.message:String(s);await o.error(`[session.idle] \u67E5\u8BE2\u547D\u4EE4 template \u5931\u8D25: ${c}`)}if(l===null){await o.debug(`[session.idle] \u4F1A\u8BDD ${e} \u672A\u627E\u5230 /record-memory \u547D\u4EE4\u7684 template\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F`),S.delete(e);return}if(P.has(e)){await o.debug(`[session.idle] \u6CE8\u5165\u524D\u68C0\u6D4B\u5230\u7528\u6237\u4E3B\u52A8\u505C\u6B62\uFF0C\u6E05\u7406\u5E76\u7ED3\u675F | sessionId=${e}`),P.delete(e),S.delete(e);return}await o.debug(`[session.idle] \u5F00\u59CB\u6CE8\u5165\u63D0\u793A\u8BCD | sessionId=${e}, promptText=${l.substring(0,50)}...`);try{await r.session.prompt({path:{id:e},body:{parts:[{type:"text",text:l}],noReply:!1}}),await o.debug(`[session.idle] \u2705 \u6210\u529F\u6CE8\u5165\u63D0\u793A\u8BCD\u5230\u4F1A\u8BDD ${e}`),A.add(e),S.delete(e),await o.debug(`[session.idle] \u6CE8\u5165\u5B8C\u6210\uFF0C\u6E05\u7406\u72B6\u6001: injectedSessions=${JSON.stringify([...A])}, injectingSessions=${JSON.stringify([...S])}, userStoppedSessions=${JSON.stringify([...P])}`),st.delete(e)}catch(s){let c=s instanceof Error?s.message:String(s);await o.error(`[session.idle] \u274C \u6CE8\u5165\u63D0\u793A\u8BCD\u5931\u8D25: ${c}`),S.delete(e),await o.debug(`[session.idle] \u6CE8\u5165\u5931\u8D25\uFF0C\u6E05\u7406\u72B6\u6001: injectingSessions=${JSON.stringify([...S])}, userStoppedSessions=${JSON.stringify([...P])}`)}return}}catch(e){let i=e instanceof Error?e.message:String(e);await o.error(`[event] \u5904\u7406\u4E8B\u4EF6 ${a.type} \u5931\u8D25: ${i}`)}}}};export{In as HaimatiPlugin};
package/dist/package.json CHANGED
@@ -1,27 +1,27 @@
1
- {
2
- "name": "opencode-haimati",
3
- "version": "1.1.4",
4
- "description": "OpenCode plugin for a file-based memory system inspired by the hippocampus, providing long-term memory storage and retrieval across sessions.",
5
- "main": "./dist/index.js",
6
- "type": "module",
7
- "license": "MIT",
8
- "files": [
9
- "dist"
10
- ],
11
- "scripts": {
12
- "build": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin --minify && cp package.json dist/",
13
- "build:uncompressed": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin && cp package.json dist/",
14
- "typecheck": "tsc --noEmit",
15
- "prepublishOnly": "npm run build",
16
- "test": "npx tsx test/index.ts"
17
- },
18
- "peerDependencies": {
19
- "@opencode-ai/plugin": ">=0.15.0",
20
- "typescript": ">=5.0.0"
21
- },
22
- "devDependencies": {
23
- "@opencode-ai/plugin": "^0.15.0",
24
- "@types/bun": "^1.3.1",
25
- "typescript": "^5.9.3"
26
- }
27
- }
1
+ {
2
+ "name": "opencode-haimati",
3
+ "version": "1.2.0",
4
+ "description": "OpenCode plugin for a file-based memory system inspired by the hippocampus, providing long-term memory storage and retrieval across sessions.",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin --minify && cp package.json dist/",
13
+ "build:uncompressed": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin && cp package.json dist/",
14
+ "typecheck": "tsc --noEmit",
15
+ "prepublishOnly": "npm run build",
16
+ "test": "npx tsx test/index.ts"
17
+ },
18
+ "peerDependencies": {
19
+ "@opencode-ai/plugin": ">=0.15.0",
20
+ "typescript": ">=5.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@opencode-ai/plugin": "^0.15.0",
24
+ "@types/bun": "^1.3.1",
25
+ "typescript": "^5.9.3"
26
+ }
27
+ }
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
- {
2
- "name": "opencode-haimati",
3
- "version": "1.1.4",
4
- "description": "OpenCode plugin for a file-based memory system inspired by the hippocampus, providing long-term memory storage and retrieval across sessions.",
5
- "main": "./dist/index.js",
6
- "type": "module",
7
- "license": "MIT",
8
- "files": [
9
- "dist"
10
- ],
11
- "scripts": {
12
- "build": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin --minify && cp package.json dist/",
13
- "build:uncompressed": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin && cp package.json dist/",
14
- "typecheck": "tsc --noEmit",
15
- "prepublishOnly": "npm run build",
16
- "test": "npx tsx test/index.ts"
17
- },
18
- "peerDependencies": {
19
- "@opencode-ai/plugin": ">=0.15.0",
20
- "typescript": ">=5.0.0"
21
- },
22
- "devDependencies": {
23
- "@opencode-ai/plugin": "^0.15.0",
24
- "@types/bun": "^1.3.1",
25
- "typescript": "^5.9.3"
26
- }
27
- }
1
+ {
2
+ "name": "opencode-haimati",
3
+ "version": "1.2.0",
4
+ "description": "OpenCode plugin for a file-based memory system inspired by the hippocampus, providing long-term memory storage and retrieval across sessions.",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin --minify && cp package.json dist/",
13
+ "build:uncompressed": "rm -rf dist && npx esbuild src/index.ts --bundle --platform=node --outdir=dist --format=esm --external:@opencode-ai/plugin && cp package.json dist/",
14
+ "typecheck": "tsc --noEmit",
15
+ "prepublishOnly": "npm run build",
16
+ "test": "npx tsx test/index.ts"
17
+ },
18
+ "peerDependencies": {
19
+ "@opencode-ai/plugin": ">=0.15.0",
20
+ "typescript": ">=5.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@opencode-ai/plugin": "^0.15.0",
24
+ "@types/bun": "^1.3.1",
25
+ "typescript": "^5.9.3"
26
+ }
27
+ }