@co-engram/core 0.1.2 → 0.1.4

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.
Files changed (239) hide show
  1. package/dist/bootstrap/classify.d.ts +73 -0
  2. package/dist/bootstrap/classify.d.ts.map +1 -0
  3. package/dist/bootstrap/classify.js +134 -0
  4. package/dist/bootstrap/classify.js.map +1 -0
  5. package/dist/bootstrap/index.d.ts +89 -0
  6. package/dist/bootstrap/index.d.ts.map +1 -0
  7. package/dist/bootstrap/index.js +158 -0
  8. package/dist/bootstrap/index.js.map +1 -0
  9. package/dist/concepts/dictionary.d.ts +260 -0
  10. package/dist/concepts/dictionary.d.ts.map +1 -0
  11. package/dist/concepts/dictionary.js +253 -0
  12. package/dist/concepts/dictionary.js.map +1 -0
  13. package/dist/concepts/index.d.ts +11 -0
  14. package/dist/concepts/index.d.ts.map +1 -0
  15. package/dist/concepts/index.js +10 -0
  16. package/dist/concepts/index.js.map +1 -0
  17. package/dist/concepts/types.d.ts +65 -0
  18. package/dist/concepts/types.d.ts.map +1 -0
  19. package/dist/concepts/types.js +15 -0
  20. package/dist/concepts/types.js.map +1 -0
  21. package/dist/config/defaults.d.ts +32 -3
  22. package/dist/config/defaults.d.ts.map +1 -1
  23. package/dist/config/defaults.js +53 -3
  24. package/dist/config/defaults.js.map +1 -1
  25. package/dist/config/index.d.ts +18 -1
  26. package/dist/config/index.d.ts.map +1 -1
  27. package/dist/config/index.js +75 -3
  28. package/dist/config/index.js.map +1 -1
  29. package/dist/config/loader.d.ts +10 -0
  30. package/dist/config/loader.d.ts.map +1 -0
  31. package/dist/config/loader.js +10 -0
  32. package/dist/config/loader.js.map +1 -0
  33. package/dist/config/types.d.ts +97 -1
  34. package/dist/config/types.d.ts.map +1 -1
  35. package/dist/contradiction/auto-degrade.d.ts +11 -2
  36. package/dist/contradiction/auto-degrade.d.ts.map +1 -1
  37. package/dist/contradiction/auto-degrade.js +22 -0
  38. package/dist/contradiction/auto-degrade.js.map +1 -1
  39. package/dist/contradiction/resolver.d.ts.map +1 -1
  40. package/dist/contradiction/resolver.js +7 -1
  41. package/dist/contradiction/resolver.js.map +1 -1
  42. package/dist/dreaming/index.d.ts +1 -0
  43. package/dist/dreaming/index.d.ts.map +1 -1
  44. package/dist/dreaming/index.js +1 -0
  45. package/dist/dreaming/index.js.map +1 -1
  46. package/dist/dreaming/llm-pattern-abstraction.d.ts +31 -0
  47. package/dist/dreaming/llm-pattern-abstraction.d.ts.map +1 -0
  48. package/dist/dreaming/llm-pattern-abstraction.js +70 -0
  49. package/dist/dreaming/llm-pattern-abstraction.js.map +1 -0
  50. package/dist/dreaming/rem.d.ts.map +1 -1
  51. package/dist/dreaming/rem.js +1 -0
  52. package/dist/dreaming/rem.js.map +1 -1
  53. package/dist/dreaming/scheduler.d.ts +13 -0
  54. package/dist/dreaming/scheduler.d.ts.map +1 -1
  55. package/dist/dreaming/scheduler.js +14 -2
  56. package/dist/dreaming/scheduler.js.map +1 -1
  57. package/dist/evolution/triggered.d.ts.map +1 -1
  58. package/dist/evolution/triggered.js +1 -0
  59. package/dist/evolution/triggered.js.map +1 -1
  60. package/dist/generative/hypothesis.d.ts.map +1 -1
  61. package/dist/generative/hypothesis.js +1 -0
  62. package/dist/generative/hypothesis.js.map +1 -1
  63. package/dist/i18n/en.d.ts.map +1 -1
  64. package/dist/i18n/en.js +1278 -33
  65. package/dist/i18n/en.js.map +1 -1
  66. package/dist/i18n/index.d.ts +34 -1
  67. package/dist/i18n/index.d.ts.map +1 -1
  68. package/dist/i18n/index.js +36 -7
  69. package/dist/i18n/index.js.map +1 -1
  70. package/dist/i18n/zh.d.ts +709 -32
  71. package/dist/i18n/zh.d.ts.map +1 -1
  72. package/dist/i18n/zh.js +1282 -33
  73. package/dist/i18n/zh.js.map +1 -1
  74. package/dist/index/graph-builder.js +3 -3
  75. package/dist/index/graph-builder.js.map +1 -1
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/learning/loop.d.ts +9 -0
  81. package/dist/learning/loop.d.ts.map +1 -1
  82. package/dist/learning/loop.js +42 -1
  83. package/dist/learning/loop.js.map +1 -1
  84. package/dist/maintenance/types.d.ts +11 -0
  85. package/dist/maintenance/types.d.ts.map +1 -1
  86. package/dist/maintenance/types.js.map +1 -1
  87. package/dist/merge/auto-onboard.d.ts +7 -1
  88. package/dist/merge/auto-onboard.d.ts.map +1 -1
  89. package/dist/merge/auto-onboard.js +35 -13
  90. package/dist/merge/auto-onboard.js.map +1 -1
  91. package/dist/merge/post-merge-hook.d.ts.map +1 -1
  92. package/dist/merge/post-merge-hook.js +16 -2
  93. package/dist/merge/post-merge-hook.js.map +1 -1
  94. package/dist/merge/synapse-merger.js +6 -0
  95. package/dist/merge/synapse-merger.js.map +1 -1
  96. package/dist/merge-driver.cjs +64 -5
  97. package/dist/observability/audit-log.d.ts +7 -1
  98. package/dist/observability/audit-log.d.ts.map +1 -1
  99. package/dist/observability/audit-log.js.map +1 -1
  100. package/dist/observability/necessity-evaluator.d.ts +29 -0
  101. package/dist/observability/necessity-evaluator.d.ts.map +1 -1
  102. package/dist/observability/necessity-evaluator.js +240 -13
  103. package/dist/observability/necessity-evaluator.js.map +1 -1
  104. package/dist/observability/proposal-engine.d.ts +81 -4
  105. package/dist/observability/proposal-engine.d.ts.map +1 -1
  106. package/dist/observability/proposal-engine.js +207 -13
  107. package/dist/observability/proposal-engine.js.map +1 -1
  108. package/dist/observability/runtime-description-check.d.ts +55 -0
  109. package/dist/observability/runtime-description-check.d.ts.map +1 -0
  110. package/dist/observability/runtime-description-check.js +63 -0
  111. package/dist/observability/runtime-description-check.js.map +1 -0
  112. package/dist/prompt-signals/cache.d.ts +73 -0
  113. package/dist/prompt-signals/cache.d.ts.map +1 -1
  114. package/dist/prompt-signals/cache.js +102 -0
  115. package/dist/prompt-signals/cache.js.map +1 -1
  116. package/dist/prompt-signals/event-bus.d.ts +82 -0
  117. package/dist/prompt-signals/event-bus.d.ts.map +1 -0
  118. package/dist/prompt-signals/event-bus.js +105 -0
  119. package/dist/prompt-signals/event-bus.js.map +1 -0
  120. package/dist/prompt-signals/index.d.ts +2 -1
  121. package/dist/prompt-signals/index.d.ts.map +1 -1
  122. package/dist/prompt-signals/index.js +2 -1
  123. package/dist/prompt-signals/index.js.map +1 -1
  124. package/dist/reinforcement/ltp.d.ts +15 -1
  125. package/dist/reinforcement/ltp.d.ts.map +1 -1
  126. package/dist/reinforcement/ltp.js +24 -5
  127. package/dist/reinforcement/ltp.js.map +1 -1
  128. package/dist/reinforcement/related.d.ts +31 -2
  129. package/dist/reinforcement/related.d.ts.map +1 -1
  130. package/dist/reinforcement/related.js +39 -3
  131. package/dist/reinforcement/related.js.map +1 -1
  132. package/dist/retrieval/filter.d.ts.map +1 -1
  133. package/dist/retrieval/filter.js +7 -0
  134. package/dist/retrieval/filter.js.map +1 -1
  135. package/dist/retrieval/fts.d.ts +6 -5
  136. package/dist/retrieval/fts.d.ts.map +1 -1
  137. package/dist/retrieval/fts.js +74 -22
  138. package/dist/retrieval/fts.js.map +1 -1
  139. package/dist/status/index.d.ts +7 -0
  140. package/dist/status/index.d.ts.map +1 -0
  141. package/dist/status/index.js +7 -0
  142. package/dist/status/index.js.map +1 -0
  143. package/dist/status/status.d.ts +132 -0
  144. package/dist/status/status.d.ts.map +1 -0
  145. package/dist/status/status.js +437 -0
  146. package/dist/status/status.js.map +1 -0
  147. package/dist/storage/engram-store.d.ts.map +1 -1
  148. package/dist/storage/engram-store.js +17 -2
  149. package/dist/storage/engram-store.js.map +1 -1
  150. package/dist/storage/git.d.ts +168 -0
  151. package/dist/storage/git.d.ts.map +1 -1
  152. package/dist/storage/git.js +616 -33
  153. package/dist/storage/git.js.map +1 -1
  154. package/dist/storage/index.d.ts +1 -0
  155. package/dist/storage/index.d.ts.map +1 -1
  156. package/dist/storage/index.js +1 -0
  157. package/dist/storage/index.js.map +1 -1
  158. package/dist/storage/infra-doctor.d.ts +42 -0
  159. package/dist/storage/infra-doctor.d.ts.map +1 -0
  160. package/dist/storage/infra-doctor.js +92 -0
  161. package/dist/storage/infra-doctor.js.map +1 -0
  162. package/dist/storage/obsidian-links.d.ts +73 -0
  163. package/dist/storage/obsidian-links.d.ts.map +1 -0
  164. package/dist/storage/obsidian-links.js +177 -0
  165. package/dist/storage/obsidian-links.js.map +1 -0
  166. package/dist/storage/path.d.ts +24 -0
  167. package/dist/storage/path.d.ts.map +1 -1
  168. package/dist/storage/path.js +53 -0
  169. package/dist/storage/path.js.map +1 -1
  170. package/dist/storage/repository.d.ts +74 -5
  171. package/dist/storage/repository.d.ts.map +1 -1
  172. package/dist/storage/repository.js +337 -21
  173. package/dist/storage/repository.js.map +1 -1
  174. package/dist/storage/synapse-store.d.ts +7 -1
  175. package/dist/storage/synapse-store.d.ts.map +1 -1
  176. package/dist/storage/synapse-store.js +8 -0
  177. package/dist/storage/synapse-store.js.map +1 -1
  178. package/dist/tools/audit-query-tool.d.ts +53 -0
  179. package/dist/tools/audit-query-tool.d.ts.map +1 -0
  180. package/dist/tools/audit-query-tool.js +123 -0
  181. package/dist/tools/audit-query-tool.js.map +1 -0
  182. package/dist/tools/doctor-tools.d.ts +5 -0
  183. package/dist/tools/doctor-tools.d.ts.map +1 -1
  184. package/dist/tools/doctor-tools.js +11 -3
  185. package/dist/tools/doctor-tools.js.map +1 -1
  186. package/dist/tools/engram-tools.d.ts +13 -0
  187. package/dist/tools/engram-tools.d.ts.map +1 -1
  188. package/dist/tools/engram-tools.js +72 -8
  189. package/dist/tools/engram-tools.js.map +1 -1
  190. package/dist/tools/index.d.ts +3 -0
  191. package/dist/tools/index.d.ts.map +1 -1
  192. package/dist/tools/index.js +3 -0
  193. package/dist/tools/index.js.map +1 -1
  194. package/dist/tools/llm-descriptions.d.ts +28 -28
  195. package/dist/tools/llm-descriptions.d.ts.map +1 -1
  196. package/dist/tools/llm-descriptions.js +56 -489
  197. package/dist/tools/llm-descriptions.js.map +1 -1
  198. package/dist/tools/normalization.d.ts +43 -0
  199. package/dist/tools/normalization.d.ts.map +1 -0
  200. package/dist/tools/normalization.js +68 -0
  201. package/dist/tools/normalization.js.map +1 -0
  202. package/dist/tools/proposal-tools.d.ts +23 -1
  203. package/dist/tools/proposal-tools.d.ts.map +1 -1
  204. package/dist/tools/proposal-tools.js +58 -17
  205. package/dist/tools/proposal-tools.js.map +1 -1
  206. package/dist/tools/registry.d.ts.map +1 -1
  207. package/dist/tools/registry.js +6 -0
  208. package/dist/tools/registry.js.map +1 -1
  209. package/dist/tools/schemas.d.ts +96 -22
  210. package/dist/tools/schemas.d.ts.map +1 -1
  211. package/dist/tools/schemas.js +84 -11
  212. package/dist/tools/schemas.js.map +1 -1
  213. package/dist/tools/skill-tools.js +1 -1
  214. package/dist/tools/skill-tools.js.map +1 -1
  215. package/dist/tools/synapse-tools.d.ts.map +1 -1
  216. package/dist/tools/synapse-tools.js +1 -0
  217. package/dist/tools/synapse-tools.js.map +1 -1
  218. package/dist/tools/sync-tools.d.ts +102 -0
  219. package/dist/tools/sync-tools.d.ts.map +1 -0
  220. package/dist/tools/sync-tools.js +309 -0
  221. package/dist/tools/sync-tools.js.map +1 -0
  222. package/dist/tools/synthesize-tools.d.ts +79 -0
  223. package/dist/tools/synthesize-tools.d.ts.map +1 -0
  224. package/dist/tools/synthesize-tools.js +297 -0
  225. package/dist/tools/synthesize-tools.js.map +1 -0
  226. package/dist/tools/tool-profile.d.ts +68 -0
  227. package/dist/tools/tool-profile.d.ts.map +1 -0
  228. package/dist/tools/tool-profile.js +174 -0
  229. package/dist/tools/tool-profile.js.map +1 -0
  230. package/dist/tools/tool.d.ts +17 -0
  231. package/dist/tools/tool.d.ts.map +1 -1
  232. package/dist/tools/tool.js.map +1 -1
  233. package/dist/types/disclosure.d.ts +7 -0
  234. package/dist/types/disclosure.d.ts.map +1 -1
  235. package/dist/types/repository-types.d.ts +17 -1
  236. package/dist/types/repository-types.d.ts.map +1 -1
  237. package/dist/types/synapse.d.ts +19 -1
  238. package/dist/types/synapse.d.ts.map +1 -1
  239. package/package.json +9 -9
