@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.
Files changed (103) hide show
  1. package/dist/package.json +71 -0
  2. package/dist/src/browser/action-builder/analyzer.d.ts +0 -1
  3. package/dist/src/browser/action-builder/analyzer.d.ts.map +1 -1
  4. package/dist/src/browser/action-builder/analyzer.js +43 -21
  5. package/dist/src/browser/action-builder/analyzer.js.map +1 -1
  6. package/dist/src/browser/adapters/index.d.ts.map +1 -1
  7. package/dist/src/browser/adapters/index.js +4 -0
  8. package/dist/src/browser/adapters/index.js.map +1 -1
  9. package/dist/src/browser/browser.js +2 -2
  10. package/dist/src/browser/browser.js.map +1 -1
  11. package/dist/src/browser/cdp.d.ts +6 -0
  12. package/dist/src/browser/cdp.d.ts.map +1 -1
  13. package/dist/src/browser/cdp.js +56 -1
  14. package/dist/src/browser/cdp.js.map +1 -1
  15. package/dist/src/browser/dashboard/api-types.d.ts +1 -1
  16. package/dist/src/browser/dashboard/server.d.ts +12 -1
  17. package/dist/src/browser/dashboard/server.d.ts.map +1 -1
  18. package/dist/src/browser/dashboard/server.js +23 -28
  19. package/dist/src/browser/dashboard/server.js.map +1 -1
  20. package/dist/src/browser/dashboard/ui.html +1811 -0
  21. package/dist/src/browser/playbook/browser-handlers.d.ts +3 -0
  22. package/dist/src/browser/playbook/browser-handlers.d.ts.map +1 -0
  23. package/dist/src/browser/playbook/browser-handlers.js +377 -0
  24. package/dist/src/browser/playbook/browser-handlers.js.map +1 -0
  25. package/dist/src/browser/playbook/builtin-handlers.d.ts +3 -0
  26. package/dist/src/browser/playbook/builtin-handlers.d.ts.map +1 -0
  27. package/dist/src/browser/playbook/builtin-handlers.js +364 -0
  28. package/dist/src/browser/playbook/builtin-handlers.js.map +1 -0
  29. package/dist/src/browser/playbook/index.d.ts +3 -0
  30. package/dist/src/browser/playbook/index.d.ts.map +1 -0
  31. package/dist/src/browser/playbook/index.js +3 -0
  32. package/dist/src/browser/playbook/index.js.map +1 -0
  33. package/dist/src/browser/playbook/store.d.ts +8 -0
  34. package/dist/src/browser/playbook/store.d.ts.map +1 -0
  35. package/dist/src/browser/playbook/store.js +87 -0
  36. package/dist/src/browser/playbook/store.js.map +1 -0
  37. package/dist/src/browser/screenshot.d.ts +2 -0
  38. package/dist/src/browser/screenshot.d.ts.map +1 -1
  39. package/dist/src/browser/screenshot.js +69 -2
  40. package/dist/src/browser/screenshot.js.map +1 -1
  41. package/dist/src/browser/types.d.ts.map +1 -1
  42. package/dist/src/browser/types.js +11 -0
  43. package/dist/src/browser/types.js.map +1 -1
  44. package/dist/src/cli/action.d.ts +3 -0
  45. package/dist/src/cli/action.d.ts.map +1 -0
  46. package/dist/src/cli/action.js +142 -0
  47. package/dist/src/cli/action.js.map +1 -0
  48. package/dist/src/cli/commands.d.ts +8 -0
  49. package/dist/src/cli/commands.d.ts.map +1 -0
  50. package/dist/src/cli/commands.js +3018 -0
  51. package/dist/src/cli/commands.js.map +1 -0
  52. package/dist/src/cli/output.d.ts +11 -0
  53. package/dist/src/cli/output.d.ts.map +1 -0
  54. package/dist/src/cli/output.js +33 -0
  55. package/dist/src/cli/output.js.map +1 -0
  56. package/dist/src/cli/platform.d.ts +7 -0
  57. package/dist/src/cli/platform.d.ts.map +1 -0
  58. package/dist/src/cli/platform.js +193 -0
  59. package/dist/src/cli/platform.js.map +1 -0
  60. package/dist/src/cli/playbook.d.ts +3 -0
  61. package/dist/src/cli/playbook.d.ts.map +1 -0
  62. package/dist/src/cli/playbook.js +265 -0
  63. package/dist/src/cli/playbook.js.map +1 -0
  64. package/dist/src/cli/types.d.ts +42 -0
  65. package/dist/src/cli/types.d.ts.map +1 -0
  66. package/dist/src/cli/types.js +2 -0
  67. package/dist/src/cli/types.js.map +1 -0
  68. package/dist/src/cli/workflow.d.ts +2 -0
  69. package/dist/src/cli/workflow.d.ts.map +1 -0
  70. package/dist/src/cli/workflow.js +3 -0
  71. package/dist/src/cli/workflow.js.map +1 -0
  72. package/dist/src/cli.d.ts +7 -0
  73. package/dist/src/cli.d.ts.map +1 -0
  74. package/dist/src/cli.js +187 -0
  75. package/dist/src/cli.js.map +1 -0
  76. package/dist/src/index.d.ts +0 -1
  77. package/dist/src/index.d.ts.map +1 -1
  78. package/dist/src/index.js +0 -1
  79. package/dist/src/index.js.map +1 -1
  80. package/dist/tsconfig.tsbuildinfo +1 -1
  81. package/package.json +21 -11
  82. package/src/browser/action-builder/analyzer.ts +41 -23
  83. package/src/browser/adapters/index.ts +4 -0
  84. package/src/browser/browser.ts +2 -2
  85. package/src/browser/cdp.ts +68 -1
  86. package/src/browser/dashboard/api-types.ts +1 -1
  87. package/src/browser/dashboard/server.ts +41 -30
  88. package/src/browser/dashboard/ui.html +1412 -45
  89. package/src/browser/screenshot.ts +78 -3
  90. package/src/browser/types.ts +11 -0
  91. package/src/cli/action.ts +149 -0
  92. package/src/cli/commands.ts +2892 -0
  93. package/src/cli/output.ts +37 -0
  94. package/src/cli/platform.ts +211 -0
  95. package/src/cli/types.ts +47 -0
  96. package/src/cli.ts +208 -0
  97. package/src/index.ts +0 -1
  98. package/src/browser/workflow/builtin-handlers.ts +0 -379
  99. package/src/browser/workflow/engine.ts +0 -202
  100. package/src/browser/workflow/expression.ts +0 -107
  101. package/src/browser/workflow/index.ts +0 -5
  102. package/src/browser/workflow/store.ts +0 -87
  103. 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
- import type { StepEvent, RunRecord } from '../workflow/types.js';
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
- // Merge in-memory runs with persisted runs so the UI shows history even across restarts
72
- loadPersistedRuns().then(persisted => {
73
- const seen = new Set(runHistory.map(r => r.id));
74
- const merged = [...runHistory, ...persisted.filter(r => !seen.has(r.id))]
75
- .sort((a, b) => b.startedAt - a.startedAt)
76
- .slice(0, MAX_RUN_HISTORY);
77
- res.writeHead(200, { 'Content-Type': 'application/json' });
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 endpoint (fallback when ws not available).
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 — workflow will run without live dashboard.`);
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); // WebSocket
178
+ client.send(msg);
172
179
  } else {
173
- client.write(`data: ${msg}\n\n`); // SSE
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 {