reviewflow 3.40.0 → 3.40.2

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 (70) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/frameworks/claude/claudeInvoker.d.ts.map +1 -1
  3. package/dist/frameworks/claude/claudeInvoker.js +12 -0
  4. package/dist/frameworks/claude/claudeInvoker.js.map +1 -1
  5. package/dist/main/routes.d.ts.map +1 -1
  6. package/dist/main/routes.js +6 -2
  7. package/dist/main/routes.js.map +1 -1
  8. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.d.ts +1 -0
  9. package/dist/modules/platform-integration/entities/webhookEvent/webhookEvent.d.ts.map +1 -1
  10. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.d.ts +1 -2
  11. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.d.ts.map +1 -1
  12. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.js +129 -188
  13. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/github.controller.js.map +1 -1
  14. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.d.ts +1 -2
  15. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.d.ts.map +1 -1
  16. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.js +129 -209
  17. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/gitlab.controller.js.map +1 -1
  18. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.d.ts +71 -0
  19. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.d.ts.map +1 -0
  20. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.js +104 -0
  21. package/dist/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.js.map +1 -0
  22. package/dist/modules/platform-integration/usecases/processReviewRequest.usecase.d.ts +39 -0
  23. package/dist/modules/platform-integration/usecases/processReviewRequest.usecase.d.ts.map +1 -0
  24. package/dist/modules/platform-integration/usecases/processReviewRequest.usecase.js +45 -0
  25. package/dist/modules/platform-integration/usecases/processReviewRequest.usecase.js.map +1 -0
  26. package/dist/modules/platform-integration/usecases/processWebhook.usecase.d.ts +16 -0
  27. package/dist/modules/platform-integration/usecases/processWebhook.usecase.d.ts.map +1 -1
  28. package/dist/modules/platform-integration/usecases/processWebhook.usecase.js +44 -1
  29. package/dist/modules/platform-integration/usecases/processWebhook.usecase.js.map +1 -1
  30. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-B.acceptance.test.js +3 -3
  31. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-B.acceptance.test.js.map +1 -1
  32. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-C.acceptance.test.js +22 -2
  33. package/dist/tests/acceptance/180-quality-threshold-block-approval-iter-C.acceptance.test.js.map +1 -1
  34. package/dist/tests/acceptance/197-trusted-actor-provenance-gate.acceptance.test.js +14 -12
  35. package/dist/tests/acceptance/197-trusted-actor-provenance-gate.acceptance.test.js.map +1 -1
  36. package/dist/tests/acceptance/200-webhook-event-idempotency.acceptance.test.js +10 -8
  37. package/dist/tests/acceptance/200-webhook-event-idempotency.acceptance.test.js.map +1 -1
  38. package/dist/tests/acceptance/46-github-followup-review-on-push.acceptance.test.js +8 -6
  39. package/dist/tests/acceptance/46-github-followup-review-on-push.acceptance.test.js.map +1 -1
  40. package/dist/tests/acceptance/73-process-webhook.acceptance.test.js +2 -0
  41. package/dist/tests/acceptance/73-process-webhook.acceptance.test.js.map +1 -1
  42. package/dist/tests/acceptance/73-stage4-controller-thinning.acceptance.test.d.ts +2 -0
  43. package/dist/tests/acceptance/73-stage4-controller-thinning.acceptance.test.d.ts.map +1 -0
  44. package/dist/tests/acceptance/73-stage4-controller-thinning.acceptance.test.js +226 -0
  45. package/dist/tests/acceptance/73-stage4-controller-thinning.acceptance.test.js.map +1 -0
  46. package/dist/tests/units/frameworks/claude/claudeInvoker.test.js +15 -0
  47. package/dist/tests/units/frameworks/claude/claudeInvoker.test.js.map +1 -1
  48. package/dist/tests/units/interface-adapters/controllers/webhook/github.controller.test.js +50 -70
  49. package/dist/tests/units/interface-adapters/controllers/webhook/github.controller.test.js.map +1 -1
  50. package/dist/tests/units/interface-adapters/controllers/webhook/gitlab.controller.test.js +51 -47
  51. package/dist/tests/units/interface-adapters/controllers/webhook/gitlab.controller.test.js.map +1 -1
  52. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/gitlabIdempotency.controller.test.js +7 -5
  53. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/gitlabIdempotency.controller.test.js.map +1 -1
  54. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.test.d.ts +2 -0
  55. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.test.d.ts.map +1 -0
  56. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.test.js +309 -0
  57. package/dist/tests/units/modules/platform-integration/interface-adapters/controllers/webhook/webhookReply.test.js.map +1 -0
  58. package/dist/tests/units/modules/platform-integration/usecases/processReviewRequest.usecase.test.d.ts +2 -0
  59. package/dist/tests/units/modules/platform-integration/usecases/processReviewRequest.usecase.test.d.ts.map +1 -0
  60. package/dist/tests/units/modules/platform-integration/usecases/processReviewRequest.usecase.test.js +170 -0
  61. package/dist/tests/units/modules/platform-integration/usecases/processReviewRequest.usecase.test.js.map +1 -0
  62. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.js +99 -8
  63. package/dist/tests/units/modules/platform-integration/usecases/processWebhook.usecase.test.js.map +1 -1
  64. package/package.json +1 -1
  65. package/templates/en/followup-basic/SKILL.md +12 -0
  66. package/templates/en/review-basic/SKILL.md +12 -0
  67. package/templates/en/review-with-agents/SKILL.md +12 -0
  68. package/templates/fr/followup-basic/SKILL.md +12 -0
  69. package/templates/fr/review-basic/SKILL.md +12 -0
  70. package/templates/fr/review-with-agents/SKILL.md +12 -0
