ai-sdlc 0.1.1-alpha.2 → 0.2.0-alpha.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.
@@ -1,13 +1,64 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { KANBAN_FOLDERS, ReviewDecision, BLOCKED_DIR } from '../types/index.js';
3
+ import { glob } from 'glob';
4
+ import { KANBAN_FOLDERS, ReviewDecision, BLOCKED_DIR, STORIES_FOLDER, STORY_FILENAME } from '../types/index.js';
4
5
  import { parseStory, isAtMaxRetries, canRetryRefinement, getLatestReviewAttempt, moveToBlocked, getEffectiveMaxRetries, sanitizeReasonText } from './story.js';
5
6
  import { loadConfig } from './config.js';
6
7
  import { determineTargetPhase } from '../agents/rework.js';
8
+ /**
9
+ * Find all stories in the stories/ folder structure
10
+ * Globs stories/*\u200B/story.md and returns all story objects
11
+ * Skips malformed folders (folders without story.md)
12
+ */
13
+ export function findAllStories(sdlcRoot) {
14
+ const storiesFolder = path.join(sdlcRoot, STORIES_FOLDER);
15
+ if (!fs.existsSync(storiesFolder)) {
16
+ return [];
17
+ }
18
+ const stories = [];
19
+ const pattern = path.join(storiesFolder, '*', STORY_FILENAME);
20
+ try {
21
+ const storyPaths = glob.sync(pattern);
22
+ for (const storyPath of storyPaths) {
23
+ try {
24
+ const story = parseStory(storyPath);
25
+ stories.push(story);
26
+ }
27
+ catch (err) {
28
+ // Skip malformed stories
29
+ continue;
30
+ }
31
+ }
32
+ }
33
+ catch (err) {
34
+ // If glob fails, return empty array
35
+ return [];
36
+ }
37
+ return stories;
38
+ }
39
+ /**
40
+ * Find stories by frontmatter status
41
+ * Filters stories by frontmatter status and sorts by priority ascending
42
+ */
43
+ export function findStoriesByStatus(sdlcRoot, status) {
44
+ const allStories = findAllStories(sdlcRoot);
45
+ return allStories
46
+ .filter(story => story.frontmatter.status === status)
47
+ .sort((a, b) => {
48
+ // Sort by priority ascending
49
+ if (a.frontmatter.priority !== b.frontmatter.priority) {
50
+ return a.frontmatter.priority - b.frontmatter.priority;
51
+ }
52
+ // Tiebreaker: sort by creation date
53
+ return a.frontmatter.created.localeCompare(b.frontmatter.created);
54
+ });
55
+ }
7
56
  /**
8
57
  * Get all stories in a specific kanban folder
58
+ * @deprecated Use findStoriesByStatus() instead
9
59
  */
