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.
- package/README.md +253 -178
- package/dist/cli.js +109 -8
- package/dist/cli.js.map +1 -1
- package/dist/gates/codex-gate.d.ts +51 -0
- package/dist/gates/codex-gate.js +121 -0
- package/dist/gates/codex-gate.js.map +1 -0
- package/dist/go/auto-chain.d.ts +13 -23
- package/dist/go/auto-chain.js +29 -101
- package/dist/go/auto-chain.js.map +1 -1
- package/dist/go/executor.d.ts +5 -0
- package/dist/go/executor.js +43 -5
- package/dist/go/executor.js.map +1 -1
- package/dist/go/finalize.d.ts +50 -1
- package/dist/go/finalize.js +122 -0
- package/dist/go/finalize.js.map +1 -1
- package/dist/go/prd-queue.d.ts +43 -0
- package/dist/go/prd-queue.js +67 -0
- package/dist/go/prd-queue.js.map +1 -0
- package/dist/go/prd-selector.d.ts +57 -0
- package/dist/go/prd-selector.js +101 -0
- package/dist/go/prd-selector.js.map +1 -0
- package/dist/go/verify-loop.d.ts +18 -1
- package/dist/go/verify-loop.js +119 -2
- package/dist/go/verify-loop.js.map +1 -1
- package/dist/spec/templates.d.ts +2 -2
- package/dist/state/prd-status.d.ts +59 -0
- package/dist/state/prd-status.js +121 -0
- package/dist/state/prd-status.js.map +1 -0
- package/dist/state/reader.d.ts +2 -24
- package/dist/state/reader.js +4 -77
- package/dist/state/reader.js.map +1 -1
- package/dist/state/writer.d.ts +2 -41
- package/dist/state/writer.js +14 -130
- package/dist/state/writer.js.map +1 -1
- package/dist/team/consensus.d.ts +28 -0
- package/dist/team/consensus.js +130 -0
- package/dist/team/consensus.js.map +1 -0
- package/dist/team/index.d.ts +4 -0
- package/dist/team/index.js +5 -0
- package/dist/team/index.js.map +1 -0
- package/dist/team/lifecycle.d.ts +37 -0
- package/dist/team/lifecycle.js +92 -0
- package/dist/team/lifecycle.js.map +1 -0
- package/dist/team/reviewer.d.ts +10 -0
- package/dist/team/reviewer.js +345 -0
- package/dist/team/reviewer.js.map +1 -0
- package/dist/team/types.d.ts +269 -0
- package/dist/team/types.js +70 -0
- package/dist/team/types.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/utils/browser.d.ts +1 -1
- package/dist/utils/browser.js +8 -1
- package/dist/utils/browser.js.map +1 -1
- package/dist/worktree/session.d.ts +3 -0
- package/dist/worktree/session.js +1 -0
- package/dist/worktree/session.js.map +1 -1
- package/package.json +2 -1
- package/skills/forge-go.md +176 -62
- 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 @@
|
|
|
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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"}
|