forge-cc 0.1.9 → 0.1.11

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 (59) hide show
  1. package/README.md +253 -178
  2. package/dist/cli.js +109 -8
  3. package/dist/cli.js.map +1 -1
  4. package/dist/gates/codex-gate.d.ts +51 -0
  5. package/dist/gates/codex-gate.js +121 -0
  6. package/dist/gates/codex-gate.js.map +1 -0
  7. package/dist/go/auto-chain.d.ts +13 -23
  8. package/dist/go/auto-chain.js +29 -101
  9. package/dist/go/auto-chain.js.map +1 -1
  10. package/dist/go/executor.d.ts +5 -0
  11. package/dist/go/executor.js +43 -5
  12. package/dist/go/executor.js.map +1 -1
  13. package/dist/go/finalize.d.ts +50 -1
  14. package/dist/go/finalize.js +122 -0
  15. package/dist/go/finalize.js.map +1 -1
  16. package/dist/go/prd-queue.d.ts +43 -0
  17. package/dist/go/prd-queue.js +67 -0
  18. package/dist/go/prd-queue.js.map +1 -0
  19. package/dist/go/prd-selector.d.ts +57 -0
  20. package/dist/go/prd-selector.js +101 -0
  21. package/dist/go/prd-selector.js.map +1 -0
  22. package/dist/go/verify-loop.d.ts +18 -1
  23. package/dist/go/verify-loop.js +119 -2
  24. package/dist/go/verify-loop.js.map +1 -1
  25. package/dist/spec/templates.d.ts +2 -2
  26. package/dist/state/prd-status.d.ts +59 -0
  27. package/dist/state/prd-status.js +121 -0
  28. package/dist/state/prd-status.js.map +1 -0
  29. package/dist/state/reader.d.ts +2 -24
  30. package/dist/state/reader.js +4 -77
  31. package/dist/state/reader.js.map +1 -1
  32. package/dist/state/writer.d.ts +2 -41
  33. package/dist/state/writer.js +14 -130
  34. package/dist/state/writer.js.map +1 -1
  35. package/dist/team/consensus.d.ts +28 -0
  36. package/dist/team/consensus.js +130 -0
  37. package/dist/team/consensus.js.map +1 -0
  38. package/dist/team/index.d.ts +4 -0
  39. package/dist/team/index.js +5 -0
  40. package/dist/team/index.js.map +1 -0
  41. package/dist/team/lifecycle.d.ts +37 -0
  42. package/dist/team/lifecycle.js +92 -0
  43. package/dist/team/lifecycle.js.map +1 -0
  44. package/dist/team/reviewer.d.ts +10 -0
  45. package/dist/team/reviewer.js +345 -0
  46. package/dist/team/reviewer.js.map +1 -0
  47. package/dist/team/types.d.ts +269 -0
  48. package/dist/team/types.js +70 -0
  49. package/dist/team/types.js.map +1 -0
  50. package/dist/types.d.ts +1 -0
  51. package/dist/utils/browser.d.ts +1 -1
  52. package/dist/utils/browser.js +8 -1
  53. package/dist/utils/browser.js.map +1 -1
  54. package/dist/worktree/session.d.ts +3 -0
  55. package/dist/worktree/session.js +1 -0
  56. package/dist/worktree/session.js.map +1 -1
  57. package/package.json +2 -1
  58. package/skills/forge-go.md +176 -62
  59. package/skills/forge-spec.md +30 -5
