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.
- package/dist/api/__tests__/app-store.test.d.ts +7 -0
- package/dist/api/__tests__/app-store.test.js +60 -0
- package/dist/api/app-store.d.ts +7 -3
- package/dist/api/app-store.js +35 -2
- package/dist/api/chat.d.ts +4 -4
- package/dist/api/chat.js +4 -4
- package/dist/api/cross-product.d.ts +1 -1
- package/dist/api/cross-product.js +1 -1
- package/dist/api/features/__tests__/feature-utils.test.js +21 -21
- package/dist/api/features/__tests__/status-updater.test.js +12 -12
- package/dist/api/features/approval-checker.js +1 -1
- package/dist/api/features/batch-operations.d.ts +1 -1
- package/dist/api/features/batch-operations.js +1 -1
- package/dist/api/features/feature-utils.d.ts +1 -1
- package/dist/api/features/feature-utils.js +1 -1
- package/dist/api/features/get-feature.d.ts +1 -1
- package/dist/api/features/index.d.ts +4 -4
- package/dist/api/features/index.js +4 -4
- package/dist/api/features/status-updater.js +6 -4
- package/dist/api/features/test-cases.d.ts +3 -3
- package/dist/api/features/test-cases.js +1 -1
- package/dist/api/features/update-feature.d.ts +1 -1
- package/dist/api/features/update-feature.js +1 -1
- package/dist/api/features/user-stories.d.ts +1 -1
- package/dist/api/features/user-stories.js +1 -1
- package/dist/api/github.js +1 -1
- package/dist/api/growth.d.ts +8 -8
- package/dist/api/growth.js +1 -1
- package/dist/api/products.d.ts +6 -1
- package/dist/api/storage.d.ts +1 -1
- package/dist/api/storage.js +6 -3
- package/dist/api/tasks.js +1 -1
- package/dist/api/test-reports.d.ts +1 -1
- package/dist/api/test-reports.js +1 -1
- package/dist/auth/auth-store.js +5 -4
- package/dist/auth/env-store.d.ts +2 -2
- package/dist/auth/env-store.js +3 -3
- package/dist/auth/login.d.ts +2 -2
- package/dist/auth/login.js +5 -5
- package/dist/commands/agent-workflow/chat-worker.js +28 -12
- package/dist/commands/agent-workflow/feature-worker.js +2 -2
- package/dist/commands/agent-workflow/index.d.ts +1 -1
- package/dist/commands/agent-workflow/index.js +13 -9
- package/dist/commands/agent-workflow/processor.d.ts +1 -1
- package/dist/commands/agent-workflow/processor.js +56 -23
- package/dist/commands/analyze-logs/index.d.ts +1 -1
- package/dist/commands/analyze-logs/index.js +1 -1
- package/dist/commands/app-store/index.d.ts +1 -1
- package/dist/commands/app-store/index.js +11 -13
- package/dist/commands/checklists/index.d.ts +13 -0
- package/dist/commands/checklists/index.js +120 -0
- package/dist/commands/checklists/tools.d.ts +10 -0
- package/dist/commands/checklists/tools.js +212 -0
- package/dist/commands/code-review/index.d.ts +1 -1
- package/dist/commands/code-review/index.js +2 -2
- package/dist/commands/code-review/reviewer.d.ts +1 -1
- package/dist/commands/code-review/reviewer.js +46 -39
- package/dist/commands/config/index.js +2 -2
- package/dist/commands/growth-analysis/index.d.ts +1 -1
- package/dist/commands/growth-analysis/index.js +9 -7
- package/dist/commands/init/index.d.ts +1 -1
- package/dist/commands/init/index.js +36 -30
- package/dist/commands/refactor/refactor.d.ts +1 -1
- package/dist/commands/refactor/refactor.js +28 -22
- package/dist/commands/task-worker/index.d.ts +1 -1
- package/dist/commands/task-worker/processor.d.ts +1 -1
- package/dist/commands/task-worker/processor.js +9 -6
- package/dist/commands/workflow/config/phase-configs.d.ts +1 -1
- package/dist/commands/workflow/config/phase-configs.js +10 -10
- package/dist/commands/workflow/core/__tests__/feature-filter.test.js +57 -66
- package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.js +74 -83
- package/dist/commands/workflow/core/__tests__/state-manager.test.js +35 -35
- package/dist/commands/workflow/core/feature-filter.js +2 -1
- package/dist/commands/workflow/core/workflow-logger.js +3 -3
- package/dist/commands/workflow/executors/phase-executor.d.ts +3 -3
- package/dist/commands/workflow/executors/phase-executor.js +137 -116
- package/dist/commands/workflow/feature-coordinator.d.ts +2 -2
- package/dist/commands/workflow/feature-coordinator.js +1 -1
- package/dist/commands/workflow/index.d.ts +1 -1
- package/dist/commands/workflow/index.js +2 -2
- package/dist/commands/workflow/phase-orchestrator.d.ts +2 -2
- package/dist/commands/workflow/phase-orchestrator.js +13 -5
- package/dist/commands/workflow/processor.d.ts +1 -1
- package/dist/commands/workflow/processor.js +5 -5
- package/dist/config/__tests__/config.test.js +35 -35
- package/dist/config/__tests__/feature-status.test.js +16 -16
- package/dist/config.d.ts +1 -1
- package/dist/constants.js +3 -2
- package/dist/errors/__tests__/index.test.js +81 -81
- package/dist/index.d.ts +2 -2
- package/dist/index.js +41 -17
- package/dist/phases/analyze-logs/agent.js +7 -4
- package/dist/phases/analyze-logs/index.js +1 -1
- package/dist/phases/analyze-logs/prompts.d.ts +1 -1
- package/dist/phases/app-store-generation/__tests__/agent.test.js +11 -11
- package/dist/phases/app-store-generation/__tests__/context.test.js +39 -35
- package/dist/phases/app-store-generation/__tests__/prompts.test.js +33 -33
- package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.js +50 -50
- package/dist/phases/app-store-generation/agent.d.ts +2 -2
- package/dist/phases/app-store-generation/agent.js +12 -5
- package/dist/phases/app-store-generation/context.d.ts +1 -1
- package/dist/phases/app-store-generation/context.js +4 -3
- package/dist/phases/app-store-generation/index.d.ts +4 -3
- package/dist/phases/app-store-generation/index.js +46 -37
- package/dist/phases/app-store-generation/prompts.js +12 -10
- package/dist/phases/app-store-generation/screenshot-composer.d.ts +0 -1
- package/dist/phases/app-store-generation/screenshot-composer.js +55 -49
- package/dist/phases/app-store-generation/uploader.d.ts +3 -2
- package/dist/phases/app-store-generation/uploader.js +26 -16
- package/dist/phases/autonomous/index.d.ts +12 -4
- package/dist/phases/autonomous/index.js +192 -137
- package/dist/phases/autonomous/prompts.d.ts +1 -1
- package/dist/phases/branch-planning/context.d.ts +1 -1
- package/dist/phases/branch-planning/context.js +2 -2
- package/dist/phases/branch-planning/index.d.ts +2 -2
- package/dist/phases/branch-planning/index.js +178 -132
- package/dist/phases/branch-planning/outcome.d.ts +1 -1
- package/dist/phases/branch-planning/outcome.js +2 -1
- package/dist/phases/branch-planning/prompts.d.ts +6 -6
- package/dist/phases/bug-fixing/analyzer.d.ts +1 -1
- package/dist/phases/bug-fixing/analyzer.js +56 -68
- package/dist/phases/bug-fixing/context-fetcher.d.ts +1 -1
- package/dist/phases/bug-fixing/context-fetcher.js +6 -4
- package/dist/phases/bug-fixing/index.d.ts +1 -1
- package/dist/phases/bug-fixing/index.js +1 -1
- package/dist/phases/bug-fixing/prompts.d.ts +1 -1
- package/dist/phases/chat-processor/context.d.ts +6 -6
- package/dist/phases/chat-processor/context.js +7 -1
- package/dist/phases/chat-processor/index.d.ts +10 -1
- package/dist/phases/chat-processor/index.js +43 -28
- package/dist/phases/chat-processor/product-context.d.ts +4 -4
- package/dist/phases/chat-processor/product-context.js +13 -5
- package/dist/phases/chat-processor/product-tools.js +90 -44
- package/dist/phases/chat-processor/prompts.d.ts +2 -2
- package/dist/phases/chat-processor/tools.js +119 -55
- package/dist/phases/code-implementation/branch-pr-creator.js +11 -6
- package/dist/phases/code-implementation/context.d.ts +1 -1
- package/dist/phases/code-implementation/context.js +6 -4
- package/dist/phases/code-implementation/index.d.ts +6 -6
- package/dist/phases/code-implementation/index.js +236 -154
- package/dist/phases/code-implementation/outcome.d.ts +32 -4
- package/dist/phases/code-implementation/outcome.js +4 -2
- package/dist/phases/code-implementation/prompts.d.ts +2 -2
- package/dist/phases/code-implementation-verification/agent.d.ts +2 -1
- package/dist/phases/code-implementation-verification/agent.js +148 -127
- package/dist/phases/code-implementation-verification/index.d.ts +16 -4
- package/dist/phases/code-implementation-verification/index.js +4 -9
- package/dist/phases/code-implementation-verification/prompts.d.ts +10 -2
- package/dist/phases/code-implementation-verification/prompts.js +2 -1
- package/dist/phases/code-refine/context.js +19 -7
- package/dist/phases/code-refine/index.d.ts +9 -9
- package/dist/phases/code-refine/index.js +57 -190
- package/dist/phases/code-refine/prompts.d.ts +2 -2
- package/dist/phases/code-refine/prompts.js +3 -3
- package/dist/phases/code-refine/refine-iteration.d.ts +33 -0
- package/dist/phases/code-refine/refine-iteration.js +165 -0
- package/dist/phases/code-refine/retry-handler.d.ts +2 -2
- package/dist/phases/code-refine/retry-handler.js +6 -4
- package/dist/phases/code-refine-verification/github.d.ts +12 -4
- package/dist/phases/code-refine-verification/github.js +13 -7
- package/dist/phases/code-refine-verification/index.d.ts +1 -1
- package/dist/phases/code-refine-verification/index.js +5 -4
- package/dist/phases/code-refine-verification/llm-analyzer.d.ts +4 -4
- package/dist/phases/code-refine-verification/llm-analyzer.js +49 -33
- package/dist/phases/code-refine-verification/prompts.d.ts +1 -1
- package/dist/phases/code-refine-verification/prompts.js +1 -2
- package/dist/phases/code-refine-verification/types.d.ts +7 -7
- package/dist/phases/code-review/context.js +6 -2
- package/dist/phases/code-review/index.d.ts +5 -5
- package/dist/phases/code-review/index.js +134 -96
- package/dist/phases/code-testing/analyzer.d.ts +2 -2
- package/dist/phases/code-testing/analyzer.js +87 -96
- package/dist/phases/code-testing/context-fetcher.d.ts +1 -1
- package/dist/phases/code-testing/context-fetcher.js +6 -4
- package/dist/phases/code-testing/index.d.ts +2 -2
- package/dist/phases/code-testing/prompts.d.ts +1 -1
- package/dist/phases/feature-analysis/agent.d.ts +13 -2
- package/dist/phases/feature-analysis/agent.js +12 -4
- package/dist/phases/feature-analysis/context.d.ts +2 -2
- package/dist/phases/feature-analysis/context.js +9 -7
- package/dist/phases/feature-analysis/index.d.ts +2 -2
- package/dist/phases/feature-analysis/index.js +44 -8
- package/dist/phases/feature-analysis/outcome.d.ts +3 -3
- package/dist/phases/feature-analysis/outcome.js +18 -9
- package/dist/phases/feature-analysis/prompts.d.ts +3 -3
- package/dist/phases/feature-analysis-verification/agent.d.ts +4 -4
- package/dist/phases/feature-analysis-verification/agent.js +43 -37
- package/dist/phases/feature-analysis-verification/index.d.ts +15 -5
- package/dist/phases/feature-analysis-verification/index.js +9 -9
- package/dist/phases/feature-analysis-verification/prompts.d.ts +2 -2
- package/dist/phases/functional-testing/analyzer.d.ts +10 -10
- package/dist/phases/functional-testing/analyzer.js +343 -307
- package/dist/phases/functional-testing/context-fetcher.d.ts +1 -1
- package/dist/phases/functional-testing/context-fetcher.js +6 -4
- package/dist/phases/functional-testing/http-fallback.js +1 -1
- package/dist/phases/functional-testing/index.d.ts +3 -3
- package/dist/phases/functional-testing/index.js +2 -2
- package/dist/phases/functional-testing/prompts.d.ts +1 -1
- package/dist/phases/functional-testing/test-report-creator.js +23 -15
- package/dist/phases/functional-testing/test-retry-handler.d.ts +2 -2
- package/dist/phases/functional-testing/test-retry-handler.js +9 -5
- package/dist/phases/growth-analysis/agent.d.ts +2 -2
- package/dist/phases/growth-analysis/agent.js +12 -5
- package/dist/phases/growth-analysis/context.d.ts +1 -1
- package/dist/phases/growth-analysis/context.js +2 -2
- package/dist/phases/growth-analysis/index.d.ts +5 -5
- package/dist/phases/growth-analysis/index.js +46 -37
- package/dist/phases/growth-analysis/prompts.js +4 -2
- package/dist/phases/pr-execution/context.d.ts +1 -1
- package/dist/phases/pr-execution/context.js +15 -9
- package/dist/phases/pr-execution/index.d.ts +1 -1
- package/dist/phases/pr-execution/index.js +29 -17
- package/dist/phases/pr-execution/pr-executor.js +2 -2
- package/dist/phases/pr-execution/prompts.d.ts +9 -1
- package/dist/phases/pr-execution/prompts.js +2 -4
- package/dist/phases/pr-splitting/context.d.ts +1 -1
- package/dist/phases/pr-splitting/context.js +15 -8
- package/dist/phases/pr-splitting/index.d.ts +4 -4
- package/dist/phases/pr-splitting/index.js +47 -39
- package/dist/phases/pr-splitting/outcome.d.ts +1 -1
- package/dist/phases/pr-splitting/outcome.js +2 -1
- package/dist/phases/pr-splitting/prompts.d.ts +7 -7
- package/dist/phases/pr-splitting/prompts.js +8 -2
- package/dist/phases/pull-request/creator.js +30 -13
- package/dist/phases/pull-request/handler.d.ts +1 -1
- package/dist/phases/pull-request/handler.js +6 -3
- package/dist/phases/task/agent.d.ts +1 -1
- package/dist/phases/task/agent.js +20 -12
- package/dist/phases/task/context.js +1 -1
- package/dist/phases/task/index.d.ts +1 -1
- package/dist/phases/task/index.js +3 -3
- package/dist/phases/technical-design/context.d.ts +1 -1
- package/dist/phases/technical-design/context.js +2 -2
- package/dist/phases/technical-design/index.d.ts +2 -2
- package/dist/phases/technical-design/index.js +134 -116
- package/dist/phases/technical-design/outcome.js +3 -1
- package/dist/phases/technical-design/prompts.d.ts +2 -2
- package/dist/phases/technical-design/prompts.js +2 -0
- package/dist/phases/technical-design-verification/agent.d.ts +3 -3
- package/dist/phases/technical-design-verification/agent.js +54 -41
- package/dist/phases/technical-design-verification/index.d.ts +18 -6
- package/dist/phases/technical-design-verification/index.js +7 -8
- package/dist/phases/technical-design-verification/prompts.d.ts +3 -3
- package/dist/phases/technical-design-verification/prompts.js +5 -8
- package/dist/phases/test-cases-analysis/agent.d.ts +9 -2
- package/dist/phases/test-cases-analysis/agent.js +12 -4
- package/dist/phases/test-cases-analysis/context.d.ts +2 -2
- package/dist/phases/test-cases-analysis/context.js +5 -5
- package/dist/phases/test-cases-analysis/formatters.d.ts +1 -1
- package/dist/phases/test-cases-analysis/formatters.js +1 -1
- package/dist/phases/test-cases-analysis/index.d.ts +3 -3
- package/dist/phases/test-cases-analysis/index.js +42 -9
- package/dist/phases/test-cases-analysis/outcome.d.ts +1 -1
- package/dist/phases/test-cases-analysis/outcome.js +13 -5
- package/dist/phases/test-cases-analysis/prompts.d.ts +2 -2
- package/dist/phases/user-stories-analysis/agent.d.ts +9 -2
- package/dist/phases/user-stories-analysis/agent.js +12 -4
- package/dist/phases/user-stories-analysis/context.d.ts +2 -2
- package/dist/phases/user-stories-analysis/context.js +5 -5
- package/dist/phases/user-stories-analysis/formatters.d.ts +1 -1
- package/dist/phases/user-stories-analysis/formatters.js +1 -1
- package/dist/phases/user-stories-analysis/index.d.ts +3 -3
- package/dist/phases/user-stories-analysis/index.js +42 -9
- package/dist/phases/user-stories-analysis/outcome.d.ts +1 -1
- package/dist/phases/user-stories-analysis/outcome.js +14 -6
- package/dist/phases/user-stories-analysis/prompts.d.ts +2 -2
- package/dist/services/audit-logs.d.ts +10 -10
- package/dist/services/audit-logs.js +1 -1
- package/dist/services/branches.d.ts +3 -3
- package/dist/services/branches.js +10 -7
- package/dist/services/checklist.d.ts +9 -9
- package/dist/services/checklist.js +36 -38
- package/dist/services/coaching/__tests__/coaching-agent.test.d.ts +1 -0
- package/dist/services/coaching/__tests__/coaching-agent.test.js +74 -0
- package/dist/services/coaching/__tests__/coaching-loop.test.d.ts +1 -0
- package/dist/services/coaching/__tests__/coaching-loop.test.js +59 -0
- package/dist/services/coaching/__tests__/self-rating.test.d.ts +1 -0
- package/dist/services/coaching/__tests__/self-rating.test.js +188 -0
- package/dist/services/coaching/coaching-agent.d.ts +39 -0
- package/dist/services/coaching/coaching-agent.js +283 -0
- package/dist/services/coaching/coaching-loop.d.ts +62 -0
- package/dist/services/coaching/coaching-loop.js +265 -0
- package/dist/services/coaching/index.d.ts +8 -0
- package/dist/services/coaching/index.js +8 -0
- package/dist/services/coaching/phase-coaching.d.ts +47 -0
- package/dist/services/coaching/phase-coaching.js +60 -0
- package/dist/services/coaching/self-rating.d.ts +26 -0
- package/dist/services/coaching/self-rating.js +153 -0
- package/dist/services/feedbacks.d.ts +1 -1
- package/dist/services/feedbacks.js +15 -10
- package/dist/services/phase-ratings.d.ts +70 -0
- package/dist/services/phase-ratings.js +80 -0
- package/dist/services/product-logs.js +2 -1
- package/dist/services/pull-requests.d.ts +5 -5
- package/dist/services/pull-requests.js +2 -2
- package/dist/services/video/__tests__/video-pipeline.test.js +53 -37
- package/dist/services/video/device-frames.js +16 -3
- package/dist/services/video/index.d.ts +1 -1
- package/dist/services/video/index.js +22 -16
- package/dist/services/video/screenshot-generator.d.ts +3 -1
- package/dist/services/video/screenshot-generator.js +10 -8
- package/dist/services/video/tts-generator.d.ts +2 -2
- package/dist/services/video/tts-generator.js +2 -2
- package/dist/services/video/video-assembler.js +102 -55
- package/dist/services/video/video-uploader.js +7 -6
- package/dist/system/session-manager.js +8 -4
- package/dist/system/sleep-notification.js +5 -2
- package/dist/types/features.d.ts +1 -1
- package/dist/types/index.d.ts +9 -2
- package/dist/types/llm-responses.d.ts +22 -22
- package/dist/types/pipeline.d.ts +2 -2
- package/dist/updater/auto-updater.js +5 -3
- package/dist/utils/conflict-resolver.js +26 -21
- package/dist/utils/formatters.d.ts +5 -5
- package/dist/utils/formatters.js +4 -2
- package/dist/utils/git-branch-manager-async.d.ts +127 -0
- package/dist/utils/git-branch-manager-async.js +423 -0
- package/dist/utils/git-branch-manager.d.ts +1 -114
- package/dist/utils/git-branch-manager.js +31 -427
- package/dist/utils/git-push.js +12 -3
- package/dist/utils/image-downloader.js +29 -21
- package/dist/utils/json-extractor.d.ts +27 -0
- package/dist/utils/json-extractor.js +102 -0
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +24 -15
- package/dist/utils/pipeline-logger.d.ts +1 -1
- package/dist/utils/pipeline-logger.js +1 -1
- package/dist/utils/validation.d.ts +4 -3
- package/dist/utils/workflow-utils.d.ts +3 -2
- package/dist/utils/workflow-utils.js +2 -2
- package/dist/workspace/workspace-manager.d.ts +1 -1
- package/dist/workspace/workspace-manager.js +10 -5
- package/eslint.config.mjs +22 -0
- package/package.json +3 -1
|
@@ -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
|
+
});
|
package/dist/api/app-store.d.ts
CHANGED
|
@@ -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[]
|
|
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>;
|
package/dist/api/app-store.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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
|
+
}
|
package/dist/api/chat.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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,
|
|
35
|
-
export declare function getUnreadCount(channelId: string,
|
|
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,
|
|
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,
|
|
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,
|
|
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 {
|
|
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,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 {
|
|
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:
|
|
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
|
-
}
|
|
21
|
+
}[], verbose?: boolean): Promise<boolean>;
|
|
22
22
|
/**
|
|
23
23
|
* Delete a test case
|
|
24
24
|
*/
|
package/dist/api/github.js
CHANGED
|
@@ -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
|