terminal-commands 0.2.0 → 0.2.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.
- package/dist/agent.js +55 -6
- package/dist/cli.js +55 -6
- package/dist/index.js +2 -2
- package/dist/stdio.js +1 -1
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -35857,19 +35857,33 @@ function assertActive(signal) {
|
|
|
35857
35857
|
);
|
|
35858
35858
|
}
|
|
35859
35859
|
}
|
|
35860
|
-
async function authorizeToolCall(tool, args, allowDestructive, approve, signal) {
|
|
35860
|
+
async function authorizeToolCall(tool, args, allowDestructive, approve, signal, progress) {
|
|
35861
|
+
const notify = (phase) => {
|
|
35862
|
+
try {
|
|
35863
|
+
progress?.(phase);
|
|
35864
|
+
} catch {
|
|
35865
|
+
}
|
|
35866
|
+
};
|
|
35861
35867
|
assertActive(signal);
|
|
35862
35868
|
if (!destructiveTools.has(tool)) return;
|
|
35863
35869
|
if (!allowDestructive) {
|
|
35870
|
+
notify("denied");
|
|
35864
35871
|
throw new Error(
|
|
35865
35872
|
"This action requires local approval. Commands and writes are disabled unless explicitly enabled."
|
|
35866
35873
|
);
|
|
35867
35874
|
}
|
|
35868
|
-
if (!approve
|
|
35875
|
+
if (!approve) {
|
|
35876
|
+
notify("denied");
|
|
35877
|
+
throw new Error("The action was not approved on the connected machine.");
|
|
35878
|
+
}
|
|
35879
|
+
notify("awaiting_approval");
|
|
35880
|
+
if (!await approve(tool, args, signal)) {
|
|
35869
35881
|
assertActive(signal);
|
|
35882
|
+
notify("denied");
|
|
35870
35883
|
throw new Error("The action was not approved on the connected machine.");
|
|
35871
35884
|
}
|
|
35872
35885
|
assertActive(signal);
|
|
35886
|
+
notify("approved");
|
|
35873
35887
|
}
|
|
35874
35888
|
async function connectOnce(options, acknowledged) {
|
|
35875
35889
|
const { config: config3, signal } = options;
|
|
@@ -35880,7 +35894,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35880
35894
|
}
|
|
35881
35895
|
const client = new Client({
|
|
35882
35896
|
name: "terminal-commands-cli",
|
|
35883
|
-
version: "0.2.
|
|
35897
|
+
version: "0.2.1"
|
|
35884
35898
|
});
|
|
35885
35899
|
let disposeSocket;
|
|
35886
35900
|
try {
|
|
@@ -35902,6 +35916,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35902
35916
|
});
|
|
35903
35917
|
disposeSocket = () => socket.terminate();
|
|
35904
35918
|
const pending = /* @__PURE__ */ new Map();
|
|
35919
|
+
let requestProgressEnabled = false;
|
|
35905
35920
|
const forwarder = new ProcessEventForwarder(
|
|
35906
35921
|
async (name, args) => client.callTool({ name, arguments: args }),
|
|
35907
35922
|
(message) => {
|
|
@@ -35952,6 +35967,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35952
35967
|
return;
|
|
35953
35968
|
}
|
|
35954
35969
|
if (message && typeof message === "object" && "type" in message && message.type === "ready") {
|
|
35970
|
+
requestProgressEnabled = message.requestProgressVersion === 1;
|
|
35955
35971
|
void forwarder.recover().catch(
|
|
35956
35972
|
(error62) => options.log?.(
|
|
35957
35973
|
"Could not recover local process streams: " + (error62 instanceof Error ? error62.message : "unknown error")
|
|
@@ -35963,7 +35979,15 @@ async function connectOnce(options, acknowledged) {
|
|
|
35963
35979
|
options.log?.("Ignoring a malformed gateway message.");
|
|
35964
35980
|
return;
|
|
35965
35981
|
}
|
|
35966
|
-
void handleMessage(
|
|
35982
|
+
void handleMessage(
|
|
35983
|
+
options,
|
|
35984
|
+
client,
|
|
35985
|
+
socket,
|
|
35986
|
+
raw,
|
|
35987
|
+
pending,
|
|
35988
|
+
forwarder,
|
|
35989
|
+
requestProgressEnabled
|
|
35990
|
+
);
|
|
35967
35991
|
});
|
|
35968
35992
|
socket.on("close", () => {
|
|
35969
35993
|
forwarder.close();
|
|
@@ -35978,7 +36002,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35978
36002
|
await client.close().catch(() => void 0);
|
|
35979
36003
|
}
|
|
35980
36004
|
}
|
|
35981
|
-
async function handleMessage(options, client, socket, raw, pending, forwarder) {
|
|
36005
|
+
async function handleMessage(options, client, socket, raw, pending, forwarder, requestProgressEnabled) {
|
|
35982
36006
|
let requestId;
|
|
35983
36007
|
let controller2;
|
|
35984
36008
|
let deadlineTimer;
|
|
@@ -36015,12 +36039,37 @@ async function handleMessage(options, client, socket, raw, pending, forwarder) {
|
|
|
36015
36039
|
() => controller2?.abort(),
|
|
36016
36040
|
Math.max(0, deadlineAt - Date.now())
|
|
36017
36041
|
);
|
|
36042
|
+
let progressSequence = 0;
|
|
36043
|
+
const progress = (phase) => {
|
|
36044
|
+
if (!requestProgressEnabled || parsed.data.tool !== "start_process" || socket.readyState !== wrapper_default.OPEN)
|
|
36045
|
+
return;
|
|
36046
|
+
if (socket.bufferedAmount > 512e3) {
|
|
36047
|
+
socket.close(1013, "Request progress backpressure");
|
|
36048
|
+
return;
|
|
36049
|
+
}
|
|
36050
|
+
try {
|
|
36051
|
+
socket.send(
|
|
36052
|
+
JSON.stringify({
|
|
36053
|
+
type: "request_progress",
|
|
36054
|
+
requestId,
|
|
36055
|
+
sequence: ++progressSequence,
|
|
36056
|
+
phase,
|
|
36057
|
+
...phase === "approved" ? {
|
|
36058
|
+
approvalMode: options.config.MACHINE_TERMINAL_AUTO_APPROVE === "1" ? "automatic" : "manual"
|
|
36059
|
+
} : {}
|
|
36060
|
+
})
|
|
36061
|
+
);
|
|
36062
|
+
} catch {
|
|
36063
|
+
}
|
|
36064
|
+
};
|
|
36065
|
+
progress("received");
|
|
36018
36066
|
await authorizeToolCall(
|
|
36019
36067
|
parsed.data.tool,
|
|
36020
36068
|
parsed.data.arguments,
|
|
36021
36069
|
options.config.MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE === "1",
|
|
36022
36070
|
options.approve,
|
|
36023
|
-
controller2.signal
|
|
36071
|
+
controller2.signal,
|
|
36072
|
+
progress
|
|
36024
36073
|
);
|
|
36025
36074
|
assertActive(controller2.signal);
|
|
36026
36075
|
const result = await client.callTool({
|
package/dist/cli.js
CHANGED
|
@@ -35866,19 +35866,33 @@ function assertActive(signal) {
|
|
|
35866
35866
|
);
|
|
35867
35867
|
}
|
|
35868
35868
|
}
|
|
35869
|
-
async function authorizeToolCall(tool, args, allowDestructive, approve, signal) {
|
|
35869
|
+
async function authorizeToolCall(tool, args, allowDestructive, approve, signal, progress) {
|
|
35870
|
+
const notify = (phase) => {
|
|
35871
|
+
try {
|
|
35872
|
+
progress?.(phase);
|
|
35873
|
+
} catch {
|
|
35874
|
+
}
|
|
35875
|
+
};
|
|
35870
35876
|
assertActive(signal);
|
|
35871
35877
|
if (!destructiveTools.has(tool)) return;
|
|
35872
35878
|
if (!allowDestructive) {
|
|
35879
|
+
notify("denied");
|
|
35873
35880
|
throw new Error(
|
|
35874
35881
|
"This action requires local approval. Commands and writes are disabled unless explicitly enabled."
|
|
35875
35882
|
);
|
|
35876
35883
|
}
|
|
35877
|
-
if (!approve
|
|
35884
|
+
if (!approve) {
|
|
35885
|
+
notify("denied");
|
|
35886
|
+
throw new Error("The action was not approved on the connected machine.");
|
|
35887
|
+
}
|
|
35888
|
+
notify("awaiting_approval");
|
|
35889
|
+
if (!await approve(tool, args, signal)) {
|
|
35878
35890
|
assertActive(signal);
|
|
35891
|
+
notify("denied");
|
|
35879
35892
|
throw new Error("The action was not approved on the connected machine.");
|
|
35880
35893
|
}
|
|
35881
35894
|
assertActive(signal);
|
|
35895
|
+
notify("approved");
|
|
35882
35896
|
}
|
|
35883
35897
|
async function connectOnce(options, acknowledged) {
|
|
35884
35898
|
const { config: config2, signal } = options;
|
|
@@ -35889,7 +35903,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35889
35903
|
}
|
|
35890
35904
|
const client = new Client({
|
|
35891
35905
|
name: "terminal-commands-cli",
|
|
35892
|
-
version: "0.2.
|
|
35906
|
+
version: "0.2.1"
|
|
35893
35907
|
});
|
|
35894
35908
|
let disposeSocket;
|
|
35895
35909
|
try {
|
|
@@ -35911,6 +35925,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35911
35925
|
});
|
|
35912
35926
|
disposeSocket = () => socket.terminate();
|
|
35913
35927
|
const pending = /* @__PURE__ */ new Map();
|
|
35928
|
+
let requestProgressEnabled = false;
|
|
35914
35929
|
const forwarder = new ProcessEventForwarder(
|
|
35915
35930
|
async (name, args) => client.callTool({ name, arguments: args }),
|
|
35916
35931
|
(message) => {
|
|
@@ -35961,6 +35976,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35961
35976
|
return;
|
|
35962
35977
|
}
|
|
35963
35978
|
if (message && typeof message === "object" && "type" in message && message.type === "ready") {
|
|
35979
|
+
requestProgressEnabled = message.requestProgressVersion === 1;
|
|
35964
35980
|
void forwarder.recover().catch(
|
|
35965
35981
|
(error62) => options.log?.(
|
|
35966
35982
|
"Could not recover local process streams: " + (error62 instanceof Error ? error62.message : "unknown error")
|
|
@@ -35972,7 +35988,15 @@ async function connectOnce(options, acknowledged) {
|
|
|
35972
35988
|
options.log?.("Ignoring a malformed gateway message.");
|
|
35973
35989
|
return;
|
|
35974
35990
|
}
|
|
35975
|
-
void handleMessage(
|
|
35991
|
+
void handleMessage(
|
|
35992
|
+
options,
|
|
35993
|
+
client,
|
|
35994
|
+
socket,
|
|
35995
|
+
raw,
|
|
35996
|
+
pending,
|
|
35997
|
+
forwarder,
|
|
35998
|
+
requestProgressEnabled
|
|
35999
|
+
);
|
|
35976
36000
|
});
|
|
35977
36001
|
socket.on("close", () => {
|
|
35978
36002
|
forwarder.close();
|
|
@@ -35987,7 +36011,7 @@ async function connectOnce(options, acknowledged) {
|
|
|
35987
36011
|
await client.close().catch(() => void 0);
|
|
35988
36012
|
}
|
|
35989
36013
|
}
|
|
35990
|
-
async function handleMessage(options, client, socket, raw, pending, forwarder) {
|
|
36014
|
+
async function handleMessage(options, client, socket, raw, pending, forwarder, requestProgressEnabled) {
|
|
35991
36015
|
let requestId;
|
|
35992
36016
|
let controller;
|
|
35993
36017
|
let deadlineTimer;
|
|
@@ -36024,12 +36048,37 @@ async function handleMessage(options, client, socket, raw, pending, forwarder) {
|
|
|
36024
36048
|
() => controller?.abort(),
|
|
36025
36049
|
Math.max(0, deadlineAt - Date.now())
|
|
36026
36050
|
);
|
|
36051
|
+
let progressSequence = 0;
|
|
36052
|
+
const progress = (phase) => {
|
|
36053
|
+
if (!requestProgressEnabled || parsed.data.tool !== "start_process" || socket.readyState !== wrapper_default.OPEN)
|
|
36054
|
+
return;
|
|
36055
|
+
if (socket.bufferedAmount > 512e3) {
|
|
36056
|
+
socket.close(1013, "Request progress backpressure");
|
|
36057
|
+
return;
|
|
36058
|
+
}
|
|
36059
|
+
try {
|
|
36060
|
+
socket.send(
|
|
36061
|
+
JSON.stringify({
|
|
36062
|
+
type: "request_progress",
|
|
36063
|
+
requestId,
|
|
36064
|
+
sequence: ++progressSequence,
|
|
36065
|
+
phase,
|
|
36066
|
+
...phase === "approved" ? {
|
|
36067
|
+
approvalMode: options.config.MACHINE_TERMINAL_AUTO_APPROVE === "1" ? "automatic" : "manual"
|
|
36068
|
+
} : {}
|
|
36069
|
+
})
|
|
36070
|
+
);
|
|
36071
|
+
} catch {
|
|
36072
|
+
}
|
|
36073
|
+
};
|
|
36074
|
+
progress("received");
|
|
36027
36075
|
await authorizeToolCall(
|
|
36028
36076
|
parsed.data.tool,
|
|
36029
36077
|
parsed.data.arguments,
|
|
36030
36078
|
options.config.MACHINE_TERMINAL_AGENT_ALLOW_DESTRUCTIVE === "1",
|
|
36031
36079
|
options.approve,
|
|
36032
|
-
controller.signal
|
|
36080
|
+
controller.signal,
|
|
36081
|
+
progress
|
|
36033
36082
|
);
|
|
36034
36083
|
assertActive(controller.signal);
|
|
36035
36084
|
const result = await client.callTool({
|
package/dist/index.js
CHANGED
|
@@ -63373,7 +63373,7 @@ function createServer(options = {}) {
|
|
|
63373
63373
|
}
|
|
63374
63374
|
};
|
|
63375
63375
|
const server = new McpServer(
|
|
63376
|
-
{ name: "terminal-commands", version: "0.2.
|
|
63376
|
+
{ name: "terminal-commands", version: "0.2.1" },
|
|
63377
63377
|
{
|
|
63378
63378
|
instructions: "This server controls the user's machine. Prefer dedicated file tools over commands. Every command and write can modify or expose local data and must receive user approval. Never request secrets or bypass configured roots and safety controls."
|
|
63379
63379
|
}
|
|
@@ -63749,7 +63749,7 @@ app.get("/health", (request, response) => {
|
|
|
63749
63749
|
response.status(available ? 200 : 503).json({
|
|
63750
63750
|
status: available ? "ok" : "filesystem_unavailable",
|
|
63751
63751
|
server: "terminal-commands",
|
|
63752
|
-
version: "0.2.
|
|
63752
|
+
version: "0.2.1",
|
|
63753
63753
|
...proof ? { agentProof: proof } : {}
|
|
63754
63754
|
});
|
|
63755
63755
|
});
|
package/dist/stdio.js
CHANGED
|
@@ -37280,7 +37280,7 @@ function createServer(options = {}) {
|
|
|
37280
37280
|
}
|
|
37281
37281
|
};
|
|
37282
37282
|
const server2 = new McpServer(
|
|
37283
|
-
{ name: "terminal-commands", version: "0.2.
|
|
37283
|
+
{ name: "terminal-commands", version: "0.2.1" },
|
|
37284
37284
|
{
|
|
37285
37285
|
instructions: "This server controls the user's machine. Prefer dedicated file tools over commands. Every command and write can modify or expose local data and must receive user approval. Never request secrets or bypass configured roots and safety controls."
|
|
37286
37286
|
}
|
package/package.json
CHANGED