@amalgm/shell 0.1.116 → 0.1.118

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/README.md CHANGED
@@ -29,6 +29,9 @@ credential-bearing redirects are rejected, and missing or unreadable stored
29
29
  key material fails closed rather than silently rotating a server-pinned
30
30
  identity. Recovery stages a separate candidate, requires browser approval and
31
31
  candidate-key proof, and promotes only the server-accepted key.
32
+ macOS writes private keys through the native Security framework, Windows uses
33
+ DPAPI, and a mode-0600 file is the verified fallback when the preferred store
34
+ is unavailable; private key material is never placed in a process argument.
32
35
  Consumers use the contained `@amalgm/shell/authorization` export; importing
33
36
  authorization does not load unrelated native runtime adapters.
34
37
 
@@ -13,3 +13,4 @@ export declare function createDeviceKeyStore(input: Readonly<{
13
13
  account: string;
14
14
  platform?: NodeJS.Platform;
15
15
  }>): DeviceKeyStore;
16
+ export declare function createPreferredDeviceKeyStore(primary: DeviceKeyStore, fallback: DeviceKeyStore): DeviceKeyStore;
@@ -1,17 +1,15 @@
1
- import { execFile } from "node:child_process";
2
1
  import { readFileSync, rmSync } from "node:fs";
3
- import { promisify } from "node:util";
4
2
  import { atomicJson } from "../filesystem.js";
3
+ import { createNativeKeyringStore } from "./native-keyring.js";
5
4
  import { runSecretProcess } from "./secret-process.js";
6
- const execFileAsync = promisify(execFile);
7
- const KEYCHAIN_SERVICE = "com.amalgm.shell.authorization";
8
5
  export function createDeviceKeyStore(input) {
9
6
  const file = fileStore(input.file);
10
7
  const platform = input.platform ?? process.platform;
11
- if (platform === "darwin")
12
- return preferredStore(keychainStore(input.account), file);
8
+ if (platform === "darwin") {
9
+ return createPreferredDeviceKeyStore(createNativeKeyringStore(input.account), file);
10
+ }
13
11
  if (platform === "win32")
14
- return preferredStore(dpapiStore(input.file), file);
12
+ return createPreferredDeviceKeyStore(dpapiStore(input.file), file);
15
13
  return file;
16
14
  }
17
15
  function fileStore(file) {
@@ -21,44 +19,6 @@ function fileStore(file) {
21
19
  remove: async () => rmSync(file, { force: true }),
22
20
  };
23
21
  }
