@hasna/terminal 0.6.2 → 0.7.0
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.
- package/dist/cli.js +58 -0
- package/dist/command-rewriter.js +2 -2
- package/package.json +1 -1
- package/src/cli.tsx +61 -0
- package/src/command-rewriter.ts +2 -2
package/dist/cli.js
CHANGED
|
@@ -51,6 +51,64 @@ if (args[0] === "--version" || args[0] === "-v") {
|
|
|
51
51
|
console.log("0.6.1");
|
|
52
52
|
process.exit(0);
|
|
53
53
|
}
|
|
54
|
+
// ── Exec command — smart execution for agents ────────────────────────────────
|
|
55
|
+
if (args[0] === "exec") {
|
|
56
|
+
const command = args.slice(1).join(" ");
|
|
57
|
+
if (!command) {
|
|
58
|
+
console.error("Usage: terminal exec <command>");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const { execSync } = await import("child_process");
|
|
62
|
+
const { stripAnsi } = await import("./compression.js");
|
|
63
|
+
const { stripNoise } = await import("./noise-filter.js");
|
|
64
|
+
const { processOutput, shouldProcess } = await import("./output-processor.js");
|
|
65
|
+
const { rewriteCommand } = await import("./command-rewriter.js");
|
|
66
|
+
const { shouldBeLazy, toLazy } = await import("./lazy-executor.js");
|
|
67
|
+
const { estimateTokens } = await import("./parsers/index.js");
|
|
68
|
+
// Rewrite command if possible
|
|
69
|
+
const rw = rewriteCommand(command);
|
|
70
|
+
const actualCmd = rw.changed ? rw.rewritten : command;
|
|
71
|
+
if (rw.changed)
|
|
72
|
+
console.error(`[open-terminal] rewritten: ${actualCmd} (${rw.reason})`);
|
|
73
|
+
try {
|
|
74
|
+
const start = Date.now();
|
|
75
|
+
const raw = execSync(actualCmd, { encoding: "utf8", maxBuffer: 10 * 1024 * 1024, cwd: process.cwd() });
|
|
76
|
+
const duration = Date.now() - start;
|
|
77
|
+
const clean = stripNoise(stripAnsi(raw)).cleaned;
|
|
78
|
+
const rawTokens = estimateTokens(raw);
|
|
79
|
+
// Lazy mode for huge output
|
|
80
|
+
if (shouldBeLazy(clean)) {
|
|
81
|
+
const lazy = toLazy(clean, actualCmd);
|
|
82
|
+
const savedTokens = rawTokens - estimateTokens(JSON.stringify(lazy));
|
|
83
|
+
console.log(JSON.stringify({ ...lazy, duration, tokensSaved: savedTokens }));
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
// AI summary for medium-large output
|
|
87
|
+
if (shouldProcess(clean)) {
|
|
88
|
+
const processed = await processOutput(actualCmd, clean);
|
|
89
|
+
if (processed.aiProcessed && processed.tokensSaved > 30) {
|
|
90
|
+
console.log(processed.summary);
|
|
91
|
+
const savedTokens = rawTokens - estimateTokens(processed.summary);
|
|
92
|
+
console.error(`[open-terminal] ${rawTokens} → ${rawTokens - savedTokens} tokens (saved ${savedTokens}, ${Math.round(savedTokens / rawTokens * 100)}%)`);
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Small/medium output — just noise-strip and return
|
|
97
|
+
console.log(clean);
|
|
98
|
+
const savedTokens = rawTokens - estimateTokens(clean);
|
|
99
|
+
if (savedTokens > 10) {
|
|
100
|
+
console.error(`[open-terminal] saved ${savedTokens} tokens (noise filter)`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
// Command failed — show error output
|
|
105
|
+
const stderr = e.stderr?.toString() ?? "";
|
|
106
|
+
const stdout = e.stdout?.toString() ?? "";
|
|
107
|
+
console.log(stripNoise(stripAnsi(stdout + stderr)).cleaned);
|
|
108
|
+
process.exit(e.status ?? 1);
|
|
109
|
+
}
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
54
112
|
// ── MCP commands ─────────────────────────────────────────────────────────────
|
|
55
113
|
if (args[0] === "mcp") {
|
|
56
114
|
if (args[1] === "serve" || args.length === 1) {
|
package/dist/command-rewriter.js
CHANGED
|
@@ -41,10 +41,10 @@ const rules = [
|
|
|
41
41
|
rewrite: () => "npm ls --depth=0",
|
|
42
42
|
reason: "full tree is massive, top-level usually enough",
|
|
43
43
|
},
|
|
44
|
-
// ps aux without filter →
|
|
44
|
+
// ps aux without filter → sort by memory and head (macOS compatible)
|
|
45
45
|
{
|
|
46
46
|
pattern: /^ps\s+aux\s*$/,
|
|
47
|
-
rewrite: () => "ps aux
|
|
47
|
+
rewrite: () => "ps aux | sort -k4 -rn | head -20",
|
|
48
48
|
reason: "full process list is noise, show top consumers",
|
|
49
49
|
},
|
|
50
50
|
];
|
package/package.json
CHANGED
package/src/cli.tsx
CHANGED
|
@@ -56,6 +56,67 @@ if (args[0] === "--version" || args[0] === "-v") {
|
|
|
56
56
|
process.exit(0);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// ── Exec command — smart execution for agents ────────────────────────────────
|
|
60
|
+
|
|
61
|
+
if (args[0] === "exec") {
|
|
62
|
+
const command = args.slice(1).join(" ");
|
|
63
|
+
if (!command) { console.error("Usage: terminal exec <command>"); process.exit(1); }
|
|
64
|
+
|
|
65
|
+
const { execSync } = await import("child_process");
|
|
66
|
+
const { stripAnsi } = await import("./compression.js");
|
|
67
|
+
const { stripNoise } = await import("./noise-filter.js");
|
|
68
|
+
const { processOutput, shouldProcess } = await import("./output-processor.js");
|
|
69
|
+
const { rewriteCommand } = await import("./command-rewriter.js");
|
|
70
|
+
const { shouldBeLazy, toLazy } = await import("./lazy-executor.js");
|
|
71
|
+
const { estimateTokens } = await import("./parsers/index.js");
|
|
72
|
+
|
|
73
|
+
// Rewrite command if possible
|
|
74
|
+
const rw = rewriteCommand(command);
|
|
75
|
+
const actualCmd = rw.changed ? rw.rewritten : command;
|
|
76
|
+
if (rw.changed) console.error(`[open-terminal] rewritten: ${actualCmd} (${rw.reason})`);
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const start = Date.now();
|
|
80
|
+
const raw = execSync(actualCmd, { encoding: "utf8", maxBuffer: 10 * 1024 * 1024, cwd: process.cwd() });
|
|
81
|
+
const duration = Date.now() - start;
|
|
82
|
+
const clean = stripNoise(stripAnsi(raw)).cleaned;
|
|
83
|
+
const rawTokens = estimateTokens(raw);
|
|
84
|
+
|
|
85
|
+
// Lazy mode for huge output
|
|
86
|
+
if (shouldBeLazy(clean)) {
|
|
87
|
+
const lazy = toLazy(clean, actualCmd);
|
|
88
|
+
const savedTokens = rawTokens - estimateTokens(JSON.stringify(lazy));
|
|
89
|
+
console.log(JSON.stringify({ ...lazy, duration, tokensSaved: savedTokens }));
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// AI summary for medium-large output
|
|
94
|
+
if (shouldProcess(clean)) {
|
|
95
|
+
const processed = await processOutput(actualCmd, clean);
|
|
96
|
+
if (processed.aiProcessed && processed.tokensSaved > 30) {
|
|
97
|
+
console.log(processed.summary);
|
|
98
|
+
const savedTokens = rawTokens - estimateTokens(processed.summary);
|
|
99
|
+
console.error(`[open-terminal] ${rawTokens} → ${rawTokens - savedTokens} tokens (saved ${savedTokens}, ${Math.round(savedTokens/rawTokens*100)}%)`);
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Small/medium output — just noise-strip and return
|
|
105
|
+
console.log(clean);
|
|
106
|
+
const savedTokens = rawTokens - estimateTokens(clean);
|
|
107
|
+
if (savedTokens > 10) {
|
|
108
|
+
console.error(`[open-terminal] saved ${savedTokens} tokens (noise filter)`);
|
|
109
|
+
}
|
|
110
|
+
} catch (e: any) {
|
|
111
|
+
// Command failed — show error output
|
|
112
|
+
const stderr = e.stderr?.toString() ?? "";
|
|
113
|
+
const stdout = e.stdout?.toString() ?? "";
|
|
114
|
+
console.log(stripNoise(stripAnsi(stdout + stderr)).cleaned);
|
|
115
|
+
process.exit(e.status ?? 1);
|
|
116
|
+
}
|
|
117
|
+
process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
|
|
59
120
|
// ── MCP commands ─────────────────────────────────────────────────────────────
|
|
60
121
|
|
|
61
122
|
if (args[0] === "mcp") {
|
package/src/command-rewriter.ts
CHANGED
|
@@ -47,10 +47,10 @@ const rules: RewriteRule[] = [
|
|
|
47
47
|
rewrite: () => "npm ls --depth=0",
|
|
48
48
|
reason: "full tree is massive, top-level usually enough",
|
|
49
49
|
},
|
|
50
|
-
// ps aux without filter →
|
|
50
|
+
// ps aux without filter → sort by memory and head (macOS compatible)
|
|
51
51
|
{
|
|
52
52
|
pattern: /^ps\s+aux\s*$/,
|
|
53
|
-
rewrite: () => "ps aux
|
|
53
|
+
rewrite: () => "ps aux | sort -k4 -rn | head -20",
|
|
54
54
|
reason: "full process list is noise, show top consumers",
|
|
55
55
|
},
|
|
56
56
|
];
|