command-cmd 1.0.4 → 1.0.6
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 +626 -22
- package/doc.md +118 -4
- package/docPTBR.md +121 -4
- package/map.md +6 -0
- package/mapPTBR.md +6 -0
- package/package.json +1 -1
package/cmd.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
3
4
|
|
|
4
|
-
const { readFile, writeFile } = fs.promises;
|
|
5
|
-
const { resolve: resolvePath } = path;
|
|
5
|
+
const { readFile, writeFile, mkdir } = fs.promises;
|
|
6
|
+
const { resolve: resolvePath, dirname: dirnamePath } = path;
|
|
7
|
+
|
|
8
|
+
const MODULE_DIR = dirnamePath(fileURLToPath(import.meta.url));
|
|
6
9
|
|
|
7
10
|
const DEFAULT_APPS = Object.freeze({
|
|
8
11
|
spotify: {
|
|
@@ -19,6 +22,35 @@ const DEFAULT_APPS = Object.freeze({
|
|
|
19
22
|
}
|
|
20
23
|
});
|
|
21
24
|
|
|
25
|
+
const DOC_TEMPLATE_MAP = Object.freeze({
|
|
26
|
+
doc_en: Object.freeze({
|
|
27
|
+
key: 'doc_en',
|
|
28
|
+
source: 'doc.md',
|
|
29
|
+
target: 'doc.md',
|
|
30
|
+
isMapDoc: false
|
|
31
|
+
}),
|
|
32
|
+
doc_ptbr: Object.freeze({
|
|
33
|
+
key: 'doc_ptbr',
|
|
34
|
+
source: 'docPTBR.md',
|
|
35
|
+
target: 'docPTBR.md',
|
|
36
|
+
isMapDoc: false
|
|
37
|
+
}),
|
|
38
|
+
map_en: Object.freeze({
|
|
39
|
+
key: 'map_en',
|
|
40
|
+
source: 'map.md',
|
|
41
|
+
target: 'map.md',
|
|
42
|
+
isMapDoc: true
|
|
43
|
+
}),
|
|
44
|
+
map_ptbr: Object.freeze({
|
|
45
|
+
key: 'map_ptbr',
|
|
46
|
+
source: 'mapPTBR.md',
|
|
47
|
+
target: 'mapPTBR.md',
|
|
48
|
+
isMapDoc: true
|
|
49
|
+
})
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const DOC_TEMPLATES = Object.freeze(Object.values(DOC_TEMPLATE_MAP));
|
|
53
|
+
|
|
22
54
|
const ACTION_ALIASES = Object.freeze({
|
|
23
55
|
skip_ads: 'skip_ads',
|
|
24
56
|
skipads: 'skip_ads',
|
|
@@ -45,7 +77,20 @@ const ACTION_ALIASES = Object.freeze({
|
|
|
45
77
|
close_app: 'close_app',
|
|
46
78
|
closeapp: 'close_app',
|
|
47
79
|
fechar_app: 'close_app',
|
|
48
|
-
fecharapp: 'close_app'
|
|
80
|
+
fecharapp: 'close_app',
|
|
81
|
+
key_tap: 'key_tap',
|
|
82
|
+
keytap: 'key_tap',
|
|
83
|
+
tap_key: 'key_tap',
|
|
84
|
+
tapkey: 'key_tap',
|
|
85
|
+
press_key: 'key_tap',
|
|
86
|
+
pressionar_tecla: 'key_tap',
|
|
87
|
+
tecla: 'key_tap',
|
|
88
|
+
type_string_delayed: 'type_string_delayed',
|
|
89
|
+
typestringdelayed: 'type_string_delayed',
|
|
90
|
+
type_string: 'type_string_delayed',
|
|
91
|
+
typestring: 'type_string_delayed',
|
|
92
|
+
digitar: 'type_string_delayed',
|
|
93
|
+
escrever: 'type_string_delayed'
|
|
49
94
|
});
|
|
50
95
|
|
|
51
96
|
const BUTTON_ALIASES = Object.freeze({
|
|
@@ -84,6 +129,10 @@ const CLICK_MODE = Object.freeze({
|
|
|
84
129
|
});
|
|
85
130
|
|
|
86
131
|
let robotCache;
|
|
132
|
+
const MAPER_POLL_INTERVAL = 50;
|
|
133
|
+
let maperInterval = null;
|
|
134
|
+
let maperLastPosition = null;
|
|
135
|
+
let maperPrintedLine = false;
|
|
87
136
|
|
|
88
137
|
export function cmd(message) {
|
|
89
138
|
if (typeof message !== 'string') {
|
|
@@ -103,6 +152,10 @@ export function cmd(message) {
|
|
|
103
152
|
command: undefined,
|
|
104
153
|
extra: undefined,
|
|
105
154
|
button: undefined,
|
|
155
|
+
key: undefined,
|
|
156
|
+
modifiers: undefined,
|
|
157
|
+
text: undefined,
|
|
158
|
+
typeDelay: undefined,
|
|
106
159
|
points: undefined,
|
|
107
160
|
path: undefined,
|
|
108
161
|
interval: undefined,
|
|
@@ -140,6 +193,42 @@ export function cmd(message) {
|
|
|
140
193
|
command.extra = value;
|
|
141
194
|
} else if (key === 'button' || key === 'botao' || key === 'botão') {
|
|
142
195
|
command.button = value;
|
|
196
|
+
} else if (key === 'key' || key === 'tecla' || key === 'hotkey') {
|
|
197
|
+
command.key = value;
|
|
198
|
+
if (!command.command) {
|
|
199
|
+
command.command = value;
|
|
200
|
+
}
|
|
201
|
+
} else if (
|
|
202
|
+
key === 'modifier' ||
|
|
203
|
+
key === 'modifiers' ||
|
|
204
|
+
key === 'modificador' ||
|
|
205
|
+
key === 'modificadores'
|
|
206
|
+
) {
|
|
207
|
+
command.modifiers = value;
|
|
208
|
+
} else if (
|
|
209
|
+
key === 'text' ||
|
|
210
|
+
key === 'texto' ||
|
|
211
|
+
key === 'string' ||
|
|
212
|
+
key === 'mensagem'
|
|
213
|
+
) {
|
|
214
|
+
command.text = value;
|
|
215
|
+
if (!command.command) {
|
|
216
|
+
command.command = value;
|
|
217
|
+
}
|
|
218
|
+
} else if (
|
|
219
|
+
key === 'typedelay' ||
|
|
220
|
+
key === 'type_delay' ||
|
|
221
|
+
key === 'typingdelay' ||
|
|
222
|
+
key === 'typing_delay' ||
|
|
223
|
+
key === 'textdelay' ||
|
|
224
|
+
key === 'delaytexto' ||
|
|
225
|
+
key === 'delaydigitacao' ||
|
|
226
|
+
key === 'delaydigitar'
|
|
227
|
+
) {
|
|
228
|
+
const typeDelay = toNonNegativeInteger(value);
|
|
229
|
+
if (typeDelay !== null) {
|
|
230
|
+
command.typeDelay = typeDelay;
|
|
231
|
+
}
|
|
143
232
|
} else if (
|
|
144
233
|
key === 'points' ||
|
|
145
234
|
key === 'pontos' ||
|
|
@@ -200,7 +289,7 @@ export function cmd(message) {
|
|
|
200
289
|
}
|
|
201
290
|
}
|
|
202
291
|
|
|
203
|
-
if (command
|
|
292
|
+
if (hasCommandPayload(command)) {
|
|
204
293
|
results.push(command);
|
|
205
294
|
}
|
|
206
295
|
}
|
|
@@ -213,6 +302,161 @@ export function extractFirstCommand(message) {
|
|
|
213
302
|
return first || null;
|
|
214
303
|
}
|
|
215
304
|
|
|
305
|
+
export async function maper(enabled) {
|
|
306
|
+
const shouldEnable = parseBooleanValue(enabled);
|
|
307
|
+
if (shouldEnable === null) {
|
|
308
|
+
throw new Error('maper_requires_boolean_true_or_false');
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!shouldEnable) {
|
|
312
|
+
if (maperInterval) {
|
|
313
|
+
clearInterval(maperInterval);
|
|
314
|
+
maperInterval = null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
maperLastPosition = null;
|
|
318
|
+
|
|
319
|
+
if (maperPrintedLine && process.stdout && typeof process.stdout.write === 'function') {
|
|
320
|
+
process.stdout.write('\n');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
maperPrintedLine = false;
|
|
324
|
+
return { active: false, pollInterval: MAPER_POLL_INTERVAL };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const robot = await getRobot();
|
|
328
|
+
|
|
329
|
+
const printPosition = (position) => {
|
|
330
|
+
const line = `[maper] x: ${position.x} | y: ${position.y}`;
|
|
331
|
+
|
|
332
|
+
if (process.stdout && process.stdout.isTTY && typeof process.stdout.write === 'function') {
|
|
333
|
+
process.stdout.write(`\r${line}`);
|
|
334
|
+
maperPrintedLine = true;
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
console.log(line);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const pollPosition = () => {
|
|
342
|
+
let position;
|
|
343
|
+
try {
|
|
344
|
+
position = robot.getMousePos();
|
|
345
|
+
} catch (error) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (!position || !Number.isFinite(position.x) || !Number.isFinite(position.y)) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (
|
|
354
|
+
maperLastPosition &&
|
|
355
|
+
position.x === maperLastPosition.x &&
|
|
356
|
+
position.y === maperLastPosition.y
|
|
357
|
+
) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
maperLastPosition = { x: position.x, y: position.y };
|
|
362
|
+
printPosition(position);
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
if (maperInterval) {
|
|
366
|
+
return { active: true, pollInterval: MAPER_POLL_INTERVAL };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
maperLastPosition = null;
|
|
370
|
+
pollPosition();
|
|
371
|
+
maperInterval = setInterval(pollPosition, MAPER_POLL_INTERVAL);
|
|
372
|
+
|
|
373
|
+
if (typeof maperInterval.unref === 'function') {
|
|
374
|
+
maperInterval.unref();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return { active: true, pollInterval: MAPER_POLL_INTERVAL };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export async function initMap(options = {}) {
|
|
381
|
+
const config = buildCursorConfig(options);
|
|
382
|
+
const mapAlreadyExists = await pathExists(config.mapPath);
|
|
383
|
+
const store = await createMapStore(config);
|
|
384
|
+
|
|
385
|
+
const persistMerged =
|
|
386
|
+
parseBooleanValue(options && options.persistMerged) === true ||
|
|
387
|
+
parseBooleanValue(options && options.writeMerged) === true;
|
|
388
|
+
|
|
389
|
+
if (!mapAlreadyExists && config.persistMap) {
|
|
390
|
+
// already persisted by createMapStore when file is missing
|
|
391
|
+
} else if (persistMerged && config.persistMap) {
|
|
392
|
+
await persistMapStore(store);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
path: store.path,
|
|
397
|
+
created: !mapAlreadyExists,
|
|
398
|
+
persisted: (!mapAlreadyExists || persistMerged) && config.persistMap,
|
|
399
|
+
version: store.map.version,
|
|
400
|
+
appCount: Object.keys(store.map.apps || {}).length,
|
|
401
|
+
map: store.map
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export async function initDoc(options = {}) {
|
|
406
|
+
const raw = options && typeof options === 'object' ? options : {};
|
|
407
|
+
const outputDir = resolveDocOutputDir(raw);
|
|
408
|
+
const overwrite = parseBooleanValue(raw.overwrite) === true;
|
|
409
|
+
const includeMapDocs = shouldIncludeMapDocs(raw.includeMapDocs);
|
|
410
|
+
const templates = resolveDocTemplates(raw.files, includeMapDocs);
|
|
411
|
+
|
|
412
|
+
await mkdir(outputDir, { recursive: true });
|
|
413
|
+
|
|
414
|
+
const created = [];
|
|
415
|
+
const updated = [];
|
|
416
|
+
const skipped = [];
|
|
417
|
+
|
|
418
|
+
for (const template of templates) {
|
|
419
|
+
const sourcePath = resolvePath(MODULE_DIR, template.source);
|
|
420
|
+
const targetPath = resolvePath(outputDir, template.target);
|
|
421
|
+
const targetExists = await pathExists(targetPath);
|
|
422
|
+
|
|
423
|
+
if (targetExists && !overwrite) {
|
|
424
|
+
skipped.push({
|
|
425
|
+
key: template.key,
|
|
426
|
+
path: targetPath,
|
|
427
|
+
reason: 'exists'
|
|
428
|
+
});
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let content;
|
|
433
|
+
try {
|
|
434
|
+
content = await readFile(sourcePath, 'utf8');
|
|
435
|
+
} catch (error) {
|
|
436
|
+
if (error && error.code === 'ENOENT') {
|
|
437
|
+
throw new Error(`doc_template_not_found:${template.source}`);
|
|
438
|
+
}
|
|
439
|
+
throw error;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
await writeFile(targetPath, content, 'utf8');
|
|
443
|
+
|
|
444
|
+
if (targetExists) {
|
|
445
|
+
updated.push({ key: template.key, path: targetPath });
|
|
446
|
+
} else {
|
|
447
|
+
created.push({ key: template.key, path: targetPath });
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
outputDir,
|
|
453
|
+
overwrite,
|
|
454
|
+
created,
|
|
455
|
+
updated,
|
|
456
|
+
skipped
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
216
460
|
export async function cursor(input, options = {}) {
|
|
217
461
|
const commands = normalizeCursorInput(input);
|
|
218
462
|
if (commands.length === 0) {
|
|
@@ -313,6 +557,10 @@ export async function cursor(input, options = {}) {
|
|
|
313
557
|
command: command.command,
|
|
314
558
|
extra: command.extra,
|
|
315
559
|
button: command.button,
|
|
560
|
+
key: command.key,
|
|
561
|
+
modifiers: command.modifiers,
|
|
562
|
+
text: command.text,
|
|
563
|
+
typeDelay: command.typeDelay,
|
|
316
564
|
points: command.points,
|
|
317
565
|
path: command.path,
|
|
318
566
|
interval: command.interval,
|
|
@@ -428,6 +676,45 @@ function mergeOptionApps(customApps) {
|
|
|
428
676
|
return merged;
|
|
429
677
|
}
|
|
430
678
|
|
|
679
|
+
function toCommandText(value) {
|
|
680
|
+
if (typeof value === 'string') {
|
|
681
|
+
const trimmed = value.trim();
|
|
682
|
+
return trimmed || '';
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
if (Number.isFinite(value)) {
|
|
686
|
+
return String(value);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return '';
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function hasCommandPayload(command) {
|
|
693
|
+
if (!command || !command.type) {
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const actionKey = resolveActionKey(command.type);
|
|
698
|
+
|
|
699
|
+
if (actionKey === 'key_tap') {
|
|
700
|
+
return Boolean(toCommandText(command.key) || toCommandText(command.command));
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if (actionKey === 'type_string_delayed') {
|
|
704
|
+
return Boolean(
|
|
705
|
+
toCommandText(command.text) ||
|
|
706
|
+
toCommandText(command.command) ||
|
|
707
|
+
toCommandText(command.extra)
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (actionKey === 'move_sequence') {
|
|
712
|
+
return Boolean(command.points || command.path || toCommandText(command.command));
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return Boolean(toCommandText(command.command));
|
|
716
|
+
}
|
|
717
|
+
|
|
431
718
|
function normalizeCommandObject(value) {
|
|
432
719
|
if (!value || typeof value !== 'object') {
|
|
433
720
|
return null;
|
|
@@ -435,6 +722,28 @@ function normalizeCommandObject(value) {
|
|
|
435
722
|
|
|
436
723
|
const rawType = value.type !== undefined ? value.type : value.tipo;
|
|
437
724
|
const rawCommand = value.command !== undefined ? value.command : value.comando;
|
|
725
|
+
const rawKey =
|
|
726
|
+
value.key !== undefined
|
|
727
|
+
? value.key
|
|
728
|
+
: value.tecla !== undefined
|
|
729
|
+
? value.tecla
|
|
730
|
+
: value.hotkey;
|
|
731
|
+
const rawModifiers =
|
|
732
|
+
value.modifiers !== undefined
|
|
733
|
+
? value.modifiers
|
|
734
|
+
: value.modifier !== undefined
|
|
735
|
+
? value.modifier
|
|
736
|
+
: value.modificadores !== undefined
|
|
737
|
+
? value.modificadores
|
|
738
|
+
: value.modificador;
|
|
739
|
+
const rawText =
|
|
740
|
+
value.text !== undefined
|
|
741
|
+
? value.text
|
|
742
|
+
: value.texto !== undefined
|
|
743
|
+
? value.texto
|
|
744
|
+
: value.string !== undefined
|
|
745
|
+
? value.string
|
|
746
|
+
: value.mensagem;
|
|
438
747
|
const rawButton =
|
|
439
748
|
value.button !== undefined
|
|
440
749
|
? value.button
|
|
@@ -482,37 +791,66 @@ function normalizeCommandObject(value) {
|
|
|
482
791
|
: value.cliqueDuplo !== undefined
|
|
483
792
|
? value.cliqueDuplo
|
|
484
793
|
: value.clique_duplo;
|
|
794
|
+
const rawTypeDelay =
|
|
795
|
+
value.typeDelay !== undefined
|
|
796
|
+
? value.typeDelay
|
|
797
|
+
: value.type_delay !== undefined
|
|
798
|
+
? value.type_delay
|
|
799
|
+
: value.typingDelay !== undefined
|
|
800
|
+
? value.typingDelay
|
|
801
|
+
: value.typing_delay !== undefined
|
|
802
|
+
? value.typing_delay
|
|
803
|
+
: value.textDelay !== undefined
|
|
804
|
+
? value.textDelay
|
|
805
|
+
: value.delayTexto !== undefined
|
|
806
|
+
? value.delayTexto
|
|
807
|
+
: value.delayDigitacao !== undefined
|
|
808
|
+
? value.delayDigitacao
|
|
809
|
+
: value.delayDigitar;
|
|
485
810
|
|
|
486
811
|
const type =
|
|
487
812
|
typeof rawType === 'string' ? rawType.trim() : String(rawType || '').trim();
|
|
813
|
+
const actionKey = resolveActionKey(type);
|
|
488
814
|
|
|
489
815
|
const normalizedPoints = normalizePointsValue(
|
|
490
816
|
rawPoints !== undefined ? rawPoints : rawPath
|
|
491
817
|
);
|
|
492
818
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
? String(rawCommand)
|
|
498
|
-
: '';
|
|
819
|
+
const key = toCommandText(rawKey);
|
|
820
|
+
const text = toCommandText(rawText);
|
|
821
|
+
|
|
822
|
+
let command = toCommandText(rawCommand);
|
|
499
823
|
|
|
500
824
|
if (!command && normalizedPoints) {
|
|
501
825
|
command = serializePoints(normalizedPoints);
|
|
502
826
|
}
|
|
503
827
|
|
|
504
|
-
if (!
|
|
505
|
-
|
|
828
|
+
if (!command && text) {
|
|
829
|
+
command = text;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
if (!command && key) {
|
|
833
|
+
command = key;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
const extra =
|
|
837
|
+
value.extra === undefined || value.extra === null
|
|
838
|
+
? undefined
|
|
839
|
+
: toCommandText(value.extra) || String(value.extra);
|
|
840
|
+
|
|
841
|
+
if (!command && actionKey === 'type_string_delayed' && extra) {
|
|
842
|
+
command = extra;
|
|
506
843
|
}
|
|
507
844
|
|
|
508
845
|
const normalized = {
|
|
509
846
|
type,
|
|
510
847
|
command,
|
|
511
|
-
extra
|
|
512
|
-
value.extra === undefined || value.extra === null
|
|
513
|
-
? undefined
|
|
514
|
-
: String(value.extra),
|
|
848
|
+
extra,
|
|
515
849
|
button: undefined,
|
|
850
|
+
key: undefined,
|
|
851
|
+
modifiers: undefined,
|
|
852
|
+
text: undefined,
|
|
853
|
+
typeDelay: undefined,
|
|
516
854
|
points: undefined,
|
|
517
855
|
path: undefined,
|
|
518
856
|
interval: undefined,
|
|
@@ -529,6 +867,24 @@ function normalizeCommandObject(value) {
|
|
|
529
867
|
}
|
|
530
868
|
}
|
|
531
869
|
|
|
870
|
+
if (key) {
|
|
871
|
+
normalized.key = key;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
const modifiers = parseKeyModifiers(rawModifiers);
|
|
875
|
+
if (modifiers && modifiers.length > 0) {
|
|
876
|
+
normalized.modifiers = modifiers;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (text) {
|
|
880
|
+
normalized.text = text;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
const typeDelay = toNonNegativeInteger(rawTypeDelay);
|
|
884
|
+
if (typeDelay !== null) {
|
|
885
|
+
normalized.typeDelay = typeDelay;
|
|
886
|
+
}
|
|
887
|
+
|
|
532
888
|
if (normalizedPoints) {
|
|
533
889
|
normalized.points = normalizedPoints;
|
|
534
890
|
normalized.path = normalizedPoints;
|
|
@@ -562,7 +918,7 @@ function normalizeCommandObject(value) {
|
|
|
562
918
|
normalized.seq = seq;
|
|
563
919
|
}
|
|
564
920
|
|
|
565
|
-
return normalized;
|
|
921
|
+
return hasCommandPayload(normalized) ? normalized : null;
|
|
566
922
|
}
|
|
567
923
|
|
|
568
924
|
function normalizeCursorInput(input) {
|
|
@@ -896,6 +1252,70 @@ function canonicalToken(value) {
|
|
|
896
1252
|
.replace(/[-\s]+/g, '_');
|
|
897
1253
|
}
|
|
898
1254
|
|
|
1255
|
+
function normalizeKeyTapToken(value) {
|
|
1256
|
+
const token = canonicalToken(value);
|
|
1257
|
+
if (!token) {
|
|
1258
|
+
return undefined;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
if (
|
|
1262
|
+
token === 'cmd' ||
|
|
1263
|
+
token === 'command' ||
|
|
1264
|
+
token === 'meta' ||
|
|
1265
|
+
token === 'super' ||
|
|
1266
|
+
token === 'win' ||
|
|
1267
|
+
token === 'windows'
|
|
1268
|
+
) {
|
|
1269
|
+
return 'command';
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
if (token === 'ctrl' || token === 'control' || token === 'ctl') {
|
|
1273
|
+
return 'control';
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
if (token === 'option' || token === 'opt') {
|
|
1277
|
+
return 'alt';
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
if (token === 'spacebar') {
|
|
1281
|
+
return 'space';
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
return token;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
function parseKeyModifiers(value) {
|
|
1288
|
+
if (value === undefined || value === null) {
|
|
1289
|
+
return undefined;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
const list = Array.isArray(value) ? value : [value];
|
|
1293
|
+
const modifiers = [];
|
|
1294
|
+
|
|
1295
|
+
for (const item of list) {
|
|
1296
|
+
if (item === undefined || item === null) {
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
const chunks =
|
|
1301
|
+
typeof item === 'string'
|
|
1302
|
+
? item.split(/[+|,\s]+/g)
|
|
1303
|
+
: [String(item)];
|
|
1304
|
+
|
|
1305
|
+
for (const chunk of chunks) {
|
|
1306
|
+
const modifier = normalizeKeyTapToken(chunk);
|
|
1307
|
+
if (!modifier) continue;
|
|
1308
|
+
modifiers.push(modifier);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
if (modifiers.length === 0) {
|
|
1313
|
+
return undefined;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
return Array.from(new Set(modifiers));
|
|
1317
|
+
}
|
|
1318
|
+
|
|
899
1319
|
function resolveActionKey(type) {
|
|
900
1320
|
const key = canonicalToken(type);
|
|
901
1321
|
return ACTION_ALIASES[key];
|
|
@@ -1016,6 +1436,124 @@ function cloneAppMap(app) {
|
|
|
1016
1436
|
};
|
|
1017
1437
|
}
|
|
1018
1438
|
|
|
1439
|
+
async function pathExists(filePath) {
|
|
1440
|
+
try {
|
|
1441
|
+
await readFile(filePath, 'utf8');
|
|
1442
|
+
return true;
|
|
1443
|
+
} catch (error) {
|
|
1444
|
+
if (error && error.code === 'ENOENT') {
|
|
1445
|
+
return false;
|
|
1446
|
+
}
|
|
1447
|
+
throw error;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
function shouldIncludeMapDocs(value) {
|
|
1452
|
+
const parsed = parseBooleanValue(value);
|
|
1453
|
+
if (parsed === null) {
|
|
1454
|
+
return value !== false;
|
|
1455
|
+
}
|
|
1456
|
+
return parsed;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
function resolveDocTemplateByName(value) {
|
|
1460
|
+
const token = canonicalToken(value);
|
|
1461
|
+
if (!token) {
|
|
1462
|
+
return null;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
if (
|
|
1466
|
+
token === 'doc' ||
|
|
1467
|
+
token === 'doc_en' ||
|
|
1468
|
+
token === 'docmd' ||
|
|
1469
|
+
token === 'en' ||
|
|
1470
|
+
token === 'english'
|
|
1471
|
+
) {
|
|
1472
|
+
return DOC_TEMPLATE_MAP.doc_en;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
if (
|
|
1476
|
+
token === 'doc_ptbr' ||
|
|
1477
|
+
token === 'docptbr' ||
|
|
1478
|
+
token === 'ptbr' ||
|
|
1479
|
+
token === 'pt_br' ||
|
|
1480
|
+
token === 'pt'
|
|
1481
|
+
) {
|
|
1482
|
+
return DOC_TEMPLATE_MAP.doc_ptbr;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
if (
|
|
1486
|
+
token === 'map' ||
|
|
1487
|
+
token === 'map_en' ||
|
|
1488
|
+
token === 'mapmd' ||
|
|
1489
|
+
token === 'map_doc' ||
|
|
1490
|
+
token === 'mapdoc'
|
|
1491
|
+
) {
|
|
1492
|
+
return DOC_TEMPLATE_MAP.map_en;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
if (
|
|
1496
|
+
token === 'map_ptbr' ||
|
|
1497
|
+
token === 'mapptbr' ||
|
|
1498
|
+
token === 'map_pt' ||
|
|
1499
|
+
token === 'map_ptbr_md'
|
|
1500
|
+
) {
|
|
1501
|
+
return DOC_TEMPLATE_MAP.map_ptbr;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
return null;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
function resolveDocTemplates(filesOption, includeMapDocs) {
|
|
1508
|
+
const defaultTemplates = includeMapDocs
|
|
1509
|
+
? DOC_TEMPLATES
|
|
1510
|
+
: DOC_TEMPLATES.filter((template) => !template.isMapDoc);
|
|
1511
|
+
|
|
1512
|
+
if (filesOption === undefined || filesOption === null) {
|
|
1513
|
+
return defaultTemplates;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
const values = Array.isArray(filesOption) ? filesOption : [filesOption];
|
|
1517
|
+
const selected = [];
|
|
1518
|
+
const invalid = [];
|
|
1519
|
+
|
|
1520
|
+
for (const value of values) {
|
|
1521
|
+
const template = resolveDocTemplateByName(value);
|
|
1522
|
+
if (!template) {
|
|
1523
|
+
invalid.push(String(value));
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (!includeMapDocs && template.isMapDoc) {
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
if (!selected.find((item) => item.key === template.key)) {
|
|
1530
|
+
selected.push(template);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
if (selected.length === 0 && invalid.length > 0) {
|
|
1535
|
+
throw new Error(`invalid_doc_templates:${invalid.join('|')}`);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
return selected.length > 0 ? selected : defaultTemplates;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
function resolveDocOutputDir(options) {
|
|
1542
|
+
const rawOutput =
|
|
1543
|
+
options.outputDir !== undefined
|
|
1544
|
+
? options.outputDir
|
|
1545
|
+
: options.dir !== undefined
|
|
1546
|
+
? options.dir
|
|
1547
|
+
: options.path;
|
|
1548
|
+
|
|
1549
|
+
const output = typeof rawOutput === 'string' ? rawOutput.trim() : '';
|
|
1550
|
+
if (!output) {
|
|
1551
|
+
return resolvePath(process.cwd());
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
return resolvePath(output);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1019
1557
|
function normalizeButtonConfig(rawConfig) {
|
|
1020
1558
|
if (rawConfig === undefined || rawConfig === null) {
|
|
1021
1559
|
return null;
|
|
@@ -1307,6 +1845,7 @@ async function updateAppState(store, appName, nextState) {
|
|
|
1307
1845
|
|
|
1308
1846
|
async function persistMapStore(store) {
|
|
1309
1847
|
if (!store.persistMap) return;
|
|
1848
|
+
await mkdir(dirnamePath(store.path), { recursive: true });
|
|
1310
1849
|
const serialized = JSON.stringify(store.map, null, 2) + '\n';
|
|
1311
1850
|
await writeFile(store.path, serialized, 'utf8');
|
|
1312
1851
|
}
|
|
@@ -1420,10 +1959,6 @@ function createActionHandlers(robot, runtime) {
|
|
|
1420
1959
|
throw new Error(`missing_launcher:${appName}`);
|
|
1421
1960
|
}
|
|
1422
1961
|
|
|
1423
|
-
if (config.launchKey) {
|
|
1424
|
-
robot.keyTap(config.launchKey);
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
1962
|
if (appConfig.launcher.path) {
|
|
1428
1963
|
await clickTarget(robot, appConfig.launcher, config);
|
|
1429
1964
|
} else {
|
|
@@ -1499,6 +2034,58 @@ function createActionHandlers(robot, runtime) {
|
|
|
1499
2034
|
return config.sequenceDoubleClick;
|
|
1500
2035
|
}
|
|
1501
2036
|
|
|
2037
|
+
async function tapKey(key, modifiers) {
|
|
2038
|
+
if (modifiers && modifiers.length > 0) {
|
|
2039
|
+
robot.keyTap(key, modifiers);
|
|
2040
|
+
return;
|
|
2041
|
+
}
|
|
2042
|
+
robot.keyTap(key);
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
function resolveKeyTapPayload(command) {
|
|
2046
|
+
const key = normalizeKeyTapToken(
|
|
2047
|
+
command.key !== undefined ? command.key : command.command
|
|
2048
|
+
);
|
|
2049
|
+
|
|
2050
|
+
if (!key) {
|
|
2051
|
+
throw new Error('key_tap_requires_key');
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
const modifiers =
|
|
2055
|
+
command.modifiers !== undefined
|
|
2056
|
+
? parseKeyModifiers(command.modifiers)
|
|
2057
|
+
: parseKeyModifiers(command.extra);
|
|
2058
|
+
|
|
2059
|
+
return {
|
|
2060
|
+
key,
|
|
2061
|
+
modifiers
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
function resolveTypeStringPayload(command) {
|
|
2066
|
+
const text =
|
|
2067
|
+
command.text !== undefined && command.text !== null
|
|
2068
|
+
? String(command.text)
|
|
2069
|
+
: command.command !== undefined && command.command !== null
|
|
2070
|
+
? String(command.command)
|
|
2071
|
+
: command.extra !== undefined && command.extra !== null
|
|
2072
|
+
? String(command.extra)
|
|
2073
|
+
: '';
|
|
2074
|
+
|
|
2075
|
+
if (!text.trim()) {
|
|
2076
|
+
throw new Error('type_string_delayed_requires_text');
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
const customDelay = toNonNegativeInteger(
|
|
2080
|
+
command.typeDelay !== undefined ? command.typeDelay : command.interval
|
|
2081
|
+
);
|
|
2082
|
+
|
|
2083
|
+
return {
|
|
2084
|
+
text,
|
|
2085
|
+
typeDelay: customDelay !== null ? customDelay : config.typeDelay
|
|
2086
|
+
};
|
|
2087
|
+
}
|
|
2088
|
+
|
|
1502
2089
|
return {
|
|
1503
2090
|
async skip_ads(command) {
|
|
1504
2091
|
let point = config.skipAdsPoint;
|
|
@@ -1598,7 +2185,19 @@ function createActionHandlers(robot, runtime) {
|
|
|
1598
2185
|
}
|
|
1599
2186
|
},
|
|
1600
2187
|
|
|
2188
|
+
async key_tap(command) {
|
|
2189
|
+
const payload = resolveKeyTapPayload(command);
|
|
2190
|
+
await tapKey(payload.key, payload.modifiers);
|
|
2191
|
+
},
|
|
2192
|
+
|
|
2193
|
+
async type_string_delayed(command) {
|
|
2194
|
+
const payload = resolveTypeStringPayload(command);
|
|
2195
|
+
robot.typeStringDelayed(payload.text, payload.typeDelay);
|
|
2196
|
+
},
|
|
2197
|
+
|
|
1601
2198
|
async open_app(command) {
|
|
2199
|
+
await tapKey('command');
|
|
2200
|
+
|
|
1602
2201
|
const mapStore = await getMapStore();
|
|
1603
2202
|
const appRef = resolveAppInMap(mapStore, command.command);
|
|
1604
2203
|
if (!appRef.app) {
|
|
@@ -1626,7 +2225,12 @@ function createActionHandlers(robot, runtime) {
|
|
|
1626
2225
|
if (appRef.app.searchIcon && appRef.app.searchIcon.position) {
|
|
1627
2226
|
await clickTarget(robot, appRef.app.searchIcon, config);
|
|
1628
2227
|
}
|
|
1629
|
-
|
|
2228
|
+
|
|
2229
|
+
const customTypeDelay = toNonNegativeInteger(command.typeDelay);
|
|
2230
|
+
const typeDelay =
|
|
2231
|
+
customTypeDelay !== null ? customTypeDelay : config.typeDelay;
|
|
2232
|
+
|
|
2233
|
+
robot.typeStringDelayed(String(command.extra), typeDelay);
|
|
1630
2234
|
}
|
|
1631
2235
|
},
|
|
1632
2236
|
|
package/doc.md
CHANGED
|
@@ -7,6 +7,9 @@ Exported functions:
|
|
|
7
7
|
- `cmd`
|
|
8
8
|
- `extractFirstCommand`
|
|
9
9
|
- `cursor`
|
|
10
|
+
- `initMap`
|
|
11
|
+
- `initDoc`
|
|
12
|
+
- `maper`
|
|
10
13
|
|
|
11
14
|
## Installation
|
|
12
15
|
|
|
@@ -17,7 +20,7 @@ npm install command-cmd
|
|
|
17
20
|
## Import
|
|
18
21
|
|
|
19
22
|
```js
|
|
20
|
-
import { cmd, extractFirstCommand, cursor } from 'command-cmd';
|
|
23
|
+
import { cmd, extractFirstCommand, cursor, initMap, initDoc, maper } from 'command-cmd';
|
|
21
24
|
```
|
|
22
25
|
|
|
23
26
|
## 1) `cmd(message)`
|
|
@@ -61,7 +64,23 @@ Returns only the first valid command.
|
|
|
61
64
|
Output:
|
|
62
65
|
|
|
63
66
|
```js
|
|
64
|
-
{
|
|
67
|
+
{
|
|
68
|
+
type,
|
|
69
|
+
command,
|
|
70
|
+
extra,
|
|
71
|
+
button,
|
|
72
|
+
key,
|
|
73
|
+
modifiers,
|
|
74
|
+
text,
|
|
75
|
+
typeDelay,
|
|
76
|
+
points,
|
|
77
|
+
path,
|
|
78
|
+
interval,
|
|
79
|
+
clickDelay,
|
|
80
|
+
click,
|
|
81
|
+
doubleClick,
|
|
82
|
+
seq
|
|
83
|
+
} | null
|
|
65
84
|
```
|
|
66
85
|
|
|
67
86
|
## 3) `cursor(input, options?)`
|
|
@@ -79,6 +98,10 @@ Accepted object keys:
|
|
|
79
98
|
- `type` or `tipo`
|
|
80
99
|
- `command` or `comando`
|
|
81
100
|
- `button` or `botao`
|
|
101
|
+
- `key` or `tecla` (for `key_tap`)
|
|
102
|
+
- `modifiers` or `modificadores` (example: `command+shift`)
|
|
103
|
+
- `text` or `texto` (for `type_string_delayed`)
|
|
104
|
+
- `typeDelay` or `typingDelay` (ms per character while typing)
|
|
82
105
|
- `points` or `pontos` (coordinate sequence)
|
|
83
106
|
- `path` or `caminho` or `trajeto` (alias of `points`)
|
|
84
107
|
- `interval` or `intervalo` (ms between points)
|
|
@@ -88,6 +111,67 @@ Accepted object keys:
|
|
|
88
111
|
- `seq` or `sequencia`
|
|
89
112
|
- `extra`
|
|
90
113
|
|
|
114
|
+
## 4) `initMap(options?)`
|
|
115
|
+
|
|
116
|
+
Creates (or loads/merges) `map.json` explicitly.
|
|
117
|
+
|
|
118
|
+
Example:
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
await initMap();
|
|
122
|
+
await initMap({ mapPath: './config/map.json' });
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Optional keys:
|
|
126
|
+
|
|
127
|
+
- `mapPath`
|
|
128
|
+
- `createMapIfMissing`
|
|
129
|
+
- `persistMap`
|
|
130
|
+
- `apps`
|
|
131
|
+
- `defaultClosePoint`
|
|
132
|
+
- `skipAdsPoint`
|
|
133
|
+
- `persistMerged` (writes merged defaults even when map already exists)
|
|
134
|
+
|
|
135
|
+
## 5) `initDoc(options?)`
|
|
136
|
+
|
|
137
|
+
Creates documentation files from package templates.
|
|
138
|
+
|
|
139
|
+
By default it writes in current working directory:
|
|
140
|
+
|
|
141
|
+
- `doc.md`
|
|
142
|
+
- `docPTBR.md`
|
|
143
|
+
- `map.md`
|
|
144
|
+
- `mapPTBR.md`
|
|
145
|
+
|
|
146
|
+
Example:
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
await initDoc();
|
|
150
|
+
await initDoc({ outputDir: './docs', overwrite: true, includeMapDocs: false });
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Optional keys:
|
|
154
|
+
|
|
155
|
+
- `outputDir` (alias: `dir`, `path`)
|
|
156
|
+
- `overwrite`
|
|
157
|
+
- `includeMapDocs`
|
|
158
|
+
- `files` (e.g. `['doc', 'docPTBR', 'map', 'mapPTBR']`)
|
|
159
|
+
|
|
160
|
+
## 6) `maper(enabled)`
|
|
161
|
+
|
|
162
|
+
Turns terminal mouse position mapping on/off.
|
|
163
|
+
|
|
164
|
+
- pass `true` to start mapping
|
|
165
|
+
- pass `false` to stop mapping
|
|
166
|
+
- while active, it prints current `x/y` only when mouse position changes
|
|
167
|
+
|
|
168
|
+
Example:
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
await maper(true); // starts mapper
|
|
172
|
+
await maper(false); // stops mapper
|
|
173
|
+
```
|
|
174
|
+
|
|
91
175
|
### App and button names (important)
|
|
92
176
|
|
|
93
177
|
You can name apps and buttons however you want.
|
|
@@ -131,10 +215,18 @@ For app commands (`open_app`, `close_app`), the library uses `map.json`:
|
|
|
131
215
|
3. Executes mapped button click.
|
|
132
216
|
4. If that button has `setState`, it updates app state in `map.json`.
|
|
133
217
|
|
|
218
|
+
Note: `open_app/abrir_app` always triggers `robot.keyTap("command")` before app flow.
|
|
219
|
+
|
|
134
220
|
### Automatic `map.json` creation
|
|
135
221
|
|
|
136
222
|
If `map.json` does not exist, the library creates it automatically in the project root (cwd) by default.
|
|
137
223
|
|
|
224
|
+
You can also create it explicitly before any automation:
|
|
225
|
+
|
|
226
|
+
```js
|
|
227
|
+
await initMap();
|
|
228
|
+
```
|
|
229
|
+
|
|
138
230
|
The generated file includes:
|
|
139
231
|
|
|
140
232
|
- `state` for each app;
|
|
@@ -162,6 +254,28 @@ AI output example:
|
|
|
162
254
|
- `scroll` / `rolar`
|
|
163
255
|
- `move_sequence` / `mover_sequencia`
|
|
164
256
|
- `skip_ads` / `pular_ads`
|
|
257
|
+
- `key_tap` / `tecla`
|
|
258
|
+
- `type_string_delayed` / `digitar`
|
|
259
|
+
|
|
260
|
+
## Keyboard and typing
|
|
261
|
+
|
|
262
|
+
Single key:
|
|
263
|
+
|
|
264
|
+
```txt
|
|
265
|
+
[key_tap, key: enter]
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
With modifier:
|
|
269
|
+
|
|
270
|
+
```txt
|
|
271
|
+
[key_tap, key: v, modifiers: command]
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Slow typing:
|
|
275
|
+
|
|
276
|
+
```txt
|
|
277
|
+
[type_string_delayed, text: Typing slowly..., typeDelay: 100]
|
|
278
|
+
```
|
|
165
279
|
|
|
166
280
|
## Sequential movement (new)
|
|
167
281
|
|
|
@@ -236,7 +350,7 @@ await cursor({
|
|
|
236
350
|
mapPath: 'map.json',
|
|
237
351
|
createMapIfMissing: true,
|
|
238
352
|
persistMap: true,
|
|
239
|
-
launchKey: 'command', //
|
|
353
|
+
launchKey: 'command', // used by close_app fallback shortcut (command+w)
|
|
240
354
|
moveSteps: 50,
|
|
241
355
|
moveDelay: 8,
|
|
242
356
|
scrollSteps: 10,
|
|
@@ -267,7 +381,7 @@ They explain:
|
|
|
267
381
|
```txt
|
|
268
382
|
You are a technical assistant.
|
|
269
383
|
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>]
|
|
384
|
+
[type: <type>, command: <app_or_value>, key: <optional_key>, modifiers: <optional_modifiers>, text: <optional_text>, typeDelay: <typing_ms>, 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
385
|
|
|
272
386
|
Rules:
|
|
273
387
|
1. Always use square brackets.
|
package/docPTBR.md
CHANGED
|
@@ -7,6 +7,9 @@ Funcoes exportadas:
|
|
|
7
7
|
- `cmd`
|
|
8
8
|
- `extractFirstCommand`
|
|
9
9
|
- `cursor`
|
|
10
|
+
- `initMap`
|
|
11
|
+
- `initDoc`
|
|
12
|
+
- `maper`
|
|
10
13
|
|
|
11
14
|
## Instalacao
|
|
12
15
|
|
|
@@ -20,7 +23,10 @@ npm install command-cmd
|
|
|
20
23
|
import {
|
|
21
24
|
cmd as extrairComandos,
|
|
22
25
|
extractFirstCommand as extrairPrimeiroComando,
|
|
23
|
-
cursor as executarCursor
|
|
26
|
+
cursor as executarCursor,
|
|
27
|
+
initMap as iniciarMap,
|
|
28
|
+
initDoc as iniciarDoc,
|
|
29
|
+
maper
|
|
24
30
|
} from 'command-cmd';
|
|
25
31
|
```
|
|
26
32
|
|
|
@@ -65,7 +71,23 @@ Retorna apenas o primeiro comando valido.
|
|
|
65
71
|
Saida:
|
|
66
72
|
|
|
67
73
|
```js
|
|
68
|
-
{
|
|
74
|
+
{
|
|
75
|
+
type,
|
|
76
|
+
command,
|
|
77
|
+
extra,
|
|
78
|
+
button,
|
|
79
|
+
key,
|
|
80
|
+
modifiers,
|
|
81
|
+
text,
|
|
82
|
+
typeDelay,
|
|
83
|
+
points,
|
|
84
|
+
path,
|
|
85
|
+
interval,
|
|
86
|
+
clickDelay,
|
|
87
|
+
click,
|
|
88
|
+
doubleClick,
|
|
89
|
+
seq
|
|
90
|
+
} | null
|
|
69
91
|
```
|
|
70
92
|
|
|
71
93
|
## 3) `cursor(input, options?)`
|
|
@@ -83,6 +105,10 @@ Campos aceitos no objeto:
|
|
|
83
105
|
- `type` ou `tipo`
|
|
84
106
|
- `command` ou `comando`
|
|
85
107
|
- `button` ou `botao`
|
|
108
|
+
- `key` ou `tecla` (para `key_tap`)
|
|
109
|
+
- `modifiers` ou `modificadores` (ex.: `command+shift`)
|
|
110
|
+
- `text` ou `texto` (para `type_string_delayed`)
|
|
111
|
+
- `typeDelay` ou `typingDelay` (ms por caractere na digitacao)
|
|
86
112
|
- `points` ou `pontos` (sequencia de coordenadas)
|
|
87
113
|
- `path` ou `caminho` ou `trajeto` (alias de `points`)
|
|
88
114
|
- `interval` ou `intervalo` (ms entre pontos)
|
|
@@ -92,6 +118,67 @@ Campos aceitos no objeto:
|
|
|
92
118
|
- `seq` ou `sequencia`
|
|
93
119
|
- `extra`
|
|
94
120
|
|
|
121
|
+
## 4) `initMap(options?)`
|
|
122
|
+
|
|
123
|
+
Cria (ou carrega/mescla) o `map.json` de forma explicita.
|
|
124
|
+
|
|
125
|
+
Exemplo:
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
await iniciarMap();
|
|
129
|
+
await iniciarMap({ mapPath: './config/map.json' });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Campos opcionais:
|
|
133
|
+
|
|
134
|
+
- `mapPath`
|
|
135
|
+
- `createMapIfMissing`
|
|
136
|
+
- `persistMap`
|
|
137
|
+
- `apps`
|
|
138
|
+
- `defaultClosePoint`
|
|
139
|
+
- `skipAdsPoint`
|
|
140
|
+
- `persistMerged` (salva defaults mesclados mesmo se o map ja existir)
|
|
141
|
+
|
|
142
|
+
## 5) `initDoc(options?)`
|
|
143
|
+
|
|
144
|
+
Cria os arquivos de documentacao usando os templates do pacote.
|
|
145
|
+
|
|
146
|
+
Por padrao, escreve no diretório atual:
|
|
147
|
+
|
|
148
|
+
- `doc.md`
|
|
149
|
+
- `docPTBR.md`
|
|
150
|
+
- `map.md`
|
|
151
|
+
- `mapPTBR.md`
|
|
152
|
+
|
|
153
|
+
Exemplo:
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
await iniciarDoc();
|
|
157
|
+
await iniciarDoc({ outputDir: './docs', overwrite: true, includeMapDocs: false });
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Campos opcionais:
|
|
161
|
+
|
|
162
|
+
- `outputDir` (alias: `dir`, `path`)
|
|
163
|
+
- `overwrite`
|
|
164
|
+
- `includeMapDocs`
|
|
165
|
+
- `files` (ex.: `['doc', 'docPTBR', 'map', 'mapPTBR']`)
|
|
166
|
+
|
|
167
|
+
## 6) `maper(enabled)`
|
|
168
|
+
|
|
169
|
+
Liga/desliga o mapeador de posicao do mouse no terminal.
|
|
170
|
+
|
|
171
|
+
- passe `true` para ativar
|
|
172
|
+
- passe `false` para desativar
|
|
173
|
+
- enquanto ativo, ele mostra `x/y` apenas quando a posicao muda
|
|
174
|
+
|
|
175
|
+
Exemplo:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
await maper(true); // inicia o mapeador
|
|
179
|
+
await maper(false); // encerra o mapeador
|
|
180
|
+
```
|
|
181
|
+
|
|
95
182
|
### Nome dos apps e botoes (importante)
|
|
96
183
|
|
|
97
184
|
Voce pode chamar apps e botoes como quiser.
|
|
@@ -135,10 +222,18 @@ Para comandos de app (`abrir_app`, `close_app`), a lib usa `map.json`:
|
|
|
135
222
|
3. Executa o clique no botao mapeado.
|
|
136
223
|
4. Se o botao tiver `setState`, atualiza o estado no `map.json`.
|
|
137
224
|
|
|
225
|
+
Obs.: `abrir_app/open_app` sempre dispara `robot.keyTap("command")` antes do fluxo do app.
|
|
226
|
+
|
|
138
227
|
### Criacao automatica do `map.json`
|
|
139
228
|
|
|
140
229
|
Se o arquivo `map.json` nao existir, a lib cria automaticamente na raiz do projeto (cwd), por padrao.
|
|
141
230
|
|
|
231
|
+
Tambem da para criar explicitamente antes das automacoes:
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
await iniciarMap();
|
|
235
|
+
```
|
|
236
|
+
|
|
142
237
|
Esse arquivo inicial ja vem com:
|
|
143
238
|
|
|
144
239
|
- `state` em cada app;
|
|
@@ -166,6 +261,28 @@ A IA pode converter para:
|
|
|
166
261
|
- `scroll` / `rolar`
|
|
167
262
|
- `mover_sequencia` / `move_sequence`
|
|
168
263
|
- `skip_ads` / `pular_ads`
|
|
264
|
+
- `key_tap` / `tecla`
|
|
265
|
+
- `type_string_delayed` / `digitar`
|
|
266
|
+
|
|
267
|
+
## Teclado e digitacao
|
|
268
|
+
|
|
269
|
+
Atalho simples:
|
|
270
|
+
|
|
271
|
+
```txt
|
|
272
|
+
[key_tap, key: enter]
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Atalho com modificador:
|
|
276
|
+
|
|
277
|
+
```txt
|
|
278
|
+
[key_tap, key: v, modifiers: command]
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Digitando devagar:
|
|
282
|
+
|
|
283
|
+
```txt
|
|
284
|
+
[type_string_delayed, text: Digitando devagar..., typeDelay: 100]
|
|
285
|
+
```
|
|
169
286
|
|
|
170
287
|
## Movimento sequencial (novo)
|
|
171
288
|
|
|
@@ -240,7 +357,7 @@ await executarCursor({
|
|
|
240
357
|
mapPath: 'map.json', // caminho do mapeador
|
|
241
358
|
createMapIfMissing: true, // padrao: cria map automaticamente se faltar
|
|
242
359
|
persistMap: true, // salva estado no arquivo
|
|
243
|
-
launchKey: 'command', //
|
|
360
|
+
launchKey: 'command', // usado no fallback de close_app (atalho command+w)
|
|
244
361
|
moveSteps: 50,
|
|
245
362
|
moveDelay: 8,
|
|
246
363
|
scrollSteps: 10,
|
|
@@ -272,7 +389,7 @@ Esses arquivos explicam:
|
|
|
272
389
|
```txt
|
|
273
390
|
Voce e um assistente tecnico.
|
|
274
391
|
Quando sugerir acao executavel, responda apenas com blocos:
|
|
275
|
-
[tipo: <tipo>, comando: <app_ou_valor>, points: <pontos_opcionais>, botao: <botao_opcional>, interval: <ms_opcional>, clickDelay: <ms_ate_click>, click: <modo_opcional>, doubleClick: <boolean_opcional>, extra: <texto_opcional>, seq: <inteiro_opcional>]
|
|
392
|
+
[tipo: <tipo>, comando: <app_ou_valor>, key: <tecla_opcional>, modifiers: <mods_opcional>, text: <texto_opcional>, typeDelay: <ms_digitacao>, points: <pontos_opcionais>, botao: <botao_opcional>, interval: <ms_opcional>, clickDelay: <ms_ate_click>, click: <modo_opcional>, doubleClick: <boolean_opcional>, extra: <texto_opcional>, seq: <inteiro_opcional>]
|
|
276
393
|
|
|
277
394
|
Regras:
|
|
278
395
|
1. Use sempre colchetes.
|
package/map.md
CHANGED
|
@@ -14,6 +14,12 @@ Create `map.json` in your project root (where Node runs).
|
|
|
14
14
|
|
|
15
15
|
By default, the library auto-creates this file if it does not exist.
|
|
16
16
|
|
|
17
|
+
You can also create it explicitly:
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
await initMap();
|
|
21
|
+
```
|
|
22
|
+
|
|
17
23
|
If you need another path:
|
|
18
24
|
|
|
19
25
|
```js
|
package/mapPTBR.md
CHANGED
|
@@ -14,6 +14,12 @@ Crie `map.json` na raiz do seu projeto (mesma pasta onde voce roda o Node).
|
|
|
14
14
|
|
|
15
15
|
Por padrao, a lib cria esse arquivo automaticamente se ele nao existir.
|
|
16
16
|
|
|
17
|
+
Tambem da para criar explicitamente:
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
await initMap();
|
|
21
|
+
```
|
|
22
|
+
|
|
17
23
|
Se quiser outro caminho, passe em `cursor`:
|
|
18
24
|
|
|
19
25
|
```js
|