qa-flowkit 0.4.0-alpha.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/.qa-ai/adapters/aider/.aider/README.md +25 -0
- package/.qa-ai/adapters/aider/.aider.conf.yml +6 -0
- package/.qa-ai/adapters/claude/agents/qa-workflow-orchestrator.md +18 -0
- package/.qa-ai/adapters/claude/commands/qa-add-tests.md +42 -0
- package/.qa-ai/adapters/claude/commands/qa-automation-plan.md +43 -0
- package/.qa-ai/adapters/claude/commands/qa-clean.md +42 -0
- package/.qa-ai/adapters/claude/commands/qa-config.md +51 -0
- package/.qa-ai/adapters/claude/commands/qa-coverage.md +46 -0
- package/.qa-ai/adapters/claude/commands/qa-doctor.md +11 -0
- package/.qa-ai/adapters/claude/commands/qa-full-flow.md +59 -0
- package/.qa-ai/adapters/claude/commands/qa-gate.md +36 -0
- package/.qa-ai/adapters/claude/commands/qa-help.md +30 -0
- package/.qa-ai/adapters/claude/commands/qa-init.md +70 -0
- package/.qa-ai/adapters/claude/commands/qa-status.md +56 -0
- package/.qa-ai/adapters/claude/commands/qa-update-tests.md +47 -0
- package/.qa-ai/adapters/claude/commands/qa-validate-features.md +36 -0
- package/.qa-ai/adapters/cline/.cline/README.md +25 -0
- package/.qa-ai/adapters/cline/.clinerules +9 -0
- package/.qa-ai/adapters/codex/README.md +44 -0
- package/.qa-ai/adapters/codex/prompts/implement-project.md +15 -0
- package/.qa-ai/adapters/continue/README.md +26 -0
- package/.qa-ai/adapters/continue/checks/qa-feature-conventions.md +15 -0
- package/.qa-ai/adapters/gemini/GEMINI.md +40 -0
- package/.qa-ai/adapters/generic/AGENTS.md +100 -0
- package/.qa-ai/adapters/goose/recipes/qa-flowkit.yaml +20 -0
- package/.qa-ai/adapters/opencode/README.md +57 -0
- package/.qa-ai/adapters/opencode/agents/qa-workflow.md +18 -0
- package/.qa-ai/adapters/opencode/commands/qa-add-tests.md +42 -0
- package/.qa-ai/adapters/opencode/commands/qa-automation-plan.md +43 -0
- package/.qa-ai/adapters/opencode/commands/qa-clean.md +42 -0
- package/.qa-ai/adapters/opencode/commands/qa-config.md +51 -0
- package/.qa-ai/adapters/opencode/commands/qa-coverage.md +46 -0
- package/.qa-ai/adapters/opencode/commands/qa-doctor.md +13 -0
- package/.qa-ai/adapters/opencode/commands/qa-full-flow.md +59 -0
- package/.qa-ai/adapters/opencode/commands/qa-gate.md +36 -0
- package/.qa-ai/adapters/opencode/commands/qa-help.md +30 -0
- package/.qa-ai/adapters/opencode/commands/qa-init.md +70 -0
- package/.qa-ai/adapters/opencode/commands/qa-status.md +56 -0
- package/.qa-ai/adapters/opencode/commands/qa-update-tests.md +47 -0
- package/.qa-ai/adapters/opencode/commands/qa-validate-features.md +36 -0
- package/.qa-ai/agents/README.md +39 -0
- package/.qa-ai/agents/api-testing-agent.md +73 -0
- package/.qa-ai/agents/automation-feasibility-agent.md +128 -0
- package/.qa-ai/agents/gherkin-test-design-agent.md +110 -0
- package/.qa-ai/agents/jira-task-agent.md +92 -0
- package/.qa-ai/agents/pr-agent.md +101 -0
- package/.qa-ai/agents/qa-context-intake-agent.md +75 -0
- package/.qa-ai/agents/qa-workflow-orchestrator.md +113 -0
- package/.qa-ai/agents/release-gate-agent.md +50 -0
- package/.qa-ai/agents/requirements-intake-agent.md +79 -0
- package/.qa-ai/agents/requirements-normalization-agent.md +80 -0
- package/.qa-ai/agents/specialists/available/appium.md +59 -0
- package/.qa-ai/agents/specialists/available/cypress.md +68 -0
- package/.qa-ai/agents/specialists/available/generic-test-design.md +117 -0
- package/.qa-ai/agents/specialists/available/jira.md +108 -0
- package/.qa-ai/agents/specialists/available/karate.md +97 -0
- package/.qa-ai/agents/specialists/available/playwright-api.md +87 -0
- package/.qa-ai/agents/specialists/available/playwright-ui.md +87 -0
- package/.qa-ai/agents/specialists/available/postman.md +108 -0
- package/.qa-ai/agents/specialists/available/rest-assured.md +103 -0
- package/.qa-ai/agents/specialists/available/selenium.md +91 -0
- package/.qa-ai/agents/specialists/available/testrail.md +85 -0
- package/.qa-ai/agents/specialists/available/webdriverio.md +81 -0
- package/.qa-ai/agents/test-design-system-agent.md +33 -0
- package/.qa-ai/agents/testrail-coverage-agent.md +84 -0
- package/.qa-ai/agents/testrail-sync-agent.md +96 -0
- package/.qa-ai/agents/webdriverio-implementation-agent.md +84 -0
- package/.qa-ai/presets/manual-only.yaml +65 -0
- package/.qa-ai/presets/selenium-jest-browserstack.yaml +72 -0
- package/.qa-ai/presets/webdriverio-playwright-api.yaml +85 -0
- package/.qa-ai/rules/api-testing.rules.md +7 -0
- package/.qa-ai/rules/approval.rules.md +8 -0
- package/.qa-ai/rules/automation.rules.md +7 -0
- package/.qa-ai/rules/gherkin.rules.md +12 -0
- package/.qa-ai/rules/testrail.rules.md +10 -0
- package/.qa-ai/rules/webdriverio.rules.md +9 -0
- package/.qa-ai/scripts/bootstrap-agent-adapters.mjs +127 -0
- package/.qa-ai/scripts/clean.mjs +243 -0
- package/.qa-ai/scripts/config.mjs +202 -0
- package/.qa-ai/scripts/doctor.mjs +383 -0
- package/.qa-ai/scripts/init.mjs +447 -0
- package/.qa-ai/scripts/lib/markdown-table.mjs +76 -0
- package/.qa-ai/scripts/lib/project-config.mjs +184 -0
- package/.qa-ai/scripts/lib/qa-next-steps.mjs +578 -0
- package/.qa-ai/scripts/lib/release-gate.mjs +66 -0
- package/.qa-ai/scripts/lib/test-design.mjs +92 -0
- package/.qa-ai/scripts/lib/test-management-mapping.mjs +73 -0
- package/.qa-ai/scripts/lib/utils.mjs +331 -0
- package/.qa-ai/scripts/qa-help.mjs +44 -0
- package/.qa-ai/scripts/smoke-npm-pack.mjs +187 -0
- package/.qa-ai/scripts/smoke-test.mjs +465 -0
- package/.qa-ai/scripts/sync-agent-adapters.mjs +121 -0
- package/.qa-ai/scripts/test-validators.mjs +334 -0
- package/.qa-ai/scripts/validate-active-specialists.mjs +106 -0
- package/.qa-ai/scripts/validate-features.mjs +277 -0
- package/.qa-ai/scripts/validate-release-gate.mjs +105 -0
- package/.qa-ai/scripts/validate-sync-plan.mjs +186 -0
- package/.qa-ai/scripts/validate-target.mjs +104 -0
- package/.qa-ai/scripts/validate-test-design.mjs +117 -0
- package/.qa-ai/scripts/validate-traceability.mjs +183 -0
- package/.qa-ai/templates/automation-feasibility-report.template.md +21 -0
- package/.qa-ai/templates/automation-implementation-plan.template.md +23 -0
- package/.qa-ai/templates/feature.template +13 -0
- package/.qa-ai/templates/jira-automation-task.template.md +25 -0
- package/.qa-ai/templates/pr-template.md +60 -0
- package/.qa-ai/templates/release-gate.template.yaml +16 -0
- package/.qa-ai/templates/requirement-analysis.template.md +17 -0
- package/.qa-ai/templates/test-design-proposal.template.md +26 -0
- package/.qa-ai/templates/test-design-system.template.md +15 -0
- package/.qa-ai/templates/test-management-mapping.template.json +18 -0
- package/.qa-ai/templates/testrail-coverage-analysis.template.md +17 -0
- package/.qa-ai/templates/testrail-sync-plan.template.md +22 -0
- package/.qa-ai/templates/traceability-matrix.template.md +4 -0
- package/.qa-ai/workflows/automation-analysis.md +23 -0
- package/.qa-ai/workflows/cleanup.md +52 -0
- package/.qa-ai/workflows/context-intake.md +66 -0
- package/.qa-ai/workflows/full-flow.md +55 -0
- package/.qa-ai/workflows/implementation.md +24 -0
- package/.qa-ai/workflows/intake.md +3 -0
- package/.qa-ai/workflows/pr.md +3 -0
- package/.qa-ai/workflows/release-gate.md +22 -0
- package/.qa-ai/workflows/test-design-system.md +33 -0
- package/.qa-ai/workflows/test-design.md +23 -0
- package/.qa-ai/workflows/testrail-sync.md +23 -0
- package/CHANGELOG.md +108 -0
- package/CODE_OF_CONDUCT.md +11 -0
- package/CONTRIBUTING.md +39 -0
- package/LICENSE +21 -0
- package/README.es.md +602 -0
- package/README.md +633 -0
- package/ROADMAP.md +107 -0
- package/SECURITY.md +18 -0
- package/bin/qa-flowkit.mjs +214 -0
- package/docs/qa-ai/agent-compatibility.md +100 -0
- package/docs/qa-ai/architecture.md +130 -0
- package/docs/qa-ai/backlog.md +393 -0
- package/docs/qa-ai/cleanup.md +104 -0
- package/docs/qa-ai/customizing-agents.md +148 -0
- package/docs/qa-ai/getting-started.md +385 -0
- package/docs/qa-ai/implementation-guide-for-codex.md +210 -0
- package/docs/qa-ai/npm-migration-plan.md +50 -0
- package/docs/qa-ai/open-source-release-checklist.md +17 -0
- package/docs/qa-ai/qa-help.md +76 -0
- package/docs/qa-ai/release-gate.md +60 -0
- package/docs/qa-ai/terminal-transcripts.md +316 -0
- package/docs/qa-ai/test-design-dual-mode.md +75 -0
- package/docs/qa-ai/troubleshooting.md +740 -0
- package/docs/qa-ai/workflow.md +147 -0
- package/package.json +72 -0
package/ROADMAP.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
## Current status - Target-repo hardening
|
|
4
|
+
|
|
5
|
+
QA FlowKit has moved beyond the folder-copy MVP. The portable `.qa-ai/` framework, init/bootstrap scripts, adapters, validation workflow, CI, GitHub repository hardening and public releases are in place.
|
|
6
|
+
|
|
7
|
+
The current product phase is **Target-repo hardening**: the starter has been validated in a real pilot repository and the core workflow is correct. Current work should focus on stricter target-repository validation, clearer pilot migration notes, guided examples and packaging.
|
|
8
|
+
|
|
9
|
+
## Completed - Portable folder MVP
|
|
10
|
+
|
|
11
|
+
Goal: create a folder that can be copied into any QA/automation repository.
|
|
12
|
+
|
|
13
|
+
Delivered:
|
|
14
|
+
|
|
15
|
+
- `.qa-ai/` portable framework structure.
|
|
16
|
+
- `qa-ai.config.yaml` generation.
|
|
17
|
+
- Agent adapter generation for Claude Code, OpenCode, Codex, Cline, Continue, Aider, Goose and Gemini CLI.
|
|
18
|
+
- Agent-first bootstrap through `/qa-init` for Claude Code and OpenCode.
|
|
19
|
+
- Documentation, rules, templates and validation scripts.
|
|
20
|
+
- Manifest-based cleanup with dry-run default.
|
|
21
|
+
- CI workflow running doctor, validators and smoke tests.
|
|
22
|
+
- GitHub repository hardening with branch rules, CodeQL, Dependabot and secret scanning.
|
|
23
|
+
|
|
24
|
+
## Completed - Pilot repositories
|
|
25
|
+
|
|
26
|
+
Goal: validate that the workflow works across different QA and automation setups.
|
|
27
|
+
|
|
28
|
+
Delivered:
|
|
29
|
+
|
|
30
|
+
- Pilot with WebdriverIO + Playwright API.
|
|
31
|
+
- Feedback from generated Gherkin, traceability and automation planning.
|
|
32
|
+
- Confirmation that the folder-copy workflow, init scripts, adapters and validators work correctly in a target repository.
|
|
33
|
+
|
|
34
|
+
Follow-up:
|
|
35
|
+
|
|
36
|
+
- Document friction points and migration notes from the pilot.
|
|
37
|
+
- Add a second pilot when useful, preferably Selenium + Jest + BrowserStack or manual-only, to widen coverage.
|
|
38
|
+
|
|
39
|
+
## Phase 2 - Stronger validators
|
|
40
|
+
|
|
41
|
+
Goal: make the framework reliable without trusting prompts only.
|
|
42
|
+
|
|
43
|
+
Delivered:
|
|
44
|
+
|
|
45
|
+
- Parsed Gherkin structure validation for feature files.
|
|
46
|
+
- Duplicate explicit test case ID validation.
|
|
47
|
+
- Traceability matrix coverage validation.
|
|
48
|
+
- Traceability matrix row shape and duplicate matrix entry validation.
|
|
49
|
+
- Proposal-first test-management sync plan validation.
|
|
50
|
+
- Test-management sync plan table shape and duplicate ID validation.
|
|
51
|
+
- Test-management mapping file shape, duplicate external ID and secret-like value validation.
|
|
52
|
+
- Active specialist index validation against `qa-ai.config.yaml`.
|
|
53
|
+
- `doctor --strict` for fully initialized target repositories.
|
|
54
|
+
|
|
55
|
+
Next:
|
|
56
|
+
|
|
57
|
+
- Replace lightweight parsing with a full Gherkin parser when the project accepts dependencies or ships an npm CLI.
|
|
58
|
+
- Validate dry-run TestRail/Zephyr/Xray plans against richer mapping schemas.
|
|
59
|
+
|
|
60
|
+
## Phase 3 - Guided examples and public docs
|
|
61
|
+
|
|
62
|
+
Goal: make adoption obvious for first-time users.
|
|
63
|
+
|
|
64
|
+
Deliverables:
|
|
65
|
+
|
|
66
|
+
- Example manual-only repository.
|
|
67
|
+
- Example WebdriverIO + Playwright API repository.
|
|
68
|
+
- Getting-started flows by user type: manual QA, automation QA, maintainers and agent-first users.
|
|
69
|
+
- Troubleshooting guide for init, adapters, feature validation and CI failures.
|
|
70
|
+
- Screenshots or short terminal transcripts for common workflows.
|
|
71
|
+
|
|
72
|
+
## Phase 4 - npm CLI
|
|
73
|
+
|
|
74
|
+
Goal: replace manual copy with `npx qa-flowkit init` while keeping the folder-copy workflow as a fallback.
|
|
75
|
+
|
|
76
|
+
Deliverables:
|
|
77
|
+
|
|
78
|
+
- Node package: delivered for `0.4.0-alpha.0`.
|
|
79
|
+
- Non-interactive CI-friendly install: delivered through `qa-flowkit init`.
|
|
80
|
+
- Update/migration command: delivered through `qa-flowkit update`.
|
|
81
|
+
- Presets: reused from `.qa-ai/presets`.
|
|
82
|
+
- Interactive prompts: future enhancement after the zero-dependency alpha CLI.
|
|
83
|
+
|
|
84
|
+
## Phase 5 - MCP and integrations
|
|
85
|
+
|
|
86
|
+
Goal: add controlled integrations with Jira, Confluence, TestRail and GitHub.
|
|
87
|
+
|
|
88
|
+
Deliverables:
|
|
89
|
+
|
|
90
|
+
- MCP configuration templates.
|
|
91
|
+
- Read-only requirement intake tools.
|
|
92
|
+
- Proposal-first write tools.
|
|
93
|
+
- Audit logs.
|
|
94
|
+
- Approval gates.
|
|
95
|
+
|
|
96
|
+
## Phase 6 - Productization
|
|
97
|
+
|
|
98
|
+
Goal: turn the starter into a stable open-source framework.
|
|
99
|
+
|
|
100
|
+
Deliverables:
|
|
101
|
+
|
|
102
|
+
- Public documentation site.
|
|
103
|
+
- Example repositories.
|
|
104
|
+
- Adapter registry.
|
|
105
|
+
- Stable config contract.
|
|
106
|
+
- Release automation.
|
|
107
|
+
- Compatibility and migration policy.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
The project is currently in MVP stage. Security fixes target the latest version of `main`.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Do not open public issues for secrets, credential leaks or high-impact security problems. Contact the maintainers privately.
|
|
10
|
+
|
|
11
|
+
## Security principles
|
|
12
|
+
|
|
13
|
+
- Never commit credentials, API tokens or personal data.
|
|
14
|
+
- `.qa-ai/` must not store secrets.
|
|
15
|
+
- Generated `.mcp.json` files must use environment variables.
|
|
16
|
+
- External writes to Jira, Confluence, TestRail or GitHub must require explicit user approval.
|
|
17
|
+
- Deletion operations should be disabled by default.
|
|
18
|
+
- Scripts must prefer dry-run or proposal-first behavior.
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
9
|
+
const packagedFramework = path.join(packageRoot, '.qa-ai');
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
const targetFramework = path.join(cwd, '.qa-ai');
|
|
12
|
+
|
|
13
|
+
const commandMap = {
|
|
14
|
+
doctor: 'doctor.mjs',
|
|
15
|
+
'validate-target': 'validate-target.mjs',
|
|
16
|
+
'validate-features': 'validate-features.mjs',
|
|
17
|
+
'sync-adapters': 'sync-agent-adapters.mjs',
|
|
18
|
+
help: 'qa-help.mjs',
|
|
19
|
+
clean: 'clean.mjs'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function printHelp() {
|
|
23
|
+
console.log(`QA FlowKit
|
|
24
|
+
|
|
25
|
+
Usage:
|
|
26
|
+
qa-flowkit init [options]
|
|
27
|
+
qa-flowkit update [options]
|
|
28
|
+
qa-flowkit doctor [options]
|
|
29
|
+
qa-flowkit validate-target [options]
|
|
30
|
+
qa-flowkit validate-features [options]
|
|
31
|
+
qa-flowkit sync-adapters [options]
|
|
32
|
+
qa-flowkit help [options]
|
|
33
|
+
qa-flowkit clean [options]
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
npx qa-flowkit init
|
|
37
|
+
npx qa-flowkit init --preset manual-only --interface-language es --gherkin-language es
|
|
38
|
+
npx qa-flowkit update
|
|
39
|
+
npx qa-flowkit validate-target --allow-empty --allow-missing --no-strict-doctor
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function pathExists(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(filePath);
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function hasFlag(args, name) {
|
|
53
|
+
return args.includes(`--${name}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function withoutCliOnlyFlags(args) {
|
|
57
|
+
return args.filter((arg) => !['--skip-doctor'].includes(arg));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function assertPackagedFramework() {
|
|
61
|
+
if (!await pathExists(path.join(packagedFramework, 'scripts', 'init.mjs'))) {
|
|
62
|
+
console.error(`Packaged QA FlowKit framework is incomplete: ${packagedFramework}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function assertTargetFramework(command) {
|
|
68
|
+
if (!await pathExists(path.join(targetFramework, 'scripts'))) {
|
|
69
|
+
console.error(`Missing .qa-ai framework folder. Run "qa-flowkit init" before "qa-flowkit ${command}".`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runNodeScript(scriptName, args = [], { allowWarnings = false } = {}) {
|
|
75
|
+
const scriptPath = path.join(targetFramework, 'scripts', scriptName);
|
|
76
|
+
const result = spawnSync(process.execPath, [scriptPath, ...args], {
|
|
77
|
+
cwd,
|
|
78
|
+
stdio: 'inherit',
|
|
79
|
+
shell: false
|
|
80
|
+
});
|
|
81
|
+
const status = result.status ?? 1;
|
|
82
|
+
if (status !== 0 && !allowWarnings) process.exit(status);
|
|
83
|
+
return status;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function copyPackagedFramework(target) {
|
|
87
|
+
await fs.cp(packagedFramework, target, {
|
|
88
|
+
recursive: true,
|
|
89
|
+
force: false,
|
|
90
|
+
errorOnExist: true
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function copyIfExists(source, target) {
|
|
95
|
+
if (!await pathExists(source)) return false;
|
|
96
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
97
|
+
await fs.cp(source, target, { recursive: true, force: true });
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function restoreIfExists(source, target) {
|
|
102
|
+
if (!await pathExists(source)) return false;
|
|
103
|
+
await fs.rm(target, { recursive: true, force: true });
|
|
104
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
105
|
+
await fs.cp(source, target, { recursive: true, force: true });
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function selectedExistingAdapters() {
|
|
110
|
+
const candidates = [
|
|
111
|
+
['claude', '.claude'],
|
|
112
|
+
['codex', '.codex'],
|
|
113
|
+
['opencode', '.opencode'],
|
|
114
|
+
['cline', '.cline'],
|
|
115
|
+
['continue', '.continue'],
|
|
116
|
+
['aider', '.aider'],
|
|
117
|
+
['goose', '.goose'],
|
|
118
|
+
['gemini', 'GEMINI.md']
|
|
119
|
+
];
|
|
120
|
+
const names = [];
|
|
121
|
+
for (const [name, relPath] of candidates) {
|
|
122
|
+
if (await pathExists(path.join(cwd, relPath))) names.push(name);
|
|
123
|
+
}
|
|
124
|
+
if (await pathExists(path.join(cwd, '.clinerules'))) names.push('cline');
|
|
125
|
+
if (await pathExists(path.join(cwd, '.aider.conf.yml'))) names.push('aider');
|
|
126
|
+
if (await pathExists(path.join(cwd, 'AGENTS.md'))) names.unshift('generic');
|
|
127
|
+
return [...new Set(names)];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function init(args) {
|
|
131
|
+
await assertPackagedFramework();
|
|
132
|
+
if (await pathExists(targetFramework)) {
|
|
133
|
+
console.error('A .qa-ai framework folder already exists in this repository.');
|
|
134
|
+
console.error('Run "qa-flowkit update" to refresh it, or remove it intentionally before running init.');
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
await copyPackagedFramework(targetFramework);
|
|
139
|
+
runNodeScript('init.mjs', withoutCliOnlyFlags(args));
|
|
140
|
+
if (!hasFlag(args, 'skip-doctor')) {
|
|
141
|
+
runNodeScript('doctor.mjs', [], { allowWarnings: true });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function update(args) {
|
|
146
|
+
await assertPackagedFramework();
|
|
147
|
+
await assertTargetFramework('update');
|
|
148
|
+
|
|
149
|
+
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'qa-flowkit-update-'));
|
|
150
|
+
const backupFramework = path.join(tempRoot, '.qa-ai');
|
|
151
|
+
try {
|
|
152
|
+
await copyIfExists(path.join(targetFramework, 'state'), path.join(backupFramework, 'state'));
|
|
153
|
+
await copyIfExists(path.join(targetFramework, 'config-profiles'), path.join(backupFramework, 'config-profiles'));
|
|
154
|
+
|
|
155
|
+
await fs.rm(targetFramework, { recursive: true, force: true });
|
|
156
|
+
await fs.cp(packagedFramework, targetFramework, { recursive: true, force: true });
|
|
157
|
+
|
|
158
|
+
await restoreIfExists(path.join(backupFramework, 'state'), path.join(targetFramework, 'state'));
|
|
159
|
+
await restoreIfExists(path.join(backupFramework, 'config-profiles'), path.join(targetFramework, 'config-profiles'));
|
|
160
|
+
} finally {
|
|
161
|
+
await fs.rm(tempRoot, { recursive: true, force: true });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log('Updated .qa-ai framework from the installed QA FlowKit package.');
|
|
165
|
+
runNodeScript('init.mjs', ['--no-adapters']);
|
|
166
|
+
|
|
167
|
+
const adapters = await selectedExistingAdapters();
|
|
168
|
+
if (adapters.length > 0) {
|
|
169
|
+
const syncArgs = ['--adapters', adapters.join(',')];
|
|
170
|
+
if (hasFlag(args, 'force')) syncArgs.push('--force');
|
|
171
|
+
runNodeScript('sync-agent-adapters.mjs', syncArgs);
|
|
172
|
+
} else {
|
|
173
|
+
console.log('No existing root adapters detected; skipping adapter sync.');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!hasFlag(args, 'skip-doctor')) {
|
|
177
|
+
runNodeScript('doctor.mjs', [], { allowWarnings: true });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function main() {
|
|
182
|
+
const [command = 'help', ...args] = process.argv.slice(2);
|
|
183
|
+
if (['-h', '--help', 'help'].includes(command)) {
|
|
184
|
+
printHelp();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (['-v', '--version', 'version'].includes(command)) {
|
|
188
|
+
const packageJson = JSON.parse(await fs.readFile(path.join(packageRoot, 'package.json'), 'utf8'));
|
|
189
|
+
console.log(packageJson.version);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (command === 'init') {
|
|
193
|
+
await init(args);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (command === 'update') {
|
|
197
|
+
await update(args);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (command in commandMap) {
|
|
201
|
+
await assertTargetFramework(command);
|
|
202
|
+
runNodeScript(commandMap[command], args);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
console.error(`Unknown command: ${command}`);
|
|
207
|
+
printHelp();
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
main().catch((error) => {
|
|
212
|
+
console.error(error);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Agent Compatibility
|
|
2
|
+
|
|
3
|
+
The MVP uses `AGENTS.md` as the generic compatibility layer and syncs tool-specific adapter files where useful. No adapter should become the only source of truth; every adapter points back to `AGENTS.md`, `qa-ai.config.yaml`, `.qa-ai/rules/` and `.qa-ai/workflows/`.
|
|
4
|
+
|
|
5
|
+
## Syncing adapters
|
|
6
|
+
|
|
7
|
+
Default init syncs only the OpenCode adapter, keeping the first setup small:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node .qa-ai/scripts/init.mjs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Additional adapters can be synced explicitly:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
node .qa-ai/scripts/sync-agent-adapters.mjs --adapters generic,codex,claude
|
|
17
|
+
node .qa-ai/scripts/sync-agent-adapters.mjs --adapter cline --adapter continue
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Existing adapter files are skipped unless `--force` is passed.
|
|
21
|
+
|
|
22
|
+
## Agent-first initialization
|
|
23
|
+
|
|
24
|
+
Claude Code and OpenCode discover project slash commands from tool-specific folders in the repository root:
|
|
25
|
+
|
|
26
|
+
- Claude Code: `.claude/commands/`
|
|
27
|
+
- OpenCode: `.opencode/commands/`
|
|
28
|
+
|
|
29
|
+
Because those folders are outside the copied `.qa-ai/` framework folder, an agent-first setup needs one bootstrap step before the first agent session:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
node .qa-ai/scripts/bootstrap-agent-adapters.mjs --agents claude,opencode
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
That script copies:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
.claude/commands/qa-init.md
|
|
39
|
+
.opencode/commands/qa-init.md
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After copying `.qa-ai/` and running the bootstrap script, start the agent and run:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
/qa-init
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The command asks for the required initialization choices, including optional QA context folder, interface language, Gherkin language, base template, requirement source, optional framework overrides and adapter selection, then runs `node .qa-ai/scripts/init.mjs`. Use `/qa-init`, not `/init`, because `/init` is a built-in command in both Claude Code and OpenCode.
|
|
49
|
+
|
|
50
|
+
Advanced users may still pass flags directly:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
/qa-init --preset webdriverio-playwright-api --interface-language es --gherkin-language en --adapters claude,opencode
|
|
54
|
+
/qa-init --qa-context qa-ai-knowledge --adapters claude,opencode
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Interactive command behavior:
|
|
58
|
+
|
|
59
|
+
- `/qa-init` asks for optional QA context, interface language, Gherkin language, base template, requirement source, optional UI/API framework overrides, adapters and overwrite behavior. When QA context is provided, it reads `.qa-ai/workflows/context-intake.md` and proposes defaults before running init.
|
|
60
|
+
- `/qa-config` imports or exports reusable `qa-ai.config.yaml` profiles and asks for overwrite approval before using `--force`.
|
|
61
|
+
- `/qa-full-flow` asks for requirement source, official RF ID, configured test management project/suite and whether to stop at proposals.
|
|
62
|
+
- `/qa-add-tests` asks for the new requirement/RF source, official RF ID and whether to stop at proposal artifacts before adding new `.feature` files.
|
|
63
|
+
- `/qa-update-tests` asks for the updated RF source, official RF ID, existing test scope and proposal/apply mode before changing current tests.
|
|
64
|
+
- `/qa-automation-plan` asks which existing tests to analyze and produces automation feasibility plus implementation planning before any automation code is written.
|
|
65
|
+
- `/qa-coverage` asks for RF, requirement source or repo scope and reports functional coverage across requirements, manual tests and automated tests.
|
|
66
|
+
- `/qa-help` inspects artifacts and `project.qaTrack` to recommend the next workflow phase (CLI: `node .qa-ai/scripts/qa-help.mjs`).
|
|
67
|
+
- `/qa-status` summarizes configuration, feature health, QA artifacts, active specialists and recommended next steps without modifying files. It should include output from `qa-help` for the next command.
|
|
68
|
+
- `/qa-clean` previews cleanup first, then asks for scope and execution approval.
|
|
69
|
+
- `/qa-validate-features` uses the configured feature path unless the user asks for a custom path.
|
|
70
|
+
- `/qa-doctor` runs without extra input.
|
|
71
|
+
|
|
72
|
+
The framework agents under `.qa-ai/agents/` are role instructions. If a tool does not expose them as callable subagents, it must read `.qa-ai/agents/README.md`, the matching phase agent and `.qa-ai/agents/specialists/active.md` directly before doing QA workflow work. When `knowledge.enabled` is true, it must also read the configured QA knowledge summary and init decisions artifacts before planning.
|
|
73
|
+
|
|
74
|
+
## Supported adapters
|
|
75
|
+
|
|
76
|
+
| Adapter | Generated path | Purpose |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Generic | `AGENTS.md` | Cross-agent behavior and safety policy. |
|
|
79
|
+
| Claude Code | `.claude/agents/`, `.claude/commands/` | Claude-specific agent and slash command documentation. |
|
|
80
|
+
| Codex Desktop | `.codex/README.md`, `.codex/prompts/` | Codex onboarding prompts and local validation commands. |
|
|
81
|
+
| OpenCode | `.opencode/agents/`, `.opencode/commands/` | OpenCode agent and slash command documentation. |
|
|
82
|
+
| Cline | `.clinerules`, `.cline/` | Cline behavior rules and docs. |
|
|
83
|
+
| Continue | `.continue/` | Review/check documentation. |
|
|
84
|
+
| Aider | `.aider.conf.yml`, `.aider/` | Aider read-list and usage notes. |
|
|
85
|
+
| Goose | `.goose/recipes/qa-flowkit.yaml` | Reusable Goose workflow recipe. |
|
|
86
|
+
| Gemini CLI | `GEMINI.md` | Gemini CLI project context that points back to the shared QA AI instructions. |
|
|
87
|
+
|
|
88
|
+
## Required behavior for every agent
|
|
89
|
+
|
|
90
|
+
- Read `AGENTS.md` before acting.
|
|
91
|
+
- Read `qa-ai.config.yaml` when present.
|
|
92
|
+
- Read configured QA knowledge artifacts when `knowledge.enabled` is true.
|
|
93
|
+
- Read `.qa-ai/rules/` before changing workflow behavior.
|
|
94
|
+
- Present a plan before modifying files.
|
|
95
|
+
- Do not overwrite existing files unless explicitly approved or `--force` behavior is requested.
|
|
96
|
+
- Do not perform external writes in the MVP.
|
|
97
|
+
- Run `node .qa-ai/scripts/doctor.mjs` for setup checks.
|
|
98
|
+
- Run `node .qa-ai/scripts/validate-features.mjs` after `.feature` changes.
|
|
99
|
+
- Run `node .qa-ai/scripts/clean.mjs` as a dry-run before removing generated artifacts.
|
|
100
|
+
- Never pass `--include-modified` to clean unless the user explicitly wants to discard edited generated files.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## High-level architecture
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
.qa-ai/ portable framework copied into a target repo
|
|
7
|
+
agents/ role prompts for QA workflow steps
|
|
8
|
+
README.md protocol for loading role instructions
|
|
9
|
+
specialists/available/ optional specialist instructions by tool/framework
|
|
10
|
+
specialists/active.md generated active specialist index
|
|
11
|
+
adapters/ tool-specific adapter templates
|
|
12
|
+
presets/ YAML starter configurations
|
|
13
|
+
rules/ mandatory workflow rules
|
|
14
|
+
scripts/ dependency-light Node.js utilities
|
|
15
|
+
state/ generated local state, including init manifest
|
|
16
|
+
templates/ generated QA artifact templates
|
|
17
|
+
workflows/ task playbooks
|
|
18
|
+
|
|
19
|
+
qa-ai.config.yaml target repo configuration generated by init
|
|
20
|
+
AGENTS.md generic instruction layer when generic/all adapters are requested
|
|
21
|
+
GEMINI.md optional Gemini CLI project context when gemini adapter is requested
|
|
22
|
+
qa-ai-output/ workflow artifact folder; starter docs are optional
|
|
23
|
+
qa-ai-output/qa-knowledge-summary.md optional QA context summary written by an agent
|
|
24
|
+
qa-ai-output/qa-init-decisions.md optional approved context-based init decisions
|
|
25
|
+
features/ Gherkin source of truth for test design
|
|
26
|
+
tests/ automation code when configured
|
|
27
|
+
|
|
28
|
+
.claude/commands/qa-init.md optional Claude Code bootstrap copied before init
|
|
29
|
+
.opencode/commands/qa-init.md optional OpenCode bootstrap copied before init
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Script responsibilities
|
|
33
|
+
|
|
34
|
+
- `bootstrap-agent-adapters.mjs` copies the minimal root `/qa-init` command files for Claude Code and OpenCode after only `.qa-ai/` has been copied.
|
|
35
|
+
- `init.mjs` reads a base template, generates `qa-ai.config.yaml`, records an optional `--qa-context` folder, creates configured `qa-ai-output/`, `features/` and `tests/` folders, and syncs the OpenCode adapter by default without overwriting existing files unless `--force` is passed. Starter QA artifacts and extra adapters are opt-in.
|
|
36
|
+
- `doctor.mjs` validates the framework folder, required scripts/rules/templates/agents/presets/adapters, generated target files, optional QA context configuration and configured paths. `qa-ai.config.yaml` is required in initialized target repositories and optional in the framework source repository.
|
|
37
|
+
- `doctor.mjs --strict` is intended for initialized target repositories and CI. It requires `qa-ai.config.yaml`, configured workflow artifacts, configured mapping/traceability files, QA knowledge artifacts when enabled and framework config files for configured automation stacks. Optional adapters remain warnings unless explicitly generated and required by the team.
|
|
38
|
+
- `clean.mjs` reads `.qa-ai/state/init-manifest.json`, previews cleanup by default, and removes only tracked generated files or empty directories when `--force` is passed.
|
|
39
|
+
- `validate-features.mjs` parses configured `.feature` files for one Feature, one Scenario, acceptance criteria, required tag values, language directives, RF IDs and duplicate explicit test case IDs.
|
|
40
|
+
- `validate-traceability.mjs` checks that feature RF/test identifiers are represented in the configured traceability matrix, validates the Markdown table shape and detects duplicate test case or feature-file rows.
|
|
41
|
+
- `validate-sync-plan.mjs` checks that test-management sync plans remain proposal-first, mention approval, cover feature identifiers, validate Markdown table shape, detect duplicate plan IDs and validate the optional test-management mapping file shape.
|
|
42
|
+
- `validate-active-specialists.mjs` checks that `.qa-ai/agents/specialists/active.md` matches the configured tools/frameworks.
|
|
43
|
+
- `smoke-test.mjs` runs native Node smoke checks for init, config profiles, selected adapters, no-overwrite behavior and unsafe path rejection.
|
|
44
|
+
- `sync-agent-adapters.mjs` copies selected adapter templates into target tool paths.
|
|
45
|
+
|
|
46
|
+
Supported sync adapters are `generic`, `claude`, `codex`, `opencode`, `cline`, `continue`, `aider`, `goose` and `gemini`.
|
|
47
|
+
|
|
48
|
+
All scripts use native Node.js APIs and are intended for Node.js 20+.
|
|
49
|
+
|
|
50
|
+
Agent behavior can be customized through phase agents, specialists, shared rules and adapter templates. See [Customizing Agents](customizing-agents.md) for the recommended customization workflow and safety checklist.
|
|
51
|
+
|
|
52
|
+
## Bootstrap model
|
|
53
|
+
|
|
54
|
+
The framework supports two initialization modes:
|
|
55
|
+
|
|
56
|
+
- Node-first: copy `.qa-ai/`, then run `node .qa-ai/scripts/init.mjs`.
|
|
57
|
+
- Agent-first: copy `.qa-ai/`, run `node .qa-ai/scripts/bootstrap-agent-adapters.mjs`, then run `/qa-init` inside Claude Code or OpenCode.
|
|
58
|
+
|
|
59
|
+
Agent-first bootstrap files live outside `.qa-ai/` because Claude Code and OpenCode discover slash commands from root-level tool folders. The bootstrap script copies those files from `.qa-ai/adapters/` into `.claude/commands/` and `.opencode/commands/`. The `/qa-init` command delegates to the same `init.mjs` script, so both modes produce the same target repository structure.
|
|
60
|
+
|
|
61
|
+
## QA context model
|
|
62
|
+
|
|
63
|
+
QA context is optional and agent-assisted. A user can provide one repository-local folder with team QA working-practice documentation:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node .qa-ai/scripts/init.mjs --qa-context qa-ai-knowledge
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`init.mjs` validates that the folder is inside the repository, records it under `knowledge.sourcePath`, and sets `knowledge.enabled: true`. It does not interpret the documents. Claude Code, OpenCode or another agent reads `.qa-ai/workflows/context-intake.md` and `.qa-ai/agents/qa-context-intake-agent.md`, proposes init defaults, asks for approval and writes local summary/decision artifacts.
|
|
70
|
+
|
|
71
|
+
## Source of truth strategy
|
|
72
|
+
|
|
73
|
+
- Requirements source: configured source from `qa-ai.config.yaml`.
|
|
74
|
+
- QA working-practice source: optional `knowledge.sourcePath`, summarized into `knowledge.summaryPath` and `knowledge.decisionsPath`.
|
|
75
|
+
- Interface language: configured by `project.interfaceLanguage` for generated QA artifact headings and user-facing workflow text.
|
|
76
|
+
- Complementary sources: PRD, RF markdown, configured documentation tools and attachments.
|
|
77
|
+
- Test design source: versioned `.feature` files in the repository.
|
|
78
|
+
- Test management: configured tool for execution/reporting, not as the only source of truth.
|
|
79
|
+
- Traceability: `qa-ai-output/traceability-matrix.md`.
|
|
80
|
+
|
|
81
|
+
## Agent workflow
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
qa-workflow-orchestrator
|
|
85
|
+
-> requirements-intake-agent
|
|
86
|
+
-> requirements-normalization-agent
|
|
87
|
+
-> test management coverage agent
|
|
88
|
+
-> gherkin-test-design-agent
|
|
89
|
+
-> test management sync agent
|
|
90
|
+
-> automation-feasibility-agent
|
|
91
|
+
-> UI automation implementation agent
|
|
92
|
+
-> api-testing-agent
|
|
93
|
+
-> issue task agent
|
|
94
|
+
-> pr-agent
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Safety model
|
|
98
|
+
|
|
99
|
+
The Early Product release uses prompt rules, local validation scripts, smoke tests and GitHub CI. Future versions may add full parser dependencies, strict target-repo CI templates and MCP tools.
|
|
100
|
+
|
|
101
|
+
Safety principles:
|
|
102
|
+
|
|
103
|
+
- Read operations are allowed.
|
|
104
|
+
- Local writes require a plan.
|
|
105
|
+
- Existing files are not overwritten by default.
|
|
106
|
+
- Configured paths must stay inside the repository.
|
|
107
|
+
- External writes require explicit approval and are not performed by the MVP scripts.
|
|
108
|
+
- Updates to existing tests require approval.
|
|
109
|
+
- Deletes are blocked by default.
|
|
110
|
+
- Cleanup is dry-run by default and manifest-based.
|
|
111
|
+
- Modified generated files are protected by hash checks unless `--include-modified` is explicitly passed.
|
|
112
|
+
- Secrets are never stored in `.qa-ai/` or generated repository files.
|
|
113
|
+
|
|
114
|
+
## Init manifest
|
|
115
|
+
|
|
116
|
+
The init manifest is generated in the target repository:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
.qa-ai/state/init-manifest.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Each entry stores:
|
|
123
|
+
|
|
124
|
+
- Repository-relative path.
|
|
125
|
+
- Entry type: `file` or `dir`.
|
|
126
|
+
- Category: `generated` or `adapter`.
|
|
127
|
+
- Source command or adapter.
|
|
128
|
+
- SHA-256 hash for files.
|
|
129
|
+
|
|
130
|
+
The manifest exists to make cleanup auditable. It intentionally records only paths created or overwritten by framework scripts. Existing files skipped by safe writes are not tracked as generated ownership.
|