@hasna/terminal 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/ai.js +21 -2
  2. package/package.json +1 -1
  3. package/src/ai.ts +20 -2
package/dist/ai.js CHANGED
@@ -198,8 +198,27 @@ export async function translateToCommand(nl, perms, sessionEntries, onToken) {
198
198
  }
199
199
  if (text.startsWith("BLOCKED:"))
200
200
  throw new Error(text);
201
- cacheSet(nl, text);
202
- return text;
201
+ // Strip AI reasoning — extract only the shell command
202
+ // AI sometimes prefixes with "Based on..." or wraps in backticks
203
+ let cleaned = text.trim();
204
+ // Remove markdown code blocks
205
+ cleaned = cleaned.replace(/^```(?:bash|sh|shell)?\n?/m, "").replace(/\n?```$/m, "");
206
+ // Remove lines that look like AI reasoning (start with capital letter, contain "I ", "Based on", etc.)
207
+ const lines = cleaned.split("\n");
208
+ const commandLines = lines.filter(l => {
209
+ const t = l.trim();
210
+ if (!t)
211
+ return false;
212
+ // Skip obvious reasoning lines
213
+ if (/^(Based on|I |This |The |Let me|Here|Note:|Since|Looking|To )/.test(t))
214
+ return false;
215
+ if (/^[A-Z][a-z].*\.$/.test(t))
216
+ return false; // English sentence ending with period
217
+ return true;
218
+ });
219
+ cleaned = commandLines.join("\n").trim() || cleaned;
220
+ cacheSet(nl, cleaned);
221
+ return cleaned;
203
222
  }
204
223
  // ── prefetch ──────────────────────────────────────────────────────────────────
205
224
  export function prefetchNext(lastNl, perms, sessionEntries) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Smart terminal wrapper for AI agents and humans — structured output, token compression, MCP server, natural language",
5
5
  "type": "module",
6
6
  "bin": {
package/src/ai.ts CHANGED
@@ -239,8 +239,26 @@ export async function translateToCommand(
239
239
  }
240
240
 
241
241
  if (text.startsWith("BLOCKED:")) throw new Error(text);
242
- cacheSet(nl, text);
243
- return text;
242
+
243
+ // Strip AI reasoning — extract only the shell command
244
+ // AI sometimes prefixes with "Based on..." or wraps in backticks
245
+ let cleaned = text.trim();
246
+ // Remove markdown code blocks
247
+ cleaned = cleaned.replace(/^```(?:bash|sh|shell)?\n?/m, "").replace(/\n?```$/m, "");
248
+ // Remove lines that look like AI reasoning (start with capital letter, contain "I ", "Based on", etc.)
249
+ const lines = cleaned.split("\n");
250
+ const commandLines = lines.filter(l => {
251
+ const t = l.trim();
252
+ if (!t) return false;
253
+ // Skip obvious reasoning lines
254
+ if (/^(Based on|I |This |The |Let me|Here|Note:|Since|Looking|To )/.test(t)) return false;
255
+ if (/^[A-Z][a-z].*\.$/.test(t)) return false; // English sentence ending with period
256
+ return true;
257
+ });
258
+ cleaned = commandLines.join("\n").trim() || cleaned;
259
+
260
+ cacheSet(nl, cleaned);
261
+ return cleaned;
244
262
  }
245
263
 
246
264
  // ── prefetch ──────────────────────────────────────────────────────────────────