@@ -0,0 +1,73 @@
1
+ /**
2
+ * dataRoot 路径分类与切换逻辑(CLI + viewer UI 共享)
3
+ *
4
+ * 从 `@co-engram/claude-code/cli.ts` 提取,让 viewer 的 PUT /api/config 也能安全地
5
+ * 修改 dataRoot。两入口共享同一份验证 + 初始化 + 写 bootstrap 逻辑,保证行为一致。
6
+ *
7
+ * @module @co-engram/core/bootstrap
8
+ */
9
+ import type { Language } from "../i18n/index.js";
10
+ /** 目标路径分类结果 */
11
+ export type TargetPathClassification = "missing" | "empty" | "engram-warehouse" | "non-engram";
12
+ /**
13
+ * 探测目标路径状态,返回分类结果
14
+ *
15
+ * 分类:
16
+ * - 'missing':路径不存在
17
+ * - 'empty':存在但完全空(可立即接管)
18
+ * - 'engram-warehouse':已是 co-engram 仓库(有 .co-engram/config.json)
19
+ * - 'non-engram':有其他文件,可能是用户用作他途
20
+ */
21
+ export declare function classifyTargetPath(targetPath: string): TargetPathClassification;
22
+ /**
23
+ * 初始化一个空的 team-memory 目录(创建 .co-engram/config.json)
24
+ *
25
+ * 用于首次切换到新 dataRoot 时。失败抛错。
26
+ */
27
+ export declare function initializeEmptyWarehouse(targetPath: string, options?: {
28
+ readonly createdBy?: string;
29
+ readonly language?: Language;
30
+ }): Promise<void>;
31
+ /** applyDataRootChange 成功结果 */
32
+ export interface ApplyDataRootSuccessResult {
33
+ readonly ok: true;
34
+ readonly dataRoot: string;
35
+ readonly classification: TargetPathClassification;
36
+ readonly initialized: boolean;
37
+ }
38
+ /** applyDataRootChange 失败结果 */
39
+ export interface ApplyDataRootFailureResult {
40
+ readonly ok: false;
41
+ readonly error: string;
42
+ readonly reason: "non-engram" | "invalid" | "init-failed";
43
+ /**
44
+ * non-engram 失败时附带:目标目录里现有的文件/子目录名(最多 10 个)+ 总数。
45
+ * UI 用它给用户展示"将接管此目录,你的这些文件不会被改动",让用户二次确认。
46
+ */
47
+ readonly existingFiles?: readonly string[];
48
+ readonly existingCount?: number;
49
+ }
50
+ /** applyDataRootChange 结果 */
51
+ export type ApplyDataRootResult = ApplyDataRootSuccessResult | ApplyDataRootFailureResult;
52
+ /**
53
+ * 应用 dataRoot 变更:验证 + 初始化(若需) + 写 bootstrap config
54
+ *
55
+ * 用于 CLI `co-engram config data-root <path>` 和 viewer PUT /api/config。
56
+ *
57
+ * 行为:
58
+ * - 'missing' / 'empty':mkdir + initializeEmptyWarehouse + writeBootstrap
59
+ * - 'engram-warehouse':直接 writeBootstrap(不重新初始化,保留已有数据)
60
+ * - 'non-engram' + force=true:mkdir + initializeEmptyWarehouse + writeBootstrap
61
+ * - 'non-engram' + force=false:拒绝,返回 reason='non-engram'
62
+ *
63
+ * @param rawPath 用户输入的路径(相对或绝对)
64
+ * @param opts.force 是否强制接管非空非 co-engram 目录(UI 默认 false,CLI 支持 --force)
65
+ * @param opts.createdBy 可选,初始化空 warehouse 时的 defaultCreatedBy
66
+ * @param opts.language 可选,初始化空 warehouse 时的 language
67
+ */
68
+ export declare function applyDataRootChange(rawPath: string, options?: {
69
+ readonly force?: boolean;
70
+ readonly createdBy?: string;
71
+ readonly language?: Language;
72
+ }): Promise<ApplyDataRootResult>;
73
+ //# sourceMappingURL=classify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/bootstrap/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,eAAe;AACf,MAAM,MAAM,wBAAwB,GAChC,SAAS,GACT,OAAO,GACP,kBAAkB,GAClB,YAAY,CAAC;AAEjB;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,GACjB,wBAAwB,CAc1B;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAO,GAC1E,OAAO,CAAC,IAAI,CAAC,CAef;AAED,+BAA+B;AAC/B,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,wBAAwB,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,+BAA+B;AAC/B,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,6BAA6B;AAC7B,MAAM,MAAM,mBAAmB,GAC3B,0BAA0B,GAC1B,0BAA0B,CAAC;AAE/B;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAO,GACpG,OAAO,CAAC,mBAAmB,CAAC,CA4D9B"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * dataRoot 路径分类与切换逻辑(CLI + viewer UI 共享)
3
+ *
4
+ * 从 `@co-engram/claude-code/cli.ts` 提取,让 viewer 的 PUT /api/config 也能安全地
5
+ * 修改 dataRoot。两入口共享同一份验证 + 初始化 + 写 bootstrap 逻辑,保证行为一致。
6
+ *
7
+ * @module @co-engram/core/bootstrap
8
+ */
9
+ import { existsSync, mkdirSync, readdirSync } from "node:fs";
10
+ import { isAbsolute, resolve } from "node:path";
11
+ import { writeTeamMemoryConfig } from "../config/index.js";
12
+ import { detectGitAuthor } from "../host/detect-git-author.js";
13
+ import { DEFAULT_LANGUAGE } from "../i18n/index.js";
14
+ import { writeBootstrapDataRoot } from "./index.js";
15
+ /**
16
+ * 探测目标路径状态,返回分类结果
17
+ *
18
+ * 分类:
19
+ * - 'missing':路径不存在
20
+ * - 'empty':存在但完全空(可立即接管)
21
+ * - 'engram-warehouse':已是 co-engram 仓库(有 .co-engram/config.json)
22
+ * - 'non-engram':有其他文件,可能是用户用作他途
23
+ */
24
+ export function classifyTargetPath(targetPath) {
25
+ if (!existsSync(targetPath))
26
+ return "missing";
27
+ let entries;
28
+ try {
29
+ entries = readdirSync(targetPath);
30
+ }
31
+ catch {
32
+ return "non-engram";
33
+ }
34
+ if (entries.length === 0)
35
+ return "empty";
36
+ const hasCoEngramConfig = existsSync(resolve(targetPath, ".co-engram", "config.json"));
37
+ if (hasCoEngramConfig)
38
+ return "engram-warehouse";
39
+ return "non-engram";
40
+ }
41
+ /**
42
+ * 初始化一个空的 team-memory 目录(创建 .co-engram/config.json)
43
+ *
44
+ * 用于首次切换到新 dataRoot 时。失败抛错。
45
+ */
46
+ export async function initializeEmptyWarehouse(targetPath, options = {}) {
47
+ const createdBy = options.createdBy ??
48
+ detectGitAuthor() ??
49
+ process.env.USER ??
50
+ "unknown";
51
+ const language = options.language ?? DEFAULT_LANGUAGE;
52
+ mkdirSync(resolve(targetPath, ".co-engram"), { recursive: true });
53
+ await writeTeamMemoryConfig(targetPath, {
54
+ version: 1,
55
+ language,
56
+ defaultCreatedBy: createdBy,
57
+ createdAt: new Date().toISOString(),
58
+ initializedBy: "co-engram-cli",
59
+ });
60
+ }
61
+ /**
62
+ * 应用 dataRoot 变更:验证 + 初始化(若需) + 写 bootstrap config
63
+ *
64
+ * 用于 CLI `co-engram config data-root <path>` 和 viewer PUT /api/config。
65
+ *
66
+ * 行为:
67
+ * - 'missing' / 'empty':mkdir + initializeEmptyWarehouse + writeBootstrap
68
+ * - 'engram-warehouse':直接 writeBootstrap(不重新初始化,保留已有数据)
69
+ * - 'non-engram' + force=true:mkdir + initializeEmptyWarehouse + writeBootstrap
70
+ * - 'non-engram' + force=false:拒绝,返回 reason='non-engram'
71
+ *
72
+ * @param rawPath 用户输入的路径(相对或绝对)
73
+ * @param opts.force 是否强制接管非空非 co-engram 目录(UI 默认 false,CLI 支持 --force)
74
+ * @param opts.createdBy 可选,初始化空 warehouse 时的 defaultCreatedBy
75
+ * @param opts.language 可选,初始化空 warehouse 时的 language
76
+ */
77
+ export async function applyDataRootChange(rawPath, options = {}) {
78
+ const trimmed = rawPath.trim();
79
+ if (!trimmed) {
80
+ return { ok: false, error: "Path is empty", reason: "invalid" };
81
+ }
82
+ const newPath = isAbsolute(trimmed) ? trimmed : resolve(trimmed);
83
+ const classification = classifyTargetPath(newPath);
84
+ if (classification === "non-engram" && !options.force) {
85
+ // 收集目录里现有的文件/子目录名(最多 10 个),让 UI 展示给用户。
86
+ // co-engram 接管时只在目录里创建 .co-engram/ 子目录,不会触碰这些文件;
87
+ // 但仍需让用户清楚地"看到自己在接管什么",二次确认后再 force=true 重发。
88
+ let existingFiles = [];
89
+ let existingCount = 0;
90
+ try {
91
+ const all = readdirSync(newPath);
92
+ existingCount = all.length;
93
+ existingFiles = all.slice(0, 10);
94
+ }
95
+ catch {
96
+ // 读失败就空数组返回,UI 仍可继续(基于 reason 给出二次确认)
97
+ }
98
+ return {
99
+ ok: false,
100
+ error: `Directory ${newPath} exists but is not a co-engram warehouse (no .co-engram/config.json). It may contain unrelated user data. Use --force (CLI) to take over.`,
101
+ reason: "non-engram",
102
+ existingFiles,
103
+ existingCount,
104
+ };
105
+ }
106
+ let initialized = false;
107
+ if (classification === "missing" ||
108
+ classification === "empty" ||
109
+ classification === "non-engram") {
110
+ mkdirSync(newPath, { recursive: true });
111
+ try {
112
+ await initializeEmptyWarehouse(newPath, {
113
+ ...(options.createdBy ? { createdBy: options.createdBy } : {}),
114
+ ...(options.language ? { language: options.language } : {}),
115
+ });
116
+ initialized = true;
117
+ }
118
+ catch (err) {
119
+ return {
120
+ ok: false,
121
+ error: `Failed to initialize warehouse: ${err instanceof Error ? err.message : String(err)}`,
122
+ reason: "init-failed",
123
+ };
124
+ }
125
+ }
126
+ await writeBootstrapDataRoot(newPath);
127
+ return {
128
+ ok: true,
129
+ dataRoot: newPath,
130
+ classification,
131
+ initialized,
132
+ };
133
+ }
134
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/bootstrap/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Bootstrap 配置:dataRoot 的单一权威入口
3
+ *
4
+ * 设计动机:
5
+ * co-engram 启动时需要先找到 dataRoot,但 dataRoot 内的 `.co-engram/config.json`
6
+ * 又保存了大部分配置 —— "鸡生蛋" 问题。本模块解决这个悖论:
7
+ *
8
+ * - **bootstrap 配置文件位置固定**:`~/.co-engram/config.json`(用户 home 下,
9
+ * 不在 dataRoot 内),只保存 dataRoot 一个字段
10
+ * - **单一权威入口**:用户通过 `co-engram config data-root <path>` CLI 命令修改
11
+ * - **不再支持 env / openclaw.json / viewer UI 修改 dataRoot**(避免多处入口造成混乱)
12
+ *
13
+ * 解析优先级:
14
+ * 1. `~/.co-engram/config.json:dataRoot`(权威)
15
+ * 2. `$HOME/team-memory`(默认 fallback)
16
+ *
17
+ * 异常处理:
18
+ * - bootstrap 文件不存在 → fallback 到默认 + warning(首次运行场景)
19
+ * - bootstrap 文件损坏 → 备份后重建 + warning
20
+ * - dataRoot 字段缺失 → fallback 到默认 + warning
21
+ *
22
+ * @module @co-engram/core/bootstrap
23
+ */
24
+ /** bootstrap 配置文件名 */
25
+ export declare const BOOTSTRAP_CONFIG_FILENAME = "config.json";
26
+ /** bootstrap 配置目录(用户 home 下,固定) */
27
+ export declare function getBootstrapDir(): string;
28
+ /** bootstrap 配置文件完整路径 */
29
+ export declare function getBootstrapConfigPath(): string;
30
+ /** 默认 dataRoot fallback */
31
+ export declare function getDefaultDataRoot(): string;
32
+ /** bootstrap 配置 schema */
33
+ export interface BootstrapConfig {
34
+ /** schema 版本 */
35
+ readonly version: 1;
36
+ /** 数据根目录(绝对路径) */
37
+ readonly dataRoot: string;
38
+ }
39
+ /** resolve 结果来源标签 */
40
+ export type BootstrapSource = "bootstrap-config" | "default" | "repaired";
41
+ /** resolve 结果 */
42
+ export interface BootstrapResolveResult {
43
+ /** 解析后的 dataRoot(绝对路径) */
44
+ readonly dataRoot: string;
45
+ /** 来源 */
46
+ readonly source: BootstrapSource;
47
+ /** 用户可读的 warning 列表(stderr 输出用) */
48
+ readonly warnings: readonly string[];
49
+ }
50
+ /**
51
+ * 解析当前 dataRoot
52
+ *
53
+ * 调用方:mcp-server / openclaw plugin-entry 启动时调用一次,
54
+ * 拿到 dataRoot 后再 loadAndSelfHealConfig 加载完整配置。
55
+ */
56
+ export declare function resolveBootstrapDataRoot(): Promise<BootstrapResolveResult>;
57
+ /**
58
+ * 写入 bootstrap dataRoot(CLI 调用)
59
+ *
60
+ * 创建父目录,完整覆盖文件。
61
+ */
62
+ export declare function writeBootstrapDataRoot(dataRoot: string): Promise<void>;
63
+ /**
64
+ * 读取 bootstrap dataRoot(同步,无错误抛出)
65
+ *
66
+ * CLI 显示当前值时使用。文件不存在或损坏返回 undefined。
67
+ */
68
+ export declare function readBootstrapDataRootSync(): string | undefined;
69
+ /** 同步 resolve 结果来源标签 */
70
+ export type BootstrapSourceSync = "bootstrap-config" | "default" | "repaired";
71
+ /** 同步 resolve 结果(用于 OpenClaw 等要求 register 同步的宿主) */
72
+ export interface BootstrapResolveSyncResult {
73
+ /** 解析后的 dataRoot(绝对路径) */
74
+ readonly dataRoot: string;
75
+ /** 来源 */
76
+ readonly source: BootstrapSourceSync;
77
+ /** 用户可读的 warning 列表(stderr 输出用) */
78
+ readonly warnings: readonly string[];
79
+ }
80
+ /**
81
+ * 同步解析当前 dataRoot
82
+ *
83
+ * OpenClaw 1.8+ 要求 plugin register() 同步完成,无法 await 异步 fs,
84
+ * 这里用 readFileSync 替代。功能与 resolveBootstrapDataRoot 等价,
85
+ * 但损坏文件时不做备份重建(只读 + warning)—— 重建由下次 CLI 调用完成。
86
+ */
87
+ export declare function resolveBootstrapDataRootSync(): BootstrapResolveSyncResult;
88
+ export * from "./classify.js";
89
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,sBAAsB;AACtB,eAAO,MAAM,yBAAyB,gBAAgB,CAAC;AAEvD,mCAAmC;AACnC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,yBAAyB;AACzB,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,2BAA2B;AAC3B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,0BAA0B;AAC1B,MAAM,WAAW,eAAe;IAC9B,gBAAgB;IAChB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,kBAAkB;IAClB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAqB;AACrB,MAAM,MAAM,eAAe,GACvB,kBAAkB,GAClB,SAAS,GACT,UAAU,CAAC;AAEf,iBAAiB;AACjB,MAAM,WAAW,sBAAsB;IACrC,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,SAAS;IACT,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAgDhF;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,SAAS,CAa9D;AAED,wBAAwB;AACxB,MAAM,MAAM,mBAAmB,GAC3B,kBAAkB,GAClB,SAAS,GACT,UAAU,CAAC;AAEf,oDAAoD;AACpD,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,SAAS;IACT,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,IAAI,0BAA0B,CAuCzE;AAGD,cAAc,eAAe,CAAC"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Bootstrap 配置:dataRoot 的单一权威入口
3
+ *
4
+ * 设计动机:
5
+ * co-engram 启动时需要先找到 dataRoot,但 dataRoot 内的 `.co-engram/config.json`
6
+ * 又保存了大部分配置 —— "鸡生蛋" 问题。本模块解决这个悖论:
7
+ *
8
+ * - **bootstrap 配置文件位置固定**:`~/.co-engram/config.json`(用户 home 下,
9
+ * 不在 dataRoot 内),只保存 dataRoot 一个字段
10
+ * - **单一权威入口**:用户通过 `co-engram config data-root <path>` CLI 命令修改
11
+ * - **不再支持 env / openclaw.json / viewer UI 修改 dataRoot**(避免多处入口造成混乱)
12
+ *
13
+ * 解析优先级:
14
+ * 1. `~/.co-engram/config.json:dataRoot`(权威)
15
+ * 2. `$HOME/team-memory`(默认 fallback)
16
+ *
17
+ * 异常处理:
18
+ * - bootstrap 文件不存在 → fallback 到默认 + warning(首次运行场景)
19
+ * - bootstrap 文件损坏 → 备份后重建 + warning
20
+ * - dataRoot 字段缺失 → fallback 到默认 + warning
21
+ *
22
+ * @module @co-engram/core/bootstrap
23
+ */
24
+ import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
25
+ import { readFileSync, existsSync } from "node:fs";
26
+ import { dirname, join } from "node:path";
27
+ /** bootstrap 配置文件名 */
28
+ export const BOOTSTRAP_CONFIG_FILENAME = "config.json";
29
+ /** bootstrap 配置目录(用户 home 下,固定) */
30
+ export function getBootstrapDir() {
31
+ return join(process.env.HOME ?? "/tmp", ".co-engram");
32
+ }
33
+ /** bootstrap 配置文件完整路径 */
34
+ export function getBootstrapConfigPath() {
35
+ return join(getBootstrapDir(), BOOTSTRAP_CONFIG_FILENAME);
36
+ }
37
+ /** 默认 dataRoot fallback */
38
+ export function getDefaultDataRoot() {
39
+ return join(process.env.HOME ?? "/tmp", "team-memory");
40
+ }
41
+ /**
42
+ * 解析当前 dataRoot
43
+ *
44
+ * 调用方:mcp-server / openclaw plugin-entry 启动时调用一次,
45
+ * 拿到 dataRoot 后再 loadAndSelfHealConfig 加载完整配置。
46
+ */
47
+ export async function resolveBootstrapDataRoot() {
48
+ const path = getBootstrapConfigPath();
49
+ const defaultRoot = getDefaultDataRoot();
50
+ const warnings = [];
51
+ if (!existsSync(path)) {
52
+ // 首次运行 / 配置被删除:fallback 到默认,提示用户运行 CLI 配置
53
+ warnings.push(`Bootstrap config not found at ${path}. Using default ${defaultRoot}. Run 'co-engram config data-root <path>' to change.`);
54
+ return { dataRoot: defaultRoot, source: "default", warnings };
55
+ }
56
+ let raw;
57
+ try {
58
+ const content = await readFile(path, "utf-8");
59
+ const parsed = JSON.parse(content);
60
+ if (parsed && typeof parsed === "object" && parsed.version === 1) {
61
+ raw = parsed;
62
+ }
63
+ }
64
+ catch {
65
+ // JSON 损坏:备份后重建
66
+ }
67
+ if (raw === undefined) {
68
+ const ts = new Date().toISOString().replace(/[:.]/g, "-");
69
+ const backupPath = `${path}.broken.${ts}`;
70
+ try {
71
+ await rename(path, backupPath);
72
+ }
73
+ catch {
74
+ // 备份失败不阻塞
75
+ }
76
+ await writeBootstrapDataRoot(defaultRoot);
77
+ warnings.push(`Bootstrap config at ${path} was corrupt; backed up to ${backupPath}. Using default ${defaultRoot}.`);
78
+ return { dataRoot: defaultRoot, source: "repaired", warnings };
79
+ }
80
+ const dataRoot = raw.dataRoot?.trim();
81
+ if (!dataRoot) {
82
+ warnings.push(`Bootstrap config at ${path} has no dataRoot field; using default ${defaultRoot}.`);
83
+ return { dataRoot: defaultRoot, source: "default", warnings };
84
+ }
85
+ return { dataRoot, source: "bootstrap-config", warnings };
86
+ }
87
+ /**
88
+ * 写入 bootstrap dataRoot(CLI 调用)
89
+ *
90
+ * 创建父目录,完整覆盖文件。
91
+ */
92
+ export async function writeBootstrapDataRoot(dataRoot) {
93
+ const path = getBootstrapConfigPath();
94
+ const config = { version: 1, dataRoot };
95
+ await mkdir(dirname(path), { recursive: true });
96
+ await writeFile(path, JSON.stringify(config, null, 2) + "\n", "utf-8");
97
+ }
98
+ /**
99
+ * 读取 bootstrap dataRoot(同步,无错误抛出)
100
+ *
101
+ * CLI 显示当前值时使用。文件不存在或损坏返回 undefined。
102
+ */
103
+ export function readBootstrapDataRootSync() {
104
+ const path = getBootstrapConfigPath();
105
+ if (!existsSync(path))
106
+ return undefined;
107
+ try {
108
+ const content = readFileSync(path, "utf-8");
109
+ const parsed = JSON.parse(content);
110
+ if (parsed && typeof parsed === "object" && parsed.version === 1) {
111
+ return parsed.dataRoot?.trim() || undefined;
112
+ }
113
+ return undefined;
114
+ }
115
+ catch {
116
+ return undefined;
117
+ }
118
+ }
119
+ /**
120
+ * 同步解析当前 dataRoot
121
+ *
122
+ * OpenClaw 1.8+ 要求 plugin register() 同步完成,无法 await 异步 fs,
123
+ * 这里用 readFileSync 替代。功能与 resolveBootstrapDataRoot 等价,
124
+ * 但损坏文件时不做备份重建(只读 + warning)—— 重建由下次 CLI 调用完成。
125
+ */
126
+ export function resolveBootstrapDataRootSync() {
127
+ const path = getBootstrapConfigPath();
128
+ const defaultRoot = getDefaultDataRoot();
129
+ const warnings = [];
130
+ if (!existsSync(path)) {
131
+ warnings.push(`Bootstrap config not found at ${path}. Using default ${defaultRoot}. Run 'co-engram config data-root <path>' to change.`);
132
+ return { dataRoot: defaultRoot, source: "default", warnings };
133
+ }
134
+ let parsed;
135
+ try {
136
+ const content = readFileSync(path, "utf-8");
137
+ parsed = JSON.parse(content);
138
+ if (!parsed || typeof parsed !== "object" || parsed.version !== 1) {
139
+ parsed = undefined;
140
+ }
141
+ }
142
+ catch {
143
+ parsed = undefined;
144
+ }
145
+ if (parsed === undefined) {
146
+ warnings.push(`Bootstrap config at ${path} is corrupt or unreadable. Using default ${defaultRoot}. Run 'co-engram config data-root <path>' to repair.`);
147
+ return { dataRoot: defaultRoot, source: "repaired", warnings };
148
+ }
149
+ const dataRoot = parsed.dataRoot?.trim();
150
+ if (!dataRoot) {
151
+ warnings.push(`Bootstrap config at ${path} has no dataRoot field; using default ${defaultRoot}.`);
152
+ return { dataRoot: defaultRoot, source: "default", warnings };
153
+ }
154
+ return { dataRoot, source: "bootstrap-config", warnings };
155
+ }
156
+ // 共享 dataRoot 切换逻辑(CLI + viewer UI 都用)
157
+ export * from "./classify.js";
158
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bootstrap/index.ts"],"names":[],"mappings":"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"}