@hasna/terminal 3.3.6 → 3.3.8

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.
@@ -64,6 +64,12 @@ function smartTruncate(text, maxTokens) {
64
64
  export function compress(command, output, options = {}) {
65
65
  const { maxTokens, stripAnsi: doStrip = true } = options;
66
66
  const originalTokens = estimateTokens(output);
67
+ // Short output — no-op, skip all processing
68
+ if (output.split("\n").length <= 20 && !maxTokens) {
69
+ const clean = doStrip ? stripAnsi(output) : output;
70
+ const cleanTokens = estimateTokens(clean);
71
+ return { content: clean, originalTokens, compressedTokens: cleanTokens, tokensSaved: Math.max(0, originalTokens - cleanTokens), savingsPercent: 0 };
72
+ }
67
73
  // Step 1: Strip ANSI codes
68
74
  let text = doStrip ? stripAnsi(output) : output;
69
75
  // Step 2: Deduplicate similar lines
@@ -54,9 +54,11 @@ export async function searchContent(pattern, cwd, options = {}) {
54
54
  const totalMatches = [...fileMap.values()].reduce((sum, m) => sum + m.length, 0);
55
55
  const filtered = filteredCount > 0 ? [{ count: filteredCount, reason: "excluded directories" }] : [];
56
56
  const rawTokens = Math.ceil(raw.length / 4);
57
+ const truncated = totalMatches > files.reduce((s, f) => s + f.matches.length, 0);
57
58
  const result = { query: pattern, totalMatches, files, filtered };
58
59
  const resultTokens = Math.ceil(JSON.stringify(result).length / 4);
59
60
  result.tokensSaved = Math.max(0, rawTokens - resultTokens);
61
+ result.truncated = truncated;
60
62
  // Overflow guard — warn when results are truncated
61
63
  if (totalMatches > maxResults * 3) {
62
64
  result.overflow = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "3.3.6",
3
+ "version": "3.3.8",
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
  "files": [
@@ -89,6 +89,13 @@ export function compress(command: string, output: string, options: CompressOptio
89
89
  const { maxTokens, stripAnsi: doStrip = true } = options;
90
90
  const originalTokens = estimateTokens(output);
91
91
 
92
+ // Short output — no-op, skip all processing
93
+ if (output.split("\n").length <= 20 && !maxTokens) {
94
+ const clean = doStrip ? stripAnsi(output) : output;
95
+ const cleanTokens = estimateTokens(clean);
96
+ return { content: clean, originalTokens, compressedTokens: cleanTokens, tokensSaved: Math.max(0, originalTokens - cleanTokens), savingsPercent: 0 };
97
+ }
98
+
92
99
  // Step 1: Strip ANSI codes
93
100
  let text = doStrip ? stripAnsi(output) : output;
94
101
 
@@ -89,9 +89,11 @@ export async function searchContent(
89
89
  const filtered = filteredCount > 0 ? [{ count: filteredCount, reason: "excluded directories" }] : [];
90
90
 
91
91
  const rawTokens = Math.ceil(raw.length / 4);
92
+ const truncated = totalMatches > files.reduce((s, f) => s + f.matches.length, 0);
92
93
  const result: ContentSearchResult = { query: pattern, totalMatches, files, filtered };
93
94
  const resultTokens = Math.ceil(JSON.stringify(result).length / 4);
94
95
  result.tokensSaved = Math.max(0, rawTokens - resultTokens);
96
+ (result as any).truncated = truncated;
95
97
 
96
98
  // Overflow guard — warn when results are truncated
97
99
  if (totalMatches > maxResults * 3) {