@hasna/terminal 3.3.0 → 3.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.
@@ -24,15 +24,15 @@ function installClaude(bin) {
24
24
  return false;
25
25
  }
26
26
  try {
27
- execSync(`claude mcp add --transport stdio --scope user open-terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
27
+ execSync(`claude mcp add --transport stdio --scope user terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
28
28
  log("✓", "Claude Code");
29
29
  return true;
30
30
  }
31
31
  catch {
32
32
  // May already exist
33
33
  try {
34
- execSync(`claude mcp remove open-terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
35
- execSync(`claude mcp add --transport stdio --scope user open-terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
34
+ execSync(`claude mcp remove terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
35
+ execSync(`claude mcp add --transport stdio --scope user terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
36
36
  log("✓", "Claude Code (updated)");
37
37
  return true;
38
38
  }
@@ -55,8 +55,8 @@ function installCodex(bin) {
55
55
  mkdirSync(dir, { recursive: true });
56
56
  let content = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
57
57
  // Remove old entry if exists
58
- content = content.replace(/\n?\[mcp_servers\.open-terminal\][^\[]*/g, "");
59
- content += `\n[mcp_servers.open-terminal]\ncommand = "${bin}"\nargs = ["mcp", "serve"]\n`;
58
+ content = content.replace(/\n?\[mcp_servers\.terminal\][^\[]*/g, "");
59
+ content += `\n[mcp_servers.terminal]\ncommand = "${bin}"\nargs = ["mcp", "serve"]\n`;
60
60
  writeFileSync(configPath, content);
61
61
  log("✓", "Codex");
62
62
  return true;
@@ -86,7 +86,7 @@ function installGemini(bin) {
86
86
  }
87
87
  if (!config.mcpServers)
88
88
  config.mcpServers = {};
89
- config.mcpServers["open-terminal"] = { command: bin, args: ["mcp", "serve"] };
89
+ config.mcpServers["terminal"] = { command: bin, args: ["mcp", "serve"] };
90
90
  writeFileSync(configPath, JSON.stringify(config, null, 2));
91
91
  log("✓", "Gemini CLI");
92
92
  return true;
@@ -101,7 +101,7 @@ function uninstallClaude() {
101
101
  if (!hasClaude())
102
102
  return false;
103
103
  try {
104
- execSync(`claude mcp remove open-terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
104
+ execSync(`claude mcp remove terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
105
105
  log("✓", "Removed from Claude Code");
106
106
  return true;
107
107
  }
@@ -115,9 +115,9 @@ function uninstallCodex() {
115
115
  return false;
116
116
  try {
117
117
  let content = readFileSync(configPath, "utf8");
118
- if (!content.includes("open-terminal"))
118
+ if (!content.includes("terminal"))
119
119
  return false;
120
- content = content.replace(/\n?\[mcp_servers\.open-terminal\][^\[]*/g, "");
120
+ content = content.replace(/\n?\[mcp_servers\.terminal\][^\[]*/g, "");
121
121
  writeFileSync(configPath, content);
122
122
  log("✓", "Removed from Codex");
123
123
  return true;
@@ -132,9 +132,9 @@ function uninstallGemini() {
132
132
  return false;
133
133
  try {
134
134
  const config = JSON.parse(readFileSync(configPath, "utf8"));
135
- if (!config.mcpServers?.["open-terminal"])
135
+ if (!config.mcpServers?.["terminal"])
136
136
  return false;
137
- delete config.mcpServers["open-terminal"];
137
+ delete config.mcpServers["terminal"];
138
138
  writeFileSync(configPath, JSON.stringify(config, null, 2));
139
139
  log("✓", "Removed from Gemini CLI");
140
140
  return true;
@@ -148,7 +148,7 @@ export function handleInstall(args) {
148
148
  const flags = new Set(args);
149
149
  // Uninstall
150
150
  if (flags.has("uninstall") || flags.has("--uninstall")) {
151
- console.log("\n Removing open-terminal MCP server...\n");
151
+ console.log("\n Removing terminal MCP server...\n");
152
152
  uninstallClaude();
153
153
  uninstallCodex();
154
154
  uninstallGemini();
@@ -170,14 +170,7 @@ export function handleInstall(args) {
170
170
  }
171
171
  // ── Default: install everything ─────────────────────────────────────────
172
172
  const bin = which("terminal") ?? which("t") ?? "npx @hasna/terminal";
173
- console.log(`
174
- ┌─────────────────────────────────────┐
175
- │ open-terminal │
176
- │ Smart terminal for AI agents │
177
- └─────────────────────────────────────┘
178
-
179
- Setting up MCP server for all agents...
180
- `);
173
+ console.log(`\n terminal — setting up MCP...\n`);
181
174
  let count = 0;
182
175
  if (installClaude(bin))
183
176
  count++;
@@ -186,30 +179,10 @@ export function handleInstall(args) {
186
179
  if (installGemini(bin))
187
180
  count++;
188
181
  if (count === 0) {
189
- console.log(`
190
- No AI agents found. Install one first:
191
-
192
- npm i -g @anthropic-ai/claude-code # Claude Code
193
- npm i -g @openai/codex # Codex
194
- npm i -g @anthropic-ai/gemini-cli # Gemini CLI
195
-
196
- Then run: terminal install
197
- `);
182
+ console.log(`\n No agents found. Install Claude Code, Codex, or Gemini CLI first.\n`);
198
183
  }
199
184
  else {
200
- console.log(`
201
- Done. ${count} agent${count > 1 ? "s" : ""} configured.
202
- Restart your agent to start using open-terminal.
203
-
204
- Your AI agent now has these tools:
205
- execute_smart Run any command, get AI-summarized output
206
- execute_diff Run command, see only what changed
207
- search_content Smart grep with file grouping
208
- search_files Find files by pattern
209
- read_symbol Read a function by name (not whole file)
210
- boot Full project context in one call
211
- repo_state Git status + log + diff in one call
212
- `);
185
+ console.log(`\n ${count} agent${count > 1 ? "s" : ""} ready. Restart to apply.\n`);
213
186
  }
214
187
  }
215
188
  // Re-export individual installers for programmatic use
@@ -1,4 +1,4 @@
1
- // MCP Server for open-terminal — exposes terminal capabilities to AI agents
1
+ // MCP Server for terminal — exposes terminal capabilities to AI agents
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { z } from "zod";
@@ -56,7 +56,7 @@ function exec(command, cwd, timeout) {
56
56
  // ── server ───────────────────────────────────────────────────────────────────
57
57
  export function createServer() {
58
58
  const server = new McpServer({
59
- name: "open-terminal",
59
+ name: "terminal",
60
60
  version: "0.2.0",
61
61
  });
62
62
  // ── execute: run a command, return structured result ──────────────────────
@@ -202,10 +202,10 @@ export function createServer() {
202
202
  };
203
203
  });
204
204
  // ── status: show server info ──────────────────────────────────────────────
205
- server.tool("status", "Get open-terminal server status, capabilities, and available parsers.", async () => {
205
+ server.tool("status", "Get terminal server status, capabilities, and available parsers.", async () => {
206
206
  return {
207
207
  content: [{ type: "text", text: JSON.stringify({
208
- name: "open-terminal", version: "0.3.0", cwd: process.cwd(),
208
+ name: "terminal", version: "3.3.0", cwd: process.cwd(),
209
209
  features: ["ai-output-processing", "token-compression", "noise-filtering", "diff-caching", "lazy-execution", "progressive-disclosure"],
210
210
  }) }],
211
211
  };
@@ -541,5 +541,5 @@ export async function startMcpServer() {
541
541
  const server = createServer();
542
542
  const transport = new StdioServerTransport();
543
543
  await server.connect(transport);
544
- console.error("open-terminal MCP server running on stdio");
544
+ console.error("terminal MCP server running on stdio");
545
545
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/terminal",
3
- "version": "3.3.0",
3
+ "version": "3.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
  "files": [
@@ -23,14 +23,14 @@ function hasGemini(): boolean { return !!which("gemini"); }
23
23
  function installClaude(bin: string): boolean {
24
24
  if (!hasClaude()) { log("–", "Claude Code not found, skipping"); return false; }
25
25
  try {
26
- execSync(`claude mcp add --transport stdio --scope user open-terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
26
+ execSync(`claude mcp add --transport stdio --scope user terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
27
27
  log("✓", "Claude Code");
28
28
  return true;
29
29
  } catch {
30
30
  // May already exist
31
31
  try {
32
- execSync(`claude mcp remove open-terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
33
- execSync(`claude mcp add --transport stdio --scope user open-terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
32
+ execSync(`claude mcp remove terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] });
33
+ execSync(`claude mcp add --transport stdio --scope user terminal -- ${bin} mcp serve`, { stdio: ["pipe", "pipe", "pipe"] });
34
34
  log("✓", "Claude Code (updated)");
35
35
  return true;
36
36
  } catch (e) {
@@ -50,8 +50,8 @@ function installCodex(bin: string): boolean {
50
50
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
51
51
  let content = existsSync(configPath) ? readFileSync(configPath, "utf8") : "";
52
52
  // Remove old entry if exists
53
- content = content.replace(/\n?\[mcp_servers\.open-terminal\][^\[]*/g, "");
54
- content += `\n[mcp_servers.open-terminal]\ncommand = "${bin}"\nargs = ["mcp", "serve"]\n`;
53
+ content = content.replace(/\n?\[mcp_servers\.terminal\][^\[]*/g, "");
54
+ content += `\n[mcp_servers.terminal]\ncommand = "${bin}"\nargs = ["mcp", "serve"]\n`;
55
55
  writeFileSync(configPath, content);
56
56
  log("✓", "Codex");
57
57
  return true;
@@ -74,7 +74,7 @@ function installGemini(bin: string): boolean {
74
74
  try { config = JSON.parse(readFileSync(configPath, "utf8")); } catch {}
75
75
  }
76
76
  if (!config.mcpServers) config.mcpServers = {};
77
- config.mcpServers["open-terminal"] = { command: bin, args: ["mcp", "serve"] };
77
+ config.mcpServers["terminal"] = { command: bin, args: ["mcp", "serve"] };
78
78
  writeFileSync(configPath, JSON.stringify(config, null, 2));
79
79
  log("✓", "Gemini CLI");
80
80
  return true;
@@ -88,7 +88,7 @@ function installGemini(bin: string): boolean {
88
88
 
89
89
  function uninstallClaude(): boolean {
90
90
  if (!hasClaude()) return false;
91
- try { execSync(`claude mcp remove open-terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] }); log("✓", "Removed from Claude Code"); return true; } catch { return false; }
91
+ try { execSync(`claude mcp remove terminal -s user`, { stdio: ["pipe", "pipe", "pipe"] }); log("✓", "Removed from Claude Code"); return true; } catch { return false; }
92
92
  }
93
93
 
94
94
  function uninstallCodex(): boolean {
@@ -96,8 +96,8 @@ function uninstallCodex(): boolean {
96
96
  if (!existsSync(configPath)) return false;
97
97
  try {
98
98
  let content = readFileSync(configPath, "utf8");
99
- if (!content.includes("open-terminal")) return false;
100
- content = content.replace(/\n?\[mcp_servers\.open-terminal\][^\[]*/g, "");
99
+ if (!content.includes("terminal")) return false;
100
+ content = content.replace(/\n?\[mcp_servers\.terminal\][^\[]*/g, "");
101
101
  writeFileSync(configPath, content);
102
102
  log("✓", "Removed from Codex");
103
103
  return true;
@@ -109,8 +109,8 @@ function uninstallGemini(): boolean {
109
109
  if (!existsSync(configPath)) return false;
110
110
  try {
111
111
  const config = JSON.parse(readFileSync(configPath, "utf8"));
112
- if (!config.mcpServers?.["open-terminal"]) return false;
113
- delete config.mcpServers["open-terminal"];
112
+ if (!config.mcpServers?.["terminal"]) return false;
113
+ delete config.mcpServers["terminal"];
114
114
  writeFileSync(configPath, JSON.stringify(config, null, 2));
115
115
  log("✓", "Removed from Gemini CLI");
116
116
  return true;
@@ -124,7 +124,7 @@ export function handleInstall(args: string[]): void {
124
124
 
125
125
  // Uninstall
126
126
  if (flags.has("uninstall") || flags.has("--uninstall")) {
127
- console.log("\n Removing open-terminal MCP server...\n");
127
+ console.log("\n Removing terminal MCP server...\n");
128
128
  uninstallClaude();
129
129
  uninstallCodex();
130
130
  uninstallGemini();
@@ -147,14 +147,7 @@ export function handleInstall(args: string[]): void {
147
147
 
148
148
  const bin = which("terminal") ?? which("t") ?? "npx @hasna/terminal";
149
149
 
150
- console.log(`
151
- ┌─────────────────────────────────────┐
152
- │ open-terminal │
153
- │ Smart terminal for AI agents │
154
- └─────────────────────────────────────┘
155
-
156
- Setting up MCP server for all agents...
157
- `);
150
+ console.log(`\n terminal — setting up MCP...\n`);
158
151
 
159
152
  let count = 0;
160
153
  if (installClaude(bin)) count++;
@@ -162,29 +155,9 @@ export function handleInstall(args: string[]): void {
162
155
  if (installGemini(bin)) count++;
163
156
 
164
157
  if (count === 0) {
165
- console.log(`
166
- No AI agents found. Install one first:
167
-
168
- npm i -g @anthropic-ai/claude-code # Claude Code
169
- npm i -g @openai/codex # Codex
170
- npm i -g @anthropic-ai/gemini-cli # Gemini CLI
171
-
172
- Then run: terminal install
173
- `);
158
+ console.log(`\n No agents found. Install Claude Code, Codex, or Gemini CLI first.\n`);
174
159
  } else {
175
- console.log(`
176
- Done. ${count} agent${count > 1 ? "s" : ""} configured.
177
- Restart your agent to start using open-terminal.
178
-
179
- Your AI agent now has these tools:
180
- execute_smart Run any command, get AI-summarized output
181
- execute_diff Run command, see only what changed
182
- search_content Smart grep with file grouping
183
- search_files Find files by pattern
184
- read_symbol Read a function by name (not whole file)
185
- boot Full project context in one call
186
- repo_state Git status + log + diff in one call
187
- `);
160
+ console.log(`\n ${count} agent${count > 1 ? "s" : ""} ready. Restart to apply.\n`);
188
161
  }
189
162
  }
190
163
 
package/src/mcp/server.ts CHANGED
@@ -1,4 +1,4 @@
1
- // MCP Server for open-terminal — exposes terminal capabilities to AI agents
1
+ // MCP Server for terminal — exposes terminal capabilities to AI agents
2
2
 
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -61,7 +61,7 @@ function exec(command: string, cwd?: string, timeout?: number): Promise<{ exitCo
61
61
 
62
62
  export function createServer(): McpServer {
63
63
  const server = new McpServer({
64
- name: "open-terminal",
64
+ name: "terminal",
65
65
  version: "0.2.0",
66
66
  });
67
67
 
@@ -251,11 +251,11 @@ export function createServer(): McpServer {
251
251
 
252
252
  server.tool(
253
253
  "status",
254
- "Get open-terminal server status, capabilities, and available parsers.",
254
+ "Get terminal server status, capabilities, and available parsers.",
255
255
  async () => {
256
256
  return {
257
257
  content: [{ type: "text" as const, text: JSON.stringify({
258
- name: "open-terminal", version: "0.3.0", cwd: process.cwd(),
258
+ name: "terminal", version: "3.3.0", cwd: process.cwd(),
259
259
  features: ["ai-output-processing", "token-compression", "noise-filtering", "diff-caching", "lazy-execution", "progressive-disclosure"],
260
260
  }) }],
261
261
  };
@@ -762,5 +762,5 @@ export async function startMcpServer(): Promise<void> {
762
762
  const server = createServer();
763
763
  const transport = new StdioServerTransport();
764
764
  await server.connect(transport);
765
- console.error("open-terminal MCP server running on stdio");
765
+ console.error("terminal MCP server running on stdio");
766
766
  }