cc-control-agent 2.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 (57) hide show
  1. package/dist/auth/device-manager.d.ts +20 -0
  2. package/dist/auth/device-manager.d.ts.map +1 -0
  3. package/dist/auth/device-manager.js +101 -0
  4. package/dist/auth/device-manager.js.map +1 -0
  5. package/dist/auth/user-credentials.d.ts +35 -0
  6. package/dist/auth/user-credentials.d.ts.map +1 -0
  7. package/dist/auth/user-credentials.js +128 -0
  8. package/dist/auth/user-credentials.js.map +1 -0
  9. package/dist/claude/hook-handler.d.ts +27 -0
  10. package/dist/claude/hook-handler.d.ts.map +1 -0
  11. package/dist/claude/hook-handler.js +191 -0
  12. package/dist/claude/hook-handler.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +195 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/command/handler.d.ts +34 -0
  18. package/dist/command/handler.d.ts.map +1 -0
  19. package/dist/command/handler.js +371 -0
  20. package/dist/command/handler.js.map +1 -0
  21. package/dist/command/validator.d.ts +23 -0
  22. package/dist/command/validator.d.ts.map +1 -0
  23. package/dist/command/validator.js +295 -0
  24. package/dist/command/validator.js.map +1 -0
  25. package/dist/communication/websocket-client.d.ts +28 -0
  26. package/dist/communication/websocket-client.d.ts.map +1 -0
  27. package/dist/communication/websocket-client.js +224 -0
  28. package/dist/communication/websocket-client.js.map +1 -0
  29. package/dist/config/default.d.ts +19 -0
  30. package/dist/config/default.d.ts.map +1 -0
  31. package/dist/config/default.js +40 -0
  32. package/dist/config/default.js.map +1 -0
  33. package/dist/index.d.ts +16 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +155 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/session/claude-monitor.d.ts +66 -0
  38. package/dist/session/claude-monitor.d.ts.map +1 -0
  39. package/dist/session/claude-monitor.js +770 -0
  40. package/dist/session/claude-monitor.js.map +1 -0
  41. package/dist/session/monitor.d.ts +22 -0
  42. package/dist/session/monitor.d.ts.map +1 -0
  43. package/dist/session/monitor.js +189 -0
  44. package/dist/session/monitor.js.map +1 -0
  45. package/dist/session/parser.d.ts +51 -0
  46. package/dist/session/parser.d.ts.map +1 -0
  47. package/dist/session/parser.js +139 -0
  48. package/dist/session/parser.js.map +1 -0
  49. package/dist/utils/logger-new.d.ts +1 -0
  50. package/dist/utils/logger-new.d.ts.map +1 -0
  51. package/dist/utils/logger-new.js +2 -0
  52. package/dist/utils/logger-new.js.map +1 -0
  53. package/dist/utils/logger.d.ts +11 -0
  54. package/dist/utils/logger.d.ts.map +1 -0
  55. package/dist/utils/logger.js +37 -0
  56. package/dist/utils/logger.js.map +1 -0
  57. package/package.json +42 -0
