edsger 0.51.0 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.claude/settings.local.json +23 -3
  2. package/.env.local +12 -0
  3. package/dist/commands/find-smells/index.d.ts +21 -0
  4. package/dist/commands/find-smells/index.js +65 -0
  5. package/dist/index.js +29 -0
  6. package/dist/phases/find-bugs/index.js +7 -92
  7. package/dist/phases/find-bugs/state.d.ts +10 -35
  8. package/dist/phases/find-bugs/state.js +12 -120
  9. package/dist/phases/find-features/index.js +16 -83
  10. package/dist/phases/find-features/prompts.d.ts +7 -1
  11. package/dist/phases/find-features/prompts.js +31 -11
  12. package/dist/phases/find-features/state.d.ts +15 -19
  13. package/dist/phases/find-features/state.js +17 -89
  14. package/dist/phases/find-features/types.d.ts +1 -1
  15. package/dist/phases/find-shared/git.d.ts +24 -0
  16. package/dist/phases/find-shared/git.js +60 -0
  17. package/dist/phases/find-shared/mcp.d.ts +33 -0
  18. package/dist/phases/find-shared/mcp.js +69 -0
  19. package/dist/phases/find-shared/scan-state.d.ts +33 -0
  20. package/dist/phases/find-shared/scan-state.js +112 -0
  21. package/dist/phases/find-smells/index.d.ts +47 -0
  22. package/dist/phases/find-smells/index.js +278 -0
  23. package/dist/phases/find-smells/prompts.d.ts +30 -0
  24. package/dist/phases/find-smells/prompts.js +129 -0
  25. package/dist/phases/find-smells/state.d.ts +21 -0
  26. package/dist/phases/find-smells/state.js +17 -0
  27. package/dist/phases/find-smells/types.d.ts +51 -0
  28. package/dist/phases/find-smells/types.js +64 -0
  29. package/dist/phases/pr-execution/context.js +40 -32
  30. package/dist/phases/pr-splitting/context.js +18 -13
  31. package/dist/utils/github-repo-info.d.ts +13 -1
  32. package/dist/utils/github-repo-info.js +32 -6
  33. package/package.json +1 -1
  34. package/vitest.config.ts +2 -0
  35. package/dist/api/__tests__/app-store.test.d.ts +0 -7
  36. package/dist/api/__tests__/app-store.test.js +0 -60
  37. package/dist/api/__tests__/intelligence.test.d.ts +0 -11
  38. package/dist/api/__tests__/intelligence.test.js +0 -315
  39. package/dist/api/features/__tests__/feature-utils.test.d.ts +0 -4
  40. package/dist/api/features/__tests__/feature-utils.test.js +0 -370
  41. package/dist/api/features/__tests__/status-updater.test.d.ts +0 -4
  42. package/dist/api/features/__tests__/status-updater.test.js +0 -88
  43. package/dist/api/features/approval-checker.d.ts +0 -20
  44. package/dist/api/features/approval-checker.js +0 -152
  45. package/dist/api/features/batch-operations.d.ts +0 -17
  46. package/dist/api/features/batch-operations.js +0 -100
  47. package/dist/api/features/feature-utils.d.ts +0 -23
  48. package/dist/api/features/feature-utils.js +0 -80
  49. package/dist/api/features/get-feature.d.ts +0 -5
  50. package/dist/api/features/get-feature.js +0 -21
  51. package/dist/api/features/index.d.ts +0 -8
  52. package/dist/api/features/index.js +0 -10
  53. package/dist/api/features/status-updater.d.ts +0 -41
  54. package/dist/api/features/status-updater.js +0 -122
  55. package/dist/api/features/test-cases.d.ts +0 -29
  56. package/dist/api/features/test-cases.js +0 -110
  57. package/dist/api/features/update-feature.d.ts +0 -20
  58. package/dist/api/features/update-feature.js +0 -83
  59. package/dist/api/features/user-stories.d.ts +0 -21
  60. package/dist/api/features/user-stories.js +0 -88
  61. package/dist/commands/agent-workflow/feature-worker.d.ts +0 -14
  62. package/dist/commands/agent-workflow/feature-worker.js +0 -65
  63. package/dist/commands/build/__tests__/build.test.d.ts +0 -5
  64. package/dist/commands/build/__tests__/build.test.js +0 -206
  65. package/dist/commands/build/__tests__/detect-project.test.d.ts +0 -6
  66. package/dist/commands/build/__tests__/detect-project.test.js +0 -160
  67. package/dist/commands/build/__tests__/run-build.test.d.ts +0 -6
  68. package/dist/commands/build/__tests__/run-build.test.js +0 -433
  69. package/dist/commands/intelligence/__tests__/command.test.d.ts +0 -4
  70. package/dist/commands/intelligence/__tests__/command.test.js +0 -48
  71. package/dist/commands/workflow/core/__tests__/feature-filter.test.d.ts +0 -5
  72. package/dist/commands/workflow/core/__tests__/feature-filter.test.js +0 -316
  73. package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.d.ts +0 -4
  74. package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.js +0 -397
  75. package/dist/commands/workflow/core/__tests__/state-manager.test.d.ts +0 -4
  76. package/dist/commands/workflow/core/__tests__/state-manager.test.js +0 -384
  77. package/dist/commands/workflow/core/feature-filter.d.ts +0 -16
  78. package/dist/commands/workflow/core/feature-filter.js +0 -47
  79. package/dist/commands/workflow/feature-coordinator.d.ts +0 -18
  80. package/dist/commands/workflow/feature-coordinator.js +0 -161
  81. package/dist/config/__tests__/config.test.d.ts +0 -4
  82. package/dist/config/__tests__/config.test.js +0 -286
  83. package/dist/config/__tests__/feature-status.test.d.ts +0 -4
  84. package/dist/config/__tests__/feature-status.test.js +0 -111
  85. package/dist/config/feature-status.d.ts +0 -56
  86. package/dist/config/feature-status.js +0 -130
  87. package/dist/errors/__tests__/index.test.d.ts +0 -4
  88. package/dist/errors/__tests__/index.test.js +0 -349
  89. package/dist/phases/app-store-generation/__tests__/agent.test.d.ts +0 -5
  90. package/dist/phases/app-store-generation/__tests__/agent.test.js +0 -142
  91. package/dist/phases/app-store-generation/__tests__/context.test.d.ts +0 -4
  92. package/dist/phases/app-store-generation/__tests__/context.test.js +0 -284
  93. package/dist/phases/app-store-generation/__tests__/prompts.test.d.ts +0 -4
  94. package/dist/phases/app-store-generation/__tests__/prompts.test.js +0 -122
  95. package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.d.ts +0 -5
  96. package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.js +0 -826
  97. package/dist/phases/code-review/__tests__/diff-utils.test.d.ts +0 -1
  98. package/dist/phases/code-review/__tests__/diff-utils.test.js +0 -101
  99. package/dist/phases/feature-analysis/agent.d.ts +0 -13
  100. package/dist/phases/feature-analysis/agent.js +0 -112
  101. package/dist/phases/feature-analysis/context.d.ts +0 -24
  102. package/dist/phases/feature-analysis/context.js +0 -138
  103. package/dist/phases/feature-analysis/index.d.ts +0 -8
  104. package/dist/phases/feature-analysis/index.js +0 -199
  105. package/dist/phases/feature-analysis/outcome.d.ts +0 -40
  106. package/dist/phases/feature-analysis/outcome.js +0 -280
  107. package/dist/phases/feature-analysis/prompts.d.ts +0 -10
  108. package/dist/phases/feature-analysis/prompts.js +0 -212
  109. package/dist/phases/feature-analysis-verification/agent.d.ts +0 -33
  110. package/dist/phases/feature-analysis-verification/agent.js +0 -124
  111. package/dist/phases/feature-analysis-verification/index.d.ts +0 -25
  112. package/dist/phases/feature-analysis-verification/index.js +0 -92
  113. package/dist/phases/feature-analysis-verification/prompts.d.ts +0 -10
  114. package/dist/phases/feature-analysis-verification/prompts.js +0 -100
  115. package/dist/phases/intelligence-analysis/__tests__/context.test.d.ts +0 -4
  116. package/dist/phases/intelligence-analysis/__tests__/context.test.js +0 -192
  117. package/dist/phases/intelligence-analysis/__tests__/matching.test.d.ts +0 -13
  118. package/dist/phases/intelligence-analysis/__tests__/matching.test.js +0 -154
  119. package/dist/phases/intelligence-analysis/__tests__/orchestration.test.d.ts +0 -5
  120. package/dist/phases/intelligence-analysis/__tests__/orchestration.test.js +0 -378
  121. package/dist/phases/intelligence-analysis/__tests__/prompts.test.d.ts +0 -4
  122. package/dist/phases/intelligence-analysis/__tests__/prompts.test.js +0 -33
  123. package/dist/phases/pr-execution/__tests__/file-assigner.test.d.ts +0 -1
  124. package/dist/phases/pr-execution/__tests__/file-assigner.test.js +0 -303
  125. package/dist/phases/pr-resolve/__tests__/checklist-learner.test.d.ts +0 -1
  126. package/dist/phases/pr-resolve/__tests__/checklist-learner.test.js +0 -157
  127. package/dist/phases/pr-resolve/__tests__/prompts.test.d.ts +0 -1
  128. package/dist/phases/pr-resolve/__tests__/prompts.test.js +0 -116
  129. package/dist/phases/pr-resolve/__tests__/resolve-mapping.test.d.ts +0 -1
  130. package/dist/phases/pr-resolve/__tests__/resolve-mapping.test.js +0 -138
  131. package/dist/phases/pr-resolve/__tests__/types.test.d.ts +0 -1
  132. package/dist/phases/pr-resolve/__tests__/types.test.js +0 -43
  133. package/dist/phases/pr-resolve/__tests__/workspace.test.d.ts +0 -1
  134. package/dist/phases/pr-resolve/__tests__/workspace.test.js +0 -111
  135. package/dist/phases/pr-review/__tests__/prompts.test.d.ts +0 -1
  136. package/dist/phases/pr-review/__tests__/prompts.test.js +0 -49
  137. package/dist/phases/pr-review/__tests__/review-comments.test.d.ts +0 -1
  138. package/dist/phases/pr-review/__tests__/review-comments.test.js +0 -110
  139. package/dist/phases/pr-shared/__tests__/agent-utils.test.d.ts +0 -1
  140. package/dist/phases/pr-shared/__tests__/agent-utils.test.js +0 -91
  141. package/dist/phases/pr-shared/__tests__/context.test.d.ts +0 -1
  142. package/dist/phases/pr-shared/__tests__/context.test.js +0 -94
  143. package/dist/phases/pr-splitting/__tests__/import-dep-validator.test.d.ts +0 -1
  144. package/dist/phases/pr-splitting/__tests__/import-dep-validator.test.js +0 -331
  145. package/dist/phases/run-sheet/render.d.ts +0 -60
  146. package/dist/phases/run-sheet/render.js +0 -297
  147. package/dist/phases/smoke-test/__tests__/agent.test.d.ts +0 -4
  148. package/dist/phases/smoke-test/__tests__/agent.test.js +0 -84
  149. package/dist/phases/smoke-test/__tests__/github.test.d.ts +0 -9
  150. package/dist/phases/smoke-test/__tests__/github.test.js +0 -120
  151. package/dist/phases/smoke-test/__tests__/snapshot.test.d.ts +0 -8
  152. package/dist/phases/smoke-test/__tests__/snapshot.test.js +0 -93
  153. package/dist/phases/smoke-test/github.d.ts +0 -54
  154. package/dist/phases/smoke-test/github.js +0 -101
  155. package/dist/phases/smoke-test/snapshot.d.ts +0 -27
  156. package/dist/phases/smoke-test/snapshot.js +0 -157
  157. package/dist/services/coaching/__tests__/coaching-agent.test.d.ts +0 -1
  158. package/dist/services/coaching/__tests__/coaching-agent.test.js +0 -74
  159. package/dist/services/coaching/__tests__/coaching-loop.test.d.ts +0 -1
  160. package/dist/services/coaching/__tests__/coaching-loop.test.js +0 -59
  161. package/dist/services/coaching/__tests__/self-rating.test.d.ts +0 -1
  162. package/dist/services/coaching/__tests__/self-rating.test.js +0 -188
  163. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.d.ts +0 -4
  164. package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.js +0 -133
  165. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.d.ts +0 -4
  166. package/dist/services/lifecycle-agent/__tests__/transition-rules.test.js +0 -336
  167. package/dist/services/lifecycle-agent/index.d.ts +0 -24
  168. package/dist/services/lifecycle-agent/index.js +0 -25
  169. package/dist/services/lifecycle-agent/phase-criteria.d.ts +0 -57
  170. package/dist/services/lifecycle-agent/phase-criteria.js +0 -335
  171. package/dist/services/lifecycle-agent/transition-rules.d.ts +0 -60
  172. package/dist/services/lifecycle-agent/transition-rules.js +0 -184
  173. package/dist/services/lifecycle-agent/types.d.ts +0 -190
  174. package/dist/services/lifecycle-agent/types.js +0 -12
  175. package/dist/services/phase-hooks/__tests__/bindings-fetcher.test.d.ts +0 -1
  176. package/dist/services/phase-hooks/__tests__/bindings-fetcher.test.js +0 -122
  177. package/dist/services/phase-hooks/__tests__/hook-executor.test.d.ts +0 -1
  178. package/dist/services/phase-hooks/__tests__/hook-executor.test.js +0 -321
  179. package/dist/services/phase-hooks/__tests__/hook-runner.test.d.ts +0 -1
  180. package/dist/services/phase-hooks/__tests__/hook-runner.test.js +0 -261
  181. package/dist/services/phase-hooks/__tests__/plugin-loader.test.d.ts +0 -1
  182. package/dist/services/phase-hooks/__tests__/plugin-loader.test.js +0 -158
  183. package/dist/services/video/__tests__/video-pipeline.test.d.ts +0 -6
  184. package/dist/services/video/__tests__/video-pipeline.test.js +0 -249
  185. package/dist/types/features.d.ts +0 -35
  186. package/dist/types/features.js +0 -1
  187. package/dist/workspace/__tests__/workspace-manager.test.d.ts +0 -7
  188. package/dist/workspace/__tests__/workspace-manager.test.js +0 -52
