exomind 0.3.0 → 0.3.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
@@ -42,35 +42,36 @@ exomind feedback "entities/Redis.md" positive
42
42
 
43
43
  加 `--json` 获取机器可读输出(脚本/管道):`exomind --json stats | jq .total_nodes`。
44
44
 
45
- ## 接入 Claude Code
45
+ ## 接入 Claude Code(一条命令,默认全装)
46
46
 
47
47
  ```bash
48
- exomind install --with-hook
48
+ exomind install # 装 skill + hook + MCP,全部自动(幂等+备份)
49
+ # 不想要某项: exomind install --no-hook 或 --no-mcp
49
50
  ```
50
51
 
51
- 一行完成:① 装 Claude Code skill(教 Agent 何时用 CLI);② 写入 `UserPromptSubmit` hook 指向 `exomind hook`(幂等,自动备份,不影响其它工具)。重启 Claude Code 后:
52
+ 一行完成三层,免手改任何 JSON:
53
+ - **① MCP 工具**(能力):写 `~/.claude.json` 的 `mcpServers.exomind` → Agent 拿到 `mcp__exomind__*` 确定性工具。
54
+ - **② skill**(指导):拷到 `~/.claude/skills/exomind/`。
55
+ - **③ hook**(闸门):写 `settings.json` 的 `UserPromptSubmit → exomind hook`。
52
56
 
53
- - **`存档`** / **`jdit`** → 自动回顾会话、运行 `exomind ingest`。
57
+ 重启 Claude Code 后:
58
+ - 说 **`存档`** / **`jdit`** → 自动回顾会话、摄入。
54
59
  - 提问涉及知识库已有实体 → 自动注入 `[ExoMind 知识库上下文]`。
55
- - 产出经验/踩坑/架构决策/性能数据/最佳实践自动提示摄入(飞轮)。
60
+ - Agent 需查询/摄入时 直接调 `mcp__exomind__*`(确定),或按 skill 跑 `exomind` CLI
56
61
 
57
- 即便不装 hook,skill 也会让 Agent 主动遵循飞轮规则。完整接入步骤见服务端仓库 `myExoMindManager/docs/new-machine-setup.md`。
62
+ 完整接入步骤见服务端仓库 `myExoMindManager/docs/new-machine-setup.md`。
58
63
 
59
- ## 作为 MCP 工具接入(可选,更确定 + 跨宿主)
64
+ **升级**:`npm i -g exomind@latest && exomind install`(幂等,刷新 skill/hook/mcp;`~/.exomind/` 的 config 与 manifest 保留)。注意:`npm i -g` 只换二进制(CLI+MCP 自动用新),**skill 是拷贝的,需 `exomind install` 才刷新**。
60
65
 
61
- `exomind mcp` 启动一个**本地 stdio MCP server**,把 ingest/query/search/entity/relations/stats 暴露为**typed tool**。Agent 直接调 tool(确定参数/返回),不必"读 skill bash"。复用同一份凭证(`~/.exomind/config.json`),本地 stdio 所以三平台都能跑。
66
+ ## 关于 MCP 工具层(Claude Code + OpenCode 都已默认装)
62
67
 
63
- **Claude Code**(`~/.claude.json` 或项目 `.mcp.json`):
64
- ```json
65
- { "mcpServers": { "exomind": { "command": "exomind", "args": ["mcp"] } } }
66
- ```
68
+ `exomind install` 一次写**两个宿主**的 MCP 配置(都幂等+备份,互不干扰,各读各的):
69
+ - **Claude Code**:`~/.claude.json` → `mcpServers.exomind`
70
+ - **OpenCode**:`~/.config/opencode/opencode.json` `mcp.exomind`
67
71
 
68
- **OpenCode**(`opencode.json`):
69
- ```json
70
- { "mcp": { "exomind": { "type": "local", "command": ["exomind", "mcp"] } } }
71
- ```
72
+ 只关 MCP:`exomind install --no-mcp`(两个宿主都不写)。手写/其它宿主(如 Cursor)参考 [docs/mcp.md](./docs/mcp.md)
72
73
 
73
- > skill+hook 并存,不冲突:MCP 提供"确定的工具调用",skill 提供"何时用的指导",hook 提供"每 prompt 的强制注入"。详见 [三层模式说明](./docs/mcp.md)。
74
+ `exomind mcp` 是本地 stdio MCP server,把 ingest/query/search/entity/relations/stats 暴露为 typed tool;复用同一份凭证,三平台都能跑(本地 stdio,不涉及远程 SSE 的 Windows 坑)。
74
75
 
75
76
  ## 命令一览
76
77
 
