command-cmd 1.0.0 → 1.0.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.
- package/cmd.js +11 -2
- package/doc.md +243 -0
- package/docPTBR.md +243 -0
- package/package.json +2 -1
package/cmd.js
CHANGED
|
@@ -11,7 +11,12 @@ export function cmd(message) {
|
|
|
11
11
|
const inside = match[1].trim();
|
|
12
12
|
if (!inside) continue;
|
|
13
13
|
|
|
14
|
-
const obj = {
|
|
14
|
+
const obj = {
|
|
15
|
+
type: undefined,
|
|
16
|
+
command: undefined,
|
|
17
|
+
extra: undefined,
|
|
18
|
+
seq: undefined
|
|
19
|
+
};
|
|
15
20
|
|
|
16
21
|
const parts = inside.split(',');
|
|
17
22
|
|
|
@@ -32,6 +37,11 @@ export function cmd(message) {
|
|
|
32
37
|
obj.command = value;
|
|
33
38
|
} else if (key === 'extra') {
|
|
34
39
|
obj.extra = value;
|
|
40
|
+
} else if (key === 'seq') {
|
|
41
|
+
const seq = Number(value);
|
|
42
|
+
if (Number.isInteger(seq) && seq >= 0) {
|
|
43
|
+
obj.seq = seq;
|
|
44
|
+
}
|
|
35
45
|
} else if (!obj.type) {
|
|
36
46
|
obj.type = rawKey.trim();
|
|
37
47
|
obj.command = value;
|
|
@@ -54,4 +64,3 @@ export function extractFirstCommand(message) {
|
|
|
54
64
|
const [first] = cmd(message);
|
|
55
65
|
return first || null;
|
|
56
66
|
}
|
|
57
|
-
|
package/doc.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# command-cmd (English Documentation)
|
|
2
|
+
|
|
3
|
+
`command-cmd` is a lightweight parser for detecting and extracting structured commands from free-form text, especially AI output.
|
|
4
|
+
|
|
5
|
+
It is useful when a model returns natural language plus command blocks and you need clean structured data for automation.
|
|
6
|
+
|
|
7
|
+
## What it is for
|
|
8
|
+
|
|
9
|
+
Use this library to:
|
|
10
|
+
|
|
11
|
+
- Extract commands embedded in AI responses.
|
|
12
|
+
- Capture multiple commands from a single message.
|
|
13
|
+
- Normalize output into a standard object: `type`, `command`, `extra`, and `seq`.
|
|
14
|
+
- Accept both English and Portuguese keys (`type/tipo`, `command/comando`).
|
|
15
|
+
|
|
16
|
+
It **does not execute commands**. It only parses text.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install command-cmd
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import { cmd, extractFirstCommand } from 'command-cmd';
|
|
28
|
+
|
|
29
|
+
const aiMessage = `
|
|
30
|
+
Run this sequence:
|
|
31
|
+
[type: shell, command: npm test, extra: run from project root, seq: 2]
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const commandList = cmd(aiMessage);
|
|
35
|
+
const firstCommand = extractFirstCommand(aiMessage);
|
|
36
|
+
|
|
37
|
+
console.log(commandList);
|
|
38
|
+
console.log(firstCommand);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Expected output:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
type: 'shell',
|
|
47
|
+
command: 'npm test',
|
|
48
|
+
extra: 'run from project root',
|
|
49
|
+
seq: 2
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
type: 'shell',
|
|
55
|
+
command: 'npm test',
|
|
56
|
+
extra: 'run from project root',
|
|
57
|
+
seq: 2
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Full API
|
|
62
|
+
|
|
63
|
+
### `cmd(message)`
|
|
64
|
+
|
|
65
|
+
Extracts **all** valid commands from a string.
|
|
66
|
+
|
|
67
|
+
- Input: `message` (string).
|
|
68
|
+
- Output: `Array<{ type: string, command: string, extra?: string, seq?: number }>`
|
|
69
|
+
- If `message` is not a string: returns `[]`.
|
|
70
|
+
- If no valid command is found: returns `[]`.
|
|
71
|
+
|
|
72
|
+
A block is returned only when it contains:
|
|
73
|
+
|
|
74
|
+
- `type` (or `tipo`)
|
|
75
|
+
- `command` (or `comando`)
|
|
76
|
+
|
|
77
|
+
`seq` rules:
|
|
78
|
+
|
|
79
|
+
- Optional field.
|
|
80
|
+
- Accepts only integer values greater than or equal to zero.
|
|
81
|
+
- If invalid (for example `seq: many`), it remains `undefined`.
|
|
82
|
+
|
|
83
|
+
### `extractFirstCommand(message)`
|
|
84
|
+
|
|
85
|
+
Returns only the first valid command.
|
|
86
|
+
|
|
87
|
+
- Input: `message` (string).
|
|
88
|
+
- Output: `{ type, command, extra, seq } | null`
|
|
89
|
+
- If no valid command is found: returns `null`.
|
|
90
|
+
|
|
91
|
+
## Expected command format
|
|
92
|
+
|
|
93
|
+
Each command must be inside square brackets:
|
|
94
|
+
|
|
95
|
+
```txt
|
|
96
|
+
[type: value, command: value, extra: value, seq: 3]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Recognized keys:
|
|
100
|
+
|
|
101
|
+
- `type` or `tipo`
|
|
102
|
+
- `command` or `comando`
|
|
103
|
+
- `extra`
|
|
104
|
+
- `seq`
|
|
105
|
+
|
|
106
|
+
Key matching is case-insensitive.
|
|
107
|
+
|
|
108
|
+
Valid examples:
|
|
109
|
+
|
|
110
|
+
```txt
|
|
111
|
+
[TYPE: shell, COMMAND: ls -la, SEQ: 1]
|
|
112
|
+
[tipo: shell, comando: pwd, seq: 2]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Parsing rules
|
|
116
|
+
|
|
117
|
+
- The parser searches for `[ ... ]` blocks.
|
|
118
|
+
- Internal content is split by commas.
|
|
119
|
+
- Each segment needs `:` to become `key: value`.
|
|
120
|
+
- Blocks without `type/tipo` or `command/comando` are ignored.
|
|
121
|
+
- `seq` is applied only when it is a non-negative integer.
|
|
122
|
+
- Unknown keys use fallback behavior:
|
|
123
|
+
- The first unknown key may become `type`, and its value becomes `command`.
|
|
124
|
+
- Later unknown keys may fill `extra` if it is still empty.
|
|
125
|
+
|
|
126
|
+
## Real AI response examples
|
|
127
|
+
|
|
128
|
+
### Example 1: single command
|
|
129
|
+
|
|
130
|
+
AI text:
|
|
131
|
+
|
|
132
|
+
```txt
|
|
133
|
+
To list files:
|
|
134
|
+
[type: shell, command: ls -la, extra: linux or mac, seq: 1]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Result:
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
[
|
|
141
|
+
{
|
|
142
|
+
type: 'shell',
|
|
143
|
+
command: 'ls -la',
|
|
144
|
+
extra: 'linux or mac',
|
|
145
|
+
seq: 1
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Example 2: multiple commands
|
|
151
|
+
|
|
152
|
+
AI text:
|
|
153
|
+
|
|
154
|
+
```txt
|
|
155
|
+
Step 1: [type: shell, command: npm install, seq: 1]
|
|
156
|
+
Step 2: [type: shell, command: npm run dev, extra: default port 3000, seq: 1]
|
|
157
|
+
Step 3: [type: shell, command: npm test, seq: 3]
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Result:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
[
|
|
164
|
+
{ type: 'shell', command: 'npm install', extra: undefined, seq: 1 },
|
|
165
|
+
{ type: 'shell', command: 'npm run dev', extra: 'default port 3000', seq: 1 },
|
|
166
|
+
{ type: 'shell', command: 'npm test', extra: undefined, seq: 3 }
|
|
167
|
+
]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Example 3: invalid `seq`
|
|
171
|
+
|
|
172
|
+
AI text:
|
|
173
|
+
|
|
174
|
+
```txt
|
|
175
|
+
[type: shell, command: npm test, seq: three]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Result:
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
[
|
|
182
|
+
{
|
|
183
|
+
type: 'shell',
|
|
184
|
+
command: 'npm test',
|
|
185
|
+
extra: undefined,
|
|
186
|
+
seq: undefined
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## How to build the AI system prompt
|
|
192
|
+
|
|
193
|
+
Extraction quality depends on stable formatting. The best approach is to force the model to emit valid command blocks.
|
|
194
|
+
|
|
195
|
+
### Template 1: strict mode (blocks only)
|
|
196
|
+
|
|
197
|
+
```txt
|
|
198
|
+
You are a technical assistant.
|
|
199
|
+
Whenever you suggest an executable action, output blocks in this format:
|
|
200
|
+
[type: <category>, command: <command>, extra: <optional context>, seq: <optional integer>]
|
|
201
|
+
|
|
202
|
+
Mandatory rules:
|
|
203
|
+
1. Always use square brackets.
|
|
204
|
+
2. Always use keys exactly as: type, command, extra, seq.
|
|
205
|
+
3. seq must be an integer >= 0.
|
|
206
|
+
4. Do not use commas inside values.
|
|
207
|
+
5. One command per block.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Template 2: explanation + blocks
|
|
211
|
+
|
|
212
|
+
```txt
|
|
213
|
+
You can explain in natural language.
|
|
214
|
+
Whenever a command is needed, include one block per command using:
|
|
215
|
+
[type: <category>, command: <command>, extra: <optional context>, seq: <optional integer>]
|
|
216
|
+
|
|
217
|
+
If no command is needed, do not create a block.
|
|
218
|
+
If a command must be repeated, set seq accordingly.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Example of expected AI answer
|
|
222
|
+
|
|
223
|
+
```txt
|
|
224
|
+
To prepare the environment:
|
|
225
|
+
[type: shell, command: npm install, extra: install dependencies, seq: 1]
|
|
226
|
+
[type: shell, command: npm test, extra: repeat for stability check, seq: 3]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Current limitations
|
|
230
|
+
|
|
231
|
+
- Values containing commas may break parsing because splitting uses `,`.
|
|
232
|
+
- Values containing `[` or `]` may interfere with block matching.
|
|
233
|
+
- Only one `extra` field is returned per block.
|
|
234
|
+
|
|
235
|
+
## Security
|
|
236
|
+
|
|
237
|
+
This library does not execute commands.
|
|
238
|
+
|
|
239
|
+
If you execute parsed output:
|
|
240
|
+
|
|
241
|
+
- Use an allowlist of allowed commands.
|
|
242
|
+
- Block dangerous patterns.
|
|
243
|
+
- Require confirmation for destructive operations.
|
package/docPTBR.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# command-cmd (Documentacao PT-BR)
|
|
2
|
+
|
|
3
|
+
`command-cmd` e uma biblioteca para detectar e extrair comandos estruturados de texto livre, com foco em respostas de IA.
|
|
4
|
+
|
|
5
|
+
Ela e util quando o modelo retorna linguagem natural junto com blocos de comando e voce precisa transformar isso em dados para automacao.
|
|
6
|
+
|
|
7
|
+
## Para que serve
|
|
8
|
+
|
|
9
|
+
Use esta biblioteca para:
|
|
10
|
+
|
|
11
|
+
- Extrair comandos embutidos em respostas de IA.
|
|
12
|
+
- Capturar varios comandos na mesma mensagem.
|
|
13
|
+
- Normalizar saida em um objeto padrao com `type`, `command`, `extra` e `seq`.
|
|
14
|
+
- Interpretar entradas com chaves em ingles e portugues (`type/tipo`, `command/comando`).
|
|
15
|
+
|
|
16
|
+
Ela **nao executa comandos**. Ela apenas faz parsing.
|
|
17
|
+
|
|
18
|
+
## Instalacao
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install command-cmd
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Uso rapido
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import { cmd, extractFirstCommand } from 'command-cmd';
|
|
28
|
+
|
|
29
|
+
const textoDaIA = `
|
|
30
|
+
Vamos executar em duas etapas:
|
|
31
|
+
[tipo: shell, comando: npm test, extra: executar na raiz do projeto, seq: 2]
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const listaDeComandos = cmd(textoDaIA);
|
|
35
|
+
const primeiroComando = extractFirstCommand(textoDaIA);
|
|
36
|
+
|
|
37
|
+
console.log(listaDeComandos);
|
|
38
|
+
console.log(primeiroComando);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Saida esperada:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
[
|
|
45
|
+
{
|
|
46
|
+
type: 'shell',
|
|
47
|
+
command: 'npm test',
|
|
48
|
+
extra: 'executar na raiz do projeto',
|
|
49
|
+
seq: 2
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
type: 'shell',
|
|
55
|
+
command: 'npm test',
|
|
56
|
+
extra: 'executar na raiz do projeto',
|
|
57
|
+
seq: 2
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## API completa
|
|
62
|
+
|
|
63
|
+
### `cmd(message)`
|
|
64
|
+
|
|
65
|
+
Extrai **todos** os comandos validos de uma string.
|
|
66
|
+
|
|
67
|
+
- Entrada: `message` (string).
|
|
68
|
+
- Saida: `Array<{ type: string, command: string, extra?: string, seq?: number }>`
|
|
69
|
+
- Se `message` nao for string: retorna `[]`.
|
|
70
|
+
- Se nenhum comando valido for encontrado: retorna `[]`.
|
|
71
|
+
|
|
72
|
+
Um comando so entra no resultado quando tem:
|
|
73
|
+
|
|
74
|
+
- `type` (ou `tipo`)
|
|
75
|
+
- `command` (ou `comando`)
|
|
76
|
+
|
|
77
|
+
Regras do campo `seq`:
|
|
78
|
+
|
|
79
|
+
- E opcional.
|
|
80
|
+
- Aceita apenas numero inteiro maior ou igual a zero.
|
|
81
|
+
- Se o valor for invalido (ex.: `seq: duas_vezes`), o campo fica `undefined`.
|
|
82
|
+
|
|
83
|
+
### `extractFirstCommand(message)`
|
|
84
|
+
|
|
85
|
+
Retorna apenas o primeiro comando valido.
|
|
86
|
+
|
|
87
|
+
- Entrada: `message` (string).
|
|
88
|
+
- Saida: `{ type, command, extra, seq } | null`
|
|
89
|
+
- Se nao houver comando valido: retorna `null`.
|
|
90
|
+
|
|
91
|
+
## Formato esperado dos comandos
|
|
92
|
+
|
|
93
|
+
Cada comando deve estar entre colchetes:
|
|
94
|
+
|
|
95
|
+
```txt
|
|
96
|
+
[tipo: valor, comando: valor, extra: valor, seq: 3]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Chaves reconhecidas:
|
|
100
|
+
|
|
101
|
+
- `type` ou `tipo`
|
|
102
|
+
- `command` ou `comando`
|
|
103
|
+
- `extra`
|
|
104
|
+
- `seq`
|
|
105
|
+
|
|
106
|
+
A comparacao das chaves e case-insensitive.
|
|
107
|
+
|
|
108
|
+
Exemplos validos:
|
|
109
|
+
|
|
110
|
+
```txt
|
|
111
|
+
[TYPE: shell, COMMAND: ls -la, SEQ: 1]
|
|
112
|
+
[tipo: shell, comando: pwd, seq: 2]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Regras de parsing
|
|
116
|
+
|
|
117
|
+
- A biblioteca procura trechos no formato `[ ... ]`.
|
|
118
|
+
- O conteudo interno e dividido por virgula.
|
|
119
|
+
- Cada parte precisa ter `:` para virar `chave: valor`.
|
|
120
|
+
- Bloco sem `type/tipo` ou `command/comando` e ignorado.
|
|
121
|
+
- `seq` so e aplicado quando for numero inteiro nao negativo.
|
|
122
|
+
- Chaves desconhecidas usam fallback:
|
|
123
|
+
- A primeira chave desconhecida pode virar `type`, e o valor vira `command`.
|
|
124
|
+
- Chaves desconhecidas seguintes podem preencher `extra`, se ainda estiver vazio.
|
|
125
|
+
|
|
126
|
+
## Exemplos com respostas de IA
|
|
127
|
+
|
|
128
|
+
### Exemplo 1: comando unico
|
|
129
|
+
|
|
130
|
+
Texto da IA:
|
|
131
|
+
|
|
132
|
+
```txt
|
|
133
|
+
Para listar arquivos:
|
|
134
|
+
[tipo: shell, comando: ls -la, extra: linux ou mac, seq: 1]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Resultado:
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
[
|
|
141
|
+
{
|
|
142
|
+
type: 'shell',
|
|
143
|
+
command: 'ls -la',
|
|
144
|
+
extra: 'linux ou mac',
|
|
145
|
+
seq: 1
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Exemplo 2: varios comandos
|
|
151
|
+
|
|
152
|
+
Texto da IA:
|
|
153
|
+
|
|
154
|
+
```txt
|
|
155
|
+
Passo 1: [tipo: shell, comando: npm install, seq: 1]
|
|
156
|
+
Passo 2: [tipo: shell, comando: npm run dev, extra: porta padrao 3000, seq: 1]
|
|
157
|
+
Passo 3: [tipo: shell, comando: npm test, seq: 3]
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Resultado:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
[
|
|
164
|
+
{ type: 'shell', command: 'npm install', extra: undefined, seq: 1 },
|
|
165
|
+
{ type: 'shell', command: 'npm run dev', extra: 'porta padrao 3000', seq: 1 },
|
|
166
|
+
{ type: 'shell', command: 'npm test', extra: undefined, seq: 3 }
|
|
167
|
+
]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Exemplo 3: `seq` invalido
|
|
171
|
+
|
|
172
|
+
Texto da IA:
|
|
173
|
+
|
|
174
|
+
```txt
|
|
175
|
+
[tipo: shell, comando: npm test, seq: tres]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Resultado:
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
[
|
|
182
|
+
{
|
|
183
|
+
type: 'shell',
|
|
184
|
+
command: 'npm test',
|
|
185
|
+
extra: undefined,
|
|
186
|
+
seq: undefined
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Como construir o system prompt da IA
|
|
192
|
+
|
|
193
|
+
A qualidade da extracao depende de um formato estavel. O ideal e forcar o modelo a sempre emitir blocos validos.
|
|
194
|
+
|
|
195
|
+
### Modelo 1: estrito (somente blocos)
|
|
196
|
+
|
|
197
|
+
```txt
|
|
198
|
+
Voce e um assistente tecnico.
|
|
199
|
+
Sempre que sugerir uma acao executavel, responda usando blocos no formato:
|
|
200
|
+
[tipo: <categoria>, comando: <comando>, extra: <contexto opcional>, seq: <inteiro opcional>]
|
|
201
|
+
|
|
202
|
+
Regras obrigatorias:
|
|
203
|
+
1. Use sempre colchetes.
|
|
204
|
+
2. Use as chaves exatamente como: tipo, comando, extra, seq.
|
|
205
|
+
3. seq deve ser inteiro >= 0.
|
|
206
|
+
4. Nao use virgula dentro dos valores.
|
|
207
|
+
5. Um comando por bloco.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Modelo 2: explicacao + blocos
|
|
211
|
+
|
|
212
|
+
```txt
|
|
213
|
+
Voce pode explicar em linguagem natural.
|
|
214
|
+
Quando houver comando, inclua um bloco por comando no formato:
|
|
215
|
+
[tipo: <categoria>, comando: <comando>, extra: <contexto opcional>, seq: <inteiro opcional>]
|
|
216
|
+
|
|
217
|
+
Se nao houver comando, nao invente bloco.
|
|
218
|
+
Se houver repeticao, informe em seq.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Exemplo de resposta esperada da IA
|
|
222
|
+
|
|
223
|
+
```txt
|
|
224
|
+
Para preparar o ambiente, siga:
|
|
225
|
+
[tipo: shell, comando: npm install, extra: instalar dependencias, seq: 1]
|
|
226
|
+
[tipo: shell, comando: npm test, extra: repetir para validar estabilidade, seq: 3]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Limitacoes atuais
|
|
230
|
+
|
|
231
|
+
- Valores com virgula podem quebrar o parsing porque a divisao interna usa `,`.
|
|
232
|
+
- Colchetes dentro do valor (`[` ou `]`) podem interferir na captura.
|
|
233
|
+
- Apenas um campo `extra` e retornado por bloco.
|
|
234
|
+
|
|
235
|
+
## Seguranca
|
|
236
|
+
|
|
237
|
+
Esta biblioteca nao executa comandos.
|
|
238
|
+
|
|
239
|
+
Se voce for executar o resultado extraido:
|
|
240
|
+
|
|
241
|
+
- Use allowlist de comandos permitidos.
|
|
242
|
+
- Bloqueie padroes perigosos.
|
|
243
|
+
- Exija confirmacao para operacoes destrutivas.
|