@monoes/monobrowse 1.0.0 → 1.0.2
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/package.json +71 -0
- package/dist/src/browser/action-builder/analyzer.d.ts +0 -1
- package/dist/src/browser/action-builder/analyzer.d.ts.map +1 -1
- package/dist/src/browser/action-builder/analyzer.js +43 -21
- package/dist/src/browser/action-builder/analyzer.js.map +1 -1
- package/dist/src/browser/adapters/index.d.ts.map +1 -1
- package/dist/src/browser/adapters/index.js +4 -0
- package/dist/src/browser/adapters/index.js.map +1 -1
- package/dist/src/browser/browser.js +2 -2
- package/dist/src/browser/browser.js.map +1 -1
- package/dist/src/browser/cdp.d.ts +6 -0
- package/dist/src/browser/cdp.d.ts.map +1 -1
- package/dist/src/browser/cdp.js +56 -1
- package/dist/src/browser/cdp.js.map +1 -1
- package/dist/src/browser/dashboard/api-types.d.ts +1 -1
- package/dist/src/browser/dashboard/server.d.ts +12 -1
- package/dist/src/browser/dashboard/server.d.ts.map +1 -1
- package/dist/src/browser/dashboard/server.js +23 -28
- package/dist/src/browser/dashboard/server.js.map +1 -1
- package/dist/src/browser/dashboard/ui.html +1811 -0
- package/dist/src/browser/playbook/browser-handlers.d.ts +3 -0
- package/dist/src/browser/playbook/browser-handlers.d.ts.map +1 -0
- package/dist/src/browser/playbook/browser-handlers.js +377 -0
- package/dist/src/browser/playbook/browser-handlers.js.map +1 -0
- package/dist/src/browser/playbook/builtin-handlers.d.ts +3 -0
- package/dist/src/browser/playbook/builtin-handlers.d.ts.map +1 -0
- package/dist/src/browser/playbook/builtin-handlers.js +364 -0
- package/dist/src/browser/playbook/builtin-handlers.js.map +1 -0
- package/dist/src/browser/playbook/index.d.ts +3 -0
- package/dist/src/browser/playbook/index.d.ts.map +1 -0
- package/dist/src/browser/playbook/index.js +3 -0
- package/dist/src/browser/playbook/index.js.map +1 -0
- package/dist/src/browser/playbook/store.d.ts +8 -0
- package/dist/src/browser/playbook/store.d.ts.map +1 -0
- package/dist/src/browser/playbook/store.js +87 -0
- package/dist/src/browser/playbook/store.js.map +1 -0
- package/dist/src/browser/screenshot.d.ts +2 -0
- package/dist/src/browser/screenshot.d.ts.map +1 -1
- package/dist/src/browser/screenshot.js +69 -2
- package/dist/src/browser/screenshot.js.map +1 -1
- package/dist/src/browser/types.d.ts.map +1 -1
- package/dist/src/browser/types.js +11 -0
- package/dist/src/browser/types.js.map +1 -1
- package/dist/src/cli/action.d.ts +3 -0
- package/dist/src/cli/action.d.ts.map +1 -0
- package/dist/src/cli/action.js +142 -0
- package/dist/src/cli/action.js.map +1 -0
- package/dist/src/cli/commands.d.ts +8 -0
- package/dist/src/cli/commands.d.ts.map +1 -0
- package/dist/src/cli/commands.js +3018 -0
- package/dist/src/cli/commands.js.map +1 -0
- package/dist/src/cli/output.d.ts +11 -0
- package/dist/src/cli/output.d.ts.map +1 -0
- package/dist/src/cli/output.js +33 -0
- package/dist/src/cli/output.js.map +1 -0
- package/dist/src/cli/platform.d.ts +7 -0
- package/dist/src/cli/platform.d.ts.map +1 -0
- package/dist/src/cli/platform.js +193 -0
- package/dist/src/cli/platform.js.map +1 -0
- package/dist/src/cli/playbook.d.ts +3 -0
- package/dist/src/cli/playbook.d.ts.map +1 -0
- package/dist/src/cli/playbook.js +265 -0
- package/dist/src/cli/playbook.js.map +1 -0
- package/dist/src/cli/types.d.ts +42 -0
- package/dist/src/cli/types.d.ts.map +1 -0
- package/dist/src/cli/types.js +2 -0
- package/dist/src/cli/types.js.map +1 -0
- package/dist/src/cli/workflow.d.ts +2 -0
- package/dist/src/cli/workflow.d.ts.map +1 -0
- package/dist/src/cli/workflow.js +3 -0
- package/dist/src/cli/workflow.js.map +1 -0
- package/dist/src/cli.d.ts +7 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +187 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -11
- package/src/browser/action-builder/analyzer.ts +41 -23
- package/src/browser/adapters/index.ts +4 -0
- package/src/browser/browser.ts +2 -2
- package/src/browser/cdp.ts +68 -1
- package/src/browser/dashboard/api-types.ts +1 -1
- package/src/browser/dashboard/server.ts +41 -30
- package/src/browser/dashboard/ui.html +1412 -45
- package/src/browser/screenshot.ts +78 -3
- package/src/browser/types.ts +11 -0
- package/src/cli/action.ts +149 -0
- package/src/cli/commands.ts +2892 -0
- package/src/cli/output.ts +37 -0
- package/src/cli/platform.ts +211 -0
- package/src/cli/types.ts +47 -0
- package/src/cli.ts +208 -0
- package/src/index.ts +0 -1
- package/src/browser/workflow/builtin-handlers.ts +0 -379
- package/src/browser/workflow/engine.ts +0 -202
- package/src/browser/workflow/expression.ts +0 -107
- package/src/browser/workflow/index.ts +0 -5
- package/src/browser/workflow/store.ts +0 -87
- package/src/browser/workflow/types.ts +0 -62
|
@@ -1,14 +1,36 @@
|
|
|
1
|
-
import { createServer } from 'node:http';
|
|
1
|
+
import { createServer, IncomingMessage, ServerResponse } from 'node:http';
|
|
2
2
|
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
4
4
|
import { join, dirname } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
export interface StepEvent {
|
|
10
|
+
type: string;
|
|
11
|
+
projectDir?: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface RunRecord {
|
|
16
|
+
id: string;
|
|
17
|
+
startedAt: number;
|
|
18
|
+
status: string;
|
|
19
|
+
itemsProcessed?: number;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
9
22
|
|
|
10
23
|
const RUNS_FILE = join(homedir(), '.monomind', 'browse-runs.json');
|
|
11
24
|
|
|
25
|
+
function readBody(req: IncomingMessage): Promise<string> {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
let body = '';
|
|
28
|
+
req.on('data', (chunk: Buffer) => { body += chunk.toString(); });
|
|
29
|
+
req.on('end', () => resolve(body));
|
|
30
|
+
req.on('error', reject);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
12
34
|
async function loadPersistedRuns(): Promise<RunRecord[]> {
|
|
13
35
|
if (!existsSync(RUNS_FILE)) return [];
|
|
14
36
|
try {
|
|
@@ -58,7 +80,7 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
58
80
|
uiHtml = `<!DOCTYPE html><html><head><title>monobrowse dashboard</title></head><body style="background:#0f0f1a;color:#ccc;font-family:system-ui;padding:20px"><h1>monobrowse dashboard</h1><p>Dashboard UI not found. Run the build to include ui.html.</p><script>let _retryDelay=1000;function connectSSE(){const es=new EventSource('/events');es.onmessage=e=>{console.log(JSON.parse(e.data));_retryDelay=1000;};es.onerror=()=>{es.close();setTimeout(connectSSE,Math.min(_retryDelay*=2,30000));};};connectSSE();</script></body></html>`;
|
|
59
81
|
}
|
|
60
82
|
|
|
61
|
-
const server = createServer((req, res) => {
|
|
83
|
+
const server = createServer(async (req, res) => {
|
|
62
84
|
const url = req.url ?? '/';
|
|
63
85
|
|
|
64
86
|
if (url === '/' && req.method === 'GET') {
|
|
@@ -68,18 +90,13 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
68
90
|
}
|
|
69
91
|
|
|
70
92
|
if (url === '/runs' && req.method === 'GET') {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
res.end(JSON.stringify(merged));
|
|
79
|
-
}).catch(() => {
|
|
80
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
81
|
-
res.end(JSON.stringify(runHistory));
|
|
82
|
-
});
|
|
93
|
+
const persisted = await loadPersistedRuns().catch(() => [] as RunRecord[]);
|
|
94
|
+
const seen = new Set(runHistory.map(r => r.id));
|
|
95
|
+
const merged = [...runHistory, ...persisted.filter(r => !seen.has(r.id))]
|
|
96
|
+
.sort((a, b) => b.startedAt - a.startedAt)
|
|
97
|
+
.slice(0, MAX_RUN_HISTORY);
|
|
98
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
99
|
+
res.end(JSON.stringify(merged));
|
|
83
100
|
return;
|
|
84
101
|
}
|
|
85
102
|
|
|
@@ -91,12 +108,9 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
91
108
|
return;
|
|
92
109
|
}
|
|
93
110
|
|
|
94
|
-
// Parse the URL to correctly handle query parameters such as ?dir=
|
|
95
111
|
const parsed = new URL(url, 'http://localhost');
|
|
96
112
|
if (parsed.pathname === '/events' && (req.method === 'GET' || req.method === 'HEAD') && !WebSocketServer) {
|
|
97
|
-
// SSE
|
|
98
|
-
// No CORS header — the dashboard is served from 127.0.0.1:4242 and no cross-origin
|
|
99
|
-
// access is needed. A wildcard ACAO would let any web page subscribe to workflow events.
|
|
113
|
+
// SSE fallback when ws not available
|
|
100
114
|
const subscribedDir = parsed.searchParams.get('dir') ?? null;
|
|
101
115
|
res.writeHead(200, {
|
|
102
116
|
'Content-Type': 'text/event-stream',
|
|
@@ -105,7 +119,6 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
105
119
|
});
|
|
106
120
|
res.write(`data: ${JSON.stringify({ type: 'connected' })}\n\n`);
|
|
107
121
|
clientDirs.set(res, subscribedDir);
|
|
108
|
-
// 30-second keep-alive heartbeat prevents proxy idle-timeout drops.
|
|
109
122
|
const heartbeat = setInterval(() => {
|
|
110
123
|
try { res.write(': keep-alive\n\n'); } catch { clearInterval(heartbeat); }
|
|
111
124
|
}, 30_000);
|
|
@@ -123,12 +136,10 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
123
136
|
if (WebSocketServer) {
|
|
124
137
|
const wss = new WebSocketServer({ server });
|
|
125
138
|
wss.on('connection', async (ws: any, req: any) => {
|
|
126
|
-
// Extract optional project-dir filter from the WebSocket upgrade URL
|
|
127
139
|
const upgradeUrl = req?.url ?? '/ws';
|
|
128
140
|
const upgradeParsed = new URL(upgradeUrl, 'http://localhost');
|
|
129
141
|
const subscribedDir = upgradeParsed.searchParams.get('dir') ?? null;
|
|
130
142
|
clientDirs.set(ws, subscribedDir);
|
|
131
|
-
// Merge in-memory and persisted runs so history survives server restarts
|
|
132
143
|
const persisted = await loadPersistedRuns().catch(() => [] as RunRecord[]);
|
|
133
144
|
const seen = new Set(runHistory.map(r => r.id));
|
|
134
145
|
const merged = [...runHistory, ...persisted.filter(r => !seen.has(r.id))]
|
|
@@ -141,11 +152,10 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
141
152
|
|
|
142
153
|
server.on('error', (err: NodeJS.ErrnoException) => {
|
|
143
154
|
if (err.code === 'EADDRINUSE') {
|
|
144
|
-
console.log(`Dashboard port ${port} in use —
|
|
155
|
+
console.log(`Dashboard port ${port} in use — continuing without live dashboard.`);
|
|
145
156
|
} else {
|
|
146
157
|
console.error(`Dashboard server error: ${err.message}`);
|
|
147
158
|
}
|
|
148
|
-
// Replace with a no-op instance so the engine doesn't crash
|
|
149
159
|
instance = {
|
|
150
160
|
broadcast: () => {},
|
|
151
161
|
addRunRecord: () => {},
|
|
@@ -160,17 +170,14 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
160
170
|
function broadcast(event: StepEvent): void {
|
|
161
171
|
const msg = JSON.stringify(event);
|
|
162
172
|
for (const [client, subscribedDir] of clientDirs) {
|
|
163
|
-
// Server-side project filtering: if the client subscribed with ?dir=<path>, only
|
|
164
|
-
// deliver events whose projectDir matches. Clients without a dir filter (subscribedDir
|
|
165
|
-
// === null) receive all events, preserving backward-compatibility with ui.html.
|
|
166
173
|
if (subscribedDir !== null && event.projectDir !== undefined && subscribedDir !== event.projectDir) {
|
|
167
174
|
continue;
|
|
168
175
|
}
|
|
169
176
|
try {
|
|
170
177
|
if (typeof client.send === 'function') {
|
|
171
|
-
client.send(msg);
|
|
178
|
+
client.send(msg);
|
|
172
179
|
} else {
|
|
173
|
-
client.write(`data: ${msg}\n\n`);
|
|
180
|
+
client.write(`data: ${msg}\n\n`);
|
|
174
181
|
}
|
|
175
182
|
} catch {
|
|
176
183
|
clientDirs.delete(client);
|
|
@@ -186,6 +193,10 @@ export function startDashboard(port = DEFAULT_PORT): DashboardServer {
|
|
|
186
193
|
runHistory.unshift(record);
|
|
187
194
|
if (runHistory.length > MAX_RUN_HISTORY) runHistory.pop();
|
|
188
195
|
}
|
|
196
|
+
const dir = join(homedir(), '.monomind');
|
|
197
|
+
mkdir(dir, { recursive: true }).then(() =>
|
|
198
|
+
writeFile(RUNS_FILE, JSON.stringify(runHistory, null, 2))
|
|
199
|
+
).catch(() => {});
|
|
189
200
|
}
|
|
190
201
|
|
|
191
202
|
function isStopRequested(runId: string): boolean {
|