opencode-haimati 2.1.1 → 2.1.2

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,209 +1,154 @@
1
- # opencode-haimati
2
-
3
- OpenCode 提供基于文件系统的长期记忆存储和检索功能。
4
-
5
- ## 功能特性
6
-
7
- - 类海马体记忆机制:模拟人脑记忆系统的分类存储
8
- - 树形索引结构 + 分组书页存储
9
- - 多模式搜索:序号精确查询 + 关键字模糊搜索
10
- - 完整 CRUD:读取、写入、更新、删除、移动
11
- - 版本并发控制:基于 version 的乐观锁
12
- - 文件锁机制:支持网络共享挂载多用户并发写入
13
- - 自动工作规则提示:会话首条消息时自动注入工作流程提醒
14
- - memo-map 文件关联:记忆与项目文件/目录建立关联(多路径数组支持),读取文件时自动注入关联记忆的完整正文
15
- - 文件路径校验:filePath 自动检查路径是否存在,项目内用相对路径、项目外用绝对路径
16
- - 自动关联记忆检索(auto-read):关键词提取 → 搜索 → 注入 Top 3 相关记忆到消息上下文
17
- - 自动记忆写入(autoWrite,默认关闭):AI 回复完成后异步触发 AI 自主审查并写入有价值的知识
18
- - autoUpdate:启动时自动检查 npm registry 新版本,无需手动升级
19
- - 启动清理:自动清除 memo-map 中已不存在的文件/目录条目
20
-
21
- ## 安装
22
-
23
- ```bash
24
- npm install -g opencode-haimati
25
- #
26
- bun add -g opencode-haimati
27
- ```
28
-
29
- ## 配置
30
-
31
- `opencode.json` 中添加插件:
32
-
33
- ```json
34
- {
35
- "$schema": "https://opencode.ai/config.json",
36
- "plugin": ["opencode-haimati"]
37
- }
38
- ```
39
-
40
- 支持三级配置(优先级从低到高):
41
-
42
- 1. **全局**:`~/.config/opencode/haimati.jsonc` 或 `haimati.json`
43
- 2. **自定义**:`$OPENCODE_CONFIG_DIR/haimati.jsonc` 或 `haimati.json`(如果环境变量存在)
44
- 3. **项目**:`.opencode/haimati.jsonc` 或 `haimati.json`
45
-
46
- 配置示例(haimati.jsonc):
47
- ```jsonc
48
- {
49
- // 海马体存储路径(相对项目根目录,或绝对路径)
50
- "haimatiPath": ".haimati",
51
-
52
- // 日志配置(仅全局配置有效)
53
- "log": {
54
- "level": "info", // debug、info、warn、error
55
- "logRetentionDays": 180 // 日志保留天数
56
- },
57
-
58
- // 自动更新:设为 false 禁用启动时版本检查(默认 true)
59
- "autoUpdate": true,
60
-
61
- // 自动记忆写入:设为 true 启用 AI 自主记忆写入(默认 false,需显式开启)
62
- "autoWrite": true
63
- }
64
- ```
65
-
66
- 插件在每次会话的首条用户消息时自动注入工作规则提示,
67
- 告知 AI 海马体插件可用,指导其按需使用 `haimati_search`/`haimati_read` 读取记忆,
68
- 并在工作完成后写入新知识。
69
-
70
- `autoUpdate` 控制插件是否在启动时检查 npm registry 新版本。检测到新版本且依赖声明允许更新时,删除插件包裹目录,触发 OpenCode 下次启动时自动安装最新版。
71
-
72
- 首次运行时自动创建全局配置模板。
73
-
74
- ## 目录结构
75
-
76
- ```
77
- .haimati/
78
- ├── .lock # 文件锁(支持网络共享挂载多用户协调)
79
- ├── 索引.md # 树形索引
80
- ├── memo-map.yaml # 文件/目录与记忆的关联映射
81
- └── 书页/ # 记忆内容(每50个序号一分组)
82
- ```
83
-
84
- ## 工具
85
-
86
- | 工具 | 说明 |
87
- |------|------|
88
- | `haimati_read` | 读取记忆(单条/批量,支持分页,正文后展示系统元数据) |
89
- | `haimati_write` | 写入新记忆,可选 filePath 数组建立文件关联 |
90
- | `haimati_search` | 搜索(标题/分类/内容,match必填) |
91
- | `haimati_edit` | 部分修改(字符串替换 + 增减文件关联数组) |
92
- | `haimati_move` | 修改分类路径和/或标题 |
93
- | `haimati_delete` | 删除记忆(自动清理文件关联) |
94
- | `haimati_list` | 列出索引(按分类浏览,支持详细内容) |
95
-
96
- ## 使用示例
97
-
98
- ```typescript
99
- // 写入(title 不能以 " - 序号" 结尾)
100
- haimati_write({ category: "xxx项目/签章", title: "签章服务WS通信机制", content: "..." })
101
-
102
- // 写入 + 文件关联
103
- haimati_write({ category: "xxx项目/签章", title: "签章服务WS通信机制", content: "...", filePath: ["src/ws.ts"] })
104
-
105
- // 写入 + 多文件关联(数组支持多路径)
106
- haimati_write({ category: "xxx项目/签章", title: "签章服务WS通信机制", content: "...", filePath: ["src/ws.ts", "src/tools.ts"] })
107
-
108
- // 写入 + 目录关联(末尾 / 表示目录,匹配该目录下所有文件)
109
- haimati_write({ category: "xxx项目/签章", title: "签章服务WS通信机制", content: "...", filePath: ["src/"] })
110
-
111
- // 读取(单条)
112
- haimati_read({ query: "086" })
113
-
114
- // 读取(批量:逗号分隔或范围)
115
- haimati_read({ query: "086,087,088" })
116
- haimati_read({ query: "086-090" })
117
-
118
- // 搜索
119
- haimati_search({ keyword: "WebSocket", match: "or" })
120
-
121
- // 修改
122
- // 单处替换
123
- haimati_edit({
124
- query: "086",
125
- oldString: "旧文本",
126
- newString: "新文本"
127
- })
128
-
129
- // 全部替换
130
- haimati_edit({
131
- query: "086",
132
- oldString: "旧文本",
133
- newString: "新文本",
134
- replaceAll: true
135
- })
136
-
137
- // 编辑 + 新增文件关联(数组支持多路径)
138
- haimati_edit({ query: "086", oldString: "...", newString: "...", filePath: ["src/new.ts", "src/utils.ts"] })
139
-
140
- // 编辑 + 移除文件关联(数组支持多路径)
141
- haimati_edit({ query: "086", oldString: "...", newString: "...", removeFilePath: ["src/old.ts"] })
142
-
143
- // 移动
144
- haimati_move({ query: "086", newCategory: "xxx项目/客户端" })
145
-
146
- // 删除
147
- haimati_delete({ query: "086" })
148
-
149
- // 列出(树形索引)
150
- haimati_list()
151
-
152
- // 列出(指定分类,含详细内容)
153
- haimati_list({ category: "xxx项目", recursive: true, detail: true })
154
- ```
155
-
156
- ### memo-map 文件关联
157
-
158
- 记忆可与项目文件/目录建立关联。AI 通过 `read` 工具读取文件时,自动在输出末尾注入关联记忆的完整正文:
159
-
160
- ```
161
- <system-reminder>
162
- 文件 src/index.ts 关联了以下海马体记忆:
163
-
164
- ===== #043 =====
165
- 1|记忆正文内容...
166
- ------system------
167
- title:xxx
168
- create_time:xxx
169
- update_time:xxx
170
- file_paths: src/index.ts, src/tools.ts, docs/
171
- </system-reminder>
172
- ```
173
-
174
- - `filePath: ["src/index.ts"]` — 精确文件关联(数组支持多路径)
175
- - `filePath: ["src/"]` — 目录关联(末尾 `/`,匹配该目录下所有文件及子目录)
176
- - `filePath: ["./"]` — 项目根目录关联,读取任何项目文件时均触发
177
- - `filePath: ["src/index.ts", "C:/external/file.txt"]` — 项目内文件用相对路径,项目外文件用绝对路径
178
- - 路径失效校验:filePath 中不存在的路径会报错提示
179
- - 关联关系记录在 `.haimati/memo-map.yaml`
180
- - 插件启动时自动清理已不存在的文件/目录条目
181
- - 去重机制:按记忆 ID + update_time 跟踪,无变化不重复注入;haimati_read 读取过的记忆也不会重复注入;记忆编辑后自动重新注入
182
- - 输出系统区域包含 `file_paths` 行,列出该记忆关联的所有文件/目录路径(字典序),无关联时不显示
183
-
184
- ### haimati_edit 使用说明
185
-
186
- **三种编辑模式**:
187
-
188
- 1. **内容替换**:提供 `oldString` + `newString`,替换记忆正文中的文本
189
- 2. **关联变更**:提供 `filePath` / `removeFilePath` 数组,增减文件关联
190
- 3. **同时执行**:以上参数都提供时,内容替换和关联变更都会生效
191
-
192
- **参数说明**:
193
- - `oldString` / `newString` 均为可选,必须**同时存在**才执行内容替换
194
- - `filePath` / `removeFilePath` 可选,存在时才执行关联增减
195
- - 至少需要提供**内容替换**或**关联变更**之一,否则报错
196
- - `replaceAll=false`(默认):只替换第一个匹配项
197
- - `replaceAll=true`:替换所有匹配项
198
- - 如果 `oldString` 在内容中不存在,会报错提示,说明内容已被修改
199
-
200
- ## 日志
201
-
202
- 日志位于:`~/.opencode-haimati/log/{yyyy-MM-dd}.log`(按天轮转)
203
-
204
- 日志配置整合在 `~/.config/opencode/haimati.jsonc` 的 `log` 字段中。
205
-
206
- ## 依赖
207
-
208
- - OpenCode v0.15.0+
209
- - Node.js 或 Bun
1
+ # opencode-haimati
2
+
3
+ OpenCode 的长期记忆插件。它把记忆保存在项目文件系统里,让 AI 能跨会话读取、维护项目知识。
4
+
5
+ ## 它做什么
6
+
7
+ - 提供 `haimati_*` 工具,用于写入、搜索、读取、编辑和删除记忆
8
+ - 支持把记忆关联到文件或目录
9
+ - AI 读取文件时,会自动把关联记忆注入到 `read` 输出里
10
+ - 会话首条消息会提示 AI 使用海马体记忆,并在工作结束后维护记忆
11
+ - 可选开启 `autoWrite`,让 AI 回复完成后自动审查并写入有价值的新知识
12
+
13
+ ## 安装
14
+
15
+ ```bash
16
+ npm install -g opencode-haimati
17
+ ```
18
+
19
+ 或:
20
+
21
+ ```bash
22
+ bun add -g opencode-haimati
23
+ ```
24
+
25
+ ## 启用插件
26
+
27
+ 在 `opencode.json` 中添加:
28
+
29
+ ```json
30
+ {
31
+ "$schema": "https://opencode.ai/config.json",
32
+ "plugin": ["opencode-haimati"]
33
+ }
34
+ ```
35
+
36
+ ## 配置
37
+
38
+ 插件可不配置直接使用,默认把记忆存到项目下的 `.haimati/`。
39
+
40
+ 需要自定义时,可创建 `haimati.jsonc`:
41
+
42
+ ```jsonc
43
+ {
44
+ // 记忆存储路径,支持相对项目根目录或绝对路径
45
+ "haimatiPath": ".haimati",
46
+
47
+ // 启动时自动检查新版本,默认 true
48
+ "autoUpdate": true,
49
+
50
+ // AI 回复后自动维护记忆,默认 false
51
+ "autoWrite": false,
52
+
53
+ // 日志配置,仅全局配置有效
54
+ "log": {
55
+ "level": "info",
56
+ "logRetentionDays": 180
57
+ }
58
+ }
59
+ ```
60
+
61
+ 配置读取顺序从低到高:
62
+
63
+ 1. `~/.config/opencode/haimati.jsonc`
64
+ 2. `$OPENCODE_CONFIG_DIR/haimati.jsonc`
65
+ 3. 项目内 `.opencode/haimati.jsonc`
66
+
67
+ ## 常用工具
68
+
69
+ | 工具 | 用途 |
70
+ |------|------|
71
+ | `haimati_search` | 搜索记忆 |
72
+ | `haimati_read` | 读取记忆,支持单条、批量和范围 |
73
+ | `haimati_write` | 写入新记忆,可同时建立文件关联 |
74
+ | `haimati_edit` | 修改记忆内容,或增减文件关联 |
75
+ | `haimati_move` | 修改分类或标题 |
76
+ | `haimati_delete` | 删除记忆 |
77
+ | `haimati_list` | 浏览索引和分类 |
78
+
79
+ ## 常见用法
80
+
81
+ 写入记忆:
82
+
83
+ ```ts
84
+ haimati_write({
85
+ category: "项目/后端",
86
+ title: "鉴权中间件规则",
87
+ content: "鉴权失败统一返回 401,不在业务层重复判断。"
88
+ })
89
+ ```
90
+
91
+ 写入并关联文件:
92
+
93
+ ```ts
94
+ haimati_write({
95
+ category: "项目/后端",
96
+ title: "鉴权中间件规则",
97
+ content: "鉴权逻辑集中在 src/auth.ts。",
98
+ filePath: ["src/auth.ts"]
99
+ })
100
+ ```
101
+
102
+ 搜索和读取:
103
+
104
+ ```ts
105
+ haimati_search({ keyword: "鉴权", match: "or" })
106
+ haimati_read({ query: "086" })
107
+ haimati_read({ query: "086-090" })
108
+ ```
109
+
110
+ 修改内容或文件关联:
111
+
112
+ ```ts
113
+ haimati_edit({
114
+ query: "086",
115
+ oldString: "旧规则",
116
+ newString: "新规则"
117
+ })
118
+
119
+ haimati_edit({
120
+ query: "086",
121
+ filePath: ["src/auth.ts", "src/middleware/"]
122
+ })
123
+ ```
124
+
125
+ ## 文件关联
126
+
127
+ `filePath` 用来把记忆和代码文件关联起来。之后 AI 读取这些文件时,插件会自动注入相关记忆。
128
+
129
+ 常用写法:
130
+
131
+ - `filePath: ["src/auth.ts"]`:关联单个文件
132
+ - `filePath: ["src/"]`:关联目录,末尾 `/` 表示目录
133
+ - `filePath: ["./"]`:关联整个项目
134
+ - `filePath: ["src/auth.ts", "src/api.ts"]`:一次关联多个路径
135
+
136
+ 项目内路径建议使用相对路径。项目外文件会记录为绝对路径。
137
+
138
+ ## 本地文件
139
+
140
+ 默认目录结构:
141
+
142
+ ```text
143
+ .haimati/
144
+ ├── 索引.md
145
+ ├── memo-map.yaml
146
+ └── 书页/
147
+ ```
148
+
149
+ 一般不需要手动编辑这些文件,优先通过 `haimati_*` 工具操作。
150
+
151
+ ## 运行要求
152
+
153
+ - OpenCode v0.15.0+
154
+ - Node.js 或 Bun
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import at from"path";import{tool as w}from"@opencode-ai/plugin";import S from"path";import Lt from"os";import X from"fs";var Dt=".haimati",Et="\u7D22\u5F15.md";var kt="info";import J from"path";import ue from"os";import U from"fs";var fe=["haimati.jsonc","haimati.json"];function de(t){let n="",e=0,r=!1;for(;e<t.length;){let i=t[e],o=t[e+1];if(r){if(i==="\\"){n+=i+o,e+=2;continue}i==='"'&&(r=!1),n+=i,e++;continue}if(i==='"'){r=!0,n+=i,e++;continue}if(i==="/"&&o==="/"){for(;e<t.length&&t[e]!==`
1
+ import at from"path";import{tool as w}from"@opencode-ai/plugin";import S from"path";import Lt from"os";import X from"fs";var Et=".haimati",Dt="\u7D22\u5F15.md";var kt="info";import J from"path";import ue from"os";import U from"fs";var fe=["haimati.jsonc","haimati.json"];function de(t){let n="",e=0,r=!1;for(;e<t.length;){let i=t[e],o=t[e+1];if(r){if(i==="\\"){n+=i+o,e+=2;continue}i==='"'&&(r=!1),n+=i,e++;continue}if(i==='"'){r=!0,n+=i,e++;continue}if(i==="/"&&o==="/"){for(;e<t.length&&t[e]!==`
2
2
  `;)e++;continue}if(i==="/"&&o==="*"){for(e+=2;e<t.length-1&&!(t[e]==="*"&&t[e+1]==="/");)e++;e+=2;continue}n+=i,e++}return n}function lt(t){let e=de(t).replace(/,\s*([}\]])/g,"$1");return JSON.parse(e)}function st(t){for(let n of fe){let e=J.join(t,n);if(U.existsSync(e))return e}return null}function ct(t){try{let n=U.readFileSync(t,"utf-8"),e=lt(n);return typeof e=="object"&&e!==null?e:{}}catch{return{}}}function V(t,n){let e={...t};for(let r of Object.keys(n)){let i=e[r],o=n[r];i&&o&&typeof i=="object"&&typeof o=="object"&&!Array.isArray(i)&&!Array.isArray(o)?e[r]=V(i,o):o!==void 0&&(e[r]=o)}return e}function vt(){return J.join(ue.homedir(),".config","opencode")}function me(){return process.env.OPENCODE_CONFIG_DIR||null}function ge(t){return J.join(t,".opencode")}function pe(){let t=vt(),n=J.join(t,"haimati.jsonc");if(!U.existsSync(n))try{U.existsSync(t)||U.mkdirSync(t,{recursive:!0}),U.writeFileSync(n,`{
3
3
  // \u6D77\u9A6C\u4F53\u5B58\u50A8\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\uFF0C\u6216\u4F7F\u7528\u7EDD\u5BF9\u8DEF\u5F84\uFF09
4
4
  // "haimatiPath": ".haimati",
@@ -22,10 +22,10 @@ import at from"path";import{tool as w}from"@opencode-ai/plugin";import S from"pa
22
22
  // \u542F\u52A8\u65F6\u68C0\u67E5 npm registry \u662F\u5426\u6709\u65B0\u7248\u672C
23
23
  // "autoUpdate": true
24
24
  }
25
- `,"utf-8")}catch{}}function Y(t){pe();let n={},e=st(vt());if(e){let o=ct(e);n=V(n,o)}let r=me();if(r){let o=st(r);if(o){let a=ct(o);n=V(n,a)}}let i=st(ge(t));if(i){let o=ct(i);n=V(n,o)}return n}function Ct(t,n,e){return t.haimatiPath?J.resolve(n,t.haimatiPath):e}function I(t){let n=Y(t),e=S.join(t,Dt);return Ct(n,t,e)}function D(t){return S.join(I(t),Et)}function ft(t){return S.join(I(t),".lock")}function dt(t){return S.join(I(t),"\u4E66\u9875")}function mt(t,n){let e=parseInt(n,10),r=Math.floor((e-1)/50)*50+1,i=r+50-1,o=`${String(r).padStart(3,"0")}-${String(i).padStart(3,"0")}`;return S.join(dt(t),o)}function Z(t,n){let e=String(parseInt(n,10)).padStart(3,"0");return S.join(mt(t,n),`${e}.md`)}function gt(){let t=Lt.homedir();return S.join(t,".opencode-haimati","log")}function pt(){let t={level:kt,logRetentionDays:180},n=S.join(Lt.homedir(),".config","opencode"),e=[S.join(n,"haimati.jsonc"),S.join(n,"haimati.json")].find(r=>X.existsSync(r));if(e)try{let r=X.readFileSync(e,"utf-8"),i=lt(r);if(i?.log)return{level:i.log.level||t.level,logRetentionDays:i.log.logRetentionDays??t.logRetentionDays}}catch{}return t}function L(t){return X.promises.mkdir(t,{recursive:!0}).then(()=>{})}function b(t){return X.promises.access(t).then(()=>!0).catch(()=>!1)}import Nt from"fs";import{promisify as Rt}from"util";import et from"fs";import ht from"path";import{promisify as nt}from"util";var we=nt(et.appendFile),$e=nt(et.readdir),be=nt(et.unlink),Pe=nt(et.stat),Ft={debug:0,info:1,warn:2,error:3};function Me(t){let n=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return`${n}-${e}-${r}`}function xe(t){let n=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),o=String(t.getMinutes()).padStart(2,"0"),a=String(t.getSeconds()).padStart(2,"0");return`${n}-${e}-${r} ${i}:${o}:${a}`}function _e(){let t=Me(new Date);return ht.join(gt(),`${t}.log`)}async function Se(t,n){try{let e=ht.dirname(t);await b(e)||await L(e),await we(t,n+`
26
- `,"utf-8"),De()}catch(e){console.error("[haimati] \u5199\u5165\u65E5\u5FD7\u6587\u4EF6\u5931\u8D25:",e)}}async function Tt(){try{let t=pt(),n=gt();if(!await b(n))return;let e=await $e(n),i=new Date().getTime()-t.logRetentionDays*24*60*60*1e3;for(let o of e){if(!o.match(/^\d{4}-\d{2}-\d{2}\.log$/))continue;let a=ht.join(n,o);(await Pe(a)).mtime.getTime()<i&&await be(a)}}catch(t){console.error("[haimati] \u6E05\u7406\u5386\u53F2\u65E5\u5FD7\u5931\u8D25:",t)}}async function tt(t,n,e){try{let r=pt();if(Ft[t]<Ft[r.level])return;let o=xe(new Date),a=e?`[${e}] `:"",l=`[${o}] [${t.toUpperCase()}] ${a}${n}`,f=_e();await Se(f,l)}catch(r){console.error("[haimati] \u65E5\u5FD7\u8BB0\u5F55\u5931\u8D25:",r)}}var c={debug(t,n){return tt("debug",t,n)},info(t,n){return tt("info",t,n)},warn(t,n){return tt("warn",t,n)},error(t,n){return tt("error",t,n)}};async function jt(){await Tt()}var At=0,Ie=36e5;async function De(){let t=Date.now();t-At<Ie||(At=t,await Tt())}var Ee=Rt(Nt.readFile),ke=Rt(Nt.writeFile);function ve(t){let n=0,e=0,r=t.length;for(;e<r;)if(t[e]==="\u2502"&&e+3<r&&t.slice(e+1,e+4)===" ")n++,e+=4;else if(t.slice(e,e+4)===" ")n++,e+=4;else{if((t[e]==="\u251C"||t[e]==="\u2514")&&e+3<r&&t.slice(e+1,e+4)==="\u2500\u2500 ")break;break}return n}function Ce(t){let e=t.trim().replace(/^[│├└─\s]+/,"").trim();return e==="/"?"/":!e.endsWith("/")||(e=e.slice(0,-1),!e)?null:e}function Le(t){let n=[],e=t.split(`
25
+ `,"utf-8")}catch{}}function Y(t){pe();let n={},e=st(vt());if(e){let o=ct(e);n=V(n,o)}let r=me();if(r){let o=st(r);if(o){let a=ct(o);n=V(n,a)}}let i=st(ge(t));if(i){let o=ct(i);n=V(n,o)}return n}function Ct(t,n,e){return t.haimatiPath?J.resolve(n,t.haimatiPath):e}function I(t){let n=Y(t),e=S.join(t,Et);return Ct(n,t,e)}function E(t){return S.join(I(t),Dt)}function ft(t){return S.join(I(t),".lock")}function dt(t){return S.join(I(t),"\u4E66\u9875")}function mt(t,n){let e=parseInt(n,10),r=Math.floor((e-1)/50)*50+1,i=r+50-1,o=`${String(r).padStart(3,"0")}-${String(i).padStart(3,"0")}`;return S.join(dt(t),o)}function Z(t,n){let e=String(parseInt(n,10)).padStart(3,"0");return S.join(mt(t,n),`${e}.md`)}function gt(){let t=Lt.homedir();return S.join(t,".opencode-haimati","log")}function pt(){let t={level:kt,logRetentionDays:180},n=S.join(Lt.homedir(),".config","opencode"),e=[S.join(n,"haimati.jsonc"),S.join(n,"haimati.json")].find(r=>X.existsSync(r));if(e)try{let r=X.readFileSync(e,"utf-8"),i=lt(r);if(i?.log)return{level:i.log.level||t.level,logRetentionDays:i.log.logRetentionDays??t.logRetentionDays}}catch{}return t}function L(t){return X.promises.mkdir(t,{recursive:!0}).then(()=>{})}function b(t){return X.promises.access(t).then(()=>!0).catch(()=>!1)}import Nt from"fs";import{promisify as Rt}from"util";import et from"fs";import ht from"path";import{promisify as nt}from"util";var we=nt(et.appendFile),$e=nt(et.readdir),be=nt(et.unlink),Pe=nt(et.stat),Ft={debug:0,info:1,warn:2,error:3};function Me(t){let n=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return`${n}-${e}-${r}`}function xe(t){let n=t.getFullYear(),e=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),o=String(t.getMinutes()).padStart(2,"0"),a=String(t.getSeconds()).padStart(2,"0");return`${n}-${e}-${r} ${i}:${o}:${a}`}function _e(){let t=Me(new Date);return ht.join(gt(),`${t}.log`)}async function Se(t,n){try{let e=ht.dirname(t);await b(e)||await L(e),await we(t,n+`
26
+ `,"utf-8"),Ee()}catch(e){console.error("[haimati] \u5199\u5165\u65E5\u5FD7\u6587\u4EF6\u5931\u8D25:",e)}}async function Tt(){try{let t=pt(),n=gt();if(!await b(n))return;let e=await $e(n),i=new Date().getTime()-t.logRetentionDays*24*60*60*1e3;for(let o of e){if(!o.match(/^\d{4}-\d{2}-\d{2}\.log$/))continue;let a=ht.join(n,o);(await Pe(a)).mtime.getTime()<i&&await be(a)}}catch(t){console.error("[haimati] \u6E05\u7406\u5386\u53F2\u65E5\u5FD7\u5931\u8D25:",t)}}async function tt(t,n,e){try{let r=pt();if(Ft[t]<Ft[r.level])return;let o=xe(new Date),a=e?`[${e}] `:"",l=`[${o}] [${t.toUpperCase()}] ${a}${n}`,f=_e();await Se(f,l)}catch(r){console.error("[haimati] \u65E5\u5FD7\u8BB0\u5F55\u5931\u8D25:",r)}}var c={debug(t,n){return tt("debug",t,n)},info(t,n){return tt("info",t,n)},warn(t,n){return tt("warn",t,n)},error(t,n){return tt("error",t,n)}};async function jt(){await Tt()}var At=0,Ie=36e5;async function Ee(){let t=Date.now();t-At<Ie||(At=t,await Tt())}var De=Rt(Nt.readFile),ke=Rt(Nt.writeFile);function ve(t){let n=0,e=0,r=t.length;for(;e<r;)if(t[e]==="\u2502"&&e+3<r&&t.slice(e+1,e+4)===" ")n++,e+=4;else if(t.slice(e,e+4)===" ")n++,e+=4;else{if((t[e]==="\u251C"||t[e]==="\u2514")&&e+3<r&&t.slice(e+1,e+4)==="\u2500\u2500 ")break;break}return n}function Ce(t){let e=t.trim().replace(/^[│├└─\s]+/,"").trim();return e==="/"?"/":!e.endsWith("/")||(e=e.slice(0,-1),!e)?null:e}function Le(t){let n=[],e=t.split(`
27
27
  `),r=[];for(let i of e){if(!i.trim())continue;let o=ve(i),a=i.match(/^\s*[│├└─\s]*(.+?)\s*-\s*(\d+)\s*$/);if(a){let l=a[1].trim(),f=String(parseInt(a[2],10)),m=r.slice(0,o).filter(u=>u!=="").join("/");n.push({id:f,category:m,title:l})}else{let l=Ce(i);if(l)if(l==="/"){r[o]="";for(let f=o+1;f<r.length;f++)delete r[f]}else{r[o]=l;for(let f=o+1;f<r.length;f++)delete r[f]}}}return n}function F(t,n){return t.find(e=>e.id===n)||null}function Wt(t,n,e){return t.find(r=>r.category===n&&r.title===e)||null}function Ot(t,n){return t.filter(e=>e.id!==n)}function yt(t){if(t.length===0)return null;let n={name:"/",children:[],entry:null};for(let r of t){let i=r.category.split("/"),o=n;for(let l=0;l<i.length;l++){let f=i[l];if(!f)continue;let d=o.children.find(m=>m.name===f);d||(d={name:f,children:[],entry:null},o.children.push(d)),o=d}let a={name:r.id,children:[],entry:r};o.children.push(a)}function e(r){r.children.sort((i,o)=>i.name.localeCompare(o.name,void 0,{sensitivity:"base"}));for(let i of r.children)e(i)}return e(n),n}function qt(t,n,e){let r=[],i=n+(e?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 "),o=t.name==="/"?"/":t.name+"/";r.push(`${i}${o}`),n=n+(e?" ":"\u2502 ");let a=t.children.filter(d=>d.entry===null),l=t.children.filter(d=>d.entry!==null),f=[...a,...l];for(let d=0;d<f.length;d++){let m=f[d],u=d===f.length-1;if(m.entry){let s=m.entry.id.padStart(3,"0"),g=n+(u?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ");r.push(`${g}${m.entry.title} - ${s}`)}else r.push(...qt(m,n,u))}return r}function wt(t){let n=yt(t);return n?qt(n,"",!0).join(`
28
- `):""}async function M(t){let n=D(t);if(!await b(n))return[];let e=await Ee(n,"utf-8");return Le(e)}async function K(t,n){let e=I(t);await b(e)||await L(e);let r=wt(n),i=D(t);await ke(i,r,"utf-8"),await c.debug(`[writeIndex] \u5199\u5165\u7D22\u5F15: ${i}, \u5171${n.length}\u6761`)}import it from"fs";import{promisify as rt}from"util";var Fe=rt(it.readFile),Ae=rt(it.writeFile),Te=rt(it.unlink),Ut=rt(it.mkdir);async function P(t,n){let e=Z(t,n);if(!await b(e))return null;let i=(await Fe(e,"utf-8")).split(`
28
+ `):""}async function M(t){let n=E(t);if(!await b(n))return[];let e=await De(n,"utf-8");return Le(e)}async function K(t,n){let e=I(t);await b(e)||await L(e);let r=wt(n),i=E(t);await ke(i,r,"utf-8"),await c.debug(`[writeIndex] \u5199\u5165\u7D22\u5F15: ${i}, \u5171${n.length}\u6761`)}import it from"fs";import{promisify as rt}from"util";var Fe=rt(it.readFile),Ae=rt(it.writeFile),Te=rt(it.unlink),Ut=rt(it.mkdir);async function P(t,n){let e=Z(t,n);if(!await b(e))return null;let i=(await Fe(e,"utf-8")).split(`
29
29
  `),o="------system------",a=Math.max(0,i.length-5),l=-1;for(let m=i.length-1;m>=a;m--)if(i[m].trim()===o){l=m;break}if(l===-1)return{title:"",createdAt:"",updatedAt:"",content:i.join(`
30
30
  `)};let f=i.slice(0,l).join(`
31
31
  `),d=i[l+1]?.trim();if(!d)return await c.warn("[readPage] \u51FA\u53C2: \u5143\u6570\u636E\u884C\u4E3A\u7A7A"),null;if(d.startsWith("{"))try{let m=JSON.parse(d);return{title:m.title||"",createdAt:m.create_time||"",updatedAt:m.update_time||m.create_time||"",content:f,systemMeta:m}}catch{return await c.warn("[readPage] \u51FA\u53C2: JSON \u89E3\u6790\u5931\u8D25"),null}return l+3>=i.length?(await c.warn("[readPage] \u51FA\u53C2: \u65E7\u683C\u5F0F\u4E0D\u5B8C\u6574"),null):{title:d,createdAt:i[l+2]||"",updatedAt:"",content:f,systemMeta:{title:d,create_time:i[l+2]||""}}}async function H(t,n,e,r,i,o){let a=dt(t);await b(a)||await Ut(a,{recursive:!0});let l=mt(t,n);await b(l)||await Ut(l,{recursive:!0});let f=Z(t,n),d="------system------",m=JSON.stringify({title:e,create_time:r,update_time:i}),u=`${d}
@@ -84,7 +84,7 @@ ${u}`:u;await Ae(f,s,"utf-8"),await c.debug(`[writePage] \u5199\u5165\u4E66\u987
84
84
  `;continue}u+=`#### ${s.title} - ${s.id.padStart(3,"0")}
85
85
  `,u+=N(s,g)+`
86
86
 
87
- `}return u}function oe(){return{haimati_read:w({description:`\u4ECE\u6D77\u9A6C\u4F53\u8BFB\u53D6\u8BB0\u5FC6\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0C\u81EA\u52A8\u8865\u5168\uFF08\u8F93\u5165'86'\u2192'086'\uFF09\u3002\u652F\u6301\u5355\u6761\u5206\u9875\uFF08offset/limit\uFF09\u548C\u6279\u91CF\u8BFB\u53D6\uFF08\u9017\u53F7\u5206\u9694\u5982'086,087'\uFF0C\u8303\u56F4\u5982'086-090'\uFF09\u3002\u8FD4\u56DE\u4EE5 "===== #N =====" \u5F00\u5934\uFF0C\u884C\u9996 "N|" \u4E3A\u884C\u53F7\u3002`,args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u5355\u6761\u5982 '086'\uFF0C\u6279\u91CF\u652F\u6301\u9017\u53F7\u5206\u9694\u5982 '086,087,088' \u6216\u8303\u56F4 '086-090'"),offset:w.schema.number().optional().default(1).describe("\u8D77\u59CB\u884C\u53F7\uFF08\u9ED8\u8BA4 1\uFF0C\u4EC5\u5355\u6761\u8BFB\u53D6\u751F\u6548\uFF09"),limit:w.schema.number().optional().default(2e3).describe("\u6700\u5927\u8BFB\u53D6\u884C\u6570\uFF08\u9ED8\u8BA4 2000\uFF0C\u4EC5\u5355\u6761\u8BFB\u53D6\u751F\u6548\uFF09")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e);if(await c.info(`[haimati_read] \u5F00\u59CB\u8BFB\u53D6 #${t.query}`),await c.debug(`[haimati_read] \u5165\u53C2: query="${t.query}", offset=${t.offset??1}, limit=${t.limit??2e3}`),!await b(r)){let i=`\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728\u4E8E ${r}`;return await c.debug(`[haimati_read] \u51FA\u53C2:
87
+ `}return u}function oe(){return{haimati_read:w({description:`\u4ECE\u6D77\u9A6C\u4F53\u8BFB\u53D6\u8BB0\u5FC6\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0C\u81EA\u52A8\u8865\u5168\uFF08\u8F93\u5165'86'\u2192'086'\uFF09\u3002\u652F\u6301\u5355\u6761\u5206\u9875\uFF08offset/limit\uFF09\u548C\u6279\u91CF\u8BFB\u53D6\uFF08\u9017\u53F7\u5206\u9694\u5982'086,087'\uFF0C\u8303\u56F4\u5982'086-090'\uFF09\u3002\u8FD4\u56DE\u4EE5 "===== #N =====" \u5F00\u5934\uFF0C\u884C\u9996 "N|" \u4E3A\u884C\u53F7\u3002`,args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u5355\u6761\u5982 '086'\uFF0C\u6279\u91CF\u652F\u6301\u9017\u53F7\u5206\u9694\u5982 '086,087,088' \u6216\u8303\u56F4 '086-090'"),offset:w.schema.number().optional().default(1).describe("\u8D77\u59CB\u884C\u53F7\uFF08\u9ED8\u8BA4 1\uFF0C\u4EC5\u5355\u6761\u8BFB\u53D6\u751F\u6548\uFF0C\u6279\u91CF\u8BFB\u53D6\u65F6\u5FFD\u7565\u6B64\u53C2\u6570\uFF09"),limit:w.schema.number().optional().default(2e3).describe("\u6700\u5927\u8BFB\u53D6\u884C\u6570\uFF08\u9ED8\u8BA4 2000\uFF0C\u4EC5\u5355\u6761\u8BFB\u53D6\u751F\u6548\uFF0C\u6279\u91CF\u8BFB\u53D6\u65F6\u5FFD\u7565\u6B64\u53C2\u6570\uFF09")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e);if(await c.info(`[haimati_read] \u5F00\u59CB\u8BFB\u53D6 #${t.query}`),await c.debug(`[haimati_read] \u5165\u53C2: query="${t.query}", offset=${t.offset??1}, limit=${t.limit??2e3}`),!await b(r)){let i=`\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728\u4E8E ${r}`;return await c.debug(`[haimati_read] \u51FA\u53C2:
88
88
  ${i}`),i}try{let i=await M(e),o=t.query.trim(),a=Mt(o);if(!a||a.length===0){let u=`\u9519\u8BEF\uFF1A\u65E0\u6548\u7684\u67E5\u8BE2\u683C\u5F0F "${o}"`;return await c.debug(`[haimati_read] \u51FA\u53C2:
89
89
  ${u}`),u}if(a.length===1){let u=a[0],s=F(i,u);if(!s)return await c.info(`[haimati_read] \u8BFB\u53D6\u5931\u8D25: \u672A\u627E\u5230\u8BB0\u5FC6 #${t.query}`),`\u672A\u627E\u5230\u8BB0\u5FC6: ${t.query}`;let g=await P(e,s.id);if(!g)return`\u672A\u627E\u5230\u4E66\u9875: #${s.id.padStart(3,"0")}`;let h=await C(e),p=Q(h,s.id);p.length>0&&(g.systemMeta={...g.systemMeta,file_paths:p.join(", ")});let y=N(s,g,{offset:t.offset??1,limit:t.limit??2e3}),$=`===== #${s.id.padStart(3,"0")} =====
90
90
  ${y}`;return await c.debug(`[haimati_read] \u51FA\u53C2:
@@ -102,34 +102,34 @@ ${t.content}`);try{let i=new Date().toLocaleString("zh-CN",{hour12:!1}),o=null;f
102
102
  \u7248\u672C: 1`;return await c.debug(`[haimati_write] \u51FA\u53C2:
103
103
  ${d}`),await c.info(`[haimati_write] \u5199\u5165\u6210\u529F: #${o} (${t.category}/${t.title})`),d}let a=await M(e),l=Wt(a,t.category,t.title);if(l){let d=`\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 c.debug(`[haimati_write] \u51FA\u53C2:
104
104
  ${d}`),d}let f="\u9519\u8BEF\uFF1A\u65E0\u6CD5\u5206\u914D\u5E8F\u53F7\uFF08\u9501\u7B49\u5F85\u8D85\u65F6\uFF09";return await c.debug(`[haimati_write] \u51FA\u53C2:
105
- ${f}`),f}catch(i){return await j(i,"haimati_write")}}}),haimati_search:w({description:'\u641C\u7D22\u8BB0\u5FC6\uFF08\u591A\u5173\u952E\u5B57\u7A7A\u683C\u5206\u9694\uFF09\u3002\u641C\u7D22\u8303\u56F4\uFF1A\u6807\u9898\uFF08\u6743\u91CD\u9AD8\uFF09\u3001\u5206\u7C7B\u3001\u5E8F\u53F7\u3001\u6B63\u6587\u3002match="and" \u9700\u5168\u90E8\u5339\u914D\uFF08\u7CBE\u786E\uFF09\uFF0Cmatch="or" \u4EFB\u610F\u5339\u914D\uFF08\u5E7F\u6CDB\uFF09\u3002\u6309\u5339\u914D\u5EA6\u6392\u5E8F\uFF0C\u7ED3\u679C\u542B\u6458\u8981\uFF0C\u652F\u6301 limit/offset \u5206\u9875\u3002',args:{keyword:w.schema.string().describe("\u641C\u7D22\u5173\u952E\u8BCD\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09"),match:w.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:w.schema.number().default(10).describe("\u8FD4\u56DE\u7ED3\u679C\u6570\u91CF\u9650\u5236"),offset:w.schema.number().default(0).describe("\u5206\u9875\u504F\u79FB\u91CF\uFF0C\u7528\u4E8E\u83B7\u53D6\u540E\u7EED\u9875\u9762")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e);if(await c.info(`[haimati_search] \u5F00\u59CB\u641C\u7D22 "${t.keyword}"`),await c.debug(`[haimati_search] \u5165\u53C2: keyword="${t.keyword}", match="${t.match}", limit=${t.limit??10}, offset=${t.offset??0}`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_search] \u51FA\u53C2:
105
+ ${f}`),f}catch(i){return await j(i,"haimati_write")}}}),haimati_search:w({description:'\u641C\u7D22\u8BB0\u5FC6\uFF08\u591A\u5173\u952E\u5B57\u7A7A\u683C\u5206\u9694\uFF09\u3002\u641C\u7D22\u8303\u56F4\uFF1A\u6807\u9898\uFF08\u6743\u91CD\u9AD8\uFF09\u3001\u5206\u7C7B\u3001\u5E8F\u53F7\u3001\u6B63\u6587\u3002match="and" \u9700\u5168\u90E8\u5339\u914D\uFF08\u7CBE\u786E\uFF09\uFF0Cmatch="or" \u4EFB\u610F\u5339\u914D\uFF08\u5E7F\u6CDB\uFF09\u3002\u6309\u5339\u914D\u5EA6\u6392\u5E8F\uFF0C\u7ED3\u679C\u542B\u6458\u8981\uFF0C\u652F\u6301 limit/offset \u5206\u9875\u3002',args:{keyword:w.schema.string().describe("\u641C\u7D22\u5173\u952E\u8BCD\uFF08\u652F\u6301\u591A\u5173\u952E\u5B57\uFF0C\u7528\u7A7A\u683C\u5206\u9694\uFF09"),match:w.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:w.schema.number().default(10).describe("\u8FD4\u56DE\u7ED3\u679C\u6570\u91CF\u9650\u5236"),offset:w.schema.number().default(0).describe("\u5206\u9875\u504F\u79FB\u91CF\uFF0C\u7528\u4E8E\u83B7\u53D6\u540E\u7EED\u9875\u9762")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e);if(await c.info(`[haimati_search] \u5F00\u59CB\u641C\u7D22 "${t.keyword}"`),await c.debug(`[haimati_search] \u5165\u53C2: keyword="${t.keyword}", match="${t.match}", limit=${t.limit??10}, offset=${t.offset??0}`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_search] \u51FA\u53C2:
106
106
  ${i}`),await c.info("[haimati_search] \u641C\u7D22\u5931\u8D25: \u7D22\u5F15\u4E0D\u5B58\u5728"),i}try{let i=await M(e),o=t.keyword.trim(),a=t.match,l=t.limit??10,f=t.offset??0,d=await Gt(i,o,a,e,!0),m=d.length,u=d.slice(f,f+l);if(u.length===0){let y=`\u672A\u627E\u5230\u5305\u542B '${o}' \u7684\u8BB0\u5FC6`;return await c.debug(`[haimati_search] \u51FA\u53C2:
107
107
  ${y}`),await c.info("[haimati_search] \u641C\u7D22\u5B8C\u6210: \u672A\u627E\u5230\u5339\u914D"),y}let s=[],g=f+u.length<m,h=`${f+1}-${f+u.length}/${m}`;s.push(`\u627E\u5230 ${h} \u6761\u5339\u914D\uFF1A
108
108
  `),g&&s.push(`\uFF08\u5982\u9700\u83B7\u53D6\u66F4\u591A\uFF0C\u8BF7\u4F7F\u7528 offset=${f+l} \u7EE7\u7EED\u7FFB\u9875\uFF09
109
- `);for(let y of u){let $=await P(e,y.id),E=`${y.category}/${y.title}`,k="";$&&(k=$.content.split(`
110
- `).filter(v=>v.trim()).slice(0,3).join(" | ").substring(0,150),k.length===150&&(k+="...")),s.push(`## ${E} [${y.id}]`),k&&s.push(`> ${k}`),s.push("")}let p=s.join(`
109
+ `);for(let y of u){let $=await P(e,y.id),D=`${y.category}/${y.title}`,k="";$&&(k=$.content.split(`
110
+ `).filter(v=>v.trim()).slice(0,3).join(" | ").substring(0,150),k.length===150&&(k+="...")),s.push(`## ${D} [${y.id}]`),k&&s.push(`> ${k}`),s.push("")}let p=s.join(`
111
111
  `);return await c.debug(`[haimati_search] \u51FA\u53C2:
112
- ${p}`),await c.info(`[haimati_search] \u641C\u7D22\u5B8C\u6210: \u627E\u5230 ${m} \u6761\u5339\u914D`),p}catch(i){return await j(i,"haimati_search")}}}),haimati_edit:w({description:"\u7F16\u8F91\u8BB0\u5FC6\u3002\u652F\u6301\u4E09\u79CD\u6A21\u5F0F\uFF1A1) \u5185\u5BB9\u66FF\u6362\uFF1AoldString\u2192newString\uFF08\u533A\u5206\u5927\u5C0F\u5199\uFF09\uFF0CreplaceAll \u53EF\u9009\u5168\u5C40\u66FF\u6362\uFF1B2) \u5173\u8054\u53D8\u66F4\uFF1AfilePath/removeFilePath \u6570\u7EC4\u589E\u51CF\u6587\u4EF6\u5173\u8054\uFF1B3) \u540C\u65F6\u6267\u884C\u4E24\u8005\u3002oldString \u548C newString \u5FC5\u987B\u540C\u65F6\u5B58\u5728\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362\u3002\u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u5185\u5BB9\u66FF\u6362\u6216\u5173\u8054\u53D8\u66F4\u4E4B\u4E00\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u66F4\u65B0\u7684\u8BB0\u5FC6"),oldString:w.schema.string().optional().describe("\u8981\u641C\u7D22\u7684\u65E7\u6587\u672C\uFF08\u533A\u5206\u5927\u5C0F\u5199\uFF09\uFF0C\u4E0E newString \u540C\u65F6\u5B58\u5728\u65F6\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362"),newString:w.schema.string().optional().describe("\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C\uFF0C\u4E0E oldString \u540C\u65F6\u5B58\u5728\u65F6\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362"),replaceAll:w.schema.boolean().optional().describe("\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF0C\u9ED8\u8BA4\u4E3A false\uFF08\u53EA\u66FF\u6362\u7B2C\u4E00\u4E2A\uFF09"),filePath:w.schema.array(w.schema.string()).optional().describe("\u5173\u8054\u7684\u9879\u76EE\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\u6570\u7EC4\uFF0C\u5982 ['src/index.ts', 'src/tools.ts']\u3002\u672B\u5C3E\u52A0 / \u8868\u793A\u76EE\u5F55\uFF0C\u5982 'src/' \u4F1A\u5339\u914D\u8BE5\u76EE\u5F55\u4E0B\u6240\u6709\u6587\u4EF6\uFF08\u542B\u5B50\u76EE\u5F55\uFF09\u3002\u4F20\u5165\u540E\u5728 .haimati/memo-map.yaml \u4E2D\u5EFA\u7ACB\u6587\u4EF6\u2192\u8BB0\u5FC6\u7684\u6620\u5C04\u5173\u7CFB\u3002\u6B64\u540E AI \u901A\u8FC7 read \u5DE5\u5177\u8BFB\u53D6\u8BE5\u6587\u4EF6\u6216\u76EE\u5F55\u4E0B\u7684\u6587\u4EF6\u65F6\uFF0C\u4F1A\u81EA\u52A8\u5728\u8F93\u51FA\u4E2D\u6CE8\u5165\u5173\u8054\u8BB0\u5FC6\u7684\u5B8C\u6574\u6B63\u6587"),removeFilePath:w.schema.array(w.schema.string()).optional().describe("\u8981\u79FB\u9664\u5173\u8054\u7684\u9879\u76EE\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\u6570\u7EC4\uFF0C\u5982 ['src/index.ts', 'src/tools.ts']\u3002\u4F20\u5165\u540E\u4F1A\u4ECE memo-map.yaml \u4E2D\u79FB\u9664\u8BE5\u6587\u4EF6\u4E0E\u6B64\u8BB0\u5FC6\u7684\u5173\u8054")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e),i=t.replaceAll===!0,o=t.filePath||null,a=t.removeFilePath||null,l=!!t.oldString&&!!t.newString,f=o&&o.length>0||a&&a.length>0;if(!l&&!f)return await c.debug("[haimati_edit] \u51FA\u53C2: \u672A\u63D0\u4F9B\u4EFB\u4F55\u7F16\u8F91\u64CD\u4F5C"),"\u9519\u8BEF\uFF1A\u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u5185\u5BB9\u66FF\u6362\uFF08oldString+newString\uFF09\u6216\u6587\u4EF6\u5173\u8054\u53D8\u66F4\uFF08filePath/removeFilePath\uFF09";if(o&&o.length>0){let d=await ie(e,o);if(d.length>0){let m=`\u9519\u8BEF\uFF1A\u4EE5\u4E0B\u6587\u4EF6/\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u786E\u8BA4\u8DEF\u5F84\u540E\u91CD\u8BD5
112
+ ${p}`),await c.info(`[haimati_search] \u641C\u7D22\u5B8C\u6210: \u627E\u5230 ${m} \u6761\u5339\u914D`),p}catch(i){return await j(i,"haimati_search")}}}),haimati_edit:w({description:"\u7F16\u8F91\u8BB0\u5FC6\u3002\u652F\u6301\u4E09\u79CD\u6A21\u5F0F\uFF1A1) \u5185\u5BB9\u66FF\u6362\uFF1AoldString\u2192newString\uFF08\u533A\u5206\u5927\u5C0F\u5199\uFF09\uFF0CreplaceAll \u53EF\u9009\u5168\u5C40\u66FF\u6362\uFF1B2) \u5173\u8054\u53D8\u66F4\uFF1AfilePath/removeFilePath \u6570\u7EC4\u589E\u51CF\u6587\u4EF6\u5173\u8054\uFF1B3) \u540C\u65F6\u6267\u884C\u4E24\u8005\u3002oldString \u548C newString \u5FC5\u987B\u540C\u65F6\u5B58\u5728\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362\u3002\u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u5185\u5BB9\u66FF\u6362\u6216\u5173\u8054\u53D8\u66F4\u4E4B\u4E00\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\uFF0C\u7528\u4E8E\u5B9A\u4F4D\u8981\u66F4\u65B0\u7684\u8BB0\u5FC6"),oldString:w.schema.string().optional().describe("\u8981\u641C\u7D22\u7684\u65E7\u6587\u672C\uFF08\u533A\u5206\u5927\u5C0F\u5199\uFF09\uFF0C\u4E0E newString \u540C\u65F6\u5B58\u5728\u65F6\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362"),newString:w.schema.string().optional().describe("\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C\uFF0C\u4E0E oldString \u540C\u65F6\u5B58\u5728\u65F6\u624D\u6267\u884C\u5185\u5BB9\u66FF\u6362"),replaceAll:w.schema.boolean().optional().describe("\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF0C\u9ED8\u8BA4\u4E3A false\uFF08\u53EA\u66FF\u6362\u7B2C\u4E00\u4E2A\uFF09"),filePath:w.schema.array(w.schema.string()).optional().describe("\u5173\u8054\u7684\u9879\u76EE\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\u6570\u7EC4\uFF0C\u5982 ['src/index.ts', 'src/tools.ts']\u3002\u672B\u5C3E\u52A0 / \u8868\u793A\u76EE\u5F55\uFF0C\u5982 'src/' \u4F1A\u5339\u914D\u8BE5\u76EE\u5F55\u4E0B\u6240\u6709\u6587\u4EF6\uFF08\u542B\u5B50\u76EE\u5F55\uFF09\u3002\u4F20\u5165\u540E\u5728 .haimati/memo-map.yaml \u4E2D\u5EFA\u7ACB\u6587\u4EF6\u2192\u8BB0\u5FC6\u7684\u6620\u5C04\u5173\u7CFB\u3002\u6B64\u540E AI \u901A\u8FC7 read \u5DE5\u5177\u8BFB\u53D6\u8BE5\u6587\u4EF6\u6216\u76EE\u5F55\u4E0B\u7684\u6587\u4EF6\u65F6\uFF0C\u4F1A\u81EA\u52A8\u5728\u8F93\u51FA\u4E2D\u6CE8\u5165\u5173\u8054\u8BB0\u5FC6\u7684\u5B8C\u6574\u6B63\u6587"),removeFilePath:w.schema.array(w.schema.string()).optional().describe("\u8981\u79FB\u9664\u5173\u8054\u7684\u9879\u76EE\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\u6570\u7EC4\uFF0C\u5982 ['src/index.ts', 'src/tools.ts']\u3002\u4F20\u5165\u540E\u4F1A\u4ECE memo-map.yaml \u4E2D\u79FB\u9664\u8BE5\u6587\u4EF6\u4E0E\u6B64\u8BB0\u5FC6\u7684\u5173\u8054")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e),i=t.replaceAll===!0,o=t.filePath||null,a=t.removeFilePath||null,l=!!t.oldString&&!!t.newString,f=o&&o.length>0||a&&a.length>0;if(!l&&!f)return await c.debug("[haimati_edit] \u51FA\u53C2: \u672A\u63D0\u4F9B\u4EFB\u4F55\u7F16\u8F91\u64CD\u4F5C"),"\u9519\u8BEF\uFF1A\u81F3\u5C11\u9700\u8981\u63D0\u4F9B\u5185\u5BB9\u66FF\u6362\uFF08oldString+newString\uFF09\u6216\u6587\u4EF6\u5173\u8054\u53D8\u66F4\uFF08filePath/removeFilePath\uFF09";if(o&&o.length>0){let d=await ie(e,o);if(d.length>0){let m=`\u9519\u8BEF\uFF1A\u4EE5\u4E0B\u6587\u4EF6/\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u786E\u8BA4\u8DEF\u5F84\u540E\u91CD\u8BD5
113
113
  ${d.join(`
114
114
  `)}`;return await c.debug(`[haimati_edit] \u51FA\u53C2: \u8DEF\u5F84\u4E0D\u5B58\u5728
115
115
  ${m}`),m}}if(await c.info(`[haimati_edit] \u5F00\u59CB\u7F16\u8F91 #${t.query}`),await c.debug(`[haimati_edit] \u5165\u53C2: query="${t.query}", replaceAll=${i}, filePath="${o?o.join(", "):"(\u65E0)"}", removeFilePath="${a?a.join(", "):"(\u65E0)"}", oldString="${t.oldString||"(\u65E0)"}", newString="${t.newString||"(\u65E0)"}"`),!await b(r))return await c.debug("[haimati_edit] \u51FA\u53C2: \u7D22\u5F15\u6587\u4EF6\u4E0D\u5B58\u5728"),"\u7D22\u5F15\u6587\u4EF6\u4E0D\u5B58\u5728";try{let d=await M(e),m=bt(t.query);if(!m)return"\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";let u=F(d,m);if(!u)return await c.info("[haimati_edit] \u7F16\u8F91\u5931\u8D25: \u672A\u627E\u5230\u8BB0\u5FC6"),`\u672A\u627E\u5230\u4E0E '${t.query}' \u76F8\u5173\u7684\u8BB0\u5FC6`;if(l){let h=await P(e,u.id);if(!h)return await c.debug("[haimati_edit] \u51FA\u53C2: \u4E66\u9875\u4E0D\u5B58\u5728"),`\u672A\u627E\u5230\u4E66\u9875: #${u.id.padStart(3,"0")}`;if(!h.content.includes(t.oldString))return await c.debug("[haimati_edit] \u51FA\u53C2: \u672A\u627E\u5230\u5339\u914D\u6587\u672C"),`\u9519\u8BEF\uFF1A\u5728\u8BB0\u5FC6 #${u.id.padStart(3,"0")} \u4E2D\u672A\u627E\u5230\u5339\u914D\u7684\u6587\u672C\uFF0C\u5185\u5BB9\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u4FEE\u6539\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u540E\u91CD\u8BD5`;let p=i?h.content.replaceAll(t.oldString,t.newString):h.content.replace(t.oldString,t.newString),y=new Date().toLocaleString("zh-CN",{hour12:!1});await H(e,u.id,u.title,h.createdAt,y,p)}if(f){let h=await C(e);if(o&&o.length>0)for(let p of o){let y=G(e,p);$t(h,y,u.id),await c.info(`[haimati_edit] \u5EFA\u7ACB\u6587\u4EF6\u5173\u8054: ${y} -> #${u.id}`)}if(a&&a.length>0)for(let p of a){let y=G(e,p);te(h,y,u.id),await c.info(`[haimati_edit] \u79FB\u9664\u6587\u4EF6\u5173\u8054: ${y} x #${u.id}`)}await B(e,h)}let s=`${u.category}/${u.title}`,g=`\u5DF2\u66F4\u65B0\u6D77\u9A6C\u4F53 #${u.id.padStart(3,"0")}
116
116
  \u8DEF\u5F84: ${s}`;return await c.debug(`[haimati_edit] \u51FA\u53C2:
117
- ${g}`),await c.info(`[haimati_edit] \u7F16\u8F91\u6210\u529F: #${u.id.padStart(3,"0")}`),g}catch(d){return await j(d,"haimati_edit")}}}),haimati_delete:w({description:"\u5220\u9664\u8BB0\u5FC6\uFF0C\u4E0D\u53EF\u9006\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0C\u81EA\u52A8\u8865\u5168\u3002\u5220\u9664\u540E\u5E8F\u53F7\u4E0D\u590D\u7528\uFF0C\u540C\u65F6\u6E05\u7406 memo-map \u4E2D\u7684\u6587\u4EF6\u5173\u8054\u3002\u5EFA\u8BAE\u5148 haimati_read \u786E\u8BA4\u5185\u5BB9\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e);if(await c.info(`[haimati_delete] \u5F00\u59CB\u5220\u9664 #${t.query}`),await c.debug(`[haimati_delete] \u5165\u53C2: query="${t.query}"`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_delete] \u51FA\u53C2:
117
+ ${g}`),await c.info(`[haimati_edit] \u7F16\u8F91\u6210\u529F: #${u.id.padStart(3,"0")}`),g}catch(d){return await j(d,"haimati_edit")}}}),haimati_delete:w({description:"\u5220\u9664\u8BB0\u5FC6\uFF0C\u4E0D\u53EF\u9006\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0C\u81EA\u52A8\u8865\u5168\u3002\u5220\u9664\u540E\u5E8F\u53F7\u4E0D\u590D\u7528\uFF0C\u540C\u65F6\u6E05\u7406 memo-map \u4E2D\u7684\u6587\u4EF6\u5173\u8054\u3002\u5EFA\u8BAE\u5148 haimati_read \u786E\u8BA4\u5185\u5BB9\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e);if(await c.info(`[haimati_delete] \u5F00\u59CB\u5220\u9664 #${t.query}`),await c.debug(`[haimati_delete] \u5165\u53C2: query="${t.query}"`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_delete] \u51FA\u53C2:
118
118
  ${i}`),i}try{let i=await M(e),o=bt(t.query);if(!o)return"\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";let a=F(i,o);if(!a)return await c.info(`[haimati_delete] \u5220\u9664\u5931\u8D25: \u672A\u627E\u5230\u8BB0\u5FC6 #${t.query}`),`\u672A\u627E\u5230\u8BB0\u5FC6: ${t.query}`;await Ht(e,a.id);let l=Ot(i,a.id);await K(e,l);let f=await C(e);Zt(f,a.id),await B(e,f),await c.info(`[haimati_delete] \u6E05\u7406\u6587\u4EF6\u5173\u8054: #${a.id}`);let d=`${a.category}/${a.title}`,m=`\u5DF2\u5220\u9664\u6D77\u9A6C\u4F53 #${a.id.padStart(3,"0")}
119
119
  \u8DEF\u5F84: ${d}`;return await c.debug(`[haimati_delete] \u51FA\u53C2:
120
- ${m}`),await c.info(`[haimati_delete] \u5220\u9664\u6210\u529F: #${a.id.padStart(3,"0")} (${d})`),m}catch(i){return await j(i,"haimati_delete")}}}),haimati_move:w({description:"\u4FEE\u6539\u8BB0\u5FC6\u7684\u5206\u7C7B\u548C/\u6216\u6807\u9898\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0CnewCategory/newTitle \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u3002\u5E8F\u53F7\u548C\u5185\u5BB9\u4E0D\u53D8\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'"),newCategory:w.schema.string().optional().describe("\u65B0\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u5BA2\u6237\u7AEF' \u6216 '\u901A\u7528'"),newTitle:w.schema.string().optional().describe("\u65B0\u7684\u6807\u9898\uFF0C\u5982 '\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236v2'")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e);if(await c.info(`[haimati_move] \u5F00\u59CB\u79FB\u52A8 ${t.query}`),await c.debug(`[haimati_move] \u5165\u53C2: query="${t.query}", newCategory="${t.newCategory}", newTitle="${t.newTitle}"`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_move] \u51FA\u53C2:
120
+ ${m}`),await c.info(`[haimati_delete] \u5220\u9664\u6210\u529F: #${a.id.padStart(3,"0")} (${d})`),m}catch(i){return await j(i,"haimati_delete")}}}),haimati_move:w({description:"\u4FEE\u6539\u8BB0\u5FC6\u7684\u5206\u7C7B\u548C/\u6216\u6807\u9898\u3002\u901A\u8FC7\u5E8F\u53F7\u5B9A\u4F4D\uFF0CnewCategory/newTitle \u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u3002\u5E8F\u53F7\u548C\u5185\u5BB9\u4E0D\u53D8\u3002",args:{query:w.schema.string().describe("\u5E8F\u53F7\u3002\u4F8B\u5982\uFF1A'086'"),newCategory:w.schema.string().optional().describe("\u65B0\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5982 'xxx\u9879\u76EE/\u5BA2\u6237\u7AEF' \u6216 '\u901A\u7528'"),newTitle:w.schema.string().optional().describe("\u65B0\u7684\u6807\u9898\uFF0C\u5982 '\u7B7E\u7AE0\u670D\u52A1WS\u901A\u4FE1\u673A\u5236v2'")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e);if(await c.info(`[haimati_move] \u5F00\u59CB\u79FB\u52A8 ${t.query}`),await c.debug(`[haimati_move] \u5165\u53C2: query="${t.query}", newCategory="${t.newCategory}", newTitle="${t.newTitle}"`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_move] \u51FA\u53C2:
121
121
  ${i}`),i}try{let i=await M(e),o=bt(t.query);if(!o)return"\u9519\u8BEF\uFF1Aquery \u5FC5\u987B\u662F\u5E8F\u53F7\uFF0C\u53EA\u652F\u6301\u5E8F\u53F7\u67E5\u8BE2";let a=F(i,o);if(!a)return await c.info(`[haimati_move] \u79FB\u52A8\u5931\u8D25: \u672A\u627E\u5230\u8BB0\u5FC6 #${t.query}`),`\u672A\u627E\u5230\u8BB0\u5FC6: ${t.query}`;let l=t.newCategory?.trim(),f=t.newTitle?.trim();if(f&&/ - \d{3}$/.test(f)){let $='\u9519\u8BEF\uFF1A\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';return await c.debug(`[haimati_move] \u51FA\u53C2:
122
122
  ${$}`),$}if(!l&&!f){let $="\u9519\u8BEF\uFF1A\u81F3\u5C11\u9700\u8981\u63D0\u4F9B newCategory \u6216 newTitle \u4E2D\u7684\u4E00\u4E2A";return await c.debug(`[haimati_move] \u51FA\u53C2:
123
- ${$}`),$}let d=a.category,m=a.title,u=l||d,s=f||m,g=`${d}/${m}`,h=`${u}/${s}`,p=i.map($=>$.id===a.id?{...$,category:u,title:s}:$);if(await K(e,p),f){let $=await P(e,a.id);if($){let E=new Date().toLocaleString("zh-CN",{hour12:!1});await H(e,a.id,s,$.createdAt,E,$.content)}}let y=`\u5DF2\u79FB\u52A8\u6D77\u9A6C\u4F53 #${a.id}
123
+ ${$}`),$}let d=a.category,m=a.title,u=l||d,s=f||m,g=`${d}/${m}`,h=`${u}/${s}`,p=i.map($=>$.id===a.id?{...$,category:u,title:s}:$);if(await K(e,p),f){let $=await P(e,a.id);if($){let D=new Date().toLocaleString("zh-CN",{hour12:!1});await H(e,a.id,s,$.createdAt,D,$.content)}}let y=`\u5DF2\u79FB\u52A8\u6D77\u9A6C\u4F53 #${a.id}
124
124
  \u65E7\u8DEF\u5F84: ${g}
125
125
  \u65B0\u8DEF\u5F84: ${h}`;return await c.debug(`[haimati_move] \u51FA\u53C2:
126
- ${y}`),await c.info(`[haimati_move] \u79FB\u52A8\u6210\u529F: #${a.id} ${g} -> ${h}`),y}catch(i){return await j(i,"haimati_move")}}}),haimati_list:w({description:"\u5217\u51FA\u6D77\u9A6C\u4F53\u7D22\u5F15\u3002\u65E0\u53C2\u6570\uFF1A\u5B8C\u6574\u6811\u5F62\u7ED3\u6784\uFF1Bcategory\uFF1A\u6307\u5B9A\u5206\u7C7B\uFF1Brecursive=true\uFF1A\u9012\u5F52\u5B50\u5206\u7C7B\uFF1Bdetail=true\uFF1A\u540C\u65F6\u663E\u793A\u6B63\u6587\u3002\u5EFA\u8BAE\u5DE5\u4F5C\u4E2D\u5148 list/search \u6D4F\u89C8\u5DF2\u6709\u8BB0\u5FC6\u3002",args:{category:w.schema.string().optional().describe("\u53EF\u9009\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5217\u51FA\u8BE5\u5206\u7C7B\u4E0B\u7684\u6761\u76EE"),recursive:w.schema.boolean().optional().default(!1).describe("\u662F\u5426\u9012\u5F52\u904D\u5386\u5B50\u5206\u7C7B\uFF0C\u9ED8\u8BA4false"),detail:w.schema.boolean().optional().default(!1).describe("\u662F\u5426\u663E\u793A\u8BB0\u5FC6\u7684\u8BE6\u7EC6\u5185\u5BB9\uFF0C\u9ED8\u8BA4false")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=D(e);if(await c.info(`[haimati_list] \u5F00\u59CB\u5217\u51FA${t.category?` ${t.category}`:" \u5168\u90E8"}${t.detail?" (\u8BE6\u7EC6\u6A21\u5F0F)":""}`),await c.debug(`[haimati_list] \u5165\u53C2: category="${t.category||"(\u65E0)"}, recursive=${t.recursive}, detail=${t.detail}`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_list] \u51FA\u53C2:
126
+ ${y}`),await c.info(`[haimati_move] \u79FB\u52A8\u6210\u529F: #${a.id} ${g} -> ${h}`),y}catch(i){return await j(i,"haimati_move")}}}),haimati_list:w({description:"\u5217\u51FA\u6D77\u9A6C\u4F53\u7D22\u5F15\u3002\u65E0\u53C2\u6570\uFF1A\u5B8C\u6574\u6811\u5F62\u7ED3\u6784\uFF1Bcategory\uFF1A\u6307\u5B9A\u5206\u7C7B\uFF1Brecursive=true\uFF1A\u9012\u5F52\u5B50\u5206\u7C7B\uFF1Bdetail=true\uFF1A\u540C\u65F6\u663E\u793A\u6B63\u6587\u3002\u5EFA\u8BAE\u5DE5\u4F5C\u4E2D\u5148 list/search \u6D4F\u89C8\u5DF2\u6709\u8BB0\u5FC6\u3002",args:{category:w.schema.string().optional().describe("\u53EF\u9009\u7684\u5206\u7C7B\u8DEF\u5F84\uFF0C\u5217\u51FA\u8BE5\u5206\u7C7B\u4E0B\u7684\u6761\u76EE"),recursive:w.schema.boolean().optional().default(!1).describe("\u662F\u5426\u9012\u5F52\u904D\u5386\u5B50\u5206\u7C7B\uFF0C\u9ED8\u8BA4false"),detail:w.schema.boolean().optional().default(!1).describe("\u662F\u5426\u663E\u793A\u8BB0\u5FC6\u7684\u8BE6\u7EC6\u5185\u5BB9\uFF0C\u9ED8\u8BA4false")},async execute(t,n){let e=T(n);if(!e)return"\u9519\u8BEF\uFF1A\u7F3A\u5C11 directory \u914D\u7F6E";let r=E(e);if(await c.info(`[haimati_list] \u5F00\u59CB\u5217\u51FA${t.category?` ${t.category}`:" \u5168\u90E8"}${t.detail?" (\u8BE6\u7EC6\u6A21\u5F0F)":""}`),await c.debug(`[haimati_list] \u5165\u53C2: category="${t.category||"(\u65E0)"}, recursive=${t.recursive}, detail=${t.detail}`),!await b(r)){let i="\u9519\u8BEF\uFF1A\u6D77\u9A6C\u4F53\u7D22\u5F15\u4E0D\u5B58\u5728";return await c.debug(`[haimati_list] \u51FA\u53C2:
127
127
  ${i}`),i}try{let i=await M(e);if(t.category){let l=await Be(e,i,t.category,t.recursive??!1,t.detail??!1);return await c.debug(`[haimati_list] \u51FA\u53C2:
128
128
  ${l}`),await c.info(`[haimati_list] \u5217\u51FA\u6210\u529F: ${t.category}${t.detail?" (\u8BE6\u7EC6\u6A21\u5F0F)":""}`),l}if(t.detail){let l=await Ke(e,i);return await c.debug(`[haimati_list] \u51FA\u53C2:
129
129
  ${l}`),await c.info("[haimati_list] \u5217\u51FA\u6210\u529F: \u5168\u90E8 (\u8BE6\u7EC6\u6A21\u5F0F)"),l}let a=`## \u6D77\u9A6C\u4F53\u7D22\u5F15
130
130
 
131
131
  ${wt(i)||"(\u7A7A)"}`;return await c.debug(`[haimati_list] \u51FA\u53C2:
132
- ${a}`),await c.info("[haimati_list] \u5217\u51FA\u6210\u529F: \u5168\u90E8"),a}catch(i){return await j(i,"haimati_list")}}})}}import{readFile as Qe,rm as Ve}from"node:fs/promises";import{basename as z,dirname as R,join as xt}from"node:path";import{fileURLToPath as Ye}from"node:url";var Xe="opencode-haimati";function se(t,n){if(!n)return;let e=new AbortController,r=setTimeout(()=>e.abort(),1e4);Ze(e.signal).then(i=>{i.updated&&(c.info(`[autoUpdate] \u53D1\u73B0\u65B0\u7248\u672C: ${i.current} \u2192 ${i.latest}`),setTimeout(()=>{t.client.tui.showToast({body:{title:"\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u63D2\u4EF6\u66F4\u65B0",message:`${i.name} \u5DF2\u4ECE ${i.current} \u66F4\u65B0\u5230 ${i.latest}\uFF0C\u91CD\u542F OpenCode \u5B8C\u6210\u66F4\u65B0`,variant:"info"}})},5e3))}).catch(()=>{}).finally(()=>clearTimeout(r))}async function Ze(t){let n=await tn(Xe);if(!n)return{updated:!1};let e=await _t(xt(n,"package.json"));if(!e?.name||!e.version)return{updated:!1};let r=await on(e.name,t);if(!r||!an(r,e.version))return{updated:!1};let i=await en(n,e.name);if(!i)return{updated:!1};try{await Ve(i,{recursive:!0,force:!0})}catch{return{updated:!1,error:"remove_failed",name:e.name,current:e.version,latest:r}}return{updated:!0,name:e.name,current:e.version,latest:r}}async function tn(t){let n=R(Ye(import.meta.url));for(;;){if((await _t(xt(n,"package.json")))?.name===t)return z(n)==="dist"?R(n):n;let r=R(n);if(r===n)return;n=r}}async function en(t,n){let e=R(t),r=z(e).startsWith("@")?R(e):e;if(z(r)!=="node_modules")return;let i=R(r),o=await _t(xt(i,"package.json")),a=nn(i,n)??o?.dependencies?.[n];if(!(!a||!rn(a)))return i}function nn(t,n){if(n.startsWith("@")){let[i,o]=n.split("/");if(!i||!o||z(R(t))!==i)return;let a=`${o}@`,l=z(t);return l.startsWith(a)?l.slice(a.length):void 0}let e=`${n}@`,r=z(t);return r.startsWith(e)?r.slice(e.length):void 0}function rn(t){let n=t.trim();return n?!!(n==="latest"||n==="*"||/^[~^]/.test(n)||/^(?:>=|>|<=|<)/.test(n)||/\s+(?:\|\||-|[<>=])\s+/.test(n)):!1}async function _t(t){try{let n=JSON.parse(await Qe(t,"utf-8"));return n&&typeof n=="object"?n:void 0}catch{return}}async function on(t,n){try{let e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{signal:n});if(!e.ok)return;let r=await e.json();if(!r||typeof r!="object")return;let i=r.version;return typeof i=="string"?i:void 0}catch{return}}function an(t,n){let e=ae(t),r=ae(n);if(!e||!r)return!1;for(let i=0;i<3;i++)if(e.parts[i]!==r.parts[i])return e.parts[i]>r.parts[i];if(!e.pre.length&&r.pre.length)return!0;if(e.pre.length&&!r.pre.length)return!1;for(let i=0;i<Math.max(e.pre.length,r.pre.length);i++){let o=e.pre[i],a=r.pre[i];if(o===void 0)return!1;if(a===void 0)return!0;if(o===a)continue;let l=/^\d+$/.test(o)?Number(o):void 0,f=/^\d+$/.test(a)?Number(a):void 0;return l!==void 0&&f!==void 0?l>f:l!==void 0?!1:f!==void 0?!0:o>a}return!1}function ae(t){let n=t.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.+)?$/);if(n)return{parts:[Number(n[1]),Number(n[2]),Number(n[3])],pre:n[4]?.split(".")??[]}}var sn="2026-06-03 15:29:12",ce=!1;function cn(t){return t.type==="text"&&t.ignored!==!0}var Si=async t=>{await jt(),ce||(ce=!0,await c.debug(`[HaimatiPlugin] \u4EE3\u7801\u6700\u540E\u4FEE\u6539\u65E5\u671F: ${sn}`));let n=Y(t.directory),e=oe(),r=new Set,i=new Set,o=new Set,a=new Map,l=1e4,f=new Set,d=new Map;function m(u){let s=d.get(u);return s||(s=new Map,d.set(u,s)),s}return se(t,n.autoUpdate!==!1),ne(t.directory).then(u=>{u>0&&c.info(`[HaimatiPlugin] \u542F\u52A8\u65F6\u6E05\u7406\u4E86 ${u} \u4E2A\u4E0D\u5B58\u5728\u7684\u6587\u4EF6\u5173\u8054`)}).catch(u=>{c.warn(`[HaimatiPlugin] \u6E05\u7406\u8FC7\u671F\u6587\u4EF6\u5173\u8054\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`)}),{tool:e,event:async({event:u})=>{if(u.type==="message.updated"&&u.properties.info.role==="assistant"){let s=u.properties.info;if(s.finish==="stop"&&!r.has(s.id)){if(r.add(s.id),o.has(s.id)){o.delete(s.id);return}if(i.has(s.sessionID))return;let g=a.get(s.sessionID);if(g&&Date.now()<g)return;n.autoWrite===!0&&(i.add(s.sessionID),c.info(`[autoWrite] \u5F00\u59CB\u5F02\u6B65\u8BB0\u5FC6\u5199\u5165 session=${s.sessionID}`),t.client.session.prompt({path:{id:s.sessionID},body:{parts:[{type:"text",text:`\u56DE\u987E\u5F53\u524D\u4F1A\u8BDD\uFF0C\u5BF9\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u8FDB\u884C\u7EF4\u62A4\u3002
132
+ ${a}`),await c.info("[haimati_list] \u5217\u51FA\u6210\u529F: \u5168\u90E8"),a}catch(i){return await j(i,"haimati_list")}}})}}import{readFile as Qe,rm as Ve}from"node:fs/promises";import{basename as z,dirname as R,join as xt}from"node:path";import{fileURLToPath as Ye}from"node:url";var Xe="opencode-haimati";function se(t,n){if(!n)return;let e=new AbortController,r=setTimeout(()=>e.abort(),1e4);Ze(e.signal).then(i=>{i.updated&&(c.info(`[autoUpdate] \u53D1\u73B0\u65B0\u7248\u672C: ${i.current} \u2192 ${i.latest}`),setTimeout(()=>{t.client.tui.showToast({body:{title:"\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u63D2\u4EF6\u66F4\u65B0",message:`${i.name} \u5DF2\u4ECE ${i.current} \u66F4\u65B0\u5230 ${i.latest}\uFF0C\u91CD\u542F OpenCode \u5B8C\u6210\u66F4\u65B0`,variant:"info"}})},5e3))}).catch(()=>{}).finally(()=>clearTimeout(r))}async function Ze(t){let n=await tn(Xe);if(!n)return{updated:!1};let e=await _t(xt(n,"package.json"));if(!e?.name||!e.version)return{updated:!1};let r=await on(e.name,t);if(!r||!an(r,e.version))return{updated:!1};let i=await en(n,e.name);if(!i)return{updated:!1};try{await Ve(i,{recursive:!0,force:!0})}catch{return{updated:!1,error:"remove_failed",name:e.name,current:e.version,latest:r}}return{updated:!0,name:e.name,current:e.version,latest:r}}async function tn(t){let n=R(Ye(import.meta.url));for(;;){if((await _t(xt(n,"package.json")))?.name===t)return z(n)==="dist"?R(n):n;let r=R(n);if(r===n)return;n=r}}async function en(t,n){let e=R(t),r=z(e).startsWith("@")?R(e):e;if(z(r)!=="node_modules")return;let i=R(r),o=await _t(xt(i,"package.json")),a=nn(i,n)??o?.dependencies?.[n];if(!(!a||!rn(a)))return i}function nn(t,n){if(n.startsWith("@")){let[i,o]=n.split("/");if(!i||!o||z(R(t))!==i)return;let a=`${o}@`,l=z(t);return l.startsWith(a)?l.slice(a.length):void 0}let e=`${n}@`,r=z(t);return r.startsWith(e)?r.slice(e.length):void 0}function rn(t){let n=t.trim();return n?!!(n==="latest"||n==="*"||/^[~^]/.test(n)||/^(?:>=|>|<=|<)/.test(n)||/\s+(?:\|\||-|[<>=])\s+/.test(n)):!1}async function _t(t){try{let n=JSON.parse(await Qe(t,"utf-8"));return n&&typeof n=="object"?n:void 0}catch{return}}async function on(t,n){try{let e=await fetch(`https://registry.npmjs.org/${encodeURIComponent(t)}/latest`,{signal:n});if(!e.ok)return;let r=await e.json();if(!r||typeof r!="object")return;let i=r.version;return typeof i=="string"?i:void 0}catch{return}}function an(t,n){let e=ae(t),r=ae(n);if(!e||!r)return!1;for(let i=0;i<3;i++)if(e.parts[i]!==r.parts[i])return e.parts[i]>r.parts[i];if(!e.pre.length&&r.pre.length)return!0;if(e.pre.length&&!r.pre.length)return!1;for(let i=0;i<Math.max(e.pre.length,r.pre.length);i++){let o=e.pre[i],a=r.pre[i];if(o===void 0)return!1;if(a===void 0)return!0;if(o===a)continue;let l=/^\d+$/.test(o)?Number(o):void 0,f=/^\d+$/.test(a)?Number(a):void 0;return l!==void 0&&f!==void 0?l>f:l!==void 0?!1:f!==void 0?!0:o>a}return!1}function ae(t){let n=t.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+.+)?$/);if(n)return{parts:[Number(n[1]),Number(n[2]),Number(n[3])],pre:n[4]?.split(".")??[]}}var sn="2026-06-04 18:32:17",ce=!1;function cn(t){return t.type==="text"&&t.ignored!==!0}var Si=async t=>{await jt(),ce||(ce=!0,await c.debug(`[HaimatiPlugin] \u4EE3\u7801\u6700\u540E\u4FEE\u6539\u65E5\u671F: ${sn}`));let n=Y(t.directory),e=oe(),r=new Set,i=new Set,o=new Set,a=new Map,l=1e4,f=new Set,d=new Map;function m(u){let s=d.get(u);return s||(s=new Map,d.set(u,s)),s}return se(t,n.autoUpdate!==!1),ne(t.directory).then(u=>{u>0&&c.info(`[HaimatiPlugin] \u542F\u52A8\u65F6\u6E05\u7406\u4E86 ${u} \u4E2A\u4E0D\u5B58\u5728\u7684\u6587\u4EF6\u5173\u8054`)}).catch(u=>{c.warn(`[HaimatiPlugin] \u6E05\u7406\u8FC7\u671F\u6587\u4EF6\u5173\u8054\u5931\u8D25: ${u instanceof Error?u.message:String(u)}`)}),{tool:e,event:async({event:u})=>{if(u.type==="message.updated"&&u.properties.info.role==="assistant"){let s=u.properties.info;if(s.finish==="stop"&&!r.has(s.id)){if(r.add(s.id),o.has(s.id)){o.delete(s.id);return}if(i.has(s.sessionID))return;let g=a.get(s.sessionID);if(g&&Date.now()<g)return;n.autoWrite===!0&&(i.add(s.sessionID),c.info(`[autoWrite] \u5F00\u59CB\u5F02\u6B65\u8BB0\u5FC6\u5199\u5165 session=${s.sessionID}`),t.client.session.prompt({path:{id:s.sessionID},body:{parts:[{type:"text",text:`\u56DE\u987E\u5F53\u524D\u4F1A\u8BDD\uFF0C\u5BF9\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u8FDB\u884C\u7EF4\u62A4\u3002
133
133
 
134
134
  \u4F60\u7684\u804C\u8D23\uFF1A
135
135
  1. \u5199\u5165\u65B0\u77E5\u8BC6 - \u67B6\u6784\u51B3\u7B56\u3001API\u7528\u6CD5\u3001Bug\u6839\u56E0\u4E0E\u4FEE\u590D\u3001\u914D\u7F6E\u65B9\u6CD5\u3001\u5F00\u53D1\u89C4\u8303\u7B49\u503C\u5F97\u957F\u671F\u8BB0\u5F55\u7684\u77E5\u8BC6
@@ -145,9 +145,7 @@ ${a}`),await c.info("[haimati_list] \u5217\u51FA\u6210\u529F: \u5168\u90E8"),a}c
145
145
  - \u9519\u8BEF\u6216\u8FC7\u671F\u7684\u4FE1\u606F\u76F4\u63A5\u5220\u9664\u6216\u4FEE\u6539
146
146
  - \u4E0D\u786E\u5B9A\u5206\u7C7B\u65F6\uFF0C\u5148\u7528 haimati_list \u67E5\u770B\u73B0\u6709\u7ED3\u6784
147
147
 
148
- \u5982\u679C\u6CA1\u4EC0\u4E48\u53EF\u505A\u7684\uFF0C\u56DE\u590D"\u65E0"`}]}}).then(h=>{let p=h?.data?.info?.id;p&&o.add(p),i.delete(s.sessionID),a.set(s.sessionID,Date.now()+l),c.info(`[autoWrite] AI\u8BB0\u5FC6\u5199\u5165\u5B8C\u6210 session=${s.sessionID}`)}).catch(h=>{i.delete(s.sessionID),a.set(s.sessionID,Date.now()+l);let p=h instanceof Error?h.message:String(h);c.error(`[autoWrite] \u5931\u8D25: ${p}`)})),await c.debug(`[message.updated] AI\u56DE\u590D\u7ED3\u675F messageID=${s.id}`)}}},"chat.message":async(u,s)=>{let g=s.parts.filter(cn);if(g.length!==0){if(f.has(s.message.sessionID)){s.parts.unshift({id:`prt_auto_reminder_${Date.now()}`,sessionID:g[0].sessionID??s.message.sessionID,messageID:g[0].messageID??s.message.id,type:"text",text:`<\u6D77\u9A6C\u4F53\u81EA\u52A8\u63D0\u793A>
149
- 1\u3001\u5DE5\u4F5C\u524D\u8BFB\u53D6\u6240\u6709\u76F8\u5173\u7684\u6D77\u9A6C\u4F53\u8BB0\u5FC6\uFF1B2\u3001\u5DE5\u4F5C\u540E\u603B\u7ED3\u8BB0\u5FC6
150
- </\u6D77\u9A6C\u4F53\u81EA\u52A8\u63D0\u793A>`,synthetic:!0}),await c.debug("[chat.message] \u6CE8\u5165\u7B80\u77ED\u786E\u8BA4\u63D0\u793A");return}f.add(s.message.sessionID),s.parts.unshift({id:`prt_auto_reminder_${Date.now()}`,sessionID:g[0].sessionID??s.message.sessionID,messageID:g[0].messageID??s.message.id,type:"text",text:`<system-reminder>
148
+ \u5982\u679C\u6CA1\u4EC0\u4E48\u53EF\u505A\u7684\uFF0C\u56DE\u590D"\u65E0"`}]}}).then(h=>{let p=h?.data?.info?.id;p&&o.add(p),i.delete(s.sessionID),a.set(s.sessionID,Date.now()+l),c.info(`[autoWrite] AI\u8BB0\u5FC6\u5199\u5165\u5B8C\u6210 session=${s.sessionID}`)}).catch(h=>{i.delete(s.sessionID),a.set(s.sessionID,Date.now()+l);let p=h instanceof Error?h.message:String(h);c.error(`[autoWrite] \u5931\u8D25: ${p}`)})),await c.debug(`[message.updated] AI\u56DE\u590D\u7ED3\u675F messageID=${s.id}`)}}},"chat.message":async(u,s)=>{let g=s.parts.filter(cn);g.length!==0&&(f.has(s.message.sessionID)||(f.add(s.message.sessionID),s.parts.unshift({id:`prt_auto_reminder_${Date.now()}`,sessionID:g[0].sessionID??s.message.sessionID,messageID:g[0].messageID??s.message.id,type:"text",text:`<system-reminder>
151
149
  \u4F60\u6709\u4E00\u5957\u6D77\u9A6C\u4F53\u8BB0\u5FC6\u63D2\u4EF6\u53EF\u7528
152
150
 
153
151
  1\u3001\u5DE5\u4F5C\u524D\u8BFB\u53D6\u6240\u6709\u76F8\u5173\u7684\u6D77\u9A6C\u4F53\u8BB0\u5FC6
@@ -161,7 +159,7 @@ ${a}`),await c.info("[haimati_list] \u5217\u51FA\u6210\u529F: \u5168\u90E8"),a}c
161
159
  - \u6574\u5408\u91CD\u590D\u7684\u8BB0\u5FC6
162
160
  - \u5982\u679C\u5B58\u5728\u5206\u7C7B\u4E0D\u5408\u7406\u7684\uFF0C\u5219\u8C03\u6574
163
161
  - \u5728\u8282\u7EA6TOKEN\u7684\u60C5\u51B5\u4E0B\uFF0C\u7CBE\u7B80\u6D77\u9A6C\u4F53\u8BB0\u5FC6
164
- </system-reminder>`,synthetic:!0}),await c.debug("[chat.message] \u6CE8\u5165\u5DE5\u4F5C\u89C4\u5219\u63D0\u793A")}},"tool.execute.after":async(u,s)=>{if(u.tool==="haimati_read"){try{let p=u.args?.query;if(typeof p!="string")return;let y=Mt(p);if(!y)return;let $=t.directory,E=u.sessionID;if(typeof E=="string"){let k=m(E);for(let W of y){let v=await P($,W);v&&k.set(W,v.updatedAt)}}await c.debug(`[tool.execute.after] \u8BB0\u5F55 haimati_read \u7248\u672C: ${y.join(",")}`)}catch(p){await c.error(`[tool.execute.after] haimati_read \u8BB0\u5F55\u7248\u672C\u5931\u8D25: ${p instanceof Error?p.message:String(p)}`)}return}if(u.tool!=="read")return;let g=u.args?.filePath;if(!g||typeof g!="string")return;let h=u.sessionID;if(typeof h=="string")try{let p=t.directory,y=G(p,g),$=await C(p);if(Object.keys($).length===0)return;let E=ee($,y,p);if(E.length===0)return;let k=await M(p),W=m(h),v=[],St=[];for(let O of E){let x=F(k,O);if(!x)continue;let q=await P(p,x.id);if(!q)continue;let It=Q($,x.id);if(It.length>0&&(q.systemMeta={...q.systemMeta,file_paths:It.join(", ")}),W.get(O)===q.updatedAt)continue;St.push(O);let le=N(x,q);v.push(`===== #${x.id.padStart(3,"0")} =====
162
+ </system-reminder>`,synthetic:!0}),await c.debug("[chat.message] \u6CE8\u5165\u5DE5\u4F5C\u89C4\u5219\u63D0\u793A")))},"tool.execute.after":async(u,s)=>{if(u.tool==="haimati_read"){try{let p=u.args?.query;if(typeof p!="string")return;let y=Mt(p);if(!y)return;let $=t.directory,D=u.sessionID;if(typeof D=="string"){let k=m(D);for(let W of y){let v=await P($,W);v&&k.set(W,v.updatedAt)}}await c.debug(`[tool.execute.after] \u8BB0\u5F55 haimati_read \u7248\u672C: ${y.join(",")}`)}catch(p){await c.error(`[tool.execute.after] haimati_read \u8BB0\u5F55\u7248\u672C\u5931\u8D25: ${p instanceof Error?p.message:String(p)}`)}return}if(u.tool!=="read")return;let g=u.args?.filePath;if(!g||typeof g!="string")return;let h=u.sessionID;if(typeof h=="string")try{let p=t.directory,y=G(p,g),$=await C(p);if(Object.keys($).length===0)return;let D=ee($,y,p);if(D.length===0)return;let k=await M(p),W=m(h),v=[],St=[];for(let O of D){let x=F(k,O);if(!x)continue;let q=await P(p,x.id);if(!q)continue;let It=Q($,x.id);if(It.length>0&&(q.systemMeta={...q.systemMeta,file_paths:It.join(", ")}),W.get(O)===q.updatedAt)continue;St.push(O);let le=N(x,q);v.push(`===== #${x.id.padStart(3,"0")} =====
165
163
  ${le}`),W.set(O,q.updatedAt)}if(v.length>0){s.output+=`
166
164
 
167
165
  <system-reminder>
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-haimati",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
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
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -14,7 +14,9 @@
14
14
  "typecheck": "tsc --noEmit",
15
15
  "prepublishOnly": "npm run build",
16
16
  "publish": "node scripts/publish-npmjs.js",
17
- "debug-build-copy": "node scripts/debug-build-copy.js"
17
+ "debug-build-copy": "node scripts/debug-build-copy.js",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest"
18
20
  },
19
21
  "peerDependencies": {
20
22
  "@opencode-ai/plugin": ">=0.15.0",
@@ -24,6 +26,7 @@
24
26
  "@opencode-ai/plugin": "^0.15.0",
25
27
  "@types/bun": "^1.3.1",
26
28
  "esbuild": "^0.28.0",
27
- "typescript": "^5.9.3"
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.1.8"
28
31
  }
29
32
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-haimati",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
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
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -14,7 +14,9 @@
14
14
  "typecheck": "tsc --noEmit",
15
15
  "prepublishOnly": "npm run build",
16
16
  "publish": "node scripts/publish-npmjs.js",
17
- "debug-build-copy": "node scripts/debug-build-copy.js"
17
+ "debug-build-copy": "node scripts/debug-build-copy.js",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest"
18
20
  },
19
21
  "peerDependencies": {
20
22
  "@opencode-ai/plugin": ">=0.15.0",
@@ -24,6 +26,7 @@
24
26
  "@opencode-ai/plugin": "^0.15.0",
25
27
  "@types/bun": "^1.3.1",
26
28
  "esbuild": "^0.28.0",
27
- "typescript": "^5.9.3"
29
+ "typescript": "^5.9.3",
30
+ "vitest": "^4.1.8"
28
31
  }
29
32
  }