command-cmd 1.0.4 → 1.0.5
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 +547 -22
- package/doc.md +102 -4
- package/docPTBR.md +104 -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({
|
|
@@ -103,6 +148,10 @@ export function cmd(message) {
|
|
|
103
148
|
command: undefined,
|
|
104
149
|
extra: undefined,
|
|
105
150
|
button: undefined,
|
|
151
|
+
key: undefined,
|
|
152
|
+
modifiers: undefined,
|
|
153
|
+
text: undefined,
|
|
154
|
+
typeDelay: undefined,
|
|
106
155
|
points: undefined,
|
|
107
156
|
path: undefined,
|
|
108
157
|
interval: undefined,
|
|
@@ -140,6 +189,42 @@ export function cmd(message) {
|
|
|
140
189
|
command.extra = value;
|
|
141
190
|
} else if (key === 'button' || key === 'botao' || key === 'botão') {
|
|
142
191
|
command.button = value;
|
|
192
|
+
} else if (key === 'key' || key === 'tecla' || key === 'hotkey') {
|
|
193
|
+
command.key = value;
|
|
194
|
+
if (!command.command) {
|
|
195
|
+
command.command = value;
|
|
196
|
+
}
|
|
197
|
+
} else if (
|
|
198
|
+
key === 'modifier' ||
|
|
199
|
+
key === 'modifiers' ||
|
|
200
|
+
key === 'modificador' ||
|
|
201
|
+
key === 'modificadores'
|
|
202
|
+
) {
|
|
203
|
+
command.modifiers = value;
|
|
204
|
+
} else if (
|
|
205
|
+
key === 'text' ||
|
|
206
|
+
key === 'texto' ||
|
|
207
|
+
key === 'string' ||
|
|
208
|
+
key === 'mensagem'
|
|
209
|
+
) {
|
|
210
|
+
command.text = value;
|
|
211
|
+
if (!command.command) {
|
|
212
|
+
command.command = value;
|
|
213
|
+
}
|
|
214
|
+
} else if (
|
|
215
|
+
key === 'typedelay' ||
|
|
216
|
+
key === 'type_delay' ||
|
|
217
|
+
key === 'typingdelay' ||
|
|
218
|
+
key === 'typing_delay' ||
|
|
219
|
+
key === 'textdelay' ||
|
|
220
|
+
key === 'delaytexto' ||
|
|
221
|
+
key === 'delaydigitacao' ||
|
|
222
|
+
key === 'delaydigitar'
|
|
223
|
+
) {
|
|
224
|
+
const typeDelay = toNonNegativeInteger(value);
|
|
225
|
+
if (typeDelay !== null) {
|
|
226
|
+
command.typeDelay = typeDelay;
|
|
227
|
+
}
|
|
143
228
|
} else if (
|
|
144
229
|
key === 'points' ||
|
|
145
230
|
key === 'pontos' ||
|
|
@@ -200,7 +285,7 @@ export function cmd(message) {
|
|
|
200
285
|
}
|
|
201
286
|
}
|
|
202
287
|
|
|
203
|
-
if (command
|
|
288
|
+
if (hasCommandPayload(command)) {
|
|
204
289
|
results.push(command);
|
|
205
290
|
}
|
|
206
291
|
}
|
|
@@ -213,6 +298,86 @@ export function extractFirstCommand(message) {
|
|
|
213
298
|
return first || null;
|
|
214
299
|
}
|
|
215
300
|
|
|
301
|
+
export async function initMap(options = {}) {
|
|
302
|
+
const config = buildCursorConfig(options);
|
|
303
|
+
const mapAlreadyExists = await pathExists(config.mapPath);
|
|
304
|
+
const store = await createMapStore(config);
|
|
305
|
+
|
|
306
|
+
const persistMerged =
|
|
307
|
+
parseBooleanValue(options && options.persistMerged) === true ||
|
|
308
|
+
parseBooleanValue(options && options.writeMerged) === true;
|
|
309
|
+
|
|
310
|
+
if (!mapAlreadyExists && config.persistMap) {
|
|
311
|
+
// already persisted by createMapStore when file is missing
|
|
312
|
+
} else if (persistMerged && config.persistMap) {
|
|
313
|
+
await persistMapStore(store);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
path: store.path,
|
|
318
|
+
created: !mapAlreadyExists,
|
|
319
|
+
persisted: (!mapAlreadyExists || persistMerged) && config.persistMap,
|
|
320
|
+
version: store.map.version,
|
|
321
|
+
appCount: Object.keys(store.map.apps || {}).length,
|
|
322
|
+
map: store.map
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export async function initDoc(options = {}) {
|
|
327
|
+
const raw = options && typeof options === 'object' ? options : {};
|
|
328
|
+
const outputDir = resolveDocOutputDir(raw);
|
|
329
|
+
const overwrite = parseBooleanValue(raw.overwrite) === true;
|
|
330
|
+
const includeMapDocs = shouldIncludeMapDocs(raw.includeMapDocs);
|
|
331
|
+
const templates = resolveDocTemplates(raw.files, includeMapDocs);
|
|
332
|
+
|
|
333
|
+
await mkdir(outputDir, { recursive: true });
|
|
334
|
+
|
|
335
|
+
const created = [];
|
|
336
|
+
const updated = [];
|
|
337
|
+
const skipped = [];
|
|
338
|
+
|
|
339
|
+
for (const template of templates) {
|
|
340
|
+
const sourcePath = resolvePath(MODULE_DIR, template.source);
|
|
341
|
+
const targetPath = resolvePath(outputDir, template.target);
|
|
342
|
+
const targetExists = await pathExists(targetPath);
|
|
343
|
+
|
|
344
|
+
if (targetExists && !overwrite) {
|
|
345
|
+
skipped.push({
|
|
346
|
+
key: template.key,
|
|
347
|
+
path: targetPath,
|
|
348
|
+
reason: 'exists'
|
|
349
|
+
});
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
let content;
|
|
354
|
+
try {
|
|
355
|
+
content = await readFile(sourcePath, 'utf8');
|
|
356
|
+
} catch (error) {
|
|
357
|
+
if (error && error.code === 'ENOENT') {
|
|
358
|
+
throw new Error(`doc_template_not_found:${template.source}`);
|
|
359
|
+
}
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
await writeFile(targetPath, content, 'utf8');
|
|
364
|
+
|
|
365
|
+
if (targetExists) {
|
|
366
|
+
updated.push({ key: template.key, path: targetPath });
|
|
367
|
+
} else {
|
|
368
|
+
created.push({ key: template.key, path: targetPath });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
outputDir,
|
|
374
|
+
overwrite,
|
|
375
|
+
created,
|
|
376
|
+
updated,
|
|
377
|
+
skipped
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
216
381
|
export async function cursor(input, options = {}) {
|
|
217
382
|
const commands = normalizeCursorInput(input);
|
|
218
383
|
if (commands.length === 0) {
|
|
@@ -313,6 +478,10 @@ export async function cursor(input, options = {}) {
|
|
|
313
478
|
command: command.command,
|
|
314
479
|
extra: command.extra,
|
|
315
480
|
button: command.button,
|
|
481
|
+
key: command.key,
|
|
482
|
+
modifiers: command.modifiers,
|
|
483
|
+
text: command.text,
|
|
484
|
+
typeDelay: command.typeDelay,
|
|
316
485
|
points: command.points,
|
|
317
486
|
path: command.path,
|
|
318
487
|
interval: command.interval,
|
|
@@ -428,6 +597,45 @@ function mergeOptionApps(customApps) {
|
|
|
428
597
|
return merged;
|
|
429
598
|
}
|
|
430
599
|
|
|
600
|
+
function toCommandText(value) {
|
|
601
|
+
if (typeof value === 'string') {
|
|
602
|
+
const trimmed = value.trim();
|
|
603
|
+
return trimmed || '';
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (Number.isFinite(value)) {
|
|
607
|
+
return String(value);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return '';
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
function hasCommandPayload(command) {
|
|
614
|
+
if (!command || !command.type) {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
const actionKey = resolveActionKey(command.type);
|
|
619
|
+
|
|
620
|
+
if (actionKey === 'key_tap') {
|
|
621
|
+
return Boolean(toCommandText(command.key) || toCommandText(command.command));
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
if (actionKey === 'type_string_delayed') {
|
|
625
|
+
return Boolean(
|
|
626
|
+
toCommandText(command.text) ||
|
|
627
|
+
toCommandText(command.command) ||
|
|
628
|
+
toCommandText(command.extra)
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (actionKey === 'move_sequence') {
|
|
633
|
+
return Boolean(command.points || command.path || toCommandText(command.command));
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return Boolean(toCommandText(command.command));
|
|
637
|
+
}
|
|
638
|
+
|
|
431
639
|
function normalizeCommandObject(value) {
|
|
432
640
|
if (!value || typeof value !== 'object') {
|
|
433
641
|
return null;
|
|
@@ -435,6 +643,28 @@ function normalizeCommandObject(value) {
|
|
|
435
643
|
|
|
436
644
|
const rawType = value.type !== undefined ? value.type : value.tipo;
|
|
437
645
|
const rawCommand = value.command !== undefined ? value.command : value.comando;
|
|
646
|
+
const rawKey =
|
|
647
|
+
value.key !== undefined
|
|
648
|
+
? value.key
|
|
649
|
+
: value.tecla !== undefined
|
|
650
|
+
? value.tecla
|
|
651
|
+
: value.hotkey;
|
|
652
|
+
const rawModifiers =
|
|
653
|
+
value.modifiers !== undefined
|
|
654
|
+
? value.modifiers
|
|
655
|
+
: value.modifier !== undefined
|
|
656
|
+
? value.modifier
|
|
657
|
+
: value.modificadores !== undefined
|
|
658
|
+
? value.modificadores
|
|
659
|
+
: value.modificador;
|
|
660
|
+
const rawText =
|
|
661
|
+
value.text !== undefined
|
|
662
|
+
? value.text
|
|
663
|
+
: value.texto !== undefined
|
|
664
|
+
? value.texto
|
|
665
|
+
: value.string !== undefined
|
|
666
|
+
? value.string
|
|
667
|
+
: value.mensagem;
|
|
438
668
|
const rawButton =
|
|
439
669
|
value.button !== undefined
|
|
440
670
|
? value.button
|
|
@@ -482,37 +712,66 @@ function normalizeCommandObject(value) {
|
|
|
482
712
|
: value.cliqueDuplo !== undefined
|
|
483
713
|
? value.cliqueDuplo
|
|
484
714
|
: value.clique_duplo;
|
|
715
|
+
const rawTypeDelay =
|
|
716
|
+
value.typeDelay !== undefined
|
|
717
|
+
? value.typeDelay
|
|
718
|
+
: value.type_delay !== undefined
|
|
719
|
+
? value.type_delay
|
|
720
|
+
: value.typingDelay !== undefined
|
|
721
|
+
? value.typingDelay
|
|
722
|
+
: value.typing_delay !== undefined
|
|
723
|
+
? value.typing_delay
|
|
724
|
+
: value.textDelay !== undefined
|
|
725
|
+
? value.textDelay
|
|
726
|
+
: value.delayTexto !== undefined
|
|
727
|
+
? value.delayTexto
|
|
728
|
+
: value.delayDigitacao !== undefined
|
|
729
|
+
? value.delayDigitacao
|
|
730
|
+
: value.delayDigitar;
|
|
485
731
|
|
|
486
732
|
const type =
|
|
487
733
|
typeof rawType === 'string' ? rawType.trim() : String(rawType || '').trim();
|
|
734
|
+
const actionKey = resolveActionKey(type);
|
|
488
735
|
|
|
489
736
|
const normalizedPoints = normalizePointsValue(
|
|
490
737
|
rawPoints !== undefined ? rawPoints : rawPath
|
|
491
738
|
);
|
|
492
739
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
? String(rawCommand)
|
|
498
|
-
: '';
|
|
740
|
+
const key = toCommandText(rawKey);
|
|
741
|
+
const text = toCommandText(rawText);
|
|
742
|
+
|
|
743
|
+
let command = toCommandText(rawCommand);
|
|
499
744
|
|
|
500
745
|
if (!command && normalizedPoints) {
|
|
501
746
|
command = serializePoints(normalizedPoints);
|
|
502
747
|
}
|
|
503
748
|
|
|
504
|
-
if (!
|
|
505
|
-
|
|
749
|
+
if (!command && text) {
|
|
750
|
+
command = text;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (!command && key) {
|
|
754
|
+
command = key;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
const extra =
|
|
758
|
+
value.extra === undefined || value.extra === null
|
|
759
|
+
? undefined
|
|
760
|
+
: toCommandText(value.extra) || String(value.extra);
|
|
761
|
+
|
|
762
|
+
if (!command && actionKey === 'type_string_delayed' && extra) {
|
|
763
|
+
command = extra;
|
|
506
764
|
}
|
|
507
765
|
|
|
508
766
|
const normalized = {
|
|
509
767
|
type,
|
|
510
768
|
command,
|
|
511
|
-
extra
|
|
512
|
-
value.extra === undefined || value.extra === null
|
|
513
|
-
? undefined
|
|
514
|
-
: String(value.extra),
|
|
769
|
+
extra,
|
|
515
770
|
button: undefined,
|
|
771
|
+
key: undefined,
|
|
772
|
+
modifiers: undefined,
|
|
773
|
+
text: undefined,
|
|
774
|
+
typeDelay: undefined,
|
|
516
775
|
points: undefined,
|
|
517
776
|
path: undefined,
|
|
518
777
|
interval: undefined,
|
|
@@ -529,6 +788,24 @@ function normalizeCommandObject(value) {
|
|
|
529
788
|
}
|
|
530
789
|
}
|
|
531
790
|
|
|
791
|
+
if (key) {
|
|
792
|
+
normalized.key = key;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const modifiers = parseKeyModifiers(rawModifiers);
|
|
796
|
+
if (modifiers && modifiers.length > 0) {
|
|
797
|
+
normalized.modifiers = modifiers;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (text) {
|
|
801
|
+
normalized.text = text;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
const typeDelay = toNonNegativeInteger(rawTypeDelay);
|
|
805
|
+
if (typeDelay !== null) {
|
|
806
|
+
normalized.typeDelay = typeDelay;
|
|
807
|
+
}
|
|
808
|
+
|
|
532
809
|
if (normalizedPoints) {
|
|
533
810
|
normalized.points = normalizedPoints;
|
|
534
811
|
normalized.path = normalizedPoints;
|
|
@@ -562,7 +839,7 @@ function normalizeCommandObject(value) {
|
|
|
562
839
|
normalized.seq = seq;
|
|
563
840
|
}
|
|
564
841
|
|
|
565
|
-
return normalized;
|
|
842
|
+
return hasCommandPayload(normalized) ? normalized : null;
|
|
566
843
|
}
|
|
567
844
|
|
|
568
845
|
function normalizeCursorInput(input) {
|
|
@@ -896,6 +1173,70 @@ function canonicalToken(value) {
|
|
|
896
1173
|
.replace(/[-\s]+/g, '_');
|
|
897
1174
|
}
|
|
898
1175
|
|
|
1176
|
+
function normalizeKeyTapToken(value) {
|
|
1177
|
+
const token = canonicalToken(value);
|
|
1178
|
+
if (!token) {
|
|
1179
|
+
return undefined;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
if (
|
|
1183
|
+
token === 'cmd' ||
|
|
1184
|
+
token === 'command' ||
|
|
1185
|
+
token === 'meta' ||
|
|
1186
|
+
token === 'super' ||
|
|
1187
|
+
token === 'win' ||
|
|
1188
|
+
token === 'windows'
|
|
1189
|
+
) {
|
|
1190
|
+
return 'command';
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
if (token === 'ctrl' || token === 'control' || token === 'ctl') {
|
|
1194
|
+
return 'control';
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
if (token === 'option' || token === 'opt') {
|
|
1198
|
+
return 'alt';
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
if (token === 'spacebar') {
|
|
1202
|
+
return 'space';
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
return token;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
function parseKeyModifiers(value) {
|
|
1209
|
+
if (value === undefined || value === null) {
|
|
1210
|
+
return undefined;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
const list = Array.isArray(value) ? value : [value];
|
|
1214
|
+
const modifiers = [];
|
|
1215
|
+
|
|
1216
|
+
for (const item of list) {
|
|
1217
|
+
if (item === undefined || item === null) {
|
|
1218
|
+
continue;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
const chunks =
|
|
1222
|
+
typeof item === 'string'
|
|
1223
|
+
? item.split(/[+|,\s]+/g)
|
|
1224
|
+
: [String(item)];
|
|
1225
|
+
|
|
1226
|
+
for (const chunk of chunks) {
|
|
1227
|
+
const modifier = normalizeKeyTapToken(chunk);
|
|
1228
|
+
if (!modifier) continue;
|
|
1229
|
+
modifiers.push(modifier);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
if (modifiers.length === 0) {
|
|
1234
|
+
return undefined;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
return Array.from(new Set(modifiers));
|
|
1238
|
+
}
|
|
1239
|
+
|
|
899
1240
|
function resolveActionKey(type) {
|
|
900
1241
|
const key = canonicalToken(type);
|
|
901
1242
|
return ACTION_ALIASES[key];
|
|
@@ -1016,6 +1357,124 @@ function cloneAppMap(app) {
|
|
|
1016
1357
|
};
|
|
1017
1358
|
}
|
|
1018
1359
|
|
|
1360
|
+
async function pathExists(filePath) {
|
|
1361
|
+
try {
|
|
1362
|
+
await readFile(filePath, 'utf8');
|
|
1363
|
+
return true;
|
|
1364
|
+
} catch (error) {
|
|
1365
|
+
if (error && error.code === 'ENOENT') {
|
|
1366
|
+
return false;
|
|
1367
|
+
}
|
|
1368
|
+
throw error;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
function shouldIncludeMapDocs(value) {
|
|
1373
|
+
const parsed = parseBooleanValue(value);
|
|
1374
|
+
if (parsed === null) {
|
|
1375
|
+
return value !== false;
|
|
1376
|
+
}
|
|
1377
|
+
return parsed;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
function resolveDocTemplateByName(value) {
|
|
1381
|
+
const token = canonicalToken(value);
|
|
1382
|
+
if (!token) {
|
|
1383
|
+
return null;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
if (
|
|
1387
|
+
token === 'doc' ||
|
|
1388
|
+
token === 'doc_en' ||
|
|
1389
|
+
token === 'docmd' ||
|
|
1390
|
+
token === 'en' ||
|
|
1391
|
+
token === 'english'
|
|
1392
|
+
) {
|
|
1393
|
+
return DOC_TEMPLATE_MAP.doc_en;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
if (
|
|
1397
|
+
token === 'doc_ptbr' ||
|
|
1398
|
+
token === 'docptbr' ||
|
|
1399
|
+
token === 'ptbr' ||
|
|
1400
|
+
token === 'pt_br' ||
|
|
1401
|
+
token === 'pt'
|
|
1402
|
+
) {
|
|
1403
|
+
return DOC_TEMPLATE_MAP.doc_ptbr;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
if (
|
|
1407
|
+
token === 'map' ||
|
|
1408
|
+
token === 'map_en' ||
|
|
1409
|
+
token === 'mapmd' ||
|
|
1410
|
+
token === 'map_doc' ||
|
|
1411
|
+
token === 'mapdoc'
|
|
1412
|
+
) {
|
|
1413
|
+
return DOC_TEMPLATE_MAP.map_en;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
if (
|
|
1417
|
+
token === 'map_ptbr' ||
|
|
1418
|
+
token === 'mapptbr' ||
|
|
1419
|
+
token === 'map_pt' ||
|
|
1420
|
+
token === 'map_ptbr_md'
|
|
1421
|
+
) {
|
|
1422
|
+
return DOC_TEMPLATE_MAP.map_ptbr;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
return null;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
function resolveDocTemplates(filesOption, includeMapDocs) {
|
|
1429
|
+
const defaultTemplates = includeMapDocs
|
|
1430
|
+
? DOC_TEMPLATES
|
|
1431
|
+
: DOC_TEMPLATES.filter((template) => !template.isMapDoc);
|
|
1432
|
+
|
|
1433
|
+
if (filesOption === undefined || filesOption === null) {
|
|
1434
|
+
return defaultTemplates;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
const values = Array.isArray(filesOption) ? filesOption : [filesOption];
|
|
1438
|
+
const selected = [];
|
|
1439
|
+
const invalid = [];
|
|
1440
|
+
|
|
1441
|
+
for (const value of values) {
|
|
1442
|
+
const template = resolveDocTemplateByName(value);
|
|
1443
|
+
if (!template) {
|
|
1444
|
+
invalid.push(String(value));
|
|
1445
|
+
continue;
|
|
1446
|
+
}
|
|
1447
|
+
if (!includeMapDocs && template.isMapDoc) {
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
if (!selected.find((item) => item.key === template.key)) {
|
|
1451
|
+
selected.push(template);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
if (selected.length === 0 && invalid.length > 0) {
|
|
1456
|
+
throw new Error(`invalid_doc_templates:${invalid.join('|')}`);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
return selected.length > 0 ? selected : defaultTemplates;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
function resolveDocOutputDir(options) {
|
|
1463
|
+
const rawOutput =
|
|
1464
|
+
options.outputDir !== undefined
|
|
1465
|
+
? options.outputDir
|
|
1466
|
+
: options.dir !== undefined
|
|
1467
|
+
? options.dir
|
|
1468
|
+
: options.path;
|
|
1469
|
+
|
|
1470
|
+
const output = typeof rawOutput === 'string' ? rawOutput.trim() : '';
|
|
1471
|
+
if (!output) {
|
|
1472
|
+
return resolvePath(process.cwd());
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
return resolvePath(output);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1019
1478
|
function normalizeButtonConfig(rawConfig) {
|
|
1020
1479
|
if (rawConfig === undefined || rawConfig === null) {
|
|
1021
1480
|
return null;
|
|
@@ -1307,6 +1766,7 @@ async function updateAppState(store, appName, nextState) {
|
|
|
1307
1766
|
|
|
1308
1767
|
async function persistMapStore(store) {
|
|
1309
1768
|
if (!store.persistMap) return;
|
|
1769
|
+
await mkdir(dirnamePath(store.path), { recursive: true });
|
|
1310
1770
|
const serialized = JSON.stringify(store.map, null, 2) + '\n';
|
|
1311
1771
|
await writeFile(store.path, serialized, 'utf8');
|
|
1312
1772
|
}
|
|
@@ -1420,10 +1880,6 @@ function createActionHandlers(robot, runtime) {
|
|
|
1420
1880
|
throw new Error(`missing_launcher:${appName}`);
|
|
1421
1881
|
}
|
|
1422
1882
|
|
|
1423
|
-
if (config.launchKey) {
|
|
1424
|
-
robot.keyTap(config.launchKey);
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
1883
|
if (appConfig.launcher.path) {
|
|
1428
1884
|
await clickTarget(robot, appConfig.launcher, config);
|
|
1429
1885
|
} else {
|
|
@@ -1499,6 +1955,58 @@ function createActionHandlers(robot, runtime) {
|
|
|
1499
1955
|
return config.sequenceDoubleClick;
|
|
1500
1956
|
}
|
|
1501
1957
|
|
|
1958
|
+
async function tapKey(key, modifiers) {
|
|
1959
|
+
if (modifiers && modifiers.length > 0) {
|
|
1960
|
+
robot.keyTap(key, modifiers);
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
robot.keyTap(key);
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
function resolveKeyTapPayload(command) {
|
|
1967
|
+
const key = normalizeKeyTapToken(
|
|
1968
|
+
command.key !== undefined ? command.key : command.command
|
|
1969
|
+
);
|
|
1970
|
+
|
|
1971
|
+
if (!key) {
|
|
1972
|
+
throw new Error('key_tap_requires_key');
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
const modifiers =
|
|
1976
|
+
command.modifiers !== undefined
|
|
1977
|
+
? parseKeyModifiers(command.modifiers)
|
|
1978
|
+
: parseKeyModifiers(command.extra);
|
|
1979
|
+
|
|
1980
|
+
return {
|
|
1981
|
+
key,
|
|
1982
|
+
modifiers
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
function resolveTypeStringPayload(command) {
|
|
1987
|
+
const text =
|
|
1988
|
+
command.text !== undefined && command.text !== null
|
|
1989
|
+
? String(command.text)
|
|
1990
|
+
: command.command !== undefined && command.command !== null
|
|
1991
|
+
? String(command.command)
|
|
1992
|
+
: command.extra !== undefined && command.extra !== null
|
|
1993
|
+
? String(command.extra)
|
|
1994
|
+
: '';
|
|
1995
|
+
|
|
1996
|
+
if (!text.trim()) {
|
|
1997
|
+
throw new Error('type_string_delayed_requires_text');
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
const customDelay = toNonNegativeInteger(
|
|
2001
|
+
command.typeDelay !== undefined ? command.typeDelay : command.interval
|
|
2002
|
+
);
|
|
2003
|
+
|
|
2004
|
+
return {
|
|
2005
|
+
text,
|
|
2006
|
+
typeDelay: customDelay !== null ? customDelay : config.typeDelay
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1502
2010
|
return {
|
|
1503
2011
|
async skip_ads(command) {
|
|
1504
2012
|
let point = config.skipAdsPoint;
|
|
@@ -1598,7 +2106,19 @@ function createActionHandlers(robot, runtime) {
|
|
|
1598
2106
|
}
|
|
1599
2107
|
},
|
|
1600
2108
|
|
|
2109
|
+
async key_tap(command) {
|
|
2110
|
+
const payload = resolveKeyTapPayload(command);
|
|
2111
|
+
await tapKey(payload.key, payload.modifiers);
|
|
2112
|
+
},
|
|
2113
|
+
|
|
2114
|
+
async type_string_delayed(command) {
|
|
2115
|
+
const payload = resolveTypeStringPayload(command);
|
|
2116
|
+
robot.typeStringDelayed(payload.text, payload.typeDelay);
|
|
2117
|
+
},
|
|
2118
|
+
|
|
1601
2119
|
async open_app(command) {
|
|
2120
|
+
await tapKey('command');
|
|
2121
|
+
|
|
1602
2122
|
const mapStore = await getMapStore();
|
|
1603
2123
|
const appRef = resolveAppInMap(mapStore, command.command);
|
|
1604
2124
|
if (!appRef.app) {
|
|
@@ -1626,7 +2146,12 @@ function createActionHandlers(robot, runtime) {
|
|
|
1626
2146
|
if (appRef.app.searchIcon && appRef.app.searchIcon.position) {
|
|
1627
2147
|
await clickTarget(robot, appRef.app.searchIcon, config);
|
|
1628
2148
|
}
|
|
1629
|
-
|
|
2149
|
+
|
|
2150
|
+
const customTypeDelay = toNonNegativeInteger(command.typeDelay);
|
|
2151
|
+
const typeDelay =
|
|
2152
|
+
customTypeDelay !== null ? customTypeDelay : config.typeDelay;
|
|
2153
|
+
|
|
2154
|
+
robot.typeStringDelayed(String(command.extra), typeDelay);
|
|
1630
2155
|
}
|
|
1631
2156
|
},
|
|
1632
2157
|
|
package/doc.md
CHANGED
|
@@ -7,6 +7,8 @@ Exported functions:
|
|
|
7
7
|
- `cmd`
|
|
8
8
|
- `extractFirstCommand`
|
|
9
9
|
- `cursor`
|
|
10
|
+
- `initMap`
|
|
11
|
+
- `initDoc`
|
|
10
12
|
|
|
11
13
|
## Installation
|
|
12
14
|
|
|
@@ -17,7 +19,7 @@ npm install command-cmd
|
|
|
17
19
|
## Import
|
|
18
20
|
|
|
19
21
|
```js
|
|
20
|
-
import { cmd, extractFirstCommand, cursor } from 'command-cmd';
|
|
22
|
+
import { cmd, extractFirstCommand, cursor, initMap, initDoc } from 'command-cmd';
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
## 1) `cmd(message)`
|
|
@@ -61,7 +63,23 @@ Returns only the first valid command.
|
|
|
61
63
|
Output:
|
|
62
64
|
|
|
63
65
|
```js
|
|
64
|
-
{
|
|
66
|
+
{
|
|
67
|
+
type,
|
|
68
|
+
command,
|
|
69
|
+
extra,
|
|
70
|
+
button,
|
|
71
|
+
key,
|
|
72
|
+
modifiers,
|
|
73
|
+
text,
|
|
74
|
+
typeDelay,
|
|
75
|
+
points,
|
|
76
|
+
path,
|
|
77
|
+
interval,
|
|
78
|
+
clickDelay,
|
|
79
|
+
click,
|
|
80
|
+
doubleClick,
|
|
81
|
+
seq
|
|
82
|
+
} | null
|
|
65
83
|
```
|
|
66
84
|
|
|
67
85
|
## 3) `cursor(input, options?)`
|
|
@@ -79,6 +97,10 @@ Accepted object keys:
|
|
|
79
97
|
- `type` or `tipo`
|
|
80
98
|
- `command` or `comando`
|
|
81
99
|
- `button` or `botao`
|
|
100
|
+
- `key` or `tecla` (for `key_tap`)
|
|
101
|
+
- `modifiers` or `modificadores` (example: `command+shift`)
|
|
102
|
+
- `text` or `texto` (for `type_string_delayed`)
|
|
103
|
+
- `typeDelay` or `typingDelay` (ms per character while typing)
|
|
82
104
|
- `points` or `pontos` (coordinate sequence)
|
|
83
105
|
- `path` or `caminho` or `trajeto` (alias of `points`)
|
|
84
106
|
- `interval` or `intervalo` (ms between points)
|
|
@@ -88,6 +110,52 @@ Accepted object keys:
|
|
|
88
110
|
- `seq` or `sequencia`
|
|
89
111
|
- `extra`
|
|
90
112
|
|
|
113
|
+
## 4) `initMap(options?)`
|
|
114
|
+
|
|
115
|
+
Creates (or loads/merges) `map.json` explicitly.
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
await initMap();
|
|
121
|
+
await initMap({ mapPath: './config/map.json' });
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Optional keys:
|
|
125
|
+
|
|
126
|
+
- `mapPath`
|
|
127
|
+
- `createMapIfMissing`
|
|
128
|
+
- `persistMap`
|
|
129
|
+
- `apps`
|
|
130
|
+
- `defaultClosePoint`
|
|
131
|
+
- `skipAdsPoint`
|
|
132
|
+
- `persistMerged` (writes merged defaults even when map already exists)
|
|
133
|
+
|
|
134
|
+
## 5) `initDoc(options?)`
|
|
135
|
+
|
|
136
|
+
Creates documentation files from package templates.
|
|
137
|
+
|
|
138
|
+
By default it writes in current working directory:
|
|
139
|
+
|
|
140
|
+
- `doc.md`
|
|
141
|
+
- `docPTBR.md`
|
|
142
|
+
- `map.md`
|
|
143
|
+
- `mapPTBR.md`
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
await initDoc();
|
|
149
|
+
await initDoc({ outputDir: './docs', overwrite: true, includeMapDocs: false });
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Optional keys:
|
|
153
|
+
|
|
154
|
+
- `outputDir` (alias: `dir`, `path`)
|
|
155
|
+
- `overwrite`
|
|
156
|
+
- `includeMapDocs`
|
|
157
|
+
- `files` (e.g. `['doc', 'docPTBR', 'map', 'mapPTBR']`)
|
|
158
|
+
|
|
91
159
|
### App and button names (important)
|
|
92
160
|
|
|
93
161
|
You can name apps and buttons however you want.
|
|
@@ -131,10 +199,18 @@ For app commands (`open_app`, `close_app`), the library uses `map.json`:
|
|
|
131
199
|
3. Executes mapped button click.
|
|
132
200
|
4. If that button has `setState`, it updates app state in `map.json`.
|
|
133
201
|
|
|
202
|
+
Note: `open_app/abrir_app` always triggers `robot.keyTap("command")` before app flow.
|
|
203
|
+
|
|
134
204
|
### Automatic `map.json` creation
|
|
135
205
|
|
|
136
206
|
If `map.json` does not exist, the library creates it automatically in the project root (cwd) by default.
|
|
137
207
|
|
|
208
|
+
You can also create it explicitly before any automation:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
await initMap();
|
|
212
|
+
```
|
|
213
|
+
|
|
138
214
|
The generated file includes:
|
|
139
215
|
|
|
140
216
|
- `state` for each app;
|
|
@@ -162,6 +238,28 @@ AI output example:
|
|
|
162
238
|
- `scroll` / `rolar`
|
|
163
239
|
- `move_sequence` / `mover_sequencia`
|
|
164
240
|
- `skip_ads` / `pular_ads`
|
|
241
|
+
- `key_tap` / `tecla`
|
|
242
|
+
- `type_string_delayed` / `digitar`
|
|
243
|
+
|
|
244
|
+
## Keyboard and typing
|
|
245
|
+
|
|
246
|
+
Single key:
|
|
247
|
+
|
|
248
|
+
```txt
|
|
249
|
+
[key_tap, key: enter]
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
With modifier:
|
|
253
|
+
|
|
254
|
+
```txt
|
|
255
|
+
[key_tap, key: v, modifiers: command]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Slow typing:
|
|
259
|
+
|
|
260
|
+
```txt
|
|
261
|
+
[type_string_delayed, text: Typing slowly..., typeDelay: 100]
|
|
262
|
+
```
|
|
165
263
|
|
|
166
264
|
## Sequential movement (new)
|
|
167
265
|
|
|
@@ -236,7 +334,7 @@ await cursor({
|
|
|
236
334
|
mapPath: 'map.json',
|
|
237
335
|
createMapIfMissing: true,
|
|
238
336
|
persistMap: true,
|
|
239
|
-
launchKey: 'command', //
|
|
337
|
+
launchKey: 'command', // used by close_app fallback shortcut (command+w)
|
|
240
338
|
moveSteps: 50,
|
|
241
339
|
moveDelay: 8,
|
|
242
340
|
scrollSteps: 10,
|
|
@@ -267,7 +365,7 @@ They explain:
|
|
|
267
365
|
```txt
|
|
268
366
|
You are a technical assistant.
|
|
269
367
|
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>]
|
|
368
|
+
[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
369
|
|
|
272
370
|
Rules:
|
|
273
371
|
1. Always use square brackets.
|
package/docPTBR.md
CHANGED
|
@@ -7,6 +7,8 @@ Funcoes exportadas:
|
|
|
7
7
|
- `cmd`
|
|
8
8
|
- `extractFirstCommand`
|
|
9
9
|
- `cursor`
|
|
10
|
+
- `initMap`
|
|
11
|
+
- `initDoc`
|
|
10
12
|
|
|
11
13
|
## Instalacao
|
|
12
14
|
|
|
@@ -20,7 +22,9 @@ npm install command-cmd
|
|
|
20
22
|
import {
|
|
21
23
|
cmd as extrairComandos,
|
|
22
24
|
extractFirstCommand as extrairPrimeiroComando,
|
|
23
|
-
cursor as executarCursor
|
|
25
|
+
cursor as executarCursor,
|
|
26
|
+
initMap as iniciarMap,
|
|
27
|
+
initDoc as iniciarDoc
|
|
24
28
|
} from 'command-cmd';
|
|
25
29
|
```
|
|
26
30
|
|
|
@@ -65,7 +69,23 @@ Retorna apenas o primeiro comando valido.
|
|
|
65
69
|
Saida:
|
|
66
70
|
|
|
67
71
|
```js
|
|
68
|
-
{
|
|
72
|
+
{
|
|
73
|
+
type,
|
|
74
|
+
command,
|
|
75
|
+
extra,
|
|
76
|
+
button,
|
|
77
|
+
key,
|
|
78
|
+
modifiers,
|
|
79
|
+
text,
|
|
80
|
+
typeDelay,
|
|
81
|
+
points,
|
|
82
|
+
path,
|
|
83
|
+
interval,
|
|
84
|
+
clickDelay,
|
|
85
|
+
click,
|
|
86
|
+
doubleClick,
|
|
87
|
+
seq
|
|
88
|
+
} | null
|
|
69
89
|
```
|
|
70
90
|
|
|
71
91
|
## 3) `cursor(input, options?)`
|
|
@@ -83,6 +103,10 @@ Campos aceitos no objeto:
|
|
|
83
103
|
- `type` ou `tipo`
|
|
84
104
|
- `command` ou `comando`
|
|
85
105
|
- `button` ou `botao`
|
|
106
|
+
- `key` ou `tecla` (para `key_tap`)
|
|
107
|
+
- `modifiers` ou `modificadores` (ex.: `command+shift`)
|
|
108
|
+
- `text` ou `texto` (para `type_string_delayed`)
|
|
109
|
+
- `typeDelay` ou `typingDelay` (ms por caractere na digitacao)
|
|
86
110
|
- `points` ou `pontos` (sequencia de coordenadas)
|
|
87
111
|
- `path` ou `caminho` ou `trajeto` (alias de `points`)
|
|
88
112
|
- `interval` ou `intervalo` (ms entre pontos)
|
|
@@ -92,6 +116,52 @@ Campos aceitos no objeto:
|
|
|
92
116
|
- `seq` ou `sequencia`
|
|
93
117
|
- `extra`
|
|
94
118
|
|
|
119
|
+
## 4) `initMap(options?)`
|
|
120
|
+
|
|
121
|
+
Cria (ou carrega/mescla) o `map.json` de forma explicita.
|
|
122
|
+
|
|
123
|
+
Exemplo:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
await iniciarMap();
|
|
127
|
+
await iniciarMap({ mapPath: './config/map.json' });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Campos opcionais:
|
|
131
|
+
|
|
132
|
+
- `mapPath`
|
|
133
|
+
- `createMapIfMissing`
|
|
134
|
+
- `persistMap`
|
|
135
|
+
- `apps`
|
|
136
|
+
- `defaultClosePoint`
|
|
137
|
+
- `skipAdsPoint`
|
|
138
|
+
- `persistMerged` (salva defaults mesclados mesmo se o map ja existir)
|
|
139
|
+
|
|
140
|
+
## 5) `initDoc(options?)`
|
|
141
|
+
|
|
142
|
+
Cria os arquivos de documentacao usando os templates do pacote.
|
|
143
|
+
|
|
144
|
+
Por padrao, escreve no diretório atual:
|
|
145
|
+
|
|
146
|
+
- `doc.md`
|
|
147
|
+
- `docPTBR.md`
|
|
148
|
+
- `map.md`
|
|
149
|
+
- `mapPTBR.md`
|
|
150
|
+
|
|
151
|
+
Exemplo:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
await iniciarDoc();
|
|
155
|
+
await iniciarDoc({ outputDir: './docs', overwrite: true, includeMapDocs: false });
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Campos opcionais:
|
|
159
|
+
|
|
160
|
+
- `outputDir` (alias: `dir`, `path`)
|
|
161
|
+
- `overwrite`
|
|
162
|
+
- `includeMapDocs`
|
|
163
|
+
- `files` (ex.: `['doc', 'docPTBR', 'map', 'mapPTBR']`)
|
|
164
|
+
|
|
95
165
|
### Nome dos apps e botoes (importante)
|
|
96
166
|
|
|
97
167
|
Voce pode chamar apps e botoes como quiser.
|
|
@@ -135,10 +205,18 @@ Para comandos de app (`abrir_app`, `close_app`), a lib usa `map.json`:
|
|
|
135
205
|
3. Executa o clique no botao mapeado.
|
|
136
206
|
4. Se o botao tiver `setState`, atualiza o estado no `map.json`.
|
|
137
207
|
|
|
208
|
+
Obs.: `abrir_app/open_app` sempre dispara `robot.keyTap("command")` antes do fluxo do app.
|
|
209
|
+
|
|
138
210
|
### Criacao automatica do `map.json`
|
|
139
211
|
|
|
140
212
|
Se o arquivo `map.json` nao existir, a lib cria automaticamente na raiz do projeto (cwd), por padrao.
|
|
141
213
|
|
|
214
|
+
Tambem da para criar explicitamente antes das automacoes:
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
await iniciarMap();
|
|
218
|
+
```
|
|
219
|
+
|
|
142
220
|
Esse arquivo inicial ja vem com:
|
|
143
221
|
|
|
144
222
|
- `state` em cada app;
|
|
@@ -166,6 +244,28 @@ A IA pode converter para:
|
|
|
166
244
|
- `scroll` / `rolar`
|
|
167
245
|
- `mover_sequencia` / `move_sequence`
|
|
168
246
|
- `skip_ads` / `pular_ads`
|
|
247
|
+
- `key_tap` / `tecla`
|
|
248
|
+
- `type_string_delayed` / `digitar`
|
|
249
|
+
|
|
250
|
+
## Teclado e digitacao
|
|
251
|
+
|
|
252
|
+
Atalho simples:
|
|
253
|
+
|
|
254
|
+
```txt
|
|
255
|
+
[key_tap, key: enter]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Atalho com modificador:
|
|
259
|
+
|
|
260
|
+
```txt
|
|
261
|
+
[key_tap, key: v, modifiers: command]
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Digitando devagar:
|
|
265
|
+
|
|
266
|
+
```txt
|
|
267
|
+
[type_string_delayed, text: Digitando devagar..., typeDelay: 100]
|
|
268
|
+
```
|
|
169
269
|
|
|
170
270
|
## Movimento sequencial (novo)
|
|
171
271
|
|
|
@@ -240,7 +340,7 @@ await executarCursor({
|
|
|
240
340
|
mapPath: 'map.json', // caminho do mapeador
|
|
241
341
|
createMapIfMissing: true, // padrao: cria map automaticamente se faltar
|
|
242
342
|
persistMap: true, // salva estado no arquivo
|
|
243
|
-
launchKey: 'command', //
|
|
343
|
+
launchKey: 'command', // usado no fallback de close_app (atalho command+w)
|
|
244
344
|
moveSteps: 50,
|
|
245
345
|
moveDelay: 8,
|
|
246
346
|
scrollSteps: 10,
|
|
@@ -272,7 +372,7 @@ Esses arquivos explicam:
|
|
|
272
372
|
```txt
|
|
273
373
|
Voce e um assistente tecnico.
|
|
274
374
|
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>]
|
|
375
|
+
[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
376
|
|
|
277
377
|
Regras:
|
|
278
378
|
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
|