@qa-ai-stlc/cli 0.2.1 → 0.4.0

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/README.md CHANGED
@@ -1,9 +1,16 @@
1
1
  # @qa-ai-stlc/cli
2
2
 
3
- The `qa` command: a thin client over `@qa-ai-stlc/core` for CI and humans. `qa init` creates the
4
- `.qa/` store and a starting `config.yaml`; `qa doctor` checks Node, browsers, identities and
5
- environment reachability before a run. Every command supports `--json` for machine-readable
6
- output and exits non-zero on failure.
3
+ The `qa` command: a thin client over `@qa-ai-stlc/core` and `@qa-ai-stlc/explorer` for CI and
4
+ humans. `qa init` creates the `.qa/` store and runs the testing scope survey; `qa doctor` checks
5
+ Node, browsers, identities and environment reachability before a run; `qa explore` crawls the
6
+ configured environment, optionally merges static source analysis (`--static`) and pick-mode
7
+ entries (`--pick <url>`), and writes the selector registry and a generated locator module;
8
+ `qa explore --verify` re-checks stored selectors against the live page without re-crawling.
9
+ `qa config set testing.<type> <value>` changes a scope decision after `init`; `qa config add
10
+ environment <name> --base-url <url> --allowlist <a,b,c>` and `qa config add identity <name> --auth
11
+ <cdp-attach|storage-state> --secret <QA_...> [--login-url <url>] [--username <user>]` add a
12
+ schema-validated entry instead of hand-editing `config.yaml`. Every command supports `--json` for
13
+ machine-readable output and exits non-zero on failure.
7
14
 
