aboutsummaryrefslogtreecommitdiff
path: root/modules/core
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-09-29 13:49:18 +0200
committerAgando <roduccomm@gmail.com>2026-09-29 13:49:18 +0200
commit014573d72dee7088408475fedb3ffc9381e719e0 (patch)
tree1f6702afa57cecfd92d6799b81b02f811059155c /modules/core
parentdd50ae715f3a648aeb42fb524fe1b106a0c084c7 (diff)
fix: parse per-call captured output for unknown-cmd error (race-free under Promise.all)
Diffstat (limited to 'modules/core')
-rw-r--r--modules/core/core-bundle.js11
-rw-r--r--modules/core/module-aiassist.js8
-rw-r--r--modules/core/terminal.js3
3 files changed, 8 insertions, 14 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js
index 942f836..8db04d4 100644
--- a/modules/core/core-bundle.js
+++ b/modules/core/core-bundle.js
@@ -2443,7 +2443,6 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
this.whitelist = new Set(this._baseWhitelist);
// AI loop-guard: depth counter (reentrant, race-safe vs parallel tool calls)
this._aiToolDepth = 0;
- this._lastUnknownCmd = null;
// Load persisted user deltas (add/remove) so hardcoded defaults can be demoted.
this._loadSecurityDeltas();
this._registerBuiltIn();
@@ -2597,7 +2596,6 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
return { cmd, args, known, destructive, system, unknown, hasSuspicious };
}
async checkAndRun(rawInput) {
- this._lastUnknownCmd = null;
const { cmd, args, known, destructive, system, unknown, hasSuspicious } = this._classify(rawInput);
// Level 3 Audit: just log and allow
if (this.level === 3) {
@@ -2628,7 +2626,6 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm
}
// AI-invoked commands must not route back to AI (infinite loop) — return structured error
if (this._aiToolDepth > 0) {
- this._lastUnknownCmd = cmd;
this.terminal.print(`Command not found: ${cmd}${sug ? `. Did you mean: ${sug.cmd}?` : ''}`, 'error');
return;
}
@@ -10262,10 +10259,10 @@ buildSystemPrompt() {
// 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 });
+ // Parse per-call captured output (race-free) — not shared security state
+ const nfMatch = output.match(/Command not found: (\S+?)(?:\. Did you mean: (\S+)\?)?/);
+ if (nfMatch) {
+ return JSON.stringify({ error: `Command not found: ${nfMatch[1]}`, suggestion: nfMatch[2] || null });
}
// 📸 Diff and append shadow report
const shadowDiff = this._diffShadowVFS();
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js
index 85aae46..145e248 100644
--- a/modules/core/module-aiassist.js
+++ b/modules/core/module-aiassist.js
@@ -2267,10 +2267,10 @@ buildSystemPrompt() {
// 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 });
+ // Parse per-call captured output (race-free) — not shared security state
+ const nfMatch = output.match(/Command not found: (\S+?)(?:\. Did you mean: (\S+)\?)?/);
+ if (nfMatch) {
+ return JSON.stringify({ error: `Command not found: ${nfMatch[1]}`, suggestion: nfMatch[2] || null });
}
// 📸 Diff and append shadow report
const shadowDiff = this._diffShadowVFS();
diff --git a/modules/core/terminal.js b/modules/core/terminal.js
index 5c7a8fb..3b28b52 100644
--- a/modules/core/terminal.js
+++ b/modules/core/terminal.js
@@ -17,7 +17,6 @@
this.whitelist = new Set(this._baseWhitelist);
// AI loop-guard: depth counter (reentrant, race-safe vs parallel tool calls)
this._aiToolDepth = 0;
- this._lastUnknownCmd = null;
// Load persisted user deltas (add/remove) so hardcoded defaults can be demoted.
this._loadSecurityDeltas();
this._registerBuiltIn();
@@ -171,7 +170,6 @@
return { cmd, args, known, destructive, system, unknown, hasSuspicious };
}
async checkAndRun(rawInput) {
- this._lastUnknownCmd = null;
const { cmd, args, known, destructive, system, unknown, hasSuspicious } = this._classify(rawInput);
// Level 3 Audit: just log and allow
if (this.level === 3) {
@@ -202,7 +200,6 @@
}
// AI-invoked commands must not route back to AI (infinite loop) — return structured error
if (this._aiToolDepth > 0) {
- this._lastUnknownCmd = cmd;
this.terminal.print(`Command not found: ${cmd}${sug ? `. Did you mean: ${sug.cmd}?` : ''}`, 'error');
return;
}