mstro-app 0.3.7 → 0.3.9

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 (131) hide show
  1. package/README.md +4 -8
  2. package/bin/mstro.js +54 -15
  3. package/dist/server/cli/headless/claude-invoker.d.ts.map +1 -1
  4. package/dist/server/cli/headless/claude-invoker.js +18 -9
  5. package/dist/server/cli/headless/claude-invoker.js.map +1 -1
  6. package/dist/server/cli/headless/headless-logger.d.ts +10 -0
  7. package/dist/server/cli/headless/headless-logger.d.ts.map +1 -0
  8. package/dist/server/cli/headless/headless-logger.js +66 -0
  9. package/dist/server/cli/headless/headless-logger.js.map +1 -0
  10. package/dist/server/cli/headless/mcp-config.d.ts.map +1 -1
  11. package/dist/server/cli/headless/mcp-config.js +6 -5
  12. package/dist/server/cli/headless/mcp-config.js.map +1 -1
  13. package/dist/server/cli/headless/runner.d.ts.map +1 -1
  14. package/dist/server/cli/headless/runner.js +4 -0
  15. package/dist/server/cli/headless/runner.js.map +1 -1
  16. package/dist/server/cli/headless/stall-assessor.d.ts +21 -0
  17. package/dist/server/cli/headless/stall-assessor.d.ts.map +1 -1
  18. package/dist/server/cli/headless/stall-assessor.js +74 -20
  19. package/dist/server/cli/headless/stall-assessor.js.map +1 -1
  20. package/dist/server/cli/headless/tool-watchdog.d.ts +0 -12
  21. package/dist/server/cli/headless/tool-watchdog.d.ts.map +1 -1
  22. package/dist/server/cli/headless/tool-watchdog.js +30 -9
  23. package/dist/server/cli/headless/tool-watchdog.js.map +1 -1
  24. package/dist/server/cli/headless/types.d.ts +8 -1
  25. package/dist/server/cli/headless/types.d.ts.map +1 -1
  26. package/dist/server/cli/improvisation-session-manager.d.ts +16 -0
  27. package/dist/server/cli/improvisation-session-manager.d.ts.map +1 -1
  28. package/dist/server/cli/improvisation-session-manager.js +94 -11
  29. package/dist/server/cli/improvisation-session-manager.js.map +1 -1
  30. package/dist/server/index.js +0 -4
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/mcp/bouncer-cli.d.ts +3 -0
  33. package/dist/server/mcp/bouncer-cli.d.ts.map +1 -0
  34. package/dist/server/mcp/bouncer-cli.js +54 -0
  35. package/dist/server/mcp/bouncer-cli.js.map +1 -0
  36. package/dist/server/mcp/bouncer-integration.d.ts +2 -0
  37. package/dist/server/mcp/bouncer-integration.d.ts.map +1 -1
  38. package/dist/server/mcp/bouncer-integration.js +55 -39
  39. package/dist/server/mcp/bouncer-integration.js.map +1 -1
  40. package/dist/server/mcp/bouncer-sandbox.d.ts +60 -0
  41. package/dist/server/mcp/bouncer-sandbox.d.ts.map +1 -0
  42. package/dist/server/mcp/bouncer-sandbox.js +182 -0
  43. package/dist/server/mcp/bouncer-sandbox.js.map +1 -0
  44. package/dist/server/mcp/security-patterns.d.ts +6 -12
  45. package/dist/server/mcp/security-patterns.d.ts.map +1 -1
  46. package/dist/server/mcp/security-patterns.js +197 -10
  47. package/dist/server/mcp/security-patterns.js.map +1 -1
  48. package/dist/server/services/plan/composer.d.ts +4 -0
  49. package/dist/server/services/plan/composer.d.ts.map +1 -0
  50. package/dist/server/services/plan/composer.js +181 -0
  51. package/dist/server/services/plan/composer.js.map +1 -0
  52. package/dist/server/services/plan/dependency-resolver.d.ts +28 -0
  53. package/dist/server/services/plan/dependency-resolver.d.ts.map +1 -0
  54. package/dist/server/services/plan/dependency-resolver.js +152 -0
  55. package/dist/server/services/plan/dependency-resolver.js.map +1 -0
  56. package/dist/server/services/plan/executor.d.ts +91 -0
  57. package/dist/server/services/plan/executor.d.ts.map +1 -0
  58. package/dist/server/services/plan/executor.js +545 -0
  59. package/dist/server/services/plan/executor.js.map +1 -0
  60. package/dist/server/services/plan/parser.d.ts +11 -0
  61. package/dist/server/services/plan/parser.d.ts.map +1 -0
  62. package/dist/server/services/plan/parser.js +415 -0
  63. package/dist/server/services/plan/parser.js.map +1 -0
  64. package/dist/server/services/plan/state-reconciler.d.ts +2 -0
  65. package/dist/server/services/plan/state-reconciler.d.ts.map +1 -0
  66. package/dist/server/services/plan/state-reconciler.js +105 -0
  67. package/dist/server/services/plan/state-reconciler.js.map +1 -0
  68. package/dist/server/services/plan/types.d.ts +120 -0
  69. package/dist/server/services/plan/types.d.ts.map +1 -0
  70. package/dist/server/services/plan/types.js +4 -0
  71. package/dist/server/services/plan/types.js.map +1 -0
  72. package/dist/server/services/plan/watcher.d.ts +14 -0
  73. package/dist/server/services/plan/watcher.d.ts.map +1 -0
  74. package/dist/server/services/plan/watcher.js +69 -0
  75. package/dist/server/services/plan/watcher.js.map +1 -0
  76. package/dist/server/services/websocket/file-explorer-handlers.js +20 -0
  77. package/dist/server/services/websocket/file-explorer-handlers.js.map +1 -1
  78. package/dist/server/services/websocket/handler.d.ts +0 -1
  79. package/dist/server/services/websocket/handler.d.ts.map +1 -1
  80. package/dist/server/services/websocket/handler.js +28 -2
  81. package/dist/server/services/websocket/handler.js.map +1 -1
  82. package/dist/server/services/websocket/plan-handlers.d.ts +6 -0
  83. package/dist/server/services/websocket/plan-handlers.d.ts.map +1 -0
  84. package/dist/server/services/websocket/plan-handlers.js +494 -0
  85. package/dist/server/services/websocket/plan-handlers.js.map +1 -0
  86. package/dist/server/services/websocket/quality-handlers.d.ts +4 -0
  87. package/dist/server/services/websocket/quality-handlers.d.ts.map +1 -0
  88. package/dist/server/services/websocket/quality-handlers.js +470 -0
  89. package/dist/server/services/websocket/quality-handlers.js.map +1 -0
  90. package/dist/server/services/websocket/quality-persistence.d.ts +45 -0
  91. package/dist/server/services/websocket/quality-persistence.d.ts.map +1 -0
  92. package/dist/server/services/websocket/quality-persistence.js +187 -0
  93. package/dist/server/services/websocket/quality-persistence.js.map +1 -0
  94. package/dist/server/services/websocket/quality-service.d.ts +54 -0
  95. package/dist/server/services/websocket/quality-service.d.ts.map +1 -0
  96. package/dist/server/services/websocket/quality-service.js +816 -0
  97. package/dist/server/services/websocket/quality-service.js.map +1 -0
  98. package/dist/server/services/websocket/session-handlers.d.ts.map +1 -1
  99. package/dist/server/services/websocket/session-handlers.js +23 -0
  100. package/dist/server/services/websocket/session-handlers.js.map +1 -1
  101. package/dist/server/services/websocket/types.d.ts +2 -2
  102. package/dist/server/services/websocket/types.d.ts.map +1 -1
  103. package/package.json +3 -2
  104. package/server/cli/headless/claude-invoker.ts +21 -9
  105. package/server/cli/headless/headless-logger.ts +78 -0
  106. package/server/cli/headless/mcp-config.ts +6 -5
  107. package/server/cli/headless/runner.ts +4 -0
  108. package/server/cli/headless/stall-assessor.ts +101 -20
  109. package/server/cli/headless/tool-watchdog.ts +18 -9
  110. package/server/cli/headless/types.ts +10 -1
  111. package/server/cli/improvisation-session-manager.ts +118 -11
  112. package/server/index.ts +0 -4
  113. package/server/mcp/bouncer-cli.ts +73 -0
  114. package/server/mcp/bouncer-integration.ts +66 -44
  115. package/server/mcp/bouncer-sandbox.ts +214 -0
  116. package/server/mcp/security-patterns.ts +206 -10
  117. package/server/services/plan/composer.ts +199 -0
  118. package/server/services/plan/dependency-resolver.ts +179 -0
  119. package/server/services/plan/executor.ts +604 -0
  120. package/server/services/plan/parser.ts +459 -0
  121. package/server/services/plan/state-reconciler.ts +132 -0
  122. package/server/services/plan/types.ts +164 -0
  123. package/server/services/plan/watcher.ts +73 -0
  124. package/server/services/websocket/file-explorer-handlers.ts +20 -0
  125. package/server/services/websocket/handler.ts +28 -2
  126. package/server/services/websocket/plan-handlers.ts +592 -0
  127. package/server/services/websocket/quality-handlers.ts +570 -0
  128. package/server/services/websocket/quality-persistence.ts +250 -0
  129. package/server/services/websocket/quality-service.ts +975 -0
  130. package/server/services/websocket/session-handlers.ts +26 -0
  131. package/server/services/websocket/types.ts +62 -2
