ai-mind-map 1.1.0
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/LICENSE +21 -0
- package/README.md +554 -0
- package/dist/change-tracker/change-log.d.ts +160 -0
- package/dist/change-tracker/change-log.d.ts.map +1 -0
- package/dist/change-tracker/change-log.js +507 -0
- package/dist/change-tracker/change-log.js.map +1 -0
- package/dist/change-tracker/diff-engine.d.ts +149 -0
- package/dist/change-tracker/diff-engine.d.ts.map +1 -0
- package/dist/change-tracker/diff-engine.js +530 -0
- package/dist/change-tracker/diff-engine.js.map +1 -0
- package/dist/change-tracker/watcher.d.ts +137 -0
- package/dist/change-tracker/watcher.d.ts.map +1 -0
- package/dist/change-tracker/watcher.js +300 -0
- package/dist/change-tracker/watcher.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +937 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +222 -0
- package/dist/config.js.map +1 -0
- package/dist/context/compressor.d.ts +49 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +769 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/progressive-disclosure.d.ts +71 -0
- package/dist/context/progressive-disclosure.d.ts.map +1 -0
- package/dist/context/progressive-disclosure.js +470 -0
- package/dist/context/progressive-disclosure.js.map +1 -0
- package/dist/context/token-budget.d.ts +121 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +282 -0
- package/dist/context/token-budget.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +944 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +66 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +946 -0
- package/dist/install.js.map +1 -0
- package/dist/knowledge-graph/architecture.d.ts +213 -0
- package/dist/knowledge-graph/architecture.d.ts.map +1 -0
- package/dist/knowledge-graph/architecture.js +585 -0
- package/dist/knowledge-graph/architecture.js.map +1 -0
- package/dist/knowledge-graph/cypher.d.ts +113 -0
- package/dist/knowledge-graph/cypher.d.ts.map +1 -0
- package/dist/knowledge-graph/cypher.js +1051 -0
- package/dist/knowledge-graph/cypher.js.map +1 -0
- package/dist/knowledge-graph/dead-code.d.ts +121 -0
- package/dist/knowledge-graph/dead-code.d.ts.map +1 -0
- package/dist/knowledge-graph/dead-code.js +331 -0
- package/dist/knowledge-graph/dead-code.js.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts +167 -0
- package/dist/knowledge-graph/flow-analyzer.d.ts.map +1 -0
- package/dist/knowledge-graph/flow-analyzer.js +739 -0
- package/dist/knowledge-graph/flow-analyzer.js.map +1 -0
- package/dist/knowledge-graph/graph.d.ts +291 -0
- package/dist/knowledge-graph/graph.d.ts.map +1 -0
- package/dist/knowledge-graph/graph.js +978 -0
- package/dist/knowledge-graph/graph.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +17 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +14 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/indexer.d.ts +112 -0
- package/dist/knowledge-graph/indexer.d.ts.map +1 -0
- package/dist/knowledge-graph/indexer.js +506 -0
- package/dist/knowledge-graph/indexer.js.map +1 -0
- package/dist/knowledge-graph/pagerank.d.ts +141 -0
- package/dist/knowledge-graph/pagerank.d.ts.map +1 -0
- package/dist/knowledge-graph/pagerank.js +493 -0
- package/dist/knowledge-graph/pagerank.js.map +1 -0
- package/dist/knowledge-graph/parser.d.ts +55 -0
- package/dist/knowledge-graph/parser.d.ts.map +1 -0
- package/dist/knowledge-graph/parser.js +1090 -0
- package/dist/knowledge-graph/parser.js.map +1 -0
- package/dist/knowledge-graph/snapshot.d.ts +107 -0
- package/dist/knowledge-graph/snapshot.d.ts.map +1 -0
- package/dist/knowledge-graph/snapshot.js +435 -0
- package/dist/knowledge-graph/snapshot.js.map +1 -0
- package/dist/memory/decision-log.d.ts +151 -0
- package/dist/memory/decision-log.d.ts.map +1 -0
- package/dist/memory/decision-log.js +482 -0
- package/dist/memory/decision-log.js.map +1 -0
- package/dist/memory/persistent-memory.d.ts +182 -0
- package/dist/memory/persistent-memory.d.ts.map +1 -0
- package/dist/memory/persistent-memory.js +579 -0
- package/dist/memory/persistent-memory.js.map +1 -0
- package/dist/memory/session-memory.d.ts +165 -0
- package/dist/memory/session-memory.d.ts.map +1 -0
- package/dist/memory/session-memory.js +382 -0
- package/dist/memory/session-memory.js.map +1 -0
- package/dist/stress-test.d.ts +10 -0
- package/dist/stress-test.d.ts.map +1 -0
- package/dist/stress-test.js +258 -0
- package/dist/stress-test.js.map +1 -0
- package/dist/tools/advanced-tools.d.ts +32 -0
- package/dist/tools/advanced-tools.d.ts.map +1 -0
- package/dist/tools/advanced-tools.js +480 -0
- package/dist/tools/advanced-tools.js.map +1 -0
- package/dist/tools/change-tools.d.ts +76 -0
- package/dist/tools/change-tools.d.ts.map +1 -0
- package/dist/tools/change-tools.js +93 -0
- package/dist/tools/change-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +68 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +141 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/debug-tools.d.ts +25 -0
- package/dist/tools/debug-tools.d.ts.map +1 -0
- package/dist/tools/debug-tools.js +286 -0
- package/dist/tools/debug-tools.js.map +1 -0
- package/dist/tools/evolving-tools.d.ts +23 -0
- package/dist/tools/evolving-tools.d.ts.map +1 -0
- package/dist/tools/evolving-tools.js +207 -0
- package/dist/tools/evolving-tools.js.map +1 -0
- package/dist/tools/flow-tools.d.ts +24 -0
- package/dist/tools/flow-tools.d.ts.map +1 -0
- package/dist/tools/flow-tools.js +265 -0
- package/dist/tools/flow-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +71 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +165 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +62 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +195 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/smart-tools.d.ts +23 -0
- package/dist/tools/smart-tools.d.ts.map +1 -0
- package/dist/tools/smart-tools.js +482 -0
- package/dist/tools/smart-tools.js.map +1 -0
- package/dist/tools/snapshot-tools.d.ts +19 -0
- package/dist/tools/snapshot-tools.d.ts.map +1 -0
- package/dist/tools/snapshot-tools.js +149 -0
- package/dist/tools/snapshot-tools.js.map +1 -0
- package/dist/types.d.ts +181 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +142 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/token-counter.d.ts +51 -0
- package/dist/utils/token-counter.d.ts.map +1 -0
- package/dist/utils/token-counter.js +181 -0
- package/dist/utils/token-counter.js.map +1 -0
- package/install.ps1 +321 -0
- package/install.sh +345 -0
- package/package.json +94 -0
- package/setup.bat +62 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Mind Map — Diff Engine
|
|
3
|
+
*
|
|
4
|
+
* Git-aware diff analysis using simple-git. Provides rich, human-readable
|
|
5
|
+
* change summaries suitable for an LLM session preamble (so the agent knows
|
|
6
|
+
* what happened since it last looked). Falls back to filesystem timestamps
|
|
7
|
+
* when the project is not under git.
|
|
8
|
+
*
|
|
9
|
+
* Inspired by Aider's repo-map diff view and context-mode's session deltas.
|
|
10
|
+
*/
|
|
11
|
+
import { stat, readdir } from 'node:fs/promises';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { simpleGit } from 'simple-git';
|
|
14
|
+
// ---------------------------------------------------------------- engine --
|
|
15
|
+
/**
|
|
16
|
+
* Stateless diff engine — every public method takes the information it needs
|
|
17
|
+
* and returns structured results. The class exists mainly to hold the
|
|
18
|
+
* project-root and lazily-initialised git client.
|
|
19
|
+
*/
|
|
20
|
+
export class DiffEngine {
|
|
21
|
+
projectRoot;
|
|
22
|
+
git = null;
|
|
23
|
+
isGitRepo = null;
|
|
24
|
+
constructor(projectRoot) {
|
|
25
|
+
this.projectRoot = path.resolve(projectRoot);
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------- public API ------
|
|
28
|
+
/**
|
|
29
|
+
* Get all changes that occurred since a given unix-epoch timestamp.
|
|
30
|
+
*
|
|
31
|
+
* When the project is a git repo the engine queries `git log --since`;
|
|
32
|
+
* otherwise it falls back to filesystem `mtime`.
|
|
33
|
+
*
|
|
34
|
+
* @param sinceTimestamp Unix-epoch **milliseconds**.
|
|
35
|
+
* @param sessionId Identifier for the current session.
|
|
36
|
+
*/
|
|
37
|
+
async getChangesSinceTimestamp(sinceTimestamp, sessionId, options) {
|
|
38
|
+
if (await this.ensureGit()) {
|
|
39
|
+
return this.gitChangesSinceTimestamp(sinceTimestamp, sessionId, options);
|
|
40
|
+
}
|
|
41
|
+
return this.fsChangesSinceTimestamp(sinceTimestamp, sessionId, options);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get all uncommitted changes (working tree + staged).
|
|
45
|
+
*/
|
|
46
|
+
async getUncommittedChanges(sessionId, options) {
|
|
47
|
+
if (await this.ensureGit()) {
|
|
48
|
+
return this.gitUncommittedChanges(sessionId, options);
|
|
49
|
+
}
|
|
50
|
+
// Non-git repo — no concept of "uncommitted", return empty.
|
|
51
|
+
return this.emptyDiffSummary(false);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get changes between two git refs (commits, branches, tags).
|
|
55
|
+
*
|
|
56
|
+
* Throws if the project is not a git repo.
|
|
57
|
+
*/
|
|
58
|
+
async getChangesBetweenRefs(fromRef, toRef, sessionId, options) {
|
|
59
|
+
if (!(await this.ensureGit())) {
|
|
60
|
+
throw new Error('getChangesBetweenRefs requires a git repository');
|
|
61
|
+
}
|
|
62
|
+
return this.gitChangesBetweenRefs(fromRef, toRef, sessionId, options);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate a human-readable summary string from a set of FileChange
|
|
66
|
+
* records. Useful when the caller assembles changes from the change-log
|
|
67
|
+
* rather than from git directly.
|
|
68
|
+
*/
|
|
69
|
+
formatSummary(changes, contextLabel) {
|
|
70
|
+
return DiffEngine.buildSummaryText(changes, contextLabel);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the actual diff content (patch hunks) for changes since a timestamp.
|
|
74
|
+
* Unlike getChangesSinceTimestamp which only gives summary counts,
|
|
75
|
+
* this returns the ACTUAL code changes.
|
|
76
|
+
*/
|
|
77
|
+
async getActualDiff(sinceTimestamp, options) {
|
|
78
|
+
if (!(await this.ensureGit())) {
|
|
79
|
+
return { diff: 'Not a git repository — actual diff not available.', files: [], truncated: false };
|
|
80
|
+
}
|
|
81
|
+
const git = this.git;
|
|
82
|
+
const sinceISO = new Date(sinceTimestamp).toISOString();
|
|
83
|
+
try {
|
|
84
|
+
// Find the oldest commit since the timestamp
|
|
85
|
+
const log = await git.log({ '--since': sinceISO });
|
|
86
|
+
const args = [];
|
|
87
|
+
if (log.total > 0) {
|
|
88
|
+
const oldestHash = log.all[log.all.length - 1]?.hash;
|
|
89
|
+
if (oldestHash) {
|
|
90
|
+
args.push(`${oldestHash}~1`, 'HEAD');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// If no commits, show uncommitted changes
|
|
94
|
+
if (args.length === 0) {
|
|
95
|
+
args.push('HEAD');
|
|
96
|
+
}
|
|
97
|
+
// Add file filter if specified
|
|
98
|
+
if (options?.filePath) {
|
|
99
|
+
args.push('--', options.filePath);
|
|
100
|
+
}
|
|
101
|
+
const rawDiff = await git.diff(args);
|
|
102
|
+
// Also get uncommitted changes
|
|
103
|
+
const uncommittedArgs = options?.filePath ? ['--', options.filePath] : [];
|
|
104
|
+
const uncommittedDiff = await git.diff(uncommittedArgs).catch(() => '');
|
|
105
|
+
const stagedDiff = await git.diff(['--cached', ...uncommittedArgs]).catch(() => '');
|
|
106
|
+
let fullDiff = [rawDiff, uncommittedDiff, stagedDiff].filter(Boolean).join('\n');
|
|
107
|
+
const files = [...new Set(fullDiff.match(/^diff --git a\/(.+?) b\//gm)?.map(m => m.replace('diff --git a/', '').replace(/ b\/.*$/, '')) ?? [])];
|
|
108
|
+
// Truncate if too long
|
|
109
|
+
const maxLines = options?.maxLines ?? 500;
|
|
110
|
+
const lines = fullDiff.split('\n');
|
|
111
|
+
let truncated = false;
|
|
112
|
+
if (lines.length > maxLines) {
|
|
113
|
+
fullDiff = lines.slice(0, maxLines).join('\n') +
|
|
114
|
+
`\n\n... [truncated ${lines.length - maxLines} more lines]`;
|
|
115
|
+
truncated = true;
|
|
116
|
+
}
|
|
117
|
+
return { diff: fullDiff || 'No changes found.', files, truncated };
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
return { diff: `Error getting diff: ${msg}`, files: [], truncated: false };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get the content of a file at a specific git revision.
|
|
126
|
+
* This lets the AI see "what the file looked like BEFORE the change".
|
|
127
|
+
*
|
|
128
|
+
* @param filePath Relative path within the repo.
|
|
129
|
+
* @param revision Git ref — 'HEAD~1', a commit hash, a branch, or 'HEAD'.
|
|
130
|
+
*/
|
|
131
|
+
async getFileAtRevision(filePath, revision = 'HEAD~1') {
|
|
132
|
+
if (!(await this.ensureGit())) {
|
|
133
|
+
return { content: 'Not a git repository.', revision, found: false };
|
|
134
|
+
}
|
|
135
|
+
const git = this.git;
|
|
136
|
+
try {
|
|
137
|
+
const content = await git.show([`${revision}:${filePath}`]);
|
|
138
|
+
return { content, revision, found: true };
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return {
|
|
142
|
+
content: `File "${filePath}" not found at revision "${revision}" — it may not have existed yet.`,
|
|
143
|
+
revision,
|
|
144
|
+
found: false,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get the recent git log for a specific file — who changed it, when, and why.
|
|
150
|
+
*/
|
|
151
|
+
async getFileHistory(filePath, maxCommits = 10) {
|
|
152
|
+
if (!(await this.ensureGit())) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
const git = this.git;
|
|
156
|
+
try {
|
|
157
|
+
const log = await git.log({
|
|
158
|
+
file: filePath,
|
|
159
|
+
maxCount: maxCommits,
|
|
160
|
+
});
|
|
161
|
+
return log.all.map(entry => ({
|
|
162
|
+
hash: entry.hash.substring(0, 8),
|
|
163
|
+
date: entry.date,
|
|
164
|
+
message: entry.message,
|
|
165
|
+
author: entry.author_name,
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Detect whether the project root is inside a git repository.
|
|
174
|
+
*/
|
|
175
|
+
async isGitRepository() {
|
|
176
|
+
return this.ensureGit();
|
|
177
|
+
}
|
|
178
|
+
// -------------------------------------------------- git: since ts -----
|
|
179
|
+
async gitChangesSinceTimestamp(sinceTimestamp, sessionId, options) {
|
|
180
|
+
const git = this.git;
|
|
181
|
+
// ISO date for git --since
|
|
182
|
+
const sinceISO = new Date(sinceTimestamp).toISOString();
|
|
183
|
+
const timeDelta = humanTimeDelta(sinceTimestamp);
|
|
184
|
+
try {
|
|
185
|
+
// Get the list of commits since the timestamp
|
|
186
|
+
const log = await git.log({ '--since': sinceISO });
|
|
187
|
+
if (log.total === 0) {
|
|
188
|
+
// No commits since then — check for uncommitted changes
|
|
189
|
+
return this.gitUncommittedChanges(sessionId, options);
|
|
190
|
+
}
|
|
191
|
+
// Diff between the oldest commit's parent and HEAD
|
|
192
|
+
const oldestHash = log.all[log.all.length - 1]?.hash;
|
|
193
|
+
if (!oldestHash) {
|
|
194
|
+
return this.emptyDiffSummary(true);
|
|
195
|
+
}
|
|
196
|
+
const diffResult = await git.diffSummary([`${oldestHash}~1`, 'HEAD']).catch(
|
|
197
|
+
// If oldestHash has no parent (initial commit), diff against empty tree
|
|
198
|
+
() => git.diffSummary([
|
|
199
|
+
'4b825dc642cb6eb9a060e54bf899d8b2b04e3660', // git empty-tree hash
|
|
200
|
+
'HEAD',
|
|
201
|
+
]));
|
|
202
|
+
// Also include uncommitted changes
|
|
203
|
+
const uncommitted = await this.getRawUncommitted();
|
|
204
|
+
const allFiles = this.mergeDiffFiles(diffResult.files, uncommitted);
|
|
205
|
+
let changes = this.diffFilesToFileChanges(allFiles, sessionId);
|
|
206
|
+
changes = this.applyFilters(changes, options);
|
|
207
|
+
return {
|
|
208
|
+
text: DiffEngine.buildSummaryText(changes, `Since last session (${timeDelta} ago)`),
|
|
209
|
+
changes,
|
|
210
|
+
totalLinesAdded: sumField(changes, 'linesAdded'),
|
|
211
|
+
totalLinesRemoved: sumField(changes, 'linesRemoved'),
|
|
212
|
+
filesAffected: changes.length,
|
|
213
|
+
usedGit: true,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
// Graceful degradation — fall back to FS timestamps
|
|
218
|
+
return this.fsChangesSinceTimestamp(sinceTimestamp, sessionId, options);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// -------------------------------------------------- git: uncommitted ---
|
|
222
|
+
async gitUncommittedChanges(sessionId, options) {
|
|
223
|
+
const files = await this.getRawUncommitted();
|
|
224
|
+
let changes = this.diffFilesToFileChanges(files, sessionId);
|
|
225
|
+
changes = this.applyFilters(changes, options);
|
|
226
|
+
return {
|
|
227
|
+
text: DiffEngine.buildSummaryText(changes, 'Uncommitted changes'),
|
|
228
|
+
changes,
|
|
229
|
+
totalLinesAdded: sumField(changes, 'linesAdded'),
|
|
230
|
+
totalLinesRemoved: sumField(changes, 'linesRemoved'),
|
|
231
|
+
filesAffected: changes.length,
|
|
232
|
+
usedGit: true,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/** Retrieve raw uncommitted diff files (staged + unstaged). */
|
|
236
|
+
async getRawUncommitted() {
|
|
237
|
+
const git = this.git;
|
|
238
|
+
try {
|
|
239
|
+
const [staged, unstaged] = await Promise.all([
|
|
240
|
+
git.diffSummary(['--cached']),
|
|
241
|
+
git.diffSummary(),
|
|
242
|
+
]);
|
|
243
|
+
return this.mergeDiffFiles(staged.files, unstaged.files);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// -------------------------------------------------- git: between refs --
|
|
250
|
+
async gitChangesBetweenRefs(fromRef, toRef, sessionId, options) {
|
|
251
|
+
const git = this.git;
|
|
252
|
+
const diffResult = await git.diffSummary([fromRef, toRef]);
|
|
253
|
+
let changes = this.diffFilesToFileChanges(diffResult.files, sessionId);
|
|
254
|
+
changes = this.applyFilters(changes, options);
|
|
255
|
+
const label = `Changes between ${fromRef} → ${toRef}`;
|
|
256
|
+
return {
|
|
257
|
+
text: DiffEngine.buildSummaryText(changes, label),
|
|
258
|
+
changes,
|
|
259
|
+
totalLinesAdded: sumField(changes, 'linesAdded'),
|
|
260
|
+
totalLinesRemoved: sumField(changes, 'linesRemoved'),
|
|
261
|
+
filesAffected: changes.length,
|
|
262
|
+
usedGit: true,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// --------------------------------------------- filesystem fallback -----
|
|
266
|
+
/**
|
|
267
|
+
* Walk the project tree and report every file whose `mtime` is newer than
|
|
268
|
+
* `sinceTimestamp`. This is the fallback for non-git projects.
|
|
269
|
+
*/
|
|
270
|
+
async fsChangesSinceTimestamp(sinceTimestamp, sessionId, options) {
|
|
271
|
+
const modifiedFiles = await this.walkForModified(this.projectRoot, sinceTimestamp);
|
|
272
|
+
const now = Date.now();
|
|
273
|
+
let changes = modifiedFiles.map((fp) => ({
|
|
274
|
+
filePath: path.relative(this.projectRoot, fp),
|
|
275
|
+
changeType: 'modified',
|
|
276
|
+
summary: 'File modified (detected via filesystem timestamp)',
|
|
277
|
+
symbolsAffected: [],
|
|
278
|
+
linesAdded: 0,
|
|
279
|
+
linesRemoved: 0,
|
|
280
|
+
timestamp: now,
|
|
281
|
+
sessionId,
|
|
282
|
+
}));
|
|
283
|
+
changes = this.applyFilters(changes, options);
|
|
284
|
+
const timeDelta = humanTimeDelta(sinceTimestamp);
|
|
285
|
+
return {
|
|
286
|
+
text: DiffEngine.buildSummaryText(changes, `Since last session (${timeDelta} ago)`),
|
|
287
|
+
changes,
|
|
288
|
+
totalLinesAdded: 0,
|
|
289
|
+
totalLinesRemoved: 0,
|
|
290
|
+
filesAffected: changes.length,
|
|
291
|
+
usedGit: false,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/** Recursively find files modified after `sinceMs` (epoch ms). */
|
|
295
|
+
async walkForModified(dir, sinceMs) {
|
|
296
|
+
const results = [];
|
|
297
|
+
let entries;
|
|
298
|
+
try {
|
|
299
|
+
entries = await readdir(dir);
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return results;
|
|
303
|
+
}
|
|
304
|
+
for (const entry of entries) {
|
|
305
|
+
// Skip common non-source directories.
|
|
306
|
+
if (entry === 'node_modules' || entry === '.git' || entry === 'dist')
|
|
307
|
+
continue;
|
|
308
|
+
const full = path.join(dir, entry);
|
|
309
|
+
try {
|
|
310
|
+
const st = await stat(full);
|
|
311
|
+
if (st.isDirectory()) {
|
|
312
|
+
const sub = await this.walkForModified(full, sinceMs);
|
|
313
|
+
results.push(...sub);
|
|
314
|
+
}
|
|
315
|
+
else if (st.isFile() && st.mtimeMs > sinceMs) {
|
|
316
|
+
results.push(full);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
// Inaccessible — skip.
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return results;
|
|
324
|
+
}
|
|
325
|
+
// --------------------------------------------------------- conversion --
|
|
326
|
+
/**
|
|
327
|
+
* Convert simple-git `DiffResultTextFile` records into our domain
|
|
328
|
+
* `FileChange` objects.
|
|
329
|
+
*/
|
|
330
|
+
diffFilesToFileChanges(files, sessionId) {
|
|
331
|
+
const now = Date.now();
|
|
332
|
+
return files.map((f) => {
|
|
333
|
+
const changeType = this.inferChangeType(f);
|
|
334
|
+
const renamed = isRename(f.file);
|
|
335
|
+
const change = {
|
|
336
|
+
filePath: renamed ? renamed.newPath : f.file,
|
|
337
|
+
changeType,
|
|
338
|
+
summary: this.buildFileSummary(f, changeType),
|
|
339
|
+
symbolsAffected: [], // Populated later by AST comparison
|
|
340
|
+
linesAdded: f.insertions,
|
|
341
|
+
linesRemoved: f.deletions,
|
|
342
|
+
timestamp: now,
|
|
343
|
+
sessionId,
|
|
344
|
+
};
|
|
345
|
+
if (renamed) {
|
|
346
|
+
change.oldPath = renamed.oldPath;
|
|
347
|
+
}
|
|
348
|
+
return change;
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/** Infer the {@link ChangeType} from a git diff file record. */
|
|
352
|
+
inferChangeType(f) {
|
|
353
|
+
// simple-git marks binary/rename files; we infer from insertions/deletions
|
|
354
|
+
const file = f.file;
|
|
355
|
+
if (isRename(file))
|
|
356
|
+
return 'renamed';
|
|
357
|
+
if (f.deletions > 0 && f.insertions === 0 && this.looksDeleted(f))
|
|
358
|
+
return 'deleted';
|
|
359
|
+
if (f.insertions > 0 && f.deletions === 0)
|
|
360
|
+
return 'created';
|
|
361
|
+
return 'modified';
|
|
362
|
+
}
|
|
363
|
+
/** Heuristic: a file is "deleted" when it has only deletions and the
|
|
364
|
+
* file no longer exists on disk. */
|
|
365
|
+
looksDeleted(f) {
|
|
366
|
+
// We can't easily check disk here without async, so rely on git's info.
|
|
367
|
+
// When the file is present in `--name-status` as "D" simple-git already
|
|
368
|
+
// marks it, but the type we receive doesn't expose that. We fall back
|
|
369
|
+
// to treating it as "modified" and let the change-log correct later.
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
/** Build a one-line human-readable summary for a single file change. */
|
|
373
|
+
buildFileSummary(f, changeType) {
|
|
374
|
+
const parts = [];
|
|
375
|
+
switch (changeType) {
|
|
376
|
+
case 'created':
|
|
377
|
+
parts.push(`Created (+${f.insertions} lines)`);
|
|
378
|
+
break;
|
|
379
|
+
case 'deleted':
|
|
380
|
+
parts.push('[DELETED]');
|
|
381
|
+
break;
|
|
382
|
+
case 'renamed': {
|
|
383
|
+
const r = isRename(f.file);
|
|
384
|
+
parts.push(`Renamed from ${r?.oldPath ?? '?'} (+${f.insertions}, -${f.deletions} lines)`);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case 'modified':
|
|
388
|
+
parts.push(`Modified (+${f.insertions}, -${f.deletions} lines)`);
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
return parts.join('; ');
|
|
392
|
+
}
|
|
393
|
+
// --------------------------------------------------- merge / filter ---
|
|
394
|
+
/**
|
|
395
|
+
* Merge two arrays of diff files, deduplicating by file path (later entry
|
|
396
|
+
* wins so that staged + unstaged don't double-count).
|
|
397
|
+
*/
|
|
398
|
+
mergeDiffFiles(a, b) {
|
|
399
|
+
const map = new Map();
|
|
400
|
+
for (const f of a)
|
|
401
|
+
map.set(f.file, f);
|
|
402
|
+
for (const f of b) {
|
|
403
|
+
const existing = map.get(f.file);
|
|
404
|
+
if (existing) {
|
|
405
|
+
// Sum insertions/deletions when both staged and unstaged touch the same file.
|
|
406
|
+
map.set(f.file, {
|
|
407
|
+
...existing,
|
|
408
|
+
insertions: existing.insertions + f.insertions,
|
|
409
|
+
deletions: existing.deletions + f.deletions,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
map.set(f.file, f);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return Array.from(map.values());
|
|
417
|
+
}
|
|
418
|
+
/** Apply include/exclude glob filters to a list of changes. */
|
|
419
|
+
applyFilters(changes, options) {
|
|
420
|
+
if (!options)
|
|
421
|
+
return changes;
|
|
422
|
+
let result = changes;
|
|
423
|
+
if (options.includePatterns?.length) {
|
|
424
|
+
const patterns = options.includePatterns;
|
|
425
|
+
result = result.filter((c) => patterns.some((p) => matchGlob(c.filePath, p)));
|
|
426
|
+
}
|
|
427
|
+
if (options.excludePatterns?.length) {
|
|
428
|
+
const patterns = options.excludePatterns;
|
|
429
|
+
result = result.filter((c) => !patterns.some((p) => matchGlob(c.filePath, p)));
|
|
430
|
+
}
|
|
431
|
+
return result;
|
|
432
|
+
}
|
|
433
|
+
// ---------------------------------------------------------- git init ---
|
|
434
|
+
/**
|
|
435
|
+
* Lazily initialise the git client and probe whether the directory is a
|
|
436
|
+
* git repo. Returns `true` when git is available.
|
|
437
|
+
*/
|
|
438
|
+
async ensureGit() {
|
|
439
|
+
if (this.isGitRepo !== null)
|
|
440
|
+
return this.isGitRepo;
|
|
441
|
+
this.git = simpleGit(this.projectRoot);
|
|
442
|
+
try {
|
|
443
|
+
const isRepo = await this.git.checkIsRepo();
|
|
444
|
+
this.isGitRepo = isRepo;
|
|
445
|
+
return isRepo;
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
this.isGitRepo = false;
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// ------------------------------------------------------ static helpers --
|
|
453
|
+
/** Build the multi-line summary text. */
|
|
454
|
+
static buildSummaryText(changes, contextLabel) {
|
|
455
|
+
if (changes.length === 0) {
|
|
456
|
+
return contextLabel
|
|
457
|
+
? `${contextLabel}:\n No changes detected.`
|
|
458
|
+
: 'No changes detected.';
|
|
459
|
+
}
|
|
460
|
+
const header = contextLabel ? `${contextLabel}:` : 'Changes:';
|
|
461
|
+
const lines = changes.map((c) => {
|
|
462
|
+
const prefix = ` - ${c.filePath}:`;
|
|
463
|
+
return `${prefix} ${c.summary}`;
|
|
464
|
+
});
|
|
465
|
+
return [header, ...lines].join('\n');
|
|
466
|
+
}
|
|
467
|
+
/** Convenience for an empty summary. */
|
|
468
|
+
emptyDiffSummary(usedGit) {
|
|
469
|
+
return {
|
|
470
|
+
text: 'No changes detected.',
|
|
471
|
+
changes: [],
|
|
472
|
+
totalLinesAdded: 0,
|
|
473
|
+
totalLinesRemoved: 0,
|
|
474
|
+
filesAffected: 0,
|
|
475
|
+
usedGit,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
// ============================================================ utilities ==
|
|
480
|
+
/** Parse git's rename notation `{old => new}` or `old => new` into paths. */
|
|
481
|
+
function isRename(file) {
|
|
482
|
+
// Pattern: "path/{old => new}/rest" or "old => new"
|
|
483
|
+
const braceMatch = file.match(/^(.*)\{(.+?) => (.+?)\}(.*)$/);
|
|
484
|
+
if (braceMatch) {
|
|
485
|
+
const [, prefix, oldPart, newPart, suffix] = braceMatch;
|
|
486
|
+
return {
|
|
487
|
+
oldPath: `${prefix}${oldPart}${suffix}`.replace(/\/\//g, '/'),
|
|
488
|
+
newPath: `${prefix}${newPart}${suffix}`.replace(/\/\//g, '/'),
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
const arrowMatch = file.match(/^(.+?) => (.+?)$/);
|
|
492
|
+
if (arrowMatch) {
|
|
493
|
+
return { oldPath: arrowMatch[1], newPath: arrowMatch[2] };
|
|
494
|
+
}
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
/** Trivial glob match — supports `*` and `**` segments. */
|
|
498
|
+
function matchGlob(filepath, pattern) {
|
|
499
|
+
// Normalise separators
|
|
500
|
+
const fp = filepath.replace(/\\/g, '/');
|
|
501
|
+
const p = pattern.replace(/\\/g, '/');
|
|
502
|
+
// Convert glob to regex
|
|
503
|
+
const regexStr = p
|
|
504
|
+
.replace(/\./g, '\\.')
|
|
505
|
+
.replace(/\*\*/g, '⚬⚬') // placeholder
|
|
506
|
+
.replace(/\*/g, '[^/]*')
|
|
507
|
+
.replace(/⚬⚬/g, '.*');
|
|
508
|
+
return new RegExp(`^${regexStr}$`).test(fp) ||
|
|
509
|
+
new RegExp(`(^|/)${regexStr}($|/)`).test(fp);
|
|
510
|
+
}
|
|
511
|
+
/** Sum a numeric field across an array. */
|
|
512
|
+
function sumField(arr, field) {
|
|
513
|
+
return arr.reduce((acc, c) => acc + c[field], 0);
|
|
514
|
+
}
|
|
515
|
+
/** Convert a past timestamp into a human-friendly delta like "2h". */
|
|
516
|
+
function humanTimeDelta(pastMs) {
|
|
517
|
+
const delta = Date.now() - pastMs;
|
|
518
|
+
const seconds = Math.floor(delta / 1000);
|
|
519
|
+
if (seconds < 60)
|
|
520
|
+
return `${seconds}s`;
|
|
521
|
+
const minutes = Math.floor(seconds / 60);
|
|
522
|
+
if (minutes < 60)
|
|
523
|
+
return `${minutes}m`;
|
|
524
|
+
const hours = Math.floor(minutes / 60);
|
|
525
|
+
if (hours < 24)
|
|
526
|
+
return `${hours}h`;
|
|
527
|
+
const days = Math.floor(hours / 24);
|
|
528
|
+
return `${days}d`;
|
|
529
|
+
}
|
|
530
|
+
//# sourceMappingURL=diff-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-engine.js","sourceRoot":"","sources":["../../src/change-tracker/diff-engine.ts"],"names":[],"mappings":"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"}
|