@observeone/cli 1.8.0 → 1.9.1

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 (54) hide show
  1. package/README.md +37 -0
  2. package/dist/README.md +37 -0
  3. package/dist/commands/ai-check/create.d.ts +6 -0
  4. package/dist/commands/ai-check/create.d.ts.map +1 -0
  5. package/dist/commands/ai-check/create.js +79 -0
  6. package/dist/commands/ai-check/create.js.map +1 -0
  7. package/dist/commands/ai-check/delete.d.ts +6 -0
  8. package/dist/commands/ai-check/delete.d.ts.map +1 -0
  9. package/dist/commands/ai-check/delete.js +51 -0
  10. package/dist/commands/ai-check/delete.js.map +1 -0
  11. package/dist/commands/ai-check/get.d.ts +6 -0
  12. package/dist/commands/ai-check/get.d.ts.map +1 -0
  13. package/dist/commands/ai-check/get.js +37 -0
  14. package/dist/commands/ai-check/get.js.map +1 -0
  15. package/dist/commands/ai-check/index.d.ts +6 -0
  16. package/dist/commands/ai-check/index.d.ts.map +1 -0
  17. package/dist/commands/ai-check/index.js +22 -0
  18. package/dist/commands/ai-check/index.js.map +1 -0
  19. package/dist/commands/ai-check/list.d.ts +6 -0
  20. package/dist/commands/ai-check/list.d.ts.map +1 -0
  21. package/dist/commands/ai-check/list.js +36 -0
  22. package/dist/commands/ai-check/list.js.map +1 -0
  23. package/dist/commands/ai-check/run.d.ts +6 -0
  24. package/dist/commands/ai-check/run.d.ts.map +1 -0
  25. package/dist/commands/{ai-check.js → ai-check/run.js} +6 -316
  26. package/dist/commands/ai-check/run.js.map +1 -0
  27. package/dist/commands/ai-check/status.d.ts +6 -0
  28. package/dist/commands/ai-check/status.d.ts.map +1 -0
  29. package/dist/commands/ai-check/status.js +32 -0
  30. package/dist/commands/ai-check/status.js.map +1 -0
  31. package/dist/commands/ai-check/wait.d.ts +6 -0
  32. package/dist/commands/ai-check/wait.d.ts.map +1 -0
  33. package/dist/commands/ai-check/wait.js +59 -0
  34. package/dist/commands/ai-check/wait.js.map +1 -0
  35. package/dist/commands/schema.d.ts +4 -0
  36. package/dist/commands/schema.d.ts.map +1 -0
  37. package/dist/commands/schema.js +42 -0
  38. package/dist/commands/schema.js.map +1 -0
  39. package/dist/commands/templates.d.ts +4 -0
  40. package/dist/commands/templates.d.ts.map +1 -0
  41. package/dist/commands/templates.js +35 -0
  42. package/dist/commands/templates.js.map +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +5 -1
  45. package/dist/index.js.map +1 -1
  46. package/dist/package.json +1 -1
  47. package/dist/utils/schemas.d.ts +2 -0
  48. package/dist/utils/schemas.d.ts.map +1 -1
  49. package/dist/utils/schemas.js +56 -0
  50. package/dist/utils/schemas.js.map +1 -1
  51. package/package.json +1 -1
  52. package/dist/commands/ai-check.d.ts +0 -9
  53. package/dist/commands/ai-check.d.ts.map +0 -1
  54. package/dist/commands/ai-check.js.map +0 -1
@@ -1,20 +1,13 @@
1
1
  import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
2
  import chalk from 'chalk';
4
3
  import ora from 'ora';
5
- import { SSEClient } from '../services/sse-client.service.js';
4
+ import { SSEClient } from '../../services/sse-client.service.js';
6
5
  import { writeFileSync } from 'fs';
7
6
  function isJsonOutputMode(options) {
8
7
  return (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true || options.reporter === 'json');
9
8
  }
10
- /**
11
- * Factory function to create ai-check command with direct service injection
12
- */
13
- export function createAiCheckCommand(configService, apiClient, outputService) {
14
- const aiCheck = new Command('ai-check').description('Manage and run AI-powered tests');
15
- // RUN (Default)
16
- aiCheck
17
- .command('run', { isDefault: true })
9
+ export function createAiCheckRunCommand(configService, apiClient, outputService) {
10
+ return new Command('run')
18
11
  .description('Run AI-powered tests')
19
12
  .argument('[test-names...]', 'Test names to run (by name or ID)')
20
13
  .option('-u, --url <url>', 'URL to test')
@@ -65,286 +58,7 @@ export function createAiCheckCommand(configService, apiClient, outputService) {
65
58
  process.exit(1);
66
59
  }
67
60
  });
