specweave 0.23.12 ā 0.23.16
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/CLAUDE.md +55 -0
- package/dist/src/core/progress/error-logger.d.ts +58 -0
- package/dist/src/core/progress/error-logger.d.ts.map +1 -0
- package/dist/src/core/progress/error-logger.js +99 -0
- package/dist/src/core/progress/error-logger.js.map +1 -0
- package/dist/src/core/spec-detector.d.ts +5 -0
- package/dist/src/core/spec-detector.d.ts.map +1 -1
- package/dist/src/core/spec-detector.js +91 -33
- package/dist/src/core/spec-detector.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/docs-changed.sh +9 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/human-input-required.sh +9 -1
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +6 -1
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +6 -1
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh +6 -1
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-metadata-change.sh +7 -1
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh +9 -1
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +9 -1
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +9 -1
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh +9 -2
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-github/.claude-plugin/plugin.json +15 -1
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +16 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +62 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh +9 -1
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +48 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-alternatives/skills/bmad-method-expert/SKILL.md +0 -626
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/analyze-project.js +0 -318
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/check-setup.js +0 -208
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/generate-template.js +0 -1149
- package/plugins/specweave-alternatives/skills/bmad-method-expert/scripts/validate-documents.js +0 -340
- package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +0 -1010
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-cost-optimizer/skills/cost-optimizer/SKILL.md +0 -190
- package/plugins/specweave-docs/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +0 -613
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/README.md +0 -264
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +0 -439
- package/plugins/specweave-docs/skills/spec-driven-debugging/README.md +0 -479
- package/plugins/specweave-docs/skills/spec-driven-debugging/SKILL.md +0 -652
- package/plugins/specweave-figma/.claude-plugin/.mcp.json +0 -12
- package/plugins/specweave-figma/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-figma/ARCHITECTURE.md +0 -453
- package/plugins/specweave-figma/README.md +0 -728
- package/plugins/specweave-figma/skills/figma-to-code/SKILL.md +0 -632
- package/plugins/specweave-figma/skills/figma-to-code/test-1-token-generation.yaml +0 -29
- package/plugins/specweave-figma/skills/figma-to-code/test-2-component-generation.yaml +0 -27
- package/plugins/specweave-figma/skills/figma-to-code/test-3-typescript-generation.yaml +0 -28
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +0 -21
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +0 -107
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +0 -177
- package/plugins/specweave-frontend/skills/nextjs/SKILL.md +0 -176
- package/plugins/specweave-testing/.claude-plugin/plugin.json +0 -20
- package/plugins/specweave-testing/skills/e2e-playwright/README.md +0 -506
- package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +0 -457
- package/plugins/specweave-testing/skills/e2e-playwright/execute.js +0 -373
- package/plugins/specweave-testing/skills/e2e-playwright/lib/utils.js +0 -514
- package/plugins/specweave-testing/skills/e2e-playwright/package.json +0 -33
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +0 -19
- package/plugins/specweave-tooling/skills/skill-creator/LICENSE.txt +0 -202
- package/plugins/specweave-tooling/skills/skill-creator/SKILL.md +0 -209
- package/plugins/specweave-tooling/skills/skill-creator/scripts/init_skill.py +0 -303
- package/plugins/specweave-tooling/skills/skill-creator/scripts/package_skill.py +0 -110
- package/plugins/specweave-tooling/skills/skill-creator/scripts/quick_validate.py +0 -65
- package/plugins/specweave-tooling/skills/skill-router/SKILL.md +0 -479
- package/plugins/specweave-ui/.claude-plugin/plugin.json +0 -26
- package/plugins/specweave-ui/.mcp.json +0 -10
- package/plugins/specweave-ui/README.md +0 -492
- package/plugins/specweave-ui/skills/browser-automation/SKILL.md +0 -676
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Playwright Test Executor for SpecWeave
|
|
5
|
-
*
|
|
6
|
-
* Universal executor that handles Playwright test scripts with intelligent
|
|
7
|
-
* code wrapping, dependency management, and SpecWeave context awareness.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* node execute.js <test-file.js> # Execute from file
|
|
11
|
-
* node execute.js "<inline-code>" # Execute inline code
|
|
12
|
-
* echo "code" | node execute.js # Execute from stdin
|
|
13
|
-
* node execute.js --version # Show version info
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const fs = require('fs');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
const { execSync } = require('child_process');
|
|
19
|
-
|
|
20
|
-
// Version info
|
|
21
|
-
const VERSION = '1.0.0';
|
|
22
|
-
const SKILL_NAME = 'e2e-playwright';
|
|
23
|
-
|
|
24
|
-
// Configuration
|
|
25
|
-
const TEMP_DIR = '/tmp';
|
|
26
|
-
const TEMP_PREFIX = 'e2e-execution-';
|
|
27
|
-
|
|
28
|
-
// ANSI colors for output
|
|
29
|
-
const colors = {
|
|
30
|
-
reset: '\x1b[0m',
|
|
31
|
-
bright: '\x1b[1m',
|
|
32
|
-
green: '\x1b[32m',
|
|
33
|
-
red: '\x1b[31m',
|
|
34
|
-
yellow: '\x1b[33m',
|
|
35
|
-
blue: '\x1b[34m',
|
|
36
|
-
cyan: '\x1b[36m'
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Print colored message
|
|
41
|
-
*/
|
|
42
|
-
function log(message, color = 'reset') {
|
|
43
|
-
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Check if Playwright is installed
|
|
48
|
-
*/
|
|
49
|
-
function isPlaywrightInstalled() {
|
|
50
|
-
try {
|
|
51
|
-
require.resolve('playwright');
|
|
52
|
-
return true;
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Install Playwright dependencies
|
|
60
|
-
*/
|
|
61
|
-
function installPlaywright() {
|
|
62
|
-
log('š¦ Installing Playwright...', 'cyan');
|
|
63
|
-
try {
|
|
64
|
-
execSync('npm install playwright', {
|
|
65
|
-
cwd: __dirname,
|
|
66
|
-
stdio: 'inherit'
|
|
67
|
-
});
|
|
68
|
-
log('ā
Playwright installed successfully', 'green');
|
|
69
|
-
} catch (error) {
|
|
70
|
-
log('ā Failed to install Playwright', 'red');
|
|
71
|
-
log(error.message, 'red');
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Check if Chromium browser is installed
|
|
78
|
-
*/
|
|
79
|
-
function isChromiumInstalled() {
|
|
80
|
-
try {
|
|
81
|
-
const { chromium } = require('playwright');
|
|
82
|
-
return true;
|
|
83
|
-
} catch {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Install Chromium browser
|
|
90
|
-
*/
|
|
91
|
-
function installChromium() {
|
|
92
|
-
log('š Installing Chromium browser...', 'cyan');
|
|
93
|
-
try {
|
|
94
|
-
execSync('npx playwright install chromium', {
|
|
95
|
-
cwd: __dirname,
|
|
96
|
-
stdio: 'inherit'
|
|
97
|
-
});
|
|
98
|
-
log('ā
Chromium installed successfully', 'green');
|
|
99
|
-
} catch (error) {
|
|
100
|
-
log('ā Failed to install Chromium', 'red');
|
|
101
|
-
log(error.message, 'red');
|
|
102
|
-
process.exit(1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Ensure Playwright and browser are installed
|
|
108
|
-
*/
|
|
109
|
-
function ensureDependencies() {
|
|
110
|
-
if (!isPlaywrightInstalled()) {
|
|
111
|
-
installPlaywright();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!isChromiumInstalled()) {
|
|
115
|
-
installChromium();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Read code from various input sources
|
|
121
|
-
*/
|
|
122
|
-
function readCode() {
|
|
123
|
-
const args = process.argv.slice(2);
|
|
124
|
-
|
|
125
|
-
// Handle --version flag
|
|
126
|
-
if (args.includes('--version') || args.includes('-v')) {
|
|
127
|
-
log(`${SKILL_NAME} v${VERSION}`, 'cyan');
|
|
128
|
-
process.exit(0);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// No arguments - check stdin
|
|
132
|
-
if (args.length === 0) {
|
|
133
|
-
if (!process.stdin.isTTY) {
|
|
134
|
-
// Read from stdin (piped input)
|
|
135
|
-
const chunks = [];
|
|
136
|
-
process.stdin.on('data', chunk => chunks.push(chunk));
|
|
137
|
-
process.stdin.on('end', () => {
|
|
138
|
-
const code = Buffer.concat(chunks).toString('utf8');
|
|
139
|
-
if (code.trim()) {
|
|
140
|
-
executeCode(code);
|
|
141
|
-
} else {
|
|
142
|
-
showUsage();
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
return;
|
|
147
|
-
} else {
|
|
148
|
-
showUsage();
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const input = args[0];
|
|
154
|
-
|
|
155
|
-
// Check if input is a file path
|
|
156
|
-
if (fs.existsSync(input)) {
|
|
157
|
-
const code = fs.readFileSync(input, 'utf8');
|
|
158
|
-
executeCode(code);
|
|
159
|
-
} else {
|
|
160
|
-
// Treat as inline code
|
|
161
|
-
executeCode(input);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Show usage information
|
|
167
|
-
*/
|
|
168
|
-
function showUsage() {
|
|
169
|
-
log(`
|
|
170
|
-
${SKILL_NAME} v${VERSION} - Playwright Test Executor
|
|
171
|
-
|
|
172
|
-
Usage:
|
|
173
|
-
node execute.js <test-file.js> Execute test from file
|
|
174
|
-
node execute.js "<inline-code>" Execute inline code
|
|
175
|
-
echo "code" | node execute.js Execute from stdin
|
|
176
|
-
node execute.js --version Show version info
|
|
177
|
-
|
|
178
|
-
Examples:
|
|
179
|
-
node execute.js /tmp/login-test.js
|
|
180
|
-
node execute.js "console.log('Hello')"
|
|
181
|
-
echo "await page.goto('http://localhost:3000')" | node execute.js
|
|
182
|
-
|
|
183
|
-
Documentation:
|
|
184
|
-
See SKILL.md for complete API reference and examples
|
|
185
|
-
`, 'cyan');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Determine if code needs wrapping
|
|
190
|
-
*/
|
|
191
|
-
function needsWrapping(code) {
|
|
192
|
-
const hasRequire = code.includes('require(\'playwright\')') || code.includes('require("playwright")');
|
|
193
|
-
const hasImport = code.includes('import') && code.includes('playwright');
|
|
194
|
-
const hasAsyncWrapper = code.includes('(async ()') || code.includes('(async function');
|
|
195
|
-
|
|
196
|
-
return !hasRequire && !hasImport && !hasAsyncWrapper;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Wrap code with Playwright imports and async IIFE
|
|
201
|
-
*/
|
|
202
|
-
function wrapCode(code) {
|
|
203
|
-
return `
|
|
204
|
-
// Auto-generated wrapper by ${SKILL_NAME}
|
|
205
|
-
const { chromium, firefox, webkit, devices } = require('playwright');
|
|
206
|
-
|
|
207
|
-
// Helper utilities
|
|
208
|
-
const utils = require('${path.join(__dirname, 'lib', 'utils.js')}');
|
|
209
|
-
|
|
210
|
-
// Make utilities available globally
|
|
211
|
-
Object.assign(global, utils);
|
|
212
|
-
|
|
213
|
-
(async () => {
|
|
214
|
-
try {
|
|
215
|
-
${code}
|
|
216
|
-
} catch (error) {
|
|
217
|
-
console.error('ā Test execution failed:', error.message);
|
|
218
|
-
console.error(error.stack);
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
})();
|
|
222
|
-
`;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Clean up old temporary execution files
|
|
227
|
-
*/
|
|
228
|
-
function cleanupOldTempFiles() {
|
|
229
|
-
try {
|
|
230
|
-
const files = fs.readdirSync(TEMP_DIR);
|
|
231
|
-
const oldFiles = files.filter(f =>
|
|
232
|
-
f.startsWith(TEMP_PREFIX) &&
|
|
233
|
-
f.endsWith('.js')
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
// Keep only the 5 most recent files
|
|
237
|
-
if (oldFiles.length > 5) {
|
|
238
|
-
const sorted = oldFiles
|
|
239
|
-
.map(f => ({
|
|
240
|
-
name: f,
|
|
241
|
-
time: fs.statSync(path.join(TEMP_DIR, f)).mtime.getTime()
|
|
242
|
-
}))
|
|
243
|
-
.sort((a, b) => b.time - a.time);
|
|
244
|
-
|
|
245
|
-
// Delete older files
|
|
246
|
-
sorted.slice(5).forEach(({ name }) => {
|
|
247
|
-
try {
|
|
248
|
-
fs.unlinkSync(path.join(TEMP_DIR, name));
|
|
249
|
-
log(`šļø Cleaned up old temp file: ${name}`, 'yellow');
|
|
250
|
-
} catch (e) {
|
|
251
|
-
// Ignore cleanup errors
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
} catch (error) {
|
|
256
|
-
// Ignore cleanup errors - not critical
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Detect SpecWeave context
|
|
262
|
-
*/
|
|
263
|
-
function detectSpecWeaveContext() {
|
|
264
|
-
const cwd = process.cwd();
|
|
265
|
-
const specweavePath = path.join(cwd, '.specweave');
|
|
266
|
-
|
|
267
|
-
if (!fs.existsSync(specweavePath)) {
|
|
268
|
-
return { isSpecweaveProject: false };
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Find active increment (in-progress status)
|
|
272
|
-
const incrementsPath = path.join(specweavePath, 'increments');
|
|
273
|
-
if (!fs.existsSync(incrementsPath)) {
|
|
274
|
-
return { isSpecweaveProject: true };
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
try {
|
|
278
|
-
const increments = fs.readdirSync(incrementsPath)
|
|
279
|
-
.filter(name => /^\d{4}-/.test(name));
|
|
280
|
-
|
|
281
|
-
// Look for tasks.md with in-progress status
|
|
282
|
-
for (const increment of increments) {
|
|
283
|
-
const tasksPath = path.join(incrementsPath, increment, 'tasks.md');
|
|
284
|
-
if (fs.existsSync(tasksPath)) {
|
|
285
|
-
const tasksContent = fs.readFileSync(tasksPath, 'utf8');
|
|
286
|
-
if (tasksContent.includes('## Status: in-progress')) {
|
|
287
|
-
return {
|
|
288
|
-
isSpecweaveProject: true,
|
|
289
|
-
activeIncrement: increment,
|
|
290
|
-
incrementPath: path.join(incrementsPath, increment),
|
|
291
|
-
reportsPath: path.join(incrementsPath, increment, 'reports')
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
} catch (e) {
|
|
297
|
-
// Continue without increment context
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return { isSpecweaveProject: true };
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Execute Playwright code
|
|
305
|
-
*/
|
|
306
|
-
function executeCode(code) {
|
|
307
|
-
log('\nš Starting Playwright execution...', 'bright');
|
|
308
|
-
|
|
309
|
-
// Detect SpecWeave context
|
|
310
|
-
const context = detectSpecWeaveContext();
|
|
311
|
-
if (context.isSpecweaveProject) {
|
|
312
|
-
log('š· SpecWeave project detected', 'cyan');
|
|
313
|
-
if (context.activeIncrement) {
|
|
314
|
-
log(`š¦ Active increment: ${context.activeIncrement}`, 'cyan');
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Wrap code if needed
|
|
319
|
-
const processedCode = needsWrapping(code) ? wrapCode(code) : code;
|
|
320
|
-
|
|
321
|
-
// Create temporary file with timestamp
|
|
322
|
-
const timestamp = Date.now();
|
|
323
|
-
const tempFile = path.join(TEMP_DIR, `${TEMP_PREFIX}${timestamp}.js`);
|
|
324
|
-
|
|
325
|
-
try {
|
|
326
|
-
// Write code to temp file
|
|
327
|
-
fs.writeFileSync(tempFile, processedCode, 'utf8');
|
|
328
|
-
log(`š Test script: ${tempFile}`, 'blue');
|
|
329
|
-
|
|
330
|
-
// Clean up old files
|
|
331
|
-
cleanupOldTempFiles();
|
|
332
|
-
|
|
333
|
-
// Execute from skill directory for proper module resolution
|
|
334
|
-
log('š Executing test...', 'bright');
|
|
335
|
-
log('ā'.repeat(60), 'blue');
|
|
336
|
-
|
|
337
|
-
const startTime = Date.now();
|
|
338
|
-
|
|
339
|
-
// Execute the test
|
|
340
|
-
require(tempFile);
|
|
341
|
-
|
|
342
|
-
// Note: For async code, the process will exit when the async function completes
|
|
343
|
-
// or errors out, so we don't need explicit waiting here
|
|
344
|
-
|
|
345
|
-
} catch (error) {
|
|
346
|
-
log('\nā Execution failed', 'red');
|
|
347
|
-
log(error.message, 'red');
|
|
348
|
-
if (error.stack) {
|
|
349
|
-
log('\nStack trace:', 'yellow');
|
|
350
|
-
log(error.stack, 'yellow');
|
|
351
|
-
}
|
|
352
|
-
process.exit(1);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Main execution
|
|
357
|
-
function main() {
|
|
358
|
-
// Change to skill directory for module resolution
|
|
359
|
-
process.chdir(__dirname);
|
|
360
|
-
|
|
361
|
-
// Ensure dependencies are installed
|
|
362
|
-
ensureDependencies();
|
|
363
|
-
|
|
364
|
-
// Read and execute code
|
|
365
|
-
readCode();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Run if called directly
|
|
369
|
-
if (require.main === module) {
|
|
370
|
-
main();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
module.exports = { executeCode, detectSpecWeaveContext };
|