File size: 2,419 Bytes
11ae1d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { Worker } from 'worker_threads';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const WORKER_PATH = path.join(__dirname, 'worker.js');

// --- Swap this for real scouted signals later. Each entry becomes its own
// parallel pipeline thread. Keep the fleet small while you're validating —
// each thread spends real money the moment it starts.
const seeds = [
  {
    id: 'browser-games-absurd',
    niche: 'casual browser games',
    rawSignal:
      'Absurd one-joke browser games (play as an inanimate object, single dumb ' +
      'mechanic, <2min sessions) trending on CrazyGames and getting clipped on shorts.',
    target_format: 'browser game',
  },
  {
    id: 'utility-apps-declutter',
    niche: 'mobile utility apps',
    rawSignal:
      'App Store reviews for photo-organizing apps repeatedly complain about ' +
      'subscription paywalls for basic duplicate-detection features.',
    target_format: 'mobile app',
  },
];

function runWorker(seedEntry) {
  return new Promise((resolve) => {
    const worker = new Worker(WORKER_PATH, {
      workerData: { id: seedEntry.id, seed: seedEntry },
    });

    worker.on('message', (msg) => {
      if (msg.type === 'progress') {
        console.log(`[${msg.seedId}] -> ${msg.stage} (spent so far: $${msg.spentUsd.toFixed(4)})`);
      } else if (msg.type === 'done') {
        console.log(`[${msg.seedId}] DONE`);
        resolve({ id: msg.seedId, ...msg.result });
      } else if (msg.type === 'error') {
        console.error(`[${msg.seedId}] ERROR: ${msg.error}`);
        resolve({ id: msg.seedId, error: msg.error });
      }
    });

    worker.on('error', (err) => {
      console.error(`[${seedEntry.id}] worker crashed: ${err.message}`);
      resolve({ id: seedEntry.id, error: err.message });
    });
  });
}

async function main() {
  console.log(`Spawning ${seeds.length} parallel pipeline threads...\n`);
  const results = await Promise.all(seeds.map(runWorker));

  console.log('\n\n========== FLEET SUMMARY ==========');
  for (const r of results) {
    if (r.error) {
      console.log(`- ${r.id}: FAILED (${r.error})`);
    } else if (r.killed) {
      console.log(`- ${r.id}: killed at [${r.killedAt}] — ${r.reason}`);
    } else {
      console.log(`- ${r.id}: SURVIVED -> ${r.final?.title || 'see full trace'}`);
    }
  }
}

main();