@zcloak/ai-agent 1.0.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 (80) hide show
  1. package/README.md +5 -0
  2. package/dist/bind.d.ts +22 -0
  3. package/dist/bind.js +145 -0
  4. package/dist/bind.js.map +1 -0
  5. package/dist/cli.d.ts +31 -0
  6. package/dist/cli.js +126 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config.d.ts +14 -0
  9. package/dist/config.js +34 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/crypto.d.ts +113 -0
  12. package/dist/crypto.js +252 -0
  13. package/dist/crypto.js.map +1 -0
  14. package/dist/daemon.d.ts +94 -0
  15. package/dist/daemon.js +271 -0
  16. package/dist/daemon.js.map +1 -0
  17. package/dist/delete.d.ts +22 -0
  18. package/dist/delete.js +231 -0
  19. package/dist/delete.js.map +1 -0
  20. package/dist/doc.d.ts +23 -0
  21. package/dist/doc.js +180 -0
  22. package/dist/doc.js.map +1 -0
  23. package/dist/error.d.ts +45 -0
  24. package/dist/error.js +79 -0
  25. package/dist/error.js.map +1 -0
  26. package/dist/feed.d.ts +20 -0
  27. package/dist/feed.js +83 -0
  28. package/dist/feed.js.map +1 -0
  29. package/dist/identity.d.ts +50 -0
  30. package/dist/identity.js +99 -0
  31. package/dist/identity.js.map +1 -0
  32. package/dist/identity_cmd.d.ts +23 -0
  33. package/dist/identity_cmd.js +136 -0
  34. package/dist/identity_cmd.js.map +1 -0
  35. package/dist/idl.d.ts +99 -0
  36. package/dist/idl.js +213 -0
  37. package/dist/idl.js.map +1 -0
  38. package/dist/key-store.d.ts +88 -0
  39. package/dist/key-store.js +171 -0
  40. package/dist/key-store.js.map +1 -0
  41. package/dist/pow.d.ts +24 -0
  42. package/dist/pow.js +86 -0
  43. package/dist/pow.js.map +1 -0
  44. package/dist/register.d.ts +24 -0
  45. package/dist/register.js +191 -0
  46. package/dist/register.js.map +1 -0
  47. package/dist/rpc.d.ts +107 -0
  48. package/dist/rpc.js +60 -0
  49. package/dist/rpc.js.map +1 -0
  50. package/dist/serve.d.ts +55 -0
  51. package/dist/serve.js +455 -0
  52. package/dist/serve.js.map +1 -0
  53. package/dist/session.d.ts +104 -0
  54. package/dist/session.js +189 -0
  55. package/dist/session.js.map +1 -0
  56. package/dist/sign.d.ts +33 -0
  57. package/dist/sign.js +355 -0
  58. package/dist/sign.js.map +1 -0
  59. package/dist/types/common.d.ts +63 -0
  60. package/dist/types/common.js +8 -0
  61. package/dist/types/common.js.map +1 -0
  62. package/dist/types/config.d.ts +28 -0
  63. package/dist/types/config.js +8 -0
  64. package/dist/types/config.js.map +1 -0
  65. package/dist/types/registry.d.ts +72 -0
  66. package/dist/types/registry.js +13 -0
  67. package/dist/types/registry.js.map +1 -0
  68. package/dist/types/sign-event.d.ts +134 -0
  69. package/dist/types/sign-event.js +13 -0
  70. package/dist/types/sign-event.js.map +1 -0
  71. package/dist/utils.d.ts +113 -0
  72. package/dist/utils.js +382 -0
  73. package/dist/utils.js.map +1 -0
  74. package/dist/verify.d.ts +23 -0
  75. package/dist/verify.js +207 -0
  76. package/dist/verify.js.map +1 -0
  77. package/dist/vetkey.d.ts +27 -0
  78. package/dist/vetkey.js +507 -0
  79. package/dist/vetkey.js.map +1 -0
  80. package/package.json +55 -0
