fix: restore current in-place project files

This commit is contained in:
muena
2026-10-06 13:17:18 +02:00
parent 43fbf46014
commit 0ec5b0745e
3 changed files with 28 additions and 3 deletions

View File

@@ -318,8 +318,10 @@ export function runCopiesPath(run: ProjectRun, directory: string): string {
export async function scanRestorableCopyFiles(run: ProjectRun, directory: string, current = true): Promise<{
root: string; files: ProjectFile[]; skipped: number;
}> {
let root = current ? runCopiesPath(run, directory) : join(directory, "files");
if (current && run.copyPath) {
const inPlace = Boolean(run.inPlace || run.sourceInPlace);
let root = current && inPlace ? canonicalProjectPath(run.projectPath)
: current ? runCopiesPath(run, directory) : join(directory, "files");
if (current && !inPlace && run.copyPath) {
try {
if (!(await fs.lstat(root)).isDirectory()) throw new Error("Kopienpfad ist kein regulärer Ordner.");
} catch (error) {

View File

@@ -206,6 +206,8 @@ function FilePicker(props: { run: ProjectRun; directory: string; historical?: bo
}
const textFiles = files.filter((file) => file.kind === "text");
const complexFiles = files.filter((file) => file.kind === "document");
const sourceLabel = props.historical ? "Gespeicherter Projektstand"
: props.run.inPlace || props.run.sourceInPlace ? "Aktueller Projektordner" : "Pseudonymisierte Kopien";
const renderFile = (file: ProjectFile) => <List.Item key={file.relPath}
icon={selected.has(file.relPath) ? Icon.CheckCircle : Icon.Circle}
title={restorePath(file.relPath, props.run.mapping, props.run.matchModes)} subtitle={file.relPath}
@@ -224,7 +226,7 @@ function FilePicker(props: { run: ProjectRun; directory: string; historical?: bo
subtitle="Klartext-Kopien in Downloads/Velum erstellen · Office-Dateien nur nach Auswahl"
actions={<ActionPanel><Action title="Auswahl nach Downloads wiederherstellen"
icon={Icon.Download} onAction={exportFiles} /></ActionPanel>} />
<List.Item key="source" icon={Icon.Folder} title="Quelle für die Wiederherstellung" subtitle={sourceRoot}
<List.Item key="source" icon={Icon.Folder} title={sourceLabel} subtitle={sourceRoot}
actions={<ActionPanel><Action title="Quellordner im Finder anzeigen" onAction={() => showInFinder(sourceRoot)} /></ActionPanel>} />
</List.Section>
<List.Section title={`Textdateien · ${textFiles.length} · standardmäßig ausgewählt`}>

View File

@@ -99,6 +99,27 @@ describe("Velum-Projektstände", () => {
expect(await project.loadProjectEntityTypes(other, support)).toBeNull();
});
it("stellt aktuelle In-Place-Dateien aus dem Projektordner und frühere Stände aus dem Snapshot bereit", async () => {
const root = await fs.mkdtemp(join(tmpdir(), "velum-current-source-test-"));
roots.push(root);
const source = join(root, "Projekt");
const support = join(root, "Raycast");
await fs.mkdir(source);
const created = await project.createRun(source, support);
created.run.inPlace = true;
created.run.files = [{ source: "Notiz.txt", output: "Notiz.txt", kind: "text" }];
await fs.writeFile(join(created.directory, "files", "Notiz.txt"), "PERSON_01");
await fs.writeFile(join(source, "Notiz.txt"), "PERSON_01");
await fs.writeFile(join(source, "Antwort.txt"), "PERSON_01 antwortet");
const current = await project.scanRestorableCopyFiles(created.run, created.directory);
expect(current.root).toBe(source);
expect(current.files.map((file) => file.relPath)).toEqual(["Antwort.txt", "Notiz.txt"]);
const historical = await project.scanRestorableCopyFiles(created.run, created.directory, false);
expect(historical.root).toBe(join(created.directory, "files"));
expect(historical.files.map((file) => file.relPath)).toEqual(["Notiz.txt"]);
});
it("ersetzt nur bestätigte Vorkommen und stellt Dateinamen wieder her", () => {
const hits = [
{ id: "a", start: 0, end: 3, placeholder: "PERSON_01" },