stellavault 0.1.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 (385) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/bin/ekh.js +2 -2
  3. package/packages/cli/dist/commands/federate-cmd.js +61 -31
  4. package/packages/core/dist/api/dashboard.d.ts +3 -0
  5. package/packages/core/{src/api/dashboard.ts → dist/api/dashboard.js} +8 -11
  6. package/packages/core/dist/api/graph-data.d.ts +11 -0
  7. package/packages/core/dist/api/graph-data.js +255 -0
  8. package/packages/core/dist/api/pwa.d.ts +3 -0
  9. package/packages/core/{src/api/pwa.ts → dist/api/pwa.js} +27 -32
  10. package/packages/core/dist/api/server.d.ts +16 -0
  11. package/packages/core/dist/api/server.js +647 -0
  12. package/packages/core/dist/capture/voice.d.ts +24 -0
  13. package/packages/core/dist/capture/voice.js +135 -0
  14. package/packages/core/{src/cloud/index.ts → dist/cloud/index.d.ts} +1 -0
  15. package/packages/core/dist/cloud/index.js +2 -0
  16. package/packages/core/dist/cloud/sync.d.ts +29 -0
  17. package/packages/core/dist/cloud/sync.js +137 -0
  18. package/packages/core/dist/config.d.ts +27 -0
  19. package/packages/core/dist/config.js +55 -0
  20. package/packages/core/dist/federation/credits.d.ts +26 -0
  21. package/packages/core/dist/federation/credits.js +56 -0
  22. package/packages/core/dist/federation/identity.d.ts +14 -0
  23. package/packages/core/dist/federation/identity.js +74 -0
  24. package/packages/core/{src/federation/index.ts → dist/federation/index.d.ts} +1 -2
  25. package/packages/core/dist/federation/index.js +5 -0
  26. package/packages/core/dist/federation/node.d.ts +31 -0
  27. package/packages/core/dist/federation/node.js +216 -0
  28. package/packages/core/dist/federation/privacy.d.ts +8 -0
  29. package/packages/core/dist/federation/privacy.js +40 -0
  30. package/packages/core/dist/federation/reputation.d.ts +37 -0
  31. package/packages/core/dist/federation/reputation.js +139 -0
  32. package/packages/core/dist/federation/search.d.ts +19 -0
  33. package/packages/core/dist/federation/search.js +101 -0
  34. package/packages/core/dist/federation/sharing.d.ts +72 -0
  35. package/packages/core/dist/federation/sharing.js +246 -0
  36. package/packages/core/dist/federation/trust.d.ts +15 -0
  37. package/packages/core/dist/federation/trust.js +60 -0
  38. package/packages/core/dist/federation/types.d.ts +40 -0
  39. package/packages/core/dist/federation/types.js +3 -0
  40. package/packages/core/dist/i18n/index.d.ts +6 -0
  41. package/packages/core/dist/i18n/index.js +81 -0
  42. package/packages/core/{src/index.ts → dist/index.d.ts} +48 -67
  43. package/packages/core/dist/index.js +69 -0
  44. package/packages/core/dist/indexer/chunker.d.ts +14 -0
  45. package/packages/core/dist/indexer/chunker.js +148 -0
  46. package/packages/core/dist/indexer/embedder.d.ts +8 -0
  47. package/packages/core/dist/indexer/embedder.js +3 -0
  48. package/packages/core/dist/indexer/index.d.ts +28 -0
  49. package/packages/core/dist/indexer/index.js +74 -0
  50. package/packages/core/dist/indexer/local-embedder.d.ts +3 -0
  51. package/packages/core/dist/indexer/local-embedder.js +29 -0
  52. package/packages/core/dist/indexer/scanner.d.ts +11 -0
  53. package/packages/core/dist/indexer/scanner.js +137 -0
  54. package/packages/core/dist/indexer/watcher.d.ts +19 -0
  55. package/packages/core/dist/indexer/watcher.js +49 -0
  56. package/packages/core/dist/intelligence/contradiction-detector.d.ts +20 -0
  57. package/packages/core/dist/intelligence/contradiction-detector.js +115 -0
  58. package/packages/core/dist/intelligence/decay-engine.d.ts +27 -0
  59. package/packages/core/dist/intelligence/decay-engine.js +190 -0
  60. package/packages/core/dist/intelligence/duplicate-detector.d.ts +20 -0
  61. package/packages/core/dist/intelligence/duplicate-detector.js +55 -0
  62. package/packages/core/dist/intelligence/fsrs.d.ts +43 -0
  63. package/packages/core/dist/intelligence/fsrs.js +70 -0
  64. package/packages/core/dist/intelligence/gap-detector.d.ts +25 -0
  65. package/packages/core/dist/intelligence/gap-detector.js +78 -0
  66. package/packages/core/dist/intelligence/learning-path.d.ts +31 -0
  67. package/packages/core/dist/intelligence/learning-path.js +53 -0
  68. package/packages/core/dist/intelligence/notifications.d.ts +31 -0
  69. package/packages/core/dist/intelligence/notifications.js +65 -0
  70. package/packages/core/dist/intelligence/predictive-gaps.d.ts +14 -0
  71. package/packages/core/dist/intelligence/predictive-gaps.js +74 -0
  72. package/packages/core/dist/intelligence/semantic-versioning.d.ts +37 -0
  73. package/packages/core/dist/intelligence/semantic-versioning.js +68 -0
  74. package/packages/core/dist/intelligence/types.d.ts +28 -0
  75. package/packages/core/dist/intelligence/types.js +3 -0
  76. package/packages/core/dist/mcp/custom-tools.d.ts +29 -0
  77. package/packages/core/dist/mcp/custom-tools.js +70 -0
  78. package/packages/core/{src/mcp/index.ts → dist/mcp/index.d.ts} +1 -0
  79. package/packages/core/dist/mcp/index.js +2 -0
  80. package/packages/core/dist/mcp/server.d.ts +49 -0
  81. package/packages/core/dist/mcp/server.js +133 -0
  82. package/packages/core/dist/mcp/tools/agentic-graph.d.ts +87 -0
  83. package/packages/core/dist/mcp/tools/agentic-graph.js +88 -0
  84. package/packages/core/dist/mcp/tools/brief.d.ts +31 -0
  85. package/packages/core/dist/mcp/tools/brief.js +39 -0
  86. package/packages/core/dist/mcp/tools/decay.d.ts +33 -0
  87. package/packages/core/dist/mcp/tools/decay.js +32 -0
  88. package/packages/core/dist/mcp/tools/decision-journal.d.ts +78 -0
  89. package/packages/core/dist/mcp/tools/decision-journal.js +79 -0
  90. package/packages/core/dist/mcp/tools/export.d.ts +29 -0
  91. package/packages/core/dist/mcp/tools/export.js +60 -0
  92. package/packages/core/dist/mcp/tools/federated-search.d.ts +29 -0
  93. package/packages/core/dist/mcp/tools/federated-search.js +36 -0
  94. package/packages/core/dist/mcp/tools/generate-claude-md.d.ts +35 -0
  95. package/packages/core/dist/mcp/tools/generate-claude-md.js +107 -0
  96. package/packages/core/dist/mcp/tools/get-document.d.ts +35 -0
  97. package/packages/core/dist/mcp/tools/get-document.js +25 -0
  98. package/packages/core/dist/mcp/tools/get-related.d.ts +32 -0
  99. package/packages/core/dist/mcp/tools/get-related.js +33 -0
  100. package/packages/core/dist/mcp/tools/learning-path.d.ts +23 -0
  101. package/packages/core/dist/mcp/tools/learning-path.js +45 -0
  102. package/packages/core/dist/mcp/tools/list-topics.d.ts +15 -0
  103. package/packages/core/dist/mcp/tools/list-topics.js +18 -0
  104. package/packages/core/dist/mcp/tools/search.d.ts +39 -0
  105. package/packages/core/dist/mcp/tools/search.js +29 -0
  106. package/packages/core/dist/mcp/tools/snapshot.d.ts +47 -0
  107. package/packages/core/dist/mcp/tools/snapshot.js +84 -0
  108. package/packages/core/dist/multi-vault/index.d.ts +26 -0
  109. package/packages/core/dist/multi-vault/index.js +80 -0
  110. package/packages/core/dist/pack/creator.d.ts +21 -0
  111. package/packages/core/dist/pack/creator.js +105 -0
  112. package/packages/core/dist/pack/exporter.d.ts +4 -0
  113. package/packages/core/dist/pack/exporter.js +18 -0
  114. package/packages/core/dist/pack/importer.d.ts +10 -0
  115. package/packages/core/dist/pack/importer.js +55 -0
  116. package/packages/core/{src/pack/index.ts → dist/pack/index.d.ts} +1 -0
  117. package/packages/core/dist/pack/index.js +5 -0
  118. package/packages/core/dist/pack/marketplace.d.ts +14 -0
  119. package/packages/core/dist/pack/marketplace.js +90 -0
  120. package/packages/core/dist/pack/pii-masker.d.ts +7 -0
  121. package/packages/core/dist/pack/pii-masker.js +29 -0
  122. package/packages/core/dist/pack/types.d.ts +36 -0
  123. package/packages/core/dist/pack/types.js +3 -0
  124. package/packages/core/dist/plugins/index.d.ts +35 -0
  125. package/packages/core/dist/plugins/index.js +57 -0
  126. package/packages/core/dist/plugins/webhooks.d.ts +30 -0
  127. package/packages/core/dist/plugins/webhooks.js +79 -0
  128. package/packages/core/dist/search/bm25.d.ts +4 -0
  129. package/packages/core/dist/search/bm25.js +10 -0
  130. package/packages/core/dist/search/index.d.ts +13 -0
  131. package/packages/core/dist/search/index.js +63 -0
  132. package/packages/core/dist/search/rrf.d.ts +7 -0
  133. package/packages/core/dist/search/rrf.js +21 -0
  134. package/packages/core/dist/search/semantic.d.ts +5 -0
  135. package/packages/core/dist/search/semantic.js +6 -0
  136. package/packages/core/{src/store/index.ts → dist/store/index.d.ts} +1 -0
  137. package/packages/core/dist/store/index.js +2 -0
  138. package/packages/core/dist/store/sqlite-vec.d.ts +6 -0
  139. package/packages/core/dist/store/sqlite-vec.js +251 -0
  140. package/packages/core/dist/store/types.d.ts +20 -0
  141. package/packages/core/dist/store/types.js +3 -0
  142. package/packages/core/dist/team/index.d.ts +25 -0
  143. package/packages/core/dist/team/index.js +97 -0
  144. package/packages/core/dist/types/chunk.d.ts +23 -0
  145. package/packages/core/dist/types/chunk.js +3 -0
  146. package/packages/core/dist/types/document.d.ts +23 -0
  147. package/packages/core/dist/types/document.js +3 -0
  148. package/packages/core/dist/types/graph.d.ts +39 -0
  149. package/packages/core/dist/types/graph.js +3 -0
  150. package/packages/core/dist/types/index.d.ts +5 -0
  151. package/packages/core/dist/types/index.js +2 -0
  152. package/packages/core/dist/types/search.d.ts +39 -0
  153. package/packages/core/dist/types/search.js +3 -0
  154. package/packages/core/dist/utils/retry.d.ts +25 -0
  155. package/packages/core/dist/utils/retry.js +59 -0
  156. package/memory/MEMORY.md +0 -25
  157. package/packages/cli/dist/commands/brief-cmd.d.ts.map +0 -1
  158. package/packages/cli/dist/commands/brief-cmd.js.map +0 -1
  159. package/packages/cli/dist/commands/capture-cmd.d.ts.map +0 -1
  160. package/packages/cli/dist/commands/capture-cmd.js.map +0 -1
  161. package/packages/cli/dist/commands/card-cmd.d.ts.map +0 -1
  162. package/packages/cli/dist/commands/card-cmd.js.map +0 -1
  163. package/packages/cli/dist/commands/clip-cmd.d.ts.map +0 -1
  164. package/packages/cli/dist/commands/clip-cmd.js.map +0 -1
  165. package/packages/cli/dist/commands/cloud-cmd.d.ts.map +0 -1
  166. package/packages/cli/dist/commands/cloud-cmd.js.map +0 -1
  167. package/packages/cli/dist/commands/contradictions-cmd.d.ts.map +0 -1
  168. package/packages/cli/dist/commands/contradictions-cmd.js.map +0 -1
  169. package/packages/cli/dist/commands/decay-cmd.d.ts.map +0 -1
  170. package/packages/cli/dist/commands/decay-cmd.js.map +0 -1
  171. package/packages/cli/dist/commands/digest-cmd.d.ts.map +0 -1
  172. package/packages/cli/dist/commands/digest-cmd.js.map +0 -1
  173. package/packages/cli/dist/commands/duplicates-cmd.d.ts.map +0 -1
  174. package/packages/cli/dist/commands/duplicates-cmd.js.map +0 -1
  175. package/packages/cli/dist/commands/federate-cmd.d.ts.map +0 -1
  176. package/packages/cli/dist/commands/federate-cmd.js.map +0 -1
  177. package/packages/cli/dist/commands/gaps-cmd.d.ts.map +0 -1
  178. package/packages/cli/dist/commands/gaps-cmd.js.map +0 -1
  179. package/packages/cli/dist/commands/graph-cmd.d.ts.map +0 -1
  180. package/packages/cli/dist/commands/graph-cmd.js.map +0 -1
  181. package/packages/cli/dist/commands/index-cmd.d.ts.map +0 -1
  182. package/packages/cli/dist/commands/index-cmd.js.map +0 -1
  183. package/packages/cli/dist/commands/init-cmd.d.ts.map +0 -1
  184. package/packages/cli/dist/commands/init-cmd.js.map +0 -1
  185. package/packages/cli/dist/commands/learn-cmd.d.ts.map +0 -1
  186. package/packages/cli/dist/commands/learn-cmd.js.map +0 -1
  187. package/packages/cli/dist/commands/pack-cmd.d.ts.map +0 -1
  188. package/packages/cli/dist/commands/pack-cmd.js.map +0 -1
  189. package/packages/cli/dist/commands/review-cmd.d.ts.map +0 -1
  190. package/packages/cli/dist/commands/review-cmd.js.map +0 -1
  191. package/packages/cli/dist/commands/search-cmd.d.ts.map +0 -1
  192. package/packages/cli/dist/commands/search-cmd.js.map +0 -1
  193. package/packages/cli/dist/commands/serve-cmd.d.ts.map +0 -1
  194. package/packages/cli/dist/commands/serve-cmd.js.map +0 -1
  195. package/packages/cli/dist/commands/status-cmd.d.ts.map +0 -1
  196. package/packages/cli/dist/commands/status-cmd.js.map +0 -1
  197. package/packages/cli/dist/commands/sync-cmd.d.ts.map +0 -1
  198. package/packages/cli/dist/commands/sync-cmd.js.map +0 -1
  199. package/packages/cli/dist/commands/vault-cmd.d.ts.map +0 -1
  200. package/packages/cli/dist/commands/vault-cmd.js.map +0 -1
  201. package/packages/cli/dist/index.d.ts.map +0 -1
  202. package/packages/cli/dist/index.js.map +0 -1
  203. package/packages/cli/src/commands/brief-cmd.ts +0 -87
  204. package/packages/cli/src/commands/capture-cmd.ts +0 -34
  205. package/packages/cli/src/commands/card-cmd.ts +0 -29
  206. package/packages/cli/src/commands/clip-cmd.ts +0 -172
  207. package/packages/cli/src/commands/cloud-cmd.ts +0 -75
  208. package/packages/cli/src/commands/contradictions-cmd.ts +0 -41
  209. package/packages/cli/src/commands/decay-cmd.ts +0 -57
  210. package/packages/cli/src/commands/digest-cmd.ts +0 -89
  211. package/packages/cli/src/commands/duplicates-cmd.ts +0 -38
  212. package/packages/cli/src/commands/federate-cmd.ts +0 -236
  213. package/packages/cli/src/commands/gaps-cmd.ts +0 -40
  214. package/packages/cli/src/commands/graph-cmd.ts +0 -88
  215. package/packages/cli/src/commands/index-cmd.ts +0 -65
  216. package/packages/cli/src/commands/init-cmd.ts +0 -145
  217. package/packages/cli/src/commands/learn-cmd.ts +0 -56
  218. package/packages/cli/src/commands/pack-cmd.ts +0 -121
  219. package/packages/cli/src/commands/review-cmd.ts +0 -125
  220. package/packages/cli/src/commands/search-cmd.ts +0 -45
  221. package/packages/cli/src/commands/serve-cmd.ts +0 -17
  222. package/packages/cli/src/commands/status-cmd.ts +0 -37
  223. package/packages/cli/src/commands/sync-cmd.ts +0 -68
  224. package/packages/cli/src/commands/vault-cmd.ts +0 -64
  225. package/packages/cli/src/index.ts +0 -187
  226. package/packages/core/src/api/graph-data.ts +0 -286
  227. package/packages/core/src/api/server.ts +0 -660
  228. package/packages/core/src/capture/voice.ts +0 -168
  229. package/packages/core/src/cloud/sync.ts +0 -167
  230. package/packages/core/src/config.ts +0 -82
  231. package/packages/core/src/federation/credits.ts +0 -80
  232. package/packages/core/src/federation/hyperswarm.d.ts +0 -19
  233. package/packages/core/src/federation/identity.ts +0 -90
  234. package/packages/core/src/federation/node.ts +0 -235
  235. package/packages/core/src/federation/privacy.ts +0 -52
  236. package/packages/core/src/federation/reputation.ts +0 -202
  237. package/packages/core/src/federation/search.ts +0 -129
  238. package/packages/core/src/federation/sharing.ts +0 -165
  239. package/packages/core/src/federation/trust.ts +0 -76
  240. package/packages/core/src/federation/types.ts +0 -25
  241. package/packages/core/src/i18n/index.ts +0 -85
  242. package/packages/core/src/indexer/chunker.ts +0 -180
  243. package/packages/core/src/indexer/embedder.ts +0 -9
  244. package/packages/core/src/indexer/index.ts +0 -113
  245. package/packages/core/src/indexer/local-embedder.ts +0 -35
  246. package/packages/core/src/indexer/scanner.ts +0 -142
  247. package/packages/core/src/indexer/watcher.ts +0 -62
  248. package/packages/core/src/intelligence/contradiction-detector.ts +0 -134
  249. package/packages/core/src/intelligence/decay-engine.ts +0 -229
  250. package/packages/core/src/intelligence/duplicate-detector.ts +0 -71
  251. package/packages/core/src/intelligence/fsrs.ts +0 -79
  252. package/packages/core/src/intelligence/gap-detector.ts +0 -109
  253. package/packages/core/src/intelligence/learning-path.ts +0 -86
  254. package/packages/core/src/intelligence/notifications.ts +0 -106
  255. package/packages/core/src/intelligence/predictive-gaps.ts +0 -94
  256. package/packages/core/src/intelligence/semantic-versioning.ts +0 -97
  257. package/packages/core/src/intelligence/types.ts +0 -28
  258. package/packages/core/src/mcp/custom-tools.ts +0 -97
  259. package/packages/core/src/mcp/server.ts +0 -142
  260. package/packages/core/src/mcp/tools/agentic-graph.ts +0 -96
  261. package/packages/core/src/mcp/tools/brief.ts +0 -49
  262. package/packages/core/src/mcp/tools/decay.ts +0 -40
  263. package/packages/core/src/mcp/tools/decision-journal.ts +0 -95
  264. package/packages/core/src/mcp/tools/export.ts +0 -72
  265. package/packages/core/src/mcp/tools/federated-search.ts +0 -43
  266. package/packages/core/src/mcp/tools/generate-claude-md.ts +0 -130
  267. package/packages/core/src/mcp/tools/get-document.ts +0 -26
  268. package/packages/core/src/mcp/tools/get-related.ts +0 -41
  269. package/packages/core/src/mcp/tools/learning-path.ts +0 -52
  270. package/packages/core/src/mcp/tools/list-topics.ts +0 -20
  271. package/packages/core/src/mcp/tools/search.ts +0 -35
  272. package/packages/core/src/mcp/tools/snapshot.ts +0 -98
  273. package/packages/core/src/multi-vault/index.ts +0 -118
  274. package/packages/core/src/pack/creator.ts +0 -127
  275. package/packages/core/src/pack/exporter.ts +0 -21
  276. package/packages/core/src/pack/importer.ts +0 -82
  277. package/packages/core/src/pack/marketplace.ts +0 -103
  278. package/packages/core/src/pack/pii-masker.ts +0 -38
  279. package/packages/core/src/pack/types.ts +0 -39
  280. package/packages/core/src/plugins/index.ts +0 -100
  281. package/packages/core/src/plugins/webhooks.ts +0 -110
  282. package/packages/core/src/search/bm25.ts +0 -16
  283. package/packages/core/src/search/index.ts +0 -83
  284. package/packages/core/src/search/rrf.ts +0 -31
  285. package/packages/core/src/search/semantic.ts +0 -15
  286. package/packages/core/src/store/sqlite-vec.ts +0 -290
  287. package/packages/core/src/store/types.ts +0 -22
  288. package/packages/core/src/team/index.ts +0 -126
  289. package/packages/core/src/types/chunk.ts +0 -25
  290. package/packages/core/src/types/document.ts +0 -24
  291. package/packages/core/src/types/graph.ts +0 -44
  292. package/packages/core/src/types/index.ts +0 -15
  293. package/packages/core/src/types/search.ts +0 -38
  294. package/packages/core/src/utils/retry.ts +0 -85
  295. package/packages/core/tests/api-card.test.ts +0 -60
  296. package/packages/core/tests/api-routes.test.ts +0 -98
  297. package/packages/core/tests/bm25.test.ts +0 -87
  298. package/packages/core/tests/chunker.test.ts +0 -48
  299. package/packages/core/tests/cluster.test.ts +0 -75
  300. package/packages/core/tests/constellation.test.ts +0 -77
  301. package/packages/core/tests/export-utils.test.ts +0 -97
  302. package/packages/core/tests/fsrs.test.ts +0 -96
  303. package/packages/core/tests/gesture-detector.test.ts +0 -45
  304. package/packages/core/tests/graph-data.test.ts +0 -87
  305. package/packages/core/tests/layout.test.ts +0 -83
  306. package/packages/core/tests/mcp.test.ts +0 -148
  307. package/packages/core/tests/pack.test.ts +0 -127
  308. package/packages/core/tests/pii-masker.test.ts +0 -42
  309. package/packages/core/tests/profile-card.test.ts +0 -62
  310. package/packages/core/tests/rrf.test.ts +0 -29
  311. package/packages/core/tests/search-integration.test.ts +0 -139
  312. package/packages/core/tests/store.test.ts +0 -80
  313. package/packages/graph/click-result.png +0 -0
  314. package/packages/graph/index.html +0 -17
  315. package/packages/graph/package.json +0 -32
  316. package/packages/graph/src/App.tsx +0 -7
  317. package/packages/graph/src/api/client.ts +0 -39
  318. package/packages/graph/src/components/ClusterFilter.tsx +0 -73
  319. package/packages/graph/src/components/ConstellationView.tsx +0 -232
  320. package/packages/graph/src/components/ExportPanel.tsx +0 -177
  321. package/packages/graph/src/components/Graph3D.tsx +0 -230
  322. package/packages/graph/src/components/GraphEdges.tsx +0 -100
  323. package/packages/graph/src/components/GraphNodes.tsx +0 -386
  324. package/packages/graph/src/components/HealthDashboard.tsx +0 -173
  325. package/packages/graph/src/components/Layout.tsx +0 -214
  326. package/packages/graph/src/components/MotionOverlay.tsx +0 -81
  327. package/packages/graph/src/components/MotionToggle.tsx +0 -33
  328. package/packages/graph/src/components/MultiverseView.tsx +0 -286
  329. package/packages/graph/src/components/NodeDetail.tsx +0 -232
  330. package/packages/graph/src/components/PulseParticle.tsx +0 -232
  331. package/packages/graph/src/components/SearchBar.tsx +0 -107
  332. package/packages/graph/src/components/StarField.tsx +0 -197
  333. package/packages/graph/src/components/StatusBar.tsx +0 -53
  334. package/packages/graph/src/components/Timeline.tsx +0 -148
  335. package/packages/graph/src/components/ToolsPanel.tsx +0 -512
  336. package/packages/graph/src/components/Tooltip.tsx +0 -100
  337. package/packages/graph/src/components/TypeFilter.tsx +0 -131
  338. package/packages/graph/src/embed/EmbedGraph.tsx +0 -144
  339. package/packages/graph/src/hooks/useConstellationLOD.ts +0 -76
  340. package/packages/graph/src/hooks/useDecay.ts +0 -37
  341. package/packages/graph/src/hooks/useExport.ts +0 -165
  342. package/packages/graph/src/hooks/useGraph.ts +0 -69
  343. package/packages/graph/src/hooks/useKeyboardNav.ts +0 -122
  344. package/packages/graph/src/hooks/useLayout.ts +0 -45
  345. package/packages/graph/src/hooks/useMotion.ts +0 -120
  346. package/packages/graph/src/hooks/usePulse.ts +0 -58
  347. package/packages/graph/src/hooks/useSearch.ts +0 -71
  348. package/packages/graph/src/lib/constellation.ts +0 -107
  349. package/packages/graph/src/lib/export-utils.ts +0 -48
  350. package/packages/graph/src/lib/gesture-detector.ts +0 -123
  351. package/packages/graph/src/lib/layout.worker.ts +0 -153
  352. package/packages/graph/src/lib/motion-controller.ts +0 -83
  353. package/packages/graph/src/lib/profile-card.ts +0 -122
  354. package/packages/graph/src/main.tsx +0 -4
  355. package/packages/graph/src/stores/graph-store.ts +0 -155
  356. package/packages/graph/success.png +0 -0
  357. package/packages/graph/test-click.mjs +0 -49
  358. package/packages/graph/test-explore.mjs +0 -102
  359. package/packages/graph/test-final.mjs +0 -61
  360. package/packages/graph/test-graph.mjs +0 -139
  361. package/packages/graph/test-hover.mjs +0 -48
  362. package/packages/graph/test-pulse.mjs +0 -68
  363. package/packages/graph/test-screenshot.mjs +0 -56
  364. package/packages/graph/test-v2.mjs +0 -97
  365. package/packages/graph/vite.config.ts +0 -15
  366. package/packages/sync/.env.example +0 -11
  367. package/packages/sync/.sync-state.json +0 -317
  368. package/packages/sync/.upload-state.json +0 -1009
  369. package/packages/sync/create-stella-network-notion.mjs +0 -151
  370. package/packages/sync/create-stellavault-project-notion.mjs +0 -322
  371. package/packages/sync/logs/sync-2026-03-28.log +0 -6
  372. package/packages/sync/logs/sync-2026-03-29.log +0 -12
  373. package/packages/sync/logs/sync-2026-03-30.log +0 -6
  374. package/packages/sync/logs/sync-2026-03-31.log +0 -6
  375. package/packages/sync/logs/sync-2026-04-01.log +0 -6
  376. package/packages/sync/logs/sync-2026-04-02.log +0 -6
  377. package/packages/sync/package-lock.json +0 -373
  378. package/packages/sync/package.json +0 -16
  379. package/packages/sync/run-sync.bat +0 -18
  380. package/packages/sync/run-sync.mjs +0 -46
  381. package/packages/sync/setup-scheduler.mjs +0 -119
  382. package/packages/sync/structured-sync.mjs +0 -187
  383. package/packages/sync/sync-to-obsidian.mjs +0 -264
  384. package/packages/sync/upload-pdca-to-notion.mjs +0 -495
  385. package/tsconfig.base.json +0 -18