10
60
  export function getStoriesInFolder(sdlcRoot, folder) {
61
+ console.warn('getStoriesInFolder() is deprecated. Use findStoriesByStatus() instead.');
11
62
  const folderPath = path.join(sdlcRoot, folder);
12
63
  if (!fs.existsSync(folderPath)) {
13
64
  return [];
@@ -19,18 +70,54 @@ export function getStoriesInFolder(sdlcRoot, folder) {
19
70
  }
20
71
  /**
21
72
  * Get all stories across all kanban folders
73
+ * In new architecture, uses findAllStories() and groups by status
22
74
  */
23
75
  export function getAllStories(sdlcRoot) {
24
76
  const stories = new Map();
77
+ // Initialize empty arrays for each folder
25
78
  for (const folder of KANBAN_FOLDERS) {
26
- stories.set(folder, getStoriesInFolder(sdlcRoot, folder));
79
+ stories.set(folder, []);
80
+ }
81
+ // Get all stories and group by status
82
+ const allStories = findAllStories(sdlcRoot);
83
+ for (const story of allStories) {
84
+ const status = story.frontmatter.status;
85
+ // Only add to map if status matches a kanban folder (exclude 'blocked')
86
+ if (status === 'backlog' || status === 'ready' || status === 'in-progress' || status === 'done') {
87
+ const folder = status;
88
+ const folderStories = stories.get(folder) || [];
89
+ folderStories.push(story);
90
+ stories.set(folder, folderStories);
91
+ }
92
+ }
93
+ // Sort each folder's stories by priority
94
+ for (const [folder, folderStories] of stories.entries()) {
95
+ folderStories.sort((a, b) => {
96
+ if (a.frontmatter.priority !== b.frontmatter.priority) {
97
+ return a.frontmatter.priority - b.frontmatter.priority;
98
+ }
99
+ return a.frontmatter.created.localeCompare(b.frontmatter.created);
100
+ });
101
+ stories.set(folder, folderStories);
27
102
  }
28
103
  return stories;
29
104
  }
30
105
  /**
31
- * Find a story by ID across all folders (including blocked)
106
+ * Find a story by ID using O(1) direct path lookup
107
+ * Falls back to searching old folder structure for backwards compatibility
32
108
  */
33
109
  export function findStoryById(sdlcRoot, storyId) {
110
+ // O(1) direct path construction for new architecture
111
+ const storyPath = path.join(sdlcRoot, STORIES_FOLDER, storyId, STORY_FILENAME);
112
+ if (fs.existsSync(storyPath)) {
113
+ try {
114
+ return parseStory(storyPath);
115
+ }
116
+ catch (err) {
117
+ // Story file exists but is malformed, fall through to search
118
+ }
119
+ }
120
+ // Fallback: search old folder structure for backwards compatibility
34
121
  // Search kanban folders first
35
122
  for (const folder of KANBAN_FOLDERS) {
36
123
  const stories = getStoriesInFolder(sdlcRoot, folder);
@@ -44,9 +131,14 @@ export function findStoryById(sdlcRoot, storyId) {
44
131
  const blockedFiles = fs.readdirSync(blockedFolder).filter(f => f.endsWith('.md'));
45
132
  for (const file of blockedFiles) {
46
133
  const filePath = path.join(blockedFolder, file);
47
- const story = parseStory(filePath);
48
- if (story.frontmatter.id === storyId) {
49
- return story;
134
+ try {
135
+ const story = parseStory(filePath);
136
+ if (story.frontmatter.id === storyId) {
137
+ return story;
138
+ }
139
+ }
140
+ catch (err) {
141
+ continue;
50
142
  }
51
143
  }
52
144
  }
@@ -56,13 +148,8 @@ export function findStoryById(sdlcRoot, storyId) {
56
148
  * Find a story by slug across all folders
57
149
  */
58
150
  export function findStoryBySlug(sdlcRoot, slug) {
59
- for (const folder of KANBAN_FOLDERS) {
60
- const stories = getStoriesInFolder(sdlcRoot, folder);
61
- const found = stories.find(s => s.slug === slug);
62
- if (found)
63
- return found;
64
- }
65
- return null;
151
+ const allStories = findAllStories(sdlcRoot);
152
+ return allStories.find(s => s.slug === slug) || null;
66
153
  }
67
154
  /**
68
155
  * Calculate completion score for a story based on workflow progress.
@@ -96,10 +183,10 @@ function hasFailedReview(story) {
96
183
  * Assess the current state of the kanban board and recommend actions
97
184
  */
98
185
  export function assessState(sdlcRoot) {
99
- const backlogItems = getStoriesInFolder(sdlcRoot, 'backlog');
100
- const readyItems = getStoriesInFolder(sdlcRoot, 'ready');
101
- const inProgressItems = getStoriesInFolder(sdlcRoot, 'in-progress');
102
- const doneItems = getStoriesInFolder(sdlcRoot, 'done');
186
+ const backlogItems = findStoriesByStatus(sdlcRoot, 'backlog');
187
+ const readyItems = findStoriesByStatus(sdlcRoot, 'ready');
188
+ const inProgressItems = findStoriesByStatus(sdlcRoot, 'in-progress');
189
+ const doneItems = findStoriesByStatus(sdlcRoot, 'done');
103
190
  const recommendedActions = [];
104
191
  const workingDir = path.dirname(sdlcRoot);
105
192
  const config = loadConfig(workingDir);
@@ -293,18 +380,19 @@ export function assessState(sdlcRoot) {
293
380
  * Initialize the kanban folder structure
294
381
  */
295
382
  export function initializeKanban(sdlcRoot) {
296
- for (const folder of KANBAN_FOLDERS) {
297
- const folderPath = path.join(sdlcRoot, folder);
298
- if (!fs.existsSync(folderPath)) {
299
- fs.mkdirSync(folderPath, { recursive: true });
300
- }
383
+ // Create stories/ folder for new architecture
384
+ const storiesFolder = path.join(sdlcRoot, STORIES_FOLDER);
385
+ if (!fs.existsSync(storiesFolder)) {
386
+ fs.mkdirSync(storiesFolder, { recursive: true });
301
387
  }
302
388
  }
303
389
  /**
304
390
  * Check if kanban structure exists
305
391
  */
306
392
  export function kanbanExists(sdlcRoot) {
307
- return KANBAN_FOLDERS.every(folder => fs.existsSync(path.join(sdlcRoot, folder)));
393
+ // Check for new stories/ folder architecture
394
+ const storiesFolder = path.join(sdlcRoot, STORIES_FOLDER);
395
+ return fs.existsSync(storiesFolder);
308
396
  }
309
397
  /**
310
398
  * Get board statistics
@@ -317,7 +405,7 @@ export function getBoardStats(sdlcRoot) {
317
405
  done: 0,
318
406
  };
319
407
  for (const folder of KANBAN_FOLDERS) {
320
- stats[folder] = getStoriesInFolder(sdlcRoot, folder).length;
408
+ stats[folder] = findStoriesByStatus(sdlcRoot, folder).length;
321
409
  }
322
410
  return stats;
323
411
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kanban.js","sourceRoot":"","sources":["../../src/core/kanban.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kanban.js","sourceRoot":"","sources":["../../src/core/kanban.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,28 @@
1
- import { Story, StoryFrontmatter, ReviewAttempt, Config } from '../types/index.js';
1
+ import { Story, StoryFrontmatter, StoryStatus, ReviewAttempt, Config } from '../types/index.js';
2
2
  /**
3
3
  * Parse a story markdown file into a Story object
4
+ *
5
+ * In the new architecture, story ID is extracted from the parent folder name,
6
+ * and slug is read from frontmatter (with fallback to ID if missing).
4
7
  */
5
8
  export declare function parseStory(filePath: string): Story;
6
9
  /**
7
10
  * Write a story back to disk
8
11
  */
9
12
  export declare function writeStory(story: Story): void;
13
+ /**
14
+ * Update story status in frontmatter without moving files
15
+ * This is the preferred method in the new folder-per-story architecture
16
+ */
17
+ export declare function updateStoryStatus(story: Story, newStatus: StoryStatus): Story;
10
18
  /**
11
19
  * Move a story to a different kanban folder
20
+ * @deprecated Use updateStoryStatus() instead. Will be removed in v2.0
12
21
  */
13
22
  export declare function moveStory(story: Story, toFolder: string, sdlcRoot: string): Story;
14
23
  /**
15
- * Move a story to the blocked folder with reason and timestamp
24
+ * Move a story to blocked status with reason and timestamp
25
+ * In the new architecture, this only updates frontmatter - file path remains unchanged
16
26
  *
17
27
  * @param storyPath - Absolute path to the story file
18
28
  * @param reason - Reason for blocking (e.g., "Max refinement attempts (2/2) reached")
@@ -27,7 +37,10 @@ export declare function generateStoryId(): string;
27
37
  */
28
38
  export declare function slugify(title: string): string;
29
39
  /**
30
- * Create a new story in the backlog
40
+ * Create a new story in the folder-per-story structure
41
+ *
42
+ * Creates stories/{id}/story.md with slug and priority in frontmatter.
43
+ * Priority uses gaps (10, 20, 30...) for easy insertion without renumbering.
31
44
  */
32
45
  export declare function createStory(title: string, sdlcRoot: string, options?: Partial<StoryFrontmatter>): Story;
33
46
  /**
@@ -102,13 +115,13 @@ export declare function snapshotMaxRetries(story: Story, config: Config): Story;
102
115
  */
103
116
  export declare function sanitizeReasonText(text: string): string;
104
117
  /**
105
- * Unblock a story from the blocked folder and move it back to the workflow
106
- * Determines destination folder based on workflow completion state
118
+ * Unblock a story and set status back to in-progress
119
+ * In the new architecture, this only updates frontmatter - file path remains unchanged
107
120
  *
108
121
  * @param storyId - Story ID to unblock
109
122
  * @param sdlcRoot - Root path of the .ai-sdlc folder
110
123
  * @param options - Optional configuration { resetRetries?: boolean }
111
- * @returns The unblocked and moved story
124
+ * @returns The unblocked story
112
125
  */
113
126
  export declare function unblockStory(storyId: string, sdlcRoot: string, options?: {
114
127
  resetRetries?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/core/story.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"story.d.ts","sourceRoot":"","sources":["../../src/core/story.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,36 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import matter from 'gray-matter';
4
- import { FOLDER_TO_STATUS, BLOCKED_DIR } from '../types/index.js';
4
+ import { FOLDER_TO_STATUS, BLOCKED_DIR, STORIES_FOLDER, STORY_FILENAME, DEFAULT_PRIORITY_GAP } from '../types/index.js';
5
5
  /**
6
6
  * Parse a story markdown file into a Story object
7
+ *
8
+ * In the new architecture, story ID is extracted from the parent folder name,
9
+ * and slug is read from frontmatter (with fallback to ID if missing).
7
10
  */
8
11
  export function parseStory(filePath) {
9
12
  const content = fs.readFileSync(filePath, 'utf-8');
10
13
  const { data, content: body } = matter(content);
11
- // Extract slug from filename (remove priority prefix and .md extension)
12
- const filename = path.basename(filePath, '.md');
13
- const slug = filename.replace(/^\d+-/, '');
14
+ const frontmatter = data;
15
+ // Extract slug from frontmatter (new architecture) or filename (old architecture fallback)
16
+ let slug;
17
+ if (frontmatter.slug) {
18
+ // New architecture: slug is in frontmatter
19
+ slug = frontmatter.slug;
20
+ }
21
+ else {
22
+ // Fallback for old architecture: extract from filename
23
+ const filename = path.basename(filePath, '.md');
24
+ slug = filename.replace(/^\d+-/, '');
25
+ // Also fallback to ID if available
26
+ if (!slug && frontmatter.id) {
27
+ slug = frontmatter.id;
28
+ }
29
+ }
14
30
  return {
15
31
  path: filePath,
16
32
  slug,
17
- frontmatter: data,
33
+ frontmatter,
18
34
  content: body.trim(),
19
35
  };
20
36
  }
@@ -25,10 +41,22 @@ export function writeStory(story) {
25
41
  const content = matter.stringify(story.content, story.frontmatter);
26
42
  fs.writeFileSync(story.path, content);
27
43
  }
44
+ /**
45
+ * Update story status in frontmatter without moving files
46
+ * This is the preferred method in the new folder-per-story architecture
47
+ */
48
+ export function updateStoryStatus(story, newStatus) {
49
+ story.frontmatter.status = newStatus;
50
+ story.frontmatter.updated = new Date().toISOString().split('T')[0];
51
+ writeStory(story);
52
+ return story;
53
+ }
28
54
  /**
29
55
  * Move a story to a different kanban folder
56
+ * @deprecated Use updateStoryStatus() instead. Will be removed in v2.0
30
57
  */
31
58
  export function moveStory(story, toFolder, sdlcRoot) {
59
+ console.warn('moveStory() is deprecated. Use updateStoryStatus() instead. Will be removed in v2.0');
32
60
  const targetFolder = path.join(sdlcRoot, toFolder);
33
61
  // Ensure target folder exists
34
62
  if (!fs.existsSync(targetFolder)) {
@@ -55,7 +83,8 @@ export function moveStory(story, toFolder, sdlcRoot) {
55
83
  return story;
56
84
  }
57
85
  /**
58
- * Move a story to the blocked folder with reason and timestamp
86
+ * Move a story to blocked status with reason and timestamp
87
+ * In the new architecture, this only updates frontmatter - file path remains unchanged
59
88
  *
60
89
  * @param storyPath - Absolute path to the story file
61
90
  * @param reason - Reason for blocking (e.g., "Max refinement attempts (2/2) reached")
@@ -64,7 +93,8 @@ export function moveToBlocked(storyPath, reason) {
64
93
  // Security: Validate path BEFORE any file I/O operations
65
94
  const resolvedPath = path.resolve(storyPath);
66
95
  const storyDir = path.dirname(resolvedPath);
67
- const sdlcRoot = path.dirname(storyDir);
96
+ const storiesFolder = path.dirname(storyDir);
97
+ const sdlcRoot = path.dirname(storiesFolder);
68
98
  const resolvedRoot = path.resolve(sdlcRoot);
69
99
  // Validate that the path is within an SDLC root
70
100
  if (!resolvedPath.startsWith(resolvedRoot)) {
@@ -75,34 +105,13 @@ export function moveToBlocked(storyPath, reason) {
75
105
  }
76
106
  // Parse the story (after security validation passes)
77
107
  const story = parseStory(storyPath);
78
- // Calculate blocked folder path
79
- const blockedFolder = path.join(sdlcRoot, BLOCKED_DIR);
80
- // Create blocked directory if it doesn't exist
81
- if (!fs.existsSync(blockedFolder)) {
82
- fs.mkdirSync(blockedFolder, { recursive: true });
83
- }
84
- // Handle filename conflicts by appending timestamp
85
- let filename = `${story.slug}.md`;
86
- let newPath = path.join(blockedFolder, filename);
87
- // If story already exists in blocked folder with same slug, append timestamp
88
- if (fs.existsSync(newPath) && newPath !== storyPath) {
89
- const timestamp = Date.now();
90
- filename = `${story.slug}-${timestamp}.md`;
91
- newPath = path.join(blockedFolder, filename);
92
- }
93
- // Update frontmatter (sanitize reason at storage point for defense in depth)
108
+ // Update frontmatter only - no file moves in new architecture
94
109
  story.frontmatter.status = 'blocked';
95
110
  story.frontmatter.blocked_reason = sanitizeReasonText(reason);
96
111
  story.frontmatter.blocked_at = new Date().toISOString();
97
112
  story.frontmatter.updated = new Date().toISOString().split('T')[0];
98
- // Write to new location
99
- const oldPath = story.path;
100
- story.path = newPath;
113
+ // Write back to same location
101
114
  writeStory(story);
102
- // Remove old file (only if it's different from new path)
103
- if (fs.existsSync(oldPath) && oldPath !== newPath) {
104
- fs.unlinkSync(oldPath);
105
- }
106
115
  }
107
116
  /**
108
117
  * Generate a unique story ID
@@ -123,23 +132,58 @@ export function slugify(title) {
123
132
  .substring(0, 50);
124
133
  }
125
134
  /**
126
- * Create a new story in the backlog
135
+ * Create a new story in the folder-per-story structure
136
+ *
137
+ * Creates stories/{id}/story.md with slug and priority in frontmatter.
138
+ * Priority uses gaps (10, 20, 30...) for easy insertion without renumbering.
127
139
  */
128
140
  export function createStory(title, sdlcRoot, options = {}) {
129
- const backlogFolder = path.join(sdlcRoot, 'backlog');
130
- // Ensure backlog folder exists
131
- if (!fs.existsSync(backlogFolder)) {
132
- fs.mkdirSync(backlogFolder, { recursive: true });
141
+ const storiesFolder = path.join(sdlcRoot, STORIES_FOLDER);
142
+ // Validate parent stories/ directory exists
143
+ if (!fs.existsSync(storiesFolder)) {
144
+ throw new Error(`Stories folder does not exist: ${storiesFolder}. Run 'ai-sdlc init' first.`);
133
145
  }
134
- // Get existing stories to determine priority
135
- const existingFiles = fs.readdirSync(backlogFolder).filter(f => f.endsWith('.md'));
136
- const priority = existingFiles.length + 1;
146
+ // Generate unique ID and slug
147
+ const id = generateStoryId();
137
148
  const slug = slugify(title);
138
- const filename = `${String(priority).padStart(2, '0')}-${slug}.md`;
139
- const filePath = path.join(backlogFolder, filename);
149
+ // Create story folder: stories/{id}/
150
+ const storyFolder = path.join(storiesFolder, id);
151
+ fs.mkdirSync(storyFolder, { recursive: true });
152
+ // Create story file path: stories/{id}/story.md
153
+ const filePath = path.join(storyFolder, STORY_FILENAME);
154
+ // Calculate priority using gaps - find max priority and add DEFAULT_PRIORITY_GAP
155
+ let priority = DEFAULT_PRIORITY_GAP; // Start at 10 for first story
156
+ try {
157
+ const existingDirs = fs.readdirSync(storiesFolder, { withFileTypes: true })
158
+ .filter(dirent => dirent.isDirectory());
159
+ if (existingDirs.length > 0) {
160
+ let maxPriority = 0;
161
+ for (const dir of existingDirs) {
162
+ const storyPath = path.join(storiesFolder, dir.name, STORY_FILENAME);
163
+ if (fs.existsSync(storyPath)) {
164
+ try {
165
+ const existingStory = parseStory(storyPath);
166
+ if (existingStory.frontmatter.priority > maxPriority) {
167
+ maxPriority = existingStory.frontmatter.priority;
168
+ }
169
+ }
170
+ catch (err) {
171
+ // Skip malformed stories
172
+ continue;
173
+ }
174
+ }
175
+ }
176
+ priority = maxPriority + DEFAULT_PRIORITY_GAP;
177
+ }
178
+ }
179
+ catch (err) {
180
+ // If we can't read existing stories, start at DEFAULT_PRIORITY_GAP
181
+ priority = DEFAULT_PRIORITY_GAP;
182
+ }
140
183
  const frontmatter = {
141
- id: generateStoryId(),
184
+ id,
142
185
  title,
186
+ slug,
143
187
  priority,
144
188
  status: 'backlog',
145
189
  type: options.type || 'feature',
@@ -427,63 +471,57 @@ export function sanitizeReasonText(text) {
427
471
  return sanitized.trim();
428
472
  }
429
473
  /**
430
- * Unblock a story from the blocked folder and move it back to the workflow
431
- * Determines destination folder based on workflow completion state
474
+ * Unblock a story and set status back to in-progress
475
+ * In the new architecture, this only updates frontmatter - file path remains unchanged
432
476
  *
433
477
  * @param storyId - Story ID to unblock
434
478
  * @param sdlcRoot - Root path of the .ai-sdlc folder
435
479
  * @param options - Optional configuration { resetRetries?: boolean }
436
- * @returns The unblocked and moved story
480
+ * @returns The unblocked story
437
481
  */
438
482
  export function unblockStory(storyId, sdlcRoot, options) {
439
- const blockedFolder = path.join(sdlcRoot, BLOCKED_DIR);
440
- // Find story in blocked folder
441
- if (!fs.existsSync(blockedFolder)) {
442
- throw new Error(`Story ${storyId} not found in blocked folder`);
443
- }
444
- const blockedFiles = fs.readdirSync(blockedFolder).filter(f => f.endsWith('.md'));
483
+ // In new architecture, try direct path lookup first
484
+ const storyPath = path.join(sdlcRoot, STORIES_FOLDER, storyId, STORY_FILENAME);
445
485
  let foundStory = null;
446
- let foundPath = null;
447
- for (const file of blockedFiles) {
448
- const filePath = path.join(blockedFolder, file);
449
- const story = parseStory(filePath);
450
- if (story.frontmatter.id === storyId) {
451
- foundStory = story;
452
- foundPath = filePath;
453
- break;
486
+ if (fs.existsSync(storyPath)) {
487
+ // Found in new structure
488
+ foundStory = parseStory(storyPath);
489
+ }
490
+ else {
491
+ // Fallback: search for story in old blocked folder (backwards compatibility)
492
+ const blockedFolder = path.join(sdlcRoot, BLOCKED_DIR);
493
+ if (fs.existsSync(blockedFolder)) {
494
+ const blockedFiles = fs.readdirSync(blockedFolder).filter(f => f.endsWith('.md'));
495
+ for (const file of blockedFiles) {
496
+ const filePath = path.join(blockedFolder, file);
497
+ const story = parseStory(filePath);
498
+ if (story.frontmatter.id === storyId) {
499
+ foundStory = story;
500
+ break;
501
+ }
502
+ }
454
503
  }
455
504
  }
456
505
  if (!foundStory) {
457
- throw new Error(`Story ${storyId} not found in blocked folder`);
506
+ throw new Error(`Story ${storyId} not found`);
507
+ }
508
+ // Verify story is actually blocked
509
+ if (foundStory.frontmatter.status !== 'blocked') {
510
+ throw new Error(`Story ${storyId} is not blocked (current status: ${foundStory.frontmatter.status})`);
458
511
  }
459
512
  // Clear blocking fields
460
513
  delete foundStory.frontmatter.blocked_reason;
461
514
  delete foundStory.frontmatter.blocked_at;
462
- // Determine destination folder based on workflow state
463
- let destinationFolder;
464
- if (foundStory.frontmatter.implementation_complete) {
465
- // If implementation is complete, move to in-progress for review
466
- destinationFolder = 'in-progress';
467
- }
468
- else if (foundStory.frontmatter.plan_complete || foundStory.frontmatter.research_complete) {
469
- // If plan or research is complete, move to ready for next phase
470
- destinationFolder = 'ready';
471
- }
472
- else {
473
- // Otherwise, return to backlog
474
- destinationFolder = 'backlog';
475
- }
476
515
  // Reset retries if requested
477
516
  if (options?.resetRetries) {
478
517
  foundStory.frontmatter.retry_count = 0;
479
518
  foundStory.frontmatter.refinement_count = 0;
480
519
  }
481
- // Move story to destination folder
482
- const movedStory = moveStory(foundStory, destinationFolder, sdlcRoot);
483
- // Clean up the old blocked file if it still exists (in case of collision handling)
484
- if (fs.existsSync(foundPath) && foundPath !== movedStory.path) {
485
- fs.unlinkSync(foundPath);
486
- }
487
- return movedStory;
520
+ // Update status to in-progress (no file moves in new architecture)
521
+ foundStory.frontmatter.status = 'in-progress';
522
+ foundStory.frontmatter.updated = new Date().toISOString().split('T')[0];
523
+ // Write back to same location
524
+ writeStory(foundStory);
525
+ return foundStory;
488
526
  }
489
527
  //# sourceMappingURL=story.js.map