@paa1997/metho 1.0.3 → 1.0.5

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/src/server.js CHANGED
@@ -4,7 +4,7 @@ import { resolve, dirname, join } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import { exec } from 'child_process';
6
6
  import { createLogger } from './logger.js';
7
- import { runPipeline } from './engine.js';
7
+ import { runPipeline, findIncompleteRun, deleteAllRuns } from './engine.js';
8
8
  import { createRunContext } from './signals.js';
9
9
 
10
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -129,6 +129,7 @@ export function startServer(port = 3000) {
129
129
  katanaChunkSize: parseInt(params.katanaChunkSize, 10) || 1000,
130
130
  katanaDepth: parseInt(params.katanaDepth, 10) || 2,
131
131
  findsomethingPath: params.findsomethingPath || '',
132
+ resumeDir: params.resumeDir || null,
132
133
  debug: true,
133
134
  };
134
135
 
@@ -195,6 +196,39 @@ export function startServer(port = 3000) {
195
196
  }
196
197
  }
197
198
 
199
+ // POST /check-resume → check for incomplete runs
200
+ if (method === 'POST' && url === '/check-resume') {
201
+ const body = await readBody(req);
202
+ let params;
203
+ try { params = JSON.parse(body); } catch {
204
+ res.writeHead(400, { 'Content-Type': 'application/json' });
205
+ return res.end(JSON.stringify({ error: 'Invalid JSON' }));
206
+ }
207
+ const outputDir = resolve(params.outputDir || './metho-results');
208
+ const result = findIncompleteRun(outputDir, params.domain || null, params.domainList || null);
209
+ res.writeHead(200, { 'Content-Type': 'application/json' });
210
+ if (result) {
211
+ return res.end(JSON.stringify({
212
+ hasIncomplete: true,
213
+ runDir: result.runDir,
214
+ completedSteps: result.completedSteps,
215
+ label: result.label,
216
+ }));
217
+ }
218
+ return res.end(JSON.stringify({ hasIncomplete: false }));
219
+ }
220
+
221
+ // POST /delete-logs → delete all run directories
222
+ if (method === 'POST' && url === '/delete-logs') {
223
+ const body = await readBody(req);
224
+ let params = {};
225
+ try { params = JSON.parse(body); } catch { /* use defaults */ }
226
+ const outputDir = resolve(params.outputDir || './metho-results');
227
+ const count = deleteAllRuns(outputDir);
228
+ res.writeHead(200, { 'Content-Type': 'application/json' });
229
+ return res.end(JSON.stringify({ ok: true, deleted: count }));
230
+ }
231
+
198
232
  // 404
199
233
  res.writeHead(404, { 'Content-Type': 'application/json' });
200
234
  res.end(JSON.stringify({ error: 'Not found' }));
@@ -232,18 +266,6 @@ export function startServer(port = 3000) {
232
266
  } finally {
233
267
  activeRuns.delete(runId);
234
268
  broadcast({ type: 'run-ended', runId, activeRuns: activeRuns.size });
235
-
236
- // Close SSE clients only when ALL runs are done
237
- if (activeRuns.size === 0) {
238
- setTimeout(() => {
239
- if (activeRuns.size === 0) {
240
- for (const client of sseClients) {
241
- try { client.end(); } catch { /* ignore */ }
242
- }
243
- sseClients = [];
244
- }
245
- }, 3000);
246
- }
247
269
  }
248
270
  }
249
271
 
@@ -34,7 +34,7 @@ export class FindSomethingStep extends BaseStep {
34
34
 
35
35
  this.logger.debug(`Using findsomething script: ${scriptPath}`);
36
36
  const pythonBin = isWin ? 'python' : 'python3';
37
- const args = [scriptPath, '-l', inputFile, '-o', outputFile];
37
+ const args = [scriptPath, '-l', inputFile, '-o', outputFile, '--html'];
38
38
 
39
39
  const result = await this.runCommand(pythonBin, args, { outputFile });
40
40
  return result;