aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-aiassist.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/module-aiassist.js')
-rw-r--r--modules/core/module-aiassist.js21
1 files changed, 15 insertions, 6 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js
index e134d69..85aae46 100644
--- a/modules/core/module-aiassist.js
+++ b/modules/core/module-aiassist.js
@@ -948,8 +948,10 @@ buildSystemPrompt() {
const originalPrint = this.terminal.print.bind(this.terminal);
let output = '';
this.terminal.print = (text, type) => { output += text + '\n'; };
+ // Loop guard: AI-initiated commands must not route back to AI on unknown command
+ this.terminal.security._aiToolDepth++;
try { await this.terminal.security.checkAndRun(cmd); }
- finally { this.terminal.print = originalPrint; }
+ finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; }
return output.trim();
}
async _captureShellCommand(cmd) {
@@ -957,8 +959,10 @@ buildSystemPrompt() {
const originalPrint = this.terminal.print.bind(this.terminal);
let output = '';
this.terminal.print = (text, type) => { output += text + '\n'; };
+ // Loop guard: AI-initiated commands must not route back to AI on unknown command
+ this.terminal.security._aiToolDepth++;
try { await this.terminal.executeCommand(cmd); }
- finally { this.terminal.print = originalPrint; }
+ finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; }
return output.trim();
}
async _captureConsoleErrors(durationMs) {
@@ -2259,10 +2263,15 @@ buildSystemPrompt() {
const originalPrint = this.terminal.print.bind(this.terminal);
let output = '';
this.terminal.print = (text, type) => { output += text + '\n'; };
- // Flag security so unknown commands return an error instead of routing back to AI (loop guard)
- const prevAiFlag = this.terminal.security._aiToolCall;
- this.terminal.security._aiToolCall = true;
- try { await this.terminal.security.checkAndRun(cmd); } finally { this.terminal.security._aiToolCall = prevAiFlag; this.terminal.print = originalPrint; }
+ // Loop guard (depth counter — race-safe under Promise.all tool fan-out):
+ // unknown commands return an error instead of routing back to AI
+ this.terminal.security._aiToolDepth++;
+ try { await this.terminal.security.checkAndRun(cmd); } finally { this.terminal.security._aiToolDepth--; this.terminal.print = originalPrint; }
+ const unknownCmd = this.terminal.security._lastUnknownCmd;
+ if (unknownCmd) {
+ const sug = this.terminal.security.suggest(unknownCmd);
+ return JSON.stringify({ error: `Command not found: ${unknownCmd}`, suggestion: sug ? sug.cmd : null });
+ }
// 📸 Diff and append shadow report
const shadowDiff = this._diffShadowVFS();
if (shadowDiff && shadowDiff.length > 0) {