mcp-spec-cli 1.1.0 → 1.2.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 (68) hide show
  1. package/api/spec-workflow.openapi.yaml +31 -23
  2. package/dist/cli.js +25 -14
  3. package/dist/cli.js.map +1 -1
  4. package/dist/features/shared/MarkdownTaskUpdater.d.ts +14 -0
  5. package/dist/features/shared/MarkdownTaskUpdater.d.ts.map +1 -0
  6. package/dist/features/shared/MarkdownTaskUpdater.js +75 -0
  7. package/dist/features/shared/MarkdownTaskUpdater.js.map +1 -0
  8. package/dist/features/shared/SpecManager.d.ts +4 -1
  9. package/dist/features/shared/SpecManager.d.ts.map +1 -1
  10. package/dist/features/shared/SpecManager.js +16 -16
  11. package/dist/features/shared/SpecManager.js.map +1 -1
  12. package/dist/features/shared/TaskGuidanceRepository.d.ts +36 -0
  13. package/dist/features/shared/TaskGuidanceRepository.d.ts.map +1 -0
  14. package/dist/features/shared/TaskGuidanceRepository.js +23 -0
  15. package/dist/features/shared/TaskGuidanceRepository.js.map +1 -0
  16. package/dist/features/shared/TaskLexer.d.ts +18 -0
  17. package/dist/features/shared/TaskLexer.d.ts.map +1 -0
  18. package/dist/features/shared/TaskLexer.js +60 -0
  19. package/dist/features/shared/TaskLexer.js.map +1 -0
  20. package/dist/features/shared/TemplateRepository.d.ts +14 -0
  21. package/dist/features/shared/TemplateRepository.d.ts.map +1 -0
  22. package/dist/features/shared/TemplateRepository.js +40 -0
  23. package/dist/features/shared/TemplateRepository.js.map +1 -0
  24. package/dist/features/shared/WorkflowStateRepository.d.ts +18 -0
  25. package/dist/features/shared/WorkflowStateRepository.d.ts.map +1 -0
  26. package/dist/features/shared/WorkflowStateRepository.js +30 -0
  27. package/dist/features/shared/WorkflowStateRepository.js.map +1 -0
  28. package/dist/features/shared/markdownTaskUpdater.d.ts +14 -0
  29. package/dist/features/shared/markdownTaskUpdater.d.ts.map +1 -0
  30. package/dist/features/shared/markdownTaskUpdater.js +75 -0
  31. package/dist/features/shared/markdownTaskUpdater.js.map +1 -0
  32. package/dist/features/shared/openApiLoader.d.ts +37 -42
  33. package/dist/features/shared/openApiLoader.d.ts.map +1 -1
  34. package/dist/features/shared/openApiLoader.js +13 -127
  35. package/dist/features/shared/openApiLoader.js.map +1 -1
  36. package/dist/features/shared/taskGuidanceRepository.d.ts +36 -0
  37. package/dist/features/shared/taskGuidanceRepository.d.ts.map +1 -0
  38. package/dist/features/shared/taskGuidanceRepository.js +23 -0
  39. package/dist/features/shared/taskGuidanceRepository.js.map +1 -0
  40. package/dist/features/shared/taskLexer.d.ts +18 -0
  41. package/dist/features/shared/taskLexer.d.ts.map +1 -0
  42. package/dist/features/shared/taskLexer.js +66 -0
  43. package/dist/features/shared/taskLexer.js.map +1 -0
  44. package/dist/features/shared/taskParser.d.ts +32 -13
  45. package/dist/features/shared/taskParser.d.ts.map +1 -1
  46. package/dist/features/shared/taskParser.js +72 -240
  47. package/dist/features/shared/taskParser.js.map +1 -1
  48. package/dist/features/shared/templateRepository.d.ts +14 -0
  49. package/dist/features/shared/templateRepository.d.ts.map +1 -0
  50. package/dist/features/shared/templateRepository.js +40 -0
  51. package/dist/features/shared/templateRepository.js.map +1 -0
  52. package/dist/features/shared/workflowStateRepository.d.ts +18 -0
  53. package/dist/features/shared/workflowStateRepository.d.ts.map +1 -0
  54. package/dist/features/shared/workflowStateRepository.js +30 -0
  55. package/dist/features/shared/workflowStateRepository.js.map +1 -0
  56. package/dist/features/task/TaskGuidancePresenter.d.ts +20 -0
  57. package/dist/features/task/TaskGuidancePresenter.d.ts.map +1 -0
  58. package/dist/features/task/TaskGuidancePresenter.js +84 -0
  59. package/dist/features/task/TaskGuidancePresenter.js.map +1 -0
  60. package/dist/features/task/completeTask.d.ts +3 -3
  61. package/dist/features/task/completeTask.d.ts.map +1 -1
  62. package/dist/features/task/completeTask.js +63 -309
  63. package/dist/features/task/completeTask.js.map +1 -1
  64. package/dist/features/task/taskGuidancePresenter.d.ts +20 -0
  65. package/dist/features/task/taskGuidancePresenter.d.ts.map +1 -0
  66. package/dist/features/task/taskGuidancePresenter.js +84 -0
  67. package/dist/features/task/taskGuidancePresenter.js.map +1 -0
  68. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ import { openApiLoader } from './openApiLoader.js';
