keyfabe 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +23 -12
  2. package/dist/commands/clone.js +42 -15
  3. package/dist/commands/clone.js.map +1 -1
  4. package/dist/commands/delete.d.ts +1 -1
  5. package/dist/commands/delete.js +17 -3
  6. package/dist/commands/delete.js.map +1 -1
  7. package/dist/commands/doctor.js +28 -23
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/export.js +2 -3
  10. package/dist/commands/export.js.map +1 -1
  11. package/dist/commands/import.js +5 -5
  12. package/dist/commands/import.js.map +1 -1
  13. package/dist/commands/list.js +8 -9
  14. package/dist/commands/list.js.map +1 -1
  15. package/dist/commands/read.js +34 -9
  16. package/dist/commands/read.js.map +1 -1
  17. package/dist/commands/rename.d.ts +1 -1
  18. package/dist/commands/rename.js +24 -4
  19. package/dist/commands/rename.js.map +1 -1
  20. package/dist/commands/setup.js +65 -56
  21. package/dist/commands/setup.js.map +1 -1
  22. package/dist/commands/show.d.ts +1 -1
  23. package/dist/commands/show.js +19 -10
  24. package/dist/commands/show.js.map +1 -1
  25. package/dist/commands/write.d.ts +1 -1
  26. package/dist/commands/write.js +15 -6
  27. package/dist/commands/write.js.map +1 -1
  28. package/dist/index.js +44 -5
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/card-ops.js +29 -16
  31. package/dist/lib/card-ops.js.map +1 -1
  32. package/dist/lib/display.js +7 -9
  33. package/dist/lib/display.js.map +1 -1
  34. package/dist/lib/parsers.d.ts +1 -0
  35. package/dist/lib/parsers.js +22 -0
  36. package/dist/lib/parsers.js.map +1 -1
  37. package/dist/lib/pm3.js +2 -2
  38. package/dist/lib/pm3.js.map +1 -1
  39. package/dist/lib/prompts.d.ts +2 -1
  40. package/dist/lib/prompts.js +25 -17
  41. package/dist/lib/prompts.js.map +1 -1
  42. package/package.json +8 -3
package/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A TypeScript CLI tool that wraps the Proxmark3 client to provide an ergonomic keyfob cloning workflow.
4
4
 
5
+ <p align="center">
6
+ <img src="demo.gif" alt="keyfabe demo" width="800" />
7
+ </p>
8
+
5
9
  ## What it does
6
10
 
7
11
  - Automates the multi-step read/detect/clone/verify process into a single guided flow
@@ -35,7 +39,12 @@ npx keyfabe
35
39
 
36
40
  ## Usage
37
41
 
42
+ Running `keyfabe` with no arguments launches an interactive wizard menu that guides you through all available actions.
43
+
38
44
  ```sh
45
+ # launch interactive wizard
46
+ keyfabe
47
+
39
48
  # check device connection, firmware, and antenna health
40
49
  keyfabe doctor
41
50
 
@@ -49,19 +58,19 @@ keyfabe clone
49
58
  keyfabe read
50
59
 
51
60
  # write a previously-saved identity to a blank fob
52
- keyfabe write <name>
61
+ keyfabe write [name]
53
62
 
54
63
  # list saved identities
55
64
  keyfabe list
56
65
 
57
66
  # show details of a saved identity
58
- keyfabe show <name>
67
+ keyfabe show [name]
59
68
 
60
69
  # rename a saved identity
61
- keyfabe rename <old-name> <new-name>
70
+ keyfabe rename [old-name] [new-name]
62
71
 
63
72
  # delete a saved identity
64
- keyfabe delete <name>
73
+ keyfabe delete [name]
65
74
 
66
75
  # export all saved identities as JSON
67
76
  keyfabe export > fobs.json
@@ -70,6 +79,8 @@ keyfabe export > fobs.json
70
79
  keyfabe import fobs.json
71
80
  ```
72
81
 
82
+ Commands that take `[name]` arguments are fully optional — when omitted, you'll get an interactive fob picker.
83
+
73
84
  ## Commands
