@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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +94 -0
  3. package/bin/remote-cli.js +2 -0
  4. package/dist/client/MessageHandler.d.ts +92 -0
  5. package/dist/client/MessageHandler.d.ts.map +1 -0
  6. package/dist/client/MessageHandler.js +496 -0
  7. package/dist/client/MessageHandler.js.map +1 -0
  8. package/dist/client/WebSocketClient.d.ts +109 -0
  9. package/dist/client/WebSocketClient.d.ts.map +1 -0
  10. package/dist/client/WebSocketClient.js +234 -0
  11. package/dist/client/WebSocketClient.js.map +1 -0
  12. package/dist/commands/config.d.ts +35 -0
  13. package/dist/commands/config.d.ts.map +1 -0
  14. package/dist/commands/config.js +195 -0
  15. package/dist/commands/config.js.map +1 -0
  16. package/dist/commands/init.d.ts +25 -0
  17. package/dist/commands/init.d.ts.map +1 -0
  18. package/dist/commands/init.js +112 -0
  19. package/dist/commands/init.js.map +1 -0
  20. package/dist/commands/start.d.ts +20 -0
  21. package/dist/commands/start.d.ts.map +1 -0
  22. package/dist/commands/start.js +108 -0
  23. package/dist/commands/start.js.map +1 -0
  24. package/dist/commands/status.d.ts +37 -0
  25. package/dist/commands/status.d.ts.map +1 -0
  26. package/dist/commands/status.js +71 -0
  27. package/dist/commands/status.js.map +1 -0
  28. package/dist/commands/stop.d.ts +23 -0
  29. package/dist/commands/stop.d.ts.map +1 -0
  30. package/dist/commands/stop.js +52 -0
  31. package/dist/commands/stop.js.map +1 -0
  32. package/dist/config/ConfigManager.d.ts +109 -0
  33. package/dist/config/ConfigManager.d.ts.map +1 -0
  34. package/dist/config/ConfigManager.js +262 -0
  35. package/dist/config/ConfigManager.js.map +1 -0
  36. package/dist/executor/ClaudeExecutor.d.ts +89 -0
  37. package/dist/executor/ClaudeExecutor.d.ts.map +1 -0
  38. package/dist/executor/ClaudeExecutor.js +365 -0
  39. package/dist/executor/ClaudeExecutor.js.map +1 -0
  40. package/dist/executor/ClaudePersistentExecutor.d.ts +175 -0
  41. package/dist/executor/ClaudePersistentExecutor.d.ts.map +1 -0
  42. package/dist/executor/ClaudePersistentExecutor.js +958 -0
  43. package/dist/executor/ClaudePersistentExecutor.js.map +1 -0
  44. package/dist/executor/index.d.ts +20 -0
  45. package/dist/executor/index.d.ts.map +1 -0
  46. package/dist/executor/index.js +48 -0
  47. package/dist/executor/index.js.map +1 -0
  48. package/dist/hooks/ClaudeCodeHooks.d.ts +281 -0
  49. package/dist/hooks/ClaudeCodeHooks.d.ts.map +1 -0
  50. package/dist/hooks/ClaudeCodeHooks.js +350 -0
  51. package/dist/hooks/ClaudeCodeHooks.js.map +1 -0
  52. package/dist/hooks/FeishuNotificationAdapter.d.ts +87 -0
  53. package/dist/hooks/FeishuNotificationAdapter.d.ts.map +1 -0
  54. package/dist/hooks/FeishuNotificationAdapter.js +280 -0
  55. package/dist/hooks/FeishuNotificationAdapter.js.map +1 -0
  56. package/dist/hooks/index.d.ts +4 -0
  57. package/dist/hooks/index.d.ts.map +1 -0
  58. package/dist/hooks/index.js +10 -0
  59. package/dist/hooks/index.js.map +1 -0
  60. package/dist/index.d.ts +3 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +333 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/security/DirectoryGuard.d.ts +54 -0
  65. package/dist/security/DirectoryGuard.d.ts.map +1 -0
  66. package/dist/security/DirectoryGuard.js +143 -0
  67. package/dist/security/DirectoryGuard.js.map +1 -0
  68. package/dist/types/config.d.ts +46 -0
  69. package/dist/types/config.d.ts.map +1 -0
  70. package/dist/types/config.js +22 -0
  71. package/dist/types/config.js.map +1 -0
  72. package/dist/types/index.d.ts +110 -0
  73. package/dist/types/index.d.ts.map +1 -0
  74. package/dist/types/index.js +3 -0
  75. package/dist/types/index.js.map +1 -0
  76. package/dist/utils/FeishuMessageFormatter.d.ts +84 -0
  77. package/dist/utils/FeishuMessageFormatter.d.ts.map +1 -0
  78. package/dist/utils/FeishuMessageFormatter.js +395 -0
  79. package/dist/utils/FeishuMessageFormatter.js.map +1 -0
  80. package/dist/utils/stripAnsi.d.ts +21 -0
  81. package/dist/utils/stripAnsi.d.ts.map +1 -0
  82. package/dist/utils/stripAnsi.js +30 -0
  83. package/dist/utils/stripAnsi.js.map +1 -0
  84. 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":"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"}
@@ -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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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