@mario.andreschak/mcp-bash 3.46.1 → 3.46.2

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 (2) hide show
  1. package/dist/resources.js +242 -242
  2. package/package.json +6 -1
package/dist/resources.js CHANGED
@@ -52,247 +52,247 @@ export function bashReadResource(uri) {
52
52
  },
53
53
  };
54
54
  }
55
- const BASH_TERMINAL_APP_HTML = `<!doctype html>
56
- <html lang="en">
57
- <head>
58
- <meta charset="utf-8" />
59
- <meta name="viewport" content="width=device-width,initial-scale=1" />
60
- <style>${XTERM_CSS}</style>
61
- <style>
62
- :root { color-scheme:dark; --bar:#111827; --border:#334155; --fg:#e5e7eb; --muted:#94a3b8; --accent:#60a5fa; --danger:#f87171; }
63
- * { box-sizing:border-box; }
64
- html,body { width:100%; height:100%; margin:0; overflow:hidden; background:#050a07; color:var(--fg); font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
65
- body { display:flex; flex-direction:column; }
66
- #toolbar { display:flex; align-items:center; gap:7px; min-height:40px; padding:5px 8px; background:var(--bar); border-bottom:1px solid var(--border); }
67
- #terminal { flex:1 1 auto; min-height:180px; padding:5px; }
68
- #status { flex:1 1 auto; min-width:0; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
69
- .live { color:#86efac !important; }
70
- .error { color:var(--danger) !important; }
71
- button,select,input { min-height:28px; border:1px solid var(--border); border-radius:5px; background:#0f172a; color:var(--fg); font:inherit; padding:3px 7px; }
72
- button { cursor:pointer; }
73
- button:disabled { opacity:.5; cursor:not-allowed; }
74
- #cwd { width:min(28vw,260px); }
75
- #shell { max-width:125px; }
76
- .xterm { height:100%; }
77
- .xterm-viewport { scrollbar-color:#475569 #07120d; }
78
- </style>
79
- <script>${XTERM_JS}</script>
80
- <script>${XTERM_FIT_JS}</script>
81
- </head>
82
- <body>
83
- <div id="toolbar">
84
- <select id="shell" aria-label="Shell"><option value="default">Automatic</option><option value="pwsh">PowerShell 7</option><option value="powershell">Windows PowerShell 5.1</option><option value="bash">Bash</option><option value="cmd">cmd</option></select>
85
- <input id="cwd" aria-label="Working directory" value="." title="Working directory" />
86
- <button id="new" type="button">New</button>
87
- <button id="copy" type="button" title="Copy selection">Copy</button>
88
- <button id="clear" type="button">Clear</button>
89
- <button id="close" type="button">Close</button>
90
- <span id="status">Initializing terminal…</span>
91
- </div>
92
- <div id="terminal" aria-label="Interactive terminal"></div>
93
- <script>
94
- (function () {
95
- "use strict";
96
- var nextId = 1;
97
- var pending = {};
98
- var sessionId = "";
99
- var cursor = 0;
100
- var running = false;
101
- var pollTimer = null;
102
- var pollBusy = false;
103
- var opening = false;
104
- var inputQueue = "";
105
- var inputBusy = false;
106
- var resizeTimer = null;
107
- var lastToolInput = {};
108
-
109
- var statusEl = document.getElementById("status");
110
- var shellEl = document.getElementById("shell");
111
- var cwdEl = document.getElementById("cwd");
112
- var terminal = new Terminal({
113
- cursorBlink:true,
114
- convertEol:false,
115
- scrollback:10000,
116
- fontFamily:'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
117
- fontSize:13,
118
- theme:{ background:'#050a07', foreground:'#d1fae5', cursor:'#86efac', selectionBackground:'#2563eb88' }
119
- });
120
- var fitAddon = new FitAddon.FitAddon();
121
- terminal.loadAddon(fitAddon);
122
- terminal.open(document.getElementById("terminal"));
123
- fitAddon.fit();
124
-
125
- function post(message) { window.parent.postMessage(message, "*"); }
126
- function rpc(method, params) {
127
- return new Promise(function (resolve, reject) {
128
- var id = nextId++;
129
- pending[id] = { resolve:resolve, reject:reject };
130
- post({ jsonrpc:"2.0", id:id, method:method, params:params || {} });
131
- });
132
- }
133
- function notify(method, params) { post({ jsonrpc:"2.0", method:method, params:params || {} }); }
134
- function payloadOf(result) {
135
- if (!result) return null;
136
- if (result.structuredContent) return result.structuredContent;
137
- try {
138
- var text = result.content && result.content[0] && result.content[0].text;
139
- return text ? JSON.parse(text) : null;
140
- } catch (e) { return null; }
141
- }
142
- async function callTool(name, args) {
143
- var result = await rpc("tools/call", { name:name, arguments:args || {} });
144
- var data = payloadOf(result) || {};
145
- if (result && result.isError) throw new Error(data.error || name + " failed");
146
- return data;
147
- }
148
- function setStatus(message, kind) {
149
- statusEl.textContent = message;
150
- statusEl.className = kind || "";
151
- }
152
- function schedulePoll(delay) {
153
- if (pollTimer) clearTimeout(pollTimer);
154
- pollTimer = sessionId ? setTimeout(poll, delay == null ? (running ? 60 : 500) : delay) : null;
155
- }
156
- function acceptSession(data) {
157
- if (!data || !data.sessionId) return false;
158
- sessionId = String(data.sessionId);
159
- cursor = Number(data.cursor || data.nextCursor || 0);
160
- running = data.running !== false;
161
- setStatus((running ? "● " : "○ ") + (data.shell || "terminal") + " — " + (data.cwd || sessionId), running ? "live" : "");
162
- schedulePoll(0);
163
- terminal.focus();
164
- return true;
165
- }
166
- async function openTerminal() {
167
- if (opening) return;
168
- opening = true;
169
- document.getElementById("new").disabled = true;
170
- try {
171
- if (sessionId && running) await callTool("terminal_close", { sessionId:sessionId }).catch(function () {});
172
- terminal.reset();
173
- terminal.clear();
174
- var data = await callTool("open_terminal", {
175
- shell:shellEl.value,
176
- cwd:cwdEl.value.trim() || ".",
177
- cols:terminal.cols,
178
- rows:terminal.rows
179
- });
180
- acceptSession(data);
181
- } catch (error) {
182
- setStatus(error && error.message ? error.message : String(error), "error");
183
- terminal.writeln("\\r\\n\\x1b[31m" + (error && error.message ? error.message : String(error)) + "\\x1b[0m");
184
- } finally {
185
- opening = false;
186
- document.getElementById("new").disabled = false;
187
- }
188
- }
189
- async function poll() {
190
- if (!sessionId || pollBusy) return;
191
- pollBusy = true;
192
- try {
193
- var data = await callTool("terminal_read", { sessionId:sessionId, cursor:cursor });
194
- if (data.reset) { terminal.reset(); terminal.clear(); }
195
- if (typeof data.chunk === "string" && data.chunk) terminal.write(data.chunk);
196
- cursor = Number(data.nextCursor == null ? cursor : data.nextCursor);
197
- running = data.running !== false;
198
- setStatus((running ? "● " : "○ ") + (data.shell || "terminal") + " — " + (data.cwd || sessionId) + (running ? "" : " — exited " + String(data.exitCode)), running ? "live" : "");
199
- } catch (error) {
200
- running = false;
201
- setStatus(error && error.message ? error.message : String(error), "error");
202
- } finally {
203
- pollBusy = false;
204
- schedulePoll();
205
- }
206
- }
207
- async function flushInput() {
208
- if (inputBusy || !inputQueue || !sessionId || !running) return;
209
- inputBusy = true;
210
- var data = inputQueue;
211
- inputQueue = "";
212
- try { await callTool("terminal_write", { sessionId:sessionId, data:data }); }
213
- catch (error) { setStatus(error && error.message ? error.message : String(error), "error"); }
214
- finally { inputBusy = false; if (inputQueue) setTimeout(flushInput, 0); }
215
- }
216
- function sendResize() {
217
- if (!sessionId || !running) return;
218
- callTool("terminal_resize", { sessionId:sessionId, cols:terminal.cols, rows:terminal.rows }).catch(function () {});
219
- }
220
- function acceptToolResult(result) {
221
- var data = payloadOf(result) || {};
222
- acceptSession(data);
223
- }
224
-
225
- terminal.onData(function (data) {
226
- inputQueue += data;
227
- setTimeout(flushInput, 0);
228
- });
229
- terminal.onResize(function () {
230
- if (resizeTimer) clearTimeout(resizeTimer);
231
- resizeTimer = setTimeout(sendResize, 100);
232
- });
233
- window.addEventListener("resize", function () { try { fitAddon.fit(); } catch (e) {} });
234
- document.getElementById("new").onclick = openTerminal;
235
- document.getElementById("clear").onclick = function () { terminal.clear(); };
236
- document.getElementById("copy").onclick = function () {
237
- var text = terminal.getSelection();
238
- if (!text) { setStatus("Select terminal text first.", ""); return; }
239
- if (navigator.clipboard && navigator.clipboard.writeText) {
240
- navigator.clipboard.writeText(text).then(function () { setStatus("Selection copied.", ""); }).catch(function () { setStatus("Copy was denied by the host.", "error"); });
241
- }
242
- };
243
- document.getElementById("close").onclick = async function () {
244
- if (!sessionId) return;
245
- await callTool("terminal_close", { sessionId:sessionId }).catch(function () {});
246
- running = false;
247
- setStatus("Terminal closed.", "");
248
- };
249
-
250
- window.addEventListener("message", function (event) {
251
- var message = event.data;
252
- if (!message || message.jsonrpc !== "2.0") return;
253
- if (message.id !== undefined && (message.result !== undefined || message.error !== undefined)) {
254
- var waiting = pending[message.id];
255
- if (!waiting) return;
256
- delete pending[message.id];
257
- if (message.error) waiting.reject(new Error(message.error.message || "RPC error"));
258
- else waiting.resolve(message.result);
259
- return;
260
- }
261
- if (message.method === "ui/notifications/tool-input") {
262
- lastToolInput = message.params && message.params.arguments || {};
263
- if (typeof lastToolInput.cwd === "string") cwdEl.value = lastToolInput.cwd;
264
- if (typeof lastToolInput.shell === "string") shellEl.value = lastToolInput.shell;
265
- return;
266
- }
267
- if (message.method === "ui/notifications/tool-result") { acceptToolResult(message.params && message.params.result ? message.params.result : message.params); return; }
268
- if (message.method === "ping" && message.id !== undefined) { post({ jsonrpc:"2.0", id:message.id, result:{} }); return; }
269
- if (message.method === "ui/resource-teardown" && message.id !== undefined) {
270
- // Dock/fullscreen transitions tear down Views; the owner-scoped PTY stays
271
- // alive so the replacement View can reattach through terminal_list.
272
- post({ jsonrpc:"2.0", id:message.id, result:{} });
273
- }
274
- });
275
-
276
- rpc("ui/initialize", {
277
- appInfo:{ name:"bash-terminal", version:"2.0.0" },
278
- appCapabilities:{ availableDisplayModes:["inline","fullscreen","pip"] },
279
- protocolVersion:"${MCP_APPS_PROTOCOL_VERSION}"
280
- }).then(async function () {
281
- notify("ui/notifications/initialized", {});
282
- try { fitAddon.fit(); } catch (e) {}
283
- setTimeout(async function () {
284
- if (sessionId) return;
285
- try {
286
- var listed = await callTool("terminal_list", {});
287
- var sessions = Array.isArray(listed.sessions) ? listed.sessions : [];
288
- var active = sessions.filter(function (item) { return item.running; }).pop();
289
- if (!acceptSession(active)) await openTerminal();
290
- } catch (e) { await openTerminal(); }
291
- }, 350);
292
- rpc("ui/request-display-mode", { mode:"pip" }).catch(function () {});
293
- }).catch(function (error) { setStatus("MCP App initialization failed: " + (error && error.message ? error.message : error), "error"); });
294
- })();
295
- </script>
296
- </body>
55
+ const BASH_TERMINAL_APP_HTML = `<!doctype html>
56
+ <html lang="en">
57
+ <head>
58
+ <meta charset="utf-8" />
59
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
60
+ <style>${XTERM_CSS}</style>
61
+ <style>
62
+ :root { color-scheme:dark; --bar:#111827; --border:#334155; --fg:#e5e7eb; --muted:#94a3b8; --accent:#60a5fa; --danger:#f87171; }
63
+ * { box-sizing:border-box; }
64
+ html,body { width:100%; height:100%; margin:0; overflow:hidden; background:#050a07; color:var(--fg); font:12px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
65
+ body { display:flex; flex-direction:column; }
66
+ #toolbar { display:flex; align-items:center; gap:7px; min-height:40px; padding:5px 8px; background:var(--bar); border-bottom:1px solid var(--border); }
67
+ #terminal { flex:1 1 auto; min-height:180px; padding:5px; }
68
+ #status { flex:1 1 auto; min-width:0; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
69
+ .live { color:#86efac !important; }
70
+ .error { color:var(--danger) !important; }
71
+ button,select,input { min-height:28px; border:1px solid var(--border); border-radius:5px; background:#0f172a; color:var(--fg); font:inherit; padding:3px 7px; }
72
+ button { cursor:pointer; }
73
+ button:disabled { opacity:.5; cursor:not-allowed; }
74
+ #cwd { width:min(28vw,260px); }
75
+ #shell { max-width:125px; }
76
+ .xterm { height:100%; }
77
+ .xterm-viewport { scrollbar-color:#475569 #07120d; }
78
+ </style>
79
+ <script>${XTERM_JS}</script>
80
+ <script>${XTERM_FIT_JS}</script>
81
+ </head>
82
+ <body>
83
+ <div id="toolbar">
84
+ <select id="shell" aria-label="Shell"><option value="default">Automatic</option><option value="pwsh">PowerShell 7</option><option value="powershell">Windows PowerShell 5.1</option><option value="bash">Bash</option><option value="cmd">cmd</option></select>
85
+ <input id="cwd" aria-label="Working directory" value="." title="Working directory" />
86
+ <button id="new" type="button">New</button>
87
+ <button id="copy" type="button" title="Copy selection">Copy</button>
88
+ <button id="clear" type="button">Clear</button>
89
+ <button id="close" type="button">Close</button>
90
+ <span id="status">Initializing terminal…</span>
91
+ </div>
92
+ <div id="terminal" aria-label="Interactive terminal"></div>
93
+ <script>
94
+ (function () {
95
+ "use strict";
96
+ var nextId = 1;
97
+ var pending = {};
98
+ var sessionId = "";
99
+ var cursor = 0;
100
+ var running = false;
101
+ var pollTimer = null;
102
+ var pollBusy = false;
103
+ var opening = false;
104
+ var inputQueue = "";
105
+ var inputBusy = false;
106
+ var resizeTimer = null;
107
+ var lastToolInput = {};
108
+
109
+ var statusEl = document.getElementById("status");
110
+ var shellEl = document.getElementById("shell");
111
+ var cwdEl = document.getElementById("cwd");
112
+ var terminal = new Terminal({
113
+ cursorBlink:true,
114
+ convertEol:false,
115
+ scrollback:10000,
116
+ fontFamily:'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
117
+ fontSize:13,
118
+ theme:{ background:'#050a07', foreground:'#d1fae5', cursor:'#86efac', selectionBackground:'#2563eb88' }
119
+ });
120
+ var fitAddon = new FitAddon.FitAddon();
121
+ terminal.loadAddon(fitAddon);
122
+ terminal.open(document.getElementById("terminal"));
123
+ fitAddon.fit();
124
+
125
+ function post(message) { window.parent.postMessage(message, "*"); }
126
+ function rpc(method, params) {
127
+ return new Promise(function (resolve, reject) {
128
+ var id = nextId++;
129
+ pending[id] = { resolve:resolve, reject:reject };
130
+ post({ jsonrpc:"2.0", id:id, method:method, params:params || {} });
131
+ });
132
+ }
133
+ function notify(method, params) { post({ jsonrpc:"2.0", method:method, params:params || {} }); }
134
+ function payloadOf(result) {
135
+ if (!result) return null;
136
+ if (result.structuredContent) return result.structuredContent;
137
+ try {
138
+ var text = result.content && result.content[0] && result.content[0].text;
139
+ return text ? JSON.parse(text) : null;
140
+ } catch (e) { return null; }
141
+ }
142
+ async function callTool(name, args) {
143
+ var result = await rpc("tools/call", { name:name, arguments:args || {} });
144
+ var data = payloadOf(result) || {};
145
+ if (result && result.isError) throw new Error(data.error || name + " failed");
146
+ return data;
147
+ }
148
+ function setStatus(message, kind) {
149
+ statusEl.textContent = message;
150
+ statusEl.className = kind || "";
151
+ }
152
+ function schedulePoll(delay) {
153
+ if (pollTimer) clearTimeout(pollTimer);
154
+ pollTimer = sessionId ? setTimeout(poll, delay == null ? (running ? 60 : 500) : delay) : null;
155
+ }
156
+ function acceptSession(data) {
157
+ if (!data || !data.sessionId) return false;
158
+ sessionId = String(data.sessionId);
159
+ cursor = Number(data.cursor || data.nextCursor || 0);
160
+ running = data.running !== false;
161
+ setStatus((running ? "● " : "○ ") + (data.shell || "terminal") + " — " + (data.cwd || sessionId), running ? "live" : "");
162
+ schedulePoll(0);
163
+ terminal.focus();
164
+ return true;
165
+ }
166
+ async function openTerminal() {
167
+ if (opening) return;
168
+ opening = true;
169
+ document.getElementById("new").disabled = true;
170
+ try {
171
+ if (sessionId && running) await callTool("terminal_close", { sessionId:sessionId }).catch(function () {});
172
+ terminal.reset();
173
+ terminal.clear();
174
+ var data = await callTool("open_terminal", {
175
+ shell:shellEl.value,
176
+ cwd:cwdEl.value.trim() || ".",
177
+ cols:terminal.cols,
178
+ rows:terminal.rows
179
+ });
180
+ acceptSession(data);
181
+ } catch (error) {
182
+ setStatus(error && error.message ? error.message : String(error), "error");
183
+ terminal.writeln("\\r\\n\\x1b[31m" + (error && error.message ? error.message : String(error)) + "\\x1b[0m");
184
+ } finally {
185
+ opening = false;
186
+ document.getElementById("new").disabled = false;
187
+ }
188
+ }
189
+ async function poll() {
190
+ if (!sessionId || pollBusy) return;
191
+ pollBusy = true;
192
+ try {
193
+ var data = await callTool("terminal_read", { sessionId:sessionId, cursor:cursor });
194
+ if (data.reset) { terminal.reset(); terminal.clear(); }
195
+ if (typeof data.chunk === "string" && data.chunk) terminal.write(data.chunk);
196
+ cursor = Number(data.nextCursor == null ? cursor : data.nextCursor);
197
+ running = data.running !== false;
198
+ setStatus((running ? "● " : "○ ") + (data.shell || "terminal") + " — " + (data.cwd || sessionId) + (running ? "" : " — exited " + String(data.exitCode)), running ? "live" : "");
199
+ } catch (error) {
200
+ running = false;
201
+ setStatus(error && error.message ? error.message : String(error), "error");
202
+ } finally {
203
+ pollBusy = false;
204
+ schedulePoll();
205
+ }
206
+ }
207
+ async function flushInput() {
208
+ if (inputBusy || !inputQueue || !sessionId || !running) return;
209
+ inputBusy = true;
210
+ var data = inputQueue;
211
+ inputQueue = "";
212
+ try { await callTool("terminal_write", { sessionId:sessionId, data:data }); }
213
+ catch (error) { setStatus(error && error.message ? error.message : String(error), "error"); }
214
+ finally { inputBusy = false; if (inputQueue) setTimeout(flushInput, 0); }
215
+ }
216
+ function sendResize() {
217
+ if (!sessionId || !running) return;
218
+ callTool("terminal_resize", { sessionId:sessionId, cols:terminal.cols, rows:terminal.rows }).catch(function () {});
219
+ }
220
+ function acceptToolResult(result) {
221
+ var data = payloadOf(result) || {};
222
+ acceptSession(data);
223
+ }
224
+
225
+ terminal.onData(function (data) {
226
+ inputQueue += data;
227
+ setTimeout(flushInput, 0);
228
+ });
229
+ terminal.onResize(function () {
230
+ if (resizeTimer) clearTimeout(resizeTimer);
231
+ resizeTimer = setTimeout(sendResize, 100);
232
+ });
233
+ window.addEventListener("resize", function () { try { fitAddon.fit(); } catch (e) {} });
234
+ document.getElementById("new").onclick = openTerminal;
235
+ document.getElementById("clear").onclick = function () { terminal.clear(); };
236
+ document.getElementById("copy").onclick = function () {
237
+ var text = terminal.getSelection();
238
+ if (!text) { setStatus("Select terminal text first.", ""); return; }
239
+ if (navigator.clipboard && navigator.clipboard.writeText) {
240
+ navigator.clipboard.writeText(text).then(function () { setStatus("Selection copied.", ""); }).catch(function () { setStatus("Copy was denied by the host.", "error"); });
241
+ }
242
+ };
243
+ document.getElementById("close").onclick = async function () {
244
+ if (!sessionId) return;
245
+ await callTool("terminal_close", { sessionId:sessionId }).catch(function () {});
246
+ running = false;
247
+ setStatus("Terminal closed.", "");
248
+ };
249
+
250
+ window.addEventListener("message", function (event) {
251
+ var message = event.data;
252
+ if (!message || message.jsonrpc !== "2.0") return;
253
+ if (message.id !== undefined && (message.result !== undefined || message.error !== undefined)) {
254
+ var waiting = pending[message.id];
255
+ if (!waiting) return;
256
+ delete pending[message.id];
257
+ if (message.error) waiting.reject(new Error(message.error.message || "RPC error"));
258
+ else waiting.resolve(message.result);
259
+ return;
260
+ }
261
+ if (message.method === "ui/notifications/tool-input") {
262
+ lastToolInput = message.params && message.params.arguments || {};
263
+ if (typeof lastToolInput.cwd === "string") cwdEl.value = lastToolInput.cwd;
264
+ if (typeof lastToolInput.shell === "string") shellEl.value = lastToolInput.shell;
265
+ return;
266
+ }
267
+ if (message.method === "ui/notifications/tool-result") { acceptToolResult(message.params && message.params.result ? message.params.result : message.params); return; }
268
+ if (message.method === "ping" && message.id !== undefined) { post({ jsonrpc:"2.0", id:message.id, result:{} }); return; }
269
+ if (message.method === "ui/resource-teardown" && message.id !== undefined) {
270
+ // Dock/fullscreen transitions tear down Views; the owner-scoped PTY stays
271
+ // alive so the replacement View can reattach through terminal_list.
272
+ post({ jsonrpc:"2.0", id:message.id, result:{} });
273
+ }
274
+ });
275
+
276
+ rpc("ui/initialize", {
277
+ appInfo:{ name:"bash-terminal", version:"2.0.0" },
278
+ appCapabilities:{ availableDisplayModes:["inline","fullscreen","pip"] },
279
+ protocolVersion:"${MCP_APPS_PROTOCOL_VERSION}"
280
+ }).then(async function () {
281
+ notify("ui/notifications/initialized", {});
282
+ try { fitAddon.fit(); } catch (e) {}
283
+ setTimeout(async function () {
284
+ if (sessionId) return;
285
+ try {
286
+ var listed = await callTool("terminal_list", {});
287
+ var sessions = Array.isArray(listed.sessions) ? listed.sessions : [];
288
+ var active = sessions.filter(function (item) { return item.running; }).pop();
289
+ if (!acceptSession(active)) await openTerminal();
290
+ } catch (e) { await openTerminal(); }
291
+ }, 350);
292
+ rpc("ui/request-display-mode", { mode:"pip" }).catch(function () {});
293
+ }).catch(function (error) { setStatus("MCP App initialization failed: " + (error && error.message ? error.message : error), "error"); });
294
+ })();
295
+ </script>
296
+ </body>
297
297
  </html>`;
298
298
  //# sourceMappingURL=resources.js.map
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@mario.andreschak/mcp-bash",
3
- "version": "3.46.1",
3
+ "version": "3.46.2",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/mario-andreschak/FLUJO.git",
7
+ "directory": "mcp-servers/bash"
8
+ },
4
9
  "description": "FLUJO's standalone cross-platform shell MCP server",
5
10
  "type": "module",
6
11
  "main": "dist/index.js",