stellavault 0.1.0

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 (294) hide show
  1. package/.env.example +12 -0
  2. package/CLAUDE.md +39 -0
  3. package/CONTRIBUTING.md +65 -0
  4. package/LICENSE +21 -0
  5. package/README.md +182 -0
  6. package/memory/MEMORY.md +25 -0
  7. package/package.json +33 -0
  8. package/packages/cli/bin/ekh.js +2 -0
  9. package/packages/cli/bin/stellavault.js +2 -0
  10. package/packages/cli/dist/commands/brief-cmd.d.ts +2 -0
  11. package/packages/cli/dist/commands/brief-cmd.d.ts.map +1 -0
  12. package/packages/cli/dist/commands/brief-cmd.js +82 -0
  13. package/packages/cli/dist/commands/brief-cmd.js.map +1 -0
  14. package/packages/cli/dist/commands/capture-cmd.d.ts +7 -0
  15. package/packages/cli/dist/commands/capture-cmd.d.ts.map +1 -0
  16. package/packages/cli/dist/commands/capture-cmd.js +31 -0
  17. package/packages/cli/dist/commands/capture-cmd.js.map +1 -0
  18. package/packages/cli/dist/commands/card-cmd.d.ts +4 -0
  19. package/packages/cli/dist/commands/card-cmd.d.ts.map +1 -0
  20. package/packages/cli/dist/commands/card-cmd.js +26 -0
  21. package/packages/cli/dist/commands/card-cmd.js.map +1 -0
  22. package/packages/cli/dist/commands/clip-cmd.d.ts +4 -0
  23. package/packages/cli/dist/commands/clip-cmd.d.ts.map +1 -0
  24. package/packages/cli/dist/commands/clip-cmd.js +151 -0
  25. package/packages/cli/dist/commands/clip-cmd.js.map +1 -0
  26. package/packages/cli/dist/commands/cloud-cmd.d.ts +4 -0
  27. package/packages/cli/dist/commands/cloud-cmd.d.ts.map +1 -0
  28. package/packages/cli/dist/commands/cloud-cmd.js +64 -0
  29. package/packages/cli/dist/commands/cloud-cmd.js.map +1 -0
  30. package/packages/cli/dist/commands/contradictions-cmd.d.ts +2 -0
  31. package/packages/cli/dist/commands/contradictions-cmd.d.ts.map +1 -0
  32. package/packages/cli/dist/commands/contradictions-cmd.js +34 -0
  33. package/packages/cli/dist/commands/contradictions-cmd.js.map +1 -0
  34. package/packages/cli/dist/commands/decay-cmd.d.ts +2 -0
  35. package/packages/cli/dist/commands/decay-cmd.d.ts.map +1 -0
  36. package/packages/cli/dist/commands/decay-cmd.js +48 -0
  37. package/packages/cli/dist/commands/decay-cmd.js.map +1 -0
  38. package/packages/cli/dist/commands/digest-cmd.d.ts +4 -0
  39. package/packages/cli/dist/commands/digest-cmd.d.ts.map +1 -0
  40. package/packages/cli/dist/commands/digest-cmd.js +79 -0
  41. package/packages/cli/dist/commands/digest-cmd.js.map +1 -0
  42. package/packages/cli/dist/commands/duplicates-cmd.d.ts +4 -0
  43. package/packages/cli/dist/commands/duplicates-cmd.d.ts.map +1 -0
  44. package/packages/cli/dist/commands/duplicates-cmd.js +30 -0
  45. package/packages/cli/dist/commands/duplicates-cmd.js.map +1 -0
  46. package/packages/cli/dist/commands/federate-cmd.d.ts +5 -0
  47. package/packages/cli/dist/commands/federate-cmd.d.ts.map +1 -0
  48. package/packages/cli/dist/commands/federate-cmd.js +217 -0
  49. package/packages/cli/dist/commands/federate-cmd.js.map +1 -0
  50. package/packages/cli/dist/commands/gaps-cmd.d.ts +2 -0
  51. package/packages/cli/dist/commands/gaps-cmd.d.ts.map +1 -0
  52. package/packages/cli/dist/commands/gaps-cmd.js +33 -0
  53. package/packages/cli/dist/commands/gaps-cmd.js.map +1 -0
  54. package/packages/cli/dist/commands/graph-cmd.d.ts +2 -0
  55. package/packages/cli/dist/commands/graph-cmd.d.ts.map +1 -0
  56. package/packages/cli/dist/commands/graph-cmd.js +77 -0
  57. package/packages/cli/dist/commands/graph-cmd.js.map +1 -0
  58. package/packages/cli/dist/commands/index-cmd.d.ts +2 -0
  59. package/packages/cli/dist/commands/index-cmd.d.ts.map +1 -0
  60. package/packages/cli/dist/commands/index-cmd.js +57 -0
  61. package/packages/cli/dist/commands/index-cmd.js.map +1 -0
  62. package/packages/cli/dist/commands/init-cmd.d.ts +2 -0
  63. package/packages/cli/dist/commands/init-cmd.d.ts.map +1 -0
  64. package/packages/cli/dist/commands/init-cmd.js +123 -0
  65. package/packages/cli/dist/commands/init-cmd.js.map +1 -0
  66. package/packages/cli/dist/commands/learn-cmd.d.ts +2 -0
  67. package/packages/cli/dist/commands/learn-cmd.d.ts.map +1 -0
  68. package/packages/cli/dist/commands/learn-cmd.js +48 -0
  69. package/packages/cli/dist/commands/learn-cmd.js.map +1 -0
  70. package/packages/cli/dist/commands/pack-cmd.d.ts +15 -0
  71. package/packages/cli/dist/commands/pack-cmd.d.ts.map +1 -0
  72. package/packages/cli/dist/commands/pack-cmd.js +93 -0
  73. package/packages/cli/dist/commands/pack-cmd.js.map +1 -0
  74. package/packages/cli/dist/commands/review-cmd.d.ts +4 -0
  75. package/packages/cli/dist/commands/review-cmd.d.ts.map +1 -0
  76. package/packages/cli/dist/commands/review-cmd.js +107 -0
  77. package/packages/cli/dist/commands/review-cmd.js.map +1 -0
  78. package/packages/cli/dist/commands/search-cmd.d.ts +4 -0
  79. package/packages/cli/dist/commands/search-cmd.d.ts.map +1 -0
  80. package/packages/cli/dist/commands/search-cmd.js +38 -0
  81. package/packages/cli/dist/commands/search-cmd.js.map +1 -0
  82. package/packages/cli/dist/commands/serve-cmd.d.ts +2 -0
  83. package/packages/cli/dist/commands/serve-cmd.d.ts.map +1 -0
  84. package/packages/cli/dist/commands/serve-cmd.js +14 -0
  85. package/packages/cli/dist/commands/serve-cmd.js.map +1 -0
  86. package/packages/cli/dist/commands/status-cmd.d.ts +2 -0
  87. package/packages/cli/dist/commands/status-cmd.d.ts.map +1 -0
  88. package/packages/cli/dist/commands/status-cmd.js +33 -0
  89. package/packages/cli/dist/commands/status-cmd.js.map +1 -0
  90. package/packages/cli/dist/commands/sync-cmd.d.ts +5 -0
  91. package/packages/cli/dist/commands/sync-cmd.d.ts.map +1 -0
  92. package/packages/cli/dist/commands/sync-cmd.js +62 -0
  93. package/packages/cli/dist/commands/sync-cmd.js.map +1 -0
  94. package/packages/cli/dist/commands/vault-cmd.d.ts +10 -0
  95. package/packages/cli/dist/commands/vault-cmd.d.ts.map +1 -0
  96. package/packages/cli/dist/commands/vault-cmd.js +54 -0
  97. package/packages/cli/dist/commands/vault-cmd.js.map +1 -0
  98. package/packages/cli/dist/index.d.ts +2 -0
  99. package/packages/cli/dist/index.d.ts.map +1 -0
  100. package/packages/cli/dist/index.js +156 -0
  101. package/packages/cli/dist/index.js.map +1 -0
  102. package/packages/cli/package.json +24 -0
  103. package/packages/cli/src/commands/brief-cmd.ts +87 -0
  104. package/packages/cli/src/commands/capture-cmd.ts +34 -0
  105. package/packages/cli/src/commands/card-cmd.ts +29 -0
  106. package/packages/cli/src/commands/clip-cmd.ts +172 -0
  107. package/packages/cli/src/commands/cloud-cmd.ts +75 -0
  108. package/packages/cli/src/commands/contradictions-cmd.ts +41 -0
  109. package/packages/cli/src/commands/decay-cmd.ts +57 -0
  110. package/packages/cli/src/commands/digest-cmd.ts +89 -0
  111. package/packages/cli/src/commands/duplicates-cmd.ts +38 -0
  112. package/packages/cli/src/commands/federate-cmd.ts +236 -0
  113. package/packages/cli/src/commands/gaps-cmd.ts +40 -0
  114. package/packages/cli/src/commands/graph-cmd.ts +88 -0
  115. package/packages/cli/src/commands/index-cmd.ts +65 -0
  116. package/packages/cli/src/commands/init-cmd.ts +145 -0
  117. package/packages/cli/src/commands/learn-cmd.ts +56 -0
  118. package/packages/cli/src/commands/pack-cmd.ts +121 -0
  119. package/packages/cli/src/commands/review-cmd.ts +125 -0
  120. package/packages/cli/src/commands/search-cmd.ts +45 -0
  121. package/packages/cli/src/commands/serve-cmd.ts +17 -0
  122. package/packages/cli/src/commands/status-cmd.ts +37 -0
  123. package/packages/cli/src/commands/sync-cmd.ts +68 -0
  124. package/packages/cli/src/commands/vault-cmd.ts +64 -0
  125. package/packages/cli/src/index.ts +187 -0
  126. package/packages/core/package.json +40 -0
  127. package/packages/core/src/api/dashboard.ts +138 -0
  128. package/packages/core/src/api/graph-data.ts +286 -0
  129. package/packages/core/src/api/pwa.ts +82 -0
  130. package/packages/core/src/api/server.ts +660 -0
  131. package/packages/core/src/capture/voice.ts +168 -0
  132. package/packages/core/src/cloud/index.ts +2 -0
  133. package/packages/core/src/cloud/sync.ts +167 -0
  134. package/packages/core/src/config.ts +82 -0
  135. package/packages/core/src/federation/credits.ts +80 -0
  136. package/packages/core/src/federation/hyperswarm.d.ts +19 -0
  137. package/packages/core/src/federation/identity.ts +90 -0
  138. package/packages/core/src/federation/index.ts +8 -0
  139. package/packages/core/src/federation/node.ts +235 -0
  140. package/packages/core/src/federation/privacy.ts +52 -0
  141. package/packages/core/src/federation/reputation.ts +202 -0
  142. package/packages/core/src/federation/search.ts +129 -0
  143. package/packages/core/src/federation/sharing.ts +165 -0
  144. package/packages/core/src/federation/trust.ts +76 -0
  145. package/packages/core/src/federation/types.ts +25 -0
  146. package/packages/core/src/i18n/index.ts +85 -0
  147. package/packages/core/src/index.ts +133 -0
  148. package/packages/core/src/indexer/chunker.ts +180 -0
  149. package/packages/core/src/indexer/embedder.ts +9 -0
  150. package/packages/core/src/indexer/index.ts +113 -0
  151. package/packages/core/src/indexer/local-embedder.ts +35 -0
  152. package/packages/core/src/indexer/scanner.ts +142 -0
  153. package/packages/core/src/indexer/watcher.ts +62 -0
  154. package/packages/core/src/intelligence/contradiction-detector.ts +134 -0
  155. package/packages/core/src/intelligence/decay-engine.ts +229 -0
  156. package/packages/core/src/intelligence/duplicate-detector.ts +71 -0
  157. package/packages/core/src/intelligence/fsrs.ts +79 -0
  158. package/packages/core/src/intelligence/gap-detector.ts +109 -0
  159. package/packages/core/src/intelligence/learning-path.ts +86 -0
  160. package/packages/core/src/intelligence/notifications.ts +106 -0
  161. package/packages/core/src/intelligence/predictive-gaps.ts +94 -0
  162. package/packages/core/src/intelligence/semantic-versioning.ts +97 -0
  163. package/packages/core/src/intelligence/types.ts +28 -0
  164. package/packages/core/src/mcp/custom-tools.ts +97 -0
  165. package/packages/core/src/mcp/index.ts +1 -0
  166. package/packages/core/src/mcp/server.ts +142 -0
  167. package/packages/core/src/mcp/tools/agentic-graph.ts +96 -0
  168. package/packages/core/src/mcp/tools/brief.ts +49 -0
  169. package/packages/core/src/mcp/tools/decay.ts +40 -0
  170. package/packages/core/src/mcp/tools/decision-journal.ts +95 -0
  171. package/packages/core/src/mcp/tools/export.ts +72 -0
  172. package/packages/core/src/mcp/tools/federated-search.ts +43 -0
  173. package/packages/core/src/mcp/tools/generate-claude-md.ts +130 -0
  174. package/packages/core/src/mcp/tools/get-document.ts +26 -0
  175. package/packages/core/src/mcp/tools/get-related.ts +41 -0
  176. package/packages/core/src/mcp/tools/learning-path.ts +52 -0
  177. package/packages/core/src/mcp/tools/list-topics.ts +20 -0
  178. package/packages/core/src/mcp/tools/search.ts +35 -0
  179. package/packages/core/src/mcp/tools/snapshot.ts +98 -0
  180. package/packages/core/src/multi-vault/index.ts +118 -0
  181. package/packages/core/src/pack/creator.ts +127 -0
  182. package/packages/core/src/pack/exporter.ts +21 -0
  183. package/packages/core/src/pack/importer.ts +82 -0
  184. package/packages/core/src/pack/index.ts +5 -0
  185. package/packages/core/src/pack/marketplace.ts +103 -0
  186. package/packages/core/src/pack/pii-masker.ts +38 -0
  187. package/packages/core/src/pack/types.ts +39 -0
  188. package/packages/core/src/plugins/index.ts +100 -0
  189. package/packages/core/src/plugins/webhooks.ts +110 -0
  190. package/packages/core/src/search/bm25.ts +16 -0
  191. package/packages/core/src/search/index.ts +83 -0
  192. package/packages/core/src/search/rrf.ts +31 -0
  193. package/packages/core/src/search/semantic.ts +15 -0
  194. package/packages/core/src/store/index.ts +2 -0
  195. package/packages/core/src/store/sqlite-vec.ts +290 -0
  196. package/packages/core/src/store/types.ts +22 -0
  197. package/packages/core/src/team/index.ts +126 -0
  198. package/packages/core/src/types/chunk.ts +25 -0
  199. package/packages/core/src/types/document.ts +24 -0
  200. package/packages/core/src/types/graph.ts +44 -0
  201. package/packages/core/src/types/index.ts +15 -0
  202. package/packages/core/src/types/search.ts +38 -0
  203. package/packages/core/src/utils/retry.ts +85 -0
  204. package/packages/core/tests/api-card.test.ts +60 -0
  205. package/packages/core/tests/api-routes.test.ts +98 -0
  206. package/packages/core/tests/bm25.test.ts +87 -0
  207. package/packages/core/tests/chunker.test.ts +48 -0
  208. package/packages/core/tests/cluster.test.ts +75 -0
  209. package/packages/core/tests/constellation.test.ts +77 -0
  210. package/packages/core/tests/export-utils.test.ts +97 -0
  211. package/packages/core/tests/fsrs.test.ts +96 -0
  212. package/packages/core/tests/gesture-detector.test.ts +45 -0
  213. package/packages/core/tests/graph-data.test.ts +87 -0
  214. package/packages/core/tests/layout.test.ts +83 -0
  215. package/packages/core/tests/mcp.test.ts +148 -0
  216. package/packages/core/tests/pack.test.ts +127 -0
  217. package/packages/core/tests/pii-masker.test.ts +42 -0
  218. package/packages/core/tests/profile-card.test.ts +62 -0
  219. package/packages/core/tests/rrf.test.ts +29 -0
  220. package/packages/core/tests/search-integration.test.ts +139 -0
  221. package/packages/core/tests/store.test.ts +80 -0
  222. package/packages/graph/click-result.png +0 -0
  223. package/packages/graph/index.html +17 -0
  224. package/packages/graph/package.json +32 -0
  225. package/packages/graph/src/App.tsx +7 -0
  226. package/packages/graph/src/api/client.ts +39 -0
  227. package/packages/graph/src/components/ClusterFilter.tsx +73 -0
  228. package/packages/graph/src/components/ConstellationView.tsx +232 -0
  229. package/packages/graph/src/components/ExportPanel.tsx +177 -0
  230. package/packages/graph/src/components/Graph3D.tsx +230 -0
  231. package/packages/graph/src/components/GraphEdges.tsx +100 -0
  232. package/packages/graph/src/components/GraphNodes.tsx +386 -0
  233. package/packages/graph/src/components/HealthDashboard.tsx +173 -0
  234. package/packages/graph/src/components/Layout.tsx +214 -0
  235. package/packages/graph/src/components/MotionOverlay.tsx +81 -0
  236. package/packages/graph/src/components/MotionToggle.tsx +33 -0
  237. package/packages/graph/src/components/MultiverseView.tsx +286 -0
  238. package/packages/graph/src/components/NodeDetail.tsx +232 -0
  239. package/packages/graph/src/components/PulseParticle.tsx +232 -0
  240. package/packages/graph/src/components/SearchBar.tsx +107 -0
  241. package/packages/graph/src/components/StarField.tsx +197 -0
  242. package/packages/graph/src/components/StatusBar.tsx +53 -0
  243. package/packages/graph/src/components/Timeline.tsx +148 -0
  244. package/packages/graph/src/components/ToolsPanel.tsx +512 -0
  245. package/packages/graph/src/components/Tooltip.tsx +100 -0
  246. package/packages/graph/src/components/TypeFilter.tsx +131 -0
  247. package/packages/graph/src/embed/EmbedGraph.tsx +144 -0
  248. package/packages/graph/src/hooks/useConstellationLOD.ts +76 -0
  249. package/packages/graph/src/hooks/useDecay.ts +37 -0
  250. package/packages/graph/src/hooks/useExport.ts +165 -0
  251. package/packages/graph/src/hooks/useGraph.ts +69 -0
  252. package/packages/graph/src/hooks/useKeyboardNav.ts +122 -0
  253. package/packages/graph/src/hooks/useLayout.ts +45 -0
  254. package/packages/graph/src/hooks/useMotion.ts +120 -0
  255. package/packages/graph/src/hooks/usePulse.ts +58 -0
  256. package/packages/graph/src/hooks/useSearch.ts +71 -0
  257. package/packages/graph/src/lib/constellation.ts +107 -0
  258. package/packages/graph/src/lib/export-utils.ts +48 -0
  259. package/packages/graph/src/lib/gesture-detector.ts +123 -0
  260. package/packages/graph/src/lib/layout.worker.ts +153 -0
  261. package/packages/graph/src/lib/motion-controller.ts +83 -0
  262. package/packages/graph/src/lib/profile-card.ts +122 -0
  263. package/packages/graph/src/main.tsx +4 -0
  264. package/packages/graph/src/stores/graph-store.ts +155 -0
  265. package/packages/graph/success.png +0 -0
  266. package/packages/graph/test-click.mjs +49 -0
  267. package/packages/graph/test-explore.mjs +102 -0
  268. package/packages/graph/test-final.mjs +61 -0
  269. package/packages/graph/test-graph.mjs +139 -0
  270. package/packages/graph/test-hover.mjs +48 -0
  271. package/packages/graph/test-pulse.mjs +68 -0
  272. package/packages/graph/test-screenshot.mjs +56 -0
  273. package/packages/graph/test-v2.mjs +97 -0
  274. package/packages/graph/vite.config.ts +15 -0
  275. package/packages/sync/.env.example +11 -0
  276. package/packages/sync/.sync-state.json +317 -0
  277. package/packages/sync/.upload-state.json +1009 -0
  278. package/packages/sync/create-stella-network-notion.mjs +151 -0
  279. package/packages/sync/create-stellavault-project-notion.mjs +322 -0
  280. package/packages/sync/logs/sync-2026-03-28.log +6 -0
  281. package/packages/sync/logs/sync-2026-03-29.log +12 -0
  282. package/packages/sync/logs/sync-2026-03-30.log +6 -0
  283. package/packages/sync/logs/sync-2026-03-31.log +6 -0
  284. package/packages/sync/logs/sync-2026-04-01.log +6 -0
  285. package/packages/sync/logs/sync-2026-04-02.log +6 -0
  286. package/packages/sync/package-lock.json +373 -0
  287. package/packages/sync/package.json +16 -0
  288. package/packages/sync/run-sync.bat +18 -0
  289. package/packages/sync/run-sync.mjs +46 -0
  290. package/packages/sync/setup-scheduler.mjs +119 -0
  291. package/packages/sync/structured-sync.mjs +187 -0
  292. package/packages/sync/sync-to-obsidian.mjs +264 -0
  293. package/packages/sync/upload-pdca-to-notion.mjs +495 -0
  294. package/tsconfig.base.json +18 -0
