stellavault 0.2.0 → 0.2.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 (390) hide show
  1. package/package.json +1 -1
  2. package/packages/core/dist/api/dashboard.d.ts +3 -0
  3. package/packages/core/{src/api/dashboard.ts → dist/api/dashboard.js} +8 -11
  4. package/packages/core/dist/api/graph-data.d.ts +11 -0
  5. package/packages/core/dist/api/graph-data.js +255 -0
  6. package/packages/core/dist/api/pwa.d.ts +3 -0
  7. package/packages/core/{src/api/pwa.ts → dist/api/pwa.js} +27 -32
  8. package/packages/core/dist/api/server.d.ts +16 -0
  9. package/packages/core/dist/api/server.js +647 -0
  10. package/packages/core/dist/capture/voice.d.ts +24 -0
  11. package/packages/core/dist/capture/voice.js +135 -0
  12. package/packages/core/{src/cloud/index.ts → dist/cloud/index.d.ts} +1 -0
  13. package/packages/core/dist/cloud/index.js +2 -0
  14. package/packages/core/dist/cloud/sync.d.ts +29 -0
  15. package/packages/core/dist/cloud/sync.js +137 -0
  16. package/packages/core/dist/config.d.ts +27 -0
  17. package/packages/core/dist/config.js +55 -0
  18. package/packages/core/dist/federation/credits.d.ts +26 -0
  19. package/packages/core/dist/federation/credits.js +56 -0
  20. package/packages/core/dist/federation/identity.d.ts +14 -0
  21. package/packages/core/dist/federation/identity.js +74 -0
  22. package/packages/core/{src/federation/index.ts → dist/federation/index.d.ts} +1 -2
  23. package/packages/core/dist/federation/index.js +5 -0
  24. package/packages/core/dist/federation/node.d.ts +31 -0
  25. package/packages/core/dist/federation/node.js +216 -0
  26. package/packages/core/dist/federation/privacy.d.ts +8 -0
  27. package/packages/core/dist/federation/privacy.js +40 -0
  28. package/packages/core/dist/federation/reputation.d.ts +37 -0
  29. package/packages/core/dist/federation/reputation.js +139 -0
  30. package/packages/core/dist/federation/search.d.ts +19 -0
  31. package/packages/core/dist/federation/search.js +101 -0
  32. package/packages/core/dist/federation/sharing.d.ts +72 -0
  33. package/packages/core/dist/federation/sharing.js +246 -0
  34. package/packages/core/dist/federation/trust.d.ts +15 -0
  35. package/packages/core/dist/federation/trust.js +60 -0
  36. package/packages/core/dist/federation/types.d.ts +40 -0
  37. package/packages/core/dist/federation/types.js +3 -0
  38. package/packages/core/dist/i18n/index.d.ts +6 -0
  39. package/packages/core/dist/i18n/index.js +81 -0
  40. package/packages/core/{src/index.ts → dist/index.d.ts} +46 -65
  41. package/packages/core/dist/index.js +69 -0
  42. package/packages/core/dist/indexer/chunker.d.ts +14 -0
  43. package/packages/core/dist/indexer/chunker.js +148 -0
  44. package/packages/core/dist/indexer/embedder.d.ts +8 -0
  45. package/packages/core/dist/indexer/embedder.js +3 -0
  46. package/packages/core/dist/indexer/index.d.ts +28 -0
  47. package/packages/core/dist/indexer/index.js +74 -0
  48. package/packages/core/dist/indexer/local-embedder.d.ts +3 -0
  49. package/packages/core/dist/indexer/local-embedder.js +29 -0
  50. package/packages/core/dist/indexer/scanner.d.ts +11 -0
  51. package/packages/core/dist/indexer/scanner.js +137 -0
  52. package/packages/core/dist/indexer/watcher.d.ts +19 -0
  53. package/packages/core/dist/indexer/watcher.js +49 -0
  54. package/packages/core/dist/intelligence/contradiction-detector.d.ts +20 -0
  55. package/packages/core/dist/intelligence/contradiction-detector.js +115 -0
  56. package/packages/core/dist/intelligence/decay-engine.d.ts +27 -0
  57. package/packages/core/dist/intelligence/decay-engine.js +190 -0
  58. package/packages/core/dist/intelligence/duplicate-detector.d.ts +20 -0
  59. package/packages/core/dist/intelligence/duplicate-detector.js +55 -0
  60. package/packages/core/dist/intelligence/fsrs.d.ts +43 -0
  61. package/packages/core/dist/intelligence/fsrs.js +70 -0
  62. package/packages/core/dist/intelligence/gap-detector.d.ts +25 -0
  63. package/packages/core/dist/intelligence/gap-detector.js +78 -0
  64. package/packages/core/dist/intelligence/learning-path.d.ts +31 -0
  65. package/packages/core/dist/intelligence/learning-path.js +53 -0
  66. package/packages/core/dist/intelligence/notifications.d.ts +31 -0
  67. package/packages/core/dist/intelligence/notifications.js +65 -0
  68. package/packages/core/dist/intelligence/predictive-gaps.d.ts +14 -0
  69. package/packages/core/dist/intelligence/predictive-gaps.js +74 -0
  70. package/packages/core/dist/intelligence/semantic-versioning.d.ts +37 -0
  71. package/packages/core/dist/intelligence/semantic-versioning.js +68 -0
  72. package/packages/core/dist/intelligence/types.d.ts +28 -0
  73. package/packages/core/dist/intelligence/types.js +3 -0
  74. package/packages/core/dist/mcp/custom-tools.d.ts +29 -0
  75. package/packages/core/dist/mcp/custom-tools.js +70 -0
  76. package/packages/core/{src/mcp/index.ts → dist/mcp/index.d.ts} +1 -0
  77. package/packages/core/dist/mcp/index.js +2 -0
  78. package/packages/core/dist/mcp/server.d.ts +49 -0
  79. package/packages/core/dist/mcp/server.js +133 -0
  80. package/packages/core/dist/mcp/tools/agentic-graph.d.ts +87 -0
  81. package/packages/core/dist/mcp/tools/agentic-graph.js +88 -0
  82. package/packages/core/dist/mcp/tools/brief.d.ts +31 -0
  83. package/packages/core/dist/mcp/tools/brief.js +39 -0
  84. package/packages/core/dist/mcp/tools/decay.d.ts +33 -0
  85. package/packages/core/dist/mcp/tools/decay.js +32 -0
  86. package/packages/core/dist/mcp/tools/decision-journal.d.ts +78 -0
  87. package/packages/core/dist/mcp/tools/decision-journal.js +79 -0
  88. package/packages/core/dist/mcp/tools/export.d.ts +29 -0
  89. package/packages/core/dist/mcp/tools/export.js +60 -0
  90. package/packages/core/dist/mcp/tools/federated-search.d.ts +29 -0
  91. package/packages/core/dist/mcp/tools/federated-search.js +36 -0
  92. package/packages/core/dist/mcp/tools/generate-claude-md.d.ts +35 -0
  93. package/packages/core/dist/mcp/tools/generate-claude-md.js +107 -0
  94. package/packages/core/dist/mcp/tools/get-document.d.ts +35 -0
  95. package/packages/core/dist/mcp/tools/get-document.js +25 -0
  96. package/packages/core/dist/mcp/tools/get-related.d.ts +32 -0
  97. package/packages/core/dist/mcp/tools/get-related.js +33 -0
  98. package/packages/core/dist/mcp/tools/learning-path.d.ts +23 -0
  99. package/packages/core/dist/mcp/tools/learning-path.js +45 -0
  100. package/packages/core/dist/mcp/tools/list-topics.d.ts +15 -0
  101. package/packages/core/dist/mcp/tools/list-topics.js +18 -0
  102. package/packages/core/dist/mcp/tools/search.d.ts +39 -0
  103. package/packages/core/dist/mcp/tools/search.js +29 -0
  104. package/packages/core/dist/mcp/tools/snapshot.d.ts +47 -0
  105. package/packages/core/dist/mcp/tools/snapshot.js +84 -0
  106. package/packages/core/dist/multi-vault/index.d.ts +26 -0
  107. package/packages/core/dist/multi-vault/index.js +80 -0
  108. package/packages/core/dist/pack/creator.d.ts +21 -0
  109. package/packages/core/dist/pack/creator.js +105 -0
  110. package/packages/core/dist/pack/exporter.d.ts +4 -0
  111. package/packages/core/dist/pack/exporter.js +18 -0
  112. package/packages/core/dist/pack/importer.d.ts +10 -0
  113. package/packages/core/dist/pack/importer.js +55 -0
  114. package/packages/core/{src/pack/index.ts → dist/pack/index.d.ts} +1 -0
  115. package/packages/core/dist/pack/index.js +5 -0
  116. package/packages/core/dist/pack/marketplace.d.ts +14 -0
  117. package/packages/core/dist/pack/marketplace.js +90 -0
  118. package/packages/core/dist/pack/pii-masker.d.ts +7 -0
  119. package/packages/core/dist/pack/pii-masker.js +29 -0
  120. package/packages/core/dist/pack/types.d.ts +36 -0
  121. package/packages/core/dist/pack/types.js +3 -0
  122. package/packages/core/dist/plugins/index.d.ts +35 -0
  123. package/packages/core/dist/plugins/index.js +57 -0
  124. package/packages/core/dist/plugins/webhooks.d.ts +30 -0
  125. package/packages/core/dist/plugins/webhooks.js +79 -0
  126. package/packages/core/dist/search/bm25.d.ts +4 -0
  127. package/packages/core/dist/search/bm25.js +10 -0
  128. package/packages/core/dist/search/index.d.ts +13 -0
  129. package/packages/core/dist/search/index.js +63 -0
  130. package/packages/core/dist/search/rrf.d.ts +7 -0
  131. package/packages/core/dist/search/rrf.js +21 -0
  132. package/packages/core/dist/search/semantic.d.ts +5 -0
  133. package/packages/core/dist/search/semantic.js +6 -0
  134. package/packages/core/{src/store/index.ts → dist/store/index.d.ts} +1 -0
  135. package/packages/core/dist/store/index.js +2 -0
  136. package/packages/core/dist/store/sqlite-vec.d.ts +6 -0
  137. package/packages/core/dist/store/sqlite-vec.js +251 -0
  138. package/packages/core/dist/store/types.d.ts +20 -0
  139. package/packages/core/dist/store/types.js +3 -0
  140. package/packages/core/dist/team/index.d.ts +25 -0
  141. package/packages/core/dist/team/index.js +97 -0
  142. package/packages/core/dist/types/chunk.d.ts +23 -0
  143. package/packages/core/dist/types/chunk.js +3 -0
  144. package/packages/core/dist/types/document.d.ts +23 -0
  145. package/packages/core/dist/types/document.js +3 -0
  146. package/packages/core/dist/types/graph.d.ts +39 -0
  147. package/packages/core/dist/types/graph.js +3 -0
  148. package/packages/core/dist/types/index.d.ts +5 -0
  149. package/packages/core/dist/types/index.js +2 -0
  150. package/packages/core/dist/types/search.d.ts +39 -0
  151. package/packages/core/dist/types/search.js +3 -0
  152. package/packages/core/dist/utils/retry.d.ts +25 -0
  153. package/packages/core/dist/utils/retry.js +59 -0
  154. package/.github/workflows/pages.yml +0 -37
  155. package/memory/MEMORY.md +0 -25
  156. package/packages/cli/dist/commands/brief-cmd.d.ts.map +0 -1
  157. package/packages/cli/dist/commands/brief-cmd.js.map +0 -1
  158. package/packages/cli/dist/commands/capture-cmd.d.ts.map +0 -1
  159. package/packages/cli/dist/commands/capture-cmd.js.map +0 -1
  160. package/packages/cli/dist/commands/card-cmd.d.ts.map +0 -1
  161. package/packages/cli/dist/commands/card-cmd.js.map +0 -1
  162. package/packages/cli/dist/commands/clip-cmd.d.ts.map +0 -1
  163. package/packages/cli/dist/commands/clip-cmd.js.map +0 -1
  164. package/packages/cli/dist/commands/cloud-cmd.d.ts.map +0 -1
  165. package/packages/cli/dist/commands/cloud-cmd.js.map +0 -1
  166. package/packages/cli/dist/commands/contradictions-cmd.d.ts.map +0 -1
  167. package/packages/cli/dist/commands/contradictions-cmd.js.map +0 -1
  168. package/packages/cli/dist/commands/decay-cmd.d.ts.map +0 -1
  169. package/packages/cli/dist/commands/decay-cmd.js.map +0 -1
  170. package/packages/cli/dist/commands/digest-cmd.d.ts.map +0 -1
  171. package/packages/cli/dist/commands/digest-cmd.js.map +0 -1
  172. package/packages/cli/dist/commands/duplicates-cmd.d.ts.map +0 -1
  173. package/packages/cli/dist/commands/duplicates-cmd.js.map +0 -1
  174. package/packages/cli/dist/commands/federate-cmd.d.ts.map +0 -1
  175. package/packages/cli/dist/commands/federate-cmd.js.map +0 -1
  176. package/packages/cli/dist/commands/gaps-cmd.d.ts.map +0 -1
  177. package/packages/cli/dist/commands/gaps-cmd.js.map +0 -1
  178. package/packages/cli/dist/commands/graph-cmd.d.ts.map +0 -1
  179. package/packages/cli/dist/commands/graph-cmd.js.map +0 -1
  180. package/packages/cli/dist/commands/index-cmd.d.ts.map +0 -1
  181. package/packages/cli/dist/commands/index-cmd.js.map +0 -1
  182. package/packages/cli/dist/commands/init-cmd.d.ts.map +0 -1
  183. package/packages/cli/dist/commands/init-cmd.js.map +0 -1
  184. package/packages/cli/dist/commands/learn-cmd.d.ts.map +0 -1
  185. package/packages/cli/dist/commands/learn-cmd.js.map +0 -1
  186. package/packages/cli/dist/commands/pack-cmd.d.ts.map +0 -1
  187. package/packages/cli/dist/commands/pack-cmd.js.map +0 -1
  188. package/packages/cli/dist/commands/review-cmd.d.ts.map +0 -1
  189. package/packages/cli/dist/commands/review-cmd.js.map +0 -1
  190. package/packages/cli/dist/commands/search-cmd.d.ts.map +0 -1
  191. package/packages/cli/dist/commands/search-cmd.js.map +0 -1
  192. package/packages/cli/dist/commands/serve-cmd.d.ts.map +0 -1
  193. package/packages/cli/dist/commands/serve-cmd.js.map +0 -1
  194. package/packages/cli/dist/commands/status-cmd.d.ts.map +0 -1
  195. package/packages/cli/dist/commands/status-cmd.js.map +0 -1
  196. package/packages/cli/dist/commands/sync-cmd.d.ts.map +0 -1
  197. package/packages/cli/dist/commands/sync-cmd.js.map +0 -1
  198. package/packages/cli/dist/commands/vault-cmd.d.ts.map +0 -1
  199. package/packages/cli/dist/commands/vault-cmd.js.map +0 -1
  200. package/packages/cli/dist/index.d.ts.map +0 -1
  201. package/packages/cli/dist/index.js.map +0 -1
  202. package/packages/cli/src/commands/brief-cmd.ts +0 -87
  203. package/packages/cli/src/commands/capture-cmd.ts +0 -34
  204. package/packages/cli/src/commands/card-cmd.ts +0 -29
  205. package/packages/cli/src/commands/clip-cmd.ts +0 -172
  206. package/packages/cli/src/commands/cloud-cmd.ts +0 -75
  207. package/packages/cli/src/commands/contradictions-cmd.ts +0 -41
  208. package/packages/cli/src/commands/decay-cmd.ts +0 -57
  209. package/packages/cli/src/commands/digest-cmd.ts +0 -89
  210. package/packages/cli/src/commands/duplicates-cmd.ts +0 -38
  211. package/packages/cli/src/commands/federate-cmd.ts +0 -256
  212. package/packages/cli/src/commands/gaps-cmd.ts +0 -40
  213. package/packages/cli/src/commands/graph-cmd.ts +0 -88
  214. package/packages/cli/src/commands/index-cmd.ts +0 -65
  215. package/packages/cli/src/commands/init-cmd.ts +0 -145
  216. package/packages/cli/src/commands/learn-cmd.ts +0 -56
  217. package/packages/cli/src/commands/pack-cmd.ts +0 -121
  218. package/packages/cli/src/commands/review-cmd.ts +0 -125
  219. package/packages/cli/src/commands/search-cmd.ts +0 -45
  220. package/packages/cli/src/commands/serve-cmd.ts +0 -17
  221. package/packages/cli/src/commands/status-cmd.ts +0 -37
  222. package/packages/cli/src/commands/sync-cmd.ts +0 -68
  223. package/packages/cli/src/commands/vault-cmd.ts +0 -64
  224. package/packages/cli/src/index.ts +0 -187
  225. package/packages/core/src/api/graph-data.ts +0 -286
  226. package/packages/core/src/api/server.ts +0 -660
  227. package/packages/core/src/capture/voice.ts +0 -168
  228. package/packages/core/src/cloud/sync.ts +0 -167
  229. package/packages/core/src/config.ts +0 -82
  230. package/packages/core/src/federation/credits.ts +0 -80
  231. package/packages/core/src/federation/hyperswarm.d.ts +0 -19
  232. package/packages/core/src/federation/identity.ts +0 -90
  233. package/packages/core/src/federation/node.ts +0 -235
  234. package/packages/core/src/federation/privacy.ts +0 -52
  235. package/packages/core/src/federation/reputation.ts +0 -202
  236. package/packages/core/src/federation/search.ts +0 -129
  237. package/packages/core/src/federation/sharing.ts +0 -315
  238. package/packages/core/src/federation/trust.ts +0 -76
  239. package/packages/core/src/federation/types.ts +0 -25
  240. package/packages/core/src/i18n/index.ts +0 -85
  241. package/packages/core/src/indexer/chunker.ts +0 -180
  242. package/packages/core/src/indexer/embedder.ts +0 -9
  243. package/packages/core/src/indexer/index.ts +0 -113
  244. package/packages/core/src/indexer/local-embedder.ts +0 -35
  245. package/packages/core/src/indexer/scanner.ts +0 -142
  246. package/packages/core/src/indexer/watcher.ts +0 -62
  247. package/packages/core/src/intelligence/contradiction-detector.ts +0 -134
  248. package/packages/core/src/intelligence/decay-engine.ts +0 -229
  249. package/packages/core/src/intelligence/duplicate-detector.ts +0 -71
  250. package/packages/core/src/intelligence/fsrs.ts +0 -79
  251. package/packages/core/src/intelligence/gap-detector.ts +0 -109
  252. package/packages/core/src/intelligence/learning-path.ts +0 -86
  253. package/packages/core/src/intelligence/notifications.ts +0 -106
  254. package/packages/core/src/intelligence/predictive-gaps.ts +0 -94
  255. package/packages/core/src/intelligence/semantic-versioning.ts +0 -97
  256. package/packages/core/src/intelligence/types.ts +0 -28
  257. package/packages/core/src/mcp/custom-tools.ts +0 -97
  258. package/packages/core/src/mcp/server.ts +0 -142
  259. package/packages/core/src/mcp/tools/agentic-graph.ts +0 -96
  260. package/packages/core/src/mcp/tools/brief.ts +0 -49
  261. package/packages/core/src/mcp/tools/decay.ts +0 -40
  262. package/packages/core/src/mcp/tools/decision-journal.ts +0 -95
  263. package/packages/core/src/mcp/tools/export.ts +0 -72
  264. package/packages/core/src/mcp/tools/federated-search.ts +0 -43
  265. package/packages/core/src/mcp/tools/generate-claude-md.ts +0 -130
  266. package/packages/core/src/mcp/tools/get-document.ts +0 -26
  267. package/packages/core/src/mcp/tools/get-related.ts +0 -41
  268. package/packages/core/src/mcp/tools/learning-path.ts +0 -52
  269. package/packages/core/src/mcp/tools/list-topics.ts +0 -20
  270. package/packages/core/src/mcp/tools/search.ts +0 -35
  271. package/packages/core/src/mcp/tools/snapshot.ts +0 -98
  272. package/packages/core/src/multi-vault/index.ts +0 -118
  273. package/packages/core/src/pack/creator.ts +0 -127
  274. package/packages/core/src/pack/exporter.ts +0 -21
  275. package/packages/core/src/pack/importer.ts +0 -82
  276. package/packages/core/src/pack/marketplace.ts +0 -103
  277. package/packages/core/src/pack/pii-masker.ts +0 -38
  278. package/packages/core/src/pack/types.ts +0 -39
  279. package/packages/core/src/plugins/index.ts +0 -100
  280. package/packages/core/src/plugins/webhooks.ts +0 -110
  281. package/packages/core/src/search/bm25.ts +0 -16
  282. package/packages/core/src/search/index.ts +0 -83
  283. package/packages/core/src/search/rrf.ts +0 -31
  284. package/packages/core/src/search/semantic.ts +0 -15
  285. package/packages/core/src/store/sqlite-vec.ts +0 -290
  286. package/packages/core/src/store/types.ts +0 -22
  287. package/packages/core/src/team/index.ts +0 -126
  288. package/packages/core/src/types/chunk.ts +0 -25
  289. package/packages/core/src/types/document.ts +0 -24
  290. package/packages/core/src/types/graph.ts +0 -44
  291. package/packages/core/src/types/index.ts +0 -15
  292. package/packages/core/src/types/search.ts +0 -38
  293. package/packages/core/src/utils/retry.ts +0 -85
  294. package/packages/core/tests/api-card.test.ts +0 -60
  295. package/packages/core/tests/api-routes.test.ts +0 -98
  296. package/packages/core/tests/bm25.test.ts +0 -87
  297. package/packages/core/tests/chunker.test.ts +0 -48
  298. package/packages/core/tests/cluster.test.ts +0 -75
  299. package/packages/core/tests/constellation.test.ts +0 -77
  300. package/packages/core/tests/export-utils.test.ts +0 -97
  301. package/packages/core/tests/fsrs.test.ts +0 -96
  302. package/packages/core/tests/gesture-detector.test.ts +0 -45
  303. package/packages/core/tests/graph-data.test.ts +0 -87
  304. package/packages/core/tests/layout.test.ts +0 -83
  305. package/packages/core/tests/mcp.test.ts +0 -148
  306. package/packages/core/tests/pack.test.ts +0 -127
  307. package/packages/core/tests/pii-masker.test.ts +0 -42
  308. package/packages/core/tests/profile-card.test.ts +0 -62
  309. package/packages/core/tests/rrf.test.ts +0 -29
  310. package/packages/core/tests/search-integration.test.ts +0 -139
  311. package/packages/core/tests/store.test.ts +0 -80
  312. package/packages/graph/click-result.png +0 -0
  313. package/packages/graph/dist/assets/camera_utils-BMxqtvoZ.js +0 -1
  314. package/packages/graph/dist/assets/hands-DXA01_mx.js +0 -18
  315. package/packages/graph/dist/assets/index-DMEe2diW.js +0 -4192
  316. package/packages/graph/dist/assets/layout.worker-DbKCEFTz.js +0 -1
  317. package/packages/graph/dist/index.html +0 -17
  318. package/packages/graph/index.html +0 -17
  319. package/packages/graph/package.json +0 -32
  320. package/packages/graph/src/App.tsx +0 -7
  321. package/packages/graph/src/api/client.ts +0 -39
  322. package/packages/graph/src/components/ClusterFilter.tsx +0 -73
  323. package/packages/graph/src/components/ConstellationView.tsx +0 -232
  324. package/packages/graph/src/components/ExportPanel.tsx +0 -177
  325. package/packages/graph/src/components/Graph3D.tsx +0 -230
  326. package/packages/graph/src/components/GraphEdges.tsx +0 -100
  327. package/packages/graph/src/components/GraphNodes.tsx +0 -386
  328. package/packages/graph/src/components/HealthDashboard.tsx +0 -173
  329. package/packages/graph/src/components/Layout.tsx +0 -214
  330. package/packages/graph/src/components/MotionOverlay.tsx +0 -81
  331. package/packages/graph/src/components/MotionToggle.tsx +0 -33
  332. package/packages/graph/src/components/MultiverseView.tsx +0 -286
  333. package/packages/graph/src/components/NodeDetail.tsx +0 -232
  334. package/packages/graph/src/components/PulseParticle.tsx +0 -232
  335. package/packages/graph/src/components/SearchBar.tsx +0 -107
  336. package/packages/graph/src/components/StarField.tsx +0 -197
  337. package/packages/graph/src/components/StatusBar.tsx +0 -53
  338. package/packages/graph/src/components/Timeline.tsx +0 -148
  339. package/packages/graph/src/components/ToolsPanel.tsx +0 -512
  340. package/packages/graph/src/components/Tooltip.tsx +0 -100
  341. package/packages/graph/src/components/TypeFilter.tsx +0 -131
  342. package/packages/graph/src/embed/EmbedGraph.tsx +0 -144
  343. package/packages/graph/src/hooks/useConstellationLOD.ts +0 -76
  344. package/packages/graph/src/hooks/useDecay.ts +0 -37
  345. package/packages/graph/src/hooks/useExport.ts +0 -165
  346. package/packages/graph/src/hooks/useGraph.ts +0 -69
  347. package/packages/graph/src/hooks/useKeyboardNav.ts +0 -122
  348. package/packages/graph/src/hooks/useLayout.ts +0 -45
  349. package/packages/graph/src/hooks/useMotion.ts +0 -120
  350. package/packages/graph/src/hooks/usePulse.ts +0 -58
  351. package/packages/graph/src/hooks/useSearch.ts +0 -71
  352. package/packages/graph/src/lib/constellation.ts +0 -107
  353. package/packages/graph/src/lib/export-utils.ts +0 -48
  354. package/packages/graph/src/lib/gesture-detector.ts +0 -123
  355. package/packages/graph/src/lib/layout.worker.ts +0 -153
  356. package/packages/graph/src/lib/motion-controller.ts +0 -83
  357. package/packages/graph/src/lib/profile-card.ts +0 -122
  358. package/packages/graph/src/main.tsx +0 -4
  359. package/packages/graph/src/stores/graph-store.ts +0 -155
  360. package/packages/graph/success.png +0 -0
  361. package/packages/graph/test-click.mjs +0 -49
  362. package/packages/graph/test-explore.mjs +0 -102
  363. package/packages/graph/test-final.mjs +0 -61
  364. package/packages/graph/test-graph.mjs +0 -139
  365. package/packages/graph/test-hover.mjs +0 -48
  366. package/packages/graph/test-pulse.mjs +0 -68
  367. package/packages/graph/test-screenshot.mjs +0 -56
  368. package/packages/graph/test-v2.mjs +0 -97
  369. package/packages/graph/tsconfig.tsbuildinfo +0 -1
  370. package/packages/graph/vite.config.ts +0 -15
  371. package/packages/sync/.env.example +0 -11
  372. package/packages/sync/.sync-state.json +0 -317
  373. package/packages/sync/.upload-state.json +0 -1009
  374. package/packages/sync/create-stella-network-notion.mjs +0 -151
  375. package/packages/sync/create-stellavault-project-notion.mjs +0 -322
  376. package/packages/sync/logs/sync-2026-03-28.log +0 -6
  377. package/packages/sync/logs/sync-2026-03-29.log +0 -12
  378. package/packages/sync/logs/sync-2026-03-30.log +0 -6
  379. package/packages/sync/logs/sync-2026-03-31.log +0 -6
  380. package/packages/sync/logs/sync-2026-04-01.log +0 -6
  381. package/packages/sync/logs/sync-2026-04-02.log +0 -6
  382. package/packages/sync/package-lock.json +0 -373
  383. package/packages/sync/package.json +0 -16
  384. package/packages/sync/run-sync.bat +0 -18
  385. package/packages/sync/run-sync.mjs +0 -46
  386. package/packages/sync/setup-scheduler.mjs +0 -119
  387. package/packages/sync/structured-sync.mjs +0 -187
  388. package/packages/sync/sync-to-obsidian.mjs +0 -264
  389. package/packages/sync/upload-pdca-to-notion.mjs +0 -495
  390. package/tsconfig.base.json +0 -18