2
+ /**
3
+ * TaskGuidanceRepository manages guidance-related data from the OpenAPI spec.
4
+ */
5
+ export class TaskGuidanceRepository {
6
+ /**
7
+ * Loads the guidance template structure from the spec.
8
+ */
9
+ static getGuidanceTemplate() {
10
+ openApiLoader.loadSpec();
11
+ return openApiLoader.getTaskGuidanceTemplate();
12
+ }
13
+ /**
14
+ * Gets a specific completion message by key.
15
+ */
16
+ static getCompletionMessage(key) {
17
+ const template = this.getGuidanceTemplate();
18
+ if (!template)
19
+ throw new Error('Task guidance template not found');
20
+ return template.completionMessages[key] || '';
21
+ }
22
+ }
23
+ //# sourceMappingURL=taskGuidanceRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskGuidanceRepository.js","sourceRoot":"","sources":["../../../src/features/shared/taskGuidanceRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACjC;;OAEG;IACH,MAAM,CAAC,mBAAmB;QACxB,aAAa,CAAC,QAAQ,EAAE,CAAC;QACzB,OAAO,aAAa,CAAC,uBAAuB,EAAE,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,GAAW;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC5C,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACnE,OAAQ,QAAQ,CAAC,kBAA0B,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACzD,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ export interface TaskToken {
2
+ type: 'heading' | 'list_item';
3
+ text: string;
4
+ depth?: number;
5
+ checked?: boolean;
6
+ raw: string;
7
+ line: number;
8
+ }
9
+ /**
10
+ * TaskLexer uses 'marked' to extract relevant task tokens and their line numbers.
11
+ */
12
+ export declare class TaskLexer {
13
+ /**
14
+ * Lexes the markdown content into a stream of task-related tokens.
15
+ */
16
+ static lex(content: string): TaskToken[];
17
+ }
18
+ //# sourceMappingURL=taskLexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskLexer.d.ts","sourceRoot":"","sources":["../../../src/features/shared/taskLexer.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,GAAG,WAAW,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE;CA2DzC"}
@@ -0,0 +1,66 @@
1
+ import { lexer } from 'marked';
2
+ /**
3
+ * TaskLexer uses 'marked' to extract relevant task tokens and their line numbers.
4
+ */
5
+ export class TaskLexer {
6
+ /**
7
+ * Lexes the markdown content into a stream of task-related tokens.
8
+ */
9
+ static lex(content) {
10
+ const tokens = lexer(content);
11
+ const taskTokens = [];
12
+ const lines = content.split('\n');
13
+ const findLineNumber = (raw, startFrom) => {
14
+ for (let i = startFrom; i < lines.length; i++) {
15
+ const lineContent = lines[i].trim();
16
+ const rawFirstLine = raw.split('\n')[0].trim();
17
+ if (lineContent.includes(rawFirstLine) || rawFirstLine.includes(lineContent)) {
18
+ return i + 1;
19
+ }
20
+ }
21
+ return -1;
22
+ };
23
+ let currentLine = 0;
24
+ const processTokens = (tokens) => {
25
+ for (const token of tokens) {
26
+ if (token.type === 'heading') {
27
+ const line = findLineNumber(token.raw, currentLine);
28
+ if (line !== -1) {
29
+ taskTokens.push({
30
+ type: 'heading',
31
+ text: token.text,
32
+ depth: token.depth,
33
+ raw: token.raw,
34
+ line
35
+ });
36
+ currentLine = line;
37
+ }
38
+ }
39
+ else if (token.type === 'list_item') {
40
+ const line = findLineNumber(token.raw, currentLine);
41
+ if (line !== -1) {
42
+ taskTokens.push({
43
+ type: 'list_item',
44
+ text: token.text,
45
+ checked: token.checked,
46
+ raw: token.raw,
47
+ line
48
+ });
49
+ currentLine = line;
50
+ }
51
+ }
52
+ // Recursively process tokens if any
53
+ if ('tokens' in token && token.tokens) {
54
+ processTokens(token.tokens);
55
+ }
56
+ // Recursively process items for lists
57
+ if ('items' in token && token.items) {
58
+ processTokens(token.items);
59
+ }
60
+ }
61
+ };
62
+ processTokens(tokens);
63
+ return taskTokens;
64
+ }
65
+ }
66
+ //# sourceMappingURL=taskLexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskLexer.js","sourceRoot":"","sources":["../../../src/features/shared/taskLexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAS,MAAM,QAAQ,CAAC;AAWtC;;GAEG;AACH,MAAM,OAAO,SAAS;IACpB;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,OAAe;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAgB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,SAAiB,EAAU,EAAE;YAChE,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpC,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC/C,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC7E,OAAO,CAAC,GAAG,CAAC,CAAC;gBACf,CAAC;YACH,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC,CAAC;QAEF,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,MAAM,aAAa,GAAG,CAAC,MAAe,EAAE,EAAE;YACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC7B,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;oBACpD,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;wBAChB,UAAU,CAAC,IAAI,CAAC;4BACd,IAAI,EAAE,SAAS;4BACf,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,KAAK,EAAE,KAAK,CAAC,KAAK;4BAClB,GAAG,EAAE,KAAK,CAAC,GAAG;4BACd,IAAI;yBACL,CAAC,CAAC;wBACH,WAAW,GAAG,IAAI,CAAC;oBACrB,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACtC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;oBACpD,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;wBAChB,UAAU,CAAC,IAAI,CAAC;4BACd,IAAI,EAAE,WAAW;4BACjB,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,OAAO,EAAE,KAAK,CAAC,OAAO;4BACtB,GAAG,EAAE,KAAK,CAAC,GAAG;4BACd,IAAI;yBACL,CAAC,CAAC;wBACH,WAAW,GAAG,IAAI,CAAC;oBACrB,CAAC;gBACH,CAAC;gBAED,oCAAoC;gBACpC,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACtC,aAAa,CAAC,KAAK,CAAC,MAAiB,CAAC,CAAC;gBACzC,CAAC;gBACD,sCAAsC;gBACtC,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBACpC,aAAa,CAAC,KAAK,CAAC,KAAgB,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,aAAa,CAAC,MAAiB,CAAC,CAAC;QACjC,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
@@ -1,17 +1,36 @@
1
+ export interface Task {
2
+ id: string;
3
+ text: string;
4
+ completed: boolean;
5
+ indent: number;
6
+ line: number;
7
+ isParent?: boolean;
8
+ children: Task[];
9
+ }
1
10
  /**
2
- * Parse tasks from tasks.md file
11
+ * TaskParser builds a hierarchical task structure from Markdown tokens.
3
12
  */
