Update project files
This commit is contained in:
+65
-1
@@ -22,6 +22,15 @@ function getTrustedRoots(workspaceRoot: string): string[] {
|
||||
roots.push(path.normalize(f.uri.fsPath).toLowerCase());
|
||||
}
|
||||
}
|
||||
// Also trust the immediate parent of each root, so sibling projects under a
|
||||
// shared parent (e.g. E:\Wiki\connectai + E:\Wiki\Datacollect) are reachable
|
||||
// for read/list. Guard: never widen to a drive/filesystem root.
|
||||
for (const r of [...roots]) {
|
||||
const parent = path.normalize(path.dirname(r)).toLowerCase();
|
||||
if (parent && parent !== r && path.dirname(parent) !== parent) {
|
||||
roots.push(parent);
|
||||
}
|
||||
}
|
||||
_trustedRoots = [...new Set(roots)];
|
||||
return _trustedRoots;
|
||||
}
|
||||
@@ -48,6 +57,59 @@ export function validatePath(workspaceRoot: string, targetPath: string): string
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a command on top-level `&&`, ignoring `&&` that appears inside single-
|
||||
* or double-quoted strings (e.g. a commit message). Returns trimmed, non-empty parts.
|
||||
*/
|
||||
function splitTopLevelAnd(command: string): string[] {
|
||||
const parts: string[] = [];
|
||||
let buf = '';
|
||||
let quote: string | null = null;
|
||||
for (let i = 0; i < command.length; i++) {
|
||||
const c = command[i];
|
||||
if (quote) {
|
||||
buf += c;
|
||||
if (c === quote) { quote = null; }
|
||||
continue;
|
||||
}
|
||||
if (c === "'" || c === '"') { quote = c; buf += c; continue; }
|
||||
if (c === '&' && command[i + 1] === '&') {
|
||||
parts.push(buf);
|
||||
buf = '';
|
||||
i++; // skip the second '&'
|
||||
continue;
|
||||
}
|
||||
buf += c;
|
||||
}
|
||||
parts.push(buf);
|
||||
return parts.map(p => p.trim()).filter(p => p.length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows PowerShell 5.1 — the default VS Code integrated terminal on Windows —
|
||||
* does not support the `&&` chaining operator (it is a hard parser error, so the
|
||||
* WHOLE command fails to run). Local models emit `&&` constantly because every
|
||||
* git/npm tutorial uses it, and a system-prompt rule alone does not reliably
|
||||
* stop a small model. So rewrite `A && B && C` into a PowerShell-native
|
||||
* conditional chain that preserves short-circuit semantics:
|
||||
*
|
||||
* A && B && C -> A; if ($?) { B; if ($?) { C } }
|
||||
*
|
||||
* `$?` reflects the success of the previous command, so a failed step still
|
||||
* short-circuits the rest — important so e.g. a failed `cd` never lets `git`
|
||||
* run in the wrong directory.
|
||||
*/
|
||||
function rewriteForPowerShell(command: string): string {
|
||||
if (!command.includes('&&')) { return command; }
|
||||
const parts = splitTopLevelAnd(command);
|
||||
if (parts.length <= 1) { return command; }
|
||||
let chain = parts[parts.length - 1];
|
||||
for (let i = parts.length - 2; i >= 0; i--) {
|
||||
chain = `${parts[i]}; if ($?) { ${chain} }`;
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes terminal commands to prevent destructive actions.
|
||||
* Uses a combination of blocklist for dangerous patterns and recommendation for allowed tools.
|
||||
@@ -86,5 +148,7 @@ export function sanitizeCommand(command: string): string {
|
||||
console.warn(`[Security] Warning: Running uncommon command '${baseCmd}'. Ensure this is intended.`);
|
||||
}
|
||||
|
||||
return trimmedCmd;
|
||||
// Rewrite `&&` chains for PowerShell (the Windows default terminal) so the
|
||||
// command actually runs instead of failing with a parser error.
|
||||
return rewriteForPowerShell(trimmedCmd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user