68
- // LIST
69
- aiCheck
70
- .command('list')
71
- .description('List all AI browser checks')
72
- .option('-f, --format <format>', 'Output format (table, json)', 'table')
73
- .option('-j, --json', 'Output in JSON format')
74
- .action(async (options) => {
75
- if (process.env.OBS_JSON_OUTPUT === 'true' ||
76
- options.format === 'json' ||
77
- options.json === true) {
78
- outputService.enableJsonMode();
79
- }
80
- try {
81
- const apiKey = configService.getApiKey();
82
- if (!apiKey) {
83
- outputService.error('Not authenticated. Please run "obs login" first.');
84
- process.exit(1);
85
- }
86
- outputService.progress('Fetching AI checks...');
87
- const tests = await apiClient.getTests();
88
- if (process.env.OBS_JSON_OUTPUT === 'true' ||
89
- options.format === 'json' ||
90
- options.json === true) {
91
- outputService.formatJsonOutput(tests);
92
- }
93
- else {
94
- outputService.formatTestList(tests, process.env.OBS_VERBOSE === 'true');
95
- }
96
- }
97
- catch (error) {
98
- outputService.error(outputService.formatError(error));
99
- process.exit(1);
100
- }
101
- });
102
- // GET
103
- aiCheck
104
- .command('get <id>')
105
- .description('Get details of an AI browser check')
106
- .option('-j, --json', 'Output in JSON format')
107
- .action(async (id, options) => {
108
- if (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true) {
109
- outputService.enableJsonMode();
110
- }
111
- try {
112
- const apiKey = configService.getApiKey();
113
- if (!apiKey) {
114
- outputService.error('Not authenticated. Please run "obs login" first.');
115
- process.exit(1);
116
- }
117
- const testId = parseInt(id);
118
- if (isNaN(testId)) {
119
- outputService.error('Invalid test ID.');
120
- process.exit(1);
121
- }
122
- outputService.progress(`Fetching AI check ${testId}...`);
123
- const testData = await apiClient.getTest(testId);
124
- if (process.env.OBS_JSON_OUTPUT === 'true') {
125
- outputService.formatJsonOutput(testData);
126
- }
127
- else {
128
- outputService.formatTestList([testData], true);
129
- }
130
- }
131
- catch (error) {
132
- outputService.error(outputService.formatError(error));
133
- process.exit(1);
134
- }
135
- });
136
- // CREATE
137
- aiCheck
138
- .command('create')
139
- .description('Create a new AI browser check')
140
- .option('-n, --name <name>', 'Test name')
141
- .option('-u, --url <url>', 'URL to test')
142
- .option('-p, --prompt <prompt>', 'Test prompt')
143
- .option('-j, --json', 'Output in JSON format')
144
- .action(async (options) => {
145
- if (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true) {
146
- outputService.enableJsonMode();
147
- }
148
- try {
149
- const apiKey = configService.getApiKey();
150
- if (!apiKey) {
151
- outputService.error('Not authenticated. Please run "obs login" first.');
152
- process.exit(1);
153
- }
154
- let name = options.name;
155
- let url = options.url;
156
- let prompt = options.prompt;
157
- if (!name || !url || !prompt) {
158
- const answers = await inquirer.prompt([
159
- {
160
- type: 'input',
161
- name: 'name',
162
- message: 'Check name:',
163
- when: !name,
164
- validate: (val) => (val.trim() ? true : 'Name is required'),
165
- },
166
- {
167
- type: 'input',
168
- name: 'url',
169
- message: 'URL to test:',
170
- when: !url,
171
- validate: (val) => {
172
- try {
173
- new URL(val);
174
- return true;
175
- }
176
- catch {
177
- return 'Invalid URL';
178
- }
179
- },
180
- },
181
- {
182
- type: 'input',
183
- name: 'prompt',
184
- message: 'What should the AI check? (prompt):',
185
- when: !prompt,
186
- validate: (val) => (val.trim() ? true : 'Prompt is required'),
187
- },
188
- ]);
189
- name = name || answers.name;
190
- url = url || answers.url;
191
- prompt = prompt || answers.prompt;
192
- }
193
- outputService.progress('Creating AI browser check...');
194
- const newTest = await apiClient.createTest({
195
- name: name,
196
- url: url,
197
- prompt: prompt,
198
- description: 'Created via CLI',
199
- });
200
- if (process.env.OBS_JSON_OUTPUT === 'true') {
201
- outputService.formatJsonOutput(newTest);
202
- }
203
- else {
204
- outputService.success(`AI browser check "${name}" created! (ID: ${newTest.id})`);
205
- }
206
- }
207
- catch (error) {
208
- outputService.error(outputService.formatError(error));
209
- process.exit(1);
210
- }
211
- });
212
- // DELETE
213
- aiCheck
214
- .command('delete <id>')
215
- .description('Delete an AI browser check')
216
- .option('-y, --yes', 'Skip confirmation prompt')
217
- .option('-j, --json', 'Output in JSON format')
218
- .action(async (id, options) => {
219
- if (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true) {
220
- outputService.enableJsonMode();
221
- }
222
- try {
223
- const apiKey = configService.getApiKey();
224
- if (!apiKey) {
225
- outputService.error('Not authenticated. Please run "obs login" first.');
226
- process.exit(1);
227
- }
228
- const testId = parseInt(id);
229
- if (isNaN(testId)) {
230
- outputService.error('Invalid test ID.');
231
- process.exit(1);
232
- }
233
- if (!options.yes) {
234
- const { confirm } = await inquirer.prompt([
235
- {
236
- type: 'confirm',
237
- name: 'confirm',
238
- message: `Are you sure you want to delete AI check ${testId}?`,
239
- default: false,
240
- },
241
- ]);
242
- if (!confirm)
243
- return;
244
- }
245
- outputService.progress(`Deleting AI check ${testId}...`);
246
- await apiClient.deleteTest(testId);
247
- if (process.env.OBS_JSON_OUTPUT === 'true') {
248
- outputService.formatJsonOutput({ success: true, id: testId });
249
- }
250
- else {
251
- outputService.success(`AI check ${testId} deleted successfully.`);
252
- }
253
- }
254
- catch (error) {
255
- outputService.error(outputService.formatError(error));
256
- process.exit(1);
257
- }
258
- });
259
- // STATUS
260
- aiCheck
261
- .command('status <execution-id>')
262
- .description('Get the status of a browser check execution')
263
- .option('-j, --json', 'Output in JSON format')
264
- .action(async (executionId, options) => {
265
- if (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true) {
266
- outputService.enableJsonMode();
267
- }
268
- try {
269
- const apiKey = configService.getApiKey();
270
- if (!apiKey) {
271
- outputService.error('Not authenticated. Please run "obs login" first.');
272
- process.exit(1);
273
- }
274
- const id = parseInt(executionId);
275
- if (isNaN(id)) {
276
- outputService.error('Invalid execution ID. Must be a numeric ID from a named check run.');
277
- process.exit(1);
278
- }
279
- outputService.progress(`Fetching execution status for ${id}...`);
280
- const execution = await apiClient.getExecutionStatus(id);
281
- outputService.formatJsonOutput(execution);
282
- }
283
- catch (error) {
284
- outputService.error(outputService.formatError(error));
285
- process.exit(1);
286
- }
287
- });
288
- // WAIT
289
- aiCheck
290
- .command('wait <execution-id>')
291
- .description('Wait for a browser check execution to complete')
292
- .option('-j, --json', 'Output in JSON format')
293
- .option('-t, --timeout <ms>', 'Max time to wait in milliseconds', '300000')
294
- .action(async (executionId, options) => {
295
- const isJson = process.env.OBS_JSON_OUTPUT === 'true' || options.json === true;
296
- if (isJson) {
297
- outputService.enableJsonMode();
298
- }
299
- try {
300
- const apiKey = configService.getApiKey();
301
- if (!apiKey) {
302
- outputService.error('Not authenticated. Please run "obs login" first.');
303
- process.exit(1);
304
- }
305
- const id = parseInt(executionId);
306
- if (isNaN(id)) {
307
- outputService.error('Invalid execution ID. Must be a numeric ID from a named check run.');
308
- process.exit(1);
309
- }
310
- const timeoutMs = parseInt(options.timeout) || 300000;
311
- const intervalMs = 5000;
312
- const maxAttempts = Math.ceil(timeoutMs / intervalMs);
313
- const spinner = isJson ? null : ora(`Waiting for execution ${id}...`).start();
314
- const execution = await apiClient.pollExecutionStatus(id, maxAttempts, intervalMs);
315
- if (spinner) {
316
- if (execution.status === 'SUCCESS') {
317
- spinner.succeed(`Execution ${id} completed successfully.`);
318
- }
319
- else {
320
- spinner.fail(`Execution ${id} ended with status: ${execution.status}`);
321
- }
322
- }
323
- let results;
324
- if (execution.status === 'SUCCESS') {
325
- try {
326
- results = await apiClient.getExecutionResults(id);
327
- }
328
- catch {
329
- // results are optional — don't fail the command if they're unavailable
330
- }
331
- }
332
- const payload = { execution, ...(results !== undefined && { results }) };
333
- outputService.formatJsonOutput(payload);
334
- if (execution.status !== 'SUCCESS') {
335
- process.exit(1);
336
- }
337
- }
338
- catch (error) {
339
- outputService.error(outputService.formatError(error));
340
- process.exit(1);
341
- }
342
- });
343
- return aiCheck;
344
61
  }