4
- export interface Task {
5
- number: string;
6
- description: string;
7
- checked: boolean;
8
- subtasks?: Task[];
9
- isVirtual?: boolean;
13
+ export declare class TaskParser {
14
+ /**
15
+ * Parses task list content into a hierarchical structure.
16
+ */
17
+ static parse(content: string): Task[];
18
+ /**
19
+ * Build hierarchical relationships based on task IDs.
20
+ */
21
+ private static buildHierarchy;
22
+ }
23
+ /**
24
+ * TaskPresenter handles formatting task structures for CLI display.
25
+ */
26
+ export declare class TaskPresenter {
27
+ /**
28
+ * Formats a hierarchical task structure for full display.
29
+ */
30
+ static formatFullDisplay(tasks: Task[]): string;
31
+ /**
32
+ * Formats a single task for detailed display.
33
+ */
34
+ static formatTaskDetail(task: Task): string;
10
35
  }
11
- export declare function parseTasksFile(path: string): Task[];
12
- export declare function parseTasksFromContent(content: string): Task[];
13
- export declare function getFirstUncompletedTask(tasks: Task[]): Task | null;
14
- export declare function formatTaskForDisplay(task: Task): string;
15
- export declare function formatTaskForFullDisplay(task: Task, content: string): string;
16
- export declare function formatTaskListOverview(path: string): string;
17
36
  //# sourceMappingURL=taskParser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"taskParser.d.ts","sourceRoot":"","sources":["../../../src/features/shared/taskParser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CAmBnD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAqH7D;AAuBD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAyBlE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAYvD;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyD5E;AAGD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB3D"}
1
+ {"version":3,"file":"taskParser.d.ts","sourceRoot":"","sources":["../../../src/features/shared/taskParser.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,IAAI,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE;IAiCrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;CAwB9B;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM;IAa/C;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;CAI5C"}
@@ -1,259 +1,91 @@
1
+ import { TaskLexer } from './taskLexer.js';
1
2
  /**
2
- * Parse tasks from tasks.md file
3
+ * TaskParser builds a hierarchical task structure from Markdown tokens.
3
4
  */
4
- import { readFileSync } from 'fs';
5
- import { join } from 'path';
6
- export function parseTasksFile(path) {
7
- try {
8
- const tasksPath = join(path, 'tasks.md');
9
- const content = readFileSync(tasksPath, 'utf-8');
10
- // Remove template marker blocks
11
- const cleanContent = content
12
- .replace(/<!--\s*SPEC-MARKER[\s\S]*?-->/g, '') // Compatible with old format
13
- .replace(/<template-tasks>[\s\S]*?<\/template-tasks>/g, '') // Match actual task template markers
14
- .trim();
15
- if (!cleanContent) {
16
- return [];
17
- }
18
- return parseTasksFromContent(cleanContent);
19
- }
20
- catch {
21
- return [];
22
- }
23
- }
24
- export function parseTasksFromContent(content) {
25
- const lines = content.split('\n');
26
- const allTasks = [];
27
- // Phase 1: Collect all tasks with checkboxes
28
- for (let i = 0; i < lines.length; i++) {
29
- const line = lines[i];
30
- // Find checkbox pattern
31
- const checkboxMatch = line.match(/\[([xX ])\]/);
32
- if (!checkboxMatch)
33
- continue;
34
- // Extract task number (flexible matching)
35
- const numberMatch = line.match(/(\d+(?:\.\d+)*)/);
36
- if (!numberMatch)
37
- continue;
38
- const taskNumber = numberMatch[1];
39
- const isChecked = checkboxMatch[1].toLowerCase() === 'x';
40
- // Extract description (remove task number and checkbox)
41
- let description = line
42
- .replace(/\[([xX ])\]/, '') // Remove checkbox
43
- .replace(/(\d+(?:\.\d+)*)\s*[.:\-)]?/, '') // Remove task number
44
- .replace(/^[\s\-*]+/, '') // Remove leading symbols
45
- .trim();
46
- // If description is empty, try to get from next line
47
- if (!description && i + 1 < lines.length) {
48
- const nextLine = lines[i + 1].trim();
49
- if (nextLine && !nextLine.match(/\[([xX ])\]/) && !nextLine.match(/^#/)) {
50
- description = nextLine;
51
- i++; // Skip next line
52
- }
53
- }
54
- if (!description)
55
- continue;
56
- allTasks.push({
57
- number: taskNumber,
58
- description: description,
59
- checked: isChecked
60
- });
61
- }
62
- // Phase 2: Build hierarchy structure
63
- const taskMap = new Map();
64
- const rootTasks = [];
65
- // Infer main tasks from task numbers
66
- for (const task of allTasks) {
67
- if (!task.number.includes('.')) {
68
- // Top-level task
69
- taskMap.set(task.number, task);
70
- rootTasks.push(task);
71
- }
72
- }
73
- // Process subtasks
74
- for (const task of allTasks) {
75
- if (task.number.includes('.')) {
76
- const parts = task.number.split('.');
77
- const parentNumber = parts[0];
78
- // If main task doesn't exist, create virtual parent task
79
- if (!taskMap.has(parentNumber)) {
80
- // Try to find better title from document
81
- const betterTitle = findMainTaskTitle(lines, parentNumber);
82
- const virtualParent = {
83
- number: parentNumber,
84
- description: betterTitle || `Task Group ${parentNumber}`,
85
- checked: false,
86
- subtasks: [],
87
- isVirtual: true // 标记为虚拟任务
88
- };
89
- taskMap.set(parentNumber, virtualParent);
90
- rootTasks.push(virtualParent);
91
- }
92
- // Add subtask to main task
93
- const parent = taskMap.get(parentNumber);
94
- if (!parent.subtasks) {
95
- parent.subtasks = [];
5
+ export class TaskParser {
6
+ /**
7
+ * Parses task list content into a hierarchical structure.
8
+ */
9
+ static parse(content) {
10
+ const tokens = TaskLexer.lex(content);
11
+ const tasks = [];
12
+ let currentSection = '';
13
+ for (const token of tokens) {
14
+ if (token.type === 'heading') {
15
+ currentSection = token.text;
16
+ continue;
96
17
  }
97
- parent.subtasks.push(task);
98
- }
99
- }
100
- // Update main task completion status (only when all subtasks are completed)
101
- for (const task of rootTasks) {
102
- if (task.subtasks && task.subtasks.length > 0) {
103
- task.checked = task.subtasks.every(st => st.checked);
104
- }
105
- }
106
- // Sort by task number
107
- rootTasks.sort((a, b) => {
108
- const numA = parseInt(a.number);
109
- const numB = parseInt(b.number);
110
- return numA - numB;
111
- });
112
- // Sort subtasks
113
- for (const task of rootTasks) {
114
- if (task.subtasks) {
115
- task.subtasks.sort((a, b) => {
116
- const partsA = a.number.split('.').map(n => parseInt(n));
117
- const partsB = b.number.split('.').map(n => parseInt(n));
118
- for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
119
- const diff = (partsA[i] || 0) - (partsB[i] || 0);
120
- if (diff !== 0)
121
- return diff;
18
+ if (token.type === 'list_item') {
19
+ const match = token.text.match(/^(\d+(?:\.\d+)*)\.?(.*)$/);
20
+ if (match) {
21
+ const id = match[1];
22
+ const text = match[2].trim();
23
+ const indent = (id.split('.').length - 1) * 2; // Basic indent estimation based on ID dots
24
+ tasks.push({
25
+ id,
26
+ text,
27
+ completed: !!token.checked,
28
+ indent,
29
+ line: token.line,
30
+ children: []
31
+ });
122
32
  }
123
- return 0;
124
- });
125
- }
126
- }
127
- return rootTasks;
128
- }
129
- // Find main task title (from headers or other places)
130
- function findMainTaskTitle(lines, taskNumber) {
131
- // Look for lines like "### 1. Title" or "## 1. Title"
132
- for (const line of lines) {
133
- const headerMatch = line.match(/^#+\s*(\d+)\.\s*(.+)$/);
134
- if (headerMatch && headerMatch[1] === taskNumber) {
135
- return headerMatch[2].trim();
136
- }
137
- }
138
- // Also support other formats like "1. **Title**"
139
- for (const line of lines) {
140
- const boldMatch = line.match(/^(\d+)\.\s*\*\*(.+?)\*\*$/);
141
- if (boldMatch && boldMatch[1] === taskNumber) {
142
- return boldMatch[2].trim();
143
- }
144
- }
145
- return null;
146
- }
147
- export function getFirstUncompletedTask(tasks) {
148
- for (const task of tasks) {
149
- // 如果任务有子任务,优先检查子任务
150
- if (task.subtasks && task.subtasks.length > 0) {
151
- // 检查是否有未完成的子任务
152
- const firstUncompletedSubtask = task.subtasks.find(subtask => !subtask.checked);
153
- if (firstUncompletedSubtask) {
154
- // 无论是虚拟主任务还是真实主任务,都返回第一个未完成的子任务
155
- return firstUncompletedSubtask;
156
- }
157
- // 如果所有子任务都完成了,但主任务未完成,返回主任务
158
- if (!task.checked) {
159
- return task;
160
- }
161
- }
162
- else {
163
- // 没有子任务的情况,直接检查主任务
164
- if (!task.checked) {
165
- return task;
166
33
  }
167
34
  }
35
+ return this.buildHierarchy(tasks);
168
36
  }
169
- return null;
170
- }
171
- export function formatTaskForDisplay(task) {
172
- let display = `📋 Task ${task.number}: ${task.description}`;
173
- if (task.subtasks && task.subtasks.length > 0) {
174
- display += '\n\nSubtasks:';
175
- for (const subtask of task.subtasks) {
176
- const status = subtask.checked ? '✓' : '☐';
177
- display += `\n ${status} ${subtask.number}. ${subtask.description}`;
178
- }
179
- }
180
- return display;
181
- }
182
- export function formatTaskForFullDisplay(task, content) {
183
- const lines = content.split('\n');
184
- const taskLines = [];
185
- let capturing = false;
186
- let indent = '';
187
- for (const line of lines) {
188
- // Find task start (supports two formats: `1. - [ ] task` or `- [ ] 1. task`)
189
- const taskPattern1 = new RegExp(`^(\\s*)${task.number}\\.\\s*-\\s*\\[[ x]\\]\\s*`);
190
- const taskPattern2 = new RegExp(`^(\\s*)-\\s*\\[[ x]\\]\\s*${task.number}\\.\\s*`);
191
- if (line.match(taskPattern1) || line.match(taskPattern2)) {
192
- capturing = true;
193
- taskLines.push(line);
194
- indent = line.match(/^(\s*)/)?.[1] || '';
195
- continue;
196
- }
197
- // If capturing task content
198
- if (capturing) {
199
- // Check if reached next task at same or higher level
200
- const nextTaskPattern = /^(\s*)-\s*\[[ x]\]\s*\d+(\.\d+)*\.\s*/;
201
- const nextMatch = line.match(nextTaskPattern);
202
- if (nextMatch) {
203
- const nextIndent = nextMatch[1] || '';
204
- if (nextIndent.length <= indent.length) {
205
- break; // Found same or higher level task, stop capturing
206
- }
207
- }
208
- // Continue capturing content belonging to current task
209
- if (line.trim() === '') {
210
- taskLines.push(line);
211
- }
212
- else if (line.startsWith(indent + ' ') || line.startsWith(indent + '\t')) {
213
- // Deeper indented content belongs to current task
214
- taskLines.push(line);
215
- }
216
- else if (line.match(/^#+\s/)) {
217
- // Found header, stop capturing
218
- break;
219
- }
220
- else if (line.match(/^\d+\.\s*-\s*\[[ x]\]/)) {
221
- // Found other top-level task, stop
222
- break;
37
+ /**
38
+ * Build hierarchical relationships based on task IDs.
39
+ */
40
+ static buildHierarchy(flatTasks) {
41
+ const rootTasks = [];
42
+ const taskMap = new Map();
43
+ flatTasks.forEach(task => {
44
+ taskMap.set(task.id, task);
45
+ const parts = task.id.split('.');
46
+ if (parts.length === 1) {
47
+ rootTasks.push(task);
223
48
  }
224
49
  else {
225
- // Other cases continue capturing (might be continuation of task description)
226
- const isTaskLine = line.match(/^(\s*)-\s*\[[ x]\]/) || line.match(/^(\s*)\d+(\.\d+)*\.\s*-\s*\[[ x]\]/);
227
- if (isTaskLine) {
228
- break; // Found other task, stop
229
- }
230
- else if (line.match(/^\s/) && !line.match(/^\s{8,}/)) {
231
- // If indented but not too deep, might still be current task content
232
- taskLines.push(line);
50
+ const parentId = parts.slice(0, -1).join('.');
51
+ const parent = taskMap.get(parentId);
52
+ if (parent) {
53
+ parent.children.push(task);
54
+ parent.isParent = true;
233
55
  }
234
56
  else {
235
- break; // Otherwise stop
57
+ // If parent not found, treat as root (should not happen in valid docs)
58
+ rootTasks.push(task);
236
59
  }
237
60
  }
238
- }
61
+ });
62
+ return rootTasks;
239
63
  }
240
- return taskLines.join('\n').trimEnd();
241
64
  }
242
- // Format task list overview for display
243
- export function formatTaskListOverview(path) {
244
- try {
245
- const tasks = parseTasksFile(path);
246
- if (tasks.length === 0) {
247
- return 'No tasks found.';
248
- }
249
- const taskItems = tasks.map(task => {
250
- const status = task.checked ? '[x]' : '[ ]';
251
- return `- ${status} ${task.number}. ${task.description}`;
252
- });
253
- return taskItems.join('\n');
65
+ /**
66
+ * TaskPresenter handles formatting task structures for CLI display.
67
+ */
68
+ export class TaskPresenter {
69
+ /**
70
+ * Formats a hierarchical task structure for full display.
71
+ */
72
+ static formatFullDisplay(tasks) {
73
+ const lines = [];
74
+ const processTask = (task, level) => {
75
+ const indent = ' '.repeat(level * 2);
76
+ const checkbox = task.completed ? '[x]' : '[ ]';
77
+ lines.push(`${indent}${task.id}. ${checkbox} ${task.text}`);
78
+ task.children.forEach(child => processTask(child, level + 1));
79
+ };
80
+ tasks.forEach(task => processTask(task, 0));
81
+ return lines.join('\n');
254
82
  }
255
- catch {
256
- return 'Error loading tasks list.';
83
+ /**
84
+ * Formats a single task for detailed display.
85
+ */
86
+ static formatTaskDetail(task) {
87
+ const status = task.completed ? '✅ Completed' : '⏳ Pending';
88
+ return `${task.id}. ${task.text} (${status})`;
257
89
  }
258
90
  }
259
91
  //# sourceMappingURL=taskParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"taskParser.js","sourceRoot":"","sources":["../../../src/features/shared/taskParser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"taskParser.js","sourceRoot":"","sources":["../../../src/features/shared/taskParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * TemplateRepository manages document templates from the OpenAPI spec.
3
+ */
4
+ export declare class TemplateRepository {
5
+ /**
6
+ * Gets a document template by stage and interpolates variables.
7
+ */
8
+ static getInterpolatedTemplate(stage: 'requirements' | 'design' | 'tasks' | 'skipped', variables: Record<string, any>): string;
9
+ /**
10
+ * Internal formatter for document templates.
11
+ */
12
+ private static formatTemplate;
13
+ }
14
+ //# sourceMappingURL=templateRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateRepository.d.ts","sourceRoot":"","sources":["../../../src/features/shared/templateRepository.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,kBAAkB;IAC7B;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAU9H;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;CAqB9B"}
@@ -0,0 +1,40 @@
1
+ import { openApiLoader, OpenApiLoader } from './openApiLoader.js';
2
+ /**
3
+ * TemplateRepository manages document templates from the OpenAPI spec.
4
+ */
5
+ export class TemplateRepository {
6
+ /**
7
+ * Gets a document template by stage and interpolates variables.
8
+ */
9
+ static getInterpolatedTemplate(stage, variables) {
10
+ openApiLoader.loadSpec();
11
+ const template = openApiLoader.getDocumentTemplate(stage);
12
+ if (!template) {
13
+ throw new Error(`Template not found for stage: ${stage}`);
14
+ }
15
+ return this.formatTemplate(template, variables);
16
+ }
17
+ /**
18
+ * Internal formatter for document templates.
19
+ */
20
+ static formatTemplate(template, values) {
21
+ const lines = [];
22
+ if (template.title) {
23
+ lines.push(`# ${OpenApiLoader.replaceVariables(template.title, values)}`);
24
+ lines.push('');
25
+ }
26
+ if (Array.isArray(template.sections)) {
27
+ for (const section of template.sections) {
28
+ if (section.content) {
29
+ lines.push(OpenApiLoader.replaceVariables(section.content, values));
30
+ }
31
+ else if (section.placeholder) {
32
+ lines.push(section.placeholder);
33
+ }
34
+ lines.push('');
35
+ }
36
+ }
37
+ return lines.join('\n').trim();
38
+ }
39
+ }
40
+ //# sourceMappingURL=templateRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateRepository.js","sourceRoot":"","sources":["../../../src/features/shared/templateRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAElE;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,KAAsD,EAAE,SAA8B;QACnH,aAAa,CAAC,QAAQ,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,cAAc,CAAC,QAAa,EAAE,MAA2B;QACtE,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrC,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACxC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;gBACtE,CAAC;qBAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAClC,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * WorkflowStateRepository manages progress rules, stage names, and file mapping.
3
+ */
4
+ export declare class WorkflowStateRepository {
5
+ /**
6
+ * Gets the display name for a given stage.
7
+ */
8
+ static getStageDisplayName(stage: string): string;
9
+ /**
10
+ * Gets the file name associated with a stage.
11
+ */
12
+ static getStageFileName(stage: string): string;
13
+ /**
14
+ * Calculates overall progress based on the state of each stage.
15
+ */
16
+ static calculateOverallProgress(requirementsStatus: number, designStatus: number, tasksStatus: number): number;
17
+ }
18
+ //# sourceMappingURL=workflowStateRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowStateRepository.d.ts","sourceRoot":"","sources":["../../../src/features/shared/workflowStateRepository.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAMjD;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAM9C;;OAEG;IACH,MAAM,CAAC,wBAAwB,CAAC,kBAAkB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;CAI/G"}