@magnusekdahl/parallix 1.2.1 → 1.3.1

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 (81) hide show
  1. package/index.js +190 -185
  2. package/lib/agents/agents.js +34 -4
  3. package/lib/agents/agents.ts +40 -5
  4. package/lib/commands/active.js +502 -579
  5. package/lib/commands/active.ts +665 -0
  6. package/lib/commands/checkpoint.js +98 -74
  7. package/lib/commands/checkpoint.ts +79 -0
  8. package/lib/commands/config.js +61 -31
  9. package/lib/commands/config.ts +47 -0
  10. package/lib/commands/coverage-gate.js +271 -246
  11. package/lib/commands/coverage-gate.ts +362 -0
  12. package/lib/commands/diff.js +140 -119
  13. package/lib/commands/diff.ts +125 -0
  14. package/lib/commands/draft.js +770 -923
  15. package/lib/commands/draft.ts +1021 -0
  16. package/lib/commands/handoff.js +588 -608
  17. package/lib/commands/handoff.ts +694 -0
  18. package/lib/commands/integrate.js +1331 -1468
  19. package/lib/commands/integrate.ts +1688 -0
  20. package/lib/commands/mission-start.js +279 -237
  21. package/lib/commands/mission-start.ts +263 -0
  22. package/lib/commands/rebase.js +606 -582
  23. package/lib/commands/rebase.ts +635 -0
  24. package/lib/commands/repair-handoff.js +181 -179
  25. package/lib/commands/repair-handoff.ts +228 -0
  26. package/lib/commands/resolve-conflict.js +121 -102
  27. package/lib/commands/resolve-conflict.ts +112 -0
  28. package/lib/commands/review.js +3 -4
  29. package/lib/commands/review.ts +14 -0
  30. package/lib/commands/setup-review.js +4 -5
  31. package/lib/commands/setup-review.ts +14 -0
  32. package/lib/commands/setup.js +3 -3
  33. package/lib/commands/setup.ts +2 -0
  34. package/lib/commands/stats-backfill.js +394 -359
  35. package/lib/commands/stats-backfill.ts +418 -0
  36. package/lib/commands/stats.js +1424 -1665
  37. package/lib/commands/stats.ts +2186 -0
  38. package/lib/commands/status.js +219 -200
  39. package/lib/commands/status.ts +219 -0
  40. package/lib/commands/verify.js +3 -1
  41. package/lib/commands/verify.ts +2 -0
  42. package/lib/core/nels.js +112 -127
  43. package/lib/core/nels.ts +189 -0
  44. package/lib/core/subagent-limit.js +15 -16
  45. package/lib/core/subagent-limit.ts +25 -0
  46. package/lib/index.js +142 -59
  47. package/lib/index.ts +134 -0
  48. package/lib/review/rebase.js +142 -145
  49. package/lib/review/rebase.ts +188 -0
  50. package/lib/review/review-adapter.js +99 -87
  51. package/lib/review/review-adapter.ts +198 -0
  52. package/lib/review/review-artifacts.js +486 -629
  53. package/lib/review/review-artifacts.ts +622 -0
  54. package/lib/review/review-commands.js +1220 -1373
  55. package/lib/review/review-commands.ts +1579 -0
  56. package/lib/review/review-events.js +544 -886
  57. package/lib/review/review-events.ts +954 -0
  58. package/lib/review/review-loop.js +945 -1020
  59. package/lib/review/review-loop.ts +1174 -0
  60. package/lib/review/review-polling.js +86 -115
  61. package/lib/review/review-polling.ts +194 -0
  62. package/lib/review/review-prompts.js +154 -189
  63. package/lib/review/review-prompts.ts +182 -0
  64. package/lib/review/review-state.js +246 -225
  65. package/lib/review/review-state.ts +353 -0
  66. package/lib/review/review.js +63 -84
  67. package/lib/review/review.ts +138 -0
  68. package/lib/tools/backlog.js +694 -680
  69. package/lib/tools/backlog.ts +835 -0
  70. package/lib/tools/forgejo.js +1270 -1405
  71. package/lib/tools/forgejo.ts +1793 -0
  72. package/lib/tools/gatekeeper.js +106 -96
  73. package/lib/tools/gatekeeper.ts +124 -0
  74. package/lib/tools/redgreen.js +200 -181
  75. package/lib/tools/redgreen.ts +221 -0
  76. package/lib/tools/sessions.js +58 -52
  77. package/lib/tools/sessions.ts +81 -0
  78. package/lib/tools/setup-review.js +902 -975
  79. package/lib/tools/setup-review.ts +1152 -0
  80. package/package.json +4 -4
  81. package/px.js +226 -208
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Reviewer-family persistence for the autonomous review loop.
3
+ *
4
+ * State is stored under the adapter-resolved mission directory on the mission branch.
5
+ * Writing and committing state before each round ensures session-restart safety.
6
+ *
7
+ * Owned by the Node workflow harness (ADR 0037 / task-089).
8
+ */
9
+
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { git } from '../core/git.js';
13
+ import { findMissionDir, resolveWorktree } from '../core/mission-utils.js';
14
+ import { log } from '../core/fmt.js';
15
+
16
+ /**
17
+ * Return the path to the review-state file for a given slug.
18
+ * Resolves using the same mission-dir discovery as other workflow commands.
19
+ *
20
+ * @param {string} slug
21
+ * @param {string} [rootDir]
22
+ * @returns {string|null} Absolute path, or null if mission dir not found
23
+ */
24
+ export function reviewStateFile(slug: string, rootDir = process.cwd()): string | null {
25
+ const missionDir = findMissionDir(slug, rootDir);
26
+ if (!missionDir) { return null; }
27
+ return path.join(missionDir, 'review-state.json');
28
+ }
29
+
30
+ /**
31
+ * Read the persisted review state for a mission.
32
+ *
33
+ * @param {string} slug
34
+ * @param {string} [rootDir] Directory to resolve the mission from (defaults to process.cwd())
35
+ * @returns {ReviewState|null}
36
+ */
37
+ export function readReviewState(slug: string, rootDir = process.cwd()): ReviewState | null {
38
+ const statePath = reviewStateFile(slug, rootDir);
39
+ if (!statePath || !fs.existsSync(statePath)) { return null; }
40
+
41
+ try {
42
+ const raw = fs.readFileSync(statePath, 'utf8');
43
+ const parsed = JSON.parse(raw);
44
+ if (parsed && parsed.reviewer && parsed.implementer) {
45
+ return new ReviewState(slug, parsed);
46
+ }
47
+ return null;
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Resolve the review-provider identity for a review workflow path.
55
+ *
56
+ * The normal contract is review-state-backed so standard review/handoff/rebase
57
+ * paths do not require a provider identity env var to be exported.
58
+ *
59
+ * @param {string} slug
60
+ * @param {string} [rootDir]
61
+ * @param {{readReviewStateFn?: Function}} [options]
62
+ * @returns {{ identityUser: string|null, commentIdentityUser: string|null, forgejoUser: string|null, commentForgejoUser: string|null, reviewState: ReviewState|null, source: 'review-state'|null }}
63
+ */
64
+ export function resolveReviewIdentity(
65
+ slug: string,
66
+ rootDir = process.cwd(),
67
+ options: { readReviewStateFn?: (s: string, r: string) => ReviewState | null } = {}
68
+ ): {
69
+ identityUser: string | null;
70
+ commentIdentityUser: string | null;
71
+ forgejoUser: string | null;
72
+ commentForgejoUser: string | null;
73
+ reviewState: ReviewState | null;
74
+ source: 'review-state' | null;
75
+ } {
76
+ const readReviewStateFn = options.readReviewStateFn || readReviewState;
77
+ const reviewState = readReviewStateFn(slug, rootDir);
78
+ const reviewerUser = reviewState ? (reviewState.reviewer || reviewState.implementer || null) : null;
79
+ const implementerUser = reviewState ? (reviewState.implementer || reviewState.reviewer || null) : null;
80
+
81
+ return {
82
+ identityUser: reviewerUser || null,
83
+ commentIdentityUser: implementerUser || null,
84
+ forgejoUser: reviewerUser || null,
85
+ commentForgejoUser: implementerUser || null,
86
+ reviewState,
87
+ source: reviewerUser ? 'review-state' : null
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Manager class for mission review state.
93
+ * Expanded to include phase, disposition, and metadata for canonical state ownership.
94
+ */
95
+ export const VALID_PHASES = ['reviewing', 'fixing', 'pending-approval', 'approved'] as const;
96
+ const PHASE_ALIASES = new Map<string, string>([
97
+ ['review', 'reviewing'],
98
+ ['rewiewing', 'reviewing'],
99
+ ['fix', 'fixing'],
100
+ ['pending_approval', 'pending-approval'],
101
+ ['pending approval', 'pending-approval']
102
+ ]);
103
+
104
+ const PHASE_TRANSITIONS: Record<string, string[]> = {
105
+ 'reviewing': ['fixing', 'approved'],
106
+ 'fixing': ['reviewing', 'pending-approval'],
107
+ 'pending-approval': ['reviewing'],
108
+ 'approved': []
109
+ };
110
+
111
+ /** @param {string} disposition */
112
+ function inferPhaseFromDisposition(disposition: string): string {
113
+ switch (String(disposition || '').trim().toUpperCase()) {
114
+ case 'APPROVED':
115
+ return 'approved';
116
+ case 'REQUEST_CHANGES':
117
+ case 'COMMENT':
118
+ case 'PUSHBACK_ALL':
119
+ case 'BLOCKED':
120
+ case 'PARKED':
121
+ return 'fixing';
122
+ case 'CHANGES_MADE':
123
+ return 'reviewing';
124
+ default:
125
+ return 'reviewing';
126
+ }
127
+ }
128
+
129
+ /** @param {string} phase @param {string} disposition */
130
+ export function normalizeReviewPhase(phase: string, disposition: string): { phase: string; original: string | null; normalized: boolean } {
131
+ if (!phase) {
132
+ return { phase: 'reviewing', original: null, normalized: false };
133
+ }
134
+
135
+ const raw = String(phase).trim();
136
+ const canonical = raw.toLowerCase().replace(/[_\s]+/g, '-');
137
+ if ((VALID_PHASES as readonly string[]).includes(canonical)) {
138
+ return { phase: canonical, original: raw, normalized: canonical !== raw };
139
+ }
140
+
141
+ const alias = PHASE_ALIASES.get(raw.toLowerCase()) || PHASE_ALIASES.get(canonical);
142
+ if (alias) {
143
+ return { phase: alias, original: raw, normalized: true };
144
+ }
145
+
146
+ return {
147
+ phase: inferPhaseFromDisposition(disposition),
148
+ original: raw,
149
+ normalized: true
150
+ };
151
+ }
152
+
153
+ /** @typedef {{reviewer?: string, implementer?: string, round?: number, startedAt?: string, phase?: string, disposition?: string | null, reviewerRetryCount?: number, implementerRetryCount?: number, metadata?: {[key: string]: unknown}}} ReviewStateData */
154
+ export interface ReviewStateData {
155
+ reviewer?: string;
156
+ implementer?: string;
157
+ round?: number;
158
+ startedAt?: string;
159
+ phase?: string;
160
+ disposition?: string | null;
161
+ reviewerRetryCount?: number;
162
+ implementerRetryCount?: number;
163
+ metadata?: Record<string, unknown>;
164
+ }
165
+
166
+ export class ReviewState {
167
+ slug: string;
168
+ reviewer?: string;
169
+ implementer?: string;
170
+ round: number;
171
+ startedAt: string;
172
+ phase: string;
173
+ disposition: string | null;
174
+ reviewerRetryCount: number;
175
+ implementerRetryCount: number;
176
+ metadata: Record<string, unknown>;
177
+ phaseOriginal: string | null;
178
+
179
+ /**
180
+ * @param {string} slug
181
+ * @param {ReviewStateData} [data]
182
+ */
183
+ constructor(slug: string, data: ReviewStateData = {}) {
184
+ const phaseInfo = normalizeReviewPhase(data.phase || '', data.disposition || '');
185
+ this.slug = slug;
186
+ this.reviewer = data.reviewer;
187
+ this.implementer = data.implementer;
188
+ this.round = data.round || 1;
189
+ this.startedAt = data.startedAt || new Date().toISOString();
190
+ this.phase = phaseInfo.phase;
191
+ this.disposition = data.disposition || null;
192
+ this.reviewerRetryCount = data.reviewerRetryCount || 0;
193
+ this.implementerRetryCount = data.implementerRetryCount || 0;
194
+ this.metadata = data.metadata || {};
195
+ this.phaseOriginal = phaseInfo.normalized ? phaseInfo.original : null;
196
+ }
197
+
198
+ /**
199
+ * @param {string} slug
200
+ * @param {ReviewState|ReviewStateData} dataOrInstance
201
+ * @returns {ReviewState}
202
+ */
203
+ static from(slug: string, dataOrInstance: ReviewState | ReviewStateData): ReviewState {
204
+ if (dataOrInstance instanceof ReviewState) {
205
+ if (dataOrInstance.slug !== slug) {
206
+ throw new Error(`ReviewState slug mismatch: expected "${slug}", got "${dataOrInstance.slug}"`);
207
+ }
208
+ return dataOrInstance;
209
+ }
210
+ return new ReviewState(slug, dataOrInstance || {});
211
+ }
212
+
213
+ /**
214
+ * @param {string} nextPhase
215
+ * @returns {ReviewState}
216
+ */
217
+ transitionTo(nextPhase: string): ReviewState {
218
+ if (!(VALID_PHASES as readonly string[]).includes(nextPhase)) {
219
+ throw new Error(`Invalid phase: "${nextPhase}". Valid: ${(VALID_PHASES as readonly string[]).join(', ')}`);
220
+ }
221
+ const allowedArr = PHASE_TRANSITIONS[this.phase];
222
+ if (!allowedArr || !allowedArr.includes(nextPhase)) {
223
+ throw new Error(`Cannot transition from "${this.phase}" to "${nextPhase}". Allowed: ${(allowedArr || []).join(', ') || 'none'}`);
224
+ }
225
+ this.phase = nextPhase;
226
+ return this;
227
+ }
228
+
229
+ advanceRound(): ReviewState {
230
+ this.round += 1;
231
+ this.phase = 'reviewing';
232
+ this.disposition = null;
233
+ this.reviewerRetryCount = 0;
234
+ this.implementerRetryCount = 0;
235
+ this.startedAt = new Date().toISOString();
236
+ return this;
237
+ }
238
+
239
+ /**
240
+ * @returns {{reviewer?: string, implementer?: string, round?: number, startedAt?: string, phase?: string, disposition?: string, reviewerRetryCount?: number, implementerRetryCount?: number, metadata?: {[key: string]: unknown}}}
241
+ */
242
+ toJSON(): {
243
+ reviewer?: string;
244
+ implementer?: string;
245
+ round?: number;
246
+ startedAt?: string;
247
+ phase?: string;
248
+ disposition?: string;
249
+ reviewerRetryCount?: number;
250
+ implementerRetryCount?: number;
251
+ metadata?: Record<string, unknown>;
252
+ } {
253
+ const payload: {
254
+ reviewer?: string;
255
+ implementer?: string;
256
+ round?: number;
257
+ startedAt?: string;
258
+ phase?: string;
259
+ disposition?: string;
260
+ reviewerRetryCount?: number;
261
+ implementerRetryCount?: number;
262
+ metadata?: Record<string, unknown>;
263
+ } = {
264
+ reviewer: this.reviewer,
265
+ implementer: this.implementer,
266
+ round: this.round,
267
+ startedAt: this.startedAt,
268
+ phase: this.phase,
269
+ disposition: this.disposition || undefined
270
+ };
271
+
272
+ if (this.reviewerRetryCount > 0) { payload.reviewerRetryCount = this.reviewerRetryCount; }
273
+ if (this.implementerRetryCount > 0) { payload.implementerRetryCount = this.implementerRetryCount; }
274
+ if (Object.keys(this.metadata || {}).length > 0) { payload.metadata = this.metadata; }
275
+
276
+ return payload;
277
+ }
278
+
279
+ save(
280
+ worktree = resolveWorktree(this.slug) || process.cwd(),
281
+ gitFn = git
282
+ ): boolean {
283
+ const statePath = reviewStateFile(this.slug, worktree);
284
+ if (!statePath) { return false; }
285
+
286
+ const payload = this.toJSON();
287
+ fs.writeFileSync(statePath, JSON.stringify(payload, null, 2) + '\n', 'utf8');
288
+
289
+ const relPath = path.relative(worktree, statePath);
290
+ const result = gitFn(['-C', worktree, 'add', relPath]);
291
+ const msg = `review-state(${this.slug}): round ${this.round} (${this.phase}) [${this.reviewer} -> ${this.implementer}]${this.disposition ? ` disposition=${this.disposition}` : ''}`;
292
+ const commitResult = gitFn(['-C', worktree, 'commit', '-m', msg]);
293
+
294
+ if (commitResult.status !== 0) {
295
+ const statusResult = gitFn(['-C', worktree, 'status', '--porcelain', relPath]);
296
+ if (statusResult.stdout.trim() === '') {
297
+ return true;
298
+ }
299
+ log.warn(`Failed to commit review state update: ${commitResult.stderr}`);
300
+ }
301
+
302
+ return true;
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Write and commit the review state for a mission.
308
+ * Commits to the current branch so the state is visible after session restarts.
309
+ *
310
+ * @param {string} slug
311
+ * @param {ReviewState|object} state
312
+ * @returns {boolean} true if written successfully
313
+ */
314
+ export function writeReviewState(
315
+ slug: string,
316
+ state: ReviewState | Record<string, unknown>,
317
+ worktree = resolveWorktree(slug) || process.cwd(),
318
+ gitFn = git
319
+ ): boolean {
320
+ const instance = state instanceof ReviewState ? state : new ReviewState(slug, state as ReviewStateData);
321
+ return instance.save(worktree, gitFn);
322
+ }
323
+
324
+ /**
325
+ * Delete the review state file for a mission (used by --reset).
326
+ * Commits the deletion if the file was tracked.
327
+ *
328
+ * @param {string} slug
329
+ * @returns {boolean} true if a file was deleted
330
+ */
331
+ export function resetReviewState(
332
+ slug: string,
333
+ worktree = resolveWorktree(slug) || process.cwd(),
334
+ gitFn = git
335
+ ): boolean {
336
+ const statePath = reviewStateFile(slug, worktree);
337
+ if (!statePath || !fs.existsSync(statePath)) { return false; }
338
+
339
+ fs.unlinkSync(statePath);
340
+
341
+ const relPath = path.relative(worktree, statePath);
342
+ try {
343
+ gitFn(['-C', worktree, 'rm', '--cached', relPath]);
344
+ const result = gitFn(['-C', worktree, 'commit', '-m', `review-state(${slug}): reset (--reset flag)`]);
345
+ if (result.status !== 0) {
346
+ log.warn(`Failed to commit review state reset: ${result.stderr}`);
347
+ }
348
+ } catch {
349
+ // file may not have been tracked yet
350
+ }
351
+
352
+ return true;
353
+ }
@@ -1,97 +1,76 @@
1
+ "use strict";
1
2
  /**
2
3
  * Review Module - Main Entry Point
3
4
  * Refactored for task-1201: complexity reduction via service extraction
4
- *
5
+ *
5
6
  * This file now serves as a re-export hub for the extracted sub-modules:
6
- * - review-commands.js (command dispatcher and CLI handlers)
7
- * - review-loop.js (autonomous review loop orchestration)
8
- * - review-artifacts.js (artifact handling and posting)
9
- * - review-polling.js (polling utilities)
7
+ * - review-commands.ts (command dispatcher and CLI handlers)
8
+ * - review-loop.ts (autonomous review loop orchestration)
9
+ * - review-artifacts.ts (artifact handling and posting)
10
+ * - review-polling.ts (polling utilities)
10
11
  */
11
-
12
- // Re-export from review-polling module
13
- const { POLL_TIMEOUT, delay, resolvePollIntervalMs, resolvePollTimeoutMs, formatElapsed, isPollTimeout, pollForReview, pollForDisposition } = require('./review-polling');
14
-
15
- // Re-export from review-artifacts module
16
- const { buildMetadataFooter, reviewArtifactPath, readArtifactFile, deleteArtifactFile, normalizeReviewVerdict, normalizeDisposition, postWorkflowComment, postWorkflowReview, consumeReviewerArtifacts, consumeImplementerArtifacts } = require('./review-artifacts');
17
-
18
- // Re-export from review-loop module
19
- const { maybeUpdateGraphifyBeforeReview, commitSafeMissionArtifacts, rebaseBeforeReviewRound, applyAgentFallback, persistNormalizedPhaseRepair, startReviewLoop, recordStageStatsSafe } = require('./review-loop');
20
-
21
- // Re-export from review-commands module
22
- const {
23
- flagValue,
24
- readTextFlag,
25
- formatStaticReviewFindings,
26
- formatStaticReviewSuccess,
27
- postStaticReviewComment,
28
- performStaticReview,
29
- verifyReview,
30
- submitForReview,
31
- readComments,
32
- pushRound,
33
- showReviewStatus,
34
- commentRound,
35
- submitReviewRound,
36
- closeMissionPr,
37
- createEventHandler,
38
- importLegacyHandler,
39
- review
40
- } = require('./review-commands');
41
-
12
+ // Import from review-polling module
13
+ const review_polling_js_1 = require("./review-polling.js");
14
+ // Import from review-artifacts module
15
+ const review_artifacts_js_1 = require("./review-artifacts.js");
16
+ // Import from review-loop module
17
+ const review_loop_js_1 = require("./review-loop.js");
18
+ // Import from review-commands module
19
+ const review_commands_js_1 = require("./review-commands.js");
20
+ // Import from review-state module
21
+ const review_state_js_1 = require("./review-state.js");
42
22
  // ============================================================================
43
23
  // Module Exports
44
24
  // ============================================================================
45
- // Set module.exports to the main review function (for backward compatibility)
25
+ // Set the module exports to the main review function (for backward compatibility)
46
26
  // then add all other exports as properties
47
-
48
- module.exports = review;
49
-
27
+ const _review = review_commands_js_1.review;
50
28
  // From review-polling
51
- module.exports.POLL_TIMEOUT = POLL_TIMEOUT;
52
- module.exports.delay = delay;
53
- module.exports.resolvePollIntervalMs = resolvePollIntervalMs;
54
- module.exports.resolvePollTimeoutMs = resolvePollTimeoutMs;
55
- module.exports.formatElapsed = formatElapsed;
56
- module.exports.isPollTimeout = isPollTimeout;
57
- module.exports.pollForReview = pollForReview;
58
- module.exports.pollForDisposition = pollForDisposition;
59
-
29
+ _review.POLL_TIMEOUT = review_polling_js_1.POLL_TIMEOUT;
30
+ _review.delay = review_polling_js_1.delay;
31
+ _review.resolvePollIntervalMs = review_polling_js_1.resolvePollIntervalMs;
32
+ _review.resolvePollTimeoutMs = review_polling_js_1.resolvePollTimeoutMs;
33
+ _review.formatElapsed = review_polling_js_1.formatElapsed;
34
+ _review.isPollTimeout = review_polling_js_1.isPollTimeout;
35
+ _review.pollForReview = review_polling_js_1.pollForReview;
36
+ _review.pollForDisposition = review_polling_js_1.pollForDisposition;
60
37
  // From review-artifacts
61
- module.exports.buildMetadataFooter = buildMetadataFooter;
62
- module.exports.reviewArtifactPath = reviewArtifactPath;
63
- module.exports.readArtifactFile = readArtifactFile;
64
- module.exports.deleteArtifactFile = deleteArtifactFile;
65
- module.exports.normalizeReviewVerdict = normalizeReviewVerdict;
66
- module.exports.normalizeDisposition = normalizeDisposition;
67
- module.exports.postWorkflowComment = postWorkflowComment;
68
- module.exports.postWorkflowReview = postWorkflowReview;
69
- module.exports.consumeReviewerArtifacts = consumeReviewerArtifacts;
70
- module.exports.consumeImplementerArtifacts = consumeImplementerArtifacts;
71
-
38
+ _review.buildMetadataFooter = review_artifacts_js_1.buildMetadataFooter;
39
+ _review.reviewArtifactPath = review_artifacts_js_1.reviewArtifactPath;
40
+ _review.readArtifactFile = review_artifacts_js_1.readArtifactFile;
41
+ _review.deleteArtifactFile = review_artifacts_js_1.deleteArtifactFile;
42
+ _review.normalizeReviewVerdict = review_artifacts_js_1.normalizeReviewVerdict;
43
+ _review.normalizeDisposition = review_artifacts_js_1.normalizeDisposition;
44
+ _review.postWorkflowComment = review_artifacts_js_1.postWorkflowComment;
45
+ _review.postWorkflowReview = review_artifacts_js_1.postWorkflowReview;
46
+ _review.consumeReviewerArtifacts = review_artifacts_js_1.consumeReviewerArtifacts;
47
+ _review.consumeImplementerArtifacts = review_artifacts_js_1.consumeImplementerArtifacts;
72
48
  // From review-loop
73
- module.exports.recordStageStatsSafe = recordStageStatsSafe;
74
- module.exports.maybeUpdateGraphifyBeforeReview = maybeUpdateGraphifyBeforeReview;
75
- module.exports.commitSafeMissionArtifacts = commitSafeMissionArtifacts;
76
- module.exports.rebaseBeforeReviewRound = rebaseBeforeReviewRound;
77
- module.exports.applyAgentFallback = applyAgentFallback;
78
- module.exports.persistNormalizedPhaseRepair = persistNormalizedPhaseRepair;
79
- module.exports.startReviewLoop = startReviewLoop;
80
-
49
+ _review.recordStageStatsSafe = review_loop_js_1.recordStageStatsSafe;
50
+ _review.maybeUpdateGraphifyBeforeReview = review_loop_js_1.maybeUpdateGraphifyBeforeReview;
51
+ _review.commitSafeMissionArtifacts = review_loop_js_1.commitSafeMissionArtifacts;
52
+ _review.rebaseBeforeReviewRound = review_loop_js_1.rebaseBeforeReviewRound;
53
+ _review.applyAgentFallback = review_loop_js_1.applyAgentFallback;
54
+ _review.persistNormalizedPhaseRepair = review_loop_js_1.persistNormalizedPhaseRepair;
55
+ _review.startReviewLoop = review_loop_js_1.startReviewLoop;
81
56
  // From review-commands
82
- module.exports.flagValue = flagValue;
83
- module.exports.readTextFlag = readTextFlag;
84
- module.exports.formatStaticReviewFindings = formatStaticReviewFindings;
85
- module.exports.formatStaticReviewSuccess = formatStaticReviewSuccess;
86
- module.exports.postStaticReviewComment = postStaticReviewComment;
87
- module.exports.performStaticReview = performStaticReview;
88
- module.exports.verifyReview = verifyReview;
89
- module.exports.submitForReview = submitForReview;
90
- module.exports.readComments = readComments;
91
- module.exports.pushRound = pushRound;
92
- module.exports.showReviewStatus = showReviewStatus;
93
- module.exports.commentRound = commentRound;
94
- module.exports.submitReviewRound = submitReviewRound;
95
- module.exports.closeMissionPr = closeMissionPr;
96
- module.exports.createEventHandler = createEventHandler;
97
- module.exports.importLegacyHandler = importLegacyHandler;
57
+ _review.flagValue = review_commands_js_1.flagValue;
58
+ _review.readTextFlag = review_commands_js_1.readTextFlag;
59
+ _review.formatStaticReviewFindings = review_commands_js_1.formatStaticReviewFindings;
60
+ _review.formatStaticReviewSuccess = review_commands_js_1.formatStaticReviewSuccess;
61
+ _review.postStaticReviewComment = review_commands_js_1.postStaticReviewComment;
62
+ _review.performStaticReview = review_commands_js_1.performStaticReview;
63
+ _review.verifyReview = review_commands_js_1.verifyReview;
64
+ _review.submitForReview = review_commands_js_1.submitForReview;
65
+ _review.readComments = review_commands_js_1.readComments;
66
+ _review.pushRound = review_commands_js_1.pushRound;
67
+ _review.showReviewStatus = review_commands_js_1.showReviewStatus;
68
+ _review.commentRound = review_commands_js_1.commentRound;
69
+ _review.submitReviewRound = review_commands_js_1.submitReviewRound;
70
+ _review.closeMissionPr = review_commands_js_1.closeMissionPr;
71
+ _review.createEventHandler = review_commands_js_1.createEventHandler;
72
+ _review.importLegacyHandler = review_commands_js_1.importLegacyHandler;
73
+ // From review-state
74
+ _review.reviewStateFile = review_state_js_1.reviewStateFile;
75
+ _review.ReviewState = review_state_js_1.ReviewState;
76
+ module.exports = _review;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Review Module - Main Entry Point
3
+ * Refactored for task-1201: complexity reduction via service extraction
4
+ *
5
+ * This file now serves as a re-export hub for the extracted sub-modules:
6
+ * - review-commands.ts (command dispatcher and CLI handlers)
7
+ * - review-loop.ts (autonomous review loop orchestration)
8
+ * - review-artifacts.ts (artifact handling and posting)
9
+ * - review-polling.ts (polling utilities)
10
+ */
11
+
12
+ // Import from review-polling module
13
+ import {
14
+ POLL_TIMEOUT,
15
+ delay,
16
+ resolvePollIntervalMs,
17
+ resolvePollTimeoutMs,
18
+ formatElapsed,
19
+ isPollTimeout,
20
+ pollForReview,
21
+ pollForDisposition
22
+ } from './review-polling.js';
23
+
24
+ // Import from review-artifacts module
25
+ import {
26
+ buildMetadataFooter,
27
+ reviewArtifactPath,
28
+ readArtifactFile,
29
+ deleteArtifactFile,
30
+ normalizeReviewVerdict,
31
+ normalizeDisposition,
32
+ postWorkflowComment,
33
+ postWorkflowReview,
34
+ consumeReviewerArtifacts,
35
+ consumeImplementerArtifacts
36
+ } from './review-artifacts.js';
37
+
38
+ // Import from review-loop module
39
+ import {
40
+ maybeUpdateGraphifyBeforeReview,
41
+ commitSafeMissionArtifacts,
42
+ rebaseBeforeReviewRound,
43
+ applyAgentFallback,
44
+ persistNormalizedPhaseRepair,
45
+ startReviewLoop,
46
+ recordStageStatsSafe
47
+ } from './review-loop.js';
48
+
49
+ // Import from review-commands module
50
+ import {
51
+ flagValue,
52
+ readTextFlag,
53
+ formatStaticReviewFindings,
54
+ formatStaticReviewSuccess,
55
+ postStaticReviewComment,
56
+ performStaticReview,
57
+ verifyReview,
58
+ submitForReview,
59
+ readComments,
60
+ pushRound,
61
+ showReviewStatus,
62
+ commentRound,
63
+ submitReviewRound,
64
+ closeMissionPr,
65
+ createEventHandler,
66
+ importLegacyHandler,
67
+ review
68
+ } from './review-commands.js';
69
+
70
+ // Import from review-state module
71
+ import {
72
+ reviewStateFile,
73
+ ReviewState
74
+ } from './review-state.js';
75
+
76
+ // ============================================================================
77
+ // Module Exports
78
+ // ============================================================================
79
+ // Set the module exports to the main review function (for backward compatibility)
80
+ // then add all other exports as properties
81
+
82
+ const _review = review as any;
83
+
84
+ // From review-polling
85
+ _review.POLL_TIMEOUT = POLL_TIMEOUT;
86
+ _review.delay = delay;
87
+ _review.resolvePollIntervalMs = resolvePollIntervalMs;
88
+ _review.resolvePollTimeoutMs = resolvePollTimeoutMs;
89
+ _review.formatElapsed = formatElapsed;
90
+ _review.isPollTimeout = isPollTimeout;
91
+ _review.pollForReview = pollForReview;
92
+ _review.pollForDisposition = pollForDisposition;
93
+
94
+ // From review-artifacts
95
+ _review.buildMetadataFooter = buildMetadataFooter;
96
+ _review.reviewArtifactPath = reviewArtifactPath;
97
+ _review.readArtifactFile = readArtifactFile;
98
+ _review.deleteArtifactFile = deleteArtifactFile;
99
+ _review.normalizeReviewVerdict = normalizeReviewVerdict;
100
+ _review.normalizeDisposition = normalizeDisposition;
101
+ _review.postWorkflowComment = postWorkflowComment;
102
+ _review.postWorkflowReview = postWorkflowReview;
103
+ _review.consumeReviewerArtifacts = consumeReviewerArtifacts;
104
+ _review.consumeImplementerArtifacts = consumeImplementerArtifacts;
105
+
106
+ // From review-loop
107
+ _review.recordStageStatsSafe = recordStageStatsSafe;
108
+ _review.maybeUpdateGraphifyBeforeReview = maybeUpdateGraphifyBeforeReview;
109
+ _review.commitSafeMissionArtifacts = commitSafeMissionArtifacts;
110
+ _review.rebaseBeforeReviewRound = rebaseBeforeReviewRound;
111
+ _review.applyAgentFallback = applyAgentFallback;
112
+ _review.persistNormalizedPhaseRepair = persistNormalizedPhaseRepair;
113
+ _review.startReviewLoop = startReviewLoop;
114
+
115
+ // From review-commands
116
+ _review.flagValue = flagValue;
117
+ _review.readTextFlag = readTextFlag;
118
+ _review.formatStaticReviewFindings = formatStaticReviewFindings;
119
+ _review.formatStaticReviewSuccess = formatStaticReviewSuccess;
120
+ _review.postStaticReviewComment = postStaticReviewComment;
121
+ _review.performStaticReview = performStaticReview;
122
+ _review.verifyReview = verifyReview;
123
+ _review.submitForReview = submitForReview;
124
+ _review.readComments = readComments;
125
+ _review.pushRound = pushRound;
126
+ _review.showReviewStatus = showReviewStatus;
127
+ _review.commentRound = commentRound;
128
+ _review.submitReviewRound = submitReviewRound;
129
+ _review.closeMissionPr = closeMissionPr;
130
+ _review.createEventHandler = createEventHandler;
131
+ _review.importLegacyHandler = importLegacyHandler;
132
+
133
+ // From review-state
134
+ _review.reviewStateFile = reviewStateFile;
135
+ _review.ReviewState = ReviewState;
136
+
137
+ // Export the review function as the module exports (CJS-compatible)
138
+ export = _review;