@specmind/format 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/README.md +138 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +44 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +97 -0
- package/dist/parser.js.map +1 -0
- package/dist/schemas.d.ts +42 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +26 -0
- package/dist/schemas.js.map +1 -0
- package/dist/utils.d.ts +50 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +76 -0
- package/dist/utils.js.map +1 -0
- package/dist/writer.d.ts +37 -0
- package/dist/writer.d.ts.map +1 -0
- package/dist/writer.js +135 -0
- package/dist/writer.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
# @specmind/format
|
2
|
+
|
3
|
+
.sm file format parser and writer for SpecMind.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
This package provides the core .sm file format implementation:
|
8
|
+
- **Zod schemas** for validation and type generation
|
9
|
+
- **Parser** for converting markdown to SmFile objects
|
10
|
+
- **Writer** for generating .sm files from SmFile objects
|
11
|
+
- **Utilities** for feature naming and file paths
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```bash
|
16
|
+
npm install @specmind/format
|
17
|
+
# or
|
18
|
+
pnpm add @specmind/format
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```typescript
|
24
|
+
import { parseSmFile, writeSmFile, createFeatureName } from '@specmind/format'
|
25
|
+
|
26
|
+
// Parse .sm file content
|
27
|
+
const content = '# Feature Name\n\n## Overview\nDescription...'
|
28
|
+
const result = parseSmFile(content, 'feature')
|
29
|
+
|
30
|
+
if (result.success) {
|
31
|
+
console.log(result.data.name) // "Feature Name"
|
32
|
+
console.log(result.data.requirements) // ["req1", "req2"]
|
33
|
+
|
34
|
+
// Write back to markdown
|
35
|
+
const writeResult = writeSmFile(result.data)
|
36
|
+
console.log(writeResult.content) // Generated .sm content
|
37
|
+
}
|
38
|
+
|
39
|
+
// Create feature names
|
40
|
+
const featureName = createFeatureName('User Authentication')
|
41
|
+
console.log(featureName.slug) // "user-authentication"
|
42
|
+
console.log(featureName.filename) // "user-authentication.sm"
|
43
|
+
```
|
44
|
+
|
45
|
+
## Development
|
46
|
+
|
47
|
+
### Commands
|
48
|
+
|
49
|
+
```bash
|
50
|
+
# Build package
|
51
|
+
pnpm build
|
52
|
+
|
53
|
+
# Run unit tests
|
54
|
+
pnpm test
|
55
|
+
|
56
|
+
# Type checking
|
57
|
+
pnpm lint
|
58
|
+
|
59
|
+
# Validate test fixtures (end-to-end)
|
60
|
+
pnpm validate-fixtures
|
61
|
+
|
62
|
+
# Clean build outputs
|
63
|
+
pnpm clean
|
64
|
+
```
|
65
|
+
|
66
|
+
### Testing Strategy
|
67
|
+
|
68
|
+
This package uses **two complementary testing approaches**:
|
69
|
+
|
70
|
+
#### **Unit Tests** (`pnpm test`)
|
71
|
+
- **Purpose**: Test individual functions with controlled inputs
|
72
|
+
- **Location**: `src/*.test.ts`
|
73
|
+
- **Speed**: Fast (milliseconds)
|
74
|
+
- **Examples**:
|
75
|
+
- Function behavior with edge cases
|
76
|
+
- Error handling and validation
|
77
|
+
- Small, focused test cases
|
78
|
+
|
79
|
+
#### **Fixture Validation** (`pnpm validate-fixtures`)
|
80
|
+
- **Purpose**: End-to-end validation with realistic .sm files
|
81
|
+
- **Location**: `test-fixtures/` + `scripts/validate-fixtures.mjs`
|
82
|
+
- **Speed**: Slower (file I/O, full parsing)
|
83
|
+
- **Examples**:
|
84
|
+
- Complete feature specifications
|
85
|
+
- Complex Mermaid diagrams with subgraphs
|
86
|
+
- Real-world content roundtrip testing
|
87
|
+
|
88
|
+
**Both are important**: Unit tests catch regressions and edge cases, while fixture validation ensures real-world usage works correctly.
|
89
|
+
|
90
|
+
## API Reference
|
91
|
+
|
92
|
+
### Types
|
93
|
+
|
94
|
+
```typescript
|
95
|
+
import type { SmFile, FeatureName } from '@specmind/format'
|
96
|
+
```
|
97
|
+
|
98
|
+
### Functions
|
99
|
+
|
100
|
+
- `parseSmFile(content, type?)` - Parse .sm content to SmFile object
|
101
|
+
- `writeSmFile(smFile)` - Convert SmFile object to markdown
|
102
|
+
- `validateSmFileForWriting(smFile)` - Check for writing issues
|
103
|
+
- `createFeatureName(name)` - Generate slug and filename from feature name
|
104
|
+
- `slugify(name)` - Convert string to kebab-case slug
|
105
|
+
- `getFeatureFilePath(slug)` - Get `.specmind/features/{slug}.sm` path
|
106
|
+
- `getSystemFilePath()` - Get `.specmind/system.sm` path
|
107
|
+
|
108
|
+
## .sm File Format
|
109
|
+
|
110
|
+
See [CONSTITUTION.md](../../CONSTITUTION.md) Section 4.2 for complete format specification.
|
111
|
+
|
112
|
+
**Example:**
|
113
|
+
```markdown
|
114
|
+
# Feature Name
|
115
|
+
|
116
|
+
## Overview
|
117
|
+
Feature description here.
|
118
|
+
|
119
|
+
## Requirements
|
120
|
+
- Requirement 1
|
121
|
+
- Requirement 2
|
122
|
+
|
123
|
+
## Architecture
|
124
|
+
```mermaid
|
125
|
+
graph TD
|
126
|
+
A --> B
|
127
|
+
```
|
128
|
+
|
129
|
+
## Design Decisions
|
130
|
+
Rationale and trade-offs.
|
131
|
+
|
132
|
+
## Integration Points
|
133
|
+
- Service A: Integration details
|
134
|
+
- Service B: Integration details
|
135
|
+
|
136
|
+
## Notes
|
137
|
+
Warnings, optimizations, tips.
|
138
|
+
```
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
/**
|
2
|
+
* @specmind/format
|
3
|
+
*
|
4
|
+
* Simplified .sm file format utilities for SpecMind
|
5
|
+
*
|
6
|
+
* This package provides:
|
7
|
+
* - Mermaid diagram extraction from markdown
|
8
|
+
* - Simple validation (markdown + at least one diagram)
|
9
|
+
* - Utilities for feature naming and file paths
|
10
|
+
*
|
11
|
+
* Based on CONSTITUTION.md Section 4.2:
|
12
|
+
* - .sm files are flexible markdown with any structure
|
13
|
+
* - Must contain at least one Mermaid diagram
|
14
|
+
* - No rigid section requirements
|
15
|
+
*/
|
16
|
+
export { SmFileSchema, FeatureNameSchema, type SmFile, type FeatureName } from './schemas.js';
|
17
|
+
export { extractMermaidDiagrams, validateSmFile, parseSmFile, tryParseSmFile } from './parser.js';
|
18
|
+
export { slugify, createFeatureName, isValidSlug, extractSlugFromFilename, getFeatureFilePath, getSystemFilePath } from './utils.js';
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAG7F,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
/**
|
2
|
+
* @specmind/format
|
3
|
+
*
|
4
|
+
* Simplified .sm file format utilities for SpecMind
|
5
|
+
*
|
6
|
+
* This package provides:
|
7
|
+
* - Mermaid diagram extraction from markdown
|
8
|
+
* - Simple validation (markdown + at least one diagram)
|
9
|
+
* - Utilities for feature naming and file paths
|
10
|
+
*
|
11
|
+
* Based on CONSTITUTION.md Section 4.2:
|
12
|
+
* - .sm files are flexible markdown with any structure
|
13
|
+
* - Must contain at least one Mermaid diagram
|
14
|
+
* - No rigid section requirements
|
15
|
+
*/
|
16
|
+
// Schemas
|
17
|
+
export { SmFileSchema, FeatureNameSchema } from './schemas.js';
|
18
|
+
// Parser
|
19
|
+
export { extractMermaidDiagrams, validateSmFile, parseSmFile, tryParseSmFile } from './parser.js';
|
20
|
+
// Utilities
|
21
|
+
export { slugify, createFeatureName, isValidSlug, extractSlugFromFilename, getFeatureFilePath, getSystemFilePath } from './utils.js';
|
22
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAiC,MAAM,cAAc,CAAA;AAE7F,SAAS;AACT,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,YAAY;AACZ,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,YAAY,CAAA"}
|
package/dist/parser.d.ts
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
import { SmFile } from './schemas.js';
|
2
|
+
/**
|
3
|
+
* Extracts all Mermaid diagrams from markdown content
|
4
|
+
*
|
5
|
+
* @param markdown Markdown content
|
6
|
+
* @returns Array of Mermaid diagram strings (without the ``` markers)
|
7
|
+
*/
|
8
|
+
export declare function extractMermaidDiagrams(markdown: string): string[];
|
9
|
+
/**
|
10
|
+
* Validates that content is a valid .sm file
|
11
|
+
*
|
12
|
+
* Requirements:
|
13
|
+
* - Non-empty content
|
14
|
+
* - At least one Mermaid diagram
|
15
|
+
*
|
16
|
+
* @param content Markdown content
|
17
|
+
* @returns Validation result
|
18
|
+
*/
|
19
|
+
export declare function validateSmFile(content: string): {
|
20
|
+
valid: boolean;
|
21
|
+
error?: string;
|
22
|
+
};
|
23
|
+
/**
|
24
|
+
* Parses a .sm file content
|
25
|
+
*
|
26
|
+
* @param content Markdown content
|
27
|
+
* @returns Parsed SmFile object
|
28
|
+
* @throws Error if validation fails
|
29
|
+
*/
|
30
|
+
export declare function parseSmFile(content: string): SmFile;
|
31
|
+
/**
|
32
|
+
* Safe version of parseSmFile that returns a result object
|
33
|
+
*
|
34
|
+
* @param content Markdown content
|
35
|
+
* @returns Parse result with success flag
|
36
|
+
*/
|
37
|
+
export declare function tryParseSmFile(content: string): {
|
38
|
+
success: true;
|
39
|
+
data: SmFile;
|
40
|
+
} | {
|
41
|
+
success: false;
|
42
|
+
error: string;
|
43
|
+
};
|
44
|
+
//# sourceMappingURL=parser.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,cAAc,CAAA;AAEnD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAkBlF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAenD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAC1C;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAWpC"}
|
package/dist/parser.js
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
import { SmFileSchema } from './schemas.js';
|
2
|
+
/**
|
3
|
+
* Extracts all Mermaid diagrams from markdown content
|
4
|
+
*
|
5
|
+
* @param markdown Markdown content
|
6
|
+
* @returns Array of Mermaid diagram strings (without the ``` markers)
|
7
|
+
*/
|
8
|
+
export function extractMermaidDiagrams(markdown) {
|
9
|
+
const diagrams = [];
|
10
|
+
const lines = markdown.split('\n');
|
11
|
+
let inMermaidBlock = false;
|
12
|
+
let currentDiagram = [];
|
13
|
+
for (const line of lines) {
|
14
|
+
const trimmed = line.trim();
|
15
|
+
if (trimmed === '```mermaid') {
|
16
|
+
inMermaidBlock = true;
|
17
|
+
currentDiagram = [];
|
18
|
+
continue;
|
19
|
+
}
|
20
|
+
if (trimmed === '```' && inMermaidBlock) {
|
21
|
+
inMermaidBlock = false;
|
22
|
+
if (currentDiagram.length > 0) {
|
23
|
+
diagrams.push(currentDiagram.join('\n').trim());
|
24
|
+
}
|
25
|
+
currentDiagram = [];
|
26
|
+
continue;
|
27
|
+
}
|
28
|
+
if (inMermaidBlock) {
|
29
|
+
currentDiagram.push(line);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
return diagrams;
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* Validates that content is a valid .sm file
|
36
|
+
*
|
37
|
+
* Requirements:
|
38
|
+
* - Non-empty content
|
39
|
+
* - At least one Mermaid diagram
|
40
|
+
*
|
41
|
+
* @param content Markdown content
|
42
|
+
* @returns Validation result
|
43
|
+
*/
|
44
|
+
export function validateSmFile(content) {
|
45
|
+
if (!content || content.trim().length === 0) {
|
46
|
+
return {
|
47
|
+
valid: false,
|
48
|
+
error: 'Content cannot be empty'
|
49
|
+
};
|
50
|
+
}
|
51
|
+
const diagrams = extractMermaidDiagrams(content);
|
52
|
+
if (diagrams.length === 0) {
|
53
|
+
return {
|
54
|
+
valid: false,
|
55
|
+
error: 'Must have at least one Mermaid diagram'
|
56
|
+
};
|
57
|
+
}
|
58
|
+
return { valid: true };
|
59
|
+
}
|
60
|
+
/**
|
61
|
+
* Parses a .sm file content
|
62
|
+
*
|
63
|
+
* @param content Markdown content
|
64
|
+
* @returns Parsed SmFile object
|
65
|
+
* @throws Error if validation fails
|
66
|
+
*/
|
67
|
+
export function parseSmFile(content) {
|
68
|
+
const validation = validateSmFile(content);
|
69
|
+
if (!validation.valid) {
|
70
|
+
throw new Error(validation.error);
|
71
|
+
}
|
72
|
+
const diagrams = extractMermaidDiagrams(content);
|
73
|
+
const smFile = {
|
74
|
+
content,
|
75
|
+
diagrams
|
76
|
+
};
|
77
|
+
return SmFileSchema.parse(smFile);
|
78
|
+
}
|
79
|
+
/**
|
80
|
+
* Safe version of parseSmFile that returns a result object
|
81
|
+
*
|
82
|
+
* @param content Markdown content
|
83
|
+
* @returns Parse result with success flag
|
84
|
+
*/
|
85
|
+
export function tryParseSmFile(content) {
|
86
|
+
try {
|
87
|
+
const data = parseSmFile(content);
|
88
|
+
return { success: true, data };
|
89
|
+
}
|
90
|
+
catch (error) {
|
91
|
+
return {
|
92
|
+
success: false,
|
93
|
+
error: error instanceof Error ? error.message : 'Unknown parsing error'
|
94
|
+
};
|
95
|
+
}
|
96
|
+
}
|
97
|
+
//# sourceMappingURL=parser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,cAAc,CAAA;AAEnD;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAElC,IAAI,cAAc,GAAG,KAAK,CAAA;IAC1B,IAAI,cAAc,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAE3B,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;YAC7B,cAAc,GAAG,IAAI,CAAA;YACrB,cAAc,GAAG,EAAE,CAAA;YACnB,SAAQ;QACV,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,IAAI,cAAc,EAAE,CAAC;YACxC,cAAc,GAAG,KAAK,CAAA;YACtB,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YACjD,CAAC;YACD,cAAc,GAAG,EAAE,CAAA;YACnB,SAAQ;QACV,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,yBAAyB;SACjC,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAEhD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,wCAAwC;SAChD,CAAA;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACxB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IAE1C,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAEhD,MAAM,MAAM,GAAW;QACrB,OAAO;QACP,QAAQ;KACT,CAAA;IAED,OAAO,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAI5C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;QACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAA;IACH,CAAC;AACH,CAAC"}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
/**
|
3
|
+
* Simplified schema for .sm file format
|
4
|
+
*
|
5
|
+
* Based on CONSTITUTION.md Section 4.2 (Flexible Format):
|
6
|
+
* - Markdown with any structure/sections (customizable)
|
7
|
+
* - Must contain at least one Mermaid diagram
|
8
|
+
*/
|
9
|
+
export declare const SmFileSchema: z.ZodObject<{
|
10
|
+
/** Full markdown content */
|
11
|
+
content: z.ZodString;
|
12
|
+
/** Extracted Mermaid diagrams */
|
13
|
+
diagrams: z.ZodArray<z.ZodString, "many">;
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
15
|
+
content: string;
|
16
|
+
diagrams: string[];
|
17
|
+
}, {
|
18
|
+
content: string;
|
19
|
+
diagrams: string[];
|
20
|
+
}>;
|
21
|
+
export type SmFile = z.infer<typeof SmFileSchema>;
|
22
|
+
/**
|
23
|
+
* Schema for feature naming and slugification
|
24
|
+
*/
|
25
|
+
export declare const FeatureNameSchema: z.ZodObject<{
|
26
|
+
/** Original feature name as provided by user */
|
27
|
+
original: z.ZodString;
|
28
|
+
/** Slugified name for filename (kebab-case) */
|
29
|
+
slug: z.ZodString;
|
30
|
+
/** Filename with .sm extension */
|
31
|
+
filename: z.ZodString;
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
33
|
+
original: string;
|
34
|
+
slug: string;
|
35
|
+
filename: string;
|
36
|
+
}, {
|
37
|
+
original: string;
|
38
|
+
slug: string;
|
39
|
+
filename: string;
|
40
|
+
}>;
|
41
|
+
export type FeatureName = z.infer<typeof FeatureNameSchema>;
|
42
|
+
//# sourceMappingURL=schemas.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;GAMG;AAEH,eAAO,MAAM,YAAY;IACvB,4BAA4B;;IAG5B,iCAAiC;;;;;;;;EAEjC,CAAA;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,iBAAiB;IAC5B,gDAAgD;;IAGhD,+CAA+C;;IAG/C,kCAAkC;;;;;;;;;;EAElC,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA"}
|
package/dist/schemas.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
/**
|
3
|
+
* Simplified schema for .sm file format
|
4
|
+
*
|
5
|
+
* Based on CONSTITUTION.md Section 4.2 (Flexible Format):
|
6
|
+
* - Markdown with any structure/sections (customizable)
|
7
|
+
* - Must contain at least one Mermaid diagram
|
8
|
+
*/
|
9
|
+
export const SmFileSchema = z.object({
|
10
|
+
/** Full markdown content */
|
11
|
+
content: z.string().min(1, 'Content cannot be empty'),
|
12
|
+
/** Extracted Mermaid diagrams */
|
13
|
+
diagrams: z.array(z.string()).min(1, 'Must have at least one Mermaid diagram')
|
14
|
+
});
|
15
|
+
/**
|
16
|
+
* Schema for feature naming and slugification
|
17
|
+
*/
|
18
|
+
export const FeatureNameSchema = z.object({
|
19
|
+
/** Original feature name as provided by user */
|
20
|
+
original: z.string().min(1),
|
21
|
+
/** Slugified name for filename (kebab-case) */
|
22
|
+
slug: z.string().min(1).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, 'Must be kebab-case'),
|
23
|
+
/** Filename with .sm extension */
|
24
|
+
filename: z.string().min(1).endsWith('.sm')
|
25
|
+
});
|
26
|
+
//# sourceMappingURL=schemas.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,4BAA4B;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,yBAAyB,CAAC;IAErD,iCAAiC;IACjC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;CAC/E,CAAC,CAAA;AAIF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,gDAAgD;IAChD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE3B,+CAA+C;IAC/C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,0BAA0B,EAAE,oBAAoB,CAAC;IAE/E,kCAAkC;IAClC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;CAC5C,CAAC,CAAA"}
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
import { FeatureName } from './schemas.js';
|
2
|
+
/**
|
3
|
+
* Slugifies a feature name according to CONSTITUTION.md Section 4.2
|
4
|
+
*
|
5
|
+
* Rules:
|
6
|
+
* 1. Convert to lowercase
|
7
|
+
* 2. Replace spaces and special characters with hyphens (-)
|
8
|
+
* 3. Remove leading/trailing hyphens
|
9
|
+
* 4. Use descriptive, meaningful names
|
10
|
+
* 5. No timestamps in filename
|
11
|
+
*
|
12
|
+
* @param name Original feature name
|
13
|
+
* @returns Slugified name suitable for filename
|
14
|
+
*/
|
15
|
+
export declare function slugify(name: string): string;
|
16
|
+
/**
|
17
|
+
* Creates a FeatureName object from a user-provided name
|
18
|
+
*
|
19
|
+
* @param originalName Feature name as provided by user
|
20
|
+
* @returns Validated FeatureName object
|
21
|
+
*/
|
22
|
+
export declare function createFeatureName(originalName: string): FeatureName;
|
23
|
+
/**
|
24
|
+
* Validates if a string is a valid feature slug
|
25
|
+
*
|
26
|
+
* @param slug String to validate
|
27
|
+
* @returns True if valid kebab-case slug
|
28
|
+
*/
|
29
|
+
export declare function isValidSlug(slug: string): boolean;
|
30
|
+
/**
|
31
|
+
* Extracts feature name from .sm filename
|
32
|
+
*
|
33
|
+
* @param filename .sm filename
|
34
|
+
* @returns Feature slug or null if invalid
|
35
|
+
*/
|
36
|
+
export declare function extractSlugFromFilename(filename: string): string | null;
|
37
|
+
/**
|
38
|
+
* Gets the file path for a feature .sm file
|
39
|
+
*
|
40
|
+
* @param slug Feature slug
|
41
|
+
* @returns Relative path from project root
|
42
|
+
*/
|
43
|
+
export declare function getFeatureFilePath(slug: string): string;
|
44
|
+
/**
|
45
|
+
* Gets the file path for system.sm
|
46
|
+
*
|
47
|
+
* @returns Relative path from project root
|
48
|
+
*/
|
49
|
+
export declare function getSystemFilePath(): string;
|
50
|
+
//# sourceMappingURL=utils.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqB,MAAM,cAAc,CAAA;AAE7D;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,CAWnE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
package/dist/utils.js
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
import { FeatureNameSchema } from './schemas.js';
|
2
|
+
/**
|
3
|
+
* Slugifies a feature name according to CONSTITUTION.md Section 4.2
|
4
|
+
*
|
5
|
+
* Rules:
|
6
|
+
* 1. Convert to lowercase
|
7
|
+
* 2. Replace spaces and special characters with hyphens (-)
|
8
|
+
* 3. Remove leading/trailing hyphens
|
9
|
+
* 4. Use descriptive, meaningful names
|
10
|
+
* 5. No timestamps in filename
|
11
|
+
*
|
12
|
+
* @param name Original feature name
|
13
|
+
* @returns Slugified name suitable for filename
|
14
|
+
*/
|
15
|
+
export function slugify(name) {
|
16
|
+
return name
|
17
|
+
.toLowerCase()
|
18
|
+
.replace(/[^a-z0-9]+/g, '-')
|
19
|
+
.replace(/^-|-$/g, '');
|
20
|
+
}
|
21
|
+
/**
|
22
|
+
* Creates a FeatureName object from a user-provided name
|
23
|
+
*
|
24
|
+
* @param originalName Feature name as provided by user
|
25
|
+
* @returns Validated FeatureName object
|
26
|
+
*/
|
27
|
+
export function createFeatureName(originalName) {
|
28
|
+
const slug = slugify(originalName);
|
29
|
+
const filename = `${slug}.sm`;
|
30
|
+
const featureName = {
|
31
|
+
original: originalName,
|
32
|
+
slug,
|
33
|
+
filename
|
34
|
+
};
|
35
|
+
return FeatureNameSchema.parse(featureName);
|
36
|
+
}
|
37
|
+
/**
|
38
|
+
* Validates if a string is a valid feature slug
|
39
|
+
*
|
40
|
+
* @param slug String to validate
|
41
|
+
* @returns True if valid kebab-case slug
|
42
|
+
*/
|
43
|
+
export function isValidSlug(slug) {
|
44
|
+
return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug);
|
45
|
+
}
|
46
|
+
/**
|
47
|
+
* Extracts feature name from .sm filename
|
48
|
+
*
|
49
|
+
* @param filename .sm filename
|
50
|
+
* @returns Feature slug or null if invalid
|
51
|
+
*/
|
52
|
+
export function extractSlugFromFilename(filename) {
|
53
|
+
if (!filename.endsWith('.sm')) {
|
54
|
+
return null;
|
55
|
+
}
|
56
|
+
const slug = filename.slice(0, -3); // Remove .sm extension
|
57
|
+
return isValidSlug(slug) ? slug : null;
|
58
|
+
}
|
59
|
+
/**
|
60
|
+
* Gets the file path for a feature .sm file
|
61
|
+
*
|
62
|
+
* @param slug Feature slug
|
63
|
+
* @returns Relative path from project root
|
64
|
+
*/
|
65
|
+
export function getFeatureFilePath(slug) {
|
66
|
+
return `.specmind/features/${slug}.sm`;
|
67
|
+
}
|
68
|
+
/**
|
69
|
+
* Gets the file path for system.sm
|
70
|
+
*
|
71
|
+
* @returns Relative path from project root
|
72
|
+
*/
|
73
|
+
export function getSystemFilePath() {
|
74
|
+
return '.specmind/system.sm';
|
75
|
+
}
|
76
|
+
//# sourceMappingURL=utils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,GAAG,IAAI,KAAK,CAAA;IAE7B,MAAM,WAAW,GAAG;QAClB,QAAQ,EAAE,YAAY;QACtB,IAAI;QACJ,QAAQ;KACT,CAAA;IAED,OAAO,iBAAiB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,uBAAuB;IAC1D,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,sBAAsB,IAAI,KAAK,CAAA;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,qBAAqB,CAAA;AAC9B,CAAC"}
|
package/dist/writer.d.ts
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
import { SmFile } from './schemas.js';
|
2
|
+
/**
|
3
|
+
* Converts a SmFile object to markdown format
|
4
|
+
*
|
5
|
+
* Generates .sm file content according to CONSTITUTION.md Section 4.2 format:
|
6
|
+
* - Feature name as # heading
|
7
|
+
* - Overview section with markdown content
|
8
|
+
* - Requirements as bulleted list
|
9
|
+
* - Architecture with mermaid code block
|
10
|
+
* - Design decisions as markdown
|
11
|
+
* - Integration points as bulleted list
|
12
|
+
* - Notes as markdown
|
13
|
+
*/
|
14
|
+
export interface WriteResult {
|
15
|
+
success: boolean;
|
16
|
+
content?: string;
|
17
|
+
error?: string;
|
18
|
+
}
|
19
|
+
export declare function writeSmFile(smFile: SmFile): WriteResult;
|
20
|
+
/**
|
21
|
+
* Formats a SmFile for display with metadata
|
22
|
+
*
|
23
|
+
* @param smFile SmFile object
|
24
|
+
* @returns Formatted content with metadata comments
|
25
|
+
*/
|
26
|
+
export declare function writeSmFileWithMetadata(smFile: SmFile): WriteResult;
|
27
|
+
/**
|
28
|
+
* Validates that a SmFile can be written without data loss
|
29
|
+
*
|
30
|
+
* @param smFile SmFile to validate
|
31
|
+
* @returns Validation result
|
32
|
+
*/
|
33
|
+
export declare function validateSmFileForWriting(smFile: SmFile): {
|
34
|
+
valid: boolean;
|
35
|
+
issues: string[];
|
36
|
+
};
|
37
|
+
//# sourceMappingURL=writer.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CA8EvD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CA2BnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAgC7F"}
|
package/dist/writer.js
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
export function writeSmFile(smFile) {
|
2
|
+
try {
|
3
|
+
const sections = [];
|
4
|
+
// Feature name as main heading
|
5
|
+
sections.push(`# ${smFile.name}`);
|
6
|
+
sections.push('');
|
7
|
+
// Overview section
|
8
|
+
if (smFile.overview) {
|
9
|
+
sections.push('## Overview');
|
10
|
+
sections.push('');
|
11
|
+
sections.push(smFile.overview);
|
12
|
+
sections.push('');
|
13
|
+
}
|
14
|
+
// Requirements section
|
15
|
+
if (smFile.requirements.length > 0) {
|
16
|
+
sections.push('## Requirements');
|
17
|
+
sections.push('');
|
18
|
+
for (const requirement of smFile.requirements) {
|
19
|
+
sections.push(`- ${requirement}`);
|
20
|
+
}
|
21
|
+
sections.push('');
|
22
|
+
}
|
23
|
+
// Architecture section
|
24
|
+
if (smFile.architecture) {
|
25
|
+
sections.push('## Architecture');
|
26
|
+
sections.push('');
|
27
|
+
sections.push('```mermaid');
|
28
|
+
sections.push(smFile.architecture);
|
29
|
+
sections.push('```');
|
30
|
+
sections.push('');
|
31
|
+
}
|
32
|
+
// Design decisions section
|
33
|
+
if (smFile.designDecisions) {
|
34
|
+
sections.push('## Design Decisions');
|
35
|
+
sections.push('');
|
36
|
+
sections.push(smFile.designDecisions);
|
37
|
+
sections.push('');
|
38
|
+
}
|
39
|
+
// Integration points section
|
40
|
+
if (smFile.integrationPoints.length > 0) {
|
41
|
+
sections.push('## Integration Points');
|
42
|
+
sections.push('');
|
43
|
+
for (const point of smFile.integrationPoints) {
|
44
|
+
sections.push(`- ${point}`);
|
45
|
+
}
|
46
|
+
sections.push('');
|
47
|
+
}
|
48
|
+
// Notes section
|
49
|
+
if (smFile.notes) {
|
50
|
+
sections.push('## Notes');
|
51
|
+
sections.push('');
|
52
|
+
sections.push(smFile.notes);
|
53
|
+
}
|
54
|
+
// Remove trailing empty lines
|
55
|
+
while (sections.length > 0 && sections[sections.length - 1] === '') {
|
56
|
+
sections.pop();
|
57
|
+
}
|
58
|
+
const content = sections.join('\n');
|
59
|
+
return {
|
60
|
+
success: true,
|
61
|
+
content
|
62
|
+
};
|
63
|
+
}
|
64
|
+
catch (error) {
|
65
|
+
return {
|
66
|
+
success: false,
|
67
|
+
error: error instanceof Error ? error.message : 'Unknown writing error'
|
68
|
+
};
|
69
|
+
}
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* Formats a SmFile for display with metadata
|
73
|
+
*
|
74
|
+
* @param smFile SmFile object
|
75
|
+
* @returns Formatted content with metadata comments
|
76
|
+
*/
|
77
|
+
export function writeSmFileWithMetadata(smFile) {
|
78
|
+
try {
|
79
|
+
const result = writeSmFile(smFile);
|
80
|
+
if (!result.success || !result.content) {
|
81
|
+
return result;
|
82
|
+
}
|
83
|
+
const metadata = [
|
84
|
+
`<!-- Generated by SpecMind -->`,
|
85
|
+
`<!-- Type: ${smFile.type} -->`,
|
86
|
+
`<!-- Created: ${smFile.createdAt.toISOString()} -->`,
|
87
|
+
`<!-- Updated: ${smFile.updatedAt.toISOString()} -->`,
|
88
|
+
''
|
89
|
+
];
|
90
|
+
const content = metadata.join('\n') + result.content;
|
91
|
+
return {
|
92
|
+
success: true,
|
93
|
+
content
|
94
|
+
};
|
95
|
+
}
|
96
|
+
catch (error) {
|
97
|
+
return {
|
98
|
+
success: false,
|
99
|
+
error: error instanceof Error ? error.message : 'Unknown writing error'
|
100
|
+
};
|
101
|
+
}
|
102
|
+
}
|
103
|
+
/**
|
104
|
+
* Validates that a SmFile can be written without data loss
|
105
|
+
*
|
106
|
+
* @param smFile SmFile to validate
|
107
|
+
* @returns Validation result
|
108
|
+
*/
|
109
|
+
export function validateSmFileForWriting(smFile) {
|
110
|
+
const issues = [];
|
111
|
+
if (!smFile.name.trim()) {
|
112
|
+
issues.push('Feature name is required');
|
113
|
+
}
|
114
|
+
if (smFile.architecture && !smFile.architecture.trim()) {
|
115
|
+
issues.push('Architecture section is empty but present');
|
116
|
+
}
|
117
|
+
if (smFile.requirements.some(req => !req.trim())) {
|
118
|
+
issues.push('One or more requirements are empty');
|
119
|
+
}
|
120
|
+
if (smFile.integrationPoints.some(point => !point.trim())) {
|
121
|
+
issues.push('One or more integration points are empty');
|
122
|
+
}
|
123
|
+
// Check for potentially problematic content
|
124
|
+
if (smFile.name.includes('\n')) {
|
125
|
+
issues.push('Feature name contains newlines');
|
126
|
+
}
|
127
|
+
if (smFile.architecture.includes('```')) {
|
128
|
+
issues.push('Architecture contains code block markers (``` will be added automatically)');
|
129
|
+
}
|
130
|
+
return {
|
131
|
+
valid: issues.length === 0,
|
132
|
+
issues
|
133
|
+
};
|
134
|
+
}
|
135
|
+
//# sourceMappingURL=writer.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"name": "@specmind/format",
|
3
|
+
"version": "0.1.0",
|
4
|
+
"description": ".sm file format parser and writer",
|
5
|
+
"type": "module",
|
6
|
+
"main": "./dist/index.js",
|
7
|
+
"types": "./dist/index.d.ts",
|
8
|
+
"exports": {
|
9
|
+
".": {
|
10
|
+
"types": "./dist/index.d.ts",
|
11
|
+
"import": "./dist/index.js",
|
12
|
+
"require": "./dist/index.js"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"files": [
|
16
|
+
"dist"
|
17
|
+
],
|
18
|
+
"scripts": {
|
19
|
+
"build": "tsc",
|
20
|
+
"test": "vitest",
|
21
|
+
"lint": "tsc --noEmit",
|
22
|
+
"clean": "rm -rf dist",
|
23
|
+
"validate-fixtures": "node test-fixtures/validate-fixtures.mjs"
|
24
|
+
},
|
25
|
+
"keywords": [
|
26
|
+
"specmind",
|
27
|
+
"architecture",
|
28
|
+
"documentation",
|
29
|
+
"mermaid",
|
30
|
+
"sm-format",
|
31
|
+
"parser"
|
32
|
+
],
|
33
|
+
"author": "SpecMind",
|
34
|
+
"license": "MIT",
|
35
|
+
"repository": {
|
36
|
+
"type": "git",
|
37
|
+
"url": "https://github.com/specmind/specmind.git",
|
38
|
+
"directory": "packages/format"
|
39
|
+
},
|
40
|
+
"dependencies": {
|
41
|
+
"zod": "^3.22.4"
|
42
|
+
},
|
43
|
+
"devDependencies": {
|
44
|
+
"typescript": "^5.6.3",
|
45
|
+
"vitest": "^3.2.4"
|
46
|
+
},
|
47
|
+
"publishConfig": {
|
48
|
+
"access": "public"
|
49
|
+
}
|
50
|
+
}
|