@sudobility/testomniac_runner 0.0.131 → 0.0.133

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/bun.lock CHANGED
@@ -8,8 +8,8 @@
8
8
  "@noble/curves": "^1.0.0",
9
9
  "@noble/hashes": "^1.0.0",
10
10
  "@sudobility/signic_sdk": "^0.1.7",
11
- "@sudobility/testomniac_runner_service": "^0.1.130",
12
- "@sudobility/testomniac_types": "^0.0.68",
11
+ "@sudobility/testomniac_runner_service": "^0.1.131",
12
+ "@sudobility/testomniac_types": "^0.0.69",
13
13
  "hono": "^4.7.0",
14
14
  "jose": "^6.1.2",
15
15
  "openai": "^6.7.0",
@@ -172,9 +172,9 @@
172
172
 
173
173
  "@sudobility/signic_sdk": ["@sudobility/signic_sdk@0.1.7", "", {}, "sha512-5XSgHSVsmyrMQ/ui1nDywwzt9dbRCsaeJ5tX6mKw2ZXbTZ82OsMr+dqDyV9XV3pfy7IHRIZq73af5KBamx72Fw=="],
174
174
 
175
- "@sudobility/testomniac_runner_service": ["@sudobility/testomniac_runner_service@0.1.130", "", { "peerDependencies": { "@sudobility/testomniac_types": "^0.0.68", "openai": ">=6.0.0", "react": ">=18.0.0" }, "optionalPeers": ["openai", "react"] }, "sha512-C6I/8Zo/ZqBrOMXeiWqaAKEJIEdRI6xWvtRQoyYEtxuh51WN8CtbVyhPn5AEzDQJQTWa+RJllo9u0SxW0L/o1g=="],
175
+ "@sudobility/testomniac_runner_service": ["@sudobility/testomniac_runner_service@0.1.131", "", { "peerDependencies": { "@sudobility/testomniac_types": "^0.0.69", "openai": ">=6.0.0", "react": ">=18.0.0" }, "optionalPeers": ["openai", "react"] }, "sha512-1ZJk1EjCJlFVXJXhlU3MLNPL53VwUJ6yOq4O9qvkpEn4VoCBnZlmVNOjicVXZE0UEP2u32GUGvBNEUHJGE5rFg=="],
176
176
 
177
- "@sudobility/testomniac_types": ["@sudobility/testomniac_types@0.0.68", "", { "peerDependencies": { "@sudobility/types": "^1.9.62" } }, "sha512-io3qbAuOLuCrjC4txkD+B21n/RGrfz2MH+W0XciAOkaxcfXagdHRUdWie/520HeItC9F91jP9SA67YAcx5aZ0A=="],
177
+ "@sudobility/testomniac_types": ["@sudobility/testomniac_types@0.0.69", "", { "peerDependencies": { "@sudobility/types": "^1.9.62" } }, "sha512-VkWcWdy4zwddCZspzc0qhHIqyfuuzyMUh6Dvjk614y8+A8GQ8N6D9AiNmFtqrDOoMEnfo9VNU8AvdJGOjjc/1A=="],
178
178
 
179
179
  "@sudobility/types": ["@sudobility/types@1.9.61", "", {}, "sha512-SODGpstB/iKfK3H/4BvJx/FBcc1h3gutUjGotyxN19VnOfWyzaDoEmW7eyoxOAYhZyXMXagSiii+NIEZvuxKog=="],
180
180
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/testomniac_runner",
3
- "version": "0.0.131",
3
+ "version": "0.0.133",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -24,8 +24,8 @@
24
24
  "@noble/curves": "^1.0.0",
25
25
  "@noble/hashes": "^1.0.0",
26
26
  "@sudobility/signic_sdk": "^0.1.7",
27
- "@sudobility/testomniac_runner_service": "^0.1.130",
28
- "@sudobility/testomniac_types": "^0.0.68",
27
+ "@sudobility/testomniac_runner_service": "^0.1.131",
28
+ "@sudobility/testomniac_types": "^0.0.69",
29
29
  "hono": "^4.7.0",
30
30
  "jose": "^6.1.2",
31
31
  "openai": "^6.7.0",
package/src/index.ts CHANGED
@@ -15,6 +15,10 @@ const config = loadConfig();
15
15
  const pollIntervalMs = Number(process.env.SCAN_POLL_INTERVAL_MS ?? 10_000);
16
16
  const maxConcurrentRunners = config.maxConcurrentRunners;
17
17
  const runnerManager = new RunnerManager(pollIntervalMs, maxConcurrentRunners);
18
+ const runnerInstanceId =
19
+ process.env.TESTOMNIAC_RUNNER_INSTANCE_ID ??
20
+ process.env.TESTOMNIAC_RUNNER_PROCESS_INSTANCE_ID;
21
+ const runnerInstanceName = process.env.TESTOMNIAC_RUNNER_INSTANCE_NAME;
18
22
 
