fix: workaround accesso agy a file esterni al workspace

Quando un file da analizzare è FUORI dalla cartella di lavoro corrente, agy può
fallire a leggerlo per mancanza di competenze/permessi sul workspace. Workaround:
- stageExternalFiles(): copia automaticamente i file esterni in ~/.agy-scratch/
  e riscrive i riferimenti del prompt con il nuovo percorso accessibile.
- executeAgy: applica lo staging prima di costruire gli argomenti, aggiunge
  ~/.agy-scratch via --add-dir.
- I file già sotto la cwd non vengono toccati (nessun overhead).
- Testato: immagine in /tmp copiata in scratch e analizzata correttamente da agy.
This commit is contained in:
2026-08-11 00:54:14 +02:00
parent 2137150da3
commit 7fa1f028d9
+43 -2
View File
@@ -26,6 +26,8 @@ const execFileAsync = promisify(execFile);
const AGY_CHAT_DIR = path.join(os.homedir(), ".agy-chat");
const STATE_FILE = path.join(AGY_CHAT_DIR, "conversation_id");
const CONV_DIR = path.join(os.homedir(), ".gemini", "antigravity-cli", "conversations");
// Cartella scratch per i file esterni da analizzare (workaround accesso agy)
const AGY_SCRATCH = path.join(os.homedir(), ".agy-scratch");
const DEFAULT_TIMEOUT_MS = 180_000; // 3 min
const IMAGE_TIMEOUT_MS = 300_000; // 5 min
@@ -678,14 +680,53 @@ ${body}
${blocks.join("\n\n")}`;
}
// Workaround: se un file da analizzare è FUORI dalla cartella di lavoro corrente,
// lo copia in una cartella scratch accessibile e riscrive i riferimenti nel prompt.
// Previene errori di accesso/competenza quando agy legge file esterni al workspace.
function stageExternalFiles(
prompt: string,
filePaths: string[],
): { prompt: string; filePaths: string[]; dirs: string[] } {
const cwdBase = path.resolve(process.cwd()) + path.sep;
const dirs = new Set<string>();
const stagedPaths: string[] = [];
let newPrompt = prompt;
for (const f of filePaths) {
if (!f) continue;
const abs = path.resolve(f);
// già sotto la cartella di lavoro corrente → nessuna copia necessaria
if (abs.startsWith(cwdBase)) {
stagedPaths.push(f);
continue;
}
try {
fs.mkdirSync(AGY_SCRATCH, { recursive: true });
const dest = path.join(AGY_SCRATCH, path.basename(abs));
fs.copyFileSync(abs, dest);
// riscrivi i riferimenti nel prompt (path originale e assoluto)
newPrompt = newPrompt.split(f).join(dest).split(abs).join(dest);
stagedPaths.push(dest);
dirs.add(AGY_SCRATCH);
} catch {
// se la copia fallisce, lascia il path originale (potrebbe comunque funzionare)
stagedPaths.push(f);
}
}
return { prompt: newPrompt, filePaths: stagedPaths, dirs: [...dirs] };
}
async function executeAgy(opts: AgyExecOptions) {
const finalPrompt = opts.contextBlock ? `${opts.contextBlock}\n\n${opts.prompt}` : opts.prompt;
// Staging dei file esterni (workaround accesso agy a file fuori dal workspace)
const staged = stageExternalFiles(opts.prompt, opts.filePaths ?? []);
const finalPrompt = opts.contextBlock ? `${opts.contextBlock}\n\n${staged.prompt}` : staged.prompt;
const args: string[] = ["-p", finalPrompt];
// add-dir per i file
const dirs = new Set<string>();
for (const d of opts.addDirs ?? []) if (d) dirs.add(d);
for (const f of opts.filePaths ?? []) if (f) dirs.add(path.dirname(f));
for (const f of staged.filePaths) if (f) dirs.add(path.dirname(f));
for (const d of staged.dirs) dirs.add(d);
for (const d of dirs) args.push("--add-dir", d);
// conversazione