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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AuthTokens, Device } from "cc-control-shared";
|
|
2
|
+
export declare class DeviceManager {
|
|
3
|
+
private deviceId;
|
|
4
|
+
private accessToken;
|
|
5
|
+
private refreshToken;
|
|
6
|
+
private deviceInfo;
|
|
7
|
+
constructor();
|
|
8
|
+
initialize(): Promise<void>;
|
|
9
|
+
getDeviceId(): string;
|
|
10
|
+
getDeviceInfo(): Device;
|
|
11
|
+
getAccessToken(): string | undefined;
|
|
12
|
+
getRefreshToken(): string | undefined;
|
|
13
|
+
hasValidToken(): boolean;
|
|
14
|
+
saveTokens(tokens: AuthTokens): Promise<void>;
|
|
15
|
+
updateDeviceStatus(status: "online" | "offline"): void;
|
|
16
|
+
updatePairedDevices(deviceIds: string[]): void;
|
|
17
|
+
clearTokens(): Promise<void>;
|
|
18
|
+
shutdown(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=device-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-manager.d.ts","sourceRoot":"","sources":["../../src/auth/device-manager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAM5D,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAS;;IAcrB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCjC,WAAW,IAAI,MAAM;IAIrB,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC,aAAa,IAAI,OAAO;IAIlB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,kBAAkB,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI;IAKtD,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAIhC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Device Manager - Loads user credentials and device info for agent
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { logger } from "../utils/logger.js";
|
|
7
|
+
import { getConfig } from "../config/default.js";
|
|
8
|
+
const CONFIG_DIR = join(process.env.HOME || "~", ".cc-control");
|
|
9
|
+
const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
|
|
10
|
+
export class DeviceManager {
|
|
11
|
+
deviceId = "";
|
|
12
|
+
accessToken;
|
|
13
|
+
refreshToken;
|
|
14
|
+
deviceInfo;
|
|
15
|
+
constructor() {
|
|
16
|
+
this.deviceInfo = {
|
|
17
|
+
id: "",
|
|
18
|
+
name: "",
|
|
19
|
+
type: "desktop",
|
|
20
|
+
status: "offline",
|
|
21
|
+
lastSeen: new Date(),
|
|
22
|
+
pairedDevices: [],
|
|
23
|
+
capabilities: { version: "2.0.0", features: [] },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async initialize() {
|
|
27
|
+
try {
|
|
28
|
+
// Load user credentials (created by `cc-control login`)
|
|
29
|
+
const data = await fs.readFile(CREDENTIALS_FILE, "utf-8");
|
|
30
|
+
const creds = JSON.parse(data);
|
|
31
|
+
if (!creds.accessToken || !creds.deviceId) {
|
|
32
|
+
throw new Error("Incomplete credentials. Run 'cc-control login' first.");
|
|
33
|
+
}
|
|
34
|
+
this.deviceId = creds.deviceId;
|
|
35
|
+
this.accessToken = creds.accessToken;
|
|
36
|
+
this.refreshToken = creds.refreshToken;
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
this.deviceInfo = {
|
|
39
|
+
id: this.deviceId,
|
|
40
|
+
name: config.deviceName,
|
|
41
|
+
type: "desktop",
|
|
42
|
+
status: "offline",
|
|
43
|
+
lastSeen: new Date(),
|
|
44
|
+
pairedDevices: [],
|
|
45
|
+
capabilities: config.capabilities,
|
|
46
|
+
};
|
|
47
|
+
logger.info("Device manager initialized", { deviceId: this.deviceId, email: creds.email });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
logger.error("Failed to initialize device manager", error);
|
|
51
|
+
throw new Error("Not logged in. Run 'cc-control login' or 'cc-control register' first.");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
getDeviceId() {
|
|
55
|
+
return this.deviceId;
|
|
56
|
+
}
|
|
57
|
+
getDeviceInfo() {
|
|
58
|
+
return { ...this.deviceInfo };
|
|
59
|
+
}
|
|
60
|
+
getAccessToken() {
|
|
61
|
+
return this.accessToken;
|
|
62
|
+
}
|
|
63
|
+
getRefreshToken() {
|
|
64
|
+
return this.refreshToken;
|
|
65
|
+
}
|
|
66
|
+
hasValidToken() {
|
|
67
|
+
return !!this.accessToken;
|
|
68
|
+
}
|
|
69
|
+
async saveTokens(tokens) {
|
|
70
|
+
this.accessToken = tokens.accessToken;
|
|
71
|
+
this.refreshToken = tokens.refreshToken;
|
|
72
|
+
// Update the credentials file
|
|
73
|
+
try {
|
|
74
|
+
const data = await fs.readFile(CREDENTIALS_FILE, "utf-8");
|
|
75
|
+
const creds = JSON.parse(data);
|
|
76
|
+
creds.accessToken = tokens.accessToken;
|
|
77
|
+
creds.refreshToken = tokens.refreshToken;
|
|
78
|
+
creds.expiresAt = tokens.expiresAt.toISOString();
|
|
79
|
+
await fs.writeFile(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), "utf-8");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
updateDeviceStatus(status) {
|
|
86
|
+
this.deviceInfo.status = status;
|
|
87
|
+
this.deviceInfo.lastSeen = new Date();
|
|
88
|
+
}
|
|
89
|
+
updatePairedDevices(deviceIds) {
|
|
90
|
+
this.deviceInfo.pairedDevices = deviceIds;
|
|
91
|
+
}
|
|
92
|
+
async clearTokens() {
|
|
93
|
+
this.accessToken = undefined;
|
|
94
|
+
this.refreshToken = undefined;
|
|
95
|
+
}
|
|
96
|
+
async shutdown() {
|
|
97
|
+
this.updateDeviceStatus("offline");
|
|
98
|
+
logger.info("Device manager shut down");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=device-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-manager.js","sourceRoot":"","sources":["../../src/auth/device-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface StoredCredentials {
|
|
2
|
+
userId: string;
|
|
3
|
+
email: string;
|
|
4
|
+
accessToken: string;
|
|
5
|
+
refreshToken: string;
|
|
6
|
+
expiresAt: string;
|
|
7
|
+
deviceId?: string;
|
|
8
|
+
relayUrl: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class UserCredentialManager {
|
|
11
|
+
private credentials;
|
|
12
|
+
load(): Promise<StoredCredentials | null>;
|
|
13
|
+
save(creds: StoredCredentials): Promise<void>;
|
|
14
|
+
clear(): Promise<void>;
|
|
15
|
+
get(): StoredCredentials | null;
|
|
16
|
+
isLoggedIn(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Login to the relay server and store credentials
|
|
19
|
+
*/
|
|
20
|
+
login(email: string, password: string, relayUrl: string): Promise<StoredCredentials>;
|
|
21
|
+
/**
|
|
22
|
+
* Register a new account on the relay server
|
|
23
|
+
*/
|
|
24
|
+
register(email: string, password: string, relayUrl: string): Promise<StoredCredentials>;
|
|
25
|
+
/**
|
|
26
|
+
* Register this machine as a device
|
|
27
|
+
*/
|
|
28
|
+
registerDevice(deviceName: string): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Refresh the access token
|
|
31
|
+
*/
|
|
32
|
+
refreshAccessToken(): Promise<string>;
|
|
33
|
+
private getMachineFingerprint;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=user-credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-credentials.d.ts","sourceRoot":"","sources":["../../src/auth/user-credentials.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAKD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,WAAW,CAAkC;IAE/C,IAAI,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAYzC,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,GAAG,IAAI,iBAAiB,GAAG,IAAI;IAI/B,UAAU,IAAI,OAAO;IAMrB;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsB1F;;OAEG;IACG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsB7F;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BzD;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;IAmB3C,OAAO,CAAC,qBAAqB;CAI9B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// User Credentials Manager - Store user auth tokens for desktop agent
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { hostname, platform, arch } from "os";
|
|
7
|
+
import axios from "axios";
|
|
8
|
+
const CONFIG_DIR = join(process.env.HOME || "~", ".cc-control");
|
|
9
|
+
const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
|
|
10
|
+
export class UserCredentialManager {
|
|
11
|
+
credentials = null;
|
|
12
|
+
async load() {
|
|
13
|
+
try {
|
|
14
|
+
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
15
|
+
const data = await fs.readFile(CREDENTIALS_FILE, "utf-8");
|
|
16
|
+
this.credentials = JSON.parse(data);
|
|
17
|
+
return this.credentials;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
this.credentials = null;
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async save(creds) {
|
|
25
|
+
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
26
|
+
this.credentials = creds;
|
|
27
|
+
await fs.writeFile(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), "utf-8");
|
|
28
|
+
}
|
|
29
|
+
async clear() {
|
|
30
|
+
this.credentials = null;
|
|
31
|
+
try {
|
|
32
|
+
await fs.unlink(CREDENTIALS_FILE);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
get() {
|
|
39
|
+
return this.credentials;
|
|
40
|
+
}
|
|
41
|
+
isLoggedIn() {
|
|
42
|
+
if (!this.credentials)
|
|
43
|
+
return false;
|
|
44
|
+
const expiresAt = new Date(this.credentials.expiresAt);
|
|
45
|
+
return expiresAt > new Date();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Login to the relay server and store credentials
|
|
49
|
+
*/
|
|
50
|
+
async login(email, password, relayUrl) {
|
|
51
|
+
const response = await axios.post(`${relayUrl}/api/auth/login`, { email, password });
|
|
52
|
+
if (!response.data.success) {
|
|
53
|
+
throw new Error(response.data.error || "Login failed");
|
|
54
|
+
}
|
|
55
|
+
const { user, accessToken, refreshToken, expiresAt } = response.data.data;
|
|
56
|
+
const creds = {
|
|
57
|
+
userId: user.id,
|
|
58
|
+
email: user.email,
|
|
59
|
+
accessToken,
|
|
60
|
+
refreshToken,
|
|
61
|
+
expiresAt,
|
|
62
|
+
relayUrl,
|
|
63
|
+
};
|
|
64
|
+
await this.save(creds);
|
|
65
|
+
return creds;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Register a new account on the relay server
|
|
69
|
+
*/
|
|
70
|
+
async register(email, password, relayUrl) {
|
|
71
|
+
const response = await axios.post(`${relayUrl}/api/auth/register`, { email, password });
|
|
72
|
+
if (!response.data.success) {
|
|
73
|
+
throw new Error(response.data.error || "Registration failed");
|
|
74
|
+
}
|
|
75
|
+
const { user, accessToken, refreshToken, expiresAt } = response.data.data;
|
|
76
|
+
const creds = {
|
|
77
|
+
userId: user.id,
|
|
78
|
+
email: user.email,
|
|
79
|
+
accessToken,
|
|
80
|
+
refreshToken,
|
|
81
|
+
expiresAt,
|
|
82
|
+
relayUrl,
|
|
83
|
+
};
|
|
84
|
+
await this.save(creds);
|
|
85
|
+
return creds;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Register this machine as a device
|
|
89
|
+
*/
|
|
90
|
+
async registerDevice(deviceName) {
|
|
91
|
+
if (!this.credentials)
|
|
92
|
+
throw new Error("Not logged in");
|
|
93
|
+
const response = await axios.post(`${this.credentials.relayUrl}/api/devices`, {
|
|
94
|
+
deviceType: "desktop",
|
|
95
|
+
deviceName,
|
|
96
|
+
fingerprint: this.getMachineFingerprint(),
|
|
97
|
+
}, {
|
|
98
|
+
headers: { Authorization: `Bearer ${this.credentials.accessToken}` },
|
|
99
|
+
});
|
|
100
|
+
if (!response.data.success) {
|
|
101
|
+
throw new Error(response.data.error || "Device registration failed");
|
|
102
|
+
}
|
|
103
|
+
const deviceId = response.data.data.device.id;
|
|
104
|
+
this.credentials.deviceId = deviceId;
|
|
105
|
+
await this.save(this.credentials);
|
|
106
|
+
return deviceId;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Refresh the access token
|
|
110
|
+
*/
|
|
111
|
+
async refreshAccessToken() {
|
|
112
|
+
if (!this.credentials)
|
|
113
|
+
throw new Error("Not logged in");
|
|
114
|
+
const response = await axios.post(`${this.credentials.relayUrl}/api/auth/refresh`, { refreshToken: this.credentials.refreshToken });
|
|
115
|
+
if (!response.data.success) {
|
|
116
|
+
throw new Error(response.data.error || "Token refresh failed");
|
|
117
|
+
}
|
|
118
|
+
this.credentials.accessToken = response.data.data.accessToken;
|
|
119
|
+
this.credentials.expiresAt = response.data.data.expiresAt;
|
|
120
|
+
await this.save(this.credentials);
|
|
121
|
+
return this.credentials.accessToken;
|
|
122
|
+
}
|
|
123
|
+
getMachineFingerprint() {
|
|
124
|
+
const user = process.env.USER || process.env.USERNAME || "unknown";
|
|
125
|
+
return `${hostname()}-${platform()}-${arch()}-${user}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=user-credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-credentials.js","sourceRoot":"","sources":["../../src/auth/user-credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WebSocketClient } from "../communication/websocket-client.js";
|
|
2
|
+
export interface ClaudeHook {
|
|
3
|
+
type: "before_prompt" | "after_prompt" | "before_tool" | "after_tool" | "on_error";
|
|
4
|
+
sessionId: string;
|
|
5
|
+
data: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare class HookHandler {
|
|
8
|
+
private wsClient;
|
|
9
|
+
private config;
|
|
10
|
+
private hooksDirectory;
|
|
11
|
+
private enabledHooks;
|
|
12
|
+
constructor(wsClient: WebSocketClient);
|
|
13
|
+
initialize(): Promise<void>;
|
|
14
|
+
processHook(hook: ClaudeHook): Promise<void>;
|
|
15
|
+
private handleBeforePrompt;
|
|
16
|
+
private handleAfterPrompt;
|
|
17
|
+
private handleBeforeTool;
|
|
18
|
+
private handleAfterTool;
|
|
19
|
+
private handleError;
|
|
20
|
+
private notifyHook;
|
|
21
|
+
writeHookLog(hook: ClaudeHook): Promise<void>;
|
|
22
|
+
getHookHistory(sessionId: string): Promise<ClaudeHook[]>;
|
|
23
|
+
enableHook(hookType: string): void;
|
|
24
|
+
disableHook(hookType: string): void;
|
|
25
|
+
shutdown(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=hook-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-handler.d.ts","sourceRoot":"","sources":["../../src/claude/hook-handler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAE5E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,eAAe,GAAG,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,UAAU,CAAC;IACnF,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAc;gBAEtB,QAAQ,EAAE,eAAe;IAY/B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAqCpC,kBAAkB;YAYlB,iBAAiB;YAWjB,gBAAgB;YAchB,eAAe;YAcf,WAAW;IAazB,OAAO,CAAC,UAAU;IA0BZ,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B7C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAW9D,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKlC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK7B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Hook Handler - Process Claude Code Hooks
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { logger } from "../utils/logger.js";
|
|
7
|
+
import { getConfig } from "../config/default.js";
|
|
8
|
+
export class HookHandler {
|
|
9
|
+
wsClient;
|
|
10
|
+
config = getConfig();
|
|
11
|
+
hooksDirectory;
|
|
12
|
+
enabledHooks;
|
|
13
|
+
constructor(wsClient) {
|
|
14
|
+
this.wsClient = wsClient;
|
|
15
|
+
this.hooksDirectory = join(this.config.claudeConfigPath, "hooks");
|
|
16
|
+
this.enabledHooks = new Set([
|
|
17
|
+
"before_prompt",
|
|
18
|
+
"after_prompt",
|
|
19
|
+
"before_tool",
|
|
20
|
+
"after_tool",
|
|
21
|
+
"on_error",
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
async initialize() {
|
|
25
|
+
try {
|
|
26
|
+
// Create hooks directory if it doesn't exist
|
|
27
|
+
await fs.mkdir(this.hooksDirectory, { recursive: true });
|
|
28
|
+
logger.info("Hook handler initialized");
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
logger.error("Failed to initialize hook handler", error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async processHook(hook) {
|
|
36
|
+
if (!this.enabledHooks.has(hook.type)) {
|
|
37
|
+
logger.debug(`Hook type disabled: ${hook.type}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
logger.debug(`Processing hook: ${hook.type}`, { sessionId: hook.sessionId });
|
|
41
|
+
try {
|
|
42
|
+
// Execute hook-specific logic
|
|
43
|
+
switch (hook.type) {
|
|
44
|
+
case "before_prompt":
|
|
45
|
+
await this.handleBeforePrompt(hook);
|
|
46
|
+
break;
|
|
47
|
+
case "after_prompt":
|
|
48
|
+
await this.handleAfterPrompt(hook);
|
|
49
|
+
break;
|
|
50
|
+
case "before_tool":
|
|
51
|
+
await this.handleBeforeTool(hook);
|
|
52
|
+
break;
|
|
53
|
+
case "after_tool":
|
|
54
|
+
await this.handleAfterTool(hook);
|
|
55
|
+
break;
|
|
56
|
+
case "on_error":
|
|
57
|
+
await this.handleError(hook);
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
logger.warn(`Unknown hook type: ${hook.type}`);
|
|
61
|
+
}
|
|
62
|
+
// Notify relay server about hook
|
|
63
|
+
this.notifyHook(hook);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger.error(`Failed to process hook: ${hook.type}`, error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async handleBeforePrompt(hook) {
|
|
70
|
+
// Called before a prompt is sent to Claude
|
|
71
|
+
const prompt = hook.data.prompt;
|
|
72
|
+
logger.debug("Before prompt hook", {
|
|
73
|
+
sessionId: hook.sessionId,
|
|
74
|
+
promptLength: prompt?.length,
|
|
75
|
+
});
|
|
76
|
+
// Could modify prompt, validate it, etc.
|
|
77
|
+
// For now, just log it
|
|
78
|
+
}
|
|
79
|
+
async handleAfterPrompt(hook) {
|
|
80
|
+
// Called after a prompt is completed
|
|
81
|
+
const response = hook.data.response;
|
|
82
|
+
logger.debug("After prompt hook", {
|
|
83
|
+
sessionId: hook.sessionId,
|
|
84
|
+
responseLength: response?.length,
|
|
85
|
+
});
|
|
86
|
+
// Could analyze response, extract insights, etc.
|
|
87
|
+
}
|
|
88
|
+
async handleBeforeTool(hook) {
|
|
89
|
+
// Called before a tool is executed
|
|
90
|
+
const toolName = hook.data.toolName;
|
|
91
|
+
const toolArgs = hook.data.arguments;
|
|
92
|
+
logger.debug("Before tool hook", {
|
|
93
|
+
sessionId: hook.sessionId,
|
|
94
|
+
toolName,
|
|
95
|
+
toolArgs,
|
|
96
|
+
});
|
|
97
|
+
// Could validate tool arguments, check permissions, etc.
|
|
98
|
+
}
|
|
99
|
+
async handleAfterTool(hook) {
|
|
100
|
+
// Called after a tool is executed
|
|
101
|
+
const toolName = hook.data.toolName;
|
|
102
|
+
const result = hook.data.result;
|
|
103
|
+
logger.debug("After tool hook", {
|
|
104
|
+
sessionId: hook.sessionId,
|
|
105
|
+
toolName,
|
|
106
|
+
success: hook.data.success,
|
|
107
|
+
});
|
|
108
|
+
// Could track tool usage, audit file operations, etc.
|
|
109
|
+
}
|
|
110
|
+
async handleError(hook) {
|
|
111
|
+
// Called when an error occurs
|
|
112
|
+
const error = hook.data.error;
|
|
113
|
+
logger.error("Error hook", {
|
|
114
|
+
sessionId: hook.sessionId,
|
|
115
|
+
error: error.message,
|
|
116
|
+
stack: error.stack,
|
|
117
|
+
});
|
|
118
|
+
// Could send error notifications, create error reports, etc.
|
|
119
|
+
}
|
|
120
|
+
notifyHook(hook) {
|
|
121
|
+
if (!this.wsClient.isConnected()) {
|
|
122
|
+
logger.debug("WebSocket not connected, skipping hook notification");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Send hook event to relay server
|
|
126
|
+
this.wsClient.send({
|
|
127
|
+
type: "logs:stream",
|
|
128
|
+
payload: {
|
|
129
|
+
sessionId: hook.sessionId,
|
|
130
|
+
logs: [
|
|
131
|
+
{
|
|
132
|
+
id: `hook-${Date.now()}`,
|
|
133
|
+
sessionId: hook.sessionId,
|
|
134
|
+
source: "claude_code",
|
|
135
|
+
level: "info",
|
|
136
|
+
timestamp: new Date(),
|
|
137
|
+
message: `Hook executed: ${hook.type}`,
|
|
138
|
+
metadata: hook.data,
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async writeHookLog(hook) {
|
|
145
|
+
try {
|
|
146
|
+
const hookLogFile = join(this.hooksDirectory, `${hook.sessionId}-hooks.json`);
|
|
147
|
+
// Read existing hooks
|
|
148
|
+
let hooks = [];
|
|
149
|
+
try {
|
|
150
|
+
const content = await fs.readFile(hookLogFile, "utf-8");
|
|
151
|
+
hooks = JSON.parse(content);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// File doesn't exist, start with empty array
|
|
155
|
+
}
|
|
156
|
+
// Add new hook
|
|
157
|
+
hooks.push({
|
|
158
|
+
...hook,
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
});
|
|
161
|
+
// Write back to file
|
|
162
|
+
await fs.writeFile(hookLogFile, JSON.stringify(hooks, null, 2), "utf-8");
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
logger.error("Failed to write hook log", error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async getHookHistory(sessionId) {
|
|
169
|
+
try {
|
|
170
|
+
const hookLogFile = join(this.hooksDirectory, `${sessionId}-hooks.json`);
|
|
171
|
+
const content = await fs.readFile(hookLogFile, "utf-8");
|
|
172
|
+
return JSON.parse(content);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
// File doesn't exist or error reading
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
enableHook(hookType) {
|
|
180
|
+
this.enabledHooks.add(hookType);
|
|
181
|
+
logger.info(`Hook enabled: ${hookType}`);
|
|
182
|
+
}
|
|
183
|
+
disableHook(hookType) {
|
|
184
|
+
this.enabledHooks.delete(hookType);
|
|
185
|
+
logger.info(`Hook disabled: ${hookType}`);
|
|
186
|
+
}
|
|
187
|
+
async shutdown() {
|
|
188
|
+
logger.info("Hook handler shut down");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=hook-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-handler.js","sourceRoot":"","sources":["../../src/claude/hook-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|