speccore 1.0.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.
Files changed (196) hide show
  1. package/README.en.md +401 -0
  2. package/README.md +401 -0
  3. package/bin/speccore +2 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +450 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/archive.d.ts +10 -0
  9. package/dist/commands/archive.d.ts.map +1 -0
  10. package/dist/commands/archive.js +138 -0
  11. package/dist/commands/archive.js.map +1 -0
  12. package/dist/commands/audit.d.ts +10 -0
  13. package/dist/commands/audit.d.ts.map +1 -0
  14. package/dist/commands/audit.js +278 -0
  15. package/dist/commands/audit.js.map +1 -0
  16. package/dist/commands/baseline.d.ts +13 -0
  17. package/dist/commands/baseline.d.ts.map +1 -0
  18. package/dist/commands/baseline.js +227 -0
  19. package/dist/commands/baseline.js.map +1 -0
  20. package/dist/commands/bugfix.d.ts +13 -0
  21. package/dist/commands/bugfix.d.ts.map +1 -0
  22. package/dist/commands/bugfix.js +181 -0
  23. package/dist/commands/bugfix.js.map +1 -0
  24. package/dist/commands/change.d.ts +14 -0
  25. package/dist/commands/change.d.ts.map +1 -0
  26. package/dist/commands/change.js +150 -0
  27. package/dist/commands/change.js.map +1 -0
  28. package/dist/commands/config.d.ts +7 -0
  29. package/dist/commands/config.d.ts.map +1 -0
  30. package/dist/commands/config.js +110 -0
  31. package/dist/commands/config.js.map +1 -0
  32. package/dist/commands/dashboard.d.ts +9 -0
  33. package/dist/commands/dashboard.d.ts.map +1 -0
  34. package/dist/commands/dashboard.js +209 -0
  35. package/dist/commands/dashboard.js.map +1 -0
  36. package/dist/commands/demo.d.ts +10 -0
  37. package/dist/commands/demo.d.ts.map +1 -0
  38. package/dist/commands/demo.js +151 -0
  39. package/dist/commands/demo.js.map +1 -0
  40. package/dist/commands/execute.d.ts +18 -0
  41. package/dist/commands/execute.d.ts.map +1 -0
  42. package/dist/commands/execute.js +127 -0
  43. package/dist/commands/execute.js.map +1 -0
  44. package/dist/commands/global-status.d.ts +9 -0
  45. package/dist/commands/global-status.d.ts.map +1 -0
  46. package/dist/commands/global-status.js +135 -0
  47. package/dist/commands/global-status.js.map +1 -0
  48. package/dist/commands/goal.d.ts +15 -0
  49. package/dist/commands/goal.d.ts.map +1 -0
  50. package/dist/commands/goal.js +282 -0
  51. package/dist/commands/goal.js.map +1 -0
  52. package/dist/commands/handover.d.ts +11 -0
  53. package/dist/commands/handover.d.ts.map +1 -0
  54. package/dist/commands/handover.js +169 -0
  55. package/dist/commands/handover.js.map +1 -0
  56. package/dist/commands/health.d.ts +7 -0
  57. package/dist/commands/health.d.ts.map +1 -0
  58. package/dist/commands/health.js +80 -0
  59. package/dist/commands/health.js.map +1 -0
  60. package/dist/commands/help.d.ts +10 -0
  61. package/dist/commands/help.d.ts.map +1 -0
  62. package/dist/commands/help.js +93 -0
  63. package/dist/commands/help.js.map +1 -0
  64. package/dist/commands/history.d.ts +9 -0
  65. package/dist/commands/history.d.ts.map +1 -0
  66. package/dist/commands/history.js +87 -0
  67. package/dist/commands/history.js.map +1 -0
  68. package/dist/commands/impact.d.ts +12 -0
  69. package/dist/commands/impact.d.ts.map +1 -0
  70. package/dist/commands/impact.js +238 -0
  71. package/dist/commands/impact.js.map +1 -0
  72. package/dist/commands/import.d.ts +15 -0
  73. package/dist/commands/import.d.ts.map +1 -0
  74. package/dist/commands/import.js +366 -0
  75. package/dist/commands/import.js.map +1 -0
  76. package/dist/commands/init.d.ts +6 -0
  77. package/dist/commands/init.d.ts.map +1 -0
  78. package/dist/commands/init.js +564 -0
  79. package/dist/commands/init.js.map +1 -0
  80. package/dist/commands/iteration/create.d.ts +7 -0
  81. package/dist/commands/iteration/create.d.ts.map +1 -0
  82. package/dist/commands/iteration/create.js +141 -0
  83. package/dist/commands/iteration/create.js.map +1 -0
  84. package/dist/commands/iteration/split.d.ts +9 -0
  85. package/dist/commands/iteration/split.d.ts.map +1 -0
  86. package/dist/commands/iteration/split.js +165 -0
  87. package/dist/commands/iteration/split.js.map +1 -0
  88. package/dist/commands/iteration-from-global.d.ts +11 -0
  89. package/dist/commands/iteration-from-global.d.ts.map +1 -0
  90. package/dist/commands/iteration-from-global.js +294 -0
  91. package/dist/commands/iteration-from-global.js.map +1 -0
  92. package/dist/commands/plan.d.ts +12 -0
  93. package/dist/commands/plan.d.ts.map +1 -0
  94. package/dist/commands/plan.js +126 -0
  95. package/dist/commands/plan.js.map +1 -0
  96. package/dist/commands/progress.d.ts +10 -0
  97. package/dist/commands/progress.d.ts.map +1 -0
  98. package/dist/commands/progress.js +89 -0
  99. package/dist/commands/progress.js.map +1 -0
  100. package/dist/commands/rename.d.ts +14 -0
  101. package/dist/commands/rename.d.ts.map +1 -0
  102. package/dist/commands/rename.js +298 -0
  103. package/dist/commands/rename.js.map +1 -0
  104. package/dist/commands/report.d.ts +10 -0
  105. package/dist/commands/report.d.ts.map +1 -0
  106. package/dist/commands/report.js +124 -0
  107. package/dist/commands/report.js.map +1 -0
  108. package/dist/commands/research.d.ts +14 -0
  109. package/dist/commands/research.d.ts.map +1 -0
  110. package/dist/commands/research.js +181 -0
  111. package/dist/commands/research.js.map +1 -0
  112. package/dist/commands/retro.d.ts +10 -0
  113. package/dist/commands/retro.d.ts.map +1 -0
  114. package/dist/commands/retro.js +130 -0
  115. package/dist/commands/retro.js.map +1 -0
  116. package/dist/commands/spec.d.ts +8 -0
  117. package/dist/commands/spec.d.ts.map +1 -0
  118. package/dist/commands/spec.js +155 -0
  119. package/dist/commands/spec.js.map +1 -0
  120. package/dist/commands/status.d.ts +7 -0
  121. package/dist/commands/status.d.ts.map +1 -0
  122. package/dist/commands/status.js +48 -0
  123. package/dist/commands/status.js.map +1 -0
  124. package/dist/commands/sync-global.d.ts +13 -0
  125. package/dist/commands/sync-global.d.ts.map +1 -0
  126. package/dist/commands/sync-global.js +218 -0
  127. package/dist/commands/sync-global.js.map +1 -0
  128. package/dist/commands/sync.d.ts +13 -0
  129. package/dist/commands/sync.d.ts.map +1 -0
  130. package/dist/commands/sync.js +170 -0
  131. package/dist/commands/sync.js.map +1 -0
  132. package/dist/commands/task/new.d.ts +13 -0
  133. package/dist/commands/task/new.d.ts.map +1 -0
  134. package/dist/commands/task/new.js +195 -0
  135. package/dist/commands/task/new.js.map +1 -0
  136. package/dist/commands/template-add.d.ts +12 -0
  137. package/dist/commands/template-add.d.ts.map +1 -0
  138. package/dist/commands/template-add.js +65 -0
  139. package/dist/commands/template-add.js.map +1 -0
  140. package/dist/commands/validate.d.ts +10 -0
  141. package/dist/commands/validate.d.ts.map +1 -0
  142. package/dist/commands/validate.js +37 -0
  143. package/dist/commands/validate.js.map +1 -0
  144. package/dist/commands/welcome.d.ts +9 -0
  145. package/dist/commands/welcome.d.ts.map +1 -0
  146. package/dist/commands/welcome.js +166 -0
  147. package/dist/commands/welcome.js.map +1 -0
  148. package/dist/core/context.d.ts +31 -0
  149. package/dist/core/context.d.ts.map +1 -0
  150. package/dist/core/context.js +145 -0
  151. package/dist/core/context.js.map +1 -0
  152. package/dist/core/global-layer.d.ts +124 -0
  153. package/dist/core/global-layer.d.ts.map +1 -0
  154. package/dist/core/global-layer.js +456 -0
  155. package/dist/core/global-layer.js.map +1 -0
  156. package/dist/core/index.d.ts +8 -0
  157. package/dist/core/index.d.ts.map +1 -0
  158. package/dist/core/index.js +24 -0
  159. package/dist/core/index.js.map +1 -0
  160. package/dist/core/intent-recognition.d.ts +48 -0
  161. package/dist/core/intent-recognition.d.ts.map +1 -0
  162. package/dist/core/intent-recognition.js +485 -0
  163. package/dist/core/intent-recognition.js.map +1 -0
  164. package/dist/core/state.d.ts +26 -0
  165. package/dist/core/state.d.ts.map +1 -0
  166. package/dist/core/state.js +187 -0
  167. package/dist/core/state.js.map +1 -0
  168. package/dist/core/template-engine.d.ts +28 -0
  169. package/dist/core/template-engine.d.ts.map +1 -0
  170. package/dist/core/template-engine.js +57 -0
  171. package/dist/core/template-engine.js.map +1 -0
  172. package/dist/core/validator.d.ts +26 -0
  173. package/dist/core/validator.d.ts.map +1 -0
  174. package/dist/core/validator.js +246 -0
  175. package/dist/core/validator.js.map +1 -0
  176. package/dist/core/yaml-parser.d.ts +25 -0
  177. package/dist/core/yaml-parser.d.ts.map +1 -0
  178. package/dist/core/yaml-parser.js +113 -0
  179. package/dist/core/yaml-parser.js.map +1 -0
  180. package/dist/index.d.ts +2 -0
  181. package/dist/index.d.ts.map +1 -0
  182. package/dist/index.js +18 -0
  183. package/dist/index.js.map +1 -0
  184. package/dist/utils/file.d.ts +29 -0
  185. package/dist/utils/file.d.ts.map +1 -0
  186. package/dist/utils/file.js +126 -0
  187. package/dist/utils/file.js.map +1 -0
  188. package/dist/utils/git.d.ts +25 -0
  189. package/dist/utils/git.d.ts.map +1 -0
  190. package/dist/utils/git.js +77 -0
  191. package/dist/utils/git.js.map +1 -0
  192. package/dist/utils/logger.d.ts +41 -0
  193. package/dist/utils/logger.d.ts.map +1 -0
  194. package/dist/utils/logger.js +184 -0
  195. package/dist/utils/logger.js.map +1 -0
  196. package/package.json +49 -0
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readProjectGraph = readProjectGraph;
37
+ exports.scanTasks = scanTasks;
38
+ exports.calculateCompletionRate = calculateCompletionRate;
39
+ exports.buildDependencyGraph = buildDependencyGraph;
40
+ exports.topologicalSort = topologicalSort;
41
+ const fs_extra_1 = require("fs-extra");
42
+ const path_1 = require("path");
43
+ async function readProjectGraph(iteration) {
44
+ const graphPath = (0, path_1.join)(`期次-${iteration}`, '00-期次总览', 'PROJECT_GRAPH.md');
45
+ if (!(await (0, fs_extra_1.pathExists)(graphPath))) {
46
+ return {
47
+ name: iteration,
48
+ status: 'unknown',
49
+ startDate: '',
50
+ endDate: '',
51
+ tasks: [],
52
+ completionRate: 0
53
+ };
54
+ }
55
+ const content = await (0, fs_extra_1.readFile)(graphPath, 'utf-8');
56
+ return parseProjectGraph(content, iteration);
57
+ }
58
+ function parseProjectGraph(content, iterationName) {
59
+ const state = {
60
+ name: iterationName,
61
+ status: 'unknown',
62
+ startDate: '',
63
+ endDate: '',
64
+ tasks: [],
65
+ completionRate: 0
66
+ };
67
+ // Extract status from markdown
68
+ const statusMatch = content.match(/期次状态[::]\s*(.+)/);
69
+ if (statusMatch) {
70
+ state.status = statusMatch[1].trim();
71
+ }
72
+ // Extract date range
73
+ const dateMatch = content.match(/时间范围[::]\s*(\d{4}-\d{2}-\d{2})\s*[~~]\s*(\d{4}-\d{2}-\d{2})/);
74
+ if (dateMatch) {
75
+ state.startDate = dateMatch[1];
76
+ state.endDate = dateMatch[2];
77
+ }
78
+ // Parse tasks table
79
+ const taskMatches = content.matchAll(/\|\s*(Task-\d+)\s*\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|\s*(\d+)%?\s*\|\s*(\S+)\s*\|\s*([^|]+)\s*\|/g);
80
+ for (const match of taskMatches) {
81
+ state.tasks.push({
82
+ id: match[1].trim(),
83
+ name: match[2].trim(),
84
+ type: match[3].trim(),
85
+ progress: parseInt(match[4]) || 0,
86
+ status: parseStatus(match[5].trim()),
87
+ assignee: match[6].trim(),
88
+ dependencies: [],
89
+ priority: 'medium'
90
+ });
91
+ }
92
+ // Calculate completion rate
93
+ if (state.tasks.length > 0) {
94
+ const completed = state.tasks.filter(t => t.status === 'completed').length;
95
+ state.completionRate = Math.round((completed / state.tasks.length) * 100);
96
+ }
97
+ return state;
98
+ }
99
+ function parseStatus(status) {
100
+ if (status.includes('已完成') || status.includes('completed'))
101
+ return 'completed';
102
+ if (status.includes('进行中') || status.includes('in_progress'))
103
+ return 'in_progress';
104
+ if (status.includes('已归档') || status.includes('archived'))
105
+ return 'archived';
106
+ return 'pending';
107
+ }
108
+ async function scanTasks(iteration) {
109
+ const { pathExists, readdir } = await Promise.resolve().then(() => __importStar(require('fs-extra')));
110
+ const { join } = await Promise.resolve().then(() => __importStar(require('path')));
111
+ const iterationDir = `期次-${iteration}`;
112
+ if (!(await pathExists(iterationDir))) {
113
+ return [];
114
+ }
115
+ const entries = await readdir(iterationDir, { withFileTypes: true });
116
+ const tasks = [];
117
+ for (const entry of entries) {
118
+ if (entry.isDirectory() && entry.name.startsWith('Task-')) {
119
+ const taskId = entry.name;
120
+ const taskPath = join(iterationDir, taskId);
121
+ // Try to read task type
122
+ let type = 'feature';
123
+ const typePath = join(taskPath, '.task-type');
124
+ if (await pathExists(typePath)) {
125
+ const typeContent = await (0, fs_extra_1.readFile)(typePath, 'utf-8');
126
+ type = typeContent.trim();
127
+ }
128
+ // Try to read task name from TASK.md
129
+ let name = taskId;
130
+ const taskMdPath = join(taskPath, 'backend', 'TASK.md');
131
+ if (await pathExists(taskMdPath)) {
132
+ const taskMd = await (0, fs_extra_1.readFile)(taskMdPath, 'utf-8');
133
+ const nameMatch = taskMd.match(/#\s+(.+)/);
134
+ if (nameMatch) {
135
+ name = nameMatch[1].trim();
136
+ }
137
+ }
138
+ tasks.push({
139
+ id: taskId,
140
+ name,
141
+ type,
142
+ status: 'pending',
143
+ assignee: '',
144
+ dependencies: [],
145
+ priority: 'medium',
146
+ progress: 0
147
+ });
148
+ }
149
+ }
150
+ return tasks;
151
+ }
152
+ function calculateCompletionRate(tasks) {
153
+ if (tasks.length === 0)
154
+ return 0;
155
+ const completed = tasks.filter(t => t.status === 'completed').length;
156
+ return Math.round((completed / tasks.length) * 100);
157
+ }
158
+ function buildDependencyGraph(tasks) {
159
+ const graph = new Map();
160
+ for (const task of tasks) {
161
+ graph.set(task.id, task.dependencies);
162
+ }
163
+ return graph;
164
+ }
165
+ function topologicalSort(tasks) {
166
+ const graph = buildDependencyGraph(tasks);
167
+ const visited = new Set();
168
+ const result = [];
169
+ function visit(taskId) {
170
+ if (visited.has(taskId))
171
+ return;
172
+ visited.add(taskId);
173
+ const deps = graph.get(taskId) || [];
174
+ for (const dep of deps) {
175
+ visit(dep);
176
+ }
177
+ const task = tasks.find(t => t.id === taskId);
178
+ if (task) {
179
+ result.push(task);
180
+ }
181
+ }
182
+ for (const task of tasks) {
183
+ visit(task.id);
184
+ }
185
+ return result;
186
+ }
187
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export interface TemplateData {
2
+ [key: string]: string | number | boolean;
3
+ }
4
+ /**
5
+ * Simple template engine that replaces {{key}} placeholders
6
+ */
7
+ export declare class TemplateEngine {
8
+ private templatesDir;
9
+ constructor(templatesDir: string);
10
+ /**
11
+ * Render a template file with data
12
+ */
13
+ render(templateName: string, data: TemplateData): Promise<string>;
14
+ /**
15
+ * Render a template string with data
16
+ */
17
+ renderString(template: string, data: TemplateData): string;
18
+ /**
19
+ * Render and save to file
20
+ */
21
+ renderToFile(templateName: string, data: TemplateData, outputPath: string): Promise<void>;
22
+ /**
23
+ * List available templates
24
+ */
25
+ listTemplates(): Promise<string[]>;
26
+ }
27
+ export declare const templateEngine: TemplateEngine;
28
+ //# sourceMappingURL=template-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../../src/core/template-engine.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC1C;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,EAAE,MAAM;IAIhC;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAWvE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM;IAO1D;;OAEG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/F;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAUzC;AAGD,eAAO,MAAM,cAAc,gBAAyD,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templateEngine = exports.TemplateEngine = void 0;
4
+ const fs_extra_1 = require("fs-extra");
5
+ const path_1 = require("path");
6
+ /**
7
+ * Simple template engine that replaces {{key}} placeholders
8
+ */
9
+ class TemplateEngine {
10
+ constructor(templatesDir) {
11
+ this.templatesDir = templatesDir;
12
+ }
13
+ /**
14
+ * Render a template file with data
15
+ */
16
+ async render(templateName, data) {
17
+ const templatePath = (0, path_1.join)(this.templatesDir, templateName);
18
+ if (!(await (0, fs_extra_1.pathExists)(templatePath))) {
19
+ throw new Error(`Template not found: ${templatePath}`);
20
+ }
21
+ const template = await (0, fs_extra_1.readFile)(templatePath, 'utf-8');
22
+ return this.renderString(template, data);
23
+ }
24
+ /**
25
+ * Render a template string with data
26
+ */
27
+ renderString(template, data) {
28
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
29
+ const value = data[key];
30
+ return value !== undefined ? String(value) : match;
31
+ });
32
+ }
33
+ /**
34
+ * Render and save to file
35
+ */
36
+ async renderToFile(templateName, data, outputPath) {
37
+ const rendered = await this.render(templateName, data);
38
+ await (0, fs_extra_1.ensureDir)((0, path_1.join)(outputPath, '..'));
39
+ await (0, fs_extra_1.writeFile)(outputPath, rendered, 'utf-8');
40
+ }
41
+ /**
42
+ * List available templates
43
+ */
44
+ async listTemplates() {
45
+ if (!(await (0, fs_extra_1.pathExists)(this.templatesDir))) {
46
+ return [];
47
+ }
48
+ const entries = await (0, fs_extra_1.readdir)(this.templatesDir, { withFileTypes: true });
49
+ return entries
50
+ .filter(e => e.isFile())
51
+ .map(e => e.name);
52
+ }
53
+ }
54
+ exports.TemplateEngine = TemplateEngine;
55
+ // Default template engine instance
56
+ exports.templateEngine = new TemplateEngine((0, path_1.join)(__dirname, '..', 'templates'));
57
+ //# sourceMappingURL=template-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-engine.js","sourceRoot":"","sources":["../../src/core/template-engine.ts"],"names":[],"mappings":";;;AAAA,uCAA+E;AAC/E,+BAA4B;AAO5B;;GAEG;AACH,MAAa,cAAc;IAGzB,YAAY,YAAoB;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,YAAoB,EAAE,IAAkB;QACnD,MAAM,YAAY,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAE3D,IAAI,CAAC,CAAC,MAAM,IAAA,qBAAU,EAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAQ,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,QAAgB,EAAE,IAAkB;QAC/C,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,YAAoB,EAAE,IAAkB,EAAE,UAAkB;QAC7E,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACvD,MAAM,IAAA,oBAAS,EAAC,IAAA,WAAI,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QACxC,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,CAAC,MAAM,IAAA,qBAAU,EAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;CACF;AArDD,wCAqDC;AAED,mCAAmC;AACtB,QAAA,cAAc,GAAG,IAAI,cAAc,CAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ export interface ValidationError {
2
+ file: string;
3
+ issue: string;
4
+ severity: 'error' | 'warning';
5
+ fixable?: boolean;
6
+ }
7
+ export interface ValidationResult {
8
+ errors: ValidationError[];
9
+ warnings: ValidationError[];
10
+ passRate: number;
11
+ totalChecks: number;
12
+ taskResults: Record<string, TaskValidationResult>;
13
+ }
14
+ export interface TaskValidationResult {
15
+ taskId: string;
16
+ errors: ValidationError[];
17
+ warnings: ValidationError[];
18
+ passRate: number;
19
+ }
20
+ export declare function validateProject(iteration?: string, taskId?: string, options?: {
21
+ fix?: boolean;
22
+ strict?: boolean;
23
+ }): Promise<ValidationResult>;
24
+ export declare function formatValidationResult(result: ValidationResult, format: 'text' | 'json'): string;
25
+ export declare function autoFix(result: ValidationResult): Promise<number>;
26
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CACnC,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5C,OAAO,CAAC,gBAAgB,CAAC,CAgC3B;AAgJD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAmChG;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBvE"}
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.validateProject = validateProject;
37
+ exports.formatValidationResult = formatValidationResult;
38
+ exports.autoFix = autoFix;
39
+ const fs_extra_1 = require("fs-extra");
40
+ const path_1 = require("path");
41
+ const yaml_parser_1 = require("./yaml-parser");
42
+ async function validateProject(iteration, taskId, options) {
43
+ const result = {
44
+ errors: [],
45
+ warnings: [],
46
+ passRate: 0,
47
+ totalChecks: 0,
48
+ taskResults: {}
49
+ };
50
+ const iterations = iteration ? [iteration] : await findIterations();
51
+ for (const iter of iterations) {
52
+ const tasks = taskId ? [taskId] : await findTasks(iter);
53
+ for (const task of tasks) {
54
+ const taskResult = await validateTask(iter, task, options);
55
+ result.errors.push(...taskResult.errors);
56
+ result.warnings.push(...taskResult.warnings);
57
+ result.totalChecks += taskResult.errors.length + taskResult.warnings.length;
58
+ result.taskResults[task] = taskResult;
59
+ }
60
+ }
61
+ // Calculate pass rate
62
+ if (result.totalChecks > 0) {
63
+ const passed = result.totalChecks - result.errors.length;
64
+ result.passRate = Math.round((passed / result.totalChecks) * 100);
65
+ }
66
+ else {
67
+ result.passRate = 100;
68
+ }
69
+ return result;
70
+ }
71
+ async function validateTask(iteration, taskId, options) {
72
+ const result = {
73
+ taskId,
74
+ errors: [],
75
+ warnings: [],
76
+ passRate: 0
77
+ };
78
+ const taskPath = (0, path_1.join)(`期次-${iteration}`, taskId);
79
+ // Check if task directory exists
80
+ if (!(await (0, fs_extra_1.pathExists)(taskPath))) {
81
+ result.errors.push({
82
+ file: taskPath,
83
+ issue: 'Task directory does not exist',
84
+ severity: 'error'
85
+ });
86
+ return result;
87
+ }
88
+ // Check required files
89
+ const requiredFiles = [
90
+ '.task-type',
91
+ 'backend/REQ.md',
92
+ 'backend/TASK.md',
93
+ 'backend/TECH.md',
94
+ 'frontend/REQ.md',
95
+ 'frontend/TASK.md',
96
+ 'frontend/TECH.md'
97
+ ];
98
+ for (const file of requiredFiles) {
99
+ const filePath = (0, path_1.join)(taskPath, file);
100
+ if (!(await (0, fs_extra_1.pathExists)(filePath))) {
101
+ if (options?.strict) {
102
+ result.errors.push({
103
+ file: filePath,
104
+ issue: `Missing required file: ${file}`,
105
+ severity: 'error',
106
+ fixable: true
107
+ });
108
+ }
109
+ else if (file.includes('backend/') || file.includes('frontend/')) {
110
+ // In non-strict mode, only backend OR frontend is required
111
+ const counterpart = file.replace('backend/', 'frontend/').replace('frontend/', 'backend/');
112
+ const counterpartPath = (0, path_1.join)(taskPath, counterpart);
113
+ if (!(await (0, fs_extra_1.pathExists)(counterpartPath))) {
114
+ result.errors.push({
115
+ file: filePath,
116
+ issue: `Missing required file: ${file} (and ${counterpart})`,
117
+ severity: 'error'
118
+ });
119
+ }
120
+ }
121
+ }
122
+ }
123
+ // Check YAML files
124
+ const yamlPath = (0, path_1.join)(taskPath, '_shared', 'API_CONTRACT.yaml');
125
+ if (await (0, fs_extra_1.pathExists)(yamlPath)) {
126
+ const parseResult = await (0, yaml_parser_1.parseYamlFile)(yamlPath);
127
+ if (!parseResult.success) {
128
+ result.errors.push({
129
+ file: yamlPath,
130
+ issue: parseResult.error || 'Invalid YAML',
131
+ severity: 'error',
132
+ fixable: false
133
+ });
134
+ }
135
+ else if (parseResult.data) {
136
+ const yamlErrors = (0, yaml_parser_1.validateApiContract)(parseResult.data);
137
+ for (const error of yamlErrors) {
138
+ result.errors.push({
139
+ file: yamlPath,
140
+ issue: error,
141
+ severity: 'error',
142
+ fixable: true
143
+ });
144
+ }
145
+ }
146
+ }
147
+ // Check markdown files for content
148
+ const mdFiles = ['backend/REQ.md', 'backend/TECH.md', 'frontend/REQ.md', 'frontend/TECH.md'];
149
+ for (const file of mdFiles) {
150
+ const filePath = (0, path_1.join)(taskPath, file);
151
+ if (await (0, fs_extra_1.pathExists)(filePath)) {
152
+ const content = await (0, fs_extra_1.readFile)(filePath, 'utf-8');
153
+ if (content.length < 100) {
154
+ result.warnings.push({
155
+ file: filePath,
156
+ issue: `Content too short (${content.length} chars), may be incomplete`,
157
+ severity: 'warning'
158
+ });
159
+ }
160
+ if (!content.includes('##') && content.length > 0) {
161
+ result.warnings.push({
162
+ file: filePath,
163
+ issue: 'Missing section headers (##)',
164
+ severity: 'warning'
165
+ });
166
+ }
167
+ }
168
+ }
169
+ // Calculate task pass rate
170
+ const total = result.errors.length + result.warnings.length;
171
+ if (total > 0) {
172
+ result.passRate = Math.round(((total - result.errors.length) / total) * 100);
173
+ }
174
+ else {
175
+ result.passRate = 100;
176
+ }
177
+ return result;
178
+ }
179
+ async function findIterations() {
180
+ const { pathExists, readdir } = await Promise.resolve().then(() => __importStar(require('fs-extra')));
181
+ if (!(await pathExists('.')))
182
+ return [];
183
+ const entries = await readdir('.', { withFileTypes: true });
184
+ return entries
185
+ .filter(e => e.isDirectory() && e.name.startsWith('期次-'))
186
+ .map(e => e.name.replace('期次-', ''));
187
+ }
188
+ async function findTasks(iteration) {
189
+ const { pathExists, readdir } = await Promise.resolve().then(() => __importStar(require('fs-extra')));
190
+ const { join } = await Promise.resolve().then(() => __importStar(require('path')));
191
+ const iterPath = `期次-${iteration}`;
192
+ if (!(await pathExists(iterPath)))
193
+ return [];
194
+ const entries = await readdir(iterPath, { withFileTypes: true });
195
+ return entries
196
+ .filter(e => e.isDirectory() && e.name.startsWith('Task-'))
197
+ .map(e => e.name);
198
+ }
199
+ function formatValidationResult(result, format) {
200
+ if (format === 'json') {
201
+ return JSON.stringify(result, null, 2);
202
+ }
203
+ const lines = [];
204
+ lines.push('📋 Spec Compliance Validation Result');
205
+ lines.push('');
206
+ lines.push(`Pass Rate: ${result.passRate}%`);
207
+ lines.push(`Total Checks: ${result.totalChecks}`);
208
+ lines.push(`Errors: ${result.errors.length}`);
209
+ lines.push(`Warnings: ${result.warnings.length}`);
210
+ lines.push('');
211
+ if (result.errors.length > 0) {
212
+ lines.push('❌ Errors:');
213
+ for (const error of result.errors) {
214
+ lines.push(` [${error.severity.toUpperCase()}] ${error.file}: ${error.issue}`);
215
+ }
216
+ lines.push('');
217
+ }
218
+ if (result.warnings.length > 0) {
219
+ lines.push('⚠️ Warnings:');
220
+ for (const warning of result.warnings) {
221
+ lines.push(` [${warning.severity.toUpperCase()}] ${warning.file}: ${warning.issue}`);
222
+ }
223
+ lines.push('');
224
+ }
225
+ if (result.errors.length === 0 && result.warnings.length === 0) {
226
+ lines.push('✅ All checks passed!');
227
+ }
228
+ return lines.join('\n');
229
+ }
230
+ async function autoFix(result) {
231
+ let fixedCount = 0;
232
+ for (const error of result.errors) {
233
+ if (!error.fixable)
234
+ continue;
235
+ // Try to fix missing files by creating them
236
+ if (error.issue.includes('Missing')) {
237
+ const { ensureDir, writeFile } = await Promise.resolve().then(() => __importStar(require('fs-extra')));
238
+ const { dirname } = await Promise.resolve().then(() => __importStar(require('path')));
239
+ await ensureDir(dirname(error.file));
240
+ await writeFile(error.file, `# ${(0, path_1.basename)(error.file)}\n\n> Auto-generated by SpecCore\n`, 'utf-8');
241
+ fixedCount++;
242
+ }
243
+ }
244
+ return fixedCount;
245
+ }
246
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface ParseResult {
2
+ success: boolean;
3
+ data?: any;
4
+ error?: string;
5
+ }
6
+ /**
7
+ * Parse a YAML file and return structured data
8
+ */
9
+ export declare function parseYamlFile(filePath: string): Promise<ParseResult>;
10
+ /**
11
+ * Validate API contract YAML structure
12
+ */
13
+ export declare function validateApiContract(data: any): string[];
14
+ /**
15
+ * Convert YAML to JSON string
16
+ */
17
+ export declare function yamlToJson(data: any): string;
18
+ /**
19
+ * Extract API endpoints from YAML content
20
+ */
21
+ export declare function extractEndpoints(data: any): Array<{
22
+ path: string;
23
+ method: string;
24
+ }>;
25
+ //# sourceMappingURL=yaml-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-parser.d.ts","sourceRoot":"","sources":["../../src/core/yaml-parser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAiB1E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,CA6BvD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAWnF"}