opencode-remote-control 0.2.0 → 0.2.1

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/cli.js CHANGED
@@ -45,7 +45,18 @@ async function promptChannel() {
45
45
  process.stdout.write('Enter your choice (1 or 2): ');
46
46
  const choice = await new Promise((resolve) => {
47
47
  process.stdin.setEncoding('utf8');
48
+ const cleanup = () => {
49
+ process.stdin.pause();
50
+ process.removeListener('SIGINT', onSigint);
51
+ };
52
+ const onSigint = () => {
53
+ cleanup();
54
+ console.log('\nCancelled');
55
+ process.exit(0);
56
+ };
57
+ process.once('SIGINT', onSigint);
48
58
  process.stdin.once('data', (chunk) => {
59
+ cleanup();
49
60
  resolve(chunk.toString().trim());
50
61
  });
51
62
  });
@@ -71,7 +82,18 @@ async function promptToken() {
71
82
  // Read from stdin
72
83
  const token = await new Promise((resolve) => {
73
84
  process.stdin.setEncoding('utf8');
85
+ const cleanup = () => {
86
+ process.stdin.pause();
87
+ process.removeListener('SIGINT', onSigint);
88
+ };
89
+ const onSigint = () => {
90
+ cleanup();
91
+ console.log('\nCancelled');
92
+ process.exit(0);
93
+ };
94
+ process.once('SIGINT', onSigint);
74
95
  process.stdin.once('data', (chunk) => {
96
+ cleanup();
75
97
  resolve(chunk.toString().trim());
76
98
  });
77
99
  });
@@ -86,20 +108,28 @@ async function promptFeishuConfig() {
86
108
  console.log(' 3. Fill in app name and description');
87
109
  console.log(' 4. Go to "凭证与基础信息" (Credentials) page');
88
110
  console.log('');
89
- process.stdout.write('Enter your App ID: ');
90
- const appId = await new Promise((resolve) => {
91
- process.stdin.setEncoding('utf8');
92
- process.stdin.once('data', (chunk) => {
93
- resolve(chunk.toString().trim());
111
+ const promptInput = async (promptText) => {
112
+ process.stdout.write(promptText);
113
+ return new Promise((resolve) => {
114
+ process.stdin.setEncoding('utf8');
115
+ const cleanup = () => {
116
+ process.stdin.pause();
117
+ process.removeListener('SIGINT', onSigint);
118
+ };
119
+ const onSigint = () => {
120
+ cleanup();
121
+ console.log('\nCancelled');
122
+ process.exit(0);
123
+ };
124
+ process.once('SIGINT', onSigint);
125
+ process.stdin.once('data', (chunk) => {
126
+ cleanup();
127
+ resolve(chunk.toString().trim());
128
+ });
94
129
  });
95
- });
96
- process.stdout.write('Enter your App Secret: ');
97
- const appSecret = await new Promise((resolve) => {
98
- process.stdin.setEncoding('utf8');
99
- process.stdin.once('data', (chunk) => {
100
- resolve(chunk.toString().trim());
101
- });
102
- });
130
+ };
131
+ const appId = await promptInput('Enter your App ID: ');
132
+ const appSecret = await promptInput('Enter your App Secret: ');
103
133
  return { appId, appSecret };
104
134
  }
105
135
  function showFeishuSetupGuide() {
@@ -316,6 +346,23 @@ async function runStart() {
316
346
  console.log(' opencode-remote config-feishu # Configure Feishu');
317
347
  process.exit(1);
318
348
  }
349
+ // Track shutdown state
350
+ let isShuttingDown = false;
351
+ // Handle graceful shutdown at CLI level
352
+ const handleShutdown = () => {
353
+ if (isShuttingDown)
354
+ return;
355
+ isShuttingDown = true;
356
+ console.log('\n🛑 Shutting down...');
357
+ // The individual bots will handle their own cleanup via their SIGINT handlers
358
+ // We just need to ensure the process exits
359
+ setTimeout(() => {
360
+ console.log('Goodbye!');
361
+ process.exit(0);
362
+ }, 1000);
363
+ };
364
+ process.once('SIGINT', handleShutdown);
365
+ process.once('SIGTERM', handleShutdown);
319
366
  // Start bots
320
367
  const promises = [];
321
368
  if (hasTelegram) {
@@ -339,7 +339,14 @@ export async function startFeishuBot(botConfig) {
339
339
  reject(err);
340
340
  });
341
341
  // Handle graceful shutdown
342
- process.on('SIGINT', () => {
342
+ process.once('SIGINT', () => {
343
+ console.log('\n🛑 Shutting down Feishu bot...');
344
+ server.close(() => {
345
+ console.log('Feishu bot stopped');
346
+ resolve();
347
+ });
348
+ });
349
+ process.once('SIGTERM', () => {
343
350
  console.log('\n🛑 Shutting down Feishu bot...');
344
351
  server.close(() => {
345
352
  console.log('Feishu bot stopped');
@@ -236,5 +236,19 @@ export async function startBot() {
236
236
  console.log('Make sure OpenCode is running');
237
237
  }
238
238
  console.log('🚀 Starting Telegram bot...');
239
+ // Handle graceful shutdown
240
+ const shutdown = async () => {
241
+ console.log('\n🛑 Shutting down Telegram bot...');
242
+ if (bot) {
243
+ await bot.stop();
244
+ }
245
+ console.log('Telegram bot stopped');
246
+ };
247
+ process.once('SIGINT', async () => {
248
+ await shutdown();
249
+ });
250
+ process.once('SIGTERM', async () => {
251
+ await shutdown();
252
+ });
239
253
  await bot.start();
240
254
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-remote-control",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Control OpenCode from anywhere via Telegram or Feishu",
5
5
  "type": "module",
6
6
  "bin": {