74
85
 
75
86
  ### `keyfabe doctor`
@@ -88,25 +99,25 @@ Guided clone flow: reads the original fob, detects a blank T55x7, writes the ID,
88
99
 
89
100
  Reads and identifies whatever fob is on the antenna. Supports EM410x and HID Prox. Optionally saves the identity.
90
101
 
91
- ### `keyfabe write <name>`
102
+ ### `keyfabe write [name]`
92
103
 
93
- Writes a previously-saved identity to a blank T55x7 fob.
104
+ Writes a previously-saved identity to a blank T55x7 fob. Without a name, presents an interactive picker.
94
105
 
95
106
  ### `keyfabe list`
96
107
 
97
108
  Lists all saved fob identities from `~/.keyfabe/fobs.json`.
98
109
 
99
- ### `keyfabe show <name>`
110
+ ### `keyfabe show [name]`
100
111
 
101
- Displays full details of a saved fob identity (type, ID, encoding, save date).
112
+ Displays full details of a saved fob identity (type, ID, encoding, save date). Without a name, presents an interactive picker.
102
113
 
103
- ### `keyfabe rename <old-name> <new-name>`
114
+ ### `keyfabe rename [old-name] [new-name]`
104
115
 
105
- Renames a saved fob identity.
116
+ Renames a saved fob identity. Missing arguments are prompted interactively.
106
117
 
107
- ### `keyfabe delete <name>`
118
+ ### `keyfabe delete [name]`
108
119
 
109
- Deletes a saved fob identity.
120
+ Deletes a saved fob identity. Without a name, presents an interactive picker.
110
121
 
111
122
  ### `keyfabe export`
112
123
 
@@ -1,8 +1,7 @@
1
- import chalk from "chalk";
2
- import ora from "ora";
1
+ import * as p from "@clack/prompts";
3
2
  import { writeAndVerify } from "../lib/card-ops.js";
4
3
  import { printCardInfo, printDoctorHint } from "../lib/display.js";
5
- import { parseLfSearch } from "../lib/parsers.js";
4
+ import { parseHfSearch, parseLfSearch } from "../lib/parsers.js";
6
5
  import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
7
6
  import { promptName, waitForEnter } from "../lib/prompts.js";
8
7
  import { saveFob } from "../lib/store.js";
