@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 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
+ ```
@@ -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"}
@@ -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"}
@@ -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"}
@@ -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"}
@@ -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
+ }