@@ -1,60 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
- import { createSqliteVecStore } from '../src/store/sqlite-vec.js';
3
- import { createSearchEngine } from '../src/search/index.js';
4
- import { createApiServer } from '../src/api/server.js';
5
- import type { VectorStore } from '../src/store/types.js';
6
-
7
- const DIMS = 4;
8
- const PORT = 13334;
9
- let store: VectorStore;
10
-
11
- beforeAll(async () => {
12
- store = createSqliteVecStore(':memory:', DIMS);
13
- await store.initialize();
14
- await store.upsertDocument({
15
- id: 'doc1', filePath: 'test.md', title: 'Test',
16
- content: 'Content', frontmatter: {}, tags: ['test'],
17
- lastModified: '2026-01-01', contentHash: 'h1',
18
- });
19
- await store.upsertChunks([{
20
- id: 'doc1#0', documentId: 'doc1', content: 'Content',
21
- heading: 'Test', startLine: 1, endLine: 1, tokenCount: 2,
22
- embedding: [1, 0, 0, 0],
23
- }]);
24
-
25
- const embedder = {
26
- dimensions: DIMS, modelName: 'test',
27
- initialize: async () => {},
28
- embed: async () => [0.5, 0.5, 0.5, 0.5],
29
- embedBatch: async (t: string[]) => t.map(() => [0.5, 0.5, 0.5, 0.5]),
30
- };
31
- const searchEngine = createSearchEngine({ store, embedder });
32
- const server = createApiServer({ store, searchEngine, port: PORT });
33
- await server.start();
34
- });
35
-
36
- afterAll(async () => { await store.close(); });
37
-
38
- describe('GET /api/profile-card', () => {
39
- it('SVG 반환', async () => {
40
- const res = await fetch(`http://127.0.0.1:${PORT}/api/profile-card`);
41
- expect(res.ok).toBe(true);
42
- expect(res.headers.get('content-type')).toContain('image/svg+xml');
43
- const text = await res.text();
44
- expect(text).toContain('<svg');
45
- expect(text).toContain('</svg>');
46
- });
47
-
48
- it('문서 수 포함', async () => {
49
- const res = await fetch(`http://127.0.0.1:${PORT}/api/profile-card`);
50
- const text = await res.text();
51
- expect(text).toContain('1 docs');
52
- });
53
-
54
- it('mode=folder 지원', async () => {
55
- const res = await fetch(`http://127.0.0.1:${PORT}/api/profile-card?mode=folder`);
56
- expect(res.ok).toBe(true);
57
- const text = await res.text();
58
- expect(text).toContain('<svg');
59
- });
60
- });
@@ -1,98 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
- import { createSqliteVecStore } from '../src/store/sqlite-vec.js';
3
- import { createSearchEngine } from '../src/search/index.js';
4
- import { createApiServer } from '../src/api/server.js';
5
- import type { VectorStore } from '../src/store/types.js';
6
- import type { Embedder } from '../src/indexer/embedder.js';
7
-
8
- const DIMS = 4;
9
- let store: VectorStore;
10
- let server: ReturnType<typeof createApiServer>;
11
- const PORT = 13333; // 테스트용 포트
12
-
13
- function mockEmbedder(): Embedder {
14
- return {
15
- dimensions: DIMS, modelName: 'test',
16
- initialize: async () => {},
17
- embed: async () => [0.5, 0.5, 0.5, 0.5],
18
- embedBatch: async (texts) => texts.map(() => [0.5, 0.5, 0.5, 0.5]),
19
- };
20
- }
21
-
22
- beforeAll(async () => {
23
- store = createSqliteVecStore(':memory:', DIMS);
24
- await store.initialize();
25
-
26
- await store.upsertDocument({
27
- id: 'doc1', filePath: 'test.md', title: 'Test Doc',
28
- content: 'OAuth authentication patterns', frontmatter: {}, tags: ['auth'],
29
- lastModified: '2026-01-01', contentHash: 'h1',
30
- });
31
- await store.upsertChunks([{
32
- id: 'doc1#0', documentId: 'doc1', content: 'OAuth authentication patterns',
33
- heading: 'Auth', startLine: 1, endLine: 1, tokenCount: 3,
34
- embedding: [1, 0, 0, 0],
35
- }]);
36
-
37
- const embedder = mockEmbedder();
38
- const searchEngine = createSearchEngine({ store, embedder });
39
- server = createApiServer({ store, searchEngine, port: PORT });
40
- await server.start();
41
- });
42
-
43
- afterAll(async () => { await store.close(); });
44
-
45
- describe('API Routes', () => {
46
- it('GET /api/stats', async () => {
47
- const res = await fetch(`http://127.0.0.1:${PORT}/api/stats`);
48
- expect(res.ok).toBe(true);
49
- const data = await res.json();
50
- expect(data.documentCount).toBe(1);
51
- expect(data.chunkCount).toBe(1);
52
- });
53
-
54
- it('GET /api/graph', async () => {
55
- const res = await fetch(`http://127.0.0.1:${PORT}/api/graph`);
56
- expect(res.ok).toBe(true);
57
- const data = await res.json();
58
- expect(data.data.nodes.length).toBe(1);
59
- expect(data.data.stats.nodeCount).toBe(1);
60
- });
61
-
62
- it('GET /api/graph?mode=folder', async () => {
63
- const res = await fetch(`http://127.0.0.1:${PORT}/api/graph?mode=folder`);
64
- expect(res.ok).toBe(true);
65
- const data = await res.json();
66
- expect(data.data.clusters.length).toBeGreaterThan(0);
67
- });
68
-
69
- it('GET /api/search?q=OAuth', async () => {
70
- const res = await fetch(`http://127.0.0.1:${PORT}/api/search?q=OAuth`);
71
- expect(res.ok).toBe(true);
72
- const data = await res.json();
73
- expect(data.query).toBe('OAuth');
74
- expect(data.results.length).toBeGreaterThan(0);
75
- expect(data.results[0].documentId).toBe('doc1');
76
- });
77
-
78
- it('GET /api/search 빈 쿼리', async () => {
79
- const res = await fetch(`http://127.0.0.1:${PORT}/api/search?q=`);
80
- expect(res.ok).toBe(true);
81
- const data = await res.json();
82
- expect(data.results).toEqual([]);
83
- });
84
-
85
- it('GET /api/document/:id 존재', async () => {
86
- const res = await fetch(`http://127.0.0.1:${PORT}/api/document/doc1`);
87
- expect(res.ok).toBe(true);
88
- const data = await res.json();
89
- expect(data.title).toBe('Test Doc');
90
- expect(data.content).toContain('OAuth');
91
- expect(data.related).toBeDefined();
92
- });
93
-
94
- it('GET /api/document/:id 미존재 → 404', async () => {
95
- const res = await fetch(`http://127.0.0.1:${PORT}/api/document/nonexistent`);
96
- expect(res.status).toBe(404);
97
- });
98
- });
@@ -1,87 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { searchBm25 } from '../src/search/bm25.js';
3
- import type { VectorStore } from '../src/store/types.js';
4
- import type { ScoredChunk } from '../src/types/chunk.js';
5
-
6
- // FTS5 검색을 시뮬레이션하는 mock store
7
- function createMockStore(keywordResults: ScoredChunk[] = []): VectorStore {
8
- return {
9
- searchKeyword: async (_query: string, _limit: number) => keywordResults,
10
- // 사용하지 않는 메서드 stub
11
- initialize: async () => {},
12
- close: async () => {},
13
- upsertDocument: async () => {},
14
- upsertChunks: async () => {},
15
- deleteByDocumentId: async () => {},
16
- getDocument: async () => null,
17
- getChunk: async () => null,
18
- searchSemantic: async () => [],
19
- getTopics: async () => [],
20
- getStats: async () => ({ documentCount: 0, chunkCount: 0, dbSizeBytes: 0, lastIndexed: null }),
21
- getAllDocumentHashes: async () => new Map(),
22
- } as VectorStore;
23
- }
24
-
25
- describe('searchBm25', () => {
26
- it('빈 쿼리는 빈 결과 반환', async () => {
27
- const store = createMockStore();
28
- const results = await searchBm25(store, '', 10);
29
- expect(results).toEqual([]);
30
- });
31
-
32
- it('특수문자만 있는 쿼리는 빈 결과 반환', async () => {
33
- const store = createMockStore();
34
- const results = await searchBm25(store, '!@#$%^&*()', 10);
35
- expect(results).toEqual([]);
36
- });
37
-
38
- it('일반 영문 쿼리 OR 조합 생성', async () => {
39
- let capturedQuery = '';
40
- const store = createMockStore();
41
- store.searchKeyword = async (query: string, _limit: number) => {
42
- capturedQuery = query;
43
- return [];
44
- };
45
-
46
- await searchBm25(store, 'React state management', 10);
47
- expect(capturedQuery).toBe('React OR state OR management');
48
- });
49
-
50
- it('한국어 쿼리 처리', async () => {
51
- let capturedQuery = '';
52
- const store = createMockStore();
53
- store.searchKeyword = async (query: string, _limit: number) => {
54
- capturedQuery = query;
55
- return [];
56
- };
57
-
58
- await searchBm25(store, '리액트 상태관리', 10);
59
- expect(capturedQuery).toBe('리액트 OR 상태관리');
60
- });
61
-
62
- it('특수문자 제거 후 정상 검색', async () => {
63
- let capturedQuery = '';
64
- const store = createMockStore();
65
- store.searchKeyword = async (query: string, _limit: number) => {
66
- capturedQuery = query;
67
- return [];
68
- };
69
-
70
- await searchBm25(store, 'OAuth2.0 인증/설계', 10);
71
- // 특수문자(., /) 제거 후 단어 추출
72
- expect(capturedQuery).toContain('OR');
73
- expect(capturedQuery).not.toContain('.');
74
- expect(capturedQuery).not.toContain('/');
75
- });
76
-
77
- it('결과를 그대로 반환', async () => {
78
- const mockResults: ScoredChunk[] = [
79
- { chunkId: 'doc1#0', score: 0.9 },
80
- { chunkId: 'doc2#1', score: 0.5 },
81
- ];
82
- const store = createMockStore(mockResults);
83
- const results = await searchBm25(store, 'test query', 10);
84
- expect(results).toEqual(mockResults);
85
- expect(results.length).toBe(2);
86
- });
87
- });
@@ -1,48 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { chunkDocument, estimateTokens } from '../src/indexer/chunker.js';
3
-
4
- describe('estimateTokens', () => {
5
- it('영문 토큰 추정', () => {
6
- expect(estimateTokens('hello world')).toBe(3);
7
- });
8
-
9
- it('한국어 토큰 추정', () => {
10
- expect(estimateTokens('안녕하세요')).toBe(3);
11
- });
12
-
13
- it('빈 문자열', () => {
14
- expect(estimateTokens('')).toBe(0);
15
- });
16
- });
17
-
18
- describe('chunkDocument', () => {
19
- it('짧은 문서는 1개 청크', () => {
20
- const chunks = chunkDocument('doc1', '# Title\n\nShort content.');
21
- expect(chunks.length).toBe(1);
22
- expect(chunks[0].documentId).toBe('doc1');
23
- expect(chunks[0].id).toBe('doc1#0');
24
- });
25
-
26
- it('heading으로 분할', () => {
27
- const md = '# Title\n\nIntro.\n\n## A\n\n' + 'Content A. '.repeat(50) + '\n\n## B\n\n' + 'Content B. '.repeat(50);
28
- const chunks = chunkDocument('doc2', md);
29
- expect(chunks.length).toBeGreaterThanOrEqual(2);
30
- });
31
-
32
- it('빈 문서는 빈 배열', () => {
33
- const chunks = chunkDocument('doc3', '');
34
- expect(chunks).toEqual([]);
35
- });
36
-
37
- it('heading 없는 문서도 처리', () => {
38
- const chunks = chunkDocument('doc4', 'Just plain text without headings.');
39
- expect(chunks.length).toBe(1);
40
- });
41
-
42
- it('짧은 청크 병합', () => {
43
- const md = '## A\n\nHi\n\n## B\n\nBye';
44
- const chunks = chunkDocument('doc5', md, { minTokens: 50 });
45
- // 둘 다 50 토큰 미만이므로 병합됨
46
- expect(chunks.length).toBe(1);
47
- });
48
- });
@@ -1,75 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- // graph-data.ts에서 K-means 내부 함수는 export 안 되므로, buildGraphData로 간접 테스트
4
- import { buildGraphData } from '../src/api/graph-data.js';
5
- import { createSqliteVecStore } from '../src/store/sqlite-vec.js';
6
- import type { VectorStore } from '../src/store/types.js';
7
-
8
- const DIMS = 4;
9
-
10
- async function setupStore(docCount: number): Promise<VectorStore> {
11
- const store = createSqliteVecStore(':memory:', DIMS);
12
- await store.initialize();
13
-
14
- for (let i = 0; i < docCount; i++) {
15
- // 3그룹으로 나뉘는 벡터: [1,0,0,0], [0,1,0,0], [0,0,1,0]
16
- const group = i % 3;
17
- const vec = [0, 0, 0, 0.1];
18
- vec[group] = 1;
19
-
20
- await store.upsertDocument({
21
- id: `d${i}`, filePath: `folder${group}/doc${i}.md`, title: `Doc ${i} Group ${group}`,
22
- content: `Content ${i}`, frontmatter: {}, tags: [],
23
- lastModified: '2026-01-01', contentHash: `h${i}`,
24
- });
25
- await store.upsertChunks([{
26
- id: `d${i}#0`, documentId: `d${i}`, content: `Content ${i}`,
27
- heading: `Doc ${i}`, startLine: 1, endLine: 1, tokenCount: 2,
28
- embedding: vec,
29
- }]);
30
- }
31
- return store;
32
- }
33
-
34
- describe('K-Means Clustering (via buildGraphData)', () => {
35
- it('클러스터 수가 5~10 범위', async () => {
36
- const store = await setupStore(30);
37
- const data = await buildGraphData(store, { mode: 'semantic' });
38
- expect(data.clusters.length).toBeGreaterThanOrEqual(3);
39
- expect(data.clusters.length).toBeLessThanOrEqual(10);
40
- await store.close();
41
- });
42
-
43
- it('모든 노드에 clusterId 할당', async () => {
44
- const store = await setupStore(15);
45
- const data = await buildGraphData(store);
46
- for (const node of data.nodes) {
47
- expect(node.clusterId).toBeTypeOf('number');
48
- }
49
- await store.close();
50
- });
51
-
52
- it('클러스터 라벨이 비어있지 않음', async () => {
53
- const store = await setupStore(15);
54
- const data = await buildGraphData(store);
55
- for (const c of data.clusters) {
56
- expect(c.label.length).toBeGreaterThan(0);
57
- }
58
- await store.close();
59
- });
60
-
61
- it('클러스터 nodeCount 합 = 전체 노드 수', async () => {
62
- const store = await setupStore(12);
63
- const data = await buildGraphData(store);
64
- const totalFromClusters = data.clusters.reduce((sum, c) => sum + c.nodeCount, 0);
65
- expect(totalFromClusters).toBe(data.nodes.length);
66
- await store.close();
67
- });
68
-
69
- it('folder 모드: 폴더 수만큼 클러스터', async () => {
70
- const store = await setupStore(9);
71
- const data = await buildGraphData(store, { mode: 'folder' });
72
- expect(data.clusters.length).toBe(3); // folder0, folder1, folder2
73
- await store.close();
74
- });
75
- });
@@ -1,77 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- // constellation.ts는 graph 패키지에 있으므로 MST 알고리즘 로직만 테스트
4
- // Prim's MST: 노드를 최소 거리로 연결
5
-
6
- function primMST(positions: Array<[number, number, number]>): Array<[number, number]> {
7
- const n = positions.length;
8
- if (n < 2) return [];
9
-
10
- const inMST = new Array(n).fill(false);
11
- const minEdge = new Array(n).fill(Infinity);
12
- const parent = new Array(n).fill(-1);
13
- minEdge[0] = 0;
14
- const edges: Array<[number, number]> = [];
15
-
16
- for (let iter = 0; iter < n; iter++) {
17
- let u = -1;
18
- for (let i = 0; i < n; i++) {
19
- if (!inMST[i] && (u === -1 || minEdge[i] < minEdge[u])) u = i;
20
- }
21
- if (u === -1) break;
22
- inMST[u] = true;
23
- if (parent[u] !== -1) edges.push([parent[u], u]);
24
-
25
- for (let v = 0; v < n; v++) {
26
- if (inMST[v]) continue;
27
- const d = Math.sqrt(
28
- (positions[u][0] - positions[v][0]) ** 2 +
29
- (positions[u][1] - positions[v][1]) ** 2 +
30
- (positions[u][2] - positions[v][2]) ** 2
31
- );
32
- if (d < minEdge[v]) { minEdge[v] = d; parent[v] = u; }
33
- }
34
- }
35
- return edges;
36
- }
37
-
38
- describe('Constellation MST', () => {
39
- it('2개 노드 → 1개 엣지', () => {
40
- const edges = primMST([[0, 0, 0], [10, 0, 0]]);
41
- expect(edges.length).toBe(1);
42
- });
43
-
44
- it('3개 노드 → 2개 엣지', () => {
45
- const edges = primMST([[0, 0, 0], [10, 0, 0], [5, 10, 0]]);
46
- expect(edges.length).toBe(2);
47
- });
48
-
49
- it('1개 노드 → 엣지 없음', () => {
50
- const edges = primMST([[0, 0, 0]]);
51
- expect(edges.length).toBe(0);
52
- });
53
-
54
- it('빈 배열 → 엣지 없음', () => {
55
- const edges = primMST([]);
56
- expect(edges.length).toBe(0);
57
- });
58
-
59
- it('MST는 N-1개 엣지 (트리)', () => {
60
- const positions: Array<[number, number, number]> = [];
61
- for (let i = 0; i < 10; i++) positions.push([i * 10, Math.random() * 10, 0]);
62
- const edges = primMST(positions);
63
- expect(edges.length).toBe(9);
64
- });
65
-
66
- it('모든 노드가 연결됨', () => {
67
- const positions: Array<[number, number, number]> = [[0, 0, 0], [100, 0, 0], [50, 100, 0], [50, 50, 50]];
68
- const edges = primMST(positions);
69
- const connected = new Set<number>();
70
- connected.add(0);
71
- for (const [a, b] of edges) {
72
- connected.add(a);
73
- connected.add(b);
74
- }
75
- expect(connected.size).toBe(4);
76
- });
77
- });
@@ -1,97 +0,0 @@
1
- // Phase 4a: export-utils 순수 함수 테스트
2
-
3
- import { describe, it, expect } from 'vitest';
4
-
5
- // export-utils는 graph 패키지에 있지만 순수 함수만 테스트
6
- // DOM 의존 함수는 통합 테스트로 분리
7
-
8
- describe('export-utils filename generation', () => {
9
- it('generates screenshot filename with timestamp', () => {
10
- // 파일명 패턴 검증: stellavault-screenshot-YYYY-MM-DDTHH-MM-SS.png
11
- const pattern = /^stellavault-screenshot-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}\.png$/;
12
- const now = new Date();
13
- const ts = now.toISOString().replace(/[:.]/g, '-').slice(0, 19);
14
- const filename = `stellavault-screenshot-${ts}.png`;
15
- expect(filename).toMatch(pattern);
16
- });
17
-
18
- it('generates recording filename with webm extension', () => {
19
- const pattern = /^stellavault-recording-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}\.webm$/;
20
- const now = new Date();
21
- const ts = now.toISOString().replace(/[:.]/g, '-').slice(0, 19);
22
- const filename = `stellavault-recording-${ts}.webm`;
23
- expect(filename).toMatch(pattern);
24
- });
25
- });
26
-
27
- describe('LOD thresholds', () => {
28
- const UNIVERSE_MIN = 800;
29
- const NOTE_MAX = 300;
30
-
31
- it('returns universe level for distance > 800', () => {
32
- const dist = 900;
33
- const level = dist > UNIVERSE_MIN ? 'universe' : dist < NOTE_MAX ? 'note' : 'constellation';
34
- expect(level).toBe('universe');
35
- });
36
-
37
- it('returns note level for distance < 300', () => {
38
- const dist = 200;
39
- const level = dist > UNIVERSE_MIN ? 'universe' : dist < NOTE_MAX ? 'note' : 'constellation';
40
- expect(level).toBe('note');
41
- });
42
-
43
- it('returns constellation level for distance 300-800', () => {
44
- for (const dist of [300, 500, 799]) {
45
- const level = dist > UNIVERSE_MIN ? 'universe' : dist < NOTE_MAX ? 'note' : 'constellation';
46
- expect(level).toBe('constellation');
47
- }
48
- });
49
-
50
- it('interpolates constellation opacity correctly', () => {
51
- const dist = 550; // middle of 300~800 range
52
- const t = (dist - NOTE_MAX) / (UNIVERSE_MIN - NOTE_MAX);
53
- expect(t).toBeCloseTo(0.5, 1);
54
-
55
- // At distance 300, t = 0 (no constellation lines)
56
- const t300 = (300 - NOTE_MAX) / (UNIVERSE_MIN - NOTE_MAX);
57
- expect(t300).toBeCloseTo(0, 1);
58
-
59
- // At distance 800, t = 1 (full constellation lines)
60
- const t800 = (800 - NOTE_MAX) / (UNIVERSE_MIN - NOTE_MAX);
61
- expect(t800).toBeCloseTo(1, 1);
62
- });
63
-
64
- it('node scale ranges from 1 (far) to 3 (close)', () => {
65
- const tFar = (800 - NOTE_MAX) / (UNIVERSE_MIN - NOTE_MAX);
66
- const scaleFar = 1 + (1 - tFar) * 2;
67
- expect(scaleFar).toBeCloseTo(1, 1);
68
-
69
- const tClose = (300 - NOTE_MAX) / (UNIVERSE_MIN - NOTE_MAX);
70
- const scaleClose = 1 + (1 - tClose) * 2;
71
- expect(scaleClose).toBeCloseTo(3, 1);
72
- });
73
- });
74
-
75
- describe('graph-store export state', () => {
76
- it('lodLevel accepts valid values', () => {
77
- const validLevels = ['universe', 'constellation', 'note'] as const;
78
- for (const level of validLevels) {
79
- expect(typeof level).toBe('string');
80
- expect(validLevels).toContain(level);
81
- }
82
- });
83
-
84
- it('LOD nodeScale mapping matches design', () => {
85
- // Design Ref: §8 — LOD node scale factors
86
- const lodScaleMap = { universe: 0.6, constellation: 1.0, note: 1.2 };
87
- expect(lodScaleMap.universe).toBeLessThan(lodScaleMap.constellation);
88
- expect(lodScaleMap.constellation).toBeLessThan(lodScaleMap.note);
89
- });
90
-
91
- it('screenshot resolution capped at 4096', () => {
92
- const cap = (v: number) => Math.min(v, 4096);
93
- expect(cap(2048)).toBe(2048);
94
- expect(cap(8192)).toBe(4096);
95
- expect(cap(1024)).toBe(1024);
96
- });
97
- });
@@ -1,96 +0,0 @@
1
- // Phase 4b: FSRS 알고리즘 단위 테스트
2
-
3
- import { describe, it, expect } from 'vitest';
4
- import {
5
- computeRetrievability,
6
- updateStability,
7
- estimateInitialStability,
8
- elapsedDays,
9
- FSRS_PARAMS,
10
- } from '../src/intelligence/fsrs.js';
11
-
12
- describe('FSRS computeRetrievability', () => {
13
- it('returns 1.0 for 0 elapsed days', () => {
14
- expect(computeRetrievability(7, 0)).toBe(1.0);
15
- });
16
-
17
- it('returns ~0.9 after stability days', () => {
18
- // R(S) = (1 + S/(9*S))^(-1) = (1 + 1/9)^(-1) = 0.9
19
- const r = computeRetrievability(7, 7);
20
- expect(r).toBeCloseTo(0.9, 1);
21
- });
22
-
23
- it('decays over time', () => {
24
- const r7 = computeRetrievability(7, 7);
25
- const r30 = computeRetrievability(7, 30);
26
- const r90 = computeRetrievability(7, 90);
27
- expect(r7).toBeGreaterThan(r30);
28
- expect(r30).toBeGreaterThan(r90);
29
- });
30
-
31
- it('higher stability = slower decay', () => {
32
- const rLow = computeRetrievability(3, 30);
33
- const rHigh = computeRetrievability(30, 30);
34
- expect(rHigh).toBeGreaterThan(rLow);
35
- });
36
-
37
- it('returns 0 for 0 stability', () => {
38
- expect(computeRetrievability(0, 10)).toBe(0.0);
39
- });
40
-
41
- it('60 days with default stability gives R < 0.5', () => {
42
- // Plan SC-01: 장기 미접근 노트는 감쇠
43
- // R(60, S=7) ≈ 0.51, R(90, S=7) ≈ 0.41
44
- const r90 = computeRetrievability(FSRS_PARAMS.initialStability, 90);
45
- expect(r90).toBeLessThan(0.5);
46
- });
47
- });
48
-
49
- describe('FSRS updateStability', () => {
50
- it('increases stability on access', () => {
51
- const newS = updateStability(7, 5, 0.5);
52
- expect(newS).toBeGreaterThan(7);
53
- });
54
-
55
- it('increases more when R is low (forgotten but recalled)', () => {
56
- const sHighR = updateStability(7, 5, 0.9);
57
- const sLowR = updateStability(7, 5, 0.3);
58
- expect(sLowR).toBeGreaterThan(sHighR);
59
- });
60
-
61
- it('caps at 365 days', () => {
62
- const s = updateStability(300, 1, 0.1);
63
- expect(s).toBeLessThanOrEqual(365);
64
- });
65
- });
66
-
67
- describe('FSRS estimateInitialStability', () => {
68
- it('base stability for short notes', () => {
69
- const s = estimateInitialStability(100, 0);
70
- expect(s).toBeCloseTo(FSRS_PARAMS.initialStability, 0);
71
- });
72
-
73
- it('longer notes get higher stability', () => {
74
- const sShort = estimateInitialStability(100, 0);
75
- const sLong = estimateInitialStability(5000, 0);
76
- expect(sLong).toBeGreaterThan(sShort);
77
- });
78
-
79
- it('more connections increase stability', () => {
80
- const s0 = estimateInitialStability(1000, 0);
81
- const s5 = estimateInitialStability(1000, 5);
82
- expect(s5).toBeGreaterThan(s0);
83
- });
84
- });
85
-
86
- describe('elapsedDays', () => {
87
- it('computes correct days', () => {
88
- const d = elapsedDays('2026-03-01T00:00:00Z', '2026-03-31T00:00:00Z');
89
- expect(d).toBeCloseTo(30, 0);
90
- });
91
-
92
- it('returns 0 for same timestamp', () => {
93
- const now = new Date().toISOString();
94
- expect(elapsedDays(now, now)).toBe(0);
95
- });
96
- });
@@ -1,45 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- // gesture-detector는 graph 패키지에 있으므로 로직만 단위 테스트
4
- // 핵심 알고리즘: 손가락 수 카운팅 + 핀치 거리 + 흔들기 감지
5
-
6
- describe('Gesture Detection Logic', () => {
7
- it('5개 손가락 펼침 = rotate', () => {
8
- // extended >= 4 → rotate
9
- const extended = 5;
10
- expect(extended >= 4).toBe(true);
11
- });
12
-
13
- it('0개 손가락 = pan', () => {
14
- const extended = 0;
15
- expect(extended === 0).toBe(true);
16
- });
17
-
18
- it('핀치 거리 < 0.06 = zoom', () => {
19
- const pinchDistance = 0.04;
20
- expect(pinchDistance < 0.06).toBe(true);
21
- });
22
-
23
- it('핀치 거리 >= 0.06 = not zoom', () => {
24
- const pinchDistance = 0.08;
25
- expect(pinchDistance < 0.06).toBe(false);
26
- });
27
-
28
- it('1개 손가락 (검지) = select', () => {
29
- const extended = 1;
30
- const isIndexExtended = true;
31
- expect(extended === 1 && isIndexExtended).toBe(true);
32
- });
33
-
34
- it('흔들기 감지: 3회 이상 방향 전환', () => {
35
- // x 좌표 시퀀스: 좌 → 우 → 좌 → 우
36
- const history = [0.3, 0.35, 0.4, 0.35, 0.3, 0.35, 0.4, 0.35, 0.3, 0.35];
37
- let dirChanges = 0;
38
- for (let i = 2; i < history.length; i++) {
39
- const prev = history[i - 1] - history[i - 2];
40
- const curr = history[i] - history[i - 1];
41
- if (prev * curr < 0 && Math.abs(curr) > 0.005) dirChanges++;
42
- }
43
- expect(dirChanges).toBeGreaterThanOrEqual(3);
44
- });
45
- });