qualyx 0.3.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.
Files changed (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +523 -0
  3. package/dist/cli/commands/init.d.ts +6 -0
  4. package/dist/cli/commands/init.d.ts.map +1 -0
  5. package/dist/cli/commands/init.js +124 -0
  6. package/dist/cli/commands/init.js.map +1 -0
  7. package/dist/cli/commands/list.d.ts +3 -0
  8. package/dist/cli/commands/list.d.ts.map +1 -0
  9. package/dist/cli/commands/list.js +122 -0
  10. package/dist/cli/commands/list.js.map +1 -0
  11. package/dist/cli/commands/run.d.ts +12 -0
  12. package/dist/cli/commands/run.d.ts.map +1 -0
  13. package/dist/cli/commands/run.js +160 -0
  14. package/dist/cli/commands/run.js.map +1 -0
  15. package/dist/cli/commands/schedule.d.ts +19 -0
  16. package/dist/cli/commands/schedule.d.ts.map +1 -0
  17. package/dist/cli/commands/schedule.js +240 -0
  18. package/dist/cli/commands/schedule.js.map +1 -0
  19. package/dist/cli/commands/validate.d.ts +3 -0
  20. package/dist/cli/commands/validate.d.ts.map +1 -0
  21. package/dist/cli/commands/validate.js +47 -0
  22. package/dist/cli/commands/validate.js.map +1 -0
  23. package/dist/cli/index.d.ts +3 -0
  24. package/dist/cli/index.d.ts.map +1 -0
  25. package/dist/cli/index.js +194 -0
  26. package/dist/cli/index.js.map +1 -0
  27. package/dist/core/claude-runner.d.ts +23 -0
  28. package/dist/core/claude-runner.d.ts.map +1 -0
  29. package/dist/core/claude-runner.js +196 -0
  30. package/dist/core/claude-runner.js.map +1 -0
  31. package/dist/core/config-loader.d.ts +137 -0
  32. package/dist/core/config-loader.d.ts.map +1 -0
  33. package/dist/core/config-loader.js +239 -0
  34. package/dist/core/config-loader.js.map +1 -0
  35. package/dist/core/executor.d.ts +75 -0
  36. package/dist/core/executor.d.ts.map +1 -0
  37. package/dist/core/executor.js +337 -0
  38. package/dist/core/executor.js.map +1 -0
  39. package/dist/core/index.d.ts +6 -0
  40. package/dist/core/index.d.ts.map +1 -0
  41. package/dist/core/index.js +7 -0
  42. package/dist/core/index.js.map +1 -0
  43. package/dist/core/prompt-builder.d.ts +24 -0
  44. package/dist/core/prompt-builder.d.ts.map +1 -0
  45. package/dist/core/prompt-builder.js +145 -0
  46. package/dist/core/prompt-builder.js.map +1 -0
  47. package/dist/core/retry-handler.d.ts +42 -0
  48. package/dist/core/retry-handler.d.ts.map +1 -0
  49. package/dist/core/retry-handler.js +126 -0
  50. package/dist/core/retry-handler.js.map +1 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +16 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/integrations/email.d.ts +38 -0
  56. package/dist/integrations/email.d.ts.map +1 -0
  57. package/dist/integrations/email.js +216 -0
  58. package/dist/integrations/email.js.map +1 -0
  59. package/dist/integrations/index.d.ts +5 -0
  60. package/dist/integrations/index.d.ts.map +1 -0
  61. package/dist/integrations/index.js +5 -0
  62. package/dist/integrations/index.js.map +1 -0
  63. package/dist/integrations/jira.d.ts +68 -0
  64. package/dist/integrations/jira.d.ts.map +1 -0
  65. package/dist/integrations/jira.js +288 -0
  66. package/dist/integrations/jira.js.map +1 -0
  67. package/dist/integrations/slack.d.ts +66 -0
  68. package/dist/integrations/slack.d.ts.map +1 -0
  69. package/dist/integrations/slack.js +192 -0
  70. package/dist/integrations/slack.js.map +1 -0
  71. package/dist/integrations/teams.d.ts +72 -0
  72. package/dist/integrations/teams.d.ts.map +1 -0
  73. package/dist/integrations/teams.js +197 -0
  74. package/dist/integrations/teams.js.map +1 -0
  75. package/dist/reporters/console.d.ts +83 -0
  76. package/dist/reporters/console.d.ts.map +1 -0
  77. package/dist/reporters/console.js +299 -0
  78. package/dist/reporters/console.js.map +1 -0
  79. package/dist/reporters/html.d.ts +29 -0
  80. package/dist/reporters/html.d.ts.map +1 -0
  81. package/dist/reporters/html.js +105 -0
  82. package/dist/reporters/html.js.map +1 -0
  83. package/dist/storage/results.d.ts +61 -0
  84. package/dist/storage/results.d.ts.map +1 -0
  85. package/dist/storage/results.js +111 -0
  86. package/dist/storage/results.js.map +1 -0
  87. package/dist/storage/sqlite.d.ts +70 -0
  88. package/dist/storage/sqlite.d.ts.map +1 -0
  89. package/dist/storage/sqlite.js +240 -0
  90. package/dist/storage/sqlite.js.map +1 -0
  91. package/dist/types/index.d.ts +1239 -0
  92. package/dist/types/index.d.ts.map +1 -0
  93. package/dist/types/index.js +105 -0
  94. package/dist/types/index.js.map +1 -0
  95. package/package.json +75 -0
  96. package/templates/crontab.hbs +24 -0
  97. package/templates/github-schedule.yml.hbs +153 -0
  98. package/templates/prompt.md.hbs +147 -0
  99. package/templates/report.html.hbs +423 -0
  100. package/templates/slack-message.json.hbs +93 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createCli(): Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,SAAS,IAAI,OAAO,CAmNnC"}
@@ -0,0 +1,194 @@
1
+ import { Command } from 'commander';
2
+ import { runInit } from './commands/init.js';
3
+ import { runValidate } from './commands/validate.js';
4
+ import { runList } from './commands/list.js';
5
+ import { runRun } from './commands/run.js';
6
+ import { runScheduleList, runScheduleCron, runScheduleGithub } from './commands/schedule.js';
7
+ const VERSION = '0.3.0';
8
+ export function createCli() {
9
+ const program = new Command();
10
+ program
11
+ .name('qualyx')
12
+ .description('AI-powered QA automation platform using Claude Code CLI and Playwright')
13
+ .version(VERSION);
14
+ // Init command
15
+ program
16
+ .command('init')
17
+ .description('Create a starter qualyx.yml configuration file')
18
+ .option('-f, --force', 'Overwrite existing configuration file')
19
+ .option('-p, --path <path>', 'Path for the configuration file', 'qualyx.yml')
20
+ .action(async (options) => {
21
+ await runInit(options);
22
+ });
23
+ // Validate command
24
+ program
25
+ .command('validate')
26
+ .description('Validate the configuration file')
27
+ .option('-c, --config <path>', 'Path to configuration file')
28
+ .option('-s, --strict', 'Treat warnings as errors')
29
+ .action(async (options) => {
30
+ await runValidate(options.config, { strict: options.strict });
31
+ });
32
+ // List command
33
+ program
34
+ .command('list [resource]')
35
+ .description('List apps and rules from configuration')
36
+ .option('-c, --config <path>', 'Path to configuration file')
37
+ .option('-f, --format <format>', 'Output format: table or json', 'table')
38
+ .action(async (resource, options) => {
39
+ await runList(resource, options.config, { format: options.format });
40
+ });
41
+ // Run command
42
+ program
43
+ .command('run')
44
+ .description('Execute tests')
45
+ .option('-c, --config <path>', 'Path to configuration file')
46
+ .option('-a, --app <name>', 'Run tests only for specified app')
47
+ .option('-r, --rule <id>', 'Run only specified rule')
48
+ .option('-e, --environment <name>', 'Environment to run against')
49
+ .option('--dry-run', 'Preview tests without executing')
50
+ .option('--headed', 'Run browser in headed mode (visible)')
51
+ .option('-v, --verbose', 'Show detailed output')
52
+ .option('--retries <number>', 'Number of retries on failure', parseInt)
53
+ .option('--timeout <ms>', 'Timeout per test in milliseconds', parseInt)
54
+ .option('--parallel', 'Run tests in parallel')
55
+ .option('--max-parallel <number>', 'Maximum number of parallel tests', parseInt)
56
+ .option('--collect-metrics', 'Collect performance metrics during tests')
57
+ .option('--report', 'Generate HTML report')
58
+ .option('--report-dir <path>', 'Directory for HTML reports', './qualyx-reports')
59
+ .option('--no-save', 'Do not save results to history')
60
+ .action(async (options) => {
61
+ await runRun({
62
+ config: options.config,
63
+ app: options.app,
64
+ rule: options.rule,
65
+ environment: options.environment,
66
+ dryRun: options.dryRun,
67
+ headed: options.headed,
68
+ verbose: options.verbose,
69
+ retries: options.retries,
70
+ timeout: options.timeout,
71
+ parallel: options.parallel,
72
+ maxParallel: options.maxParallel,
73
+ collectMetrics: options.collectMetrics,
74
+ report: options.report,
75
+ reportDir: options.reportDir,
76
+ save: options.save,
77
+ });
78
+ });
79
+ // Schedule command
80
+ const scheduleCmd = program
81
+ .command('schedule')
82
+ .description('Manage scheduled test rules');
83
+ scheduleCmd
84
+ .command('list')
85
+ .description('List all scheduled rules')
86
+ .option('-c, --config <path>', 'Path to configuration file')
87
+ .option('-f, --format <format>', 'Output format: table or json', 'table')
88
+ .action(async (options) => {
89
+ await runScheduleList({
90
+ config: options.config,
91
+ format: options.format,
92
+ });
93
+ });
94
+ scheduleCmd
95
+ .command('cron')
96
+ .description('Generate crontab entries for scheduled rules')
97
+ .option('-c, --config <path>', 'Path to configuration file')
98
+ .option('-o, --output <path>', 'Output file path')
99
+ .option('-p, --project-path <path>', 'Project path for cron commands')
100
+ .action(async (options) => {
101
+ await runScheduleCron({
102
+ config: options.config,
103
+ output: options.output,
104
+ projectPath: options.projectPath,
105
+ });
106
+ });
107
+ scheduleCmd
108
+ .command('github')
109
+ .description('Generate GitHub Actions workflow for scheduled rules')
110
+ .option('-c, --config <path>', 'Path to configuration file')
111
+ .option('-o, --output <path>', 'Output file path')
112
+ .action(async (options) => {
113
+ await runScheduleGithub({
114
+ config: options.config,
115
+ output: options.output,
116
+ });
117
+ });
118
+ // Report command (view last report)
119
+ program
120
+ .command('report')
121
+ .description('View or regenerate the last test report')
122
+ .option('-c, --config <path>', 'Path to configuration file')
123
+ .option('-o, --output <path>', 'Output path for HTML report')
124
+ .option('--run-id <id>', 'Generate report for specific run ID')
125
+ .action(async (options) => {
126
+ const { getLatestRunResult, getRunResult } = await import('../storage/results.js');
127
+ const { generateHtmlReport } = await import('../reporters/html.js');
128
+ const { loadConfig } = await import('../core/config-loader.js');
129
+ const chalk = (await import('chalk')).default;
130
+ // Get the run result
131
+ const runResult = options.runId ? getRunResult(options.runId) : getLatestRunResult();
132
+ if (!runResult) {
133
+ console.log();
134
+ console.log(chalk.yellow(' No test runs found in history'));
135
+ console.log(chalk.gray(' Run tests first with: qualyx run'));
136
+ console.log();
137
+ return;
138
+ }
139
+ // Load config to get organization name
140
+ let orgName = 'Qualyx';
141
+ try {
142
+ const configResult = loadConfig(options.config);
143
+ orgName = configResult.config.organization.name;
144
+ }
145
+ catch {
146
+ // Use default org name
147
+ }
148
+ // Generate the report
149
+ const reportPath = generateHtmlReport(runResult, { outputDir: options.output || './qualyx-reports' }, orgName);
150
+ console.log();
151
+ console.log(chalk.green(` Report generated: ${reportPath}`));
152
+ console.log(chalk.gray(` Run ID: ${runResult.runId}`));
153
+ console.log(chalk.gray(` Date: ${new Date(runResult.startedAt).toLocaleString()}`));
154
+ console.log(chalk.gray(` Results: ${runResult.passed}/${runResult.totalTests} passed`));
155
+ console.log();
156
+ });
157
+ // History command
158
+ program
159
+ .command('history')
160
+ .description('View test run history')
161
+ .option('-l, --limit <number>', 'Number of runs to show', '10')
162
+ .option('--failed', 'Show only failed runs')
163
+ .option('-f, --format <format>', 'Output format: table or json', 'table')
164
+ .action(async (options) => {
165
+ const { getRecentRunResults, getFailedRunResults } = await import('../storage/results.js');
166
+ const chalk = (await import('chalk')).default;
167
+ const limit = parseInt(options.limit, 10);
168
+ const runs = options.failed ? getFailedRunResults(limit) : getRecentRunResults(limit);
169
+ if (runs.length === 0) {
170
+ console.log();
171
+ console.log(chalk.yellow(' No test runs found in history'));
172
+ console.log();
173
+ return;
174
+ }
175
+ if (options.format === 'json') {
176
+ console.log(JSON.stringify(runs, null, 2));
177
+ return;
178
+ }
179
+ console.log();
180
+ console.log(chalk.bold.cyan(' Test Run History'));
181
+ console.log();
182
+ for (const run of runs) {
183
+ const date = new Date(run.startedAt).toLocaleString();
184
+ const status = run.failed > 0 ? chalk.red('FAILED') : chalk.green('PASSED');
185
+ const stats = `${run.passed}/${run.totalTests} passed`;
186
+ console.log(` ${status} ${chalk.gray(date)} - ${stats}`);
187
+ console.log(chalk.gray(` ID: ${run.runId.slice(0, 8)}...`));
188
+ console.log(chalk.gray(` Environment: ${run.environment}`));
189
+ console.log();
190
+ }
191
+ });
192
+ return program;
193
+ }
194
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ClaudeRunnerOptions, ClaudeResponse, TestStatus, StepResult, ValidationResult } from '../types/index.js';
2
+ export declare class ClaudeRunnerError extends Error {
3
+ readonly exitCode?: number | undefined;
4
+ readonly stderr?: string | undefined;
5
+ constructor(message: string, exitCode?: number | undefined, stderr?: string | undefined);
6
+ }
7
+ /**
8
+ * Run Claude Code CLI with the given prompt.
9
+ */
10
+ export declare function runClaude(prompt: string, options?: Partial<ClaudeRunnerOptions>): Promise<ClaudeResponse>;
11
+ /**
12
+ * Check if Claude Code CLI is available.
13
+ */
14
+ export declare function isClaudeAvailable(): Promise<boolean>;
15
+ /**
16
+ * Get Claude Code CLI version.
17
+ */
18
+ export declare function getClaudeVersion(): Promise<string | null>;
19
+ /**
20
+ * Create a mock response for testing purposes.
21
+ */
22
+ export declare function createMockResponse(status: TestStatus, steps?: StepResult[], validations?: ValidationResult[], error?: string): ClaudeResponse;
23
+ //# sourceMappingURL=claude-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/core/claude-runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,UAAU,EACV,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,QAAQ,CAAC,EAAE,MAAM;aACjB,MAAM,CAAC,EAAE,MAAM;gBAF/B,OAAO,EAAE,MAAM,EACC,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,MAAM,CAAC,EAAE,MAAM,YAAA;CAKlC;AA6DD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAiFD;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAc1D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwB/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,KAAK,GAAE,UAAU,EAAO,EACxB,WAAW,GAAE,gBAAgB,EAAO,EACpC,KAAK,CAAC,EAAE,MAAM,GACb,cAAc,CAOhB"}
@@ -0,0 +1,196 @@
1
+ import { spawn } from 'node:child_process';
2
+ export class ClaudeRunnerError extends Error {
3
+ exitCode;
4
+ stderr;
5
+ constructor(message, exitCode, stderr) {
6
+ super(message);
7
+ this.exitCode = exitCode;
8
+ this.stderr = stderr;
9
+ this.name = 'ClaudeRunnerError';
10
+ }
11
+ }
12
+ const DEFAULT_OPTIONS = {
13
+ timeout: 60000,
14
+ headless: true,
15
+ retries: 2,
16
+ dryRun: false,
17
+ };
18
+ /**
19
+ * Parse JSON response from Claude output.
20
+ * Claude may output additional text before/after the JSON, so we need to extract it.
21
+ */
22
+ function parseClaudeResponse(output) {
23
+ // Try to find JSON in the output
24
+ const jsonMatch = output.match(/\{[\s\S]*"status"[\s\S]*\}/);
25
+ if (!jsonMatch) {
26
+ // If no valid JSON found, treat it as a failure
27
+ return {
28
+ status: 'failed',
29
+ steps: [],
30
+ validations: [],
31
+ error: `Could not parse Claude response. Raw output: ${output.slice(0, 500)}...`,
32
+ };
33
+ }
34
+ try {
35
+ const parsed = JSON.parse(jsonMatch[0]);
36
+ // Validate the response structure
37
+ const response = {
38
+ status: parsed.status === 'passed' ? 'passed' : 'failed',
39
+ steps: Array.isArray(parsed.steps) ? parsed.steps : [],
40
+ validations: Array.isArray(parsed.validations) ? parsed.validations : [],
41
+ error: parsed.error,
42
+ screenshot: parsed.screenshot,
43
+ };
44
+ return response;
45
+ }
46
+ catch (error) {
47
+ return {
48
+ status: 'failed',
49
+ steps: [],
50
+ validations: [],
51
+ error: `Failed to parse JSON response: ${error instanceof Error ? error.message : 'Unknown error'}`,
52
+ };
53
+ }
54
+ }
55
+ /**
56
+ * Build the Claude Code CLI command arguments.
57
+ */
58
+ function buildClaudeArgs() {
59
+ return [
60
+ '--print', // Non-interactive mode
61
+ '--output-format', 'text', // Use text format (we'll parse JSON from output)
62
+ '--dangerously-skip-permissions', // Skip permission prompts for automation
63
+ ];
64
+ }
65
+ /**
66
+ * Run Claude Code CLI with the given prompt.
67
+ */
68
+ export async function runClaude(prompt, options = {}) {
69
+ const opts = { ...DEFAULT_OPTIONS, ...options };
70
+ if (opts.dryRun) {
71
+ // In dry-run mode, return a mock response
72
+ return {
73
+ status: 'skipped',
74
+ steps: [],
75
+ validations: [],
76
+ error: 'Dry run - no execution performed',
77
+ };
78
+ }
79
+ const args = buildClaudeArgs();
80
+ const output = await executeClaudeProcess(args, prompt, opts.timeout);
81
+ return parseClaudeResponse(output);
82
+ }
83
+ /**
84
+ * Execute the Claude Code CLI process and capture output.
85
+ * Uses stdin to pass the prompt for better handling of long prompts.
86
+ */
87
+ async function executeClaudeProcess(args, prompt, timeout) {
88
+ return new Promise((resolve, reject) => {
89
+ let stdout = '';
90
+ let stderr = '';
91
+ let isResolved = false;
92
+ const claude = spawn('claude', args, {
93
+ stdio: ['pipe', 'pipe', 'pipe'],
94
+ env: {
95
+ ...process.env,
96
+ // Ensure Claude uses the right settings
97
+ NO_COLOR: '1', // Disable color output for easier parsing
98
+ },
99
+ });
100
+ const timeoutId = setTimeout(() => {
101
+ if (!isResolved) {
102
+ isResolved = true;
103
+ claude.kill('SIGTERM');
104
+ reject(new ClaudeRunnerError(`Claude execution timed out after ${timeout}ms`));
105
+ }
106
+ }, timeout);
107
+ // Write prompt to stdin and close it
108
+ claude.stdin.write(prompt);
109
+ claude.stdin.end();
110
+ claude.stdout.on('data', (data) => {
111
+ stdout += data.toString();
112
+ });
113
+ claude.stderr.on('data', (data) => {
114
+ stderr += data.toString();
115
+ });
116
+ claude.on('error', (error) => {
117
+ if (!isResolved) {
118
+ isResolved = true;
119
+ clearTimeout(timeoutId);
120
+ if (error.code === 'ENOENT') {
121
+ reject(new ClaudeRunnerError('Claude Code CLI not found. Please install it with: npm install -g @anthropic-ai/claude-code'));
122
+ }
123
+ else {
124
+ reject(new ClaudeRunnerError(`Failed to spawn Claude process: ${error.message}`));
125
+ }
126
+ }
127
+ });
128
+ claude.on('close', (code) => {
129
+ if (!isResolved) {
130
+ isResolved = true;
131
+ clearTimeout(timeoutId);
132
+ if (code !== 0 && !stdout) {
133
+ // Process failed without output
134
+ reject(new ClaudeRunnerError(`Claude exited with code ${code}`, code ?? undefined, stderr));
135
+ }
136
+ else {
137
+ // Process completed (may have non-zero exit but still produced output)
138
+ resolve(stdout);
139
+ }
140
+ }
141
+ });
142
+ });
143
+ }
144
+ /**
145
+ * Check if Claude Code CLI is available.
146
+ */
147
+ export async function isClaudeAvailable() {
148
+ return new Promise((resolve) => {
149
+ const claude = spawn('claude', ['--version'], {
150
+ stdio: ['pipe', 'pipe', 'pipe'],
151
+ });
152
+ claude.on('error', () => {
153
+ resolve(false);
154
+ });
155
+ claude.on('close', (code) => {
156
+ resolve(code === 0);
157
+ });
158
+ });
159
+ }
160
+ /**
161
+ * Get Claude Code CLI version.
162
+ */
163
+ export async function getClaudeVersion() {
164
+ return new Promise((resolve) => {
165
+ let stdout = '';
166
+ const claude = spawn('claude', ['--version'], {
167
+ stdio: ['pipe', 'pipe', 'pipe'],
168
+ });
169
+ claude.stdout.on('data', (data) => {
170
+ stdout += data.toString();
171
+ });
172
+ claude.on('error', () => {
173
+ resolve(null);
174
+ });
175
+ claude.on('close', (code) => {
176
+ if (code === 0) {
177
+ resolve(stdout.trim());
178
+ }
179
+ else {
180
+ resolve(null);
181
+ }
182
+ });
183
+ });
184
+ }
185
+ /**
186
+ * Create a mock response for testing purposes.
187
+ */
188
+ export function createMockResponse(status, steps = [], validations = [], error) {
189
+ return {
190
+ status,
191
+ steps,
192
+ validations,
193
+ error,
194
+ };
195
+ }
196
+ //# sourceMappingURL=claude-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-runner.js","sourceRoot":"","sources":["../../src/core/claude-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { ZodError } from 'zod';
2
+ import { type QualyxConfig } from '../types/index.js';
3
+ export declare class ConfigLoadError extends Error {
4
+ readonly filePath?: string | undefined;
5
+ readonly validationErrors?: ZodError | undefined;
6
+ constructor(message: string, filePath?: string | undefined, validationErrors?: ZodError | undefined);
7
+ }
8
+ /**
9
+ * Find the configuration file path.
10
+ * Searches for default config file names if no path is specified.
11
+ */
12
+ export declare function findConfigFile(configPath?: string): string;
13
+ export interface LoadConfigResult {
14
+ config: QualyxConfig;
15
+ filePath: string;
16
+ warnings: string[];
17
+ }
18
+ /**
19
+ * Load, parse, and validate the Qualyx configuration file.
20
+ */
21
+ export declare function loadConfig(configPath?: string): LoadConfigResult;
22
+ /**
23
+ * Get a specific app from the configuration by name.
24
+ */
25
+ export declare function getApp(config: QualyxConfig, appName: string): {
26
+ name: string;
27
+ url: string;
28
+ rules: {
29
+ id: string;
30
+ name: string;
31
+ severity: "critical" | "high" | "medium" | "low";
32
+ steps: (string | {
33
+ action: string;
34
+ hint?: string | undefined;
35
+ caution?: string | undefined;
36
+ })[];
37
+ timeout?: number | undefined;
38
+ validations?: string[] | undefined;
39
+ on_failure?: string[] | undefined;
40
+ test_data?: Record<string, unknown> | undefined;
41
+ schedule?: string | undefined;
42
+ skip_setup?: boolean | undefined;
43
+ }[];
44
+ environments?: Record<string, string> | undefined;
45
+ auth?: {
46
+ type: "form-login" | "basic" | "bearer" | "cookie" | "none";
47
+ credentials?: Record<string, string> | undefined;
48
+ login_url?: string | undefined;
49
+ } | undefined;
50
+ screenshots?: {
51
+ on_failure: boolean;
52
+ on_success: boolean;
53
+ each_step: boolean;
54
+ } | undefined;
55
+ setup?: string[] | undefined;
56
+ };
57
+ /**
58
+ * Get a specific rule from an app by ID.
59
+ */
60
+ export declare function getRule(config: QualyxConfig, appName: string, ruleId: string): {
61
+ app: {
62
+ name: string;
63
+ url: string;
64
+ rules: {
65
+ id: string;
66
+ name: string;
67
+ severity: "critical" | "high" | "medium" | "low";
68
+ steps: (string | {
69
+ action: string;
70
+ hint?: string | undefined;
71
+ caution?: string | undefined;
72
+ })[];
73
+ timeout?: number | undefined;
74
+ validations?: string[] | undefined;
75
+ on_failure?: string[] | undefined;
76
+ test_data?: Record<string, unknown> | undefined;
77
+ schedule?: string | undefined;
78
+ skip_setup?: boolean | undefined;
79
+ }[];
80
+ environments?: Record<string, string> | undefined;
81
+ auth?: {
82
+ type: "form-login" | "basic" | "bearer" | "cookie" | "none";
83
+ credentials?: Record<string, string> | undefined;
84
+ login_url?: string | undefined;
85
+ } | undefined;
86
+ screenshots?: {
87
+ on_failure: boolean;
88
+ on_success: boolean;
89
+ each_step: boolean;
90
+ } | undefined;
91
+ setup?: string[] | undefined;
92
+ };
93
+ rule: {
94
+ id: string;
95
+ name: string;
96
+ severity: "critical" | "high" | "medium" | "low";
97
+ steps: (string | {
98
+ action: string;
99
+ hint?: string | undefined;
100
+ caution?: string | undefined;
101
+ })[];
102
+ timeout?: number | undefined;
103
+ validations?: string[] | undefined;
104
+ on_failure?: string[] | undefined;
105
+ test_data?: Record<string, unknown> | undefined;
106
+ schedule?: string | undefined;
107
+ skip_setup?: boolean | undefined;
108
+ };
109
+ };
110
+ /**
111
+ * Get the URL for a specific environment, with fallback to the default URL.
112
+ */
113
+ export declare function getEnvironmentUrl(app: {
114
+ url: string;
115
+ environments?: Record<string, string>;
116
+ }, environment?: string): string;
117
+ /**
118
+ * Get the directory containing the configuration file.
119
+ */
120
+ export declare function getConfigDir(filePath: string): string;
121
+ /**
122
+ * Get all scheduled rules from the configuration.
123
+ */
124
+ export declare function getScheduledRules(config: QualyxConfig): Array<{
125
+ appName: string;
126
+ ruleId: string;
127
+ ruleName: string;
128
+ schedule: string;
129
+ severity: string;
130
+ }>;
131
+ /**
132
+ * Get setup steps for an app.
133
+ */
134
+ export declare function getAppSetup(app: {
135
+ setup?: string[];
136
+ }): string[];
137
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/core/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI1E,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,QAAQ,CAAC,EAAE,MAAM;aACjB,gBAAgB,CAAC,EAAE,QAAQ;gBAF3C,OAAO,EAAE,MAAM,EACC,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,gBAAgB,CAAC,EAAE,QAAQ,YAAA;CAK9C;AAyCD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAqB1D;AA+FD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAyBhE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM3D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO5E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAW3H;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,KAAK,CAAC;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAwBD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,MAAM,EAAE,CAE/D"}