@geometra/cli 1.15.5 → 1.16.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/dist/bin.js +53 -24
- package/dist/bin.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/text-dump.d.ts +6 -0
- package/dist/text-dump.d.ts.map +1 -0
- package/dist/text-dump.js +98 -0
- package/dist/text-dump.js.map +1 -0
- package/package.json +4 -4
package/dist/bin.js
CHANGED
|
@@ -1,44 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { viewInTerminal } from './viewer.js';
|
|
3
3
|
import { TerminalCompositor } from './compositor.js';
|
|
4
|
-
|
|
4
|
+
import { dumpPage } from './text-dump.js';
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
const flags = new Set(args.filter(a => a.startsWith('--')));
|
|
7
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
8
|
+
const url = positional[0];
|
|
9
|
+
const textMode = flags.has('--text');
|
|
10
|
+
const jsonMode = flags.has('--json');
|
|
5
11
|
if (!url) {
|
|
6
|
-
console.error('Usage: geometra <url>');
|
|
12
|
+
console.error('Usage: geometra <url> [--text] [--json]');
|
|
7
13
|
console.error('');
|
|
8
14
|
console.error(' View any Geometra-powered site in the terminal.');
|
|
9
15
|
console.error('');
|
|
16
|
+
console.error('Options:');
|
|
17
|
+
console.error(' --text Output page content as plain text (pipeable to Claude Code)');
|
|
18
|
+
console.error(' --json Output raw UI tree + layout as JSON');
|
|
19
|
+
console.error('');
|
|
10
20
|
console.error('Examples:');
|
|
11
21
|
console.error(' geometra https://artemis-two.razroo.com/');
|
|
12
|
-
console.error(' geometra
|
|
22
|
+
console.error(' geometra https://artemis-two.razroo.com/ --text');
|
|
23
|
+
console.error(' geometra https://artemis-two.razroo.com/ --json');
|
|
24
|
+
console.error(' geometra https://artemis-two.razroo.com/ --text | claude');
|
|
13
25
|
console.error(' geometra ws://localhost:8080/geometra-ws');
|
|
14
26
|
process.exit(1);
|
|
15
27
|
}
|
|
16
28
|
// Direct WebSocket URL — single view
|
|
17
29
|
if (url.startsWith('ws://') || url.startsWith('wss://')) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
if (textMode || jsonMode) {
|
|
31
|
+
dumpPage([url], textMode ? 'text' : 'json').then(() => process.exit(0));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const viewer = viewInTerminal({ url });
|
|
35
|
+
process.on('SIGINT', () => { viewer.close(); process.exit(0); });
|
|
36
|
+
process.on('SIGTERM', () => { viewer.close(); process.exit(0); });
|
|
37
|
+
}
|
|
22
38
|
}
|
|
23
39
|
else {
|
|
24
|
-
// HTTP(S) URL — discover all Geometra WebSocket endpoints and composite
|
|
25
40
|
;
|
|
26
41
|
(async () => {
|
|
27
42
|
const parsed = new URL(url);
|
|
28
43
|
const wsProto = parsed.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
29
44
|
const baseWs = `${wsProto}//${parsed.host}`;
|
|
30
45
|
const baseHttp = `${parsed.protocol}//${parsed.host}`;
|
|
31
|
-
|
|
46
|
+
if (!textMode && !jsonMode) {
|
|
47
|
+
process.stderr.write(`Discovering Geometra views at ${parsed.host}...\n`);
|
|
48
|
+
}
|
|
49
|
+
// Discover WebSocket paths
|
|
32
50
|
const paths = new Set();
|
|
33
51
|
let m;
|
|
34
52
|
try {
|
|
35
53
|
const res = await fetch(url);
|
|
36
54
|
const html = await res.text();
|
|
37
|
-
// Scan HTML for WS paths
|
|
38
55
|
const wsPathRe = /(\/geometra-ws(?:-[a-z]+)*)/g;
|
|
39
56
|
while ((m = wsPathRe.exec(html)) !== null)
|
|
40
57
|
paths.add(m[1]);
|
|
41
|
-
// Fetch and scan JS bundles
|
|
42
58
|
const scriptRe = /src=["']([^"']+\.js)["']/g;
|
|
43
59
|
const scriptUrls = [];
|
|
44
60
|
while ((m = scriptRe.exec(html)) !== null) {
|
|
@@ -57,23 +73,36 @@ else {
|
|
|
57
73
|
}
|
|
58
74
|
}
|
|
59
75
|
catch {
|
|
60
|
-
|
|
76
|
+
process.stderr.write('Could not fetch page HTML.\n');
|
|
61
77
|
}
|
|
62
78
|
if (paths.size === 0)
|
|
63
79
|
paths.add('/geometra-ws');
|
|
64
|
-
// For
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
// For --text/--json, use ALL views to get complete content
|
|
81
|
+
// For terminal rendering, skip HUD and console panel
|
|
82
|
+
let viewPaths;
|
|
83
|
+
if (textMode || jsonMode) {
|
|
84
|
+
viewPaths = [...paths].sort((a, b) => {
|
|
85
|
+
const order = (p) => p.includes('header') ? 0 :
|
|
86
|
+
p === '/geometra-ws' ? 1 :
|
|
87
|
+
p.includes('hud') ? 2 :
|
|
88
|
+
p.includes('below') ? 3 : 4;
|
|
89
|
+
return order(a) - order(b);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const terminal = [...paths].filter(p => p.includes('header') || p.includes('below'));
|
|
94
|
+
viewPaths = terminal.length > 0 ? terminal : [[...paths][0] ?? '/geometra-ws'];
|
|
95
|
+
viewPaths.sort((a, b) => {
|
|
96
|
+
const order = (p) => p.includes('header') ? 0 : p.includes('below') ? 1 : 2;
|
|
97
|
+
return order(a) - order(b);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const wsUrls = viewPaths.map(p => `${baseWs}${p}`);
|
|
101
|
+
if (textMode || jsonMode) {
|
|
102
|
+
await dumpPage(wsUrls, textMode ? 'text' : 'json');
|
|
103
|
+
process.exit(0);
|
|
70
104
|
}
|
|
71
|
-
|
|
72
|
-
const order = (p) => p.includes('header') ? 0 : p.includes('below') ? 1 : 2;
|
|
73
|
-
return order(a) - order(b);
|
|
74
|
-
});
|
|
75
|
-
const wsUrls = sorted.map(p => `${baseWs}${p}`);
|
|
76
|
-
console.error(`Found ${sorted.length} view(s): ${sorted.join(', ')}`);
|
|
105
|
+
process.stderr.write(`Found ${viewPaths.length} view(s): ${viewPaths.join(', ')}\n`);
|
|
77
106
|
const compositor = new TerminalCompositor(wsUrls);
|
|
78
107
|
compositor.start();
|
|
79
108
|
process.on('SIGINT', () => { compositor.close(); process.exit(0); });
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-dump.d.ts","sourceRoot":"","sources":["../src/text-dump.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
/**
|
|
3
|
+
* Connect to Geometra WebSocket endpoints, receive one frame from each,
|
|
4
|
+
* and output the page content as plain text or JSON.
|
|
5
|
+
*/
|
|
6
|
+
export async function dumpPage(urls, mode) {
|
|
7
|
+
const frames = await Promise.all(urls.map(url => fetchOneFrame(url)));
|
|
8
|
+
if (mode === 'json') {
|
|
9
|
+
const output = frames.map(f => ({
|
|
10
|
+
url: f.url,
|
|
11
|
+
layout: f.layout,
|
|
12
|
+
tree: f.tree,
|
|
13
|
+
}));
|
|
14
|
+
process.stdout.write(JSON.stringify(output, null, 2) + '\n');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// Plain text — extract all text content in reading order
|
|
18
|
+
for (const frame of frames) {
|
|
19
|
+
if (frame.tree && frame.layout) {
|
|
20
|
+
const lines = extractText(frame.tree, frame.layout);
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
if (line.trim())
|
|
23
|
+
process.stdout.write(line + '\n');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function fetchOneFrame(url) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
const ws = new WebSocket(url);
|
|
32
|
+
const timeout = setTimeout(() => {
|
|
33
|
+
ws.close();
|
|
34
|
+
resolve({ url, layout: null, tree: null });
|
|
35
|
+
}, 10000);
|
|
36
|
+
ws.on('message', (data) => {
|
|
37
|
+
try {
|
|
38
|
+
const msg = JSON.parse(data.toString());
|
|
39
|
+
if (msg.type === 'frame') {
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
ws.close();
|
|
42
|
+
resolve({ url, layout: msg.layout, tree: msg.tree });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch { /* ignore */ }
|
|
46
|
+
});
|
|
47
|
+
ws.on('error', () => {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
resolve({ url, layout: null, tree: null });
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function extractText(tree, layout) {
|
|
54
|
+
const textLines = [];
|
|
55
|
+
collectText(tree, layout, 0, 0, textLines);
|
|
56
|
+
// Sort by y position then x
|
|
57
|
+
textLines.sort((a, b) => a.y - b.y || a.x - b.x);
|
|
58
|
+
// Group lines by approximate y position (within 5px = same line)
|
|
59
|
+
const grouped = [];
|
|
60
|
+
let currentY = -999;
|
|
61
|
+
let currentLine = '';
|
|
62
|
+
for (const tl of textLines) {
|
|
63
|
+
if (Math.abs(tl.y - currentY) > 5) {
|
|
64
|
+
if (currentLine.trim())
|
|
65
|
+
grouped.push(currentLine.trimEnd());
|
|
66
|
+
currentLine = '';
|
|
67
|
+
currentY = tl.y;
|
|
68
|
+
}
|
|
69
|
+
// Add spacing between items on the same line
|
|
70
|
+
if (currentLine.length > 0)
|
|
71
|
+
currentLine += ' ';
|
|
72
|
+
currentLine += tl.text;
|
|
73
|
+
}
|
|
74
|
+
if (currentLine.trim())
|
|
75
|
+
grouped.push(currentLine.trimEnd());
|
|
76
|
+
return grouped;
|
|
77
|
+
}
|
|
78
|
+
function collectText(element, layout, offsetX, offsetY, out) {
|
|
79
|
+
const absX = offsetX + layout.x;
|
|
80
|
+
const absY = offsetY + layout.y;
|
|
81
|
+
if (element.kind === 'box') {
|
|
82
|
+
const childOffsetX = absX;
|
|
83
|
+
const childOffsetY = absY;
|
|
84
|
+
for (let i = 0; i < element.children.length; i++) {
|
|
85
|
+
const childLayout = layout.children[i];
|
|
86
|
+
if (childLayout) {
|
|
87
|
+
collectText(element.children[i], childLayout, childOffsetX, childOffsetY, out);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (element.kind !== 'scene3d' && element.kind !== 'image') {
|
|
92
|
+
const text = element.props.text ?? '';
|
|
93
|
+
if (text.trim()) {
|
|
94
|
+
out.push({ y: absY, x: absX, text: text.trim() });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=text-dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-dump.js","sourceRoot":"","sources":["../src/text-dump.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geometra/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "CLI to view any Geometra-powered site in the terminal",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"check": "tsc --noEmit"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@geometra/core": "^1.
|
|
39
|
-
"@geometra/renderer-terminal": "^1.
|
|
40
|
-
"textura": "^1.
|
|
38
|
+
"@geometra/core": "^1.16.0",
|
|
39
|
+
"@geometra/renderer-terminal": "^1.16.0",
|
|
40
|
+
"textura": "^1.16.0",
|
|
41
41
|
"ws": "^8.18.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|