@qa-ai-stlc/cli 0.1.4 → 0.2.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.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAK9F,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,2BAA2B,EAAE,aAAa,GAAG,MAAM,CAAC,GAAG;IAC3F,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAmBF;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BvG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAO9F,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,2BAA2B,EAAE,aAAa,GAAG,MAAM,CAAC,GAAG;IAC3F,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAcF;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BvG"}
package/dist/cli.js CHANGED
@@ -1,27 +1,24 @@
1
1
  // Copyright The QA-AI-STLC Authors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { createRequire } from 'node:module';
4
3
  import { parseArgs } from 'node:util';
5
4
  import { QaError } from '@qa-ai-stlc/core';
6
5
  import { createCommandContext } from './command-context.js';
7
6
  import { runDoctor } from './commands/doctor.js';
7
+ import { runExplore } from './commands/explore.js';
8
8
  import { runInit } from './commands/init.js';
9
9
  import { EXIT_FAILURE, EXIT_SUCCESS, EXIT_USAGE } from './exit-codes.js';
10
+ import { readPackageVersion } from './package-version.js';
10
11
  const USAGE = `Usage: qa <command> [options]
11
12
 
12
13
  Commands:
13
14
  init Create the .qa/ store and a starting config.yaml
14
15
  doctor Check Node, browsers, identities and environment reachability
16
+ explore Build the selector registry: crawl, static source analysis, pick mode, --verify
15
17
 
16
18
  Global options:
17
19
  --json Print machine-readable JSON instead of human text
18
20
  -h, --help Show this help
19
21
  --version Show the CLI version`;
