wdyt 0.1.13 → 0.1.15
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/package.json +1 -1
- package/src/commands/chat.ts +65 -3
- package/src/context/hints.test.ts +135 -0
- package/src/context/hints.ts +264 -0
- package/src/context/index.ts +48 -0
- package/src/context/references.test.ts +341 -0
- package/src/context/references.ts +232 -0
- package/src/context/rereview.test.ts +135 -0
- package/src/context/rereview.ts +204 -0
- package/src/context/symbols.test.ts +550 -0
- package/src/context/symbols.ts +234 -0
- package/src/flow/index.ts +18 -0
- package/src/flow/specs.test.ts +260 -0
- package/src/flow/specs.ts +255 -0
- package/src/git/diff.test.ts +311 -0
- package/src/git/diff.ts +205 -0
- package/src/integration.test.ts +538 -0
package/src/git/diff.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git diff context module for wdyt
|
|
3
|
+
*
|
|
4
|
+
* Gathers git context for code reviews including diff stats,
|
|
5
|
+
* commit history, and changed files.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from "child_process";
|
|
9
|
+
|
|
10
|
+
/** Options for getting git diff context */
|
|
11
|
+
export interface GitDiffOptions {
|
|
12
|
+
/** Base branch/commit to diff against (default: "main") */
|
|
13
|
+
base?: string;
|
|
14
|
+
/** Target ref to compare (default: "HEAD") */
|
|
15
|
+
head?: string;
|
|
16
|
+
/** Working directory (defaults to cwd) */
|
|
17
|
+
cwd?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Git diff context result */
|
|
21
|
+
export interface GitDiffContext {
|
|
22
|
+
/** Diff stat summary */
|
|
23
|
+
diffStat: string;
|
|
24
|
+
/** Commit history */
|
|
25
|
+
commits: string[];
|
|
26
|
+
/** List of changed files */
|
|
27
|
+
changedFiles: string[];
|
|
28
|
+
/** Current branch name */
|
|
29
|
+
branch: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Execute a git command and return stdout
|
|
34
|
+
*/
|
|
35
|
+
async function execGit(
|
|
36
|
+
args: string[],
|
|
37
|
+
cwd: string
|
|
38
|
+
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
const process = spawn("git", args, {
|
|
41
|
+
cwd,
|
|
42
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
let stdout = "";
|
|
46
|
+
let stderr = "";
|
|
47
|
+
|
|
48
|
+
process.stdout.on("data", (data) => {
|
|
49
|
+
stdout += data.toString();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
process.stderr.on("data", (data) => {
|
|
53
|
+
stderr += data.toString();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
process.on("close", (exitCode) => {
|
|
57
|
+
resolve({ stdout, stderr, exitCode: exitCode ?? 0 });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
process.on("error", () => {
|
|
61
|
+
resolve({ stdout: "", stderr: "Failed to spawn git", exitCode: 1 });
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get git diff --stat between base and head
|
|
68
|
+
*/
|
|
69
|
+
export async function getDiffStat(
|
|
70
|
+
options: GitDiffOptions = {}
|
|
71
|
+
): Promise<string> {
|
|
72
|
+
const { base = "main", head = "HEAD", cwd = process.cwd() } = options;
|
|
73
|
+
|
|
74
|
+
const { stdout, exitCode } = await execGit(
|
|
75
|
+
["diff", "--stat", `${base}...${head}`],
|
|
76
|
+
cwd
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (exitCode !== 0) {
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return stdout.trim();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get commit history between base and head
|
|
88
|
+
*/
|
|
89
|
+
export async function getCommits(
|
|
90
|
+
options: GitDiffOptions = {}
|
|
91
|
+
): Promise<string[]> {
|
|
92
|
+
const { base = "main", head = "HEAD", cwd = process.cwd() } = options;
|
|
93
|
+
|
|
94
|
+
const { stdout, exitCode } = await execGit(
|
|
95
|
+
["log", "--oneline", `${base}..${head}`],
|
|
96
|
+
cwd
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (exitCode !== 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return stdout
|
|
104
|
+
.trim()
|
|
105
|
+
.split("\n")
|
|
106
|
+
.filter((line) => line.trim() !== "");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get list of changed files between base and head
|
|
111
|
+
*/
|
|
112
|
+
export async function getChangedFiles(
|
|
113
|
+
options: GitDiffOptions = {}
|
|
114
|
+
): Promise<string[]> {
|
|
115
|
+
const { base = "main", head = "HEAD", cwd = process.cwd() } = options;
|
|
116
|
+
|
|
117
|
+
const { stdout, exitCode } = await execGit(
|
|
118
|
+
["diff", "--name-only", `${base}...${head}`],
|
|
119
|
+
cwd
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (exitCode !== 0) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return stdout
|
|
127
|
+
.trim()
|
|
128
|
+
.split("\n")
|
|
129
|
+
.filter((line) => line.trim() !== "");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get current branch name
|
|
134
|
+
*/
|
|
135
|
+
export async function getBranchName(cwd: string = process.cwd()): Promise<string> {
|
|
136
|
+
const { stdout, exitCode } = await execGit(
|
|
137
|
+
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
138
|
+
cwd
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
if (exitCode !== 0) {
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return stdout.trim();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get full git diff context
|
|
150
|
+
*/
|
|
151
|
+
export async function getGitDiffContext(
|
|
152
|
+
options: GitDiffOptions = {}
|
|
153
|
+
): Promise<GitDiffContext> {
|
|
154
|
+
const { cwd = process.cwd() } = options;
|
|
155
|
+
|
|
156
|
+
// Run all git commands in parallel
|
|
157
|
+
const [diffStat, commits, changedFiles, branch] = await Promise.all([
|
|
158
|
+
getDiffStat(options),
|
|
159
|
+
getCommits(options),
|
|
160
|
+
getChangedFiles(options),
|
|
161
|
+
getBranchName(cwd),
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
diffStat,
|
|
166
|
+
commits,
|
|
167
|
+
changedFiles,
|
|
168
|
+
branch,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Format git diff context as XML block (matching flowctl format)
|
|
174
|
+
*/
|
|
175
|
+
export function formatDiffContextXml(context: GitDiffContext): string {
|
|
176
|
+
const sections: string[] = [];
|
|
177
|
+
|
|
178
|
+
if (context.diffStat) {
|
|
179
|
+
sections.push(`<diff_summary>\n${context.diffStat}\n</diff_summary>`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (context.commits.length > 0) {
|
|
183
|
+
sections.push(`<commits>\n${context.commits.join("\n")}\n</commits>`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (context.changedFiles.length > 0) {
|
|
187
|
+
sections.push(
|
|
188
|
+
`<changed_files>\n${context.changedFiles.join("\n")}\n</changed_files>`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return sections.join("\n\n");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get formatted git diff context as XML
|
|
197
|
+
*
|
|
198
|
+
* This is the main entry point for getting review context.
|
|
199
|
+
*/
|
|
200
|
+
export async function getFormattedDiffContext(
|
|
201
|
+
options: GitDiffOptions = {}
|
|
202
|
+
): Promise<string> {
|
|
203
|
+
const context = await getGitDiffContext(options);
|
|
204
|
+
return formatDiffContextXml(context);
|
|
205
|
+
}
|