@@ -0,0 +1,415 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * PPS Parser — Parses .pm/ (or legacy .plan/) directory files into structured TypeScript objects.
5
+ *
6
+ * Handles YAML front matter extraction and markdown body parsing.
7
+ */
8
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ function stripQuotes(v) {
11
+ if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
12
+ return v.slice(1, -1);
13
+ }
14
+ return v;
15
+ }
16
+ function parseYamlValue(v) {
17
+ if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
18
+ return v.slice(1, -1);
19
+ }
20
+ if (v.startsWith('[') && v.endsWith(']')) {
21
+ return v.slice(1, -1).split(',').map(s => stripQuotes(s.trim())).filter(Boolean);
22
+ }
23
+ if (v === 'true')
24
+ return true;
25
+ if (v === 'false')
26
+ return false;
27
+ if (v === 'null' || v === '~' || v === '')
28
+ return null;
29
+ if (/^-?\d+(\.\d+)?$/.test(v))
30
+ return Number(v);
31
+ return v;
32
+ }
33
+ function parseFrontMatter(content) {
34
+ const match = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
35
+ if (!match) {
36
+ return { frontMatter: {}, body: content };
37
+ }
38
+ const frontMatter = {};
39
+ for (const line of match[1].split('\n')) {
40
+ const trimmed = line.trim();
41
+ if (!trimmed || trimmed.startsWith('#'))
42
+ continue;
43
+ const colonIdx = trimmed.indexOf(':');
44
+ if (colonIdx === -1)
45
+ continue;
46
+ frontMatter[trimmed.slice(0, colonIdx).trim()] = parseYamlValue(trimmed.slice(colonIdx + 1).trim());
47
+ }
48
+ return { frontMatter, body: match[2] };
49
+ }
50
+ // ============================================================================
51
+ // Section Extraction
52
+ // ============================================================================
53
+ function extractSections(body) {
54
+ const sections = new Map();
55
+ const lines = body.split('\n');
56
+ let currentSection = '';
57
+ let currentContent = [];
58
+ for (const line of lines) {
59
+ if (line.startsWith('## ')) {
60
+ if (currentSection) {
61
+ sections.set(currentSection, currentContent.join('\n').trim());
62
+ }
63
+ currentSection = line.slice(3).trim();
64
+ currentContent = [];
65
+ }
66
+ else {
67
+ currentContent.push(line);
68
+ }
69
+ }
70
+ if (currentSection) {
71
+ sections.set(currentSection, currentContent.join('\n').trim());
72
+ }
73
+ return sections;
74
+ }
75
+ function parseCheckboxes(content) {
76
+ const items = [];
77
+ for (const line of content.split('\n')) {
78
+ const match = line.match(/^[-*]\s+\[([ xX])\]\s+(.+)$/);
79
+ if (match) {
80
+ items.push({ text: match[2].trim(), checked: match[1] !== ' ' });
81
+ }
82
+ }
83
+ return items;
84
+ }
85
+ function parseListItems(content) {
86
+ const items = [];
87
+ for (const line of content.split('\n')) {
88
+ const match = line.match(/^[-*]\s+(.+)$/);
89
+ if (match)
90
+ items.push(match[1].trim());
91
+ }
92
+ return items;
93
+ }
94
+ function parseIssueSummaries(content) {
95
+ const summaries = [];
96
+ for (const line of content.split('\n')) {
97
+ // Match: 1. [IS-003](backlog/IS-003.md) — Title (P1)
98
+ const match = line.match(/\d+\.\s+\[([^\]]+)\]\(([^)]+)\)\s*[—–-]\s*(.+?)(?:\s*\((\w+)\))?\s*$/);
99
+ if (match) {
100
+ summaries.push({
101
+ id: match[1],
102
+ path: match[2],
103
+ title: match[3].trim(),
104
+ priority: match[4] || '',
105
+ });
106
+ continue;
107
+ }
108
+ // Match: - [IS-001](backlog/IS-001.md) — Title
109
+ const match2 = line.match(/^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s*[—–-]\s*(.+?)(?:\s*[→→]\s*blocked by\s+\[([^\]]+)\])?\s*$/i);
110
+ if (match2) {
111
+ summaries.push({
112
+ id: match2[1],
113
+ path: match2[2],
114
+ title: match2[3].trim(),
115
+ priority: '',
116
+ blockedBy: match2[4] || undefined,
117
+ });
118
+ }
119
+ }
120
+ return summaries;
121
+ }
122
+ function parseCompletedSummaries(content) {
123
+ const summaries = [];
124
+ for (const line of content.split('\n')) {
125
+ const match = line.match(/^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s*[—–-]\s*(.+?)(?:\s*✓)?\s*$/);
126
+ if (match) {
127
+ summaries.push({
128
+ id: match[1],
129
+ path: match[2],
130
+ title: match[3].trim(),
131
+ priority: '',
132
+ });
133
+ }
134
+ }
135
+ return summaries;
136
+ }
137
+ // ============================================================================
138
+ // Entity Parsers
139
+ // ============================================================================
140
+ function parseWorkflows(section) {
141
+ if (!section)
142
+ return [];
143
+ const workflows = [];
144
+ for (const line of section.split('\n')) {
145
+ const match = line.match(/\|\s*(\w+)\s*\|\s*(\w+)\s*\|\s*(.+?)\s*\|/);
146
+ if (match && match[1] !== 'Status') {
147
+ workflows.push({
148
+ status: match[1],
149
+ category: match[2],
150
+ description: match[3].trim(),
151
+ });
152
+ }
153
+ }
154
+ return workflows;
155
+ }
156
+ function parseTeams(section) {
157
+ if (!section)
158
+ return [];
159
+ const teams = [];
160
+ for (const line of section.split('\n')) {
161
+ const match = line.match(/^[-*]\s+(\w+)(?:\s*[—–-]\s*(.+))?$/);
162
+ if (match)
163
+ teams.push({ name: match[1], description: match[2]?.trim() });
164
+ }
165
+ return teams;
166
+ }
167
+ function parseProjectConfig(content) {
168
+ const { frontMatter, body } = parseFrontMatter(content);
169
+ const sections = extractSections(body);
170
+ const idPrefixes = {};
171
+ const rawPrefixes = frontMatter.id_prefixes;
172
+ if (rawPrefixes && typeof rawPrefixes === 'object') {
173
+ Object.assign(idPrefixes, rawPrefixes);
174
+ }
175
+ return {
176
+ name: String(frontMatter.name || ''),
177
+ id: String(frontMatter.id || ''),
178
+ created: String(frontMatter.created || ''),
179
+ status: frontMatter.status || 'active',
180
+ estimation: frontMatter.estimation || 'none',
181
+ idPrefixes,
182
+ workflows: parseWorkflows(sections.get('Workflows')),
183
+ labels: (Array.isArray(frontMatter.labels) ? frontMatter.labels : []),
184
+ teams: parseTeams(sections.get('Teams')),
185
+ };
186
+ }
187
+ function parseProjectState(content) {
188
+ const { frontMatter, body } = parseFrontMatter(content);
189
+ const sections = extractSections(body);
190
+ return {
191
+ project: String(frontMatter.project || ''),
192
+ currentSprint: frontMatter.current_sprint || null,
193
+ activeMilestone: frontMatter.active_milestone || null,
194
+ paused: frontMatter.paused === true,
195
+ lastSession: frontMatter.last_session || null,
196
+ readyToWork: parseIssueSummaries(sections.get('Ready to Work') || ''),
197
+ inProgress: parseIssueSummaries(sections.get('In Progress') || ''),
198
+ blocked: parseIssueSummaries(sections.get('Blocked') || ''),
199
+ recentlyCompleted: parseCompletedSummaries(sections.get('Recently Completed') || ''),
200
+ warnings: parseListItems(sections.get('Warnings') || ''),
201
+ };
202
+ }
203
+ function toStringArray(val) {
204
+ return Array.isArray(val) ? val.map(String) : [];
205
+ }
206
+ function optionalString(val) {
207
+ return val || null;
208
+ }
209
+ function parseIssue(content, filePath) {
210
+ const { frontMatter: fm, body } = parseFrontMatter(content);
211
+ const sections = extractSections(body);
212
+ return {
213
+ id: String(fm.id || ''),
214
+ title: String(fm.title || ''),
215
+ type: fm.type || 'issue',
216
+ status: String(fm.status || 'backlog'),
217
+ priority: String(fm.priority || 'P2'),
218
+ estimate: fm.estimate != null ? fm.estimate : null,
219
+ labels: toStringArray(fm.labels),
220
+ epic: optionalString(fm.epic),
221
+ sprint: optionalString(fm.sprint),
222
+ milestone: optionalString(fm.milestone),
223
+ assigned: optionalString(fm.assigned),
224
+ created: String(fm.created || ''),
225
+ updated: optionalString(fm.updated),
226
+ due: optionalString(fm.due),
227
+ blockedBy: toStringArray(fm.blocked_by),
228
+ blocks: toStringArray(fm.blocks),
229
+ relatesTo: toStringArray(fm.relates_to),
230
+ children: toStringArray(fm.children),
231
+ progress: optionalString(fm.progress),
232
+ description: sections.get('Description') || '',
233
+ acceptanceCriteria: parseCheckboxes(sections.get('Acceptance Criteria') || ''),
234
+ technicalNotes: sections.get('Technical Notes') || null,
235
+ filesToModify: parseListItems(sections.get('Files to Modify') || ''),
236
+ activity: parseListItems(sections.get('Activity') || ''),
237
+ body,
238
+ path: filePath,
239
+ };
240
+ }
241
+ function parseSprintIssues(section) {
242
+ if (!section)
243
+ return [];
244
+ const issues = [];
245
+ for (const line of section.split('\n')) {
246
+ const match = line.match(/\|\s*\[([^\]]+)\]\(([^)]+)\)\s*\|\s*(.+?)\s*\|\s*(\S+)\s*\|\s*(\S+)\s*\|/);
247
+ if (match) {
248
+ issues.push({
249
+ id: match[1],
250
+ path: match[2],
251
+ title: match[3].trim(),
252
+ points: /^\d+$/.test(match[4]) ? Number(match[4]) : match[4],
253
+ status: match[5],
254
+ });
255
+ }
256
+ }
257
+ return issues;
258
+ }
259
+ function optionalNumber(val) {
260
+ return val != null ? Number(val) : null;
261
+ }
262
+ function parseSprint(content, filePath) {
263
+ const { frontMatter: fm, body } = parseFrontMatter(content);
264
+ const sections = extractSections(body);
265
+ return {
266
+ id: String(fm.id || ''),
267
+ title: String(fm.title || ''),
268
+ status: fm.status || 'planned',
269
+ start: String(fm.start || ''),
270
+ end: String(fm.end || ''),
271
+ goal: String(fm.goal || sections.get('Goal') || ''),
272
+ capacity: optionalNumber(fm.capacity),
273
+ committed: optionalNumber(fm.committed),
274
+ completed: optionalNumber(fm.completed),
275
+ issues: parseSprintIssues(sections.get('Issues')),
276
+ path: filePath,
277
+ };
278
+ }
279
+ function parseMilestone(content, filePath) {
280
+ const { frontMatter, body } = parseFrontMatter(content);
281
+ const sections = extractSections(body);
282
+ const epics = [];
283
+ const epicSection = sections.get('Epics');
284
+ if (epicSection) {
285
+ for (const line of epicSection.split('\n')) {
286
+ const match = line.match(/\|\s*\[([^\]]+)\]\(([^)]+)\)\s*\|\s*(.+?)\s*\|\s*(\S+)\s*\|/);
287
+ if (match) {
288
+ epics.push({
289
+ id: match[1],
290
+ path: match[2],
291
+ title: match[3].trim(),
292
+ progress: match[4],
293
+ });
294
+ }
295
+ }
296
+ }
297
+ return {
298
+ id: String(frontMatter.id || ''),
299
+ title: String(frontMatter.title || ''),
300
+ status: frontMatter.status || 'planned',
301
+ targetDate: frontMatter.target_date || null,
302
+ progress: frontMatter.progress || null,
303
+ definition: sections.get('Definition of Done') || '',
304
+ epics,
305
+ path: filePath,
306
+ };
307
+ }
308
+ // ============================================================================
309
+ // Directory Parser
310
+ // ============================================================================
311
+ /** Resolve the PM directory — prefers .pm/, falls back to legacy .plan/ */
312
+ export function resolvePmDir(workingDir) {
313
+ const pmDir = join(workingDir, '.pm');
314
+ if (existsSync(pmDir))
315
+ return pmDir;
316
+ const legacyDir = join(workingDir, '.plan');
317
+ if (existsSync(legacyDir))
318
+ return legacyDir;
319
+ return null;
320
+ }
321
+ export function planDirExists(workingDir) {
322
+ return resolvePmDir(workingDir) !== null;
323
+ }
324
+ function readFileIfExists(path) {
325
+ try {
326
+ if (existsSync(path))
327
+ return readFileSync(path, 'utf-8');
328
+ }
329
+ catch { /* skip */ }
330
+ return null;
331
+ }
332
+ function readMdFilesInDir(dirPath) {
333
+ if (!existsSync(dirPath))
334
+ return [];
335
+ try {
336
+ return readdirSync(dirPath)
337
+ .filter(f => f.endsWith('.md'))
338
+ .map(name => {
339
+ const content = readFileSync(join(dirPath, name), 'utf-8');
340
+ return { name, content };
341
+ });
342
+ }
343
+ catch {
344
+ return [];
345
+ }
346
+ }
347
+ export function parsePlanDirectory(workingDir) {
348
+ const planDir = resolvePmDir(workingDir);
349
+ if (!planDir)
350
+ return null;
351
+ // Parse project.md
352
+ const projectContent = readFileIfExists(join(planDir, 'project.md'));
353
+ const project = projectContent
354
+ ? parseProjectConfig(projectContent)
355
+ : { name: '', id: '', created: '', status: 'active', estimation: 'none', idPrefixes: {}, workflows: [], labels: [], teams: [] };
356
+ // Parse STATE.md
357
+ const stateContent = readFileIfExists(join(planDir, 'STATE.md'));
358
+ const state = stateContent
359
+ ? parseProjectState(stateContent)
360
+ : { project: '', currentSprint: null, activeMilestone: null, paused: false, lastSession: null, readyToWork: [], inProgress: [], blocked: [], recentlyCompleted: [], warnings: [] };
361
+ // Parse backlog issues
362
+ const issueFiles = readMdFilesInDir(join(planDir, 'backlog'));
363
+ const issues = issueFiles.map(f => parseIssue(f.content, `backlog/${f.name}`));
364
+ // Parse sprints
365
+ const sprintFiles = readMdFilesInDir(join(planDir, 'sprints'));
366
+ const sprints = sprintFiles.map(f => parseSprint(f.content, `sprints/${f.name}`));
367
+ // Parse milestones
368
+ const milestoneFiles = readMdFilesInDir(join(planDir, 'milestones'));
369
+ const milestones = milestoneFiles.map(f => parseMilestone(f.content, `milestones/${f.name}`));
370
+ return { project, state, issues, sprints, milestones };
371
+ }
372
+ export function parseSingleIssue(workingDir, issuePath) {
373
+ const pmDir = resolvePmDir(workingDir);
374
+ if (!pmDir)
375
+ return null;
376
+ const fullPath = join(pmDir, issuePath);
377
+ const content = readFileIfExists(fullPath);
378
+ if (!content)
379
+ return null;
380
+ return parseIssue(content, issuePath);
381
+ }
382
+ export function parseSingleSprint(workingDir, sprintPath) {
383
+ const pmDir = resolvePmDir(workingDir);
384
+ if (!pmDir)
385
+ return null;
386
+ const fullPath = join(pmDir, sprintPath);
387
+ const content = readFileIfExists(fullPath);
388
+ if (!content)
389
+ return null;
390
+ return parseSprint(content, sprintPath);
391
+ }
392
+ export function parseSingleMilestone(workingDir, milestonePath) {
393
+ const pmDir = resolvePmDir(workingDir);
394
+ if (!pmDir)
395
+ return null;
396
+ const fullPath = join(pmDir, milestonePath);
397
+ const content = readFileIfExists(fullPath);
398
+ if (!content)
399
+ return null;
400
+ return parseMilestone(content, milestonePath);
401
+ }
402
+ /** Compute the next available ID for a given prefix (e.g., "IS" → "IS-004") */
403
+ export function getNextId(issues, prefix) {
404
+ let max = 0;
405
+ for (const issue of issues) {
406
+ const match = issue.id.match(new RegExp(`^${prefix}-(\\d+)$`));
407
+ if (match) {
408
+ const num = Number.parseInt(match[1], 10);
409
+ if (num > max)
410
+ max = num;
411
+ }
412
+ }
413
+ return `${prefix}-${String(max + 1).padStart(3, '0')}`;
414
+ }
415
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../server/services/plan/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function reconcileState(workingDir: string): void;
2
+ //# sourceMappingURL=state-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-reconciler.d.ts","sourceRoot":"","sources":["../../../../server/services/plan/state-reconciler.ts"],"names":[],"mappings":"AA6GA,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAsBvD"}
@@ -0,0 +1,105 @@
1
+ // Copyright (c) 2025-present Mstro, Inc. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file for details.
3
+ /**
4
+ * State Reconciler — Recomputes STATE.md from individual issue files.
5
+ *
6
+ * When individual issues change (detected by watcher), this module
7
+ * scans all backlog files and rebuilds the STATE.md sections.
8
+ */
9
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { resolveReadyToWork } from './dependency-resolver.js';
12
+ import { parsePlanDirectory, resolvePmDir } from './parser.js';
13
+ function categorizeIssues(issues, issueByPath) {
14
+ const inProgress = [];
15
+ const blocked = [];
16
+ const recentlyCompleted = [];
17
+ const readyToWork = resolveReadyToWork(issues);
18
+ for (const issue of issues) {
19
+ if (issue.type === 'epic')
20
+ continue;
21
+ if (issue.status === 'in_progress' || issue.status === 'in_review') {
22
+ inProgress.push(issue);
23
+ }
24
+ else if (issue.blockedBy.length > 0 && issue.status !== 'done' && issue.status !== 'cancelled') {
25
+ const allBlockersDone = issue.blockedBy.every(bp => {
26
+ const blocker = issueByPath.get(bp);
27
+ return blocker && (blocker.status === 'done' || blocker.status === 'cancelled');
28
+ });
29
+ if (!allBlockersDone) {
30
+ blocked.push(issue);
31
+ }
32
+ }
33
+ if (issue.status === 'done') {
34
+ recentlyCompleted.push(issue);
35
+ }
36
+ }
37
+ return { inProgress, blocked, recentlyCompleted, readyToWork };
38
+ }
39
+ function computeWarnings(issues) {
40
+ const warnings = [];
41
+ const today = new Date().toISOString().split('T')[0];
42
+ for (const issue of issues) {
43
+ if (issue.due && issue.due <= today && issue.status !== 'done' && issue.status !== 'cancelled') {
44
+ const daysOverdue = Math.ceil((Date.now() - new Date(issue.due).getTime()) / (1000 * 60 * 60 * 24));
45
+ warnings.push(`${issue.id} due date was ${issue.due} (${daysOverdue} day${daysOverdue !== 1 ? 's' : ''} overdue)`);
46
+ }
47
+ }
48
+ return warnings;
49
+ }
50
+ function buildStateMarkdown(frontMatter, categories, warnings, issueByPath) {
51
+ const formatSummary = (issue, index) => {
52
+ return `${index + 1}. [${issue.id}](${issue.path}) — ${issue.title} (${issue.priority})`;
53
+ };
54
+ const formatBlocked = (issue) => {
55
+ const blockerIds = issue.blockedBy.map(bp => {
56
+ const blocker = issueByPath.get(bp);
57
+ return blocker ? `[${blocker.id}](${blocker.path})` : bp;
58
+ }).join(', ');
59
+ return `- [${issue.id}](${issue.path}) — ${issue.title} → blocked by ${blockerIds}`;
60
+ };
61
+ const sections = [
62
+ '# Project State',
63
+ '',
64
+ '## Current Focus',
65
+ '',
66
+ '## Ready to Work',
67
+ ...categories.readyToWork.map(formatSummary),
68
+ '',
69
+ '## In Progress',
70
+ ...categories.inProgress.map(issue => `- [${issue.id}](${issue.path}) — ${issue.title}`),
71
+ '',
72
+ '## Blocked',
73
+ ...categories.blocked.map(formatBlocked),
74
+ '',
75
+ '## Recently Completed',
76
+ ...categories.recentlyCompleted.slice(0, 10).map(issue => `- [${issue.id}](${issue.path}) — ${issue.title} ✓`),
77
+ '',
78
+ '## Warnings',
79
+ ...warnings.map(w => `- ${w}`),
80
+ '',
81
+ ];
82
+ return `---\n${frontMatter}\n---\n\n${sections.join('\n')}`;
83
+ }
84
+ export function reconcileState(workingDir) {
85
+ const pmDir = resolvePmDir(workingDir);
86
+ if (!pmDir)
87
+ return;
88
+ const statePath = join(pmDir, 'STATE.md');
89
+ if (!existsSync(statePath))
90
+ return;
91
+ const fullState = parsePlanDirectory(workingDir);
92
+ if (!fullState)
93
+ return;
94
+ const { issues, project } = fullState;
95
+ const issueByPath = new Map(issues.map(i => [i.path, i]));
96
+ const categories = categorizeIssues(issues, issueByPath);
97
+ const warnings = computeWarnings(issues);
98
+ // Read existing front matter
99
+ const content = readFileSync(statePath, 'utf-8');
100
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
101
+ const frontMatter = fmMatch ? fmMatch[1] : `project: "${project.name}"\ncurrent_sprint: null\nactive_milestone: null\npaused: false\nlast_session: null`;
102
+ const newContent = buildStateMarkdown(frontMatter, categories, warnings, issueByPath);
103
+ writeFileSync(statePath, newContent, 'utf-8');
104
+ }
105
+ //# sourceMappingURL=state-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-reconciler.js","sourceRoot":"","sources":["../../../../server/services/plan/state-reconciler.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,gEAAgE;AAEhE;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU/D,SAAS,gBAAgB,CAAC,MAAe,EAAE,WAA+B;IACxE,MAAM,UAAU,GAAY,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,iBAAiB,GAAY,EAAE,CAAC;IACtC,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,aAAa,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACnE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YACjG,MAAM,eAAe,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;gBACjD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACpC,OAAO,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;YAClF,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC5B,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,eAAe,CAAC,MAAe;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/F,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YACpG,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,iBAAiB,KAAK,CAAC,GAAG,KAAK,WAAW,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QACrH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,kBAAkB,CACzB,WAAmB,EACnB,UAA6B,EAC7B,QAAkB,EAClB,WAA+B;IAE/B,MAAM,aAAa,GAAG,CAAC,KAAY,EAAE,KAAa,EAAU,EAAE;QAC5D,OAAO,GAAG,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC;IAC3F,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,KAAY,EAAU,EAAE;QAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAC1C,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpC,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,MAAM,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,iBAAiB,UAAU,EAAE,CAAC;IACtF,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,iBAAiB;QACjB,EAAE;QACF,kBAAkB;QAClB,EAAE;QACF,kBAAkB;QAClB,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC;QAC5C,EAAE;QACF,gBAAgB;QAChB,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QACxF,EAAE;QACF,YAAY;QACZ,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACxC,EAAE;QACF,uBAAuB;QACvB,GAAG,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,KAAK,IAAI,CAAC;QAC9G,EAAE;QACF,aAAa;QACb,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,EAAE;KACH,CAAC;IAEF,OAAO,QAAQ,WAAW,YAAY,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO;IAEnC,MAAM,SAAS,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS;QAAE,OAAO;IAEvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAEtC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAEzC,6BAA6B;IAC7B,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,IAAI,oFAAoF,CAAC;IAEzJ,MAAM,UAAU,GAAG,kBAAkB,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACtF,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}