20
- function readCliVersion() {
21
- const require = createRequire(import.meta.url);
22
- const packageJson = require('../package.json');
23
- return packageJson.version;
24
- }
25
22
  /**
26
23
  * Parses argv and dispatches to a command, returning the process exit code (AGENTS.md 5.4:
27
24
  * `process.exit` itself belongs only in the bin entry point). Never throws: an unexpected error
@@ -35,7 +32,7 @@ export async function runCli(argv, dependencies) {
35
32
  return command === undefined ? EXIT_USAGE : EXIT_SUCCESS;
36
33
  }
37
34
  if (command === '--version') {
38
- io.stdout(readCliVersion());
35
+ io.stdout(readPackageVersion());
39
36
  return EXIT_SUCCESS;
40
37
  }
41
38
  try {
@@ -44,6 +41,8 @@ export async function runCli(argv, dependencies) {
44
41
  return await dispatchInit(rest, dependencies);
45
42
  case 'doctor':
46
43
  return await dispatchDoctor(rest, dependencies);
44
+ case 'explore':
45
+ return await dispatchExplore(rest, dependencies);
47
46
  default:
48
47
  io.stderr(`Unknown command "${command}".\n\n${USAGE}`);
49
48
  return EXIT_USAGE;
@@ -108,6 +107,46 @@ async function dispatchDoctor(rest, dependencies) {
108
107
  printResult(context.io, json, 'doctor', report, formatDoctorReport(report));
109
108
  return report.ok ? EXIT_SUCCESS : EXIT_FAILURE;
110
109
  }
110
+ function parsePositiveInt(value, flag) {
111
+ const parsed = Number.parseInt(value, 10);
112
+ if (!Number.isInteger(parsed) || parsed <= 0) {
113
+ throw new QaError('EXPLORE_OPTION_INVALID', `"${value}" is not a positive integer for ${flag}`);
114
+ }
115
+ return parsed;
116
+ }
117
+ async function dispatchExplore(rest, dependencies) {
118
+ const values = parseCommandArgs(rest, {
119
+ json: { type: 'boolean', default: false },
120
+ environment: { type: 'string' },
121
+ identity: { type: 'string' },
122
+ 'cdp-endpoint': { type: 'string' },
123
+ policy: { type: 'string' },
124
+ static: { type: 'boolean', default: false },
125
+ pick: { type: 'string' },
126
+ 'max-pages': { type: 'string' },
127
+ verify: { type: 'boolean', default: false },
128
+ });
129
+ const json = values.json === true;
130
+ const context = createCommandContext({
131
+ ...dependencies,
132
+ projectRoot: dependencies.projectRoot ?? process.cwd(),
133
+ json,
134
+ });
135
+ const report = await runExplore(context, {
136
+ ...(typeof values.environment === 'string' ? { environment: values.environment } : {}),
137
+ ...(typeof values.identity === 'string' ? { identity: values.identity } : {}),
138
+ ...(typeof values['cdp-endpoint'] === 'string' ? { cdpEndpointUrl: values['cdp-endpoint'] } : {}),
139
+ ...(typeof values.policy === 'string' ? { policy: values.policy } : {}),
140
+ static: values.static === true,
141
+ ...(typeof values.pick === 'string' ? { pick: values.pick } : {}),
142
+ ...(typeof values['max-pages'] === 'string'
143
+ ? { maxPages: parsePositiveInt(values['max-pages'], '--max-pages') }
144
+ : {}),
145
+ verify: values.verify === true,
146
+ });
147
+ printResult(context.io, json, 'explore', report, formatExploreReport(report));
148
+ return report.degraded.length > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
149
+ }
111
150
  function printResult(io, json, command, data, humanLines) {
112
151
  if (json) {
113
152
  io.stdout(JSON.stringify({ command, data }));
@@ -130,4 +169,24 @@ function formatDoctorReport(report) {
130
169
  return `[${marker}] ${check.name}: ${check.message}${remediation}`;
131
170
  });
132
171
  }
172
+ function formatExploreReport(report) {
173
+ if (report.mode === 'verify') {
174
+ const lines = [`Verified ${report.registryPath}: ${String(report.elementCount)} element(s) checked.`];
175
+ if (report.degraded.length === 0) {
176
+ lines.push('No degraded selectors.');
177
+ return lines;
178
+ }
179
+ lines.push(`${String(report.degraded.length)} degraded selector(s):`);
180
+ for (const element of report.degraded) {
181
+ lines.push(` ${element.elementId}: ${String(element.previousScore)} -> ${String(element.currentScore)}`);
182
+ }
183
+ return lines;
184
+ }
185
+ return [
186
+ `Wrote ${report.registryPath}: ${String(report.elementCount)} element(s) (` +
187
+ `${String(report.added)} added, ${String(report.removed)} removed, ${String(report.degraded.length)} degraded).`,
188
+ `${String(report.missingLocatorCount)} element(s) with no locator candidate.`,
189
+ `${String(report.blockedRequestCount)} non-GET request(s) blocked by safe mode.`,
190
+ ];
191
+ }
133
192
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type Clock, type FileSystem, type HttpClient, type Logger, type ProcessRunner } from '@qa-ai-stlc/core';
1
+ import { type BrowserLauncher, type Clock, type FileSystem, type HttpClient, type Logger, type ProcessRunner } from '@qa-ai-stlc/core';
2
2
  import type { CliIO } from './cli-io.js';
3
3
  /**
4
4
  * Everything a command needs, injected so commands are testable without real I/O, a real clock
@@ -14,6 +14,7 @@ export interface CommandContext {
14
14
  readonly logger: Logger;
15
15
  readonly processRunner: ProcessRunner;
16
16
  readonly httpClient: HttpClient;
17
+ readonly browserLauncher: BrowserLauncher;
17
18
  readonly env: Readonly<Record<string, string | undefined>>;
18
19
  }
19
20
  export interface CreateCommandContextOptions {
@@ -25,6 +26,7 @@ export interface CreateCommandContextOptions {
25
26
  readonly logger?: Logger;
26
27
  readonly processRunner?: ProcessRunner;
27
28
  readonly httpClient?: HttpClient;
29
+ readonly browserLauncher?: BrowserLauncher;
28
30
  readonly env?: Readonly<Record<string, string | undefined>>;
29
31
  }
30
32
  export declare function createCommandContext(options: CreateCommandContextOptions): CommandContext;
@@ -1 +1 @@
1
- {"version":3,"file":"command-context.d.ts","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"AAGA,OAAO,EAML,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC7D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAYzF"}
1
+ {"version":3,"file":"command-context.d.ts","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,eAAe,EACpB,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CAC7D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAazF"}
@@ -1,6 +1,6 @@
1
1
  // Copyright The QA-AI-STLC Authors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { fetchHttpClient, nodeFileSystem, nodeProcessRunner, noopLogger, systemClock, } from '@qa-ai-stlc/core';
3
+ import { fetchHttpClient, nodeFileSystem, nodeProcessRunner, noopLogger, playwrightBrowserLauncher, systemClock, } from '@qa-ai-stlc/core';
4
4
  export function createCommandContext(options) {
5
5
  return {
6
6
  projectRoot: options.projectRoot,
@@ -11,6 +11,7 @@ export function createCommandContext(options) {
11
11
  logger: options.logger ?? noopLogger,
12
12
  processRunner: options.processRunner ?? nodeProcessRunner,
13
13
  httpClient: options.httpClient ?? fetchHttpClient,
14
+ browserLauncher: options.browserLauncher ?? playwrightBrowserLauncher,
14
15
  env: options.env ?? process.env,
15
16
  };
16
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"command-context.js","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EACL,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,WAAW,GAMZ,MAAM,kBAAkB,CAAC;AAgC1B,MAAM,UAAU,oBAAoB,CAAC,OAAoC;IACvE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;QAC3B,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,cAAc;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,UAAU;QACpC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,iBAAiB;QACzD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,eAAe;QACjD,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG;KAChC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"command-context.js","sourceRoot":"","sources":["../src/command-context.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EACL,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,yBAAyB,EACzB,WAAW,GAOZ,MAAM,kBAAkB,CAAC;AAkC1B,MAAM,UAAU,oBAAoB,CAAC,OAAoC;IACvE,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;QAC3B,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,cAAc;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,UAAU;QACpC,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,iBAAiB;QACzD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,eAAe;QACjD,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,yBAAyB;QACrE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { type DegradedSelectorElement } from '@qa-ai-stlc/explorer';
2
+ import type { CommandContext } from '../command-context.js';
3
+ export interface ExploreOptions {
4
+ readonly environment?: string;
5
+ readonly identity?: string;
6
+ readonly cdpEndpointUrl?: string;
7
+ readonly policy?: string;
8
+ readonly static?: boolean;
9
+ /** A single URL to run pick mode against instead of crawling. */
10
+ readonly pick?: string;
11
+ readonly maxPages?: number;
12
+ /** Re-checks the stored registry's candidates live instead of building a new one. */
13
+ readonly verify?: boolean;
14
+ }
15
+ export interface ExploreReport {
16
+ readonly mode: 'explore' | 'verify';
17
+ readonly registryPath: string;
18
+ readonly elementCount: number;
19
+ readonly added: number;
20
+ readonly removed: number;
21
+ readonly degraded: readonly DegradedSelectorElement[];
22
+ readonly missingLocatorCount: number;
23
+ readonly blockedRequestCount: number;
24
+ }
25
+ /**
26
+ * `qa explore`: builds the selector registry (development plan section 6.3) by crawling, then
27
+ * merges in static source analysis (`--static`) or a manual pick-mode session (`--pick <url>`)
28
+ * when asked, writes `.qa/selectors/registry.json`, `.qa/selectors/missing-test-ids.json` and the
29
+ * generated `tests/qa/locators.ts`, and registers all three in the manifest. `--verify` skips
30
+ * building anything: it re-checks every stored, non-deprecated element's primary candidate against
31
+ * the live page it was found on and fails (`degraded` non-empty) when one no longer resolves as
32
+ * well as it did when last recorded — the signal a stale selector (e.g. a renamed test ID) needs.
33
+ */
34
+ export declare function runExplore(context: CommandContext, options?: ExploreOptions): Promise<ExploreReport>;
35
+ //# sourceMappingURL=explore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explore.d.ts","sourceRoot":"","sources":["../../src/commands/explore.ts"],"names":[],"mappings":"AAYA,OAAO,EAeL,KAAK,uBAAuB,EAG7B,MAAM,sBAAsB,CAAC;AAW9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAa5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AA6OD;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAuDxB"}
@@ -0,0 +1,247 @@
1
+ // Copyright The QA-AI-STLC Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { ManifestStore, QaError, QaStore, loadConfig, resolveRelativePath, toRelativePath, } from '@qa-ai-stlc/core';
4
+ import { analyzePages, analyzeStaticSource, buildMissingTestIdReport, buildSelectorRegistry, capturePickModeElements, crawl, diffSelectorRegistry, finalizeManualSelectorEntries, generateLocatorModule, injectPickModeOverlay, mergeSelectorRegistry, resolveStorageState, scoreLocatorStability, waitForPickModeCompletion, } from '@qa-ai-stlc/explorer';
5
+ import { SCHEMA_VERSION, SelectorPolicySchema, SelectorRegistrySchema, } from '@qa-ai-stlc/schemas';
6
+ import { readPackageVersion } from '../package-version.js';
7
+ const REGISTRY_PATH = 'selectors/registry.json';
8
+ const MISSING_TEST_ID_REPORT_PATH = 'selectors/missing-test-ids.json';
9
+ const LOCATOR_MODULE_PATH = 'tests/qa/locators.ts';
10
+ // EJS is included alongside the three frameworks the development plan names (React/Angular/Vue):
11
+ // its templates are plain HTML, the same literal-attribute shape analyzeStaticSource looks for in
12
+ // any of the three, and the demo app (the only fixture this command is validated against) is
13
+ // server-rendered EJS.
14
+ const STATIC_SOURCE_EXTENSIONS = ['.tsx', '.jsx', '.ts', '.js', '.vue', '.html', '.ejs'];
15
+ function resolvePolicy(config, given) {
16
+ if (given === undefined) {
17
+ return config.selectors.policy;
18
+ }
19
+ const result = SelectorPolicySchema.safeParse(given);
20
+ if (!result.success) {
21
+ throw new QaError('EXPLORE_POLICY_INVALID', `"${given}" is not a known selector policy`, {
22
+ remediation: `Use one of: ${SelectorPolicySchema.options.join(', ')}.`,
23
+ });
24
+ }
25
+ return result.data;
26
+ }
27
+ function resolveEnvironment(config, name) {
28
+ const names = Object.keys(config.environments);
29
+ if (name !== undefined) {
30
+ const environment = config.environments[name];
31
+ if (environment === undefined) {
32
+ throw new QaError('EXPLORE_ENVIRONMENT_UNKNOWN', `No environment named "${name}" in config.yaml`, {
33
+ remediation: `Use one of: ${names.join(', ')}.`,
34
+ });
35
+ }
36
+ return { name, config: environment };
37
+ }
38
+ const [onlyEntry] = Object.entries(config.environments);
39
+ if (names.length === 1 && onlyEntry !== undefined) {
40
+ const [onlyName, onlyEnvironment] = onlyEntry;
41
+ return { name: onlyName, config: onlyEnvironment };
42
+ }
43
+ throw new QaError('EXPLORE_ENVIRONMENT_AMBIGUOUS', names.length === 0
44
+ ? 'config.yaml defines no environments'
45
+ : 'No --environment given and config.yaml defines more than one', {
46
+ remediation: names.length === 0
47
+ ? 'Add an environment to config.yaml.'
48
+ : `Pass --environment, one of: ${names.join(', ')}.`,
49
+ });
50
+ }
51
+ function resolveIdentity(context, config, options) {
52
+ if (options.identity === undefined) {
53
+ return undefined;
54
+ }
55
+ const identityConfig = config.identities[options.identity];
56
+ if (identityConfig === undefined) {
57
+ throw new QaError('EXPLORE_IDENTITY_UNKNOWN', `No identity named "${options.identity}" in config.yaml`, {
58
+ remediation: `Use one of: ${Object.keys(config.identities).join(', ')}.`,
59
+ });
60
+ }
61
+ return {
62
+ config: identityConfig,
63
+ env: context.env,
64
+ ...(options.cdpEndpointUrl !== undefined ? { cdpEndpointUrl: options.cdpEndpointUrl } : {}),
65
+ };
66
+ }
67
+ async function readStaticSourceFiles(fs, projectRoot, sourcePath) {
68
+ const absoluteSourceDir = resolveRelativePath(projectRoot, sourcePath);
69
+ const absolutePaths = (await fs.listFiles(absoluteSourceDir)).filter((path) => STATIC_SOURCE_EXTENSIONS.some((extension) => path.endsWith(extension)));
70
+ return Promise.all(absolutePaths.map(async (absolutePath) => ({
71
+ filePath: toRelativePath(projectRoot, absolutePath),
72
+ content: await fs.readFile(absolutePath),
73
+ })));
74
+ }
75
+ async function runCrawlAndBuild(context, config, options) {
76
+ const environment = resolveEnvironment(config, options.environment);
77
+ const identity = resolveIdentity(context, config, options);
78
+ const policy = resolvePolicy(config, options.policy);
79
+ const crawlResult = await crawl({
80
+ startUrl: environment.config.baseUrl,
81
+ allowlist: environment.config.allowlist,
82
+ browserLauncher: context.browserLauncher,
83
+ ...(identity !== undefined ? { identity } : {}),
84
+ ...(options.maxPages !== undefined ? { maxPages: options.maxPages } : {}),
85
+ });
86
+ const urls = crawlResult.routeMap.routes.map((route) => route.url);
87
+ const { pageModelSet, blockedRequestCount: analyzeBlocked } = await analyzePages({
88
+ urls,
89
+ browserLauncher: context.browserLauncher,
90
+ ...(identity !== undefined ? { identity } : {}),
91
+ });
92
+ const { registry, blockedRequestCount: buildBlocked } = await buildSelectorRegistry({
93
+ pageModelSet,
94
+ browserLauncher: context.browserLauncher,
95
+ ...(identity !== undefined ? { identity } : {}),
96
+ policy,
97
+ });
98
+ const elements = [...registry.elements];
99
+ if (options.static === true) {
100
+ if (config.source === undefined) {
101
+ throw new QaError('EXPLORE_STATIC_SOURCE_MISSING', '--static was given but config.yaml has no source.path', {
102
+ remediation: 'Set source.path in config.yaml to the application checkout to scan.',
103
+ });
104
+ }
105
+ const files = await readStaticSourceFiles(context.fs, context.projectRoot, config.source.path);
106
+ elements.push(...analyzeStaticSource({ files, clock: context.clock }).elements);
107
+ }
108
+ return {
109
+ elements,
110
+ blockedRequestCount: crawlResult.blockedRequestCount + analyzeBlocked + buildBlocked,
111
+ };
112
+ }
113
+ async function runPickModeSession(context, config, options) {
114
+ const identity = resolveIdentity(context, config, options);
115
+ const policy = resolvePolicy(config, options.policy);
116
+ const storageState = await resolveStorageState(context.browserLauncher, identity);
117
+ const browser = await context.browserLauncher.launch();
118
+ try {
119
+ const browserContext = await browser.newContext(storageState === undefined ? {} : { storageState });
120
+ const page = await browserContext.newPage();
121
+ await page.goto(options.pick);
122
+ await injectPickModeOverlay(page);
123
+ context.io.stdout(`Pick mode: a browser window opened at ${options.pick}. Click every element to capture, then click "Finish picking".`);
124
+ const captures = await waitForPickModeCompletion(page);
125
+ const pickModeElements = await capturePickModeElements(page, options.pick, captures, { policy });
126
+ const generatedAt = context.clock.now().toISOString();
127
+ const elements = finalizeManualSelectorEntries(pickModeElements, new Map(), generatedAt);
128
+ return { elements, blockedRequestCount: 0 };
129
+ }
130
+ finally {
131
+ await browser.close();
132
+ }
133
+ }
134
+ async function runVerify(context, store, config, options) {
135
+ const exists = await store.pathExists(REGISTRY_PATH);
136
+ if (!exists) {
137
+ throw new QaError('EXPLORE_NO_REGISTRY', 'No selector registry found to verify', {
138
+ remediation: 'Run "qa explore" first to build a registry.',
139
+ });
140
+ }
141
+ const stored = await store.readJson(REGISTRY_PATH, SelectorRegistrySchema);
142
+ const identity = resolveIdentity(context, config, options);
143
+ const storageState = await resolveStorageState(context.browserLauncher, identity);
144
+ const checkable = stored.elements.filter((element) => element.deprecatedAt === undefined &&
145
+ element.pageUrl !== undefined &&
146
+ element.locatorCandidates.length > 0);
147
+ const elementsByPageUrl = new Map();
148
+ for (const element of checkable) {
149
+ // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style -- filtered above
150
+ const pageUrl = element.pageUrl;
151
+ const group = elementsByPageUrl.get(pageUrl);
152
+ if (group === undefined) {
153
+ elementsByPageUrl.set(pageUrl, [element]);
154
+ }
155
+ else {
156
+ group.push(element);
157
+ }
158
+ }
159
+ const degraded = [];
160
+ const browser = await context.browserLauncher.launch();
161
+ try {
162
+ const browserContext = await browser.newContext(storageState === undefined ? {} : { storageState });
163
+ const page = await browserContext.newPage();
164
+ for (const [pageUrl, elements] of elementsByPageUrl) {
165
+ await page.goto(pageUrl);
166
+ for (const element of elements) {
167
+ // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style -- filtered above
168
+ const primary = element.locatorCandidates[0];
169
+ const currentScore = await scoreLocatorStability(page, primary);
170
+ if (currentScore < element.stabilityScore) {
171
+ degraded.push({
172
+ elementId: element.elementId,
173
+ previousScore: element.stabilityScore,
174
+ currentScore,
175
+ });
176
+ }
177
+ }
178
+ }
179
+ }
180
+ finally {
181
+ await browser.close();
182
+ }
183
+ const missingLocatorCount = generateLocatorModule(stored, { generatorVersion: readPackageVersion() })
184
+ .missingLocators.length;
185
+ return {
186
+ mode: 'verify',
187
+ registryPath: REGISTRY_PATH,
188
+ elementCount: stored.elements.length,
189
+ added: 0,
190
+ removed: 0,
191
+ degraded,
192
+ missingLocatorCount,
193
+ blockedRequestCount: 0,
194
+ };
195
+ }
196
+ /**
197
+ * `qa explore`: builds the selector registry (development plan section 6.3) by crawling, then
198
+ * merges in static source analysis (`--static`) or a manual pick-mode session (`--pick <url>`)
199
+ * when asked, writes `.qa/selectors/registry.json`, `.qa/selectors/missing-test-ids.json` and the
200
+ * generated `tests/qa/locators.ts`, and registers all three in the manifest. `--verify` skips
201
+ * building anything: it re-checks every stored, non-deprecated element's primary candidate against
202
+ * the live page it was found on and fails (`degraded` non-empty) when one no longer resolves as
203
+ * well as it did when last recorded — the signal a stale selector (e.g. a renamed test ID) needs.
204
+ */
205
+ export async function runExplore(context, options = {}) {
206
+ const store = new QaStore({ projectRoot: context.projectRoot, fs: context.fs });
207
+ const manifest = new ManifestStore({ store, clock: context.clock });
208
+ const config = await loadConfig(store);
209
+ if (options.verify === true) {
210
+ return runVerify(context, store, config, options);
211
+ }
212
+ const previous = (await store.pathExists(REGISTRY_PATH))
213
+ ? await store.readJson(REGISTRY_PATH, SelectorRegistrySchema)
214
+ : undefined;
215
+ const { elements, blockedRequestCount } = options.pick !== undefined
216
+ ? await runPickModeSession(context, config, { ...options, pick: options.pick })
217
+ : await runCrawlAndBuild(context, config, options);
218
+ const generatedAt = context.clock.now().toISOString();
219
+ const fresh = { schemaVersion: SCHEMA_VERSION, generatedAt, elements };
220
+ const merged = previous === undefined ? fresh : mergeSelectorRegistry(previous, fresh, generatedAt);
221
+ await store.writeJson(REGISTRY_PATH, merged);
222
+ await manifest.register(REGISTRY_PATH, JSON.stringify(merged));
223
+ const moduleResult = generateLocatorModule(merged, { generatorVersion: readPackageVersion() });
224
+ await context.fs.mkdir(resolveRelativePath(context.projectRoot, 'tests/qa'));
225
+ await context.fs.writeFile(resolveRelativePath(context.projectRoot, LOCATOR_MODULE_PATH), moduleResult.source);
226
+ await manifest.register(LOCATOR_MODULE_PATH, moduleResult.source);
227
+ const missingTestIdReport = buildMissingTestIdReport(merged);
228
+ await store.writeJson(MISSING_TEST_ID_REPORT_PATH, missingTestIdReport);
229
+ await manifest.register(MISSING_TEST_ID_REPORT_PATH, JSON.stringify(missingTestIdReport));
230
+ // Diffed against the fresh, unmerged registry, not the merged one: a merge always keeps an
231
+ // element the fresh run no longer found (deprecating it in place) rather than dropping it, so
232
+ // diffing the merged result would never show a "removed" element at all.
233
+ const diff = previous === undefined
234
+ ? { added: fresh.elements, removed: [], degraded: [] }
235
+ : diffSelectorRegistry(previous, fresh);
236
+ return {
237
+ mode: 'explore',
238
+ registryPath: REGISTRY_PATH,
239
+ elementCount: merged.elements.length,
240
+ added: diff.added.length,
241
+ removed: diff.removed.length,
242
+ degraded: diff.degraded,
243
+ missingLocatorCount: moduleResult.missingLocators.length,
244
+ blockedRequestCount,
245
+ };
246
+ }
247
+ //# sourceMappingURL=explore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explore.js","sourceRoot":"","sources":["../../src/commands/explore.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EACL,aAAa,EACb,OAAO,EACP,OAAO,EACP,UAAU,EACV,mBAAmB,EACnB,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,GAI1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,sBAAsB,GAMvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAChD,MAAM,2BAA2B,GAAG,iCAAiC,CAAC;AACtE,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAEnD,iGAAiG;AACjG,kGAAkG;AAClG,6FAA6F;AAC7F,uBAAuB;AACvB,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AA0BzF,SAAS,aAAa,CAAC,MAAc,EAAE,KAAyB;IAC9D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,OAAO,CAAC,wBAAwB,EAAE,IAAI,KAAK,kCAAkC,EAAE;YACvF,WAAW,EAAE,eAAe,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SACvE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,kBAAkB,CACzB,MAAc,EACd,IAAwB;IAExB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,OAAO,CAAC,6BAA6B,EAAE,yBAAyB,IAAI,kBAAkB,EAAE;gBAChG,WAAW,EAAE,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;aAChD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACvC,CAAC;IACD,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAClD,MAAM,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,SAAS,CAAC;QAC9C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,OAAO,CACf,+BAA+B,EAC/B,KAAK,CAAC,MAAM,KAAK,CAAC;QAChB,CAAC,CAAC,qCAAqC;QACvC,CAAC,CAAC,8DAA8D,EAClE;QACE,WAAW,EACT,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,oCAAoC;YACtC,CAAC,CAAC,+BAA+B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KACzD,CACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,OAAuB,EACvB,MAAc,EACd,OAAuB;IAEvB,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,OAAO,CAAC,0BAA0B,EAAE,sBAAsB,OAAO,CAAC,QAAQ,kBAAkB,EAAE;YACtG,WAAW,EAAE,eAAe,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SACzE,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,MAAM,EAAE,cAAc;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5F,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,EAAc,EACd,WAAmB,EACnB,UAAkB;IAElB,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5E,wBAAwB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CACvE,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAChB,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;QACzC,QAAQ,EAAE,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC;QACnD,OAAO,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;KACzC,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,OAAuB,EACvB,MAAc,EACd,OAAuB;IAEvB,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAErD,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC;QAC9B,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;QACpC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,SAAS;QACvC,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnE,MAAM,EAAE,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,GAAG,MAAM,YAAY,CAAC;QAC/E,IAAI;QACJ,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,MAAM,EAAE,QAAQ,EAAE,mBAAmB,EAAE,YAAY,EAAE,GAAG,MAAM,qBAAqB,CAAC;QAClF,YAAY;QACZ,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAsB,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,OAAO,CACf,+BAA+B,EAC/B,uDAAuD,EACvD;gBACE,WAAW,EAAE,qEAAqE;aACnF,CACF,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/F,QAAQ,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAClF,CAAC;IAED,OAAO;QACL,QAAQ;QACR,mBAAmB,EAAE,WAAW,CAAC,mBAAmB,GAAG,cAAc,GAAG,YAAY;KACrF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,OAAuB,EACvB,MAAc,EACd,OAAmD;IAEnD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAElF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;QACpG,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,CAAC,MAAM,CACf,yCAAyC,OAAO,CAAC,IAAI,gEAAgE,CACtH,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACjG,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,6BAA6B,CAAC,gBAAgB,EAAE,IAAI,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;QACzF,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,OAAuB,EACvB,KAAc,EACd,MAAc,EACd,OAAuB;IAEvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,OAAO,CAAC,qBAAqB,EAAE,sCAAsC,EAAE;YAC/E,WAAW,EAAE,6CAA6C;SAC3D,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAElF,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CACtC,CAAC,OAAO,EAAE,EAAE,CACV,OAAO,CAAC,YAAY,KAAK,SAAS;QAClC,OAAO,CAAC,OAAO,KAAK,SAAS;QAC7B,OAAO,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CACvC,CAAC;IACF,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC/D,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,kGAAkG;QAClG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAiB,CAAC;QAC1C,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC;QACpG,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC;YACpD,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,kGAAkG;gBAClG,MAAM,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAiD,CAAC;gBAC7F,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAChE,IAAI,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;oBAC1C,QAAQ,CAAC,IAAI,CAAC;wBACZ,SAAS,EAAE,OAAO,CAAC,SAAS;wBAC5B,aAAa,EAAE,OAAO,CAAC,cAAc;wBACrC,YAAY;qBACb,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,EAAE,CAAC;SAClG,eAAe,CAAC,MAAM,CAAC;IAE1B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,aAAa;QAC3B,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QACpC,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,CAAC;QACV,QAAQ;QACR,mBAAmB;QACnB,mBAAmB,EAAE,CAAC;KACvB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAuB,EACvB,UAA0B,EAAE;IAE5B,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QACtD,CAAC,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE,sBAAsB,CAAC;QAC7D,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GACrC,OAAO,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/E,CAAC,CAAC,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,MAAM,KAAK,GAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACzF,MAAM,MAAM,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,qBAAqB,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAC/F,MAAM,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAC7E,MAAM,OAAO,CAAC,EAAE,CAAC,SAAS,CACxB,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,EAC7D,YAAY,CAAC,MAAM,CACpB,CAAC;IACF,MAAM,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAElE,MAAM,mBAAmB,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,KAAK,CAAC,SAAS,CAAC,2BAA2B,EAAE,mBAAmB,CAAC,CAAC;IACxE,MAAM,QAAQ,CAAC,QAAQ,CAAC,2BAA2B,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAE1F,2FAA2F;IAC3F,8FAA8F;IAC9F,yEAAyE;IACzE,MAAM,IAAI,GACR,QAAQ,KAAK,SAAS;QACpB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACtD,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,SAAS;QACf,YAAY,EAAE,aAAa;QAC3B,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QACpC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;QACxB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;QAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,mBAAmB,EAAE,YAAY,CAAC,eAAe,CAAC,MAAM;QACxD,mBAAmB;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The published version of this CLI package, read from its own `package.json`. */
2
+ export declare function readPackageVersion(): string;
3
+ //# sourceMappingURL=package-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-version.d.ts","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAKA,mFAAmF;AACnF,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C"}
@@ -0,0 +1,10 @@
1
+ // Copyright The QA-AI-STLC Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { createRequire } from 'node:module';
4
+ /** The published version of this CLI package, read from its own `package.json`. */
5
+ export function readPackageVersion() {
6
+ const require = createRequire(import.meta.url);
7
+ const packageJson = require('../package.json');
8
+ return packageJson.version;
9
+ }
10
+ //# sourceMappingURL=package-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-version.js","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,mFAAmF;AACnF,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAiC,CAAC;IAC/E,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qa-ai-stlc/cli",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "The qa command: init, doctor and every deterministic engine operation exposed for CI and humans.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -21,18 +21,19 @@
21
21
  ".": "./dist/index.js"
