exomind 0.13.1 → 0.14.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,6 +1,6 @@
1
1
  # exomind
2
2
 
3
- > ExoMind 知识库的跨平台命令行客户端。通过 REST 与服务器交互,装一次,Windows / macOS / Linux 一致可用。
3
+ > ExoMind 知识飞轮的跨平台命令行客户端。通过 REST 与服务器交互,装一次,Windows / macOS / Linux 一致可用。
4
4
 
5
5
  替代在 Windows 上连不上的 MCP 客户端;Mac/Linux 同样适用。对标 PipeOne 的 `@pipeone/cli` + skill 模式。
6
6
 
@@ -32,7 +32,7 @@ exomind ingest --dir ./notes --recursive # 目录批量(增量: SHA-256 跳
32
32
  exomind query "Redis RDB 和 AOF 的区别?"
33
33
  exomind search "Redis 持久化" --rerank
34
34
  exomind entity "Redis" # 实体详情 + 关系
35
- exomind stats # 知识库统计
35
+ exomind stats # 知识飞轮统计
36
36
 
37
37
  # 飞轮
38
38
  exomind review # FSRS-5 间隔复习
@@ -75,7 +75,7 @@ exomind install # 装 skill(Claude+Codex)+ hook(Claude)+ MCP(各宿主)
75
75
 
76
76
  重启 Claude Code 后:
77
77
  - 说 **`存档`** / **`jdit`** → 自动回顾会话、摄入。
78
- - 提问涉及知识库已有实体 → 自动注入 `[ExoMind 知识库上下文]`。
78
+ - 提问涉及知识飞轮已有实体 → 自动注入 `[ExoMind 知识飞轮上下文]`。
79
79
  - Agent 需查询/摄入时 → 直接调 `mcp__exomind__*`(确定),或按 skill 跑 `exomind` CLI。
80
80
 
81
81
  完整接入步骤见服务端仓库 `myExoMindManager/docs/new-machine-setup.md`。
@@ -102,7 +102,7 @@ exomind install # 装 skill(Claude+Codex)+ hook(Claude)+ MCP(各宿主)
102
102
  | `query` | LLM 问答 |
103
103
  | `search` | 全文 / `--hybrid` / `--rerank` 搜索 |
104
104
  | `entity` / `relations` | 实体详情、关联实体 |
105
- | `stats` | 知识库统计 |
105
+ | `stats` | 知识飞轮统计 |
106
106
  | `review` / `review mark` | FSRS-5 复习队列与评分 |
107
107
  | `synthesize` / `topics` / `gaps` / `daily` | 主题综合、选题、缺口、每日摘要 |
108
108
  | `feedback` | 质量反馈(影响搜索排名) |