@@ -0,0 +1,226 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { processReviewRequest, } from '../../modules/platform-integration/usecases/processReviewRequest.usecase.js';
3
+ import { processWebhook, } from '../../modules/platform-integration/usecases/processWebhook.usecase.js';
4
+ import { evaluateQualityGate } from '../../modules/tracking/entities/qualityGate/qualityGate.js';
5
+ import { HandlePlatformApprovalUseCase } from '../../modules/tracking/usecases/tracking/handlePlatformApproval.usecase.js';
6
+ import { TransitionStateUseCase } from '../../modules/tracking/usecases/tracking/transitionState.usecase.js';
7
+ import { TrackedMrFactory } from '../../tests/factories/trackedMr.factory.js';
8
+ import { createStubLogger } from '../../tests/stubs/logger.stub.js';
9
+ import { InMemoryReviewRequestTrackingGateway } from '../../tests/stubs/reviewRequestTracking.stub.js';
10
+ const PROJECT_PATH = '/checkout/project';
11
+ function buildApproveEvent() {
12
+ return {
13
+ type: 'approve',
14
+ platform: 'gitlab',
15
+ projectPath: 'group/project',
16
+ localPath: PROJECT_PATH,
17
+ mergeRequestNumber: 42,
18
+ reviewId: null,
19
+ };
20
+ }
21
+ function buildDeps(tracked, threshold) {
22
+ const trackingGateway = new InMemoryReviewRequestTrackingGateway();
23
+ if (tracked) {
24
+ trackingGateway.create(PROJECT_PATH, tracked);
25
+ }
26
+ return {
27
+ handleClose: async () => ({
28
+ status: 'cleaned',
29
+ jobCancelled: true,
30
+ trackingArchived: true,
31
+ contextDeleted: true,
32
+ }),
33
+ transitionState: new TransitionStateUseCase(trackingGateway),
34
+ recordPush: { execute: () => null },
35
+ checkFollowupNeeded: { execute: () => false },
36
+ removeWorktree: async () => ({ status: 'removed' }),
37
+ handlePlatformApproval: new HandlePlatformApprovalUseCase(trackingGateway),
38
+ getQualityThreshold: () => threshold,
39
+ logger: createStubLogger(),
40
+ };
41
+ }
42
+ describe('SPEC-073 Stage 4b — approve verdict via processWebhook (acceptance)', () => {
43
+ describe('the approve verdict is decided inward, platform-neutral', () => {
44
+ it('approved: a tracked MR clearing the quality gate transitions to approved', async () => {
45
+ const tracked = TrackedMrFactory.create({
46
+ id: 'gitlab-group/project-42',
47
+ latestScore: 9,
48
+ openThreads: 0,
49
+ bypass: null,
50
+ });
51
+ const result = await processWebhook(buildApproveEvent(), buildDeps(tracked, 8));
52
+ expect(result).toEqual({ type: 'approved', mergeRequestNumber: 42 });
53
+ });
54
+ it('approval-revoked: a sub-threshold tracked MR is reverted with a revoke message', async () => {
55
+ const tracked = TrackedMrFactory.create({
56
+ id: 'gitlab-group/project-42',
57
+ latestScore: 4,
58
+ openThreads: 0,
59
+ bypass: null,
60
+ });
61
+ const result = await processWebhook(buildApproveEvent(), buildDeps(tracked, 8));
62
+ expect(result.type).toBe('approval-revoked');
63
+ if (result.type !== 'approval-revoked')
64
+ throw new Error('expected approval-revoked');
65
+ expect(result.mergeRequestNumber).toBe(42);
66
+ expect(result.reason).toBe('below-threshold');
67
+ expect(result.revokeMessage.length).toBeGreaterThan(0);
68
+ });
69
+ it('approval-revoked: blocking issues revert the approval with the blockers reason', async () => {
70
+ const tracked = TrackedMrFactory.create({
71
+ id: 'gitlab-group/project-42',
72
+ latestScore: 9,
73
+ openThreads: 2,
74
+ bypass: null,
75
+ });
76
+ const result = await processWebhook(buildApproveEvent(), buildDeps(tracked, 8));
77
+ expect(result.type).toBe('approval-revoked');
78
+ if (result.type !== 'approval-revoked')
79
+ throw new Error('expected approval-revoked');
80
+ expect(result.reason).toBe('blockers-present');
81
+ });
82
+ it('approval-ignored: an untracked MR yields a not-found ignore', async () => {
83
+ const result = await processWebhook(buildApproveEvent(), buildDeps(null, 8));
84
+ expect(result).toEqual({
85
+ type: 'approval-ignored',
86
+ mergeRequestNumber: 42,
87
+ reason: 'not-found',
88
+ });
89
+ });
90
+ it('approved: a bypassed MR below threshold passes the gate via the bypass', async () => {
91
+ const tracked = TrackedMrFactory.create({
92
+ id: 'gitlab-group/project-42',
93
+ latestScore: 4,
94
+ openThreads: 0,
95
+ bypass: { reason: 'urgent', author: 'alice', recordedAt: '2026-01-01T00:00:00Z' },
96
+ });
97
+ const result = await processWebhook(buildApproveEvent(), buildDeps(tracked, 8));
98
+ expect(result).toEqual({ type: 'approved', mergeRequestNumber: 42 });
99
+ });
100
+ });
101
+ describe('the platform-neutral usecase imports no platform-specific types', () => {
102
+ it('uses evaluateQualityGate as the gate function for the transition check', () => {
103
+ expect(typeof evaluateQualityGate).toBe('function');
104
+ });
105
+ });
106
+ });
107
+ const REVIEW_PROJECT_PATH = 'group/project';
108
+ const reviewProcessor = async () => { };
109
+ function buildReviewJob() {
110
+ return {
111
+ id: 'gitlab-group/project-42',
112
+ platform: 'gitlab',
113
+ projectPath: REVIEW_PROJECT_PATH,
114
+ localPath: PROJECT_PATH,
115
+ mrNumber: 42,
116
+ skill: 'review-front',
117
+ mrUrl: 'https://gitlab.com/group/project/-/merge_requests/42',
118
+ sourceBranch: 'feature/x',
119
+ targetBranch: 'main',
120
+ jobType: 'review',
121
+ };
122
+ }
123
+ function acceptedBudget() {
124
+ return {
125
+ limitUsd: 200,
126
+ consumedUsd: 0,
127
+ remainingUsd: 200,
128
+ percentUsed: 0,
129
+ exceeded: false,
130
+ periodStart: '2026-05-01T00:00:00.000Z',
131
+ };
132
+ }
133
+ function exceededBudget() {
134
+ return {
135
+ limitUsd: 200,
136
+ consumedUsd: 250,
137
+ remainingUsd: -50,
138
+ percentUsed: 125,
139
+ exceeded: true,
140
+ periodStart: '2026-05-01T00:00:00.000Z',
141
+ };
142
+ }
143
+ function buildReviewInput(overrides = {}) {
144
+ return {
145
+ job: buildReviewJob(),
146
+ processor: reviewProcessor,
147
+ triggerSource: 'webhook-initial',
148
+ localPaths: [PROJECT_PATH],
149
+ actorUsername: 'alice',
150
+ projectPath: REVIEW_PROJECT_PATH,
151
+ gateActorTrust: true,
152
+ ...overrides,
153
+ };
154
+ }
155
+ function buildReviewDeps(overrides = {}) {
156
+ return {
157
+ enforceBudget: { execute: vi.fn(async () => ({ accepted: true, status: acceptedBudget() })) },
158
+ enqueue: vi.fn(async () => true),
159
+ logger: createStubLogger(),
160
+ ...overrides,
161
+ };
162
+ }
163
+ describe('SPEC-073 Stage 4a — review-request enqueue sequencing via processReviewRequest (acceptance)', () => {
164
+ describe('the review-request verdict is decided inward, platform-neutral', () => {
165
+ it('budget-exceeded: a refused budget short-circuits before any enqueue', async () => {
166
+ const enqueue = vi.fn(async () => true);
167
+ const verdict = await processReviewRequest(buildReviewInput(), buildReviewDeps({
168
+ enforceBudget: {
169
+ execute: vi.fn(async () => ({ accepted: false, status: exceededBudget() })),
170
+ },
171
+ enqueue,
172
+ }));
173
+ expect(verdict).toEqual({ type: 'budget-exceeded', status: exceededBudget() });
174
+ expect(enqueue).not.toHaveBeenCalled();
175
+ });
176
+ it('queued: a trusted full-auto trigger is enqueued through the gate', async () => {
177
+ const gateClaudeInvocation = {
178
+ execute: vi.fn(async () => ({
179
+ status: 'enqueued',
180
+ jobId: 'gitlab-group/project-42',
181
+ })),
182
+ };
183
+ const verdict = await processReviewRequest(buildReviewInput(), buildReviewDeps({
184
+ gateClaudeInvocation,
185
+ isTrustedActor: { execute: vi.fn(async () => true) },
186
+ }));
187
+ expect(verdict).toEqual({ type: 'queued', jobId: 'gitlab-group/project-42' });
188
+ });
189
+ it('pending: a semi-auto trigger is parked with its pendingId', async () => {
190
+ const gateClaudeInvocation = {
191
+ execute: vi.fn(async () => ({
192
+ status: 'pending',
193
+ pendingId: 'pending-gitlab-42',
194
+ })),
195
+ };
196
+ const verdict = await processReviewRequest(buildReviewInput(), buildReviewDeps({
197
+ gateClaudeInvocation,
198
+ isTrustedActor: { execute: vi.fn(async () => true) },
199
+ }));
200
+ expect(verdict).toEqual({ type: 'pending', pendingId: 'pending-gitlab-42' });
201
+ });
202
+ it('pending (untrusted-actor): the no-gate fallback parks an untrusted actor without enqueuing', async () => {
203
+ const enqueue = vi.fn(async () => true);
204
+ const verdict = await processReviewRequest(buildReviewInput({ gateActorTrust: true }), buildReviewDeps({ enqueue, isTrustedActor: { execute: vi.fn(async () => false) } }));
205
+ expect(verdict).toEqual({ type: 'pending', pendingId: null, reason: 'untrusted-actor' });
206
+ expect(enqueue).not.toHaveBeenCalled();
207
+ });
208
+ it('deduplicated: the gate rejecting the job yields a deduplicated verdict', async () => {
209
+ const gateClaudeInvocation = {
210
+ execute: vi.fn(async () => ({ status: 'rejected', reason: 'already-active' })),
211
+ };
212
+ const verdict = await processReviewRequest(buildReviewInput(), buildReviewDeps({
213
+ gateClaudeInvocation,
214
+ isTrustedActor: { execute: vi.fn(async () => true) },
215
+ }));
216
+ expect(verdict).toEqual({ type: 'deduplicated', jobId: 'gitlab-group/project-42' });
217
+ });
218
+ it('queued (no gate): the followup raw-enqueue fallback queues an ungated trigger', async () => {
219
+ const enqueue = vi.fn(async () => true);
220
+ const verdict = await processReviewRequest(buildReviewInput({ triggerSource: 'webhook-followup', gateActorTrust: false }), buildReviewDeps({ enqueue }));
221
+ expect(verdict).toEqual({ type: 'queued', jobId: 'gitlab-group/project-42' });
222
+ expect(enqueue).toHaveBeenCalledTimes(1);
223
+ });
224
+ });
225
+ });
226
+ //# sourceMappingURL=73-stage4-controller-thinning.acceptance.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"73-stage4-controller-thinning.acceptance.test.js","sourceRoot":"","sources":["../../../src/tests/acceptance/73-stage4-controller-thinning.acceptance.test.ts"],"names":[],"mappings":"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"}
@@ -49,5 +49,20 @@ describe('buildMcpSystemPrompt', () => {
49
49
  expect(prompt).toContain('job-xyz');
50
50
  });