8
15
  Part of [QA-AI-STLC](https://github.com/Klim-101/QA-AI-STLC). See the repository root for
9
16
  license, contributing and security information.
package/dist/bin/qa.js CHANGED
@@ -3,7 +3,10 @@
3
3
  // SPDX-License-Identifier: Apache-2.0
4
4
  import { processIO } from '../cli-io.js';
5
5
  import { runCli } from '../cli.js';
6
- // The one place `process.exit` is allowed (AGENTS.md 5.4); `runCli` itself only returns a code.
7
- const exitCode = await runCli(process.argv.slice(2), { io: processIO });
8
- process.exit(exitCode);
6
+ // `runCli` itself only returns a code; setting `process.exitCode` (not calling `process.exit()`)
7
+ // lets Node drain the event loop naturally before exiting. A forced `process.exit()` right after
8
+ // a `fetch()` call (`qa doctor`'s reachability check) crashes on Windows with a libuv assertion
9
+ // ("UV_HANDLE_CLOSING") because undici's keep-alive socket handle has not finished closing yet —
10
+ // found running `qa doctor` against a real environment (P1-16).
11
+ process.exitCode = await runCli(process.argv.slice(2), { io: processIO });
9
12
  //# sourceMappingURL=qa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qa.js","sourceRoot":"","sources":["../../src/bin/qa.ts"],"names":[],"mappings":";AACA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,gGAAgG;AAChG,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;AACxE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"qa.js","sourceRoot":"","sources":["../../src/bin/qa.ts"],"names":[],"mappings":";AACA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,iGAAiG;AACjG,iGAAiG;AACjG,gGAAgG;AAChG,iGAAiG;AACjG,gEAAgE;AAChE,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
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"}
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;AAc9F,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;AAgBF;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,YAAY,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BvG"}
package/dist/cli.js CHANGED
@@ -3,6 +3,8 @@
3
3
  import { parseArgs } from 'node:util';
4
4
  import { QaError } from '@qa-ai-stlc/core';
5
5
  import { createCommandContext } from './command-context.js';
6
+ import { runConfigAddEnvironment, runConfigAddIdentity, } from './commands/config-add.js';
7
+ import { runConfigSet } from './commands/config-set.js';
6
8
  import { runDoctor } from './commands/doctor.js';
7
9
  import { runExplore } from './commands/explore.js';
8
10
  import { runInit } from './commands/init.js';
@@ -11,9 +13,11 @@ import { readPackageVersion } from './package-version.js';
11
13
  const USAGE = `Usage: qa <command> [options]
12
14
 
13
15
  Commands:
14
- init Create the .qa/ store and a starting config.yaml
15
- doctor Check Node, browsers, identities and environment reachability
16
- explore Build the selector registry: crawl, static source analysis, pick mode, --verify
16
+ init Create the .qa/ store and run the testing scope survey
17
+ doctor Check Node, browsers, identities and environment reachability
18
+ explore Build the selector registry: crawl, static source analysis, pick mode, --verify
19
+ config set Change one testing.<type> scope decision after init
20
+ config add Add an environment or identity: "config add environment <name> ..." or "config add identity <name> ..."
17
21
 
18
22
  Global options:
19
23
  --json Print machine-readable JSON instead of human text
@@ -43,6 +47,8 @@ export async function runCli(argv, dependencies) {
43
47
  return await dispatchDoctor(rest, dependencies);
44
48
  case 'explore':
45
49
  return await dispatchExplore(rest, dependencies);
50
+ case 'config':
51
+ return await dispatchConfig(rest, dependencies);
46
52
  default:
47
53
  io.stderr(`Unknown command "${command}".\n\n${USAGE}`);
48
54
  return EXIT_USAGE;
@@ -77,10 +83,28 @@ function parseCommandArgs(rest, options) {
77
83
  const { values } = parseArgs({ args: [...rest], options, allowPositionals: false, strict: true });
78
84
  return values;
79
85
  }
86
+ function parseTestingScopeFlag(value, flag) {
87
+ if (value === undefined) {
88
+ return undefined;
89
+ }
90
+ if (value !== 'in-scope' && value !== 'out-of-scope' && value !== 'undecided') {
91
+ throw new QaError('INIT_OPTION_INVALID', `"${value}" is not valid for ${flag}`, {
92
+ remediation: 'Use one of: in-scope, out-of-scope, undecided.',
93
+ });
94
+ }
95
+ return value;
96
+ }
80
97
  async function dispatchInit(rest, dependencies) {
81
98
  const values = parseCommandArgs(rest, {
82
99
  json: { type: 'boolean', default: false },
83
100
  force: { type: 'boolean', default: false },
101
+ 'defer-scope': { type: 'boolean', default: false },
102
+ e2e: { type: 'string' },
103
+ api: { type: 'string' },
104
+ a11y: { type: 'string' },
105
+ security: { type: 'string' },
106
+ 'source-path': { type: 'string' },
107
+ 'api-source': { type: 'string' },
84
108
  });
85
109
  const json = values.json === true;
86
110
  const context = createCommandContext({
@@ -88,10 +112,145 @@ async function dispatchInit(rest, dependencies) {
88
112
  projectRoot: dependencies.projectRoot ?? process.cwd(),
89
113
  json,
90
114
  });
91
- const result = await runInit(context, { force: values.force === true });
115
+ const e2e = parseTestingScopeFlag(typeof values.e2e === 'string' ? values.e2e : undefined, '--e2e');
116
+ const api = parseTestingScopeFlag(typeof values.api === 'string' ? values.api : undefined, '--api');
117
+ const a11y = parseTestingScopeFlag(typeof values.a11y === 'string' ? values.a11y : undefined, '--a11y');
118
+ const security = parseTestingScopeFlag(typeof values.security === 'string' ? values.security : undefined, '--security');
119
+ const testing = {
120
+ ...(e2e !== undefined ? { e2e } : {}),
121
+ ...(api !== undefined ? { api } : {}),
122
+ ...(a11y !== undefined ? { a11y } : {}),
123
+ ...(security !== undefined ? { security } : {}),
124
+ };
125
+ const result = await runInit(context, {
126
+ force: values.force === true,
127
+ deferScope: values['defer-scope'] === true,
128
+ testing,
129
+ ...(typeof values['source-path'] === 'string' ? { sourcePath: values['source-path'] } : {}),
130
+ ...(typeof values['api-source'] === 'string' ? { apiSource: values['api-source'] } : {}),
131
+ });
92
132
  printResult(context.io, json, 'init', result, formatInitResult(result));
93
133
  return EXIT_SUCCESS;
94
134
  }
135
+ async function dispatchConfig(rest, dependencies) {
136
+ const [subcommand, ...subRest] = rest;
137
+ if (subcommand === 'set') {
138
+ return await dispatchConfigSet(subRest, dependencies);
139
+ }
140
+ if (subcommand === 'add') {
141
+ return await dispatchConfigAdd(subRest, dependencies);
142
+ }
143
+ dependencies.io.stderr(`Unknown "qa config" subcommand "${subcommand ?? ''}".\n\n${USAGE}`);
144
+ return EXIT_USAGE;
145
+ }
146
+ async function dispatchConfigSet(rest, dependencies) {
147
+ const { values, positionals } = parseArgs({
148
+ args: rest,
149
+ options: { json: { type: 'boolean', default: false } },
150
+ allowPositionals: true,
151
+ strict: true,
152
+ });
153
+ const [key, value] = positionals;
154
+ if (key === undefined || value === undefined) {
155
+ throw new QaError('CONFIG_SET_USAGE', 'Usage: qa config set <key> <value>', {
156
+ remediation: 'Example: qa config set testing.api in-scope',
157
+ });
158
+ }
159
+ const json = values.json;
160
+ const context = createCommandContext({
161
+ ...dependencies,
162
+ projectRoot: dependencies.projectRoot ?? process.cwd(),
163
+ json,
164
+ });
165
+ const result = await runConfigSet(context, { key, value });
166
+ printResult(context.io, json, 'config-set', result, formatConfigSetResult(result));
167
+ return EXIT_SUCCESS;
168
+ }
169
+ async function dispatchConfigAdd(rest, dependencies) {
170
+ const [target, ...targetRest] = rest;
171
+ if (target === 'environment') {
172
+ return await dispatchConfigAddEnvironment(targetRest, dependencies);
173
+ }
174
+ if (target === 'identity') {
175
+ return await dispatchConfigAddIdentity(targetRest, dependencies);
176
+ }
177
+ dependencies.io.stderr(`Unknown "qa config add" target "${target ?? ''}".\n\n${USAGE}`);
178
+ return EXIT_USAGE;
179
+ }
180
+ async function dispatchConfigAddEnvironment(rest, dependencies) {
181
+ const { values, positionals } = parseArgs({
182
+ args: rest,
183
+ options: {
184
+ json: { type: 'boolean', default: false },
185
+ 'base-url': { type: 'string' },
186
+ allowlist: { type: 'string' },
187
+ force: { type: 'boolean', default: false },
188
+ },
189
+ allowPositionals: true,
190
+ strict: true,
191
+ });
192
+ const [name] = positionals;
193
+ if (name === undefined || typeof values['base-url'] !== 'string' || typeof values.allowlist !== 'string') {
194
+ throw new QaError('CONFIG_ADD_USAGE', 'Usage: qa config add environment <name> --base-url <url> --allowlist <a,b,c>', {
195
+ remediation: 'Example: qa config add environment staging --base-url https://staging.example.com --allowlist staging.example.com',
196
+ });
197
+ }
198
+ const json = values.json;
199
+ const context = createCommandContext({
200
+ ...dependencies,
201
+ projectRoot: dependencies.projectRoot ?? process.cwd(),
202
+ json,
203
+ });
204
+ const allowlist = values.allowlist
205
+ .split(',')
206
+ .map((entry) => entry.trim())
207
+ .filter((entry) => entry.length > 0);
208
+ const result = await runConfigAddEnvironment(context, {
209
+ name,
210
+ baseUrl: values['base-url'],
211
+ allowlist,
212
+ force: values.force,
213
+ });
214
+ printResult(context.io, json, 'config-add-environment', result, formatConfigAddEnvironmentResult(result));
215
+ return EXIT_SUCCESS;
216
+ }
217
+ async function dispatchConfigAddIdentity(rest, dependencies) {
218
+ const { values, positionals } = parseArgs({
219
+ args: rest,
220
+ options: {
221
+ json: { type: 'boolean', default: false },
222
+ auth: { type: 'string' },
223
+ secret: { type: 'string' },
224
+ 'login-url': { type: 'string' },
225
+ username: { type: 'string' },
226
+ force: { type: 'boolean', default: false },
227
+ },
228
+ allowPositionals: true,
229
+ strict: true,
230
+ });
231
+ const [name] = positionals;
232
+ if (name === undefined || typeof values.auth !== 'string' || typeof values.secret !== 'string') {
233
+ throw new QaError('CONFIG_ADD_USAGE', 'Usage: qa config add identity <name> --auth <cdp-attach|storage-state> --secret <QA_...>', {
234
+ remediation: 'Example: qa config add identity admin --auth storage-state --secret QA_ADMIN_PASSWORD --login-url https://staging.example.com/login --username admin@example.com',
235
+ });
236
+ }
237
+ const json = values.json;
238
+ const context = createCommandContext({
239
+ ...dependencies,
240
+ projectRoot: dependencies.projectRoot ?? process.cwd(),
241
+ json,
242
+ });
243
+ const result = await runConfigAddIdentity(context, {
244
+ name,
245
+ auth: values.auth,
246
+ secret: values.secret,
247
+ ...(typeof values['login-url'] === 'string' ? { loginUrl: values['login-url'] } : {}),
248
+ ...(typeof values.username === 'string' ? { username: values.username } : {}),
249
+ force: values.force,
250
+ });
251
+ printResult(context.io, json, 'config-add-identity', result, formatConfigAddIdentityResult(result));
252
+ return EXIT_SUCCESS;
253
+ }
95
254
  async function dispatchDoctor(rest, dependencies) {
96
255
  const values = parseCommandArgs(rest, {
97
256
  json: { type: 'boolean', default: false },
@@ -162,6 +321,17 @@ function formatInitResult(result) {
162
321
  }
163
322
  return [`Initialized ${result.qaDir}`, ...result.created.map((file) => ` wrote ${file}`)];
164
323
  }
324
+ function formatConfigSetResult(result) {
325
+ return [`Set ${result.key} = ${result.value}`];
326
+ }
327
+ function formatConfigAddEnvironmentResult(result) {
328
+ return [
329
+ `Added environment "${result.name}": ${result.environment.baseUrl} (allowlist: ${result.environment.allowlist.join(', ')})`,
330
+ ];
331
+ }
332
+ function formatConfigAddIdentityResult(result) {
333
+ return [`Added identity "${result.name}": auth=${result.identity.auth}, secret=${result.identity.secret}`];
334
+ }
165
335
  function formatDoctorReport(report) {
166
336
  return report.checks.map((check) => {
167
337
  const marker = check.status === 'pass' ? 'PASS' : 'FAIL';
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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"}
@@ -0,0 +1,39 @@
1
+ import { type EnvironmentConfig, type IdentityConfig } from '@qa-ai-stlc/schemas';
2
+ import type { CommandContext } from '../command-context.js';
3
+ export interface ConfigAddEnvironmentOptions {
4
+ readonly name: string;
5
+ readonly baseUrl: string;
6
+ readonly allowlist: readonly string[];
7
+ readonly force?: boolean;
8
+ }
9
+ export interface ConfigAddEnvironmentResult {
10
+ readonly name: string;
11
+ readonly environment: EnvironmentConfig;
12
+ }
13
+ export interface ConfigAddIdentityOptions {
14
+ readonly name: string;
15
+ readonly auth: string;
16
+ readonly secret: string;
17
+ readonly loginUrl?: string;
18
+ readonly username?: string;
19
+ readonly force?: boolean;
20
+ }
21
+ export interface ConfigAddIdentityResult {
22
+ readonly name: string;
23
+ readonly identity: IdentityConfig;
24
+ }
25
+ /**
26
+ * `qa config add environment <name> --base-url <url> --allowlist <a,b,c>` (P1-20): adds one
27
+ * environment to `config.yaml` without hand-editing YAML. Validates against
28
+ * `EnvironmentConfigSchema` before writing anything, and edits the parsed document in place
29
+ * (same technique as `qa config set`) so existing comments and formatting survive.
30
+ */
31
+ export declare function runConfigAddEnvironment(context: CommandContext, options: ConfigAddEnvironmentOptions): Promise<ConfigAddEnvironmentResult>;
32
+ /**
33
+ * `qa config add identity <name> --auth <cdp-attach|storage-state> --secret <QA_...> [--login-url
34
+ * <url>] [--username <user>]` (P1-20): same technique as `runConfigAddEnvironment`, validated
35
+ * against `IdentityConfigSchema` — which itself requires `loginUrl`/`username` when
36
+ * `auth: storage-state` — before writing.
37
+ */
38
+ export declare function runConfigAddIdentity(context: CommandContext, options: ConfigAddIdentityOptions): Promise<ConfigAddIdentityResult>;
39
+ //# sourceMappingURL=config-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-add.d.ts","sourceRoot":"","sources":["../../src/commands/config-add.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC;AAWD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CAqCrC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CAmClC"}
@@ -0,0 +1,88 @@
1
+ // Copyright The QA-AI-STLC Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { QaError, QaStore, loadConfig } from '@qa-ai-stlc/core';
4
+ import { EnvironmentConfigSchema, IdentityConfigSchema, } from '@qa-ai-stlc/schemas';
5
+ import { parseDocument } from 'yaml';
6
+ import { z } from 'zod';
7
+ function requireName(name) {
8
+ if (name.trim().length === 0) {
9
+ throw new QaError('CONFIG_ADD_NAME_INVALID', 'A name is required', {
10
+ remediation: 'Pass a non-empty name, for example "staging" or "admin".',
11
+ });
12
+ }
13
+ return name;
14
+ }
15
+ /**
16
+ * `qa config add environment <name> --base-url <url> --allowlist <a,b,c>` (P1-20): adds one
17
+ * environment to `config.yaml` without hand-editing YAML. Validates against
18
+ * `EnvironmentConfigSchema` before writing anything, and edits the parsed document in place
19
+ * (same technique as `qa config set`) so existing comments and formatting survive.
20
+ */
21
+ export async function runConfigAddEnvironment(context, options) {
22
+ const name = requireName(options.name);
23
+ const parsed = EnvironmentConfigSchema.safeParse({
24
+ baseUrl: options.baseUrl,
25
+ allowlist: options.allowlist,
26
+ });
27
+ if (!parsed.success) {
28
+ throw new QaError('CONFIG_ADD_VALUE_INVALID', `The environment is not valid:\n${z.prettifyError(parsed.error)}`, {
29
+ remediation: 'Provide a non-empty --base-url and at least one --allowlist entry.',
30
+ cause: parsed.error,
31
+ });
32
+ }
33
+ const store = new QaStore({ projectRoot: context.projectRoot, fs: context.fs });
34
+ // Throws a coded QaError (CONFIG_MISSING/CONFIG_MALFORMED/CONFIG_INVALID) if there is nothing
35
+ // valid to edit yet, rather than this command producing its own, differently-worded one.
36
+ const config = await loadConfig(store);
37
+ if (options.force !== true && name in config.environments) {
38
+ throw new QaError('CONFIG_ADD_NAME_EXISTS', `Environment "${name}" already exists`, {
39
+ remediation: 'Choose a different name, or pass --force to overwrite it.',
40
+ });
41
+ }
42
+ // `parsed.data` already satisfies EnvironmentConfigSchema, the same schema ConfigSchema embeds
43
+ // for every `environments` entry, and every other field in the loaded document already passed
44
+ // ConfigSchema in `loadConfig` above — so, unlike `qa config set` (whose testing/api fields
45
+ // interact through a cross-field refine), adding this entry cannot leave the document invalid;
46
+ // there is no further validation step here.
47
+ const raw = await store.readText('config.yaml');
48
+ const document = parseDocument(raw);
49
+ document.setIn(['environments', name], parsed.data);
50
+ await store.writeText('config.yaml', document.toString());
51
+ return { name, environment: parsed.data };
52
+ }
53
+ /**
54
+ * `qa config add identity <name> --auth <cdp-attach|storage-state> --secret <QA_...> [--login-url
55
+ * <url>] [--username <user>]` (P1-20): same technique as `runConfigAddEnvironment`, validated
56
+ * against `IdentityConfigSchema` — which itself requires `loginUrl`/`username` when
57
+ * `auth: storage-state` — before writing.
58
+ */
59
+ export async function runConfigAddIdentity(context, options) {
60
+ const name = requireName(options.name);
61
+ const parsed = IdentityConfigSchema.safeParse({
62
+ auth: options.auth,
63
+ secret: options.secret,
64
+ ...(options.loginUrl !== undefined ? { loginUrl: options.loginUrl } : {}),
65
+ ...(options.username !== undefined ? { username: options.username } : {}),
66
+ });
67
+ if (!parsed.success) {
68
+ throw new QaError('CONFIG_ADD_VALUE_INVALID', `The identity is not valid:\n${z.prettifyError(parsed.error)}`, {
69
+ remediation: 'Provide --auth (cdp-attach or storage-state), --secret (a QA_-prefixed environment variable name), and, for storage-state, --login-url and --username.',
70
+ cause: parsed.error,
71
+ });
72
+ }
73
+ const store = new QaStore({ projectRoot: context.projectRoot, fs: context.fs });
74
+ const config = await loadConfig(store);
75
+ if (options.force !== true && name in config.identities) {
76
+ throw new QaError('CONFIG_ADD_NAME_EXISTS', `Identity "${name}" already exists`, {
77
+ remediation: 'Choose a different name, or pass --force to overwrite it.',
78
+ });
79
+ }
80
+ // Same reasoning as runConfigAddEnvironment above: parsed.data already satisfies
81
+ // IdentityConfigSchema, so re-validating the whole document cannot fail.
82
+ const raw = await store.readText('config.yaml');
83
+ const document = parseDocument(raw);
84
+ document.setIn(['identities', name], parsed.data);
85
+ await store.writeText('config.yaml', document.toString());
86
+ return { name, identity: parsed.data };
87
+ }
88
+ //# sourceMappingURL=config-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-add.js","sourceRoot":"","sources":["../../src/commands/config-add.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GAGrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA6BxB,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,OAAO,CAAC,yBAAyB,EAAE,oBAAoB,EAAE;YACjE,WAAW,EAAE,0DAA0D;SACxE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAuB,EACvB,OAAoC;IAEpC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,CAAC;QAC/C,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,OAAO,CACf,0BAA0B,EAC1B,kCAAkC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjE;YACE,WAAW,EAAE,oEAAoE;YACjF,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,8FAA8F;IAC9F,yFAAyF;IACzF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QAC1D,MAAM,IAAI,OAAO,CAAC,wBAAwB,EAAE,gBAAgB,IAAI,kBAAkB,EAAE;YAClF,WAAW,EAAE,2DAA2D;SACzE,CAAC,CAAC;IACL,CAAC;IAED,+FAA+F;IAC/F,8FAA8F;IAC9F,4FAA4F;IAC5F,+FAA+F;IAC/F,4CAA4C;IAC5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAuB,EACvB,OAAiC;IAEjC,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC;QAC5C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,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,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,OAAO,CACf,0BAA0B,EAC1B,+BAA+B,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAC9D;YACE,WAAW,EACT,wJAAwJ;YAC1J,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACxD,MAAM,IAAI,OAAO,CAAC,wBAAwB,EAAE,aAAa,IAAI,kBAAkB,EAAE;YAC/E,WAAW,EAAE,2DAA2D;SACzE,CAAC,CAAC;IACL,CAAC;IAED,iFAAiF;IACjF,yEAAyE;IACzE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { CommandContext } from '../command-context.js';
2
+ export interface ConfigSetOptions {
3
+ readonly key: string;
4
+ readonly value: string;
5
+ }
6
+ export interface ConfigSetResult {
7
+ readonly key: string;
8
+ readonly value: string;
9
+ }
10
+ /**
11
+ * `qa config set testing.<type> <in-scope|out-of-scope|undecided>` (development plan section
12
+ * 2.7): changes one testing type's scope decision after `qa init`'s survey. Reopening the gates
13
+ * that decision affects is left to the state machine (P2-01), which does not exist yet; this
14
+ * command only changes and re-validates `config.yaml`. Only `testing.<type>` keys are supported
15
+ * today; anything else is a coded error naming what is supported instead of a silent no-op.
16
+ * Preserves the rest of `config.yaml` — including comments and formatting — by editing the parsed
17
+ * YAML document in place rather than re-rendering it from scratch.
18
+ */
19
+ export declare function runConfigSet(context: CommandContext, options: ConfigSetOptions): Promise<ConfigSetResult>;
20
+ //# sourceMappingURL=config-set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-set.d.ts","sourceRoot":"","sources":["../../src/commands/config-set.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAID;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CA0C1B"}
@@ -0,0 +1,47 @@
1
+ // Copyright The QA-AI-STLC Authors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { QaError, QaStore, loadConfig } from '@qa-ai-stlc/core';
4
+ import { ConfigSchema, TestingScopeDecisionSchema } from '@qa-ai-stlc/schemas';
5
+ import { parseDocument } from 'yaml';
6
+ import { z } from 'zod';
7
+ const TESTING_KEY = /^testing\.(e2e|api|a11y|security)$/;
8
+ /**
9
+ * `qa config set testing.<type> <in-scope|out-of-scope|undecided>` (development plan section
10
+ * 2.7): changes one testing type's scope decision after `qa init`'s survey. Reopening the gates
11
+ * that decision affects is left to the state machine (P2-01), which does not exist yet; this
12
+ * command only changes and re-validates `config.yaml`. Only `testing.<type>` keys are supported
13
+ * today; anything else is a coded error naming what is supported instead of a silent no-op.
14
+ * Preserves the rest of `config.yaml` — including comments and formatting — by editing the parsed
15
+ * YAML document in place rather than re-rendering it from scratch.
16
+ */
17
+ export async function runConfigSet(context, options) {
18
+ const keyMatch = TESTING_KEY.exec(options.key);
19
+ if (keyMatch === null) {
20
+ throw new QaError('CONFIG_SET_KEY_UNSUPPORTED', `"${options.key}" is not a supported config key`, {
21
+ remediation: 'Use one of: testing.e2e, testing.api, testing.a11y, testing.security.',
22
+ });
23
+ }
24
+ // The capturing group is not inside an alternation, so it always participates once the pattern
25
+ // matches at all; the cast documents that instead of a defensive, untestable branch.
26
+ const type = keyMatch[1];
27
+ const decision = TestingScopeDecisionSchema.safeParse(options.value);
28
+ if (!decision.success) {
29
+ throw new QaError('CONFIG_SET_VALUE_INVALID', `"${options.value}" is not a valid testing scope decision`, {
30
+ remediation: 'Use one of: in-scope, out-of-scope, undecided.',
31
+ });
32
+ }
33
+ const store = new QaStore({ projectRoot: context.projectRoot, fs: context.fs });
34
+ // Throws a coded QaError (CONFIG_MISSING/CONFIG_MALFORMED/CONFIG_INVALID) if there is nothing
35
+ // valid to edit yet, rather than this command producing its own, differently-worded one.
36
+ await loadConfig(store);
37
+ const raw = await store.readText('config.yaml');
38
+ const document = parseDocument(raw);
39
+ document.setIn(['testing', type], decision.data);
40
+ const updated = ConfigSchema.safeParse(document.toJS());
41
+ if (!updated.success) {
42
+ throw new QaError('CONFIG_SET_RESULT_INVALID', `Setting testing.${type} to "${decision.data}" would leave config.yaml invalid:\n${z.prettifyError(updated.error)}`, { remediation: 'Fix the reported fields, or set a different value.', cause: updated.error });
43
+ }
44
+ await store.writeText('config.yaml', document.toString());
45
+ return { key: options.key, value: decision.data };
46
+ }
47
+ //# sourceMappingURL=config-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-set.js","sourceRoot":"","sources":["../../src/commands/config-set.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAqB,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,MAAM,WAAW,GAAG,oCAAoC,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAuB,EACvB,OAAyB;IAEzB,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,OAAO,CAAC,4BAA4B,EAAE,IAAI,OAAO,CAAC,GAAG,iCAAiC,EAAE;YAChG,WAAW,EAAE,uEAAuE;SACrF,CAAC,CAAC;IACL,CAAC;IACD,+FAA+F;IAC/F,qFAAqF;IACrF,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAuB,CAAC;IAE/C,MAAM,QAAQ,GAAG,0BAA0B,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACrE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,OAAO,CACf,0BAA0B,EAC1B,IAAI,OAAO,CAAC,KAAK,yCAAyC,EAC1D;YACE,WAAW,EAAE,gDAAgD;SAC9D,CACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,8FAA8F;IAC9F,yFAAyF;IACzF,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;IAExB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,OAAO,CACf,2BAA2B,EAC3B,mBAAmB,IAAI,QAAQ,QAAQ,CAAC,IAAI,uCAAuC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EACnH,EAAE,WAAW,EAAE,oDAAoD,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1D,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AACpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,EAUL,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC/C;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAe3G"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,EAYL,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC/C;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAe3G"}
@@ -1,6 +1,6 @@
1
1
  // Copyright The QA-AI-STLC Authors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { QaError, QaStore, SUPPORTED_BROWSERS, checkBaseUrlReachable, checkBrowserInstalled, checkIdentitiesPresent, checkNodeVersion, installBrowsers, loadConfig, } from '@qa-ai-stlc/core';
3
+ import { QaError, QaStore, SUPPORTED_BROWSERS, checkApiContractReadable, checkBaseUrlReachable, checkBrowserInstalled, checkIdentitiesPresent, checkNodeVersion, checkSourcePathReadable, installBrowsers, loadConfig, } from '@qa-ai-stlc/core';
4
4
  /**
5
5
  * `qa doctor`: Node version, browser binaries, and, once a `config.yaml` exists, every
6
6
  * identity's secret and every environment's reachability (ADR-004). `--fix` installs missing
@@ -58,6 +58,10 @@ async function runConfigChecks(context, store) {
58
58
  const result = await checkBaseUrlReachable(environment.baseUrl, { httpClient: context.httpClient });
59
59
  return { ...result, name: `environment:${name}` };
60
60
  }));
61
- return [...identityChecks, ...environmentChecks];
61
+ const sourcePathChecks = await checkSourcePathReadable(context.fs, context.projectRoot, config.source);
62
+ const apiContractChecks = await checkApiContractReadable(context.fs, context.projectRoot, config.api, {
63
+ httpClient: context.httpClient,
64
+ });
65
+ return [...identityChecks, ...environmentChecks, ...sourcePathChecks, ...apiContractChecks];
62
66
  }
63
67
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,18 @@
1
+ import type { TestingScopeDecision } from '@qa-ai-stlc/schemas';
1
2
  import type { CommandContext } from '../command-context.js';
3
+ export interface TestingScopeAnswers {
4
+ readonly e2e?: TestingScopeDecision;
5
+ readonly api?: TestingScopeDecision;
6
+ readonly a11y?: TestingScopeDecision;
7
+ readonly security?: TestingScopeDecision;
8
+ }
2
9
  export interface InitOptions {
3
10
  readonly force?: boolean;
11
+ /** Skips the "every type answered" gate below, leaving an unanswered type `undecided`. */
12
+ readonly deferScope?: boolean;
13
+ readonly testing?: TestingScopeAnswers;
14
+ readonly sourcePath?: string;
15
+ readonly apiSource?: string;
4
16
  }
5
17
  export interface InitResult {
6
18
  readonly qaDir: string;
@@ -8,10 +20,13 @@ export interface InitResult {
8
20
  readonly alreadyInitialized: boolean;
9
21
  }
10
22
  /**
11
- * `qa init`: creates the documented `.qa/` layout (development plan section 3.2), a starting
12
- * `config.yaml` with every testing type `undecided`, and a `.gitignore` for the runtime-only
13
- * subdirectories. Never overwrites an existing `config.yaml` unless `force` is set, so a second
14
- * run is safe.
23
+ * `qa init`: creates the documented `.qa/` layout (development plan section 3.2), then runs the
24
+ * testing scope survey (section 2.7, P1-18) — Web E2E, API, accessibility and security are
25
+ * answered independently and written to `config.yaml`'s `testing` block. A type left `undecided`
26
+ * blocks `qa init` from finishing unless `deferScope` is set, so a project never silently starts
27
+ * with a scope nobody actually decided. Never overwrites an existing `config.yaml` unless `force`
28
+ * is set, so a second run is safe; the scope gate only applies when a `config.yaml` is actually
29
+ * about to be written.
15
30
  */
16
31
  export declare function runInit(context: CommandContext, options?: InitOptions): Promise<InitResult>;
17
32
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBrG"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG5D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;CACtC;AA6BD;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CA8CrG"}
@@ -1,22 +1,62 @@
1
1
  // Copyright The QA-AI-STLC Authors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
- import { QaStore } from '@qa-ai-stlc/core';
4
- import { CONFIG_TEMPLATE, QA_GITIGNORE } from '../config-template.js';
3
+ import { QaError, QaStore } from '@qa-ai-stlc/core';
4
+ import { QA_GITIGNORE, renderConfigYaml } from '../config-template.js';
5
+ function resolveTestingScope(answers, deferScope) {
6
+ const testing = {
7
+ e2e: answers.e2e ?? 'undecided',
8
+ api: answers.api ?? 'undecided',
9
+ a11y: answers.a11y ?? 'undecided',
10
+ security: answers.security ?? 'undecided',
11
+ };
12
+ if (deferScope) {
13
+ return testing;
14
+ }
15
+ const undecidedTypes = Object.keys(testing).filter((type) => testing[type] === 'undecided');
16
+ if (undecidedTypes.length > 0) {
17
+ throw new QaError('INIT_SCOPE_UNDECIDED', `Testing scope left undecided for: ${undecidedTypes.join(', ')}`, {
18
+ remediation: 'Answer --e2e, --api, --a11y and --security (each "in-scope" or "out-of-scope"), or pass --defer-scope to leave them undecided for now.',
19
+ });
20
+ }
21
+ return testing;
22
+ }
5
23
  /**
6
- * `qa init`: creates the documented `.qa/` layout (development plan section 3.2), a starting
7
- * `config.yaml` with every testing type `undecided`, and a `.gitignore` for the runtime-only
8
- * subdirectories. Never overwrites an existing `config.yaml` unless `force` is set, so a second
9
- * run is safe.
24
+ * `qa init`: creates the documented `.qa/` layout (development plan section 3.2), then runs the
25
+ * testing scope survey (section 2.7, P1-18) — Web E2E, API, accessibility and security are
26
+ * answered independently and written to `config.yaml`'s `testing` block. A type left `undecided`
27
+ * blocks `qa init` from finishing unless `deferScope` is set, so a project never silently starts
28
+ * with a scope nobody actually decided. Never overwrites an existing `config.yaml` unless `force`
29
+ * is set, so a second run is safe; the scope gate only applies when a `config.yaml` is actually
30
+ * about to be written.
10
31
  */
11
32
  export async function runInit(context, options = {}) {
12
33
  const store = new QaStore({ projectRoot: context.projectRoot, fs: context.fs });
13
34
  const configExisted = await store.pathExists('config.yaml');
14
- await store.ensureLayout();
35
+ const willWriteConfig = !configExisted || options.force === true;
15
36
  const created = [];
16
- if (!configExisted || options.force === true) {
17
- await store.writeText('config.yaml', CONFIG_TEMPLATE);
37
+ if (willWriteConfig) {
38
+ const testing = resolveTestingScope(options.testing ?? {}, options.deferScope === true);
39
+ if (testing.api === 'in-scope' && options.apiSource === undefined) {
40
+ throw new QaError('INIT_API_SOURCE_MISSING', '"api" testing is in-scope but no --api-source was given', {
41
+ remediation: 'Pass --api-source <file, URL, "discover" or "synthesize">.',
42
+ });
43
+ }
44
+ // `testing` is already a valid TestingScope, `api` was already checked above against
45
+ // ConfigSchema's one refine (api required when testing.api is in-scope), and sourcePath/
46
+ // apiSource are safely quoted by renderConfigYaml — nothing left that could make the
47
+ // rendered file fail ConfigSchema, so there is no further validation step here.
48
+ const configYaml = renderConfigYaml({
49
+ testing,
50
+ ...(options.sourcePath !== undefined ? { sourcePath: options.sourcePath } : {}),
51
+ ...(options.apiSource !== undefined ? { apiSource: options.apiSource } : {}),
52
+ });
53
+ await store.ensureLayout();
54
+ await store.writeText('config.yaml', configYaml);
18
55
  created.push('config.yaml');
19
56
  }
57
+ else {
58
+ await store.ensureLayout();
59
+ }
20
60
  const gitignoreExisted = await store.pathExists('.gitignore');
21
61
  if (!gitignoreExisted || options.force === true) {
22
62
  await store.writeText('.gitignore', QA_GITIGNORE);
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAYtE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB,EAAE,UAAuB,EAAE;IAC9E,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,KAAK,CAAC,YAAY,EAAE,CAAC;IAE3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,aAAa,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,CAAC,SAAS,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAC9D,IAAI,CAAC,gBAAgB,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,KAAK,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO;QACP,kBAAkB,EAAE,aAAa,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI;KAC5D,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,17 @@
1
- export declare const CONFIG_TEMPLATE: string;
1
+ import type { TestingScope } from '@qa-ai-stlc/schemas';
2
+ export interface RenderConfigYamlOptions {
3
+ readonly testing: TestingScope;
4
+ /** A local checkout of the application under test, for code-assisted checks and RCA context. */
5
+ readonly sourcePath?: string;
6
+ /** The OpenAPI contract source: a file/URL, or "discover"/"synthesize". Required when `testing.api` is `"in-scope"`. */
7
+ readonly apiSource?: string;
8
+ }
9
+ /**
10
+ * Renders `config.yaml` for `qa init` (development plan section 3.3): the testing scope survey's
11
+ * answers (P1-18), plus a safe starting point for everything else — `environments`/`identities`
12
+ * start empty so the file validates against `ConfigSchema` before the operator has configured
13
+ * anything.
14
+ */
15
+ export declare function renderConfigYaml(options: RenderConfigYamlOptions): string;
2
16
  export declare const QA_GITIGNORE = "# Generated by \"qa init\".\n/runs/\n/evidence/\n/auth/\n";
3
17
  //# sourceMappingURL=config-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-template.d.ts","sourceRoot":"","sources":["../src/config-template.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,QA2B3B,CAAC;AAIF,eAAO,MAAM,YAAY,8DAIxB,CAAC"}
1
+ {"version":3,"file":"config-template.d.ts","sourceRoot":"","sources":["../src/config-template.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,gGAAgG;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wHAAwH;IACxH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAqCzE;AAID,eAAO,MAAM,YAAY,8DAIxB,CAAC"}
@@ -1,21 +1,29 @@
1
1
  // Copyright The QA-AI-STLC Authors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { SCHEMA_VERSION } from '@qa-ai-stlc/schemas';
4
- // A safe starting point every "qa init" writes: every testing type starts "undecided" (the
5
- // testing-scope survey that turns these into real decisions is P1-18), and `environments` /
6
- // `identities` start empty so the file validates against `ConfigSchema` before the operator has
7
- // configured anything (development plan section 3.2, 3.3).
8
- export const CONFIG_TEMPLATE = `# QA-AI-STLC project configuration. Generated by "qa init".
4
+ /**
5
+ * Renders `config.yaml` for `qa init` (development plan section 3.3): the testing scope survey's
6
+ * answers (P1-18), plus a safe starting point for everything else — `environments`/`identities`
7
+ * start empty so the file validates against `ConfigSchema` before the operator has configured
8
+ * anything.
9
+ */
10
+ export function renderConfigYaml(options) {
11
+ const sourceBlock = options.sourcePath === undefined ? '' : `\nsource:\n path: ${JSON.stringify(options.sourcePath)}\n`;
12
+ const apiBlock = options.apiSource === undefined
13
+ ? ''
14
+ : `\napi:\n contract: openapi\n source: ${JSON.stringify(options.apiSource)}\n`;
15
+ return `# QA-AI-STLC project configuration. Generated by "qa init".
9
16
  schemaVersion: ${String(SCHEMA_VERSION)}
10
17
 
11
18
  # Web E2E, API, accessibility and security testing are decided independently. An "undecided"
12
- # type blocks "qa scope" and every later phase until you change it here.
19
+ # type blocks "qa scope" and every later phase until you change it here, with
20
+ # "qa config set testing.<type> in-scope|out-of-scope|undecided".
13
21
  testing:
14
- e2e: undecided
15
- api: undecided
16
- a11y: undecided
17
- security: undecided
18
-
22
+ e2e: ${options.testing.e2e}
23
+ api: ${options.testing.api}
24
+ a11y: ${options.testing.a11y}
25
+ security: ${options.testing.security}
26
+ ${sourceBlock}${apiBlock}
19
27
  environments: {}
20
28
 
21
29
  identities: {}
@@ -33,6 +41,7 @@ agents:
33
41
  spokeTimeoutSeconds: 60
34
42
  retries: 1
35
43
  `;
44
+ }
36
45
  // Runtime-only subdirectories (development plan section 3.2): everything else under `.qa/` is
37
46
  // meant to be committed.
38
47
  export const QA_GITIGNORE = `# Generated by "qa init".
@@ -1 +1 @@
1
- {"version":3,"file":"config-template.js","sourceRoot":"","sources":["../src/config-template.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,2FAA2F;AAC3F,4FAA4F;AAC5F,gGAAgG;AAChG,2DAA2D;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG;iBACd,MAAM,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BtC,CAAC;AAEF,8FAA8F;AAC9F,yBAAyB;AACzB,MAAM,CAAC,MAAM,YAAY,GAAG;;;;CAI3B,CAAC"}
1
+ {"version":3,"file":"config-template.js","sourceRoot":"","sources":["../src/config-template.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,sCAAsC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAWrD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC;IAC/D,MAAM,WAAW,GACf,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;IACvG,MAAM,QAAQ,GACZ,OAAO,CAAC,SAAS,KAAK,SAAS;QAC7B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,0CAA0C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;IAEtF,OAAO;iBACQ,MAAM,CAAC,cAAc,CAAC;;;;;;SAM9B,OAAO,CAAC,OAAO,CAAC,GAAG;SACnB,OAAO,CAAC,OAAO,CAAC,GAAG;UAClB,OAAO,CAAC,OAAO,CAAC,IAAI;cAChB,OAAO,CAAC,OAAO,CAAC,QAAQ;EACpC,WAAW,GAAG,QAAQ;;;;;;;;;;;;;;;;;CAiBvB,CAAC;AACF,CAAC;AAED,8FAA8F;AAC9F,yBAAyB;AACzB,MAAM,CAAC,MAAM,YAAY,GAAG;;;;CAI3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qa-ai-stlc/cli",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
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",
@@ -31,8 +31,8 @@
31
31
  "clean": "node ../../scripts/clean-dir.mjs dist"
32
32
  },
33
33
  "dependencies": {
34
- "@qa-ai-stlc/core": "0.4.1",
35
- "@qa-ai-stlc/explorer": "0.6.0",
34
+ "@qa-ai-stlc/core": "0.5.0",
35
+ "@qa-ai-stlc/explorer": "0.6.1",
36
36
  "@qa-ai-stlc/schemas": "0.6.0",
37
37
  "yaml": "2.9.1"
38
38
  },