345
- /**
346
- * Run an ad-hoc test
347
- */
348
62
  async function runAdhocTest(apiClient, outputService, configService, options, timeout, results, shouldWait, isJson) {
349
63
  const spinner = isJson
350
64
  ? { start: () => { }, succeed: (_msg) => { }, fail: (_msg) => { } }
@@ -358,7 +72,6 @@ async function runAdhocTest(apiClient, outputService, configService, options, ti
358
72
  });
359
73
  results.push(result);
360
74
  spinner.succeed('Ad-hoc test started');
361
- // Use SSE streaming for live progress
362
75
  if (result.task_id && shouldWait) {
363
76
  await streamTestProgress(configService, result, options.name || 'Ad-hoc Test', options, timeout, results, undefined, isJson);
364
77
  }
@@ -368,9 +81,6 @@ async function runAdhocTest(apiClient, outputService, configService, options, ti
368
81
  throw error;
369
82
  }
370
83
  }
371
- /**
372
- * Run named tests
373
- */
374
84
  async function runNamedTests(apiClient, _outputService, configService, testNames, options, timeout, results, shouldWait, isJson) {
375
85
  const spinner = isJson
376
86
  ? { start: () => { }, succeed: (_msg) => { }, fail: (_msg) => { } }
@@ -380,7 +90,6 @@ async function runNamedTests(apiClient, _outputService, configService, testNames
380
90
  const testsToRun = testNames
381
91
  .filter((name) => !name.startsWith('-'))
382
92
  .map((name) => {
383
- // Try to find by name first, then by ID
384
93
  let test = tests.find((t) => t.name === name);
385
94
  if (!test) {
386
95
  const id = parseInt(name);
@@ -394,7 +103,6 @@ async function runNamedTests(apiClient, _outputService, configService, testNames
394
103
  return test;
395
104
  });
396
105
  spinner.succeed(`Found ${testsToRun.length} test(s) to run`);
397
- // Execute each test
398
106
  for (const test of testsToRun) {
399
107
  const testSpinner = isJson
400
108
  ? { start: () => { }, succeed: (_msg) => { }, fail: (_msg) => { } }
@@ -403,7 +111,6 @@ async function runNamedTests(apiClient, _outputService, configService, testNames
403
111
  const result = await apiClient.executeTest(test.id);
404
112
  results.push(result);
405
113
  testSpinner.succeed(`Test "${test.name}" started`);
406
- // Use SSE streaming for live progress
407
114
  if (result.task_id && shouldWait) {
408
115
  await streamTestProgress(configService, result, test.name, options, timeout, results, testNames, isJson);
409
116
  }
@@ -419,31 +126,25 @@ async function runNamedTests(apiClient, _outputService, configService, testNames
419
126
  throw error;
420
127
  }
421
128
  }
422
- /**
423
- * Stream test progress using SSE
424
- */
425
129
  async function streamTestProgress(configService, result, testName, options, timeout, results, testNames, silent = false) {
426
130
  const sseClient = new SSEClient(configService);
427
131
  const startTime = Date.now();
428
132
  let renderer = null;
429
133
  let logger = null;
430
- // Check if verbose flag was passed
431
134
  const isVerbose = options.verbose ||
432
135
  (testNames && (testNames.includes('--verbose') || testNames.includes('-v'))) ||
433
136
  process.env.OBS_VERBOSE === 'true';
434
137
  if (!silent) {
435
- const { LiveProgressRenderer } = await import('../utils/live-progress.js');
436
- const { LogWriter } = await import('../utils/log-writer.js');
138
+ const { LiveProgressRenderer } = await import('../../utils/live-progress.js');
139
+ const { LogWriter } = await import('../../utils/log-writer.js');
437
140
  renderer = new LiveProgressRenderer({
438
141
  verbose: isVerbose,
439
142
  });
440
143
  logger = new LogWriter(result.task_id);
441
144
  renderer.start(testName);
442
145
  }
443
- // Track completion
444
146
  let completed = false;
445
147
  let stepCounter = 0;
446
- // Connect to SSE stream
447
148
  sseClient.connect(result.task_id, (message) => {
448
149
  if (message.type === 'step_update' && message.step) {
449
150
  stepCounter++;
@@ -469,7 +170,6 @@ async function streamTestProgress(configService, result, testName, options, time
469
170
  renderer.complete(status, message.message);
470
171
  logger.writeComplete(status, message.message);
471
172
  }
472
- // Calculate duration
473
173
  const duration = Date.now() - startTime;
474
174
  results[results.length - 1] = {
475
175
  ...result,
@@ -519,7 +219,6 @@ async function streamTestProgress(configService, result, testName, options, time
519
219
  completed = true;
520
220
  }
521
221
  });
522
- // Wait for completion
523
222
  await new Promise((resolve) => {
524
223
  const checkInterval = setInterval(() => {
525
224
  if (completed) {
@@ -547,9 +246,6 @@ async function streamTestProgress(configService, result, testName, options, time
547
246
  }, timeout);
548
247
  });
549
248
  }
550
- /**
551
- * Format and output test results
552
- */
553
249
  async function formatAndOutputResults(results, options, outputService, isJson) {
554
250
  if (isJson) {
555
251
  outputService.enableJsonMode();
@@ -566,14 +262,12 @@ async function formatAndOutputResults(results, options, outputService, isJson) {
566
262
  }
567
263
  }
568
264
  else {
569
- // Console output
570
265
  results.forEach((result, index) => {
571
266
  if (results.length > 1) {
572
267
  console.log(chalk.bold(`\nTest ${index + 1}:`));
573
268
  }
574
269
  outputService.formatTestResult(result);
575
270
  });
576
- // Summary
577
271
  const successCount = results.filter((r) => r.status === 'SUCCESS').length;
578
272
  const totalCount = results.length;
579
273
  console.log(chalk.bold('\nSummary'));
@@ -581,7 +275,6 @@ async function formatAndOutputResults(results, options, outputService, isJson) {
581
275
  console.log(`Total: ${totalCount}`);
582
276
  console.log(chalk.green(`Passed: ${successCount}`));
583
277
  console.log(chalk.red(`Failed: ${totalCount - successCount}`));
584
- // Exit with appropriate code
585
278
  if (successCount === totalCount) {
586
279
  outputService.success('All tests passed!');
587
280
  process.exit(0);
@@ -592,9 +285,6 @@ async function formatAndOutputResults(results, options, outputService, isJson) {
592
285
  }
593
286
  }
594
287
  }
595
- /**
596
- * Generate JUnit XML report
597
- */
598
288
  function generateJUnitReport(results, outputService) {
599
289
  const testSuite = {
600
290
  name: 'ObserveOne Tests',
@@ -618,4 +308,4 @@ function generateJUnitReport(results, outputService) {
618
308
  };
619
309
  return outputService.formatJUnitReport(testSuite);
620
310
  }
621
- //# sourceMappingURL=ai-check.js.map
311
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/ai-check/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAkBnC,SAAS,gBAAgB,CAAC,OAA0B;IAClD,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAC/F,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,aAA6B,EAC7B,SAAqB,EACrB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,sBAAsB,CAAC;SACnC,QAAQ,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;SACxC,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,CAAC;SAC3D,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC;SACxC,MAAM,CAAC,iCAAiC,EAAE,kBAAkB,CAAC;SAC7D,MAAM,CAAC,yBAAyB,EAAE,yBAAyB,EAAE,QAAQ,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,iDAAiD,CAAC;SAC1E,MAAM,CAAC,YAAY,EAAE,0BAA0B,CAAC;SAChD,MAAM,CAAC,SAAS,EAAE,6CAA6C,CAAC;SAChE,MAAM,CAAC,uBAAuB,EAAE,wCAAwC,EAAE,SAAS,CAAC;SACpF,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,CAAC;SACxD,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SAC7C,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SAC7C,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,SAAmB,EAAE,OAA0B,EAAE,EAAE;QAChE,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,aAAa,CAAC,cAAc,EAAE,CAAC;QACjC,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzD,IAAI,CAAC;YACH,IAAI,OAAO,CAAC,MAAM;gBAAE,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACvE,IAAI,OAAO,CAAC,MAAM;gBAAE,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAE5D,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,aAAa,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAiB,EAAE,CAAC;YAEjC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACpC,aAAa,CAAC,KAAK,CACjB,wEAAwE,CACzE,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,MAAM,YAAY,CAChB,SAAS,EACT,aAAa,EACb,aAAa,EACb,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,EACV,MAAM,CACP,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,CACjB,SAAS,EACT,aAAa,EACb,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,EACV,MAAM,CACP,CAAC;YACJ,CAAC;YAED,MAAM,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,SAAqB,EACrB,aAA6B,EAC7B,aAA6B,EAC7B,OAA0B,EAC1B,OAAe,EACf,OAAqB,EACrB,UAAmB,EACnB,MAAe;IAEf,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE;QAChF,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,KAAK,EAAE,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC;YAC9C,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,aAAa;YACnC,GAAG,EAAE,OAAO,CAAC,GAAI;YACjB,MAAM,EAAE,OAAO,CAAC,MAAO;YACvB,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEvC,IAAI,MAAM,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,kBAAkB,CACtB,aAAa,EACb,MAAM,EACN,OAAO,CAAC,IAAI,IAAI,aAAa,EAC7B,OAAO,EACP,OAAO,EACP,OAAO,EACP,SAAS,EACT,MAAM,CACP,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,SAAqB,EACrB,cAA8B,EAC9B,aAA6B,EAC7B,SAAmB,EACnB,OAA0B,EAC1B,OAAe,EACf,OAAqB,EACrB,UAAmB,EACnB,MAAe;IAEf,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE;QAChF,CAAC,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,SAAS;aACzB,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aAC/C,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;YACpB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;oBACf,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,aAAa,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEL,OAAO,CAAC,OAAO,CAAC,SAAS,UAAU,CAAC,MAAM,iBAAiB,CAAC,CAAC;QAE7D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,WAAW,GAAG,MAAM;gBACxB,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,GAAE,CAAC,EAAE;gBAChF,CAAC,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAE9C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrB,WAAW,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,WAAW,CAAC,CAAC;gBAEnD,IAAI,MAAM,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;oBACjC,MAAM,kBAAkB,CACtB,aAAa,EACb,MAAM,EACN,IAAI,CAAC,IAAI,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,SAAS,EACT,MAAM,CACP,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC;gBAC/C,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,aAA6B,EAC7B,MAAkB,EAClB,QAAgB,EAChB,OAA0B,EAC1B,OAAe,EACf,OAAqB,EACrB,SAAoB,EACpB,SAAkB,KAAK;IAEvB,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAuB7B,IAAI,QAAQ,GAAoB,IAAI,CAAC;IACrC,IAAI,MAAM,GAAkB,IAAI,CAAC;IAEjC,MAAM,SAAS,GACb,OAAO,CAAC,OAAO;QACf,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,CAAC;IAErC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;QAC9E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;QAChE,QAAQ,GAAG,IAAI,oBAAoB,CAAC;YAClC,OAAO,EAAE,SAAS;SACnB,CAAwB,CAAC;QAC1B,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,OAAQ,CAAsB,CAAC;QAC7D,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,SAAS,CAAC,OAAO,CACf,MAAM,CAAC,OAAQ,EACf,CAAC,OAAO,EAAE,EAAE;QACV,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACnD,WAAW,EAAE,CAAC;YACd,MAAM,IAAI,GAAG,OAAO,CAAC,IAAY,CAAC;YAElC,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAClC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;oBACvB,QAAQ,CAAC,aAAa,EAAE,CAAC;oBACzB,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;gBACtC,CAAC;gBAED,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,IAAI,eAAe,EAAE,IAAI,CAAC,CAAC;gBAC1E,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAClC,QAAQ,CAAC,aAAa,EAAE,CAAC;gBACzB,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;YAClE,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAClC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC3C,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAChD,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAExC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;gBAC5B,GAAG,MAAM;gBACT,MAAM,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAyB;gBAC7E,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO;gBAC1C,QAAQ,EAAE,QAAQ;aACnB,CAAC;YAEF,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAClC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC,CAAC;gBACjD,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;gBAC5B,GAAG,MAAM;gBACT,MAAM,EAAE,QAAiB;gBACzB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,sBAAsB;aACnD,CAAC;YAEF,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;QACjB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,KAA6B,CAAC;YAC1C,IAAI,CAAC,MAAM,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;gBAClC,QAAQ,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACnD,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,qBAAqB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;gBAC5B,GAAG,MAAM;gBACT,MAAM,EAAE,QAAiB;gBACzB,OAAO,EAAE,qBAAqB,GAAG,CAAC,OAAO,EAAE;aAC5C,CAAC;YACF,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;YACD,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACrC,IAAI,SAAS,EAAE,CAAC;gBACd,aAAa,CAAC,aAAa,CAAC,CAAC;gBAC7B,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,aAAa,CAAC,aAAa,CAAC,CAAC;gBAC7B,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACxB,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;gBAC7C,CAAC;gBACD,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;oBAC5B,GAAG,MAAM;oBACT,MAAM,EAAE,QAAiB;oBACzB,OAAO,EAAE,0BAA0B;iBACpC,CAAC;gBACF,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClB,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;oBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,EAAE,OAAO,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,OAAqB,EACrB,OAA0B,EAC1B,aAA6B,EAC7B,MAAe;IAEf,IAAI,MAAM,EAAE,CAAC;QACX,aAAa,CAAC,cAAc,EAAE,CAAC;QAC/B,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YAC3C,aAAa,CAAC,OAAO,CAAC,yBAAyB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YAChC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAClD,CAAC;YACD,aAAa,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QAC1E,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QAElC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,UAAU,UAAU,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,YAAY,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;YAChC,aAAa,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,YAAY,iBAAiB,CAAC,CAAC;YACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAqB,EAAE,aAA6B;IAC/E,MAAM,SAAS,GAAG;QAChB,IAAI,EAAE,kBAAkB;QACxB,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM;QAC7D,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE;QACpF,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,EAAE,QAAQ,KAAK,GAAG,CAAC,EAAE;YACzB,SAAS,EAAE,iBAAiB;YAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE;YAChD,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YACzD,OAAO,EACL,MAAM,CAAC,MAAM,KAAK,QAAQ;gBACxB,CAAC,CAAC;oBACE,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,EAAE;iBACf;gBACH,CAAC,CAAC,SAAS;SAChB,CAAC,CAAC;KACJ,CAAC;IAEF,OAAO,aAAa,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+ import { IConfigService } from '../../interfaces/config.interface.js';
3
+ import { IApiClient } from '../../interfaces/api-client.interface.js';
4
+ import { IOutputService } from '../../interfaces/output.interface.js';
5
+ export declare function createAiCheckStatusCommand(configService: IConfigService, apiClient: IApiClient, outputService: IOutputService): Command;
6
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/ai-check/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CA8BT"}
@@ -0,0 +1,32 @@
1
+ import { Command } from 'commander';
2
+ export function createAiCheckStatusCommand(configService, apiClient, outputService) {
3
+ return new Command('status')
4
+ .description('Get the status of a browser check execution')
5
+ .argument('<execution-id>', 'Execution ID')
6
+ .option('-j, --json', 'Output in JSON format')
7
+ .action(async (executionId, options) => {
8
+ if (process.env.OBS_JSON_OUTPUT === 'true' || options.json === true) {
9
+ outputService.enableJsonMode();
10
+ }
11
+ try {
12
+ const apiKey = configService.getApiKey();
13
+ if (!apiKey) {
14
+ outputService.error('Not authenticated. Please run "obs login" first.');
15
+ process.exit(1);
16
+ }
17
+ const id = parseInt(executionId);
18
+ if (isNaN(id)) {
19
+ outputService.error('Invalid execution ID. Must be a numeric ID from a named check run.');
20
+ process.exit(1);
21
+ }
22
+ outputService.progress(`Fetching execution status for ${id}...`);
23
+ const execution = await apiClient.getExecutionStatus(id);
24
+ outputService.formatJsonOutput(execution);
25
+ }
26
+ catch (error) {
27
+ outputService.error(outputService.formatError(error));
28
+ process.exit(1);
29
+ }
30
+ });
31
+ }
32
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/ai-check/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,MAAM,UAAU,0BAA0B,CACxC,aAA6B,EAC7B,SAAqB,EACrB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;SAC1C,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,OAAgC,EAAE,EAAE;QACtE,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACpE,aAAa,CAAC,cAAc,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,aAAa,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBACd,aAAa,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;gBAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,aAAa,CAAC,QAAQ,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACjE,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;YACzD,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+ import { IConfigService } from '../../interfaces/config.interface.js';
3
+ import { IApiClient } from '../../interfaces/api-client.interface.js';
4
+ import { IOutputService } from '../../interfaces/output.interface.js';
5
+ export declare function createAiCheckWaitCommand(configService: IConfigService, apiClient: IApiClient, outputService: IOutputService): Command;
6
+ //# sourceMappingURL=wait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../../src/commands/ai-check/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CA4DT"}
@@ -0,0 +1,59 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ export function createAiCheckWaitCommand(configService, apiClient, outputService) {
4
+ return new Command('wait')
5
+ .description('Wait for a browser check execution to complete')
6
+ .argument('<execution-id>', 'Execution ID')
7
+ .option('-j, --json', 'Output in JSON format')
8
+ .option('-t, --timeout <ms>', 'Max time to wait in milliseconds', '300000')
9
+ .action(async (executionId, options) => {
10
+ const isJson = process.env.OBS_JSON_OUTPUT === 'true' || options.json === true;
11
+ if (isJson) {
12
+ outputService.enableJsonMode();
13
+ }
14
+ try {
15
+ const apiKey = configService.getApiKey();
16
+ if (!apiKey) {
17
+ outputService.error('Not authenticated. Please run "obs login" first.');
18
+ process.exit(1);
19
+ }
20
+ const id = parseInt(executionId);
21
+ if (isNaN(id)) {
22
+ outputService.error('Invalid execution ID. Must be a numeric ID from a named check run.');
23
+ process.exit(1);
24
+ }
25
+ const timeoutMs = parseInt(options.timeout) || 300000;
26
+ const intervalMs = 5000;
27
+ const maxAttempts = Math.ceil(timeoutMs / intervalMs);
28
+ const spinner = isJson ? null : ora(`Waiting for execution ${id}...`).start();
29
+ const execution = await apiClient.pollExecutionStatus(id, maxAttempts, intervalMs);
30
+ if (spinner) {
31
+ if (execution.status === 'SUCCESS') {
32
+ spinner.succeed(`Execution ${id} completed successfully.`);
33
+ }
34
+ else {
35
+ spinner.fail(`Execution ${id} ended with status: ${execution.status}`);
36
+ }
37
+ }
38
+ let results;
39
+ if (execution.status === 'SUCCESS') {
40
+ try {
41
+ results = await apiClient.getExecutionResults(id);
42
+ }
43
+ catch {
44
+ // results are optional
45
+ }
46
+ }
47
+ const payload = { execution, ...(results !== undefined && { results }) };
48
+ outputService.formatJsonOutput(payload);
49
+ if (execution.status !== 'SUCCESS') {
50
+ process.exit(1);
51
+ }
52
+ }
53
+ catch (error) {
54
+ outputService.error(outputService.formatError(error));
55
+ process.exit(1);
56
+ }
57
+ });
58
+ }
59
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/commands/ai-check/wait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AAKtB,MAAM,UAAU,wBAAwB,CACtC,aAA6B,EAC7B,SAAqB,EACrB,aAA6B;IAE7B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,gDAAgD,CAAC;SAC7D,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC;SAC1C,MAAM,CAAC,YAAY,EAAE,uBAAuB,CAAC;SAC7C,MAAM,CAAC,oBAAoB,EAAE,kCAAkC,EAAE,QAAQ,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,OAAgC,EAAE,EAAE;QACtE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;QAC/E,IAAI,MAAM,EAAE,CAAC;YACX,aAAa,CAAC,cAAc,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,aAAa,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;gBACd,aAAa,CAAC,KAAK,CAAC,oEAAoE,CAAC,CAAC;gBAC1F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAiB,CAAC,IAAI,MAAM,CAAC;YAChE,MAAM,UAAU,GAAG,IAAI,CAAC;YACxB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;YAEtD,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;YAE9E,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,mBAAmB,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAEnF,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACnC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;gBAC7D,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,uBAAuB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,IAAI,OAA8B,CAAC;YACnC,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,SAAS,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;gBACpD,CAAC;gBAAC,MAAM,CAAC;oBACP,uBAAuB;gBACzB,CAAC;YACH,CAAC;YAED,MAAM,OAAO,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;YACzE,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAExC,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ import { IOutputService } from '../interfaces/output.interface.js';
3
+ export declare function createSchemaCommand(outputService: IOutputService): Command;
4
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGnE,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,cAAc,GAAG,OAAO,CAsC1E"}
@@ -0,0 +1,42 @@
1
+ import { Command } from 'commander';
2
+ import { writeFileSync, mkdirSync } from 'fs';
3
+ import { dirname } from 'path';
4
+ import { buildJsonSchema, resourceNames } from '../utils/schemas.js';
5
+ export function createSchemaCommand(outputService) {
6
+ return new Command('schema')
7
+ .description('Print the JSON Schema for a resource type')
8
+ .argument('<resource>', `Resource type (${resourceNames.join(', ')})`)
9
+ .option('-o, --out <path>', 'Write schema to file (directories auto-created)')
10
+ .option('-j, --json', 'Output in JSON format (schema is already JSON)')
11
+ .action((resource, options) => {
12
+ const isJson = process.env.OBS_JSON_OUTPUT === 'true' || options.json === true;
13
+ if (isJson)
14
+ outputService.enableJsonMode();
15
+ const schema = buildJsonSchema(resource);
16
+ if (!schema) {
17
+ outputService.error(`Unknown resource type "${resource}". Valid types: ${resourceNames.join(', ')}`);
18
+ process.exit(1);
19
+ }
20
+ const payload = JSON.stringify(schema, null, 2);
21
+ if (options.out) {
22
+ const dir = dirname(options.out);
23
+ if (dir && dir !== '.')
24
+ mkdirSync(dir, { recursive: true });
25
+ writeFileSync(options.out, payload);
26
+ if (isJson) {
27
+ outputService.formatJsonOutput({ resource, out: options.out });
28
+ }
29
+ else {
30
+ outputService.success(`Schema written to ${options.out}`);
31
+ }
32
+ return;
33
+ }
34
+ if (isJson) {
35
+ outputService.formatJsonOutput(schema);
36
+ }
37
+ else {
38
+ console.log(payload);
39
+ }
40
+ });
41
+ }
42
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErE,MAAM,UAAU,mBAAmB,CAAC,aAA6B;IAC/D,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,2CAA2C,CAAC;SACxD,QAAQ,CAAC,YAAY,EAAE,kBAAkB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SACrE,MAAM,CAAC,kBAAkB,EAAE,iDAAiD,CAAC;SAC7E,MAAM,CAAC,YAAY,EAAE,gDAAgD,CAAC;SACtE,MAAM,CAAC,CAAC,QAAgB,EAAE,OAAyC,EAAE,EAAE;QACtE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;QAC/E,IAAI,MAAM;YAAE,aAAa,CAAC,cAAc,EAAE,CAAC;QAE3C,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,aAAa,CAAC,KAAK,CACjB,0BAA0B,QAAQ,mBAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAChF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEhD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;gBAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,MAAM,EAAE,CAAC;gBACX,aAAa,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,OAAO,CAAC,qBAAqB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,aAAa,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}