opencode-remote-control 0.2.0 → 0.2.2

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,10 +82,25 @@ 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
  });
100
+ if (!token) {
101
+ console.log('\nCancelled');
102
+ process.exit(0);
103
+ }
78
104
  return token;
79
105
  }
80
106
  async function promptFeishuConfig() {
@@ -86,20 +112,36 @@ async function promptFeishuConfig() {
86
112
  console.log(' 3. Fill in app name and description');
87
113
  console.log(' 4. Go to "凭证与基础信息" (Credentials) page');
88
114
  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());
94
- });
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());
115
+ const promptInput = async (promptText) => {
116
+ process.stdout.write(promptText);
117
+ return new Promise((resolve) => {
118
+ process.stdin.setEncoding('utf8');
119
+ const cleanup = () => {
120
+ process.stdin.pause();
121
+ process.removeListener('SIGINT', onSigint);
122
+ };
123
+ const onSigint = () => {
124
+ cleanup();
125
+ console.log('\nCancelled');
126
+ process.exit(0);
127
+ };
128
+ process.once('SIGINT', onSigint);
129
+ process.stdin.once('data', (chunk) => {
130
+ cleanup();
131
+ resolve(chunk.toString().trim());
132
+ });
101
133
  });
102
- });
134
+ };
135
+ const appId = await promptInput('Enter your App ID: ');
136
+ if (!appId) {
137
+ console.log('\nCancelled');
138
+ process.exit(0);
139
+ }
140
+ const appSecret = await promptInput('Enter your App Secret: ');
141
+ if (!appSecret) {
142
+ console.log('\nCancelled');
143
+ process.exit(0);
144
+ }
103
145
  return { appId, appSecret };
104
146
  }
105
147
  function showFeishuSetupGuide() {
@@ -316,6 +358,23 @@ async function runStart() {
316
358
  console.log(' opencode-remote config-feishu # Configure Feishu');
317
359
  process.exit(1);
318
360
  }
361
+ // Track shutdown state
362
+ let isShuttingDown = false;
363
+ // Handle graceful shutdown at CLI level
364
+ const handleShutdown = () => {
365
+ if (isShuttingDown)
366
+ return;
367
+ isShuttingDown = true;
368
+ console.log('\n🛑 Shutting down...');
369
+ // The individual bots will handle their own cleanup via their SIGINT handlers
370
+ // We just need to ensure the process exits
371
+ setTimeout(() => {
372
+ console.log('Goodbye!');
373
+ process.exit(0);
374
+ }, 1000);
375
+ };
376
+ process.once('SIGINT', handleShutdown);
377
+ process.once('SIGTERM', handleShutdown);
319
378
  // Start bots
320
379
  const promises = [];
321
380
  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.2",
4
4
  "description": "Control OpenCode from anywhere via Telegram or Feishu",
5
5
  "type": "module",
6
6
  "bin": {