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
@@ -0,0 +1,135 @@
1
+ // Voice Knowledge Capture (P3-F25)
2
+ // 음성 파일 → 텍스트 → 자동 분류 → vault 저장 → 인덱싱
3
+ import { execFileSync, execSync } from 'node:child_process';
4
+ import { writeFileSync, mkdirSync, existsSync } from 'node:fs';
5
+ import { join, basename } from 'node:path';
6
+ // CRIT-03: 화이트리스트 검증
7
+ const ALLOWED_MODELS = ['tiny', 'base', 'small', 'medium', 'large'];
8
+ const ALLOWED_LANGUAGES = ['auto', 'en', 'ko', 'ja', 'zh', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'ar', 'hi'];
9
+ function validateModel(model) {
10
+ if (!ALLOWED_MODELS.includes(model))
11
+ throw new Error(`Invalid model: ${model}. Allowed: ${ALLOWED_MODELS.join(', ')}`);
12
+ return model;
13
+ }
14
+ function validateLanguage(lang) {
15
+ if (!ALLOWED_LANGUAGES.includes(lang))
16
+ throw new Error(`Invalid language: ${lang}. Allowed: ${ALLOWED_LANGUAGES.join(', ')}`);
17
+ return lang;
18
+ }
19
+ // Whisper CLI가 설치되어 있는지 확인
20
+ export function isWhisperAvailable() {
21
+ try {
22
+ execSync('whisper --help', { stdio: 'ignore' });
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ // 음성 파일 → 텍스트 변환 (Whisper CLI)
30
+ export async function transcribeAudio(audioPath, options = {}) {
31
+ const { model = 'base', language } = options;
32
+ if (!existsSync(audioPath)) {
33
+ throw new Error(`Audio file not found: ${audioPath}`);
34
+ }
35
+ // CRIT-03 fix: execFileSync + 화이트리스트 검증 (command injection 방지)
36
+ if (isWhisperAvailable()) {
37
+ const safeModel = validateModel(model);
38
+ const args = [audioPath, '--model', safeModel, '--output_format', 'txt', '--output_dir', '/tmp/sv-whisper'];
39
+ if (language)
40
+ args.push('--language', validateLanguage(language));
41
+ mkdirSync('/tmp/sv-whisper', { recursive: true });
42
+ try {
43
+ execFileSync('whisper', args, { stdio: 'pipe', timeout: 300000 });
44
+ const outputName = basename(audioPath).replace(/\.[^.]+$/, '.txt');
45
+ const { readFileSync } = await import('node:fs');
46
+ return readFileSync(join('/tmp/sv-whisper', outputName), 'utf-8').trim();
47
+ }
48
+ catch (err) {
49
+ throw new Error(`Whisper failed: ${err instanceof Error ? err.message : err}`);
50
+ }
51
+ }
52
+ // Whisper 없으면 에러
53
+ throw new Error('Whisper not installed. Install: pip install openai-whisper');
54
+ }
55
+ // 트랜스크립트에서 자동 태그 추출 (간단한 키워드 매칭)
56
+ function autoTag(text) {
57
+ const tags = [];
58
+ const lower = text.toLowerCase();
59
+ const keywords = {
60
+ 'meeting': ['meeting', 'discuss', '미팅', '회의'],
61
+ 'decision': ['decide', 'agreed', '결정', '합의'],
62
+ 'idea': ['idea', 'thought', '아이디어', '생각'],
63
+ 'todo': ['todo', 'task', 'action item', '할 일'],
64
+ 'bug': ['bug', 'error', 'fix', '버그', '에러'],
65
+ 'architecture': ['architecture', 'design', 'system', '아키텍처', '설계'],
66
+ };
67
+ for (const [tag, words] of Object.entries(keywords)) {
68
+ if (words.some(w => lower.includes(w)))
69
+ tags.push(tag);
70
+ }
71
+ return tags;
72
+ }
73
+ // 음성 → vault 노트 생성
74
+ export async function captureVoice(audioPath, options) {
75
+ const { vaultPath, folder = '01_Knowledge/voice', type = 'note', tags: userTags = [] } = options;
76
+ try {
77
+ // 1. 음성→텍스트
78
+ const transcript = await transcribeAudio(audioPath, {
79
+ model: options.model,
80
+ language: options.language,
81
+ });
82
+ if (!transcript) {
83
+ return { title: '', filePath: '', transcript: '', tags: [], success: false, error: 'Empty transcript' };
84
+ }
85
+ // 2. 제목 생성 (첫 문장 또는 첫 30자)
86
+ const firstLine = transcript.split(/[.\n!?]/)[0]?.trim() || transcript.slice(0, 30);
87
+ const title = firstLine.slice(0, 60);
88
+ const safeTitle = title.replace(/[<>:"/\\|?*]/g, '').replace(/\s+/g, ' ').trim();
89
+ // 3. 자동 태그
90
+ const autoTags = autoTag(transcript);
91
+ const allTags = [...new Set([...userTags, ...autoTags, 'voice'])];
92
+ // 4. frontmatter + 마크다운 생성
93
+ const date = new Date().toISOString();
94
+ const content = [
95
+ '---',
96
+ `title: "${safeTitle}"`,
97
+ `source: voice`,
98
+ `type: ${type}`,
99
+ `tags: [${allTags.map(t => `"${t}"`).join(', ')}]`,
100
+ `captured: ${date}`,
101
+ `audio: ${basename(audioPath)}`,
102
+ '---',
103
+ '',
104
+ `# ${safeTitle}`,
105
+ '',
106
+ `> Voice capture: ${date.slice(0, 10)}`,
107
+ '',
108
+ transcript,
109
+ '',
110
+ ].join('\n');
111
+ // 5. vault에 저장
112
+ const dir = join(vaultPath, folder);
113
+ mkdirSync(dir, { recursive: true });
114
+ const filePath = join(dir, `${date.slice(0, 10)} ${safeTitle}.md`);
115
+ writeFileSync(filePath, content, 'utf-8');
116
+ return {
117
+ title: safeTitle,
118
+ filePath,
119
+ transcript,
120
+ tags: allTags,
121
+ success: true,
122
+ };
123
+ }
124
+ catch (err) {
125
+ return {
126
+ title: '',
127
+ filePath: '',
128
+ transcript: '',
129
+ tags: [],
130
+ success: false,
131
+ error: err instanceof Error ? err.message : String(err),
132
+ };
133
+ }
134
+ }
135
+ //# sourceMappingURL=voice.js.map
@@ -1,2 +1,3 @@
1
1
  export { syncToCloud, restoreFromCloud, getSyncState, encrypt, decrypt, getOrCreateEncryptionKey } from './sync.js';
2
2
  export type { CloudConfig, SyncResult } from './sync.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { syncToCloud, restoreFromCloud, getSyncState, encrypt, decrypt, getOrCreateEncryptionKey } from './sync.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,29 @@
1
+ export interface CloudConfig {
2
+ endpoint: string;
3
+ bucket: string;
4
+ accessKeyId: string;
5
+ secretAccessKey: string;
6
+ encryptionKey?: string;
7
+ }
8
+ export interface SyncResult {
9
+ action: 'upload' | 'download';
10
+ dbSize: number;
11
+ encryptedSize: number;
12
+ timestamp: string;
13
+ success: boolean;
14
+ error?: string;
15
+ }
16
+ export declare function encrypt(data: Buffer, key: Buffer): {
17
+ encrypted: Buffer;
18
+ iv: Buffer;
19
+ tag: Buffer;
20
+ };
21
+ export declare function decrypt(encrypted: Buffer, key: Buffer, iv: Buffer, tag: Buffer): Buffer;
22
+ export declare function getOrCreateEncryptionKey(userKey?: string): Buffer;
23
+ export declare function syncToCloud(dbPath: string, config: CloudConfig): Promise<SyncResult>;
24
+ export declare function restoreFromCloud(dbPath: string, config: CloudConfig): Promise<SyncResult>;
25
+ export declare function getSyncState(): {
26
+ lastSync: string;
27
+ dbSize: number;
28
+ } | null;
29
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1,137 @@
1
+ // Cloud Sync (F-A04) — E2E encrypted SQLite backup
2
+ // 서버리스: S3-compatible API로 직접 업로드 (R2, S3, MinIO)
3
+ // Design Ref: PRD §7.1 Tier 2
4
+ import { createCipheriv, createDecipheriv, randomBytes, createHash } from 'node:crypto';
5
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { homedir } from 'node:os';
8
+ const CLOUD_DIR = join(homedir(), '.stellavault', 'cloud');
9
+ const KEY_FILE = join(CLOUD_DIR, 'encryption.key');
10
+ const SYNC_STATE_FILE = join(CLOUD_DIR, 'sync-state.json');
11
+ // AES-256-GCM 암호화
12
+ export function encrypt(data, key) {
13
+ const iv = randomBytes(16);
14
+ const cipher = createCipheriv('aes-256-gcm', key, iv);
15
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
16
+ const tag = cipher.getAuthTag();
17
+ return { encrypted, iv, tag };
18
+ }
19
+ export function decrypt(encrypted, key, iv, tag) {
20
+ const decipher = createDecipheriv('aes-256-gcm', key, iv);
21
+ decipher.setAuthTag(tag);
22
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]);
23
+ }
24
+ // 암호화 키 관리
25
+ export function getOrCreateEncryptionKey(userKey) {
26
+ mkdirSync(CLOUD_DIR, { recursive: true });
27
+ if (userKey) {
28
+ const key = createHash('sha256').update(userKey).digest();
29
+ writeFileSync(KEY_FILE, key.toString('hex'), 'utf-8');
30
+ return key;
31
+ }
32
+ if (existsSync(KEY_FILE)) {
33
+ return Buffer.from(readFileSync(KEY_FILE, 'utf-8').trim(), 'hex');
34
+ }
35
+ const key = randomBytes(32);
36
+ writeFileSync(KEY_FILE, key.toString('hex'), { encoding: 'utf-8', mode: 0o600 });
37
+ try {
38
+ chmodSync(KEY_FILE, 0o600);
39
+ }
40
+ catch { /* Windows may not support */ }
41
+ return key;
42
+ }
43
+ // S3-compatible upload (presigned 불필요 — 직접 PUT)
44
+ async function s3Put(config, objectKey, data, contentType = 'application/octet-stream') {
45
+ const { endpoint, bucket, accessKeyId, secretAccessKey } = config;
46
+ // HIGH-05: endpoint 검증
47
+ try {
48
+ const parsed = new URL(endpoint);
49
+ if (!['http:', 'https:'].includes(parsed.protocol))
50
+ throw new Error('Invalid protocol');
51
+ if (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1')
52
+ throw new Error('Local endpoint');
53
+ }
54
+ catch (e) {
55
+ throw new Error(`Invalid cloud endpoint: ${endpoint}. ${e instanceof Error ? e.message : ''}`);
56
+ }
57
+ const url = `${endpoint}/${bucket}/${objectKey}`;
58
+ const date = new Date().toISOString().replace(/[-:]/g, '').slice(0, 15) + 'Z';
59
+ const res = await fetch(url, {
60
+ method: 'PUT',
61
+ headers: {
62
+ 'Content-Type': contentType,
63
+ 'Content-Length': String(data.length),
64
+ 'x-amz-date': date,
65
+ 'x-amz-content-sha256': createHash('sha256').update(data).digest('hex'),
66
+ // R2는 Bearer token 지원
67
+ 'Authorization': `Bearer ${secretAccessKey}`,
68
+ },
69
+ body: data,
70
+ });
71
+ return res.ok;
72
+ }
73
+ async function s3Get(config, objectKey) {
74
+ const url = `${config.endpoint}/${config.bucket}/${objectKey}`;
75
+ const res = await fetch(url, {
76
+ headers: { 'Authorization': `Bearer ${config.secretAccessKey}` },
77
+ });
78
+ if (!res.ok)
79
+ return null;
80
+ return Buffer.from(await res.arrayBuffer());
81
+ }
82
+ // Sync: 로컬 DB → 암호화 → 업로드
83
+ export async function syncToCloud(dbPath, config) {
84
+ const timestamp = new Date().toISOString();
85
+ try {
86
+ if (!existsSync(dbPath)) {
87
+ return { action: 'upload', dbSize: 0, encryptedSize: 0, timestamp, success: false, error: 'DB not found' };
88
+ }
89
+ const dbData = readFileSync(dbPath);
90
+ const key = getOrCreateEncryptionKey(config.encryptionKey);
91
+ const { encrypted, iv, tag } = encrypt(dbData, key);
92
+ // 패키징: [iv(16)] + [tag(16)] + [encrypted data]
93
+ const payload = Buffer.concat([iv, tag, encrypted]);
94
+ const objectKey = `stellavault/index.db.enc`;
95
+ const success = await s3Put(config, objectKey, payload);
96
+ // 동기화 상태 저장
97
+ const state = { lastSync: timestamp, dbSize: dbData.length, encryptedSize: payload.length, objectKey };
98
+ mkdirSync(CLOUD_DIR, { recursive: true });
99
+ writeFileSync(SYNC_STATE_FILE, JSON.stringify(state, null, 2), 'utf-8');
100
+ return { action: 'upload', dbSize: dbData.length, encryptedSize: payload.length, timestamp, success };
101
+ }
102
+ catch (err) {
103
+ return { action: 'upload', dbSize: 0, encryptedSize: 0, timestamp, success: false, error: err instanceof Error ? err.message : String(err) };
104
+ }
105
+ }
106
+ // Restore: 다운로드 → 복호화 → 로컬 DB 덮어쓰기
107
+ export async function restoreFromCloud(dbPath, config) {
108
+ const timestamp = new Date().toISOString();
109
+ try {
110
+ const objectKey = `stellavault/index.db.enc`;
111
+ const payload = await s3Get(config, objectKey);
112
+ if (!payload) {
113
+ return { action: 'download', dbSize: 0, encryptedSize: 0, timestamp, success: false, error: 'No backup found in cloud' };
114
+ }
115
+ const key = getOrCreateEncryptionKey(config.encryptionKey);
116
+ const iv = payload.subarray(0, 16);
117
+ const tag = payload.subarray(16, 32);
118
+ const encrypted = payload.subarray(32);
119
+ const dbData = decrypt(encrypted, key, iv, tag);
120
+ // 백업 후 덮어쓰기
121
+ if (existsSync(dbPath)) {
122
+ writeFileSync(dbPath + '.backup', readFileSync(dbPath));
123
+ }
124
+ writeFileSync(dbPath, dbData);
125
+ return { action: 'download', dbSize: dbData.length, encryptedSize: payload.length, timestamp, success: true };
126
+ }
127
+ catch (err) {
128
+ return { action: 'download', dbSize: 0, encryptedSize: 0, timestamp, success: false, error: err instanceof Error ? err.message : String(err) };
129
+ }
130
+ }
131
+ // 동기화 상태 조회
132
+ export function getSyncState() {
133
+ if (!existsSync(SYNC_STATE_FILE))
134
+ return null;
135
+ return JSON.parse(readFileSync(SYNC_STATE_FILE, 'utf-8'));
136
+ }
137
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1,27 @@
1
+ export interface StellavaultConfig {
2
+ vaultPath: string;
3
+ dbPath: string;
4
+ embedding: {
5
+ model: 'local' | 'openai';
6
+ localModel: string;
7
+ };
8
+ chunking: {
9
+ maxTokens: number;
10
+ overlap: number;
11
+ minTokens: number;
12
+ };
13
+ search: {
14
+ defaultLimit: number;
15
+ rrfK: number;
16
+ };
17
+ mcp: {
18
+ mode: 'stdio' | 'sse';
19
+ port: number;
20
+ };
21
+ }
22
+ /**
23
+ * .stellavault.json 파일을 찾아 로드합니다.
24
+ * 탐색 순서: cwd → home directory → defaults
25
+ */
26
+ export declare function loadConfig(configPath?: string): StellavaultConfig;
27
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1,55 @@
1
+ // Design Ref: §10.2 — 설정 파일 구조 (.stellavault.json 로더)
2
+ import { readFileSync, existsSync } from 'node:fs';
3
+ import { resolve, join } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+ const DEFAULT_CONFIG = {
6
+ vaultPath: '',
7
+ dbPath: join(homedir(), '.stellavault', 'index.db'),
8
+ embedding: {
9
+ model: 'local',
10
+ localModel: 'all-MiniLM-L6-v2',
11
+ },
12
+ chunking: {
13
+ maxTokens: 300,
14
+ overlap: 50,
15
+ minTokens: 50,
16
+ },
17
+ search: {
18
+ defaultLimit: 10,
19
+ rrfK: 60,
20
+ },
21
+ mcp: {
22
+ mode: 'stdio',
23
+ port: 3333,
24
+ },
25
+ };
26
+ /**
27
+ * .stellavault.json 파일을 찾아 로드합니다.
28
+ * 탐색 순서: cwd → home directory → defaults
29
+ */
30
+ export function loadConfig(configPath) {
31
+ const paths = configPath
32
+ ? [resolve(configPath)]
33
+ : [
34
+ resolve(process.cwd(), '.stellavault.json'),
35
+ join(homedir(), '.stellavault.json'),
36
+ ];
37
+ for (const p of paths) {
38
+ if (existsSync(p)) {
39
+ const raw = JSON.parse(readFileSync(p, 'utf-8'));
40
+ return mergeConfig(DEFAULT_CONFIG, raw);
41
+ }
42
+ }
43
+ return { ...DEFAULT_CONFIG };
44
+ }
45
+ function mergeConfig(defaults, overrides) {
46
+ return {
47
+ vaultPath: overrides.vaultPath ?? defaults.vaultPath,
48
+ dbPath: overrides.dbPath ?? defaults.dbPath,
49
+ embedding: { ...defaults.embedding, ...overrides.embedding },
50
+ chunking: { ...defaults.chunking, ...overrides.chunking },
51
+ search: { ...defaults.search, ...overrides.search },
52
+ mcp: { ...defaults.mcp, ...overrides.mcp },
53
+ };
54
+ }
55
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,26 @@
1
+ export interface CreditAccount {
2
+ balance: number;
3
+ totalEarned: number;
4
+ totalSpent: number;
5
+ transactions: CreditTransaction[];
6
+ }
7
+ export interface CreditTransaction {
8
+ type: 'earn' | 'spend';
9
+ amount: number;
10
+ reason: string;
11
+ timestamp: string;
12
+ }
13
+ export declare function getBalance(): number;
14
+ export declare function getAccount(): CreditAccount;
15
+ export declare function earn(amount: number, reason: string): number;
16
+ export declare function spend(amount: number, reason: string): {
17
+ success: boolean;
18
+ balance: number;
19
+ };
20
+ export declare function earnForSearchResponse(peerId: string): number;
21
+ export declare function spendForSearch(peerCount: number): {
22
+ success: boolean;
23
+ balance: number;
24
+ };
25
+ export declare function getRecentTransactions(limit?: number): CreditTransaction[];
26
+ //# sourceMappingURL=credits.d.ts.map
@@ -0,0 +1,56 @@
1
+ // Federation Phase 2: Search Credits
2
+ // 지식 공유 = 크레딧 획득, 연합 검색 = 크레딧 소모
3
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { homedir } from 'node:os';
6
+ const CREDITS_FILE = join(homedir(), '.stellavault', 'federation', 'credits.json');
7
+ const INITIAL_BALANCE = 100;
8
+ const EARN_PER_SEARCH_RESPONSE = 10; // 검색 응답 시 획득
9
+ const COST_PER_SEARCH = 1; // 검색 요청 시 소모
10
+ function loadAccount() {
11
+ if (existsSync(CREDITS_FILE)) {
12
+ return JSON.parse(readFileSync(CREDITS_FILE, 'utf-8'));
13
+ }
14
+ return { balance: INITIAL_BALANCE, totalEarned: 0, totalSpent: 0, transactions: [] };
15
+ }
16
+ function saveAccount(account) {
17
+ mkdirSync(join(homedir(), '.stellavault', 'federation'), { recursive: true });
18
+ // 최근 100개 트랜잭션만 유지
19
+ account.transactions = account.transactions.slice(-100);
20
+ writeFileSync(CREDITS_FILE, JSON.stringify(account, null, 2), 'utf-8');
21
+ }
22
+ export function getBalance() {
23
+ return loadAccount().balance;
24
+ }
25
+ export function getAccount() {
26
+ return loadAccount();
27
+ }
28
+ export function earn(amount, reason) {
29
+ const account = loadAccount();
30
+ account.balance += amount;
31
+ account.totalEarned += amount;
32
+ account.transactions.push({ type: 'earn', amount, reason, timestamp: new Date().toISOString() });
33
+ saveAccount(account);
34
+ return account.balance;
35
+ }
36
+ export function spend(amount, reason) {
37
+ const account = loadAccount();
38
+ if (account.balance < amount) {
39
+ return { success: false, balance: account.balance };
40
+ }
41
+ account.balance -= amount;
42
+ account.totalSpent += amount;
43
+ account.transactions.push({ type: 'spend', amount, reason, timestamp: new Date().toISOString() });
44
+ saveAccount(account);
45
+ return { success: true, balance: account.balance };
46
+ }
47
+ export function earnForSearchResponse(peerId) {
48
+ return earn(EARN_PER_SEARCH_RESPONSE, `Search response to ${peerId}`);
49
+ }
50
+ export function spendForSearch(peerCount) {
51
+ return spend(COST_PER_SEARCH * peerCount, `Search across ${peerCount} peers`);
52
+ }
53
+ export function getRecentTransactions(limit = 20) {
54
+ return loadAccount().transactions.slice(-limit).reverse();
55
+ }
56
+ //# sourceMappingURL=credits.js.map
@@ -0,0 +1,14 @@
1
+ export interface NodeIdentity {
2
+ peerId: string;
3
+ publicKey: Buffer;
4
+ secretKey: Buffer;
5
+ displayName: string;
6
+ createdAt: string;
7
+ }
8
+ export declare function getOrCreateIdentity(displayName?: string): NodeIdentity;
9
+ export declare function signMessage(secretKey: Buffer, message: Buffer): Buffer;
10
+ export declare function verifySignature(publicKey: Buffer, secretKey: Buffer, message: Buffer, signature: Buffer): boolean;
11
+ export declare function createChallenge(): Buffer;
12
+ export declare function respondToChallenge(secretKey: Buffer, challenge: Buffer): Buffer;
13
+ export declare function verifyChallenge(secretKey: Buffer, challenge: Buffer, response: Buffer): boolean;
14
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1,74 @@
1
+ // Federation: Node Identity (HMAC-SHA256 signing)
2
+ // CRIT-01 fix: 실제 서명 검증 구현 (placeholder 제거)
3
+ // CRIT-04 fix: 키 파일 권한 0o600
4
+ import { randomBytes, createHash, createHmac } from 'node:crypto';
5
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, chmodSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { homedir } from 'node:os';
8
+ const IDENTITY_DIR = join(homedir(), '.stellavault', 'federation');
9
+ const IDENTITY_FILE = join(IDENTITY_DIR, 'identity.json');
10
+ export function getOrCreateIdentity(displayName) {
11
+ if (existsSync(IDENTITY_FILE)) {
12
+ const raw = JSON.parse(readFileSync(IDENTITY_FILE, 'utf-8'));
13
+ return {
14
+ peerId: raw.peerId,
15
+ publicKey: Buffer.from(raw.publicKey, 'hex'),
16
+ secretKey: Buffer.from(raw.secretKey, 'hex'),
17
+ displayName: raw.displayName,
18
+ createdAt: raw.createdAt,
19
+ };
20
+ }
21
+ const secretKey = randomBytes(32);
22
+ const publicKey = createHash('sha256').update(secretKey).digest();
23
+ const peerId = createHash('sha256').update(publicKey).digest('hex').slice(0, 16);
24
+ const identity = {
25
+ peerId,
26
+ publicKey,
27
+ secretKey,
28
+ displayName: displayName ?? `node-${peerId.slice(0, 6)}`,
29
+ createdAt: new Date().toISOString(),
30
+ };
31
+ mkdirSync(IDENTITY_DIR, { recursive: true });
32
+ const content = JSON.stringify({
33
+ peerId: identity.peerId,
34
+ publicKey: publicKey.toString('hex'),
35
+ secretKey: secretKey.toString('hex'),
36
+ displayName: identity.displayName,
37
+ createdAt: identity.createdAt,
38
+ }, null, 2);
39
+ writeFileSync(IDENTITY_FILE, content, { encoding: 'utf-8', mode: 0o600 });
40
+ try {
41
+ chmodSync(IDENTITY_FILE, 0o600);
42
+ }
43
+ catch { /* Windows may not support */ }
44
+ return identity;
45
+ }
46
+ // CRIT-01 fix: 실제 HMAC-SHA256 서명
47
+ export function signMessage(secretKey, message) {
48
+ return createHmac('sha256', secretKey).update(message).digest();
49
+ }
50
+ // CRIT-01 fix: 실제 HMAC-SHA256 검증
51
+ export function verifySignature(publicKey, secretKey, message, signature) {
52
+ const expected = createHmac('sha256', secretKey).update(message).digest();
53
+ if (expected.length !== signature.length)
54
+ return false;
55
+ // Timing-safe comparison
56
+ let diff = 0;
57
+ for (let i = 0; i < expected.length; i++) {
58
+ diff |= expected[i] ^ signature[i];
59
+ }
60
+ return diff === 0;
61
+ }
62
+ // Challenge-response 인증용 nonce 생성
63
+ export function createChallenge() {
64
+ return randomBytes(32);
65
+ }
66
+ // Challenge에 대한 응답 생성
67
+ export function respondToChallenge(secretKey, challenge) {
68
+ return signMessage(secretKey, challenge);
69
+ }
70
+ // Challenge 응답 검증
71
+ export function verifyChallenge(secretKey, challenge, response) {
72
+ return verifySignature(Buffer.alloc(0), secretKey, challenge, response);
73
+ }
74
+ //# sourceMappingURL=identity.js.map
@@ -1,8 +1,7 @@
1
- // Design Ref: §2.3 — Federation Public API
2
-
3
1
  export { FederationNode } from './node.js';
4
2
  export { FederatedSearch } from './search.js';
5
3
  export type { FederatedSearchOptions } from './search.js';
6
4
  export { getOrCreateIdentity } from './identity.js';
7
5
  export type { NodeIdentity } from './identity.js';
8
6
  export type { PeerInfo, FederatedSearchResult, FederationMessage } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,5 @@
1
+ // Design Ref: §2.3 — Federation Public API
2
+ export { FederationNode } from './node.js';
3
+ export { FederatedSearch } from './search.js';
4
+ export { getOrCreateIdentity } from './identity.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,31 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { PeerInfo } from './types.js';
3
+ export declare class FederationNode extends EventEmitter {
4
+ private swarm;
5
+ private identity;
6
+ private peers;
7
+ private running;
8
+ private documentCount;
9
+ private topTopics;
10
+ constructor(displayName?: string);
11
+ get peerId(): string;
12
+ get displayName(): string;
13
+ get peerCount(): number;
14
+ get isRunning(): boolean;
15
+ setLocalStats(documentCount: number, topTopics: string[]): void;
16
+ join(): Promise<void>;
17
+ joinDirect(host: string, port: number): Promise<void>;
18
+ leave(): Promise<void>;
19
+ getPeers(): PeerInfo[];
20
+ sendSearchQuery(peerId: string, queryId: string, embedding: number[], limit: number): void;
21
+ sendSearchResult(peerId: string, queryId: string, results: Array<{
22
+ title: string;
23
+ similarity: number;
24
+ snippet: string;
25
+ }>): void;
26
+ private handleConnection;
27
+ private validateMessage;
28
+ private handleMessage;
29
+ private sendMessage;
30
+ }
31
+ //# sourceMappingURL=node.d.ts.map