vaspera 2.10.0 → 2.10.1

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 (173) hide show
  1. package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts +2 -0
  2. package/dist/__tests__/scanners/ai-code/ai-detector.test.d.ts.map +1 -0
  3. package/dist/__tests__/scanners/ai-code/ai-detector.test.js +188 -0
  4. package/dist/__tests__/scanners/ai-code/ai-detector.test.js.map +1 -0
  5. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts +2 -0
  6. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.d.ts.map +1 -0
  7. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js +363 -0
  8. package/dist/__tests__/scanners/ai-code/confidence-scorer.test.js.map +1 -0
  9. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts +2 -0
  10. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.d.ts.map +1 -0
  11. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js +226 -0
  12. package/dist/__tests__/scanners/ai-code/hallucination-checker.test.js.map +1 -0
  13. package/dist/__tests__/scanners/ai-code/index.test.d.ts +2 -0
  14. package/dist/__tests__/scanners/ai-code/index.test.d.ts.map +1 -0
  15. package/dist/__tests__/scanners/ai-code/index.test.js +214 -0
  16. package/dist/__tests__/scanners/ai-code/index.test.js.map +1 -0
  17. package/dist/__tests__/scanners/deploy/health-checker.test.d.ts +2 -0
  18. package/dist/__tests__/scanners/deploy/health-checker.test.d.ts.map +1 -0
  19. package/dist/__tests__/scanners/deploy/health-checker.test.js +67 -0
  20. package/dist/__tests__/scanners/deploy/health-checker.test.js.map +1 -0
  21. package/dist/__tests__/scanners/deploy/index.test.d.ts +2 -0
  22. package/dist/__tests__/scanners/deploy/index.test.d.ts.map +1 -0
  23. package/dist/__tests__/scanners/deploy/index.test.js +84 -0
  24. package/dist/__tests__/scanners/deploy/index.test.js.map +1 -0
  25. package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts +2 -0
  26. package/dist/__tests__/scanners/deploy/provider-detector.test.d.ts.map +1 -0
  27. package/dist/__tests__/scanners/deploy/provider-detector.test.js +88 -0
  28. package/dist/__tests__/scanners/deploy/provider-detector.test.js.map +1 -0
  29. package/dist/__tests__/scanners/deploy/types.test.d.ts +2 -0
  30. package/dist/__tests__/scanners/deploy/types.test.d.ts.map +1 -0
  31. package/dist/__tests__/scanners/deploy/types.test.js +126 -0
  32. package/dist/__tests__/scanners/deploy/types.test.js.map +1 -0
  33. package/dist/__tests__/scanners/fp-feedback.test.js +1 -1
  34. package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -1
  35. package/dist/__tests__/scanners/fp-tracker.test.js +1 -1
  36. package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -1
  37. package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts +2 -0
  38. package/dist/__tests__/scanners/runtime/app-launcher.test.d.ts.map +1 -0
  39. package/dist/__tests__/scanners/runtime/app-launcher.test.js +94 -0
  40. package/dist/__tests__/scanners/runtime/app-launcher.test.js.map +1 -0
  41. package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts +2 -0
  42. package/dist/__tests__/scanners/runtime/golden-path-runner.test.d.ts.map +1 -0
  43. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js +195 -0
  44. package/dist/__tests__/scanners/runtime/golden-path-runner.test.js.map +1 -0
  45. package/dist/__tests__/scanners/runtime/index.test.d.ts +2 -0
  46. package/dist/__tests__/scanners/runtime/index.test.d.ts.map +1 -0
  47. package/dist/__tests__/scanners/runtime/index.test.js +120 -0
  48. package/dist/__tests__/scanners/runtime/index.test.js.map +1 -0
  49. package/dist/__tests__/scanners/runtime/types.test.d.ts +2 -0
  50. package/dist/__tests__/scanners/runtime/types.test.d.ts.map +1 -0
  51. package/dist/__tests__/scanners/runtime/types.test.js +126 -0
  52. package/dist/__tests__/scanners/runtime/types.test.js.map +1 -0
  53. package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts +2 -0
  54. package/dist/__tests__/scanners/scale/bottleneck-detector.test.d.ts.map +1 -0
  55. package/dist/__tests__/scanners/scale/bottleneck-detector.test.js +187 -0
  56. package/dist/__tests__/scanners/scale/bottleneck-detector.test.js.map +1 -0
  57. package/dist/__tests__/scanners/scale/index.test.d.ts +2 -0
  58. package/dist/__tests__/scanners/scale/index.test.d.ts.map +1 -0
  59. package/dist/__tests__/scanners/scale/index.test.js +87 -0
  60. package/dist/__tests__/scanners/scale/index.test.js.map +1 -0
  61. package/dist/__tests__/scanners/scale/load-profiler.test.d.ts +2 -0
  62. package/dist/__tests__/scanners/scale/load-profiler.test.d.ts.map +1 -0
  63. package/dist/__tests__/scanners/scale/load-profiler.test.js +122 -0
  64. package/dist/__tests__/scanners/scale/load-profiler.test.js.map +1 -0
  65. package/dist/__tests__/scanners/scale/types.test.d.ts +2 -0
  66. package/dist/__tests__/scanners/scale/types.test.d.ts.map +1 -0
  67. package/dist/__tests__/scanners/scale/types.test.js +129 -0
  68. package/dist/__tests__/scanners/scale/types.test.js.map +1 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +874 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/install-skills.d.ts +11 -0
  73. package/dist/install-skills.d.ts.map +1 -0
  74. package/dist/install-skills.js +81 -0
  75. package/dist/install-skills.js.map +1 -0
  76. package/dist/scanners/ai-code/ai-detector.d.ts +25 -0
  77. package/dist/scanners/ai-code/ai-detector.d.ts.map +1 -0
  78. package/dist/scanners/ai-code/ai-detector.js +192 -0
  79. package/dist/scanners/ai-code/ai-detector.js.map +1 -0
  80. package/dist/scanners/ai-code/confidence-scorer.d.ts +40 -0
  81. package/dist/scanners/ai-code/confidence-scorer.d.ts.map +1 -0
  82. package/dist/scanners/ai-code/confidence-scorer.js +148 -0
  83. package/dist/scanners/ai-code/confidence-scorer.js.map +1 -0
  84. package/dist/scanners/ai-code/hallucination-checker.d.ts +36 -0
  85. package/dist/scanners/ai-code/hallucination-checker.d.ts.map +1 -0
  86. package/dist/scanners/ai-code/hallucination-checker.js +298 -0
  87. package/dist/scanners/ai-code/hallucination-checker.js.map +1 -0
  88. package/dist/scanners/ai-code/index.d.ts +30 -0
  89. package/dist/scanners/ai-code/index.d.ts.map +1 -0
  90. package/dist/scanners/ai-code/index.js +224 -0
  91. package/dist/scanners/ai-code/index.js.map +1 -0
  92. package/dist/scanners/ai-code/types.d.ts +192 -0
  93. package/dist/scanners/ai-code/types.d.ts.map +1 -0
  94. package/dist/scanners/ai-code/types.js +37 -0
  95. package/dist/scanners/ai-code/types.js.map +1 -0
  96. package/dist/scanners/deploy/health-checker.d.ts +38 -0
  97. package/dist/scanners/deploy/health-checker.d.ts.map +1 -0
  98. package/dist/scanners/deploy/health-checker.js +272 -0
  99. package/dist/scanners/deploy/health-checker.js.map +1 -0
  100. package/dist/scanners/deploy/index.d.ts +44 -0
  101. package/dist/scanners/deploy/index.d.ts.map +1 -0
  102. package/dist/scanners/deploy/index.js +208 -0
  103. package/dist/scanners/deploy/index.js.map +1 -0
  104. package/dist/scanners/deploy/provider-detector.d.ts +25 -0
  105. package/dist/scanners/deploy/provider-detector.d.ts.map +1 -0
  106. package/dist/scanners/deploy/provider-detector.js +177 -0
  107. package/dist/scanners/deploy/provider-detector.js.map +1 -0
  108. package/dist/scanners/deploy/types.d.ts +406 -0
  109. package/dist/scanners/deploy/types.d.ts.map +1 -0
  110. package/dist/scanners/deploy/types.js +58 -0
  111. package/dist/scanners/deploy/types.js.map +1 -0
  112. package/dist/scanners/deploy/vercel-integration.d.ts +52 -0
  113. package/dist/scanners/deploy/vercel-integration.d.ts.map +1 -0
  114. package/dist/scanners/deploy/vercel-integration.js +280 -0
  115. package/dist/scanners/deploy/vercel-integration.js.map +1 -0
  116. package/dist/scanners/runtime/app-launcher.d.ts +33 -0
  117. package/dist/scanners/runtime/app-launcher.d.ts.map +1 -0
  118. package/dist/scanners/runtime/app-launcher.js +419 -0
  119. package/dist/scanners/runtime/app-launcher.js.map +1 -0
  120. package/dist/scanners/runtime/golden-path-runner.d.ts +48 -0
  121. package/dist/scanners/runtime/golden-path-runner.d.ts.map +1 -0
  122. package/dist/scanners/runtime/golden-path-runner.js +373 -0
  123. package/dist/scanners/runtime/golden-path-runner.js.map +1 -0
  124. package/dist/scanners/runtime/index.d.ts +41 -0
  125. package/dist/scanners/runtime/index.d.ts.map +1 -0
  126. package/dist/scanners/runtime/index.js +164 -0
  127. package/dist/scanners/runtime/index.js.map +1 -0
  128. package/dist/scanners/runtime/playwright-executor.d.ts +50 -0
  129. package/dist/scanners/runtime/playwright-executor.d.ts.map +1 -0
  130. package/dist/scanners/runtime/playwright-executor.js +387 -0
  131. package/dist/scanners/runtime/playwright-executor.js.map +1 -0
  132. package/dist/scanners/runtime/types.d.ts +215 -0
  133. package/dist/scanners/runtime/types.d.ts.map +1 -0
  134. package/dist/scanners/runtime/types.js +40 -0
  135. package/dist/scanners/runtime/types.js.map +1 -0
  136. package/dist/scanners/scale/bottleneck-detector.d.ts +17 -0
  137. package/dist/scanners/scale/bottleneck-detector.d.ts.map +1 -0
  138. package/dist/scanners/scale/bottleneck-detector.js +250 -0
  139. package/dist/scanners/scale/bottleneck-detector.js.map +1 -0
  140. package/dist/scanners/scale/capacity-estimator.d.ts +17 -0
  141. package/dist/scanners/scale/capacity-estimator.d.ts.map +1 -0
  142. package/dist/scanners/scale/capacity-estimator.js +197 -0
  143. package/dist/scanners/scale/capacity-estimator.js.map +1 -0
  144. package/dist/scanners/scale/index.d.ts +37 -0
  145. package/dist/scanners/scale/index.d.ts.map +1 -0
  146. package/dist/scanners/scale/index.js +101 -0
  147. package/dist/scanners/scale/index.js.map +1 -0
  148. package/dist/scanners/scale/load-profiler.d.ts +48 -0
  149. package/dist/scanners/scale/load-profiler.d.ts.map +1 -0
  150. package/dist/scanners/scale/load-profiler.js +377 -0
  151. package/dist/scanners/scale/load-profiler.js.map +1 -0
  152. package/dist/scanners/scale/types.d.ts +529 -0
  153. package/dist/scanners/scale/types.d.ts.map +1 -0
  154. package/dist/scanners/scale/types.js +57 -0
  155. package/dist/scanners/scale/types.js.map +1 -0
  156. package/dist/scanners/secrets.d.ts.map +1 -1
  157. package/dist/scanners/secrets.js +13 -2
  158. package/dist/scanners/secrets.js.map +1 -1
  159. package/package.json +4 -2
  160. package/skills/vaspera-add-tests/SKILL.md +102 -0
  161. package/skills/vaspera-ai-verify/SKILL.md +166 -0
  162. package/skills/vaspera-audit/SKILL.md +67 -0
  163. package/skills/vaspera-certify/SKILL.md +130 -0
  164. package/skills/vaspera-deploy/SKILL.md +152 -0
  165. package/skills/vaspera-fix-critical/SKILL.md +52 -0
  166. package/skills/vaspera-fix-high/SKILL.md +81 -0
  167. package/skills/vaspera-fix-medium/SKILL.md +56 -0
  168. package/skills/vaspera-fix-rls/SKILL.md +85 -0
  169. package/skills/vaspera-harden/SKILL.md +102 -0
  170. package/skills/vaspera-help/SKILL.md +61 -0
  171. package/skills/vaspera-load-test/SKILL.md +167 -0
  172. package/skills/vaspera-verify/SKILL.md +70 -0
  173. package/skills/vaspera-verify-e2e/SKILL.md +117 -0
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Golden Path Runner
3
+ *
4
+ * Executes user-defined flows against a running app using Playwright.
5
+ * Flows are defined in YAML files under .vaspera/flows/
6
+ *
7
+ * @module scanners/runtime/golden-path-runner
8
+ */
9
+ import { readFile, readdir, mkdir, writeFile } from "fs/promises";
10
+ import { join } from "path";
11
+ import { parse as parseYaml } from "yaml";
12
+ import { logger } from "../../logger.js";
13
+ import { GoldenPathFlowSchema, } from "./types.js";
14
+ const FLOWS_DIR = ".vaspera/flows";
15
+ const SCREENSHOTS_DIR = ".vaspera/screenshots";
16
+ /**
17
+ * Load a golden path flow from a YAML file
18
+ */
19
+ export async function loadFlow(flowPath) {
20
+ const content = await readFile(flowPath, "utf-8");
21
+ const parsed = parseYaml(content);
22
+ return GoldenPathFlowSchema.parse(parsed);
23
+ }
24
+ /**
25
+ * Discover all flows in a project
26
+ */
27
+ export async function discoverFlows(projectPath) {
28
+ const flowsDir = join(projectPath, FLOWS_DIR);
29
+ const flows = [];
30
+ try {
31
+ const files = await readdir(flowsDir);
32
+ for (const file of files) {
33
+ if (file.endsWith(".yaml") || file.endsWith(".yml")) {
34
+ try {
35
+ const flowPath = join(flowsDir, file);
36
+ const flow = await loadFlow(flowPath);
37
+ flows.push({ path: flowPath, flow });
38
+ }
39
+ catch (error) {
40
+ logger.warn("runtime.flow_parse_error", {
41
+ file,
42
+ error: error.message,
43
+ });
44
+ }
45
+ }
46
+ }
47
+ }
48
+ catch {
49
+ logger.debug("runtime.no_flows_directory", { path: flowsDir });
50
+ }
51
+ return flows;
52
+ }
53
+ /**
54
+ * Execute a single step (without Playwright - basic HTTP/assertion version)
55
+ * This is a lightweight version for initial implementation.
56
+ * Full Playwright integration will be added as a separate module.
57
+ */
58
+ async function executeStep(step, stepIndex, baseUrl, context) {
59
+ const startTime = Date.now();
60
+ try {
61
+ switch (step.action) {
62
+ case "navigate": {
63
+ const url = step.url?.startsWith("http")
64
+ ? step.url
65
+ : `${baseUrl}${step.url}`;
66
+ const response = await fetch(url, {
67
+ method: "GET",
68
+ signal: AbortSignal.timeout(step.timeout || 10000),
69
+ });
70
+ context.currentUrl = url;
71
+ context.lastResponse = response;
72
+ return {
73
+ step: stepIndex,
74
+ action: step.action,
75
+ success: response.ok,
76
+ duration: Date.now() - startTime,
77
+ error: response.ok ? undefined : `HTTP ${response.status}`,
78
+ };
79
+ }
80
+ case "api": {
81
+ const url = step.url?.startsWith("http")
82
+ ? step.url
83
+ : `${baseUrl}${step.url}`;
84
+ const response = await fetch(url, {
85
+ method: step.method || "GET",
86
+ headers: {
87
+ "Content-Type": "application/json",
88
+ ...step.headers,
89
+ },
90
+ body: step.body ? JSON.stringify(step.body) : undefined,
91
+ signal: AbortSignal.timeout(step.timeout || 10000),
92
+ });
93
+ context.lastResponse = response;
94
+ return {
95
+ step: stepIndex,
96
+ action: step.action,
97
+ success: response.ok,
98
+ duration: Date.now() - startTime,
99
+ error: response.ok ? undefined : `HTTP ${response.status}`,
100
+ };
101
+ }
102
+ case "assert": {
103
+ // For assertions, we need Playwright for DOM checks
104
+ // For now, support URL assertions only
105
+ if (step.url) {
106
+ const passed = context.currentUrl.includes(step.url);
107
+ return {
108
+ step: stepIndex,
109
+ action: step.action,
110
+ success: passed,
111
+ duration: Date.now() - startTime,
112
+ assertion: {
113
+ expected: step.url,
114
+ actual: context.currentUrl,
115
+ passed,
116
+ },
117
+ };
118
+ }
119
+ // DOM assertions require Playwright - return skipped
120
+ return {
121
+ step: stepIndex,
122
+ action: step.action,
123
+ success: true,
124
+ duration: Date.now() - startTime,
125
+ error: "DOM assertions require Playwright (skipped)",
126
+ };
127
+ }
128
+ case "wait": {
129
+ const waitTime = step.timeout || 1000;
130
+ await new Promise((resolve) => setTimeout(resolve, waitTime));
131
+ return {
132
+ step: stepIndex,
133
+ action: step.action,
134
+ success: true,
135
+ duration: Date.now() - startTime,
136
+ };
137
+ }
138
+ case "click":
139
+ case "fill":
140
+ case "select":
141
+ case "screenshot": {
142
+ // These require Playwright - return skipped
143
+ return {
144
+ step: stepIndex,
145
+ action: step.action,
146
+ success: true,
147
+ duration: Date.now() - startTime,
148
+ error: `${step.action} requires Playwright (skipped)`,
149
+ };
150
+ }
151
+ default:
152
+ return {
153
+ step: stepIndex,
154
+ action: step.action,
155
+ success: false,
156
+ duration: Date.now() - startTime,
157
+ error: `Unknown action: ${step.action}`,
158
+ };
159
+ }
160
+ }
161
+ catch (error) {
162
+ return {
163
+ step: stepIndex,
164
+ action: step.action,
165
+ success: false,
166
+ duration: Date.now() - startTime,
167
+ error: error.message,
168
+ };
169
+ }
170
+ }
171
+ /**
172
+ * Run a golden path flow
173
+ *
174
+ * By default uses lightweight HTTP-based execution.
175
+ * Pass usePlaywright: true to use full browser automation.
176
+ */
177
+ export async function runFlow(flow, baseUrl, options = {}) {
178
+ // Try Playwright if requested
179
+ if (options.usePlaywright) {
180
+ try {
181
+ const { isPlaywrightAvailable, runFlowWithPlaywright } = await import("./playwright-executor.js");
182
+ if (await isPlaywrightAvailable()) {
183
+ return runFlowWithPlaywright(flow, baseUrl, {
184
+ headless: options.headless,
185
+ slowMo: options.slowMo,
186
+ screenshotsDir: options.screenshotsDir,
187
+ });
188
+ }
189
+ logger.warn("runtime.playwright_requested_but_unavailable");
190
+ }
191
+ catch {
192
+ logger.warn("runtime.playwright_import_failed");
193
+ }
194
+ }
195
+ // Fall back to HTTP-based execution
196
+ const startTime = Date.now();
197
+ const stepResults = [];
198
+ const screenshots = [];
199
+ let failed = false;
200
+ const context = {
201
+ currentUrl: baseUrl,
202
+ lastResponse: undefined,
203
+ };
204
+ logger.info("runtime.flow_started", {
205
+ name: flow.name,
206
+ steps: flow.steps.length,
207
+ });
208
+ for (let i = 0; i < flow.steps.length; i++) {
209
+ const step = flow.steps[i];
210
+ if (failed) {
211
+ // Skip remaining steps after a failure
212
+ stepResults.push({
213
+ step: i,
214
+ action: step.action,
215
+ success: false,
216
+ duration: 0,
217
+ error: "Skipped due to previous failure",
218
+ });
219
+ continue;
220
+ }
221
+ const result = await executeStep(step, i, baseUrl, context);
222
+ stepResults.push(result);
223
+ if (!result.success && !result.error?.includes("skipped")) {
224
+ failed = true;
225
+ logger.warn("runtime.step_failed", {
226
+ flow: flow.name,
227
+ step: i,
228
+ action: step.action,
229
+ error: result.error,
230
+ });
231
+ }
232
+ else {
233
+ logger.debug("runtime.step_passed", {
234
+ flow: flow.name,
235
+ step: i,
236
+ action: step.action,
237
+ duration: result.duration,
238
+ });
239
+ }
240
+ }
241
+ const passedSteps = stepResults.filter((r) => r.success && !r.error?.includes("skipped")).length;
242
+ const failedSteps = stepResults.filter((r) => !r.success && !r.error?.includes("skipped")).length;
243
+ logger.info("runtime.flow_completed", {
244
+ name: flow.name,
245
+ passed: passedSteps,
246
+ failed: failedSteps,
247
+ duration: Date.now() - startTime,
248
+ });
249
+ return {
250
+ flowName: flow.name,
251
+ success: !failed,
252
+ totalSteps: flow.steps.length,
253
+ passedSteps,
254
+ failedSteps,
255
+ duration: Date.now() - startTime,
256
+ steps: stepResults,
257
+ screenshots,
258
+ };
259
+ }
260
+ /**
261
+ * Run all flows in a project
262
+ */
263
+ export async function runAllFlows(projectPath, baseUrl, options = {}) {
264
+ const discoveredFlows = await discoverFlows(projectPath);
265
+ const results = [];
266
+ // Filter by priority if specified
267
+ let flows = discoveredFlows;
268
+ if (options.priority) {
269
+ const priorities = [
270
+ "critical",
271
+ "high",
272
+ "medium",
273
+ "low",
274
+ ];
275
+ const minPriorityIndex = priorities.indexOf(options.priority);
276
+ flows = flows.filter((f) => {
277
+ const flowPriorityIndex = priorities.indexOf(f.flow.priority || "medium");
278
+ return flowPriorityIndex <= minPriorityIndex;
279
+ });
280
+ }
281
+ // Filter by tags if specified
282
+ if (options.tags && options.tags.length > 0) {
283
+ flows = flows.filter((f) => f.flow.tags?.some((tag) => options.tags?.includes(tag)));
284
+ }
285
+ // Sort by priority (critical first)
286
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
287
+ flows.sort((a, b) => priorityOrder[a.flow.priority || "medium"] -
288
+ priorityOrder[b.flow.priority || "medium"]);
289
+ logger.info("runtime.running_flows", {
290
+ total: flows.length,
291
+ priority: options.priority,
292
+ });
293
+ for (const { flow } of flows) {
294
+ const result = await runFlow(flow, flow.baseUrl || baseUrl, {
295
+ usePlaywright: options.usePlaywright,
296
+ headless: options.headless,
297
+ slowMo: options.slowMo,
298
+ screenshotsDir: options.screenshotsDir,
299
+ });
300
+ results.push(result);
301
+ // Stop on critical flow failure
302
+ if (!result.success && flow.priority === "critical") {
303
+ logger.error("runtime.critical_flow_failed", { name: flow.name });
304
+ break;
305
+ }
306
+ }
307
+ return results;
308
+ }
309
+ /**
310
+ * Generate a sample flow file
311
+ */
312
+ export async function generateSampleFlow(projectPath, name = "sample") {
313
+ const flowsDir = join(projectPath, FLOWS_DIR);
314
+ // Ensure directory exists
315
+ await mkdir(flowsDir, { recursive: true });
316
+ const sampleFlow = `# ${name} Golden Path Flow
317
+ # Define user flows to verify your app works correctly
318
+
319
+ name: "${name}"
320
+ description: "Sample golden path flow - customize for your app"
321
+ priority: medium
322
+ tags:
323
+ - sample
324
+ - smoke-test
325
+
326
+ steps:
327
+ # Navigate to the home page
328
+ - action: navigate
329
+ url: "/"
330
+ description: "Load home page"
331
+
332
+ # Verify home page loaded
333
+ - action: assert
334
+ url: "/"
335
+ description: "Verify on home page"
336
+
337
+ # Wait for any async content
338
+ - action: wait
339
+ timeout: 1000
340
+ description: "Wait for page to settle"
341
+
342
+ # Test an API endpoint
343
+ - action: api
344
+ url: "/api/health"
345
+ method: GET
346
+ description: "Check health endpoint"
347
+
348
+ # Navigate to another page
349
+ # - action: navigate
350
+ # url: "/about"
351
+ # description: "Go to about page"
352
+
353
+ # Fill a form (requires Playwright)
354
+ # - action: fill
355
+ # selector: "#email"
356
+ # value: "test@example.com"
357
+ # description: "Enter email"
358
+
359
+ # Click a button (requires Playwright)
360
+ # - action: click
361
+ # selector: "[data-testid='submit']"
362
+ # description: "Submit form"
363
+
364
+ # Take a screenshot (requires Playwright)
365
+ # - action: screenshot
366
+ # description: "Capture final state"
367
+ `;
368
+ const flowPath = join(flowsDir, `${name}.yaml`);
369
+ await writeFile(flowPath, sampleFlow, "utf-8");
370
+ logger.info("runtime.sample_flow_created", { path: flowPath });
371
+ return flowPath;
372
+ }
373
+ //# sourceMappingURL=golden-path-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"golden-path-runner.js","sourceRoot":"","sources":["../../../src/scanners/runtime/golden-path-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Runtime Verification Scanner
3
+ *
4
+ * Orchestrates app launching, golden path testing, and runtime verification.
5
+ * This is the entry point for M7 runtime verification capabilities.
6
+ *
7
+ * @module scanners/runtime
8
+ */
9
+ import type { RuntimeVerificationResult, GoldenPathFlow } from "./types.js";
10
+ export * from "./types.js";
11
+ export { detectFramework, launchApp, stopApp, stopAllApps, getRunningApps, } from "./app-launcher.js";
12
+ export { discoverFlows, runFlow, runAllFlows, generateSampleFlow, loadFlow, } from "./golden-path-runner.js";
13
+ export { isPlaywrightAvailable, launchBrowser, closeBrowser, runFlowWithPlaywright, } from "./playwright-executor.js";
14
+ /**
15
+ * Run full runtime verification
16
+ *
17
+ * 1. Detect framework
18
+ * 2. Launch the app
19
+ * 3. Run golden path flows
20
+ * 4. Calculate score
21
+ * 5. Stop the app
22
+ */
23
+ export declare function runRuntimeVerification(projectPath: string, options?: {
24
+ port?: number;
25
+ timeout?: number;
26
+ priority?: GoldenPathFlow["priority"];
27
+ stopAfter?: boolean;
28
+ }): Promise<RuntimeVerificationResult>;
29
+ /**
30
+ * Quick health check - just launch and verify app starts
31
+ */
32
+ export declare function quickHealthCheck(projectPath: string, options?: {
33
+ port?: number;
34
+ timeout?: number;
35
+ }): Promise<{
36
+ healthy: boolean;
37
+ url: string;
38
+ startupTime: number;
39
+ error?: string;
40
+ }>;
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,KAAK,EACV,yBAAyB,EAGzB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,SAAS,EACT,OAAO,EACP,WAAW,EACX,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,QAAQ,GACT,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAiDlC;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;CAChB,GACL,OAAO,CAAC,yBAAyB,CAAC,CAuFpC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBjF"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Runtime Verification Scanner
3
+ *
4
+ * Orchestrates app launching, golden path testing, and runtime verification.
5
+ * This is the entry point for M7 runtime verification capabilities.
6
+ *
7
+ * @module scanners/runtime
8
+ */
9
+ import { logger } from "../../logger.js";
10
+ import { detectFramework, launchApp, stopApp, } from "./app-launcher.js";
11
+ import { runAllFlows, } from "./golden-path-runner.js";
12
+ export * from "./types.js";
13
+ export { detectFramework, launchApp, stopApp, stopAllApps, getRunningApps, } from "./app-launcher.js";
14
+ export { discoverFlows, runFlow, runAllFlows, generateSampleFlow, loadFlow, } from "./golden-path-runner.js";
15
+ export { isPlaywrightAvailable, launchBrowser, closeBrowser, runFlowWithPlaywright, } from "./playwright-executor.js";
16
+ /**
17
+ * Calculate runtime verification score
18
+ */
19
+ function calculateScore(goldenPathResults) {
20
+ const goldenPathsTotal = goldenPathResults.length;
21
+ const goldenPathsPassed = goldenPathResults.filter((r) => r.success).length;
22
+ // Calculate overall score (0-100)
23
+ let overallScore = 0;
24
+ if (goldenPathsTotal > 0) {
25
+ // Golden paths are weighted by priority
26
+ const priorityWeights = { critical: 3, high: 2, medium: 1.5, low: 1 };
27
+ let weightedPassed = 0;
28
+ let totalWeight = 0;
29
+ for (const result of goldenPathResults) {
30
+ // Infer priority from flow name or default to medium
31
+ const priority = "medium"; // TODO: Store priority in result
32
+ const weight = priorityWeights[priority];
33
+ totalWeight += weight;
34
+ if (result.success) {
35
+ weightedPassed += weight;
36
+ }
37
+ }
38
+ if (totalWeight > 0) {
39
+ overallScore = Math.round((weightedPassed / totalWeight) * 100);
40
+ }
41
+ }
42
+ else {
43
+ // No flows defined - partial score
44
+ overallScore = 50; // Neutral score when no flows
45
+ }
46
+ return {
47
+ goldenPathsPassed,
48
+ goldenPathsTotal,
49
+ visualRegressionsPassed: 0, // TODO: Implement visual regression
50
+ visualRegressionsTotal: 0,
51
+ apiTestsPassed: 0, // Counted within golden paths for now
52
+ apiTestsTotal: 0,
53
+ overallScore,
54
+ };
55
+ }
56
+ /**
57
+ * Run full runtime verification
58
+ *
59
+ * 1. Detect framework
60
+ * 2. Launch the app
61
+ * 3. Run golden path flows
62
+ * 4. Calculate score
63
+ * 5. Stop the app
64
+ */
65
+ export async function runRuntimeVerification(projectPath, options = {}) {
66
+ const startTime = Date.now();
67
+ const { port, timeout = 60000, priority, stopAfter = true } = options;
68
+ logger.info("runtime.verification_started", { projectPath });
69
+ // Step 1: Detect framework
70
+ const detection = await detectFramework(projectPath);
71
+ logger.info("runtime.framework_detected", {
72
+ framework: detection.framework,
73
+ confidence: detection.confidence,
74
+ });
75
+ // Step 2: Launch the app
76
+ const launchConfig = {
77
+ projectPath,
78
+ framework: detection.framework,
79
+ port: port || detection.port,
80
+ timeout,
81
+ };
82
+ const launchResult = await launchApp(launchConfig);
83
+ if (!launchResult.success) {
84
+ return {
85
+ success: false,
86
+ framework: detection.framework,
87
+ appUrl: launchResult.url,
88
+ duration: Date.now() - startTime,
89
+ goldenPaths: [],
90
+ visualRegressions: [],
91
+ score: {
92
+ goldenPathsPassed: 0,
93
+ goldenPathsTotal: 0,
94
+ visualRegressionsPassed: 0,
95
+ visualRegressionsTotal: 0,
96
+ apiTestsPassed: 0,
97
+ apiTestsTotal: 0,
98
+ overallScore: 0,
99
+ },
100
+ error: launchResult.error || "App failed to start",
101
+ };
102
+ }
103
+ logger.info("runtime.app_launched", {
104
+ url: launchResult.url,
105
+ startupTime: launchResult.startupTime,
106
+ });
107
+ // Step 3: Run golden path flows
108
+ let goldenPathResults = [];
109
+ try {
110
+ goldenPathResults = await runAllFlows(projectPath, launchResult.url, {
111
+ priority,
112
+ });
113
+ }
114
+ catch (error) {
115
+ logger.error("runtime.golden_path_error", {
116
+ error: error.message,
117
+ });
118
+ }
119
+ // Step 4: Calculate score
120
+ const score = calculateScore(goldenPathResults);
121
+ // Step 5: Stop the app
122
+ if (stopAfter) {
123
+ await stopApp(projectPath, launchResult.port);
124
+ }
125
+ const result = {
126
+ success: score.overallScore >= 70, // Threshold for "passing"
127
+ framework: detection.framework,
128
+ appUrl: launchResult.url,
129
+ duration: Date.now() - startTime,
130
+ goldenPaths: goldenPathResults,
131
+ visualRegressions: [], // TODO: Implement
132
+ score,
133
+ };
134
+ logger.info("runtime.verification_completed", {
135
+ success: result.success,
136
+ score: score.overallScore,
137
+ duration: result.duration,
138
+ });
139
+ return result;
140
+ }
141
+ /**
142
+ * Quick health check - just launch and verify app starts
143
+ */
144
+ export async function quickHealthCheck(projectPath, options = {}) {
145
+ const { port, timeout = 30000 } = options;
146
+ const detection = await detectFramework(projectPath);
147
+ const launchResult = await launchApp({
148
+ projectPath,
149
+ framework: detection.framework,
150
+ port: port || detection.port,
151
+ timeout,
152
+ });
153
+ // Always stop after health check
154
+ if (launchResult.pid) {
155
+ await stopApp(projectPath, launchResult.port);
156
+ }
157
+ return {
158
+ healthy: launchResult.success && launchResult.healthStatus === "healthy",
159
+ url: launchResult.url,
160
+ startupTime: launchResult.startupTime,
161
+ error: launchResult.error,
162
+ };
163
+ }
164
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/scanners/runtime/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Playwright Executor
3
+ *
4
+ * Executes golden path steps using Playwright for full browser automation.
5
+ * This module is optional - falls back to HTTP-based execution when Playwright
6
+ * is not available.
7
+ *
8
+ * @module scanners/runtime/playwright-executor
9
+ */
10
+ import type { GoldenPathFlow, StepResult } from "./types.js";
11
+ /**
12
+ * Check if Playwright is available
13
+ */
14
+ export declare function isPlaywrightAvailable(): Promise<boolean>;
15
+ /**
16
+ * Launch browser for testing
17
+ */
18
+ export declare function launchBrowser(options?: {
19
+ headless?: boolean;
20
+ slowMo?: number;
21
+ }): Promise<boolean>;
22
+ /**
23
+ * Close browser
24
+ */
25
+ export declare function closeBrowser(): Promise<void>;
26
+ /**
27
+ * Execute a step using Playwright
28
+ */
29
+ export declare function executeStepWithPlaywright(step: GoldenPathFlow["steps"][0], stepIndex: number, baseUrl: string, context: {
30
+ currentUrl: string;
31
+ screenshotsDir?: string;
32
+ }): Promise<StepResult>;
33
+ /**
34
+ * Run a complete flow with Playwright
35
+ */
36
+ export declare function runFlowWithPlaywright(flow: GoldenPathFlow, baseUrl: string, options?: {
37
+ headless?: boolean;
38
+ slowMo?: number;
39
+ screenshotsDir?: string;
40
+ }): Promise<{
41
+ flowName: string;
42
+ success: boolean;
43
+ totalSteps: number;
44
+ passedSteps: number;
45
+ failedSteps: number;
46
+ duration: number;
47
+ steps: StepResult[];
48
+ screenshots: string[];
49
+ }>;
50
+ //# sourceMappingURL=playwright-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright-executor.d.ts","sourceRoot":"","sources":["../../../src/scanners/runtime/playwright-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7D;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAe9D;AAUD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBxB;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlD;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,UAAU,CAAC,CA0OrB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACpB,GACL,OAAO,CAAC;IACT,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC,CAwGD"}