@specsafe/test-gen 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agentic Engineering
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # @specsafe/test-gen
2
+
3
+ <p align="center">
4
+ <img src="https://img.shields.io/npm/v/@specsafe/test-gen.svg" alt="npm version">
5
+ <img src="https://img.shields.io/npm/l/@specsafe/test-gen.svg" alt="license">
6
+ </p>
7
+
8
+ Test generation library for the SpecSafe spec-driven development framework. Parses specifications and generates TypeScript test files.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @specsafe/test-gen
14
+ ```
15
+
16
+ ## What It Provides
17
+
18
+ - **ScenarioParser** - Parse requirement scenarios from spec files
19
+ - **TypeScriptTestGenerator** - Generate TypeScript test files from parsed requirements
20
+ - **Framework Support** - Vitest (default) and Jest
21
+
22
+ ## API Reference
23
+
24
+ ### ScenarioParser
25
+
26
+ Parses specification files and extracts requirements.
27
+
28
+ ```typescript
29
+ import { ScenarioParser } from '@specsafe/test-gen';
30
+
31
+ const parser = new ScenarioParser();
32
+ ```
33
+
34
+ #### `parseRequirements(specContent: string): Requirement[]`
35
+
36
+ Parse requirements from spec content.
37
+
38
+ ```typescript
39
+ const specContent = `
40
+ ## Requirements
41
+
42
+ ### REQ-001: User Login
43
+ **Given** a registered user with email "user@example.com"
44
+ **When** they enter the correct password
45
+ **Then** they should be redirected to the dashboard
46
+
47
+ ### REQ-002: Invalid Password
48
+ **Given** a registered user
49
+ **When** they enter an incorrect password
50
+ **Then** an error message should be displayed
51
+ `;
52
+
53
+ const requirements = parser.parseRequirements(specContent);
54
+ console.log(requirements);
55
+ // [
56
+ // {
57
+ // id: 'REQ-001',
58
+ // title: 'User Login',
59
+ // given: 'a registered user with email "user@example.com"',
60
+ // when: 'they enter the correct password',
61
+ // then: 'they should be redirected to the dashboard'
62
+ // },
63
+ // ...
64
+ // ]
65
+ ```
66
+
67
+ ---
68
+
69
+ ### TypeScriptTestGenerator
70
+
71
+ Generates TypeScript test files from requirements.
72
+
73
+ ```typescript
74
+ import { TypeScriptTestGenerator } from '@specsafe/test-gen';
75
+
76
+ const generator = new TypeScriptTestGenerator({
77
+ framework: 'vitest', // or 'jest'
78
+ specId: 'user-authentication'
79
+ });
80
+ ```
81
+
82
+ #### `generate(requirements: Requirement[]): string`
83
+
84
+ Generate test file content.
85
+
86
+ ```typescript
87
+ const requirements = [
88
+ {
89
+ id: 'REQ-001',
90
+ title: 'User Login',
91
+ given: 'a registered user',
92
+ when: 'they enter valid credentials',
93
+ then: 'they should be logged in'
94
+ }
95
+ ];
96
+
97
+ const testCode = generator.generate(requirements);
98
+ console.log(testCode);
99
+ // Output:
100
+ // import { describe, it, expect } from 'vitest';
101
+ //
102
+ // describe('User Authentication', () => {
103
+ // it('REQ-001: User Login', () => {
104
+ // // Given: a registered user
105
+ // // When: they enter valid credentials
106
+ // // Then: they should be logged in
107
+ // expect(true).toBe(true);
108
+ // });
109
+ // });
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Framework Support
115
+
116
+ ### Vitest (Default)
117
+
118
+ ```typescript
119
+ const generator = new TypeScriptTestGenerator({
120
+ framework: 'vitest',
121
+ specId: 'my-feature'
122
+ });
123
+ ```
124
+
125
+ Generates tests using Vitest's `describe`, `it`, and `expect`:
126
+
127
+ ```typescript
128
+ import { describe, it, expect } from 'vitest';
129
+
130
+ describe('My Feature', () => {
131
+ it('REQ-001: Requirement Title', () => {
132
+ // Test implementation
133
+ });
134
+ });
135
+ ```
136
+
137
+ ### Jest
138
+
139
+ ```typescript
140
+ const generator = new TypeScriptTestGenerator({
141
+ framework: 'jest',
142
+ specId: 'my-feature'
143
+ });
144
+ ```
145
+
146
+ Generates tests using Jest's globals:
147
+
148
+ ```typescript
149
+ describe('My Feature', () => {
150
+ it('REQ-001: Requirement Title', () => {
151
+ // Test implementation
152
+ });
153
+ });
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Usage Examples
159
+
160
+ ### Basic Usage
161
+
162
+ ```typescript
163
+ import { ScenarioParser, TypeScriptTestGenerator } from '@specsafe/test-gen';
164
+ import { readFileSync, writeFileSync } from 'fs';
165
+
166
+ // Read spec file
167
+ const specContent = readFileSync('./specs/active/login.spec.md', 'utf-8');
168
+
169
+ // Parse requirements
170
+ const parser = new ScenarioParser();
171
+ const requirements = parser.parseRequirements(specContent);
172
+
173
+ // Generate tests
174
+ const generator = new TypeScriptTestGenerator({
175
+ framework: 'vitest',
176
+ specId: 'login'
177
+ });
178
+
179
+ const testCode = generator.generate(requirements);
180
+
181
+ // Write to file
182
+ writeFileSync('./src/specs/login.spec.ts', testCode);
183
+ ```
184
+
185
+ ### Custom Test Body
186
+
187
+ The generated tests include comments based on the Gherkin-style requirements:
188
+
189
+ ```typescript
190
+ // Given: a registered user with valid credentials
191
+ // When: they submit the login form
192
+ // Then: they should be authenticated
193
+ ```
194
+
195
+ You fill in the actual test implementation:
196
+
197
+ ```typescript
198
+ it('REQ-001: User Login', () => {
199
+ // Given: a registered user with valid credentials
200
+ const user = createUser({ email: 'test@example.com', password: 'secret' });
201
+
202
+ // When: they submit the login form
203
+ const result = login(user.email, user.password);
204
+
205
+ // Then: they should be authenticated
206
+ expect(result.authenticated).toBe(true);
207
+ });
208
+ ```
209
+
210
+ ### Processing Multiple Specs
211
+
212
+ ```typescript
213
+ import { ScenarioParser, TypeScriptTestGenerator } from '@specsafe/test-gen';
214
+ import { readdirSync, readFileSync, writeFileSync } from 'fs';
215
+ import { join } from 'path';
216
+
217
+ const parser = new ScenarioParser();
218
+ const specsDir = './specs/active';
219
+ const outputDir = './src/specs';
220
+
221
+ const specFiles = readdirSync(specsDir).filter(f => f.endsWith('.spec.md'));
222
+
223
+ for (const file of specFiles) {
224
+ const specId = file.replace('.spec.md', '');
225
+ const content = readFileSync(join(specsDir, file), 'utf-8');
226
+
227
+ const requirements = parser.parseRequirements(content);
228
+
229
+ const generator = new TypeScriptTestGenerator({
230
+ framework: 'vitest',
231
+ specId
232
+ });
233
+
234
+ const testCode = generator.generate(requirements);
235
+ writeFileSync(join(outputDir, `${specId}.spec.ts`), testCode);
236
+
237
+ console.log(`Generated tests for ${specId}`);
238
+ }
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Specification Format
244
+
245
+ Requirements should follow this format in your spec files:
246
+
247
+ ```markdown
248
+ ## Requirements
249
+
250
+ ### REQ-XXX: Requirement Title
251
+ **Given** [context]
252
+ **When** [action]
253
+ **Then** [expected result]
254
+ ```
255
+
256
+ Where:
257
+ - `REQ-XXX` is a unique requirement ID (e.g., REQ-001, REQ-002)
258
+ - **Given** describes the initial context/state
259
+ - **When** describes the action taken
260
+ - **Then** describes the expected outcome
261
+
262
+ ---
263
+
264
+ ## License
265
+
266
+ MIT © Agentic Engineering
@@ -0,0 +1,7 @@
1
+ /**
2
+ * SpecSafe Test Generators
3
+ */
4
+ export { TypeScriptTestGenerator } from './typescript.js';
5
+ export { ScenarioParser } from './parser.js';
6
+ export type { TestGenerationOptions } from './typescript.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * SpecSafe Test Generators
3
+ */
4
+ export { TypeScriptTestGenerator } from './typescript.js';
5
+ export { ScenarioParser } from './parser.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Scenario Parser
3
+ * Extracts scenarios from spec markdown files
4
+ */
5
+ import type { Requirement } from '@specsafe/core';
6
+ export declare class ScenarioParser {
7
+ /**
8
+ * Parse requirements from spec text
9
+ */
10
+ parseRequirements(text: string): Requirement[];
11
+ private parseScenarios;
12
+ }
13
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,gBAAgB,CAAC;AAE5D,qBAAa,cAAc;IACzB;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE;IAsB9C,OAAO,CAAC,cAAc;CAyBvB"}
package/dist/parser.js ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Scenario Parser
3
+ * Extracts scenarios from spec markdown files
4
+ */
5
+ export class ScenarioParser {
6
+ /**
7
+ * Parse requirements from spec text
8
+ */
9
+ parseRequirements(text) {
10
+ // Simple parsing - could be enhanced with proper markdown parser
11
+ const requirements = [];
12
+ // Find requirement sections
13
+ const requirementMatches = text.matchAll(/###\s+Requirement:\s*(.+)/g);
14
+ for (const match of requirementMatches) {
15
+ const reqText = match[1].trim();
16
+ const scenarios = this.parseScenarios(text, match.index || 0);
17
+ requirements.push({
18
+ id: `REQ-${requirements.length + 1}`,
19
+ text: reqText,
20
+ priority: 'P1',
21
+ scenarios
22
+ });
23
+ }
24
+ return requirements;
25
+ }
26
+ parseScenarios(text, startIndex) {
27
+ const scenarios = [];
28
+ // Find scenario table after requirement, bounded by next requirement or end of text
29
+ const nextReqMatch = text.slice(startIndex + 1).search(/###\s+Requirement:/);
30
+ const endIndex = nextReqMatch !== -1 ? startIndex + 1 + nextReqMatch : text.length;
31
+ const section = text.slice(startIndex, endIndex);
32
+ const scenarioMatches = section.matchAll(/\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|/g);
33
+ let index = 0;
34
+ for (const match of scenarioMatches) {
35
+ const [, given, when, then] = match;
36
+ if (given && when && then && given.trim() !== 'GIVEN') {
37
+ scenarios.push({
38
+ id: `SC-${index++}`,
39
+ given: given.trim(),
40
+ when: when.trim(),
41
+ then: then.trim()
42
+ });
43
+ }
44
+ }
45
+ return scenarios;
46
+ }
47
+ }
48
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,cAAc;IACzB;;OAEG;IACH,iBAAiB,CAAC,IAAY;QAC5B,iEAAiE;QACjE,MAAM,YAAY,GAAkB,EAAE,CAAC;QAEvC,4BAA4B;QAC5B,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;QAEvE,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;YAE9D,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;gBACpC,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,IAAI;gBACd,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,cAAc,CAAC,IAAY,EAAE,UAAkB;QACrD,MAAM,SAAS,GAAe,EAAE,CAAC;QAEjC,oFAAoF;QACpF,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAC7E,MAAM,QAAQ,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACnF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEjD,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,kDAAkD,CAAC,CAAC;QAE7F,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;YACpC,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;gBACtD,SAAS,CAAC,IAAI,CAAC;oBACb,EAAE,EAAE,MAAM,KAAK,EAAE,EAAE;oBACnB,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;oBACnB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;oBACjB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * TypeScript/Vitest Test Generator
3
+ * Converts spec scenarios to Vitest test files
4
+ */
5
+ import type { Spec, Scenario } from '@specsafe/core';
6
+ export interface TestGenerationOptions {
7
+ framework: 'vitest' | 'jest';
8
+ includeComments: boolean;
9
+ generatePlaceholders: boolean;
10
+ }
11
+ export declare class TypeScriptTestGenerator {
12
+ private options;
13
+ constructor(options?: Partial<TestGenerationOptions>);
14
+ /**
15
+ * Generate test file content from spec
16
+ */
17
+ generate(spec: Spec): string;
18
+ private generateImports;
19
+ private generateDescribe;
20
+ private generateTest;
21
+ private scenarioToTestName;
22
+ /**
23
+ * Escape special characters in a string for use in single-quoted JS strings
24
+ */
25
+ private escapeString;
26
+ /**
27
+ * Parse scenarios from spec markdown content
28
+ */
29
+ parseScenarios(content: string): Scenario[];
30
+ }
31
+ //# sourceMappingURL=typescript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../src/typescript.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAwB;gBAE3B,OAAO,GAAE,OAAO,CAAC,qBAAqB,CAAM;IASxD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAO5B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE;CAkB5C"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * TypeScript/Vitest Test Generator
3
+ * Converts spec scenarios to Vitest test files
4
+ */
5
+ export class TypeScriptTestGenerator {
6
+ options;
7
+ constructor(options = {}) {
8
+ this.options = {
9
+ framework: 'vitest',
10
+ includeComments: true,
11
+ generatePlaceholders: true,
12
+ ...options
13
+ };
14
+ }
15
+ /**
16
+ * Generate test file content from spec
17
+ */
18
+ generate(spec) {
19
+ const imports = this.generateImports();
20
+ const describe = this.generateDescribe(spec);
21
+ return `${imports}\n\n${describe}`;
22
+ }
23
+ generateImports() {
24
+ if (this.options.framework === 'vitest') {
25
+ return "import { describe, it, expect } from 'vitest';";
26
+ }
27
+ return "import { describe, it, expect } from '@jest/globals';";
28
+ }
29
+ generateDescribe(spec) {
30
+ const tests = spec.requirements
31
+ .flatMap(r => r.scenarios)
32
+ .map(s => this.generateTest(s))
33
+ .join('\n\n');
34
+ return `describe('${this.escapeString(spec.name)}', () => {\n${tests}\n});`;
35
+ }
36
+ generateTest(scenario) {
37
+ const testName = this.escapeString(this.scenarioToTestName(scenario));
38
+ const comments = this.options.includeComments
39
+ ? ` // GIVEN: ${scenario.given}\n // WHEN: ${scenario.when}\n // THEN: ${scenario.then}\n`
40
+ : '';
41
+ const body = this.options.generatePlaceholders
42
+ ? ` expect(true).toBe(true); // TODO: Implement test`
43
+ : '';
44
+ return `${comments} it('${testName}', () => {\n${body}\n });`;
45
+ }
46
+ scenarioToTestName(scenario) {
47
+ // Convert scenario to readable test name, preserving original case
48
+ return scenario.then
49
+ .replace(/^then\s+/i, '')
50
+ .replace(/\.$/, '');
51
+ }
52
+ /**
53
+ * Escape special characters in a string for use in single-quoted JS strings
54
+ */
55
+ escapeString(str) {
56
+ return str
57
+ .replace(/\\/g, '\\\\')
58
+ .replace(/'/g, "\\'")
59
+ .replace(/\n/g, '\\n');
60
+ }
61
+ /**
62
+ * Parse scenarios from spec markdown content
63
+ */
64
+ parseScenarios(content) {
65
+ const scenarios = [];
66
+ // Match GIVEN/WHEN/THEN patterns in the content
67
+ const scenarioRegex = /(?:GIVEN|Given)\s*:\s*(.+?)(?:\n|\r)(?:WHEN|When)\s*:\s*(.+?)(?:\n|\r)(?:THEN|Then)\s*:\s*(.+?)(?:\n|\r|$)/gi;
68
+ let match;
69
+ while ((match = scenarioRegex.exec(content)) !== null) {
70
+ scenarios.push({
71
+ id: `SC-${scenarios.length + 1}`,
72
+ given: match[1].trim(),
73
+ when: match[2].trim(),
74
+ then: match[3].trim()
75
+ });
76
+ }
77
+ return scenarios;
78
+ }
79
+ }
80
+ //# sourceMappingURL=typescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../src/typescript.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@specsafe/test-gen",
3
+ "version": "0.1.0",
4
+ "description": "Test generators for SpecSafe",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=18"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ "@specsafe/core": "0.1.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^20.0.0",
30
+ "typescript": "^5.3.0",
31
+ "vitest": "^1.0.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "dev": "tsc --watch",
36
+ "test": "vitest --passWithNoTests",
37
+ "typecheck": "tsc --noEmit"
38
+ }
39
+ }