keyfabe 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +43 -4
- package/dist/commands/clone.js +3 -1
- package/dist/commands/clone.js.map +1 -1
- package/dist/commands/read.js +3 -1
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/write.js +3 -0
- package/dist/commands/write.js.map +1 -1
- package/dist/lib/pm3.d.ts +1 -0
- package/dist/lib/pm3.js +9 -0
- package/dist/lib/pm3.js.map +1 -1
- package/package.json +5 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Eugene Dobry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ A TypeScript CLI tool that wraps the Proxmark3 client to provide an ergonomic ke
|
|
|
8
8
|
- Detects and surfaces common problems (device not found, firmware mismatch, antenna issues)
|
|
9
9
|
- Stores cloned fob identities for later re-use
|
|
10
10
|
- Walks you through flashing Iceman firmware on a stock Proxmark3 Easy
|
|
11
|
+
- Export/import fob identities for backup and sharing
|
|
11
12
|
|
|
12
13
|
## Prerequisites
|
|
13
14
|
|
|
@@ -23,9 +24,13 @@ If your device has stock firmware, `keyfabe setup` will handle building and flas
|
|
|
23
24
|
## Install
|
|
24
25
|
|
|
25
26
|
```sh
|
|
26
|
-
npm install
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
npm install -g keyfabe
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or run without installing:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npx keyfabe
|
|
29
34
|
```
|
|
30
35
|
|
|
31
36
|
## Usage
|
|
@@ -49,8 +54,20 @@ keyfabe write <name>
|
|
|
49
54
|
# list saved identities
|
|
50
55
|
keyfabe list
|
|
51
56
|
|
|
57
|
+
# show details of a saved identity
|
|
58
|
+
keyfabe show <name>
|
|
59
|
+
|
|
60
|
+
# rename a saved identity
|
|
61
|
+
keyfabe rename <old-name> <new-name>
|
|
62
|
+
|
|
52
63
|
# delete a saved identity
|
|
53
64
|
keyfabe delete <name>
|
|
65
|
+
|
|
66
|
+
# export all saved identities as JSON
|
|
67
|
+
keyfabe export > fobs.json
|
|
68
|
+
|
|
69
|
+
# import identities from a JSON file
|
|
70
|
+
keyfabe import fobs.json
|
|
54
71
|
```
|
|
55
72
|
|
|
56
73
|
## Commands
|
|
@@ -79,10 +96,26 @@ Writes a previously-saved identity to a blank T55x7 fob.
|
|
|
79
96
|
|
|
80
97
|
Lists all saved fob identities from `~/.keyfabe/fobs.json`.
|
|
81
98
|
|
|
99
|
+
### `keyfabe show <name>`
|
|
100
|
+
|
|
101
|
+
Displays full details of a saved fob identity (type, ID, encoding, save date).
|
|
102
|
+
|
|
103
|
+
### `keyfabe rename <old-name> <new-name>`
|
|
104
|
+
|
|
105
|
+
Renames a saved fob identity.
|
|
106
|
+
|
|
82
107
|
### `keyfabe delete <name>`
|
|
83
108
|
|
|
84
109
|
Deletes a saved fob identity.
|
|
85
110
|
|
|
111
|
+
### `keyfabe export`
|
|
112
|
+
|
|
113
|
+
Exports all saved fob identities as JSON to stdout. Pipe to a file for backup: `keyfabe export > fobs.json`.
|
|
114
|
+
|
|
115
|
+
### `keyfabe import <file>`
|
|
116
|
+
|
|
117
|
+
Imports fob identities from a JSON file. New names are added, existing names are updated.
|
|
118
|
+
|
|
86
119
|
## Supported Card Types
|
|
87
120
|
|
|
88
121
|
| Type | Read | Clone | Notes |
|
|
@@ -101,7 +134,7 @@ npm test # run tests
|
|
|
101
134
|
npm run build # compile TypeScript
|
|
102
135
|
```
|
|
103
136
|
|
|
104
|
-
A pre-commit hook runs lint, test, and build automatically on every commit. CI does the same on push/PR via GitHub Actions.
|
|
137
|
+
A pre-commit hook runs lint, test, and build automatically on every commit. CI does the same on push/PR via GitHub Actions. Publishing to npm is handled by a separate workflow triggered by GitHub releases.
|
|
105
138
|
|
|
106
139
|
## Architecture
|
|
107
140
|
|
|
@@ -115,11 +148,17 @@ src/
|
|
|
115
148
|
clone.ts # guided clone flow
|
|
116
149
|
write.ts # write saved identity
|
|
117
150
|
list.ts # list saved identities
|
|
151
|
+
show.ts # show saved identity details
|
|
152
|
+
rename.ts # rename saved identity
|
|
118
153
|
delete.ts # delete saved identity
|
|
154
|
+
export.ts # export identities as JSON
|
|
155
|
+
import.ts # import identities from JSON
|
|
119
156
|
lib/
|
|
120
157
|
pm3.ts # spawns pm3 process, sends commands
|
|
121
158
|
firmware.ts # build/flash subprocess helpers
|
|
122
159
|
parsers.ts # parse pm3 output (card type, ID, voltages)
|
|
123
160
|
store.ts # read/write ~/.keyfabe/fobs.json
|
|
161
|
+
card-ops.ts # write-and-verify logic shared by clone/write
|
|
162
|
+
display.ts # shared display helpers and constants
|
|
124
163
|
prompts.ts # interactive user prompts
|
|
125
164
|
```
|
package/dist/commands/clone.js
CHANGED
|
@@ -3,12 +3,14 @@ import ora from "ora";
|
|
|
3
3
|
import { writeAndVerify } from "../lib/card-ops.js";
|
|
4
4
|
import { printCardInfo } from "../lib/display.js";
|
|
5
5
|
import { parseLfSearch } from "../lib/parsers.js";
|
|
6
|
-
import { Pm3Error, pm3Exec } from "../lib/pm3.js";
|
|
6
|
+
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
7
7
|
import { promptName, waitForEnter } from "../lib/prompts.js";
|
|
8
8
|
import { saveFob } from "../lib/store.js";
|
|
9
9
|
const MAX_READ_RETRIES = 3;
|
|
10
10
|
const READ_RETRY_DELAY = 2000;
|
|
11
11
|
export async function clone() {
|
|
12
|
+
if (!(await requireDevice()))
|
|
13
|
+
return false;
|
|
12
14
|
console.log(chalk.bold("\nKeyfob Clone\n"));
|
|
13
15
|
// Step 1: Read original
|
|
14
16
|
await waitForEnter("Place your original keyfob on the antenna.");
|
|
@@ -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,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/read.js
CHANGED
|
@@ -2,10 +2,12 @@ import chalk from "chalk";
|
|
|
2
2
|
import ora from "ora";
|
|
3
3
|
import { printCardInfo } from "../lib/display.js";
|
|
4
4
|
import { parseLfSearch } from "../lib/parsers.js";
|
|
5
|
-
import { Pm3Error, pm3Exec } from "../lib/pm3.js";
|
|
5
|
+
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
6
6
|
import { promptName } from "../lib/prompts.js";
|
|
7
7
|
import { saveFob } from "../lib/store.js";
|
|
8
8
|
export async function read() {
|
|
9
|
+
if (!(await requireDevice()))
|
|
10
|
+
return false;
|
|
9
11
|
let card = null;
|
|
10
12
|
const spinner = ora("Searching for card (LF)...").start();
|
|
11
13
|
try {
|
|
@@ -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,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
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,MAAM,mBAAmB,CAAC;AAClD,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,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"}
|
package/dist/commands/write.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { writeAndVerify } from "../lib/card-ops.js";
|
|
3
3
|
import { printFobNotFound } from "../lib/display.js";
|
|
4
|
+
import { requireDevice } from "../lib/pm3.js";
|
|
4
5
|
import { waitForEnter } from "../lib/prompts.js";
|
|
5
6
|
import { getFob } from "../lib/store.js";
|
|
6
7
|
export async function write(name) {
|
|
@@ -9,6 +10,8 @@ export async function write(name) {
|
|
|
9
10
|
printFobNotFound(name);
|
|
10
11
|
return false;
|
|
11
12
|
}
|
|
13
|
+
if (!(await requireDevice()))
|
|
14
|
+
return false;
|
|
12
15
|
console.log(chalk.bold(`\nWriting "${fob.name}" (${fob.type} ${fob.id})\n`));
|
|
13
16
|
await waitForEnter("Place a blank T55x7 fob on the antenna.");
|
|
14
17
|
const success = await writeAndVerify({ type: fob.type, id: fob.id, encoding: fob.encoding });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7E,MAAM,YAAY,CAAC,yCAAyC,CAAC,CAAC;IAE9D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE7F,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAClD,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":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY;IACpC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7E,MAAM,YAAY,CAAC,yCAAyC,CAAC,CAAC;IAE9D,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE7F,IAAI,OAAO,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
package/dist/lib/pm3.d.ts
CHANGED
package/dist/lib/pm3.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { readdir } from "node:fs/promises";
|
|
3
|
+
import chalk from "chalk";
|
|
3
4
|
const DEFAULT_TIMEOUT = 30_000;
|
|
4
5
|
export class Pm3Error extends Error {
|
|
5
6
|
stdout;
|
|
@@ -35,6 +36,14 @@ export async function pm3Exec(command, timeout = DEFAULT_TIMEOUT) {
|
|
|
35
36
|
});
|
|
36
37
|
});
|
|
37
38
|
}
|
|
39
|
+
export async function requireDevice() {
|
|
40
|
+
const port = await detectPort();
|
|
41
|
+
if (!port) {
|
|
42
|
+
console.log(chalk.red("\nNo Proxmark3 detected. Check USB connection.\n"));
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
38
47
|
export async function detectPort() {
|
|
39
48
|
try {
|
|
40
49
|
const entries = await readdir("/dev");
|
package/dist/lib/pm3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm3.js","sourceRoot":"","sources":["../../src/lib/pm3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"pm3.js","sourceRoot":"","sources":["../../src/lib/pm3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,OAAO,QAAS,SAAQ,KAAK;IAC/B,MAAM,CAAS;IACf,MAAM,CAAS;IACf,YAAY,OAAe,EAAE,MAAc,EAAE,MAAc;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;CACJ;AAOD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAe,EAAE,OAAO,GAAG,eAAe;IACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAClF,MAAM,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACrC,IAAI,KAAK,EAAE,CAAC;gBACR,kEAAkE;gBAClE,iEAAiE;gBACjE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACrD,MAAM,CACF,IAAI,QAAQ,CACR,yEAAyE,EACzE,GAAG,EACH,GAAG,CACN,CACJ,CAAC;oBACF,OAAO;gBACX,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,QAAQ,CAAC,+BAA+B,OAAO,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC3E,OAAO;gBACX,CAAC;gBACD,8CAA8C;gBAC9C,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtC,OAAO;YACX,CAAC;YACD,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IAC/B,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC,CAAC;QAC3E,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;QAChE,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyfabe",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI tool for Proxmark3 keyfob cloning",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
8
|
"keyfabe": "dist/index.js"
|
|
@@ -34,7 +35,10 @@
|
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@biomejs/biome": "^2.3.14",
|
|
38
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
39
|
+
"@semantic-release/git": "^10.0.1",
|
|
37
40
|
"@types/node": "^25.2.2",
|
|
41
|
+
"semantic-release": "^25.0.3",
|
|
38
42
|
"tsx": "^4.21.0",
|
|
39
43
|
"typescript": "^5.9.3",
|
|
40
44
|
"vitest": "^3.2.4"
|