@yu_robotics/remote-cli 1.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/LICENSE +21 -0
- package/README.md +94 -0
- package/bin/remote-cli.js +2 -0
- package/dist/client/MessageHandler.d.ts +92 -0
- package/dist/client/MessageHandler.d.ts.map +1 -0
- package/dist/client/MessageHandler.js +496 -0
- package/dist/client/MessageHandler.js.map +1 -0
- package/dist/client/WebSocketClient.d.ts +109 -0
- package/dist/client/WebSocketClient.d.ts.map +1 -0
- package/dist/client/WebSocketClient.js +234 -0
- package/dist/client/WebSocketClient.js.map +1 -0
- package/dist/commands/config.d.ts +35 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +195 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/init.d.ts +25 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +112 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/start.d.ts +20 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +108 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +37 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +71 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +23 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +52 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +109 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +262 -0
- package/dist/config/ConfigManager.js.map +1 -0
- package/dist/executor/ClaudeExecutor.d.ts +89 -0
- package/dist/executor/ClaudeExecutor.d.ts.map +1 -0
- package/dist/executor/ClaudeExecutor.js +365 -0
- package/dist/executor/ClaudeExecutor.js.map +1 -0
- package/dist/executor/ClaudePersistentExecutor.d.ts +175 -0
- package/dist/executor/ClaudePersistentExecutor.d.ts.map +1 -0
- package/dist/executor/ClaudePersistentExecutor.js +958 -0
- package/dist/executor/ClaudePersistentExecutor.js.map +1 -0
- package/dist/executor/index.d.ts +20 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +48 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/hooks/ClaudeCodeHooks.d.ts +281 -0
- package/dist/hooks/ClaudeCodeHooks.d.ts.map +1 -0
- package/dist/hooks/ClaudeCodeHooks.js +350 -0
- package/dist/hooks/ClaudeCodeHooks.js.map +1 -0
- package/dist/hooks/FeishuNotificationAdapter.d.ts +87 -0
- package/dist/hooks/FeishuNotificationAdapter.d.ts.map +1 -0
- package/dist/hooks/FeishuNotificationAdapter.js +280 -0
- package/dist/hooks/FeishuNotificationAdapter.js.map +1 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +10 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +333 -0
- package/dist/index.js.map +1 -0
- package/dist/security/DirectoryGuard.d.ts +54 -0
- package/dist/security/DirectoryGuard.d.ts.map +1 -0
- package/dist/security/DirectoryGuard.js +143 -0
- package/dist/security/DirectoryGuard.js.map +1 -0
- package/dist/types/config.d.ts +46 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +22 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +110 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/FeishuMessageFormatter.d.ts +84 -0
- package/dist/utils/FeishuMessageFormatter.d.ts.map +1 -0
- package/dist/utils/FeishuMessageFormatter.js +395 -0
- package/dist/utils/FeishuMessageFormatter.js.map +1 -0
- package/dist/utils/stripAnsi.d.ts +21 -0
- package/dist/utils/stripAnsi.d.ts.map +1 -0
- package/dist/utils/stripAnsi.js +30 -0
- package/dist/utils/stripAnsi.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FeishuNotificationAdapter = void 0;
|
|
4
|
+
const ClaudeCodeHooks_1 = require("./ClaudeCodeHooks");
|
|
5
|
+
/**
|
|
6
|
+
* Feishu Notification Adapter
|
|
7
|
+
*
|
|
8
|
+
* Registers hook handlers to send notifications to Feishu via WebSocket.
|
|
9
|
+
* This allows users to be notified when:
|
|
10
|
+
* - Tasks start/complete/fail/abort
|
|
11
|
+
* - Authorization is required
|
|
12
|
+
* - Progress updates occur
|
|
13
|
+
* - Tools are executed
|
|
14
|
+
*/
|
|
15
|
+
class FeishuNotificationAdapter {
|
|
16
|
+
wsClient;
|
|
17
|
+
currentOpenId;
|
|
18
|
+
enabledNotifications;
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
registeredHandlers = [];
|
|
21
|
+
/**
|
|
22
|
+
* Create a new Feishu notification adapter
|
|
23
|
+
* @param wsClient WebSocket client for sending notifications
|
|
24
|
+
* @param options Configuration options
|
|
25
|
+
*/
|
|
26
|
+
constructor(wsClient, options = {}) {
|
|
27
|
+
this.wsClient = wsClient;
|
|
28
|
+
this.enabledNotifications = new Set(options.enabledNotifications || [
|
|
29
|
+
'task_started',
|
|
30
|
+
'task_completed',
|
|
31
|
+
'task_failed',
|
|
32
|
+
'task_aborted',
|
|
33
|
+
'authorization_required',
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set the current OpenID for message routing
|
|
38
|
+
*/
|
|
39
|
+
setCurrentOpenId(openId) {
|
|
40
|
+
this.currentOpenId = openId;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Register all hook handlers
|
|
44
|
+
*/
|
|
45
|
+
register() {
|
|
46
|
+
this.registerTaskHandlers();
|
|
47
|
+
this.registerAuthorizationHandler();
|
|
48
|
+
this.registerToolExecutionHandlers();
|
|
49
|
+
this.registerProgressHandler();
|
|
50
|
+
this.registerUserInputHandler();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Unregister all hook handlers
|
|
54
|
+
*/
|
|
55
|
+
unregister() {
|
|
56
|
+
// Remove only our registered handlers
|
|
57
|
+
for (const { event, handler } of this.registeredHandlers) {
|
|
58
|
+
ClaudeCodeHooks_1.claudeCodeHooks.removeListener(event, handler);
|
|
59
|
+
}
|
|
60
|
+
this.registeredHandlers = [];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Register a handler and store its reference for cleanup
|
|
64
|
+
*/
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
registerHandler(event, handler) {
|
|
67
|
+
ClaudeCodeHooks_1.claudeCodeHooks.on(event, handler);
|
|
68
|
+
this.registeredHandlers.push({ event, handler });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Register task lifecycle handlers
|
|
72
|
+
*/
|
|
73
|
+
registerTaskHandlers() {
|
|
74
|
+
// Task started
|
|
75
|
+
const taskStartedHandler = (context) => {
|
|
76
|
+
if (!this.enabledNotifications.has('task_started'))
|
|
77
|
+
return;
|
|
78
|
+
this.sendNotification('⏳ Task Started', `Task ID: ${context.taskId}\nWorking Directory: ${context.workingDirectory}`);
|
|
79
|
+
};
|
|
80
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onTaskStarted(taskStartedHandler);
|
|
81
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TASK_STARTED, handler: taskStartedHandler });
|
|
82
|
+
// Task completed
|
|
83
|
+
const taskCompletedHandler = (context, result) => {
|
|
84
|
+
if (!this.enabledNotifications.has('task_completed'))
|
|
85
|
+
return;
|
|
86
|
+
const duration = result.duration ? ` (${Math.round(result.duration / 1000)}s)` : '';
|
|
87
|
+
this.sendNotification('✅ Task Completed', `Task completed successfully${duration}\nSession: ${context.sessionId || 'N/A'}`);
|
|
88
|
+
};
|
|
89
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onTaskCompleted(taskCompletedHandler);
|
|
90
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TASK_COMPLETED, handler: taskCompletedHandler });
|
|
91
|
+
// Task failed
|
|
92
|
+
const taskFailedHandler = (context, error) => {
|
|
93
|
+
if (!this.enabledNotifications.has('task_failed'))
|
|
94
|
+
return;
|
|
95
|
+
this.sendNotification('❌ Task Failed', `Error: ${error.message}\nSession: ${context.sessionId || 'N/A'}`);
|
|
96
|
+
};
|
|
97
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onTaskFailed(taskFailedHandler);
|
|
98
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TASK_FAILED, handler: taskFailedHandler });
|
|
99
|
+
// Task aborted
|
|
100
|
+
const taskAbortedHandler = (context, reason) => {
|
|
101
|
+
if (!this.enabledNotifications.has('task_aborted'))
|
|
102
|
+
return;
|
|
103
|
+
this.sendNotification('🛑 Task Aborted', `Reason: ${reason}\nSession: ${context.sessionId || 'N/A'}`);
|
|
104
|
+
};
|
|
105
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onTaskAborted(taskAbortedHandler);
|
|
106
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TASK_ABORTED, handler: taskAbortedHandler });
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Register authorization handler
|
|
110
|
+
*/
|
|
111
|
+
registerAuthorizationHandler() {
|
|
112
|
+
const authHandler = async (context) => {
|
|
113
|
+
if (!this.enabledNotifications.has('authorization_required')) {
|
|
114
|
+
// Default deny if no handler registered
|
|
115
|
+
return { granted: false, reason: 'Authorization notifications disabled' };
|
|
116
|
+
}
|
|
117
|
+
// Send notification about authorization requirement
|
|
118
|
+
const riskEmoji = this.getRiskLevelEmoji(context.riskLevel);
|
|
119
|
+
const message = `${riskEmoji} Authorization Required
|
|
120
|
+
|
|
121
|
+
**Action:** ${context.actionType}
|
|
122
|
+
**Description:** ${context.description}
|
|
123
|
+
**Risk Level:** ${context.riskLevel.toUpperCase()}
|
|
124
|
+
|
|
125
|
+
${context.details.filePath ? `**Path:** ${context.details.filePath}` : ''}
|
|
126
|
+
${context.details.command ? `**Command:** ${context.details.command}` : ''}
|
|
127
|
+
|
|
128
|
+
Please respond with /authorize grant or /authorize deny`;
|
|
129
|
+
this.sendNotification('🔒 Authorization Required', message);
|
|
130
|
+
// For now, auto-grant low-risk operations after notification
|
|
131
|
+
// In the future, this could wait for user response
|
|
132
|
+
if (context.riskLevel === 'low') {
|
|
133
|
+
return {
|
|
134
|
+
granted: true,
|
|
135
|
+
remember: true,
|
|
136
|
+
rememberDuration: 5 * 60 * 1000, // Remember for 5 minutes
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// For medium+ risk, require manual authorization
|
|
140
|
+
// TODO: Implement wait-for-response mechanism
|
|
141
|
+
return {
|
|
142
|
+
granted: false,
|
|
143
|
+
reason: 'Medium/high risk operations require manual authorization. Use /authorize grant <task-id>',
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onAuthorizationRequired(authHandler);
|
|
147
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.AUTHORIZATION_REQUIRED, handler: authHandler });
|
|
148
|
+
// Listen for authorization decisions
|
|
149
|
+
const authGrantedHandler = (context, decision) => {
|
|
150
|
+
this.sendNotification('✅ Authorization Granted', `${context.description} has been approved.`);
|
|
151
|
+
};
|
|
152
|
+
ClaudeCodeHooks_1.claudeCodeHooks.on(ClaudeCodeHooks_1.HookEventType.AUTHORIZATION_GRANTED, authGrantedHandler);
|
|
153
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.AUTHORIZATION_GRANTED, handler: authGrantedHandler });
|
|
154
|
+
const authDeniedHandler = (context, decision) => {
|
|
155
|
+
const reason = decision.reason ? `\nReason: ${decision.reason}` : '';
|
|
156
|
+
this.sendNotification('❌ Authorization Denied', `${context.description} was denied.${reason}`);
|
|
157
|
+
};
|
|
158
|
+
ClaudeCodeHooks_1.claudeCodeHooks.on(ClaudeCodeHooks_1.HookEventType.AUTHORIZATION_DENIED, authDeniedHandler);
|
|
159
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.AUTHORIZATION_DENIED, handler: authDeniedHandler });
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Register tool execution handlers
|
|
163
|
+
*/
|
|
164
|
+
registerToolExecutionHandlers() {
|
|
165
|
+
// Tool before execution - can prevent execution
|
|
166
|
+
const toolBeforeHandler = async (context) => {
|
|
167
|
+
console.log(`[FeishuAdapter] Tool ${context.toolName} is about to execute`, context.params);
|
|
168
|
+
// Return true to allow execution, false to block
|
|
169
|
+
return true;
|
|
170
|
+
};
|
|
171
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onToolBeforeExecution(toolBeforeHandler);
|
|
172
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TOOL_BEFORE_EXECUTION, handler: toolBeforeHandler });
|
|
173
|
+
// Tool after execution - log results
|
|
174
|
+
const toolAfterHandler = (context, result) => {
|
|
175
|
+
const status = result.success ? '✅' : '❌';
|
|
176
|
+
const duration = result.duration ? ` (${result.duration}ms)` : '';
|
|
177
|
+
console.log(`[FeishuAdapter] Tool ${context.toolName} completed ${status}${duration}`);
|
|
178
|
+
};
|
|
179
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onToolAfterExecution(toolAfterHandler);
|
|
180
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.TOOL_AFTER_EXECUTION, handler: toolAfterHandler });
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Register progress handler
|
|
184
|
+
*/
|
|
185
|
+
registerProgressHandler() {
|
|
186
|
+
const progressHandler = async (update) => {
|
|
187
|
+
// Only send progress notifications for significant milestones
|
|
188
|
+
if (update.progress === 0 || update.progress === 100 || update.progress % 25 === 0) {
|
|
189
|
+
const progressBar = this.renderProgressBar(update.progress);
|
|
190
|
+
this.sendNotification('📊 Progress Update', `${progressBar} ${update.progress}%\n${update.message}`);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onProgress(progressHandler);
|
|
194
|
+
this.registeredHandlers.push({ event: ClaudeCodeHooks_1.HookEventType.PROGRESS_UPDATE, handler: progressHandler });
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Register user input handler
|
|
198
|
+
* When Claude requests user input, send notification via Feishu
|
|
199
|
+
*/
|
|
200
|
+
registerUserInputHandler() {
|
|
201
|
+
ClaudeCodeHooks_1.claudeCodeHooks.onUserInputRequired(async (request) => {
|
|
202
|
+
const message = `💬 Input Required
|
|
203
|
+
|
|
204
|
+
**Prompt:** ${request.prompt}
|
|
205
|
+
|
|
206
|
+
Please reply with your response to continue.`;
|
|
207
|
+
this.sendNotification('⌨️ Waiting for Input', message);
|
|
208
|
+
// Return null - the actual input will be provided through MessageHandler
|
|
209
|
+
// when user sends a message while executor is waiting for input
|
|
210
|
+
return '';
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Send notification via WebSocket
|
|
215
|
+
*/
|
|
216
|
+
sendNotification(title, message) {
|
|
217
|
+
if (!this.currentOpenId) {
|
|
218
|
+
console.log(`[FeishuAdapter] No OpenID set, skipping notification: ${title}`);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
this.wsClient.send({
|
|
223
|
+
type: 'notification',
|
|
224
|
+
title,
|
|
225
|
+
message,
|
|
226
|
+
openId: this.currentOpenId,
|
|
227
|
+
timestamp: Date.now(),
|
|
228
|
+
});
|
|
229
|
+
console.log(`[FeishuAdapter] Sent notification: ${title}`);
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
console.error('[FeishuAdapter] Failed to send notification:', error);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get emoji for risk level
|
|
237
|
+
*/
|
|
238
|
+
getRiskLevelEmoji(riskLevel) {
|
|
239
|
+
switch (riskLevel) {
|
|
240
|
+
case 'low':
|
|
241
|
+
return '🟢';
|
|
242
|
+
case 'medium':
|
|
243
|
+
return '🟡';
|
|
244
|
+
case 'high':
|
|
245
|
+
return '🟠';
|
|
246
|
+
case 'critical':
|
|
247
|
+
return '🔴';
|
|
248
|
+
default:
|
|
249
|
+
return '⚪';
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Render a simple progress bar
|
|
254
|
+
*/
|
|
255
|
+
renderProgressBar(progress) {
|
|
256
|
+
const filled = Math.round(progress / 10);
|
|
257
|
+
const empty = 10 - filled;
|
|
258
|
+
return '█'.repeat(filled) + '░'.repeat(empty);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Enable specific notification types
|
|
262
|
+
*/
|
|
263
|
+
enableNotification(type) {
|
|
264
|
+
this.enabledNotifications.add(type);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Disable specific notification types
|
|
268
|
+
*/
|
|
269
|
+
disableNotification(type) {
|
|
270
|
+
this.enabledNotifications.delete(type);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get list of enabled notifications
|
|
274
|
+
*/
|
|
275
|
+
getEnabledNotifications() {
|
|
276
|
+
return Array.from(this.enabledNotifications);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
exports.FeishuNotificationAdapter = FeishuNotificationAdapter;
|
|
280
|
+
//# sourceMappingURL=FeishuNotificationAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FeishuNotificationAdapter.js","sourceRoot":"","sources":["../../src/hooks/FeishuNotificationAdapter.ts"],"names":[],"mappings":";;;AAAA,uDAW2B;AAG3B;;;;;;;;;GASG;AACH,MAAa,yBAAyB;IAC5B,QAAQ,CAAkB;IAC1B,aAAa,CAAU;IACvB,oBAAoB,CAAc;IAC1C,8DAA8D;IACtD,kBAAkB,GAA+D,EAAE,CAAC;IAE5F;;;;OAIG;IACH,YACE,QAAyB,EACzB,UAEI,EAAE;QAEN,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,oBAAoB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI;YAClE,cAAc;YACd,gBAAgB;YAChB,aAAa;YACb,cAAc;YACd,wBAAwB;SACzB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,MAA0B;QACzC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACpC,IAAI,CAAC,6BAA6B,EAAE,CAAC;QACrC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,UAAU;QACR,sCAAsC;QACtC,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACzD,iCAAe,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,8DAA8D;IACtD,eAAe,CAAC,KAAa,EAAE,OAAgC;QACrE,iCAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,eAAe;QACf,MAAM,kBAAkB,GAAG,CAAC,OAAoB,EAAE,EAAE;YAClD,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC;gBAAE,OAAO;YAE3D,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,YAAY,OAAO,CAAC,MAAM,wBAAwB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACxH,CAAC,CAAC;QACF,iCAAe,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAEjG,iBAAiB;QACjB,MAAM,oBAAoB,GAAG,CAAC,OAAoB,EAAE,MAAkB,EAAE,EAAE;YACxE,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBAAE,OAAO;YAE7D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,IAAI,CAAC,gBAAgB,CACnB,kBAAkB,EAClB,8BAA8B,QAAQ,cAAc,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CACjF,CAAC;QACJ,CAAC,CAAC;QACF,iCAAe,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;QACtD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,cAAc,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAErG,cAAc;QACd,MAAM,iBAAiB,GAAG,CAAC,OAAoB,EAAE,KAAY,EAAE,EAAE;YAC/D,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,aAAa,CAAC;gBAAE,OAAO;YAE1D,IAAI,CAAC,gBAAgB,CACnB,eAAe,EACf,UAAU,KAAK,CAAC,OAAO,cAAc,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CAClE,CAAC;QACJ,CAAC,CAAC;QACF,iCAAe,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QAChD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,WAAW,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAE/F,eAAe;QACf,MAAM,kBAAkB,GAAG,CAAC,OAAoB,EAAE,MAAc,EAAE,EAAE;YAClE,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC;gBAAE,OAAO;YAE3D,IAAI,CAAC,gBAAgB,CACnB,iBAAiB,EACjB,WAAW,MAAM,cAAc,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CAC5D,CAAC;QACJ,CAAC,CAAC;QACF,iCAAe,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACnG,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,MAAM,WAAW,GAAG,KAAK,EAAE,OAA6B,EAAkC,EAAE;YAC1F,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBAC7D,wCAAwC;gBACxC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,EAAE,CAAC;YAC5E,CAAC;YAED,oDAAoD;YACpD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,GAAG,SAAS;;cAEpB,OAAO,CAAC,UAAU;mBACb,OAAO,CAAC,WAAW;kBACpB,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;;EAE/C,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;EACvE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE;;wDAElB,CAAC;YAEnD,IAAI,CAAC,gBAAgB,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;YAE5D,6DAA6D;YAC7D,mDAAmD;YACnD,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;gBAChC,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI;oBACd,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,yBAAyB;iBAC3D,CAAC;YACJ,CAAC;YAED,iDAAiD;YACjD,8CAA8C;YAC9C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,0FAA0F;aACnG,CAAC;QACJ,CAAC,CAAC;QACF,iCAAe,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,sBAAsB,EAAE,OAAO,EAAE,WAA8C,EAAE,CAAC,CAAC;QAEvI,qCAAqC;QACrC,MAAM,kBAAkB,GAAG,CAAC,OAA6B,EAAE,QAA+B,EAAE,EAAE;YAC5F,IAAI,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,GAAG,OAAO,CAAC,WAAW,qBAAqB,CAAC,CAAC;QAChG,CAAC,CAAC;QACF,iCAAe,CAAC,EAAE,CAAC,+BAAa,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,CAAC;QAC5E,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,qBAAqB,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAE1G,MAAM,iBAAiB,GAAG,CAAC,OAA6B,EAAE,QAA+B,EAAE,EAAE;YAC3F,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,GAAG,OAAO,CAAC,WAAW,eAAe,MAAM,EAAE,CAAC,CAAC;QACjG,CAAC,CAAC;QACF,iCAAe,CAAC,EAAE,CAAC,+BAAa,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,CAAC;QAC1E,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,oBAAoB,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC1G,CAAC;IAED;;OAEG;IACK,6BAA6B;QACnC,gDAAgD;QAChD,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAA6B,EAAoB,EAAE;YAClF,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,QAAQ,sBAAsB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5F,iDAAiD;YACjD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,iCAAe,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;QACzD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,qBAAqB,EAAE,OAAO,EAAE,iBAAoD,EAAE,CAAC,CAAC;QAE5I,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,CAAC,OAA6B,EAAE,MAA2B,EAAE,EAAE;YACtF,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,CAAC,QAAQ,cAAc,MAAM,GAAG,QAAQ,EAAE,CAAC,CAAC;QACzF,CAAC,CAAC;QACF,iCAAe,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,oBAAoB,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACzG,CAAC;IAED;;OAEG;IACK,uBAAuB;QAC7B,MAAM,eAAe,GAAG,KAAK,EAAE,MAAsB,EAAiB,EAAE;YACtE,8DAA8D;YAC9D,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,QAAQ,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;gBACnF,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC5D,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,GAAG,WAAW,IAAI,MAAM,CAAC,QAAQ,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC,CAAC;QACF,iCAAe,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAC5C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAAa,CAAC,eAAe,EAAE,OAAO,EAAE,eAAkD,EAAE,CAAC,CAAC;IACtI,CAAC;IAED;;;OAGG;IACK,wBAAwB;QAC9B,iCAAe,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAyB,EAAE,EAAE;YACtE,MAAM,OAAO,GAAG;;cAER,OAAO,CAAC,MAAM;;6CAEiB,CAAC;YAExC,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;YAEvD,yEAAyE;YACzE,gEAAgE;YAChE,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAa,EAAE,OAAe;QACrD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,yDAAyD,KAAK,EAAE,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,cAAc;gBACpB,KAAK;gBACL,OAAO;gBACP,MAAM,EAAE,IAAI,CAAC,aAAa;gBAC1B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,SAAiB;QACzC,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,KAAK;gBACR,OAAO,IAAI,CAAC;YACd,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC;YACd,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC;YACd,KAAK,UAAU;gBACb,OAAO,IAAI,CAAC;YACd;gBACE,OAAO,GAAG,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,QAAgB;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC;QAC1B,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,IAAY;QAC7B,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,IAAY;QAC9B,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,uBAAuB;QACrB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC/C,CAAC;CACF;AAjTD,8DAiTC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { claudeCodeHooks, ClaudeCodeHooks, HookEventType, } from './ClaudeCodeHooks';
|
|
2
|
+
export type { AuthorizationContext, AuthorizationDecision, TaskContext, TaskResult, ToolExecutionContext, ToolExecutionResult, ProgressUpdate, ConfirmationRequest, UserInputRequest, AuthorizationHandler, TaskStartedHandler, TaskCompletedHandler, TaskFailedHandler, TaskAbortedHandler, ToolBeforeExecutionHandler, ToolAfterExecutionHandler, ProgressHandler, ConfirmationHandler, UserInputHandler, } from './ClaudeCodeHooks';
|
|
3
|
+
export { FeishuNotificationAdapter } from './FeishuNotificationAdapter';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FeishuNotificationAdapter = exports.HookEventType = exports.ClaudeCodeHooks = exports.claudeCodeHooks = void 0;
|
|
4
|
+
var ClaudeCodeHooks_1 = require("./ClaudeCodeHooks");
|
|
5
|
+
Object.defineProperty(exports, "claudeCodeHooks", { enumerable: true, get: function () { return ClaudeCodeHooks_1.claudeCodeHooks; } });
|
|
6
|
+
Object.defineProperty(exports, "ClaudeCodeHooks", { enumerable: true, get: function () { return ClaudeCodeHooks_1.ClaudeCodeHooks; } });
|
|
7
|
+
Object.defineProperty(exports, "HookEventType", { enumerable: true, get: function () { return ClaudeCodeHooks_1.HookEventType; } });
|
|
8
|
+
var FeishuNotificationAdapter_1 = require("./FeishuNotificationAdapter");
|
|
9
|
+
Object.defineProperty(exports, "FeishuNotificationAdapter", { enumerable: true, get: function () { return FeishuNotificationAdapter_1.FeishuNotificationAdapter; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;AAAA,qDAI2B;AAHzB,kHAAA,eAAe,OAAA;AACf,kHAAA,eAAe,OAAA;AACf,gHAAA,aAAa,OAAA;AAyBf,yEAAwE;AAA/D,sIAAA,yBAAyB,OAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const init_1 = require("./commands/init");
|
|
9
|
+
const start_1 = require("./commands/start");
|
|
10
|
+
const stop_1 = require("./commands/stop");
|
|
11
|
+
const status_1 = require("./commands/status");
|
|
12
|
+
const config_1 = require("./commands/config");
|
|
13
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const program = new commander_1.Command();
|
|
17
|
+
// Read package.json for version
|
|
18
|
+
const packageJsonPath = path_1.default.join(__dirname, '../package.json');
|
|
19
|
+
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
|
|
20
|
+
program
|
|
21
|
+
.name('remote-cli')
|
|
22
|
+
.description('Remote control Claude Code CLI via mobile')
|
|
23
|
+
.version(packageJson.version);
|
|
24
|
+
/**
|
|
25
|
+
* Init command
|
|
26
|
+
*/
|
|
27
|
+
program
|
|
28
|
+
.command('init')
|
|
29
|
+
.description('Initialize remote CLI and generate binding code')
|
|
30
|
+
.requiredOption('-s, --server <url>', 'Router server URL')
|
|
31
|
+
.option('-d, --dirs <dirs...>', 'Allowed directories (can specify multiple)')
|
|
32
|
+
.option('-f, --force', 'Force re-initialization')
|
|
33
|
+
.action(async (options) => {
|
|
34
|
+
try {
|
|
35
|
+
console.log(chalk_1.default.blue('🚀 Initializing remote CLI...\n'));
|
|
36
|
+
const result = await (0, init_1.initCommand)({
|
|
37
|
+
serverUrl: options.server,
|
|
38
|
+
allowedDirs: options.dirs,
|
|
39
|
+
force: options.force,
|
|
40
|
+
});
|
|
41
|
+
if (result.success) {
|
|
42
|
+
console.log(chalk_1.default.green('✅ Initialization successful!\n'));
|
|
43
|
+
console.log(chalk_1.default.yellow('📋 Binding Code:'), chalk_1.default.bold(result.bindingCode));
|
|
44
|
+
console.log(chalk_1.default.gray('Device ID:'), result.deviceId);
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(chalk_1.default.cyan('📱 Next steps:'), '\n 1. Open Feishu and send the binding code to the bot', '\n 2. Run', chalk_1.default.bold('remote-cli start'), 'to start the service');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(chalk_1.default.red('❌ Initialization failed:'), result.error);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Start command
|
|
60
|
+
*/
|
|
61
|
+
program
|
|
62
|
+
.command('start')
|
|
63
|
+
.description('Start the remote CLI service')
|
|
64
|
+
.option('-d, --daemon', 'Run as background daemon')
|
|
65
|
+
.action(async (options) => {
|
|
66
|
+
try {
|
|
67
|
+
const result = await (0, start_1.startCommand)({
|
|
68
|
+
daemon: options.daemon,
|
|
69
|
+
});
|
|
70
|
+
if (result.success) {
|
|
71
|
+
console.log(chalk_1.default.green('✅ Service started successfully!'));
|
|
72
|
+
if (result.daemonMode) {
|
|
73
|
+
console.log(chalk_1.default.gray('Running in daemon mode'));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.log(chalk_1.default.gray('Running in foreground mode (press Ctrl+C to stop)'));
|
|
77
|
+
// Keep process alive in foreground mode
|
|
78
|
+
process.on('SIGINT', () => {
|
|
79
|
+
console.log(chalk_1.default.yellow('\n⏹ Shutting down...'));
|
|
80
|
+
process.exit(0);
|
|
81
|
+
});
|
|
82
|
+
// Wait indefinitely
|
|
83
|
+
await new Promise(() => { });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.error(chalk_1.default.red('❌ Failed to start service:'), result.error);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* Stop command
|
|
98
|
+
*/
|
|
99
|
+
program
|
|
100
|
+
.command('stop')
|
|
101
|
+
.description('Stop the remote CLI service')
|
|
102
|
+
.option('-g, --graceful', 'Graceful shutdown (wait for tasks to complete)')
|
|
103
|
+
.option('-f, --force', 'Force stop immediately')
|
|
104
|
+
.action(async (options) => {
|
|
105
|
+
try {
|
|
106
|
+
const result = await (0, stop_1.stopCommand)({
|
|
107
|
+
graceful: options.graceful,
|
|
108
|
+
force: options.force,
|
|
109
|
+
});
|
|
110
|
+
if (result.success) {
|
|
111
|
+
console.log(chalk_1.default.green('✅ Service stopped successfully'));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.error(chalk_1.default.red('❌ Failed to stop service:'), result.error);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* Status command
|
|
125
|
+
*/
|
|
126
|
+
program
|
|
127
|
+
.command('status')
|
|
128
|
+
.description('Show service status')
|
|
129
|
+
.option('--json', 'Output as JSON')
|
|
130
|
+
.action(async (options) => {
|
|
131
|
+
try {
|
|
132
|
+
const result = await (0, status_1.statusCommand)({
|
|
133
|
+
json: options.json,
|
|
134
|
+
});
|
|
135
|
+
if (result.success && result.status) {
|
|
136
|
+
if (options.json) {
|
|
137
|
+
console.log(JSON.stringify(result.status, null, 2));
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log(chalk_1.default.blue('📊 Remote CLI Status\n'));
|
|
141
|
+
if (!result.status.initialized) {
|
|
142
|
+
console.log(chalk_1.default.yellow('⚠️ Device not initialized'));
|
|
143
|
+
console.log(chalk_1.default.gray('Run'), chalk_1.default.bold('remote-cli init'), chalk_1.default.gray('first'));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
console.log(chalk_1.default.gray('Device ID:'), result.status.deviceId);
|
|
147
|
+
console.log(chalk_1.default.gray('Server URL:'), result.status.serverUrl);
|
|
148
|
+
console.log(chalk_1.default.gray('Binding Status:'), result.status.bound
|
|
149
|
+
? chalk_1.default.green('✓ Bound') + chalk_1.default.gray(` (${result.status.openId})`)
|
|
150
|
+
: chalk_1.default.yellow('✗ Not bound'));
|
|
151
|
+
console.log(chalk_1.default.gray('Service Status:'), result.status.running ? chalk_1.default.green('✓ Running') : chalk_1.default.red('✗ Stopped'));
|
|
152
|
+
console.log(chalk_1.default.gray('Connection:'), result.status.connected ? chalk_1.default.green('✓ Connected') : chalk_1.default.red('✗ Disconnected'));
|
|
153
|
+
if (result.status.uptime) {
|
|
154
|
+
const uptimeSeconds = Math.floor(result.status.uptime / 1000);
|
|
155
|
+
const hours = Math.floor(uptimeSeconds / 3600);
|
|
156
|
+
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
|
|
157
|
+
const seconds = uptimeSeconds % 60;
|
|
158
|
+
console.log(chalk_1.default.gray('Uptime:'), `${hours}h ${minutes}m ${seconds}s`);
|
|
159
|
+
}
|
|
160
|
+
if (result.status.allowedDirectories && result.status.allowedDirectories.length > 0) {
|
|
161
|
+
console.log(chalk_1.default.gray('\nAllowed Directories:'));
|
|
162
|
+
result.status.allowedDirectories.forEach((dir) => {
|
|
163
|
+
console.log(chalk_1.default.gray(' •'), dir);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
console.error(chalk_1.default.red('❌ Failed to get status:'), result.error);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
/**
|
|
179
|
+
* Config command
|
|
180
|
+
*/
|
|
181
|
+
const configCmd = program
|
|
182
|
+
.command('config')
|
|
183
|
+
.description('Manage configuration');
|
|
184
|
+
configCmd
|
|
185
|
+
.command('add-dir <directory>')
|
|
186
|
+
.description('Add directory to allowed list')
|
|
187
|
+
.action(async (directory) => {
|
|
188
|
+
try {
|
|
189
|
+
const result = await (0, config_1.configCommand)({
|
|
190
|
+
action: 'add-dir',
|
|
191
|
+
directory,
|
|
192
|
+
});
|
|
193
|
+
if (result.success) {
|
|
194
|
+
console.log(chalk_1.default.green('✅ Directory added:'), directory);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
configCmd
|
|
207
|
+
.command('remove-dir <directory>')
|
|
208
|
+
.description('Remove directory from allowed list')
|
|
209
|
+
.action(async (directory) => {
|
|
210
|
+
try {
|
|
211
|
+
const result = await (0, config_1.configCommand)({
|
|
212
|
+
action: 'remove-dir',
|
|
213
|
+
directory,
|
|
214
|
+
});
|
|
215
|
+
if (result.success) {
|
|
216
|
+
console.log(chalk_1.default.green('✅ Directory removed:'), directory);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
configCmd
|
|
229
|
+
.command('list-dirs')
|
|
230
|
+
.description('List allowed directories')
|
|
231
|
+
.action(async () => {
|
|
232
|
+
try {
|
|
233
|
+
const result = await (0, config_1.configCommand)({
|
|
234
|
+
action: 'list-dirs',
|
|
235
|
+
});
|
|
236
|
+
if (result.success && result.directories) {
|
|
237
|
+
console.log(chalk_1.default.blue('📁 Allowed Directories:\n'));
|
|
238
|
+
if (result.directories.length === 0) {
|
|
239
|
+
console.log(chalk_1.default.yellow(' No directories configured'));
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
result.directories.forEach((dir) => {
|
|
243
|
+
console.log(chalk_1.default.gray(' •'), dir);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
254
|
+
process.exit(1);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
configCmd
|
|
258
|
+
.command('set <key> <value>')
|
|
259
|
+
.description('Set configuration value')
|
|
260
|
+
.action(async (key, value) => {
|
|
261
|
+
try {
|
|
262
|
+
const result = await (0, config_1.configCommand)({
|
|
263
|
+
action: 'set',
|
|
264
|
+
key,
|
|
265
|
+
value,
|
|
266
|
+
});
|
|
267
|
+
if (result.success) {
|
|
268
|
+
console.log(chalk_1.default.green('✅ Configuration updated:'), `${key} = ${value}`);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
configCmd
|
|
281
|
+
.command('get <key>')
|
|
282
|
+
.description('Get configuration value')
|
|
283
|
+
.action(async (key) => {
|
|
284
|
+
try {
|
|
285
|
+
const result = await (0, config_1.configCommand)({
|
|
286
|
+
action: 'get',
|
|
287
|
+
key,
|
|
288
|
+
});
|
|
289
|
+
if (result.success) {
|
|
290
|
+
console.log(result.value);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
294
|
+
process.exit(1);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
configCmd
|
|
303
|
+
.command('show')
|
|
304
|
+
.description('Show all configuration')
|
|
305
|
+
.option('--json', 'Output as JSON')
|
|
306
|
+
.action(async (options) => {
|
|
307
|
+
try {
|
|
308
|
+
const result = await (0, config_1.configCommand)({
|
|
309
|
+
action: 'show',
|
|
310
|
+
json: options.json,
|
|
311
|
+
});
|
|
312
|
+
if (result.success && result.config) {
|
|
313
|
+
if (options.json) {
|
|
314
|
+
console.log(JSON.stringify(result.config, null, 2));
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
console.log(chalk_1.default.blue('⚙️ Configuration:\n'));
|
|
318
|
+
console.log(JSON.stringify(result.config, null, 2));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
console.error(chalk_1.default.red('❌ Failed:'), result.error);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
console.error(chalk_1.default.red('❌ Error:'), error);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
// Parse arguments
|
|
332
|
+
program.parse();
|
|
333
|
+
//# sourceMappingURL=index.js.map
|