edsger 0.33.5 → 0.34.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 (334) hide show
  1. package/dist/api/__tests__/app-store.test.d.ts +7 -0
  2. package/dist/api/__tests__/app-store.test.js +60 -0
  3. package/dist/api/app-store.d.ts +7 -3
  4. package/dist/api/app-store.js +35 -2
  5. package/dist/api/chat.d.ts +4 -4
  6. package/dist/api/chat.js +4 -4
  7. package/dist/api/cross-product.d.ts +1 -1
  8. package/dist/api/cross-product.js +1 -1
  9. package/dist/api/features/__tests__/feature-utils.test.js +21 -21
  10. package/dist/api/features/__tests__/status-updater.test.js +12 -12
  11. package/dist/api/features/approval-checker.js +1 -1
  12. package/dist/api/features/batch-operations.d.ts +1 -1
  13. package/dist/api/features/batch-operations.js +1 -1
  14. package/dist/api/features/feature-utils.d.ts +1 -1
  15. package/dist/api/features/feature-utils.js +1 -1
  16. package/dist/api/features/get-feature.d.ts +1 -1
  17. package/dist/api/features/index.d.ts +4 -4
  18. package/dist/api/features/index.js +4 -4
  19. package/dist/api/features/status-updater.js +6 -4
  20. package/dist/api/features/test-cases.d.ts +3 -3
  21. package/dist/api/features/test-cases.js +1 -1
  22. package/dist/api/features/update-feature.d.ts +1 -1
  23. package/dist/api/features/update-feature.js +1 -1
  24. package/dist/api/features/user-stories.d.ts +1 -1
  25. package/dist/api/features/user-stories.js +1 -1
  26. package/dist/api/github.js +1 -1
  27. package/dist/api/growth.d.ts +8 -8
  28. package/dist/api/growth.js +1 -1
  29. package/dist/api/products.d.ts +6 -1
  30. package/dist/api/storage.d.ts +1 -1
  31. package/dist/api/storage.js +6 -3
  32. package/dist/api/tasks.js +1 -1
  33. package/dist/api/test-reports.d.ts +1 -1
  34. package/dist/api/test-reports.js +1 -1
  35. package/dist/auth/auth-store.js +5 -4
  36. package/dist/auth/env-store.d.ts +2 -2
  37. package/dist/auth/env-store.js +3 -3
  38. package/dist/auth/login.d.ts +2 -2
  39. package/dist/auth/login.js +5 -5
  40. package/dist/commands/agent-workflow/chat-worker.js +28 -12
  41. package/dist/commands/agent-workflow/feature-worker.js +2 -2
  42. package/dist/commands/agent-workflow/index.d.ts +1 -1
  43. package/dist/commands/agent-workflow/index.js +13 -9
  44. package/dist/commands/agent-workflow/processor.d.ts +1 -1
  45. package/dist/commands/agent-workflow/processor.js +56 -23
  46. package/dist/commands/analyze-logs/index.d.ts +1 -1
  47. package/dist/commands/analyze-logs/index.js +1 -1
  48. package/dist/commands/app-store/index.d.ts +1 -1
  49. package/dist/commands/app-store/index.js +11 -13
  50. package/dist/commands/checklists/index.d.ts +13 -0
  51. package/dist/commands/checklists/index.js +120 -0
  52. package/dist/commands/checklists/tools.d.ts +10 -0
  53. package/dist/commands/checklists/tools.js +212 -0
  54. package/dist/commands/code-review/index.d.ts +1 -1
  55. package/dist/commands/code-review/index.js +2 -2
  56. package/dist/commands/code-review/reviewer.d.ts +1 -1
  57. package/dist/commands/code-review/reviewer.js +46 -39
  58. package/dist/commands/config/index.js +2 -2
  59. package/dist/commands/growth-analysis/index.d.ts +1 -1
  60. package/dist/commands/growth-analysis/index.js +9 -7
  61. package/dist/commands/init/index.d.ts +1 -1
  62. package/dist/commands/init/index.js +36 -30
  63. package/dist/commands/refactor/refactor.d.ts +1 -1
  64. package/dist/commands/refactor/refactor.js +28 -22
  65. package/dist/commands/task-worker/index.d.ts +1 -1
  66. package/dist/commands/task-worker/processor.d.ts +1 -1
  67. package/dist/commands/task-worker/processor.js +9 -6
  68. package/dist/commands/workflow/config/phase-configs.d.ts +1 -1
  69. package/dist/commands/workflow/config/phase-configs.js +10 -10
  70. package/dist/commands/workflow/core/__tests__/feature-filter.test.js +57 -66
  71. package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.js +74 -83
  72. package/dist/commands/workflow/core/__tests__/state-manager.test.js +35 -35
  73. package/dist/commands/workflow/core/feature-filter.js +2 -1
  74. package/dist/commands/workflow/core/workflow-logger.js +3 -3
  75. package/dist/commands/workflow/executors/phase-executor.d.ts +3 -3
  76. package/dist/commands/workflow/executors/phase-executor.js +137 -116
  77. package/dist/commands/workflow/feature-coordinator.d.ts +2 -2
  78. package/dist/commands/workflow/feature-coordinator.js +1 -1
  79. package/dist/commands/workflow/index.d.ts +1 -1
  80. package/dist/commands/workflow/index.js +2 -2
  81. package/dist/commands/workflow/phase-orchestrator.d.ts +2 -2
  82. package/dist/commands/workflow/phase-orchestrator.js +13 -5
  83. package/dist/commands/workflow/processor.d.ts +1 -1
  84. package/dist/commands/workflow/processor.js +5 -5
  85. package/dist/config/__tests__/config.test.js +35 -35
  86. package/dist/config/__tests__/feature-status.test.js +16 -16
  87. package/dist/config.d.ts +1 -1
  88. package/dist/constants.js +3 -2
  89. package/dist/errors/__tests__/index.test.js +81 -81
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +41 -17
  92. package/dist/phases/analyze-logs/agent.js +7 -4
  93. package/dist/phases/analyze-logs/index.js +1 -1
  94. package/dist/phases/analyze-logs/prompts.d.ts +1 -1
  95. package/dist/phases/app-store-generation/__tests__/agent.test.js +11 -11
  96. package/dist/phases/app-store-generation/__tests__/context.test.js +39 -35
  97. package/dist/phases/app-store-generation/__tests__/prompts.test.js +33 -33
  98. package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.js +50 -50
  99. package/dist/phases/app-store-generation/agent.d.ts +2 -2
  100. package/dist/phases/app-store-generation/agent.js +12 -5
  101. package/dist/phases/app-store-generation/context.d.ts +1 -1
  102. package/dist/phases/app-store-generation/context.js +4 -3
  103. package/dist/phases/app-store-generation/index.d.ts +4 -3
  104. package/dist/phases/app-store-generation/index.js +46 -37
  105. package/dist/phases/app-store-generation/prompts.js +12 -10
  106. package/dist/phases/app-store-generation/screenshot-composer.d.ts +0 -1
  107. package/dist/phases/app-store-generation/screenshot-composer.js +55 -49
  108. package/dist/phases/app-store-generation/uploader.d.ts +3 -2
  109. package/dist/phases/app-store-generation/uploader.js +26 -16
  110. package/dist/phases/autonomous/index.d.ts +12 -4
  111. package/dist/phases/autonomous/index.js +192 -137
  112. package/dist/phases/autonomous/prompts.d.ts +1 -1
  113. package/dist/phases/branch-planning/context.d.ts +1 -1
  114. package/dist/phases/branch-planning/context.js +2 -2
  115. package/dist/phases/branch-planning/index.d.ts +2 -2
  116. package/dist/phases/branch-planning/index.js +178 -132
  117. package/dist/phases/branch-planning/outcome.d.ts +1 -1
  118. package/dist/phases/branch-planning/outcome.js +2 -1
  119. package/dist/phases/branch-planning/prompts.d.ts +6 -6
  120. package/dist/phases/bug-fixing/analyzer.d.ts +1 -1
  121. package/dist/phases/bug-fixing/analyzer.js +56 -68
  122. package/dist/phases/bug-fixing/context-fetcher.d.ts +1 -1
  123. package/dist/phases/bug-fixing/context-fetcher.js +6 -4
  124. package/dist/phases/bug-fixing/index.d.ts +1 -1
  125. package/dist/phases/bug-fixing/index.js +1 -1
  126. package/dist/phases/bug-fixing/prompts.d.ts +1 -1
  127. package/dist/phases/chat-processor/context.d.ts +6 -6
  128. package/dist/phases/chat-processor/context.js +7 -1
  129. package/dist/phases/chat-processor/index.d.ts +10 -1
  130. package/dist/phases/chat-processor/index.js +43 -28
  131. package/dist/phases/chat-processor/product-context.d.ts +4 -4
  132. package/dist/phases/chat-processor/product-context.js +13 -5
  133. package/dist/phases/chat-processor/product-tools.js +90 -44
  134. package/dist/phases/chat-processor/prompts.d.ts +2 -2
  135. package/dist/phases/chat-processor/tools.js +119 -55
  136. package/dist/phases/code-implementation/branch-pr-creator.js +11 -6
  137. package/dist/phases/code-implementation/context.d.ts +1 -1
  138. package/dist/phases/code-implementation/context.js +6 -4
  139. package/dist/phases/code-implementation/index.d.ts +6 -6
  140. package/dist/phases/code-implementation/index.js +236 -154
  141. package/dist/phases/code-implementation/outcome.d.ts +32 -4
  142. package/dist/phases/code-implementation/outcome.js +4 -2
  143. package/dist/phases/code-implementation/prompts.d.ts +2 -2
  144. package/dist/phases/code-implementation-verification/agent.d.ts +2 -1
  145. package/dist/phases/code-implementation-verification/agent.js +148 -127
  146. package/dist/phases/code-implementation-verification/index.d.ts +16 -4
  147. package/dist/phases/code-implementation-verification/index.js +4 -9
  148. package/dist/phases/code-implementation-verification/prompts.d.ts +10 -2
  149. package/dist/phases/code-implementation-verification/prompts.js +2 -1
  150. package/dist/phases/code-refine/context.js +19 -7
  151. package/dist/phases/code-refine/index.d.ts +9 -9
  152. package/dist/phases/code-refine/index.js +57 -190
  153. package/dist/phases/code-refine/prompts.d.ts +2 -2
  154. package/dist/phases/code-refine/prompts.js +3 -3
  155. package/dist/phases/code-refine/refine-iteration.d.ts +33 -0
  156. package/dist/phases/code-refine/refine-iteration.js +165 -0
  157. package/dist/phases/code-refine/retry-handler.d.ts +2 -2
  158. package/dist/phases/code-refine/retry-handler.js +6 -4
  159. package/dist/phases/code-refine-verification/github.d.ts +12 -4
  160. package/dist/phases/code-refine-verification/github.js +13 -7
  161. package/dist/phases/code-refine-verification/index.d.ts +1 -1
  162. package/dist/phases/code-refine-verification/index.js +5 -4
  163. package/dist/phases/code-refine-verification/llm-analyzer.d.ts +4 -4
  164. package/dist/phases/code-refine-verification/llm-analyzer.js +49 -33
  165. package/dist/phases/code-refine-verification/prompts.d.ts +1 -1
  166. package/dist/phases/code-refine-verification/prompts.js +1 -2
  167. package/dist/phases/code-refine-verification/types.d.ts +7 -7
  168. package/dist/phases/code-review/context.js +6 -2
  169. package/dist/phases/code-review/index.d.ts +5 -5
  170. package/dist/phases/code-review/index.js +134 -96
  171. package/dist/phases/code-testing/analyzer.d.ts +2 -2
  172. package/dist/phases/code-testing/analyzer.js +87 -96
  173. package/dist/phases/code-testing/context-fetcher.d.ts +1 -1
  174. package/dist/phases/code-testing/context-fetcher.js +6 -4
  175. package/dist/phases/code-testing/index.d.ts +2 -2
  176. package/dist/phases/code-testing/prompts.d.ts +1 -1
  177. package/dist/phases/feature-analysis/agent.d.ts +13 -2
  178. package/dist/phases/feature-analysis/agent.js +12 -4
  179. package/dist/phases/feature-analysis/context.d.ts +2 -2
  180. package/dist/phases/feature-analysis/context.js +9 -7
  181. package/dist/phases/feature-analysis/index.d.ts +2 -2
  182. package/dist/phases/feature-analysis/index.js +44 -8
  183. package/dist/phases/feature-analysis/outcome.d.ts +3 -3
  184. package/dist/phases/feature-analysis/outcome.js +18 -9
  185. package/dist/phases/feature-analysis/prompts.d.ts +3 -3
  186. package/dist/phases/feature-analysis-verification/agent.d.ts +4 -4
  187. package/dist/phases/feature-analysis-verification/agent.js +43 -37
  188. package/dist/phases/feature-analysis-verification/index.d.ts +15 -5
  189. package/dist/phases/feature-analysis-verification/index.js +9 -9
  190. package/dist/phases/feature-analysis-verification/prompts.d.ts +2 -2
  191. package/dist/phases/functional-testing/analyzer.d.ts +10 -10
  192. package/dist/phases/functional-testing/analyzer.js +343 -307
  193. package/dist/phases/functional-testing/context-fetcher.d.ts +1 -1
  194. package/dist/phases/functional-testing/context-fetcher.js +6 -4
  195. package/dist/phases/functional-testing/http-fallback.js +1 -1
  196. package/dist/phases/functional-testing/index.d.ts +3 -3
  197. package/dist/phases/functional-testing/index.js +2 -2
  198. package/dist/phases/functional-testing/prompts.d.ts +1 -1
  199. package/dist/phases/functional-testing/test-report-creator.js +23 -15
  200. package/dist/phases/functional-testing/test-retry-handler.d.ts +2 -2
  201. package/dist/phases/functional-testing/test-retry-handler.js +9 -5
  202. package/dist/phases/growth-analysis/agent.d.ts +2 -2
  203. package/dist/phases/growth-analysis/agent.js +12 -5
  204. package/dist/phases/growth-analysis/context.d.ts +1 -1
  205. package/dist/phases/growth-analysis/context.js +2 -2
  206. package/dist/phases/growth-analysis/index.d.ts +5 -5
  207. package/dist/phases/growth-analysis/index.js +46 -37
  208. package/dist/phases/growth-analysis/prompts.js +4 -2
  209. package/dist/phases/pr-execution/context.d.ts +1 -1
  210. package/dist/phases/pr-execution/context.js +15 -9
  211. package/dist/phases/pr-execution/index.d.ts +1 -1
  212. package/dist/phases/pr-execution/index.js +29 -17
  213. package/dist/phases/pr-execution/pr-executor.js +2 -2
  214. package/dist/phases/pr-execution/prompts.d.ts +9 -1
  215. package/dist/phases/pr-execution/prompts.js +2 -4
  216. package/dist/phases/pr-splitting/context.d.ts +1 -1
  217. package/dist/phases/pr-splitting/context.js +15 -8
  218. package/dist/phases/pr-splitting/index.d.ts +4 -4
  219. package/dist/phases/pr-splitting/index.js +47 -39
  220. package/dist/phases/pr-splitting/outcome.d.ts +1 -1
  221. package/dist/phases/pr-splitting/outcome.js +2 -1
  222. package/dist/phases/pr-splitting/prompts.d.ts +7 -7
  223. package/dist/phases/pr-splitting/prompts.js +8 -2
  224. package/dist/phases/pull-request/creator.js +30 -13
  225. package/dist/phases/pull-request/handler.d.ts +1 -1
  226. package/dist/phases/pull-request/handler.js +6 -3
  227. package/dist/phases/task/agent.d.ts +1 -1
  228. package/dist/phases/task/agent.js +20 -12
  229. package/dist/phases/task/context.js +1 -1
  230. package/dist/phases/task/index.d.ts +1 -1
  231. package/dist/phases/task/index.js +3 -3
  232. package/dist/phases/technical-design/context.d.ts +1 -1
  233. package/dist/phases/technical-design/context.js +2 -2
  234. package/dist/phases/technical-design/index.d.ts +2 -2
  235. package/dist/phases/technical-design/index.js +134 -116
  236. package/dist/phases/technical-design/outcome.js +3 -1
  237. package/dist/phases/technical-design/prompts.d.ts +2 -2
  238. package/dist/phases/technical-design/prompts.js +2 -0
  239. package/dist/phases/technical-design-verification/agent.d.ts +3 -3
  240. package/dist/phases/technical-design-verification/agent.js +54 -41
  241. package/dist/phases/technical-design-verification/index.d.ts +18 -6
  242. package/dist/phases/technical-design-verification/index.js +7 -8
  243. package/dist/phases/technical-design-verification/prompts.d.ts +3 -3
  244. package/dist/phases/technical-design-verification/prompts.js +5 -8
  245. package/dist/phases/test-cases-analysis/agent.d.ts +9 -2
  246. package/dist/phases/test-cases-analysis/agent.js +12 -4
  247. package/dist/phases/test-cases-analysis/context.d.ts +2 -2
  248. package/dist/phases/test-cases-analysis/context.js +5 -5
  249. package/dist/phases/test-cases-analysis/formatters.d.ts +1 -1
  250. package/dist/phases/test-cases-analysis/formatters.js +1 -1
  251. package/dist/phases/test-cases-analysis/index.d.ts +3 -3
  252. package/dist/phases/test-cases-analysis/index.js +42 -9
  253. package/dist/phases/test-cases-analysis/outcome.d.ts +1 -1
  254. package/dist/phases/test-cases-analysis/outcome.js +13 -5
  255. package/dist/phases/test-cases-analysis/prompts.d.ts +2 -2
  256. package/dist/phases/user-stories-analysis/agent.d.ts +9 -2
  257. package/dist/phases/user-stories-analysis/agent.js +12 -4
  258. package/dist/phases/user-stories-analysis/context.d.ts +2 -2
  259. package/dist/phases/user-stories-analysis/context.js +5 -5
  260. package/dist/phases/user-stories-analysis/formatters.d.ts +1 -1
  261. package/dist/phases/user-stories-analysis/formatters.js +1 -1
  262. package/dist/phases/user-stories-analysis/index.d.ts +3 -3
  263. package/dist/phases/user-stories-analysis/index.js +42 -9
  264. package/dist/phases/user-stories-analysis/outcome.d.ts +1 -1
  265. package/dist/phases/user-stories-analysis/outcome.js +14 -6
  266. package/dist/phases/user-stories-analysis/prompts.d.ts +2 -2
  267. package/dist/services/audit-logs.d.ts +10 -10
  268. package/dist/services/audit-logs.js +1 -1
  269. package/dist/services/branches.d.ts +3 -3
  270. package/dist/services/branches.js +10 -7
  271. package/dist/services/checklist.d.ts +9 -9
  272. package/dist/services/checklist.js +36 -38
  273. package/dist/services/coaching/__tests__/coaching-agent.test.d.ts +1 -0
  274. package/dist/services/coaching/__tests__/coaching-agent.test.js +74 -0
  275. package/dist/services/coaching/__tests__/coaching-loop.test.d.ts +1 -0
  276. package/dist/services/coaching/__tests__/coaching-loop.test.js +59 -0
  277. package/dist/services/coaching/__tests__/self-rating.test.d.ts +1 -0
  278. package/dist/services/coaching/__tests__/self-rating.test.js +188 -0
  279. package/dist/services/coaching/coaching-agent.d.ts +39 -0
  280. package/dist/services/coaching/coaching-agent.js +283 -0
  281. package/dist/services/coaching/coaching-loop.d.ts +62 -0
  282. package/dist/services/coaching/coaching-loop.js +265 -0
  283. package/dist/services/coaching/index.d.ts +8 -0
  284. package/dist/services/coaching/index.js +8 -0
  285. package/dist/services/coaching/phase-coaching.d.ts +47 -0
  286. package/dist/services/coaching/phase-coaching.js +60 -0
  287. package/dist/services/coaching/self-rating.d.ts +26 -0
  288. package/dist/services/coaching/self-rating.js +153 -0
  289. package/dist/services/feedbacks.d.ts +1 -1
  290. package/dist/services/feedbacks.js +15 -10
  291. package/dist/services/phase-ratings.d.ts +70 -0
  292. package/dist/services/phase-ratings.js +80 -0
  293. package/dist/services/product-logs.js +2 -1
  294. package/dist/services/pull-requests.d.ts +5 -5
  295. package/dist/services/pull-requests.js +2 -2
  296. package/dist/services/video/__tests__/video-pipeline.test.js +53 -37
  297. package/dist/services/video/device-frames.js +16 -3
  298. package/dist/services/video/index.d.ts +1 -1
  299. package/dist/services/video/index.js +22 -16
  300. package/dist/services/video/screenshot-generator.d.ts +3 -1
  301. package/dist/services/video/screenshot-generator.js +10 -8
  302. package/dist/services/video/tts-generator.d.ts +2 -2
  303. package/dist/services/video/tts-generator.js +2 -2
  304. package/dist/services/video/video-assembler.js +102 -55
  305. package/dist/services/video/video-uploader.js +7 -6
  306. package/dist/system/session-manager.js +8 -4
  307. package/dist/system/sleep-notification.js +5 -2
  308. package/dist/types/features.d.ts +1 -1
  309. package/dist/types/index.d.ts +9 -2
  310. package/dist/types/llm-responses.d.ts +22 -22
  311. package/dist/types/pipeline.d.ts +2 -2
  312. package/dist/updater/auto-updater.js +5 -3
  313. package/dist/utils/conflict-resolver.js +26 -21
  314. package/dist/utils/formatters.d.ts +5 -5
  315. package/dist/utils/formatters.js +4 -2
  316. package/dist/utils/git-branch-manager-async.d.ts +127 -0
  317. package/dist/utils/git-branch-manager-async.js +423 -0
  318. package/dist/utils/git-branch-manager.d.ts +1 -114
  319. package/dist/utils/git-branch-manager.js +31 -427
  320. package/dist/utils/git-push.js +12 -3
  321. package/dist/utils/image-downloader.js +29 -21
  322. package/dist/utils/json-extractor.d.ts +27 -0
  323. package/dist/utils/json-extractor.js +102 -0
  324. package/dist/utils/logger.d.ts +1 -1
  325. package/dist/utils/logger.js +24 -15
  326. package/dist/utils/pipeline-logger.d.ts +1 -1
  327. package/dist/utils/pipeline-logger.js +1 -1
  328. package/dist/utils/validation.d.ts +4 -3
  329. package/dist/utils/workflow-utils.d.ts +3 -2
  330. package/dist/utils/workflow-utils.js +2 -2
  331. package/dist/workspace/workspace-manager.d.ts +1 -1
  332. package/dist/workspace/workspace-manager.js +10 -5
  333. package/eslint.config.mjs +22 -0
  334. package/package.json +3 -1
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Unit tests for app-store API helpers.
3
+ *
4
+ * Tests the parsing/extraction logic that getAppStorePrimaryLocale uses
5
+ * to parse MCP response data.
6
+ */
7
+ export {};
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Unit tests for app-store API helpers.
3
+ *
4
+ * Tests the parsing/extraction logic that getAppStorePrimaryLocale uses
5
+ * to parse MCP response data.
6
+ */
7
+ import assert from 'node:assert';
8
+ import { describe, it } from 'node:test';
9
+ /**
10
+ * Extracts locale from an MCP response — mirrors the parsing logic
11
+ * inside getAppStorePrimaryLocale without requiring network mocks.
12
+ */
13
+ function parseLocaleFromMcpResponse(result) {
14
+ const text = result?.content?.[0]?.text || '{}';
15
+ const parsed = JSON.parse(text);
16
+ return parsed.locale || null;
17
+ }
18
+ void describe('parseLocaleFromMcpResponse', () => {
19
+ void it('should return locale string when present', () => {
20
+ const result = { content: [{ text: '{"locale":"en-US"}' }] };
21
+ assert.strictEqual(parseLocaleFromMcpResponse(result), 'en-US');
22
+ });
23
+ void it('should return locale for non-English locales', () => {
24
+ assert.strictEqual(parseLocaleFromMcpResponse({ content: [{ text: '{"locale":"ja"}' }] }), 'ja');
25
+ assert.strictEqual(parseLocaleFromMcpResponse({
26
+ content: [{ text: '{"locale":"zh-Hans"}' }],
27
+ }), 'zh-Hans');
28
+ assert.strictEqual(parseLocaleFromMcpResponse({ content: [{ text: '{"locale":"fr-FR"}' }] }), 'fr-FR');
29
+ });
30
+ void it('should return null when locale is null', () => {
31
+ const result = { content: [{ text: '{"locale":null}' }] };
32
+ assert.strictEqual(parseLocaleFromMcpResponse(result), null);
33
+ });
34
+ void it('should return null when locale is empty string', () => {
35
+ const result = { content: [{ text: '{"locale":""}' }] };
36
+ assert.strictEqual(parseLocaleFromMcpResponse(result), null);
37
+ });
38
+ void it('should return null when content array is empty', () => {
39
+ const result = { content: [] };
40
+ assert.strictEqual(parseLocaleFromMcpResponse(result), null);
41
+ });
42
+ void it('should return null when content field is missing', () => {
43
+ assert.strictEqual(parseLocaleFromMcpResponse({}), null);
44
+ });
45
+ void it('should return null when result is null', () => {
46
+ assert.strictEqual(parseLocaleFromMcpResponse(null), null);
47
+ });
48
+ void it('should return null when result is undefined', () => {
49
+ assert.strictEqual(parseLocaleFromMcpResponse(undefined), null);
50
+ });
51
+ void it('should throw when text is not valid JSON', () => {
52
+ assert.throws(() => {
53
+ parseLocaleFromMcpResponse({ content: [{ text: 'not json' }] });
54
+ });
55
+ });
56
+ void it('should return null when text field is missing', () => {
57
+ const result = { content: [{}] };
58
+ assert.strictEqual(parseLocaleFromMcpResponse(result), null);
59
+ });
60
+ });
@@ -5,7 +5,7 @@ export interface AppStoreConfig {
5
5
  credentials: Record<string, unknown>;
6
6
  app_identifier: string | null;
7
7
  listings: Record<string, AppStoreListing>;
8
- screenshots: AppStoreScreenshot[];
8
+ screenshots: Record<string, AppStoreScreenshot[]>;
9
9
  current_version: string | null;
10
10
  submission_status: string;
11
11
  submitted_at: string | null;
@@ -39,7 +39,6 @@ export interface AppStoreScreenshot {
39
39
  caption: string;
40
40
  background_gradient: string;
41
41
  device_frame: string;
42
- locale: string;
43
42
  }
44
43
  /**
45
44
  * Get app store configs for a product via MCP
@@ -65,7 +64,7 @@ export declare function saveAppStoreListings(configId: string, listings: Record<
65
64
  /**
66
65
  * Save screenshots to an app store config via MCP
67
66
  */
68
- export declare function saveAppStoreScreenshots(configId: string, screenshots: AppStoreScreenshot[], verbose?: boolean): Promise<AppStoreConfig | null>;
67
+ export declare function saveAppStoreScreenshots(configId: string, screenshots: Record<string, AppStoreScreenshot[]>, verbose?: boolean): Promise<AppStoreConfig | null>;
69
68
  /**
70
69
  * Update submission status via MCP
71
70
  */
@@ -74,3 +73,8 @@ export declare function updateAppStoreStatus(configId: string, updates: {
74
73
  current_version?: string;
75
74
  rejection_reason?: string;
76
75
  }, verbose?: boolean): Promise<AppStoreConfig | null>;
76
+ /**
77
+ * Fetch the primary locale from Apple App Store Connect API via MCP.
78
+ * Returns the locale string (e.g. "en-US") or null if unavailable.
79
+ */
80
+ export declare function getAppStorePrimaryLocale(productId: string, verbose?: boolean): Promise<string | null>;
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../utils/logger.js';
1
+ import { logError, logInfo } from '../utils/logger.js';
2
2
  import { callMcpEndpoint } from './mcp-client.js';
3
3
  /**
4
4
  * Get app store configs for a product via MCP
@@ -101,7 +101,8 @@ export async function saveAppStoreListings(configId, listings, verbose) {
101
101
  */
102
102
  export async function saveAppStoreScreenshots(configId, screenshots, verbose) {
103
103
  if (verbose) {
104
- logInfo(`Saving ${screenshots.length} screenshots for config: ${configId}`);
104
+ const total = Object.values(screenshots).flat().length;
105
+ logInfo(`Saving ${total} screenshots (${Object.keys(screenshots).length} locale(s)) for config: ${configId}`);
105
106
  }
106
107
  try {
107
108
  const result = (await callMcpEndpoint('app_store/configs/save_screenshots', {
@@ -146,3 +147,35 @@ export async function updateAppStoreStatus(configId, updates, verbose) {
146
147
  return null;
147
148
  }
148
149
  }
150
+ /**
151
+ * Fetch the primary locale from Apple App Store Connect API via MCP.
152
+ * Returns the locale string (e.g. "en-US") or null if unavailable.
153
+ */
154
+ export async function getAppStorePrimaryLocale(productId, verbose) {
155
+ if (verbose) {
156
+ logInfo(`Fetching primary locale from Apple App Store for product: ${productId}`);
157
+ }
158
+ try {
159
+ const result = (await callMcpEndpoint('app_store/primary_locale', {
160
+ product_id: productId,
161
+ }));
162
+ const text = result.content?.[0]?.text || '{}';
163
+ const parsed = JSON.parse(text);
164
+ const locale = parsed.locale || null;
165
+ if (verbose) {
166
+ if (locale) {
167
+ logInfo(`Primary locale from Apple: ${locale}`);
168
+ }
169
+ else {
170
+ logInfo('No primary locale returned from Apple API');
171
+ }
172
+ }
173
+ return locale;
174
+ }
175
+ catch (error) {
176
+ if (verbose) {
177
+ logError(`Failed to fetch primary locale: ${error instanceof Error ? error.message : String(error)}`);
178
+ }
179
+ return null;
180
+ }
181
+ }
@@ -2,7 +2,7 @@
2
2
  * MCP client wrappers for chat operations.
3
3
  * Used by the chat-worker subprocess to interact with chat channels and messages.
4
4
  */
5
- import type { ChatChannel, ChatChannelType, ChatMode, ChatMessage, ChatMessageType } from '../types/index.js';
5
+ import type { ChatChannel, ChatChannelType, ChatMessage, ChatMessageType, ChatMode } from '../types/index.js';
6
6
  export declare function getOrCreateChannel(channelType: ChatChannelType, channelRefId: string | null, chatMode?: ChatMode, name?: string, verbose?: boolean): Promise<{
7
7
  channel: ChatChannel;
8
8
  created: boolean;
@@ -20,7 +20,7 @@ export declare function sendAiMessage(channelId: string, content: string, metada
20
20
  parentMessageId?: string;
21
21
  }, verbose?: boolean): Promise<ChatMessage>;
22
22
  export declare function sendSystemMessage(channelId: string, content: string, metadata?: Record<string, unknown>, verbose?: boolean): Promise<ChatMessage>;
23
- export declare function getPendingMessages(channelId: string, verbose?: boolean): Promise<ChatMessage[]>;
23
+ export declare function getPendingMessages(channelId: string, _verbose?: boolean): Promise<ChatMessage[]>;
24
24
  /**
25
25
  * Atomically claim pending messages for a channel.
26
26
  * Uses FOR UPDATE SKIP LOCKED at the database level so multiple CLI workers
@@ -31,8 +31,8 @@ export declare function claimPendingMessages(channelId: string, workerId: string
31
31
  staleTimeoutSeconds?: number;
32
32
  }, verbose?: boolean): Promise<ChatMessage[]>;
33
33
  export declare function markMessageProcessed(messageId: string, verbose?: boolean): Promise<void>;
34
- export declare function markChannelRead(channelId: string, lastReadMessageId?: string, verbose?: boolean): Promise<void>;
35
- export declare function getUnreadCount(channelId: string, verbose?: boolean): Promise<number>;
34
+ export declare function markChannelRead(channelId: string, lastReadMessageId?: string, _verbose?: boolean): Promise<void>;
35
+ export declare function getUnreadCount(channelId: string, _verbose?: boolean): Promise<number>;
36
36
  /**
37
37
  * Get or create the group chat channel for a product.
38
38
  * Every product has one group channel.
package/dist/api/chat.js CHANGED
@@ -2,8 +2,8 @@
2
2
  * MCP client wrappers for chat operations.
3
3
  * Used by the chat-worker subprocess to interact with chat channels and messages.
4
4
  */
5
+ import { logError, logInfo } from '../utils/logger.js';
5
6
  import { callMcpEndpoint } from './mcp-client.js';
6
- import { logInfo, logError } from '../utils/logger.js';
7
7
  // ============================================================
8
8
  // Channels
9
9
  // ============================================================
@@ -88,7 +88,7 @@ export async function sendSystemMessage(channelId, content, metadata = {}, verbo
88
88
  }));
89
89
  return result.message;
90
90
  }
91
- export async function getPendingMessages(channelId, verbose) {
91
+ export async function getPendingMessages(channelId, _verbose) {
92
92
  const result = (await callMcpEndpoint('chat/messages/pending', {
93
93
  channel_id: channelId,
94
94
  }));
@@ -122,13 +122,13 @@ export async function markMessageProcessed(messageId, verbose) {
122
122
  // ============================================================
123
123
  // Read Status
124
124
  // ============================================================
125
- export async function markChannelRead(channelId, lastReadMessageId, verbose) {
125
+ export async function markChannelRead(channelId, lastReadMessageId, _verbose) {
126
126
  await callMcpEndpoint('chat/read_status/mark_read', {
127
127
  channel_id: channelId,
128
128
  last_read_message_id: lastReadMessageId,
129
129
  });
130
130
  }
131
- export async function getUnreadCount(channelId, verbose) {
131
+ export async function getUnreadCount(channelId, _verbose) {
132
132
  const result = (await callMcpEndpoint('chat/read_status/unread_count', {
133
133
  channel_id: channelId,
134
134
  }));
@@ -5,7 +5,7 @@
5
5
  * processes features from all products the user has access to,
6
6
  * not just a single product.
7
7
  */
8
- import { FeatureInfo } from '../types/features.js';
8
+ import { type FeatureInfo } from '../types/features.js';
9
9
  export interface ProductSummary {
10
10
  id: string;
11
11
  name: string;
@@ -5,8 +5,8 @@
5
5
  * processes features from all products the user has access to,
6
6
  * not just a single product.
7
7
  */
8
+ import { logError, logInfo } from '../utils/logger.js';
8
9
  import { callMcpEndpoint } from './mcp-client.js';
9
- import { logInfo, logError } from '../utils/logger.js';
10
10
  /**
11
11
  * List all products the authenticated user has access to
12
12
  */
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Unit tests for feature utility functions
3
3
  */
4
- import { describe, it } from 'node:test';
5
4
  import assert from 'node:assert';
5
+ import { describe, it } from 'node:test';
6
6
  import { filterFeaturesByStatus, sortFeaturesByUpdatedAt, } from '../feature-utils.js';
7
- describe('Feature Utils', () => {
8
- describe('sortFeaturesByUpdatedAt', () => {
9
- it('should sort features by updated_at in ascending order (oldest first)', () => {
7
+ void describe('Feature Utils', () => {
8
+ void describe('sortFeaturesByUpdatedAt', () => {
9
+ void it('should sort features by updated_at in ascending order (oldest first)', () => {
10
10
  const features = [
11
11
  {
12
12
  id: '1',
@@ -36,7 +36,7 @@ describe('Feature Utils', () => {
36
36
  assert.strictEqual(sorted[1].id, '1', 'Second should be Feature 1');
37
37
  assert.strictEqual(sorted[2].id, '3', 'Third should be Feature 3 (newest)');
38
38
  });
39
- it('should handle features with missing updated_at dates', () => {
39
+ void it('should handle features with missing updated_at dates', () => {
40
40
  const features = [
41
41
  {
42
42
  id: '1',
@@ -67,12 +67,12 @@ describe('Feature Utils', () => {
67
67
  assert.strictEqual(sorted[1].id, '3', 'Feature 3 should be second (older date)');
68
68
  assert.strictEqual(sorted[2].id, '1', 'Feature 1 should be third (newer date)');
69
69
  });
70
- it('should handle empty array', () => {
70
+ void it('should handle empty array', () => {
71
71
  const features = [];
72
72
  const sorted = sortFeaturesByUpdatedAt(features);
73
73
  assert.strictEqual(sorted.length, 0, 'Empty array should remain empty');
74
74
  });
75
- it('should handle single feature', () => {
75
+ void it('should handle single feature', () => {
76
76
  const features = [
77
77
  {
78
78
  id: '1',
@@ -86,7 +86,7 @@ describe('Feature Utils', () => {
86
86
  assert.strictEqual(sorted.length, 1, 'Should return single feature');
87
87
  assert.strictEqual(sorted[0].id, '1', 'Should be the same feature');
88
88
  });
89
- it('should create a new array and not mutate the original', () => {
89
+ void it('should create a new array and not mutate the original', () => {
90
90
  const features = [
91
91
  {
92
92
  id: '1',
@@ -111,7 +111,7 @@ describe('Feature Utils', () => {
111
111
  // Sorted array should be different
112
112
  assert.notDeepStrictEqual(sorted.map((f) => f.id), originalOrder, 'Sorted array should have different order');
113
113
  });
114
- it('should handle features with same updated_at timestamps consistently', () => {
114
+ void it('should handle features with same updated_at timestamps consistently', () => {
115
115
  const sameTimestamp = '2024-01-15T10:00:00Z';
116
116
  const features = [
117
117
  {
@@ -141,7 +141,7 @@ describe('Feature Utils', () => {
141
141
  // Order should be stable (same as original for equal timestamps)
142
142
  // Note: JavaScript sort is stable in modern engines
143
143
  });
144
- it('should handle various date formats correctly', () => {
144
+ void it('should handle various date formats correctly', () => {
145
145
  const features = [
146
146
  {
147
147
  id: '1',
@@ -172,8 +172,8 @@ describe('Feature Utils', () => {
172
172
  assert.strictEqual(sorted[2].id, '3', 'Feature 3 should be third (newest)');
173
173
  });
174
174
  });
175
- describe('filterFeaturesByStatus', () => {
176
- it('should filter features by exact status match', () => {
175
+ void describe('filterFeaturesByStatus', () => {
176
+ void it('should filter features by exact status match', () => {
177
177
  const features = [
178
178
  {
179
179
  id: '1',
@@ -199,7 +199,7 @@ describe('Feature Utils', () => {
199
199
  assert.strictEqual(filtered[0].id, '1', 'Should include Feature 1');
200
200
  assert.strictEqual(filtered[1].id, '3', 'Should include Feature 3');
201
201
  });
202
- it('should return empty array when no features match status', () => {
202
+ void it('should return empty array when no features match status', () => {
203
203
  const features = [
204
204
  {
205
205
  id: '1',
@@ -217,14 +217,14 @@ describe('Feature Utils', () => {
217
217
  const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
218
218
  assert.strictEqual(filtered.length, 0, 'Should return empty array');
219
219
  });
220
- it('should handle empty input array', () => {
220
+ void it('should handle empty input array', () => {
221
221
  const features = [];
222
222
  const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
223
223
  assert.strictEqual(filtered.length, 0, 'Should return empty array');
224
224
  });
225
225
  });
226
- describe('Integration Tests - Workflow Processing Order', () => {
227
- it('should process features in oldest-first order for workflow execution', () => {
226
+ void describe('Integration Tests - Workflow Processing Order', () => {
227
+ void it('should process features in oldest-first order for workflow execution', () => {
228
228
  // This test simulates the expected behavior for workflow processing
229
229
  const simulatedWorkflowFeatures = [
230
230
  {
@@ -260,7 +260,7 @@ describe('Feature Utils', () => {
260
260
  assert.ok(timestamps[i] >= timestamps[i - 1], `Feature ${i} should have timestamp >= feature ${i - 1}`);
261
261
  }
262
262
  });
263
- it('should maintain consistent ordering across multiple calls', () => {
263
+ void it('should maintain consistent ordering across multiple calls', () => {
264
264
  const features = [
265
265
  {
266
266
  id: '1',
@@ -292,7 +292,7 @@ describe('Feature Utils', () => {
292
292
  assert.deepStrictEqual(sorted1.map((f) => f.id), sorted2.map((f) => f.id), 'First and second sort should produce same order');
293
293
  assert.deepStrictEqual(sorted2.map((f) => f.id), sorted3.map((f) => f.id), 'Second and third sort should produce same order');
294
294
  });
295
- it('should verify oldest-first ordering is critical for fair workflow processing', () => {
295
+ void it('should verify oldest-first ordering is critical for fair workflow processing', () => {
296
296
  // Test that demonstrates why oldest-first ordering is important
297
297
  const featuresWithVariousAges = [
298
298
  {
@@ -324,12 +324,12 @@ describe('Feature Utils', () => {
324
324
  assert.strictEqual(orderedFeatures[2].id, 'new-enhancement');
325
325
  // Verify the business logic: older items get processed before newer ones
326
326
  // This ensures fairness and prevents newer features from always jumping ahead
327
- const ages = orderedFeatures.map((f) => new Date(f.updated_at).getTime());
327
+ const ages = orderedFeatures.map((f) => new Date(f.updated_at ?? '').getTime());
328
328
  assert.ok(ages[0] <= ages[1] && ages[1] <= ages[2], 'Features should be processed in age order (oldest first)');
329
329
  });
330
330
  });
331
- describe('getReadyForAIFeatures integration behavior', () => {
332
- it('should use sortFeaturesByUpdatedAt to ensure oldest-first processing', () => {
331
+ void describe('getReadyForAIFeatures integration behavior', () => {
332
+ void it('should use sortFeaturesByUpdatedAt to ensure oldest-first processing', () => {
333
333
  // This test verifies the integration between getReadyForAIFeatures and sortFeaturesByUpdatedAt
334
334
  // We can test this indirectly by testing the sorting function that getReadyForAIFeatures uses
335
335
  const mockApiResponse = [
@@ -1,34 +1,34 @@
1
1
  /**
2
2
  * Unit tests for status progression logic
3
3
  */
4
- import { describe, it } from 'node:test';
5
4
  import assert from 'node:assert';
5
+ import { describe, it } from 'node:test';
6
6
  import { STATUS_PROGRESSION_ORDER } from '../../../config/feature-status.js';
7
7
  import { isForwardProgression } from '../status-updater.js';
8
- describe('Status Progression Logic', () => {
9
- describe('isForwardProgression', () => {
10
- it('should allow forward progression', () => {
8
+ void describe('Status Progression Logic', () => {
9
+ void describe('isForwardProgression', () => {
10
+ void it('should allow forward progression', () => {
11
11
  assert.strictEqual(isForwardProgression('backlog', 'ready_for_ai'), true, 'Should allow progression from backlog to ready_for_ai');
12
12
  assert.strictEqual(isForwardProgression('feature_analysis', 'technical_design'), true, 'Should allow progression from feature_analysis to technical_design');
13
13
  assert.strictEqual(isForwardProgression('code_implementation', 'shipped'), true, 'Should allow progression from code_implementation to shipped');
14
14
  });
15
- it('should allow staying at same status', () => {
15
+ void it('should allow staying at same status', () => {
16
16
  assert.strictEqual(isForwardProgression('backlog', 'backlog'), true, 'Should allow staying at backlog status');
17
17
  assert.strictEqual(isForwardProgression('feature_analysis', 'feature_analysis'), true, 'Should allow staying at feature_analysis status');
18
18
  assert.strictEqual(isForwardProgression('shipped', 'shipped'), true, 'Should allow staying at shipped status');
19
19
  });
20
- it('should prevent backward progression', () => {
20
+ void it('should prevent backward progression', () => {
21
21
  assert.strictEqual(isForwardProgression('ready_for_ai', 'backlog'), false, 'Should prevent regression from ready_for_ai to backlog');
22
22
  assert.strictEqual(isForwardProgression('technical_design', 'feature_analysis'), false, 'Should prevent regression from technical_design to feature_analysis');
23
23
  assert.strictEqual(isForwardProgression('shipped', 'code_implementation'), false, 'Should prevent regression from shipped to code_implementation');
24
24
  });
25
- it('should handle edge cases correctly', () => {
25
+ void it('should handle edge cases correctly', () => {
26
26
  // First status to last status
27
27
  assert.strictEqual(isForwardProgression('backlog', 'shipped'), true, 'Should allow progression from first to last status');
28
28
  // Last status to first status
29
29
  assert.strictEqual(isForwardProgression('shipped', 'backlog'), false, 'Should prevent regression from last to first status');
30
30
  });
31
- it('should handle testing workflow correctly', () => {
31
+ void it('should handle testing workflow correctly', () => {
32
32
  // Allow progression through testing states
33
33
  assert.strictEqual(isForwardProgression('functional_testing', 'testing_in_progress'), true, 'Should allow progression to testing_in_progress');
34
34
  assert.strictEqual(isForwardProgression('testing_in_progress', 'testing_passed'), true, 'Should allow progression to testing_passed');
@@ -38,8 +38,8 @@ describe('Status Progression Logic', () => {
38
38
  assert.strictEqual(isForwardProgression('testing_passed', 'testing_in_progress'), false, 'Should prevent going back from testing_passed to testing_in_progress');
39
39
  });
40
40
  });
41
- describe('STATUS_PROGRESSION_ORDER', () => {
42
- it('should contain all expected statuses', () => {
41
+ void describe('STATUS_PROGRESSION_ORDER', () => {
42
+ void it('should contain all expected statuses', () => {
43
43
  const expectedStatuses = [
44
44
  'backlog',
45
45
  'ready_for_ai',
@@ -67,7 +67,7 @@ describe('Status Progression Logic', () => {
67
67
  assert.ok(STATUS_PROGRESSION_ORDER.includes(status), `Should include status: ${status}`);
68
68
  }
69
69
  });
70
- it('should have correct ordering for key workflow phases', () => {
70
+ void it('should have correct ordering for key workflow phases', () => {
71
71
  const backlogIndex = STATUS_PROGRESSION_ORDER.indexOf('backlog');
72
72
  const readyForDevIndex = STATUS_PROGRESSION_ORDER.indexOf('ready_for_ai');
73
73
  const featureAnalysisIndex = STATUS_PROGRESSION_ORDER.indexOf('feature_analysis');
@@ -80,7 +80,7 @@ describe('Status Progression Logic', () => {
80
80
  assert.ok(technicalDesignIndex < codeImplementationIndex, 'technical_design should come before code_implementation');
81
81
  assert.ok(codeImplementationIndex < shippedIndex, 'code_implementation should come before shipped');
82
82
  });
83
- it('should not have duplicate statuses', () => {
83
+ void it('should not have duplicate statuses', () => {
84
84
  const uniqueStatuses = new Set(STATUS_PROGRESSION_ORDER);
85
85
  assert.strictEqual(uniqueStatuses.size, STATUS_PROGRESSION_ORDER.length, 'Should not contain duplicate statuses');
86
86
  });
@@ -2,7 +2,7 @@
2
2
  * Approval workflow integration for feature phases
3
3
  * Checks if current feature status has been approved before executing next phase
4
4
  */
5
- import { logInfo, logError, logWarning } from '../../utils/logger.js';
5
+ import { logError, logInfo, logWarning } from '../../utils/logger.js';
6
6
  import { callMcpEndpoint } from '../mcp-client.js';
7
7
  import { getFeature } from './get-feature.js';
8
8
  /**
@@ -1,4 +1,4 @@
1
- import { UserStoryStatus, TestCaseStatus } from '../../types/index.js';
1
+ import { type TestCaseStatus, type UserStoryStatus } from '../../types/index.js';
2
2
  /**
3
3
  * Batch update user story statuses
4
4
  */
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../../utils/logger.js';
1
+ import { logError, logInfo } from '../../utils/logger.js';
2
2
  import { callMcpEndpoint } from '../mcp-client.js';
3
3
  /**
4
4
  * Batch update user story statuses
@@ -1,4 +1,4 @@
1
- import { FeatureInfo } from '../../types/features.js';
1
+ import { type FeatureInfo } from '../../types/features.js';
2
2
  /**
3
3
  * Claim the next available ready_for_ai feature for processing.
4
4
  * Uses database-level locking (FOR UPDATE SKIP LOCKED) to prevent
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../../utils/logger.js';
1
+ import { logError, logInfo } from '../../utils/logger.js';
2
2
  import { callMcpEndpoint } from '../mcp-client.js';
3
3
  /**
4
4
  * Claim the next available ready_for_ai feature for processing.
@@ -1,4 +1,4 @@
1
- import { FeatureInfo } from '../../types/features.js';
1
+ import { type FeatureInfo } from '../../types/features.js';
2
2
  /**
3
3
  * Get feature details by ID
4
4
  */
@@ -1,8 +1,8 @@
1
+ export * from './batch-operations.js';
2
+ export * from './feature-utils.js';
1
3
  export * from './get-feature.js';
4
+ export * from './status-updater.js';
5
+ export * from './test-cases.js';
2
6
  export * from './update-feature.js';
3
7
  export * from './user-stories.js';
4
- export * from './test-cases.js';
5
- export * from './feature-utils.js';
6
- export * from './status-updater.js';
7
- export * from './batch-operations.js';
8
8
  export * from '../../types/features.js';
@@ -1,10 +1,10 @@
1
1
  // Re-export all feature-related functions
2
+ export * from './batch-operations.js';
3
+ export * from './feature-utils.js';
2
4
  export * from './get-feature.js';
5
+ export * from './status-updater.js';
6
+ export * from './test-cases.js';
3
7
  export * from './update-feature.js';
4
8
  export * from './user-stories.js';
5
- export * from './test-cases.js';
6
- export * from './feature-utils.js';
7
- export * from './status-updater.js';
8
- export * from './batch-operations.js';
9
9
  // Re-export types
10
10
  export * from '../../types/features.js';
@@ -2,10 +2,10 @@
2
2
  * Feature status updater for workflow pipeline
3
3
  * Updates feature status at each phase of the development workflow
4
4
  */
5
- import { logInfo, logError } from '../../utils/logger.js';
5
+ import { PHASE_STATUS_MAP, STATUS_PROGRESSION_ORDER, } from '../../config/feature-status.js';
6
+ import { logError, logInfo } from '../../utils/logger.js';
6
7
  import { callMcpEndpoint } from '../mcp-client.js';
7
8
  import { getFeature } from './get-feature.js';
8
- import { STATUS_PROGRESSION_ORDER, PHASE_STATUS_MAP, } from '../../config/feature-status.js';
9
9
  /**
10
10
  * Check if moving from currentStatus to newStatus is forward progression
11
11
  *
@@ -15,11 +15,13 @@ import { STATUS_PROGRESSION_ORDER, PHASE_STATUS_MAP, } from '../../config/featur
15
15
  */
16
16
  export function isForwardProgression(currentStatus, newStatus) {
17
17
  // Any status can transition to archived
18
- if (newStatus === 'archived')
18
+ if (newStatus === 'archived') {
19
19
  return true;
20
+ }
20
21
  // Archived can only transition back to backlog (unarchive)
21
- if (currentStatus === 'archived')
22
+ if (currentStatus === 'archived') {
22
23
  return newStatus === 'backlog';
24
+ }
23
25
  const currentIndex = STATUS_PROGRESSION_ORDER.indexOf(currentStatus);
24
26
  const newIndex = STATUS_PROGRESSION_ORDER.indexOf(newStatus);
25
27
  // Allow moving forward or staying at same level (for retries, etc.)
@@ -1,4 +1,4 @@
1
- import { TestCase, TestCaseStatus } from '../../types/features.js';
1
+ import { type TestCase, type TestCaseStatus } from '../../types/features.js';
2
2
  /**
3
3
  * Get test cases for a feature
4
4
  */
@@ -14,11 +14,11 @@ export declare function createTestCase(featureId: string, testCase: {
14
14
  /**
15
15
  * Create multiple test cases for a feature
16
16
  */
17
- export declare function createTestCases(mcpServerUrl: string, mcpToken: string, featureId: string, testCases: Array<{
17
+ export declare function createTestCases(mcpServerUrl: string, mcpToken: string, featureId: string, testCases: {
18
18
  name: string;
19
19
  description: string;
20
20
  is_critical?: boolean;
21
- }>, verbose?: boolean): Promise<boolean>;
21
+ }[], verbose?: boolean): Promise<boolean>;
22
22
  /**
23
23
  * Delete a test case
24
24
  */
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../../utils/logger.js';
1
+ import { logError, logInfo } from '../../utils/logger.js';
2
2
  import { callMcpEndpoint } from '../mcp-client.js';
3
3
  /**
4
4
  * Get test cases for a feature
@@ -1,4 +1,4 @@
1
- import { FeatureWorkflow } from '../../types/pipeline.js';
1
+ import { type FeatureWorkflow } from '../../types/pipeline.js';
2
2
  /**
3
3
  * Update feature with new data
4
4
  */
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../../utils/logger.js';
1
+ import { logError, logInfo } from '../../utils/logger.js';
2
2
  import { callMcpEndpoint } from '../mcp-client.js';
3
3
  /**
4
4
  * Update feature with new data
@@ -1,4 +1,4 @@
1
- import { UserStory, UserStoryStatus } from '../../types/features.js';
1
+ import { type UserStory, type UserStoryStatus } from '../../types/features.js';
2
2
  /**
3
3
  * Get user stories for a feature
4
4
  */
@@ -1,4 +1,4 @@
1
- import { logInfo, logError } from '../../utils/logger.js';
1
+ import { logError, logInfo } from '../../utils/logger.js';
2
2
  import { callMcpEndpoint } from '../mcp-client.js';
3
3
  /**
4
4
  * Get user stories for a feature
@@ -2,8 +2,8 @@
2
2
  * GitHub API client for accessing GitHub via MCP server
3
3
  * Uses product developer configuration from the database
4
4
  */
5
+ import { logDebug, logError, logSuccess, logWarning } from '../utils/logger.js';
5
6
  import { callMcpEndpoint } from './mcp-client.js';
6
- import { logDebug, logSuccess, logWarning, logError } from '../utils/logger.js';
7
7
  /**
8
8
  * Get GitHub developer configuration for a feature
9
9
  * Returns installation_id, repository info from product_developers