@andre.li/memoark 0.3.1

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 (441) hide show
  1. package/LICENSE +191 -0
  2. package/README.en.md +606 -0
  3. package/README.md +560 -0
  4. package/bin/memoark.mjs +36 -0
  5. package/dist/adapters/file.d.ts +19 -0
  6. package/dist/adapters/file.d.ts.map +1 -0
  7. package/dist/adapters/file.js +61 -0
  8. package/dist/adapters/file.js.map +1 -0
  9. package/dist/adapters/gbrain.d.ts +29 -0
  10. package/dist/adapters/gbrain.d.ts.map +1 -0
  11. package/dist/adapters/gbrain.js +622 -0
  12. package/dist/adapters/gbrain.js.map +1 -0
  13. package/dist/adapters/index.d.ts +6 -0
  14. package/dist/adapters/index.d.ts.map +1 -0
  15. package/dist/adapters/index.js +5 -0
  16. package/dist/adapters/index.js.map +1 -0
  17. package/dist/adapters/registry.d.ts +18 -0
  18. package/dist/adapters/registry.d.ts.map +1 -0
  19. package/dist/adapters/registry.js +18 -0
  20. package/dist/adapters/registry.js.map +1 -0
  21. package/dist/adapters/stdout.d.ts +12 -0
  22. package/dist/adapters/stdout.d.ts.map +1 -0
  23. package/dist/adapters/stdout.js +29 -0
  24. package/dist/adapters/stdout.js.map +1 -0
  25. package/dist/adapters/store.d.ts +47 -0
  26. package/dist/adapters/store.d.ts.map +1 -0
  27. package/dist/adapters/store.js +641 -0
  28. package/dist/adapters/store.js.map +1 -0
  29. package/dist/cli.d.ts +2 -0
  30. package/dist/cli.d.ts.map +1 -0
  31. package/dist/cli.js +694 -0
  32. package/dist/cli.js.map +1 -0
  33. package/dist/collectors/agent/claude-code.d.ts +12 -0
  34. package/dist/collectors/agent/claude-code.d.ts.map +1 -0
  35. package/dist/collectors/agent/claude-code.js +94 -0
  36. package/dist/collectors/agent/claude-code.js.map +1 -0
  37. package/dist/collectors/agent/codex.d.ts +16 -0
  38. package/dist/collectors/agent/codex.d.ts.map +1 -0
  39. package/dist/collectors/agent/codex.js +149 -0
  40. package/dist/collectors/agent/codex.js.map +1 -0
  41. package/dist/collectors/agent/collector.d.ts +20 -0
  42. package/dist/collectors/agent/collector.d.ts.map +1 -0
  43. package/dist/collectors/agent/collector.js +108 -0
  44. package/dist/collectors/agent/collector.js.map +1 -0
  45. package/dist/collectors/agent/hermes.d.ts +13 -0
  46. package/dist/collectors/agent/hermes.d.ts.map +1 -0
  47. package/dist/collectors/agent/hermes.js +90 -0
  48. package/dist/collectors/agent/hermes.js.map +1 -0
  49. package/dist/collectors/agent/index.d.ts +6 -0
  50. package/dist/collectors/agent/index.d.ts.map +1 -0
  51. package/dist/collectors/agent/index.js +5 -0
  52. package/dist/collectors/agent/index.js.map +1 -0
  53. package/dist/collectors/agent/types.d.ts +61 -0
  54. package/dist/collectors/agent/types.d.ts.map +1 -0
  55. package/dist/collectors/agent/types.js +6 -0
  56. package/dist/collectors/agent/types.js.map +1 -0
  57. package/dist/collectors/feishu/auth.d.ts +13 -0
  58. package/dist/collectors/feishu/auth.d.ts.map +1 -0
  59. package/dist/collectors/feishu/auth.js +72 -0
  60. package/dist/collectors/feishu/auth.js.map +1 -0
  61. package/dist/collectors/feishu/collector.d.ts +23 -0
  62. package/dist/collectors/feishu/collector.d.ts.map +1 -0
  63. package/dist/collectors/feishu/collector.js +113 -0
  64. package/dist/collectors/feishu/collector.js.map +1 -0
  65. package/dist/collectors/feishu/cursor-staging.d.ts +11 -0
  66. package/dist/collectors/feishu/cursor-staging.d.ts.map +1 -0
  67. package/dist/collectors/feishu/cursor-staging.js +37 -0
  68. package/dist/collectors/feishu/cursor-staging.js.map +1 -0
  69. package/dist/collectors/feishu/http-client.d.ts +26 -0
  70. package/dist/collectors/feishu/http-client.d.ts.map +1 -0
  71. package/dist/collectors/feishu/http-client.js +94 -0
  72. package/dist/collectors/feishu/http-client.js.map +1 -0
  73. package/dist/collectors/feishu/index.d.ts +3 -0
  74. package/dist/collectors/feishu/index.d.ts.map +1 -0
  75. package/dist/collectors/feishu/index.js +2 -0
  76. package/dist/collectors/feishu/index.js.map +1 -0
  77. package/dist/collectors/feishu/lark-cli-client.d.ts +16 -0
  78. package/dist/collectors/feishu/lark-cli-client.d.ts.map +1 -0
  79. package/dist/collectors/feishu/lark-cli-client.js +69 -0
  80. package/dist/collectors/feishu/lark-cli-client.js.map +1 -0
  81. package/dist/collectors/feishu/rate-limiter.d.ts +10 -0
  82. package/dist/collectors/feishu/rate-limiter.d.ts.map +1 -0
  83. package/dist/collectors/feishu/rate-limiter.js +33 -0
  84. package/dist/collectors/feishu/rate-limiter.js.map +1 -0
  85. package/dist/collectors/feishu/sources/base.d.ts +9 -0
  86. package/dist/collectors/feishu/sources/base.d.ts.map +1 -0
  87. package/dist/collectors/feishu/sources/base.js +2 -0
  88. package/dist/collectors/feishu/sources/base.js.map +1 -0
  89. package/dist/collectors/feishu/sources/calendar.d.ts +16 -0
  90. package/dist/collectors/feishu/sources/calendar.d.ts.map +1 -0
  91. package/dist/collectors/feishu/sources/calendar.js +93 -0
  92. package/dist/collectors/feishu/sources/calendar.js.map +1 -0
  93. package/dist/collectors/feishu/sources/dm.d.ts +28 -0
  94. package/dist/collectors/feishu/sources/dm.d.ts.map +1 -0
  95. package/dist/collectors/feishu/sources/dm.js +152 -0
  96. package/dist/collectors/feishu/sources/dm.js.map +1 -0
  97. package/dist/collectors/feishu/sources/docs.d.ts +23 -0
  98. package/dist/collectors/feishu/sources/docs.d.ts.map +1 -0
  99. package/dist/collectors/feishu/sources/docs.js +154 -0
  100. package/dist/collectors/feishu/sources/docs.js.map +1 -0
  101. package/dist/collectors/feishu/sources/mail.d.ts +27 -0
  102. package/dist/collectors/feishu/sources/mail.d.ts.map +1 -0
  103. package/dist/collectors/feishu/sources/mail.js +136 -0
  104. package/dist/collectors/feishu/sources/mail.js.map +1 -0
  105. package/dist/collectors/feishu/sources/message-search.d.ts +37 -0
  106. package/dist/collectors/feishu/sources/message-search.d.ts.map +1 -0
  107. package/dist/collectors/feishu/sources/message-search.js +140 -0
  108. package/dist/collectors/feishu/sources/message-search.js.map +1 -0
  109. package/dist/collectors/feishu/sources/messages.d.ts +26 -0
  110. package/dist/collectors/feishu/sources/messages.d.ts.map +1 -0
  111. package/dist/collectors/feishu/sources/messages.js +148 -0
  112. package/dist/collectors/feishu/sources/messages.js.map +1 -0
  113. package/dist/collectors/feishu/sources/tasks.d.ts +15 -0
  114. package/dist/collectors/feishu/sources/tasks.d.ts.map +1 -0
  115. package/dist/collectors/feishu/sources/tasks.js +74 -0
  116. package/dist/collectors/feishu/sources/tasks.js.map +1 -0
  117. package/dist/collectors/feishu/types.d.ts +224 -0
  118. package/dist/collectors/feishu/types.d.ts.map +1 -0
  119. package/dist/collectors/feishu/types.js +17 -0
  120. package/dist/collectors/feishu/types.js.map +1 -0
  121. package/dist/collectors/index.d.ts +10 -0
  122. package/dist/collectors/index.d.ts.map +1 -0
  123. package/dist/collectors/index.js +18 -0
  124. package/dist/collectors/index.js.map +1 -0
  125. package/dist/config-center/connection-checks.d.ts +28 -0
  126. package/dist/config-center/connection-checks.d.ts.map +1 -0
  127. package/dist/config-center/connection-checks.js +114 -0
  128. package/dist/config-center/connection-checks.js.map +1 -0
  129. package/dist/config-center/document.d.ts +21 -0
  130. package/dist/config-center/document.d.ts.map +1 -0
  131. package/dist/config-center/document.js +93 -0
  132. package/dist/config-center/document.js.map +1 -0
  133. package/dist/config-center/index.d.ts +9 -0
  134. package/dist/config-center/index.d.ts.map +1 -0
  135. package/dist/config-center/index.js +29 -0
  136. package/dist/config-center/index.js.map +1 -0
  137. package/dist/config-center/recommendations.d.ts +16 -0
  138. package/dist/config-center/recommendations.d.ts.map +1 -0
  139. package/dist/config-center/recommendations.js +50 -0
  140. package/dist/config-center/recommendations.js.map +1 -0
  141. package/dist/config-center/reducer.d.ts +57 -0
  142. package/dist/config-center/reducer.d.ts.map +1 -0
  143. package/dist/config-center/reducer.js +192 -0
  144. package/dist/config-center/reducer.js.map +1 -0
  145. package/dist/config-center/schema.d.ts +31 -0
  146. package/dist/config-center/schema.d.ts.map +1 -0
  147. package/dist/config-center/schema.js +365 -0
  148. package/dist/config-center/schema.js.map +1 -0
  149. package/dist/config-center/secrets.d.ts +4 -0
  150. package/dist/config-center/secrets.d.ts.map +1 -0
  151. package/dist/config-center/secrets.js +27 -0
  152. package/dist/config-center/secrets.js.map +1 -0
  153. package/dist/config-center/source-dirs.d.ts +16 -0
  154. package/dist/config-center/source-dirs.d.ts.map +1 -0
  155. package/dist/config-center/source-dirs.js +81 -0
  156. package/dist/config-center/source-dirs.js.map +1 -0
  157. package/dist/config-center/tui/app.d.ts +22 -0
  158. package/dist/config-center/tui/app.d.ts.map +1 -0
  159. package/dist/config-center/tui/app.js +142 -0
  160. package/dist/config-center/tui/app.js.map +1 -0
  161. package/dist/config-center/tui/render.d.ts +20 -0
  162. package/dist/config-center/tui/render.d.ts.map +1 -0
  163. package/dist/config-center/tui/render.js +166 -0
  164. package/dist/config-center/tui/render.js.map +1 -0
  165. package/dist/config-center/validation.d.ts +9 -0
  166. package/dist/config-center/validation.d.ts.map +1 -0
  167. package/dist/config-center/validation.js +59 -0
  168. package/dist/config-center/validation.js.map +1 -0
  169. package/dist/consolidator/consolidator.d.ts +31 -0
  170. package/dist/consolidator/consolidator.d.ts.map +1 -0
  171. package/dist/consolidator/consolidator.js +57 -0
  172. package/dist/consolidator/consolidator.js.map +1 -0
  173. package/dist/consolidator/dead-link.d.ts +7 -0
  174. package/dist/consolidator/dead-link.d.ts.map +1 -0
  175. package/dist/consolidator/dead-link.js +57 -0
  176. package/dist/consolidator/dead-link.js.map +1 -0
  177. package/dist/consolidator/hot-warm.d.ts +9 -0
  178. package/dist/consolidator/hot-warm.d.ts.map +1 -0
  179. package/dist/consolidator/hot-warm.js +88 -0
  180. package/dist/consolidator/hot-warm.js.map +1 -0
  181. package/dist/consolidator/infer-preferences.d.ts +14 -0
  182. package/dist/consolidator/infer-preferences.d.ts.map +1 -0
  183. package/dist/consolidator/infer-preferences.js +73 -0
  184. package/dist/consolidator/infer-preferences.js.map +1 -0
  185. package/dist/consolidator/rules.d.ts +5 -0
  186. package/dist/consolidator/rules.d.ts.map +1 -0
  187. package/dist/consolidator/rules.js +53 -0
  188. package/dist/consolidator/rules.js.map +1 -0
  189. package/dist/consolidator/warm-cold.d.ts +13 -0
  190. package/dist/consolidator/warm-cold.d.ts.map +1 -0
  191. package/dist/consolidator/warm-cold.js +91 -0
  192. package/dist/consolidator/warm-cold.js.map +1 -0
  193. package/dist/core/block-builder.d.ts +15 -0
  194. package/dist/core/block-builder.d.ts.map +1 -0
  195. package/dist/core/block-builder.js +185 -0
  196. package/dist/core/block-builder.js.map +1 -0
  197. package/dist/core/canonicalize.d.ts +3 -0
  198. package/dist/core/canonicalize.d.ts.map +1 -0
  199. package/dist/core/canonicalize.js +137 -0
  200. package/dist/core/canonicalize.js.map +1 -0
  201. package/dist/core/concurrency.d.ts +2 -0
  202. package/dist/core/concurrency.d.ts.map +1 -0
  203. package/dist/core/concurrency.js +14 -0
  204. package/dist/core/concurrency.js.map +1 -0
  205. package/dist/core/config.d.ts +184 -0
  206. package/dist/core/config.d.ts.map +1 -0
  207. package/dist/core/config.js +136 -0
  208. package/dist/core/config.js.map +1 -0
  209. package/dist/core/cursors.d.ts +36 -0
  210. package/dist/core/cursors.d.ts.map +1 -0
  211. package/dist/core/cursors.js +90 -0
  212. package/dist/core/cursors.js.map +1 -0
  213. package/dist/core/dedup.d.ts +45 -0
  214. package/dist/core/dedup.d.ts.map +1 -0
  215. package/dist/core/dedup.js +111 -0
  216. package/dist/core/dedup.js.map +1 -0
  217. package/dist/core/entity-extract.d.ts +3 -0
  218. package/dist/core/entity-extract.d.ts.map +1 -0
  219. package/dist/core/entity-extract.js +54 -0
  220. package/dist/core/entity-extract.js.map +1 -0
  221. package/dist/core/helpers.d.ts +3 -0
  222. package/dist/core/helpers.d.ts.map +1 -0
  223. package/dist/core/helpers.js +10 -0
  224. package/dist/core/helpers.js.map +1 -0
  225. package/dist/core/identity-resolver.d.ts +21 -0
  226. package/dist/core/identity-resolver.d.ts.map +1 -0
  227. package/dist/core/identity-resolver.js +62 -0
  228. package/dist/core/identity-resolver.js.map +1 -0
  229. package/dist/core/pipeline-factory.d.ts +13 -0
  230. package/dist/core/pipeline-factory.d.ts.map +1 -0
  231. package/dist/core/pipeline-factory.js +32 -0
  232. package/dist/core/pipeline-factory.js.map +1 -0
  233. package/dist/core/pipeline.d.ts +61 -0
  234. package/dist/core/pipeline.d.ts.map +1 -0
  235. package/dist/core/pipeline.js +261 -0
  236. package/dist/core/pipeline.js.map +1 -0
  237. package/dist/core/schemas.d.ts +2470 -0
  238. package/dist/core/schemas.d.ts.map +1 -0
  239. package/dist/core/schemas.js +229 -0
  240. package/dist/core/schemas.js.map +1 -0
  241. package/dist/core/signal-scoring.d.ts +3 -0
  242. package/dist/core/signal-scoring.d.ts.map +1 -0
  243. package/dist/core/signal-scoring.js +124 -0
  244. package/dist/core/signal-scoring.js.map +1 -0
  245. package/dist/core/state.d.ts +22 -0
  246. package/dist/core/state.d.ts.map +1 -0
  247. package/dist/core/state.js +32 -0
  248. package/dist/core/state.js.map +1 -0
  249. package/dist/core/types.d.ts +231 -0
  250. package/dist/core/types.d.ts.map +1 -0
  251. package/dist/core/types.js +6 -0
  252. package/dist/core/types.js.map +1 -0
  253. package/dist/daemon/alerts.d.ts +12 -0
  254. package/dist/daemon/alerts.d.ts.map +1 -0
  255. package/dist/daemon/alerts.js +34 -0
  256. package/dist/daemon/alerts.js.map +1 -0
  257. package/dist/daemon/index.d.ts +6 -0
  258. package/dist/daemon/index.d.ts.map +1 -0
  259. package/dist/daemon/index.js +6 -0
  260. package/dist/daemon/index.js.map +1 -0
  261. package/dist/daemon/logger.d.ts +8 -0
  262. package/dist/daemon/logger.d.ts.map +1 -0
  263. package/dist/daemon/logger.js +35 -0
  264. package/dist/daemon/logger.js.map +1 -0
  265. package/dist/daemon/run-history.d.ts +29 -0
  266. package/dist/daemon/run-history.d.ts.map +1 -0
  267. package/dist/daemon/run-history.js +54 -0
  268. package/dist/daemon/run-history.js.map +1 -0
  269. package/dist/daemon/scheduler.d.ts +37 -0
  270. package/dist/daemon/scheduler.d.ts.map +1 -0
  271. package/dist/daemon/scheduler.js +142 -0
  272. package/dist/daemon/scheduler.js.map +1 -0
  273. package/dist/daemon/source-schedule.d.ts +25 -0
  274. package/dist/daemon/source-schedule.d.ts.map +1 -0
  275. package/dist/daemon/source-schedule.js +87 -0
  276. package/dist/daemon/source-schedule.js.map +1 -0
  277. package/dist/embedded-assets.generated.d.ts +4 -0
  278. package/dist/embedded-assets.generated.d.ts.map +1 -0
  279. package/dist/embedded-assets.generated.js +12 -0
  280. package/dist/embedded-assets.generated.js.map +1 -0
  281. package/dist/extractors/noise-filter.d.ts +30 -0
  282. package/dist/extractors/noise-filter.d.ts.map +1 -0
  283. package/dist/extractors/noise-filter.js +185 -0
  284. package/dist/extractors/noise-filter.js.map +1 -0
  285. package/dist/extractors/providers/anthropic.d.ts +13 -0
  286. package/dist/extractors/providers/anthropic.d.ts.map +1 -0
  287. package/dist/extractors/providers/anthropic.js +67 -0
  288. package/dist/extractors/providers/anthropic.js.map +1 -0
  289. package/dist/extractors/providers/index.d.ts +12 -0
  290. package/dist/extractors/providers/index.d.ts.map +1 -0
  291. package/dist/extractors/providers/index.js +41 -0
  292. package/dist/extractors/providers/index.js.map +1 -0
  293. package/dist/extractors/providers/mock.d.ts +14 -0
  294. package/dist/extractors/providers/mock.d.ts.map +1 -0
  295. package/dist/extractors/providers/mock.js +37 -0
  296. package/dist/extractors/providers/mock.js.map +1 -0
  297. package/dist/extractors/providers/openai.d.ts +15 -0
  298. package/dist/extractors/providers/openai.d.ts.map +1 -0
  299. package/dist/extractors/providers/openai.js +109 -0
  300. package/dist/extractors/providers/openai.js.map +1 -0
  301. package/dist/extractors/providers/types.d.ts +27 -0
  302. package/dist/extractors/providers/types.d.ts.map +1 -0
  303. package/dist/extractors/providers/types.js +6 -0
  304. package/dist/extractors/providers/types.js.map +1 -0
  305. package/dist/extractors/signal-extractor.d.ts +29 -0
  306. package/dist/extractors/signal-extractor.d.ts.map +1 -0
  307. package/dist/extractors/signal-extractor.js +279 -0
  308. package/dist/extractors/signal-extractor.js.map +1 -0
  309. package/dist/formatters/index.d.ts +3 -0
  310. package/dist/formatters/index.d.ts.map +1 -0
  311. package/dist/formatters/index.js +3 -0
  312. package/dist/formatters/index.js.map +1 -0
  313. package/dist/formatters/json.d.ts +6 -0
  314. package/dist/formatters/json.d.ts.map +1 -0
  315. package/dist/formatters/json.js +16 -0
  316. package/dist/formatters/json.js.map +1 -0
  317. package/dist/formatters/markdown.d.ts +6 -0
  318. package/dist/formatters/markdown.d.ts.map +1 -0
  319. package/dist/formatters/markdown.js +198 -0
  320. package/dist/formatters/markdown.js.map +1 -0
  321. package/dist/processors/privacy.d.ts +98 -0
  322. package/dist/processors/privacy.d.ts.map +1 -0
  323. package/dist/processors/privacy.js +271 -0
  324. package/dist/processors/privacy.js.map +1 -0
  325. package/dist/server/api.d.ts +35 -0
  326. package/dist/server/api.d.ts.map +1 -0
  327. package/dist/server/api.js +453 -0
  328. package/dist/server/api.js.map +1 -0
  329. package/dist/server/backfill-job.d.ts +36 -0
  330. package/dist/server/backfill-job.d.ts.map +1 -0
  331. package/dist/server/backfill-job.js +88 -0
  332. package/dist/server/backfill-job.js.map +1 -0
  333. package/dist/server/backfill-routes.d.ts +7 -0
  334. package/dist/server/backfill-routes.d.ts.map +1 -0
  335. package/dist/server/backfill-routes.js +123 -0
  336. package/dist/server/backfill-routes.js.map +1 -0
  337. package/dist/server/config-routes.d.ts +8 -0
  338. package/dist/server/config-routes.d.ts.map +1 -0
  339. package/dist/server/config-routes.js +114 -0
  340. package/dist/server/config-routes.js.map +1 -0
  341. package/dist/server/context.d.ts +13 -0
  342. package/dist/server/context.d.ts.map +1 -0
  343. package/dist/server/context.js +47 -0
  344. package/dist/server/context.js.map +1 -0
  345. package/dist/server/entity.d.ts +25 -0
  346. package/dist/server/entity.d.ts.map +1 -0
  347. package/dist/server/entity.js +34 -0
  348. package/dist/server/entity.js.map +1 -0
  349. package/dist/server/event-bus.d.ts +35 -0
  350. package/dist/server/event-bus.d.ts.map +1 -0
  351. package/dist/server/event-bus.js +4 -0
  352. package/dist/server/event-bus.js.map +1 -0
  353. package/dist/server/mcp.d.ts +126 -0
  354. package/dist/server/mcp.d.ts.map +1 -0
  355. package/dist/server/mcp.js +103 -0
  356. package/dist/server/mcp.js.map +1 -0
  357. package/dist/server/setup-server.d.ts +7 -0
  358. package/dist/server/setup-server.d.ts.map +1 -0
  359. package/dist/server/setup-server.js +52 -0
  360. package/dist/server/setup-server.js.map +1 -0
  361. package/dist/setup/assess-hardware.d.ts +34 -0
  362. package/dist/setup/assess-hardware.d.ts.map +1 -0
  363. package/dist/setup/assess-hardware.js +179 -0
  364. package/dist/setup/assess-hardware.js.map +1 -0
  365. package/dist/setup/connection-tests.d.ts +17 -0
  366. package/dist/setup/connection-tests.d.ts.map +1 -0
  367. package/dist/setup/connection-tests.js +67 -0
  368. package/dist/setup/connection-tests.js.map +1 -0
  369. package/dist/setup/detect-api-keys.d.ts +13 -0
  370. package/dist/setup/detect-api-keys.d.ts.map +1 -0
  371. package/dist/setup/detect-api-keys.js +41 -0
  372. package/dist/setup/detect-api-keys.js.map +1 -0
  373. package/dist/setup/detect-runtime.d.ts +14 -0
  374. package/dist/setup/detect-runtime.d.ts.map +1 -0
  375. package/dist/setup/detect-runtime.js +43 -0
  376. package/dist/setup/detect-runtime.js.map +1 -0
  377. package/dist/setup/detect-sources.d.ts +14 -0
  378. package/dist/setup/detect-sources.d.ts.map +1 -0
  379. package/dist/setup/detect-sources.js +75 -0
  380. package/dist/setup/detect-sources.js.map +1 -0
  381. package/dist/setup/generate-config.d.ts +5 -0
  382. package/dist/setup/generate-config.d.ts.map +1 -0
  383. package/dist/setup/generate-config.js +103 -0
  384. package/dist/setup/generate-config.js.map +1 -0
  385. package/dist/setup/index.d.ts +9 -0
  386. package/dist/setup/index.d.ts.map +1 -0
  387. package/dist/setup/index.js +9 -0
  388. package/dist/setup/index.js.map +1 -0
  389. package/dist/setup/init-wizard.d.ts +19 -0
  390. package/dist/setup/init-wizard.d.ts.map +1 -0
  391. package/dist/setup/init-wizard.js +501 -0
  392. package/dist/setup/init-wizard.js.map +1 -0
  393. package/dist/setup/terminal.d.ts +28 -0
  394. package/dist/setup/terminal.d.ts.map +1 -0
  395. package/dist/setup/terminal.js +258 -0
  396. package/dist/setup/terminal.js.map +1 -0
  397. package/dist/setup/validate-config.d.ts +26 -0
  398. package/dist/setup/validate-config.d.ts.map +1 -0
  399. package/dist/setup/validate-config.js +27 -0
  400. package/dist/setup/validate-config.js.map +1 -0
  401. package/dist/store/chunks.d.ts +19 -0
  402. package/dist/store/chunks.d.ts.map +1 -0
  403. package/dist/store/chunks.js +70 -0
  404. package/dist/store/chunks.js.map +1 -0
  405. package/dist/store/database.d.ts +24 -0
  406. package/dist/store/database.d.ts.map +1 -0
  407. package/dist/store/database.js +62 -0
  408. package/dist/store/database.js.map +1 -0
  409. package/dist/store/embedding.d.ts +23 -0
  410. package/dist/store/embedding.d.ts.map +1 -0
  411. package/dist/store/embedding.js +62 -0
  412. package/dist/store/embedding.js.map +1 -0
  413. package/dist/store/graph.d.ts +53 -0
  414. package/dist/store/graph.d.ts.map +1 -0
  415. package/dist/store/graph.js +186 -0
  416. package/dist/store/graph.js.map +1 -0
  417. package/dist/store/migrations/index.d.ts +9 -0
  418. package/dist/store/migrations/index.d.ts.map +1 -0
  419. package/dist/store/migrations/index.js +68 -0
  420. package/dist/store/migrations/index.js.map +1 -0
  421. package/dist/store/pages.d.ts +39 -0
  422. package/dist/store/pages.d.ts.map +1 -0
  423. package/dist/store/pages.js +150 -0
  424. package/dist/store/pages.js.map +1 -0
  425. package/dist/store/search.d.ts +37 -0
  426. package/dist/store/search.d.ts.map +1 -0
  427. package/dist/store/search.js +200 -0
  428. package/dist/store/search.js.map +1 -0
  429. package/dist/store/tags.d.ts +10 -0
  430. package/dist/store/tags.d.ts.map +1 -0
  431. package/dist/store/tags.js +31 -0
  432. package/dist/store/tags.js.map +1 -0
  433. package/dist/store/timeline.d.ts +26 -0
  434. package/dist/store/timeline.d.ts.map +1 -0
  435. package/dist/store/timeline.js +43 -0
  436. package/dist/store/timeline.js.map +1 -0
  437. package/dist/sync/obsidian.d.ts +136 -0
  438. package/dist/sync/obsidian.d.ts.map +1 -0
  439. package/dist/sync/obsidian.js +539 -0
  440. package/dist/sync/obsidian.js.map +1 -0
  441. package/package.json +84 -0