24
- function keychainStore(account) {
25
- return {
26
- load: async () => {
27
- try {
28
- const { stdout } = await execFileAsync("/usr/bin/security", [
29
- "find-generic-password", "-a", account, "-s", KEYCHAIN_SERVICE, "-w",
30
- ], { encoding: "utf8", maxBuffer: 64 * 1024 });
31
- return JSON.parse(stdout.trim());
32
- }
33
- catch (error) {
34
- const message = errorText(error);
35
- if (message.includes("could not be found") || message.includes("SecKeychainSearchCopyNext: -25300")) {
36
- return null;
37
- }
38
- throw error;
39
- }
40
- },
41
- save: async (key) => {
42
- await runSecretProcess("/usr/bin/security", [
43
- "add-generic-password", "-U", "-a", account, "-s", KEYCHAIN_SERVICE,
44
- "-w",
45
- ], `${JSON.stringify(key)}\n`);
46
- },
47
- remove: async () => {
48
- try {
49
- await execFileAsync("/usr/bin/security", [
50
- "delete-generic-password", "-a", account, "-s", KEYCHAIN_SERVICE,
51
- ], { encoding: "utf8", maxBuffer: 64 * 1024 });
52
- }
53
- catch (error) {
54
- const message = errorText(error);
55
- if (!message.includes("could not be found") && !message.includes("SecKeychainSearchCopyNext: -25300")) {
56
- throw error;
57
- }
58
- }
59
- },
60
- };
61
- }
62
22
  function dpapiStore(file) {
63
23
  const protect = [
64
24
  "$ErrorActionPreference='Stop'",
@@ -87,7 +47,7 @@ function dpapiStore(file) {
87
47
  remove: async () => rmSync(file, { force: true }),
88
48
  };
89
49
  }
90
- function preferredStore(primary, fallback) {
50
+ export function createPreferredDeviceKeyStore(primary, fallback) {
91
51
  let selected = null;
92
52
  return {
93
53
  load: async () => {
@@ -108,9 +68,14 @@ function preferredStore(primary, fallback) {
108
68
  return fallback.save(key);
109
69
  try {
110
70
  await primary.save(key);
71
+ const stored = await primary.load();
72
+ if (JSON.stringify(stored) !== JSON.stringify(key)) {
73
+ throw new Error("The preferred authorization key store did not preserve the key");
74
+ }
111
75
  selected = "primary";
112
76
  }
113
77
  catch {
78
+ await primary.remove();
114
79
  await fallback.save(key);
115
80
  selected = "fallback";
116
81
  }
@@ -127,22 +92,30 @@ function preferredStore(primary, fallback) {
127
92
  }
128
93
  function readStoredJson(file) {
129
94
  try {
130
- return JSON.parse(readFileSync(file, "utf8"));
95
+ return parseStoredJson(readFileSync(file, "utf8"));
131
96
  }
132
97
  catch (error) {
133
98
  if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
134
99
  return null;
135
100
  }
101
+ if (error && typeof error === "object" && "code" in error && error.code === "authorization_key_corrupt") {
102
+ throw error;
103
+ }
136
104
  throw Object.assign(new Error("Stored authorization key is unreadable or corrupt"), {
137
105
  code: "authorization_key_corrupt",
138
106
  cause: error,
139
107
  });
140
108
  }
141
109
  }
142
- function errorText(error) {
143
- if (!error || typeof error !== "object")
144
- return String(error);
145
- const value = error;
146
- return `${String(value.message ?? "")} ${String(value.stderr ?? "")}`;
110
+ function parseStoredJson(value) {
111
+ try {
112
+ return JSON.parse(value);
113
+ }
114
+ catch (error) {
115
+ throw Object.assign(new Error("Stored authorization key is unreadable or corrupt"), {
116
+ code: "authorization_key_corrupt",
117
+ cause: error,
118
+ });
119
+ }
147
120
  }
148
121
  //# sourceMappingURL=key-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-store.js","sourceRoot":"","sources":["../../src/authorization/key-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"key-store.js","sourceRoot":"","sources":["../../src/authorization/key-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { DeviceKeyStore } from "./key-store.js";
2
+ export interface NativeKeyringEntry {
3
+ getPassword(): Promise<string | undefined>;
4
+ setPassword(password: string): Promise<void>;
5
+ deleteCredential(): Promise<boolean>;
6
+ }
7
+ export declare function createNativeKeyringStore(account: string): DeviceKeyStore;
8
+ export declare function createNativeKeyringStoreFromEntry(entry: NativeKeyringEntry): DeviceKeyStore;
@@ -0,0 +1,35 @@
1
+ const KEYRING_SERVICE = "com.amalgm.shell.authorization";
2
+ export function createNativeKeyringStore(account) {
3
+ let entry = null;
4
+ const loadEntry = () => {
5
+ entry ??= import("@napi-rs/keyring")
6
+ .then(({ AsyncEntry }) => new AsyncEntry(KEYRING_SERVICE, account));
7
+ return entry;
8
+ };
9
+ return createNativeKeyringStoreFromEntry({
10
+ getPassword: async () => (await loadEntry()).getPassword(),
11
+ setPassword: async (password) => (await loadEntry()).setPassword(password),
12
+ deleteCredential: async () => (await loadEntry()).deleteCredential(),
13
+ });
14
+ }
15
+ export function createNativeKeyringStoreFromEntry(entry) {
16
+ return {
17
+ load: async () => {
18
+ const value = await entry.getPassword();
19
+ if (!value)
20
+ return null;
21
+ try {
22
+ return JSON.parse(value);
23
+ }
24
+ catch (error) {
25
+ throw Object.assign(new Error("Stored authorization key is unreadable or corrupt"), {
26
+ code: "authorization_key_corrupt",
27
+ cause: error,
28
+ });
29
+ }
30
+ },
31
+ save: async (key) => entry.setPassword(JSON.stringify(key)),
32
+ remove: async () => { await entry.deleteCredential(); },
33
+ };
34
+ }
35
+ //# sourceMappingURL=native-keyring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-keyring.js","sourceRoot":"","sources":["../../src/authorization/native-keyring.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,gCAAgC,CAAC;AAQzD,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,IAAI,KAAK,GAAuC,IAAI,CAAC;IACrD,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,KAAK,KAAK,MAAM,CAAC,kBAAkB,CAAC;aACjC,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,OAAO,iCAAiC,CAAC;QACvC,WAAW,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,WAAW,EAAE;QAC1D,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC;QAC1E,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC,gBAAgB,EAAE;KACrE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,KAAyB;IACzE,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAoB,CAAC;YAC9C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,EAAE;oBAClF,IAAI,EAAE,2BAA2B;oBACjC,KAAK,EAAE,KAAK;iBACb,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC3D,MAAM,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;KACxD,CAAC;AACJ,CAAC"}
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@amalgm/shell",
3
- "version": "0.1.116",
3
+ "version": "0.1.118",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@amalgm/shell",
9
- "version": "0.1.116",
9
+ "version": "0.1.118",
10
10
  "license": "UNLICENSED",
11
11
  "dependencies": {
12
12
  "@amalgm/agents": "0.2.0",
@@ -19,6 +19,7 @@
19
19
  "@amalgm/tools": "0.1.3",
20
20
  "@anthropic-ai/claude-agent-sdk": "^0.3.224",
21
21
  "@homebridge/node-pty-prebuilt-multiarch": "0.13.1",
22
+ "@napi-rs/keyring": "1.3.0",
22
23
  "better-sqlite3": "12.11.1",
23
24
  "ws": "8.21.0"
24
25
  },
@@ -470,6 +471,212 @@
470
471
  }
471
472
  }
472
473
  },
474
+ "node_modules/@napi-rs/keyring": {
475
+ "version": "1.3.0",
476
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring/-/keyring-1.3.0.tgz",
477
+ "integrity": "sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==",
478
+ "engines": {
479
+ "node": ">= 10"
480
+ },
481
+ "funding": {
482
+ "type": "github",
483
+ "url": "https://github.com/sponsors/Brooooooklyn"
484
+ },
485
+ "optionalDependencies": {
486
+ "@napi-rs/keyring-darwin-arm64": "1.3.0",
487
+ "@napi-rs/keyring-darwin-x64": "1.3.0",
488
+ "@napi-rs/keyring-freebsd-x64": "1.3.0",
489
+ "@napi-rs/keyring-linux-arm-gnueabihf": "1.3.0",
490
+ "@napi-rs/keyring-linux-arm64-gnu": "1.3.0",
491
+ "@napi-rs/keyring-linux-arm64-musl": "1.3.0",
492
+ "@napi-rs/keyring-linux-riscv64-gnu": "1.3.0",
493
+ "@napi-rs/keyring-linux-x64-gnu": "1.3.0",
494
+ "@napi-rs/keyring-linux-x64-musl": "1.3.0",
495
+ "@napi-rs/keyring-win32-arm64-msvc": "1.3.0",
496
+ "@napi-rs/keyring-win32-ia32-msvc": "1.3.0",
497
+ "@napi-rs/keyring-win32-x64-msvc": "1.3.0"
498
+ }
499
+ },
500
+ "node_modules/@napi-rs/keyring-darwin-arm64": {
501
+ "version": "1.3.0",
502
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-arm64/-/keyring-darwin-arm64-1.3.0.tgz",
503
+ "integrity": "sha512-pl76hJvdYUBn6I24bXiOBMA9nbDapo3I5B+f3OorjDU4dUMSypXeKbOVehJe8fhgTiH24flMyTS3aAIy43xegQ==",
504
+ "cpu": [
505
+ "arm64"
506
+ ],
507
+ "optional": true,
508
+ "os": [
509
+ "darwin"
510
+ ],
511
+ "engines": {
512
+ "node": ">= 10"
513
+ }
514
+ },
515
+ "node_modules/@napi-rs/keyring-darwin-x64": {
516
+ "version": "1.3.0",
517
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-darwin-x64/-/keyring-darwin-x64-1.3.0.tgz",
518
+ "integrity": "sha512-YcJtEV5LA3cvA4z3BurgxH5IhTsW1JfIvcAAcqcecwk06Si9F9NqkxbZVIfDwQ8oRHgaBmT3zZJnLAotCrVahw==",
519
+ "cpu": [
520
+ "x64"
521
+ ],
522
+ "optional": true,
523
+ "os": [
524
+ "darwin"
525
+ ],
526
+ "engines": {
527
+ "node": ">= 10"
528
+ }
529
+ },
530
+ "node_modules/@napi-rs/keyring-freebsd-x64": {
531
+ "version": "1.3.0",
532
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-freebsd-x64/-/keyring-freebsd-x64-1.3.0.tgz",
533
+ "integrity": "sha512-vlLf31TGhfRAaxLDBhg8b89ss0HHD/lyNmL5F3UjSaz5CUXElsJmKYq9fqA/B+cZKUEUcLHHGhF0I/CqcFdaVw==",
534
+ "cpu": [
535
+ "x64"
536
+ ],
537
+ "optional": true,
538
+ "os": [
539
+ "freebsd"
540
+ ],
541
+ "engines": {
542
+ "node": ">= 10"
543
+ }
544
+ },
545
+ "node_modules/@napi-rs/keyring-linux-arm-gnueabihf": {
546
+ "version": "1.3.0",
547
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm-gnueabihf/-/keyring-linux-arm-gnueabihf-1.3.0.tgz",
548
+ "integrity": "sha512-KiWdMMu/Inz/bHHIAGrnF7r54FZDYXuHO6UFF/rhIrshUsxbMG1Rl9lEymNtqqsVo927G0VYcb02FzWQ3iBQRQ==",
549
+ "cpu": [
550
+ "arm"
551
+ ],
552
+ "optional": true,
553
+ "os": [
554
+ "linux"
555
+ ],
556
+ "engines": {
557
+ "node": ">= 10"
558
+ }
559
+ },
560
+ "node_modules/@napi-rs/keyring-linux-arm64-gnu": {
561
+ "version": "1.3.0",
562
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-gnu/-/keyring-linux-arm64-gnu-1.3.0.tgz",
563
+ "integrity": "sha512-eyKGpY40lm9Jvs1aD294XRH4y7+TlJM0YVAryZeXA6TX0mb4gMkxVXwSQv7MCwgah7raeUd0dKUb4BPAYIgcMg==",
564
+ "cpu": [
565
+ "arm64"
566
+ ],
567
+ "optional": true,
568
+ "os": [
569
+ "linux"
570
+ ],
571
+ "engines": {
572
+ "node": ">= 10"
573
+ }
574
+ },
575
+ "node_modules/@napi-rs/keyring-linux-arm64-musl": {
576
+ "version": "1.3.0",
577
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-arm64-musl/-/keyring-linux-arm64-musl-1.3.0.tgz",
578
+ "integrity": "sha512-iIK6JWHXAJqDrEyLY3TmswwloVyt2vj+04TZnew+uSJ9gnDO8EwRbp3/iw3LpWaXiDO7VomGO6y8I0Id8uBZSw==",
579
+ "cpu": [
580
+ "arm64"
581
+ ],
582
+ "optional": true,
583
+ "os": [
584
+ "linux"
585
+ ],
586
+ "engines": {
587
+ "node": ">= 10"
588
+ }
589
+ },
590
+ "node_modules/@napi-rs/keyring-linux-riscv64-gnu": {
591
+ "version": "1.3.0",
592
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-riscv64-gnu/-/keyring-linux-riscv64-gnu-1.3.0.tgz",
593
+ "integrity": "sha512-/PGqrwn6EwgtK6vccASSXJRfOSP4vN1F4ASsIQ+7MdrK6hNvAJ1FZPrIuD5gGGdxezo3F++To2Wq7DbuGIeuNQ==",
594
+ "cpu": [
595
+ "riscv64"
596
+ ],
597
+ "optional": true,
598
+ "os": [
599
+ "linux"
600
+ ],
601
+ "engines": {
602
+ "node": ">= 10"
603
+ }
604
+ },
605
+ "node_modules/@napi-rs/keyring-linux-x64-gnu": {
606
+ "version": "1.3.0",
607
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-gnu/-/keyring-linux-x64-gnu-1.3.0.tgz",
608
+ "integrity": "sha512-2PDK1WKWTu9lBGq9VvNEkSlQD3O7YwVpmnyN2M3cy4v7NJ/8gDMd9GXv3G+FVXN13uhp4gnnPBS+ScefmEeD2A==",
609
+ "cpu": [
610
+ "x64"
611
+ ],
612
+ "optional": true,
613
+ "os": [
614
+ "linux"
615
+ ],
616
+ "engines": {
617
+ "node": ">= 10"
618
+ }
619
+ },
620
+ "node_modules/@napi-rs/keyring-linux-x64-musl": {
621
+ "version": "1.3.0",
622
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-linux-x64-musl/-/keyring-linux-x64-musl-1.3.0.tgz",
623
+ "integrity": "sha512-oJ2HkX8YUo46QBkn0pG+HuIKQNqr523q6vBobCn+P95s4C4K6/kLBqHY/1bg5J4ap31DzsznhnFKcfBNBsjCnw==",
624
+ "cpu": [
625
+ "x64"
626
+ ],
627
+ "optional": true,
628
+ "os": [
629
+ "linux"
630
+ ],
631
+ "engines": {
632
+ "node": ">= 10"
633
+ }
634
+ },
635
+ "node_modules/@napi-rs/keyring-win32-arm64-msvc": {
636
+ "version": "1.3.0",
637
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-arm64-msvc/-/keyring-win32-arm64-msvc-1.3.0.tgz",
638
+ "integrity": "sha512-tOd3c/uAaeoE4ycVlmAdSvygz0Zt3zdca6Y7gokBeIbaRDWpjDIUOpU3MvML59XAaqyuKGsVVu0F/DZb1lHPmw==",
639
+ "cpu": [
640
+ "arm64"
641
+ ],
642
+ "optional": true,
643
+ "os": [
644
+ "win32"
645
+ ],
646
+ "engines": {
647
+ "node": ">= 10"
648
+ }
649
+ },
650
+ "node_modules/@napi-rs/keyring-win32-ia32-msvc": {
651
+ "version": "1.3.0",
652
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-ia32-msvc/-/keyring-win32-ia32-msvc-1.3.0.tgz",
653
+ "integrity": "sha512-sPSqeAFZMGqP1R++M2JTza7GQJJ/TpCo6JU6Vcd4jnebvOaEDs9b7eipakU1PJdSvhpC2yXMCNRk9gXfrhuwHQ==",
654
+ "cpu": [
655
+ "ia32"
656
+ ],
657
+ "optional": true,
658
+ "os": [
659
+ "win32"
660
+ ],
661
+ "engines": {
662
+ "node": ">= 10"
663
+ }
664
+ },
665
+ "node_modules/@napi-rs/keyring-win32-x64-msvc": {
666
+ "version": "1.3.0",
667
+ "resolved": "https://registry.npmjs.org/@napi-rs/keyring-win32-x64-msvc/-/keyring-win32-x64-msvc-1.3.0.tgz",
668
+ "integrity": "sha512-4DnCWXwDc0HRKwyRlG5y0VhKZW2tNRQfKKfyj6IX/KWfDNyq9hn4n+GL1auyDcOO/v8PwnhmYo2+rOOqCkvvOg==",
669
+ "cpu": [
670
+ "x64"
671
+ ],
672
+ "optional": true,
673
+ "os": [
674
+ "win32"
675
+ ],
676
+ "engines": {
677
+ "node": ">= 10"
678
+ }
679
+ },
473
680
  "node_modules/@openai/codex": {
474
681
  "version": "0.150.0",
475
682
  "resolved": "https://registry.npmjs.org/@openai/codex/-/codex-0.150.0.tgz",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amalgm/shell",
3
- "version": "0.1.116",
3
+ "version": "0.1.118",
4
4
  "description": "The Amalgm runtime host assembled from the published @amalgm SDK capabilities.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -54,6 +54,7 @@
54
54
  "@amalgm/tools": "0.1.3",
55
55
  "@anthropic-ai/claude-agent-sdk": "^0.3.224",
56
56
  "@homebridge/node-pty-prebuilt-multiarch": "0.13.1",
57
+ "@napi-rs/keyring": "1.3.0",
57
58
  "better-sqlite3": "12.11.1",
58
59
  "ws": "8.21.0"
59
60
  },