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.
- package/dist/auth/device-manager.d.ts +20 -0
- package/dist/auth/device-manager.d.ts.map +1 -0
- package/dist/auth/device-manager.js +101 -0
- package/dist/auth/device-manager.js.map +1 -0
- package/dist/auth/user-credentials.d.ts +35 -0
- package/dist/auth/user-credentials.d.ts.map +1 -0
- package/dist/auth/user-credentials.js +128 -0
- package/dist/auth/user-credentials.js.map +1 -0
- package/dist/claude/hook-handler.d.ts +27 -0
- package/dist/claude/hook-handler.d.ts.map +1 -0
- package/dist/claude/hook-handler.js +191 -0
- package/dist/claude/hook-handler.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +195 -0
- package/dist/cli.js.map +1 -0
- package/dist/command/handler.d.ts +34 -0
- package/dist/command/handler.d.ts.map +1 -0
- package/dist/command/handler.js +371 -0
- package/dist/command/handler.js.map +1 -0
- package/dist/command/validator.d.ts +23 -0
- package/dist/command/validator.d.ts.map +1 -0
- package/dist/command/validator.js +295 -0
- package/dist/command/validator.js.map +1 -0
- package/dist/communication/websocket-client.d.ts +28 -0
- package/dist/communication/websocket-client.d.ts.map +1 -0
- package/dist/communication/websocket-client.js +224 -0
- package/dist/communication/websocket-client.js.map +1 -0
- package/dist/config/default.d.ts +19 -0
- package/dist/config/default.d.ts.map +1 -0
- package/dist/config/default.js +40 -0
- package/dist/config/default.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +155 -0
- package/dist/index.js.map +1 -0
- package/dist/session/claude-monitor.d.ts +66 -0
- package/dist/session/claude-monitor.d.ts.map +1 -0
- package/dist/session/claude-monitor.js +770 -0
- package/dist/session/claude-monitor.js.map +1 -0
- package/dist/session/monitor.d.ts +22 -0
- package/dist/session/monitor.d.ts.map +1 -0
- package/dist/session/monitor.js +189 -0
- package/dist/session/monitor.js.map +1 -0
- package/dist/session/parser.d.ts +51 -0
- package/dist/session/parser.d.ts.map +1 -0
- package/dist/session/parser.js +139 -0
- package/dist/session/parser.js.map +1 -0
- package/dist/utils/logger-new.d.ts +1 -0
- package/dist/utils/logger-new.d.ts.map +1 -0
- package/dist/utils/logger-new.js +2 -0
- package/dist/utils/logger-new.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +37 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +42 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// CC-Control Agent CLI - User-authenticated Desktop Agent
|
|
4
|
+
// ============================================================================
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { createInterface } from "readline";
|
|
7
|
+
import { DesktopAgent } from "./index.js";
|
|
8
|
+
import { UserCredentialManager } from "./auth/user-credentials.js";
|
|
9
|
+
import { mergeConfig } from "./config/default.js";
|
|
10
|
+
const program = new Command();
|
|
11
|
+
const credManager = new UserCredentialManager();
|
|
12
|
+
const DEFAULT_RELAY = process.env.CC_CONTROL_RELAY_URL || "https://cccontrol-relay.lemonbush-3c426472.centralindia.azurecontainerapps.io";
|
|
13
|
+
function prompt(question) {
|
|
14
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
rl.question(question, (answer) => {
|
|
17
|
+
rl.close();
|
|
18
|
+
resolve(answer.trim());
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async function promptPassword(question) {
|
|
23
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
// Note: passwords will be visible in terminal (no masking in pure Node.js readline)
|
|
26
|
+
rl.question(question, (answer) => {
|
|
27
|
+
rl.close();
|
|
28
|
+
resolve(answer.trim());
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
program
|
|
33
|
+
.name("cc-control")
|
|
34
|
+
.description("CC-Control Desktop Agent - Monitor and control Claude Code sessions remotely")
|
|
35
|
+
.version("2.0.0");
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Login
|
|
38
|
+
// ============================================================================
|
|
39
|
+
program
|
|
40
|
+
.command("login")
|
|
41
|
+
.description("Login to your CC-Control account")
|
|
42
|
+
.option("-e, --email <email>", "Email address")
|
|
43
|
+
.option("-r, --relay <url>", "Relay server URL", DEFAULT_RELAY)
|
|
44
|
+
.action(async (options) => {
|
|
45
|
+
try {
|
|
46
|
+
const email = options.email || await prompt("Email: ");
|
|
47
|
+
const password = await promptPassword("Password: ");
|
|
48
|
+
console.log(`\nLogging in to ${options.relay}...`);
|
|
49
|
+
const creds = await credManager.login(email, password, options.relay);
|
|
50
|
+
console.log(`\nLogged in as ${creds.email}`);
|
|
51
|
+
// Auto-register device
|
|
52
|
+
const deviceName = `${process.env.USER || "user"}'s Desktop`;
|
|
53
|
+
console.log(`Registering device: ${deviceName}...`);
|
|
54
|
+
const deviceId = await credManager.registerDevice(deviceName);
|
|
55
|
+
console.log(`Device registered: ${deviceId}`);
|
|
56
|
+
console.log("\nSetup complete! Run 'cc-control start' to begin monitoring.");
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const msg = error.response?.data?.error || error.message;
|
|
60
|
+
console.error(`\nLogin failed: ${msg}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// Register
|
|
66
|
+
// ============================================================================
|
|
67
|
+
program
|
|
68
|
+
.command("register")
|
|
69
|
+
.description("Create a new CC-Control account")
|
|
70
|
+
.option("-e, --email <email>", "Email address")
|
|
71
|
+
.option("-r, --relay <url>", "Relay server URL", DEFAULT_RELAY)
|
|
72
|
+
.action(async (options) => {
|
|
73
|
+
try {
|
|
74
|
+
const email = options.email || await prompt("Email: ");
|
|
75
|
+
const password = await promptPassword("Password (min 8 chars, include a number): ");
|
|
76
|
+
console.log(`\nCreating account on ${options.relay}...`);
|
|
77
|
+
const creds = await credManager.register(email, password, options.relay);
|
|
78
|
+
console.log(`\nAccount created! Logged in as ${creds.email}`);
|
|
79
|
+
// Auto-register device
|
|
80
|
+
const deviceName = `${process.env.USER || "user"}'s Desktop`;
|
|
81
|
+
console.log(`Registering device: ${deviceName}...`);
|
|
82
|
+
const deviceId = await credManager.registerDevice(deviceName);
|
|
83
|
+
console.log(`Device registered: ${deviceId}`);
|
|
84
|
+
console.log("\nSetup complete! Run 'cc-control start' to begin monitoring.");
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const msg = error.response?.data?.error || error.message;
|
|
88
|
+
console.error(`\nRegistration failed: ${msg}`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Start
|
|
94
|
+
// ============================================================================
|
|
95
|
+
program
|
|
96
|
+
.command("start")
|
|
97
|
+
.description("Start monitoring Claude Code sessions")
|
|
98
|
+
.option("-v, --verbose", "Enable verbose logging")
|
|
99
|
+
.action(async (options) => {
|
|
100
|
+
try {
|
|
101
|
+
// Load credentials
|
|
102
|
+
await credManager.load();
|
|
103
|
+
if (!credManager.get()) {
|
|
104
|
+
console.error("Not logged in. Run 'cc-control login' or 'cc-control register' first.");
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
// Auto-refresh expired access token using refresh token
|
|
108
|
+
if (!credManager.isLoggedIn()) {
|
|
109
|
+
console.log("Access token expired, refreshing...");
|
|
110
|
+
try {
|
|
111
|
+
await credManager.refreshAccessToken();
|
|
112
|
+
console.log("Token refreshed successfully.");
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.error(`Token refresh failed: ${error.message}`);
|
|
116
|
+
console.error("Please run 'cc-control login' again.");
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const creds = credManager.get();
|
|
121
|
+
if (!creds.deviceId) {
|
|
122
|
+
console.error("No device registered. Run 'cc-control login' to re-setup.");
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
// Merge config with credentials
|
|
126
|
+
const configOverrides = {
|
|
127
|
+
relayUrl: creds.relayUrl.replace("http://", "ws://").replace("https://", "wss://"),
|
|
128
|
+
};
|
|
129
|
+
if (options.verbose)
|
|
130
|
+
configOverrides.logLevel = "debug";
|
|
131
|
+
const config = mergeConfig(configOverrides);
|
|
132
|
+
console.log("=".repeat(50));
|
|
133
|
+
console.log(" CC-Control Desktop Agent v2");
|
|
134
|
+
console.log("=".repeat(50));
|
|
135
|
+
console.log(` User: ${creds.email}`);
|
|
136
|
+
console.log(` Device: ${creds.deviceId}`);
|
|
137
|
+
console.log(` Relay: ${creds.relayUrl}`);
|
|
138
|
+
console.log("=".repeat(50));
|
|
139
|
+
const agent = new DesktopAgent();
|
|
140
|
+
// Graceful shutdown
|
|
141
|
+
const shutdown = async () => {
|
|
142
|
+
console.log("\nShutting down...");
|
|
143
|
+
await agent.stop();
|
|
144
|
+
process.exit(0);
|
|
145
|
+
};
|
|
146
|
+
process.on("SIGINT", shutdown);
|
|
147
|
+
process.on("SIGTERM", shutdown);
|
|
148
|
+
await agent.start();
|
|
149
|
+
console.log("\nAgent started. Monitoring Claude Code sessions...");
|
|
150
|
+
console.log("Press Ctrl+C to stop.\n");
|
|
151
|
+
process.stdin.resume();
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error(`Failed to start: ${error.message}`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// Status
|
|
160
|
+
// ============================================================================
|
|
161
|
+
program
|
|
162
|
+
.command("status")
|
|
163
|
+
.description("Show account and connection status")
|
|
164
|
+
.action(async () => {
|
|
165
|
+
await credManager.load();
|
|
166
|
+
const creds = credManager.get();
|
|
167
|
+
console.log("\n=== CC-Control Status ===\n");
|
|
168
|
+
if (!creds) {
|
|
169
|
+
console.log("Status: Not logged in");
|
|
170
|
+
console.log("Run 'cc-control login' or 'cc-control register' to get started.\n");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
console.log(`Email: ${creds.email}`);
|
|
174
|
+
console.log(`User ID: ${creds.userId}`);
|
|
175
|
+
console.log(`Device: ${creds.deviceId || "Not registered"}`);
|
|
176
|
+
console.log(`Relay: ${creds.relayUrl}`);
|
|
177
|
+
console.log(`Token: ${credManager.isLoggedIn() ? "Valid" : "Expired"}`);
|
|
178
|
+
console.log(`Expires: ${new Date(creds.expiresAt).toLocaleString()}`);
|
|
179
|
+
console.log();
|
|
180
|
+
});
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Logout
|
|
183
|
+
// ============================================================================
|
|
184
|
+
program
|
|
185
|
+
.command("logout")
|
|
186
|
+
.description("Logout and clear stored credentials")
|
|
187
|
+
.action(async () => {
|
|
188
|
+
await credManager.clear();
|
|
189
|
+
console.log("Logged out. Credentials cleared.");
|
|
190
|
+
});
|
|
191
|
+
program.parse(process.argv);
|
|
192
|
+
if (!process.argv.slice(2).length) {
|
|
193
|
+
program.outputHelp();
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { WebSocketClient } from "../communication/websocket-client.js";
|
|
2
|
+
import type { Command } from "cc-control-shared";
|
|
3
|
+
export declare class CommandHandler {
|
|
4
|
+
private wsClient;
|
|
5
|
+
private config;
|
|
6
|
+
private validator;
|
|
7
|
+
private pendingCommands;
|
|
8
|
+
constructor(wsClient: WebSocketClient);
|
|
9
|
+
setup(): void;
|
|
10
|
+
handleCommand(command: Command): Promise<void>;
|
|
11
|
+
private executeCommand;
|
|
12
|
+
private executeSendPrompt;
|
|
13
|
+
/**
|
|
14
|
+
* Find the PID of a Claude Code process for a given session ID.
|
|
15
|
+
* Claude Code stores session data in ~/.claude/projects/<path>/<session-id>.jsonl
|
|
16
|
+
* We find which `claude` process has the matching session active.
|
|
17
|
+
*/
|
|
18
|
+
private findClaudeProcessForSession;
|
|
19
|
+
/**
|
|
20
|
+
* Get the TTY of a process by PID
|
|
21
|
+
*/
|
|
22
|
+
private getProcessTty;
|
|
23
|
+
private executeSwitchSession;
|
|
24
|
+
private executeManageTask;
|
|
25
|
+
private executeFileOperation;
|
|
26
|
+
private readFile;
|
|
27
|
+
private writeFile;
|
|
28
|
+
private deleteFile;
|
|
29
|
+
private listFiles;
|
|
30
|
+
private sendResponse;
|
|
31
|
+
private sendErrorResponse;
|
|
32
|
+
shutdown(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/command/handler.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAmC,MAAM,mBAAmB,CAAC;AAElF,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,eAAe,CAA0C;gBAErD,QAAQ,EAAE,eAAe;IAKrC,KAAK,IAAI,IAAI;IAMP,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YA4CtC,cAAc;YAed,iBAAiB;IAoF/B;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IAoDnC;;OAEG;IACH,OAAO,CAAC,aAAa;YAYP,oBAAoB;YAgBpB,iBAAiB;YAkBjB,oBAAoB;YAwBpB,QAAQ;YAgBR,SAAS;YAqBT,UAAU;YAcV,SAAS;IA+BvB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,iBAAiB;IAqBnB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC"}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Command Handler - Execute Remote Commands
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { resolve, join } from "path";
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
import { logger } from "../utils/logger.js";
|
|
8
|
+
import { getConfig } from "../config/default.js";
|
|
9
|
+
import { CommandValidator } from "./validator.js";
|
|
10
|
+
export class CommandHandler {
|
|
11
|
+
wsClient;
|
|
12
|
+
config = getConfig();
|
|
13
|
+
validator;
|
|
14
|
+
pendingCommands = new Map();
|
|
15
|
+
constructor(wsClient) {
|
|
16
|
+
this.wsClient = wsClient;
|
|
17
|
+
this.validator = new CommandValidator();
|
|
18
|
+
}
|
|
19
|
+
setup() {
|
|
20
|
+
// Setup message handler for incoming commands
|
|
21
|
+
// This will be called by the main agent class
|
|
22
|
+
logger.info("Command handler setup");
|
|
23
|
+
}
|
|
24
|
+
async handleCommand(command) {
|
|
25
|
+
logger.info(`Received command: ${command.type}`, { commandId: command.id });
|
|
26
|
+
// Validate command
|
|
27
|
+
const validation = this.validator.validateCommand(command);
|
|
28
|
+
if (!validation.valid) {
|
|
29
|
+
logger.warn(`Command validation failed: ${validation.error}`);
|
|
30
|
+
this.sendErrorResponse(command.id, "VALIDATION_ERROR", validation.error || "Invalid command");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// Set timeout for command execution
|
|
34
|
+
const timeout = setTimeout(() => {
|
|
35
|
+
logger.warn(`Command execution timeout: ${command.id}`);
|
|
36
|
+
this.sendErrorResponse(command.id, "TIMEOUT", "Command execution timeout");
|
|
37
|
+
this.pendingCommands.delete(command.id);
|
|
38
|
+
}, this.config.maxCommandExecutionTime);
|
|
39
|
+
this.pendingCommands.set(command.id, timeout);
|
|
40
|
+
try {
|
|
41
|
+
// Execute command based on type
|
|
42
|
+
const result = await this.executeCommand(command);
|
|
43
|
+
// Clear timeout
|
|
44
|
+
clearTimeout(timeout);
|
|
45
|
+
this.pendingCommands.delete(command.id);
|
|
46
|
+
// Send success response
|
|
47
|
+
this.sendResponse(command.id, "success", result);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
// Clear timeout
|
|
51
|
+
clearTimeout(timeout);
|
|
52
|
+
this.pendingCommands.delete(command.id);
|
|
53
|
+
logger.error(`Command execution error: ${command.id}`, error);
|
|
54
|
+
this.sendErrorResponse(command.id, "EXECUTION_ERROR", error instanceof Error ? error.message : "Unknown error");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async executeCommand(command) {
|
|
58
|
+
switch (command.type) {
|
|
59
|
+
case "send_prompt":
|
|
60
|
+
return await this.executeSendPrompt(command);
|
|
61
|
+
case "switch_session":
|
|
62
|
+
return await this.executeSwitchSession(command);
|
|
63
|
+
case "manage_task":
|
|
64
|
+
return await this.executeManageTask(command);
|
|
65
|
+
case "file_operation":
|
|
66
|
+
return await this.executeFileOperation(command);
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(`Unknown command type: ${command.type}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async executeSendPrompt(command) {
|
|
72
|
+
const payload = command.payload;
|
|
73
|
+
const promptText = payload.prompt;
|
|
74
|
+
if (!promptText) {
|
|
75
|
+
throw new Error("No prompt text provided");
|
|
76
|
+
}
|
|
77
|
+
logger.info("Executing send prompt", {
|
|
78
|
+
sessionId: command.sessionId,
|
|
79
|
+
promptLength: promptText.length,
|
|
80
|
+
});
|
|
81
|
+
try {
|
|
82
|
+
const pid = this.findClaudeProcessForSession(command.sessionId);
|
|
83
|
+
if (!pid) {
|
|
84
|
+
throw new Error(`No running Claude Code process found for session ${command.sessionId}`);
|
|
85
|
+
}
|
|
86
|
+
const tty = this.getProcessTty(pid);
|
|
87
|
+
if (!tty) {
|
|
88
|
+
throw new Error(`Could not find terminal for Claude process PID ${pid}`);
|
|
89
|
+
}
|
|
90
|
+
logger.info("Found Claude process", { pid, tty, sessionId: command.sessionId });
|
|
91
|
+
// Use AppleScript to type the prompt into the correct Terminal.app tab
|
|
92
|
+
// This properly simulates keyboard input (unlike writing to /dev/tty which only displays text)
|
|
93
|
+
const escapedForAppleScript = promptText
|
|
94
|
+
.replace(/\\/g, "\\\\")
|
|
95
|
+
.replace(/"/g, '\\"')
|
|
96
|
+
.replace(/\n/g, "\\n");
|
|
97
|
+
// Find the Terminal.app tab with this TTY and type into it
|
|
98
|
+
const script = `
|
|
99
|
+
tell application "Terminal"
|
|
100
|
+
set targetTTY to "/dev/${tty}"
|
|
101
|
+
repeat with w in windows
|
|
102
|
+
repeat with t in tabs of w
|
|
103
|
+
if tty of t is targetTTY then
|
|
104
|
+
-- Bring window to front and select the tab
|
|
105
|
+
set selected tab of w to t
|
|
106
|
+
set frontmost of w to true
|
|
107
|
+
activate
|
|
108
|
+
delay 0.2
|
|
109
|
+
tell application "System Events"
|
|
110
|
+
keystroke "${escapedForAppleScript}"
|
|
111
|
+
delay 0.1
|
|
112
|
+
keystroke return
|
|
113
|
+
end tell
|
|
114
|
+
return "sent"
|
|
115
|
+
end if
|
|
116
|
+
end repeat
|
|
117
|
+
end repeat
|
|
118
|
+
return "tty_not_found"
|
|
119
|
+
end tell
|
|
120
|
+
`;
|
|
121
|
+
const result = execSync(`osascript -e '${script.replace(/'/g, "'\"'\"'")}'`, {
|
|
122
|
+
encoding: "utf-8",
|
|
123
|
+
timeout: 10000,
|
|
124
|
+
}).trim();
|
|
125
|
+
if (result === "tty_not_found") {
|
|
126
|
+
throw new Error(`Terminal tab with TTY ${tty} not found`);
|
|
127
|
+
}
|
|
128
|
+
logger.info("Prompt sent to Claude terminal via AppleScript", { pid, tty, sessionId: command.sessionId });
|
|
129
|
+
return {
|
|
130
|
+
sessionId: command.sessionId,
|
|
131
|
+
pid,
|
|
132
|
+
tty,
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
134
|
+
status: "sent",
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
logger.error("Failed to send prompt to Claude process", error);
|
|
139
|
+
throw new Error(`Failed to send prompt: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Find the PID of a Claude Code process for a given session ID.
|
|
144
|
+
* Claude Code stores session data in ~/.claude/projects/<path>/<session-id>.jsonl
|
|
145
|
+
* We find which `claude` process has the matching session active.
|
|
146
|
+
*/
|
|
147
|
+
findClaudeProcessForSession(sessionId) {
|
|
148
|
+
try {
|
|
149
|
+
// Get all running claude processes with their PIDs and ttys
|
|
150
|
+
const psOutput = execSync("ps -eo pid,tty,args | grep '[c]laude' | grep -v cc-control", { encoding: "utf-8", timeout: 5000 }).trim();
|
|
151
|
+
if (!psOutput)
|
|
152
|
+
return null;
|
|
153
|
+
const processes = psOutput.split("\n").map(line => {
|
|
154
|
+
const match = line.trim().match(/^(\d+)\s+(\S+)\s+(.*)$/);
|
|
155
|
+
if (!match)
|
|
156
|
+
return null;
|
|
157
|
+
return { pid: parseInt(match[1]), tty: match[2], cmd: match[3] };
|
|
158
|
+
}).filter(Boolean);
|
|
159
|
+
if (processes.length === 0)
|
|
160
|
+
return null;
|
|
161
|
+
// Try to match session by checking which process has open file descriptors
|
|
162
|
+
// to the session JSONL file
|
|
163
|
+
for (const proc of processes) {
|
|
164
|
+
try {
|
|
165
|
+
const lsofOutput = execSync(`lsof -p ${proc.pid} 2>/dev/null | grep "${sessionId}" || true`, { encoding: "utf-8", timeout: 5000 }).trim();
|
|
166
|
+
if (lsofOutput) {
|
|
167
|
+
return proc.pid;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// lsof failed for this process, continue
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Fallback: if only one Claude process, use it
|
|
175
|
+
if (processes.length === 1) {
|
|
176
|
+
logger.warn("Could not match session to process, using only running Claude process");
|
|
177
|
+
return processes[0].pid;
|
|
178
|
+
}
|
|
179
|
+
// If multiple processes and no match found, return null
|
|
180
|
+
logger.warn("Multiple Claude processes found but none matched session", {
|
|
181
|
+
sessionId,
|
|
182
|
+
processPids: processes.map(p => p.pid),
|
|
183
|
+
});
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get the TTY of a process by PID
|
|
192
|
+
*/
|
|
193
|
+
getProcessTty(pid) {
|
|
194
|
+
try {
|
|
195
|
+
const output = execSync(`ps -o tty= -p ${pid}`, {
|
|
196
|
+
encoding: "utf-8",
|
|
197
|
+
timeout: 5000,
|
|
198
|
+
}).trim();
|
|
199
|
+
return output || null;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async executeSwitchSession(command) {
|
|
206
|
+
const payload = command.payload;
|
|
207
|
+
logger.info("Executing switch session", {
|
|
208
|
+
targetSessionId: payload.targetSessionId,
|
|
209
|
+
});
|
|
210
|
+
// Session switching is handled by the relay server
|
|
211
|
+
// We just acknowledge receipt
|
|
212
|
+
return {
|
|
213
|
+
sessionId: payload.targetSessionId,
|
|
214
|
+
switched: true,
|
|
215
|
+
timestamp: new Date().toISOString(),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
async executeManageTask(command) {
|
|
219
|
+
const payload = command.payload;
|
|
220
|
+
logger.info("Executing manage task", {
|
|
221
|
+
taskId: payload.taskId,
|
|
222
|
+
action: payload.action,
|
|
223
|
+
});
|
|
224
|
+
// Task management would involve interacting with Claude Code's task system
|
|
225
|
+
// For now, we'll acknowledge the command
|
|
226
|
+
return {
|
|
227
|
+
taskId: payload.taskId,
|
|
228
|
+
action: payload.action,
|
|
229
|
+
status: "completed",
|
|
230
|
+
timestamp: new Date().toISOString(),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async executeFileOperation(command) {
|
|
234
|
+
const payload = command.payload;
|
|
235
|
+
logger.info("Executing file operation", {
|
|
236
|
+
operation: payload.operation,
|
|
237
|
+
path: payload.path,
|
|
238
|
+
});
|
|
239
|
+
const resolvedPath = resolve(payload.path);
|
|
240
|
+
switch (payload.operation) {
|
|
241
|
+
case "read":
|
|
242
|
+
return await this.readFile(resolvedPath);
|
|
243
|
+
case "write":
|
|
244
|
+
return await this.writeFile(resolvedPath, payload.content);
|
|
245
|
+
case "delete":
|
|
246
|
+
return await this.deleteFile(resolvedPath);
|
|
247
|
+
case "list":
|
|
248
|
+
return await this.listFiles(resolvedPath);
|
|
249
|
+
default:
|
|
250
|
+
throw new Error(`Unknown file operation: ${payload.operation}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async readFile(path) {
|
|
254
|
+
try {
|
|
255
|
+
const content = await fs.readFile(path, "utf-8");
|
|
256
|
+
const stats = await fs.stat(path);
|
|
257
|
+
return {
|
|
258
|
+
path,
|
|
259
|
+
content,
|
|
260
|
+
size: stats.size,
|
|
261
|
+
modified: stats.mtime,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
throw new Error(`Failed to read file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async writeFile(path, content) {
|
|
269
|
+
try {
|
|
270
|
+
// Ensure directory exists
|
|
271
|
+
const dir = join(path, "..");
|
|
272
|
+
await fs.mkdir(dir, { recursive: true });
|
|
273
|
+
// Write file
|
|
274
|
+
await fs.writeFile(path, content, "utf-8");
|
|
275
|
+
const stats = await fs.stat(path);
|
|
276
|
+
return {
|
|
277
|
+
path,
|
|
278
|
+
size: stats.size,
|
|
279
|
+
modified: stats.mtime,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
throw new Error(`Failed to write file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async deleteFile(path) {
|
|
287
|
+
try {
|
|
288
|
+
await fs.unlink(path);
|
|
289
|
+
return {
|
|
290
|
+
path,
|
|
291
|
+
deleted: true,
|
|
292
|
+
timestamp: new Date().toISOString(),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
throw new Error(`Failed to delete file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async listFiles(path) {
|
|
300
|
+
try {
|
|
301
|
+
const stats = await fs.stat(path);
|
|
302
|
+
if (stats.isDirectory()) {
|
|
303
|
+
const entries = await fs.readdir(path, { withFileTypes: true });
|
|
304
|
+
const files = entries.map((entry) => ({
|
|
305
|
+
name: entry.name,
|
|
306
|
+
path: join(path, entry.name),
|
|
307
|
+
type: entry.isDirectory() ? "directory" : "file",
|
|
308
|
+
}));
|
|
309
|
+
return {
|
|
310
|
+
path,
|
|
311
|
+
type: "directory",
|
|
312
|
+
files,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
return {
|
|
317
|
+
path,
|
|
318
|
+
type: "file",
|
|
319
|
+
size: stats.size,
|
|
320
|
+
modified: stats.mtime,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
throw new Error(`Failed to list files: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
sendResponse(commandId, status, result) {
|
|
329
|
+
if (!this.wsClient.isConnected()) {
|
|
330
|
+
logger.warn("WebSocket not connected, cannot send response");
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
this.wsClient.send({
|
|
334
|
+
type: "response:command_result",
|
|
335
|
+
payload: {
|
|
336
|
+
commandId,
|
|
337
|
+
status,
|
|
338
|
+
result,
|
|
339
|
+
timestamp: new Date().toISOString(),
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
logger.debug("Sent command response", { commandId, status });
|
|
343
|
+
}
|
|
344
|
+
sendErrorResponse(commandId, code, message) {
|
|
345
|
+
if (!this.wsClient.isConnected()) {
|
|
346
|
+
logger.warn("WebSocket not connected, cannot send error response");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
this.wsClient.send({
|
|
350
|
+
type: "response:error",
|
|
351
|
+
payload: {
|
|
352
|
+
commandId,
|
|
353
|
+
error: {
|
|
354
|
+
code,
|
|
355
|
+
message,
|
|
356
|
+
},
|
|
357
|
+
timestamp: new Date().toISOString(),
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
logger.debug("Sent error response", { commandId, code, message });
|
|
361
|
+
}
|
|
362
|
+
async shutdown() {
|
|
363
|
+
// Clear all pending command timeouts
|
|
364
|
+
for (const timeout of this.pendingCommands.values()) {
|
|
365
|
+
clearTimeout(timeout);
|
|
366
|
+
}
|
|
367
|
+
this.pendingCommands.clear();
|
|
368
|
+
logger.info("Command handler shut down");
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/command/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Command } from "cc-control-shared";
|
|
2
|
+
export declare class CommandValidator {
|
|
3
|
+
private config;
|
|
4
|
+
private blockedPatterns;
|
|
5
|
+
private maxFileSize;
|
|
6
|
+
constructor();
|
|
7
|
+
validateCommand(command: Command): {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
error?: string;
|
|
10
|
+
};
|
|
11
|
+
private validateSendPrompt;
|
|
12
|
+
private validateSwitchSession;
|
|
13
|
+
private validateManageTask;
|
|
14
|
+
private validateFileOperation;
|
|
15
|
+
private isAllowedDirectory;
|
|
16
|
+
private isAllowedPath;
|
|
17
|
+
sanitizePath(path: string): string;
|
|
18
|
+
validatePromptContent(prompt: string): {
|
|
19
|
+
valid: boolean;
|
|
20
|
+
reason?: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/command/validator.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAwB,MAAM,mBAAmB,CAAC;AA6BvE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,WAAW,CAAoB;;IAwBvC,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IA+CrE,OAAO,CAAC,kBAAkB;IAoD1B,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,qBAAqB;IA6D7B,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,aAAa;IAYrB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAUlC,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAgC3E"}
|