@qa-gentic/stlc-agents 1.0.7 → 1.0.8
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 +5 -2
- package/bin/postinstall.js +59 -123
- package/package.json +1 -1
- package/src/cli/cmd-skills.js +2 -2
package/README.md
CHANGED
|
@@ -32,12 +32,15 @@ A sixth server — **Playwright MCP** (`http://localhost:8931/mcp`) — drives a
|
|
|
32
32
|
|
|
33
33
|
## Install
|
|
34
34
|
|
|
35
|
+
|
|
35
36
|
```bash
|
|
36
37
|
# 1. Install the CLI + npm package globally
|
|
37
|
-
# You will be prompted to choose your integration: ado / jira / both
|
|
38
|
-
# The choice is saved to ~/.qa-stlc/integration and reused by all subsequent commands.
|
|
39
38
|
npm install -g @qa-gentic/stlc-agents
|
|
39
|
+
```
|
|
40
40
|
|
|
41
|
+
The postinstall script automatically runs `pip install qa-gentic-stlc-agents` and prints next-step instructions. It does **not** prompt for input — all interactive setup is done in the next step.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
41
44
|
# 2. Bootstrap your project (installs Python agents, copies skills, writes MCP config)
|
|
42
45
|
# --integration overrides the saved preference; omit to reuse the choice from step 1.
|
|
43
46
|
qa-stlc init --vscode --integration ado # GitHub Copilot / VS Code — ADO pipeline
|
package/bin/postinstall.js
CHANGED
|
@@ -1,159 +1,95 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* postinstall.js — Auto-install Python MCP servers after
|
|
3
|
+
* postinstall.js — Auto-install Python MCP servers after npm install -g
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* npm 7+ runs lifecycle scripts with stdout suppressed by default (background
|
|
6
|
+
* mode). To guarantee output is always visible we write exclusively to
|
|
7
|
+
* stderr, which npm forwards to the terminal even in background mode.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* Interactive prompts (readline / TTY) require --foreground-scripts and are
|
|
10
|
+
* therefore NOT used here. The user is instructed to run `qa-stlc init`
|
|
11
|
+
* in their project after install — that command IS interactive.
|
|
12
12
|
*/
|
|
13
13
|
"use strict";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
// ── Route ALL output to stderr so it shows without --foreground-scripts ──────
|
|
16
|
+
const _write = (msg) => process.stderr.write(msg + "\n");
|
|
17
|
+
console.log = _write;
|
|
18
|
+
console.info = _write;
|
|
19
|
+
console.warn = _write;
|
|
20
|
+
console.error = _write;
|
|
21
|
+
|
|
22
|
+
const { spawnSync } = require("child_process");
|
|
23
|
+
const os = require("os");
|
|
24
|
+
const fs = require("fs");
|
|
25
|
+
const path = require("path");
|
|
26
|
+
const pkg = require("../package.json");
|
|
21
27
|
|
|
22
28
|
const C = {
|
|
23
29
|
reset: "\x1b[0m", bold: "\x1b[1m",
|
|
24
30
|
green: "\x1b[32m", cyan: "\x1b[36m",
|
|
25
|
-
yellow: "\x1b[33m",
|
|
31
|
+
yellow: "\x1b[33m", dim: "\x1b[2m",
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
const b = (s) => `${C.bold}${s}${C.reset}`;
|
|
29
35
|
const ok = (s) => console.log(`${C.green}✓${C.reset} ${s}`);
|
|
30
36
|
const info = (s) => console.log(`${C.cyan}→${C.reset} ${s}`);
|
|
31
37
|
const warn = (s) => console.log(`${C.yellow}⚠${C.reset} ${s}`);
|
|
32
|
-
const y = (s) => `${C.yellow}${s}${C.reset}`;
|
|
33
38
|
const d = (s) => `${C.dim}${s}${C.reset}`;
|
|
34
39
|
|
|
35
|
-
// Persistent preference file — shared with cmd-init / cmd-mcp-config / cmd-verify
|
|
36
|
-
const PREF_DIR = path.join(os.homedir(), ".qa-stlc");
|
|
37
|
-
const PREF_FILE = path.join(PREF_DIR, "integration");
|
|
38
|
-
|
|
39
|
-
function savePreference(value) {
|
|
40
|
-
try {
|
|
41
|
-
fs.mkdirSync(PREF_DIR, { recursive: true });
|
|
42
|
-
fs.writeFileSync(PREF_FILE, value, "utf8");
|
|
43
|
-
} catch (_) { /* non-fatal */ }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
40
|
console.log(`\n${b("QA STLC Agents")} v${pkg.version} — post-install\n`);
|
|
47
41
|
|
|
48
|
-
// ──
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const r = spawnSync(candidate, ["--version"], { encoding: "utf8" });
|
|
56
|
-
if (r.status === 0) { python = candidate; break; }
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (!python) {
|
|
60
|
-
warn("Python not found — skipping pip install.");
|
|
61
|
-
warn("Run manually after installing Python 3.10+:");
|
|
62
|
-
warn(" pip install qa-gentic-stlc-agents");
|
|
63
|
-
printNextSteps("ado");
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ── 2. Ask which integration ──────────────────────────────────────────────
|
|
68
|
-
const integration = await pickIntegration("ado");
|
|
69
|
-
savePreference(integration);
|
|
42
|
+
// ── 1. Find Python ────────────────────────────────────────────────────────────
|
|
43
|
+
const pythonCandidates = ["python3", "python"];
|
|
44
|
+
let python = null;
|
|
45
|
+
for (const candidate of pythonCandidates) {
|
|
46
|
+
const r = spawnSync(candidate, ["--version"], { encoding: "utf8" });
|
|
47
|
+
if (r.status === 0) { python = candidate; break; }
|
|
48
|
+
}
|
|
70
49
|
|
|
71
|
-
|
|
50
|
+
if (!python) {
|
|
51
|
+
warn("Python not found — skipping pip install.");
|
|
52
|
+
warn("After installing Python 3.10+, run inside your project:");
|
|
53
|
+
warn(" pip install qa-gentic-stlc-agents");
|
|
54
|
+
} else {
|
|
55
|
+
// ── 2. pip install (non-interactive, pipe output to stderr) ────────────────
|
|
72
56
|
info("Installing qa-gentic-stlc-agents via pip…");
|
|
73
57
|
const pip = spawnSync(
|
|
74
58
|
python,
|
|
75
59
|
["-m", "pip", "install", "qa-gentic-stlc-agents", "--upgrade", "--quiet"],
|
|
76
|
-
{ stdio: "
|
|
60
|
+
{ stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
|
|
77
61
|
);
|
|
78
|
-
|
|
79
62
|
if (pip.status === 0) {
|
|
80
63
|
ok("qa-gentic-stlc-agents installed.");
|
|
81
64
|
} else {
|
|
65
|
+
// Only surface pip output on failure
|
|
66
|
+
if (pip.stdout) process.stderr.write(pip.stdout);
|
|
67
|
+
if (pip.stderr) process.stderr.write(pip.stderr);
|
|
82
68
|
warn("pip install failed. Run manually: pip install qa-gentic-stlc-agents");
|
|
83
69
|
}
|
|
70
|
+
}
|
|
84
71
|
|
|
72
|
+
// ── 3. Print next-step instructions ──────────────────────────────────────────
|
|
73
|
+
console.log(`
|
|
74
|
+
${b("Next steps")} — run these inside your project root:
|
|
85
75
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
${b("1.")} Choose your integration and bootstrap:
|
|
77
|
+
|
|
78
|
+
${C.cyan}qa-stlc init --vscode --integration ado${C.reset} ${d("# VS Code / GitHub Copilot — Azure DevOps")}
|
|
79
|
+
${C.cyan}qa-stlc init --vscode --integration jira${C.reset} ${d("# VS Code / GitHub Copilot — Jira Cloud")}
|
|
80
|
+
${C.cyan}qa-stlc init --vscode --integration both${C.reset} ${d("# VS Code / GitHub Copilot — ADO + Jira")}
|
|
81
|
+
${C.cyan}qa-stlc init --integration ado${C.reset} ${d("# Claude Code — Azure DevOps")}
|
|
82
|
+
|
|
83
|
+
${d("This installs skills, writes .vscode/mcp.json, and sets your integration.")}
|
|
84
|
+
${d("Run it once; re-run any time to change integration.")}
|
|
85
|
+
|
|
86
|
+
${b("2.")} Scaffold a new Playwright + Cucumber + TypeScript QA project:
|
|
87
|
+
|
|
88
|
+
${C.cyan}qa-stlc scaffold --name my-qa-project${C.reset}
|
|
89
|
+
|
|
90
|
+
${b("3.")} Start the Playwright browser server (keep running in a separate terminal):
|
|
91
|
+
|
|
92
|
+
${C.cyan}npx @playwright/mcp@latest --port 8931${C.reset}
|
|
94
93
|
|
|
95
|
-
// ── 5. Prompt for scaffold ────────────────────────────────────────────────
|
|
96
|
-
const readline = require("readline");
|
|
97
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
98
|
-
rl.question("Do you want to scaffold a new QA project now? (Y/n): ", (answer) => {
|
|
99
|
-
if (!answer.trim() || answer.trim().toLowerCase() === "y") {
|
|
100
|
-
try {
|
|
101
|
-
console.log(`\n${C.cyan}→${C.reset} Running: qa-stlc scaffold\n`);
|
|
102
|
-
execSync("qa-stlc scaffold", { stdio: "inherit" });
|
|
103
|
-
} catch (e) {
|
|
104
|
-
warn("Failed to run qa-stlc scaffold automatically. You can run it manually.");
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// ── 6. Show Playwright MCP server command ───────────────────────────────
|
|
108
|
-
console.log(`\n# 4. Start the Playwright browser server (required for code generation)\n` +
|
|
109
|
-
`npx @playwright/mcp@latest --port 8931\n`);
|
|
110
|
-
rl.close();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
})();
|
|
114
|
-
|
|
115
|
-
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
116
|
-
|
|
117
|
-
function printNextSteps(integration) {
|
|
118
|
-
const initFlag = integration !== "ado" ? ` --integration ${integration}` : "";
|
|
119
|
-
|
|
120
|
-
const adoWorkflow = `
|
|
121
|
-
${d("ADO pipeline:")}
|
|
122
|
-
${d("1 →")} ${y("qa-test-case-manager")} ${d("ADO work item → manual test cases")}
|
|
123
|
-
${d("2 →")} ${y("qa-gherkin-generator")} ${d("Epic / Feature / PBI → .feature file")}
|
|
124
|
-
${d("3 →")} ${y("qa-playwright-generator")} ${d("Gherkin + live browser → self-healing Playwright TypeScript")}
|
|
125
|
-
${d("4 →")} ${y("qa-helix-writer")} ${d("Generated files → Helix-QA project on disk")}`;
|
|
126
|
-
|
|
127
|
-
const jiraWorkflow = `
|
|
128
|
-
${d("Jira pipeline:")}
|
|
129
|
-
${d("1 →")} ${y("qa-jira-manager")} ${d("Fetch Jira issue + analyse acceptance criteria")}
|
|
130
|
-
${d("2 →")} ${y("qa-jira-manager")} ${d("Generate test cases and create in Jira with 'is tested by' links")}
|
|
131
|
-
${d("3 →")} ${y("qa-gherkin-generator")} ${d("Generate Gherkin .feature file from Jira issue AC")}
|
|
132
|
-
${d("4 →")} ${y("qa-playwright-generator")} ${d("Gherkin + live browser → self-healing Playwright TypeScript")}
|
|
133
|
-
${d("5 →")} ${y("qa-helix-writer")} ${d("Generated files → Helix-QA project on disk")}
|
|
134
|
-
${d(" Requires: JIRA_CLIENT_ID + JIRA_CLIENT_SECRET + JIRA_CLOUD_ID in .env")}`;
|
|
135
|
-
|
|
136
|
-
const workflow =
|
|
137
|
-
integration === "ado" ? adoWorkflow
|
|
138
|
-
: integration === "jira" ? jiraWorkflow
|
|
139
|
-
: adoWorkflow + "\n" + jiraWorkflow;
|
|
140
|
-
|
|
141
|
-
console.log(`
|
|
142
|
-
${b("Setup")} — run once in your project root:
|
|
143
|
-
|
|
144
|
-
${C.cyan}qa-stlc init --vscode${initFlag}${C.reset} ${d("# GitHub Copilot / VS Code")}
|
|
145
|
-
${C.cyan}qa-stlc init${initFlag}${C.reset} ${d("# Claude Code")}
|
|
146
|
-
|
|
147
|
-
${d("Writes MCP config + installs skill files — then reload VS Code.")}
|
|
148
|
-
|
|
149
|
-
${b("Start Playwright MCP")} ${d("(keep running in a separate terminal)")}:
|
|
150
|
-
|
|
151
|
-
${C.cyan}npx @playwright/mcp@latest --port 8931${C.reset}
|
|
152
|
-
|
|
153
|
-
${b("STLC Workflow")}:
|
|
154
|
-
${workflow}
|
|
155
|
-
|
|
156
|
-
${d("Change integration at any time: qa-stlc init --integration <ado|jira|both>")}
|
|
157
94
|
${d("Docs: https://github.com/qa-gentic/stlc-agents")}
|
|
158
|
-
`);
|
|
159
|
-
}
|
|
95
|
+
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qa-gentic/stlc-agents",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "QA STLC Agents — five MCP servers + skills for AI-powered test case, Gherkin, Playwright generation, and Helix-QA file writing against Azure DevOps and Jira Cloud. Full pipeline for both: fetch → test cases → Gherkin → Playwright → Helix-QA. Works with Claude Code, GitHub Copilot, Cursor, Windsurf.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"playwright",
|
package/src/cli/cmd-skills.js
CHANGED
|
@@ -35,7 +35,7 @@ function readIntegrationPrefSk() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// Resolve the skills bundled with this npm package
|
|
38
|
-
const PKG_ROOT = path.resolve(__dirname, "
|
|
38
|
+
const PKG_ROOT = path.resolve(__dirname, "../..");
|
|
39
39
|
const SKILLS_DIR = path.join(PKG_ROOT, "skills");
|
|
40
40
|
const BEHAVIOR_MD = path.join(SKILLS_DIR, "AGENT-BEHAVIOR.md");
|
|
41
41
|
const AGENTS_DIR = path.join(PKG_ROOT, ".github", "agents");
|
|
@@ -189,7 +189,7 @@ module.exports = async function skills(opts) {
|
|
|
189
189
|
|
|
190
190
|
if (!fs.existsSync(SKILLS_DIR)) {
|
|
191
191
|
console.error(`Skills directory not found: ${SKILLS_DIR}`);
|
|
192
|
-
console.error("Try reinstalling: npm install -g @qa-stlc
|
|
192
|
+
console.error("Try reinstalling: npm install -g @qa-gentic/stlc-agents");
|
|
193
193
|
process.exit(1);
|
|
194
194
|
}
|
|
195
195
|
|