happy-coder 0.9.0 → 0.10.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.
- package/dist/index.cjs +851 -275
- package/dist/index.mjs +854 -278
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +64 -15
- package/dist/lib.d.mts +64 -15
- package/dist/lib.mjs +1 -1
- package/dist/{types-Cezp_n6O.mjs → types-CGbH1LGX.mjs} +102 -32
- package/dist/{types-CyOnnZ8M.cjs → types-fU2E-jQl.cjs} +102 -32
- package/package.json +6 -2
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { ChildProcess } from 'child_process';
|
|
4
3
|
import { ExpoPushMessage } from 'expo-server-sdk';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -379,6 +378,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
379
378
|
metadataVersion: z.ZodNumber;
|
|
380
379
|
agentState: z.ZodNullable<z.ZodAny>;
|
|
381
380
|
agentStateVersion: z.ZodNumber;
|
|
381
|
+
connectivityStatus: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["neverConnected", "online", "offline"]>, z.ZodString]>>;
|
|
382
|
+
connectivityStatusSince: z.ZodOptional<z.ZodNumber>;
|
|
383
|
+
connectivityStatusReason: z.ZodOptional<z.ZodString>;
|
|
384
|
+
state: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["running", "archiveRequested", "archived"]>, z.ZodString]>>;
|
|
385
|
+
stateSince: z.ZodOptional<z.ZodNumber>;
|
|
386
|
+
stateReason: z.ZodOptional<z.ZodString>;
|
|
382
387
|
}, "strip", z.ZodTypeAny, {
|
|
383
388
|
id: string;
|
|
384
389
|
seq: number;
|
|
@@ -388,6 +393,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
388
393
|
agentStateVersion: number;
|
|
389
394
|
metadata?: any;
|
|
390
395
|
agentState?: any;
|
|
396
|
+
connectivityStatus?: string | undefined;
|
|
397
|
+
connectivityStatusSince?: number | undefined;
|
|
398
|
+
connectivityStatusReason?: string | undefined;
|
|
399
|
+
state?: string | undefined;
|
|
400
|
+
stateSince?: number | undefined;
|
|
401
|
+
stateReason?: string | undefined;
|
|
391
402
|
}, {
|
|
392
403
|
id: string;
|
|
393
404
|
seq: number;
|
|
@@ -397,6 +408,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
397
408
|
agentStateVersion: number;
|
|
398
409
|
metadata?: any;
|
|
399
410
|
agentState?: any;
|
|
411
|
+
connectivityStatus?: string | undefined;
|
|
412
|
+
connectivityStatusSince?: number | undefined;
|
|
413
|
+
connectivityStatusReason?: string | undefined;
|
|
414
|
+
state?: string | undefined;
|
|
415
|
+
stateSince?: number | undefined;
|
|
416
|
+
stateReason?: string | undefined;
|
|
400
417
|
}>;
|
|
401
418
|
type Session = z.infer<typeof SessionSchema>;
|
|
402
419
|
/**
|
|
@@ -461,6 +478,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
461
478
|
activeAt: z.ZodNumber;
|
|
462
479
|
createdAt: z.ZodNumber;
|
|
463
480
|
updatedAt: z.ZodNumber;
|
|
481
|
+
connectivityStatus: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["neverConnected", "online", "offline"]>, z.ZodString]>>;
|
|
482
|
+
connectivityStatusSince: z.ZodOptional<z.ZodNumber>;
|
|
483
|
+
connectivityStatusReason: z.ZodOptional<z.ZodString>;
|
|
484
|
+
state: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["running", "archiveRequested", "archived"]>, z.ZodString]>>;
|
|
485
|
+
stateSince: z.ZodOptional<z.ZodNumber>;
|
|
486
|
+
stateReason: z.ZodOptional<z.ZodString>;
|
|
464
487
|
}, "strip", z.ZodTypeAny, {
|
|
465
488
|
id: string;
|
|
466
489
|
createdAt: number;
|
|
@@ -471,6 +494,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
471
494
|
activeAt: number;
|
|
472
495
|
metadata?: any;
|
|
473
496
|
daemonState?: any;
|
|
497
|
+
connectivityStatus?: string | undefined;
|
|
498
|
+
connectivityStatusSince?: number | undefined;
|
|
499
|
+
connectivityStatusReason?: string | undefined;
|
|
500
|
+
state?: string | undefined;
|
|
501
|
+
stateSince?: number | undefined;
|
|
502
|
+
stateReason?: string | undefined;
|
|
474
503
|
}, {
|
|
475
504
|
id: string;
|
|
476
505
|
createdAt: number;
|
|
@@ -481,6 +510,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
481
510
|
activeAt: number;
|
|
482
511
|
metadata?: any;
|
|
483
512
|
daemonState?: any;
|
|
513
|
+
connectivityStatus?: string | undefined;
|
|
514
|
+
connectivityStatusSince?: number | undefined;
|
|
515
|
+
connectivityStatusReason?: string | undefined;
|
|
516
|
+
state?: string | undefined;
|
|
517
|
+
stateSince?: number | undefined;
|
|
518
|
+
stateReason?: string | undefined;
|
|
484
519
|
}>;
|
|
485
520
|
type Machine = z.infer<typeof MachineSchema>;
|
|
486
521
|
declare const UserMessageSchema: z.ZodObject<{
|
|
@@ -571,6 +606,7 @@ type Metadata = {
|
|
|
571
606
|
updatedAt: number;
|
|
572
607
|
};
|
|
573
608
|
machineId?: string;
|
|
609
|
+
claudeSessionId?: string;
|
|
574
610
|
tools?: string[];
|
|
575
611
|
slashCommands?: string[];
|
|
576
612
|
homeDir?: string;
|
|
@@ -578,6 +614,10 @@ type Metadata = {
|
|
|
578
614
|
startedFromDaemon?: boolean;
|
|
579
615
|
hostPid?: number;
|
|
580
616
|
startedBy?: 'daemon' | 'terminal';
|
|
617
|
+
lifecycleState?: 'running' | 'archiveRequested' | 'archived' | string;
|
|
618
|
+
lifecycleStateSince?: number;
|
|
619
|
+
archivedBy?: string;
|
|
620
|
+
archiveReason?: string;
|
|
581
621
|
};
|
|
582
622
|
type AgentState = {
|
|
583
623
|
controlledByUser?: boolean | null | undefined;
|
|
@@ -603,22 +643,26 @@ type AgentState = {
|
|
|
603
643
|
};
|
|
604
644
|
|
|
605
645
|
/**
|
|
606
|
-
*
|
|
646
|
+
* RPC handlers for API session communication
|
|
647
|
+
* Handles remote procedure calls from mobile clients
|
|
607
648
|
*/
|
|
608
649
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
happySessionId?: string;
|
|
615
|
-
happySessionMetadataFromLocalWebhook?: Metadata;
|
|
616
|
-
pid: number;
|
|
617
|
-
childProcess?: ChildProcess;
|
|
618
|
-
error?: string;
|
|
619
|
-
directoryCreated?: boolean;
|
|
620
|
-
message?: string;
|
|
650
|
+
interface SpawnSessionOptions {
|
|
651
|
+
machineId?: string;
|
|
652
|
+
directory: string;
|
|
653
|
+
sessionId?: string;
|
|
654
|
+
approvedNewDirectoryCreation?: boolean;
|
|
621
655
|
}
|
|
656
|
+
type SpawnSessionResult = {
|
|
657
|
+
type: 'success';
|
|
658
|
+
sessionId: string;
|
|
659
|
+
} | {
|
|
660
|
+
type: 'requestToApproveDirectoryCreation';
|
|
661
|
+
directory: string;
|
|
662
|
+
} | {
|
|
663
|
+
type: 'error';
|
|
664
|
+
errorMessage: string;
|
|
665
|
+
};
|
|
622
666
|
|
|
623
667
|
/**
|
|
624
668
|
* WebSocket client for machine/daemon communication with Happy server
|
|
@@ -626,7 +670,7 @@ interface TrackedSession {
|
|
|
626
670
|
*/
|
|
627
671
|
|
|
628
672
|
type MachineRpcHandlers = {
|
|
629
|
-
spawnSession: (
|
|
673
|
+
spawnSession: (options: SpawnSessionOptions) => Promise<SpawnSessionResult>;
|
|
630
674
|
stopSession: (sessionId: string) => boolean;
|
|
631
675
|
requestShutdown: () => void;
|
|
632
676
|
};
|
|
@@ -717,6 +761,11 @@ declare class ApiClient {
|
|
|
717
761
|
sessionSyncClient(session: Session): ApiSessionClient;
|
|
718
762
|
machineSyncClient(machine: Machine): ApiMachineClient;
|
|
719
763
|
push(): PushNotificationClient;
|
|
764
|
+
/**
|
|
765
|
+
* Register a vendor API token with the server
|
|
766
|
+
* The token is sent as a JSON string - server handles encryption
|
|
767
|
+
*/
|
|
768
|
+
registerVendorToken(vendor: 'openai' | 'anthropic' | 'gemini', apiKey: any): Promise<void>;
|
|
720
769
|
}
|
|
721
770
|
|
|
722
771
|
/**
|
package/dist/lib.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { ChildProcess } from 'child_process';
|
|
4
3
|
import { ExpoPushMessage } from 'expo-server-sdk';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -379,6 +378,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
379
378
|
metadataVersion: z.ZodNumber;
|
|
380
379
|
agentState: z.ZodNullable<z.ZodAny>;
|
|
381
380
|
agentStateVersion: z.ZodNumber;
|
|
381
|
+
connectivityStatus: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["neverConnected", "online", "offline"]>, z.ZodString]>>;
|
|
382
|
+
connectivityStatusSince: z.ZodOptional<z.ZodNumber>;
|
|
383
|
+
connectivityStatusReason: z.ZodOptional<z.ZodString>;
|
|
384
|
+
state: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["running", "archiveRequested", "archived"]>, z.ZodString]>>;
|
|
385
|
+
stateSince: z.ZodOptional<z.ZodNumber>;
|
|
386
|
+
stateReason: z.ZodOptional<z.ZodString>;
|
|
382
387
|
}, "strip", z.ZodTypeAny, {
|
|
383
388
|
id: string;
|
|
384
389
|
seq: number;
|
|
@@ -388,6 +393,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
388
393
|
agentStateVersion: number;
|
|
389
394
|
metadata?: any;
|
|
390
395
|
agentState?: any;
|
|
396
|
+
connectivityStatus?: string | undefined;
|
|
397
|
+
connectivityStatusSince?: number | undefined;
|
|
398
|
+
connectivityStatusReason?: string | undefined;
|
|
399
|
+
state?: string | undefined;
|
|
400
|
+
stateSince?: number | undefined;
|
|
401
|
+
stateReason?: string | undefined;
|
|
391
402
|
}, {
|
|
392
403
|
id: string;
|
|
393
404
|
seq: number;
|
|
@@ -397,6 +408,12 @@ declare const SessionSchema: z.ZodObject<{
|
|
|
397
408
|
agentStateVersion: number;
|
|
398
409
|
metadata?: any;
|
|
399
410
|
agentState?: any;
|
|
411
|
+
connectivityStatus?: string | undefined;
|
|
412
|
+
connectivityStatusSince?: number | undefined;
|
|
413
|
+
connectivityStatusReason?: string | undefined;
|
|
414
|
+
state?: string | undefined;
|
|
415
|
+
stateSince?: number | undefined;
|
|
416
|
+
stateReason?: string | undefined;
|
|
400
417
|
}>;
|
|
401
418
|
type Session = z.infer<typeof SessionSchema>;
|
|
402
419
|
/**
|
|
@@ -461,6 +478,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
461
478
|
activeAt: z.ZodNumber;
|
|
462
479
|
createdAt: z.ZodNumber;
|
|
463
480
|
updatedAt: z.ZodNumber;
|
|
481
|
+
connectivityStatus: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["neverConnected", "online", "offline"]>, z.ZodString]>>;
|
|
482
|
+
connectivityStatusSince: z.ZodOptional<z.ZodNumber>;
|
|
483
|
+
connectivityStatusReason: z.ZodOptional<z.ZodString>;
|
|
484
|
+
state: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["running", "archiveRequested", "archived"]>, z.ZodString]>>;
|
|
485
|
+
stateSince: z.ZodOptional<z.ZodNumber>;
|
|
486
|
+
stateReason: z.ZodOptional<z.ZodString>;
|
|
464
487
|
}, "strip", z.ZodTypeAny, {
|
|
465
488
|
id: string;
|
|
466
489
|
createdAt: number;
|
|
@@ -471,6 +494,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
471
494
|
activeAt: number;
|
|
472
495
|
metadata?: any;
|
|
473
496
|
daemonState?: any;
|
|
497
|
+
connectivityStatus?: string | undefined;
|
|
498
|
+
connectivityStatusSince?: number | undefined;
|
|
499
|
+
connectivityStatusReason?: string | undefined;
|
|
500
|
+
state?: string | undefined;
|
|
501
|
+
stateSince?: number | undefined;
|
|
502
|
+
stateReason?: string | undefined;
|
|
474
503
|
}, {
|
|
475
504
|
id: string;
|
|
476
505
|
createdAt: number;
|
|
@@ -481,6 +510,12 @@ declare const MachineSchema: z.ZodObject<{
|
|
|
481
510
|
activeAt: number;
|
|
482
511
|
metadata?: any;
|
|
483
512
|
daemonState?: any;
|
|
513
|
+
connectivityStatus?: string | undefined;
|
|
514
|
+
connectivityStatusSince?: number | undefined;
|
|
515
|
+
connectivityStatusReason?: string | undefined;
|
|
516
|
+
state?: string | undefined;
|
|
517
|
+
stateSince?: number | undefined;
|
|
518
|
+
stateReason?: string | undefined;
|
|
484
519
|
}>;
|
|
485
520
|
type Machine = z.infer<typeof MachineSchema>;
|
|
486
521
|
declare const UserMessageSchema: z.ZodObject<{
|
|
@@ -571,6 +606,7 @@ type Metadata = {
|
|
|
571
606
|
updatedAt: number;
|
|
572
607
|
};
|
|
573
608
|
machineId?: string;
|
|
609
|
+
claudeSessionId?: string;
|
|
574
610
|
tools?: string[];
|
|
575
611
|
slashCommands?: string[];
|
|
576
612
|
homeDir?: string;
|
|
@@ -578,6 +614,10 @@ type Metadata = {
|
|
|
578
614
|
startedFromDaemon?: boolean;
|
|
579
615
|
hostPid?: number;
|
|
580
616
|
startedBy?: 'daemon' | 'terminal';
|
|
617
|
+
lifecycleState?: 'running' | 'archiveRequested' | 'archived' | string;
|
|
618
|
+
lifecycleStateSince?: number;
|
|
619
|
+
archivedBy?: string;
|
|
620
|
+
archiveReason?: string;
|
|
581
621
|
};
|
|
582
622
|
type AgentState = {
|
|
583
623
|
controlledByUser?: boolean | null | undefined;
|
|
@@ -603,22 +643,26 @@ type AgentState = {
|
|
|
603
643
|
};
|
|
604
644
|
|
|
605
645
|
/**
|
|
606
|
-
*
|
|
646
|
+
* RPC handlers for API session communication
|
|
647
|
+
* Handles remote procedure calls from mobile clients
|
|
607
648
|
*/
|
|
608
649
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
happySessionId?: string;
|
|
615
|
-
happySessionMetadataFromLocalWebhook?: Metadata;
|
|
616
|
-
pid: number;
|
|
617
|
-
childProcess?: ChildProcess;
|
|
618
|
-
error?: string;
|
|
619
|
-
directoryCreated?: boolean;
|
|
620
|
-
message?: string;
|
|
650
|
+
interface SpawnSessionOptions {
|
|
651
|
+
machineId?: string;
|
|
652
|
+
directory: string;
|
|
653
|
+
sessionId?: string;
|
|
654
|
+
approvedNewDirectoryCreation?: boolean;
|
|
621
655
|
}
|
|
656
|
+
type SpawnSessionResult = {
|
|
657
|
+
type: 'success';
|
|
658
|
+
sessionId: string;
|
|
659
|
+
} | {
|
|
660
|
+
type: 'requestToApproveDirectoryCreation';
|
|
661
|
+
directory: string;
|
|
662
|
+
} | {
|
|
663
|
+
type: 'error';
|
|
664
|
+
errorMessage: string;
|
|
665
|
+
};
|
|
622
666
|
|
|
623
667
|
/**
|
|
624
668
|
* WebSocket client for machine/daemon communication with Happy server
|
|
@@ -626,7 +670,7 @@ interface TrackedSession {
|
|
|
626
670
|
*/
|
|
627
671
|
|
|
628
672
|
type MachineRpcHandlers = {
|
|
629
|
-
spawnSession: (
|
|
673
|
+
spawnSession: (options: SpawnSessionOptions) => Promise<SpawnSessionResult>;
|
|
630
674
|
stopSession: (sessionId: string) => boolean;
|
|
631
675
|
requestShutdown: () => void;
|
|
632
676
|
};
|
|
@@ -717,6 +761,11 @@ declare class ApiClient {
|
|
|
717
761
|
sessionSyncClient(session: Session): ApiSessionClient;
|
|
718
762
|
machineSyncClient(machine: Machine): ApiMachineClient;
|
|
719
763
|
push(): PushNotificationClient;
|
|
764
|
+
/**
|
|
765
|
+
* Register a vendor API token with the server
|
|
766
|
+
* The token is sent as a JSON string - server handles encryption
|
|
767
|
+
*/
|
|
768
|
+
registerVendorToken(vendor: 'openai' | 'anthropic' | 'gemini', apiKey: any): Promise<void>;
|
|
720
769
|
}
|
|
721
770
|
|
|
722
771
|
/**
|
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-CGbH1LGX.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -14,7 +14,7 @@ import { io } from 'socket.io-client';
|
|
|
14
14
|
import { Expo } from 'expo-server-sdk';
|
|
15
15
|
|
|
16
16
|
var name = "happy-coder";
|
|
17
|
-
var version = "0.
|
|
17
|
+
var version = "0.10.0-0";
|
|
18
18
|
var description = "Claude Code session sharing CLI";
|
|
19
19
|
var author = "Kirill Dubovitskiy";
|
|
20
20
|
var license = "MIT";
|
|
@@ -79,6 +79,7 @@ var dependencies = {
|
|
|
79
79
|
"@types/react": "^19.1.9",
|
|
80
80
|
axios: "^1.10.0",
|
|
81
81
|
chalk: "^5.4.1",
|
|
82
|
+
"cross-spawn": "^7.0.6",
|
|
82
83
|
"expo-server-sdk": "^3.15.0",
|
|
83
84
|
fastify: "^5.5.0",
|
|
84
85
|
"fastify-type-provider-zod": "4.0.2",
|
|
@@ -86,6 +87,7 @@ var dependencies = {
|
|
|
86
87
|
"http-proxy-middleware": "^3.0.5",
|
|
87
88
|
ink: "^6.1.0",
|
|
88
89
|
open: "^10.2.0",
|
|
90
|
+
"ps-list": "^8.1.1",
|
|
89
91
|
"qrcode-terminal": "^0.12.0",
|
|
90
92
|
react: "^19.1.1",
|
|
91
93
|
"socket.io-client": "^4.8.1",
|
|
@@ -94,7 +96,9 @@ var dependencies = {
|
|
|
94
96
|
};
|
|
95
97
|
var devDependencies = {
|
|
96
98
|
"@eslint/compat": "^1",
|
|
99
|
+
"@types/cross-spawn": "^6.0.6",
|
|
97
100
|
"@types/node": ">=20",
|
|
101
|
+
"@types/ps-list": "^6.2.1",
|
|
98
102
|
"cross-env": "^10.0.0",
|
|
99
103
|
dotenv: "^16.6.1",
|
|
100
104
|
eslint: "^9",
|
|
@@ -153,7 +157,7 @@ class Configuration {
|
|
|
153
157
|
currentCliVersion;
|
|
154
158
|
isExperimentalEnabled;
|
|
155
159
|
constructor() {
|
|
156
|
-
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://
|
|
160
|
+
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://api.cluster-fluster.com";
|
|
157
161
|
const args = process.argv.slice(2);
|
|
158
162
|
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
159
163
|
if (process.env.HAPPY_HOME_DIR) {
|
|
@@ -533,7 +537,7 @@ class Logger {
|
|
|
533
537
|
appendFileSync(this.logFilePath, logLine);
|
|
534
538
|
} catch (appendError) {
|
|
535
539
|
if (process.env.DEBUG) {
|
|
536
|
-
console.error("Failed to append to log file:", appendError);
|
|
540
|
+
console.error("[DEV MODE ONLY THROWING] Failed to append to log file:", appendError);
|
|
537
541
|
throw appendError;
|
|
538
542
|
}
|
|
539
543
|
}
|
|
@@ -640,7 +644,23 @@ z$1.object({
|
|
|
640
644
|
metadata: z$1.any(),
|
|
641
645
|
metadataVersion: z$1.number(),
|
|
642
646
|
agentState: z$1.any().nullable(),
|
|
643
|
-
agentStateVersion: z$1.number()
|
|
647
|
+
agentStateVersion: z$1.number(),
|
|
648
|
+
// Connectivity tracking (from server)
|
|
649
|
+
connectivityStatus: z$1.union([
|
|
650
|
+
z$1.enum(["neverConnected", "online", "offline"]),
|
|
651
|
+
z$1.string()
|
|
652
|
+
// Forward compatibility
|
|
653
|
+
]).optional(),
|
|
654
|
+
connectivityStatusSince: z$1.number().optional(),
|
|
655
|
+
connectivityStatusReason: z$1.string().optional(),
|
|
656
|
+
// State tracking (from server)
|
|
657
|
+
state: z$1.union([
|
|
658
|
+
z$1.enum(["running", "archiveRequested", "archived"]),
|
|
659
|
+
z$1.string()
|
|
660
|
+
// Forward compatibility
|
|
661
|
+
]).optional(),
|
|
662
|
+
stateSince: z$1.number().optional(),
|
|
663
|
+
stateReason: z$1.string().optional()
|
|
644
664
|
});
|
|
645
665
|
z$1.object({
|
|
646
666
|
host: z$1.string(),
|
|
@@ -678,7 +698,23 @@ z$1.object({
|
|
|
678
698
|
active: z$1.boolean(),
|
|
679
699
|
activeAt: z$1.number(),
|
|
680
700
|
createdAt: z$1.number(),
|
|
681
|
-
updatedAt: z$1.number()
|
|
701
|
+
updatedAt: z$1.number(),
|
|
702
|
+
// Connectivity tracking (from server)
|
|
703
|
+
connectivityStatus: z$1.union([
|
|
704
|
+
z$1.enum(["neverConnected", "online", "offline"]),
|
|
705
|
+
z$1.string()
|
|
706
|
+
// Forward compatibility
|
|
707
|
+
]).optional(),
|
|
708
|
+
connectivityStatusSince: z$1.number().optional(),
|
|
709
|
+
connectivityStatusReason: z$1.string().optional(),
|
|
710
|
+
// State tracking (from server)
|
|
711
|
+
state: z$1.union([
|
|
712
|
+
z$1.enum(["running", "archiveRequested", "archived"]),
|
|
713
|
+
z$1.string()
|
|
714
|
+
// Forward compatibility
|
|
715
|
+
]).optional(),
|
|
716
|
+
stateSince: z$1.number().optional(),
|
|
717
|
+
stateReason: z$1.string().optional()
|
|
682
718
|
});
|
|
683
719
|
z$1.object({
|
|
684
720
|
content: SessionMessageContentSchema,
|
|
@@ -991,7 +1027,9 @@ class ApiSessionClient extends EventEmitter {
|
|
|
991
1027
|
* Send a ping message to keep the connection alive
|
|
992
1028
|
*/
|
|
993
1029
|
keepAlive(thinking, mode) {
|
|
994
|
-
|
|
1030
|
+
if (process.env.DEBUG) {
|
|
1031
|
+
logger.debug(`[API] Sending keep alive message: ${thinking}`);
|
|
1032
|
+
}
|
|
995
1033
|
this.socket.volatile.emit("session-alive", {
|
|
996
1034
|
sid: this.sessionId,
|
|
997
1035
|
time: Date.now(),
|
|
@@ -1229,37 +1267,39 @@ class ApiMachineClient {
|
|
|
1229
1267
|
this.socket.on("rpc-request", async (data, callback) => {
|
|
1230
1268
|
logger.debugLargeJson(`[API MACHINE] Received RPC request:`, data);
|
|
1231
1269
|
try {
|
|
1232
|
-
|
|
1233
|
-
const stopMethod2 = `${this.machine.id}:stop-session`;
|
|
1234
|
-
const stopDaemonMethod2 = `${this.machine.id}:stop-daemon`;
|
|
1235
|
-
if (data.method === spawnMethod2) {
|
|
1270
|
+
if (data.method === spawnMethod) {
|
|
1236
1271
|
if (!this.spawnSession) {
|
|
1237
1272
|
throw new Error("Spawn session handler not set");
|
|
1238
1273
|
}
|
|
1239
|
-
const { directory, sessionId } = decrypt(decodeBase64(data.params), this.secret) || {};
|
|
1274
|
+
const { directory, sessionId, machineId, approvedNewDirectoryCreation } = decrypt(decodeBase64(data.params), this.secret) || {};
|
|
1240
1275
|
if (!directory) {
|
|
1241
1276
|
throw new Error("Directory is required");
|
|
1242
1277
|
}
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1278
|
+
const result = await this.spawnSession({ directory, sessionId, machineId, approvedNewDirectoryCreation });
|
|
1279
|
+
switch (result.type) {
|
|
1280
|
+
case "success": {
|
|
1281
|
+
logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
|
|
1282
|
+
const response = {
|
|
1283
|
+
type: "success",
|
|
1284
|
+
sessionId: result.sessionId
|
|
1285
|
+
};
|
|
1286
|
+
logger.debug(`[API MACHINE] Sending RPC response:`, response);
|
|
1287
|
+
callback(encodeBase64(encrypt(response, this.secret)));
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
case "requestToApproveDirectoryCreation":
|
|
1291
|
+
const promptResponse = {
|
|
1292
|
+
type: "requestToApproveDirectoryCreation",
|
|
1293
|
+
directory: result.directory
|
|
1294
|
+
};
|
|
1295
|
+
logger.debug(`[API MACHINE] Requesting directory creation approval for: ${result.directory}`);
|
|
1296
|
+
callback(encodeBase64(encrypt(promptResponse, this.secret)));
|
|
1297
|
+
return;
|
|
1298
|
+
case "error":
|
|
1299
|
+
throw new Error(result.errorMessage);
|
|
1253
1300
|
}
|
|
1254
|
-
const response = {
|
|
1255
|
-
sessionId: session.happySessionId,
|
|
1256
|
-
message: session.message
|
|
1257
|
-
};
|
|
1258
|
-
logger.debug(`[API MACHINE] Sending RPC response:`, response);
|
|
1259
|
-
callback(encodeBase64(encrypt(response, this.secret)));
|
|
1260
|
-
return;
|
|
1261
1301
|
}
|
|
1262
|
-
if (data.method ===
|
|
1302
|
+
if (data.method === stopMethod) {
|
|
1263
1303
|
logger.debug("[API MACHINE] Received stop-session RPC request");
|
|
1264
1304
|
const decryptedParams = decrypt(decodeBase64(data.params), this.secret);
|
|
1265
1305
|
const { sessionId } = decryptedParams || {};
|
|
@@ -1279,7 +1319,7 @@ class ApiMachineClient {
|
|
|
1279
1319
|
callback(encryptedResponse);
|
|
1280
1320
|
return;
|
|
1281
1321
|
}
|
|
1282
|
-
if (data.method ===
|
|
1322
|
+
if (data.method === stopDaemonMethod) {
|
|
1283
1323
|
logger.debug("[API MACHINE] Received stop-daemon RPC request");
|
|
1284
1324
|
callback(encodeBase64(encrypt({
|
|
1285
1325
|
message: "Daemon stop request acknowledged, starting shutdown sequence..."
|
|
@@ -1340,7 +1380,9 @@ class ApiMachineClient {
|
|
|
1340
1380
|
machineId: this.machine.id,
|
|
1341
1381
|
time: Date.now()
|
|
1342
1382
|
};
|
|
1343
|
-
|
|
1383
|
+
if (process.env.DEBUG) {
|
|
1384
|
+
logger.debugLargeJson(`[API MACHINE] Emitting machine-alive`, payload);
|
|
1385
|
+
}
|
|
1344
1386
|
this.socket.emit("machine-alive", payload);
|
|
1345
1387
|
}, 2e4);
|
|
1346
1388
|
logger.debug("[API MACHINE] Keep-alive started (20s interval)");
|
|
@@ -1366,7 +1408,7 @@ class PushNotificationClient {
|
|
|
1366
1408
|
token;
|
|
1367
1409
|
baseUrl;
|
|
1368
1410
|
expo;
|
|
1369
|
-
constructor(token, baseUrl = "https://
|
|
1411
|
+
constructor(token, baseUrl = "https://api.cluster-fluster.com") {
|
|
1370
1412
|
this.token = token;
|
|
1371
1413
|
this.baseUrl = baseUrl;
|
|
1372
1414
|
this.expo = new Expo();
|
|
@@ -1615,6 +1657,34 @@ class ApiClient {
|
|
|
1615
1657
|
push() {
|
|
1616
1658
|
return this.pushClient;
|
|
1617
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Register a vendor API token with the server
|
|
1662
|
+
* The token is sent as a JSON string - server handles encryption
|
|
1663
|
+
*/
|
|
1664
|
+
async registerVendorToken(vendor, apiKey) {
|
|
1665
|
+
try {
|
|
1666
|
+
const response = await axios.post(
|
|
1667
|
+
`${configuration.serverUrl}/v1/connect/${vendor}/register`,
|
|
1668
|
+
{
|
|
1669
|
+
token: JSON.stringify(apiKey)
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
headers: {
|
|
1673
|
+
"Authorization": `Bearer ${this.token}`,
|
|
1674
|
+
"Content-Type": "application/json"
|
|
1675
|
+
},
|
|
1676
|
+
timeout: 5e3
|
|
1677
|
+
}
|
|
1678
|
+
);
|
|
1679
|
+
if (response.status !== 200 && response.status !== 201) {
|
|
1680
|
+
throw new Error(`Server returned status ${response.status}`);
|
|
1681
|
+
}
|
|
1682
|
+
logger.debug(`[API] Vendor token for ${vendor} registered successfully`);
|
|
1683
|
+
} catch (error) {
|
|
1684
|
+
logger.debug(`[API] [ERROR] Failed to register vendor token:`, error);
|
|
1685
|
+
throw new Error(`Failed to register vendor token: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1618
1688
|
}
|
|
1619
1689
|
|
|
1620
1690
|
const UsageSchema = z$1.object({
|