@@ -0,0 +1,295 @@
1
+ // ============================================================================
2
+ // Command Validator - Security Validation for Remote Commands
3
+ // ============================================================================
4
+ import { relative, resolve } from "path";
5
+ import { logger } from "../utils/logger.js";
6
+ import { getConfig } from "../config/default.js";
7
+ import { z } from "zod";
8
+ // Zod schemas for validation
9
+ const SendPromptPayloadSchema = z.object({
10
+ prompt: z.string().max(100000), // Max 100KB prompt
11
+ context: z
12
+ .object({
13
+ workingDirectory: z.string().optional(),
14
+ files: z.array(z.string()).optional(),
15
+ })
16
+ .optional(),
17
+ });
18
+ const SwitchSessionPayloadSchema = z.object({
19
+ targetSessionId: z.string().uuid(),
20
+ });
21
+ const ManageTaskPayloadSchema = z.object({
22
+ taskId: z.string(),
23
+ action: z.enum(["cancel", "pause", "resume"]),
24
+ });
25
+ const FileOperationPayloadSchema = z.object({
26
+ operation: z.enum(["read", "write", "delete", "list"]),
27
+ path: z.string(),
28
+ content: z.string().optional(),
29
+ });
30
+ export class CommandValidator {
31
+ config = getConfig();
32
+ blockedPatterns;
33
+ maxFileSize = 10 * 1024 * 1024; // 10MB
34
+ constructor() {
35
+ // Initialize security patterns
36
+ this.blockedPatterns = [
37
+ // Block absolute paths outside allowed directories
38
+ /^(\/(?!home\/|Users\/|mnt\/|media\/)|~\/)/,
39
+ // Block path traversal
40
+ /\.\.[\/\\]/,
41
+ // Block environment variable access
42
+ /\$\{[^}]*\}/,
43
+ // Block command substitution
44
+ /\$\(.*\)/,
45
+ // Block pipe operators
46
+ /\|/,
47
+ // Block command chaining
48
+ /;/,
49
+ // Block background processes
50
+ /&$/,
51
+ // Block redirect operators
52
+ /[<>]/,
53
+ ];
54
+ }
55
+ validateCommand(command) {
56
+ try {
57
+ // Validate command structure
58
+ if (!command.id || !command.type || !command.sessionId) {
59
+ return {
60
+ valid: false,
61
+ error: "Missing required command fields",
62
+ };
63
+ }
64
+ // Validate timestamp
65
+ const now = Date.now();
66
+ const commandTime = new Date(command.timestamp).getTime();
67
+ const maxAge = 5 * 60 * 1000; // 5 minutes
68
+ if (Math.abs(now - commandTime) > maxAge) {
69
+ return {
70
+ valid: false,
71
+ error: "Command timestamp too old or in the future",
72
+ };
73
+ }
74
+ // Validate payload based on command type
75
+ switch (command.type) {
76
+ case "send_prompt":
77
+ return this.validateSendPrompt(command.payload);
78
+ case "switch_session":
79
+ return this.validateSwitchSession(command.payload);
80
+ case "manage_task":
81
+ return this.validateManageTask(command.payload);
82
+ case "file_operation":
83
+ return this.validateFileOperation(command.payload);
84
+ default:
85
+ return {
86
+ valid: false,
87
+ error: `Unknown command type: ${command.type}`,
88
+ };
89
+ }
90
+ }
91
+ catch (error) {
92
+ logger.error("Error validating command", error);
93
+ return {
94
+ valid: false,
95
+ error: "Validation error",
96
+ };
97
+ }
98
+ }
99
+ validateSendPrompt(payload) {
100
+ try {
101
+ const validated = SendPromptPayloadSchema.parse(payload);
102
+ // Check for malicious patterns in prompt
103
+ const prompt = validated.prompt;
104
+ for (const pattern of this.blockedPatterns) {
105
+ if (pattern.test(prompt)) {
106
+ return {
107
+ valid: false,
108
+ error: "Prompt contains blocked patterns",
109
+ };
110
+ }
111
+ }
112
+ // Validate working directory if provided
113
+ if (validated.context?.workingDirectory) {
114
+ if (!this.isAllowedDirectory(validated.context.workingDirectory)) {
115
+ return {
116
+ valid: false,
117
+ error: "Working directory not in allowed paths",
118
+ };
119
+ }
120
+ }
121
+ // Validate file paths if provided
122
+ if (validated.context?.files) {
123
+ for (const file of validated.context.files) {
124
+ if (!this.isAllowedPath(file)) {
125
+ return {
126
+ valid: false,
127
+ error: `File path not allowed: ${file}`,
128
+ };
129
+ }
130
+ }
131
+ }
132
+ return { valid: true };
133
+ }
134
+ catch (error) {
135
+ if (error instanceof z.ZodError) {
136
+ return {
137
+ valid: false,
138
+ error: `Invalid payload: ${error.errors.map((e) => e.message).join(", ")}`,
139
+ };
140
+ }
141
+ return {
142
+ valid: false,
143
+ error: "Failed to validate send prompt payload",
144
+ };
145
+ }
146
+ }
147
+ validateSwitchSession(payload) {
148
+ try {
149
+ SwitchSessionPayloadSchema.parse(payload);
150
+ return { valid: true };
151
+ }
152
+ catch (error) {
153
+ if (error instanceof z.ZodError) {
154
+ return {
155
+ valid: false,
156
+ error: `Invalid payload: ${error.errors.map((e) => e.message).join(", ")}`,
157
+ };
158
+ }
159
+ return {
160
+ valid: false,
161
+ error: "Failed to validate switch session payload",
162
+ };
163
+ }
164
+ }
165
+ validateManageTask(payload) {
166
+ try {
167
+ ManageTaskPayloadSchema.parse(payload);
168
+ return { valid: true };
169
+ }
170
+ catch (error) {
171
+ if (error instanceof z.ZodError) {
172
+ return {
173
+ valid: false,
174
+ error: `Invalid payload: ${error.errors.map((e) => e.message).join(", ")}`,
175
+ };
176
+ }
177
+ return {
178
+ valid: false,
179
+ error: "Failed to validate manage task payload",
180
+ };
181
+ }
182
+ }
183
+ validateFileOperation(payload) {
184
+ try {
185
+ const validated = FileOperationPayloadSchema.parse(payload);
186
+ // Validate file path
187
+ if (!this.isAllowedPath(validated.path)) {
188
+ return {
189
+ valid: false,
190
+ error: `File path not allowed: ${validated.path}`,
191
+ };
192
+ }
193
+ // For write operations, validate content size
194
+ if (validated.operation === "write" && validated.content) {
195
+ const contentSize = Buffer.byteLength(validated.content, "utf-8");
196
+ if (contentSize > this.maxFileSize) {
197
+ return {
198
+ valid: false,
199
+ error: `File content too large: ${contentSize} bytes (max: ${this.maxFileSize})`,
200
+ };
201
+ }
202
+ }
203
+ // Prevent deletion of sensitive files
204
+ if (validated.operation === "delete") {
205
+ const filename = validated.path.toLowerCase();
206
+ const sensitiveFiles = [
207
+ ".env",
208
+ ".git",
209
+ "node_modules",
210
+ "package-lock.json",
211
+ "yarn.lock",
212
+ ".ssh",
213
+ ".gnupg",
214
+ ];
215
+ for (const sensitive of sensitiveFiles) {
216
+ if (filename.includes(sensitive)) {
217
+ return {
218
+ valid: false,
219
+ error: `Cannot delete sensitive file/directory: ${sensitive}`,
220
+ };
221
+ }
222
+ }
223
+ }
224
+ return { valid: true };
225
+ }
226
+ catch (error) {
227
+ if (error instanceof z.ZodError) {
228
+ return {
229
+ valid: false,
230
+ error: `Invalid payload: ${error.errors.map((e) => e.message).join(", ")}`,
231
+ };
232
+ }
233
+ return {
234
+ valid: false,
235
+ error: "Failed to validate file operation payload",
236
+ };
237
+ }
238
+ }
239
+ isAllowedDirectory(path) {
240
+ const resolvedPath = resolve(path);
241
+ // Check if path is within any allowed directory
242
+ return this.config.allowedDirectories.some((allowedDir) => {
243
+ const resolvedAllowed = resolve(allowedDir);
244
+ const relativePath = relative(resolvedAllowed, resolvedPath);
245
+ return !relativePath.startsWith("..");
246
+ });
247
+ }
248
+ isAllowedPath(path) {
249
+ const resolvedPath = resolve(path);
250
+ // Check for path traversal
251
+ if (resolvedPath.includes("..")) {
252
+ return false;
253
+ }
254
+ // Check if within allowed directories
255
+ return this.isAllowedDirectory(resolvedPath);
256
+ }
257
+ sanitizePath(path) {
258
+ // Remove any dangerous patterns
259
+ let sanitized = path
260
+ .replace(/\.\.[\/\\]/g, "")
261
+ .replace(/[<>|;&$()]/g, "")
262
+ .trim();
263
+ return sanitized;
264
+ }
265
+ validatePromptContent(prompt) {
266
+ // Check for command injection patterns
267
+ const injectionPatterns = [
268
+ /\beval\b/,
269
+ /\bexec\b/,
270
+ /\bsystem\b/,
271
+ /\bspawn\b/,
272
+ /\bchild_process\b/,
273
+ /\`\$\(/,
274
+ /\`/,
275
+ ];
276
+ // Check for excessive length
277
+ if (prompt.length > 100000) {
278
+ return {
279
+ valid: false,
280
+ reason: "Prompt too long",
281
+ };
282
+ }
283
+ // Check for suspicious patterns
284
+ for (const pattern of injectionPatterns) {
285
+ if (pattern.test(prompt)) {
286
+ return {
287
+ valid: false,
288
+ reason: "Suspicious pattern detected",
289
+ };
290
+ }
291
+ }
292
+ return { valid: true };
293
+ }
294
+ }
295
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/command/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { DeviceManager } from "../auth/device-manager.js";
2
+ import type { MessageEnvelope } from "cc-control-shared";
3
+ export interface SocketClientOptions {
4
+ onMessage?: (message: MessageEnvelope) => void;
5
+ onConnected?: () => void;
6
+ onDisconnected?: () => void;
7
+ onError?: (error: Error) => void;
8
+ }
9
+ export declare class WebSocketClient {
10
+ private deviceManager;
11
+ private socket;
12
+ private config;
13
+ private reconnectTimer;
14
+ reconnectAttempts: number;
15
+ private isManualDisconnect;
16
+ private messageQueue;
17
+ private options;
18
+ constructor(deviceManager: DeviceManager, options?: SocketClientOptions);
19
+ connect(): Promise<void>;
20
+ private handleMessage;
21
+ send(message: MessageEnvelope): void;
22
+ private flushMessageQueue;
23
+ private scheduleReconnect;
24
+ disconnect(): Promise<void>;
25
+ isConnected(): boolean;
26
+ getConnectionState(): "connected" | "connecting" | "disconnected" | "reconnecting";
27
+ }
28
+ //# sourceMappingURL=websocket-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../../src/communication/websocket-client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,mBAAmB,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAA+B;IACrD,iBAAiB,SAAK;IACtB,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,OAAO,CAAsB;gBAEzB,aAAa,EAAE,aAAa,EAAE,OAAO,GAAE,mBAAwB;IAKrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyI9B,OAAO,CAAC,aAAa;IAYrB,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAsBpC,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,iBAAiB;IAKnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBjC,WAAW,IAAI,OAAO;IAItB,kBAAkB,IAAI,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,cAAc;CAWnF"}
@@ -0,0 +1,224 @@
1
+ // ============================================================================
2
+ // Socket.io Client - Compatible with Relay Server
3
+ // ============================================================================
4
+ import { io } from "socket.io-client";
5
+ import { logger } from "../utils/logger.js";
6
+ import { getConfig } from "../config/default.js";
7
+ export class WebSocketClient {
8
+ deviceManager;
9
+ socket = null;
10
+ config = getConfig();
11
+ reconnectTimer = null;
12
+ reconnectAttempts = 0;
13
+ isManualDisconnect = false;
14
+ messageQueue = [];
15
+ options;
16
+ constructor(deviceManager, options = {}) {
17
+ this.deviceManager = deviceManager;
18
+ this.options = options;
19
+ }
20
+ async connect() {
21
+ if (this.socket && this.socket.connected) {
22
+ logger.warn("Socket.io already connected");
23
+ return;
24
+ }
25
+ return new Promise((resolve, reject) => {
26
+ try {
27
+ const url = this.config.relayUrl;
28
+ logger.info(`Connecting to relay server: ${url}`);
29
+ // Get auth token from user credentials (stored in ~/.cc-control/credentials.json)
30
+ const token = this.deviceManager.getAccessToken();
31
+ const deviceId = this.deviceManager.getDeviceId();
32
+ // Create Socket.io client with user JWT auth
33
+ this.socket = io(url, {
34
+ auth: {
35
+ token,
36
+ deviceId,
37
+ },
38
+ reconnection: true,
39
+ reconnectionDelay: this.config.reconnectInterval,
40
+ reconnectionDelayMax: 30000,
41
+ reconnectionAttempts: this.config.maxReconnectAttempts,
42
+ timeout: this.config.connectionTimeout,
43
+ });
44
+ // Connection established
45
+ this.socket.on("connect", () => {
46
+ logger.info("Socket.io connection established");
47
+ this.reconnectAttempts = 0;
48
+ this.isManualDisconnect = false;
49
+ // Update device status
50
+ this.deviceManager.updateDeviceStatus("online");
51
+ // Send queued messages
52
+ this.flushMessageQueue();
53
+ this.options.onConnected?.();
54
+ resolve();
55
+ });
56
+ // Receive messages from server
57
+ this.socket.on("message", (data) => {
58
+ this.handleMessage(data);
59
+ });
60
+ // Listen for command events from relay (forwarded from mobile)
61
+ const commandEvents = [
62
+ "command:send_prompt",
63
+ "command:switch_session",
64
+ "command:manage_task",
65
+ "command:file_operation",
66
+ ];
67
+ for (const event of commandEvents) {
68
+ this.socket.on(event, (data) => {
69
+ logger.info(`Received command event: ${event}`, { sessionId: data?.sessionId });
70
+ this.handleMessage({
71
+ type: event,
72
+ payload: data,
73
+ id: `cmd-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
74
+ timestamp: new Date().toISOString(),
75
+ });
76
+ });
77
+ }
78
+ // Authentication events from server
79
+ this.socket.on("auth:success", (data) => {
80
+ logger.info("Authentication successful", data);
81
+ const payload = data;
82
+ // Save tokens if provided
83
+ if (payload.token) {
84
+ this.deviceManager.saveTokens({
85
+ accessToken: payload.token,
86
+ refreshToken: payload.token, // Use access token as refresh token for now
87
+ expiresAt: new Date(payload.expiresAt),
88
+ });
89
+ }
90
+ });
91
+ this.socket.on("auth:error", (error) => {
92
+ logger.error("Authentication failed", error);
93
+ });
94
+ // Connection error
95
+ this.socket.on("connect_error", (error) => {
96
+ logger.error("Socket.io connection error", error);
97
+ this.options.onError?.(error);
98
+ reject(error);
99
+ });
100
+ // Disconnection
101
+ this.socket.on("disconnect", (reason) => {
102
+ logger.info("Socket.io disconnected", { reason });
103
+ this.deviceManager.updateDeviceStatus("offline");
104
+ this.options.onDisconnected?.();
105
+ // Attempt reconnection if not manual disconnect
106
+ if (!this.isManualDisconnect && reason !== "io client disconnect") {
107
+ this.scheduleReconnect();
108
+ }
109
+ });
110
+ // Reconnection attempts
111
+ this.socket.on("reconnect", (attemptNumber) => {
112
+ logger.info(`Reconnecting... (attempt ${attemptNumber})`);
113
+ this.reconnectAttempts = attemptNumber;
114
+ });
115
+ this.socket.on("reconnect_attempt", (attemptNumber) => {
116
+ logger.info(`Reconnection attempt ${attemptNumber}`);
117
+ });
118
+ this.socket.on("reconnect_failed", (error) => {
119
+ logger.error("Reconnection failed", error);
120
+ });
121
+ this.socket.on("reconnect_error", (error) => {
122
+ logger.error("Reconnection error", error);
123
+ });
124
+ // Connection timeout
125
+ this.socket.on("connect_timeout", () => {
126
+ logger.error("Socket.io connection timeout");
127
+ const error = new Error("Connection timeout");
128
+ reject(error);
129
+ });
130
+ }
131
+ catch (error) {
132
+ logger.error("Failed to create Socket.io client", error);
133
+ reject(error);
134
+ }
135
+ });
136
+ }
137
+ handleMessage(data) {
138
+ try {
139
+ const message = data;
140
+ logger.debug("Received message", { type: message.type, id: message.id });
141
+ // Pass all messages to handler
142
+ this.options.onMessage?.(message);
143
+ }
144
+ catch (error) {
145
+ logger.error("Failed to handle message", error);
146
+ }
147
+ }
148
+ send(message) {
149
+ // Add device ID to message
150
+ message.deviceId = this.deviceManager.getDeviceId();
151
+ message.timestamp = new Date().toISOString();
152
+ logger.info(`[WS CLIENT] Sending message: ${message.type}`, { id: message.id });
153
+ if (this.socket && this.socket.connected) {
154
+ try {
155
+ // Emit using message type as the event name (e.g., "state:session_update")
156
+ this.socket.emit(message.type, message.payload);
157
+ logger.info(`[WS CLIENT] Emitted ${message.type}`, { id: message.id });
158
+ }
159
+ catch (error) {
160
+ logger.error("Failed to send message", error);
161
+ this.messageQueue.push(message);
162
+ }
163
+ }
164
+ else {
165
+ logger.warn("Socket.io not connected, queuing message");
166
+ this.messageQueue.push(message);
167
+ }
168
+ }
169
+ flushMessageQueue() {
170
+ if (this.messageQueue.length === 0) {
171
+ return;
172
+ }
173
+ logger.info(`Flushing ${this.messageQueue.length} queued messages`);
174
+ while (this.messageQueue.length > 0 && this.socket && this.socket.connected) {
175
+ const message = this.messageQueue.shift();
176
+ if (message) {
177
+ try {
178
+ // Emit using message type as the event name (e.g., "state:session_update")
179
+ this.socket.emit(message.type, message.payload);
180
+ logger.info(`[WS CLIENT] Flushed queued message: ${message.type}`, { id: message.id });
181
+ }
182
+ catch (error) {
183
+ logger.error("Failed to send queued message", error);
184
+ // Put message back at front of queue
185
+ this.messageQueue.unshift(message);
186
+ break;
187
+ }
188
+ }
189
+ }
190
+ }
191
+ scheduleReconnect() {
192
+ // Socket.io handles reconnection automatically, but we can add custom logic here if needed
193
+ logger.info("Socket.io will handle reconnection automatically");
194
+ }
195
+ async disconnect() {
196
+ this.isManualDisconnect = true;
197
+ // Clear reconnect timer
198
+ if (this.reconnectTimer) {
199
+ clearTimeout(this.reconnectTimer);
200
+ this.reconnectTimer = null;
201
+ }
202
+ return new Promise((resolve) => {
203
+ if (this.socket) {
204
+ this.socket.disconnect();
205
+ this.socket = null;
206
+ logger.info("Socket.io disconnected");
207
+ }
208
+ resolve();
209
+ });
210
+ }
211
+ isConnected() {
212
+ return this.socket !== null && this.socket.connected;
213
+ }
214
+ getConnectionState() {
215
+ if (!this.socket) {
216
+ return "disconnected";
217
+ }
218
+ if (this.socket.connected) {
219
+ return "connected";
220
+ }
221
+ return "connecting";
222
+ }
223
+ }
224
+ //# sourceMappingURL=websocket-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../../src/communication/websocket-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { DeviceCapabilities } from "cc-control-shared";
2
+ export interface DesktopAgentConfig {
3
+ deviceName: string;
4
+ deviceType: "desktop";
5
+ capabilities: DeviceCapabilities;
6
+ relayUrl: string;
7
+ reconnectInterval: number;
8
+ maxReconnectAttempts: number;
9
+ connectionTimeout: number;
10
+ claudeConfigPath: string;
11
+ sessionWatchDebounce: number;
12
+ allowedDirectories: string[];
13
+ maxCommandExecutionTime: number;
14
+ logLevel: "debug" | "info" | "warn" | "error";
15
+ }
16
+ export declare const defaultConfig: DesktopAgentConfig;
17
+ export declare function getConfig(): DesktopAgentConfig;
18
+ export declare function mergeConfig(overrides: Partial<DesktopAgentConfig>): DesktopAgentConfig;
19
+ //# sourceMappingURL=default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/config/default.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IAEjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;IACtB,YAAY,EAAE,kBAAkB,CAAC;IAGjC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAG1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAG7B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,uBAAuB,EAAE,MAAM,CAAC;IAGhC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAED,eAAO,MAAM,aAAa,EAAE,kBA0B3B,CAAC;AAEF,wBAAgB,SAAS,IAAI,kBAAkB,CAE9C;AAED,wBAAgB,WAAW,CACzB,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACrC,kBAAkB,CASpB"}
@@ -0,0 +1,40 @@
1
+ // ============================================================================
2
+ // Default Configuration for Desktop Agent
3
+ // ============================================================================
4
+ export const defaultConfig = {
5
+ deviceName: `${process.env.USER || "user"}'s Desktop`,
6
+ deviceType: "desktop",
7
+ capabilities: {
8
+ version: "1.0.0",
9
+ features: [
10
+ "session_monitoring",
11
+ "prompt_injection",
12
+ "file_operations",
13
+ "task_management",
14
+ ],
15
+ },
16
+ relayUrl: process.env.RELAY_URL || "wss://cccontrol-relay.lemonbush-3c426472.centralindia.azurecontainerapps.io",
17
+ reconnectInterval: 2000, // Starting reconnect interval in ms
18
+ maxReconnectAttempts: 10,
19
+ connectionTimeout: 10000, // 10 seconds
20
+ claudeConfigPath: `${process.env.HOME}/.claude/projects`,
21
+ sessionWatchDebounce: 300, // Debounce file changes by 300ms
22
+ // Security: Only allow home directory by default
23
+ allowedDirectories: [process.env.HOME || "/"],
24
+ maxCommandExecutionTime: 30000, // 30 seconds
25
+ logLevel: process.env.LOG_LEVEL || "info",
26
+ };
27
+ export function getConfig() {
28
+ return { ...defaultConfig };
29
+ }
30
+ export function mergeConfig(overrides) {
31
+ return {
32
+ ...defaultConfig,
33
+ ...overrides,
34
+ capabilities: {
35
+ ...defaultConfig.capabilities,
36
+ ...(overrides.capabilities || {}),
37
+ },
38
+ };
39
+ }
40
+ //# sourceMappingURL=default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.js","sourceRoot":"","sources":["../../src/config/default.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0CAA0C;AAC1C,+EAA+E;AA4B/E,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,YAAY;IACrD,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE;QACZ,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE;YACR,oBAAoB;YACpB,kBAAkB;YAClB,iBAAiB;YACjB,iBAAiB;SAClB;KACF;IAED,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,6EAA6E;IAChH,iBAAiB,EAAE,IAAI,EAAE,oCAAoC;IAC7D,oBAAoB,EAAE,EAAE;IACxB,iBAAiB,EAAE,KAAK,EAAE,aAAa;IAEvC,gBAAgB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,mBAAmB;IACxD,oBAAoB,EAAE,GAAG,EAAE,iCAAiC;IAE5D,iDAAiD;IACjD,kBAAkB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;IAC7C,uBAAuB,EAAE,KAAK,EAAE,aAAa;IAE7C,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,SAA4C,IAAI,MAAM;CAC9E,CAAC;AAEF,MAAM,UAAU,SAAS;IACvB,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,SAAsC;IAEtC,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,SAAS;QACZ,YAAY,EAAE;YACZ,GAAG,aAAa,CAAC,YAAY;YAC7B,GAAG,CAAC,SAAS,CAAC,YAAY,IAAI,EAAE,CAAC;SAClC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export declare class DesktopAgent {
2
+ private deviceManager;
3
+ private wsClient;
4
+ private sessionMonitor?;
5
+ private commandHandler;
6
+ private hookHandler;
7
+ private isRunning;
8
+ constructor();
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ isStarted(): boolean;
12
+ private handleMessage;
13
+ private handleCommandMessage;
14
+ }
15
+ export declare function main(): Promise<void>;
16
+ //# sourceMappingURL=index.d.ts.map