@monoes/monomindcli 2.16.12 → 2.16.13

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 (217) hide show
  1. package/.claude/agents/core/coder.md +1 -1
  2. package/.claude/agents/engineering/engineering-devops-automator.md +1 -1
  3. package/.claude/agents/github/repo-architect.md +1 -1
  4. package/.claude/agents/testing/production-validator.md +1 -1
  5. package/.claude/agents/testing/testing-tool-evaluator.md +1 -1
  6. package/.claude/commands/github/pr-manager.md +1 -1
  7. package/.claude/helpers/pick-rank.cjs +34 -4
  8. package/.claude/skills/monolean-audit/SKILL.md +1 -1
  9. package/dist/src/commands/cleanup-data.d.ts +30 -0
  10. package/dist/src/commands/cleanup-data.d.ts.map +1 -0
  11. package/dist/src/commands/cleanup-data.js +138 -0
  12. package/dist/src/commands/cleanup-data.js.map +1 -0
  13. package/dist/src/commands/cleanup-scratch.d.ts +43 -0
  14. package/dist/src/commands/cleanup-scratch.d.ts.map +1 -0
  15. package/dist/src/commands/cleanup-scratch.js +125 -0
  16. package/dist/src/commands/cleanup-scratch.js.map +1 -0
  17. package/dist/src/commands/cleanup.d.ts +2 -39
  18. package/dist/src/commands/cleanup.d.ts.map +1 -1
  19. package/dist/src/commands/cleanup.js +5 -247
  20. package/dist/src/commands/cleanup.js.map +1 -1
  21. package/dist/src/commands/doctor-gitignore-checks.d.ts +10 -0
  22. package/dist/src/commands/doctor-gitignore-checks.d.ts.map +1 -0
  23. package/dist/src/commands/doctor-gitignore-checks.js +141 -0
  24. package/dist/src/commands/doctor-gitignore-checks.js.map +1 -0
  25. package/dist/src/commands/doctor-helpers-checks.d.ts +10 -0
  26. package/dist/src/commands/doctor-helpers-checks.d.ts.map +1 -0
  27. package/dist/src/commands/doctor-helpers-checks.js +292 -0
  28. package/dist/src/commands/doctor-helpers-checks.js.map +1 -0
  29. package/dist/src/commands/doctor-memory-checks.d.ts +47 -0
  30. package/dist/src/commands/doctor-memory-checks.d.ts.map +1 -0
  31. package/dist/src/commands/doctor-memory-checks.js +298 -0
  32. package/dist/src/commands/doctor-memory-checks.js.map +1 -0
  33. package/dist/src/commands/doctor-monograph-checks.d.ts +9 -0
  34. package/dist/src/commands/doctor-monograph-checks.d.ts.map +1 -0
  35. package/dist/src/commands/doctor-monograph-checks.js +331 -0
  36. package/dist/src/commands/doctor-monograph-checks.js.map +1 -0
  37. package/dist/src/commands/doctor-project-checks.d.ts +7 -66
  38. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  39. package/dist/src/commands/doctor-project-checks.js +10 -1331
  40. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  41. package/dist/src/commands/doctor-routing-checks.d.ts +10 -0
  42. package/dist/src/commands/doctor-routing-checks.d.ts.map +1 -0
  43. package/dist/src/commands/doctor-routing-checks.js +194 -0
  44. package/dist/src/commands/doctor-routing-checks.js.map +1 -0
  45. package/dist/src/commands/doctor-worker-checks.d.ts +17 -0
  46. package/dist/src/commands/doctor-worker-checks.d.ts.map +1 -0
  47. package/dist/src/commands/doctor-worker-checks.js +122 -0
  48. package/dist/src/commands/doctor-worker-checks.js.map +1 -0
  49. package/dist/src/commands/hooks-routing-commands.js +1 -1
  50. package/dist/src/commands/hooks-routing-commands.js.map +1 -1
  51. package/dist/src/commands/init.d.ts.map +1 -1
  52. package/dist/src/commands/init.js +6 -15
  53. package/dist/src/commands/init.js.map +1 -1
  54. package/dist/src/index.js +2 -2
  55. package/dist/src/index.js.map +1 -1
  56. package/dist/src/init/never-commit.d.ts +3 -3
  57. package/dist/src/init/types.d.ts +1 -1
  58. package/dist/src/init/types.js +1 -1
  59. package/dist/src/knowledge/document-store.js +1 -1
  60. package/dist/src/knowledge/document-store.js.map +1 -1
  61. package/dist/src/mcp-tools/hooks-edit-command.d.ts +10 -0
  62. package/dist/src/mcp-tools/hooks-edit-command.d.ts.map +1 -0
  63. package/dist/src/mcp-tools/hooks-edit-command.js +247 -0
  64. package/dist/src/mcp-tools/hooks-edit-command.js.map +1 -0
  65. package/dist/src/mcp-tools/hooks-learning.d.ts +9 -0
  66. package/dist/src/mcp-tools/hooks-learning.d.ts.map +1 -0
  67. package/dist/src/mcp-tools/hooks-learning.js +408 -0
  68. package/dist/src/mcp-tools/hooks-learning.js.map +1 -0
  69. package/dist/src/mcp-tools/hooks-metrics-list.d.ts +8 -0
  70. package/dist/src/mcp-tools/hooks-metrics-list.d.ts.map +1 -0
  71. package/dist/src/mcp-tools/hooks-metrics-list.js +205 -0
  72. package/dist/src/mcp-tools/hooks-metrics-list.js.map +1 -0
  73. package/dist/src/mcp-tools/hooks-route.d.ts +12 -0
  74. package/dist/src/mcp-tools/hooks-route.d.ts.map +1 -0
  75. package/dist/src/mcp-tools/hooks-route.js +251 -0
  76. package/dist/src/mcp-tools/hooks-route.js.map +1 -0
  77. package/dist/src/mcp-tools/hooks-routing.d.ts +6 -27
  78. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  79. package/dist/src/mcp-tools/hooks-routing.js +6 -1727
  80. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  81. package/dist/src/mcp-tools/hooks-session.d.ts +9 -0
  82. package/dist/src/mcp-tools/hooks-session.d.ts.map +1 -0
  83. package/dist/src/mcp-tools/hooks-session.js +243 -0
  84. package/dist/src/mcp-tools/hooks-session.js.map +1 -0
  85. package/dist/src/mcp-tools/hooks-task.d.ts +17 -0
  86. package/dist/src/mcp-tools/hooks-task.d.ts.map +1 -0
  87. package/dist/src/mcp-tools/hooks-task.js +427 -0
  88. package/dist/src/mcp-tools/hooks-task.js.map +1 -0
  89. package/dist/src/mcp-tools/hooks-tools.d.ts +2 -1
  90. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  91. package/dist/src/mcp-tools/hooks-tools.js +2 -1
  92. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  93. package/dist/src/mcp-tools/memory-tools.js +1 -1
  94. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  95. package/dist/src/memory/bm25-index.d.ts +2 -2
  96. package/dist/src/memory/bm25-index.js +2 -2
  97. package/dist/src/memory/embedding-operations.js +2 -2
  98. package/dist/src/memory/embedding-operations.js.map +1 -1
  99. package/dist/src/memory/entity-name-key.d.ts +1 -1
  100. package/dist/src/memory/entity-name-key.js +1 -1
  101. package/dist/src/memory/hnsw-operations.d.ts +1 -1
  102. package/dist/src/memory/hnsw-operations.js +1 -1
  103. package/dist/src/memory/memory-bridge-backend.d.ts +43 -0
  104. package/dist/src/memory/memory-bridge-backend.d.ts.map +1 -0
  105. package/dist/src/memory/memory-bridge-backend.js +363 -0
  106. package/dist/src/memory/memory-bridge-backend.js.map +1 -0
  107. package/dist/src/memory/memory-bridge-core.d.ts +42 -0
  108. package/dist/src/memory/memory-bridge-core.d.ts.map +1 -0
  109. package/dist/src/memory/memory-bridge-core.js +126 -0
  110. package/dist/src/memory/memory-bridge-core.js.map +1 -0
  111. package/dist/src/memory/memory-bridge-entries.d.ts +131 -0
  112. package/dist/src/memory/memory-bridge-entries.d.ts.map +1 -0
  113. package/dist/src/memory/memory-bridge-entries.js +227 -0
  114. package/dist/src/memory/memory-bridge-entries.js.map +1 -0
  115. package/dist/src/memory/memory-bridge-feedback.d.ts +60 -0
  116. package/dist/src/memory/memory-bridge-feedback.d.ts.map +1 -0
  117. package/dist/src/memory/memory-bridge-feedback.js +118 -0
  118. package/dist/src/memory/memory-bridge-feedback.js.map +1 -0
  119. package/dist/src/memory/memory-bridge-paths.d.ts +123 -0
  120. package/dist/src/memory/memory-bridge-paths.d.ts.map +1 -0
  121. package/dist/src/memory/memory-bridge-paths.js +335 -0
  122. package/dist/src/memory/memory-bridge-paths.js.map +1 -0
  123. package/dist/src/memory/memory-bridge-search.d.ts +48 -0
  124. package/dist/src/memory/memory-bridge-search.d.ts.map +1 -0
  125. package/dist/src/memory/memory-bridge-search.js +383 -0
  126. package/dist/src/memory/memory-bridge-search.js.map +1 -0
  127. package/dist/src/memory/memory-bridge-sessions.d.ts +38 -0
  128. package/dist/src/memory/memory-bridge-sessions.d.ts.map +1 -0
  129. package/dist/src/memory/memory-bridge-sessions.js +109 -0
  130. package/dist/src/memory/memory-bridge-sessions.js.map +1 -0
  131. package/dist/src/memory/memory-bridge-store.d.ts +58 -0
  132. package/dist/src/memory/memory-bridge-store.d.ts.map +1 -0
  133. package/dist/src/memory/memory-bridge-store.js +201 -0
  134. package/dist/src/memory/memory-bridge-store.js.map +1 -0
  135. package/dist/src/memory/memory-bridge.d.ts +10 -438
  136. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  137. package/dist/src/memory/memory-bridge.js +14 -1787
  138. package/dist/src/memory/memory-bridge.js.map +1 -1
  139. package/dist/src/memory/memory-kg-claims.d.ts +52 -0
  140. package/dist/src/memory/memory-kg-claims.d.ts.map +1 -0
  141. package/dist/src/memory/memory-kg-claims.js +99 -0
  142. package/dist/src/memory/memory-kg-claims.js.map +1 -0
  143. package/dist/src/memory/memory-kg-index.d.ts +86 -0
  144. package/dist/src/memory/memory-kg-index.d.ts.map +1 -0
  145. package/dist/src/memory/memory-kg-index.js +256 -0
  146. package/dist/src/memory/memory-kg-index.js.map +1 -0
  147. package/dist/src/memory/memory-kg-ingest.d.ts +44 -0
  148. package/dist/src/memory/memory-kg-ingest.d.ts.map +1 -0
  149. package/dist/src/memory/memory-kg-ingest.js +361 -0
  150. package/dist/src/memory/memory-kg-ingest.js.map +1 -0
  151. package/dist/src/memory/memory-kg-model.d.ts +168 -0
  152. package/dist/src/memory/memory-kg-model.d.ts.map +1 -0
  153. package/dist/src/memory/memory-kg-model.js +158 -0
  154. package/dist/src/memory/memory-kg-model.js.map +1 -0
  155. package/dist/src/memory/memory-kg-names.d.ts +64 -0
  156. package/dist/src/memory/memory-kg-names.d.ts.map +1 -0
  157. package/dist/src/memory/memory-kg-names.js +187 -0
  158. package/dist/src/memory/memory-kg-names.js.map +1 -0
  159. package/dist/src/memory/memory-kg-promote.d.ts +79 -0
  160. package/dist/src/memory/memory-kg-promote.d.ts.map +1 -0
  161. package/dist/src/memory/memory-kg-promote.js +248 -0
  162. package/dist/src/memory/memory-kg-promote.js.map +1 -0
  163. package/dist/src/memory/memory-kg-rebuild.d.ts +77 -0
  164. package/dist/src/memory/memory-kg-rebuild.d.ts.map +1 -0
  165. package/dist/src/memory/memory-kg-rebuild.js +299 -0
  166. package/dist/src/memory/memory-kg-rebuild.js.map +1 -0
  167. package/dist/src/memory/memory-kg-rollback.d.ts +47 -0
  168. package/dist/src/memory/memory-kg-rollback.d.ts.map +1 -0
  169. package/dist/src/memory/memory-kg-rollback.js +193 -0
  170. package/dist/src/memory/memory-kg-rollback.js.map +1 -0
  171. package/dist/src/memory/memory-kg-rules.d.ts +64 -0
  172. package/dist/src/memory/memory-kg-rules.d.ts.map +1 -0
  173. package/dist/src/memory/memory-kg-rules.js +251 -0
  174. package/dist/src/memory/memory-kg-rules.js.map +1 -0
  175. package/dist/src/memory/memory-kg-scan.d.ts +118 -0
  176. package/dist/src/memory/memory-kg-scan.d.ts.map +1 -0
  177. package/dist/src/memory/memory-kg-scan.js +209 -0
  178. package/dist/src/memory/memory-kg-scan.js.map +1 -0
  179. package/dist/src/memory/memory-kg-search.d.ts +80 -0
  180. package/dist/src/memory/memory-kg-search.d.ts.map +1 -0
  181. package/dist/src/memory/memory-kg-search.js +239 -0
  182. package/dist/src/memory/memory-kg-search.js.map +1 -0
  183. package/dist/src/memory/memory-kg.d.ts +19 -547
  184. package/dist/src/memory/memory-kg.d.ts.map +1 -1
  185. package/dist/src/memory/memory-kg.js +10 -2389
  186. package/dist/src/memory/memory-kg.js.map +1 -1
  187. package/dist/src/ui/org-hil.mjs +1 -1
  188. package/dist/src/ui/routes-org-agents.mjs +318 -0
  189. package/dist/src/ui/routes-org-approvals.mjs +133 -0
  190. package/dist/src/ui/routes-org-config.mjs +459 -0
  191. package/dist/src/ui/routes-org-control.mjs +300 -0
  192. package/dist/src/ui/routes-org-files.mjs +172 -0
  193. package/dist/src/ui/routes-org-helpers.mjs +84 -0
  194. package/dist/src/ui/routes-org-knowledge.mjs +262 -0
  195. package/dist/src/ui/routes-org-lifecycle.mjs +224 -0
  196. package/dist/src/ui/routes-org-live.mjs +278 -0
  197. package/dist/src/ui/routes-org-mastermind.mjs +346 -0
  198. package/dist/src/ui/routes-org-planning.mjs +398 -0
  199. package/dist/src/ui/routes-org-runs.mjs +430 -0
  200. package/dist/src/ui/routes-org-status.mjs +342 -0
  201. package/dist/src/ui/routes-org-workflows.mjs +212 -0
  202. package/dist/src/ui/routes-org.mjs +26 -3847
  203. package/dist/src/ui/server.mjs +1 -1
  204. package/dist/src/utils/native-error.d.ts +1 -1
  205. package/dist/src/utils/native-error.js +1 -1
  206. package/dist/src/utils/paths.d.ts +2 -1
  207. package/dist/src/utils/paths.d.ts.map +1 -1
  208. package/dist/src/utils/paths.js +2 -1
  209. package/dist/src/utils/paths.js.map +1 -1
  210. package/dist/tsconfig.tsbuildinfo +1 -1
  211. package/org-skills/adversarial-reviewer/SKILL.md +1 -1
  212. package/org-skills/board-deck-builder/SKILL.md +1 -1
  213. package/org-skills/code-reviewer/SKILL.md +1 -1
  214. package/org-skills/debugging-wizard/SKILL.md +1 -1
  215. package/org-skills/scientific-thinking-literature-review/SKILL.md +1 -1
  216. package/org-skills/scientific-thinking-scholar-evaluation/SKILL.md +1 -1
  217. package/package.json +8 -8
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Memory Bridge — project-root resolution and store path resolution
3
+ * (per-project data dir, global brain, MCP path-traversal guard). Split out
4
+ * of memory-bridge.ts, which re-exports the public symbols.
5
+ */
6
+ export interface ProjectRootResolution {
7
+ root: string;
8
+ /** Why `root` was chosen — for disclosure (doctor, debug logs), not
9
+ * behavior. `explicit-anchor`: MONOMIND_PROJECT_ROOT set and valid.
10
+ * `git`: a `.git` ancestor (any depth) was adopted. `monomind-at-start`:
11
+ * the starting directory itself carries `.monomind` (the user is
12
+ * standing in their own project — always trusted). `monomind-with-marker`:
13
+ * an ancestor's `.monomind` was corroborated by an independent project
14
+ * marker. `start-fallback`: nothing adoptable was found; `root` is
15
+ * `start`. */
16
+ reason: 'explicit-anchor' | 'git' | 'monomind-at-start' | 'monomind-with-marker' | 'start-fallback';
17
+ /** Set only on `start-fallback`: the first bare `.monomind` ancestor that
18
+ * was found but NOT adopted (no independent marker alongside it), so a
19
+ * caller can tell a genuinely ambiguous user why their brain stayed put
20
+ * instead of silently picking a directory that merely looked plausible. */
21
+ ignoredBareMonomind?: string;
22
+ /** Set whenever MONOMIND_PROJECT_ROOT was present in the environment but
23
+ * failed validation — regardless of what `reason`/`root` ended up being,
24
+ * so a typo'd anchor is never silently dropped just because the ordinary
25
+ * walk happened to land somewhere reasonable anyway (o-16 revision 1). */
26
+ invalidAnchor?: {
27
+ value: string;
28
+ problem: string;
29
+ };
30
+ }
31
+ /** The full resolution — root, reason and (when the walk found nothing
32
+ * adoptable) which bare `.monomind` ancestor it ignored. `doctor` uses this
33
+ * to disclose which directory a user's brain is keyed to and why, instead
34
+ * of a plausible-but-silent path (o-16). See `getProjectRoot` for the
35
+ * string-only form the other ~28 call sites use. */
36
+ export declare function getProjectRootResolution(from?: string): ProjectRootResolution;
37
+ /** The directory that identifies "this project" for every Second Brain store.
38
+ *
39
+ * Deliberately NOT the raw cwd: keying on cwd forked the brain per directory —
40
+ * `doc ingest ./docs` from a package subdir wrote to a different store, and a
41
+ * different metadata file, than the identical command at the repo root, and
42
+ * neither could see the other. We walk up to the nearest ancestor carrying a
43
+ * `.git` marker (any depth), or a `.monomind` marker corroborated by an
44
+ * independent project marker, so every directory inside one project resolves
45
+ * to one brain. Nested projects still win (the walk stops at the FIRST
46
+ * eligible marker), which keeps worktrees and vendored sub-repos independent.
47
+ *
48
+ * o-16: a BARE `.monomind` ancestor (no `.git`, no manifest) is NOT adopted.
49
+ * `.monomind` is created by monomind itself as a side effect of running
50
+ * anywhere — it is not independent evidence of a project, and a wrong
51
+ * resolution creates the very marker that would capture every future
52
+ * descendant if it were trusted alone. See `walkToProjectRoot`'s comment for
53
+ * the measured incident this fixes. The starting directory's OWN `.monomind`
54
+ * is still trusted unconditionally — that is the user pointing at their own
55
+ * project — and `.git` at any depth is untouched, so CI/devcontainer repos
56
+ * and subdirectory unification behave exactly as before.
57
+ *
58
+ * The walk never crosses the home directory: a dotfiles repo at `~` would
59
+ * otherwise swallow every loose project underneath it into one shared brain.
60
+ * `MONOMIND_PROJECT_ROOT`, if set AND VALID (absolute, exists, is a
61
+ * directory, is not itself the filesystem root — see `validateAnchor`), is
62
+ * an explicit anchor that skips the walk entirely — the escape hatch for
63
+ * the genuinely ambiguous case (design decision 4 / AC-3c: a real, non-git
64
+ * project whose root has a bare `.monomind` and no manifest has no other
65
+ * way to be found from a subdirectory). An invalid anchor falls through to
66
+ * the walk rather than being adopted OR silently dropped — see
67
+ * `ProjectRootResolution.invalidAnchor`.
68
+ *
69
+ * This is `MONOMIND_PROJECT_ROOT`'s SECOND consumer in this codebase —
70
+ * `mcp-tools/guidance-tools.ts:findProjectRoot()` already reads the same
71
+ * env var, for a DIFFERENT marker (`.claude`, not `.monomind`/`.git`), with
72
+ * a stricter rule: `if (envRoot && existsSync(join(envRoot, '.claude')))`,
73
+ * i.e. it only honors the anchor when `.claude` exists there, silently
74
+ * falling through to its own walk otherwise. After this revision the two
75
+ * converge on ANCHOR HANDLING for the cases that matter most — a typo'd or
76
+ * missing path is rejected by both (this one via `validateAnchor`,
77
+ * guidance-tools' because `.claude` is absent) — but "converge" describes
78
+ * only whether each accepts or rejects the anchor, not the final resolved
79
+ * root: a rejected anchor falls through to each resolver's OWN walk
80
+ * (`walkToProjectRoot` here; guidance-tools' own Strategy 1/2/3 chain
81
+ * there), which can still land on different directories for the same
82
+ * unanchored cwd. Two residual disagreements remain, both legitimate rather
83
+ * than oversights:
84
+ * 1. An anchor that exists and is a real directory but has no `.claude` in
85
+ * it: this function honors it (memory has no reason to require a
86
+ * `.claude` folder — a project's knowledge store isn't gated on whether
87
+ * an agent config lives there), guidance-tools does not (`.claude` is
88
+ * the one thing it's searching FOR, so its absence is a real signal, not
89
+ * noise, for that consumer specifically).
90
+ * 2. A RELATIVE anchor: `validateAnchor` rejects it outright (an anchor
91
+ * that silently depends on cwd defeats the point of an anchor).
92
+ * guidance-tools has no absolute-path check, so `existsSync(join(envRoot,
93
+ * '.claude'))` would resolve a relative `envRoot` against cwd and could
94
+ * accept it — narrower in practice (needs a `.claude` at that resolved
95
+ * location too) but a real gap in the two resolvers' shared assumptions.
96
+ * Reconciling the two resolvers' semantics into one shared rule is a
97
+ * separate, larger question (tracked as o-32), not something this fix
98
+ * should decide as a side effect.
99
+ *
100
+ * For anyone who already ran from the project root — the normal case — the
101
+ * resolved path is identical to before, so their store does not move.
102
+ *
103
+ * `MONOMIND_CWD` wins over the real cwd, matching `getProjectCwd()` in
104
+ * mcp-tools/types.ts — an MCP server is launched with whatever cwd the client
105
+ * chose, and that env var is already how monograph and swarm state learn which
106
+ * project they belong to. Inlined rather than imported to keep this module on
107
+ * node builtins only (see the static import in document-pipeline.ts).
108
+ */
109
+ export declare function getProjectRoot(from?: string): string;
110
+ export declare function projectDataDir(): string;
111
+ /** The personal, cross-project knowledge store. Deliberately a SIBLING of
112
+ * ~/.monomind/projects (never inside it) so per-project pruning heuristics
113
+ * (`cleanup --data`) can never touch it. Env-overridable for tests and for
114
+ * users who keep their brain on a synced/external location. Resolved lazily
115
+ * so the override works regardless of import order. */
116
+ export declare function getGlobalBrainDir(): string;
117
+ /** Sentinel callers pass as dbPath to address the global brain. */
118
+ export declare const GLOBAL_BRAIN = "@global";
119
+ export declare function getDbPath(customPath?: string): string;
120
+ /** Resolve the real on-disk SQLite data-dir path for a given custom path (or the
121
+ * default) — the dir is still named `lancedb` for legacy path back-compat. */
122
+ export declare function bridgeGetDbPath(customPath?: string): string;
123
+ //# sourceMappingURL=memory-bridge-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-bridge-paths.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-bridge-paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4CH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;mBAOe;IACf,MAAM,EACF,iBAAiB,GACjB,KAAK,GACL,mBAAmB,GACnB,sBAAsB,GACtB,gBAAgB,CAAC;IACrB;;;gFAG4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;+EAG2E;IAC3E,aAAa,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AA6HD;;;;qDAIqD;AACrD,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,MAAkD,GACvD,qBAAqB,CAavB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAkD,GAAG,MAAM,CAE/F;AAED,wBAAgB,cAAc,IAAI,MAAM,CASvC;AAaD;;;;wDAIwD;AACxD,wBAAgB,iBAAiB,IAAI,MAAM,CAI1C;AACD,mEAAmE;AACnE,eAAO,MAAM,YAAY,YAAY,CAAC;AAEtC,wBAAgB,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAsCrD;AAED;+EAC+E;AAC/E,wBAAgB,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Memory Bridge — project-root resolution and store path resolution
3
+ * (per-project data dir, global brain, MCP path-traversal guard). Split out
4
+ * of memory-bridge.ts, which re-exports the public symbols.
5
+ */
6
+ import * as crypto from 'node:crypto';
7
+ import * as fs from 'node:fs';
8
+ import * as os from 'node:os';
9
+ import * as path from 'node:path';
10
+ import { logBridgeError } from './memory-bridge-core.js';
11
+ // ===== DB path resolution =====
12
+ // LanceDB commits via atomic rename, which exFAT/SMB project volumes don't support
13
+ // (ENOTSUP os error 45) — and non-APFS volumes grow ._ AppleDouble sidecars inside
14
+ // the .lance datasets that corrupt reads. So the store always lives on the home
15
+ // volume, namespaced per project directory.
16
+ //
17
+ // The slug is a hash of the full resolved path, not a character-substitution of
18
+ // it — flattening separators to '-' is not collision-safe ('/x/foo-bar' and
19
+ // '/x/foo/bar' would both flatten to 'x-foo-bar'). A short readable prefix is
20
+ // kept purely so the directory name is browsable; only the hash guarantees
21
+ // uniqueness.
22
+ // o-16: `.git` and `.monomind` are NOT equivalent evidence of a project.
23
+ // `.git` is created by the user, deliberately (`git init`/clone) — "this
24
+ // directory is a repository". `.monomind` is created by monomind ITSELF, as
25
+ // a side effect of running anywhere — "monomind once ran here", and nothing
26
+ // more. Treating a bare `.monomind` ancestor as adoptable is a feedback
27
+ // loop: a wrong resolution creates the very marker that captures every
28
+ // future descendant. Measured against the actual incident:
29
+ // `~/mdev-tmp/.monomind` and `~/.monomind` both exist,
30
+ // neither has a `.git` or manifest, and neither is a project — both are
31
+ // monomind's own state directories. `INDEPENDENT_PROJECT_MARKERS` (other
32
+ // than `.git`, handled unconditionally) is what makes a `.monomind`
33
+ // ancestor's claim independently checkable.
34
+ const INDEPENDENT_PROJECT_MARKERS = ['package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml'];
35
+ function markerExists(p) {
36
+ try {
37
+ return fs.existsSync(p);
38
+ }
39
+ catch (e) {
40
+ logBridgeError('walkToProjectRoot', e); /* unreadable dir — treat as absent, keep walking */
41
+ return false;
42
+ }
43
+ }
44
+ /** o-16 revision 1 (reviewer MAJOR 1, measured not argued): the anchor used
45
+ * to be trusted unconditionally. Two proven harms: (a) a non-existent path
46
+ * (a typo) was adopted as-is, and `projectDataDir()` hashed it into a
47
+ * fresh, empty store directory — the exact split-store failure this item
48
+ * exists to eliminate, reintroduced by the escape hatch meant to fix it.
49
+ * (b) `MONOMIND_PROJECT_ROOT=/` disabled `getDbPath`'s MCP path-traversal
50
+ * guard entirely: the guard is `path.relative(getProjectRoot(), resolved)`
51
+ * not starting with `..`, and `path.relative('/', anything)` never does.
52
+ * `existsSync` + `isDirectory` alone catch (a) but NOT (b) — `/` exists and
53
+ * is a directory — so the filesystem-root check below is what closes (b)
54
+ * specifically; it is not redundant with the others. An invalid anchor is
55
+ * never silently accepted OR silently dropped: the caller falls through to
56
+ * the ordinary walk, and the fact that an anchor was set and rejected is
57
+ * preserved on the result (`invalidAnchor`) so `doctor` can say exactly
58
+ * what happened instead of the user just seeing an unexplained directory. */
59
+ function validateAnchor(raw) {
60
+ if (!path.isAbsolute(raw))
61
+ return { ok: false, problem: 'not an absolute path' };
62
+ const lexical = path.resolve(raw);
63
+ // o-16 revision 2 (reviewer MAJOR): resolve symlinks BEFORE validating,
64
+ // and return the REAL path, not the lexical one. Without this, a symlink
65
+ // whose real target is '/' (e.g. MONOMIND_PROJECT_ROOT=<tmp>/link-to-root)
66
+ // passes every check below on its lexical form — dirname(lexical) !==
67
+ // lexical, since the link itself sits inside a normal directory — while
68
+ // getDbPath's traversal guard (memory-bridge-paths.ts's realOrResolved(), i.e.
69
+ // fs.realpathSync) resolves the SAME anchor to '/' downstream. Two
70
+ // notions of "the root" in one module: the store gets hashed from the
71
+ // lexical path this function returned, the guard's boundary is computed
72
+ // from the real one, and path.relative('/', anything) never starts with
73
+ // '..' — the exact guard-disabling hole this function exists to close,
74
+ // reopened one indirection away. Validating and returning the SAME (real)
75
+ // path is what makes validation and consumption agree, for any
76
+ // symlinked anchor, not just a literal '/'.
77
+ let real;
78
+ try {
79
+ real = fs.realpathSync(lexical);
80
+ }
81
+ catch {
82
+ return { ok: false, problem: 'does not exist' };
83
+ }
84
+ let stat;
85
+ try {
86
+ stat = fs.statSync(real);
87
+ }
88
+ catch {
89
+ return { ok: false, problem: 'does not exist' };
90
+ }
91
+ if (!stat.isDirectory())
92
+ return { ok: false, problem: 'is not a directory' };
93
+ if (path.dirname(real) === real) {
94
+ return {
95
+ ok: false,
96
+ problem: 'is the filesystem root, which would disable the MCP path-traversal guard',
97
+ };
98
+ }
99
+ return { ok: true, resolved: real };
100
+ }
101
+ function walkToProjectRoot(start) {
102
+ // Explicit escape hatch: honored ahead of any walk, but only once valid —
103
+ // see validateAnchor's comment for why unconditional trust was wrong.
104
+ const anchorRaw = process.env.MONOMIND_PROJECT_ROOT;
105
+ let invalidAnchor;
106
+ if (anchorRaw) {
107
+ const check = validateAnchor(anchorRaw);
108
+ if (check.ok)
109
+ return { root: check.resolved, reason: 'explicit-anchor' };
110
+ invalidAnchor = { value: anchorRaw, problem: check.problem };
111
+ logBridgeError('walkToProjectRoot', new Error(`MONOMIND_PROJECT_ROOT ignored: "${anchorRaw}" ${check.problem} — falling back to the walk`));
112
+ }
113
+ // Retained from before o-16: protects the dotfiles-repo-at-$HOME case (a
114
+ // `.git` at $HOME must not swallow every loose project underneath it).
115
+ // Insufficient ALONE against the reported incident — that marker sat
116
+ // *inside* $HOME, so the walk reached it long before ever reaching home —
117
+ // which is why it is additive to, not a replacement for, the rule below.
118
+ const home = path.resolve(os.homedir());
119
+ let dir = start;
120
+ let ignoredBareMonomind;
121
+ let atStart = true;
122
+ for (;;) {
123
+ if (dir === home)
124
+ break;
125
+ if (markerExists(path.join(dir, '.git')))
126
+ return { root: dir, reason: 'git', invalidAnchor };
127
+ if (markerExists(path.join(dir, '.monomind'))) {
128
+ if (atStart)
129
+ return { root: dir, reason: 'monomind-at-start', invalidAnchor };
130
+ const corroborated = INDEPENDENT_PROJECT_MARKERS.some((m) => markerExists(path.join(dir, m)));
131
+ if (corroborated)
132
+ return { root: dir, reason: 'monomind-with-marker', invalidAnchor };
133
+ // The nearest marker found doesn't qualify — stop HERE. Continuing
134
+ // past it to adopt some more distant, unrelated ancestor's `.git`
135
+ // would break "nested projects keep their own brain" in a new way:
136
+ // a vendored sub-repo with only a bare `.monomind` would get silently
137
+ // merged into whatever repo happens to sit further up, which the
138
+ // original nearest-marker-wins design specifically existed to
139
+ // prevent. Not adopting is the fallback; walking past is not.
140
+ ignoredBareMonomind = dir;
141
+ break;
142
+ }
143
+ atStart = false;
144
+ const parent = path.dirname(dir);
145
+ if (parent === dir)
146
+ break;
147
+ dir = parent;
148
+ }
149
+ if (ignoredBareMonomind !== undefined) {
150
+ logBridgeError('walkToProjectRoot', new Error(`bare .monomind ancestor ignored at ${ignoredBareMonomind} (no independent project marker) — using ${start}`));
151
+ }
152
+ return { root: start, reason: 'start-fallback', ignoredBareMonomind, invalidAnchor };
153
+ }
154
+ // getBackend() resolves the store path on every store/search, so a bulk ingest
155
+ // would otherwise repeat the stat walk thousands of times. A project does not
156
+ // gain or lose its markers mid-process; the key is the starting directory, so a
157
+ // chdir still re-resolves.
158
+ let _rootCacheKey;
159
+ let _rootCacheVal;
160
+ /** The full resolution — root, reason and (when the walk found nothing
161
+ * adoptable) which bare `.monomind` ancestor it ignored. `doctor` uses this
162
+ * to disclose which directory a user's brain is keyed to and why, instead
163
+ * of a plausible-but-silent path (o-16). See `getProjectRoot` for the
164
+ * string-only form the other ~28 call sites use. */
165
+ export function getProjectRootResolution(from = process.env.MONOMIND_CWD || process.cwd()) {
166
+ const start = path.resolve(from);
167
+ // Cache key must cover everything walkToProjectRoot's result depends on,
168
+ // not just `start` — MONOMIND_PROJECT_ROOT short-circuits the walk (o-16),
169
+ // so a cache keyed on `start` alone would replay a stale pre-anchor (or
170
+ // stale different-anchor) result for the same cwd once the env var changes
171
+ // mid-process, silently defeating the escape hatch it's supposed to be.
172
+ const cacheKey = `${start}\n${process.env.MONOMIND_PROJECT_ROOT ?? ''}`;
173
+ if (cacheKey === _rootCacheKey && _rootCacheVal !== undefined)
174
+ return _rootCacheVal;
175
+ const resolved = walkToProjectRoot(start);
176
+ _rootCacheKey = cacheKey;
177
+ _rootCacheVal = resolved;
178
+ return resolved;
179
+ }
180
+ /** The directory that identifies "this project" for every Second Brain store.
181
+ *
182
+ * Deliberately NOT the raw cwd: keying on cwd forked the brain per directory —
183
+ * `doc ingest ./docs` from a package subdir wrote to a different store, and a
184
+ * different metadata file, than the identical command at the repo root, and
185
+ * neither could see the other. We walk up to the nearest ancestor carrying a
186
+ * `.git` marker (any depth), or a `.monomind` marker corroborated by an
187
+ * independent project marker, so every directory inside one project resolves
188
+ * to one brain. Nested projects still win (the walk stops at the FIRST
189
+ * eligible marker), which keeps worktrees and vendored sub-repos independent.
190
+ *
191
+ * o-16: a BARE `.monomind` ancestor (no `.git`, no manifest) is NOT adopted.
192
+ * `.monomind` is created by monomind itself as a side effect of running
193
+ * anywhere — it is not independent evidence of a project, and a wrong
194
+ * resolution creates the very marker that would capture every future
195
+ * descendant if it were trusted alone. See `walkToProjectRoot`'s comment for
196
+ * the measured incident this fixes. The starting directory's OWN `.monomind`
197
+ * is still trusted unconditionally — that is the user pointing at their own
198
+ * project — and `.git` at any depth is untouched, so CI/devcontainer repos
199
+ * and subdirectory unification behave exactly as before.
200
+ *
201
+ * The walk never crosses the home directory: a dotfiles repo at `~` would
202
+ * otherwise swallow every loose project underneath it into one shared brain.
203
+ * `MONOMIND_PROJECT_ROOT`, if set AND VALID (absolute, exists, is a
204
+ * directory, is not itself the filesystem root — see `validateAnchor`), is
205
+ * an explicit anchor that skips the walk entirely — the escape hatch for
206
+ * the genuinely ambiguous case (design decision 4 / AC-3c: a real, non-git
207
+ * project whose root has a bare `.monomind` and no manifest has no other
208
+ * way to be found from a subdirectory). An invalid anchor falls through to
209
+ * the walk rather than being adopted OR silently dropped — see
210
+ * `ProjectRootResolution.invalidAnchor`.
211
+ *
212
+ * This is `MONOMIND_PROJECT_ROOT`'s SECOND consumer in this codebase —
213
+ * `mcp-tools/guidance-tools.ts:findProjectRoot()` already reads the same
214
+ * env var, for a DIFFERENT marker (`.claude`, not `.monomind`/`.git`), with
215
+ * a stricter rule: `if (envRoot && existsSync(join(envRoot, '.claude')))`,
216
+ * i.e. it only honors the anchor when `.claude` exists there, silently
217
+ * falling through to its own walk otherwise. After this revision the two
218
+ * converge on ANCHOR HANDLING for the cases that matter most — a typo'd or
219
+ * missing path is rejected by both (this one via `validateAnchor`,
220
+ * guidance-tools' because `.claude` is absent) — but "converge" describes
221
+ * only whether each accepts or rejects the anchor, not the final resolved
222
+ * root: a rejected anchor falls through to each resolver's OWN walk
223
+ * (`walkToProjectRoot` here; guidance-tools' own Strategy 1/2/3 chain
224
+ * there), which can still land on different directories for the same
225
+ * unanchored cwd. Two residual disagreements remain, both legitimate rather
226
+ * than oversights:
227
+ * 1. An anchor that exists and is a real directory but has no `.claude` in
228
+ * it: this function honors it (memory has no reason to require a
229
+ * `.claude` folder — a project's knowledge store isn't gated on whether
230
+ * an agent config lives there), guidance-tools does not (`.claude` is
231
+ * the one thing it's searching FOR, so its absence is a real signal, not
232
+ * noise, for that consumer specifically).
233
+ * 2. A RELATIVE anchor: `validateAnchor` rejects it outright (an anchor
234
+ * that silently depends on cwd defeats the point of an anchor).
235
+ * guidance-tools has no absolute-path check, so `existsSync(join(envRoot,
236
+ * '.claude'))` would resolve a relative `envRoot` against cwd and could
237
+ * accept it — narrower in practice (needs a `.claude` at that resolved
238
+ * location too) but a real gap in the two resolvers' shared assumptions.
239
+ * Reconciling the two resolvers' semantics into one shared rule is a
240
+ * separate, larger question (tracked as o-32), not something this fix
241
+ * should decide as a side effect.
242
+ *
243
+ * For anyone who already ran from the project root — the normal case — the
244
+ * resolved path is identical to before, so their store does not move.
245
+ *
246
+ * `MONOMIND_CWD` wins over the real cwd, matching `getProjectCwd()` in
247
+ * mcp-tools/types.ts — an MCP server is launched with whatever cwd the client
248
+ * chose, and that env var is already how monograph and swarm state learn which
249
+ * project they belong to. Inlined rather than imported to keep this module on
250
+ * node builtins only (see the static import in document-pipeline.ts).
251
+ */
252
+ export function getProjectRoot(from = process.env.MONOMIND_CWD || process.cwd()) {
253
+ return getProjectRootResolution(from).root;
254
+ }
255
+ export function projectDataDir() {
256
+ const resolved = path.resolve(getProjectRoot());
257
+ const hash = crypto.createHash('sha256').update(resolved).digest('hex').slice(0, 16);
258
+ const readable = path
259
+ .basename(resolved)
260
+ .replace(/[^a-zA-Z0-9._-]+/g, '-')
261
+ .slice(0, 40) || 'project';
262
+ return path.join(os.homedir(), '.monomind', 'projects', `${readable}-${hash}`);
263
+ }
264
+ /** Resolve symlinks so the traversal check below can't be bypassed by a link
265
+ * that lexically resolves inside the allowed trees but points outside them. */
266
+ function realOrResolved(p) {
267
+ try {
268
+ return fs.realpathSync(p);
269
+ }
270
+ catch (e) {
271
+ logBridgeError('realOrResolved', e);
272
+ return p;
273
+ }
274
+ }
275
+ /** The personal, cross-project knowledge store. Deliberately a SIBLING of
276
+ * ~/.monomind/projects (never inside it) so per-project pruning heuristics
277
+ * (`cleanup --data`) can never touch it. Env-overridable for tests and for
278
+ * users who keep their brain on a synced/external location. Resolved lazily
279
+ * so the override works regardless of import order. */
280
+ export function getGlobalBrainDir() {
281
+ return (process.env.MONOMIND_GLOBAL_BRAIN_DIR || path.join(os.homedir(), '.monomind', 'global-brain'));
282
+ }
283
+ /** Sentinel callers pass as dbPath to address the global brain. */
284
+ export const GLOBAL_BRAIN = '@global';
285
+ export function getDbPath(customPath) {
286
+ const defaultDir = path.join(projectDataDir(), 'lancedb');
287
+ if (!customPath || customPath === ':memory:')
288
+ return defaultDir;
289
+ if (customPath === GLOBAL_BRAIN)
290
+ return getGlobalBrainDir();
291
+ // Treat legacy .db paths (and the legacy .swarm dir) as a signal to use the default
292
+ if (customPath.endsWith('.db'))
293
+ return defaultDir;
294
+ const resolved = realOrResolved(path.resolve(customPath));
295
+ // Guard against path traversal from MCP inputs: only allow paths inside the
296
+ // project, the per-project home data dir, or the global brain.
297
+ //
298
+ // STATED LIMIT (o-16 revision 2, corrected in revision 3 — verifier found
299
+ // the first version of this comment named the wrong path): `validateAnchor`
300
+ // resolves a `MONOMIND_PROJECT_ROOT` anchor to its REAL path ONCE via
301
+ // `fs.realpathSync`, and caches THAT REAL PATH STRING in `_rootCacheVal`
302
+ // (see above) — `getProjectRoot()` returns this cached real-path string on
303
+ // every subsequent call in this process; it does not re-read the anchor
304
+ // or re-run `validateAnchor`. So swapping the filesystem entry AT THE
305
+ // ANCHOR PATH after validation does nothing — the anchor itself is never
306
+ // consulted again. The actual gap is one level further in: the line below
307
+ // calls `realOrResolved()` (a fresh `fs.realpathSync`) on that cached
308
+ // REAL-PATH STRING every time `getDbPath` runs. If the filesystem entry
309
+ // AT THAT RESOLVED TARGET (not the anchor) is swapped for a symlink to
310
+ // `/` after validation but before a later call here, this re-resolves to
311
+ // the new real target live, and the guard is bypassed for that call — a
312
+ // TOCTOU gap between a one-time resolution and a re-resolved-every-call
313
+ // consumption of the same path string. NOT defended against: closing it
314
+ // properly means validating and consuming a single resolved handle rather
315
+ // than a path string, which is a real design change and out of scope for
316
+ // this fix. Accepted because it needs filesystem write access at the
317
+ // resolved target's path, timed against a live process — an attacker
318
+ // with that capability already has easier routes than this guard.
319
+ const relCwd = path.relative(realOrResolved(getProjectRoot()), resolved);
320
+ const relHome = path.relative(realOrResolved(projectDataDir()), resolved);
321
+ const relGlobal = path.relative(realOrResolved(getGlobalBrainDir()), resolved);
322
+ if (!relCwd.startsWith('..') && !path.isAbsolute(relCwd))
323
+ return resolved;
324
+ if (!relHome.startsWith('..') && !path.isAbsolute(relHome))
325
+ return resolved;
326
+ if (!relGlobal.startsWith('..') && !path.isAbsolute(relGlobal))
327
+ return resolved;
328
+ return defaultDir;
329
+ }
330
+ /** Resolve the real on-disk SQLite data-dir path for a given custom path (or the
331
+ * default) — the dir is still named `lancedb` for legacy path back-compat. */
332
+ export function bridgeGetDbPath(customPath) {
333
+ return getDbPath(customPath);
334
+ }
335
+ //# sourceMappingURL=memory-bridge-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-bridge-paths.js","sourceRoot":"","sources":["../../../src/memory/memory-bridge-paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Memory Bridge — the read/search path: bridgeSearchEntries (semantic +
3
+ * FTS5/BM25 keyword merge, stale and superseded-knowledge filtering,
4
+ * cross-encoder reranking). Split out of memory-bridge.ts, which re-exports
5
+ * it.
6
+ */
7
+ export declare function bridgeSearchEntries(options: {
8
+ query: string;
9
+ namespace?: string;
10
+ limit?: number;
11
+ threshold?: number;
12
+ dbPath?: string;
13
+ /** Skip cross-encoder reranking even if the model is loaded. */
14
+ skipRerank?: boolean;
15
+ /** When true, superseded knowledge chunks are kept in the results
16
+ * (flagged by the caller). Default false — removed documents are
17
+ * filtered out for security. */
18
+ includeSuperseded?: boolean;
19
+ /** Project root to read document metadata from for the knowledge-superseded
20
+ * check (default: getProjectRoot(), i.e. process.cwd()-derived). Callers
21
+ * operating on an explicit project directory that differs from cwd — e.g.
22
+ * searchKnowledge({ rootDir }) — must pass the SAME root here, or every
23
+ * freshly-ingested doc in that directory reads as superseded (its content
24
+ * hash won't be found in metadata read from the wrong place) and gets
25
+ * filtered out despite matching the query. */
26
+ rootDir?: string;
27
+ }): Promise<{
28
+ success: boolean;
29
+ results: {
30
+ id: string;
31
+ key: string;
32
+ content: string;
33
+ score: number;
34
+ namespace: string;
35
+ provenance?: string;
36
+ tags?: string[];
37
+ }[];
38
+ searchTime: number;
39
+ /** What actually ran, never what was requested. 'keyword-fallback' means the
40
+ * vector path was attempted and did not produce the results. */
41
+ searchMethod?: 'semantic' | 'keyword' | 'keyword-fallback';
42
+ /** Whether a cross-encoder reranker was applied to the final results. */
43
+ reranked?: boolean;
44
+ /** Why the vector path did not serve these results (absent when it did). */
45
+ fallbackReason?: 'no-embedding-model' | 'empty-query' | 'embedding-failed' | 'no-semantic-matches';
46
+ error?: string;
47
+ } | null>;
48
+ //# sourceMappingURL=memory-bridge-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-bridge-search.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-bridge-search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;qCAEiC;IACjC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;mDAM+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,EAAE,CAAC;IACJ,UAAU,EAAE,MAAM,CAAC;IACnB;qEACiE;IACjE,YAAY,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,kBAAkB,CAAC;IAC3D,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,cAAc,CAAC,EACX,oBAAoB,GACpB,aAAa,GACb,kBAAkB,GAClB,qBAAqB,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAAC,CAoZR"}