@comfanion/workflow 4.38.1-dev.2 → 4.38.1-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/build-info.json
CHANGED
|
@@ -306,83 +306,39 @@ DO NOT skip this step. DO NOT ask user what to do. Just read these files first.`
|
|
|
306
306
|
|
|
307
307
|
async function getActiveStory(): Promise<StoryContext | null> {
|
|
308
308
|
try {
|
|
309
|
-
|
|
309
|
+
let storyPath: string | null = null
|
|
310
|
+
|
|
311
|
+
// First, try epic state file for story path
|
|
310
312
|
const epicState = await getActiveEpicState()
|
|
311
|
-
if (epicState) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (storyPathMatch) {
|
|
315
|
-
const storyFileName = storyPathMatch[1]
|
|
316
|
-
// Find story file
|
|
317
|
-
const sprintMatch = epicState.statePath.match(/sprint-(\d+)/)
|
|
318
|
-
if (sprintMatch) {
|
|
319
|
-
const storyPath = `docs/sprint-artifacts/sprint-${sprintMatch[1]}/stories/${storyFileName}`
|
|
320
|
-
const storyContent = await readFile(join(directory, storyPath), "utf-8")
|
|
321
|
-
|
|
322
|
-
const titleMatch = storyContent.match(/^#\s+(.+)/m)
|
|
323
|
-
const statusMatch = storyContent.match(/\*\*Status:\*\*\s*(\w+)/i)
|
|
324
|
-
|
|
325
|
-
const completedTasks: string[] = []
|
|
326
|
-
const pendingTasks: string[] = []
|
|
327
|
-
let currentTask: string | null = null
|
|
328
|
-
|
|
329
|
-
// Parse tasks with more detail
|
|
330
|
-
const taskRegex = /- \[([ x])\]\s+\*\*T(\d+)\*\*[:\s]+(.+?)(?=\n|$)/g
|
|
331
|
-
let match
|
|
332
|
-
while ((match = taskRegex.exec(storyContent)) !== null) {
|
|
333
|
-
const [, checked, taskId, taskName] = match
|
|
334
|
-
const taskInfo = `T${taskId}: ${taskName.trim()}`
|
|
335
|
-
if (checked === "x") {
|
|
336
|
-
completedTasks.push(taskInfo)
|
|
337
|
-
} else {
|
|
338
|
-
if (!currentTask) currentTask = taskInfo
|
|
339
|
-
pendingTasks.push(taskInfo)
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Parse acceptance criteria
|
|
344
|
-
const acceptanceCriteria: string[] = []
|
|
345
|
-
const acSection = storyContent.match(/## Acceptance Criteria[\s\S]*?(?=##|$)/i)
|
|
346
|
-
if (acSection) {
|
|
347
|
-
const acRegex = /- \[([ x])\]\s+(.+?)(?=\n|$)/g
|
|
348
|
-
while ((match = acRegex.exec(acSection[0])) !== null) {
|
|
349
|
-
const [, checked, criteria] = match
|
|
350
|
-
acceptanceCriteria.push(`${checked === "x" ? "✅" : "⬜"} ${criteria.trim()}`)
|
|
351
|
-
}
|
|
352
|
-
}
|
|
313
|
+
if (epicState?.nextStoryPath) {
|
|
314
|
+
storyPath = epicState.nextStoryPath
|
|
315
|
+
}
|
|
353
316
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
fullContent: storyContent
|
|
363
|
-
}
|
|
317
|
+
// Fallback: try sprint-status.yaml
|
|
318
|
+
if (!storyPath) {
|
|
319
|
+
try {
|
|
320
|
+
const sprintStatusPath = join(directory, "docs", "sprint-artifacts", "sprint-status.yaml")
|
|
321
|
+
const content = await readFile(sprintStatusPath, "utf-8")
|
|
322
|
+
const inProgressMatch = content.match(/status:\s*in-progress[\s\S]*?path:\s*["']?([^"'\n]+)["']?/i)
|
|
323
|
+
if (inProgressMatch) {
|
|
324
|
+
storyPath = inProgressMatch[1]
|
|
364
325
|
}
|
|
326
|
+
} catch {
|
|
327
|
+
// No sprint-status.yaml
|
|
365
328
|
}
|
|
366
329
|
}
|
|
367
|
-
|
|
368
|
-
// Fallback: try old sprint-status.yaml format
|
|
369
|
-
const sprintStatusPath = join(directory, "docs", "sprint-artifacts", "sprint-status.yaml")
|
|
370
|
-
const content = await readFile(sprintStatusPath, "utf-8")
|
|
371
|
-
|
|
372
|
-
const inProgressMatch = content.match(/status:\s*in-progress[\s\S]*?path:\s*["']?([^"'\n]+)["']?/i)
|
|
373
|
-
if (!inProgressMatch) return null
|
|
374
330
|
|
|
375
|
-
|
|
331
|
+
if (!storyPath) return null
|
|
332
|
+
|
|
333
|
+
// Parse story file
|
|
376
334
|
const storyContent = await readFile(join(directory, storyPath), "utf-8")
|
|
377
|
-
|
|
378
335
|
const titleMatch = storyContent.match(/^#\s+(.+)/m)
|
|
379
336
|
const statusMatch = storyContent.match(/\*\*Status:\*\*\s*(\w+)/i)
|
|
380
|
-
|
|
337
|
+
|
|
381
338
|
const completedTasks: string[] = []
|
|
382
339
|
const pendingTasks: string[] = []
|
|
383
340
|
let currentTask: string | null = null
|
|
384
|
-
|
|
385
|
-
// Parse tasks with more detail
|
|
341
|
+
|
|
386
342
|
const taskRegex = /- \[([ x])\]\s+\*\*T(\d+)\*\*[:\s]+(.+?)(?=\n|$)/g
|
|
387
343
|
let match
|
|
388
344
|
while ((match = taskRegex.exec(storyContent)) !== null) {
|
|
@@ -395,8 +351,7 @@ DO NOT skip this step. DO NOT ask user what to do. Just read these files first.`
|
|
|
395
351
|
pendingTasks.push(taskInfo)
|
|
396
352
|
}
|
|
397
353
|
}
|
|
398
|
-
|
|
399
|
-
// Parse acceptance criteria
|
|
354
|
+
|
|
400
355
|
const acceptanceCriteria: string[] = []
|
|
401
356
|
const acSection = storyContent.match(/## Acceptance Criteria[\s\S]*?(?=##|$)/i)
|
|
402
357
|
if (acSection) {
|