51
51
  });
52
+ describe('report output path — prevents report-missing in --bg mode', () => {
53
+ it('pins the review report to .claude/reviews with the review suffix', () => {
54
+ const prompt = buildMcpSystemPrompt(buildJob({ jobType: 'review', mrNumber: 5450 }));
55
+ expect(prompt).toContain('.claude/reviews/');
56
+ expect(prompt).toContain('-MR-5450-review.md');
57
+ });
58
+ it('uses the followup suffix for followup jobs', () => {
59
+ const prompt = buildMcpSystemPrompt(buildJob({ jobType: 'followup', mrNumber: 77 }));
60
+ expect(prompt).toContain('-MR-77-followup.md');
61
+ });
62
+ it('forbids writing the report to the background job tmp directory', () => {
63
+ const prompt = buildMcpSystemPrompt(buildJob({ jobType: 'review', mrNumber: 5450 }));
64
+ expect(prompt).toContain('CLAUDE_JOB_DIR');
65
+ });
66
+ });
52
67
  });
53
68
  //# sourceMappingURL=claudeInvoker.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claudeInvoker.test.js","sourceRoot":"","sources":["../../../../../src/tests/units/frameworks/claude/claudeInvoker.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claudeInvoker.test.js","sourceRoot":"","sources":["../../../../../src/tests/units/frameworks/claude/claudeInvoker.test.ts"],"names":[],"mappings":"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"}