happy-coder 0.10.0-3 → 0.10.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.
- package/README.md +10 -1
- package/dist/{index-DPVbp4Yx.mjs → index-BI37NnoW.mjs} +93 -87
- package/dist/{index-tqOLc1Il.cjs → index-ettJex_e.cjs} +115 -87
- package/dist/index.cjs +3 -2
- package/dist/index.mjs +3 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +44 -110
- package/dist/lib.d.mts +44 -110
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-C07HQlsW.mjs → runCodex-HlLNepHI.mjs} +47 -6
- package/dist/{runCodex-BxLD6H6G.cjs → runCodex-QdQBx9HK.cjs} +47 -6
- package/dist/{types-xds_c-JJ.mjs → types-8Ad05p3x.mjs} +213 -166
- package/dist/{types-CsJGQvQ3.cjs → types-CQOz_mPp.cjs} +214 -166
- package/package.json +5 -2
|
@@ -7,7 +7,7 @@ import { join, basename } from 'node:path';
|
|
|
7
7
|
import { readFile, open, stat, unlink, mkdir, writeFile, rename } from 'node:fs/promises';
|
|
8
8
|
import * as z from 'zod';
|
|
9
9
|
import { z as z$1 } from 'zod';
|
|
10
|
-
import { randomBytes, randomUUID } from 'node:crypto';
|
|
10
|
+
import { randomBytes, createCipheriv, createDecipheriv, randomUUID } from 'node:crypto';
|
|
11
11
|
import tweetnacl from 'tweetnacl';
|
|
12
12
|
import { EventEmitter } from 'node:events';
|
|
13
13
|
import { io } from 'socket.io-client';
|
|
@@ -21,7 +21,7 @@ import { platform } from 'os';
|
|
|
21
21
|
import { Expo } from 'expo-server-sdk';
|
|
22
22
|
|
|
23
23
|
var name = "happy-coder";
|
|
24
|
-
var version = "0.10.0
|
|
24
|
+
var version = "0.10.0";
|
|
25
25
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
26
26
|
var author = "Kirill Dubovitskiy";
|
|
27
27
|
var license = "MIT";
|
|
@@ -81,7 +81,7 @@ var scripts = {
|
|
|
81
81
|
build: "shx rm -rf dist && npx tsc --noEmit && pkgroll",
|
|
82
82
|
test: "yarn build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
|
|
83
83
|
start: "yarn build && ./bin/happy.mjs",
|
|
84
|
-
dev: "
|
|
84
|
+
dev: "tsx --env-file .env.dev src/index.ts",
|
|
85
85
|
"dev:local-server": "yarn build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
86
86
|
"dev:integration-test-env": "yarn build && tsx --env-file .env.integration-test src/index.ts",
|
|
87
87
|
prepublishOnly: "yarn build && yarn test",
|
|
@@ -93,11 +93,13 @@ var dependencies = {
|
|
|
93
93
|
"@anthropic-ai/sdk": "^0.56.0",
|
|
94
94
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
95
95
|
"@stablelib/base64": "^2.0.1",
|
|
96
|
+
"@stablelib/hex": "^2.0.1",
|
|
96
97
|
"@types/cross-spawn": "^6.0.6",
|
|
97
98
|
"@types/http-proxy": "^1.17.16",
|
|
98
99
|
"@types/ps-list": "^6.2.1",
|
|
99
100
|
"@types/qrcode-terminal": "^0.12.2",
|
|
100
101
|
"@types/react": "^19.1.9",
|
|
102
|
+
"@types/tmp": "^0.2.6",
|
|
101
103
|
axios: "^1.10.0",
|
|
102
104
|
chalk: "^5.4.1",
|
|
103
105
|
"cross-spawn": "^7.0.6",
|
|
@@ -113,6 +115,7 @@ var dependencies = {
|
|
|
113
115
|
react: "^19.1.1",
|
|
114
116
|
"socket.io-client": "^4.8.1",
|
|
115
117
|
tar: "^7.4.3",
|
|
118
|
+
tmp: "^0.2.5",
|
|
116
119
|
tweetnacl: "^1.0.3",
|
|
117
120
|
zod: "^3.23.8"
|
|
118
121
|
};
|
|
@@ -166,6 +169,7 @@ var packageJson = {
|
|
|
166
169
|
|
|
167
170
|
class Configuration {
|
|
168
171
|
serverUrl;
|
|
172
|
+
webappUrl;
|
|
169
173
|
isDaemonProcess;
|
|
170
174
|
// Directories and paths (from persistence)
|
|
171
175
|
happyHomeDir;
|
|
@@ -178,6 +182,7 @@ class Configuration {
|
|
|
178
182
|
isExperimentalEnabled;
|
|
179
183
|
constructor() {
|
|
180
184
|
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://api.cluster-fluster.com";
|
|
185
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://app.happy.engineering";
|
|
181
186
|
const args = process.argv.slice(2);
|
|
182
187
|
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
183
188
|
if (process.env.HAPPY_HOME_DIR) {
|
|
@@ -222,7 +227,17 @@ function decodeBase64(base64, variant = "base64") {
|
|
|
222
227
|
function getRandomBytes(size) {
|
|
223
228
|
return new Uint8Array(randomBytes(size));
|
|
224
229
|
}
|
|
225
|
-
function
|
|
230
|
+
function libsodiumEncryptForPublicKey(data, recipientPublicKey) {
|
|
231
|
+
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
232
|
+
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
233
|
+
const encrypted = tweetnacl.box(data, nonce, recipientPublicKey, ephemeralKeyPair.secretKey);
|
|
234
|
+
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
235
|
+
result.set(ephemeralKeyPair.publicKey, 0);
|
|
236
|
+
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
237
|
+
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
function encryptLegacy(data, secret) {
|
|
226
241
|
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
227
242
|
const encrypted = tweetnacl.secretbox(new TextEncoder().encode(JSON.stringify(data)), nonce, secret);
|
|
228
243
|
const result = new Uint8Array(nonce.length + encrypted.length);
|
|
@@ -230,7 +245,7 @@ function encrypt(data, secret) {
|
|
|
230
245
|
result.set(encrypted, nonce.length);
|
|
231
246
|
return result;
|
|
232
247
|
}
|
|
233
|
-
function
|
|
248
|
+
function decryptLegacy(data, secret) {
|
|
234
249
|
const nonce = data.slice(0, tweetnacl.secretbox.nonceLength);
|
|
235
250
|
const encrypted = data.slice(tweetnacl.secretbox.nonceLength);
|
|
236
251
|
const decrypted = tweetnacl.secretbox.open(encrypted, nonce, secret);
|
|
@@ -239,6 +254,61 @@ function decrypt(data, secret) {
|
|
|
239
254
|
}
|
|
240
255
|
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
241
256
|
}
|
|
257
|
+
function encryptWithDataKey(data, dataKey) {
|
|
258
|
+
const nonce = getRandomBytes(12);
|
|
259
|
+
const cipher = createCipheriv("aes-256-gcm", dataKey, nonce);
|
|
260
|
+
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
261
|
+
const encrypted = Buffer.concat([
|
|
262
|
+
cipher.update(plaintext),
|
|
263
|
+
cipher.final()
|
|
264
|
+
]);
|
|
265
|
+
const authTag = cipher.getAuthTag();
|
|
266
|
+
const bundle = new Uint8Array(12 + encrypted.length + 16 + 1);
|
|
267
|
+
bundle.set([0], 0);
|
|
268
|
+
bundle.set(nonce, 1);
|
|
269
|
+
bundle.set(new Uint8Array(encrypted), 13);
|
|
270
|
+
bundle.set(new Uint8Array(authTag), 13 + encrypted.length);
|
|
271
|
+
return bundle;
|
|
272
|
+
}
|
|
273
|
+
function decryptWithDataKey(bundle, dataKey) {
|
|
274
|
+
if (bundle.length < 1) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
if (bundle[0] !== 0) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
if (bundle.length < 12 + 16 + 1) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
const nonce = bundle.slice(1, 13);
|
|
284
|
+
const authTag = bundle.slice(bundle.length - 16);
|
|
285
|
+
const ciphertext = bundle.slice(13, bundle.length - 16);
|
|
286
|
+
try {
|
|
287
|
+
const decipher = createDecipheriv("aes-256-gcm", dataKey, nonce);
|
|
288
|
+
decipher.setAuthTag(authTag);
|
|
289
|
+
const decrypted = Buffer.concat([
|
|
290
|
+
decipher.update(ciphertext),
|
|
291
|
+
decipher.final()
|
|
292
|
+
]);
|
|
293
|
+
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function encrypt(key, variant, data) {
|
|
299
|
+
if (variant === "legacy") {
|
|
300
|
+
return encryptLegacy(data, key);
|
|
301
|
+
} else {
|
|
302
|
+
return encryptWithDataKey(data, key);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function decrypt(key, variant, data) {
|
|
306
|
+
if (variant === "legacy") {
|
|
307
|
+
return decryptLegacy(data, key);
|
|
308
|
+
} else {
|
|
309
|
+
return decryptWithDataKey(data, key);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
242
312
|
|
|
243
313
|
const defaultSettings = {
|
|
244
314
|
onboardingCompleted: false
|
|
@@ -302,8 +372,13 @@ async function updateSettings(updater) {
|
|
|
302
372
|
}
|
|
303
373
|
}
|
|
304
374
|
const credentialsSchema = z.object({
|
|
305
|
-
|
|
306
|
-
|
|
375
|
+
token: z.string(),
|
|
376
|
+
secret: z.string().base64().nullish(),
|
|
377
|
+
// Legacy
|
|
378
|
+
encryption: z.object({
|
|
379
|
+
publicKey: z.string().base64(),
|
|
380
|
+
machineKey: z.string().base64()
|
|
381
|
+
}).nullish()
|
|
307
382
|
});
|
|
308
383
|
async function readCredentials() {
|
|
309
384
|
if (!existsSync(configuration.privateKeyFile)) {
|
|
@@ -312,15 +387,30 @@ async function readCredentials() {
|
|
|
312
387
|
try {
|
|
313
388
|
const keyBase64 = await readFile(configuration.privateKeyFile, "utf8");
|
|
314
389
|
const credentials = credentialsSchema.parse(JSON.parse(keyBase64));
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
390
|
+
if (credentials.secret) {
|
|
391
|
+
return {
|
|
392
|
+
token: credentials.token,
|
|
393
|
+
encryption: {
|
|
394
|
+
type: "legacy",
|
|
395
|
+
secret: new Uint8Array(Buffer.from(credentials.secret, "base64"))
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
} else if (credentials.encryption) {
|
|
399
|
+
return {
|
|
400
|
+
token: credentials.token,
|
|
401
|
+
encryption: {
|
|
402
|
+
type: "dataKey",
|
|
403
|
+
publicKey: new Uint8Array(Buffer.from(credentials.encryption.publicKey, "base64")),
|
|
404
|
+
machineKey: new Uint8Array(Buffer.from(credentials.encryption.machineKey, "base64"))
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
}
|
|
319
408
|
} catch {
|
|
320
409
|
return null;
|
|
321
410
|
}
|
|
411
|
+
return null;
|
|
322
412
|
}
|
|
323
|
-
async function
|
|
413
|
+
async function writeCredentialsLegacy(credentials) {
|
|
324
414
|
if (!existsSync(configuration.happyHomeDir)) {
|
|
325
415
|
await mkdir(configuration.happyHomeDir, { recursive: true });
|
|
326
416
|
}
|
|
@@ -329,6 +419,15 @@ async function writeCredentials(credentials) {
|
|
|
329
419
|
token: credentials.token
|
|
330
420
|
}, null, 2));
|
|
331
421
|
}
|
|
422
|
+
async function writeCredentialsDataKey(credentials) {
|
|
423
|
+
if (!existsSync(configuration.happyHomeDir)) {
|
|
424
|
+
await mkdir(configuration.happyHomeDir, { recursive: true });
|
|
425
|
+
}
|
|
426
|
+
await writeFile(configuration.privateKeyFile, JSON.stringify({
|
|
427
|
+
encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
|
|
428
|
+
token: credentials.token
|
|
429
|
+
}, null, 2));
|
|
430
|
+
}
|
|
332
431
|
async function clearCredentials() {
|
|
333
432
|
if (existsSync(configuration.privateKeyFile)) {
|
|
334
433
|
await unlink(configuration.privateKeyFile);
|
|
@@ -663,32 +762,6 @@ z$1.object({
|
|
|
663
762
|
]),
|
|
664
763
|
createdAt: z$1.number()
|
|
665
764
|
});
|
|
666
|
-
z$1.object({
|
|
667
|
-
createdAt: z$1.number(),
|
|
668
|
-
id: z$1.string(),
|
|
669
|
-
seq: z$1.number(),
|
|
670
|
-
updatedAt: z$1.number(),
|
|
671
|
-
metadata: z$1.any(),
|
|
672
|
-
metadataVersion: z$1.number(),
|
|
673
|
-
agentState: z$1.any().nullable(),
|
|
674
|
-
agentStateVersion: z$1.number(),
|
|
675
|
-
// Connectivity tracking (from server)
|
|
676
|
-
connectivityStatus: z$1.union([
|
|
677
|
-
z$1.enum(["neverConnected", "online", "offline"]),
|
|
678
|
-
z$1.string()
|
|
679
|
-
// Forward compatibility
|
|
680
|
-
]).optional(),
|
|
681
|
-
connectivityStatusSince: z$1.number().optional(),
|
|
682
|
-
connectivityStatusReason: z$1.string().optional(),
|
|
683
|
-
// State tracking (from server)
|
|
684
|
-
state: z$1.union([
|
|
685
|
-
z$1.enum(["running", "archiveRequested", "archived"]),
|
|
686
|
-
z$1.string()
|
|
687
|
-
// Forward compatibility
|
|
688
|
-
]).optional(),
|
|
689
|
-
stateSince: z$1.number().optional(),
|
|
690
|
-
stateReason: z$1.string().optional()
|
|
691
|
-
});
|
|
692
765
|
z$1.object({
|
|
693
766
|
host: z$1.string(),
|
|
694
767
|
platform: z$1.string(),
|
|
@@ -713,37 +786,6 @@ z$1.object({
|
|
|
713
786
|
// Forward compatibility
|
|
714
787
|
]).optional()
|
|
715
788
|
});
|
|
716
|
-
z$1.object({
|
|
717
|
-
id: z$1.string(),
|
|
718
|
-
metadata: z$1.any(),
|
|
719
|
-
// Decrypted MachineMetadata
|
|
720
|
-
metadataVersion: z$1.number(),
|
|
721
|
-
daemonState: z$1.any().nullable(),
|
|
722
|
-
// Decrypted DaemonState
|
|
723
|
-
daemonStateVersion: z$1.number(),
|
|
724
|
-
// We don't really care about these on the CLI for now
|
|
725
|
-
// ApiMachineClient will not sync these
|
|
726
|
-
active: z$1.boolean(),
|
|
727
|
-
activeAt: z$1.number(),
|
|
728
|
-
createdAt: z$1.number(),
|
|
729
|
-
updatedAt: z$1.number(),
|
|
730
|
-
// Connectivity tracking (from server)
|
|
731
|
-
connectivityStatus: z$1.union([
|
|
732
|
-
z$1.enum(["neverConnected", "online", "offline"]),
|
|
733
|
-
z$1.string()
|
|
734
|
-
// Forward compatibility
|
|
735
|
-
]).optional(),
|
|
736
|
-
connectivityStatusSince: z$1.number().optional(),
|
|
737
|
-
connectivityStatusReason: z$1.string().optional(),
|
|
738
|
-
// State tracking (from server)
|
|
739
|
-
state: z$1.union([
|
|
740
|
-
z$1.enum(["running", "archiveRequested", "archived"]),
|
|
741
|
-
z$1.string()
|
|
742
|
-
// Forward compatibility
|
|
743
|
-
]).optional(),
|
|
744
|
-
stateSince: z$1.number().optional(),
|
|
745
|
-
stateReason: z$1.string().optional()
|
|
746
|
-
});
|
|
747
789
|
z$1.object({
|
|
748
790
|
content: SessionMessageContentSchema,
|
|
749
791
|
createdAt: z$1.number(),
|
|
@@ -867,12 +909,14 @@ class AsyncLock {
|
|
|
867
909
|
class RpcHandlerManager {
|
|
868
910
|
handlers = /* @__PURE__ */ new Map();
|
|
869
911
|
scopePrefix;
|
|
870
|
-
|
|
912
|
+
encryptionKey;
|
|
913
|
+
encryptionVariant;
|
|
871
914
|
logger;
|
|
872
915
|
socket = null;
|
|
873
916
|
constructor(config) {
|
|
874
917
|
this.scopePrefix = config.scopePrefix;
|
|
875
|
-
this.
|
|
918
|
+
this.encryptionKey = config.encryptionKey;
|
|
919
|
+
this.encryptionVariant = config.encryptionVariant;
|
|
876
920
|
this.logger = config.logger || ((msg, data) => logger.debug(msg, data));
|
|
877
921
|
}
|
|
878
922
|
/**
|
|
@@ -898,20 +942,19 @@ class RpcHandlerManager {
|
|
|
898
942
|
if (!handler) {
|
|
899
943
|
this.logger("[RPC] [ERROR] Method not found", { method: request.method });
|
|
900
944
|
const errorResponse = { error: "Method not found" };
|
|
901
|
-
const encryptedError = encodeBase64(encrypt(
|
|
945
|
+
const encryptedError = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
|
|
902
946
|
return encryptedError;
|
|
903
947
|
}
|
|
904
|
-
const decryptedParams = decrypt(decodeBase64(request.params)
|
|
948
|
+
const decryptedParams = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(request.params));
|
|
905
949
|
const result = await handler(decryptedParams);
|
|
906
|
-
const encryptedResponse = encodeBase64(encrypt(
|
|
950
|
+
const encryptedResponse = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, result));
|
|
907
951
|
return encryptedResponse;
|
|
908
952
|
} catch (error) {
|
|
909
953
|
this.logger("[RPC] [ERROR] Error handling request", { error });
|
|
910
954
|
const errorResponse = {
|
|
911
955
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
912
956
|
};
|
|
913
|
-
|
|
914
|
-
return encryptedError;
|
|
957
|
+
return encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
|
|
915
958
|
}
|
|
916
959
|
}
|
|
917
960
|
onSocketConnect(socket) {
|
|
@@ -1256,7 +1299,6 @@ function registerCommonHandlers(rpcHandlerManager) {
|
|
|
1256
1299
|
|
|
1257
1300
|
class ApiSessionClient extends EventEmitter {
|
|
1258
1301
|
token;
|
|
1259
|
-
secret;
|
|
1260
1302
|
sessionId;
|
|
1261
1303
|
metadata;
|
|
1262
1304
|
metadataVersion;
|
|
@@ -1268,18 +1310,22 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1268
1310
|
rpcHandlerManager;
|
|
1269
1311
|
agentStateLock = new AsyncLock();
|
|
1270
1312
|
metadataLock = new AsyncLock();
|
|
1271
|
-
|
|
1313
|
+
encryptionKey;
|
|
1314
|
+
encryptionVariant;
|
|
1315
|
+
constructor(token, session) {
|
|
1272
1316
|
super();
|
|
1273
1317
|
this.token = token;
|
|
1274
|
-
this.secret = secret;
|
|
1275
1318
|
this.sessionId = session.id;
|
|
1276
1319
|
this.metadata = session.metadata;
|
|
1277
1320
|
this.metadataVersion = session.metadataVersion;
|
|
1278
1321
|
this.agentState = session.agentState;
|
|
1279
1322
|
this.agentStateVersion = session.agentStateVersion;
|
|
1323
|
+
this.encryptionKey = session.encryptionKey;
|
|
1324
|
+
this.encryptionVariant = session.encryptionVariant;
|
|
1280
1325
|
this.rpcHandlerManager = new RpcHandlerManager({
|
|
1281
1326
|
scopePrefix: this.sessionId,
|
|
1282
|
-
|
|
1327
|
+
encryptionKey: this.encryptionKey,
|
|
1328
|
+
encryptionVariant: this.encryptionVariant,
|
|
1283
1329
|
logger: (msg, data) => logger.debug(msg, data)
|
|
1284
1330
|
});
|
|
1285
1331
|
registerCommonHandlers(this.rpcHandlerManager);
|
|
@@ -1321,7 +1367,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1321
1367
|
return;
|
|
1322
1368
|
}
|
|
1323
1369
|
if (data.body.t === "new-message" && data.body.message.content.t === "encrypted") {
|
|
1324
|
-
const body = decrypt(decodeBase64(data.body.message.content.c)
|
|
1370
|
+
const body = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.message.content.c));
|
|
1325
1371
|
logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
|
|
1326
1372
|
const userResult = UserMessageSchema.safeParse(body);
|
|
1327
1373
|
if (userResult.success) {
|
|
@@ -1335,11 +1381,11 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1335
1381
|
}
|
|
1336
1382
|
} else if (data.body.t === "update-session") {
|
|
1337
1383
|
if (data.body.metadata && data.body.metadata.version > this.metadataVersion) {
|
|
1338
|
-
this.metadata = decrypt(decodeBase64(data.body.metadata.value)
|
|
1384
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.metadata.value));
|
|
1339
1385
|
this.metadataVersion = data.body.metadata.version;
|
|
1340
1386
|
}
|
|
1341
1387
|
if (data.body.agentState && data.body.agentState.version > this.agentStateVersion) {
|
|
1342
|
-
this.agentState = data.body.agentState.value ? decrypt(decodeBase64(data.body.agentState.value)
|
|
1388
|
+
this.agentState = data.body.agentState.value ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.agentState.value)) : null;
|
|
1343
1389
|
this.agentStateVersion = data.body.agentState.version;
|
|
1344
1390
|
}
|
|
1345
1391
|
} else if (data.body.t === "update-machine") {
|
|
@@ -1393,7 +1439,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1393
1439
|
};
|
|
1394
1440
|
}
|
|
1395
1441
|
logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
|
|
1396
|
-
const encrypted = encodeBase64(encrypt(
|
|
1442
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1397
1443
|
this.socket.emit("message", {
|
|
1398
1444
|
sid: this.sessionId,
|
|
1399
1445
|
message: encrypted
|
|
@@ -1427,7 +1473,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1427
1473
|
sentFrom: "cli"
|
|
1428
1474
|
}
|
|
1429
1475
|
};
|
|
1430
|
-
const encrypted = encodeBase64(encrypt(
|
|
1476
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1431
1477
|
this.socket.emit("message", {
|
|
1432
1478
|
sid: this.sessionId,
|
|
1433
1479
|
message: encrypted
|
|
@@ -1442,7 +1488,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1442
1488
|
data: event
|
|
1443
1489
|
}
|
|
1444
1490
|
};
|
|
1445
|
-
const encrypted = encodeBase64(encrypt(
|
|
1491
|
+
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1446
1492
|
this.socket.emit("message", {
|
|
1447
1493
|
sid: this.sessionId,
|
|
1448
1494
|
message: encrypted
|
|
@@ -1502,14 +1548,14 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1502
1548
|
this.metadataLock.inLock(async () => {
|
|
1503
1549
|
await backoff(async () => {
|
|
1504
1550
|
let updated = handler(this.metadata);
|
|
1505
|
-
const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: encodeBase64(encrypt(
|
|
1551
|
+
const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) });
|
|
1506
1552
|
if (answer.result === "success") {
|
|
1507
|
-
this.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1553
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata));
|
|
1508
1554
|
this.metadataVersion = answer.version;
|
|
1509
1555
|
} else if (answer.result === "version-mismatch") {
|
|
1510
1556
|
if (answer.version > this.metadataVersion) {
|
|
1511
1557
|
this.metadataVersion = answer.version;
|
|
1512
|
-
this.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1558
|
+
this.metadata = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata));
|
|
1513
1559
|
}
|
|
1514
1560
|
throw new Error("Metadata version mismatch");
|
|
1515
1561
|
} else if (answer.result === "error") ;
|
|
@@ -1525,15 +1571,15 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1525
1571
|
this.agentStateLock.inLock(async () => {
|
|
1526
1572
|
await backoff(async () => {
|
|
1527
1573
|
let updated = handler(this.agentState || {});
|
|
1528
|
-
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(
|
|
1574
|
+
const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
|
|
1529
1575
|
if (answer.result === "success") {
|
|
1530
|
-
this.agentState = answer.agentState ? decrypt(decodeBase64(answer.agentState)
|
|
1576
|
+
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
1531
1577
|
this.agentStateVersion = answer.version;
|
|
1532
1578
|
logger.debug("Agent state updated", this.agentState);
|
|
1533
1579
|
} else if (answer.result === "version-mismatch") {
|
|
1534
1580
|
if (answer.version > this.agentStateVersion) {
|
|
1535
1581
|
this.agentStateVersion = answer.version;
|
|
1536
|
-
this.agentState = answer.agentState ? decrypt(decodeBase64(answer.agentState)
|
|
1582
|
+
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
1537
1583
|
}
|
|
1538
1584
|
throw new Error("Agent state version mismatch");
|
|
1539
1585
|
} else if (answer.result === "error") ;
|
|
@@ -1563,13 +1609,13 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1563
1609
|
}
|
|
1564
1610
|
|
|
1565
1611
|
class ApiMachineClient {
|
|
1566
|
-
constructor(token,
|
|
1612
|
+
constructor(token, machine) {
|
|
1567
1613
|
this.token = token;
|
|
1568
|
-
this.secret = secret;
|
|
1569
1614
|
this.machine = machine;
|
|
1570
1615
|
this.rpcHandlerManager = new RpcHandlerManager({
|
|
1571
1616
|
scopePrefix: this.machine.id,
|
|
1572
|
-
|
|
1617
|
+
encryptionKey: this.machine.encryptionKey,
|
|
1618
|
+
encryptionVariant: this.machine.encryptionVariant,
|
|
1573
1619
|
logger: (msg, data) => logger.debug(msg, data)
|
|
1574
1620
|
});
|
|
1575
1621
|
registerCommonHandlers(this.rpcHandlerManager);
|
|
@@ -1583,11 +1629,12 @@ class ApiMachineClient {
|
|
|
1583
1629
|
requestShutdown
|
|
1584
1630
|
}) {
|
|
1585
1631
|
this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
|
|
1586
|
-
const { directory, sessionId, machineId, approvedNewDirectoryCreation } = params || {};
|
|
1632
|
+
const { directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token } = params || {};
|
|
1633
|
+
logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
|
|
1587
1634
|
if (!directory) {
|
|
1588
1635
|
throw new Error("Directory is required");
|
|
1589
1636
|
}
|
|
1590
|
-
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation });
|
|
1637
|
+
const result = await spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation, agent, token });
|
|
1591
1638
|
switch (result.type) {
|
|
1592
1639
|
case "success":
|
|
1593
1640
|
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
|
@@ -1630,17 +1677,17 @@ class ApiMachineClient {
|
|
|
1630
1677
|
const updated = handler(this.machine.metadata);
|
|
1631
1678
|
const answer = await this.socket.emitWithAck("machine-update-metadata", {
|
|
1632
1679
|
machineId: this.machine.id,
|
|
1633
|
-
metadata: encodeBase64(encrypt(
|
|
1680
|
+
metadata: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
|
|
1634
1681
|
expectedVersion: this.machine.metadataVersion
|
|
1635
1682
|
});
|
|
1636
1683
|
if (answer.result === "success") {
|
|
1637
|
-
this.machine.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1684
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
|
|
1638
1685
|
this.machine.metadataVersion = answer.version;
|
|
1639
1686
|
logger.debug("[API MACHINE] Metadata updated successfully");
|
|
1640
1687
|
} else if (answer.result === "version-mismatch") {
|
|
1641
1688
|
if (answer.version > this.machine.metadataVersion) {
|
|
1642
1689
|
this.machine.metadataVersion = answer.version;
|
|
1643
|
-
this.machine.metadata = decrypt(decodeBase64(answer.metadata)
|
|
1690
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
|
|
1644
1691
|
}
|
|
1645
1692
|
throw new Error("Metadata version mismatch");
|
|
1646
1693
|
}
|
|
@@ -1655,17 +1702,17 @@ class ApiMachineClient {
|
|
|
1655
1702
|
const updated = handler(this.machine.daemonState);
|
|
1656
1703
|
const answer = await this.socket.emitWithAck("machine-update-state", {
|
|
1657
1704
|
machineId: this.machine.id,
|
|
1658
|
-
daemonState: encodeBase64(encrypt(
|
|
1705
|
+
daemonState: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
|
|
1659
1706
|
expectedVersion: this.machine.daemonStateVersion
|
|
1660
1707
|
});
|
|
1661
1708
|
if (answer.result === "success") {
|
|
1662
|
-
this.machine.daemonState = decrypt(decodeBase64(answer.daemonState)
|
|
1709
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
|
|
1663
1710
|
this.machine.daemonStateVersion = answer.version;
|
|
1664
1711
|
logger.debug("[API MACHINE] Daemon state updated successfully");
|
|
1665
1712
|
} else if (answer.result === "version-mismatch") {
|
|
1666
1713
|
if (answer.version > this.machine.daemonStateVersion) {
|
|
1667
1714
|
this.machine.daemonStateVersion = answer.version;
|
|
1668
|
-
this.machine.daemonState = decrypt(decodeBase64(answer.daemonState)
|
|
1715
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
|
|
1669
1716
|
}
|
|
1670
1717
|
throw new Error("Daemon state version mismatch");
|
|
1671
1718
|
}
|
|
@@ -1712,12 +1759,12 @@ class ApiMachineClient {
|
|
|
1712
1759
|
const update = data.body;
|
|
1713
1760
|
if (update.metadata) {
|
|
1714
1761
|
logger.debug("[API MACHINE] Received external metadata update");
|
|
1715
|
-
this.machine.metadata = decrypt(decodeBase64(update.metadata.value)
|
|
1762
|
+
this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.metadata.value));
|
|
1716
1763
|
this.machine.metadataVersion = update.metadata.version;
|
|
1717
1764
|
}
|
|
1718
1765
|
if (update.daemonState) {
|
|
1719
1766
|
logger.debug("[API MACHINE] Received external daemon state update");
|
|
1720
|
-
this.machine.daemonState = decrypt(decodeBase64(update.daemonState.value)
|
|
1767
|
+
this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.daemonState.value));
|
|
1721
1768
|
this.machine.daemonStateVersion = update.daemonState.version;
|
|
1722
1769
|
}
|
|
1723
1770
|
} else {
|
|
@@ -1889,46 +1936,62 @@ class PushNotificationClient {
|
|
|
1889
1936
|
}
|
|
1890
1937
|
|
|
1891
1938
|
class ApiClient {
|
|
1892
|
-
|
|
1893
|
-
|
|
1939
|
+
static async create(credential) {
|
|
1940
|
+
return new ApiClient(credential);
|
|
1941
|
+
}
|
|
1942
|
+
credential;
|
|
1894
1943
|
pushClient;
|
|
1895
|
-
constructor(
|
|
1896
|
-
this.
|
|
1897
|
-
this.
|
|
1898
|
-
this.pushClient = new PushNotificationClient(token);
|
|
1944
|
+
constructor(credential) {
|
|
1945
|
+
this.credential = credential;
|
|
1946
|
+
this.pushClient = new PushNotificationClient(credential.token, configuration.serverUrl);
|
|
1899
1947
|
}
|
|
1900
1948
|
/**
|
|
1901
1949
|
* Create a new session or load existing one with the given tag
|
|
1902
1950
|
*/
|
|
1903
1951
|
async getOrCreateSession(opts) {
|
|
1952
|
+
let dataEncryptionKey = null;
|
|
1953
|
+
let encryptionKey;
|
|
1954
|
+
let encryptionVariant;
|
|
1955
|
+
if (this.credential.encryption.type === "dataKey") {
|
|
1956
|
+
encryptionKey = getRandomBytes(32);
|
|
1957
|
+
encryptionVariant = "dataKey";
|
|
1958
|
+
let encryptedDataKey = libsodiumEncryptForPublicKey(encryptionKey, this.credential.encryption.publicKey);
|
|
1959
|
+
dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
|
|
1960
|
+
dataEncryptionKey.set([0], 0);
|
|
1961
|
+
dataEncryptionKey.set(encryptedDataKey, 1);
|
|
1962
|
+
} else {
|
|
1963
|
+
encryptionKey = this.credential.encryption.secret;
|
|
1964
|
+
encryptionVariant = "legacy";
|
|
1965
|
+
}
|
|
1904
1966
|
try {
|
|
1905
1967
|
const response = await axios.post(
|
|
1906
1968
|
`${configuration.serverUrl}/v1/sessions`,
|
|
1907
1969
|
{
|
|
1908
1970
|
tag: opts.tag,
|
|
1909
|
-
metadata: encodeBase64(encrypt(opts.metadata
|
|
1910
|
-
agentState: opts.state ? encodeBase64(encrypt(opts.state
|
|
1971
|
+
metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
|
|
1972
|
+
agentState: opts.state ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.state)) : null,
|
|
1973
|
+
dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : null
|
|
1911
1974
|
},
|
|
1912
1975
|
{
|
|
1913
1976
|
headers: {
|
|
1914
|
-
"Authorization": `Bearer ${this.token}`,
|
|
1977
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
1915
1978
|
"Content-Type": "application/json"
|
|
1916
1979
|
},
|
|
1917
|
-
timeout:
|
|
1918
|
-
//
|
|
1980
|
+
timeout: 6e4
|
|
1981
|
+
// 1 minute timeout for very bad network connections
|
|
1919
1982
|
}
|
|
1920
1983
|
);
|
|
1921
1984
|
logger.debug(`Session created/loaded: ${response.data.session.id} (tag: ${opts.tag})`);
|
|
1922
1985
|
let raw = response.data.session;
|
|
1923
1986
|
let session = {
|
|
1924
1987
|
id: raw.id,
|
|
1925
|
-
createdAt: raw.createdAt,
|
|
1926
|
-
updatedAt: raw.updatedAt,
|
|
1927
1988
|
seq: raw.seq,
|
|
1928
|
-
metadata: decrypt(decodeBase64(raw.metadata)
|
|
1989
|
+
metadata: decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)),
|
|
1929
1990
|
metadataVersion: raw.metadataVersion,
|
|
1930
|
-
agentState: raw.agentState ? decrypt(decodeBase64(raw.agentState)
|
|
1931
|
-
agentStateVersion: raw.agentStateVersion
|
|
1991
|
+
agentState: raw.agentState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.agentState)) : null,
|
|
1992
|
+
agentStateVersion: raw.agentStateVersion,
|
|
1993
|
+
encryptionKey,
|
|
1994
|
+
encryptionVariant
|
|
1932
1995
|
};
|
|
1933
1996
|
return session;
|
|
1934
1997
|
} catch (error) {
|
|
@@ -1936,54 +1999,40 @@ class ApiClient {
|
|
|
1936
1999
|
throw new Error(`Failed to get or create session: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1937
2000
|
}
|
|
1938
2001
|
}
|
|
1939
|
-
/**
|
|
1940
|
-
* Get machine by ID from the server
|
|
1941
|
-
* Returns the current machine state from the server with decrypted metadata and daemonState
|
|
1942
|
-
*/
|
|
1943
|
-
async getMachine(machineId) {
|
|
1944
|
-
const response = await axios.get(`${configuration.serverUrl}/v1/machines/${machineId}`, {
|
|
1945
|
-
headers: {
|
|
1946
|
-
"Authorization": `Bearer ${this.token}`,
|
|
1947
|
-
"Content-Type": "application/json"
|
|
1948
|
-
},
|
|
1949
|
-
timeout: 2e3
|
|
1950
|
-
});
|
|
1951
|
-
const raw = response.data.machine;
|
|
1952
|
-
if (!raw) {
|
|
1953
|
-
return null;
|
|
1954
|
-
}
|
|
1955
|
-
logger.debug(`[API] Machine ${machineId} fetched from server`);
|
|
1956
|
-
const machine = {
|
|
1957
|
-
id: raw.id,
|
|
1958
|
-
metadata: raw.metadata ? decrypt(decodeBase64(raw.metadata), this.secret) : null,
|
|
1959
|
-
metadataVersion: raw.metadataVersion || 0,
|
|
1960
|
-
daemonState: raw.daemonState ? decrypt(decodeBase64(raw.daemonState), this.secret) : null,
|
|
1961
|
-
daemonStateVersion: raw.daemonStateVersion || 0,
|
|
1962
|
-
active: raw.active,
|
|
1963
|
-
activeAt: raw.activeAt,
|
|
1964
|
-
createdAt: raw.createdAt,
|
|
1965
|
-
updatedAt: raw.updatedAt
|
|
1966
|
-
};
|
|
1967
|
-
return machine;
|
|
1968
|
-
}
|
|
1969
2002
|
/**
|
|
1970
2003
|
* Register or update machine with the server
|
|
1971
2004
|
* Returns the current machine state from the server with decrypted metadata and daemonState
|
|
1972
2005
|
*/
|
|
1973
2006
|
async getOrCreateMachine(opts) {
|
|
2007
|
+
let dataEncryptionKey = null;
|
|
2008
|
+
let encryptionKey;
|
|
2009
|
+
let encryptionVariant;
|
|
2010
|
+
if (this.credential.encryption.type === "dataKey") {
|
|
2011
|
+
encryptionVariant = "dataKey";
|
|
2012
|
+
encryptionKey = this.credential.encryption.machineKey;
|
|
2013
|
+
let encryptedDataKey = libsodiumEncryptForPublicKey(this.credential.encryption.machineKey, this.credential.encryption.publicKey);
|
|
2014
|
+
dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
|
|
2015
|
+
dataEncryptionKey.set([0], 0);
|
|
2016
|
+
dataEncryptionKey.set(encryptedDataKey, 1);
|
|
2017
|
+
} else {
|
|
2018
|
+
encryptionKey = this.credential.encryption.secret;
|
|
2019
|
+
encryptionVariant = "legacy";
|
|
2020
|
+
}
|
|
1974
2021
|
const response = await axios.post(
|
|
1975
2022
|
`${configuration.serverUrl}/v1/machines`,
|
|
1976
2023
|
{
|
|
1977
2024
|
id: opts.machineId,
|
|
1978
|
-
metadata: encodeBase64(encrypt(opts.metadata
|
|
1979
|
-
daemonState: opts.daemonState ? encodeBase64(encrypt(opts.daemonState
|
|
2025
|
+
metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
|
|
2026
|
+
daemonState: opts.daemonState ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.daemonState)) : void 0,
|
|
2027
|
+
dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : void 0
|
|
1980
2028
|
},
|
|
1981
2029
|
{
|
|
1982
2030
|
headers: {
|
|
1983
|
-
"Authorization": `Bearer ${this.token}`,
|
|
2031
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
1984
2032
|
"Content-Type": "application/json"
|
|
1985
2033
|
},
|
|
1986
|
-
timeout:
|
|
2034
|
+
timeout: 6e4
|
|
2035
|
+
// 1 minute timeout for very bad network connections
|
|
1987
2036
|
}
|
|
1988
2037
|
);
|
|
1989
2038
|
if (response.status !== 200) {
|
|
@@ -1995,22 +2044,20 @@ class ApiClient {
|
|
|
1995
2044
|
logger.debug(`[API] Machine ${opts.machineId} registered/updated with server`);
|
|
1996
2045
|
const machine = {
|
|
1997
2046
|
id: raw.id,
|
|
1998
|
-
|
|
2047
|
+
encryptionKey,
|
|
2048
|
+
encryptionVariant,
|
|
2049
|
+
metadata: raw.metadata ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)) : null,
|
|
1999
2050
|
metadataVersion: raw.metadataVersion || 0,
|
|
2000
|
-
daemonState: raw.daemonState ? decrypt(decodeBase64(raw.daemonState)
|
|
2001
|
-
daemonStateVersion: raw.daemonStateVersion || 0
|
|
2002
|
-
active: raw.active,
|
|
2003
|
-
activeAt: raw.activeAt,
|
|
2004
|
-
createdAt: raw.createdAt,
|
|
2005
|
-
updatedAt: raw.updatedAt
|
|
2051
|
+
daemonState: raw.daemonState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.daemonState)) : null,
|
|
2052
|
+
daemonStateVersion: raw.daemonStateVersion || 0
|
|
2006
2053
|
};
|
|
2007
2054
|
return machine;
|
|
2008
2055
|
}
|
|
2009
2056
|
sessionSyncClient(session) {
|
|
2010
|
-
return new ApiSessionClient(this.token,
|
|
2057
|
+
return new ApiSessionClient(this.credential.token, session);
|
|
2011
2058
|
}
|
|
2012
2059
|
machineSyncClient(machine) {
|
|
2013
|
-
return new ApiMachineClient(this.token,
|
|
2060
|
+
return new ApiMachineClient(this.credential.token, machine);
|
|
2014
2061
|
}
|
|
2015
2062
|
push() {
|
|
2016
2063
|
return this.pushClient;
|
|
@@ -2028,7 +2075,7 @@ class ApiClient {
|
|
|
2028
2075
|
},
|
|
2029
2076
|
{
|
|
2030
2077
|
headers: {
|
|
2031
|
-
"Authorization": `Bearer ${this.token}`,
|
|
2078
|
+
"Authorization": `Bearer ${this.credential.token}`,
|
|
2032
2079
|
"Content-Type": "application/json"
|
|
2033
2080
|
},
|
|
2034
2081
|
timeout: 5e3
|
|
@@ -2093,4 +2140,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
2093
2140
|
}).passthrough()
|
|
2094
2141
|
]);
|
|
2095
2142
|
|
|
2096
|
-
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, AsyncLock as f, readDaemonState as g, clearDaemonState as h, readCredentials as i, encodeBase64 as j, encodeBase64Url as k, logger as l, decodeBase64 as m,
|
|
2143
|
+
export { ApiClient as A, RawJSONLinesSchema as R, ApiSessionClient as a, packageJson as b, configuration as c, backoff as d, delay as e, AsyncLock as f, readDaemonState as g, clearDaemonState as h, readCredentials as i, encodeBase64 as j, encodeBase64Url as k, logger as l, decodeBase64 as m, writeCredentialsDataKey as n, acquireDaemonLock as o, projectPath as p, writeDaemonState as q, readSettings as r, releaseDaemonLock as s, clearCredentials as t, updateSettings as u, clearMachineId as v, writeCredentialsLegacy as w, getLatestDaemonLog as x };
|