@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.
- package/dist/id-generator.d.ts +149 -0
- package/dist/id-generator.d.ts.map +1 -0
- package/dist/id-generator.js +197 -0
- package/dist/id-generator.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1017 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +11 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +16 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/markdown-utils.d.ts +138 -0
- package/dist/parser/markdown-utils.d.ts.map +1 -0
- package/dist/parser/markdown-utils.js +283 -0
- package/dist/parser/markdown-utils.js.map +1 -0
- package/dist/parser/plan-parser.d.ts +97 -0
- package/dist/parser/plan-parser.d.ts.map +1 -0
- package/dist/parser/plan-parser.js +286 -0
- package/dist/parser/plan-parser.js.map +1 -0
- package/dist/parser/spec-parser.d.ts +95 -0
- package/dist/parser/spec-parser.d.ts.map +1 -0
- package/dist/parser/spec-parser.js +250 -0
- package/dist/parser/spec-parser.js.map +1 -0
- package/dist/parser/supporting-docs.d.ts +119 -0
- package/dist/parser/supporting-docs.d.ts.map +1 -0
- package/dist/parser/supporting-docs.js +324 -0
- package/dist/parser/supporting-docs.js.map +1 -0
- package/dist/parser/tasks-parser.d.ts +171 -0
- package/dist/parser/tasks-parser.d.ts.map +1 -0
- package/dist/parser/tasks-parser.js +281 -0
- package/dist/parser/tasks-parser.js.map +1 -0
- package/dist/relationship-mapper.d.ts +165 -0
- package/dist/relationship-mapper.d.ts.map +1 -0
- package/dist/relationship-mapper.js +238 -0
- package/dist/relationship-mapper.js.map +1 -0
- package/dist/watcher.d.ts +137 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +599 -0
- package/dist/watcher.js.map +1 -0
- package/dist/writer/index.d.ts +8 -0
- package/dist/writer/index.d.ts.map +1 -0
- package/dist/writer/index.js +10 -0
- package/dist/writer/index.js.map +1 -0
- package/dist/writer/spec-writer.d.ts +70 -0
- package/dist/writer/spec-writer.d.ts.map +1 -0
- package/dist/writer/spec-writer.js +261 -0
- package/dist/writer/spec-writer.js.map +1 -0
- package/dist/writer/tasks-writer.d.ts +47 -0
- package/dist/writer/tasks-writer.d.ts.map +1 -0
- package/dist/writer/tasks-writer.js +161 -0
- package/dist/writer/tasks-writer.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supporting Documents Parser for Spec-Kit Integration
|
|
3
|
+
*
|
|
4
|
+
* Parses supporting documents in spec-kit feature directories:
|
|
5
|
+
* - research.md - Research notes and findings
|
|
6
|
+
* - data-model.md - Data model definitions
|
|
7
|
+
* - contracts/*.json - API contracts and schemas
|
|
8
|
+
*
|
|
9
|
+
* These documents reference the plan and provide additional context.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Types of supporting documents
|
|
13
|
+
*/
|
|
14
|
+
export type SupportingDocType = "research" | "data-model" | "contract" | "other";
|
|
15
|
+
/**
|
|
16
|
+
* Parsed supporting document
|
|
17
|
+
*/
|
|
18
|
+
export interface ParsedSupportingDoc {
|
|
19
|
+
/** Document type */
|
|
20
|
+
type: SupportingDocType;
|
|
21
|
+
/** Document title (from # header or filename) */
|
|
22
|
+
title: string;
|
|
23
|
+
/** All metadata key-value pairs */
|
|
24
|
+
metadata: Map<string, string>;
|
|
25
|
+
/** Main content */
|
|
26
|
+
content: string;
|
|
27
|
+
/** Cross-references found in the content */
|
|
28
|
+
crossReferences: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
displayText?: string;
|
|
31
|
+
}>;
|
|
32
|
+
/** Source file path */
|
|
33
|
+
filePath: string;
|
|
34
|
+
/** File name without extension */
|
|
35
|
+
fileName: string;
|
|
36
|
+
/** File extension */
|
|
37
|
+
fileExtension: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parsed contract document (JSON/YAML)
|
|
41
|
+
*/
|
|
42
|
+
export interface ParsedContract {
|
|
43
|
+
/** Contract name (from filename) */
|
|
44
|
+
name: string;
|
|
45
|
+
/** Parsed contract data */
|
|
46
|
+
data: Record<string, unknown>;
|
|
47
|
+
/** Source file path */
|
|
48
|
+
filePath: string;
|
|
49
|
+
/** File format (json, yaml, yml) */
|
|
50
|
+
format: "json" | "yaml";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Options for parsing supporting documents
|
|
54
|
+
*/
|
|
55
|
+
export interface ParseSupportingDocOptions {
|
|
56
|
+
/** Whether to include full content (default: true) */
|
|
57
|
+
includeContent?: boolean;
|
|
58
|
+
/** Whether to extract cross-references (default: true) */
|
|
59
|
+
extractReferences?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parse a research.md file
|
|
63
|
+
*
|
|
64
|
+
* @param filePath - Absolute path to the research.md file
|
|
65
|
+
* @param options - Parsing options
|
|
66
|
+
* @returns Parsed document or null
|
|
67
|
+
*/
|
|
68
|
+
export declare function parseResearch(filePath: string, options?: ParseSupportingDocOptions): ParsedSupportingDoc | null;
|
|
69
|
+
/**
|
|
70
|
+
* Parse a data-model.md file
|
|
71
|
+
*
|
|
72
|
+
* @param filePath - Absolute path to the data-model.md file
|
|
73
|
+
* @param options - Parsing options
|
|
74
|
+
* @returns Parsed document or null
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseDataModel(filePath: string, options?: ParseSupportingDocOptions): ParsedSupportingDoc | null;
|
|
77
|
+
/**
|
|
78
|
+
* Parse any supporting markdown document
|
|
79
|
+
*
|
|
80
|
+
* @param filePath - Absolute path to the file
|
|
81
|
+
* @param type - Document type
|
|
82
|
+
* @param options - Parsing options
|
|
83
|
+
* @returns Parsed document or null
|
|
84
|
+
*/
|
|
85
|
+
export declare function parseSupportingDoc(filePath: string, type?: SupportingDocType, options?: ParseSupportingDocOptions): ParsedSupportingDoc | null;
|
|
86
|
+
/**
|
|
87
|
+
* Parse a contract file (JSON or YAML)
|
|
88
|
+
*
|
|
89
|
+
* @param filePath - Absolute path to the contract file
|
|
90
|
+
* @returns Parsed contract or null
|
|
91
|
+
*/
|
|
92
|
+
export declare function parseContract(filePath: string): ParsedContract | null;
|
|
93
|
+
/**
|
|
94
|
+
* Parse all contracts in a directory
|
|
95
|
+
*
|
|
96
|
+
* @param contractsDir - Path to the contracts directory
|
|
97
|
+
* @returns Array of parsed contracts
|
|
98
|
+
*/
|
|
99
|
+
export declare function parseContractsDirectory(contractsDir: string): ParsedContract[];
|
|
100
|
+
/**
|
|
101
|
+
* Discover and parse all supporting documents in a feature directory
|
|
102
|
+
*
|
|
103
|
+
* @param featureDir - Path to the feature directory (e.g., .specify/specs/001-auth)
|
|
104
|
+
* @returns Object containing all parsed supporting documents
|
|
105
|
+
*/
|
|
106
|
+
export declare function discoverSupportingDocs(featureDir: string): {
|
|
107
|
+
research: ParsedSupportingDoc | null;
|
|
108
|
+
dataModel: ParsedSupportingDoc | null;
|
|
109
|
+
contracts: ParsedContract[];
|
|
110
|
+
other: ParsedSupportingDoc[];
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Detect the type of a supporting document from its filename
|
|
114
|
+
*
|
|
115
|
+
* @param filePath - Path to the file
|
|
116
|
+
* @returns Document type
|
|
117
|
+
*/
|
|
118
|
+
export declare function detectDocType(filePath: string): SupportingDocType;
|
|
119
|
+
//# sourceMappingURL=supporting-docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supporting-docs.d.ts","sourceRoot":"","sources":["../../src/parser/supporting-docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAYH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,YAAY,GACZ,UAAU,GACV,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oBAAoB;IACpB,IAAI,EAAE,iBAAiB,CAAC;IACxB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,mBAAmB;IACnB,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;IACjB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,yBAA8B,GACtC,mBAAmB,GAAG,IAAI,CAE5B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,yBAA8B,GACtC,mBAAmB,GAAG,IAAI,CAE5B;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,iBAA2B,EACjC,OAAO,GAAE,yBAA8B,GACtC,mBAAmB,GAAG,IAAI,CA+C5B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAsCrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,GACnB,cAAc,EAAE,CAgClB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG;IAC1D,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B,CA6DA;AAuGD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAUjE"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supporting Documents Parser for Spec-Kit Integration
|
|
3
|
+
*
|
|
4
|
+
* Parses supporting documents in spec-kit feature directories:
|
|
5
|
+
* - research.md - Research notes and findings
|
|
6
|
+
* - data-model.md - Data model definitions
|
|
7
|
+
* - contracts/*.json - API contracts and schemas
|
|
8
|
+
*
|
|
9
|
+
* These documents reference the plan and provide additional context.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
12
|
+
import { join, basename, extname } from "path";
|
|
13
|
+
import { extractMetadata, extractTitle, extractCrossReferences, findContentStartIndex, } from "./markdown-utils.js";
|
|
14
|
+
/**
|
|
15
|
+
* Parse a research.md file
|
|
16
|
+
*
|
|
17
|
+
* @param filePath - Absolute path to the research.md file
|
|
18
|
+
* @param options - Parsing options
|
|
19
|
+
* @returns Parsed document or null
|
|
20
|
+
*/
|
|
21
|
+
export function parseResearch(filePath, options = {}) {
|
|
22
|
+
return parseSupportingDoc(filePath, "research", options);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a data-model.md file
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - Absolute path to the data-model.md file
|
|
28
|
+
* @param options - Parsing options
|
|
29
|
+
* @returns Parsed document or null
|
|
30
|
+
*/
|
|
31
|
+
export function parseDataModel(filePath, options = {}) {
|
|
32
|
+
return parseSupportingDoc(filePath, "data-model", options);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parse any supporting markdown document
|
|
36
|
+
*
|
|
37
|
+
* @param filePath - Absolute path to the file
|
|
38
|
+
* @param type - Document type
|
|
39
|
+
* @param options - Parsing options
|
|
40
|
+
* @returns Parsed document or null
|
|
41
|
+
*/
|
|
42
|
+
export function parseSupportingDoc(filePath, type = "other", options = {}) {
|
|
43
|
+
const { includeContent = true, extractReferences = true } = options;
|
|
44
|
+
if (!existsSync(filePath)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
49
|
+
const lines = rawContent.split("\n");
|
|
50
|
+
const fileName = basename(filePath, extname(filePath));
|
|
51
|
+
const fileExtension = extname(filePath).slice(1); // Remove leading dot
|
|
52
|
+
// Extract title (use filename if no title in content)
|
|
53
|
+
const title = extractTitle(lines) || formatFileName(fileName);
|
|
54
|
+
// Extract metadata
|
|
55
|
+
const metadata = extractMetadata(lines);
|
|
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
|
+
type,
|
|
69
|
+
title,
|
|
70
|
+
metadata,
|
|
71
|
+
content,
|
|
72
|
+
crossReferences,
|
|
73
|
+
filePath,
|
|
74
|
+
fileName,
|
|
75
|
+
fileExtension,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`[supporting-docs] Failed to parse ${filePath}:`, error);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse a contract file (JSON or YAML)
|
|
85
|
+
*
|
|
86
|
+
* @param filePath - Absolute path to the contract file
|
|
87
|
+
* @returns Parsed contract or null
|
|
88
|
+
*/
|
|
89
|
+
export function parseContract(filePath) {
|
|
90
|
+
if (!existsSync(filePath)) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const ext = extname(filePath).toLowerCase();
|
|
95
|
+
const name = basename(filePath, ext);
|
|
96
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
97
|
+
let data;
|
|
98
|
+
let format;
|
|
99
|
+
if (ext === ".json") {
|
|
100
|
+
data = JSON.parse(rawContent);
|
|
101
|
+
format = "json";
|
|
102
|
+
}
|
|
103
|
+
else if (ext === ".yaml" || ext === ".yml") {
|
|
104
|
+
// Simple YAML parsing (for basic structures)
|
|
105
|
+
// Note: For complex YAML, a proper library should be used
|
|
106
|
+
data = parseSimpleYaml(rawContent);
|
|
107
|
+
format = "yaml";
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
return null; // Unsupported format
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
name,
|
|
114
|
+
data,
|
|
115
|
+
filePath,
|
|
116
|
+
format,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
console.error(`[supporting-docs] Failed to parse contract ${filePath}:`, error);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Parse all contracts in a directory
|
|
126
|
+
*
|
|
127
|
+
* @param contractsDir - Path to the contracts directory
|
|
128
|
+
* @returns Array of parsed contracts
|
|
129
|
+
*/
|
|
130
|
+
export function parseContractsDirectory(contractsDir) {
|
|
131
|
+
if (!existsSync(contractsDir)) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const contracts = [];
|
|
136
|
+
const entries = readdirSync(contractsDir);
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const filePath = join(contractsDir, entry);
|
|
139
|
+
const stats = statSync(filePath);
|
|
140
|
+
if (stats.isFile()) {
|
|
141
|
+
const ext = extname(entry).toLowerCase();
|
|
142
|
+
if ([".json", ".yaml", ".yml"].includes(ext)) {
|
|
143
|
+
const contract = parseContract(filePath);
|
|
144
|
+
if (contract) {
|
|
145
|
+
contracts.push(contract);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return contracts;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
console.error(`[supporting-docs] Failed to parse contracts directory:`, error);
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Discover and parse all supporting documents in a feature directory
|
|
159
|
+
*
|
|
160
|
+
* @param featureDir - Path to the feature directory (e.g., .specify/specs/001-auth)
|
|
161
|
+
* @returns Object containing all parsed supporting documents
|
|
162
|
+
*/
|
|
163
|
+
export function discoverSupportingDocs(featureDir) {
|
|
164
|
+
const result = {
|
|
165
|
+
research: null,
|
|
166
|
+
dataModel: null,
|
|
167
|
+
contracts: [],
|
|
168
|
+
other: [],
|
|
169
|
+
};
|
|
170
|
+
if (!existsSync(featureDir)) {
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
// Parse research.md
|
|
174
|
+
const researchPath = join(featureDir, "research.md");
|
|
175
|
+
if (existsSync(researchPath)) {
|
|
176
|
+
result.research = parseResearch(researchPath);
|
|
177
|
+
}
|
|
178
|
+
// Parse data-model.md
|
|
179
|
+
const dataModelPath = join(featureDir, "data-model.md");
|
|
180
|
+
if (existsSync(dataModelPath)) {
|
|
181
|
+
result.dataModel = parseDataModel(dataModelPath);
|
|
182
|
+
}
|
|
183
|
+
// Parse contracts directory
|
|
184
|
+
const contractsDir = join(featureDir, "contracts");
|
|
185
|
+
if (existsSync(contractsDir)) {
|
|
186
|
+
result.contracts = parseContractsDirectory(contractsDir);
|
|
187
|
+
}
|
|
188
|
+
// Look for other markdown files (exclude spec.md, plan.md, tasks.md)
|
|
189
|
+
try {
|
|
190
|
+
const entries = readdirSync(featureDir);
|
|
191
|
+
const knownFiles = [
|
|
192
|
+
"spec.md",
|
|
193
|
+
"plan.md",
|
|
194
|
+
"tasks.md",
|
|
195
|
+
"research.md",
|
|
196
|
+
"data-model.md",
|
|
197
|
+
];
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
const filePath = join(featureDir, entry);
|
|
200
|
+
const stats = statSync(filePath);
|
|
201
|
+
if (stats.isFile() &&
|
|
202
|
+
entry.endsWith(".md") &&
|
|
203
|
+
!knownFiles.includes(entry.toLowerCase())) {
|
|
204
|
+
const doc = parseSupportingDoc(filePath, "other");
|
|
205
|
+
if (doc) {
|
|
206
|
+
result.other.push(doc);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// Ignore errors listing directory
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Simple YAML parser for basic structures
|
|
218
|
+
* For complex YAML, a proper library like js-yaml should be used
|
|
219
|
+
*/
|
|
220
|
+
function parseSimpleYaml(content) {
|
|
221
|
+
const result = {};
|
|
222
|
+
const lines = content.split("\n");
|
|
223
|
+
let currentKey = "";
|
|
224
|
+
let currentIndent = 0;
|
|
225
|
+
const stack = [
|
|
226
|
+
{ obj: result, indent: -1 },
|
|
227
|
+
];
|
|
228
|
+
for (const line of lines) {
|
|
229
|
+
// Skip comments and empty lines
|
|
230
|
+
if (line.trim().startsWith("#") || line.trim() === "") {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
// Calculate indentation
|
|
234
|
+
const match = line.match(/^(\s*)/);
|
|
235
|
+
const indent = match ? match[1].length : 0;
|
|
236
|
+
// Pop stack to find correct parent
|
|
237
|
+
while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
|
|
238
|
+
stack.pop();
|
|
239
|
+
}
|
|
240
|
+
const parent = stack[stack.length - 1].obj;
|
|
241
|
+
// Parse key-value
|
|
242
|
+
const kvMatch = line.trim().match(/^([^:]+):\s*(.*)$/);
|
|
243
|
+
if (kvMatch) {
|
|
244
|
+
const [, key, value] = kvMatch;
|
|
245
|
+
const trimmedKey = key.trim();
|
|
246
|
+
const trimmedValue = value.trim();
|
|
247
|
+
if (trimmedValue === "" || trimmedValue === "|" || trimmedValue === ">") {
|
|
248
|
+
// Start of nested object or multiline string
|
|
249
|
+
parent[trimmedKey] = {};
|
|
250
|
+
stack.push({
|
|
251
|
+
obj: parent[trimmedKey],
|
|
252
|
+
indent,
|
|
253
|
+
});
|
|
254
|
+
currentKey = trimmedKey;
|
|
255
|
+
currentIndent = indent;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
// Simple key-value
|
|
259
|
+
parent[trimmedKey] = parseYamlValue(trimmedValue);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else if (line.trim().startsWith("-")) {
|
|
263
|
+
// Array item
|
|
264
|
+
const itemValue = line.trim().slice(1).trim();
|
|
265
|
+
if (!Array.isArray(parent[currentKey])) {
|
|
266
|
+
parent[currentKey] = [];
|
|
267
|
+
}
|
|
268
|
+
parent[currentKey].push(parseYamlValue(itemValue));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Parse a simple YAML value
|
|
275
|
+
*/
|
|
276
|
+
function parseYamlValue(value) {
|
|
277
|
+
// Remove quotes
|
|
278
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
279
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
280
|
+
return value.slice(1, -1);
|
|
281
|
+
}
|
|
282
|
+
// Boolean
|
|
283
|
+
if (value.toLowerCase() === "true")
|
|
284
|
+
return true;
|
|
285
|
+
if (value.toLowerCase() === "false")
|
|
286
|
+
return false;
|
|
287
|
+
// Null
|
|
288
|
+
if (value.toLowerCase() === "null" || value === "~")
|
|
289
|
+
return null;
|
|
290
|
+
// Number
|
|
291
|
+
if (/^-?\d+$/.test(value))
|
|
292
|
+
return parseInt(value, 10);
|
|
293
|
+
if (/^-?\d+\.\d+$/.test(value))
|
|
294
|
+
return parseFloat(value);
|
|
295
|
+
// String
|
|
296
|
+
return value;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Format a filename for display (convert kebab-case to Title Case)
|
|
300
|
+
*/
|
|
301
|
+
function formatFileName(fileName) {
|
|
302
|
+
return fileName
|
|
303
|
+
.split(/[-_]/)
|
|
304
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
305
|
+
.join(" ");
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Detect the type of a supporting document from its filename
|
|
309
|
+
*
|
|
310
|
+
* @param filePath - Path to the file
|
|
311
|
+
* @returns Document type
|
|
312
|
+
*/
|
|
313
|
+
export function detectDocType(filePath) {
|
|
314
|
+
const fileName = basename(filePath).toLowerCase();
|
|
315
|
+
if (fileName === "research.md")
|
|
316
|
+
return "research";
|
|
317
|
+
if (fileName === "data-model.md")
|
|
318
|
+
return "data-model";
|
|
319
|
+
if (filePath.includes("/contracts/") || filePath.includes("\\contracts\\")) {
|
|
320
|
+
return "contract";
|
|
321
|
+
}
|
|
322
|
+
return "other";
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=supporting-docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supporting-docs.js","sourceRoot":"","sources":["../../src/parser/supporting-docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAW,MAAM,MAAM,CAAC;AACxD,OAAO,EAEL,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAyD7B;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,UAAqC,EAAE;IAEvC,OAAO,kBAAkB,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,UAAqC,EAAE;IAEvC,OAAO,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,OAA0B,OAAO,EACjC,UAAqC,EAAE;IAEvC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEpE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB;QAEvE,sDAAsD;QACtD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;QAE9D,mBAAmB;QACnB,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAExC,uBAAuB;QACvB,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACvD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7D,CAAC;QAED,2BAA2B;QAC3B,IAAI,eAAe,GAAgD,EAAE,CAAC;QACtE,IAAI,iBAAiB,EAAE,CAAC;YACtB,eAAe,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACvD,CAAC;QAED,OAAO;YACL,IAAI;YACJ,KAAK;YACL,QAAQ;YACR,OAAO;YACP,eAAe;YACf,QAAQ;YACR,QAAQ;YACR,aAAa;SACd,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrC,MAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEnD,IAAI,IAA6B,CAAC;QAClC,IAAI,MAAuB,CAAC;QAE5B,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,GAAG,MAAM,CAAC;QAClB,CAAC;aAAM,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YAC7C,6CAA6C;YAC7C,0DAA0D;YAC1D,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;YACnC,MAAM,GAAG,MAAM,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,CAAC,qBAAqB;QACpC,CAAC;QAED,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,QAAQ;YACR,MAAM;SACP,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,8CAA8C,QAAQ,GAAG,EACzD,KAAK,CACN,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAoB;IAEpB,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAqB,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QAE1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEjC,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;gBACzC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7C,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;oBACzC,IAAI,QAAQ,EAAE,CAAC;wBACb,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,wDAAwD,EACxD,KAAK,CACN,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IAMvD,MAAM,MAAM,GAAG;QACb,QAAQ,EAAE,IAAkC;QAC5C,SAAS,EAAE,IAAkC;QAC7C,SAAS,EAAE,EAAsB;QACjC,KAAK,EAAE,EAA2B;KACnC,CAAC;IAEF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,oBAAoB;IACpB,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAED,sBAAsB;IACtB,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,SAAS,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,4BAA4B;IAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACnD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,SAAS,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAC3D,CAAC;IAED,qEAAqE;IACrE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG;YACjB,SAAS;YACT,SAAS;YACT,UAAU;YACV,aAAa;YACb,eAAe;SAChB,CAAC;QAEF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEjC,IACE,KAAK,CAAC,MAAM,EAAE;gBACd,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACrB,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EACzC,CAAC;gBACD,MAAM,GAAG,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClD,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,MAAM,KAAK,GAA4D;QACrE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE;KAC5B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,gCAAgC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3C,mCAAmC;QACnC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YACpE,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAE3C,kBAAkB;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC;YAC/B,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAElC,IAAI,YAAY,KAAK,EAAE,IAAI,YAAY,KAAK,GAAG,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;gBACxE,6CAA6C;gBAC7C,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC;oBACT,GAAG,EAAE,MAAM,CAAC,UAAU,CAA4B;oBAClD,MAAM;iBACP,CAAC,CAAC;gBACH,UAAU,GAAG,UAAU,CAAC;gBACxB,aAAa,GAAG,MAAM,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,mBAAmB;gBACnB,MAAM,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,aAAa;YACb,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBACvC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;YAC1B,CAAC;YACA,MAAM,CAAC,UAAU,CAAe,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,gBAAgB;IAChB,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,UAAU;IACV,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAElD,OAAO;IACP,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEjE,SAAS;IACT,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAEzD,SAAS;IACT,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,QAAQ;SACZ,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACzE,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAElD,IAAI,QAAQ,KAAK,aAAa;QAAE,OAAO,UAAU,CAAC;IAClD,IAAI,QAAQ,KAAK,eAAe;QAAE,OAAO,YAAY,CAAC;IACtD,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3E,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tasks Parser for Spec-Kit Integration
|
|
3
|
+
*
|
|
4
|
+
* Parses tasks.md files from spec-kit and extracts individual tasks.
|
|
5
|
+
*
|
|
6
|
+
* Expected format:
|
|
7
|
+
* ```markdown
|
|
8
|
+
* # Tasks
|
|
9
|
+
*
|
|
10
|
+
* ## Phase 1: Foundation
|
|
11
|
+
*
|
|
12
|
+
* - [ ] T001 [P] Setup project structure
|
|
13
|
+
* - [ ] T002 [US1] Create user model
|
|
14
|
+
* - [x] T003: Completed task
|
|
15
|
+
*
|
|
16
|
+
* ## Phase 2: Implementation
|
|
17
|
+
*
|
|
18
|
+
* - [ ] T004 [P] [US2] Implement authentication
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Task format: `- [ ] T001 [P?] [US?] Description`
|
|
22
|
+
* - Checkbox: `[ ]` (incomplete) or `[x]` (complete)
|
|
23
|
+
* - Task ID: T followed by digits (T001, T002, etc.)
|
|
24
|
+
* - Parallelizable: Optional `[P]` marker
|
|
25
|
+
* - User Story: Optional `[US1]`, `[US2]`, etc.
|
|
26
|
+
* - Description: Rest of the line
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Parsed task from a tasks.md file
|
|
30
|
+
*/
|
|
31
|
+
export interface ParsedTask {
|
|
32
|
+
/** Task identifier (e.g., "T001") */
|
|
33
|
+
taskId: string;
|
|
34
|
+
/** Task description (cleaned of markers) */
|
|
35
|
+
description: string;
|
|
36
|
+
/** Whether the task is completed */
|
|
37
|
+
completed: boolean;
|
|
38
|
+
/** Whether the task can be done in parallel with others */
|
|
39
|
+
parallelizable: boolean;
|
|
40
|
+
/** User story reference if present (e.g., "1", "2") */
|
|
41
|
+
userStory: string | null;
|
|
42
|
+
/** Phase number if the task is in a phase section */
|
|
43
|
+
phase: number | null;
|
|
44
|
+
/** Phase name if available */
|
|
45
|
+
phaseName: string | null;
|
|
46
|
+
/** Line number in the source file (1-indexed) */
|
|
47
|
+
lineNumber: number;
|
|
48
|
+
/** Indentation level (for nested tasks) */
|
|
49
|
+
indentLevel: number;
|
|
50
|
+
/** Raw line from the file */
|
|
51
|
+
rawLine: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Parsed result from a tasks.md file
|
|
55
|
+
*/
|
|
56
|
+
export interface ParsedTasksFile {
|
|
57
|
+
/** Optional title from the file */
|
|
58
|
+
title: string | null;
|
|
59
|
+
/** All metadata key-value pairs */
|
|
60
|
+
metadata: Map<string, string>;
|
|
61
|
+
/** Array of parsed tasks */
|
|
62
|
+
tasks: ParsedTask[];
|
|
63
|
+
/** Map of phase number to phase name */
|
|
64
|
+
phases: Map<number, string>;
|
|
65
|
+
/** Source file path */
|
|
66
|
+
filePath: string;
|
|
67
|
+
/** Summary statistics */
|
|
68
|
+
stats: {
|
|
69
|
+
total: number;
|
|
70
|
+
completed: number;
|
|
71
|
+
incomplete: number;
|
|
72
|
+
parallelizable: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Options for parsing tasks files
|
|
77
|
+
*/
|
|
78
|
+
export interface ParseTasksOptions {
|
|
79
|
+
/** Filter to only include tasks in specific phases */
|
|
80
|
+
filterPhases?: number[];
|
|
81
|
+
/** Filter to only include incomplete tasks */
|
|
82
|
+
incompleteOnly?: boolean;
|
|
83
|
+
/** Filter to only include parallelizable tasks */
|
|
84
|
+
parallelizableOnly?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Parse a tasks.md file and extract all tasks
|
|
88
|
+
*
|
|
89
|
+
* @param filePath - Absolute path to the tasks.md file
|
|
90
|
+
* @param options - Parsing options
|
|
91
|
+
* @returns Parsed tasks data or null if file doesn't exist
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* const tasksFile = parseTasks("/project/.specify/specs/001-auth/tasks.md");
|
|
95
|
+
* console.log(tasksFile?.tasks.length); // 10
|
|
96
|
+
* console.log(tasksFile?.stats.completed); // 3
|
|
97
|
+
*/
|
|
98
|
+
export declare function parseTasks(filePath: string, options?: ParseTasksOptions): ParsedTasksFile | null;
|
|
99
|
+
/**
|
|
100
|
+
* Parse tasks content from a string (for testing or in-memory parsing)
|
|
101
|
+
*
|
|
102
|
+
* @param content - Markdown content string
|
|
103
|
+
* @param filePath - Optional file path for reference
|
|
104
|
+
* @param options - Parsing options
|
|
105
|
+
* @returns Parsed tasks data or null
|
|
106
|
+
*/
|
|
107
|
+
export declare function parseTasksContent(content: string, filePath?: string, options?: ParseTasksOptions): ParsedTasksFile | null;
|
|
108
|
+
/**
|
|
109
|
+
* Get all tasks from a file as a simple array
|
|
110
|
+
*
|
|
111
|
+
* @param filePath - Path to the tasks file
|
|
112
|
+
* @returns Array of parsed tasks or empty array
|
|
113
|
+
*/
|
|
114
|
+
export declare function getAllTasks(filePath: string): ParsedTask[];
|
|
115
|
+
/**
|
|
116
|
+
* Get a specific task by ID
|
|
117
|
+
*
|
|
118
|
+
* @param filePath - Path to the tasks file
|
|
119
|
+
* @param taskId - Task ID to find (e.g., "T001")
|
|
120
|
+
* @returns The task or null if not found
|
|
121
|
+
*/
|
|
122
|
+
export declare function getTaskById(filePath: string, taskId: string): ParsedTask | null;
|
|
123
|
+
/**
|
|
124
|
+
* Get incomplete tasks ready for work (not blocked by dependencies)
|
|
125
|
+
*
|
|
126
|
+
* @param filePath - Path to the tasks file
|
|
127
|
+
* @returns Array of incomplete tasks
|
|
128
|
+
*/
|
|
129
|
+
export declare function getIncompleteTasks(filePath: string): ParsedTask[];
|
|
130
|
+
/**
|
|
131
|
+
* Get tasks that can be worked on in parallel
|
|
132
|
+
*
|
|
133
|
+
* @param filePath - Path to the tasks file
|
|
134
|
+
* @returns Array of parallelizable incomplete tasks
|
|
135
|
+
*/
|
|
136
|
+
export declare function getParallelizableTasks(filePath: string): ParsedTask[];
|
|
137
|
+
/**
|
|
138
|
+
* Get tasks grouped by phase
|
|
139
|
+
*
|
|
140
|
+
* @param filePath - Path to the tasks file
|
|
141
|
+
* @returns Map of phase number to tasks in that phase
|
|
142
|
+
*/
|
|
143
|
+
export declare function getTasksByPhase(filePath: string): Map<number, ParsedTask[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Get tasks grouped by user story
|
|
146
|
+
*
|
|
147
|
+
* @param filePath - Path to the tasks file
|
|
148
|
+
* @returns Map of user story ID to tasks
|
|
149
|
+
*/
|
|
150
|
+
export declare function getTasksByUserStory(filePath: string): Map<string | null, ParsedTask[]>;
|
|
151
|
+
/**
|
|
152
|
+
* Check if a file appears to be a valid tasks.md file
|
|
153
|
+
*
|
|
154
|
+
* @param filePath - Path to check
|
|
155
|
+
* @returns true if the file looks like a tasks file
|
|
156
|
+
*/
|
|
157
|
+
export declare function isTasksFile(filePath: string): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Get task completion statistics
|
|
160
|
+
*
|
|
161
|
+
* @param filePath - Path to the tasks file
|
|
162
|
+
* @returns Statistics object or null
|
|
163
|
+
*/
|
|
164
|
+
export declare function getTaskStats(filePath: string): {
|
|
165
|
+
total: number;
|
|
166
|
+
completed: number;
|
|
167
|
+
incomplete: number;
|
|
168
|
+
parallelizable: number;
|
|
169
|
+
completionRate: number;
|
|
170
|
+
} | null;
|
|
171
|
+
//# sourceMappingURL=tasks-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks-parser.d.ts","sourceRoot":"","sources":["../../src/parser/tasks-parser.ts"],"names":[],"mappings":"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"}
|