@@ -0,0 +1,115 @@
1
+ // Contradiction Detector (F-A12)
2
+ // Finds potentially contradicting statements across notes
3
+ // Uses embedding similarity + negation pattern detection
4
+ // Negation/opposition patterns
5
+ const NEGATION_PAIRS = [
6
+ ['should', 'should not'], ['must', 'must not'], ['always', 'never'],
7
+ ['best', 'worst'], ['good', 'bad'], ['correct', 'incorrect'],
8
+ ['true', 'false'], ['increase', 'decrease'], ['enable', 'disable'],
9
+ ['recommended', 'not recommended'], ['use', 'avoid'],
10
+ ['prefer', 'avoid'], ['do', "don't"], ['is', "isn't"],
11
+ ['can', "can't"], ['will', "won't"], ['important', 'unimportant'],
12
+ ['필요', '불필요'], ['해야', '하면 안'], ['좋', '나쁜'], ['맞', '틀'],
13
+ ];
14
+ function extractKeyStatements(content) {
15
+ return content
16
+ .split(/[.\n!?]/)
17
+ .map(s => s.trim())
18
+ .filter(s => s.length > 20 && s.length < 200)
19
+ .filter(s => {
20
+ const lower = s.toLowerCase();
21
+ return /should|must|always|never|best|important|recommend|prefer|avoid|필요|해야|좋|나쁜/.test(lower);
22
+ })
23
+ .slice(0, 10); // max 10 statements per document
24
+ }
25
+ function detectNegationConflict(stmtA, stmtB) {
26
+ const a = stmtA.toLowerCase();
27
+ const b = stmtB.toLowerCase();
28
+ // Check negation pairs
29
+ for (const [pos, neg] of NEGATION_PAIRS) {
30
+ if ((a.includes(pos) && b.includes(neg)) || (a.includes(neg) && b.includes(pos))) {
31
+ // Check if they're talking about the same subject (share words)
32
+ const wordsA = new Set(a.split(/\s+/).filter(w => w.length > 3));
33
+ const wordsB = new Set(b.split(/\s+/).filter(w => w.length > 3));
34
+ const overlap = [...wordsA].filter(w => wordsB.has(w)).length;
35
+ const minSize = Math.min(wordsA.size, wordsB.size) || 1;
36
+ const subjectOverlap = overlap / minSize;
37
+ if (subjectOverlap > 0.2) {
38
+ return { isConflict: true, confidence: Math.min(0.5 + subjectOverlap * 0.5, 0.95), type: 'negation' };
39
+ }
40
+ }
41
+ }
42
+ // Check numeric value conflicts (e.g., "timeout should be 30s" vs "timeout should be 5s")
43
+ const numsA = a.match(/\d+/g);
44
+ const numsB = b.match(/\d+/g);
45
+ if (numsA && numsB) {
46
+ const wordsA = new Set(a.replace(/\d+/g, '').split(/\s+/).filter(w => w.length > 3));
47
+ const wordsB = new Set(b.replace(/\d+/g, '').split(/\s+/).filter(w => w.length > 3));
48
+ const overlap = [...wordsA].filter(w => wordsB.has(w)).length;
49
+ if (overlap >= 2 && numsA[0] !== numsB[0]) {
50
+ return { isConflict: true, confidence: 0.6, type: 'value_conflict' };
51
+ }
52
+ }
53
+ return { isConflict: false, confidence: 0, type: 'semantic' };
54
+ }
55
+ export async function detectContradictions(store, limit = 20) {
56
+ const docs = await store.getAllDocuments();
57
+ const embeddings = await store.getDocumentEmbeddings();
58
+ if (docs.length < 2)
59
+ return [];
60
+ // Build document vectors + key statements
61
+ const docData = new Map();
62
+ for (const doc of docs) {
63
+ const vec = embeddings.get(doc.id);
64
+ if (!vec)
65
+ continue;
66
+ const statements = extractKeyStatements(doc.content);
67
+ if (statements.length === 0)
68
+ continue;
69
+ docData.set(doc.id, { vec: Array.from(vec), title: doc.title, filePath: doc.filePath, statements });
70
+ }
71
+ const ids = [...docData.keys()];
72
+ const results = [];
73
+ // Compare documents with moderate similarity (same topic, possibly conflicting)
74
+ for (let i = 0; i < ids.length && results.length < limit * 3; i++) {
75
+ for (let j = i + 1; j < ids.length && results.length < limit * 3; j++) {
76
+ const a = docData.get(ids[i]);
77
+ const b = docData.get(ids[j]);
78
+ const sim = cosineSim(a.vec, b.vec);
79
+ // Sweet spot: similar enough to be same topic, not identical
80
+ if (sim < 0.3 || sim > 0.9)
81
+ continue;
82
+ // Compare statements
83
+ for (const stmtA of a.statements) {
84
+ for (const stmtB of b.statements) {
85
+ const { isConflict, confidence, type } = detectNegationConflict(stmtA, stmtB);
86
+ if (isConflict && confidence >= 0.5) {
87
+ results.push({
88
+ docA: { id: ids[i], title: a.title, filePath: a.filePath, statement: stmtA },
89
+ docB: { id: ids[j], title: b.title, filePath: b.filePath, statement: stmtB },
90
+ similarity: Math.round(sim * 1000) / 1000,
91
+ confidence: Math.round(confidence * 100) / 100,
92
+ type,
93
+ });
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ return results
100
+ .sort((a, b) => b.confidence - a.confidence)
101
+ .slice(0, limit);
102
+ }
103
+ function cosineSim(a, b) {
104
+ if (a.length !== b.length)
105
+ return 0;
106
+ let dot = 0, na = 0, nb = 0;
107
+ for (let i = 0; i < a.length; i++) {
108
+ dot += a[i] * b[i];
109
+ na += a[i] * a[i];
110
+ nb += b[i] * b[i];
111
+ }
112
+ const d = Math.sqrt(na) * Math.sqrt(nb);
113
+ return d === 0 ? 0 : dot / d;
114
+ }
115
+ //# sourceMappingURL=contradiction-detector.js.map
@@ -0,0 +1,27 @@
1
+ import type { Database } from 'better-sqlite3';
2
+ import type { DecayState, AccessEvent, DecayReport } from './types.js';
3
+ export declare class DecayEngine {
4
+ private db;
5
+ constructor(db: Database);
6
+ private ensureTables;
7
+ /**
8
+ * Record an access event and update decay state.
9
+ */
10
+ recordAccess(event: AccessEvent): Promise<void>;
11
+ /**
12
+ * Batch compute retrievability for all documents.
13
+ */
14
+ computeAll(): Promise<DecayReport>;
15
+ private computeClusterHealth;
16
+ /**
17
+ * Get documents below decay threshold.
18
+ */
19
+ getDecaying(threshold?: number, limit?: number): Promise<Array<DecayState & {
20
+ title: string;
21
+ }>>;
22
+ /**
23
+ * Initialize decay state for documents that don't have one yet.
24
+ */
25
+ initializeNewDocuments(): Promise<number>;
26
+ }
27
+ //# sourceMappingURL=decay-engine.d.ts.map
@@ -0,0 +1,190 @@
1
+ // Design Ref: §3.2 — 감쇠 엔진 (DB 연동)
2
+ // Plan SC: SC-01, SC-02, SC-04
3
+ import { computeRetrievability, updateStability, estimateInitialStability, elapsedDays, FSRS_PARAMS, } from './fsrs.js';
4
+ export class DecayEngine {
5
+ db;
6
+ constructor(db) {
7
+ this.db = db;
8
+ this.ensureTables();
9
+ }
10
+ ensureTables() {
11
+ this.db.exec(`
12
+ CREATE TABLE IF NOT EXISTS access_log (
13
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
14
+ document_id TEXT NOT NULL,
15
+ access_type TEXT NOT NULL,
16
+ accessed_at TEXT NOT NULL
17
+ );
18
+ CREATE INDEX IF NOT EXISTS idx_access_log_doc ON access_log(document_id);
19
+ CREATE INDEX IF NOT EXISTS idx_access_log_time ON access_log(accessed_at);
20
+
21
+ CREATE TABLE IF NOT EXISTS decay_state (
22
+ document_id TEXT PRIMARY KEY,
23
+ stability REAL NOT NULL DEFAULT 7.0,
24
+ difficulty REAL NOT NULL DEFAULT 5.0,
25
+ last_access TEXT NOT NULL,
26
+ retrievability REAL NOT NULL DEFAULT 1.0,
27
+ updated_at TEXT NOT NULL
28
+ );
29
+ `);
30
+ }
31
+ /**
32
+ * Record an access event and update decay state.
33
+ */
34
+ async recordAccess(event) {
35
+ const now = event.timestamp || new Date().toISOString();
36
+ // Log the event
37
+ this.db.prepare('INSERT INTO access_log (document_id, access_type, accessed_at) VALUES (?, ?, ?)').run(event.documentId, event.type, now);
38
+ // Get or create decay state
39
+ const existing = this.db.prepare('SELECT * FROM decay_state WHERE document_id = ?').get(event.documentId);
40
+ if (existing) {
41
+ const elapsed = elapsedDays(existing.last_access, now);
42
+ const currentR = computeRetrievability(existing.stability, elapsed);
43
+ const newS = updateStability(existing.stability, existing.difficulty, currentR);
44
+ this.db.prepare(`
45
+ UPDATE decay_state SET stability = ?, last_access = ?, retrievability = 1.0, updated_at = ?
46
+ WHERE document_id = ?
47
+ `).run(newS, now, now, event.documentId);
48
+ }
49
+ else {
50
+ // New document — estimate initial stability
51
+ const doc = this.db.prepare('SELECT content FROM documents WHERE id = ?').get(event.documentId);
52
+ const contentLen = doc?.content?.length ?? 500;
53
+ const connCount = this.db.prepare('SELECT COUNT(*) as c FROM chunks WHERE document_id = ?').get(event.documentId)?.c ?? 1;
54
+ const initS = estimateInitialStability(contentLen, connCount);
55
+ this.db.prepare(`
56
+ INSERT INTO decay_state (document_id, stability, difficulty, last_access, retrievability, updated_at)
57
+ VALUES (?, ?, ?, ?, 1.0, ?)
58
+ `).run(event.documentId, initS, FSRS_PARAMS.difficulty, now, now);
59
+ }
60
+ }
61
+ /**
62
+ * Batch compute retrievability for all documents.
63
+ */
64
+ async computeAll() {
65
+ const now = new Date().toISOString();
66
+ // Initialize documents that don't have decay state yet
67
+ await this.initializeNewDocuments();
68
+ // Compute R for all
69
+ const states = this.db.prepare('SELECT * FROM decay_state').all();
70
+ const docs = this.db.prepare('SELECT id, title FROM documents').all();
71
+ const titleMap = new Map(docs.map((d) => [d.id, d.title]));
72
+ const updated = [];
73
+ const updateStmt = this.db.prepare('UPDATE decay_state SET retrievability = ?, updated_at = ? WHERE document_id = ?');
74
+ const tx = this.db.transaction(() => {
75
+ for (const s of states) {
76
+ const elapsed = elapsedDays(s.last_access, now);
77
+ const r = computeRetrievability(s.stability, elapsed);
78
+ updateStmt.run(r, now, s.document_id);
79
+ updated.push({
80
+ documentId: s.document_id,
81
+ stability: s.stability,
82
+ difficulty: s.difficulty,
83
+ lastAccess: s.last_access,
84
+ retrievability: r,
85
+ });
86
+ }
87
+ });
88
+ tx();
89
+ // Build report
90
+ const decaying = updated.filter(s => s.retrievability < 0.5);
91
+ const critical = updated.filter(s => s.retrievability < 0.3);
92
+ const avgR = updated.length > 0
93
+ ? updated.reduce((sum, s) => sum + s.retrievability, 0) / updated.length
94
+ : 1.0;
95
+ // Top decaying (sorted by R ascending)
96
+ const topDecaying = [...decaying]
97
+ .sort((a, b) => a.retrievability - b.retrievability)
98
+ .slice(0, 20)
99
+ .map(s => ({
100
+ ...s,
101
+ title: titleMap.get(s.documentId) ?? s.documentId,
102
+ daysSinceAccess: Math.round(elapsedDays(s.lastAccess, now)),
103
+ }));
104
+ // Cluster health
105
+ const clusterData = this.db.prepare(`
106
+ SELECT ds.document_id, ds.retrievability
107
+ FROM decay_state ds
108
+ JOIN documents d ON d.id = ds.document_id
109
+ `).all();
110
+ // Get cluster info from graph data cache (simplified: group by first folder)
111
+ const clusterHealth = this.computeClusterHealth(clusterData);
112
+ return {
113
+ totalDocuments: updated.length,
114
+ decayingCount: decaying.length,
115
+ criticalCount: critical.length,
116
+ averageR: Math.round(avgR * 100) / 100,
117
+ topDecaying,
118
+ clusterHealth,
119
+ };
120
+ }
121
+ computeClusterHealth(data) {
122
+ // Group by document's top-level folder as proxy for cluster
123
+ const groups = new Map();
124
+ for (const row of data) {
125
+ const doc = this.db.prepare('SELECT file_path FROM documents WHERE id = ?').get(row.document_id);
126
+ const folder = doc?.file_path?.split('/')[0] ?? 'unknown';
127
+ if (!groups.has(folder))
128
+ groups.set(folder, []);
129
+ groups.get(folder).push(row.retrievability);
130
+ }
131
+ return [...groups.entries()]
132
+ .map(([label, rs]) => ({
133
+ label,
134
+ avgR: Math.round((rs.reduce((a, b) => a + b, 0) / rs.length) * 100) / 100,
135
+ count: rs.length,
136
+ }))
137
+ .sort((a, b) => a.avgR - b.avgR);
138
+ }
139
+ /**
140
+ * Get documents below decay threshold.
141
+ */
142
+ async getDecaying(threshold = 0.5, limit = 20) {
143
+ await this.computeAll(); // refresh R values
144
+ const rows = this.db.prepare(`
145
+ SELECT ds.*, d.title FROM decay_state ds
146
+ JOIN documents d ON d.id = ds.document_id
147
+ WHERE ds.retrievability < ?
148
+ ORDER BY ds.retrievability ASC
149
+ LIMIT ?
150
+ `).all(threshold, limit);
151
+ return rows.map(r => ({
152
+ documentId: r.document_id,
153
+ stability: r.stability,
154
+ difficulty: r.difficulty,
155
+ lastAccess: r.last_access,
156
+ retrievability: r.retrievability,
157
+ title: r.title,
158
+ }));
159
+ }
160
+ /**
161
+ * Initialize decay state for documents that don't have one yet.
162
+ */
163
+ async initializeNewDocuments() {
164
+ const missing = this.db.prepare(`
165
+ SELECT d.id, d.content, d.last_modified
166
+ FROM documents d
167
+ LEFT JOIN decay_state ds ON d.id = ds.document_id
168
+ WHERE ds.document_id IS NULL
169
+ `).all();
170
+ if (missing.length === 0)
171
+ return 0;
172
+ const insert = this.db.prepare(`
173
+ INSERT OR IGNORE INTO decay_state (document_id, stability, difficulty, last_access, retrievability, updated_at)
174
+ VALUES (?, ?, ?, ?, ?, ?)
175
+ `);
176
+ const tx = this.db.transaction(() => {
177
+ for (const doc of missing) {
178
+ const contentLen = doc.content?.length ?? 500;
179
+ const initS = estimateInitialStability(contentLen, 1);
180
+ const lastAccess = doc.last_modified || new Date().toISOString();
181
+ const elapsed = elapsedDays(lastAccess);
182
+ const r = computeRetrievability(initS, elapsed);
183
+ insert.run(doc.id, initS, FSRS_PARAMS.difficulty, lastAccess, r, new Date().toISOString());
184
+ }
185
+ });
186
+ tx();
187
+ return missing.length;
188
+ }
189
+ }
190
+ //# sourceMappingURL=decay-engine.js.map
@@ -0,0 +1,20 @@
1
+ import type { VectorStore } from '../store/types.js';
2
+ export interface DuplicatePair {
3
+ docA: {
4
+ id: string;
5
+ title: string;
6
+ filePath: string;
7
+ };
8
+ docB: {
9
+ id: string;
10
+ title: string;
11
+ filePath: string;
12
+ };
13
+ similarity: number;
14
+ }
15
+ /**
16
+ * 벡터 유사도 기반 중복 노트 탐지.
17
+ * 문서별 평균 임베딩을 비교하여 threshold 이상인 쌍을 반환.
18
+ */
19
+ export declare function detectDuplicates(store: VectorStore, threshold?: number, limit?: number): Promise<DuplicatePair[]>;
20
+ //# sourceMappingURL=duplicate-detector.d.ts.map
@@ -0,0 +1,55 @@
1
+ // Design Ref: 중복/유사 노트 탐지
2
+ // 기존 벡터 임베딩의 cosine similarity 활용
3
+ /**
4
+ * 벡터 유사도 기반 중복 노트 탐지.
5
+ * 문서별 평균 임베딩을 비교하여 threshold 이상인 쌍을 반환.
6
+ */
7
+ export async function detectDuplicates(store, threshold = 0.88, limit = 20) {
8
+ const docs = await store.getAllDocuments();
9
+ const embeddings = await store.getDocumentEmbeddings();
10
+ if (docs.length < 2)
11
+ return [];
12
+ // 문서별 평균 임베딩 계산
13
+ const docVecs = new Map();
14
+ for (const doc of docs) {
15
+ const vec = embeddings.get(doc.id);
16
+ if (!vec || vec.length === 0)
17
+ continue;
18
+ docVecs.set(doc.id, { vec: Array.from(vec), title: doc.title, filePath: doc.filePath });
19
+ }
20
+ const ids = [...docVecs.keys()];
21
+ const pairs = [];
22
+ // O(n²) — 1,200 문서면 ~720K 비교, 수 초 이내
23
+ for (let i = 0; i < ids.length; i++) {
24
+ for (let j = i + 1; j < ids.length; j++) {
25
+ const a = docVecs.get(ids[i]);
26
+ const b = docVecs.get(ids[j]);
27
+ const sim = cosineSimilarity(a.vec, b.vec);
28
+ if (sim >= threshold) {
29
+ pairs.push({
30
+ docA: { id: ids[i], title: a.title, filePath: a.filePath },
31
+ docB: { id: ids[j], title: b.title, filePath: b.filePath },
32
+ similarity: Math.round(sim * 1000) / 1000,
33
+ });
34
+ }
35
+ }
36
+ if (pairs.length >= limit * 2)
37
+ break; // 충분히 찾으면 중단
38
+ }
39
+ return pairs
40
+ .sort((a, b) => b.similarity - a.similarity)
41
+ .slice(0, limit);
42
+ }
43
+ function cosineSimilarity(a, b) {
44
+ if (a.length !== b.length)
45
+ return 0;
46
+ let dot = 0, normA = 0, normB = 0;
47
+ for (let i = 0; i < a.length; i++) {
48
+ dot += a[i] * b[i];
49
+ normA += a[i] * a[i];
50
+ normB += b[i] * b[i];
51
+ }
52
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
53
+ return denom === 0 ? 0 : dot / denom;
54
+ }
55
+ //# sourceMappingURL=duplicate-detector.js.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * FSRS parameters tuned for knowledge notes (not flashcards).
3
+ * Knowledge notes have longer natural retention than flashcards.
4
+ */
5
+ export declare const FSRS_PARAMS: {
6
+ readonly initialStability: 7;
7
+ readonly difficulty: 5;
8
+ readonly a: 0.4;
9
+ readonly b: 0.6;
10
+ readonly c: 0.2;
11
+ readonly d: 1;
12
+ readonly sizeFactor: 0.5;
13
+ readonly connectionFactor: 1;
14
+ };
15
+ /**
16
+ * Compute retrievability R(t) using FSRS power forgetting curve.
17
+ * R(t) = (1 + t / (9 * S))^(-1)
18
+ *
19
+ * @param stabilityDays - Stability S (days until R drops to ~0.9)
20
+ * @param elapsedDays - Days since last access
21
+ * @returns Retrievability 0~1
22
+ */
23
+ export declare function computeRetrievability(stabilityDays: number, elapsedDays: number): number;
24
+ /**
25
+ * Update stability after an access event (successful recall).
26
+ * S' = S * (1 + a * D^(-b) * S^(-c) * (e^(d*(1-R)) - 1))
27
+ *
28
+ * @param currentS - Current stability
29
+ * @param difficulty - Note difficulty (1~10)
30
+ * @param currentR - Retrievability at access time
31
+ * @returns New stability (always >= currentS)
32
+ */
33
+ export declare function updateStability(currentS: number, difficulty: number, currentR: number): number;
34
+ /**
35
+ * Estimate initial stability based on note characteristics.
36
+ * Longer notes and more connected notes are more stable.
37
+ */
38
+ export declare function estimateInitialStability(contentLength: number, connectionCount: number): number;
39
+ /**
40
+ * Compute elapsed days between two ISO timestamps.
41
+ */
42
+ export declare function elapsedDays(from: string, to?: string): number;
43
+ //# sourceMappingURL=fsrs.d.ts.map
@@ -0,0 +1,70 @@
1
+ // Design Ref: §1 — FSRS-6 알고리즘 (순수 함수)
2
+ // Plan SC: SC-01 (R값 계산), SC-02 (stability 업데이트)
3
+ /**
4
+ * FSRS parameters tuned for knowledge notes (not flashcards).
5
+ * Knowledge notes have longer natural retention than flashcards.
6
+ */
7
+ export const FSRS_PARAMS = {
8
+ initialStability: 7.0, // 7 days for new notes
9
+ difficulty: 5.0, // default difficulty (1~10)
10
+ // Stability growth factors
11
+ a: 0.4,
12
+ b: 0.6,
13
+ c: 0.2,
14
+ d: 1.0,
15
+ // Stability bonus for large/connected notes
16
+ sizeFactor: 0.5, // additional days per 1000 chars
17
+ connectionFactor: 1.0, // additional days per connection
18
+ };
19
+ /**
20
+ * Compute retrievability R(t) using FSRS power forgetting curve.
21
+ * R(t) = (1 + t / (9 * S))^(-1)
22
+ *
23
+ * @param stabilityDays - Stability S (days until R drops to ~0.9)
24
+ * @param elapsedDays - Days since last access
25
+ * @returns Retrievability 0~1
26
+ */
27
+ export function computeRetrievability(stabilityDays, elapsedDays) {
28
+ if (elapsedDays <= 0)
29
+ return 1.0;
30
+ if (stabilityDays <= 0)
31
+ return 0.0;
32
+ return Math.pow(1 + elapsedDays / (9 * stabilityDays), -1);
33
+ }
34
+ /**
35
+ * Update stability after an access event (successful recall).
36
+ * S' = S * (1 + a * D^(-b) * S^(-c) * (e^(d*(1-R)) - 1))
37
+ *
38
+ * @param currentS - Current stability
39
+ * @param difficulty - Note difficulty (1~10)
40
+ * @param currentR - Retrievability at access time
41
+ * @returns New stability (always >= currentS)
42
+ */
43
+ export function updateStability(currentS, difficulty, currentR) {
44
+ const { a, b, c, d } = FSRS_PARAMS;
45
+ const growth = a
46
+ * Math.pow(difficulty, -b)
47
+ * Math.pow(currentS, -c)
48
+ * (Math.exp(d * (1 - currentR)) - 1);
49
+ const newS = currentS * (1 + Math.max(0, growth));
50
+ // Cap at 365 days (1 year max stability)
51
+ return Math.min(newS, 365);
52
+ }
53
+ /**
54
+ * Estimate initial stability based on note characteristics.
55
+ * Longer notes and more connected notes are more stable.
56
+ */
57
+ export function estimateInitialStability(contentLength, connectionCount) {
58
+ const base = FSRS_PARAMS.initialStability;
59
+ const sizeBonus = Math.min(contentLength / 1000, 10) * FSRS_PARAMS.sizeFactor;
60
+ const connBonus = Math.min(connectionCount, 10) * FSRS_PARAMS.connectionFactor;
61
+ return base + sizeBonus + connBonus;
62
+ }
63
+ /**
64
+ * Compute elapsed days between two ISO timestamps.
65
+ */
66
+ export function elapsedDays(from, to = new Date().toISOString()) {
67
+ const msPerDay = 86400000;
68
+ return Math.max(0, (new Date(to).getTime() - new Date(from).getTime()) / msPerDay);
69
+ }
70
+ //# sourceMappingURL=fsrs.js.map
@@ -0,0 +1,25 @@
1
+ import type { VectorStore } from '../store/types.js';
2
+ export interface KnowledgeGap {
3
+ clusterA: string;
4
+ clusterB: string;
5
+ bridgeCount: number;
6
+ suggestedTopic: string;
7
+ severity: 'high' | 'medium' | 'low';
8
+ }
9
+ export interface GapReport {
10
+ totalClusters: number;
11
+ totalGaps: number;
12
+ gaps: KnowledgeGap[];
13
+ isolatedNodes: Array<{
14
+ id: string;
15
+ title: string;
16
+ connections: number;
17
+ }>;
18
+ }
19
+ /**
20
+ * 그래프 데이터에서 지식 갭을 탐지.
21
+ * - 클러스터 간 연결이 약한 영역
22
+ * - 고립된 노드 (연결 0~1개)
23
+ */
24
+ export declare function detectKnowledgeGaps(store: VectorStore, graphData?: any): Promise<GapReport>;
25
+ //# sourceMappingURL=gap-detector.d.ts.map
@@ -0,0 +1,78 @@
1
+ // Design Ref: F01 — 지식 갭 탐지기
2
+ // 클러스터 간 브릿지 노드 부족 영역 식별
3
+ /**
4
+ * 그래프 데이터에서 지식 갭을 탐지.
5
+ * - 클러스터 간 연결이 약한 영역
6
+ * - 고립된 노드 (연결 0~1개)
7
+ */
8
+ export async function detectKnowledgeGaps(store, graphData) {
9
+ const docs = await store.getAllDocuments();
10
+ const embeddings = await store.getDocumentEmbeddings();
11
+ // 그래프 데이터가 없으면 간단히 계산
12
+ if (!graphData) {
13
+ const { buildGraphData } = await import('../api/graph-data.js');
14
+ graphData = await buildGraphData(store);
15
+ }
16
+ const { nodes, edges, clusters } = graphData;
17
+ // 1. 클러스터 간 연결 수 매트릭스
18
+ const clusterEdges = new Map();
19
+ for (const edge of edges) {
20
+ const nodeA = nodes.find((n) => n.id === edge.source);
21
+ const nodeB = nodes.find((n) => n.id === edge.target);
22
+ if (!nodeA || !nodeB || nodeA.clusterId === nodeB.clusterId)
23
+ continue;
24
+ const key = [
25
+ Math.min(nodeA.clusterId, nodeB.clusterId),
26
+ Math.max(nodeA.clusterId, nodeB.clusterId),
27
+ ].join('-');
28
+ clusterEdges.set(key, (clusterEdges.get(key) ?? 0) + 1);
29
+ }
30
+ // 2. 갭 식별 (클러스터 쌍 중 연결이 적은 것)
31
+ const gaps = [];
32
+ const clusterLabels = new Map(clusters.map((c) => [c.id, c.label]));
33
+ for (let i = 0; i < clusters.length; i++) {
34
+ for (let j = i + 1; j < clusters.length; j++) {
35
+ const key = `${Math.min(clusters[i].id, clusters[j].id)}-${Math.max(clusters[i].id, clusters[j].id)}`;
36
+ const bridgeCount = clusterEdges.get(key) ?? 0;
37
+ // 연결이 3개 미만이면 갭
38
+ if (bridgeCount < 3) {
39
+ const labelA = clusterLabels.get(clusters[i].id) ?? `Cluster ${clusters[i].id}`;
40
+ const labelB = clusterLabels.get(clusters[j].id) ?? `Cluster ${clusters[j].id}`;
41
+ // 제안 주제: 두 클러스터 이름에서 추출
42
+ const nameA = labelA.replace(/\s*\(\d+\)$/, '');
43
+ const nameB = labelB.replace(/\s*\(\d+\)$/, '');
44
+ gaps.push({
45
+ clusterA: labelA,
46
+ clusterB: labelB,
47
+ bridgeCount,
48
+ suggestedTopic: `${nameA} + ${nameB} 연결 지식`,
49
+ severity: bridgeCount === 0 ? 'high' : bridgeCount < 2 ? 'medium' : 'low',
50
+ });
51
+ }
52
+ }
53
+ }
54
+ // 3. 고립 노드 (연결 1개 이하)
55
+ const connectionCounts = new Map();
56
+ for (const edge of edges) {
57
+ connectionCounts.set(edge.source, (connectionCounts.get(edge.source) ?? 0) + 1);
58
+ connectionCounts.set(edge.target, (connectionCounts.get(edge.target) ?? 0) + 1);
59
+ }
60
+ const isolatedNodes = nodes
61
+ .filter((n) => (connectionCounts.get(n.id) ?? 0) <= 1)
62
+ .map((n) => ({
63
+ id: n.id,
64
+ title: n.label,
65
+ connections: connectionCounts.get(n.id) ?? 0,
66
+ }))
67
+ .slice(0, 20);
68
+ return {
69
+ totalClusters: clusters.length,
70
+ totalGaps: gaps.filter(g => g.severity !== 'low').length,
71
+ gaps: gaps.sort((a, b) => {
72
+ const sev = { high: 0, medium: 1, low: 2 };
73
+ return sev[a.severity] - sev[b.severity];
74
+ }).slice(0, 15),
75
+ isolatedNodes,
76
+ };
77
+ }
78
+ //# sourceMappingURL=gap-detector.js.map
@@ -0,0 +1,31 @@
1
+ import type { DecayReport } from './types.js';
2
+ export interface LearningItem {
3
+ documentId: string;
4
+ title: string;
5
+ reason: string;
6
+ priority: 'critical' | 'important' | 'suggested';
7
+ score: number;
8
+ category: 'review' | 'explore' | 'bridge';
9
+ }
10
+ export interface LearningPath {
11
+ items: LearningItem[];
12
+ summary: {
13
+ reviewCount: number;
14
+ exploreCount: number;
15
+ bridgeCount: number;
16
+ estimatedMinutes: number;
17
+ };
18
+ generatedAt: string;
19
+ }
20
+ export interface LearningPathInput {
21
+ decayReport: DecayReport;
22
+ gaps?: Array<{
23
+ clusterA: string;
24
+ clusterB: string;
25
+ severity: string;
26
+ suggestedTopic: string;
27
+ }>;
28
+ recentSearches?: string[];
29
+ }
30
+ export declare function generateLearningPath(input: LearningPathInput, limit?: number): LearningPath;
31
+ //# sourceMappingURL=learning-path.d.ts.map