19
23
  const app = new Hono();
20
24
 
@@ -66,8 +70,8 @@ if (import.meta.main) {
66
70
  baseUrl,
67
71
  sizeClass,
68
72
  scanMode,
69
- runnerInstanceId: crypto.randomUUID(),
70
- runnerInstanceName: "mcp-runner",
73
+ runnerInstanceId: runnerInstanceId ?? crypto.randomUUID(),
74
+ runnerInstanceName: runnerInstanceName ?? "mcp-runner",
71
75
  });
72
76
  logger.info({ scanId }, "one-shot run completed");
73
77
  process.exit(0);
@@ -63,7 +63,12 @@ export async function runFullScan(options: RunOptions): Promise<void> {
63
63
  const page = await chromium.newPage(defaultScreen);
64
64
  const adapter = new PuppeteerAdapter(page);
65
65
 
66
- const eventHandler: ScanEventHandler = {
66
+ const eventHandler: ScanEventHandler & {
67
+ onStatusUpdate?: (update: {
68
+ message: string;
69
+ testRunId?: number;
70
+ }) => void;
71
+ } = {
67
72
  onPageFound: p =>
68
73
  logger.info(
69
74
  { relativePath: p.relativePath, pageId: p.pageId },
@@ -89,6 +94,8 @@ export async function runFullScan(options: RunOptions): Promise<void> {
89
94
  onFindingCreated: f =>
90
95
  logger.warn({ type: f.type, title: f.title }, "finding created"),
91
96
  onStatsUpdated: stats => logger.debug(stats, "stats updated"),
97
+ onStatusUpdate: update =>
98
+ logger.info({ testRunId: update.testRunId }, update.message),
92
99
  onScreenshotCaptured: () => {},
93
100
  onScanComplete: summary => logger.info(summary, "scan complete"),
94
101
  onError: err => logger.error(err, "scan error"),
@@ -156,6 +163,8 @@ export interface SequenceRunOptions {
156
163
  sequenceRunId: number;
157
164
  runnerId: number;
158
165
  sizeClass?: string;
166
+ runnerInstanceId?: string;
167
+ runnerInstanceName?: string;
159
168
  }
160
169
 
161
170
  export async function runSequenceScan(
@@ -177,7 +186,12 @@ export async function runSequenceScan(
177
186
  const adapter = new PuppeteerAdapter(page);
178
187
  const expertises = createDefaultExpertises();
179
188
 
180
- const eventHandler: ScanEventHandler = {
189
+ const eventHandler: ScanEventHandler & {
190
+ onStatusUpdate?: (update: {
191
+ message: string;
192
+ testRunId?: number;
193
+ }) => void;
194
+ } = {
181
195
  onPageFound: p => logger.info(p, "page found"),
182
196
  onPageStateCreated: s => logger.info(s, "page state created"),
183
197
  onTestSurfaceCreated: s => logger.info(s, "surface created"),
@@ -186,6 +200,8 @@ export async function runSequenceScan(
186
200
  onTestRunCompleted: r => logger.info(r, "run completed"),
187
201
  onFindingCreated: f => logger.warn(f, "finding created"),
188
202
  onStatsUpdated: s => logger.debug(s, "stats"),
203
+ onStatusUpdate: update =>
204
+ logger.info({ testRunId: update.testRunId }, update.message),
189
205
  onScreenshotCaptured: () => {},
190
206
  onScanComplete: s => logger.info(s, "complete"),
191
207
  onError: e => logger.error(e, "error"),
@@ -197,8 +213,15 @@ export async function runSequenceScan(
197
213
  sequenceRunId: options.sequenceRunId,
198
214
  runnerId: options.runnerId,
199
215
  sizeClass,
200
- runnerInstanceId: crypto.randomUUID(),
201
- runnerInstanceName: "mcp-runner",
216
+ runnerInstanceId:
217
+ options.runnerInstanceId ??
218
+ process.env.TESTOMNIAC_RUNNER_INSTANCE_ID ??
219
+ process.env.TESTOMNIAC_RUNNER_PROCESS_INSTANCE_ID ??
220
+ crypto.randomUUID(),
221
+ runnerInstanceName:
222
+ options.runnerInstanceName ??
223
+ process.env.TESTOMNIAC_RUNNER_INSTANCE_NAME ??
224
+ "mcp-runner",
202
225
  },
203
226
  api,
204
227
  expertises,
@@ -14,7 +14,8 @@ type ActiveRun = {
14
14
  };
15
15
 
16
16
  export class RunnerManager {
17
- private readonly processInstanceId = crypto.randomUUID();
17
+ private readonly processInstanceId =
18
+ process.env.TESTOMNIAC_RUNNER_PROCESS_INSTANCE_ID ?? crypto.randomUUID();
18
19
  private readonly activeRuns = new Map<number, ActiveRun>();
19
20
  private tickInFlight = false;
20
21