@eduardo-afonso/codebase-intelligence 0.1.0 → 2.0.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.
- package/README.md +86 -11
- package/README.pt-BR.md +88 -12
- package/dist/ai/CodebaseWithAI.d.ts +91 -0
- package/dist/ai/CodebaseWithAI.d.ts.map +1 -0
- package/dist/ai/CodebaseWithAI.js +149 -0
- package/dist/ai/CodebaseWithAI.js.map +1 -0
- package/dist/ai/RAGPipeline.d.ts +66 -0
- package/dist/ai/RAGPipeline.d.ts.map +1 -0
- package/dist/ai/RAGPipeline.js +102 -0
- package/dist/ai/RAGPipeline.js.map +1 -0
- package/dist/ai/index.d.ts +6 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +5 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/providers/NoopAIProvider.d.ts +23 -0
- package/dist/ai/providers/NoopAIProvider.d.ts.map +1 -0
- package/dist/ai/providers/NoopAIProvider.js +24 -0
- package/dist/ai/providers/NoopAIProvider.js.map +1 -0
- package/dist/cli/index.js +168 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/context/ContextEngine.d.ts +54 -0
- package/dist/context/ContextEngine.d.ts.map +1 -0
- package/dist/context/ContextEngine.js +179 -0
- package/dist/context/ContextEngine.js.map +1 -0
- package/dist/context/FileContextBuilder.d.ts +49 -0
- package/dist/context/FileContextBuilder.d.ts.map +1 -0
- package/dist/context/FileContextBuilder.js +124 -0
- package/dist/context/FileContextBuilder.js.map +1 -0
- package/dist/context/SemanticChunker.d.ts +105 -0
- package/dist/context/SemanticChunker.d.ts.map +1 -0
- package/dist/context/SemanticChunker.js +293 -0
- package/dist/context/SemanticChunker.js.map +1 -0
- package/dist/context/SignatureExtractor.d.ts +49 -0
- package/dist/context/SignatureExtractor.d.ts.map +1 -0
- package/dist/context/SignatureExtractor.js +167 -0
- package/dist/context/SignatureExtractor.js.map +1 -0
- package/dist/context/interfaces.d.ts +149 -0
- package/dist/context/interfaces.d.ts.map +1 -0
- package/dist/context/interfaces.js +13 -0
- package/dist/context/interfaces.js.map +1 -0
- package/dist/context/strategies/ContextBuildStrategy.d.ts +25 -0
- package/dist/context/strategies/ContextBuildStrategy.d.ts.map +1 -0
- package/dist/context/strategies/ContextBuildStrategy.js +3 -0
- package/dist/context/strategies/ContextBuildStrategy.js.map +1 -0
- package/dist/context/strategies/DeepStrategy.d.ts +18 -0
- package/dist/context/strategies/DeepStrategy.d.ts.map +1 -0
- package/dist/context/strategies/DeepStrategy.js +19 -0
- package/dist/context/strategies/DeepStrategy.js.map +1 -0
- package/dist/context/strategies/ShallowStrategy.d.ts +15 -0
- package/dist/context/strategies/ShallowStrategy.d.ts.map +1 -0
- package/dist/context/strategies/ShallowStrategy.js +15 -0
- package/dist/context/strategies/ShallowStrategy.js.map +1 -0
- package/dist/context/strategies/SignatureStrategy.d.ts +20 -0
- package/dist/context/strategies/SignatureStrategy.d.ts.map +1 -0
- package/dist/context/strategies/SignatureStrategy.js +59 -0
- package/dist/context/strategies/SignatureStrategy.js.map +1 -0
- package/dist/context/strategies/index.d.ts +5 -0
- package/dist/context/strategies/index.d.ts.map +1 -0
- package/dist/context/strategies/index.js +4 -0
- package/dist/context/strategies/index.js.map +1 -0
- package/dist/context/types.d.ts +136 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +8 -0
- package/dist/context/types.js.map +1 -0
- package/dist/core/Codebase.d.ts +50 -0
- package/dist/core/Codebase.d.ts.map +1 -1
- package/dist/core/Codebase.js +104 -0
- package/dist/core/Codebase.js.map +1 -1
- package/dist/diff/ChangeSetImpactAnalyzer.d.ts +19 -0
- package/dist/diff/ChangeSetImpactAnalyzer.d.ts.map +1 -0
- package/dist/diff/ChangeSetImpactAnalyzer.js +121 -0
- package/dist/diff/ChangeSetImpactAnalyzer.js.map +1 -0
- package/dist/diff/GitChangeSetProvider.d.ts +86 -0
- package/dist/diff/GitChangeSetProvider.d.ts.map +1 -0
- package/dist/diff/GitChangeSetProvider.js +297 -0
- package/dist/diff/GitChangeSetProvider.js.map +1 -0
- package/dist/diff/errors.d.ts +48 -0
- package/dist/diff/errors.d.ts.map +1 -0
- package/dist/diff/errors.js +70 -0
- package/dist/diff/errors.js.map +1 -0
- package/dist/diff/types.d.ts +159 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +8 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/explorer/SnapshotBuilder.d.ts +22 -0
- package/dist/explorer/SnapshotBuilder.d.ts.map +1 -0
- package/dist/explorer/SnapshotBuilder.js +225 -0
- package/dist/explorer/SnapshotBuilder.js.map +1 -0
- package/dist/explorer/types.d.ts +88 -0
- package/dist/explorer/types.d.ts.map +1 -0
- package/dist/explorer/types.js +12 -0
- package/dist/explorer/types.js.map +1 -0
- package/dist/explorer/ui/App.d.ts +3 -0
- package/dist/explorer/ui/App.d.ts.map +1 -0
- package/dist/explorer/ui/App.js +43 -0
- package/dist/explorer/ui/App.js.map +1 -0
- package/dist/explorer/ui/main.d.ts +2 -0
- package/dist/explorer/ui/main.d.ts.map +1 -0
- package/dist/explorer/ui/main.js +8 -0
- package/dist/explorer/ui/main.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/index-D4w3JVrv.css +1 -0
- package/dist/ui/assets/index-DBRKE5qL.js +52 -0
- package/dist/ui/index.html +13 -0
- package/package.json +50 -50
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import { GitCommandError, GitNotAvailableError, InvalidGitRefError, NotAGitRepositoryError, } from './errors.js';
|
|
6
|
+
const execFile = promisify(execFileCb);
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// GitChangeSetProvider
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* A `ChangeSetProvider` implementation that reads file changes from a local
|
|
12
|
+
* Git repository using the `git` CLI.
|
|
13
|
+
*
|
|
14
|
+
* **Safety guarantees**:
|
|
15
|
+
* - All git calls use `execFile` with an args array (never `exec` with a
|
|
16
|
+
* shell-interpolated string). This prevents shell injection.
|
|
17
|
+
* - Refs provided by callers are validated and rejected if they begin with
|
|
18
|
+
* `-` or cannot be resolved in the repository.
|
|
19
|
+
* - Output is parsed using NUL (`\0`) as the field separator (`-z` flag),
|
|
20
|
+
* which correctly handles file names containing spaces, tabs, or newlines.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const provider = new GitChangeSetProvider('/path/to/codebase');
|
|
25
|
+
* const changes = await provider.getChanges({ since: 'main' });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class GitChangeSetProvider {
|
|
29
|
+
codebaseRoot;
|
|
30
|
+
/**
|
|
31
|
+
* @param codebaseRoot - Absolute path to the codebase root as passed to
|
|
32
|
+
* `Codebase.load()`. May differ from the Git repository root (e.g. when
|
|
33
|
+
* the codebase is a sub-directory of a monorepo).
|
|
34
|
+
*/
|
|
35
|
+
constructor(codebaseRoot) {
|
|
36
|
+
this.codebaseRoot = codebaseRoot;
|
|
37
|
+
}
|
|
38
|
+
async getChanges(options = {}) {
|
|
39
|
+
await this.ensureGitAvailable();
|
|
40
|
+
const gitRoot = await this.resolveGitRoot();
|
|
41
|
+
this.validateOptions(options);
|
|
42
|
+
if (options.since !== undefined)
|
|
43
|
+
await this.validateRef(options.since, gitRoot);
|
|
44
|
+
if (options.until !== undefined)
|
|
45
|
+
await this.validateRef(options.until, gitRoot);
|
|
46
|
+
let changes;
|
|
47
|
+
if (options.staged) {
|
|
48
|
+
changes = await this.getStagedChanges(gitRoot);
|
|
49
|
+
}
|
|
50
|
+
else if (options.uncommitted) {
|
|
51
|
+
changes = await this.getUncommittedChanges(gitRoot);
|
|
52
|
+
}
|
|
53
|
+
else if (options.since !== undefined) {
|
|
54
|
+
changes = await this.getChangesSince(gitRoot, options.since, options.until ?? 'HEAD');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Default: uncommitted (staged + working tree)
|
|
58
|
+
changes = await this.getUncommittedChanges(gitRoot);
|
|
59
|
+
}
|
|
60
|
+
// Normalise all paths to be relative to the codebase root and sort
|
|
61
|
+
return this.normaliseAndSort(changes, gitRoot);
|
|
62
|
+
}
|
|
63
|
+
// ---- Git modes ----------------------------------------------------------
|
|
64
|
+
/** Returns only staged (index) changes: `git diff --cached`. */
|
|
65
|
+
async getStagedChanges(gitRoot) {
|
|
66
|
+
const stdout = await this.runGit(['diff', '--name-status', '-M', '-z', '--cached'], gitRoot);
|
|
67
|
+
return this.parseDiffOutput(stdout);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Returns all uncommitted changes (staged + working tree) plus untracked
|
|
71
|
+
* files. This is the most useful default for local development.
|
|
72
|
+
*/
|
|
73
|
+
async getUncommittedChanges(gitRoot) {
|
|
74
|
+
// Check whether HEAD exists (fresh repos before first commit have no HEAD)
|
|
75
|
+
const hasHead = await this.headExists(gitRoot);
|
|
76
|
+
let diffChanges = [];
|
|
77
|
+
if (hasHead) {
|
|
78
|
+
// staged + unstaged changes vs HEAD
|
|
79
|
+
const diffStdout = await this.runGit(['diff', '--name-status', '-M', '-z', 'HEAD'], gitRoot);
|
|
80
|
+
diffChanges = this.parseDiffOutput(diffStdout);
|
|
81
|
+
}
|
|
82
|
+
// untracked files (not ignored)
|
|
83
|
+
const untrackedStdout = await this.runGit(['ls-files', '--others', '--exclude-standard', '-z'], gitRoot);
|
|
84
|
+
const untrackedChanges = this.parseUntrackedOutput(untrackedStdout);
|
|
85
|
+
return [...diffChanges, ...untrackedChanges];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns changes introduced by the current branch relative to `since`.
|
|
89
|
+
* Uses three-dot merge-base semantics so only commits not in `since` are
|
|
90
|
+
* included.
|
|
91
|
+
*/
|
|
92
|
+
async getChangesSince(gitRoot, since, until) {
|
|
93
|
+
// Verify merge-base is reachable (fails on shallow clones without full history)
|
|
94
|
+
try {
|
|
95
|
+
await this.runGit(['merge-base', '--is-ancestor', since, until], gitRoot);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// merge-base failure — check if this is a shallow clone
|
|
99
|
+
const isShallow = await this.isShallowRepository(gitRoot);
|
|
100
|
+
if (isShallow) {
|
|
101
|
+
throw new GitCommandError('git', ['merge-base', since, until], `Repository is a shallow clone. The merge-base between "${since}" and "${until}" cannot be determined.\n` +
|
|
102
|
+
'In GitHub Actions, add `fetch-depth: 0` to the checkout step. ' +
|
|
103
|
+
'Locally, run `git fetch --unshallow`.', 1);
|
|
104
|
+
}
|
|
105
|
+
// Not shallow — just proceed; three-dot diff handles this gracefully
|
|
106
|
+
}
|
|
107
|
+
const stdout = await this.runGit(['diff', '--name-status', '-M', '-z', `${since}...${until}`], gitRoot);
|
|
108
|
+
return this.parseDiffOutput(stdout);
|
|
109
|
+
}
|
|
110
|
+
// ---- Output parsers -----------------------------------------------------
|
|
111
|
+
/**
|
|
112
|
+
* Parses the NUL-delimited output of `git diff --name-status -M -z`.
|
|
113
|
+
*
|
|
114
|
+
* The `-z` flag makes git output fields separated by NUL bytes instead of
|
|
115
|
+
* newlines. For most statuses the format is:
|
|
116
|
+
* `<status> NUL <path> NUL`
|
|
117
|
+
* For renames and copies it is:
|
|
118
|
+
* `R<score> NUL <old-path> NUL <new-path> NUL`
|
|
119
|
+
*/
|
|
120
|
+
parseDiffOutput(raw) {
|
|
121
|
+
if (!raw.trim())
|
|
122
|
+
return [];
|
|
123
|
+
const changes = [];
|
|
124
|
+
// Split on NUL; filter empty trailing entries
|
|
125
|
+
const tokens = raw.split('\0').filter((t, i, arr) => {
|
|
126
|
+
// The last token after a trailing NUL is always empty — drop it
|
|
127
|
+
return !(i === arr.length - 1 && t === '');
|
|
128
|
+
});
|
|
129
|
+
let i = 0;
|
|
130
|
+
while (i < tokens.length) {
|
|
131
|
+
const statusToken = tokens[i];
|
|
132
|
+
if (!statusToken) {
|
|
133
|
+
i++;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const statusCode = statusToken[0] ?? '';
|
|
137
|
+
i++;
|
|
138
|
+
if (statusCode === 'R' || statusCode === 'C') {
|
|
139
|
+
// rename / copy: next two tokens are old-path and new-path
|
|
140
|
+
const oldPath = tokens[i] ?? '';
|
|
141
|
+
const newPath = tokens[i + 1] ?? '';
|
|
142
|
+
i += 2;
|
|
143
|
+
changes.push({
|
|
144
|
+
path: newPath,
|
|
145
|
+
oldPath,
|
|
146
|
+
status: statusCode === 'R' ? 'renamed' : 'copied',
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const filePath = tokens[i] ?? '';
|
|
151
|
+
i++;
|
|
152
|
+
const status = this.mapStatusCode(statusCode);
|
|
153
|
+
if (status !== null) {
|
|
154
|
+
changes.push({ path: filePath, status });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return changes;
|
|
159
|
+
}
|
|
160
|
+
/** Parses NUL-delimited output of `git ls-files --others -z`. */
|
|
161
|
+
parseUntrackedOutput(raw) {
|
|
162
|
+
if (!raw.trim())
|
|
163
|
+
return [];
|
|
164
|
+
return raw
|
|
165
|
+
.split('\0')
|
|
166
|
+
.filter(p => p.length > 0)
|
|
167
|
+
.map(p => ({ path: p, status: 'added' }));
|
|
168
|
+
}
|
|
169
|
+
mapStatusCode(code) {
|
|
170
|
+
switch (code) {
|
|
171
|
+
case 'A': return 'added';
|
|
172
|
+
case 'M': return 'modified';
|
|
173
|
+
case 'D': return 'deleted';
|
|
174
|
+
case 'T': return 'typechange';
|
|
175
|
+
default: return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ---- Path normalisation -------------------------------------------------
|
|
179
|
+
/**
|
|
180
|
+
* Converts absolute-or-git-root-relative paths to codebase-root-relative
|
|
181
|
+
* paths. Paths that fall outside the codebase root are kept with their
|
|
182
|
+
* original path so the analyser can mark them as `outside-codebase`.
|
|
183
|
+
*/
|
|
184
|
+
normaliseAndSort(changes, gitRoot) {
|
|
185
|
+
// Resolve gitRoot and codebaseRoot to their real absolute paths
|
|
186
|
+
// This is crucial on Windows where git might return short paths (e.g. MIRANT~1)
|
|
187
|
+
let realGitRoot = path.resolve(gitRoot);
|
|
188
|
+
let realCbRoot = path.resolve(this.codebaseRoot);
|
|
189
|
+
try {
|
|
190
|
+
realGitRoot = fs.realpathSync.native(realGitRoot);
|
|
191
|
+
}
|
|
192
|
+
catch { /* ignore */ }
|
|
193
|
+
try {
|
|
194
|
+
realCbRoot = fs.realpathSync.native(realCbRoot);
|
|
195
|
+
}
|
|
196
|
+
catch { /* ignore */ }
|
|
197
|
+
const normalised = changes.map(change => {
|
|
198
|
+
// Resolve path using path.resolve (Windows-aware) relative to realGitRoot
|
|
199
|
+
const absolutePath = path.resolve(realGitRoot, change.path);
|
|
200
|
+
const relativeToCb = path.relative(realCbRoot, absolutePath).replace(/\\/g, '/');
|
|
201
|
+
const normalisedChange = { ...change, path: relativeToCb };
|
|
202
|
+
if (change.oldPath !== undefined) {
|
|
203
|
+
const absOld = path.resolve(realGitRoot, change.oldPath);
|
|
204
|
+
normalisedChange.oldPath = path.relative(realCbRoot, absOld).replace(/\\/g, '/');
|
|
205
|
+
}
|
|
206
|
+
return normalisedChange;
|
|
207
|
+
});
|
|
208
|
+
return normalised.sort((a, b) => a.path.localeCompare(b.path));
|
|
209
|
+
}
|
|
210
|
+
// ---- Validation ---------------------------------------------------------
|
|
211
|
+
validateOptions(options) {
|
|
212
|
+
const modes = [
|
|
213
|
+
options.since !== undefined,
|
|
214
|
+
options.staged === true,
|
|
215
|
+
options.uncommitted === true,
|
|
216
|
+
].filter(Boolean).length;
|
|
217
|
+
if (modes > 1) {
|
|
218
|
+
throw new Error('GitChangeSetProvider: options `since`, `staged`, and `uncommitted` are mutually exclusive. ' +
|
|
219
|
+
'Provide at most one.');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Validates a git ref string.
|
|
224
|
+
* Rejects empty strings and strings beginning with `-` (which could be
|
|
225
|
+
* interpreted as flags by git).
|
|
226
|
+
* Uses `git rev-parse --verify --quiet <ref>^{commit}` to confirm the ref
|
|
227
|
+
* resolves to a commit object in the repository.
|
|
228
|
+
*/
|
|
229
|
+
async validateRef(ref, gitRoot) {
|
|
230
|
+
if (!ref || ref.startsWith('-')) {
|
|
231
|
+
throw new InvalidGitRefError(ref);
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
await this.runGit(['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], gitRoot);
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
throw new InvalidGitRefError(ref);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// ---- Git helpers --------------------------------------------------------
|
|
241
|
+
/** Resolves the root of the Git repository containing `codebaseRoot`. */
|
|
242
|
+
async resolveGitRoot() {
|
|
243
|
+
try {
|
|
244
|
+
const stdout = await this.runGit(['rev-parse', '--show-toplevel'], this.codebaseRoot);
|
|
245
|
+
return stdout.trim();
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
throw new NotAGitRepositoryError(this.codebaseRoot);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/** Returns `true` when the repository is a shallow clone. */
|
|
252
|
+
async isShallowRepository(gitRoot) {
|
|
253
|
+
try {
|
|
254
|
+
const stdout = await this.runGit(['rev-parse', '--is-shallow-repository'], gitRoot);
|
|
255
|
+
return stdout.trim() === 'true';
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** Returns `true` if HEAD resolves to a commit (repo has at least one commit). */
|
|
262
|
+
async headExists(gitRoot) {
|
|
263
|
+
try {
|
|
264
|
+
await this.runGit(['rev-parse', '--verify', 'HEAD'], gitRoot);
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/** Throws `GitNotAvailableError` if `git --version` fails. */
|
|
272
|
+
async ensureGitAvailable() {
|
|
273
|
+
try {
|
|
274
|
+
await execFile('git', ['--version']);
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
throw new GitNotAvailableError();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Runs a git command in the given working directory.
|
|
282
|
+
* Always uses `execFile` with an args array — never `exec` with a string.
|
|
283
|
+
*
|
|
284
|
+
* @throws `GitCommandError` on non-zero exit.
|
|
285
|
+
*/
|
|
286
|
+
async runGit(args, cwd) {
|
|
287
|
+
try {
|
|
288
|
+
const { stdout } = await execFile('git', args, { cwd, maxBuffer: 50 * 1024 * 1024 });
|
|
289
|
+
return stdout;
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
const e = err;
|
|
293
|
+
throw new GitCommandError('git', args, e.stderr ?? e.message ?? '', typeof e.code === 'number' ? e.code : 1);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=GitChangeSetProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitChangeSetProvider.js","sourceRoot":"","sources":["../../src/diff/GitChangeSetProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAErB,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;AAEvC,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,oBAAoB;IAMF,YAAY;IALzC;;;;OAIG;IACH,YAA6B,YAAoB;4BAApB,YAAY;IAAW,CAAC;IAE9C,KAAK,CAAC,UAAU,CAAC,OAAO,GAAqB,EAAE;QACpD,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEhC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAE5C,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAChF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEhF,IAAI,OAAqB,CAAC;QAE1B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAC/B,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACtD,CAAC;aAAM,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QACxF,CAAC;aAAM,CAAC;YACN,+CAA+C;YAC/C,OAAO,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACtD,CAAC;QAED,mEAAmE;QACnE,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,4EAA4E;IAE5E,gEAAgE;IACxD,KAAK,CAAC,gBAAgB,CAAC,OAAe;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAC9B,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EACjD,OAAO,CACR,CAAC;QACF,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,qBAAqB,CAAC,OAAe;QACjD,2EAA2E;QAC3E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAE/C,IAAI,WAAW,GAAiB,EAAE,CAAC;QACnC,IAAI,OAAO,EAAE,CAAC;YACZ,oCAAoC;YACpC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAClC,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAC7C,OAAO,CACR,CAAC;YACF,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC;QAED,gCAAgC;QAChC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,MAAM,CACvC,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,IAAI,CAAC,EACpD,OAAO,CACR,CAAC;QACF,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAEpE,OAAO,CAAC,GAAG,WAAW,EAAE,GAAG,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,eAAe,CAC3B,OAAe,EACf,KAAa,EACb,KAAa;QAEb,gFAAgF;QAChF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;YACxD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;YAC1D,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,IAAI,eAAe,CACvB,KAAK,EACL,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,EAC5B,0DAA0D,KAAK,UAAU,KAAK,2BAA2B;oBACvG,gEAAgE;oBAChE,uCAAuC,EACzC,CAAC,CACF,CAAC;YACJ,CAAC;YACD,qEAAqE;QACvE,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAC9B,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,MAAM,KAAK,EAAE,CAAC,EAC5D,OAAO,CACR,CAAC;QACF,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;OAQG;IACK,eAAe,CAAC,GAAW;QACjC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,8CAA8C;QAC9C,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;YAClD,gEAAgE;YAChE,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;gBAAC,CAAC,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAEpC,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACxC,CAAC,EAAE,CAAC;YAEJ,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC7C,2DAA2D;gBAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpC,CAAC,IAAI,CAAC,CAAC;gBACP,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,OAAO;oBACb,OAAO;oBACP,MAAM,EAAE,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ;iBAClD,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACjC,CAAC,EAAE,CAAC;gBACJ,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;gBAC9C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iEAAiE;IACzD,oBAAoB,CAAC,GAAW;QACtC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAC3B,OAAO,GAAG;aACP,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,OAAuB,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC;IAEO,aAAa,CAAC,IAAY;QAChC,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,GAAG,EAAE,OAAO,OAAO,CAAC;YACzB,KAAK,GAAG,EAAE,OAAO,UAAU,CAAC;YAC5B,KAAK,GAAG,EAAE,OAAO,SAAS,CAAC;YAC3B,KAAK,GAAG,EAAE,OAAO,YAAY,CAAC;YAC9B,SAAU,OAAO,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,4EAA4E;IAE5E;;;;OAIG;IACK,gBAAgB,CAAC,OAAqB,EAAE,OAAe;QAC7D,gEAAgE;QAChE,gFAAgF;QAChF,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACxB,IAAI,CAAC;YACH,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAExB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YACtC,0EAA0E;YAC1E,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAEjF,MAAM,gBAAgB,GAAe,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;YAEvE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;gBACzD,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACnF,CAAC;YAED,OAAO,gBAAgB,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,4EAA4E;IAEpE,eAAe,CAAC,OAAyB;QAC/C,MAAM,KAAK,GAAG;YACZ,OAAO,CAAC,KAAK,KAAK,SAAS;YAC3B,OAAO,CAAC,MAAM,KAAK,IAAI;YACvB,OAAO,CAAC,WAAW,KAAK,IAAI;SAC7B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAEzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,6FAA6F;gBAC3F,sBAAsB,CACzB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,WAAW,CAAC,GAAW,EAAE,OAAe;QACpD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACtF,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,4EAA4E;IAE5E,yEAAyE;IACjE,KAAK,CAAC,cAAc;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAC9B,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAChC,IAAI,CAAC,YAAY,CAClB,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,6DAA6D;IACrD,KAAK,CAAC,mBAAmB,CAAC,OAAe;QAC/C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAC9B,CAAC,WAAW,EAAE,yBAAyB,CAAC,EACxC,OAAO,CACR,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,UAAU,CAAC,OAAe;QACtC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,8DAA8D;IACtD,KAAK,CAAC,kBAAkB;QAC9B,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,MAAM,CAAC,IAAc,EAAE,GAAW;QAC9C,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;YACrF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAA2D,CAAC;YACtE,MAAM,IAAI,eAAe,CACvB,KAAK,EACL,IAAI,EACJ,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAC3B,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACxC,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Impact — Git-specific Errors
|
|
3
|
+
*
|
|
4
|
+
* These errors are specific to the Git layer and should not be caught by
|
|
5
|
+
* general application code unless the caller is explicitly handling Git
|
|
6
|
+
* failures.
|
|
7
|
+
*
|
|
8
|
+
* Library consumers who inject a custom `ChangeSetProvider` will never see
|
|
9
|
+
* these errors unless their provider chooses to re-use them.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when `git` is not found in PATH or returns a non-zero exit code
|
|
13
|
+
* during the availability check.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GitNotAvailableError extends Error {
|
|
16
|
+
constructor(message?: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Thrown when the target directory (or any ancestor) is not a Git repository.
|
|
20
|
+
*
|
|
21
|
+
* Typically triggered when `git rev-parse --git-dir` fails.
|
|
22
|
+
*/
|
|
23
|
+
export declare class NotAGitRepositoryError extends Error {
|
|
24
|
+
readonly directory: string;
|
|
25
|
+
constructor(directory: string);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Thrown when a Git ref (branch, tag, commit SHA) provided by the caller
|
|
29
|
+
* cannot be resolved in the current repository.
|
|
30
|
+
*/
|
|
31
|
+
export declare class InvalidGitRefError extends Error {
|
|
32
|
+
readonly ref: string;
|
|
33
|
+
constructor(ref: string);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Thrown when a `git` sub-command exits with a non-zero status code.
|
|
37
|
+
*
|
|
38
|
+
* The `command` and `args` fields allow callers to log or display the
|
|
39
|
+
* exact invocation that failed.
|
|
40
|
+
*/
|
|
41
|
+
export declare class GitCommandError extends Error {
|
|
42
|
+
readonly command: string;
|
|
43
|
+
readonly args: string[];
|
|
44
|
+
readonly stderr: string;
|
|
45
|
+
readonly exitCode: number;
|
|
46
|
+
constructor(command: string, args: string[], stderr: string, exitCode: number);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/diff/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,SAAkC,EAGpD;CACF;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,SAAS,EAAE,MAAM;IAA7C,YAA4B,SAAS,EAAE,MAAM,EAM5C;CACF;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aACf,GAAG,EAAE,MAAM;IAAvC,YAA4B,GAAG,EAAE,MAAM,EAOtC;CACF;AAED;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,OAAO,EAAE,MAAM;aACf,IAAI,EAAE,MAAM,EAAE;aACd,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;IAJlC,YACkB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAOjC;CACF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Impact — Git-specific Errors
|
|
3
|
+
*
|
|
4
|
+
* These errors are specific to the Git layer and should not be caught by
|
|
5
|
+
* general application code unless the caller is explicitly handling Git
|
|
6
|
+
* failures.
|
|
7
|
+
*
|
|
8
|
+
* Library consumers who inject a custom `ChangeSetProvider` will never see
|
|
9
|
+
* these errors unless their provider chooses to re-use them.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Thrown when `git` is not found in PATH or returns a non-zero exit code
|
|
13
|
+
* during the availability check.
|
|
14
|
+
*/
|
|
15
|
+
export class GitNotAvailableError extends Error {
|
|
16
|
+
constructor(message = 'git is not available in PATH.') {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'GitNotAvailableError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Thrown when the target directory (or any ancestor) is not a Git repository.
|
|
23
|
+
*
|
|
24
|
+
* Typically triggered when `git rev-parse --git-dir` fails.
|
|
25
|
+
*/
|
|
26
|
+
export class NotAGitRepositoryError extends Error {
|
|
27
|
+
directory;
|
|
28
|
+
constructor(directory) {
|
|
29
|
+
super(`"${directory}" is not inside a Git repository. ` +
|
|
30
|
+
'Run `git init` or specify a path that is part of a repository.');
|
|
31
|
+
this.directory = directory;
|
|
32
|
+
this.name = 'NotAGitRepositoryError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Thrown when a Git ref (branch, tag, commit SHA) provided by the caller
|
|
37
|
+
* cannot be resolved in the current repository.
|
|
38
|
+
*/
|
|
39
|
+
export class InvalidGitRefError extends Error {
|
|
40
|
+
ref;
|
|
41
|
+
constructor(ref) {
|
|
42
|
+
super(`Git ref "${ref}" could not be resolved. ` +
|
|
43
|
+
'Make sure the ref exists and that the repository has been fetched. ' +
|
|
44
|
+
'In CI environments, use `fetch-depth: 0` to include all history.');
|
|
45
|
+
this.ref = ref;
|
|
46
|
+
this.name = 'InvalidGitRefError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Thrown when a `git` sub-command exits with a non-zero status code.
|
|
51
|
+
*
|
|
52
|
+
* The `command` and `args` fields allow callers to log or display the
|
|
53
|
+
* exact invocation that failed.
|
|
54
|
+
*/
|
|
55
|
+
export class GitCommandError extends Error {
|
|
56
|
+
command;
|
|
57
|
+
args;
|
|
58
|
+
stderr;
|
|
59
|
+
exitCode;
|
|
60
|
+
constructor(command, args, stderr, exitCode) {
|
|
61
|
+
super(`git ${args.join(' ')} failed with exit code ${exitCode}.\n` +
|
|
62
|
+
(stderr ? `stderr: ${stderr}` : ''));
|
|
63
|
+
this.command = command;
|
|
64
|
+
this.args = args;
|
|
65
|
+
this.stderr = stderr;
|
|
66
|
+
this.exitCode = exitCode;
|
|
67
|
+
this.name = 'GitCommandError';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/diff/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,GAAG,+BAA+B;QACnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACnB,SAAS;IAArC,YAA4B,SAAiB;QAC3C,KAAK,CACH,IAAI,SAAS,oCAAoC;YAC/C,gEAAgE,CACnE,CAAC;yBAJwB,SAAS;QAKnC,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACf,GAAG;IAA/B,YAA4B,GAAW;QACrC,KAAK,CACH,YAAY,GAAG,2BAA2B;YACxC,qEAAqE;YACrE,kEAAkE,CACrE,CAAC;mBALwB,GAAG;QAM7B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAEtB,OAAO;IACP,IAAI;IACJ,MAAM;IACN,QAAQ;IAJ1B,YACkB,OAAe,EACf,IAAc,EACd,MAAc,EACd,QAAgB;QAEhC,KAAK,CACH,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,0BAA0B,QAAQ,KAAK;YAC1D,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACtC,CAAC;uBARc,OAAO;oBACP,IAAI;sBACJ,MAAM;wBACN,QAAQ;QAMxB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Impact — Core Types
|
|
3
|
+
*
|
|
4
|
+
* Defines all public-facing types for the git-diff-based impact analysis
|
|
5
|
+
* feature. No business logic lives here.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Git status codes mapped to a human-readable union.
|
|
9
|
+
* Mirrors the single-letter codes from `git diff --name-status`.
|
|
10
|
+
*/
|
|
11
|
+
export type ChangeStatus = 'added' | 'modified' | 'deleted' | 'renamed' | 'copied' | 'typechange';
|
|
12
|
+
/**
|
|
13
|
+
* A single file change as reported by a `ChangeSetProvider`.
|
|
14
|
+
*/
|
|
15
|
+
export interface FileChange {
|
|
16
|
+
/** Current path, relative to the codebase root. */
|
|
17
|
+
path: string;
|
|
18
|
+
/**
|
|
19
|
+
* Original path before a rename or copy.
|
|
20
|
+
* Only present when `status` is `'renamed'` or `'copied'`.
|
|
21
|
+
*/
|
|
22
|
+
oldPath?: string;
|
|
23
|
+
status: ChangeStatus;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Options controlling how a `ChangeSetProvider` collects file changes.
|
|
27
|
+
*
|
|
28
|
+
* **Mutual exclusivity**:
|
|
29
|
+
* - `since` may be combined with `until` but not with `staged` or `uncommitted`.
|
|
30
|
+
* - `staged` and `uncommitted` are mutually exclusive with each other.
|
|
31
|
+
*
|
|
32
|
+
* **Default (no options)**:
|
|
33
|
+
* Returns uncommitted changes (staged + working tree vs HEAD), which is the
|
|
34
|
+
* most useful default for a local development workflow.
|
|
35
|
+
*/
|
|
36
|
+
export interface ChangeSetOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Base ref for a branch/PR comparison.
|
|
39
|
+
* The provider will use `git diff <since>...<until>` (three-dot, merge-base
|
|
40
|
+
* semantics) so only commits introduced by the branch are considered.
|
|
41
|
+
*/
|
|
42
|
+
since?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Head ref for the comparison.
|
|
45
|
+
* @default 'HEAD'
|
|
46
|
+
*/
|
|
47
|
+
until?: string;
|
|
48
|
+
/**
|
|
49
|
+
* When `true`, return only staged (index) changes (`git diff --cached`).
|
|
50
|
+
*/
|
|
51
|
+
staged?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* When `true`, return all uncommitted changes — staged and unstaged — plus
|
|
54
|
+
* untracked files. This is the equivalent of what a developer sees before
|
|
55
|
+
* committing.
|
|
56
|
+
*/
|
|
57
|
+
uncommitted?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Contract for any source of file changes.
|
|
61
|
+
*
|
|
62
|
+
* The core library ships `GitChangeSetProvider` as the default implementation.
|
|
63
|
+
* Alternative implementations (e.g. a GitHub PR API client, a Mercurial
|
|
64
|
+
* adapter, or a test stub) can be injected via `codebase.impactOfChanges()`.
|
|
65
|
+
*/
|
|
66
|
+
export interface ChangeSetProvider {
|
|
67
|
+
/**
|
|
68
|
+
* Returns the list of changed files according to the provider's source.
|
|
69
|
+
* The returned list is ordered by `path` (deterministic).
|
|
70
|
+
*/
|
|
71
|
+
getChanges(options?: ChangeSetOptions): Promise<FileChange[]>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Explains why a changed file could not be traced through the dependency graph.
|
|
75
|
+
*
|
|
76
|
+
* The analyser is honest: it never invents relationships it cannot prove.
|
|
77
|
+
* Files that cannot be analysed are reported explicitly here instead of being
|
|
78
|
+
* silently omitted.
|
|
79
|
+
*/
|
|
80
|
+
export type UnanalyzableReason =
|
|
81
|
+
/** The file path is outside the codebase root that was loaded. */
|
|
82
|
+
'outside-codebase'
|
|
83
|
+
/** The file extension has no registered parser (e.g. `.md`, `.css`). */
|
|
84
|
+
| 'unsupported-language'
|
|
85
|
+
/**
|
|
86
|
+
* The file exists on disk but was not indexed (e.g. it was added after
|
|
87
|
+
* `codebase.analyze()` was called, or it is excluded by ignore rules).
|
|
88
|
+
*/
|
|
89
|
+
| 'not-in-index'
|
|
90
|
+
/**
|
|
91
|
+
* The file was deleted and the graph cannot prove which files depended on
|
|
92
|
+
* it (no recorded `unresolved` edges matching the old path).
|
|
93
|
+
*/
|
|
94
|
+
| 'deleted-unprovable';
|
|
95
|
+
/**
|
|
96
|
+
* The complete result of a change-set impact analysis.
|
|
97
|
+
*
|
|
98
|
+
* **Important — granularity**: the result operates at file granularity, not
|
|
99
|
+
* symbol granularity. A single line change in a file marks *all* dependents
|
|
100
|
+
* of that file as potentially affected. The result is therefore a
|
|
101
|
+
* **conservative upper bound**, not a minimal set.
|
|
102
|
+
*/
|
|
103
|
+
export interface ChangeSetImpact {
|
|
104
|
+
/** The raw list of file changes as provided by the `ChangeSetProvider`. */
|
|
105
|
+
changed: FileChange[];
|
|
106
|
+
/**
|
|
107
|
+
* Files that directly import/depend on at least one changed file.
|
|
108
|
+
* The changed files themselves are excluded from this list.
|
|
109
|
+
*
|
|
110
|
+
* If a file is both a direct dependent of one change and an indirect
|
|
111
|
+
* dependent of another, it is classified as **direct** (highest priority).
|
|
112
|
+
*/
|
|
113
|
+
direct: string[];
|
|
114
|
+
/**
|
|
115
|
+
* All transitive dependents, minus the files already in `direct`.
|
|
116
|
+
* Ordered alphabetically.
|
|
117
|
+
*/
|
|
118
|
+
indirect: string[];
|
|
119
|
+
/**
|
|
120
|
+
* Test files related to any changed or dependent file, discovered by
|
|
121
|
+
* naming convention (e.g. `AuthService.test.ts`). Union across all changes.
|
|
122
|
+
* Ordered alphabetically.
|
|
123
|
+
*/
|
|
124
|
+
tests: string[];
|
|
125
|
+
/**
|
|
126
|
+
* Configuration and infrastructure files that are outside the import graph
|
|
127
|
+
* but whose modification can affect the entire codebase.
|
|
128
|
+
*
|
|
129
|
+
* Examples: `package.json`, `tsconfig.json`, `vite.config.*`, lockfiles.
|
|
130
|
+
* These are reported separately because the graph cannot model their impact.
|
|
131
|
+
*/
|
|
132
|
+
globalChanges: string[];
|
|
133
|
+
/**
|
|
134
|
+
* Files that could not be fully traced through the dependency graph,
|
|
135
|
+
* along with the reason why.
|
|
136
|
+
*/
|
|
137
|
+
unanalyzable: {
|
|
138
|
+
path: string;
|
|
139
|
+
reason: UnanalyzableReason;
|
|
140
|
+
}[];
|
|
141
|
+
/**
|
|
142
|
+
* Specifiers that appear as `unresolved` edges in the dependency graph
|
|
143
|
+
* (i.e. imports whose absolute path the parser could not determine).
|
|
144
|
+
* Reported for transparency; not treated as errors.
|
|
145
|
+
*/
|
|
146
|
+
unresolvedDependencies: string[];
|
|
147
|
+
metadata: {
|
|
148
|
+
/**
|
|
149
|
+
* The analyser operates at file granularity.
|
|
150
|
+
* Every dependent of every changed file is considered potentially affected.
|
|
151
|
+
*/
|
|
152
|
+
granularity: 'file';
|
|
153
|
+
/** The base ref used for the comparison, if any. */
|
|
154
|
+
base?: string;
|
|
155
|
+
/** The head ref used for the comparison, if any. */
|
|
156
|
+
head?: string;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/diff/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,UAAU,GACV,SAAS,GACT,SAAS,GACT,QAAQ,GACR,YAAY,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACtB;AAMD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CAC/D;AAMD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB;AAC5B,kEAAkE;AAChE,kBAAkB;AACpB,wEAAwE;GACtE,sBAAsB;AACxB;;;GAGG;GACD,cAAc;AAChB;;;GAGG;GACD,oBAAoB,CAAC;AAMzB;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,OAAO,EAAE,UAAU,EAAE,CAAC;IAEtB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;OAIG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,kBAAkB,CAAA;KAAE,EAAE,CAAC;IAE7D;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,EAAE,CAAC;IAEjC,QAAQ,EAAE;QACR;;;WAGG;QACH,WAAW,EAAE,MAAM,CAAC;QACpB,oDAAoD;QACpD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,oDAAoD;QACpD,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/diff/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Codebase } from '../core/Codebase.js';
|
|
2
|
+
import type { ExplorerSnapshot } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds an {@link ExplorerSnapshot} from an analysed {@link Codebase}.
|
|
5
|
+
*
|
|
6
|
+
* Rules:
|
|
7
|
+
* - The codebase MUST have been analysed (`analyze()` called) before calling
|
|
8
|
+
* `build()`. If not, edges will be empty because the graph will be empty.
|
|
9
|
+
* - IDs are stable POSIX relative paths (e.g. `src/auth/AuthService.ts`).
|
|
10
|
+
* - External / unresolved graph nodes (not present in `codebase.files()`)
|
|
11
|
+
* are silently skipped — we never invent nodes that the analysis cannot prove.
|
|
12
|
+
* - The resulting snapshot is fully JSON-serialisable with no circular refs.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SnapshotBuilder {
|
|
15
|
+
/**
|
|
16
|
+
* @param codebase The analysed codebase instance.
|
|
17
|
+
* @param rootPath The absolute path that was passed to `Codebase.load()`.
|
|
18
|
+
* Used as `ExplorerSnapshot.rootPath`.
|
|
19
|
+
*/
|
|
20
|
+
static build(codebase: Codebase, rootPath: string): ExplorerSnapshot;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=SnapshotBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapshotBuilder.d.ts","sourceRoot":"","sources":["../../src/explorer/SnapshotBuilder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EACV,gBAAgB,EAKjB,MAAM,YAAY,CAAC;AAsDpB;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IAC1B;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CA6KnE;CACF"}
|