@@ -11,47 +10,74 @@ const READ_RETRY_DELAY = 2000;
11
10
  export async function clone() {
12
11
  if (!(await requireDevice()))
13
12
  return false;
14
- console.log(chalk.bold("\nKeyfob Clone\n"));
13
+ p.intro("Keyfob Clone");
15
14
  // Step 1: Read original
16
15
  await waitForEnter("Place your original keyfob on the antenna.");
17
16
  let card = null;
18
17
  for (let attempt = 1; attempt <= MAX_READ_RETRIES; attempt++) {
19
- const spinner = ora(`Reading original (attempt ${attempt}/${MAX_READ_RETRIES})...`).start();
18
+ const s = p.spinner();
19
+ s.start(`Reading original (attempt ${attempt}/${MAX_READ_RETRIES})...`);
20
20
  try {
21
21
  const { stdout } = await pm3Exec("lf search");
22
22
  card = parseLfSearch(stdout);
23
23
  if (card) {
24
- spinner.succeed("Original card read");
24
+ s.stop("Original card read");
25
25
  break;
26
26
  }
27
- spinner.fail("No card detected.");
27
+ s.stop("No card detected.");
28
+ p.log.error("No card detected.");
28
29
  }
29
30
  catch (err) {
30
31
  if (err instanceof Pm3Error) {
31
- spinner.fail(err.message);
32
+ s.stop(err.message);
33
+ p.log.error(err.message);
32
34
  if (err.message.includes("not found")) {
33
35
  printDoctorHint();
34
36
  }
35
37
  }
36
38
  else {
37
- spinner.fail("Read failed.");
39
+ s.stop("Read failed.");
40
+ p.log.error("Read failed.");
38
41
  }
39
42
  }
40
43
  if (attempt < MAX_READ_RETRIES) {
41
- console.log(chalk.dim(` Retrying in ${READ_RETRY_DELAY / 1000}s...`));
44
+ p.log.info(`Retrying in ${READ_RETRY_DELAY / 1000}s...`);
42
45
  await new Promise((r) => setTimeout(r, READ_RETRY_DELAY));
43
46
  }
44
47
  }
48
+ // If LF search failed, try HF
45
49
  if (!card) {
46
- console.log(chalk.red("\nFailed to read original card after all attempts."));
47
- return false;
50
+ const hfSpinner = p.spinner();
51
+ hfSpinner.start("No LF card found, trying HF...");
52
+ try {
53
+ const { stdout } = await pm3Exec("hf search");
54
+ const hfCard = parseHfSearch(stdout);
55
+ if (hfCard) {
56
+ hfSpinner.stop("HF card detected");
57
+ printCardInfo(hfCard);
58
+ p.log.warn(`HF card cloning (${hfCard.type}) is not yet supported. Only LF keyfobs (EM410x, HID Prox) can be cloned.`);
59
+ return false;
60
+ }
61
+ }
62
+ catch (err) {
63
+ if (err instanceof Pm3Error) {
64
+ hfSpinner.stop(err.message);
65
+ }
66
+ else {
67
+ hfSpinner.stop("HF search failed.");
68
+ }
69
+ }
70
+ if (!card) {
71
+ p.log.error("Failed to read original card after all attempts.");
72
+ return false;
73
+ }
48
74
  }
49
75
  printCardInfo(card);
50
76
  // Step 2: Write to blank
51
77
  await waitForEnter("Remove original and place a blank T55x7 fob on the antenna.");
52
78
  const success = await writeAndVerify(card);
53
79
  if (success) {
54
- console.log(chalk.green("\nClone successful!\n"));
80
+ p.log.success("Clone successful!");
55
81
  const name = await promptName();
56
82
  if (name) {
57
83
  await saveFob({
@@ -61,11 +87,12 @@ export async function clone() {
61
87
  encoding: card.encoding,
62
88
  savedAt: new Date().toISOString(),
63
89
  });
64
- console.log(chalk.green(`Saved as "${name}".`));
90
+ p.log.success(`Saved as "${name}".`);
65
91
  }
92
+ p.outro("Done!");
66
93
  return true;
67
94
  }
68
- console.log(chalk.red("\nClone failed.\n"));
95
+ p.log.error("Clone failed.");
69
96
  return false;
70
97
  }
71
98
  //# sourceMappingURL=clone.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B,MAAM,CAAC,KAAK,UAAU,KAAK;IACvB,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAE5C,wBAAwB;IACxB,MAAM,YAAY,CAAC,4CAA4C,CAAC,CAAC;IAEjE,IAAI,IAAI,GAAqC,IAAI,CAAC;IAElD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,6BAA6B,OAAO,IAAI,gBAAgB,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5F,IAAI,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;YAC9C,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,IAAI,EAAE,CAAC;gBACP,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;gBACtC,MAAM;YACV,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC1B,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBACpC,eAAe,EAAE,CAAC;gBACtB,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACjC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,GAAG,gBAAgB,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,gBAAgB,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC;YACvE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC7E,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,aAAa,CAAC,IAAI,CAAC,CAAC;IAEpB,yBAAyB;IACzB,MAAM,YAAY,CAAC,6DAA6D,CAAC,CAAC;IAElF,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACP,MAAM,OAAO,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- export declare function deleteFob(name: string): Promise<boolean>;
1
+ export declare function deleteFob(name?: string): Promise<boolean>;
@@ -1,13 +1,27 @@
1
- import chalk from "chalk";
1
+ import * as p from "@clack/prompts";
2
2
  import { printFobNotFound } from "../lib/display.js";
3
- import { removeFob } from "../lib/store.js";
3
+ import { confirm, selectFob } from "../lib/prompts.js";
4
+ import { loadFobs, removeFob } from "../lib/store.js";
4
5
  export async function deleteFob(name) {
6
+ if (!name) {
7
+ const fobs = await loadFobs();
8
+ if (fobs.length === 0) {
9
+ p.log.warn("No saved fobs. Use `keyfabe read` or `keyfabe clone` first.");
10
+ return false;
11
+ }
12
+ name = await selectFob(fobs, "Which fob to delete?");
13
+ }
14
+ const shouldDelete = await confirm(`Delete "${name}"?`);
15
+ if (!shouldDelete) {
16
+ p.cancel("Deletion cancelled.");
17
+ return false;
18
+ }
5
19
  const removed = await removeFob(name);
6
20
  if (!removed) {
7
21
  printFobNotFound(name);
8
22
  return false;
9
23
  }
10
- console.log(chalk.green(`\nDeleted "${name}".\n`));
24
+ p.log.success(`Deleted "${name}".`);
11
25
  return true;
12
26
  }
13
27
  //# sourceMappingURL=delete.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IACxC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAa;IACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC1E,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -1,78 +1,83 @@
1
+ import * as p from "@clack/prompts";
1
2
  import chalk from "chalk";
2
- import ora from "ora";
3
3
  import { HF_VOLTAGE_THRESHOLD, LF_VOLTAGE_THRESHOLD, printBrewInstall } from "../lib/display.js";
4
4
  import { parseHwStatus, parseHwTune } from "../lib/parsers.js";
5
5
  import { detectPort, Pm3Error, pm3Exec } from "../lib/pm3.js";
6
6
  export async function doctor() {
7
- console.log(chalk.bold("\nProxmark3 Health Check\n"));
7
+ p.intro("Proxmark3 Health Check");
8
8
  // 1. Port detection
9
9
  const port = await detectPort();
10
10
  if (port) {
11
- console.log(chalk.green(` Port: ${port}`));
11
+ p.log.success(`Port: ${port}`);
12
12
  }
13
13
  else {
14
- console.log(chalk.red(" Port: No Proxmark3 detected. Check USB connection."));
14
+ p.log.error("No Proxmark3 detected. Check USB connection.");
15
15
  return false;
16
16
  }
17
17
  // 2. Communication check
18
- const spinner = ora("Checking device communication...").start();
18
+ const s = p.spinner();
19
+ s.start("Checking device communication...");
19
20
  try {
20
21
  const { stdout } = await pm3Exec("hw status");
21
22
  const status = parseHwStatus(stdout);
22
23
  if (status.isStockFirmware) {
23
- spinner.fail("Stock firmware detected.");
24
- console.log(chalk.yellow(" Firmware: Stock firmware detected. Run `keyfabe setup` to flash Iceman firmware."));
24
+ s.stop("Stock firmware detected.");
25
+ p.log.warn("Stock firmware detected. Run `keyfabe setup` to flash Iceman firmware.");
25
26
  return false;
26
27
  }
27
28
  if (!status.connected) {
28
- spinner.fail("Cannot communicate with device.");
29
- console.log(chalk.yellow(" Cannot communicate with device. Check connection and try `keyfabe setup`."));
29
+ s.stop("Cannot communicate with device.");
30
+ p.log.warn("Cannot communicate with device. Check connection and try `keyfabe setup`.");
30
31
  return false;
31
32
  }
32
- spinner.succeed("Device communication OK");
33
- console.log(chalk.green(` Firmware: ${status.firmwareVersion}`));
33
+ s.stop("Device communication OK");
34
+ p.log.success(`Firmware: ${status.firmwareVersion}`);
34
35
  }
35
36
  catch (err) {
36
37
  if (err instanceof Pm3Error) {
37
38
  if (err.message.includes("not found")) {
38
- spinner.fail("pm3 command not found.");
39
+ s.stop("pm3 command not found.");
39
40
  printBrewInstall();
40
41
  }
41
42
  else {
42
- spinner.fail(err.message);
43
+ s.stop(err.message);
43
44
  }
44
45
  }
45
46
  else {
46
- spinner.fail("Failed to communicate with device.");
47
+ s.stop("Failed to communicate with device.");
47
48
  }
48
49
  return false;
49
50
  }
50
51
  // 3. Antenna tuning
51
- const tuneSpinner = ora("Checking antenna tuning...").start();
52
+ const tuneSpinner = p.spinner();
53
+ tuneSpinner.start("Checking antenna tuning...");
52
54
  try {
53
55
  const { stdout } = await pm3Exec("hw tune");
54
56
  const tune = parseHwTune(stdout);
55
- tuneSpinner.succeed("Antenna tuning complete");
57
+ tuneSpinner.stop("Antenna tuning complete");
56
58
  const lfColor = tune.lfVoltage >= LF_VOLTAGE_THRESHOLD ? chalk.green : chalk.red;
57
59
  const hfColor = tune.hfVoltage >= HF_VOLTAGE_THRESHOLD ? chalk.green : chalk.red;
58
- console.log(lfColor(` LF antenna: ${tune.lfVoltage.toFixed(2)}V (125 kHz)`));
59
- console.log(hfColor(` HF antenna: ${tune.hfVoltage.toFixed(2)}V (13.56 MHz)`));
60
+ const voltageLines = [
61
+ lfColor(`LF antenna: ${tune.lfVoltage.toFixed(2)}V (125 kHz)`),
62
+ hfColor(`HF antenna: ${tune.hfVoltage.toFixed(2)}V (13.56 MHz)`),
63
+ ];
64
+ p.note(voltageLines.join("\n"), "Antenna Tuning");
60
65
  if (tune.lfVoltage < LF_VOLTAGE_THRESHOLD) {
61
- console.log(chalk.yellow("LF antenna reading low. Check antenna connection."));
66
+ p.log.warn("LF antenna reading low. Check antenna connection.");
62
67
  }
63
68
  if (tune.hfVoltage < HF_VOLTAGE_THRESHOLD) {
64
- console.log(chalk.yellow("HF antenna reading low. Check antenna connection."));
69
+ p.log.warn("HF antenna reading low. Check antenna connection.");
65
70
  }
66
71
  }
67
72
  catch (err) {
68
73
  if (err instanceof Pm3Error) {
69
- tuneSpinner.fail(err.message);
74
+ tuneSpinner.stop(err.message);
70
75
  }
71
76
  else {
72
- tuneSpinner.fail("Failed to check antenna tuning.");
77
+ tuneSpinner.stop("Failed to check antenna tuning.");
73
78
  }
74
79
  }
75
- console.log();
80
+ p.outro("Device is healthy!");
76
81
  return true;
77
82
  }
78
83
  //# sourceMappingURL=doctor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,13 @@
1
- import chalk from "chalk";
2
1
  import { loadFobs } from "../lib/store.js";
3
2
  export async function exportFobs() {
4
3
  const fobs = await loadFobs();
5
4
  if (fobs.length === 0) {
6
- console.error(chalk.dim("No saved fobs to export."));
5
+ console.error("No saved fobs to export.");
7
6
  return false;
8
7
  }
9
8
  // Output clean JSON to stdout for piping
10
9
  process.stdout.write(`${JSON.stringify(fobs, null, 2)}\n`);
11
- console.error(chalk.dim(`Exported ${fobs.length} fob(s).`));
10
+ console.error(`Exported ${fobs.length} fob(s).`);
12
11
  return true;
13
12
  }
14
13
  //# sourceMappingURL=export.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { readFile } from "node:fs/promises";
2
- import chalk from "chalk";
2
+ import * as p from "@clack/prompts";
3
3
  import { importFobs } from "../lib/store.js";
4
4
  function validateFobs(data) {
5
5
  if (!Array.isArray(data))
@@ -17,7 +17,7 @@ export async function importFile(filePath) {
17
17
  raw = await readFile(filePath, "utf-8");
18
18
  }
19
19
  catch {
20
- console.log(chalk.red(`\nCannot read file: ${filePath}\n`));
20
+ p.log.error(`Cannot read file: ${filePath}`);
21
21
  return false;
22
22
  }
23
23
  let data;
@@ -25,15 +25,15 @@ export async function importFile(filePath) {
25
25
  data = JSON.parse(raw);
26
26
  }
27
27
  catch {
28
- console.log(chalk.red("\nInvalid JSON.\n"));
28
+ p.log.error("Invalid JSON.");
29
29
  return false;
30
30
  }
31
31
  if (!validateFobs(data)) {
32
- console.log(chalk.red("\nInvalid format. Expected an array of fob objects with name, type, id, and savedAt.\n"));
32
+ p.log.error("Invalid format. Expected an array of fob objects with name, type, id, and savedAt.");
33
33
  return false;
34
34
  }
35
35
  const { added, updated } = await importFobs(data);
36
- console.log(chalk.green(`\nImported ${added} new, updated ${updated} existing.\n`));
36
+ p.log.success(`Imported ${added} new, updated ${updated} existing.`);
37
37
  return true;
38
38
  }
39
39
  //# sourceMappingURL=import.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,SAAS,YAAY,CAAC,IAAa;IAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CACb,CAAC,IAAI,EAAE,EAAE,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;QAC3B,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CACvC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,QAAQ,IAAI,CAAC,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CACP,KAAK,CAAC,GAAG,CAAC,wFAAwF,CAAC,CACtG,CAAC;QACF,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,KAAK,iBAAiB,OAAO,cAAc,CAAC,CAAC,CAAC;IACpF,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,SAAS,YAAY,CAAC,IAAa;IAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CACb,CAAC,IAAI,EAAE,EAAE,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;QAC3B,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CACvC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACL,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACL,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;QAClG,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,iBAAiB,OAAO,YAAY,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import * as p from "@clack/prompts";
2
2
  import { loadFobs } from "../lib/store.js";
3
3
  export async function list(options = {}) {
4
4
  const fobs = await loadFobs();
@@ -7,7 +7,7 @@ export async function list(options = {}) {
7
7
  return true;
8
8
  }
9
9
  if (fobs.length === 0) {
10
- console.log(chalk.dim("\nNo saved fobs. Use `keyfabe read` or `keyfabe clone` to save one.\n"));
10
+ p.log.info("No saved fobs. Use `keyfabe read` or `keyfabe clone` to save one.");
11
11
  return true;
12
12
  }
13
13
  const hasEncoding = fobs.some((f) => f.encoding);
@@ -17,13 +17,12 @@ export async function list(options = {}) {
17
17
  id: Math.max(16, ...fobs.map((f) => f.id.length + 2)),
18
18
  encoding: hasEncoding ? Math.max(12, ...fobs.map((f) => (f.encoding ?? "").length + 2)) : 0,
19
19
  };
20
- console.log();
21
- let header = chalk.bold("Name".padEnd(cols.name)) + chalk.bold("Type".padEnd(cols.type)) + chalk.bold("ID".padEnd(cols.id));
20
+ let header = "Name".padEnd(cols.name) + "Type".padEnd(cols.type) + "ID".padEnd(cols.id);
22
21
  if (hasEncoding) {
23
- header += chalk.bold("Encoding".padEnd(cols.encoding));
22
+ header += "Encoding".padEnd(cols.encoding);
24
23
  }
25
- header += chalk.bold("Saved");
26
- console.log(header);
24
+ header += "Saved";
25
+ const rows = [];
27
26
  for (const fob of fobs) {
28
27
  const date = fob.savedAt.slice(0, 10);
29
28
  let row = fob.name.padEnd(cols.name) + fob.type.padEnd(cols.type) + fob.id.padEnd(cols.id);
@@ -31,9 +30,9 @@ export async function list(options = {}) {
31
30
  row += (fob.encoding ?? "").padEnd(cols.encoding);
32
31
  }
33
32
  row += date;
34
- console.log(row);
33
+ rows.push(row);
35
34
  }
36
- console.log();
35
+ p.note(`${header}\n${rows.join("\n")}`, `Saved Fobs (${fobs.length})`);
37
36
  return true;
38
37
  }
39
38
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -1,22 +1,24 @@
1
- import chalk from "chalk";
2
- import ora from "ora";
1
+ import * as p from "@clack/prompts";
3
2
  import { printCardInfo, printDoctorHint } from "../lib/display.js";
4
- import { parseLfSearch } from "../lib/parsers.js";
3
+ import { parseHfSearch, parseLfSearch } from "../lib/parsers.js";
5
4
  import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
6
5
  import { promptName } from "../lib/prompts.js";
7
6
  import { saveFob } from "../lib/store.js";
8
7
  export async function read() {
9
8
  if (!(await requireDevice()))
10
9
  return false;
10
+ p.intro("Read Card");
11
11
  let card = null;
12
- const spinner = ora("Searching for card (LF)...").start();
12
+ const s = p.spinner();
13
+ s.start("Searching for card (LF)...");
13
14
  try {
14
15
  const { stdout } = await pm3Exec("lf search");
15
16
  card = parseLfSearch(stdout);
16
17
  }
17
18
  catch (err) {
18
19
  if (err instanceof Pm3Error) {
19
- spinner.fail(err.message);
20
+ s.stop(err.message);
21
+ p.log.error(err.message);
20
22
  if (err.message.includes("not found")) {
21
23
  printDoctorHint();
22
24
  }
@@ -24,10 +26,33 @@ export async function read() {
24
26
  }
25
27
  }
26
28
  if (!card) {
27
- spinner.fail("No card detected. Make sure the fob is flat against the antenna.");
28
- return false;
29
+ s.stop("No LF card found, trying HF...");
30
+ const hf = p.spinner();
31
+ hf.start("Searching for card (HF)...");
32
+ try {
33
+ const { stdout } = await pm3Exec("hf search");
34
+ card = parseHfSearch(stdout);
35
+ }
36
+ catch (err) {
37
+ if (err instanceof Pm3Error) {
38
+ hf.stop(err.message);
39
+ p.log.error(err.message);
40
+ if (err.message.includes("not found")) {
41
+ printDoctorHint();
42
+ }
43
+ return false;
44
+ }
45
+ }
46
+ if (!card) {
47
+ hf.stop("No card detected. Make sure the card is flat against the antenna.");
48
+ p.log.error("No card detected. Make sure the card is flat against the antenna.");
49
+ return false;
50
+ }
51
+ hf.stop("Card detected");
52
+ }
53
+ else {
54
+ s.stop("Card detected");
29
55
  }
30
- spinner.succeed("Card detected");
31
56
  printCardInfo(card);
32
57
  // Prompt to save
33
58
  const name = await promptName();
@@ -39,7 +64,7 @@ export async function read() {
39
64
  encoding: card.encoding,
40
65
  savedAt: new Date().toISOString(),
41
66
  });
42
- console.log(chalk.green(`Saved as "${name}".`));
67
+ p.log.success(`Saved as "${name}".`);
43
68
  }
44
69
  return true;
45
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,IAAI;IACtB,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,IAAI,IAAI,GAAqC,IAAI,CAAC;IAElD,MAAM,OAAO,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;IAC1D,IAAI,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,eAAe,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;QACjF,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACjC,aAAa,CAAC,IAAI,CAAC,CAAC;IAEpB,iBAAiB;IACjB,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,IAAI,IAAI,EAAE,CAAC;QACP,MAAM,OAAO,CAAC;YACV,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,IAAI;IACtB,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAErB,IAAI,IAAI,GAAqC,IAAI,CAAC;IAElD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACtC,IAAI,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC1B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzB,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,eAAe,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACvB,EAAE,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACvC,IAAI,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;YAC9C,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBAC1B,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACzB,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBACpC,eAAe,EAAE,CAAC;gBACtB,CAAC;gBACD,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,EAAE,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;YAC7E,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACjF,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACJ,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC5B,CAAC;IACD,aAAa,CAAC,IAAI,CAAC,CAAC;IAEpB,iBAAiB;IACjB,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,IAAI,IAAI,EAAE,CAAC;QACP,MAAM,OAAO,CAAC;YACV,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- export declare function rename(oldName: string, newName: string): Promise<boolean>;
1
+ export declare function rename(oldName?: string, newName?: string): Promise<boolean>;