@ginkoai/cli 2.0.6 → 2.1.1

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 (149) hide show
  1. package/dist/commands/epic/index.d.ts +29 -0
  2. package/dist/commands/epic/index.d.ts.map +1 -0
  3. package/dist/commands/epic/index.js +94 -0
  4. package/dist/commands/epic/index.js.map +1 -0
  5. package/dist/commands/epic/status.d.ts +40 -0
  6. package/dist/commands/epic/status.d.ts.map +1 -0
  7. package/dist/commands/epic/status.js +244 -0
  8. package/dist/commands/epic/status.js.map +1 -0
  9. package/dist/commands/graph/api-client.d.ts +221 -1
  10. package/dist/commands/graph/api-client.d.ts.map +1 -1
  11. package/dist/commands/graph/api-client.js +141 -2
  12. package/dist/commands/graph/api-client.js.map +1 -1
  13. package/dist/commands/graph/load.d.ts.map +1 -1
  14. package/dist/commands/graph/load.js +40 -2
  15. package/dist/commands/graph/load.js.map +1 -1
  16. package/dist/commands/handoff.d.ts +3 -3
  17. package/dist/commands/handoff.d.ts.map +1 -1
  18. package/dist/commands/handoff.js +32 -3
  19. package/dist/commands/handoff.js.map +1 -1
  20. package/dist/commands/migrate/index.d.ts +27 -0
  21. package/dist/commands/migrate/index.d.ts.map +1 -0
  22. package/dist/commands/migrate/index.js +76 -0
  23. package/dist/commands/migrate/index.js.map +1 -0
  24. package/dist/commands/migrate/status-migration.d.ts +58 -0
  25. package/dist/commands/migrate/status-migration.d.ts.map +1 -0
  26. package/dist/commands/migrate/status-migration.js +323 -0
  27. package/dist/commands/migrate/status-migration.js.map +1 -0
  28. package/dist/commands/nudging/index.d.ts +24 -0
  29. package/dist/commands/nudging/index.d.ts.map +1 -0
  30. package/dist/commands/nudging/index.js +175 -0
  31. package/dist/commands/nudging/index.js.map +1 -0
  32. package/dist/commands/sprint/create.d.ts +26 -0
  33. package/dist/commands/sprint/create.d.ts.map +1 -0
  34. package/dist/commands/sprint/create.js +269 -0
  35. package/dist/commands/sprint/create.js.map +1 -0
  36. package/dist/commands/sprint/index.d.ts.map +1 -1
  37. package/dist/commands/sprint/index.js +28 -0
  38. package/dist/commands/sprint/index.js.map +1 -1
  39. package/dist/commands/sprint/quick-fix.d.ts +25 -0
  40. package/dist/commands/sprint/quick-fix.d.ts.map +1 -0
  41. package/dist/commands/sprint/quick-fix.js +151 -0
  42. package/dist/commands/sprint/quick-fix.js.map +1 -0
  43. package/dist/commands/sprint/sprint-pipeline-enhanced.d.ts.map +1 -1
  44. package/dist/commands/sprint/sprint-pipeline-enhanced.js +37 -0
  45. package/dist/commands/sprint/sprint-pipeline-enhanced.js.map +1 -1
  46. package/dist/commands/sprint/status.d.ts +42 -0
  47. package/dist/commands/sprint/status.d.ts.map +1 -0
  48. package/dist/commands/sprint/status.js +298 -0
  49. package/dist/commands/sprint/status.js.map +1 -0
  50. package/dist/commands/start/start-reflection.d.ts +53 -0
  51. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  52. package/dist/commands/start/start-reflection.js +464 -71
  53. package/dist/commands/start/start-reflection.js.map +1 -1
  54. package/dist/commands/sync/sprint-syncer.d.ts +19 -12
  55. package/dist/commands/sync/sprint-syncer.d.ts.map +1 -1
  56. package/dist/commands/sync/sprint-syncer.js +58 -140
  57. package/dist/commands/sync/sprint-syncer.js.map +1 -1
  58. package/dist/commands/sync/sync-command.d.ts.map +1 -1
  59. package/dist/commands/sync/sync-command.js +6 -18
  60. package/dist/commands/sync/sync-command.js.map +1 -1
  61. package/dist/commands/task/index.d.ts +25 -0
  62. package/dist/commands/task/index.d.ts.map +1 -0
  63. package/dist/commands/task/index.js +100 -0
  64. package/dist/commands/task/index.js.map +1 -0
  65. package/dist/commands/task/status.d.ts +46 -0
  66. package/dist/commands/task/status.d.ts.map +1 -0
  67. package/dist/commands/task/status.js +348 -0
  68. package/dist/commands/task/status.js.map +1 -0
  69. package/dist/commands/team/index.d.ts +5 -0
  70. package/dist/commands/team/index.d.ts.map +1 -1
  71. package/dist/commands/team/index.js +28 -0
  72. package/dist/commands/team/index.js.map +1 -1
  73. package/dist/commands/team/status.d.ts +16 -0
  74. package/dist/commands/team/status.d.ts.map +1 -0
  75. package/dist/commands/team/status.js +180 -0
  76. package/dist/commands/team/status.js.map +1 -0
  77. package/dist/index.js +21 -32
  78. package/dist/index.js.map +1 -1
  79. package/dist/lib/adoption-score.d.ts +69 -0
  80. package/dist/lib/adoption-score.d.ts.map +1 -0
  81. package/dist/lib/adoption-score.js +206 -0
  82. package/dist/lib/adoption-score.js.map +1 -0
  83. package/dist/lib/coaching-level.d.ts +127 -0
  84. package/dist/lib/coaching-level.d.ts.map +1 -0
  85. package/dist/lib/coaching-level.js +406 -0
  86. package/dist/lib/coaching-level.js.map +1 -0
  87. package/dist/lib/context-loader-events.d.ts.map +1 -1
  88. package/dist/lib/context-loader-events.js +7 -26
  89. package/dist/lib/context-loader-events.js.map +1 -1
  90. package/dist/lib/event-logger.d.ts +42 -0
  91. package/dist/lib/event-logger.d.ts.map +1 -1
  92. package/dist/lib/event-logger.js +77 -0
  93. package/dist/lib/event-logger.js.map +1 -1
  94. package/dist/lib/output-formatter.d.ts +8 -2
  95. package/dist/lib/output-formatter.d.ts.map +1 -1
  96. package/dist/lib/output-formatter.js +98 -18
  97. package/dist/lib/output-formatter.js.map +1 -1
  98. package/dist/lib/pending-updates.d.ts +148 -0
  99. package/dist/lib/pending-updates.d.ts.map +1 -0
  100. package/dist/lib/pending-updates.js +301 -0
  101. package/dist/lib/pending-updates.js.map +1 -0
  102. package/dist/lib/planning-menu.d.ts +69 -0
  103. package/dist/lib/planning-menu.d.ts.map +1 -0
  104. package/dist/lib/planning-menu.js +342 -0
  105. package/dist/lib/planning-menu.js.map +1 -0
  106. package/dist/lib/sprint-loader.d.ts +86 -14
  107. package/dist/lib/sprint-loader.d.ts.map +1 -1
  108. package/dist/lib/sprint-loader.js +293 -98
  109. package/dist/lib/sprint-loader.js.map +1 -1
  110. package/dist/lib/state-cache.d.ts +142 -0
  111. package/dist/lib/state-cache.d.ts.map +1 -0
  112. package/dist/lib/state-cache.js +259 -0
  113. package/dist/lib/state-cache.js.map +1 -0
  114. package/dist/lib/targeted-coaching.d.ts +71 -0
  115. package/dist/lib/targeted-coaching.d.ts.map +1 -0
  116. package/dist/lib/targeted-coaching.js +318 -0
  117. package/dist/lib/targeted-coaching.js.map +1 -0
  118. package/dist/lib/task-graph-sync.d.ts +105 -0
  119. package/dist/lib/task-graph-sync.d.ts.map +1 -0
  120. package/dist/lib/task-graph-sync.js +178 -0
  121. package/dist/lib/task-graph-sync.js.map +1 -0
  122. package/dist/lib/task-parser.d.ts +109 -0
  123. package/dist/lib/task-parser.d.ts.map +1 -0
  124. package/dist/lib/task-parser.js +407 -0
  125. package/dist/lib/task-parser.js.map +1 -0
  126. package/dist/lib/user-sprint.d.ts +53 -0
  127. package/dist/lib/user-sprint.d.ts.map +1 -1
  128. package/dist/lib/user-sprint.js +137 -2
  129. package/dist/lib/user-sprint.js.map +1 -1
  130. package/dist/lib/work-reconciliation.d.ts +59 -0
  131. package/dist/lib/work-reconciliation.d.ts.map +1 -0
  132. package/dist/lib/work-reconciliation.js +267 -0
  133. package/dist/lib/work-reconciliation.js.map +1 -0
  134. package/dist/templates/ai-instructions-template.d.ts.map +1 -1
  135. package/dist/templates/ai-instructions-template.js +7 -5
  136. package/dist/templates/ai-instructions-template.js.map +1 -1
  137. package/dist/templates/epic-template.md +0 -2
  138. package/dist/types/config.d.ts.map +1 -1
  139. package/dist/types/config.js +7 -5
  140. package/dist/types/config.js.map +1 -1
  141. package/dist/utils/synthesis.d.ts +4 -0
  142. package/dist/utils/synthesis.d.ts.map +1 -1
  143. package/dist/utils/synthesis.js +12 -18
  144. package/dist/utils/synthesis.js.map +1 -1
  145. package/dist/utils/version-check.d.ts +26 -0
  146. package/dist/utils/version-check.d.ts.map +1 -0
  147. package/dist/utils/version-check.js +186 -0
  148. package/dist/utils/version-check.js.map +1 -0
  149. package/package.json +2 -2
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-01-19
5
+ * @tags: [task-parser, sprint, epic-015, sprint-0a]
6
+ * @related: [sprint-parser.ts, task-graph-sync.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra]
10
+ */
11
+ /**
12
+ * Task status values (aligned with Status API)
13
+ */
14
+ export type TaskStatus = 'not_started' | 'in_progress' | 'blocked' | 'complete' | 'paused';
15
+ /**
16
+ * Parsed task from sprint markdown
17
+ */
18
+ export interface ParsedTask {
19
+ /** Task ID (e.g., e015_s00a_t01, TASK-1, adhoc_260119_s01_t01) */
20
+ id: string;
21
+ /** Derived sprint ID (e.g., e015_s00a, adhoc_260119_s01) */
22
+ sprint_id: string;
23
+ /** Derived epic ID (e.g., e015, adhoc_260119) */
24
+ epic_id: string;
25
+ /** Task title */
26
+ title: string;
27
+ /** Estimated effort (e.g., "3h", "4-6h") */
28
+ estimate: string | null;
29
+ /** Priority level */
30
+ priority: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
31
+ /** Assignee email or null */
32
+ assignee: string | null;
33
+ /** Initial status from checkbox (used only on CREATE) */
34
+ initial_status: TaskStatus;
35
+ /** Task goal/description */
36
+ goal: string | null;
37
+ /** Approach/implementation notes (e014_s02_t04) */
38
+ approach: string | null;
39
+ /** Acceptance criteria list */
40
+ acceptance_criteria: string[];
41
+ /** Referenced files */
42
+ files: string[];
43
+ /** Related ADR references */
44
+ related_adrs: string[];
45
+ }
46
+ /**
47
+ * Sprint metadata extracted alongside tasks
48
+ */
49
+ export interface ParsedSprint {
50
+ /** Sprint ID (derived from filename or content) */
51
+ id: string;
52
+ /** Sprint name */
53
+ name: string;
54
+ /** Epic ID */
55
+ epic_id: string;
56
+ /** Sprint file path */
57
+ file_path: string;
58
+ }
59
+ /**
60
+ * Result of parsing a sprint file
61
+ */
62
+ export interface SprintParseResult {
63
+ sprint: ParsedSprint;
64
+ tasks: ParsedTask[];
65
+ }
66
+ /**
67
+ * Parse task hierarchy from task ID
68
+ *
69
+ * @param taskId - Task ID in various formats
70
+ * @returns Object with sprint_id and epic_id, or null if invalid
71
+ */
72
+ export declare function parseTaskHierarchy(taskId: string): {
73
+ sprint_id: string;
74
+ epic_id: string;
75
+ } | null;
76
+ /**
77
+ * Parse a single task block
78
+ *
79
+ * @param blockText - Raw markdown text for one task
80
+ * @param sprintContext - Sprint context for legacy TASK-N format
81
+ * @returns ParsedTask or null if invalid
82
+ */
83
+ export declare function parseTaskBlock(blockText: string, sprintContext?: {
84
+ sprint_id: string;
85
+ epic_id: string;
86
+ }): ParsedTask | null;
87
+ /**
88
+ * Parse sprint markdown file to extract all tasks
89
+ *
90
+ * @param content - Raw sprint markdown content
91
+ * @param filePath - Path to sprint file (for metadata extraction)
92
+ * @returns SprintParseResult with sprint metadata and parsed tasks
93
+ */
94
+ export declare function parseSprintTasks(content: string, filePath: string): SprintParseResult;
95
+ /**
96
+ * Parse sprint file from filesystem
97
+ *
98
+ * @param filePath - Absolute path to sprint markdown file
99
+ * @returns SprintParseResult or null if file not found
100
+ */
101
+ export declare function parseSprintFile(filePath: string): Promise<SprintParseResult | null>;
102
+ /**
103
+ * Parse all sprint files in a directory
104
+ *
105
+ * @param sprintsDir - Path to sprints directory
106
+ * @returns Array of SprintParseResult
107
+ */
108
+ export declare function parseAllSprints(sprintsDir: string): Promise<SprintParseResult[]>;
109
+ //# sourceMappingURL=task-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-parser.d.ts","sourceRoot":"","sources":["../../src/lib/task-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmBH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3F;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qBAAqB;IACrB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,yDAAyD;IACzD,cAAc,EAAE,UAAU,CAAC;IAC3B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,+BAA+B;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,uBAAuB;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA8BhG;AAqID;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrD,UAAU,GAAG,IAAI,CAoGnB;AAgFD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAwBrF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAazF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAyBtF"}
@@ -0,0 +1,407 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-01-19
5
+ * @tags: [task-parser, sprint, epic-015, sprint-0a]
6
+ * @related: [sprint-parser.ts, task-graph-sync.ts]
7
+ * @priority: high
8
+ * @complexity: medium
9
+ * @dependencies: [fs-extra]
10
+ */
11
+ /**
12
+ * Task Parser for Sprint Markdown (EPIC-015 Sprint 0a Task 1)
13
+ *
14
+ * Parses task definitions from sprint markdown files into structured data
15
+ * for syncing to Neo4j graph. Handles multiple task ID formats:
16
+ * - Standard: e{NNN}_s{NN}_t{NN} (e.g., e015_s00a_t01)
17
+ * - Legacy: TASK-N (e.g., TASK-1)
18
+ * - Ad-hoc: adhoc_{YYMMDD}_s{NN}_t{NN} (e.g., adhoc_260119_s01_t01)
19
+ *
20
+ * Key principle (ADR-060): Content from Git, State from Graph.
21
+ * Parser extracts CONTENT fields only (title, goal, priority, estimate).
22
+ * Status in markdown is only used for initial creation, not updates.
23
+ */
24
+ import fs from 'fs-extra';
25
+ import path from 'path';
26
+ /**
27
+ * Parse task hierarchy from task ID
28
+ *
29
+ * @param taskId - Task ID in various formats
30
+ * @returns Object with sprint_id and epic_id, or null if invalid
31
+ */
32
+ export function parseTaskHierarchy(taskId) {
33
+ // Standard format: e015_s00a_t01 or e015_s00_t01
34
+ const standardMatch = taskId.match(/^(e\d{3})_(s\d{2}[a-z]?)_(t\d{2})$/i);
35
+ if (standardMatch) {
36
+ const epicId = standardMatch[1].toLowerCase();
37
+ const sprintSuffix = standardMatch[2].toLowerCase();
38
+ return {
39
+ sprint_id: `${epicId}_${sprintSuffix}`,
40
+ epic_id: epicId,
41
+ };
42
+ }
43
+ // Ad-hoc format: adhoc_260119_s01_t01
44
+ const adhocMatch = taskId.match(/^(adhoc_\d{6})_(s\d{2})_(t\d{2})$/i);
45
+ if (adhocMatch) {
46
+ const adhocId = adhocMatch[1].toLowerCase();
47
+ const sprintSuffix = adhocMatch[2].toLowerCase();
48
+ return {
49
+ sprint_id: `${adhocId}_${sprintSuffix}`,
50
+ epic_id: adhocId,
51
+ };
52
+ }
53
+ // Legacy TASK-N format - derive from context (requires sprint info)
54
+ // For legacy format, we cannot derive hierarchy without sprint context
55
+ if (taskId.match(/^TASK-\d+$/i)) {
56
+ return null; // Caller must provide sprint context
57
+ }
58
+ return null;
59
+ }
60
+ /**
61
+ * Map checkbox character to task status
62
+ *
63
+ * @param checkbox - Single character from checkbox ([x], [@], [ ], [Z])
64
+ * @returns TaskStatus value
65
+ */
66
+ function mapCheckboxToStatus(checkbox) {
67
+ if (!checkbox)
68
+ return 'not_started';
69
+ const char = checkbox.trim().toLowerCase();
70
+ switch (char) {
71
+ case 'x':
72
+ return 'complete';
73
+ case '@':
74
+ return 'in_progress';
75
+ case 'z':
76
+ return 'paused';
77
+ case ' ':
78
+ default:
79
+ return 'not_started';
80
+ }
81
+ }
82
+ /**
83
+ * Normalize priority value
84
+ */
85
+ function normalizePriority(priority) {
86
+ if (!priority)
87
+ return 'MEDIUM';
88
+ const upper = priority.trim().toUpperCase();
89
+ if (['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'].includes(upper)) {
90
+ return upper;
91
+ }
92
+ return 'MEDIUM';
93
+ }
94
+ /**
95
+ * Extract approach/implementation notes from task block (e014_s02_t04)
96
+ *
97
+ * Parses the **Approach:** section which contains 2-3 sentences describing
98
+ * how to implement the task.
99
+ */
100
+ function extractApproach(blockText) {
101
+ // Match: **Approach:** followed by text until next section
102
+ const approachMatch = blockText.match(/\*\*Approach:\*\*\s+([\s\S]*?)(?=\n\*\*(?!Approach)|\n###|\n---|\n##|$)/i);
103
+ if (!approachMatch)
104
+ return null;
105
+ // Clean up the approach text - join lines and trim
106
+ const approach = approachMatch[1]
107
+ .split('\n')
108
+ .map(line => line.trim())
109
+ .filter(line => line.length > 0)
110
+ .join(' ')
111
+ .trim();
112
+ return approach.length > 0 ? approach : null;
113
+ }
114
+ /**
115
+ * Extract acceptance criteria from task block
116
+ */
117
+ function extractAcceptanceCriteria(blockText) {
118
+ const criteria = [];
119
+ // Find acceptance criteria section
120
+ const sectionMatch = blockText.match(/\*\*Acceptance Criteria:\*\*\s*([\s\S]*?)(?=\n\*\*|\n###|\n---|\n##|$)/i);
121
+ if (!sectionMatch)
122
+ return criteria;
123
+ // Extract checkbox items: - [ ] or - [x]
124
+ const checkboxMatches = sectionMatch[1].matchAll(/^-\s+\[.\]\s+(.+?)$/gm);
125
+ for (const match of checkboxMatches) {
126
+ criteria.push(match[1].trim());
127
+ }
128
+ // Also extract plain bullets if no checkboxes found
129
+ if (criteria.length === 0) {
130
+ const bulletMatches = sectionMatch[1].matchAll(/^-\s+(.+?)$/gm);
131
+ for (const match of bulletMatches) {
132
+ criteria.push(match[1].trim());
133
+ }
134
+ }
135
+ return criteria;
136
+ }
137
+ /**
138
+ * Extract file paths from task block
139
+ */
140
+ function extractFiles(blockText) {
141
+ const files = new Set();
142
+ // Pattern: **Files:** section with bullet list
143
+ const filesSection = blockText.match(/\*\*Files(?:\sto\s(?:Create|Modify))?:\*\*\s*([\s\S]*?)(?=\n\*\*|\n###|\n---|\n##|$)/i);
144
+ if (filesSection) {
145
+ // Match: - Create: `path/to/file.ts` or - Modify: `path/to/file.ts` or just `path`
146
+ const pathMatches = filesSection[1].matchAll(/`([^`]+\.[a-z]+)`/gi);
147
+ for (const match of pathMatches) {
148
+ files.add(match[1]);
149
+ }
150
+ }
151
+ // Pattern: inline code paths that look like file paths
152
+ const inlineMatches = blockText.matchAll(/`((?:packages|dashboard|src|docs)\/[^`]+\.[a-z]+)`/gi);
153
+ for (const match of inlineMatches) {
154
+ files.add(match[1]);
155
+ }
156
+ return Array.from(files).sort();
157
+ }
158
+ /**
159
+ * Extract related ADR references
160
+ */
161
+ function extractRelatedADRs(blockText) {
162
+ const adrs = new Set();
163
+ // Match ADR-XXX patterns
164
+ const adrMatches = blockText.matchAll(/ADR-(\d+)/gi);
165
+ for (const match of adrMatches) {
166
+ adrs.add(`ADR-${match[1]}`);
167
+ }
168
+ return Array.from(adrs).sort();
169
+ }
170
+ /**
171
+ * Parse a single task block
172
+ *
173
+ * @param blockText - Raw markdown text for one task
174
+ * @param sprintContext - Sprint context for legacy TASK-N format
175
+ * @returns ParsedTask or null if invalid
176
+ */
177
+ export function parseTaskBlock(blockText, sprintContext) {
178
+ // Extract task header - multiple formats supported
179
+ // Standard: ### e015_s00a_t01: Title (3h)
180
+ // Legacy: ### TASK-1: Title (4-6h)
181
+ // Ad-hoc: ### adhoc_260119_s01_t01 - Title
182
+ // Without time: ### e015_s00a_t01: Title
183
+ const headerPatterns = [
184
+ // Standard with colon and optional time
185
+ /^###\s+([a-z0-9_]+):\s+(.+?)\s*(?:\(([0-9]+(?:-[0-9]+)?h?)\))?$/im,
186
+ // With dash separator (ad-hoc style)
187
+ /^###\s+([a-z0-9_]+)\s+-\s+(.+?)$/im,
188
+ // Legacy TASK-N format
189
+ /^###\s+(TASK-\d+):\s+(.+?)\s*(?:\(([0-9]+(?:-[0-9]+)?h?)\))?$/im,
190
+ ];
191
+ let taskId = null;
192
+ let title = null;
193
+ let estimate = null;
194
+ for (const pattern of headerPatterns) {
195
+ const match = blockText.match(pattern);
196
+ if (match) {
197
+ taskId = match[1];
198
+ title = match[2].trim();
199
+ estimate = match[3] || null;
200
+ break;
201
+ }
202
+ }
203
+ if (!taskId || !title) {
204
+ return null;
205
+ }
206
+ // Parse hierarchy
207
+ let hierarchy = parseTaskHierarchy(taskId);
208
+ // For legacy TASK-N format, use sprint context
209
+ if (!hierarchy && sprintContext) {
210
+ hierarchy = {
211
+ sprint_id: sprintContext.sprint_id,
212
+ epic_id: sprintContext.epic_id,
213
+ };
214
+ }
215
+ if (!hierarchy) {
216
+ // Cannot determine hierarchy, skip task
217
+ console.warn(`Cannot determine hierarchy for task: ${taskId}`);
218
+ return null;
219
+ }
220
+ // Extract status from checkbox: **Status:** [x]
221
+ const statusMatch = blockText.match(/\*\*Status:\*\*\s+\[(.)\]/i);
222
+ const initialStatus = mapCheckboxToStatus(statusMatch?.[1]);
223
+ // Extract priority
224
+ const priorityMatch = blockText.match(/\*\*Priority:\*\*\s+([A-Z_]+)/i);
225
+ const priority = normalizePriority(priorityMatch?.[1]);
226
+ // Extract assignee (accepts both Assignee and Owner)
227
+ const assigneeMatch = blockText.match(/\*\*(?:Assignee|Owner):\*\*\s+([^\n]+)/i);
228
+ let assignee = null;
229
+ if (assigneeMatch) {
230
+ const value = assigneeMatch[1].trim();
231
+ // Filter out "TBD", "None", empty values
232
+ if (value && !['tbd', 'none', 'n/a', '-'].includes(value.toLowerCase())) {
233
+ assignee = value;
234
+ }
235
+ }
236
+ // Extract goal
237
+ const goalMatch = blockText.match(/\*\*Goal:\*\*\s+([^\n]+)/i);
238
+ const goal = goalMatch ? goalMatch[1].trim() : null;
239
+ // Extract approach (e014_s02_t04)
240
+ const approach = extractApproach(blockText);
241
+ // Extract acceptance criteria
242
+ const acceptanceCriteria = extractAcceptanceCriteria(blockText);
243
+ // Extract files
244
+ const files = extractFiles(blockText);
245
+ // Extract related ADRs
246
+ const relatedADRs = extractRelatedADRs(blockText);
247
+ return {
248
+ id: taskId.toLowerCase(),
249
+ sprint_id: hierarchy.sprint_id,
250
+ epic_id: hierarchy.epic_id,
251
+ title,
252
+ estimate,
253
+ priority,
254
+ assignee,
255
+ initial_status: initialStatus,
256
+ goal,
257
+ approach,
258
+ acceptance_criteria: acceptanceCriteria,
259
+ files,
260
+ related_adrs: relatedADRs,
261
+ };
262
+ }
263
+ /**
264
+ * Extract sprint metadata from sprint file
265
+ *
266
+ * @param content - Sprint file content
267
+ * @param filePath - Path to sprint file
268
+ * @returns ParsedSprint metadata
269
+ */
270
+ function extractSprintMetadata(content, filePath) {
271
+ const filename = path.basename(filePath, '.md');
272
+ // Try to extract sprint ID from filename
273
+ // Pattern: SPRINT-2026-01-e015-s00a-... → e015_s00a
274
+ const filenameMatch = filename.match(/SPRINT-\d{4}-\d{2}-(e\d{3})-(s\d{2}[a-z]?)-/i);
275
+ if (filenameMatch) {
276
+ const epicId = filenameMatch[1].toLowerCase();
277
+ const sprintSuffix = filenameMatch[2].toLowerCase();
278
+ const sprintId = `${epicId}_${sprintSuffix}`;
279
+ // Extract sprint name from title
280
+ const titleMatch = content.match(/^#\s+(?:SPRINT:\s+)?(.+?)(?:\s+\(|$)/m);
281
+ const name = titleMatch ? titleMatch[1].trim() : filename;
282
+ return {
283
+ id: sprintId,
284
+ name,
285
+ epic_id: epicId,
286
+ file_path: filePath,
287
+ };
288
+ }
289
+ // Ad-hoc pattern: SPRINT-adhoc_260119-...
290
+ const adhocMatch = filename.match(/SPRINT-(adhoc_\d{6})-/i);
291
+ if (adhocMatch) {
292
+ const adhocId = adhocMatch[1].toLowerCase();
293
+ const sprintId = `${adhocId}_s01`; // Default to s01 for adhoc
294
+ const titleMatch = content.match(/^#\s+(.+?)(?:\s+\(|$)/m);
295
+ const name = titleMatch ? titleMatch[1].trim() : filename;
296
+ return {
297
+ id: sprintId,
298
+ name,
299
+ epic_id: adhocId,
300
+ file_path: filePath,
301
+ };
302
+ }
303
+ // Legacy pattern from content: # SPRINT: Name (EPIC-XXX Sprint N)
304
+ const legacyMatch = content.match(/^#\s+SPRINT:\s+(.+?)\s+\(EPIC-(\d+)\s+Sprint\s+(\d+)\)/m);
305
+ if (legacyMatch) {
306
+ const name = legacyMatch[1].trim();
307
+ const epicNum = legacyMatch[2];
308
+ const sprintNum = legacyMatch[3];
309
+ const epicId = `e${epicNum.padStart(3, '0')}`;
310
+ const sprintId = `${epicId}_s${sprintNum.padStart(2, '0')}`;
311
+ return {
312
+ id: sprintId,
313
+ name,
314
+ epic_id: epicId,
315
+ file_path: filePath,
316
+ };
317
+ }
318
+ // Fallback: generate from filename
319
+ const fallbackId = filename
320
+ .toLowerCase()
321
+ .replace(/[^a-z0-9]+/g, '_')
322
+ .replace(/^sprint_/, '');
323
+ return {
324
+ id: fallbackId,
325
+ name: filename,
326
+ epic_id: 'unknown',
327
+ file_path: filePath,
328
+ };
329
+ }
330
+ /**
331
+ * Parse sprint markdown file to extract all tasks
332
+ *
333
+ * @param content - Raw sprint markdown content
334
+ * @param filePath - Path to sprint file (for metadata extraction)
335
+ * @returns SprintParseResult with sprint metadata and parsed tasks
336
+ */
337
+ export function parseSprintTasks(content, filePath) {
338
+ // Extract sprint metadata
339
+ const sprint = extractSprintMetadata(content, filePath);
340
+ // Split content by task headers (### followed by task ID pattern)
341
+ // Match: ### e015_s00a_t01:, ### TASK-1:, ### adhoc_..._t01
342
+ const taskSections = content.split(/(?=^###\s+(?:e\d{3}_s\d{2}[a-z]?_t\d{2}|TASK-\d+|adhoc_\d{6}_s\d{2}_t\d{2})[\s:-])/im);
343
+ const tasks = [];
344
+ const sprintContext = {
345
+ sprint_id: sprint.id,
346
+ epic_id: sprint.epic_id,
347
+ };
348
+ for (const section of taskSections) {
349
+ if (!section.trim().startsWith('###'))
350
+ continue;
351
+ const task = parseTaskBlock(section, sprintContext);
352
+ if (task) {
353
+ tasks.push(task);
354
+ }
355
+ }
356
+ return { sprint, tasks };
357
+ }
358
+ /**
359
+ * Parse sprint file from filesystem
360
+ *
361
+ * @param filePath - Absolute path to sprint markdown file
362
+ * @returns SprintParseResult or null if file not found
363
+ */
364
+ export async function parseSprintFile(filePath) {
365
+ try {
366
+ if (!await fs.pathExists(filePath)) {
367
+ console.warn(`Sprint file not found: ${filePath}`);
368
+ return null;
369
+ }
370
+ const content = await fs.readFile(filePath, 'utf-8');
371
+ return parseSprintTasks(content, filePath);
372
+ }
373
+ catch (error) {
374
+ console.error(`Failed to parse sprint file ${filePath}:`, error);
375
+ return null;
376
+ }
377
+ }
378
+ /**
379
+ * Parse all sprint files in a directory
380
+ *
381
+ * @param sprintsDir - Path to sprints directory
382
+ * @returns Array of SprintParseResult
383
+ */
384
+ export async function parseAllSprints(sprintsDir) {
385
+ const results = [];
386
+ try {
387
+ if (!await fs.pathExists(sprintsDir)) {
388
+ console.warn(`Sprints directory not found: ${sprintsDir}`);
389
+ return results;
390
+ }
391
+ const files = await fs.readdir(sprintsDir);
392
+ const sprintFiles = files.filter(f => f.startsWith('SPRINT-') && f.endsWith('.md'));
393
+ for (const file of sprintFiles) {
394
+ const filePath = path.join(sprintsDir, file);
395
+ const result = await parseSprintFile(filePath);
396
+ if (result) {
397
+ results.push(result);
398
+ }
399
+ }
400
+ return results;
401
+ }
402
+ catch (error) {
403
+ console.error(`Failed to parse sprints directory ${sprintsDir}:`, error);
404
+ return results;
405
+ }
406
+ }
407
+ //# sourceMappingURL=task-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-parser.js","sourceRoot":"","sources":["../../src/lib/task-parser.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,21 @@ export interface UserSprintAssignment {
18
18
  sprintName: string;
19
19
  assignedAt: string;
20
20
  assignedBy: 'auto' | 'manual';
21
+ isAdhoc?: boolean;
22
+ consecutiveAdhocSessions?: number;
23
+ lastAdhocSessionAt?: string;
24
+ }
25
+ /**
26
+ * Result of checking user's work structure status (EPIC-016 Sprint 4 t01)
27
+ * Used by start command to determine if planning menu should be shown
28
+ */
29
+ export interface WorkStructureStatus {
30
+ hasStructuredWork: boolean;
31
+ sprintId: string | null;
32
+ incompleteTasks: number;
33
+ consecutiveAdhocSessions: number;
34
+ shouldShowPlanningMenu: boolean;
35
+ reason: 'has_sprint' | 'no_sprint' | 'all_tasks_complete' | 'adhoc_pattern';
21
36
  }
22
37
  /**
23
38
  * Get user's current sprint assignment
@@ -56,4 +71,42 @@ export declare function validateUserSprint(assignment: UserSprintAssignment): Pr
56
71
  * Get sprint file path from user assignment
57
72
  */
58
73
  export declare function getSprintFileFromAssignment(assignment: UserSprintAssignment): Promise<string>;
74
+ /**
75
+ * Check if user has structured work (sprint with incomplete tasks)
76
+ *
77
+ * Decision matrix:
78
+ * | Has Sprint | Has Tasks | Consecutive Adhoc | Result |
79
+ * |------------|-----------|-------------------|--------|
80
+ * | Yes | Yes | Any | Has structured work |
81
+ * | Yes | No (100%) | Any | No structure (complete) |
82
+ * | No | N/A | <= 1 | No structure (new) |
83
+ * | No | N/A | > 1 | No structure (adhoc pattern) |
84
+ *
85
+ * @param userSprint - User's current sprint assignment
86
+ * @param sprintChecklist - Sprint task data from graph/file (with progress info)
87
+ * @returns WorkStructureStatus with decision
88
+ */
89
+ export declare function checkWorkStructure(userSprint: UserSprintAssignment | null, sprintChecklist: {
90
+ progress?: {
91
+ total: number;
92
+ complete: number;
93
+ };
94
+ tasks?: Array<{
95
+ state: string;
96
+ }>;
97
+ } | null): WorkStructureStatus;
98
+ /**
99
+ * Increment ad-hoc session counter
100
+ * Called when user chooses ad-hoc work in planning menu
101
+ */
102
+ export declare function incrementAdhocSessionCount(): Promise<number>;
103
+ /**
104
+ * Reset ad-hoc session counter
105
+ * Called when user starts structured work (creates/selects epic/sprint)
106
+ */
107
+ export declare function resetAdhocSessionCount(): Promise<void>;
108
+ /**
109
+ * Create sprint assignment from sprint ID (for graph-based sprints)
110
+ */
111
+ export declare function createAssignmentFromSprintId(sprintId: string, sprintName: string, assignedBy?: 'auto' | 'manual'): UserSprintAssignment;
59
112
  //# sourceMappingURL=user-sprint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-sprint.d.ts","sourceRoot":"","sources":["../../src/lib/user-sprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC/B;AAaD;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoBjF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM5D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4BzG;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAAM,GAAG,QAAiB,GACrC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAkBtC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAGjB"}
1
+ {"version":3,"file":"user-sprint.d.ts","sourceRoot":"","sources":["../../src/lib/user-sprint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IAG9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB,EAAE,MAAM,CAAC;IACjC,sBAAsB,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,oBAAoB,GAAG,eAAe,CAAC;CAC7E;AAaD;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoBjF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM5D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4BzG;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAAM,GAAG,QAAiB,GACrC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAkBtC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,oBAAoB,GAAG,IAAI,EACvC,eAAe,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,IAAI,GAC3G,mBAAmB,CA2DrB;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,MAAM,CAAC,CAqBlE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAAM,GAAG,QAAiB,GACrC,oBAAoB,CAatB"}