@sudocode-ai/integration-speckit 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/id-generator.d.ts +149 -0
  2. package/dist/id-generator.d.ts.map +1 -0
  3. package/dist/id-generator.js +197 -0
  4. package/dist/id-generator.js.map +1 -0
  5. package/dist/index.d.ts +33 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +1017 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/parser/index.d.ts +11 -0
  10. package/dist/parser/index.d.ts.map +1 -0
  11. package/dist/parser/index.js +16 -0
  12. package/dist/parser/index.js.map +1 -0
  13. package/dist/parser/markdown-utils.d.ts +138 -0
  14. package/dist/parser/markdown-utils.d.ts.map +1 -0
  15. package/dist/parser/markdown-utils.js +283 -0
  16. package/dist/parser/markdown-utils.js.map +1 -0
  17. package/dist/parser/plan-parser.d.ts +97 -0
  18. package/dist/parser/plan-parser.d.ts.map +1 -0
  19. package/dist/parser/plan-parser.js +286 -0
  20. package/dist/parser/plan-parser.js.map +1 -0
  21. package/dist/parser/spec-parser.d.ts +95 -0
  22. package/dist/parser/spec-parser.d.ts.map +1 -0
  23. package/dist/parser/spec-parser.js +250 -0
  24. package/dist/parser/spec-parser.js.map +1 -0
  25. package/dist/parser/supporting-docs.d.ts +119 -0
  26. package/dist/parser/supporting-docs.d.ts.map +1 -0
  27. package/dist/parser/supporting-docs.js +324 -0
  28. package/dist/parser/supporting-docs.js.map +1 -0
  29. package/dist/parser/tasks-parser.d.ts +171 -0
  30. package/dist/parser/tasks-parser.d.ts.map +1 -0
  31. package/dist/parser/tasks-parser.js +281 -0
  32. package/dist/parser/tasks-parser.js.map +1 -0
  33. package/dist/relationship-mapper.d.ts +165 -0
  34. package/dist/relationship-mapper.d.ts.map +1 -0
  35. package/dist/relationship-mapper.js +238 -0
  36. package/dist/relationship-mapper.js.map +1 -0
  37. package/dist/watcher.d.ts +137 -0
  38. package/dist/watcher.d.ts.map +1 -0
  39. package/dist/watcher.js +599 -0
  40. package/dist/watcher.js.map +1 -0
  41. package/dist/writer/index.d.ts +8 -0
  42. package/dist/writer/index.d.ts.map +1 -0
  43. package/dist/writer/index.js +10 -0
  44. package/dist/writer/index.js.map +1 -0
  45. package/dist/writer/spec-writer.d.ts +70 -0
  46. package/dist/writer/spec-writer.d.ts.map +1 -0
  47. package/dist/writer/spec-writer.js +261 -0
  48. package/dist/writer/spec-writer.js.map +1 -0
  49. package/dist/writer/tasks-writer.d.ts +47 -0
  50. package/dist/writer/tasks-writer.d.ts.map +1 -0
  51. package/dist/writer/tasks-writer.js +161 -0
  52. package/dist/writer/tasks-writer.js.map +1 -0
  53. package/package.json +42 -0
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Plan Parser for Spec-Kit Integration
3
+ *
4
+ * Parses plan.md files from spec-kit and extracts structured data.
5
+ *
6
+ * Expected format:
7
+ * ```markdown
8
+ * # Implementation Plan: [FEATURE]
9
+ *
10
+ * **Branch**: feature/xxx
11
+ * **Spec**: [[s-001-spec]] or spec.md link
12
+ * **Status**: Draft
13
+ *
14
+ * ## Overview
15
+ * ...
16
+ * ```
17
+ */
18
+ import { readFileSync, existsSync } from "fs";
19
+ import { PATTERNS, extractMetadata, extractTitleWithPrefixRemoval, extractCrossReferences, findContentStartIndex, parseDate, normalizeStatus, } from "./markdown-utils.js";
20
+ /**
21
+ * Parse a plan.md file and extract structured data
22
+ *
23
+ * @param filePath - Absolute path to the plan.md file
24
+ * @param options - Parsing options
25
+ * @returns Parsed plan data or null if file doesn't exist
26
+ *
27
+ * @example
28
+ * const plan = parsePlan("/project/.specify/specs/001-auth/plan.md");
29
+ * console.log(plan?.title); // "Authentication"
30
+ * console.log(plan?.specReference); // "spec.md" or "s-001-spec"
31
+ */
32
+ export function parsePlan(filePath, options = {}) {
33
+ const { includeContent = true, extractReferences = true } = options;
34
+ if (!existsSync(filePath)) {
35
+ return null;
36
+ }
37
+ try {
38
+ const rawContent = readFileSync(filePath, "utf-8");
39
+ const lines = rawContent.split("\n");
40
+ // Extract raw title
41
+ const rawTitle = extractRawTitle(lines);
42
+ if (!rawTitle) {
43
+ return null; // Invalid plan file without title
44
+ }
45
+ // Clean title by removing prefix
46
+ const title = extractTitleWithPrefixRemoval(lines, [
47
+ "Implementation Plan:",
48
+ "Implementation Plan",
49
+ ]) || rawTitle;
50
+ // Extract metadata
51
+ const metadata = extractMetadata(lines);
52
+ // Extract specific metadata fields
53
+ const branch = extractBranch(lines, metadata);
54
+ const specReference = extractSpecReference(lines, metadata);
55
+ const status = extractStatus(metadata);
56
+ const createdAt = extractCreatedDate(metadata);
57
+ // Extract main content
58
+ let content = "";
59
+ if (includeContent) {
60
+ const contentStartIndex = findContentStartIndex(lines);
61
+ content = lines.slice(contentStartIndex).join("\n").trim();
62
+ }
63
+ // Extract cross-references
64
+ let crossReferences = [];
65
+ if (extractReferences) {
66
+ crossReferences = extractCrossReferences(rawContent);
67
+ }
68
+ return {
69
+ title,
70
+ rawTitle,
71
+ branch,
72
+ specReference,
73
+ status,
74
+ createdAt,
75
+ metadata,
76
+ content,
77
+ crossReferences,
78
+ filePath,
79
+ };
80
+ }
81
+ catch (error) {
82
+ console.error(`[plan-parser] Failed to parse ${filePath}:`, error);
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Parse plan content from a string (for testing or in-memory parsing)
88
+ *
89
+ * @param content - Markdown content string
90
+ * @param filePath - Optional file path for reference
91
+ * @returns Parsed plan data or null
92
+ */
93
+ export function parsePlanContent(content, filePath = "<string>") {
94
+ const lines = content.split("\n");
95
+ // Extract raw title
96
+ const rawTitle = extractRawTitle(lines);
97
+ if (!rawTitle) {
98
+ return null;
99
+ }
100
+ // Clean title by removing prefix
101
+ const title = extractTitleWithPrefixRemoval(lines, [
102
+ "Implementation Plan:",
103
+ "Implementation Plan",
104
+ ]) || rawTitle;
105
+ // Extract metadata
106
+ const metadata = extractMetadata(lines);
107
+ // Extract specific metadata fields
108
+ const branch = extractBranch(lines, metadata);
109
+ const specReference = extractSpecReference(lines, metadata);
110
+ const status = extractStatus(metadata);
111
+ const createdAt = extractCreatedDate(metadata);
112
+ // Extract main content
113
+ const contentStartIndex = findContentStartIndex(lines);
114
+ const mainContent = lines.slice(contentStartIndex).join("\n").trim();
115
+ // Extract cross-references
116
+ const crossReferences = extractCrossReferences(content);
117
+ return {
118
+ title,
119
+ rawTitle,
120
+ branch,
121
+ specReference,
122
+ status,
123
+ createdAt,
124
+ metadata,
125
+ content: mainContent,
126
+ crossReferences,
127
+ filePath,
128
+ };
129
+ }
130
+ /**
131
+ * Extract the raw title from lines
132
+ */
133
+ function extractRawTitle(lines) {
134
+ for (const line of lines) {
135
+ const match = line.match(PATTERNS.TITLE);
136
+ if (match) {
137
+ return match[1].trim();
138
+ }
139
+ }
140
+ return null;
141
+ }
142
+ /**
143
+ * Extract branch from metadata
144
+ */
145
+ function extractBranch(lines, metadata) {
146
+ // Try "Branch" key first
147
+ const branch = metadata.get("Branch");
148
+ if (branch) {
149
+ return branch;
150
+ }
151
+ // Also try "Feature Branch" for consistency
152
+ const featureBranch = metadata.get("Feature Branch");
153
+ if (featureBranch) {
154
+ return featureBranch;
155
+ }
156
+ // Try direct regex match for flexibility
157
+ for (const line of lines) {
158
+ const branchMatch = line.match(PATTERNS.BRANCH);
159
+ if (branchMatch) {
160
+ return branchMatch[1].trim();
161
+ }
162
+ const featureBranchMatch = line.match(PATTERNS.FEATURE_BRANCH);
163
+ if (featureBranchMatch) {
164
+ return featureBranchMatch[1].trim();
165
+ }
166
+ }
167
+ return null;
168
+ }
169
+ /**
170
+ * Extract spec reference from metadata
171
+ */
172
+ function extractSpecReference(lines, metadata) {
173
+ // Try "Spec" key
174
+ const spec = metadata.get("Spec");
175
+ if (spec) {
176
+ // Clean up [[...]] if present
177
+ const refMatch = spec.match(/\[\[([^\]]+)\]\]/);
178
+ if (refMatch) {
179
+ return refMatch[1].trim();
180
+ }
181
+ return spec;
182
+ }
183
+ // Try direct regex match
184
+ for (const line of lines) {
185
+ const match = line.match(PATTERNS.SPEC_LINK);
186
+ if (match) {
187
+ return match[1].trim();
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+ /**
193
+ * Extract status from metadata
194
+ */
195
+ function extractStatus(metadata) {
196
+ const status = metadata.get("Status") || metadata.get("status");
197
+ if (status) {
198
+ return normalizeStatus(status);
199
+ }
200
+ return null;
201
+ }
202
+ /**
203
+ * Extract created date from metadata
204
+ */
205
+ function extractCreatedDate(metadata) {
206
+ const created = metadata.get("Created") || metadata.get("created");
207
+ if (created) {
208
+ return parseDate(created);
209
+ }
210
+ return null;
211
+ }
212
+ /**
213
+ * Check if a file appears to be a valid plan.md file
214
+ *
215
+ * @param filePath - Path to check
216
+ * @returns true if the file looks like a plan file
217
+ */
218
+ export function isPlanFile(filePath) {
219
+ if (!existsSync(filePath)) {
220
+ return false;
221
+ }
222
+ try {
223
+ const content = readFileSync(filePath, "utf-8");
224
+ const lines = content.split("\n").slice(0, 10); // Check first 10 lines
225
+ // Look for plan-like title
226
+ for (const line of lines) {
227
+ if (PATTERNS.TITLE.test(line)) {
228
+ // Check if it has "Implementation Plan" prefix or spec reference metadata
229
+ const hasPlanPrefix = /Implementation Plan/i.test(line);
230
+ const hasSpecRef = content.includes("**Spec**");
231
+ return hasPlanPrefix || hasSpecRef;
232
+ }
233
+ }
234
+ return false;
235
+ }
236
+ catch {
237
+ return false;
238
+ }
239
+ }
240
+ /**
241
+ * Extract just the title from a plan file (fast extraction)
242
+ *
243
+ * @param filePath - Path to the plan file
244
+ * @returns The title or null
245
+ */
246
+ export function getPlanFileTitle(filePath) {
247
+ if (!existsSync(filePath)) {
248
+ return null;
249
+ }
250
+ try {
251
+ const content = readFileSync(filePath, "utf-8");
252
+ const lines = content.split("\n").slice(0, 5); // Only check first 5 lines
253
+ const rawTitle = extractRawTitle(lines);
254
+ if (!rawTitle) {
255
+ return null;
256
+ }
257
+ return extractTitleWithPrefixRemoval(lines, [
258
+ "Implementation Plan:",
259
+ "Implementation Plan",
260
+ ]) || rawTitle;
261
+ }
262
+ catch {
263
+ return null;
264
+ }
265
+ }
266
+ /**
267
+ * Extract just the status from a plan file (fast extraction)
268
+ *
269
+ * @param filePath - Path to the plan file
270
+ * @returns The status or null
271
+ */
272
+ export function getPlanFileStatus(filePath) {
273
+ if (!existsSync(filePath)) {
274
+ return null;
275
+ }
276
+ try {
277
+ const content = readFileSync(filePath, "utf-8");
278
+ const lines = content.split("\n").slice(0, 15); // Check first 15 lines for metadata
279
+ const metadata = extractMetadata(lines);
280
+ return extractStatus(metadata);
281
+ }
282
+ catch {
283
+ return null;
284
+ }
285
+ }
286
+ //# sourceMappingURL=plan-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-parser.js","sourceRoot":"","sources":["../../src/parser/plan-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Spec Parser for Spec-Kit Integration
3
+ *
4
+ * Parses spec.md files from spec-kit and extracts structured data.
5
+ *
6
+ * Expected format:
7
+ * ```markdown
8
+ * # Feature Specification: [FEATURE NAME]
9
+ *
10
+ * **Feature Branch**: feature/xxx
11
+ * **Status**: Draft
12
+ * **Created**: 2024-01-01
13
+ *
14
+ * ## Overview
15
+ * ...
16
+ * ```
17
+ */
18
+ /**
19
+ * Parsed result from a spec.md file
20
+ */
21
+ export interface ParsedSpecKitSpec {
22
+ /** The feature/spec title (without "Feature Specification:" prefix) */
23
+ title: string;
24
+ /** Full raw title as it appears in the file */
25
+ rawTitle: string;
26
+ /** Feature branch name if specified */
27
+ featureBranch: string | null;
28
+ /** Status of the spec (e.g., "Draft", "In Progress", "Complete") */
29
+ status: string | null;
30
+ /** Creation date */
31
+ createdAt: Date | null;
32
+ /** All metadata key-value pairs */
33
+ metadata: Map<string, string>;
34
+ /** Main content (everything after metadata section) */
35
+ content: string;
36
+ /** Cross-references found in the content */
37
+ crossReferences: Array<{
38
+ id: string;
39
+ displayText?: string;
40
+ }>;
41
+ /** Source file path */
42
+ filePath: string;
43
+ }
44
+ /**
45
+ * Options for parsing spec files
46
+ */
47
+ export interface ParseSpecOptions {
48
+ /** Whether to include full content (default: true) */
49
+ includeContent?: boolean;
50
+ /** Whether to extract cross-references (default: true) */
51
+ extractReferences?: boolean;
52
+ }
53
+ /**
54
+ * Parse a spec.md file and extract structured data
55
+ *
56
+ * @param filePath - Absolute path to the spec.md file
57
+ * @param options - Parsing options
58
+ * @returns Parsed spec data or null if file doesn't exist
59
+ *
60
+ * @example
61
+ * const spec = parseSpec("/project/.specify/specs/001-auth/spec.md");
62
+ * console.log(spec?.title); // "Authentication"
63
+ * console.log(spec?.status); // "Draft"
64
+ */
65
+ export declare function parseSpec(filePath: string, options?: ParseSpecOptions): ParsedSpecKitSpec | null;
66
+ /**
67
+ * Parse spec content from a string (for testing or in-memory parsing)
68
+ *
69
+ * @param content - Markdown content string
70
+ * @param filePath - Optional file path for reference
71
+ * @returns Parsed spec data or null
72
+ */
73
+ export declare function parseSpecContent(content: string, filePath?: string): ParsedSpecKitSpec | null;
74
+ /**
75
+ * Check if a file appears to be a valid spec.md file
76
+ *
77
+ * @param filePath - Path to check
78
+ * @returns true if the file looks like a spec file
79
+ */
80
+ export declare function isSpecFile(filePath: string): boolean;
81
+ /**
82
+ * Extract just the title from a spec file (fast extraction)
83
+ *
84
+ * @param filePath - Path to the spec file
85
+ * @returns The title or null
86
+ */
87
+ export declare function getSpecFileTitle(filePath: string): string | null;
88
+ /**
89
+ * Extract just the status from a spec file (fast extraction)
90
+ *
91
+ * @param filePath - Path to the spec file
92
+ * @returns The status or null
93
+ */
94
+ export declare function getSpecFileStatus(filePath: string): string | null;
95
+ //# sourceMappingURL=spec-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-parser.d.ts","sourceRoot":"","sources":["../../src/parser/spec-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAaH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,oEAAoE;IACpE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oBAAoB;IACpB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,mCAAmC;IACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,eAAe,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC7B,iBAAiB,GAAG,IAAI,CA2D1B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAmB,GAC5B,iBAAiB,GAAG,IAAI,CAyC1B;AA6DD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuBpD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBhE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAajE"}
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Spec Parser for Spec-Kit Integration
3
+ *
4
+ * Parses spec.md files from spec-kit and extracts structured data.
5
+ *
6
+ * Expected format:
7
+ * ```markdown
8
+ * # Feature Specification: [FEATURE NAME]
9
+ *
10
+ * **Feature Branch**: feature/xxx
11
+ * **Status**: Draft
12
+ * **Created**: 2024-01-01
13
+ *
14
+ * ## Overview
15
+ * ...
16
+ * ```
17
+ */
18
+ import { readFileSync, existsSync } from "fs";
19
+ import { PATTERNS, extractMetadata, extractTitleWithPrefixRemoval, extractCrossReferences, findContentStartIndex, parseDate, normalizeStatus, } from "./markdown-utils.js";
20
+ /**
21
+ * Parse a spec.md file and extract structured data
22
+ *
23
+ * @param filePath - Absolute path to the spec.md file
24
+ * @param options - Parsing options
25
+ * @returns Parsed spec data or null if file doesn't exist
26
+ *
27
+ * @example
28
+ * const spec = parseSpec("/project/.specify/specs/001-auth/spec.md");
29
+ * console.log(spec?.title); // "Authentication"
30
+ * console.log(spec?.status); // "Draft"
31
+ */
32
+ export function parseSpec(filePath, options = {}) {
33
+ const { includeContent = true, extractReferences = true } = options;
34
+ if (!existsSync(filePath)) {
35
+ return null;
36
+ }
37
+ try {
38
+ const rawContent = readFileSync(filePath, "utf-8");
39
+ const lines = rawContent.split("\n");
40
+ // Extract raw title
41
+ const rawTitle = extractRawTitle(lines);
42
+ if (!rawTitle) {
43
+ return null; // Invalid spec file without title
44
+ }
45
+ // Clean title by removing prefix
46
+ const title = extractTitleWithPrefixRemoval(lines, [
47
+ "Feature Specification:",
48
+ "Feature Specification",
49
+ ]) || rawTitle;
50
+ // Extract metadata
51
+ const metadata = extractMetadata(lines);
52
+ // Extract specific metadata fields
53
+ const featureBranch = extractFeatureBranch(lines, metadata);
54
+ const status = extractStatus(metadata);
55
+ const createdAt = extractCreatedDate(metadata);
56
+ // Extract main content
57
+ let content = "";
58
+ if (includeContent) {
59
+ const contentStartIndex = findContentStartIndex(lines);
60
+ content = lines.slice(contentStartIndex).join("\n").trim();
61
+ }
62
+ // Extract cross-references
63
+ let crossReferences = [];
64
+ if (extractReferences) {
65
+ crossReferences = extractCrossReferences(rawContent);
66
+ }
67
+ return {
68
+ title,
69
+ rawTitle,
70
+ featureBranch,
71
+ status,
72
+ createdAt,
73
+ metadata,
74
+ content,
75
+ crossReferences,
76
+ filePath,
77
+ };
78
+ }
79
+ catch (error) {
80
+ console.error(`[spec-parser] Failed to parse ${filePath}:`, error);
81
+ return null;
82
+ }
83
+ }
84
+ /**
85
+ * Parse spec content from a string (for testing or in-memory parsing)
86
+ *
87
+ * @param content - Markdown content string
88
+ * @param filePath - Optional file path for reference
89
+ * @returns Parsed spec data or null
90
+ */
91
+ export function parseSpecContent(content, filePath = "<string>") {
92
+ const lines = content.split("\n");
93
+ // Extract raw title
94
+ const rawTitle = extractRawTitle(lines);
95
+ if (!rawTitle) {
96
+ return null;
97
+ }
98
+ // Clean title by removing prefix
99
+ const title = extractTitleWithPrefixRemoval(lines, [
100
+ "Feature Specification:",
101
+ "Feature Specification",
102
+ ]) || rawTitle;
103
+ // Extract metadata
104
+ const metadata = extractMetadata(lines);
105
+ // Extract specific metadata fields
106
+ const featureBranch = extractFeatureBranch(lines, metadata);
107
+ const status = extractStatus(metadata);
108
+ const createdAt = extractCreatedDate(metadata);
109
+ // Extract main content
110
+ const contentStartIndex = findContentStartIndex(lines);
111
+ const mainContent = lines.slice(contentStartIndex).join("\n").trim();
112
+ // Extract cross-references
113
+ const crossReferences = extractCrossReferences(content);
114
+ return {
115
+ title,
116
+ rawTitle,
117
+ featureBranch,
118
+ status,
119
+ createdAt,
120
+ metadata,
121
+ content: mainContent,
122
+ crossReferences,
123
+ filePath,
124
+ };
125
+ }
126
+ /**
127
+ * Extract the raw title from lines
128
+ */
129
+ function extractRawTitle(lines) {
130
+ for (const line of lines) {
131
+ const match = line.match(PATTERNS.TITLE);
132
+ if (match) {
133
+ return match[1].trim();
134
+ }
135
+ }
136
+ return null;
137
+ }
138
+ /**
139
+ * Extract feature branch from metadata
140
+ */
141
+ function extractFeatureBranch(lines, metadata) {
142
+ // Try "Feature Branch" key first
143
+ const featureBranch = metadata.get("Feature Branch");
144
+ if (featureBranch) {
145
+ return featureBranch;
146
+ }
147
+ // Try direct regex match for flexibility
148
+ for (const line of lines) {
149
+ const match = line.match(PATTERNS.FEATURE_BRANCH);
150
+ if (match) {
151
+ return match[1].trim();
152
+ }
153
+ }
154
+ return null;
155
+ }
156
+ /**
157
+ * Extract status from metadata
158
+ */
159
+ function extractStatus(metadata) {
160
+ const status = metadata.get("Status") || metadata.get("status");
161
+ if (status) {
162
+ return normalizeStatus(status);
163
+ }
164
+ return null;
165
+ }
166
+ /**
167
+ * Extract created date from metadata
168
+ */
169
+ function extractCreatedDate(metadata) {
170
+ const created = metadata.get("Created") || metadata.get("created");
171
+ if (created) {
172
+ return parseDate(created);
173
+ }
174
+ return null;
175
+ }
176
+ /**
177
+ * Check if a file appears to be a valid spec.md file
178
+ *
179
+ * @param filePath - Path to check
180
+ * @returns true if the file looks like a spec file
181
+ */
182
+ export function isSpecFile(filePath) {
183
+ if (!existsSync(filePath)) {
184
+ return false;
185
+ }
186
+ try {
187
+ const content = readFileSync(filePath, "utf-8");
188
+ const lines = content.split("\n").slice(0, 10); // Check first 10 lines
189
+ // Look for spec-like title
190
+ for (const line of lines) {
191
+ if (PATTERNS.TITLE.test(line)) {
192
+ // Check if it has "Feature Specification" prefix or feature branch metadata
193
+ const hasSpecPrefix = /Feature Specification/i.test(line);
194
+ const hasFeatureBranch = content.includes("**Feature Branch**");
195
+ return hasSpecPrefix || hasFeatureBranch;
196
+ }
197
+ }
198
+ return false;
199
+ }
200
+ catch {
201
+ return false;
202
+ }
203
+ }
204
+ /**
205
+ * Extract just the title from a spec file (fast extraction)
206
+ *
207
+ * @param filePath - Path to the spec file
208
+ * @returns The title or null
209
+ */
210
+ export function getSpecFileTitle(filePath) {
211
+ if (!existsSync(filePath)) {
212
+ return null;
213
+ }
214
+ try {
215
+ const content = readFileSync(filePath, "utf-8");
216
+ const lines = content.split("\n").slice(0, 5); // Only check first 5 lines
217
+ const rawTitle = extractRawTitle(lines);
218
+ if (!rawTitle) {
219
+ return null;
220
+ }
221
+ return extractTitleWithPrefixRemoval(lines, [
222
+ "Feature Specification:",
223
+ "Feature Specification",
224
+ ]) || rawTitle;
225
+ }
226
+ catch {
227
+ return null;
228
+ }
229
+ }
230
+ /**
231
+ * Extract just the status from a spec file (fast extraction)
232
+ *
233
+ * @param filePath - Path to the spec file
234
+ * @returns The status or null
235
+ */
236
+ export function getSpecFileStatus(filePath) {
237
+ if (!existsSync(filePath)) {
238
+ return null;
239
+ }
240
+ try {
241
+ const content = readFileSync(filePath, "utf-8");
242
+ const lines = content.split("\n").slice(0, 15); // Check first 15 lines for metadata
243
+ const metadata = extractMetadata(lines);
244
+ return extractStatus(metadata);
245
+ }
246
+ catch {
247
+ return null;
248
+ }
249
+ }
250
+ //# sourceMappingURL=spec-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-parser.js","sourceRoot":"","sources":["../../src/parser/spec-parser.ts"],"names":[],"mappings":"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"}