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,100 +0,0 @@
1
- import { logError, logInfo } from '../../utils/logger.js';
2
- import { callMcpEndpoint } from '../mcp-client.js';
3
- /**
4
- * Batch update user story statuses
5
- */
6
- export async function batchUpdateUserStoryStatus(userStoryIds, status, verbose) {
7
- try {
8
- if (verbose) {
9
- logInfo(`Batch updating ${userStoryIds.length} user stories to status: ${status}`);
10
- }
11
- for (const id of userStoryIds) {
12
- await callMcpEndpoint('user_stories/update_status', {
13
- user_story_id: id,
14
- status,
15
- });
16
- }
17
- if (verbose) {
18
- logInfo('✅ Batch user story status update completed');
19
- }
20
- return true;
21
- }
22
- catch (error) {
23
- const errorMessage = error instanceof Error ? error.message : String(error);
24
- logError(`Failed to batch update user story statuses: ${errorMessage}`);
25
- return false;
26
- }
27
- }
28
- /**
29
- * Batch update test case statuses
30
- */
31
- export async function batchUpdateTestCaseStatus(testCaseIds, status, verbose) {
32
- try {
33
- if (verbose) {
34
- logInfo(`Batch updating ${testCaseIds.length} test cases to status: ${status}`);
35
- }
36
- for (const id of testCaseIds) {
37
- await callMcpEndpoint('test_cases/update_status', {
38
- test_case_id: id,
39
- status,
40
- });
41
- }
42
- if (verbose) {
43
- logInfo('✅ Batch test case status update completed');
44
- }
45
- return true;
46
- }
47
- catch (error) {
48
- const errorMessage = error instanceof Error ? error.message : String(error);
49
- logError(`Failed to batch update test case statuses: ${errorMessage}`);
50
- return false;
51
- }
52
- }
53
- /**
54
- * Batch delete user stories
55
- */
56
- export async function batchDeleteUserStories(userStoryIds, verbose) {
57
- try {
58
- if (verbose) {
59
- logInfo(`Batch deleting ${userStoryIds.length} user stories`);
60
- }
61
- for (const id of userStoryIds) {
62
- await callMcpEndpoint('user_stories/delete', {
63
- user_story_id: id,
64
- });
65
- }
66
- if (verbose) {
67
- logInfo('✅ Batch user story deletion completed');
68
- }
69
- return true;
70
- }
71
- catch (error) {
72
- const errorMessage = error instanceof Error ? error.message : String(error);
73
- logError(`Failed to batch delete user stories: ${errorMessage}`);
74
- return false;
75
- }
76
- }
77
- /**
78
- * Batch delete test cases
79
- */
80
- export async function batchDeleteTestCases(testCaseIds, verbose) {
81
- try {
82
- if (verbose) {
83
- logInfo(`Batch deleting ${testCaseIds.length} test cases`);
84
- }
85
- for (const id of testCaseIds) {
86
- await callMcpEndpoint('test_cases/delete', {
87
- test_case_id: id,
88
- });
89
- }
90
- if (verbose) {
91
- logInfo('✅ Batch test case deletion completed');
92
- }
93
- return true;
94
- }
95
- catch (error) {
96
- const errorMessage = error instanceof Error ? error.message : String(error);
97
- logError(`Failed to batch delete test cases: ${errorMessage}`);
98
- return false;
99
- }
100
- }
@@ -1,23 +0,0 @@
1
- import { type FeatureInfo } from '../../types/features.js';
2
- /**
3
- * Claim the next available ready_for_ai feature for processing.
4
- * Uses database-level locking (FOR UPDATE SKIP LOCKED) to prevent
5
- * race conditions between multiple workers.
6
- *
7
- * @param productId - The product ID to claim a feature from
8
- * @param verbose - Whether to log verbose output
9
- * @returns The claimed feature or null if no features available
10
- */
11
- export declare function claimNextFeature(productId: string, verbose?: boolean): Promise<FeatureInfo | null>;
12
- /**
13
- * Filter features by status
14
- */
15
- export declare function filterFeaturesByStatus(features: FeatureInfo[], status: string): FeatureInfo[];
16
- /**
17
- * Sort features by updated_at (oldest first for processing)
18
- */
19
- export declare function sortFeaturesByUpdatedAt(features: FeatureInfo[]): FeatureInfo[];
20
- /**
21
- * Get features with ready_for_ai status for a product
22
- */
23
- export declare function getReadyForAIFeatures(productId: string, verbose?: boolean): Promise<FeatureInfo[]>;
@@ -1,80 +0,0 @@
1
- import { logError, logInfo } from '../../utils/logger.js';
2
- import { callMcpEndpoint } from '../mcp-client.js';
3
- /**
4
- * Claim the next available ready_for_ai feature for processing.
5
- * Uses database-level locking (FOR UPDATE SKIP LOCKED) to prevent
6
- * race conditions between multiple workers.
7
- *
8
- * @param productId - The product ID to claim a feature from
9
- * @param verbose - Whether to log verbose output
10
- * @returns The claimed feature or null if no features available
11
- */
12
- export async function claimNextFeature(productId, verbose) {
13
- if (verbose) {
14
- logInfo(`Attempting to claim next ready_for_ai feature for product: ${productId}`);
15
- }
16
- try {
17
- const result = (await callMcpEndpoint('features/claim', {
18
- product_id: productId,
19
- }));
20
- if (result.feature) {
21
- if (verbose) {
22
- logInfo(`✅ Claimed feature: ${result.feature.name} (${result.feature.id})`);
23
- }
24
- return result.feature;
25
- }
26
- if (verbose) {
27
- logInfo('No features available for processing');
28
- }
29
- return null;
30
- }
31
- catch (error) {
32
- const errorMessage = error instanceof Error ? error.message : String(error);
33
- logError(`Failed to claim feature: ${errorMessage}`);
34
- throw error;
35
- }
36
- }
37
- /**
38
- * Filter features by status
39
- */
40
- export function filterFeaturesByStatus(features, status) {
41
- return features.filter((feature) => feature.status === status);
42
- }
43
- /**
44
- * Sort features by updated_at (oldest first for processing)
45
- */
46
- export function sortFeaturesByUpdatedAt(features) {
47
- return [...features].sort((a, b) => {
48
- const dateA = new Date(a.updated_at || 0).getTime();
49
- const dateB = new Date(b.updated_at || 0).getTime();
50
- return dateA - dateB;
51
- });
52
- }
53
- /**
54
- * Get features with ready_for_ai status for a product
55
- */
56
- export async function getReadyForAIFeatures(productId, verbose) {
57
- if (verbose) {
58
- logInfo(`Fetching ready_for_ai features for product: ${productId}`);
59
- }
60
- try {
61
- const result = (await callMcpEndpoint('features/list', {
62
- product_id: productId,
63
- status: 'ready_for_ai',
64
- }));
65
- const features = result.features || [];
66
- const sortedFeatures = sortFeaturesByUpdatedAt(features);
67
- if (verbose) {
68
- logInfo(`✅ Found ${sortedFeatures.length} ready_for_ai features (oldest first)`);
69
- sortedFeatures.forEach((feature, index) => {
70
- logInfo(` ${index + 1}. ${feature.name} (updated: ${feature.updated_at})`);
71
- });
72
- }
73
- return sortedFeatures;
74
- }
75
- catch (error) {
76
- const errorMessage = error instanceof Error ? error.message : String(error);
77
- logError(`Failed to fetch ready_for_ai features: ${errorMessage}`);
78
- throw error;
79
- }
80
- }
@@ -1,5 +0,0 @@
1
- import { type FeatureInfo } from '../../types/features.js';
2
- /**
3
- * Get feature details by ID
4
- */
5
- export declare function getFeature(featureId: string, verbose?: boolean): Promise<FeatureInfo>;
@@ -1,21 +0,0 @@
1
- import { logInfo } from '../../utils/logger.js';
2
- import { callMcpEndpoint } from '../mcp-client.js';
3
- /**
4
- * Get feature details by ID
5
- */
6
- export async function getFeature(featureId, verbose) {
7
- if (verbose) {
8
- logInfo(`Fetching feature details for: ${featureId}`);
9
- }
10
- const result = (await callMcpEndpoint('features/get', {
11
- feature_id: featureId,
12
- }));
13
- if (!result.features || result.features.length === 0) {
14
- throw new Error(`Feature not found: ${featureId}`);
15
- }
16
- const feature = result.features[0];
17
- if (!feature || typeof feature !== 'object') {
18
- throw new Error(`Invalid feature data returned for: ${featureId}`);
19
- }
20
- return feature;
21
- }
@@ -1,8 +0,0 @@
1
- export * from './batch-operations.js';
2
- export * from './feature-utils.js';
3
- export * from './get-feature.js';
4
- export * from './status-updater.js';
5
- export * from './test-cases.js';
6
- export * from './update-feature.js';
7
- export * from './user-stories.js';
8
- export * from '../../types/features.js';
@@ -1,10 +0,0 @@
1
- // Re-export all feature-related functions
2
- export * from './batch-operations.js';
3
- export * from './feature-utils.js';
4
- export * from './get-feature.js';
5
- export * from './status-updater.js';
6
- export * from './test-cases.js';
7
- export * from './update-feature.js';
8
- export * from './user-stories.js';
9
- // Re-export types
10
- export * from '../../types/features.js';
@@ -1,41 +0,0 @@
1
- /**
2
- * Feature status updater for workflow pipeline
3
- * Updates feature status at each phase of the development workflow
4
- */
5
- import type { FeatureStatus } from '../../types/index.js';
6
- interface StatusUpdateOptions {
7
- readonly featureId: string;
8
- readonly status: FeatureStatus;
9
- readonly verbose?: boolean;
10
- }
11
- /**
12
- * Check if moving from currentStatus to newStatus is forward progression
13
- *
14
- * Special cases for archived status:
15
- * - Any status → archived: Always allowed (archiving from any state)
16
- * - Archived → backlog: Always allowed (unarchiving restores to backlog)
17
- */
18
- export declare function isForwardProgression(currentStatus: FeatureStatus, newStatus: FeatureStatus): boolean;
19
- /**
20
- * Update feature status via MCP endpoint
21
- */
22
- export declare function updateFeatureStatus({ featureId, status, verbose, }: StatusUpdateOptions): Promise<boolean>;
23
- /**
24
- * Map pipeline phase to feature status
25
- */
26
- export declare const getStatusForPhase: (phase: string) => FeatureStatus | null;
27
- /**
28
- * Update feature status based on pipeline phase
29
- *
30
- * @param featureId - The feature ID to update
31
- * @param phase - The pipeline phase name
32
- * @param verbose - Whether to log verbose output
33
- * @returns Promise<boolean> - true if update succeeded, false if skipped or failed
34
- *
35
- * BREAKING CHANGE: This function was changed from synchronous to asynchronous in PR #87
36
- * to support regression prevention checks. All callers must now use await/then to handle
37
- * the Promise return type. The function now validates against status regression and will
38
- * skip updates that would move a feature backward in the development workflow.
39
- */
40
- export declare const updateFeatureStatusForPhase: (featureId: string, phase: string, verbose?: boolean) => Promise<boolean>;
41
- export {};
@@ -1,122 +0,0 @@
1
- /**
2
- * Feature status updater for workflow pipeline
3
- * Updates feature status at each phase of the development workflow
4
- */
5
- import { PHASE_STATUS_MAP, STATUS_PROGRESSION_ORDER, } from '../../config/feature-status.js';
6
- import { logError, logInfo } from '../../utils/logger.js';
7
- import { callMcpEndpoint } from '../mcp-client.js';
8
- import { getFeature } from './get-feature.js';
9
- /**
10
- * Check if moving from currentStatus to newStatus is forward progression
11
- *
12
- * Special cases for archived status:
13
- * - Any status → archived: Always allowed (archiving from any state)
14
- * - Archived → backlog: Always allowed (unarchiving restores to backlog)
15
- */
16
- export function isForwardProgression(currentStatus, newStatus) {
17
- // Any status can transition to archived
18
- if (newStatus === 'archived') {
19
- return true;
20
- }
21
- // Archived can only transition back to backlog (unarchive)
22
- if (currentStatus === 'archived') {
23
- return newStatus === 'backlog';
24
- }
25
- const currentIndex = STATUS_PROGRESSION_ORDER.indexOf(currentStatus);
26
- const newIndex = STATUS_PROGRESSION_ORDER.indexOf(newStatus);
27
- // Allow moving forward or staying at same level (for retries, etc.)
28
- return newIndex >= currentIndex;
29
- }
30
- /**
31
- * Update feature status via MCP endpoint
32
- */
33
- export async function updateFeatureStatus({ featureId, status, verbose = false, }) {
34
- try {
35
- if (verbose) {
36
- logInfo(`Updating feature ${featureId} status to: ${status}`);
37
- }
38
- // Get current feature status to check for regression
39
- let feature;
40
- let currentStatus;
41
- try {
42
- feature = await getFeature(featureId, verbose);
43
- currentStatus = feature.status;
44
- }
45
- catch (error) {
46
- const errorMessage = error instanceof Error ? error.message : String(error);
47
- logError(`Failed to get current feature status for ${featureId}: ${errorMessage}`);
48
- // If we can't get the current status, we can't safely check for regression
49
- // so we'll skip the update to prevent potential regression
50
- if (verbose) {
51
- logInfo('⚠️ Skipping status update due to inability to verify current status');
52
- }
53
- return false;
54
- }
55
- // Check if this would be a regression
56
- if (!isForwardProgression(currentStatus, status)) {
57
- const message = `⚠️ Skipping status regression: ${currentStatus} → ${status}. Only forward progression allowed.`;
58
- if (verbose) {
59
- logInfo(message);
60
- }
61
- return false;
62
- }
63
- // Only proceed if status actually changed
64
- if (currentStatus === status) {
65
- if (verbose) {
66
- logInfo(`Status already at ${status}, no update needed`);
67
- }
68
- return true;
69
- }
70
- // Update status
71
- await callMcpEndpoint('features/update', {
72
- feature_id: featureId,
73
- status,
74
- });
75
- if (verbose) {
76
- logInfo(`✅ Feature status updated successfully from ${currentStatus} to: ${status}`);
77
- }
78
- return true;
79
- }
80
- catch (error) {
81
- const errorMessage = error instanceof Error ? error.message : String(error);
82
- if (verbose) {
83
- logError(`Failed to update feature status: ${errorMessage}`);
84
- }
85
- return false;
86
- }
87
- }
88
- /**
89
- * Map pipeline phase to feature status
90
- */
91
- export const getStatusForPhase = (phase) => {
92
- // Use the externalized phase-to-status mapping
93
- return PHASE_STATUS_MAP[phase] ?? null;
94
- };
95
- /**
96
- * Update feature status based on pipeline phase
97
- *
98
- * @param featureId - The feature ID to update
99
- * @param phase - The pipeline phase name
100
- * @param verbose - Whether to log verbose output
101
- * @returns Promise<boolean> - true if update succeeded, false if skipped or failed
102
- *
103
- * BREAKING CHANGE: This function was changed from synchronous to asynchronous in PR #87
104
- * to support regression prevention checks. All callers must now use await/then to handle
105
- * the Promise return type. The function now validates against status regression and will
106
- * skip updates that would move a feature backward in the development workflow.
107
- */
108
- export const updateFeatureStatusForPhase = async (featureId, phase, verbose) => {
109
- const status = getStatusForPhase(phase);
110
- if (!status) {
111
- const message = `⚠️ Unknown phase '${phase}' - skipping status update to prevent regression`;
112
- if (verbose) {
113
- logInfo(message);
114
- }
115
- return false;
116
- }
117
- return updateFeatureStatus({
118
- featureId,
119
- status,
120
- verbose,
121
- });
122
- };
@@ -1,29 +0,0 @@
1
- import { type TestCase, type TestCaseStatus } from '../../types/features.js';
2
- /**
3
- * Get test cases for a feature
4
- */
5
- export declare function getTestCases(featureId: string, verbose?: boolean): Promise<TestCase[]>;
6
- /**
7
- * Create a new test case for a feature
8
- */
9
- export declare function createTestCase(featureId: string, testCase: {
10
- name: string;
11
- description: string;
12
- is_critical?: boolean;
13
- }, verbose?: boolean): Promise<boolean>;
14
- /**
15
- * Create multiple test cases for a feature
16
- */
17
- export declare function createTestCases(mcpServerUrl: string, mcpToken: string, featureId: string, testCases: {
18
- name: string;
19
- description: string;
20
- is_critical?: boolean;
21
- }[], verbose?: boolean): Promise<boolean>;
22
- /**
23
- * Delete a test case
24
- */
25
- export declare function deleteTestCase(testCaseId: string, verbose?: boolean): Promise<boolean>;
26
- /**
27
- * Update test case status
28
- */
29
- export declare function updateTestCaseStatus(testCaseId: string, status: TestCaseStatus, verbose?: boolean): Promise<boolean>;
@@ -1,110 +0,0 @@
1
- import { logError, logInfo } from '../../utils/logger.js';
2
- import { callMcpEndpoint } from '../mcp-client.js';
3
- /**
4
- * Get test cases for a feature
5
- */
6
- export async function getTestCases(featureId, verbose) {
7
- if (verbose) {
8
- logInfo(`Fetching test cases for feature: ${featureId}`);
9
- }
10
- const result = (await callMcpEndpoint('test_cases/list', {
11
- feature_id: featureId,
12
- }));
13
- return (result.test_cases || []);
14
- }
15
- /**
16
- * Create a new test case for a feature
17
- */
18
- export async function createTestCase(featureId, testCase, verbose) {
19
- try {
20
- if (verbose) {
21
- logInfo(`Creating test case for feature: ${featureId}`);
22
- }
23
- await callMcpEndpoint('test_cases/create', {
24
- feature_id: featureId,
25
- test_cases: [
26
- {
27
- name: testCase.name,
28
- description: testCase.description,
29
- is_critical: testCase.is_critical || false,
30
- },
31
- ],
32
- });
33
- if (verbose) {
34
- logInfo('✅ Test case created successfully');
35
- }
36
- return true;
37
- }
38
- catch (error) {
39
- const errorMessage = error instanceof Error ? error.message : String(error);
40
- logError(`Failed to create test case: ${errorMessage}`);
41
- return false;
42
- }
43
- }
44
- /**
45
- * Create multiple test cases for a feature
46
- */
47
- export async function createTestCases(mcpServerUrl, mcpToken, featureId, testCases, verbose) {
48
- try {
49
- if (verbose) {
50
- logInfo(`Creating ${testCases.length} test cases for feature: ${featureId}`);
51
- }
52
- for (const testCase of testCases) {
53
- await createTestCase(featureId, testCase, false);
54
- }
55
- if (verbose) {
56
- logInfo('✅ All test cases created successfully');
57
- }
58
- return true;
59
- }
60
- catch (error) {
61
- const errorMessage = error instanceof Error ? error.message : String(error);
62
- logError(`Failed to create test cases: ${errorMessage}`);
63
- return false;
64
- }
65
- }
66
- /**
67
- * Delete a test case
68
- */
69
- export async function deleteTestCase(testCaseId, verbose) {
70
- try {
71
- if (verbose) {
72
- logInfo(`Deleting test case: ${testCaseId}`);
73
- }
74
- await callMcpEndpoint('test_cases/delete', {
75
- test_case_id: testCaseId,
76
- });
77
- if (verbose) {
78
- logInfo('✅ Test case deleted successfully');
79
- }
80
- return true;
81
- }
82
- catch (error) {
83
- const errorMessage = error instanceof Error ? error.message : String(error);
84
- logError(`Failed to delete test case: ${errorMessage}`);
85
- return false;
86
- }
87
- }
88
- /**
89
- * Update test case status
90
- */
91
- export async function updateTestCaseStatus(testCaseId, status, verbose) {
92
- try {
93
- if (verbose) {
94
- logInfo(`Updating test case ${testCaseId} status to: ${status}`);
95
- }
96
- await callMcpEndpoint('test_cases/update_status', {
97
- test_case_id: testCaseId,
98
- status,
99
- });
100
- if (verbose) {
101
- logInfo('✅ Test case status updated successfully');
102
- }
103
- return true;
104
- }
105
- catch (error) {
106
- const errorMessage = error instanceof Error ? error.message : String(error);
107
- logError(`Failed to update test case status: ${errorMessage}`);
108
- return false;
109
- }
110
- }
@@ -1,20 +0,0 @@
1
- import { type FeatureWorkflow } from '../../types/pipeline.js';
2
- /**
3
- * Update feature with new data
4
- */
5
- export declare function updateFeature(featureId: string, updates: {
6
- technical_design?: string;
7
- status?: string;
8
- execution_mode?: string;
9
- workflow?: FeatureWorkflow;
10
- }, verbose?: boolean): Promise<boolean>;
11
- /**
12
- * Update technical design for a feature
13
- */
14
- export declare function updateTechnicalDesign(featureId: string, technicalDesign: string, verbose?: boolean): Promise<boolean>;
15
- /**
16
- * Mark a workflow phase as completed
17
- * Fetches current workflow, updates the phase status, and saves back
18
- * Accepts phase names in either format (hyphens or underscores)
19
- */
20
- export declare function markWorkflowPhaseCompleted(featureId: string, phaseName: string, verbose?: boolean): Promise<boolean>;
@@ -1,83 +0,0 @@
1
- import { logError, logInfo } from '../../utils/logger.js';
2
- import { callMcpEndpoint } from '../mcp-client.js';
3
- /**
4
- * Update feature with new data
5
- */
6
- export async function updateFeature(featureId, updates, verbose) {
7
- try {
8
- if (verbose) {
9
- logInfo(`Updating feature: ${featureId}`);
10
- }
11
- await callMcpEndpoint('features/update', {
12
- feature_id: featureId,
13
- ...updates,
14
- });
15
- if (verbose) {
16
- logInfo('✅ Feature updated successfully');
17
- }
18
- return true;
19
- }
20
- catch (error) {
21
- const errorMessage = error instanceof Error ? error.message : String(error);
22
- logError(`Failed to update feature: ${errorMessage}`);
23
- return false;
24
- }
25
- }
26
- /**
27
- * Update technical design for a feature
28
- */
29
- export async function updateTechnicalDesign(featureId, technicalDesign, verbose) {
30
- return updateFeature(featureId, { technical_design: technicalDesign }, verbose);
31
- }
32
- /**
33
- * Normalize phase name from pipeline format (hyphens) to workflow format (underscores)
34
- * e.g., 'feature-analysis' -> 'feature_analysis'
35
- */
36
- function normalizePhaseNameForWorkflow(phaseName) {
37
- return phaseName.replace(/-/g, '_');
38
- }
39
- /**
40
- * Mark a workflow phase as completed
41
- * Fetches current workflow, updates the phase status, and saves back
42
- * Accepts phase names in either format (hyphens or underscores)
43
- */
44
- export async function markWorkflowPhaseCompleted(featureId, phaseName, verbose) {
45
- try {
46
- // Normalize phase name to workflow format (underscores)
47
- const normalizedPhaseName = normalizePhaseNameForWorkflow(phaseName);
48
- if (verbose) {
49
- logInfo(`Marking workflow phase '${normalizedPhaseName}' as completed for feature: ${featureId}`);
50
- }
51
- // Fetch current feature to get workflow
52
- const response = (await callMcpEndpoint('features/get', {
53
- feature_id: featureId,
54
- }));
55
- const feature = response?.features?.[0];
56
- if (!feature) {
57
- logError(`Feature not found: ${featureId}`);
58
- return false;
59
- }
60
- const workflow = feature.workflow || [];
61
- if (workflow.length === 0) {
62
- if (verbose) {
63
- logInfo(`No workflow defined for feature, skipping phase completion`);
64
- }
65
- return true;
66
- }
67
- // Update the phase status
68
- const updatedWorkflow = workflow.map((p) => p.phase === normalizedPhaseName
69
- ? {
70
- ...p,
71
- status: 'completed',
72
- executed_at: new Date().toISOString(),
73
- }
74
- : p);
75
- // Save updated workflow
76
- return await updateFeature(featureId, { workflow: updatedWorkflow }, verbose);
77
- }
78
- catch (error) {
79
- const errorMessage = error instanceof Error ? error.message : String(error);
80
- logError(`Failed to mark workflow phase completed: ${errorMessage}`);
81
- return false;
82
- }
83
- }
@@ -1,21 +0,0 @@
1
- import { type UserStory, type UserStoryStatus } from '../../types/features.js';
2
- /**
3
- * Get user stories for a feature
4
- */
5
- export declare function getUserStories(featureId: string, verbose?: boolean): Promise<UserStory[]>;
6
- /**
7
- * Create a new user story for a feature
8
- */
9
- export declare function createUserStory(featureId: string, userStory: {
10
- title: string;
11
- description: string;
12
- status?: string;
13
- }, verbose?: boolean): Promise<boolean>;
14
- /**
15
- * Delete a user story
16
- */
17
- export declare function deleteUserStory(userStoryId: string, verbose?: boolean): Promise<boolean>;
18
- /**
19
- * Update user story status
20
- */
21
- export declare function updateUserStoryStatus(userStoryId: string, status: UserStoryStatus, verbose?: boolean): Promise<boolean>;