qa-toolkit-ai 1.0.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.
@@ -0,0 +1,353 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>{{PROJECT_NAME}} — QA Reports</title>
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
9
+ <style>
10
+ :root {
11
+ --base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif;
12
+ --base-font-size: 15px;
13
+ --base-line-height: 1.6;
14
+ --theme-color: #0c2340;
15
+ --sidebar-background: #0c2340;
16
+ --sidebar-nav-link-color: rgba(255,255,255,0.75);
17
+ --sidebar-nav-link-color--active: #ffffff;
18
+ --sidebar-nav-link-font-weight--active: 600;
19
+ --sidebar-name-color: #ffffff;
20
+ --sidebar-name-font-size: 1.1rem;
21
+ --sidebar-nav-link-color--hover: #ffffff;
22
+ --sidebar-border-width: 0;
23
+ --sidebar-width: 280px;
24
+ --link-color: #0c2340;
25
+ --heading-color: #0c2340;
26
+ --blockquote-border-color: #0c2340;
27
+ --code-theme-background: #f6f8fa;
28
+ --table-head-background: #0c2340;
29
+ --table-head-color: #ffffff;
30
+ --cover-background-color: #0c2340;
31
+ }
32
+
33
+ .sidebar-nav li a { font-size: 0.9rem; }
34
+
35
+ .markdown-section h1 {
36
+ border-bottom: 3px solid #0c2340;
37
+ padding-bottom: 0.4em;
38
+ }
39
+
40
+ .markdown-section table {
41
+ display: table;
42
+ width: 100%;
43
+ border-collapse: collapse;
44
+ font-size: 0.88rem;
45
+ }
46
+
47
+ .markdown-section table th {
48
+ background: #0c2340;
49
+ color: #fff;
50
+ padding: 10px 12px;
51
+ text-align: left;
52
+ font-weight: 600;
53
+ }
54
+
55
+ .markdown-section table td {
56
+ padding: 8px 12px;
57
+ border-bottom: 1px solid #e8e8e8;
58
+ }
59
+
60
+ .markdown-section table tr:hover td { background: #f0f4f8; }
61
+
62
+ /* Severity badge colors */
63
+ .badge-p0 { background: #dc2626; color: white; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 700; }
64
+ .badge-p1 { background: #ea580c; color: white; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 700; }
65
+ .badge-p2 { background: #ca8a04; color: white; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 700; }
66
+ .badge-p3 { background: #65a30d; color: white; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 700; }
67
+
68
+ /* Stats cards for dashboard */
69
+ .stats-grid {
70
+ display: grid;
71
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
72
+ gap: 16px;
73
+ margin: 24px 0;
74
+ }
75
+ .stat-card {
76
+ background: #f8fafc;
77
+ border: 1px solid #e2e8f0;
78
+ border-radius: 12px;
79
+ padding: 20px;
80
+ text-align: center;
81
+ }
82
+ .stat-card .number {
83
+ font-size: 2.2rem;
84
+ font-weight: 800;
85
+ color: #0c2340;
86
+ line-height: 1;
87
+ }
88
+ .stat-card .label {
89
+ font-size: 0.85rem;
90
+ color: #64748b;
91
+ margin-top: 4px;
92
+ }
93
+ .stat-card.critical { border-left: 4px solid #dc2626; }
94
+ .stat-card.high { border-left: 4px solid #ea580c; }
95
+ .stat-card.medium { border-left: 4px solid #ca8a04; }
96
+ .stat-card.low { border-left: 4px solid #65a30d; }
97
+
98
+ /* Severity filter toolbar */
99
+ .qa-toolbar {
100
+ display: flex;
101
+ gap: 8px;
102
+ align-items: center;
103
+ flex-wrap: wrap;
104
+ padding: 12px 16px;
105
+ background: #f8fafc;
106
+ border: 1px solid #e2e8f0;
107
+ border-radius: 10px;
108
+ margin: 20px 0;
109
+ position: sticky;
110
+ top: 0;
111
+ z-index: 100;
112
+ }
113
+ .qa-toolbar .toolbar-label {
114
+ font-size: 0.82rem;
115
+ font-weight: 600;
116
+ color: #64748b;
117
+ margin-right: 4px;
118
+ }
119
+ .qa-toolbar button {
120
+ border: none;
121
+ padding: 5px 14px;
122
+ border-radius: 6px;
123
+ font-size: 0.82rem;
124
+ font-weight: 600;
125
+ cursor: pointer;
126
+ transition: opacity 0.15s, transform 0.1s;
127
+ }
128
+ .qa-toolbar button:hover { transform: scale(1.04); }
129
+ .qa-toolbar button.inactive { opacity: 0.35; }
130
+ .qa-toolbar .btn-p0 { background: #dc2626; color: white; }
131
+ .qa-toolbar .btn-p1 { background: #ea580c; color: white; }
132
+ .qa-toolbar .btn-p2 { background: #ca8a04; color: white; }
133
+ .qa-toolbar .btn-p3 { background: #65a30d; color: white; }
134
+ .qa-toolbar .btn-all { background: #0c2340; color: white; }
135
+ .qa-toolbar .btn-pdf { background: white; color: #0c2340; border: 1px solid #cbd5e1; margin-left: auto; }
136
+ .qa-toolbar .btn-pdf:hover { background: #f1f5f9; }
137
+ .qa-toolbar .divider { width: 1px; height: 24px; background: #e2e8f0; margin: 0 4px; }
138
+
139
+ /* Hidden items when filtering */
140
+ .severity-hidden { display: none !important; }
141
+
142
+ /* Media gallery for screenshots/videos */
143
+ .media-grid {
144
+ display: grid;
145
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
146
+ gap: 16px;
147
+ margin: 16px 0;
148
+ }
149
+ .media-grid img {
150
+ width: 100%;
151
+ border-radius: 8px;
152
+ border: 1px solid #e2e8f0;
153
+ cursor: pointer;
154
+ transition: transform 0.2s;
155
+ }
156
+ .media-grid img:hover { transform: scale(1.02); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
157
+ .media-grid video {
158
+ width: 100%;
159
+ border-radius: 8px;
160
+ border: 1px solid #e2e8f0;
161
+ }
162
+ .media-card {
163
+ background: #f8fafc;
164
+ border: 1px solid #e2e8f0;
165
+ border-radius: 12px;
166
+ overflow: hidden;
167
+ }
168
+ .media-card video, .media-card img { border-radius: 0; border: none; }
169
+ .media-card .caption {
170
+ padding: 10px 14px;
171
+ font-size: 0.85rem;
172
+ color: #475569;
173
+ }
174
+
175
+ /* Lightbox for screenshots */
176
+ .lightbox-overlay {
177
+ display: none;
178
+ position: fixed;
179
+ top: 0; left: 0; right: 0; bottom: 0;
180
+ background: rgba(0,0,0,0.85);
181
+ z-index: 9999;
182
+ cursor: zoom-out;
183
+ justify-content: center;
184
+ align-items: center;
185
+ }
186
+ .lightbox-overlay.active { display: flex; }
187
+ .lightbox-overlay img {
188
+ max-width: 90vw;
189
+ max-height: 90vh;
190
+ border-radius: 8px;
191
+ }
192
+
193
+ .markdown-section li { margin: 4px 0; }
194
+
195
+ @media print {
196
+ .sidebar, .sidebar-toggle, .qa-toolbar { display: none !important; }
197
+ .content { margin-left: 0 !important; }
198
+ .severity-hidden { display: list-item !important; }
199
+ }
200
+ </style>
201
+ </head>
202
+ <body>
203
+ <div id="app"></div>
204
+
205
+ <!-- Lightbox for screenshots -->
206
+ <div class="lightbox-overlay" id="lightbox" onclick="this.classList.remove('active')">
207
+ <img id="lightbox-img" src="" alt="">
208
+ </div>
209
+
210
+ <script>
211
+ window.$docsify = {
212
+ name: '{{PROJECT_NAME}} QA',
213
+ repo: '',
214
+ loadSidebar: true,
215
+ subMaxLevel: 3,
216
+ search: {
217
+ placeholder: 'Search reports...',
218
+ noData: 'No results found',
219
+ depth: 6
220
+ },
221
+ auto2top: true,
222
+ coverpage: false,
223
+ themeable: { readyTransition: true, responsiveTables: true },
224
+ pagination: { previousText: '← Previous', nextText: 'Next →', crossChapter: true },
225
+ copyCode: { buttonText: 'Copy', successText: 'Copied' },
226
+ tabs: { persist: true, sync: true },
227
+ plugins: [
228
+ function qaToolbarPlugin(hook) {
229
+ hook.doneEach(function () {
230
+ var content = document.querySelector('.markdown-section');
231
+ if (!content) return;
232
+
233
+ var hasBadges = content.querySelector('.badge-p0, .badge-p1, .badge-p2, .badge-p3');
234
+ if (!hasBadges) return;
235
+
236
+ if (content.querySelector('.qa-toolbar')) return;
237
+
238
+ var toolbar = document.createElement('div');
239
+ toolbar.className = 'qa-toolbar';
240
+ toolbar.innerHTML =
241
+ '<span class="toolbar-label">Filter:</span>' +
242
+ '<button class="btn-all active" data-filter="all">All</button>' +
243
+ '<button class="btn-p0" data-filter="p0">P0</button>' +
244
+ '<button class="btn-p1" data-filter="p1">P1</button>' +
245
+ '<button class="btn-p2" data-filter="p2">P2</button>' +
246
+ '<button class="btn-p3" data-filter="p3">P3</button>' +
247
+ '<div class="divider"></div>' +
248
+ '<button class="btn-pdf" onclick="window.print()">Export PDF</button>';
249
+
250
+ var firstH1 = content.querySelector('h1');
251
+ if (firstH1 && firstH1.nextSibling) {
252
+ firstH1.parentNode.insertBefore(toolbar, firstH1.nextSibling);
253
+ } else {
254
+ content.insertBefore(toolbar, content.firstChild);
255
+ }
256
+
257
+ var activeFilters = new Set(['p0', 'p1', 'p2', 'p3']);
258
+
259
+ toolbar.addEventListener('click', function (e) {
260
+ var btn = e.target.closest('button[data-filter]');
261
+ if (!btn) return;
262
+ var filter = btn.dataset.filter;
263
+
264
+ if (filter === 'all') {
265
+ activeFilters = new Set(['p0', 'p1', 'p2', 'p3']);
266
+ } else {
267
+ var allBtn = toolbar.querySelector('.btn-all');
268
+
269
+ if (activeFilters.size === 4) {
270
+ activeFilters = new Set([filter]);
271
+ } else if (activeFilters.has(filter)) {
272
+ activeFilters.delete(filter);
273
+ if (activeFilters.size === 0) activeFilters = new Set(['p0', 'p1', 'p2', 'p3']);
274
+ } else {
275
+ activeFilters.add(filter);
276
+ }
277
+ }
278
+
279
+ var isAll = activeFilters.size === 4;
280
+ toolbar.querySelectorAll('button[data-filter]').forEach(function (b) {
281
+ if (b.dataset.filter === 'all') {
282
+ b.classList.toggle('inactive', !isAll);
283
+ } else {
284
+ b.classList.toggle('inactive', !activeFilters.has(b.dataset.filter));
285
+ }
286
+ });
287
+
288
+ applyFilter(content, activeFilters);
289
+ });
290
+ });
291
+ }
292
+ ]
293
+ }
294
+
295
+ function applyFilter(content, activeFilters) {
296
+ var isAll = activeFilters.size === 4;
297
+
298
+ // Filter list items (checklists, bullet lists)
299
+ content.querySelectorAll('li').forEach(function (li) {
300
+ var badge = li.querySelector('.badge-p0, .badge-p1, .badge-p2, .badge-p3');
301
+ if (!badge) return;
302
+ var level = badge.className.replace('badge-', '');
303
+ li.classList.toggle('severity-hidden', !isAll && !activeFilters.has(level));
304
+ });
305
+
306
+ // Filter h3 sections (report findings)
307
+ content.querySelectorAll('h3').forEach(function (h3) {
308
+ var badge = h3.querySelector('.badge-p0, .badge-p1, .badge-p2, .badge-p3');
309
+ if (!badge) return;
310
+ var level = badge.className.replace('badge-', '');
311
+ var hidden = !isAll && !activeFilters.has(level);
312
+
313
+ h3.classList.toggle('severity-hidden', hidden);
314
+ var el = h3.nextElementSibling;
315
+ while (el && el.tagName !== 'H3' && el.tagName !== 'H2' && el.tagName !== 'HR') {
316
+ el.classList.toggle('severity-hidden', hidden);
317
+ el = el.nextElementSibling;
318
+ }
319
+ // Also hide the <hr> after the finding block
320
+ if (el && el.tagName === 'HR') {
321
+ el.classList.toggle('severity-hidden', hidden);
322
+ }
323
+ });
324
+
325
+ // Filter table rows
326
+ content.querySelectorAll('table tbody tr, table tr').forEach(function (tr) {
327
+ var badge = tr.querySelector('.badge-p0, .badge-p1, .badge-p2, .badge-p3');
328
+ if (!badge) return;
329
+ var level = badge.className.replace('badge-', '');
330
+ tr.classList.toggle('severity-hidden', !isAll && !activeFilters.has(level));
331
+ });
332
+ }
333
+
334
+ // Lightbox for screenshots
335
+ document.addEventListener('click', function(e) {
336
+ if (e.target.matches('.media-grid img')) {
337
+ document.getElementById('lightbox-img').src = e.target.src;
338
+ document.getElementById('lightbox').classList.add('active');
339
+ }
340
+ });
341
+ </script>
342
+
343
+ <script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/docsify.min.js"></script>
344
+ <script src="https://cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.min.js"></script>
345
+ <script src="https://cdn.jsdelivr.net/npm/docsify-pagination/dist/docsify-pagination.min.js"></script>
346
+ <script src="https://cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
347
+ <script src="https://cdn.jsdelivr.net/npm/docsify-tabs@1/dist/docsify-tabs.min.js"></script>
348
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-php.min.js"></script>
349
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
350
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
351
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-yaml.min.js"></script>
352
+ </body>
353
+ </html>
@@ -0,0 +1,74 @@
1
+ # Screenshots & Videos
2
+
3
+ Evidence captured during QA run on **{{DATE}}** against branch `{{BRANCH}}`.
4
+
5
+ ---
6
+
7
+ ## Screenshots
8
+
9
+ Screenshots captured at **desktop** (1280px), **tablet** (768px), and **mobile** (375px) viewports.
10
+
11
+ ### Desktop (1280px)
12
+
13
+ <div class="media-grid">
14
+
15
+ {{DESKTOP_SCREENSHOTS}}
16
+
17
+ </div>
18
+
19
+ ### Tablet (768px)
20
+
21
+ <div class="media-grid">
22
+
23
+ {{TABLET_SCREENSHOTS}}
24
+
25
+ </div>
26
+
27
+ ### Mobile (375px)
28
+
29
+ <div class="media-grid">
30
+
31
+ {{MOBILE_SCREENSHOTS}}
32
+
33
+ </div>
34
+
35
+ ---
36
+
37
+ ## Videos
38
+
39
+ ### E2E Desktop
40
+
41
+ <div class="media-grid">
42
+ <div class="media-card">
43
+
44
+ {{E2E_DESKTOP_VIDEO}}
45
+
46
+ <div class="caption">Full critical user journey — desktop viewport</div>
47
+ </div>
48
+ </div>
49
+
50
+ ### Mobile Viewport
51
+
52
+ <div class="media-grid">
53
+ <div class="media-card">
54
+
55
+ {{MOBILE_VIDEO}}
56
+
57
+ <div class="caption">Key flows at 375×667 mobile viewport</div>
58
+ </div>
59
+ </div>
60
+
61
+ ### Tablet Viewport
62
+
63
+ <div class="media-grid">
64
+ <div class="media-card">
65
+
66
+ {{TABLET_VIDEO}}
67
+
68
+ <div class="caption">Key flows at 768×1024 tablet viewport</div>
69
+ </div>
70
+ </div>
71
+
72
+ ---
73
+
74
+ *Tip: Click any screenshot to enlarge. Videos can be played inline.*
@@ -0,0 +1,34 @@
1
+ # Functional Checklist — {{PROJECT_NAME}}
2
+
3
+ > **For:** Project Manager · **Date:** {{DATE}}
4
+ >
5
+ > Use this checklist to decide which issues to prioritise given the available budget.
6
+ > Items are sorted by **feature area** so you can review per section of the website.
7
+ > Tick off items as they are resolved or marked "won't fix".
8
+
9
+ ---
10
+
11
+ ## How to Use
12
+
13
+ 1. Go through each feature area below
14
+ 2. Each item describes what the **user sees or experiences** (no tech jargon)
15
+ 3. Severity tells you how impactful it is:
16
+ - <span class="badge-p0">P0</span> Must fix. Blocks users or breaks a critical flow.
17
+ - <span class="badge-p1">P1</span> Should fix. Clearly broken or confusing for users.
18
+ - <span class="badge-p2">P2</span> Nice to fix. Noticeable but not blocking.
19
+ - <span class="badge-p3">P3</span> Low priority. Polish and minor improvements.
20
+ 4. Mark items with your decision: ✅ Fix, ❌ Won't fix, ⏳ Later, ❓ Need to discuss
21
+
22
+ ---
23
+
24
+ {{FUNCTIONAL_CHECKLIST_CONTENT}}
25
+
26
+ ---
27
+
28
+ ## Videos & Screenshots
29
+
30
+ See [Screenshots & Videos](media.md) for visual evidence per viewport (desktop, tablet, mobile).
31
+
32
+ ---
33
+
34
+ *Checklist generated: {{DATE}} · Branch: `{{BRANCH}}`*
@@ -0,0 +1,38 @@
1
+ # Functional QA Report — {{PROJECT_NAME}}
2
+
3
+ > **For:** Project Manager, Client, Non-technical stakeholders
4
+ > **Date:** {{DATE}} · **Branch:** `{{BRANCH}}`
5
+
6
+ This report covers **what users see and experience** on the website. No code references — just plain descriptions of what's wrong, where it happens, and how important it is.
7
+
8
+ ---
9
+
10
+ ## How to Read This Report
11
+
12
+ - <span class="badge-p0">P0 — Critical</span> The user cannot complete an important action, or something is seriously broken/missing. Fix before launch.
13
+ - <span class="badge-p1">P1 — High</span> Something clearly doesn't work right or looks wrong. Users will notice and may get confused or stuck.
14
+ - <span class="badge-p2">P2 — Medium</span> A smaller issue that's noticeable but doesn't block the user. Fix when budget allows.
15
+ - <span class="badge-p3">P3 — Low</span> Polish items. Nice to fix but won't hurt the user experience much.
16
+
17
+ > **Budget tip:** Focus on P0 and P1 first. P2 items marked "visual" are often quick wins. P3 can wait for a future sprint.
18
+
19
+ ---
20
+
21
+ ## Summary
22
+
23
+ - **Total user-facing issues: {{FUNCTIONAL_COUNT}}**
24
+ - Critical (P0): {{FUNC_P0}} · High (P1): {{FUNC_P1}} · Medium (P2): {{FUNC_P2}} · Low (P3): {{FUNC_P3}}
25
+
26
+ ---
27
+
28
+ {{FUNCTIONAL_FINDINGS}}
29
+
30
+ ---
31
+
32
+ ## Screenshots
33
+
34
+ See the [Screenshots & Videos](media.md) page for visual evidence at desktop, tablet, and mobile sizes.
35
+
36
+ ---
37
+
38
+ *This is the non-technical companion to the [full technical QA report](qa-report-{{PROJECT_SLUG}}-{{DATE}}.md). For code-level details and fix instructions, share the technical report with the development team.*
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ # Setup Docsify QA Dashboard from template
3
+ # Usage: bash .cursor/qa-docsify-template/setup-docsify.sh <output_dir> <project_name> <project_slug> <branch> <date> <stack>
4
+ # Example: bash .cursor/qa-docsify-template/setup-docsify.sh qa-output "JLR MSS" "jlr-mss" "feature/my-branch" "2026-03-23" "Drupal 11 + Symfony 7.4 + React 19"
5
+
6
+ set -e
7
+
8
+ OUTPUT_DIR="${1:-qa-output}"
9
+ PROJECT_NAME="${2:-Project}"
10
+ PROJECT_SLUG="${3:-project}"
11
+ BRANCH="${4:-main}"
12
+ DATE="${5:-$(date +%Y-%m-%d)}"
13
+ STACK="${6:-Unknown}"
14
+ TEMPLATE_DIR="$(dirname "$0")"
15
+
16
+ mkdir -p "$OUTPUT_DIR/screenshots/desktop" \
17
+ "$OUTPUT_DIR/screenshots/tablet" \
18
+ "$OUTPUT_DIR/screenshots/mobile" \
19
+ "$OUTPUT_DIR/videos"
20
+
21
+ TEMPLATE_FILES="index.html _coverpage.md _sidebar.md README.md media.md qa-functional-report.md qa-functional-checklist.md"
22
+
23
+ for file in $TEMPLATE_FILES; do
24
+ if [ -f "$TEMPLATE_DIR/$file" ]; then
25
+ sed \
26
+ -e "s|{{PROJECT_NAME}}|$PROJECT_NAME|g" \
27
+ -e "s|{{PROJECT_SLUG}}|$PROJECT_SLUG|g" \
28
+ -e "s|{{BRANCH}}|$BRANCH|g" \
29
+ -e "s|{{DATE}}|$DATE|g" \
30
+ -e "s|{{STACK}}|$STACK|g" \
31
+ "$TEMPLATE_DIR/$file" > "$OUTPUT_DIR/$file"
32
+ fi
33
+ done
34
+
35
+ echo "Docsify QA dashboard scaffolded in $OUTPUT_DIR/"
36
+ echo ""
37
+ echo "Files created from template:"
38
+ for file in $TEMPLATE_FILES; do
39
+ [ -f "$OUTPUT_DIR/$file" ] && echo " $OUTPUT_DIR/$file"
40
+ done
41
+ echo ""
42
+ echo "Directories created:"
43
+ echo " $OUTPUT_DIR/screenshots/desktop/"
44
+ echo " $OUTPUT_DIR/screenshots/tablet/"
45
+ echo " $OUTPUT_DIR/screenshots/mobile/"
46
+ echo " $OUTPUT_DIR/videos/"
47
+ echo ""
48
+ echo "Remaining {{PLACEHOLDERS}} in README.md, media.md, functional reports"
49
+ echo "are filled by the qa-merge-report agent with actual counts and content."
50
+ echo ""
51
+ echo "To serve: npx docsify-cli serve $OUTPUT_DIR --port 3333"
package/install.sh ADDED
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ # QA Toolkit — Quick install (no npm required)
3
+ # Usage: bash install.sh [target_dir]
4
+ # Copies skills, rules, and Docsify template into .cursor/ of the target project.
5
+
6
+ set -e
7
+
8
+ TARGET="${1:-.}"
9
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
10
+ CURSOR_DIR="$TARGET/.cursor"
11
+
12
+ echo ""
13
+ echo " QA Toolkit — Installing into $CURSOR_DIR/"
14
+ echo ""
15
+
16
+ # Skills
17
+ for skill in qa-run qa-frontend qa-backend qa-e2e qa-merge-report; do
18
+ mkdir -p "$CURSOR_DIR/skills/$skill"
19
+ cp "$SCRIPT_DIR/skills/$skill/SKILL.md" "$CURSOR_DIR/skills/$skill/SKILL.md"
20
+ echo " + .cursor/skills/$skill/SKILL.md"
21
+ done
22
+
23
+ # Rules
24
+ mkdir -p "$CURSOR_DIR/rules"
25
+ cp "$SCRIPT_DIR/rules/qa-report-format.mdc" "$CURSOR_DIR/rules/qa-report-format.mdc"
26
+ echo " + .cursor/rules/qa-report-format.mdc"
27
+
28
+ # Docsify template
29
+ mkdir -p "$CURSOR_DIR/qa-docsify-template"
30
+ cp -r "$SCRIPT_DIR/docsify-template/"* "$CURSOR_DIR/qa-docsify-template/"
31
+ chmod +x "$CURSOR_DIR/qa-docsify-template/setup-docsify.sh" 2>/dev/null || true
32
+ echo " + .cursor/qa-docsify-template/"
33
+
34
+ echo ""
35
+ echo " Done! Your project now has QA skills and templates."
36
+ echo " Run /qa in Cursor to start a QA analysis."
37
+ echo ""
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "qa-toolkit-ai",
3
+ "version": "1.0.0",
4
+ "description": "AI-powered QA toolkit — skills, report templates, and Docsify dashboard for automated code quality analysis",
5
+ "author": "Luca Vandenweghe (L-ubu)",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/L-ubu/qa-toolkit.git"
10
+ },
11
+ "keywords": [
12
+ "qa",
13
+ "quality-assurance",
14
+ "docsify",
15
+ "testing",
16
+ "report",
17
+ "cursor",
18
+ "ai-agent",
19
+ "code-review"
20
+ ],
21
+ "bin": {
22
+ "qa-toolkit": "./bin/cli.js"
23
+ },
24
+ "files": [
25
+ "bin/",
26
+ "skills/",
27
+ "rules/",
28
+ "docsify-template/",
29
+ "install.sh",
30
+ "README.md"
31
+ ]
32
+ }