package/dist/cli.js ADDED
@@ -0,0 +1,694 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { resolve } from "node:path";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { Command } from "commander";
7
+ import { createClaudeCodeCollector, createCodexCollector, createFeishuCollector, createHermesCollector, getAllCollectors, getCollector, registerCollector, resetRegistry, } from "./collectors/index.js";
8
+ import { Consolidator } from "./consolidator/consolidator.js";
9
+ import { loadConfig } from "./core/config.js";
10
+ import { runPipeline } from "./core/pipeline.js";
11
+ import { ensureStateDir, statePath } from "./core/state.js";
12
+ import { Scheduler } from "./daemon/scheduler.js";
13
+ import { VERSION } from "./embedded-assets.generated.js";
14
+ import { createLLMProvider, createMockProvider } from "./extractors/providers/index.js";
15
+ import { createApiApp } from "./server/api.js";
16
+ import { createMcpServer } from "./server/mcp.js";
17
+ import { ChunkStore } from "./store/chunks.js";
18
+ import { Database } from "./store/database.js";
19
+ import { EmbeddingService } from "./store/embedding.js";
20
+ import { GraphStore } from "./store/graph.js";
21
+ import { PageStore } from "./store/pages.js";
22
+ import { SearchEngine } from "./store/search.js";
23
+ import { TagStore } from "./store/tags.js";
24
+ import { TimelineStore } from "./store/timeline.js";
25
+ function bootstrapCollectors(sources) {
26
+ resetRegistry();
27
+ const agentConfigs = {
28
+ "claude-code": { factory: createClaudeCodeCollector, config: sources["claude-code"] },
29
+ codex: { factory: createCodexCollector, config: sources.codex },
30
+ hermes: { factory: createHermesCollector, config: sources.hermes },
31
+ };
32
+ for (const [_id, { factory, config }] of Object.entries(agentConfigs)) {
33
+ if (config?.enabled !== false) {
34
+ registerCollector(factory(config?.base_dir));
35
+ }
36
+ }
37
+ if (sources.feishu?.enabled !== false && sources.feishu?.app_id) {
38
+ registerCollector(createFeishuCollector(sources.feishu));
39
+ }
40
+ }
41
+ function expandDataDir(dir) {
42
+ if (dir.startsWith("~/"))
43
+ return resolve(homedir(), dir.slice(2));
44
+ if (dir === "~")
45
+ return homedir();
46
+ return dir;
47
+ }
48
+ async function createStores(config) {
49
+ const dataDir = expandDataDir(config.store.data_dir);
50
+ mkdirSync(dataDir, { recursive: true });
51
+ const db = await Database.create(dataDir, {
52
+ embeddingDimensions: config.embedding.dimensions,
53
+ });
54
+ const pages = new PageStore(db.pg);
55
+ const chunks = new ChunkStore(db.pg);
56
+ const embedding = new EmbeddingService(db.pg, {
57
+ provider: config.embedding.provider,
58
+ model: config.embedding.model,
59
+ dimensions: config.embedding.dimensions,
60
+ apiKey: config.embedding.api_key ?? process.env.OPENAI_API_KEY,
61
+ baseUrl: config.embedding.base_url,
62
+ });
63
+ const search = new SearchEngine(db.pg, { embedText: (q) => embedding.embedText(q) });
64
+ return {
65
+ db,
66
+ pages,
67
+ chunks,
68
+ search,
69
+ graph: new GraphStore(db.pg),
70
+ tags: new TagStore(db.pg),
71
+ timeline: new TimelineStore(db.pg),
72
+ embedding,
73
+ };
74
+ }
75
+ const program = new Command();
76
+ program
77
+ .name("memoark")
78
+ .description("Local-first personal memory extraction and storage")
79
+ .version(VERSION);
80
+ program
81
+ .command("init")
82
+ .description("Interactive setup wizard - generates memoark.yaml")
83
+ .option("--auto", "Automatic mode, no prompts")
84
+ .option("--force", "Overwrite existing configuration")
85
+ .option("-c, --config <path>", "Path to output config file (default: memoark.yaml)")
86
+ .option("--no-tui", "Use non-TUI fallback")
87
+ .option("--web", "Launch browser-based setup UI")
88
+ .action(async (options) => {
89
+ if (options.web) {
90
+ const { startSetupServer } = await import("./server/setup-server.js");
91
+ await startSetupServer({ configPath: options.config });
92
+ return;
93
+ }
94
+ try {
95
+ const { runInit } = await import("./setup/index.js");
96
+ await runInit({
97
+ auto: options.auto,
98
+ force: options.force,
99
+ configPath: options.config,
100
+ tui: options.tui,
101
+ });
102
+ }
103
+ catch (error) {
104
+ console.error(error instanceof Error ? error.message : String(error));
105
+ process.exit(1);
106
+ }
107
+ });
108
+ /**
109
+ * Extract command - main pipeline execution
110
+ */
111
+ program
112
+ .command("extract")
113
+ .description("Extract signals from a platform or source")
114
+ .option("-s, --source <name>", "Source/collector name (e.g., claude-code, codex, hermes, feishu, or 'all' for all enabled sources)", "claude-code")
115
+ .option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
116
+ .option("-f, --format <type>", "Output format (json|markdown)", "json")
117
+ .option("-a, --adapter <type>", "Output adapter (store|file|gbrain|stdout)", "store")
118
+ .option("-o, --output <dir>", "Output directory for file adapter")
119
+ .option("--since <date>", "Only process messages since date (ISO 8601 or relative: 1d, 2h, 30m)")
120
+ .option("--limit <n>", "Limit number of messages to process", undefined)
121
+ .option("--dry-run", "Do not write outputs, only test pipeline")
122
+ .action(async (options) => {
123
+ try {
124
+ // Load configuration
125
+ const config = loadConfig(options.config);
126
+ // Ensure state directory exists
127
+ ensureStateDir();
128
+ // Bootstrap collectors from config
129
+ bootstrapCollectors(config.sources);
130
+ // Determine which sources to process
131
+ let sourceIds;
132
+ if (options.source === "all") {
133
+ sourceIds = getAllCollectors().map((c) => c.id);
134
+ }
135
+ else {
136
+ sourceIds = [options.source];
137
+ }
138
+ // Create LLM provider based on config (shared across all sources)
139
+ let provider;
140
+ if (!options.dryRun) {
141
+ const llmConfig = config.llm;
142
+ const envKey = llmConfig.provider === "anthropic"
143
+ ? process.env.ANTHROPIC_API_KEY
144
+ : process.env.OPENAI_API_KEY;
145
+ if (!llmConfig.api_key && !envKey) {
146
+ const envVarName = llmConfig.provider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
147
+ console.error(`Error: No API key configured. Set api_key in memoark.yaml or ${envVarName} env var.`);
148
+ process.exit(1);
149
+ }
150
+ if (!llmConfig.api_key) {
151
+ llmConfig.api_key = envKey;
152
+ }
153
+ provider = createLLMProvider(llmConfig);
154
+ }
155
+ else {
156
+ provider = createMockProvider(new Map());
157
+ }
158
+ // Build pipeline configuration
159
+ const pipelineConfig = {
160
+ dedup_checkpoint: statePath("dedup.jsonl"),
161
+ cursor_checkpoint: statePath("cursors.yaml"),
162
+ block_gap_minutes: config.block_builder.block_gap_minutes,
163
+ max_block_tokens: config.block_builder.max_block_tokens,
164
+ max_block_messages: config.block_builder.max_block_messages,
165
+ privacy: config.privacy,
166
+ output_dir: options.output || process.cwd(),
167
+ block_concurrency: config.pipeline?.block_concurrency,
168
+ };
169
+ // Parse options
170
+ const format = ["json", "markdown"].includes(options.format) ? options.format : "json";
171
+ const adapter = ["store", "file", "gbrain", "stdout"].includes(options.adapter)
172
+ ? options.adapter
173
+ : "store";
174
+ const limit = options.limit ? parseInt(options.limit, 10) : undefined;
175
+ // Create stores if using store adapter
176
+ let stores;
177
+ if (adapter === "store") {
178
+ stores = await createStores(config);
179
+ }
180
+ // Parse relative since values
181
+ let sinceValue = options.since;
182
+ if (sinceValue) {
183
+ const relMatch = sinceValue.match(/^(\d+)([dhm])$/);
184
+ if (relMatch) {
185
+ const amount = parseInt(relMatch[1], 10);
186
+ const unit = relMatch[2];
187
+ const ms = unit === "d" ? amount * 86400000 : unit === "h" ? amount * 3600000 : amount * 60000;
188
+ sinceValue = new Date(Date.now() - ms).toISOString();
189
+ }
190
+ }
191
+ let anyFailed = false;
192
+ // Process each source
193
+ for (const sourceId of sourceIds) {
194
+ const collector = getCollector(sourceId);
195
+ if (!collector) {
196
+ console.error(`Error: Unknown source '${sourceId}'`);
197
+ anyFailed = true;
198
+ continue;
199
+ }
200
+ // Health check
201
+ const health = await collector.healthCheck();
202
+ if (!health.ok) {
203
+ if (options.source === "all") {
204
+ console.warn(`Warning: ${sourceId} not available — ${health.message}. Skipping.`);
205
+ continue;
206
+ }
207
+ console.error(`Error: ${sourceId} health check failed — ${health.message}`);
208
+ process.exit(1);
209
+ }
210
+ // Run pipeline for this source
211
+ console.log(`\n--- Extracting from: ${sourceId} ---`);
212
+ console.log(`Format: ${format}, Adapter: ${adapter}`);
213
+ if (options.dryRun)
214
+ console.log("DRY-RUN mode enabled");
215
+ if (sinceValue)
216
+ console.log(`Since: ${sinceValue}`);
217
+ if (limit)
218
+ console.log(`Limit: ${limit} messages`);
219
+ console.log("");
220
+ try {
221
+ const result = await runPipeline(pipelineConfig, {
222
+ source: collector,
223
+ provider,
224
+ format: format,
225
+ adapter: adapter,
226
+ stores,
227
+ dryRun: options.dryRun || false,
228
+ since: sinceValue,
229
+ limit,
230
+ });
231
+ // Report results
232
+ console.log("Pipeline execution complete:");
233
+ console.log(` Total messages: ${result.totalMessages}`);
234
+ console.log(` Total blocks: ${result.totalBlocks}`);
235
+ console.log(` OK blocks: ${result.okBlocks}`);
236
+ console.log(` Skipped blocks: ${result.skippedBlocks}`);
237
+ console.log(` Failed blocks: ${result.failedBlocks}`);
238
+ if (result.warnings.length > 0) {
239
+ console.log("\nWarnings:");
240
+ for (const warning of result.warnings) {
241
+ console.log(` - ${warning}`);
242
+ }
243
+ }
244
+ if (result.fatal) {
245
+ console.error(`\nFatal error: ${result.error}`);
246
+ anyFailed = true;
247
+ }
248
+ }
249
+ catch (error) {
250
+ console.error(`\nPipeline failed for ${sourceId}:`, error instanceof Error ? error.message : String(error));
251
+ anyFailed = true;
252
+ }
253
+ }
254
+ // Close stores if they were created
255
+ if (stores) {
256
+ await stores.db.close();
257
+ }
258
+ if (anyFailed) {
259
+ process.exit(1);
260
+ }
261
+ }
262
+ catch (error) {
263
+ console.error("Extract failed:", error instanceof Error ? error.message : String(error));
264
+ process.exit(1);
265
+ }
266
+ });
267
+ /**
268
+ * Doctor command - diagnose configuration and setup
269
+ */
270
+ program
271
+ .command("doctor")
272
+ .description("Diagnose configuration and connectivity")
273
+ .option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
274
+ .action(async (options) => {
275
+ const issues = [];
276
+ const warnings = [];
277
+ const ok = [];
278
+ // Check config file
279
+ const configPath = options.config || resolve(process.cwd(), "memoark.yaml");
280
+ let config = null;
281
+ if (existsSync(configPath)) {
282
+ ok.push(`Configuration file found: ${configPath}`);
283
+ try {
284
+ config = loadConfig(options.config);
285
+ ok.push("Configuration loaded successfully");
286
+ }
287
+ catch (error) {
288
+ issues.push(`Configuration loading failed: ${error instanceof Error ? error.message : String(error)}`);
289
+ }
290
+ }
291
+ else {
292
+ warnings.push(`Configuration file not found: ${configPath}`);
293
+ warnings.push("Create one with: memoark init");
294
+ }
295
+ // Check state directory
296
+ const stateDir = resolve(process.cwd(), ".memoark");
297
+ if (existsSync(stateDir)) {
298
+ ok.push(`State directory exists: ${stateDir}`);
299
+ }
300
+ else {
301
+ warnings.push(`State directory does not exist: ${stateDir}`);
302
+ warnings.push("It will be created automatically on first extract");
303
+ }
304
+ // Check LLM configuration
305
+ if (config) {
306
+ if (config.llm?.provider && config.llm?.model) {
307
+ ok.push(`LLM provider configured: ${config.llm.provider} / ${config.llm.model}`);
308
+ const envKey = config.llm.provider === "anthropic" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
309
+ if (process.env[envKey] || config.llm.api_key) {
310
+ ok.push(`${config.llm.provider} API key configured`);
311
+ }
312
+ else {
313
+ warnings.push(`${envKey} environment variable not set and no api_key in config`);
314
+ warnings.push(`Set ${envKey} or add api_key to llm config`);
315
+ }
316
+ }
317
+ else {
318
+ issues.push("LLM provider or model not configured");
319
+ }
320
+ // Check sources
321
+ bootstrapCollectors(config.sources);
322
+ for (const collector of getAllCollectors()) {
323
+ const health = await collector.healthCheck();
324
+ if (health.ok) {
325
+ ok.push(`Source ${collector.id}: ${health.message}`);
326
+ }
327
+ else {
328
+ warnings.push(`Source ${collector.id}: ${health.message}`);
329
+ }
330
+ }
331
+ }
332
+ // Report results
333
+ console.log("=== Memoark Diagnostic Report ===\n");
334
+ if (ok.length > 0) {
335
+ console.log("✓ OK:");
336
+ for (const msg of ok) {
337
+ console.log(` ${msg}`);
338
+ }
339
+ console.log("");
340
+ }
341
+ if (warnings.length > 0) {
342
+ console.log("⚠ Warnings:");
343
+ for (const msg of warnings) {
344
+ console.log(` ${msg}`);
345
+ }
346
+ console.log("");
347
+ }
348
+ if (issues.length > 0) {
349
+ console.log("✗ Issues:");
350
+ for (const msg of issues) {
351
+ console.log(` ${msg}`);
352
+ }
353
+ console.log("");
354
+ process.exit(1);
355
+ }
356
+ console.log("No critical issues found.");
357
+ });
358
+ /**
359
+ * Config subcommand group
360
+ */
361
+ const configCmd = program.command("config").description("Manage configuration");
362
+ configCmd
363
+ .command("init")
364
+ .description("Generate memoark.yaml (alias for 'memoark init')")
365
+ .option("--auto", "Automatic mode, no prompts")
366
+ .option("--force", "Overwrite existing configuration")
367
+ .option("-c, --config <path>", "Path to output config file (default: memoark.yaml)")
368
+ .option("--no-tui", "Use non-TUI fallback")
369
+ .action(async (options) => {
370
+ try {
371
+ const { runInit } = await import("./setup/index.js");
372
+ await runInit({
373
+ auto: options.auto,
374
+ force: options.force,
375
+ configPath: options.config,
376
+ tui: options.tui,
377
+ });
378
+ }
379
+ catch (error) {
380
+ console.error(error instanceof Error ? error.message : String(error));
381
+ process.exit(1);
382
+ }
383
+ });
384
+ configCmd
385
+ .command("edit")
386
+ .description("Edit configuration in browser UI")
387
+ .option("--web", "Launch browser-based settings UI (default behavior)")
388
+ .action(async () => {
389
+ const { startSetupServer } = await import("./server/setup-server.js");
390
+ await startSetupServer();
391
+ });
392
+ /**
393
+ * Sources subcommand group
394
+ */
395
+ const sourcesCmd = program.command("sources").description("Manage data sources");
396
+ sourcesCmd
397
+ .command("list")
398
+ .description("List available sources")
399
+ .option("-c, --config <path>", "Path to config file")
400
+ .action((options) => {
401
+ const config = loadConfig(options.config);
402
+ bootstrapCollectors(config.sources);
403
+ const collectors = getAllCollectors();
404
+ console.log("Available sources:\n");
405
+ for (const c of collectors) {
406
+ console.log(` ${c.id} ✓ enabled`);
407
+ console.log(` ${c.description}`);
408
+ console.log("");
409
+ }
410
+ });
411
+ sourcesCmd
412
+ .command("test <name>")
413
+ .description("Test source connectivity and health")
414
+ .option("-c, --config <path>", "Path to config file")
415
+ .action(async (name, options) => {
416
+ try {
417
+ const config = loadConfig(options.config);
418
+ bootstrapCollectors(config.sources);
419
+ const collector = getCollector(name);
420
+ if (!collector) {
421
+ console.error(`Error: Unknown source '${name}'`);
422
+ process.exit(1);
423
+ }
424
+ console.log(`Testing source: ${name}\n`);
425
+ const health = await collector.healthCheck();
426
+ if (health.ok) {
427
+ console.log(`✓ ${health.message}`);
428
+ }
429
+ else {
430
+ console.log(`✗ ${health.message}`);
431
+ process.exit(1);
432
+ }
433
+ }
434
+ catch (error) {
435
+ console.error("Test failed:", error instanceof Error ? error.message : String(error));
436
+ process.exit(1);
437
+ }
438
+ });
439
+ program
440
+ .command("serve")
441
+ .description("Start Memoark HTTP API or MCP stdio server")
442
+ .option("-c, --config <path>", "Path to config file")
443
+ .option("--mcp", "Run MCP stdio transport instead of HTTP")
444
+ .action(async (options) => {
445
+ const serveConfigPath = options.config ?? resolve(process.cwd(), "memoark.yaml");
446
+ if (!existsSync(serveConfigPath)) {
447
+ console.error("No configuration file found.\nRun `memoark init` (TUI) or `memoark init --web` (browser) to set up Memoark.");
448
+ process.exit(1);
449
+ }
450
+ const config = loadConfig(options.config);
451
+ const stateDir = ensureStateDir();
452
+ const stores = await createStores(config);
453
+ let scheduler;
454
+ if (config.scheduler?.enabled) {
455
+ bootstrapCollectors(config.sources);
456
+ const llmConfig = config.llm;
457
+ const envKey = llmConfig.provider === "anthropic"
458
+ ? process.env.ANTHROPIC_API_KEY
459
+ : process.env.OPENAI_API_KEY;
460
+ if (!llmConfig.api_key && envKey)
461
+ llmConfig.api_key = envKey;
462
+ const provider = llmConfig.api_key
463
+ ? createLLMProvider(llmConfig)
464
+ : createMockProvider(new Map());
465
+ const pipelineConfig = {
466
+ dedup_checkpoint: statePath("dedup.jsonl"),
467
+ cursor_checkpoint: statePath("cursors.yaml"),
468
+ block_gap_minutes: config.block_builder.block_gap_minutes,
469
+ max_block_tokens: config.block_builder.max_block_tokens,
470
+ max_block_messages: config.block_builder.max_block_messages,
471
+ privacy: config.privacy,
472
+ output_dir: process.cwd(),
473
+ block_concurrency: config.pipeline?.block_concurrency,
474
+ };
475
+ scheduler = new Scheduler(config.scheduler, stateDir);
476
+ scheduler.setRunSource(async (sourceId) => {
477
+ const collector = getCollector(sourceId);
478
+ if (!collector)
479
+ throw new Error(`Unknown source: ${sourceId}`);
480
+ return runPipeline(pipelineConfig, {
481
+ source: collector,
482
+ provider,
483
+ format: "json",
484
+ adapter: "store",
485
+ stores,
486
+ dryRun: false,
487
+ });
488
+ });
489
+ scheduler.setOnTick((sourceId, result, duration_ms) => {
490
+ const status = result.fatal ? "failed" : "ok";
491
+ console.log(`[scheduler] ${sourceId}: ${status} (${duration_ms}ms)`);
492
+ });
493
+ await scheduler.start();
494
+ }
495
+ const getDaemonStatus = scheduler
496
+ ? () => {
497
+ const hb = scheduler?.getHeartbeat();
498
+ const now = Date.now();
499
+ let lastRunAt = null;
500
+ let nextAt = null;
501
+ for (const id of scheduler?.getSourceIds() ?? []) {
502
+ const s = scheduler?.getSourceState(id);
503
+ if (!s)
504
+ continue;
505
+ if (s.last_run_at !== null && (lastRunAt === null || s.last_run_at > lastRunAt)) {
506
+ lastRunAt = s.last_run_at;
507
+ }
508
+ const next = s.last_run_at !== null ? s.last_run_at + s.interval_secs * 1000 : now;
509
+ if (nextAt === null || next < nextAt)
510
+ nextAt = next;
511
+ }
512
+ return {
513
+ running: true,
514
+ uptime_seconds: Math.floor((now - (hb?.daemon_started_at ?? now)) / 1000),
515
+ last_run: lastRunAt ? new Date(lastRunAt).toISOString() : null,
516
+ next_scheduled: nextAt !== null ? new Date(nextAt).toISOString() : null,
517
+ };
518
+ }
519
+ : undefined;
520
+ const storesWithDaemon = { ...stores, getDaemonStatus };
521
+ const shutdown = () => {
522
+ scheduler?.stop();
523
+ };
524
+ process.on("SIGTERM", shutdown);
525
+ process.on("SIGINT", shutdown);
526
+ if (options.mcp) {
527
+ const server = createMcpServer(storesWithDaemon);
528
+ await server.connect(new StdioServerTransport());
529
+ return;
530
+ }
531
+ const app = createApiApp(storesWithDaemon);
532
+ const server = Bun.serve({ port: config.server.http_port, fetch: app.fetch });
533
+ console.log(`Memoark HTTP API listening on http://localhost:${server.port}`);
534
+ if (scheduler) {
535
+ console.log(`Scheduler running — tick every ${config.scheduler?.tick_interval_secs}s, sources: ${scheduler.getSourceIds().join(", ")}`);
536
+ }
537
+ });
538
+ program
539
+ .command("search <query>")
540
+ .description("Search Memoark memory")
541
+ .option("-c, --config <path>", "Path to config file")
542
+ .option("--mode <mode>", "Search mode (hybrid|fts)", "hybrid")
543
+ .option("--limit <n>", "Limit results", "20")
544
+ .action(async (query, options) => {
545
+ const stores = await createStores(loadConfig(options.config));
546
+ const limit = Number(options.limit);
547
+ const results = options.mode === "fts"
548
+ ? await stores.search.search(query, { limit })
549
+ : await stores.search.query(query, { limit });
550
+ for (const result of results) {
551
+ console.log(`${result.slug}\t${result.score.toFixed(4)}\t${result.snippet.slice(0, 200)}`);
552
+ }
553
+ await stores.db.close();
554
+ });
555
+ program
556
+ .command("embed")
557
+ .description("Embed stale Memoark chunks")
558
+ .option("-c, --config <path>", "Path to config file")
559
+ .option("--limit <n>", "Limit chunks")
560
+ .action(async (options) => {
561
+ const stores = await createStores(loadConfig(options.config));
562
+ const result = await stores.embedding.embedStale({
563
+ limit: options.limit ? Number(options.limit) : undefined,
564
+ });
565
+ console.log(`Embedded ${result.embedded} chunks, errors ${result.errors}`);
566
+ await stores.db.close();
567
+ });
568
+ /**
569
+ * Obsidian sync — bidirectional export/import between PGLite and a vault.
570
+ * See docs/specs/memoark-2026-06-04-obsidian-sync.md
571
+ */
572
+ program
573
+ .command("export")
574
+ .description("Export Memoark pages to an Obsidian vault (Markdown)")
575
+ .requiredOption("--vault <path>", "Obsidian vault directory")
576
+ .option("--force", "Ignore hash comparison, overwrite all files")
577
+ .option("--dry-run", "Print intended actions without writing")
578
+ .option("-c, --config <path>", "Path to config file")
579
+ .action(async (options) => {
580
+ const { exportToVault } = await import("./sync/obsidian.js");
581
+ const stores = await createStores(loadConfig(options.config));
582
+ try {
583
+ const result = await exportToVault(stores, options.vault, {
584
+ force: options.force,
585
+ dryRun: options.dryRun,
586
+ });
587
+ console.log(`Exported: ${result.written} written, ${result.skipped} skipped, ${result.errors.length} errors`);
588
+ for (const err of result.errors) {
589
+ console.error(` error: ${err.slug}: ${err.reason}`);
590
+ }
591
+ if (options.dryRun)
592
+ console.log("(dry-run: no files written)");
593
+ }
594
+ finally {
595
+ await stores.db.close();
596
+ }
597
+ });
598
+ program
599
+ .command("import")
600
+ .description("Import an Obsidian vault back into Memoark")
601
+ .requiredOption("--vault <path>", "Obsidian vault directory")
602
+ .option("--force", "Ignore hash comparison, import all files")
603
+ .option("--dry-run", "Print intended actions without writing")
604
+ .option("--strict-conflict", "Skip files where DB has changed since last sync instead of overwriting")
605
+ .option("-c, --config <path>", "Path to config file")
606
+ .action(async (options) => {
607
+ const { importFromVault } = await import("./sync/obsidian.js");
608
+ const stores = await createStores(loadConfig(options.config));
609
+ try {
610
+ const result = await importFromVault(stores, options.vault, {
611
+ force: options.force,
612
+ dryRun: options.dryRun,
613
+ strictConflict: options.strictConflict,
614
+ });
615
+ console.log(`Imported: ${result.imported} imported, ${result.skipped} skipped, ${result.errors.length} errors`);
616
+ for (const w of result.warnings) {
617
+ console.warn(` warn: ${w.slug}: ${w.reason}`);
618
+ }
619
+ for (const err of result.errors) {
620
+ console.error(` error: ${err.file}: ${err.reason}`);
621
+ }
622
+ if (!options.dryRun && result.imported > 0) {
623
+ console.log("Tip: Run 'memoark embed' to update embeddings for changed pages.");
624
+ }
625
+ }
626
+ finally {
627
+ await stores.db.close();
628
+ }
629
+ });
630
+ program
631
+ .command("consolidate")
632
+ .description("Run memory lifecycle tier rotation (hot→warm and/or warm→cold)")
633
+ .option("-c, --config <path>", "Path to config file (default: memoark.yaml)")
634
+ .option("--hot", "Run hot→warm rotation only")
635
+ .option("--warm", "Run warm→cold rotation only (requires LLM API key)")
636
+ .option("--dry-run", "Report what would be consolidated without writing")
637
+ .action(async (options) => {
638
+ try {
639
+ const config = loadConfig(options.config);
640
+ const stores = await createStores(config);
641
+ let llmProvider;
642
+ if (options.warm || (!options.hot && !options.warm)) {
643
+ const llmConfig = config.llm;
644
+ const envKey = llmConfig.provider === "anthropic"
645
+ ? process.env.ANTHROPIC_API_KEY
646
+ : process.env.OPENAI_API_KEY;
647
+ const apiKey = llmConfig.api_key ?? envKey;
648
+ if (apiKey) {
649
+ if (!llmConfig.api_key)
650
+ llmConfig.api_key = apiKey;
651
+ llmProvider = createLLMProvider(llmConfig);
652
+ }
653
+ else if (options.warm) {
654
+ // Explicit --warm with no LLM key: fail fast
655
+ console.error("Error: --warm requires an LLM API key. Set ANTHROPIC_API_KEY or configure api_key in memoark.yaml.");
656
+ process.exit(1);
657
+ }
658
+ else {
659
+ // Full run with no LLM: skip warm→cold, run hot only
660
+ console.warn("Warning: no LLM API key found. Running hot→warm only. " +
661
+ "Set ANTHROPIC_API_KEY to enable warm→cold consolidation.");
662
+ }
663
+ }
664
+ const consolidator = new Consolidator({
665
+ pages: stores.pages,
666
+ graph: stores.graph,
667
+ tags: stores.tags,
668
+ timeline: stores.timeline,
669
+ }, llmProvider);
670
+ const mode = options.hot
671
+ ? "hot"
672
+ : options.warm
673
+ ? "warm"
674
+ : llmProvider
675
+ ? "all"
676
+ : "hot"; // fall back to hot-only when full run has no LLM
677
+ const dryRun = options.dryRun ?? false;
678
+ if (dryRun)
679
+ console.log("DRY-RUN mode — no writes will occur\n");
680
+ const result = await consolidator.runOnce(mode, dryRun);
681
+ console.log("Consolidation complete:");
682
+ console.log(` hot→warm pages moved: ${result.hotToWarm}`);
683
+ console.log(` warm→cold pages archived: ${result.warmToCold}`);
684
+ console.log(` dead links checked: ${result.deadLinksChecked}`);
685
+ console.log(` preferences inferred: ${result.preferencesInferred}`);
686
+ await stores.db.close();
687
+ }
688
+ catch (error) {
689
+ console.error("Consolidate failed:", error instanceof Error ? error.message : String(error));
690
+ process.exit(1);
691
+ }
692
+ });
693
+ program.parse(process.argv);
694
+ //# sourceMappingURL=cli.js.map