threadlines 0.4.0 → 0.5.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/dist/git/local.js +31 -48
- package/package.json +1 -1
package/dist/git/local.js
CHANGED
|
@@ -95,58 +95,38 @@ async function getLocalContext(repoRoot, commitSha) {
|
|
|
95
95
|
* or review unstaged changes if nothing is staged.
|
|
96
96
|
*/
|
|
97
97
|
async function getDiff(repoRoot) {
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
// Use git diff commands as source of truth (more reliable than git status --porcelain)
|
|
99
|
+
// git status --porcelain can be inconsistent in some edge cases
|
|
100
|
+
// Check staged files first (source of truth)
|
|
101
|
+
const stagedFilesOutput = (0, child_process_1.execSync)('git diff --cached --name-only', {
|
|
102
|
+
encoding: 'utf-8',
|
|
103
|
+
cwd: repoRoot
|
|
104
|
+
}).trim();
|
|
105
|
+
const actualStagedFiles = stagedFilesOutput ? stagedFilesOutput.split('\n') : [];
|
|
106
|
+
// Check unstaged files (source of truth)
|
|
107
|
+
const unstagedFilesOutput = (0, child_process_1.execSync)('git diff --name-only', {
|
|
108
|
+
encoding: 'utf-8',
|
|
109
|
+
cwd: repoRoot
|
|
110
|
+
}).trim();
|
|
111
|
+
const actualUnstagedFiles = unstagedFilesOutput ? unstagedFilesOutput.split('\n') : [];
|
|
112
|
+
// Get untracked files from git status --porcelain (only reliable way to get untracked)
|
|
103
113
|
const statusOutput = (0, child_process_1.execSync)('git status --porcelain', {
|
|
104
114
|
encoding: 'utf-8',
|
|
105
115
|
cwd: repoRoot
|
|
106
116
|
}).trim();
|
|
107
117
|
const lines = statusOutput ? statusOutput.split('\n') : [];
|
|
108
|
-
const staged = [];
|
|
109
|
-
const unstaged = [];
|
|
110
118
|
const untracked = [];
|
|
111
119
|
for (const line of lines) {
|
|
112
120
|
const stagedStatus = line[0];
|
|
113
121
|
const unstagedStatus = line[1];
|
|
114
|
-
// Collect untracked files
|
|
122
|
+
// Collect untracked files (only reliable way to detect them)
|
|
115
123
|
if (stagedStatus === '?' && unstagedStatus === '?') {
|
|
116
|
-
// Format: "?? filename" - skip 3 characters
|
|
117
124
|
const file = line.slice(3);
|
|
118
125
|
untracked.push(file);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
// For tracked files, the format can be:
|
|
122
|
-
// - "M filename" (staged, no leading space) - skip 2 characters
|
|
123
|
-
// - " M filename" (unstaged, leading space) - skip 3 characters
|
|
124
|
-
// - "MM filename" (both staged and unstaged) - skip 3 characters
|
|
125
|
-
let file;
|
|
126
|
-
if (stagedStatus !== ' ' && unstagedStatus === ' ') {
|
|
127
|
-
// Staged only: "M filename" - skip 2 characters (M + space)
|
|
128
|
-
file = line.slice(2);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
// Unstaged or both: " M filename" or "MM filename" - skip 3 characters
|
|
132
|
-
file = line.slice(3);
|
|
133
|
-
}
|
|
134
|
-
if (stagedStatus !== ' ') {
|
|
135
|
-
staged.push(file);
|
|
136
|
-
}
|
|
137
|
-
if (unstagedStatus !== ' ' && unstagedStatus !== '?') {
|
|
138
|
-
unstaged.push(file);
|
|
139
126
|
}
|
|
140
127
|
}
|
|
141
128
|
let diff;
|
|
142
129
|
let changedFiles;
|
|
143
|
-
// Check if there are actually staged files (use git diff as source of truth)
|
|
144
|
-
// git status parsing can be inconsistent, so we verify with git diff
|
|
145
|
-
const stagedFilesOutput = (0, child_process_1.execSync)('git diff --cached --name-only', {
|
|
146
|
-
encoding: 'utf-8',
|
|
147
|
-
cwd: repoRoot
|
|
148
|
-
}).trim();
|
|
149
|
-
const actualStagedFiles = stagedFilesOutput ? stagedFilesOutput.split('\n') : [];
|
|
150
130
|
// Workflow A: Developer has staged files - check ONLY staged files
|
|
151
131
|
// (Ignore unstaged and untracked - developer explicitly chose to check staged)
|
|
152
132
|
if (actualStagedFiles.length > 0) {
|
|
@@ -168,27 +148,22 @@ async function getDiff(repoRoot) {
|
|
|
168
148
|
};
|
|
169
149
|
}
|
|
170
150
|
// No staged files - log clearly and continue to unstaged/untracked
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
logger_1.logger.info(`No staged files detected (files may have been unstaged), checking unstaged/untracked files instead.`);
|
|
151
|
+
if (actualUnstagedFiles.length > 0 || untracked.length > 0) {
|
|
152
|
+
logger_1.logger.info(`No staged files, checking unstaged/untracked files.`);
|
|
174
153
|
}
|
|
175
154
|
else {
|
|
176
|
-
logger_1.logger.info(`No staged files
|
|
155
|
+
logger_1.logger.info(`No staged files detected.`);
|
|
177
156
|
}
|
|
178
157
|
// Workflow B: Developer hasn't staged files - check unstaged + untracked files
|
|
179
158
|
// (Untracked files are conceptually "unstaged" - files being worked on but not committed)
|
|
180
|
-
if (
|
|
159
|
+
if (actualUnstagedFiles.length > 0 || untracked.length > 0) {
|
|
181
160
|
// Get unstaged diff if there are unstaged files
|
|
182
|
-
if (
|
|
161
|
+
if (actualUnstagedFiles.length > 0) {
|
|
183
162
|
diff = (0, child_process_1.execSync)('git diff -U200', {
|
|
184
163
|
encoding: 'utf-8',
|
|
185
164
|
cwd: repoRoot
|
|
186
165
|
});
|
|
187
|
-
|
|
188
|
-
encoding: 'utf-8',
|
|
189
|
-
cwd: repoRoot
|
|
190
|
-
}).trim();
|
|
191
|
-
changedFiles = changedFilesOutput ? changedFilesOutput.split('\n') : [];
|
|
166
|
+
changedFiles = actualUnstagedFiles;
|
|
192
167
|
}
|
|
193
168
|
else {
|
|
194
169
|
diff = '';
|
|
@@ -222,6 +197,14 @@ async function getDiff(repoRoot) {
|
|
|
222
197
|
? (diff ? diff + '\n' : '') + untrackedDiffs.join('\n')
|
|
223
198
|
: diff;
|
|
224
199
|
const allChangedFiles = [...changedFiles, ...untrackedFileList];
|
|
200
|
+
// Validate that we actually have changes to review
|
|
201
|
+
// This can happen if:
|
|
202
|
+
// 1. git status showed files but git diff returns empty (files were staged/unstaged between commands)
|
|
203
|
+
// 2. All untracked items are directories (skipped)
|
|
204
|
+
// 3. Parsing incorrectly categorized files
|
|
205
|
+
if (allChangedFiles.length === 0 || !combinedDiff || combinedDiff.trim() === '') {
|
|
206
|
+
throw new Error('No changes detected. Stage files with "git add" or modify files to run threadlines.');
|
|
207
|
+
}
|
|
225
208
|
const unstagedCount = changedFiles.length;
|
|
226
209
|
const untrackedCount = untrackedFileList.length;
|
|
227
210
|
if (unstagedCount > 0 && untrackedCount > 0) {
|
|
@@ -230,7 +213,7 @@ async function getDiff(repoRoot) {
|
|
|
230
213
|
else if (unstagedCount > 0) {
|
|
231
214
|
logger_1.logger.info(`Checking UNSTAGED changes (${unstagedCount} file(s))`);
|
|
232
215
|
}
|
|
233
|
-
else {
|
|
216
|
+
else if (untrackedCount > 0) {
|
|
234
217
|
logger_1.logger.info(`Checking UNTRACKED files (${untrackedCount} file(s))`);
|
|
235
218
|
}
|
|
236
219
|
return {
|