command-cmd 1.0.2 → 1.0.4
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 +1640 -16
- package/doc.md +199 -157
- package/docPTBR.md +204 -157
- package/map.md +238 -0
- package/mapPTBR.md +238 -0
- package/package.json +5 -2
package/doc.md
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
# command-cmd (English Documentation)
|
|
2
2
|
|
|
3
|
-
`command-cmd`
|
|
3
|
+
`command-cmd` parses AI text commands and runs cursor automation through `robotjs`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Exported functions:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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.
|
|
7
|
+
- `cmd`
|
|
8
|
+
- `extractFirstCommand`
|
|
9
|
+
- `cursor`
|
|
17
10
|
|
|
18
11
|
## Installation
|
|
19
12
|
|
|
@@ -21,223 +14,272 @@ It **does not execute commands**. It only parses text.
|
|
|
21
14
|
npm install command-cmd
|
|
22
15
|
```
|
|
23
16
|
|
|
24
|
-
##
|
|
17
|
+
## Import
|
|
25
18
|
|
|
26
19
|
```js
|
|
27
|
-
import { cmd, extractFirstCommand } from 'command-cmd';
|
|
20
|
+
import { cmd, extractFirstCommand, cursor } from 'command-cmd';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 1) `cmd(message)`
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
Run this sequence:
|
|
31
|
-
[type: shell, command: npm test, extra: run from project root, seq: 2]
|
|
32
|
-
`;
|
|
25
|
+
Extracts command blocks from text.
|
|
33
26
|
|
|
34
|
-
|
|
35
|
-
const firstCommand = extractFirstCommand(aiMessage);
|
|
27
|
+
Accepted format:
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
```txt
|
|
30
|
+
[type: open_app, command: tiktok, button: search_bar, seq: 1]
|
|
39
31
|
```
|
|
40
32
|
|
|
41
|
-
|
|
33
|
+
For sequential movement:
|
|
42
34
|
|
|
43
|
-
```
|
|
44
|
-
[
|
|
45
|
-
|
|
46
|
-
type: 'shell',
|
|
47
|
-
command: 'npm test',
|
|
48
|
-
extra: 'run from project root',
|
|
49
|
-
seq: 2
|
|
50
|
-
}
|
|
51
|
-
]
|
|
35
|
+
```txt
|
|
36
|
+
[move_sequence, points: 120x220|420x260|800x300, interval: 300, click: between, doubleClick: true]
|
|
37
|
+
```
|
|
52
38
|
|
|
39
|
+
Short format is also supported:
|
|
40
|
+
|
|
41
|
+
```txt
|
|
42
|
+
[open_app, command: tiktok, button: skip_ads]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Returned object:
|
|
46
|
+
|
|
47
|
+
```js
|
|
53
48
|
{
|
|
54
|
-
type: '
|
|
55
|
-
command: '
|
|
56
|
-
extra:
|
|
57
|
-
|
|
49
|
+
type: 'open_app',
|
|
50
|
+
command: 'tiktok',
|
|
51
|
+
extra: undefined,
|
|
52
|
+
button: 'skip_ads',
|
|
53
|
+
seq: 1
|
|
58
54
|
}
|
|
59
55
|
```
|
|
60
56
|
|
|
61
|
-
##
|
|
57
|
+
## 2) `extractFirstCommand(message)`
|
|
62
58
|
|
|
63
|
-
|
|
59
|
+
Returns only the first valid command.
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
Output:
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- If no valid command is found: returns `[]`.
|
|
63
|
+
```js
|
|
64
|
+
{ type, command, extra, button, points, path, interval, clickDelay, click, doubleClick, seq } | null
|
|
65
|
+
```
|
|
71
66
|
|
|
72
|
-
|
|
67
|
+
## 3) `cursor(input, options?)`
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
- `command` (or `comando`)
|
|
69
|
+
Runs mouse/keyboard actions.
|
|
76
70
|
|
|
77
|
-
`
|
|
71
|
+
`input` can be:
|
|
78
72
|
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
73
|
+
- string (internally parsed with `cmd`)
|
|
74
|
+
- one command object
|
|
75
|
+
- array of command objects
|
|
82
76
|
|
|
83
|
-
|
|
77
|
+
Accepted object keys:
|
|
84
78
|
|
|
85
|
-
|
|
79
|
+
- `type` or `tipo`
|
|
80
|
+
- `command` or `comando`
|
|
81
|
+
- `button` or `botao`
|
|
82
|
+
- `points` or `pontos` (coordinate sequence)
|
|
83
|
+
- `path` or `caminho` or `trajeto` (alias of `points`)
|
|
84
|
+
- `interval` or `intervalo` (ms between points)
|
|
85
|
+
- `clickDelay` or `delayClique` (ms between arriving and click)
|
|
86
|
+
- `click` or `clique` (`none`, `between`, `each`, `first`, `last`)
|
|
87
|
+
- `doubleClick` or `duplo` (true/false)
|
|
88
|
+
- `seq` or `sequencia`
|
|
89
|
+
- `extra`
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
- Output: `{ type, command, extra, seq } | null`
|
|
89
|
-
- If no valid command is found: returns `null`.
|
|
91
|
+
### App and button names (important)
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
You can name apps and buttons however you want.
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
The library uses the name only to resolve keys in `map.json`, with normalization:
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
- case-insensitive;
|
|
98
|
+
- spaces/hyphens converted to `_`;
|
|
99
|
+
- accents removed.
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
Examples that resolve to the same logical key:
|
|
100
102
|
|
|
101
|
-
- `
|
|
102
|
-
- `
|
|
103
|
-
- `
|
|
104
|
-
- `seq`
|
|
103
|
+
- `Skip ADS`
|
|
104
|
+
- `skip-ads`
|
|
105
|
+
- `skip_ads`
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
Same idea for app names:
|
|
107
108
|
|
|
108
|
-
|
|
109
|
+
- `Tik Tok`
|
|
110
|
+
- `tik-tok`
|
|
111
|
+
- `tik_tok`
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
Example:
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
const commands = [
|
|
117
|
+
{ type: 'open_app', command: 'youtube', button: 'search_bar', seq: 1 },
|
|
118
|
+
{ type: 'open_app', command: 'youtube', button: 'skip_ads', seq: 1 }
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
const runSummary = await cursor(commands);
|
|
122
|
+
console.log(runSummary);
|
|
113
123
|
```
|
|
114
124
|
|
|
115
|
-
##
|
|
125
|
+
## App state flow (open/closed)
|
|
116
126
|
|
|
117
|
-
|
|
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.
|
|
127
|
+
For app commands (`open_app`, `close_app`), the library uses `map.json`:
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
1. Reads app state (`open` or `closed` / `aberto` or `fechado`).
|
|
130
|
+
2. If already open, it does not open the app again.
|
|
131
|
+
3. Executes mapped button click.
|
|
132
|
+
4. If that button has `setState`, it updates app state in `map.json`.
|
|
127
133
|
|
|
128
|
-
###
|
|
134
|
+
### Automatic `map.json` creation
|
|
129
135
|
|
|
130
|
-
|
|
136
|
+
If `map.json` does not exist, the library creates it automatically in the project root (cwd) by default.
|
|
131
137
|
|
|
132
|
-
|
|
133
|
-
To list files:
|
|
134
|
-
[type: shell, command: ls -la, extra: linux or mac, seq: 1]
|
|
135
|
-
```
|
|
138
|
+
The generated file includes:
|
|
136
139
|
|
|
137
|
-
|
|
140
|
+
- `state` for each app;
|
|
141
|
+
- `buttons` for each app;
|
|
142
|
+
- a default `fechar/close` button for each app (`setState: "fechado"`).
|
|
138
143
|
|
|
139
|
-
|
|
140
|
-
[
|
|
141
|
-
{
|
|
142
|
-
type: 'shell',
|
|
143
|
-
command: 'ls -la',
|
|
144
|
-
extra: 'linux or mac',
|
|
145
|
-
seq: 1
|
|
146
|
-
}
|
|
147
|
-
]
|
|
148
|
-
```
|
|
144
|
+
This supports flows such as:
|
|
149
145
|
|
|
150
|
-
|
|
146
|
+
- "click TikTok search bar"
|
|
147
|
+
- "click YouTube skip ad button"
|
|
151
148
|
|
|
152
|
-
AI
|
|
149
|
+
AI output example:
|
|
153
150
|
|
|
154
151
|
```txt
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
Step 3: [type: shell, command: npm test, seq: 3]
|
|
152
|
+
[open_app, command: tiktok, button: search_bar]
|
|
153
|
+
[open_app, command: youtube, button: skip_ads]
|
|
158
154
|
```
|
|
159
155
|
|
|
160
|
-
|
|
156
|
+
## Supported `type` values
|
|
161
157
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
158
|
+
- `open_app` / `abrir_app`
|
|
159
|
+
- `close_app` / `fechar_app`
|
|
160
|
+
- `click` / `clicar`
|
|
161
|
+
- `double_click` / `clique_duplo`
|
|
162
|
+
- `scroll` / `rolar`
|
|
163
|
+
- `move_sequence` / `mover_sequencia`
|
|
164
|
+
- `skip_ads` / `pular_ads`
|
|
165
|
+
|
|
166
|
+
## Sequential movement (new)
|
|
169
167
|
|
|
170
|
-
|
|
168
|
+
Use `move_sequence` to move mouse through 2+ points in order.
|
|
171
169
|
|
|
172
|
-
|
|
170
|
+
### Coordinate format
|
|
171
|
+
|
|
172
|
+
Use `points` as:
|
|
173
173
|
|
|
174
174
|
```txt
|
|
175
|
-
|
|
175
|
+
100x200|300x260|640x420
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
`:` is also accepted:
|
|
179
179
|
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
{
|
|
183
|
-
type: 'shell',
|
|
184
|
-
command: 'npm test',
|
|
185
|
-
extra: undefined,
|
|
186
|
-
seq: undefined
|
|
187
|
-
}
|
|
188
|
-
]
|
|
180
|
+
```txt
|
|
181
|
+
100:200|300:260|640:420
|
|
189
182
|
```
|
|
190
183
|
|
|
191
|
-
|
|
184
|
+
### Click behavior between points
|
|
192
185
|
|
|
193
|
-
|
|
186
|
+
`click` field:
|
|
194
187
|
|
|
195
|
-
|
|
188
|
+
- `none`: no click
|
|
189
|
+
- `between`: click every point except the last
|
|
190
|
+
- `each`: click every point
|
|
191
|
+
- `first`: click only the first point
|
|
192
|
+
- `last`: click only the last point
|
|
196
193
|
|
|
197
|
-
|
|
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>]
|
|
194
|
+
`doubleClick` field:
|
|
201
195
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
196
|
+
- `true`: use double click when click is triggered
|
|
197
|
+
- `false`: single click
|
|
198
|
+
|
|
199
|
+
`clickDelay` field:
|
|
200
|
+
|
|
201
|
+
- delay (ms) between arriving at a point and clicking that point
|
|
202
|
+
|
|
203
|
+
### AI text example
|
|
204
|
+
|
|
205
|
+
```txt
|
|
206
|
+
[move_sequence, points: 140x260|520x280|980x300, interval: 250, click: between, doubleClick: true]
|
|
208
207
|
```
|
|
209
208
|
|
|
210
|
-
|
|
209
|
+
With `clickDelay`:
|
|
211
210
|
|
|
212
211
|
```txt
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
[move_sequence, path: 140x260|520x280|980x300, interval: 250, clickDelay: 120, click: between, doubleClick: true]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### JS object example (recommended for devs)
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
217
|
+
```js
|
|
218
|
+
await cursor({
|
|
219
|
+
type: 'move_sequence',
|
|
220
|
+
points: [
|
|
221
|
+
{ x: 140, y: 260 },
|
|
222
|
+
{ x: 520, y: 280 },
|
|
223
|
+
{ x: 980, y: 300 }
|
|
224
|
+
],
|
|
225
|
+
interval: 250,
|
|
226
|
+
clickDelay: 120,
|
|
227
|
+
click: 'between',
|
|
228
|
+
doubleClick: true
|
|
229
|
+
});
|
|
219
230
|
```
|
|
220
231
|
|
|
221
|
-
|
|
232
|
+
## `cursor` options
|
|
222
233
|
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
234
|
+
```js
|
|
235
|
+
{
|
|
236
|
+
mapPath: 'map.json',
|
|
237
|
+
createMapIfMissing: true,
|
|
238
|
+
persistMap: true,
|
|
239
|
+
launchKey: 'command', // set false to disable launcher key tap
|
|
240
|
+
moveSteps: 50,
|
|
241
|
+
moveDelay: 8,
|
|
242
|
+
scrollSteps: 10,
|
|
243
|
+
scrollDelay: 20,
|
|
244
|
+
typeDelay: 50,
|
|
245
|
+
sequenceInterval: 250,
|
|
246
|
+
sequenceClick: 'none',
|
|
247
|
+
sequenceDoubleClick: false,
|
|
248
|
+
defaultClosePoint: { x: 1888, y: 16 }
|
|
249
|
+
}
|
|
227
250
|
```
|
|
228
251
|
|
|
229
|
-
##
|
|
252
|
+
## Dedicated mapper docs
|
|
253
|
+
|
|
254
|
+
Dedicated docs for creating and calibrating `map.json`:
|
|
230
255
|
|
|
231
|
-
-
|
|
232
|
-
-
|
|
233
|
-
- Only one `extra` field is returned per block.
|
|
256
|
+
- `mapPTBR.md` (PT-BR)
|
|
257
|
+
- `map.md` (English)
|
|
234
258
|
|
|
235
|
-
|
|
259
|
+
They explain:
|
|
236
260
|
|
|
237
|
-
|
|
261
|
+
- app mapping and coordinates;
|
|
262
|
+
- per-app button mapping;
|
|
263
|
+
- state management with `setState`.
|
|
264
|
+
|
|
265
|
+
## Recommended system prompt (AI -> command)
|
|
266
|
+
|
|
267
|
+
```txt
|
|
268
|
+
You are a technical assistant.
|
|
269
|
+
When you suggest executable actions, output only blocks:
|
|
270
|
+
[type: <type>, command: <app_or_value>, points: <optional_points>, button: <optional_button>, interval: <optional_ms>, clickDelay: <optional_ms_before_click>, click: <optional_mode>, doubleClick: <optional_boolean>, extra: <optional_text>, seq: <optional_integer>]
|
|
271
|
+
|
|
272
|
+
Rules:
|
|
273
|
+
1. Always use square brackets.
|
|
274
|
+
2. One command per block.
|
|
275
|
+
3. seq must be an integer >= 0.
|
|
276
|
+
4. For app interaction, use type open_app and command with app name.
|
|
277
|
+
5. For UI clicks, fill button using a key that exists in map.json.
|
|
278
|
+
6. For sequential movement, use type move_sequence and points in `xXy|xXy|xXy` format.
|
|
279
|
+
```
|
|
238
280
|
|
|
239
|
-
|
|
281
|
+
## Important notes
|
|
240
282
|
|
|
241
|
-
-
|
|
242
|
-
-
|
|
243
|
-
-
|
|
283
|
+
- `cursor` requires a desktop environment where `robotjs` works.
|
|
284
|
+
- If `map.json` does not exist and `createMapIfMissing` is `false`, app commands fail.
|
|
285
|
+
- Avoid commas inside `[ ... ]` values because parser splitting uses commas.
|