package/dist/crypto.js ADDED
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ /**
3
+ * Cryptographic Primitives for VetKey Operations
4
+ *
5
+ * Two categories of operations:
6
+ *
7
+ * 1. IBE (Identity-Based Encryption) — Uses @dfinity/vetkeys for BLS12-381 operations.
8
+ * Used for per-operation Kind5 PrivatePost encryption.
9
+ *
10
+ * 2. AES-256-GCM — Uses Node.js built-in crypto module.
11
+ * Used for daemon mode fast file encryption/decryption.
12
+ * VKDA binary format: [magic "VKDA":4B][version:1B][nonce:12B][ciphertext+GCM tag]
13
+ *
14
+ * All formats are byte-level compatible with the Rust vetkey-tool implementation.
15
+ */
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.generateTransportKeypair = generateTransportKeypair;
21
+ exports.ibeEncrypt = ibeEncrypt;
22
+ exports.ibeDecrypt = ibeDecrypt;
23
+ exports.decryptVetkey = decryptVetkey;
24
+ exports.makeIbeIdentity = makeIbeIdentity;
25
+ exports.vetkeyToAes256 = vetkeyToAes256;
26
+ exports.aes256Encrypt = aes256Encrypt;
27
+ exports.aes256Decrypt = aes256Decrypt;
28
+ const crypto_1 = __importDefault(require("crypto"));
29
+ const vetkeys_1 = require("@dfinity/vetkeys");
30
+ const error_1 = require("./error");
31
+ // ============================================================================
32
+ // Constants
33
+ // ============================================================================
34
+ /** VKDA magic header bytes ("VKDA" in ASCII) */
35
+ const AES_DAEMON_MAGIC = Buffer.from([0x56, 0x4b, 0x44, 0x41]);
36
+ /** VKDA format version */
37
+ const AES_DAEMON_VERSION = 0x01;
38
+ /** AES-256-GCM nonce size in bytes */
39
+ const AES_GCM_NONCE_BYTES = 12;
40
+ /** AES-256-GCM authentication tag size in bytes */
41
+ const AES_GCM_TAG_BYTES = 16;
42
+ /** VKDA header overhead: magic(4) + version(1) + nonce(12) + tag(16) = 33 bytes */
43
+ const VKDA_OVERHEAD = 4 + 1 + AES_GCM_NONCE_BYTES + AES_GCM_TAG_BYTES;
44
+ /** HKDF domain separator for VetKey → AES-256 key derivation (must match Rust) */
45
+ const VETKEY_AES256_DOMAIN = "vetkey-aes256-file-encryption";
46
+ // ============================================================================
47
+ // IBE Operations (via @dfinity/vetkeys)
48
+ // ============================================================================
49
+ /**
50
+ * Generate an ephemeral transport key pair for secure VetKey delivery.
51
+ *
52
+ * The transport secret key is used to decrypt the EncryptedVetKey received
53
+ * from the canister. The public key is sent to the canister so it can
54
+ * encrypt the VetKey for this specific requester.
55
+ *
56
+ * @returns [transportSecretKey, transportPublicKeyBytes (48 bytes, compressed G1)]
57
+ */
58
+ function generateTransportKeypair() {
59
+ const tsk = vetkeys_1.TransportSecretKey.random();
60
+ const publicKeyBytes = tsk.publicKeyBytes();
61
+ return [tsk, publicKeyBytes];
62
+ }
63
+ /**
64
+ * IBE-encrypt plaintext using the derived public key and identity string.
65
+ *
66
+ * Uses the Fujisaki-Okamoto transform internally (handled by @dfinity/vetkeys).
67
+ * Output format: [header:8B][C1:96B][C2:32B][C3:plaintext_len+16B] (152 bytes overhead)
68
+ *
69
+ * @param dpkBytes - IBE derived public key (96 bytes, compressed G2 point)
70
+ * @param ibeIdentity - IBE identity string (e.g. "{principal}:{hash}:{timestamp}")
71
+ * @param plaintext - Data to encrypt
72
+ * @returns IBE ciphertext bytes
73
+ */
74
+ function ibeEncrypt(dpkBytes, ibeIdentity, plaintext) {
75
+ try {
76
+ const dpk = vetkeys_1.DerivedPublicKey.deserialize(dpkBytes);
77
+ const identity = vetkeys_1.IbeIdentity.fromString(ibeIdentity);
78
+ const seed = vetkeys_1.IbeSeed.random();
79
+ const ciphertext = vetkeys_1.IbeCiphertext.encrypt(dpk, identity, plaintext, seed);
80
+ return ciphertext.serialize();
81
+ }
82
+ catch (e) {
83
+ throw (0, error_1.encryptionError)(`IBE encrypt failed: ${e instanceof Error ? e.message : String(e)}`, e);
84
+ }
85
+ }
86
+ /**
87
+ * Full IBE decrypt: transport-decrypt VetKey, then IBE-decrypt ciphertext.
88
+ *
89
+ * Complete flow:
90
+ * 1. Deserialize EncryptedVetKey (192 bytes)
91
+ * 2. Transport-decrypt and verify BLS signature → VetKey
92
+ * 3. Deserialize IBE ciphertext
93
+ * 4. IBE-decrypt using VetKey → plaintext
94
+ *
95
+ * @param encryptedKeyBytes - Transport-encrypted VetKey (192 bytes)
96
+ * @param dpkBytes - IBE derived public key (96 bytes)
97
+ * @param ibeIdentity - IBE identity string
98
+ * @param ciphertextBytes - IBE ciphertext
99
+ * @param transportSecret - Transport secret key (for decrypting the VetKey)
100
+ * @returns Decrypted plaintext
101
+ */
102
+ function ibeDecrypt(encryptedKeyBytes, dpkBytes, ibeIdentity, ciphertextBytes, transportSecret) {
103
+ try {
104
+ // Step 1-2: Transport-decrypt the VetKey
105
+ const encryptedVetKey = vetkeys_1.EncryptedVetKey.deserialize(encryptedKeyBytes);
106
+ const dpk = vetkeys_1.DerivedPublicKey.deserialize(dpkBytes);
107
+ // decryptAndVerify expects raw bytes for the input (derivation ID / IBE identity)
108
+ const identityBytes = new TextEncoder().encode(ibeIdentity);
109
+ const vetKey = encryptedVetKey.decryptAndVerify(transportSecret, dpk, identityBytes);
110
+ // Step 3-4: IBE-decrypt the ciphertext
111
+ const ibeCiphertext = vetkeys_1.IbeCiphertext.deserialize(ciphertextBytes);
112
+ return ibeCiphertext.decrypt(vetKey);
113
+ }
114
+ catch (e) {
115
+ throw (0, error_1.decryptionError)(`IBE decrypt failed: ${e instanceof Error ? e.message : String(e)}`, e);
116
+ }
117
+ }
118
+ /**
119
+ * Transport-decrypt an EncryptedVetKey and return raw VetKey bytes.
120
+ *
121
+ * Used by daemon mode to obtain the VetKey for AES-256 key derivation.
122
+ * The derivation ID serves as the IBE identity in this context.
123
+ *
124
+ * @param encryptedKeyBytes - Transport-encrypted VetKey (192 bytes)
125
+ * @param dpkBytes - IBE derived public key (96 bytes)
126
+ * @param derivationId - Derivation ID string (used as IBE identity)
127
+ * @param transportSecret - Transport secret key
128
+ * @returns Raw VetKey bytes (48 bytes, compressed G1 point)
129
+ */
130
+ function decryptVetkey(encryptedKeyBytes, dpkBytes, derivationId, transportSecret) {
131
+ try {
132
+ const encryptedVetKey = vetkeys_1.EncryptedVetKey.deserialize(encryptedKeyBytes);
133
+ const dpk = vetkeys_1.DerivedPublicKey.deserialize(dpkBytes);
134
+ // decryptAndVerify expects raw bytes for the input (derivation ID)
135
+ const derivationIdBytes = new TextEncoder().encode(derivationId);
136
+ const vetKey = encryptedVetKey.decryptAndVerify(transportSecret, dpk, derivationIdBytes);
137
+ return vetKey.signatureBytes();
138
+ }
139
+ catch (e) {
140
+ throw (0, error_1.decryptionError)(`VetKey transport decryption failed: ${e instanceof Error ? e.message : String(e)}`, e);
141
+ }
142
+ }
143
+ // ============================================================================
144
+ // IBE Identity Generation
145
+ // ============================================================================
146
+ /**
147
+ * Generate an IBE identity string for Kind5 PrivatePost.
148
+ *
149
+ * Format: "{principal}:{short_hash_16_hex}:{timestamp_ms}"
150
+ * - short_hash: first 16 hex chars of SHA-256(content)
151
+ * - timestamp_ms: current time in milliseconds
152
+ *
153
+ * Must match the Rust implementation exactly for cross-compatibility.
154
+ *
155
+ * @param principal - ICP principal text
156
+ * @param content - Content bytes to hash
157
+ * @returns IBE identity string
158
+ */
159
+ function makeIbeIdentity(principal, content) {
160
+ const hash = crypto_1.default.createHash("sha256").update(content).digest("hex");
161
+ const shortHash = hash.slice(0, 16); // First 16 hex chars
162
+ const timestamp = Date.now();
163
+ return `${principal}:${shortHash}:${timestamp}`;
164
+ }
165
+ // ============================================================================
166
+ // AES-256-GCM Operations (Daemon Mode)
167
+ // ============================================================================
168
+ /**
169
+ * Derive an AES-256 key from VetKey bytes using HKDF-SHA256.
170
+ *
171
+ * Domain separator: "vetkey-aes256-file-encryption" (must match Rust implementation)
172
+ *
173
+ * @param vetkeyBytes - Raw VetKey bytes (48 bytes, compressed G1 point)
174
+ * @returns AES-256 key (32 bytes)
175
+ */
176
+ function vetkeyToAes256(vetkeyBytes) {
177
+ if (vetkeyBytes.length !== 48) {
178
+ throw (0, error_1.encryptionError)(`Invalid VetKey length: expected 48, got ${vetkeyBytes.length}`);
179
+ }
180
+ // HKDF-SHA256 with VetKey as IKM and domain separator as info
181
+ // Using empty salt (matches Rust hkdf::Hkdf::new(None, ikm))
182
+ return Buffer.from(crypto_1.default.hkdfSync("sha256", vetkeyBytes, Buffer.alloc(0), VETKEY_AES256_DOMAIN, 32));
183
+ }
184
+ /**
185
+ * Encrypt plaintext using AES-256-GCM in VKDA format.
186
+ *
187
+ * Output format: [magic "VKDA":4B][version 0x01:1B][nonce:12B][ciphertext+GCM tag]
188
+ * This format is byte-level compatible with the Rust vetkey-tool implementation.
189
+ *
190
+ * @param key - AES-256 key (32 bytes)
191
+ * @param plaintext - Data to encrypt
192
+ * @returns VKDA-formatted ciphertext
193
+ */
194
+ function aes256Encrypt(key, plaintext) {
195
+ // Generate random 12-byte nonce
196
+ const nonce = crypto_1.default.randomBytes(AES_GCM_NONCE_BYTES);
197
+ // Encrypt with AES-256-GCM
198
+ const cipher = crypto_1.default.createCipheriv("aes-256-gcm", key, nonce);
199
+ const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);
200
+ const tag = cipher.getAuthTag(); // 16 bytes
201
+ // Assemble VKDA format: magic + version + nonce + ciphertext + tag
202
+ return Buffer.concat([
203
+ AES_DAEMON_MAGIC,
204
+ Buffer.from([AES_DAEMON_VERSION]),
205
+ nonce,
206
+ encrypted,
207
+ tag,
208
+ ]);
209
+ }
210
+ /**
211
+ * Decrypt VKDA-formatted ciphertext using AES-256-GCM.
212
+ *
213
+ * Validates the VKDA magic header and version, then performs
214
+ * authenticated GCM decryption.
215
+ *
216
+ * @param key - AES-256 key (32 bytes)
217
+ * @param data - VKDA-formatted ciphertext
218
+ * @returns Decrypted plaintext
219
+ */
220
+ function aes256Decrypt(key, data) {
221
+ // Validate minimum size
222
+ if (data.length < VKDA_OVERHEAD) {
223
+ throw (0, error_1.decryptionError)(`Data too short: ${data.length} bytes (minimum ${VKDA_OVERHEAD} bytes for VKDA format)`);
224
+ }
225
+ // Validate magic header
226
+ if (data[0] !== 0x56 || // 'V'
227
+ data[1] !== 0x4b || // 'K'
228
+ data[2] !== 0x44 || // 'D'
229
+ data[3] !== 0x41 // 'A'
230
+ ) {
231
+ throw (0, error_1.decryptionError)("Invalid VKDA magic header (expected 'VKDA')");
232
+ }
233
+ // Validate version
234
+ if (data[4] !== AES_DAEMON_VERSION) {
235
+ throw (0, error_1.decryptionError)(`Unsupported VKDA version: ${data[4]} (expected ${AES_DAEMON_VERSION})`);
236
+ }
237
+ // Extract components
238
+ const nonce = data.subarray(5, 5 + AES_GCM_NONCE_BYTES); // bytes 5-16
239
+ const ciphertextWithTag = data.subarray(5 + AES_GCM_NONCE_BYTES); // bytes 17+
240
+ const ciphertext = ciphertextWithTag.subarray(0, ciphertextWithTag.length - AES_GCM_TAG_BYTES);
241
+ const tag = ciphertextWithTag.subarray(ciphertextWithTag.length - AES_GCM_TAG_BYTES);
242
+ // Decrypt with AES-256-GCM
243
+ try {
244
+ const decipher = crypto_1.default.createDecipheriv("aes-256-gcm", key, nonce);
245
+ decipher.setAuthTag(tag);
246
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
247
+ }
248
+ catch (e) {
249
+ throw (0, error_1.decryptionError)(`AES-256-GCM decryption failed (authentication tag mismatch or corrupted data): ${e instanceof Error ? e.message : String(e)}`, e);
250
+ }
251
+ }
252
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Daemon Lifecycle Management — PID file, socket path, runtime directory
3
+ *
4
+ * Manages the daemon's file system footprint:
5
+ * - Runtime directory: ~/.vetkey-tool/ (created with 0o700 permissions)
6
+ * - PID file: ~/.vetkey-tool/{sanitized_id}.pid
7
+ * - Socket file: ~/.vetkey-tool/{sanitized_id}.sock
8
+ *
9
+ * Prevents duplicate daemon instances by checking PID files and verifying
10
+ * whether the process is still alive. Stale PID/socket files from crashed
11
+ * daemons are automatically cleaned up.
12
+ *
13
+ * The DaemonRuntime class implements cleanup-on-drop semantics via
14
+ * process exit handlers, ensuring PID and socket files are removed
15
+ * even on unexpected termination (SIGTERM, SIGINT, uncaught exceptions).
16
+ */
17
+ /** Get the runtime directory path (~/.vetkey-tool/) */
18
+ export declare function runtimeDir(): string;
19
+ /**
20
+ * Sanitize a derivation ID for use in file names.
21
+ *
22
+ * Replaces special characters (:, /, \) with underscores.
23
+ * If the resulting path would exceed the Unix socket path limit,
24
+ * falls back to a SHA-256 hash prefix (16 hex characters) to keep
25
+ * the path short enough.
26
+ *
27
+ * @param derivationId - Raw derivation ID (e.g. "abc-def:default")
28
+ * @returns Safe file name prefix
29
+ */
30
+ export declare function sanitizeDerivationId(derivationId: string): string;
31
+ /** Get the socket file path for a derivation ID */
32
+ export declare function socketPath(derivationId: string): string;
33
+ /** Get the PID file path for a derivation ID */
34
+ export declare function pidPath(derivationId: string): string;
35
+ /**
36
+ * Manages the lifecycle of a daemon instance.
37
+ *
38
+ * On creation:
39
+ * - Creates the runtime directory if needed
40
+ * - Checks for existing running instances (PID file + process alive check)
41
+ * - Cleans up stale PID/socket files from crashed daemons
42
+ * - Writes the current PID to the PID file
43
+ *
44
+ * On cleanup (via destroy() or process exit handlers):
45
+ * - Removes the PID file
46
+ * - Removes the socket file
47
+ */
48
+ export declare class DaemonRuntime {
49
+ private _socketPath;
50
+ private _pidPath;
51
+ private _derivationId;
52
+ private cleanedUp;
53
+ /** Bound cleanup handler for process exit events */
54
+ private exitHandler;
55
+ private constructor();
56
+ /**
57
+ * Create a new DaemonRuntime, performing all startup checks.
58
+ *
59
+ * @param derivationId - Derivation ID for this daemon instance
60
+ * @returns Initialized DaemonRuntime
61
+ * @throws ToolError with code DAEMON if another instance is already running
62
+ */
63
+ static create(derivationId: string): DaemonRuntime;
64
+ /** Socket file path */
65
+ get socketFilePath(): string;
66
+ /** PID file path */
67
+ get pidFilePath(): string;
68
+ /** Derivation ID */
69
+ get derivationId(): string;
70
+ /**
71
+ * Clean up PID and socket files.
72
+ *
73
+ * Safe to call multiple times — subsequent calls are no-ops.
74
+ * Called automatically on process exit.
75
+ */
76
+ cleanup(): void;
77
+ /**
78
+ * Explicitly destroy the runtime (alias for cleanup).
79
+ * Removes PID and socket files, unregisters handlers.
80
+ */
81
+ destroy(): void;
82
+ }
83
+ /**
84
+ * Find the socket path for a running daemon (used by stop/status commands).
85
+ *
86
+ * Checks if the socket file exists and the daemon is actually running
87
+ * (via PID file check).
88
+ *
89
+ * @param derivationId - Derivation ID to look up
90
+ * @returns Socket path if daemon is running
91
+ * @throws ToolError if no running daemon is found
92
+ */
93
+ export declare function findRunningDaemon(derivationId: string): string;
94
+ //# sourceMappingURL=daemon.d.ts.map
package/dist/daemon.js ADDED
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /**
3
+ * Daemon Lifecycle Management — PID file, socket path, runtime directory
4
+ *
5
+ * Manages the daemon's file system footprint:
6
+ * - Runtime directory: ~/.vetkey-tool/ (created with 0o700 permissions)
7
+ * - PID file: ~/.vetkey-tool/{sanitized_id}.pid
8
+ * - Socket file: ~/.vetkey-tool/{sanitized_id}.sock
9
+ *
10
+ * Prevents duplicate daemon instances by checking PID files and verifying
11
+ * whether the process is still alive. Stale PID/socket files from crashed
12
+ * daemons are automatically cleaned up.
13
+ *
14
+ * The DaemonRuntime class implements cleanup-on-drop semantics via
15
+ * process exit handlers, ensuring PID and socket files are removed
16
+ * even on unexpected termination (SIGTERM, SIGINT, uncaught exceptions).
17
+ */
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.DaemonRuntime = void 0;
23
+ exports.runtimeDir = runtimeDir;
24
+ exports.sanitizeDerivationId = sanitizeDerivationId;
25
+ exports.socketPath = socketPath;
26
+ exports.pidPath = pidPath;
27
+ exports.findRunningDaemon = findRunningDaemon;
28
+ const fs_1 = require("fs");
29
+ const path_1 = require("path");
30
+ const os_1 = require("os");
31
+ const crypto_1 = __importDefault(require("crypto"));
32
+ const error_1 = require("./error");
33
+ /** Runtime directory name under home directory */
34
+ const RUNTIME_DIR_NAME = ".vetkey-tool";
35
+ /**
36
+ * Maximum socket path length.
37
+ * macOS limits Unix socket paths to 104 bytes, Linux to 108 bytes.
38
+ * We use 100 as a safe threshold.
39
+ */
40
+ const MAX_SOCKET_PATH_LEN = 100;
41
+ // ============================================================================
42
+ // Path Utilities
43
+ // ============================================================================
44
+ /** Get the runtime directory path (~/.vetkey-tool/) */
45
+ function runtimeDir() {
46
+ return (0, path_1.join)((0, os_1.homedir)(), RUNTIME_DIR_NAME);
47
+ }
48
+ /**
49
+ * Sanitize a derivation ID for use in file names.
50
+ *
51
+ * Replaces special characters (:, /, \) with underscores.
52
+ * If the resulting path would exceed the Unix socket path limit,
53
+ * falls back to a SHA-256 hash prefix (16 hex characters) to keep
54
+ * the path short enough.
55
+ *
56
+ * @param derivationId - Raw derivation ID (e.g. "abc-def:default")
57
+ * @returns Safe file name prefix
58
+ */
59
+ function sanitizeDerivationId(derivationId) {
60
+ const sanitized = derivationId
61
+ .replace(/:/g, "_")
62
+ .replace(/\//g, "_")
63
+ .replace(/\\/g, "_");
64
+ // Check if the full socket path would be too long
65
+ const dir = runtimeDir();
66
+ const fullPath = (0, path_1.join)(dir, `${sanitized}.sock`);
67
+ if (fullPath.length > MAX_SOCKET_PATH_LEN) {
68
+ // Use SHA-256 hash prefix for long derivation IDs
69
+ const hash = crypto_1.default.createHash("sha256").update(derivationId).digest("hex");
70
+ return `vk_${hash.slice(0, 16)}`;
71
+ }
72
+ return sanitized;
73
+ }
74
+ /** Get the socket file path for a derivation ID */
75
+ function socketPath(derivationId) {
76
+ const name = sanitizeDerivationId(derivationId);
77
+ return (0, path_1.join)(runtimeDir(), `${name}.sock`);
78
+ }
79
+ /** Get the PID file path for a derivation ID */
80
+ function pidPath(derivationId) {
81
+ const name = sanitizeDerivationId(derivationId);
82
+ return (0, path_1.join)(runtimeDir(), `${name}.pid`);
83
+ }
84
+ // ============================================================================
85
+ // Process Detection
86
+ // ============================================================================
87
+ /**
88
+ * Check if a process with the given PID is still alive.
89
+ *
90
+ * Uses `kill -0` which checks process existence without sending a signal.
91
+ * Works on both macOS and Linux without requiring native dependencies.
92
+ *
93
+ * @param pid - Process ID to check
94
+ * @returns true if the process exists, false otherwise
95
+ */
96
+ function isProcessAlive(pid) {
97
+ try {
98
+ // kill -0 checks existence without actually sending a signal
99
+ process.kill(pid, 0);
100
+ return true;
101
+ }
102
+ catch (e) {
103
+ // EPERM = process exists but we don't have permission → still alive
104
+ if (e && typeof e === "object" && "code" in e && e.code === "EPERM") {
105
+ return true;
106
+ }
107
+ // ESRCH = no such process → dead
108
+ return false;
109
+ }
110
+ }
111
+ // ============================================================================
112
+ // DaemonRuntime
113
+ // ============================================================================
114
+ /**
115
+ * Manages the lifecycle of a daemon instance.
116
+ *
117
+ * On creation:
118
+ * - Creates the runtime directory if needed
119
+ * - Checks for existing running instances (PID file + process alive check)
120
+ * - Cleans up stale PID/socket files from crashed daemons
121
+ * - Writes the current PID to the PID file
122
+ *
123
+ * On cleanup (via destroy() or process exit handlers):
124
+ * - Removes the PID file
125
+ * - Removes the socket file
126
+ */
127
+ class DaemonRuntime {
128
+ constructor(socketFilePath, pidFilePath, derivationId) {
129
+ this.cleanedUp = false;
130
+ this._socketPath = socketFilePath;
131
+ this._pidPath = pidFilePath;
132
+ this._derivationId = derivationId;
133
+ // Register cleanup handler for process exit
134
+ this.exitHandler = () => this.cleanup();
135
+ process.on("exit", this.exitHandler);
136
+ // Note: SIGTERM/SIGINT signal handlers are managed by serve.ts
137
+ // to coordinate with the server shutdown. We only handle 'exit' here.
138
+ }
139
+ /**
140
+ * Create a new DaemonRuntime, performing all startup checks.
141
+ *
142
+ * @param derivationId - Derivation ID for this daemon instance
143
+ * @returns Initialized DaemonRuntime
144
+ * @throws ToolError with code DAEMON if another instance is already running
145
+ */
146
+ static create(derivationId) {
147
+ const dir = runtimeDir();
148
+ const sock = socketPath(derivationId);
149
+ const pid = pidPath(derivationId);
150
+ // Create runtime directory with restricted permissions (0o700)
151
+ if (!(0, fs_1.existsSync)(dir)) {
152
+ (0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
153
+ }
154
+ // Check for existing running instance
155
+ if ((0, fs_1.existsSync)(pid)) {
156
+ try {
157
+ const pidStr = (0, fs_1.readFileSync)(pid, "utf-8").trim();
158
+ const existingPid = parseInt(pidStr, 10);
159
+ if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
160
+ throw (0, error_1.daemonError)(`Daemon already running (PID ${existingPid}, derivation_id: ${derivationId}). ` +
161
+ `Use 'zcloak-ai vetkey stop --key-name ...' to stop it first.`);
162
+ }
163
+ // Stale PID file — clean up
164
+ console.error(`Removing stale PID file (PID ${pidStr} no longer running)`);
165
+ }
166
+ catch (e) {
167
+ // Re-throw ToolError (daemon already running)
168
+ if (e instanceof Error && e.name === "ToolError")
169
+ throw e;
170
+ // Other errors (corrupted PID file) — just clean up
171
+ console.error(`Removing corrupted PID file: ${e}`);
172
+ }
173
+ safeUnlink(pid);
174
+ safeUnlink(sock);
175
+ }
176
+ // Remove stale socket file if it exists without a PID file
177
+ if ((0, fs_1.existsSync)(sock)) {
178
+ console.error("Removing stale socket file");
179
+ safeUnlink(sock);
180
+ }
181
+ // Write current PID to PID file
182
+ (0, fs_1.writeFileSync)(pid, `${process.pid}\n`, { mode: 0o600 });
183
+ return new DaemonRuntime(sock, pid, derivationId);
184
+ }
185
+ /** Socket file path */
186
+ get socketFilePath() {
187
+ return this._socketPath;
188
+ }
189
+ /** PID file path */
190
+ get pidFilePath() {
191
+ return this._pidPath;
192
+ }
193
+ /** Derivation ID */
194
+ get derivationId() {
195
+ return this._derivationId;
196
+ }
197
+ /**
198
+ * Clean up PID and socket files.
199
+ *
200
+ * Safe to call multiple times — subsequent calls are no-ops.
201
+ * Called automatically on process exit.
202
+ */
203
+ cleanup() {
204
+ if (this.cleanedUp)
205
+ return;
206
+ this.cleanedUp = true;
207
+ safeUnlink(this._pidPath);
208
+ safeUnlink(this._socketPath);
209
+ // Unregister process exit handler
210
+ process.removeListener("exit", this.exitHandler);
211
+ }
212
+ /**
213
+ * Explicitly destroy the runtime (alias for cleanup).
214
+ * Removes PID and socket files, unregisters handlers.
215
+ */
216
+ destroy() {
217
+ this.cleanup();
218
+ }
219
+ }
220
+ exports.DaemonRuntime = DaemonRuntime;
221
+ /**
222
+ * Find the socket path for a running daemon (used by stop/status commands).
223
+ *
224
+ * Checks if the socket file exists and the daemon is actually running
225
+ * (via PID file check).
226
+ *
227
+ * @param derivationId - Derivation ID to look up
228
+ * @returns Socket path if daemon is running
229
+ * @throws ToolError if no running daemon is found
230
+ */
231
+ function findRunningDaemon(derivationId) {
232
+ const sock = socketPath(derivationId);
233
+ const pid = pidPath(derivationId);
234
+ if (!(0, fs_1.existsSync)(sock)) {
235
+ throw (0, error_1.daemonError)(`No running daemon found for derivation_id '${derivationId}'. ` +
236
+ `Socket file not found: ${sock}`);
237
+ }
238
+ // Optionally verify the PID is still alive
239
+ if ((0, fs_1.existsSync)(pid)) {
240
+ try {
241
+ const pidStr = (0, fs_1.readFileSync)(pid, "utf-8").trim();
242
+ const existingPid = parseInt(pidStr, 10);
243
+ if (!isNaN(existingPid) && !isProcessAlive(existingPid)) {
244
+ // Stale files — clean up
245
+ safeUnlink(sock);
246
+ safeUnlink(pid);
247
+ throw (0, error_1.daemonError)(`Daemon for '${derivationId}' is no longer running (PID ${existingPid} is dead). ` +
248
+ `Stale files have been cleaned up.`);
249
+ }
250
+ }
251
+ catch (e) {
252
+ if (e instanceof Error && e.name === "ToolError")
253
+ throw e;
254
+ // Corrupted PID file but socket exists — try connecting anyway
255
+ }
256
+ }
257
+ return sock;
258
+ }
259
+ // ============================================================================
260
+ // Internal Helpers
261
+ // ============================================================================
262
+ /** Safely delete a file, ignoring errors if it doesn't exist */
263
+ function safeUnlink(filePath) {
264
+ try {
265
+ (0, fs_1.unlinkSync)(filePath);
266
+ }
267
+ catch {
268
+ // Ignore — file may not exist
269
+ }
270
+ }
271
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;AAuBH,gCAEC;AAaD,oDAgBC;AAGD,gCAGC;AAGD,0BAGC;AA6KD,8CAgCC;AA7QD,2BAAoF;AACpF,+BAA4B;AAC5B,2BAA6B;AAC7B,oDAA4B;AAC5B,mCAAsC;AAEtC,kDAAkD;AAClD,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,uDAAuD;AACvD,SAAgB,UAAU;IACxB,OAAO,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,gBAAgB,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAAC,YAAoB;IACvD,MAAM,SAAS,GAAG,YAAY;SAC3B,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEvB,kDAAkD;IAClD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QAC1C,kDAAkD;QAClD,MAAM,IAAI,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,mDAAmD;AACnD,SAAgB,UAAU,CAAC,YAAoB;IAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,OAAO,IAAA,WAAI,EAAC,UAAU,EAAE,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,gDAAgD;AAChD,SAAgB,OAAO,CAAC,YAAoB;IAC1C,MAAM,IAAI,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,OAAO,IAAA,WAAI,EAAC,UAAU,EAAE,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,6DAA6D;QAC7D,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,oEAAoE;QACpE,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,IAAK,CAA2B,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC/F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,iCAAiC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E;;;;;;;;;;;;GAYG;AACH,MAAa,aAAa;IASxB,YAAoB,cAAsB,EAAE,WAAmB,EAAE,YAAoB;QAL7E,cAAS,GAAG,KAAK,CAAC;QAMxB,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC;QAClC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAElC,4CAA4C;QAC5C,IAAI,CAAC,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACxC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACrC,+DAA+D;QAC/D,sEAAsE;IACxE,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,YAAoB;QAChC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QAElC,+DAA+D;QAC/D,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACrB,IAAA,cAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,sCAAsC;QACtC,IAAI,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAA,iBAAY,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;gBACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAEzC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;oBACvD,MAAM,IAAA,mBAAW,EACf,+BAA+B,WAAW,oBAAoB,YAAY,KAAK;wBAC/E,8DAA8D,CAC/D,CAAC;gBACJ,CAAC;gBAED,4BAA4B;gBAC5B,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,qBAAqB,CAAC,CAAC;YAC7E,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,8CAA8C;gBAC9C,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;oBAAE,MAAM,CAAC,CAAC;gBAC1D,oDAAoD;gBACpD,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,UAAU,CAAC,GAAG,CAAC,CAAC;YAChB,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,2DAA2D;QAC3D,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC5C,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,gCAAgC;QAChC,IAAA,kBAAa,EAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAExD,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IACpD,CAAC;IAED,uBAAuB;IACvB,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,oBAAoB;IACpB,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,oBAAoB;IACpB,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE7B,kCAAkC;QAClC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF;AAlHD,sCAkHC;AAED;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAAC,YAAoB;IACpD,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAElC,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAA,mBAAW,EACf,8CAA8C,YAAY,KAAK;YAC/D,0BAA0B,IAAI,EAAE,CACjC,CAAC;IACJ,CAAC;IAED,2CAA2C;IAC3C,IAAI,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAA,iBAAY,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;gBACxD,yBAAyB;gBACzB,UAAU,CAAC,IAAI,CAAC,CAAC;gBACjB,UAAU,CAAC,GAAG,CAAC,CAAC;gBAChB,MAAM,IAAA,mBAAW,EACf,eAAe,YAAY,+BAA+B,WAAW,aAAa;oBAClF,mCAAmC,CACpC,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW;gBAAE,MAAM,CAAC,CAAC;YAC1D,+DAA+D;QACjE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,gEAAgE;AAChE,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,CAAC;QACH,IAAA,eAAU,EAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * zCloak.ai File Deletion with 2FA Verification Tool
4
+ *
5
+ * Implements secure file deletion requiring 2FA (WebAuthn passkey) authorization.
6
+ * The deletion flow: prepare → user authenticates via browser → confirm & delete.
7
+ * Uses @dfinity JS SDK to interact directly with ICP canister, no dfx required.
8
+ *
9
+ * Usage:
10
+ * zcloak-ai delete prepare <file_path> Prepare 2FA request and generate authentication URL
11
+ * zcloak-ai delete check <challenge> Check 2FA verification status
12
+ * zcloak-ai delete confirm <challenge> <file_path> Confirm 2FA and delete file if authorized
13
+ *
14
+ * All commands support --identity=<pem_path> to specify identity file.
15
+ */
16
+ import { Session } from './session';
17
+ /**
18
+ * Entry point when invoked via cli.ts.
19
+ * Receives a Session instance with pre-parsed arguments.
20
+ */
21
+ export declare function run(session: Session): Promise<void>;
22
+ //# sourceMappingURL=delete.d.ts.map