22
22
  },
23
23
  "scripts": {
24
- "pretypecheck": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
24
+ "pretypecheck": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/explorer --workspace @qa-ai-stlc/test-utils",
25
25
  "typecheck": "tsc --noEmit -p .",
26
- "pretest": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
26
+ "pretest": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/explorer --workspace @qa-ai-stlc/test-utils",
27
27
  "test": "vitest run",
28
- "pretest:coverage": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/test-utils",
28
+ "pretest:coverage": "npm run build --workspace @qa-ai-stlc/schemas --workspace @qa-ai-stlc/core --workspace @qa-ai-stlc/explorer --workspace @qa-ai-stlc/test-utils",
29
29
  "test:coverage": "vitest run --coverage",
30
30
  "build": "tsc -b tsconfig.build.json",
31
31
  "clean": "node ../../scripts/clean-dir.mjs dist"
32
32
  },
33
33
  "dependencies": {
34
- "@qa-ai-stlc/core": "0.3.0",
35
- "@qa-ai-stlc/schemas": "0.4.0",
34
+ "@qa-ai-stlc/core": "0.4.1",
35
+ "@qa-ai-stlc/explorer": "0.6.0",
36
+ "@qa-ai-stlc/schemas": "0.6.0",
36
37
  "yaml": "2.9.1"
37
38
  },
38
39
  "devDependencies": {