@@ -0,0 +1,61 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage({ viewport: { width: 1400, height: 800 } });
5
+ await page.goto('http://localhost:5173');
6
+ await page.waitForTimeout(5000);
7
+
8
+ const canvas = await page.locator('canvas').boundingBox();
9
+ const cx = canvas.x + canvas.width / 2;
10
+ const cy = canvas.y + canvas.height / 2;
11
+
12
+ for (let dx = -250; dx <= 250; dx += 20) {
13
+ for (let dy = -200; dy <= 200; dy += 20) {
14
+ await page.mouse.move(cx + dx, cy + dy);
15
+ await page.waitForTimeout(30);
16
+ const cursor = await page.evaluate(() => document.body.style.cursor);
17
+ if (cursor === 'pointer') {
18
+ console.log(`Node at [${dx}, ${dy}]`);
19
+
20
+ // 클릭
21
+ await page.mouse.click(cx + dx, cy + dy);
22
+ await page.waitForTimeout(1500);
23
+
24
+ // 확인
25
+ const result = await page.evaluate(() => {
26
+ const text = document.body.innerText;
27
+ const has380 = !!Array.from(document.querySelectorAll('div')).find(d => d.style.width === '380px');
28
+ return {
29
+ hasPanel: has380,
30
+ hasPreview: text.includes('DOCUMENT PREVIEW') || text.includes('Document Preview'),
31
+ hasExplore: text.includes('Explore connections'),
32
+ };
33
+ });
34
+ console.log('Result:', JSON.stringify(result));
35
+
36
+ if (result.hasPanel) {
37
+ console.log('SUCCESS - Panel is visible!');
38
+ await page.screenshot({ path: 'success.png', fullPage: true });
39
+ } else {
40
+ console.log('FAIL - Panel not found');
41
+
42
+ // 디버그: selectedNodeId 확인
43
+ const debug = await page.evaluate(() => {
44
+ // zustand 내부 상태에 접근할 수 없으므로 DOM 기반으로 확인
45
+ return {
46
+ allText: document.body.innerText.slice(0, 300),
47
+ divCount: document.querySelectorAll('div').length,
48
+ };
49
+ });
50
+ console.log('Debug:', JSON.stringify(debug, null, 2));
51
+ }
52
+
53
+ await page.waitForTimeout(2000);
54
+ await browser.close();
55
+ process.exit(0);
56
+ }
57
+ }
58
+ }
59
+
60
+ console.log('No node found');
61
+ await browser.close();
@@ -0,0 +1,139 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage();
5
+
6
+ console.log('1. Opening graph...');
7
+ await page.goto('http://localhost:5173');
8
+ await page.waitForTimeout(3000);
9
+
10
+ // 페이지 상태 확인
11
+ const statusText = await page.locator('body').innerText();
12
+ console.log('2. Page text:', statusText.slice(0, 200));
13
+
14
+ // 콘솔 로그 캡처
15
+ page.on('console', msg => {
16
+ if (msg.type() === 'error') console.log(' [CONSOLE ERROR]', msg.text());
17
+ });
18
+
19
+ // zustand store 상태 확인
20
+ const storeState = await page.evaluate(() => {
21
+ // zustand store 직접 접근 시도
22
+ const root = document.getElementById('root');
23
+ return {
24
+ rootExists: !!root,
25
+ rootChildren: root?.children?.length ?? 0,
26
+ rootHTML: root?.innerHTML?.slice(0, 500) ?? 'empty',
27
+ };
28
+ });
29
+ console.log('3. Root state:', JSON.stringify(storeState, null, 2));
30
+
31
+ // selectedNodeId 상태 확인
32
+ const graphState = await page.evaluate(() => {
33
+ try {
34
+ // window에 노출된 함수로 상태 확인
35
+ return {
36
+ hasPulse: typeof window.__sv_pulse === 'function',
37
+ hasStopPulse: typeof window.__sv_stopPulse === 'function',
38
+ };
39
+ } catch (e) {
40
+ return { error: String(e) };
41
+ }
42
+ });
43
+ console.log('4. Graph functions:', JSON.stringify(graphState));
44
+
45
+ // Canvas 요소 확인
46
+ const canvasInfo = await page.evaluate(() => {
47
+ const canvas = document.querySelector('canvas');
48
+ return {
49
+ canvasExists: !!canvas,
50
+ canvasSize: canvas ? `${canvas.width}x${canvas.height}` : 'none',
51
+ };
52
+ });
53
+ console.log('5. Canvas:', JSON.stringify(canvasInfo));
54
+
55
+ // 노드 호버 시뮬레이션: 캔버스 중앙 근처로 마우스 이동
56
+ const canvasBounds = await page.locator('canvas').boundingBox();
57
+ if (canvasBounds) {
58
+ const cx = canvasBounds.x + canvasBounds.width / 2;
59
+ const cy = canvasBounds.y + canvasBounds.height / 2;
60
+
61
+ console.log('6. Moving mouse to canvas center:', cx, cy);
62
+ await page.mouse.move(cx, cy);
63
+ await page.waitForTimeout(500);
64
+
65
+ // 호버 후 상태
66
+ const afterHover = await page.evaluate(() => {
67
+ // DOM에서 사이드패널 찾기
68
+ const panels = document.querySelectorAll('div');
69
+ let sidePanel = null;
70
+ panels.forEach(p => {
71
+ if (p.style.width === '380px') sidePanel = p;
72
+ });
73
+ return {
74
+ panelFound: !!sidePanel,
75
+ totalDivs: panels.length,
76
+ };
77
+ });
78
+ console.log('7. After hover:', JSON.stringify(afterHover));
79
+
80
+ // 클릭
81
+ console.log('8. Clicking...');
82
+ await page.mouse.click(cx, cy);
83
+ await page.waitForTimeout(1000);
84
+
85
+ // 클릭 후 상태
86
+ const afterClick = await page.evaluate(() => {
87
+ const panels = document.querySelectorAll('div');
88
+ let sidePanel = null;
89
+ let sidePanelText = '';
90
+ panels.forEach(p => {
91
+ if (p.style.width === '380px') {
92
+ sidePanel = p;
93
+ sidePanelText = p.innerText?.slice(0, 100) ?? '';
94
+ }
95
+ });
96
+
97
+ // zustand 상태 직접 확인 — React 내부 접근
98
+ const allText = document.body.innerText;
99
+ const hasDocPreview = allText.includes('Document Preview');
100
+ const hasExplore = allText.includes('Explore connections');
101
+
102
+ return {
103
+ panelFound: !!sidePanel,
104
+ sidePanelText,
105
+ hasDocPreview,
106
+ hasExplore,
107
+ bodyTextSnippet: allText.slice(0, 300),
108
+ };
109
+ });
110
+ console.log('9. After click:', JSON.stringify(afterClick, null, 2));
111
+
112
+ // 여러 위치에서 클릭 시도 (노드가 있을만한 곳)
113
+ for (const offset of [[0, 0], [-100, -50], [100, 50], [-50, 80], [80, -60]]) {
114
+ const x = cx + offset[0];
115
+ const y = cy + offset[1];
116
+ await page.mouse.move(x, y);
117
+ await page.waitForTimeout(300);
118
+
119
+ const cursorStyle = await page.evaluate(() => document.body.style.cursor);
120
+ if (cursorStyle === 'pointer') {
121
+ console.log(`10. Found node at offset [${offset}]! Clicking...`);
122
+ await page.mouse.click(x, y);
123
+ await page.waitForTimeout(1000);
124
+
125
+ const result = await page.evaluate(() => {
126
+ return {
127
+ bodyText: document.body.innerText.slice(0, 500),
128
+ has380Panel: !!Array.from(document.querySelectorAll('div')).find(d => d.style.width === '380px'),
129
+ };
130
+ });
131
+ console.log('11. After node click:', JSON.stringify(result, null, 2));
132
+ break;
133
+ }
134
+ }
135
+ }
136
+
137
+ await page.waitForTimeout(3000);
138
+ await browser.close();
139
+ console.log('Done.');
@@ -0,0 +1,48 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage({ viewport: { width: 1400, height: 800 } });
5
+ await page.goto('http://localhost:5173');
6
+ await page.waitForTimeout(5000);
7
+
8
+ const canvas = await page.locator('canvas').boundingBox();
9
+ const cx = canvas.x + canvas.width / 2;
10
+ const cy = canvas.y + canvas.height / 2;
11
+
12
+ // 1. 노드 찾아서 호버만 (클릭 없이)
13
+ for (let dx = -250; dx <= 250; dx += 20) {
14
+ for (let dy = -200; dy <= 200; dy += 20) {
15
+ await page.mouse.move(cx + dx, cy + dy);
16
+ await page.waitForTimeout(30);
17
+ const cursor = await page.evaluate(() => document.body.style.cursor);
18
+ if (cursor === 'pointer') {
19
+ console.log(`Node at [${dx}, ${dy}] — hovering (no click)`);
20
+ await page.waitForTimeout(1500);
21
+
22
+ const result = await page.evaluate(() => {
23
+ const text = document.body.innerText;
24
+ return {
25
+ hasPreview: text.includes('Document Preview') || text.includes('DOCUMENT PREVIEW'),
26
+ hasExplore: text.includes('Explore connections'),
27
+ snippet: text.slice(0, 300),
28
+ };
29
+ });
30
+ console.log('Hover result:', JSON.stringify(result, null, 2));
31
+
32
+ // 2. 마우스를 빈 곳으로 이동 → 패널 사라지는지
33
+ await page.mouse.move(cx + 250, cy + 200);
34
+ await page.waitForTimeout(800);
35
+ const afterLeave = await page.evaluate(() => {
36
+ return document.body.innerText.includes('Document Preview');
37
+ });
38
+ console.log('After leave:', afterLeave ? 'Panel still visible' : 'Panel hidden');
39
+
40
+ await page.waitForTimeout(2000);
41
+ await browser.close();
42
+ process.exit(0);
43
+ }
44
+ }
45
+ }
46
+
47
+ console.log('No node found');
48
+ await browser.close();
@@ -0,0 +1,68 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage({ viewport: { width: 1400, height: 800 } });
5
+ page.on('console', m => { if (m.type() === 'error') console.log('ERR:', m.text()); });
6
+ await page.goto('http://localhost:5173');
7
+ await page.waitForTimeout(5000);
8
+
9
+ const canvas = await page.locator('canvas').boundingBox();
10
+ const cx = canvas.x + canvas.width / 2;
11
+ const cy = canvas.y + canvas.height / 2;
12
+
13
+ // 노드 찾아서 클릭
14
+ for (let dx = -250; dx <= 250; dx += 15) {
15
+ for (let dy = -200; dy <= 200; dy += 15) {
16
+ await page.mouse.move(cx + dx, cy + dy);
17
+ await page.waitForTimeout(20);
18
+ if (await page.evaluate(() => document.body.style.cursor) === 'pointer') {
19
+ await page.waitForTimeout(200);
20
+ await page.mouse.down(); await page.waitForTimeout(50); await page.mouse.up();
21
+ await page.waitForTimeout(1500);
22
+
23
+ // Explore 클릭
24
+ const btn = page.locator('button', { hasText: 'Explore connections' });
25
+ if (await btn.isVisible()) {
26
+ console.log('Clicking Explore...');
27
+ await btn.click();
28
+
29
+ // 2초 동안 모니터링
30
+ for (let i = 0; i < 20; i++) {
31
+ await page.waitForTimeout(200);
32
+ const state = await page.evaluate(() => {
33
+ const cv = document.querySelector('canvas');
34
+ // 빛 입자가 있는지 확인 (mesh 개수 변화)
35
+ return {
36
+ canvasOK: cv ? cv.offsetWidth > 0 : false,
37
+ };
38
+ });
39
+ if (i % 5 === 0) console.log(` ${i * 200}ms: canvas=${state.canvasOK}`);
40
+ }
41
+
42
+ // 완료 후 다른 노드 클릭
43
+ console.log('Clicking another node...');
44
+ for (let dx2 = -100; dx2 <= 100; dx2 += 15) {
45
+ for (let dy2 = -100; dy2 <= 100; dy2 += 15) {
46
+ await page.mouse.move(cx + dx2, cy + dy2);
47
+ await page.waitForTimeout(20);
48
+ if (await page.evaluate(() => document.body.style.cursor) === 'pointer') {
49
+ await page.mouse.down(); await page.waitForTimeout(50); await page.mouse.up();
50
+ await page.waitForTimeout(1000);
51
+ const ok = await page.evaluate(() => {
52
+ const cv = document.querySelector('canvas');
53
+ return { canvasW: cv?.offsetWidth ?? 0, hasPanel: document.body.innerText.includes('DOCUMENT PREVIEW') };
54
+ });
55
+ console.log('After 2nd click:', JSON.stringify(ok));
56
+ break;
57
+ }
58
+ }
59
+ break;
60
+ }
61
+ }
62
+ await page.waitForTimeout(2000);
63
+ await browser.close();
64
+ process.exit(0);
65
+ }
66
+ }
67
+ }
68
+ await browser.close();
@@ -0,0 +1,56 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage({ viewport: { width: 1400, height: 800 } });
5
+ await page.goto('http://localhost:5173');
6
+ await page.waitForTimeout(5000);
7
+
8
+ await page.screenshot({ path: '../../../images/before-click.png' });
9
+ console.log('1. Before click screenshot saved');
10
+
11
+ const canvas = await page.locator('canvas').boundingBox();
12
+ const cx = canvas.x + canvas.width / 2;
13
+ const cy = canvas.y + canvas.height / 2;
14
+
15
+ // 노드 찾기
16
+ for (let dx = -250; dx <= 250; dx += 20) {
17
+ for (let dy = -200; dy <= 200; dy += 20) {
18
+ await page.mouse.move(cx + dx, cy + dy);
19
+ await page.waitForTimeout(30);
20
+ const cursor = await page.evaluate(() => document.body.style.cursor);
21
+ if (cursor === 'pointer') {
22
+ console.log(`2. Node found at [${dx}, ${dy}], clicking...`);
23
+ await page.mouse.click(cx + dx, cy + dy);
24
+ await page.waitForTimeout(2000);
25
+ await page.screenshot({ path: '../../../images/after-click.png' });
26
+ console.log('3. After click screenshot saved');
27
+
28
+ // DOM 디버그
29
+ const debug = await page.evaluate(() => {
30
+ const all = document.querySelectorAll('*');
31
+ let panel = null;
32
+ all.forEach(el => {
33
+ if (el.textContent?.includes('DOCUMENT PREVIEW') && el.tagName === 'DIV') {
34
+ const rect = el.getBoundingClientRect();
35
+ panel = {
36
+ tag: el.tagName,
37
+ rect: { x: rect.x, y: rect.y, w: rect.width, h: rect.height },
38
+ visible: rect.width > 0 && rect.height > 0,
39
+ display: getComputedStyle(el).display,
40
+ overflow: getComputedStyle(el).overflow,
41
+ zIndex: getComputedStyle(el).zIndex,
42
+ };
43
+ }
44
+ });
45
+ return { panel, windowSize: { w: window.innerWidth, h: window.innerHeight } };
46
+ });
47
+ console.log('4. Panel debug:', JSON.stringify(debug, null, 2));
48
+
49
+ await browser.close();
50
+ process.exit(0);
51
+ }
52
+ }
53
+ }
54
+
55
+ console.log('No node found');
56
+ await browser.close();
@@ -0,0 +1,97 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch({ headless: false });
4
+ const page = await browser.newPage({ viewport: { width: 1400, height: 800 } });
5
+ await page.goto('http://localhost:5173');
6
+ await page.waitForTimeout(5000);
7
+
8
+ const canvas = await page.locator('canvas').boundingBox();
9
+ const cx = canvas.x + canvas.width / 2;
10
+ const cy = canvas.y + canvas.height / 2;
11
+
12
+ // 1. 노드 찾기
13
+ let nodeX = 0, nodeY = 0;
14
+ for (let dx = -250; dx <= 250; dx += 15) {
15
+ for (let dy = -200; dy <= 200; dy += 15) {
16
+ await page.mouse.move(cx + dx, cy + dy);
17
+ await page.waitForTimeout(20);
18
+ const cursor = await page.evaluate(() => document.body.style.cursor);
19
+ if (cursor === 'pointer') {
20
+ nodeX = cx + dx;
21
+ nodeY = cy + dy;
22
+ console.log(`1. Node found at [${dx}, ${dy}]`);
23
+ break;
24
+ }
25
+ }
26
+ if (nodeX) break;
27
+ }
28
+
29
+ if (!nodeX) { console.log('No node found'); await browser.close(); process.exit(1); }
30
+
31
+ // 2. 호버 상태 확인 (툴팁만, 사이드패널 없음)
32
+ await page.mouse.move(nodeX, nodeY);
33
+ await page.waitForTimeout(500);
34
+ let result = await page.evaluate(() => ({
35
+ hasPanel: document.body.innerText.includes('Document Preview'),
36
+ bodySnippet: document.body.innerText.slice(0, 200),
37
+ }));
38
+ console.log(`2. Hover only — panel: ${result.hasPanel}`);
39
+
40
+ // 3. 클릭 (mousedown + mouseup at same position)
41
+ await page.mouse.move(nodeX, nodeY);
42
+ await page.waitForTimeout(200);
43
+ await page.mouse.down();
44
+ await page.waitForTimeout(50);
45
+ await page.mouse.up();
46
+ await page.waitForTimeout(1500);
47
+
48
+ result = await page.evaluate(() => ({
49
+ hasPanel: document.body.innerText.includes('Document Preview'),
50
+ hasExplore: document.body.innerText.includes('Explore connections'),
51
+ snippet: document.body.innerText.slice(0, 400),
52
+ }));
53
+ console.log(`3. After click — panel: ${result.hasPanel}, explore: ${result.hasExplore}`);
54
+ if (result.hasPanel) console.log(' Content:', result.snippet.slice(200, 400));
55
+
56
+ // 4. 빈 곳 클릭 → 해제
57
+ await page.mouse.move(cx + 300, cy + 250);
58
+ await page.waitForTimeout(200);
59
+ await page.mouse.down();
60
+ await page.waitForTimeout(50);
61
+ await page.mouse.up();
62
+ await page.waitForTimeout(800);
63
+
64
+ result = await page.evaluate(() => ({
65
+ hasPanel: document.body.innerText.includes('Document Preview'),
66
+ }));
67
+ console.log(`4. After empty click — panel: ${result.hasPanel}`);
68
+
69
+ // 5. 같은 노드 다시 클릭 → 열기
70
+ await page.mouse.move(nodeX, nodeY);
71
+ await page.waitForTimeout(300);
72
+ await page.mouse.down();
73
+ await page.waitForTimeout(50);
74
+ await page.mouse.up();
75
+ await page.waitForTimeout(1500);
76
+
77
+ result = await page.evaluate(() => ({
78
+ hasPanel: document.body.innerText.includes('Document Preview'),
79
+ }));
80
+ console.log(`5. Re-click node — panel: ${result.hasPanel}`);
81
+
82
+ // 6. 같은 노드 또 클릭 → 토글 닫기
83
+ await page.mouse.move(nodeX, nodeY);
84
+ await page.waitForTimeout(300);
85
+ await page.mouse.down();
86
+ await page.waitForTimeout(50);
87
+ await page.mouse.up();
88
+ await page.waitForTimeout(800);
89
+
90
+ result = await page.evaluate(() => ({
91
+ hasPanel: document.body.innerText.includes('Document Preview'),
92
+ }));
93
+ console.log(`6. Toggle off — panel: ${result.hasPanel}`);
94
+
95
+ console.log('\nDone!');
96
+ await page.waitForTimeout(2000);
97
+ await browser.close();
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 5173,
8
+ proxy: {
9
+ '/api': {
10
+ target: 'http://127.0.0.1:3333',
11
+ changeOrigin: true,
12
+ },
13
+ },
14
+ },
15
+ });
@@ -0,0 +1,11 @@
1
+ # Notion API 키 (https://www.notion.so/my-integrations 에서 생성)
2
+ NOTION_API_KEY=ntn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3
+
4
+ # 프로젝트 상위 페이지 ID (노션 URL의 마지막 32자리)
5
+ NOTION_ROOT_PAGE_ID=330dcee017df808d92d4d9ff46fa7697
6
+
7
+ # 옵시디언 저장 경로
8
+ OBSIDIAN_PATH=F:/obsidian/Evan/04_Projects
9
+
10
+ # 로컬 프로젝트 경로들 (쉼표 구분)
11
+ PROJECT_PATHS=E:/AI코딩프로젝트/클로드코드/ai_destiny,E:/AI코딩프로젝트/클로드코드/project-manager,E:/AI코딩프로젝트/클로드코드/stock_analist_beta,E:/AI코딩프로젝트/클로드코드/stock-autotrade,E:/AI코딩프로젝트/클로드코드/vibevonweb,E:/AI코딩프로젝트/클로드코드/TEST