package/dist/cli.js CHANGED
@@ -3119,7 +3119,7 @@ var {
3119
3119
  // package.json
3120
3120
  var package_default = {
3121
3121
  name: "exomind",
3122
- version: "0.3.0",
3122
+ version: "0.3.2",
3123
3123
  description: "ExoMind \u8DE8\u5E73\u53F0\u547D\u4EE4\u884C\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4E0E ExoMind \u77E5\u8BC6\u5E93\u4EA4\u4E92(ingest/query/search/review),\u66FF\u4EE3 Windows \u4E0D\u53EF\u7528\u7684 MCP \u5BA2\u6237\u7AEF\u3002",
3124
3124
  bin: {
3125
3125
  exomind: "dist/cli.js"
@@ -4294,7 +4294,23 @@ function backup(file) {
4294
4294
  const bak = `${file}.bak-${Date.now()}`;
4295
4295
  try {
4296
4296
  fs6.copyFileSync(file, bak);
4297
- console.log(dim(` (\u5DF2\u5907\u4EFD\u539F\u914D\u7F6E \u2192 ${path6.basename(bak)})`));
4297
+ console.log(dim(` (\u5DF2\u5907\u4EFD \u2192 ${path6.basename(bak)})`));
4298
+ } catch {
4299
+ return;
4300
+ }
4301
+ pruneBackups(file, 3);
4302
+ }
4303
+ function pruneBackups(file, keep) {
4304
+ try {
4305
+ const dir = path6.dirname(file);
4306
+ const prefix = path6.basename(file) + ".bak-";
4307
+ const olds = fs6.readdirSync(dir).filter((f) => f.startsWith(prefix)).map((f) => ({ f, mt: fs6.statSync(path6.join(dir, f)).mtimeMs })).sort((a, b) => b.mt - a.mt);
4308
+ for (const o of olds.slice(keep)) {
4309
+ try {
4310
+ fs6.unlinkSync(path6.join(dir, o.f));
4311
+ } catch {
4312
+ }
4313
+ }
4298
4314
  } catch {
4299
4315
  }
4300
4316
  }
@@ -4308,7 +4324,7 @@ async function install(_client, opts) {
4308
4324
  fs6.copyFileSync(SKILL_SRC, path6.join(skillDestDir, "SKILL.md"));
4309
4325
  console.log(ok("\u5DF2\u5B89\u88C5 Claude Code skill"));
4310
4326
  console.log(dim(` \u2192 ${skillDestDir}/SKILL.md`));
4311
- if (opts.withHook) {
4327
+ if (opts.hook !== false) {
4312
4328
  const settingsFile = path6.join(claudeDir, "settings.json");
4313
4329
  fs6.mkdirSync(claudeDir, { recursive: true });
4314
4330
  backup(settingsFile);
@@ -4327,9 +4343,30 @@ async function install(_client, opts) {
4327
4343
  console.log(ok("\u5DF2\u914D\u7F6E UserPromptSubmit hook \u2192 exomind hook"));
4328
4344
  console.log(dim(" \u91CD\u542F Claude Code \u751F\u6548\u3002hook \u51FA\u9519\u4E0D\u4F1A\u963B\u585E\u4F60\u7684\u8F93\u5165(\u9519\u8BEF\u53EA\u8FDB stderr)\u3002"));
4329
4345
  }
4346
+ if (opts.mcp !== false) {
4347
+ const ccJson = path6.join(os2.homedir(), ".claude.json");
4348
+ backup(ccJson);
4349
+ const cc = readJson2(ccJson) ?? {};
4350
+ const ccMcp = cc.mcpServers ?? {};
4351
+ ccMcp.exomind = { command: "exomind", args: ["mcp"] };
4352
+ cc.mcpServers = ccMcp;
4353
+ fs6.writeFileSync(ccJson, JSON.stringify(cc, null, 2) + "\n");
4354
+ const ocJson = path6.join(os2.homedir(), ".config", "opencode", "opencode.json");
4355
+ fs6.mkdirSync(path6.dirname(ocJson), { recursive: true });
4356
+ backup(ocJson);
4357
+ const oc = readJson2(ocJson) ?? {};
4358
+ const ocMcp = oc.mcp ?? {};
4359
+ ocMcp.exomind = { type: "local", command: ["exomind", "mcp"] };
4360
+ oc.mcp = ocMcp;
4361
+ fs6.writeFileSync(ocJson, JSON.stringify(oc, null, 2) + "\n");
4362
+ console.log(ok("\u5DF2\u914D\u7F6E MCP server \u2192 exomind mcp"));
4363
+ console.log(dim(" \u2192 Claude Code: ~/.claude.json (mcpServers.exomind)"));
4364
+ console.log(dim(" \u2192 OpenCode: ~/.config/opencode/opencode.json (mcp.exomind)"));
4365
+ console.log(dim(" \u91CD\u542F\u5BF9\u5E94 Agent \u2192 \u62FF\u5230 mcp__exomind__* \u5DE5\u5177"));
4366
+ }
4330
4367
  console.log(yellow("\n\u4E0B\u4E00\u6B65:"));
4331
4368
  console.log(dim(" 1. \u82E5\u672A\u914D\u7F6E\u51ED\u8BC1: exomind login"));
4332
- console.log(dim(" 2. \u91CD\u542F Claude Code(\u82E5\u88C5\u4E86 hook)"));
4369
+ console.log(dim(" 2. \u91CD\u542F Claude Code \u2192 skill + hook + mcp__exomind__* \u5168\u90E8\u751F\u6548"));
4333
4370
  }
4334
4371
 
4335
4372
  // src/cli.ts
@@ -4413,7 +4450,7 @@ program2.command("mcp").description("\u542F\u52A8 stdio MCP server(\u4F9B Claude
4413
4450
  const client = new ApiClient(cfg);
4414
4451
  await runMcpServer(client);
4415
4452
  });
4416
- program2.command("install").description("\u5B89\u88C5 Claude Code skill(\u53EF\u9009 --with-hook \u5199\u5165 UserPromptSubmit)").option("--with-hook", "\u540C\u65F6\u5199\u5165 ~/.claude/settings.json \u7684 hook").action(run(install));
4453
+ program2.command("install").description("\u5B89\u88C5 skill + hook + MCP(\u9ED8\u8BA4\u5168\u88C5;--no-hook / --no-mcp \u5173\u95ED\u67D0\u9879)").option("--no-hook", "\u4E0D\u5199 UserPromptSubmit hook").option("--no-mcp", "\u4E0D\u5199 MCP server \u914D\u7F6E(Claude Code + OpenCode \u90FD\u4E0D\u5199)").action(run(install));
4417
4454
  async function main() {
4418
4455
  const first = process.argv[2];
4419
4456
  if (first && /^(-v|--version)$/.test(first)) {