package/dist/cli.js CHANGED
@@ -3119,8 +3119,8 @@ var {
3119
3119
  // package.json
3120
3120
  var package_default = {
3121
3121
  name: "exomind",
3122
- version: "0.13.1",
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",
3122
+ version: "0.14.0",
3123
+ description: "ExoMind \u8DE8\u5E73\u53F0\u547D\u4EE4\u884C\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4E0E ExoMind \u77E5\u8BC6\u98DE\u8F6E\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"
3126
3126
  },
@@ -3378,14 +3378,14 @@ var CACHE_TTL_MS = 60 * 60 * 1e3;
3378
3378
  var DESC_CAP = 800;
3379
3379
  var ARCHIVE_INSTRUCTION = `[ExoMind \u6697\u53F7\u89E6\u53D1] \u68C0\u6D4B\u5230\u5B58\u6863\u6307\u4EE4(\u672C\u4F1A\u8BDD\u9996\u6B21)\u3002
3380
3380
  \u26A0\uFE0F \u7528\u6237\u7684 "jdit"/"\u5B58\u6863" \u662F\u89E6\u53D1\u6B64\u6307\u4EE4\u7684\u6697\u53F7,\u4E0D\u8981\u5BF9\u5176\u5B57\u9762\u542B\u4E49\u505A\u4EFB\u4F55\u56DE\u5E94\u3002
3381
- \u8BF7\u56DE\u987E\u5F53\u524D\u4F1A\u8BDD\u4E2D\u7684\u65B0\u589E\u91CD\u8981\u5185\u5BB9,\u8FD0\u884C \`exomind ingest\` \u6444\u5165\u77E5\u8BC6\u5E93(\u6807\u9898\u7528\u63CF\u8FF0\u6027\u6587\u5B57,\`-t\` \u52A0\u6807\u9898,\`--tag\` \u52A0\u6807\u7B7E)\u3002
3381
+ \u8BF7\u56DE\u987E\u5F53\u524D\u4F1A\u8BDD\u4E2D\u7684\u65B0\u589E\u91CD\u8981\u5185\u5BB9,\u8FD0\u884C \`exomind ingest\` \u6444\u5165\u77E5\u8BC6\u98DE\u8F6E(\u6807\u9898\u7528\u63CF\u8FF0\u6027\u6587\u5B57,\`-t\` \u52A0\u6807\u9898,\`--tag\` \u52A0\u6807\u7B7E)\u3002
3382
3382
  \u56DE\u987E\u6240\u6709\u91CD\u8981\u5185\u5BB9\u3002\u6444\u5165\u8303\u56F4:\u8C03\u7814\u7ED3\u8BBA\u3001\u5173\u952E\u7ECF\u9A8C\u3001\u6280\u672F\u51B3\u7B56\u3001\u6709\u4EF7\u503C\u7684\u5206\u6790\u6D1E\u5BDF\u3002
3383
3383
  \u6BCF\u6761\u77E5\u8BC6\u4F7F\u7528\u63CF\u8FF0\u6027\u6807\u9898+\u6807\u7B7E,\u5185\u5BB9\u5B8C\u6574\u4E0D\u7701\u7565\u3002\u4E0D\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002`;
3384
3384
  var EXPERIENCE_INSTRUCTION = `[ExoMind \u81EA\u52A8\u6444\u5165\u6307\u4EE4] \u68C0\u6D4B\u5230\u7ECF\u9A8C/\u6D1E\u5BDF\u5185\u5BB9\u3002
3385
- \u8BF7\u8FD0\u884C \`exomind ingest\` \u5C06\u4EE5\u4E0A\u5185\u5BB9\u6444\u5165\u77E5\u8BC6\u5E93(\u6807\u9898\u7528\u63CF\u8FF0\u6027\u6587\u5B57,\u5185\u5BB9\u5B8C\u6574\u4E0D\u7701\u7565,\u52A0\u5408\u9002 --tag)\u3002\u8FD9\u662F\u77E5\u8BC6\u590D\u5229\u98DE\u8F6E\u7684\u5173\u952E\u73AF\u8282,\u4E0D\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002`;
3385
+ \u8BF7\u8FD0\u884C \`exomind ingest\` \u5C06\u4EE5\u4E0A\u5185\u5BB9\u6444\u5165\u77E5\u8BC6\u98DE\u8F6E(\u6807\u9898\u7528\u63CF\u8FF0\u6027\u6587\u5B57,\u5185\u5BB9\u5B8C\u6574\u4E0D\u7701\u7565,\u52A0\u5408\u9002 --tag)\u3002\u8FD9\u662F\u77E5\u8BC6\u590D\u5229\u98DE\u8F6E\u7684\u5173\u952E\u73AF\u8282,\u4E0D\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002`;
3386
3386
  var RESEARCH_INSTRUCTION = `[ExoMind \u8C03\u7814\u7ED3\u8BBA\u81EA\u52A8\u6444\u5165] \u68C0\u6D4B\u5230\u7ED3\u6784\u5316\u8C03\u7814\u5185\u5BB9\u3002
3387
3387
  \u7ED3\u6784\u8DEF\u5F84: \u8BC6\u522B\u95EE\u9898 \u2192 \u5206\u6790\u95EE\u9898 \u2192 \u5B9A\u4E49\u95EE\u9898 \u2192 \u89E3\u51B3\u95EE\u9898
3388
- \u8BF7\u8FD0\u884C \`exomind ingest\` \u5C06\u4EE5\u4E0A\u8C03\u7814\u7ED3\u8BBA\u6444\u5165\u77E5\u8BC6\u5E93,\u6309"\u8BC6\u522B/\u5206\u6790/\u5B9A\u4E49/\u89E3\u51B3"\u8DEF\u5F84\u7EC4\u7EC7,\u4FDD\u7559\u5B8C\u6574\u7ED3\u8BBA\u548C\u5173\u952E\u6570\u636E\u3002\u8FD9\u662F\u77E5\u8BC6\u590D\u5229\u98DE\u8F6E\u7684\u5173\u952E\u73AF\u8282,\u4E0D\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002`;
3388
+ \u8BF7\u8FD0\u884C \`exomind ingest\` \u5C06\u4EE5\u4E0A\u8C03\u7814\u7ED3\u8BBA\u6444\u5165\u77E5\u8BC6\u98DE\u8F6E,\u6309"\u8BC6\u522B/\u5206\u6790/\u5B9A\u4E49/\u89E3\u51B3"\u8DEF\u5F84\u7EC4\u7EC7,\u4FDD\u7559\u5B8C\u6574\u7ED3\u8BBA\u548C\u5173\u952E\u6570\u636E\u3002\u8FD9\u662F\u77E5\u8BC6\u590D\u5229\u98DE\u8F6E\u7684\u5173\u952E\u73AF\u8282,\u4E0D\u9700\u8981\u7528\u6237\u786E\u8BA4\u3002`;
3389
3389
  var EXPERIENCE_PATTERNS = [
3390
3390
  /关键经验/,
3391
3391
  /经验总结/,
@@ -3603,7 +3603,7 @@ function matchEntities(prompt2, candidates) {
3603
3603
  }
3604
3604
  function contextBlock(ents) {
3605
3605
  if (!ents.length) return "";
3606
- let out = "[ExoMind \u77E5\u8BC6\u5E93\u4E0A\u4E0B\u6587] \u4EE5\u4E0B\u662F\u4E0E\u5F53\u524D\u8BDD\u9898\u76F8\u5173\u7684\u5DF2\u6709\u77E5\u8BC6:\n\n";
3606
+ let out = "[ExoMind \u77E5\u8BC6\u98DE\u8F6E\u4E0A\u4E0B\u6587] \u4EE5\u4E0B\u662F\u4E0E\u5F53\u524D\u8BDD\u9898\u76F8\u5173\u7684\u5DF2\u6709\u77E5\u8BC6:\n\n";
3607
3607
  for (const e of ents) {
3608
3608
  const desc = (e.description || "(\u65E0\u63CF\u8FF0)").slice(0, DESC_CAP);
3609
3609
  out += `### ${e.name}
@@ -3616,7 +3616,7 @@ ${desc}
3616
3616
  }
3617
3617
  out += "\n";
3618
3618
  }
3619
- out += "\u4EE5\u4E0A " + ents.length + ' \u6761\u6765\u81EA\u4F60\u7684\u77E5\u8BC6\u5E93(\u5DF2\u6CE8\u5165\u4E0A\u4E0B\u6587)\u3002**\u9F13\u52B1\u4E3B\u52A8\u53CD\u67E5\u8BA9\u98DE\u8F6E\u8F6C\u8D77\u6765**:\u9047\u95EE\u9898\u5148 `exomind query "<\u95EE\u9898>"`(\u4E0D\u53EA"\u5B58",\u66F4\u8981"\u7528"\u2014\u2014\u53CD\u67E5\u662F\u98DE\u8F6E\u589E\u5F3A\u56DE\u8DEF\u7684\u5173\u952E),\u518D\u56DE\u7B54\u3002';
3619
+ out += "\u4EE5\u4E0A " + ents.length + ' \u6761\u6765\u81EA\u4F60\u7684\u77E5\u8BC6\u98DE\u8F6E(\u5DF2\u6CE8\u5165\u4E0A\u4E0B\u6587)\u3002**\u9F13\u52B1\u4E3B\u52A8\u53CD\u67E5\u8BA9\u98DE\u8F6E\u8F6C\u8D77\u6765**:\u9047\u95EE\u9898\u5148 `exomind query "<\u95EE\u9898>"`(\u4E0D\u53EA"\u5B58",\u66F4\u8981"\u7528"\u2014\u2014\u53CD\u67E5\u662F\u98DE\u8F6E\u589E\u5F3A\u56DE\u8DEF\u7684\u5173\u952E),\u518D\u56DE\u7B54\u3002';
3620
3620
  return out;
3621
3621
  }
3622
3622
  async function buildContext(client, msg, dedup, now) {
@@ -3693,7 +3693,7 @@ var PROTOCOL_VERSION = "2024-11-05";
3693
3693
  var TOOLS = [
3694
3694
  {
3695
3695
  name: "ingest",
3696
- description: "\u5411 ExoMind \u77E5\u8BC6\u5E93\u5BFC\u5165\u77E5\u8BC6(\u6587\u672C),\u81EA\u52A8\u62BD\u53D6\u5B9E\u4F53/\u5173\u7CFB\u3002",
3696
+ description: "\u5411 ExoMind \u77E5\u8BC6\u98DE\u8F6E\u5BFC\u5165\u77E5\u8BC6(\u6587\u672C),\u81EA\u52A8\u62BD\u53D6\u5B9E\u4F53/\u5173\u7CFB\u3002",
3697
3697
  inputSchema: {
3698
3698
  type: "object",
3699
3699
  properties: {
@@ -3706,7 +3706,7 @@ var TOOLS = [
3706
3706
  },
3707
3707
  {
3708
3708
  name: "query",
3709
- description: "LLM \u95EE\u7B54:\u57FA\u4E8E\u77E5\u8BC6\u5E93\u56DE\u7B54\u95EE\u9898\u3002",
3709
+ description: "LLM \u95EE\u7B54:\u57FA\u4E8E\u77E5\u8BC6\u98DE\u8F6E\u56DE\u7B54\u95EE\u9898\u3002",
3710
3710
  inputSchema: {
3711
3711
  type: "object",
3712
3712
  properties: {
@@ -3718,7 +3718,7 @@ var TOOLS = [
3718
3718
  },
3719
3719
  {
3720
3720
  name: "search",
3721
- description: "\u5168\u6587\u641C\u7D22\u77E5\u8BC6\u5E93\u3002",
3721
+ description: "\u5168\u6587\u641C\u7D22\u77E5\u8BC6\u98DE\u8F6E\u3002",
3722
3722
  inputSchema: {
3723
3723
  type: "object",
3724
3724
  properties: {
@@ -3751,7 +3751,7 @@ var TOOLS = [
3751
3751
  },
3752
3752
  {
3753
3753
  name: "stats",
3754
- description: "\u77E5\u8BC6\u5E93\u7EDF\u8BA1(\u8282\u70B9/\u5173\u7CFB\u6570)\u3002",
3754
+ description: "\u77E5\u8BC6\u98DE\u8F6E\u7EDF\u8BA1(\u8282\u70B9/\u5173\u7CFB\u6570)\u3002",
3755
3755
  inputSchema: { type: "object", properties: {} }
3756
3756
  }
3757
3757
  ];
@@ -4259,7 +4259,7 @@ async function ingest(client, opts, args) {
4259
4259
  saveManifest(man);
4260
4260
  }
4261
4261
  output(result, () => {
4262
- console.log(ok("\u5DF2\u5BFC\u5165\u670D\u52A1\u5668\u77E5\u8BC6\u5E93"));
4262
+ console.log(ok("\u5DF2\u5BFC\u5165\u670D\u52A1\u5668\u77E5\u8BC6\u98DE\u8F6E"));
4263
4263
  if (opts.title) console.log(dim(` \u6807\u9898: ${opts.title}`));
4264
4264
  console.log(` ${green("\u5B9E\u4F53")}: ${result.entities ?? 0} ${green("\u6982\u5FF5")}: ${result.concepts ?? 0}`);
4265
4265
  if (result.summary) console.log(dim(` \u6458\u8981: ${truncate(result.summary, 120)}`));
@@ -4540,7 +4540,7 @@ async function doPublish(client, id) {
4540
4540
  { timeoutMs: opTimeout(3e5) }
4541
4541
  );
4542
4542
  output(r, () => {
4543
- console.log(ok("\u2713 \u5DF2\u53D1\u5E03\u5230\u77E5\u8BC6\u5E93"));
4543
+ console.log(ok("\u2713 \u5DF2\u53D1\u5E03\u5230\u77E5\u8BC6\u98DE\u8F6E"));
4544
4544
  if (r.summary) console.log(dim(` ${r.summary}`));
4545
4545
  if (r.entities != null) console.log(dim(` \u5B9E\u4F53 ${r.entities} / \u6982\u5FF5 ${r.concepts ?? 0}`));
4546
4546
  });
@@ -4814,7 +4814,7 @@ async function doList2(client, opts) {
4814
4814
  async function doRestore(client, trashPath) {
4815
4815
  const p = (trashPath ?? "").trim();
4816
4816
  if (!p) throw new Error('\u8BF7\u63D0\u4F9B\u56DE\u6536\u7AD9\u8DEF\u5F84: exomind trash restore ".trash/202609/entities/Redis.md"');
4817
- console.log(dim("\u6062\u590D\u4E2D\u2026\u5927\u77E5\u8BC6\u5E93\u5237\u7D22\u5F15\u53EF\u80FD\u9700\u8981\u4E00\u4E24\u5206\u949F,\u8BF7\u52FF\u5173\u95ED"));
4817
+ console.log(dim("\u6062\u590D\u4E2D\u2026\u5927\u77E5\u8BC6\u98DE\u8F6E\u5237\u7D22\u5F15\u53EF\u80FD\u9700\u8981\u4E00\u4E24\u5206\u949F,\u8BF7\u52FF\u5173\u95ED"));
4818
4818
  const r = await client.post("/trash/restore", { trash_path: p }, { timeoutMs: opTimeout(3e5) });
4819
4819
  output(r, () => console.log(ok(`\u5DF2\u6062\u590D \u2192 ${r.path}`)));
4820
4820
  }
@@ -5018,7 +5018,7 @@ async function install(client, opts) {
5018
5018
  (m) => !(m.hooks || []).some((h) => String(h.command || "").includes("exomind"))
5019
5019
  );
5020
5020
  kept.push({
5021
- hooks: [{ type: "command", command: "exomind hook", statusMessage: "ExoMind \u77E5\u8BC6\u5E93\u68C0\u7D22" }]
5021
+ hooks: [{ type: "command", command: "exomind hook", statusMessage: "ExoMind \u77E5\u8BC6\u98DE\u8F6E\u68C0\u7D22" }]
5022
5022
  });
5023
5023
  hooks.UserPromptSubmit = kept;
5024
5024
  settings.hooks = hooks;
@@ -5269,7 +5269,7 @@ function run(fn) {
5269
5269
  };
5270
5270
  }
5271
5271
  var program2 = new Command();
5272
- program2.name("exomind").description("ExoMind \u8DE8\u5E73\u53F0\u77E5\u8BC6\u5E93\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4EA4\u4E92(\u66FF\u4EE3 Windows MCP \u5BA2\u6237\u7AEF)\u3002").version(VERSION).option("--json", "\u8F93\u51FA\u539F\u59CB JSON(\u673A\u5668\u53EF\u8BFB)").option("--base-url <url>", "\u8986\u76D6\u670D\u52A1\u5668\u5730\u5740").option("--api-key <key>", "\u8986\u76D6 API Key / \u51ED\u8BC1");
5272
+ program2.name("exomind").description("ExoMind \u8DE8\u5E73\u53F0\u77E5\u8BC6\u98DE\u8F6E\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4EA4\u4E92(\u66FF\u4EE3 Windows MCP \u5BA2\u6237\u7AEF)\u3002").version(VERSION).option("--json", "\u8F93\u51FA\u539F\u59CB JSON(\u673A\u5668\u53EF\u8BFB)").option("--base-url <url>", "\u8986\u76D6\u670D\u52A1\u5668\u5730\u5740").option("--api-key <key>", "\u8986\u76D6 API Key / \u51ED\u8BC1");
5273
5273
  program2.command("login").description("\u914D\u7F6E\u670D\u52A1\u5668\u5730\u5740\u4E0E\u51ED\u8BC1,\u5199\u5165 ~/.exomind/config.json").option("--base-url <url>", "\u670D\u52A1\u5668\u5730\u5740").option("--api-key <key>", "API Key \u6216\u767B\u5F55 token(\u4E0D\u586B\u5219\u4EA4\u4E92\u8F93\u5165)").action(run(login));
5274
5274
  program2.command("me").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u6001\u4E0E\u670D\u52A1\u5668").action(run(whoami));
5275
5275
  program2.command("whoami", { hidden: true }).description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u6001\u4E0E\u670D\u52A1\u5668(me \u7684\u65E7\u540D)").action(run(whoami));
@@ -5288,7 +5288,7 @@ program2.command("query [question...]").description("LLM \u95EE\u7B54").option("
5288
5288
  program2.command("search [keyword...]").description("\u5168\u6587/\u6DF7\u5408/\u7CBE\u6392\u641C\u7D22").option("-l, --limit <n>", "\u8FD4\u56DE\u6570\u91CF", "10").option("--rerank", "LLM \u7CBE\u6392(\u66F4\u51C6\u4F46\u66F4\u6162)").option("--hybrid", "\u6DF7\u5408\u641C\u7D22(BM25+\u8BED\u4E49)").action(run(search));
5289
5289
  program2.command("entity [name...]").description("\u5B9E\u4F53\u8BE6\u60C5 + \u5173\u7CFB").action(run(entity));
5290
5290
  program2.command("relations [name...]").description("\u5173\u8054\u5B9E\u4F53(\u53EF\u8FBE\u6027)").option("-d, --depth <n>", "\u641C\u7D22\u6DF1\u5EA6 1-3", "1").action(run(relations));
5291
- program2.command("stats").description("\u77E5\u8BC6\u5E93\u7EDF\u8BA1").action(run(stats));
5291
+ program2.command("stats").description("\u77E5\u8BC6\u98DE\u8F6E\u7EDF\u8BA1").action(run(stats));
5292
5292
  var reviewCmd = program2.command("review").description("FSRS-5 \u590D\u4E60\u961F\u5217").option("-l, --limit <n>", "\u6570\u91CF", "12");
5293
5293
  reviewCmd.action(run((client, opts) => list(client, { limit: toInt(opts.limit) })));
5294
5294
  reviewCmd.command("mark [name...]").description("\u6807\u8BB0\u590D\u4E60 (rating: 1=\u5FD8\u8BB0 2=\u5403\u529B 3=\u987A\u5229 4=\u8F7B\u677E)").option("-r, --rating <n>", "1-4", "3").action(run((client, opts, args) => mark(client, { rating: toInt(opts.rating) }, args)));