Smart Context: deep (#1527)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Introduce a new "deep" Smart Context mode that supplies versioned files (by commit) to the engine, adds code search rendering, stores source commit hashes, improves search-replace recovery, and updates UI/tests. > > - **Smart Context (deep)**: > - Replace `conservative` with `deep`; limit context to ~200 turns; send `sourceCommitHash` per message. > - Build and pass `versioned_files` (hash-id map + per-message file refs) and `app_id` to engine. > - **DB**: > - Add `messages.source_commit_hash` (+ migration/snapshot). > - **Engine/Processing**: > - Retry Turbo Edits v2: first re-read then fallback to `dyad-write` if search-replace fails. > - Include provider options and versioned files in requests; add `getCurrentCommitHash`/`getFileAtCommit`. > - **UI**: > - Pro mode selector: new `deep` option; tooltips polish. > - Add `DyadCodeSearch` and `DyadCodeSearchResult` components; parser supports new tags. > - **Tests/E2E**: > - New `smart_context_deep` e2e; update snapshots to include `app_id` and deep mode; adjust Playwright timeout. > - Unit tests for versioned codebase context. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e3d3bffabb2bc6caf52103461f9d6f2d5ad39df8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This commit is contained in:
@@ -6,7 +6,8 @@ import pathModule from "node:path";
|
||||
import { exec } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { readSettings } from "../../main/settings";
|
||||
|
||||
import log from "electron-log";
|
||||
const logger = log.scope("git_utils");
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
async function verboseExecAsync(
|
||||
@@ -26,6 +27,18 @@ async function verboseExecAsync(
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCurrentCommitHash({
|
||||
path,
|
||||
}: {
|
||||
path: string;
|
||||
}): Promise<string> {
|
||||
return await git.resolveRef({
|
||||
fs,
|
||||
dir: path,
|
||||
ref: "HEAD",
|
||||
});
|
||||
}
|
||||
|
||||
export async function gitCommit({
|
||||
path,
|
||||
message,
|
||||
@@ -166,3 +179,45 @@ export async function gitAddAll({ path }: { path: string }): Promise<void> {
|
||||
return git.add({ fs, dir: path, filepath: "." });
|
||||
}
|
||||
}
|
||||
|
||||
export async function getFileAtCommit({
|
||||
path,
|
||||
filePath,
|
||||
commitHash,
|
||||
}: {
|
||||
path: string;
|
||||
filePath: string;
|
||||
commitHash: string;
|
||||
}): Promise<string | null> {
|
||||
const settings = readSettings();
|
||||
if (settings.enableNativeGit) {
|
||||
try {
|
||||
const { stdout } = await execAsync(
|
||||
`git -C "${path}" show "${commitHash}:${filePath}"`,
|
||||
);
|
||||
return stdout;
|
||||
} catch (error: any) {
|
||||
logger.error(
|
||||
`Error getting file at commit ${commitHash}: ${error.message}`,
|
||||
);
|
||||
// File doesn't exist at this commit
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const { blob } = await git.readBlob({
|
||||
fs,
|
||||
dir: path,
|
||||
oid: commitHash,
|
||||
filepath: filePath,
|
||||
});
|
||||
return Buffer.from(blob).toString("utf-8");
|
||||
} catch (error: any) {
|
||||
logger.error(
|
||||
`Error getting file at commit ${commitHash}: ${error.message}`,
|
||||
);
|
||||
// File doesn't exist at this commit
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user