stellavault 0.1.0 → 0.2.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.
- package/.github/workflows/pages.yml +37 -0
- package/package.json +1 -1
- package/packages/cli/bin/ekh.js +2 -2
- package/packages/cli/dist/commands/federate-cmd.d.ts.map +1 -1
- package/packages/cli/dist/commands/federate-cmd.js +61 -31
- package/packages/cli/dist/commands/federate-cmd.js.map +1 -1
- package/packages/cli/src/commands/federate-cmd.ts +49 -29
- package/packages/core/src/federation/sharing.ts +236 -86
- package/packages/core/src/index.ts +2 -2
- package/packages/graph/dist/assets/camera_utils-BMxqtvoZ.js +1 -0
- package/packages/graph/dist/assets/hands-DXA01_mx.js +18 -0
- package/packages/graph/dist/assets/index-DMEe2diW.js +4192 -0
- package/packages/graph/dist/assets/layout.worker-DbKCEFTz.js +1 -0
- package/packages/graph/dist/index.html +17 -0
- package/packages/graph/test-click.mjs +49 -49
- package/packages/graph/test-explore.mjs +102 -102
- package/packages/graph/test-final.mjs +61 -61
- package/packages/graph/test-hover.mjs +48 -48
- package/packages/graph/test-pulse.mjs +68 -68
- package/packages/graph/test-screenshot.mjs +56 -56
- package/packages/graph/test-v2.mjs +97 -97
- package/packages/graph/tsconfig.tsbuildinfo +1 -0
- package/packages/sync/.env.example +11 -11
- package/packages/sync/create-stella-network-notion.mjs +151 -151
- package/packages/sync/create-stellavault-project-notion.mjs +322 -322
- package/packages/sync/package-lock.json +373 -373
- package/tsconfig.base.json +18 -18
|
@@ -1,68 +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();
|
|
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();
|
|
@@ -1,56 +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();
|
|
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();
|
|
@@ -1,97 +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();
|
|
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 @@
|
|
|
1
|
+
{"root":["./src/app.tsx","./src/main.tsx","./src/api/client.ts","./src/components/clusterfilter.tsx","./src/components/constellationview.tsx","./src/components/exportpanel.tsx","./src/components/graph3d.tsx","./src/components/graphedges.tsx","./src/components/graphnodes.tsx","./src/components/healthdashboard.tsx","./src/components/layout.tsx","./src/components/motionoverlay.tsx","./src/components/motiontoggle.tsx","./src/components/multiverseview.tsx","./src/components/nodedetail.tsx","./src/components/pulseparticle.tsx","./src/components/searchbar.tsx","./src/components/starfield.tsx","./src/components/statusbar.tsx","./src/components/timeline.tsx","./src/components/toolspanel.tsx","./src/components/tooltip.tsx","./src/components/typefilter.tsx","./src/embed/embedgraph.tsx","./src/hooks/useconstellationlod.ts","./src/hooks/usedecay.ts","./src/hooks/useexport.ts","./src/hooks/usegraph.ts","./src/hooks/usekeyboardnav.ts","./src/hooks/uselayout.ts","./src/hooks/usemotion.ts","./src/hooks/usepulse.ts","./src/hooks/usesearch.ts","./src/lib/constellation.ts","./src/lib/export-utils.ts","./src/lib/gesture-detector.ts","./src/lib/layout.worker.ts","./src/lib/motion-controller.ts","./src/lib/profile-card.ts","./src/stores/graph-store.ts"],"version":"5.9.3"}
|
|
@@ -1,11 +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
|
|
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
|