@thenajs/tools 0.6.0 → 0.9.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/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/shell.tool.d.ts +51 -2
- package/dist/shell.tool.d.ts.map +1 -1
- package/dist/shell.tool.js +92 -4
- package/dist/shell.tool.js.map +1 -1
- package/package.json +10 -2
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ShellTool } from "./shell.tool.js";
|
|
1
|
+
export { ShellTool, shellTool } from "./shell.tool.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/shell.tool.d.ts
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
|
+
import type { ToolType } from "@thenajs/core";
|
|
2
|
+
export interface ShellToolOptions {
|
|
3
|
+
/** Teto de tempo do comando, em ms. Default: 30s. */
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
/** Diretório de trabalho. Default: o do processo. */
|
|
6
|
+
cwd?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Só executa comandos cujo **primeiro token** esteja nesta lista.
|
|
9
|
+
*
|
|
10
|
+
* É a única proteção real contra prompt injection nesta tool. Sem allowlist,
|
|
11
|
+
* qualquer coisa que o modelo escrever é executada com as permissões do
|
|
12
|
+
* processo.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* shellTool({ allow: ["ls", "cat", "grep", "git"] })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
allow?: string[];
|
|
19
|
+
/** Teto de caracteres devolvidos ao modelo. Default: 8000. */
|
|
20
|
+
maxChars?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Executa um comando shell.
|
|
24
|
+
*
|
|
25
|
+
* ## ⚠️ Leia antes de usar
|
|
26
|
+
*
|
|
27
|
+
* Esta tool dá ao modelo **execução arbitrária de comando** com as permissões
|
|
28
|
+
* do seu processo. Um agente que leia conteúdo de terceiro — um README, uma
|
|
29
|
+
* issue, um arquivo do repositório — pode ser induzido a executar o que
|
|
30
|
+
* estiver escrito lá. O framework não tem defesa contra prompt injection.
|
|
31
|
+
*
|
|
32
|
+
* Use `allow` sempre que o agente puder ver entrada não confiável:
|
|
33
|
+
*
|
|
34
|
+
* ```ts
|
|
35
|
+
* @Agent({ provider, prompt: "./a.agent.md", tools: [shellTool({ allow: ["git", "ls"] })] })
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Sem `allow`, restrinja o uso a ambiente controlado — sua máquina, um
|
|
39
|
+
* container descartável — e nunca a um serviço exposto.
|
|
40
|
+
*/
|
|
41
|
+
export declare function shellTool(options?: ShellToolOptions): ToolType;
|
|
42
|
+
/**
|
|
43
|
+
* Versão sem configuração, para uso rápido em ambiente controlado.
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ **Sem allowlist** — o modelo executa qualquer comando. Leia o aviso de
|
|
46
|
+
* `shellTool` antes de usar; para agente que vê entrada não confiável, prefira
|
|
47
|
+
* `shellTool({ allow: [...] })`.
|
|
48
|
+
*/
|
|
1
49
|
export declare class ShellTool {
|
|
2
|
-
|
|
50
|
+
private readonly impl;
|
|
51
|
+
execute(args: {
|
|
3
52
|
command: string;
|
|
4
|
-
}): Promise<string>;
|
|
53
|
+
}): Promise<string | import("@thenajs/core").ToolOutput>;
|
|
5
54
|
}
|
|
6
55
|
//# sourceMappingURL=shell.tool.d.ts.map
|
package/dist/shell.tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.tool.d.ts","sourceRoot":"","sources":["../src/shell.tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shell.tool.d.ts","sourceRoot":"","sources":["../src/shell.tool.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAa9C,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,QAAQ,CA4DlE;AAED;;;;;;GAMG;AACH,qBAKa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IAEpC,OAAO,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE;CAGlC"}
|
package/dist/shell.tool.js
CHANGED
|
@@ -9,17 +9,105 @@ import { promisify } from "node:util";
|
|
|
9
9
|
import { Tool } from "@thenajs/core";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
const run = promisify(exec);
|
|
12
|
+
const schema = z.object({ command: z.string() });
|
|
13
|
+
/** Teto de tempo padrão. Sem ele, um comando pendurado trava a run para sempre. */
|
|
14
|
+
const DEFAULT_TIMEOUT = 30_000;
|
|
15
|
+
/** Teto de saída devolvida ao modelo, para não entupir a janela de contexto. */
|
|
16
|
+
const MAX_CHARS = 8_000;
|
|
17
|
+
/**
|
|
18
|
+
* Executa um comando shell.
|
|
19
|
+
*
|
|
20
|
+
* ## ⚠️ Leia antes de usar
|
|
21
|
+
*
|
|
22
|
+
* Esta tool dá ao modelo **execução arbitrária de comando** com as permissões
|
|
23
|
+
* do seu processo. Um agente que leia conteúdo de terceiro — um README, uma
|
|
24
|
+
* issue, um arquivo do repositório — pode ser induzido a executar o que
|
|
25
|
+
* estiver escrito lá. O framework não tem defesa contra prompt injection.
|
|
26
|
+
*
|
|
27
|
+
* Use `allow` sempre que o agente puder ver entrada não confiável:
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* @Agent({ provider, prompt: "./a.agent.md", tools: [shellTool({ allow: ["git", "ls"] })] })
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Sem `allow`, restrinja o uso a ambiente controlado — sua máquina, um
|
|
34
|
+
* container descartável — e nunca a um serviço exposto.
|
|
35
|
+
*/
|
|
36
|
+
export function shellTool(options = {}) {
|
|
37
|
+
const timeout = options.timeoutMs ?? DEFAULT_TIMEOUT;
|
|
38
|
+
const maxChars = options.maxChars ?? MAX_CHARS;
|
|
39
|
+
const allow = options.allow?.map((c) => c.trim()).filter(Boolean);
|
|
40
|
+
return {
|
|
41
|
+
name: "shell",
|
|
42
|
+
description: allow
|
|
43
|
+
? `Executa um comando shell. Permitidos: ${allow.join(", ")}.`
|
|
44
|
+
: "Executa um comando shell e retorna a saída.",
|
|
45
|
+
schema,
|
|
46
|
+
async execute({ command }) {
|
|
47
|
+
if (allow) {
|
|
48
|
+
// O primeiro token decide. Não tenta interpretar a linha inteira: um
|
|
49
|
+
// parser de shell parcial dá falsa sensação de segurança, e `;`, `&&`,
|
|
50
|
+
// `$(…)` e pipes contornariam qualquer coisa mais esperta que isto.
|
|
51
|
+
const programa = command.trim().split(/\s+/)[0] ?? "";
|
|
52
|
+
if (!allow.includes(programa)) {
|
|
53
|
+
return {
|
|
54
|
+
content: `Comando "${programa}" não permitido. ` +
|
|
55
|
+
`Disponíveis: ${allow.join(", ")}.`,
|
|
56
|
+
isError: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (/[;&|`$><]/.test(command)) {
|
|
60
|
+
// Com allowlist ligada, encadeamento anularia a lista.
|
|
61
|
+
return {
|
|
62
|
+
content: "Encadeamento e redirecionamento não são permitidos " +
|
|
63
|
+
"(`;`, `&&`, `|`, `$(…)`, `>`). Rode um comando por vez.",
|
|
64
|
+
isError: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const { stdout, stderr } = await run(command, {
|
|
70
|
+
timeout,
|
|
71
|
+
cwd: options.cwd,
|
|
72
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
73
|
+
});
|
|
74
|
+
const saida = stdout || stderr || "(sem saída)";
|
|
75
|
+
return saida.length > maxChars
|
|
76
|
+
? `${saida.slice(0, maxChars)}\n… [truncado]`
|
|
77
|
+
: saida;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const e = err;
|
|
81
|
+
if (e.killed) {
|
|
82
|
+
return {
|
|
83
|
+
content: `O comando excedeu ${timeout}ms e foi encerrado.`,
|
|
84
|
+
isError: true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Erro vira observação: o modelo lê e tenta outra coisa.
|
|
88
|
+
return { content: e.stderr || e.message, isError: true };
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Versão sem configuração, para uso rápido em ambiente controlado.
|
|
95
|
+
*
|
|
96
|
+
* ⚠️ **Sem allowlist** — o modelo executa qualquer comando. Leia o aviso de
|
|
97
|
+
* `shellTool` antes de usar; para agente que vê entrada não confiável, prefira
|
|
98
|
+
* `shellTool({ allow: [...] })`.
|
|
99
|
+
*/
|
|
12
100
|
let ShellTool = class ShellTool {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return
|
|
101
|
+
impl = shellTool();
|
|
102
|
+
execute(args) {
|
|
103
|
+
return this.impl.execute(args);
|
|
16
104
|
}
|
|
17
105
|
};
|
|
18
106
|
ShellTool = __decorate([
|
|
19
107
|
Tool({
|
|
20
108
|
name: "shell",
|
|
21
109
|
description: "Executa um comando shell e retorna a saída.",
|
|
22
|
-
schema
|
|
110
|
+
schema,
|
|
23
111
|
})
|
|
24
112
|
], ShellTool);
|
|
25
113
|
export { ShellTool };
|
package/dist/shell.tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.tool.js","sourceRoot":"","sources":["../src/shell.tool.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"shell.tool.js","sourceRoot":"","sources":["../src/shell.tool.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thenajs/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Tools prontas para agentes ThenaJS (ex.: ShellTool).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "castroneto",
|
|
@@ -22,8 +22,16 @@
|
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20.19"
|
|
27
|
+
},
|
|
25
28
|
"dependencies": {
|
|
26
|
-
"@thenajs/core": "^0.
|
|
29
|
+
"@thenajs/core": "^0.9.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"zod": "^4.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
27
35
|
"zod": "^4.0.0"
|
|
28
36
|
}
|
|
29
37
|
}
|