@@ -0,0 +1,130 @@
1
+ // ---------------------------------------------------------------------------
2
+ // createConsensusState — initializes tracking state for a single finding
3
+ // ---------------------------------------------------------------------------
4
+ export function createConsensusState(finding, maxRounds = 2) {
5
+ return {
6
+ finding,
7
+ rounds: [],
8
+ maxRounds,
9
+ resolved: false,
10
+ result: null,
11
+ };
12
+ }
13
+ // ---------------------------------------------------------------------------
14
+ // recordBuilderResponse — records a builder's response and advances state
15
+ // ---------------------------------------------------------------------------
16
+ export function recordBuilderResponse(state, response) {
17
+ const round = state.rounds.length + 1;
18
+ const consensusRound = {
19
+ findingId: state.finding.id,
20
+ round,
21
+ builderName: response.builderName,
22
+ response: response.response,
23
+ reason: response.reason,
24
+ alternativeProposal: response.alternativeProposal,
25
+ };
26
+ const newRounds = [...state.rounds, consensusRound];
27
+ // Builder agrees — resolve immediately as accepted
28
+ if (response.response === "agree") {
29
+ return {
30
+ ...state,
31
+ rounds: newRounds,
32
+ resolved: true,
33
+ result: {
34
+ findingId: state.finding.id,
35
+ resolution: "accepted",
36
+ rounds: newRounds,
37
+ },
38
+ };
39
+ }
40
+ // Builder disagrees or proposes alternative
41
+ // If we haven't exhausted rounds, leave unresolved for next round
42
+ // If rounds exhausted, still leave unresolved — escalateToExecutive will resolve
43
+ return {
44
+ ...state,
45
+ rounds: newRounds,
46
+ resolved: false,
47
+ result: null,
48
+ };
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // needsEscalation — true when rounds are exhausted without agreement
52
+ // ---------------------------------------------------------------------------
53
+ export function needsEscalation(state) {
54
+ if (state.resolved)
55
+ return false;
56
+ if (state.rounds.length < state.maxRounds)
57
+ return false;
58
+ const lastRound = state.rounds[state.rounds.length - 1];
59
+ if (!lastRound)
60
+ return false;
61
+ return lastRound.response === "disagree" || lastRound.response === "alternative";
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // escalateToExecutive — resolves a deadlocked finding via executive decision
65
+ // ---------------------------------------------------------------------------
66
+ export function escalateToExecutive(state, decision) {
67
+ const resolution = decision.accepted ? "accepted" : "rejected";
68
+ return {
69
+ ...state,
70
+ resolved: true,
71
+ result: {
72
+ findingId: state.finding.id,
73
+ resolution,
74
+ rounds: [...state.rounds],
75
+ finalDecision: decision.decision,
76
+ },
77
+ };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // runConsensusProtocol — batch-processes multiple findings with responses
81
+ // ---------------------------------------------------------------------------
82
+ export function runConsensusProtocol(findings, responses) {
83
+ const results = [];
84
+ const escalationList = [];
85
+ for (const finding of findings) {
86
+ let state = createConsensusState(finding);
87
+ const findingResponses = responses.get(finding.id) ?? [];
88
+ for (const response of findingResponses) {
89
+ state = recordBuilderResponse(state, response);
90
+ if (state.resolved)
91
+ break;
92
+ }
93
+ if (state.resolved && state.result) {
94
+ results.push(state.result);
95
+ }
96
+ else if (needsEscalation(state)) {
97
+ escalationList.push(finding);
98
+ }
99
+ }
100
+ return { results, needsEscalation: escalationList };
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // formatFindingForReview — human-readable finding string for messages
104
+ // ---------------------------------------------------------------------------
105
+ export function formatFindingForReview(finding) {
106
+ const location = finding.file != null
107
+ ? `${finding.file}${finding.line != null ? `:${finding.line}` : ""}`
108
+ : undefined;
109
+ const locationLine = location ? `${location} — ${finding.source}` : finding.source;
110
+ return [
111
+ `**[${finding.severity}]** ${finding.message}`,
112
+ locationLine,
113
+ `> Remediation: ${finding.remediation}`,
114
+ ].join("\n");
115
+ }
116
+ // ---------------------------------------------------------------------------
117
+ // formatConsensusResult — human-readable consensus outcome
118
+ // ---------------------------------------------------------------------------
119
+ export function formatConsensusResult(result, finding) {
120
+ const lines = [
121
+ `Finding: ${finding.message}`,
122
+ `Resolution: ${result.resolution}`,
123
+ `Rounds: ${result.rounds.length}`,
124
+ ];
125
+ if (result.finalDecision) {
126
+ lines.push(`Executive decision: ${result.finalDecision}`);
127
+ }
128
+ return lines.join("\n");
129
+ }
130
+ //# sourceMappingURL=consensus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus.js","sourceRoot":"","sources":["../../src/team/consensus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./lifecycle.js";
3
+ export * from "./reviewer.js";
4
+ export * from "./consensus.js";
@@ -0,0 +1,5 @@
1
+ export * from "./types.js";
2
+ export * from "./lifecycle.js";
3
+ export * from "./reviewer.js";
4
+ export * from "./consensus.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/team/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { TeamConfig } from "./types.js";
2
+ export declare function createTeamConfig(options: {
3
+ prdSlug: string;
4
+ milestoneNumber: number;
5
+ builderCount: number;
6
+ includeNotetaker?: boolean;
7
+ }): TeamConfig;
8
+ export declare function buildTeamCreateParams(config: TeamConfig): {
9
+ team_name: string;
10
+ description: string;
11
+ };
12
+ export declare function buildAgentSpawnConfig(config: TeamConfig, agentName: string, prompt: string): {
13
+ team_name: string;
14
+ name: string;
15
+ prompt: string;
16
+ subagent_type: string;
17
+ mode: string;
18
+ run_in_background: boolean;
19
+ };
20
+ export declare function buildShutdownMessage(agentName: string): {
21
+ type: "shutdown_request";
22
+ recipient: string;
23
+ content: string;
24
+ };
25
+ export declare function buildMessage(recipient: string, content: string, summary: string): {
26
+ type: "message";
27
+ recipient: string;
28
+ content: string;
29
+ summary: string;
30
+ };
31
+ export declare function buildBroadcast(content: string, summary: string): {
32
+ type: "broadcast";
33
+ content: string;
34
+ summary: string;
35
+ };
36
+ export declare function getBuilderNames(config: TeamConfig): string[];
37
+ export declare function shouldIncludeNotetaker(waveCount: number, maxAgentsPerWave: number): boolean;
@@ -0,0 +1,92 @@
1
+ // ---------------------------------------------------------------------------
2
+ // createTeamConfig — builds a TeamConfig for a milestone execution
3
+ // ---------------------------------------------------------------------------
4
+ export function createTeamConfig(options) {
5
+ const { prdSlug, milestoneNumber, builderCount, includeNotetaker } = options;
6
+ const roles = {
7
+ executive: "executive",
8
+ };
9
+ for (let i = 1; i <= builderCount; i++) {
10
+ roles[`builder-${i}`] = "builder";
11
+ }
12
+ roles["reviewer"] = "reviewer";
13
+ if (includeNotetaker) {
14
+ roles["notetaker"] = "notetaker";
15
+ }
16
+ return {
17
+ teamName: `m${milestoneNumber}-${prdSlug}`,
18
+ prdSlug,
19
+ milestoneNumber,
20
+ roles,
21
+ };
22
+ }
23
+ // ---------------------------------------------------------------------------
24
+ // buildTeamCreateParams — returns params the skill passes to TeamCreate
25
+ // ---------------------------------------------------------------------------
26
+ export function buildTeamCreateParams(config) {
27
+ return {
28
+ team_name: config.teamName,
29
+ description: `Milestone ${config.milestoneNumber} execution for ${config.prdSlug}`,
30
+ };
31
+ }
32
+ // ---------------------------------------------------------------------------
33
+ // buildAgentSpawnConfig — returns config for spawning an agent via Task tool
34
+ // ---------------------------------------------------------------------------
35
+ export function buildAgentSpawnConfig(config, agentName, prompt) {
36
+ // Look up role to validate agent name exists in config
37
+ const _role = config.roles[agentName];
38
+ return {
39
+ team_name: config.teamName,
40
+ name: agentName,
41
+ prompt,
42
+ subagent_type: "general-purpose",
43
+ mode: "bypassPermissions",
44
+ run_in_background: true,
45
+ };
46
+ }
47
+ // ---------------------------------------------------------------------------
48
+ // buildShutdownMessage — returns SendMessage params for shutdown request
49
+ // ---------------------------------------------------------------------------
50
+ export function buildShutdownMessage(agentName) {
51
+ return {
52
+ type: "shutdown_request",
53
+ recipient: agentName,
54
+ content: `Task complete, shutting down ${agentName}`,
55
+ };
56
+ }
57
+ // ---------------------------------------------------------------------------
58
+ // buildMessage — returns SendMessage params for a direct message
59
+ // ---------------------------------------------------------------------------
60
+ export function buildMessage(recipient, content, summary) {
61
+ return {
62
+ type: "message",
63
+ recipient,
64
+ content,
65
+ summary,
66
+ };
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // buildBroadcast — returns SendMessage params for broadcast
70
+ // ---------------------------------------------------------------------------
71
+ export function buildBroadcast(content, summary) {
72
+ return {
73
+ type: "broadcast",
74
+ content,
75
+ summary,
76
+ };
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // getBuilderNames — returns array of builder agent names from config
80
+ // ---------------------------------------------------------------------------
81
+ export function getBuilderNames(config) {
82
+ return Object.entries(config.roles)
83
+ .filter(([, role]) => role === "builder")
84
+ .map(([name]) => name);
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // shouldIncludeNotetaker — decision logic per PRD
88
+ // ---------------------------------------------------------------------------
89
+ export function shouldIncludeNotetaker(waveCount, maxAgentsPerWave) {
90
+ return waveCount >= 3 || maxAgentsPerWave >= 4;
91
+ }
92
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/team/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Finding } from "./types.js";
2
+ interface ReviewWaveDiffOptions {
3
+ projectDir: string;
4
+ prdPath?: string;
5
+ claudeMdPath?: string;
6
+ baseBranch?: string;
7
+ }
8
+ declare function reviewWaveDiff(options: ReviewWaveDiffOptions): Finding[];
9
+ export { reviewWaveDiff };
10
+ export type { ReviewWaveDiffOptions };
@@ -0,0 +1,345 @@
1
+ import { execSync } from "node:child_process";
2
+ import { readFileSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ // ---------------------------------------------------------------------------
5
+ // Diff Parsing (local copy — review-gate.ts does not export these)
6
+ // ---------------------------------------------------------------------------
7
+ const DIFF_FILE_RE = /^diff --git a\/(.+?) b\/(.+?)$/;
8
+ const HUNK_HEADER_RE = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
9
+ function parseDiffHunks(diffContent) {
10
+ const lines = diffContent.split("\n");
11
+ const hunks = [];
12
+ let currentFile = "";
13
+ let currentHunk = null;
14
+ let currentLine = 0;
15
+ for (const line of lines) {
16
+ // New file header
17
+ const fileMatch = line.match(DIFF_FILE_RE);
18
+ if (fileMatch) {
19
+ if (currentHunk)
20
+ hunks.push(currentHunk);
21
+ currentFile = fileMatch[2];
22
+ currentHunk = null;
23
+ continue;
24
+ }
25
+ // New hunk header
26
+ const hunkMatch = line.match(HUNK_HEADER_RE);
27
+ if (hunkMatch) {
28
+ if (currentHunk)
29
+ hunks.push(currentHunk);
30
+ currentLine = parseInt(hunkMatch[1], 10);
31
+ currentHunk = {
32
+ file: currentFile,
33
+ startLine: currentLine,
34
+ content: "",
35
+ addedLines: [],
36
+ removedLines: [],
37
+ };
38
+ continue;
39
+ }
40
+ if (!currentHunk)
41
+ continue;
42
+ currentHunk.content += line + "\n";
43
+ if (line.startsWith("+") && !line.startsWith("+++")) {
44
+ currentHunk.addedLines.push({ line: currentLine, text: line.slice(1) });
45
+ currentLine++;
46
+ }
47
+ else if (line.startsWith("-") && !line.startsWith("---")) {
48
+ currentHunk.removedLines.push({
49
+ line: currentLine,
50
+ text: line.slice(1),
51
+ });
52
+ // Removed lines don't advance the new-file line counter
53
+ }
54
+ else {
55
+ // Context line
56
+ currentLine++;
57
+ }
58
+ }
59
+ if (currentHunk)
60
+ hunks.push(currentHunk);
61
+ return hunks;
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Diff Retrieval
65
+ // ---------------------------------------------------------------------------
66
+ function getDiffContent(projectDir, baseBranch) {
67
+ const execOpts = { cwd: projectDir, encoding: "utf-8", timeout: 30_000 };
68
+ // Try diff against base branch first if provided
69
+ if (baseBranch) {
70
+ try {
71
+ const diff = execSync(`git diff ${baseBranch}...HEAD`, execOpts);
72
+ if (diff.trim())
73
+ return diff;
74
+ }
75
+ catch {
76
+ // Fall through to other strategies
77
+ }
78
+ }
79
+ // Try HEAD~1 (last commit's diff)
80
+ try {
81
+ const diff = execSync("git diff HEAD~1", execOpts);
82
+ if (diff.trim())
83
+ return diff;
84
+ }
85
+ catch {
86
+ // Fall through
87
+ }
88
+ // Try staged changes
89
+ try {
90
+ const diff = execSync("git diff --cached", execOpts);
91
+ if (diff.trim())
92
+ return diff;
93
+ }
94
+ catch {
95
+ // Fall through
96
+ }
97
+ // Try unstaged changes
98
+ try {
99
+ const diff = execSync("git diff", execOpts);
100
+ if (diff.trim())
101
+ return diff;
102
+ }
103
+ catch {
104
+ // Nothing available
105
+ }
106
+ return null;
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // PRD Checklist Extraction
110
+ // ---------------------------------------------------------------------------
111
+ function extractPrdChecklist(prdPath, projectDir) {
112
+ const checklist = [];
113
+ if (!prdPath)
114
+ return checklist;
115
+ const resolvedPath = prdPath.startsWith("/") || prdPath.includes(":")
116
+ ? prdPath
117
+ : join(projectDir, prdPath);
118
+ if (!existsSync(resolvedPath))
119
+ return checklist;
120
+ try {
121
+ const content = readFileSync(resolvedPath, "utf-8");
122
+ const lines = content.split("\n");
123
+ let currentSection = "General";
124
+ for (const line of lines) {
125
+ const trimmed = line.trim();
126
+ // Track section headings (## or ###)
127
+ const headingMatch = trimmed.match(/^#{2,3}\s+(.+)/);
128
+ if (headingMatch) {
129
+ currentSection = headingMatch[1].trim();
130
+ continue;
131
+ }
132
+ // Unchecked checkbox lines: - [ ] ...
133
+ const checkboxMatch = trimmed.match(/^-\s+\[ \]\s+(.+)/);
134
+ if (checkboxMatch) {
135
+ checklist.push({
136
+ text: checkboxMatch[1].trim(),
137
+ section: currentSection,
138
+ });
139
+ }
140
+ }
141
+ }
142
+ catch {
143
+ // PRD unreadable -- skip
144
+ }
145
+ return checklist;
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // Finding ID Generator
149
+ // ---------------------------------------------------------------------------
150
+ function generateFindingId() {
151
+ return "f-" + Math.random().toString(36).slice(2, 8);
152
+ }
153
+ // ---------------------------------------------------------------------------
154
+ // Keyword Extraction (for PRD criterion matching)
155
+ // ---------------------------------------------------------------------------
156
+ const STOP_WORDS = new Set([
157
+ "the",
158
+ "and",
159
+ "for",
160
+ "are",
161
+ "but",
162
+ "not",
163
+ "you",
164
+ "all",
165
+ "can",
166
+ "has",
167
+ "her",
168
+ "was",
169
+ "one",
170
+ "our",
171
+ "out",
172
+ "its",
173
+ "his",
174
+ "how",
175
+ "may",
176
+ "who",
177
+ "did",
178
+ "get",
179
+ "let",
180
+ "say",
181
+ "she",
182
+ "too",
183
+ "use",
184
+ "way",
185
+ "each",
186
+ "which",
187
+ "their",
188
+ "will",
189
+ "other",
190
+ "about",
191
+ "many",
192
+ "then",
193
+ "them",
194
+ "been",
195
+ "have",
196
+ "from",
197
+ "with",
198
+ "they",
199
+ "this",
200
+ "that",
201
+ "what",
202
+ "when",
203
+ "make",
204
+ "like",
205
+ "just",
206
+ "over",
207
+ "such",
208
+ "take",
209
+ "into",
210
+ "than",
211
+ "most",
212
+ "also",
213
+ "should",
214
+ "would",
215
+ "could",
216
+ "must",
217
+ "shall",
218
+ "might",
219
+ "does",
220
+ "display",
221
+ "show",
222
+ "page",
223
+ "user",
224
+ "view",
225
+ "click",
226
+ "able",
227
+ "ensure",
228
+ "given",
229
+ ]);
230
+ function extractKeywords(text) {
231
+ return text
232
+ .toLowerCase()
233
+ .replace(/[^a-z0-9\s-]/g, " ")
234
+ .split(/\s+/)
235
+ .filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
236
+ }
237
+ // ---------------------------------------------------------------------------
238
+ // Main: reviewWaveDiff
239
+ // ---------------------------------------------------------------------------
240
+ function reviewWaveDiff(options) {
241
+ const { projectDir, prdPath, baseBranch } = options;
242
+ const findings = [];
243
+ // 1. Get diff content
244
+ const diffContent = getDiffContent(projectDir, baseBranch);
245
+ if (!diffContent)
246
+ return findings;
247
+ // 2. Parse into hunks
248
+ const hunks = parseDiffHunks(diffContent);
249
+ if (hunks.length === 0)
250
+ return findings;
251
+ // 3. Extract PRD checklist
252
+ const prdChecklist = extractPrdChecklist(prdPath, projectDir);
253
+ // 4. For each PRD criterion, check if any hunk addresses it
254
+ for (const criterion of prdChecklist) {
255
+ const keywords = extractKeywords(criterion.text);
256
+ if (keywords.length === 0)
257
+ continue;
258
+ let matched = false;
259
+ for (const hunk of hunks) {
260
+ const hunkText = hunk.content.toLowerCase();
261
+ const fileText = hunk.file.toLowerCase();
262
+ const keywordHits = keywords.filter((kw) => hunkText.includes(kw) || fileText.includes(kw));
263
+ // Require at least 40% of keywords to match
264
+ if (keywordHits.length >= Math.ceil(keywords.length * 0.4)) {
265
+ matched = true;
266
+ break;
267
+ }
268
+ }
269
+ if (!matched) {
270
+ findings.push({
271
+ id: generateFindingId(),
272
+ severity: "error",
273
+ message: `PRD criterion may not be addressed: "${criterion.text}"`,
274
+ remediation: `Review PRD section "${criterion.section}" and ensure this criterion is covered by the current changes.`,
275
+ source: `PRD: ${criterion.section}`,
276
+ });
277
+ }
278
+ }
279
+ // 5. Check added lines for common issues
280
+ for (const hunk of hunks) {
281
+ // Only check TypeScript/JavaScript files for code-level issues
282
+ if (!/\.[tj]sx?$/.test(hunk.file))
283
+ continue;
284
+ for (const addedLine of hunk.addedLines) {
285
+ const text = addedLine.text;
286
+ // console.log( -> warning
287
+ if (/console\.log\(/.test(text)) {
288
+ findings.push({
289
+ id: generateFindingId(),
290
+ severity: "warning",
291
+ file: hunk.file,
292
+ line: addedLine.line,
293
+ message: "console.log() left in code -- consider removing debug output.",
294
+ remediation: "Remove console.log statements before committing, or use a proper logger.",
295
+ source: "Style: debug output",
296
+ });
297
+ }
298
+ // : any type usage -> warning
299
+ if (/:\s*any\b/.test(text) &&
300
+ !text.includes("// eslint-disable") &&
301
+ !text.includes("@ts-")) {
302
+ findings.push({
303
+ id: generateFindingId(),
304
+ severity: "warning",
305
+ file: hunk.file,
306
+ line: addedLine.line,
307
+ message: "Explicit 'any' type used -- consider using a more specific type.",
308
+ remediation: "Replace 'any' with a specific type or 'unknown' for type safety.",
309
+ source: "Style: TypeScript strict mode",
310
+ });
311
+ }
312
+ // TODO|FIXME|HACK -> warning
313
+ if (/\b(TODO|FIXME|HACK)\b/.test(text)) {
314
+ findings.push({
315
+ id: generateFindingId(),
316
+ severity: "warning",
317
+ file: hunk.file,
318
+ line: addedLine.line,
319
+ message: "TODO/FIXME/HACK marker found in new code.",
320
+ remediation: "Resolve the TODO or track it as a separate issue before merging.",
321
+ source: "Style: code cleanliness",
322
+ });
323
+ }
324
+ // Missing .js in relative imports -> error
325
+ // Match from "./..." or from '../...' without .js extension
326
+ if (/from\s+["'][.][^"']*(?<!\.js)["']/.test(text)) {
327
+ findings.push({
328
+ id: generateFindingId(),
329
+ severity: "error",
330
+ file: hunk.file,
331
+ line: addedLine.line,
332
+ message: "Relative import missing .js extension (ES module requirement).",
333
+ remediation: "Add .js extension to all relative imports per ES module convention.",
334
+ source: "Style: ES module imports",
335
+ });
336
+ }
337
+ }
338
+ }
339
+ return findings;
340
+ }
341
+ // ---------------------------------------------------------------------------
342
+ // Exports
343
+ // ---------------------------------------------------------------------------
344
+ export { reviewWaveDiff };
345
+ //# sourceMappingURL=reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../../src/team/reviewer.ts"],"names":[],"mappings":"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"}