fix: preserve changes when diff fails
This commit is contained in:
1 parent
7e024093b1
commit
f9e21195c1
3 files changed
+50
-5
No files matched your search
@@ -98,6 +98,10 @@
|
|||||||
`changes.touched` ACK bridge; full diff/preview data stays Main-only; and
|
`changes.touched` ACK bridge; full diff/preview data stays Main-only; and
|
||||||
untracked reads plus previews are both limited to 8 KiB while size/mtime
|
untracked reads plus previews are both limited to 8 KiB while size/mtime
|
||||||
detect equal-length changes beyond that window.
|
detect equal-length changes beyond that window.
|
||||||
|
- Closed the follow-up review finding by making per-candidate Git diff failure,
|
||||||
|
non-zero exit, or output-limit rejection non-fatal: the Main snapshot keeps
|
||||||
|
the changed relative path and status while omitting only the unavailable
|
||||||
|
diff. The regression uses the same `Git output is too large` failure shape.
|
||||||
- The packaged smoke now has two halves: a staged production-closure Pi
|
- The packaged smoke now has two halves: a staged production-closure Pi
|
||||||
process check and a controlled Electron-Node authenticated bridge check that
|
process check and a controlled Electron-Node authenticated bridge check that
|
||||||
actually executes browser status/screenshot attachment and game asset
|
actually executes browser status/screenshot attachment and game asset
|
||||||
@@ -114,7 +118,7 @@
|
|||||||
`Makelore/index.tsx`; none are in this task's changed scope).
|
`Makelore/index.tsx`; none are in this task's changed scope).
|
||||||
- Final focused PI-090/Pi projection/bridge/game/resource suite: 12 files,
|
- Final focused PI-090/Pi projection/bridge/game/resource suite: 12 files,
|
||||||
71 tests passed. The planner's five minimal failure shapes are also covered
|
71 tests passed. The planner's five minimal failure shapes are also covered
|
||||||
by the 4-file 19-test tracker/bridge/runtime subset.
|
by the final 4-file 20-test tracker/bridge/runtime subset.
|
||||||
- Final serial full suite
|
- Final serial full suite
|
||||||
(`corepack pnpm vitest run --maxWorkers=1 --no-file-parallelism`): 203 files,
|
(`corepack pnpm vitest run --maxWorkers=1 --no-file-parallelism`): 203 files,
|
||||||
2226 tests passed, 2 skipped. Two preceding parallel full-suite runs each
|
2226 tests passed, 2 skipped. Two preceding parallel full-suite runs each
|
||||||
|
|||||||
@@ -325,10 +325,17 @@ export class ConversationChangeTracker {
|
|||||||
diff?: string;
|
diff?: string;
|
||||||
truncated?: boolean;
|
truncated?: boolean;
|
||||||
}> {
|
}> {
|
||||||
const [working, staged] = await Promise.all([
|
let working: GitCommandResult;
|
||||||
this.git.run(projectPath, ['diff', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
let staged: GitCommandResult;
|
||||||
this.git.run(projectPath, ['diff', '--cached', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
try {
|
||||||
]);
|
[working, staged] = await Promise.all([
|
||||||
|
this.git.run(projectPath, ['diff', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||||
|
this.git.run(projectPath, ['diff', '--cached', '--no-ext-diff', '--no-color', '--relative', '--', relativePath]),
|
||||||
|
]);
|
||||||
|
} catch {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (working.code !== 0 || staged.code !== 0) return {};
|
||||||
const bounded = boundedText(`${staged.stdout}${working.stdout}`, MAX_DIFF_BYTES);
|
const bounded = boundedText(`${staged.stdout}${working.stdout}`, MAX_DIFF_BYTES);
|
||||||
return {
|
return {
|
||||||
...(bounded.text ? { diff: bounded.text } : {}),
|
...(bounded.text ? { diff: bounded.text } : {}),
|
||||||
|
|||||||
@@ -143,6 +143,40 @@ describe('PI-090 product tools', () => {
|
|||||||
)).files).toEqual([expect.objectContaining({ path: 'notes.txt', preview: 'local notes\n' })]);
|
)).files).toEqual([expect.objectContaining({ path: 'notes.txt', preview: 'local notes\n' })]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps the changed path when a candidate diff is unavailable or oversized', async () => {
|
||||||
|
const root = await temporaryRoot('makelore-pi-diff-unavailable-');
|
||||||
|
await writeFile(path.join(root, 'tracked.txt'), 'changed\n', 'utf8');
|
||||||
|
let statusReads = 0;
|
||||||
|
const tracker = new ConversationChangeTracker({
|
||||||
|
async run(_projectPath, args) {
|
||||||
|
if (args[0] === 'rev-parse' && args[1] === '--is-inside-work-tree') {
|
||||||
|
return { code: 0, stdout: 'true\n' };
|
||||||
|
}
|
||||||
|
if (args[0] === 'rev-parse') return { code: 0, stdout: `${'a'.repeat(40)}\n` };
|
||||||
|
if (args[0] === 'status') {
|
||||||
|
statusReads += 1;
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
stdout: statusReads === 1
|
||||||
|
? ''
|
||||||
|
: '1 .M N... 100644 100644 100644 abc abc tracked.txt\0',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (args[0] === 'diff') throw new Error('Git output is too large');
|
||||||
|
throw new Error(`Unexpected Git call: ${args.join(' ')}`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await tracker.beginRun({
|
||||||
|
conversationId: 'conversation-a', runId: 'run-a', projectPath: root,
|
||||||
|
});
|
||||||
|
const snapshot = await tracker.recordTouchedPaths(
|
||||||
|
'conversation-a', 'run-a', ['tracked.txt'],
|
||||||
|
);
|
||||||
|
expect(snapshot.files).toEqual([{
|
||||||
|
path: 'tracked.txt', status: 'modified',
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
|
||||||
it('supports no-git projects and rejects paths outside the project', async () => {
|
it('supports no-git projects and rejects paths outside the project', async () => {
|
||||||
const root = await temporaryRoot('makelore-pi-no-git-');
|
const root = await temporaryRoot('makelore-pi-no-git-');
|
||||||
await writeFile(path.join(root, 'notes.txt'), 'local notes\n', 'utf8');
|
await writeFile(path.join(root, 'notes.txt'), 'local notes\n', 'utf8');
|
||||||
|
|||||||
Reference in new issue
Block a user