@@ -1,280 +0,0 @@
1
- import { batchDeleteTestCases, batchDeleteUserStories, batchUpdateTestCaseStatus, batchUpdateUserStoryStatus, getTestCases, getUserStories, } from '../../api/features/index.js';
2
- import { callMcpEndpoint } from '../../api/mcp-client.js';
3
- import { logError, logInfo } from '../../utils/logger.js';
4
- /**
5
- * Reset ready user stories and test cases to draft for re-analysis
6
- */
7
- export async function resetReadyArtifactsToDraft(featureId, verbose) {
8
- const [stories, testCases] = await Promise.all([
9
- getUserStories(featureId, false),
10
- getTestCases(featureId, false),
11
- ]);
12
- const readyStoryIds = stories
13
- .filter((s) => s.status === 'pending_approval')
14
- .map((s) => s.id);
15
- const readyTestCaseIds = testCases
16
- .filter((tc) => tc.status === 'pending_approval')
17
- .map((tc) => tc.id);
18
- if (readyStoryIds.length > 0) {
19
- if (verbose) {
20
- logInfo(`šŸ”„ Resetting ${readyStoryIds.length} ready user stories to draft for re-analysis...`);
21
- }
22
- await batchUpdateUserStoryStatus(readyStoryIds, 'draft', verbose);
23
- }
24
- if (readyTestCaseIds.length > 0) {
25
- if (verbose) {
26
- logInfo(`šŸ”„ Resetting ${readyTestCaseIds.length} ready test cases to draft for re-analysis...`);
27
- }
28
- await batchUpdateTestCaseStatus(readyTestCaseIds, 'draft', verbose);
29
- }
30
- return {
31
- resetUserStories: readyStoryIds.length,
32
- resetTestCases: readyTestCaseIds.length,
33
- };
34
- }
35
- /**
36
- * Get all draft artifact IDs for a feature
37
- */
38
- export async function getAllDraftArtifactIds(featureId, verbose) {
39
- const [stories, testCases] = await Promise.all([
40
- getUserStories(featureId, false),
41
- getTestCases(featureId, false),
42
- ]);
43
- const userStoryIds = stories
44
- .filter((s) => s.status === 'draft')
45
- .map((s) => s.id);
46
- const testCaseIds = testCases
47
- .filter((tc) => tc.status === 'draft')
48
- .map((tc) => tc.id);
49
- if (verbose) {
50
- logInfo(`Found ${userStoryIds.length} draft user stories and ${testCaseIds.length} draft test cases`);
51
- }
52
- return { userStoryIds, testCaseIds };
53
- }
54
- /**
55
- * Delete artifacts after verification failure
56
- */
57
- export async function deleteArtifacts(userStoryIds, testCaseIds, verbose) {
58
- if (userStoryIds.length > 0) {
59
- if (verbose) {
60
- logInfo(`Deleting ${userStoryIds.length} user stories due to verification failure...`);
61
- }
62
- await batchDeleteUserStories(userStoryIds, verbose);
63
- }
64
- if (testCaseIds.length > 0) {
65
- if (verbose) {
66
- logInfo(`Deleting ${testCaseIds.length} test cases due to verification failure...`);
67
- }
68
- await batchDeleteTestCases(testCaseIds, verbose);
69
- }
70
- }
71
- /**
72
- * Validate UUID format
73
- */
74
- function isValidUUID(id) {
75
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
76
- return uuidRegex.test(id);
77
- }
78
- /**
79
- * Delete specific artifacts identified by AI during analysis
80
- * Only deletes artifacts with status 'draft'
81
- */
82
- export async function deleteSpecificArtifacts(featureId, deletedUserStoryIds, deletedTestCaseIds, deletionReasons, verbose) {
83
- // Fetch current artifacts to verify their status
84
- const [currentUserStories, currentTestCases] = await Promise.all([
85
- getUserStories(featureId, false),
86
- getTestCases(featureId, false),
87
- ]);
88
- // Create maps for quick lookup
89
- const userStoryStatusMap = new Map(currentUserStories.map((story) => [story.id, story.status]));
90
- const testCaseStatusMap = new Map(currentTestCases.map((testCase) => [testCase.id, testCase.status]));
91
- // Filter user story IDs: only valid UUIDs with draft status
92
- const validUserStoryIds = deletedUserStoryIds.filter((id) => {
93
- if (!isValidUUID(id)) {
94
- logError(`Invalid user story UUID format: ${id}`);
95
- return false;
96
- }
97
- const status = userStoryStatusMap.get(id);
98
- if (!status) {
99
- logError(`User story not found: ${id}`);
100
- return false;
101
- }
102
- if (status !== 'draft') {
103
- logError(`Cannot delete user story ${id}: status is '${status}', only 'draft' items can be deleted`);
104
- return false;
105
- }
106
- return true;
107
- });
108
- // Filter test case IDs: only valid UUIDs with draft status
109
- const validTestCaseIds = deletedTestCaseIds.filter((id) => {
110
- if (!isValidUUID(id)) {
111
- logError(`Invalid test case UUID format: ${id}`);
112
- return false;
113
- }
114
- const status = testCaseStatusMap.get(id);
115
- if (!status) {
116
- logError(`Test case not found: ${id}`);
117
- return false;
118
- }
119
- if (status !== 'draft') {
120
- logError(`Cannot delete test case ${id}: status is '${status}', only 'draft' items can be deleted`);
121
- return false;
122
- }
123
- return true;
124
- });
125
- if (validUserStoryIds.length > 0) {
126
- if (verbose) {
127
- logInfo(`Deleting ${validUserStoryIds.length} draft user stories identified by AI...`);
128
- validUserStoryIds.forEach((id) => {
129
- const reason = deletionReasons[id] || 'No reason provided';
130
- logInfo(` - ${id}: ${reason}`);
131
- });
132
- }
133
- await batchDeleteUserStories(validUserStoryIds, verbose);
134
- }
135
- if (validTestCaseIds.length > 0) {
136
- if (verbose) {
137
- logInfo(`Deleting ${validTestCaseIds.length} draft test cases identified by AI...`);
138
- validTestCaseIds.forEach((id) => {
139
- const reason = deletionReasons[id] || 'No reason provided';
140
- logInfo(` - ${id}: ${reason}`);
141
- });
142
- }
143
- await batchDeleteTestCases(validTestCaseIds, verbose);
144
- }
145
- }
146
- /**
147
- * Update artifacts to pending_approval status after successful verification
148
- */
149
- export async function updateArtifactsToReady(userStoryIds, testCaseIds, verbose) {
150
- if (userStoryIds.length > 0) {
151
- if (verbose) {
152
- logInfo(`Updating ${userStoryIds.length} user stories from draft to pending_approval...`);
153
- }
154
- await batchUpdateUserStoryStatus(userStoryIds, 'pending_approval', verbose);
155
- }
156
- if (testCaseIds.length > 0) {
157
- if (verbose) {
158
- logInfo(`Updating ${testCaseIds.length} test cases from draft to pending_approval...`);
159
- }
160
- await batchUpdateTestCaseStatus(testCaseIds, 'pending_approval', verbose);
161
- }
162
- }
163
- /**
164
- * Save analysis artifacts as draft and return their IDs
165
- */
166
- export async function saveAnalysisArtifactsAsDraft(featureId, createdUserStories, createdTestCases, verbose) {
167
- const userStoryIds = [];
168
- const testCaseIds = [];
169
- // Save user stories as draft
170
- if (createdUserStories && createdUserStories.length > 0) {
171
- if (verbose) {
172
- logInfo(`Saving ${createdUserStories.length} user stories as draft...`);
173
- }
174
- try {
175
- const result = (await callMcpEndpoint('user_stories/create', {
176
- feature_id: featureId,
177
- user_stories: createdUserStories.map((story) => ({
178
- title: story.title,
179
- description: story.description,
180
- status: 'draft',
181
- })),
182
- }));
183
- if (result.created_user_stories) {
184
- userStoryIds.push(...result.created_user_stories.map((story) => story.id));
185
- if (verbose) {
186
- logInfo(`āœ… Saved ${userStoryIds.length} user stories as draft`);
187
- }
188
- }
189
- }
190
- catch (error) {
191
- logError(`Failed to save user stories: ${error instanceof Error ? error.message : String(error)}`);
192
- }
193
- }
194
- // Save test cases as draft
195
- if (createdTestCases && createdTestCases.length > 0) {
196
- if (verbose) {
197
- logInfo(`Saving ${createdTestCases.length} test cases as draft...`);
198
- }
199
- try {
200
- const result = (await callMcpEndpoint('test_cases/create', {
201
- feature_id: featureId,
202
- test_cases: createdTestCases.map((testCase) => ({
203
- name: testCase.name,
204
- description: testCase.description,
205
- is_critical: testCase.is_critical || false,
206
- status: 'draft',
207
- })),
208
- }));
209
- if (result.created_test_cases) {
210
- testCaseIds.push(...result.created_test_cases.map((testCase) => testCase.id));
211
- if (verbose) {
212
- logInfo(`āœ… Saved ${testCaseIds.length} test cases as draft`);
213
- }
214
- }
215
- }
216
- catch (error) {
217
- logError(`Failed to save test cases: ${error instanceof Error ? error.message : String(error)}`);
218
- }
219
- }
220
- return { userStoryIds, testCaseIds };
221
- }
222
- /**
223
- * Build the final analysis result object
224
- */
225
- export function buildAnalysisResult(featureId, context,
226
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
- structuredAnalysisResult, currentIteration) {
228
- const { created_user_stories, created_test_cases, deleted_user_story_ids, deleted_test_case_ids, deletion_reasons, checklist_results, checklist_item_results, } = structuredAnalysisResult;
229
- return {
230
- featureId,
231
- productInfo: context.product,
232
- featureInfo: context.feature,
233
- existingUserStories: context.existing_user_stories.map((story) => {
234
- const approvedOrDraft = story.status === 'approved' ? 'approved' : 'draft';
235
- return {
236
- ...story,
237
- status: story.status === 'pending_approval'
238
- ? 'pending_approval'
239
- : approvedOrDraft,
240
- created_at: story.created_at || new Date().toISOString(),
241
- updated_at: story.updated_at || new Date().toISOString(),
242
- };
243
- }),
244
- existingTestCases: context.existing_test_cases.map((testCase) => ({
245
- ...testCase,
246
- created_at: testCase.created_at || new Date().toISOString(),
247
- updated_at: testCase.updated_at || new Date().toISOString(),
248
- })),
249
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
- createdUserStories: (created_user_stories || []).map((story) => ({
251
- id: '',
252
- title: story.title,
253
- description: story.description,
254
- status: 'draft',
255
- created_at: new Date().toISOString(),
256
- updated_at: new Date().toISOString(),
257
- })),
258
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
- createdTestCases: (created_test_cases || []).map((testCase) => ({
260
- id: '',
261
- name: testCase.name,
262
- description: testCase.description,
263
- is_critical: testCase.is_critical || false,
264
- created_at: new Date().toISOString(),
265
- updated_at: new Date().toISOString(),
266
- })),
267
- summary: structuredAnalysisResult.summary ||
268
- `Analysis completed${currentIteration > 1 ? ` after ${currentIteration} iterations` : ''}`,
269
- status: structuredAnalysisResult.status === 'success' ? 'success' : 'error',
270
- data: {
271
- checklist_results,
272
- checklist_item_results,
273
- verification_result: structuredAnalysisResult.verification_result,
274
- iterations: currentIteration,
275
- deleted_user_story_ids: deleted_user_story_ids || [],
276
- deleted_test_case_ids: deleted_test_case_ids || [],
277
- deletion_reasons: deletion_reasons || {},
278
- },
279
- };
280
- }
@@ -1,10 +0,0 @@
1
- import { type ChecklistVerificationResult } from '../feature-analysis-verification/agent.js';
2
- export declare const createFeatureAnalysisSystemPrompt: (projectDir?: string) => Promise<string>;
3
- export declare const createFeatureAnalysisPromptWithContext: (featureId: string, contextInfo: string) => string;
4
- /**
5
- * Create a prompt for the analysis agent to improve based on verification feedback
6
- */
7
- export declare const createImprovementPrompt: (verificationResult: ChecklistVerificationResult, previousAnalysis: {
8
- created_user_stories: Record<string, unknown>[];
9
- created_test_cases: Record<string, unknown>[];
10
- }) => string;
@@ -1,212 +0,0 @@
1
- import { resolveSkill } from '../../services/skill-resolver.js';
2
- import { OUTPUT_CONTRACTS } from '../output-contracts.js';
3
- export const createFeatureAnalysisSystemPrompt = async (projectDir) => {
4
- const skill = await resolveSkill('phase/feature-analysis', { projectDir });
5
- if (!skill) {
6
- throw new Error('Failed to load skill: phase/feature-analysis');
7
- }
8
- return `${skill.prompt}\n\n${OUTPUT_CONTRACTS['feature-analysis']}`;
9
- };
10
- export const createFeatureAnalysisPromptWithContext = (featureId, contextInfo) => {
11
- return `Please conduct comprehensive business analysis for feature ID: ${featureId}
12
-
13
- ${contextInfo}
14
-
15
- ## Analysis Instructions
16
-
17
- Follow this systematic approach:
18
-
19
- 1. **Review Feature Context**: Analyze the feature information, product context, and technical design above
20
-
21
- 2. **Review Existing Items**: Study the existing user stories and test cases to understand:
22
- - What scenarios are already covered
23
- - What user perspectives are already addressed
24
- - Where gaps might exist
25
-
26
- 3. **Business Analysis**: Think about the feature from a business perspective:
27
- - Who are the different types of users?
28
- - What problems does this feature solve?
29
- - What are the different use cases and user workflows?
30
- - What edge cases and error scenarios might occur?
31
- - How does this integrate with other features?
32
-
33
- 4. **Create New User Stories**: Generate user stories that ADD VALUE by covering:
34
- - Different user types or personas not yet covered
35
- - New use cases or workflows
36
- - Edge cases or error scenarios
37
- - Different permission levels or access patterns
38
- - Integration scenarios
39
-
40
- 5. **Design Test Cases**: Create test cases that ensure comprehensive coverage:
41
- - Happy path scenarios
42
- - Edge cases and boundary conditions
43
- - Error handling and validation
44
- - Security and permission testing
45
- - Performance and usability aspects
46
- - Integration testing scenarios
47
-
48
- 6. **Provide Results**: Output your analysis in the required JSON format
49
-
50
- ## Important Notes
51
- - Focus on creating NEW user stories and test cases that add business value
52
- - Avoid duplicating existing user stories and test cases
53
- - Consider different user types (admin, regular user, guest, etc.)
54
- - Think about accessibility, security, and performance implications
55
- - The feature should already have some design - you're analyzing business requirements
56
- - Be thorough but focus on practical, testable scenarios
57
-
58
- Begin your systematic analysis based on the above context.`;
59
- };
60
- /**
61
- * Create a prompt for the analysis agent to improve based on verification feedback
62
- */
63
- export const createImprovementPrompt = (verificationResult, previousAnalysis) => {
64
- // Format rejected items with specific feedback and improvement suggestions
65
- const rejectedItemsSection = verificationResult.item_verifications
66
- .filter((v) => v.verification_status === 'rejected')
67
- .map((v, index) => {
68
- return `### Rejected Requirement ${index + 1}
69
- **Checklist Item ID**: ${v.checklist_item_id}
70
- **Satisfaction Status**: ${v.is_satisfied ? 'āœ… Satisfied' : 'āŒ Not Satisfied'}
71
- **Verification Result**: āŒ REJECTED
72
- **Reason**: ${v.verification_reason}
73
- ${v.concerns && v.concerns.length > 0 ? `**Specific Concerns**:\n${v.concerns.map((c) => `- ${c}`).join('\n')}` : ''}
74
- ${v.improvement_suggestions && v.improvement_suggestions.length > 0 ? `\n**šŸ’” Improvement Suggestions**:\n${v.improvement_suggestions.map((s) => `- ${s}`).join('\n')}` : ''}
75
- `;
76
- })
77
- .join('\n---\n');
78
- // Format uncertain items with improvement suggestions
79
- const uncertainItemsSection = verificationResult.item_verifications
80
- .filter((v) => v.verification_status === 'uncertain')
81
- .map((v, index) => {
82
- return `### Uncertain Requirement ${index + 1}
83
- **Checklist Item ID**: ${v.checklist_item_id}
84
- **Satisfaction Status**: ${v.is_satisfied ? 'āœ… Satisfied' : 'āš ļø Partially Satisfied'}
85
- **Verification Result**: āš ļø UNCERTAIN
86
- **Reason**: ${v.verification_reason}
87
- ${v.concerns && v.concerns.length > 0 ? `**Specific Concerns**:\n${v.concerns.map((c) => `- ${c}`).join('\n')}` : ''}
88
- ${v.improvement_suggestions && v.improvement_suggestions.length > 0 ? `\n**šŸ’” Improvement Suggestions**:\n${v.improvement_suggestions.map((s) => `- ${s}`).join('\n')}` : ''}
89
- `;
90
- })
91
- .join('\n---\n');
92
- return `# Verification Feedback - Improvements Required
93
-
94
- Your previous analysis was verified, and **${verificationResult.rejected_count} checklist requirements were NOT SATISFIED** and **${verificationResult.uncertain_count} requirements are PARTIALLY SATISFIED**.
95
-
96
- ## Verification Summary
97
- ${verificationResult.summary}
98
-
99
- ## Results Breakdown
100
- - āœ… Satisfied: ${verificationResult.confirmed_count}
101
- - āŒ Not Satisfied: ${verificationResult.rejected_count}
102
- - āš ļø Partially Satisfied: ${verificationResult.uncertain_count}
103
-
104
- ${verificationResult.overall_suggestions && verificationResult.overall_suggestions.length > 0 ? `## šŸ’” Overall Improvement Suggestions\n\n${verificationResult.overall_suggestions.map((s) => `- ${s}`).join('\n')}\n\n` : ''}
105
-
106
- ${verificationResult.rejected_count > 0 ? `## āŒ Unsatisfied Requirements\n\n${rejectedItemsSection}` : ''}
107
-
108
- ${verificationResult.uncertain_count > 0 ? `## āš ļø Partially Satisfied Requirements\n\n${uncertainItemsSection}` : ''}
109
-
110
- ## Your Previous Work
111
-
112
- ### User Stories You Created (${previousAnalysis.created_user_stories.length})
113
- ${previousAnalysis.created_user_stories
114
- .map((story, index) => `${index + 1}. **${story.title}**
115
- ${story.description}
116
- Status: ${story.status || 'draft'}`)
117
- .join('\n\n')}
118
-
119
- ### Test Cases You Created (${previousAnalysis.created_test_cases.length})
120
- ${previousAnalysis.created_test_cases
121
- .map((tc, index) => `${index + 1}. **${tc.name}** ${tc.is_critical ? '[CRITICAL]' : '[OPTIONAL]'}
122
- ${tc.description}`)
123
- .join('\n\n')}
124
-
125
- ---
126
-
127
- ## Your Task: Improve Your Artifacts
128
-
129
- You need to **revise and improve** your user stories and test cases to satisfy the checklist requirements.
130
-
131
- **What You Should Do**:
132
-
133
- 1. **Review the improvement suggestions** provided above for each rejected/uncertain requirement
134
- 2. **Follow the specific, actionable suggestions** - they tell you exactly what to add or modify
135
- 3. **Add NEW user stories and test cases** as suggested by the verifier
136
- 4. **DELETE user stories or test cases** that are duplicates, no longer relevant, or conflict with requirements
137
- 5. **Improve the quality and specificity** of your artifacts
138
- 6. **Ensure each requirement is adequately covered** based on the feedback
139
-
140
- **IMPORTANT Guidelines**:
141
- - **Pay close attention to the šŸ’” Improvement Suggestions** - these are specific actions you should take
142
- - You can **keep your existing user stories and test cases** that are good
143
- - **Add NEW items** exactly as suggested to satisfy the unsatisfied requirements
144
- - **DELETE items** that are duplicates, no longer relevant, or don't add value
145
- - **Make your artifacts concrete and specific** - they will be verified again
146
- - The suggestions are your roadmap - follow them to ensure verification passes
147
- - Ensure your artifacts directly address the checklist requirements
148
-
149
- **CRITICAL - Output Format**:
150
- You MUST return ONLY the JSON object below. Do NOT include any explanatory text, commentary, or markdown before or after the JSON. Return ONLY the JSON in this exact format:
151
-
152
- \`\`\`json
153
- {
154
- "analysis": {
155
- "feature_id": "...",
156
- "status": "success",
157
- "summary": "Improved analysis based on verification feedback",
158
- "created_user_stories": [
159
- {
160
- "title": "User story title",
161
- "description": "As a [user], I want [goal] so that [benefit]",
162
- "status": "draft",
163
- "differentiation": "REQUIRED: Explain how this differs from existing user stories",
164
- "invest_compliance": {
165
- "independent": "How this story can be developed independently",
166
- "negotiable": "What aspects are open for discussion",
167
- "valuable": "The specific business value delivered",
168
- "estimable": "Why this story is clear enough to estimate",
169
- "small": "Confirmation this fits within a sprint",
170
- "testable": "How this story can be verified/tested"
171
- }
172
- }
173
- ],
174
- "created_test_cases": [
175
- {
176
- "name": "Test case name",
177
- "description": "Detailed test case description",
178
- "is_critical": true,
179
- "differentiation": "REQUIRED: Explain how this differs from existing test cases"
180
- }
181
- ],
182
- "deleted_user_story_ids": [
183
- // UUIDs of user stories to delete
184
- ],
185
- "deleted_test_case_ids": [
186
- // UUIDs of test cases to delete
187
- ],
188
- "deletion_reasons": {
189
- // UUID -> reason mapping for all deletions
190
- },
191
- "checklist_item_results": [
192
- {
193
- "checklist_item_id": "EXACT_CHECKLIST_ITEM_UUID_FROM_ID_FIELD",
194
- "is_passed": true,
195
- "value": "Result value based on item type (boolean, text, number, etc.)",
196
- "notes": "Optional notes about this specific checklist item"
197
- }
198
- ],
199
- "recommendations": "..."
200
- }
201
- }
202
- \`\`\`
203
-
204
- **CRITICAL - Differentiation Requirement**:
205
- - The "differentiation" field is MANDATORY for every user story and test case
206
- - You MUST explain WHY each item is NOT a duplicate of existing items
207
- - If you cannot clearly articulate the difference, DO NOT include the item
208
-
209
- MANDATORY: You MUST include checklist_item_results for ALL checklist items in your response. Every checklist item ID must be addressed - either passed or with explanation in notes why it cannot be satisfied. Missing any checklist item will cause the pipeline to fail again.
210
-
211
- IMPORTANT: Return ONLY the JSON above. Do not add any text explaining what you did or how you improved the analysis. The JSON should be the complete and only content of your response.`;
212
- };
@@ -1,33 +0,0 @@
1
- import { type ChecklistPhaseContext } from '../../services/checklist.js';
2
- import { type EdsgerConfig } from '../../types/index.js';
3
- import { type FeatureAnalysisContext } from '../feature-analysis/context.js';
4
- export interface ChecklistItemVerificationResult {
5
- checklist_item_id: string;
6
- is_satisfied: boolean;
7
- verification_status: 'confirmed' | 'rejected' | 'uncertain';
8
- verification_reason: string;
9
- concerns?: string[];
10
- improvement_suggestions?: string[];
11
- }
12
- export interface ChecklistVerificationResult {
13
- all_verified: boolean;
14
- total_items: number;
15
- confirmed_count: number;
16
- rejected_count: number;
17
- uncertain_count: number;
18
- item_verifications: ChecklistItemVerificationResult[];
19
- summary: string;
20
- overall_suggestions?: string[];
21
- }
22
- export interface VerifyChecklistOptions {
23
- checklistContext: ChecklistPhaseContext;
24
- analysisContext: FeatureAnalysisContext;
25
- createdUserStories: any[];
26
- createdTestCases: any[];
27
- verbose?: boolean;
28
- }
29
- /**
30
- * Verify checklist compliance using an independent AI agent
31
- * This agent acts as a "challenger" to validate the claims made by the analysis agent
32
- */
33
- export declare function verifyChecklistCompliance(options: VerifyChecklistOptions, _config: EdsgerConfig): Promise<ChecklistVerificationResult>;
@@ -1,124 +0,0 @@
1
- /**
2
- * Checklist verification agent for feature analysis
3
- * This agent independently reviews checklist compliance to ensure objectivity
4
- */
5
- import { query } from '@anthropic-ai/claude-agent-sdk';
6
- import { DEFAULT_MODEL } from '../../constants.js';
7
- import { logDebug, logError, logInfo } from '../../utils/logger.js';
8
- import { createChecklistVerificationPrompt, createChecklistVerificationSystemPrompt, } from './prompts.js';
9
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- function extractTextFromContent(content, verbose) {
11
- let text = '';
12
- for (const item of content) {
13
- if (item.type === 'text') {
14
- text += `${item.text}\n`;
15
- logDebug(`šŸ” ${item.text}`, verbose);
16
- }
17
- }
18
- return text;
19
- }
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
- function parseVerificationJson(responseText) {
22
- try {
23
- const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- const jsonResult = jsonBlockMatch
26
- ? JSON.parse(jsonBlockMatch[1])
27
- : JSON.parse(responseText);
28
- if (jsonResult && jsonResult.verification) {
29
- return jsonResult.verification;
30
- }
31
- throw new Error('Invalid verification JSON structure');
32
- }
33
- catch (error) {
34
- logError(`Failed to parse verification result: ${error}`);
35
- return null;
36
- }
37
- }
38
- function userMessage(content) {
39
- return {
40
- type: 'user',
41
- message: { role: 'user', content },
42
- };
43
- }
44
- // eslint-disable-next-line @typescript-eslint/require-await -- async generator required by SDK interface
45
- async function* prompt(verificationPrompt) {
46
- yield userMessage(verificationPrompt);
47
- }
48
- /**
49
- * Verify checklist compliance using an independent AI agent
50
- * This agent acts as a "challenger" to validate the claims made by the analysis agent
51
- */
52
- export async function verifyChecklistCompliance(options, _config) {
53
- const { checklistContext, analysisContext, createdUserStories, createdTestCases, verbose, } = options;
54
- const totalChecklistItems = checklistContext.checklists.reduce((sum, checklist) => sum + checklist.items.length, 0);
55
- if (verbose) {
56
- logInfo('šŸ” Starting checklist verification...');
57
- logInfo(` Verifying ${totalChecklistItems} checklist items`);
58
- }
59
- const systemPrompt = await createChecklistVerificationSystemPrompt();
60
- const verificationPrompt = createChecklistVerificationPrompt({
61
- checklistContext,
62
- analysisContext,
63
- createdUserStories,
64
- createdTestCases,
65
- });
66
- let lastAssistantResponse = '';
67
- let verificationResult = null;
68
- if (verbose) {
69
- logInfo('šŸ¤– Starting verification agent query...');
70
- }
71
- // Use Claude Code SDK for verification
72
- for await (const message of query({
73
- prompt: prompt(verificationPrompt),
74
- options: {
75
- systemPrompt: {
76
- type: 'preset',
77
- preset: 'claude_code',
78
- append: systemPrompt,
79
- },
80
- model: DEFAULT_MODEL,
81
- maxTurns: 100,
82
- permissionMode: 'bypassPermissions',
83
- },
84
- })) {
85
- if (verbose) {
86
- logInfo(` Received message type: ${message.type}`);
87
- }
88
- // Capture assistant responses
89
- if (message.type === 'assistant' && message.message?.content) {
90
- lastAssistantResponse += extractTextFromContent(message.message.content, verbose);
91
- }
92
- if (message.type !== 'result') {
93
- continue;
94
- }
95
- if (message.subtype === 'success') {
96
- logInfo('\nāœ… Verification completed, parsing results...');
97
- verificationResult = parseVerificationJson(message.result || lastAssistantResponse);
98
- }
99
- else {
100
- logError(`\nāš ļø Verification incomplete: ${message.subtype}`);
101
- }
102
- }
103
- if (!verificationResult) {
104
- throw new Error('No verification result received');
105
- }
106
- if (verbose) {
107
- logInfo('\nšŸ“Š Verification Summary:');
108
- logInfo(` Total items: ${verificationResult.total_items}`);
109
- logInfo(` āœ… Confirmed: ${verificationResult.confirmed_count}`);
110
- logInfo(` āŒ Rejected: ${verificationResult.rejected_count}`);
111
- logInfo(` āš ļø Uncertain: ${verificationResult.uncertain_count}`);
112
- logInfo(` Summary: ${verificationResult.summary}`);
113
- if (verificationResult.rejected_count > 0) {
114
- logInfo('\nāŒ Rejected items:');
115
- verificationResult.item_verifications
116
- .filter((v) => v.verification_status === 'rejected')
117
- .forEach((v) => {
118
- logInfo(` - ${v.checklist_item_id}`);
119
- logInfo(` Reason: ${v.verification_reason}`);
120
- });
121
- }
122
- }
123
- return verificationResult;
124
- }