From cecb655a4b3b948794ed3ad2cee44b58b1bcad5a Mon Sep 17 00:00:00 2001 From: RRRosmontis Date: Wed, 2 Sep 2026 16:07:53 +0800 Subject: [PATCH] fix: register /cancel as a proper command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously /cancel was intercepted inside the 'unknown' branch, and the comparison used the command WITHOUT the leading slash while parseCommand returns it WITH one ('/cancel') — the check never matched, so /cancel always fell through to the unknown-command reply, even with a pending ask/approval. Now a first-class command (menu included): closes the TG-side answer/approval channel when one is pending, otherwise reports that nothing is awaiting a reply. --- lib/bridge.js | 26 ++++++++++++++------------ lib/commands.d.ts | 3 +++ lib/commands.js | 2 ++ src/bridge.ts | 22 ++++++++++++---------- src/commands.ts | 3 +++ 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/lib/bridge.js b/lib/bridge.js index 0f4463a..b0c9060 100644 --- a/lib/bridge.js +++ b/lib/bridge.js @@ -107,6 +107,7 @@ export class TelegramBridge { { command: 'stop', description: '中止当前正在运行的任务' }, { command: 'mission', description: '查看任务清单与完成情况' }, { command: 'new', description: '在当前工作区新开对话并附着' }, + { command: 'cancel', description: '关闭 TG 端作答/审批(Web 端仍可答)' }, { command: 'help', description: '显示帮助' }, ]).then(() => { this.ctx.logger.info('dsh-telegram-channel: bot commands registered'); @@ -204,19 +205,20 @@ export class TelegramBridge { case 'new': await this.newSessionHere(chatId); return; - case 'unknown': + case 'cancel': { // /cancel closes the TG-side answer/approval channel; the UI side stays open. - if (parsed.command === 'cancel') { - let cancelled = false; - if (this.pendingApprovalsTG.delete(String(chatId))) - cancelled = true; - if (this.pendingAsks.delete(String(chatId))) - cancelled = true; - if (cancelled) { - await this.enqueueNotice(chatId, '已关闭 TG 端作答/审批(该问题仍可在 Web 端回答)'); - return; - } - } + let cancelled = false; + if (this.pendingApprovalsTG.delete(String(chatId))) + cancelled = true; + if (this.pendingAsks.delete(String(chatId))) + cancelled = true; + if (cancelled) + await this.enqueueNotice(chatId, '已关闭 TG 端作答/审批(该问题仍可在 Web 端回答)'); + else + await this.client.sendMessage(chatId, '当前没有待作答的提问或审批'); + return; + } + case 'unknown': await this.client.sendMessage(chatId, MSG.unknown(parsed.command)); return; case 'plain': { diff --git a/lib/commands.d.ts b/lib/commands.d.ts index 4631c20..e62e830 100644 --- a/lib/commands.d.ts +++ b/lib/commands.d.ts @@ -53,6 +53,9 @@ export type ParsedCommand = { } | { type: 'new'; text: string; +} | { + type: 'cancel'; + text: string; } | { type: 'unknown'; command: string; diff --git a/lib/commands.js b/lib/commands.js index f0d6648..5aa4ea4 100644 --- a/lib/commands.js +++ b/lib/commands.js @@ -95,6 +95,8 @@ export function parseCommand(text) { case '/new': case '/create': return { type: 'new', text }; + case '/cancel': + return { type: 'cancel', text }; default: return { type: 'unknown', command, text }; } diff --git a/src/bridge.ts b/src/bridge.ts index 9e886ff..1b6429c 100644 --- a/src/bridge.ts +++ b/src/bridge.ts @@ -218,6 +218,7 @@ export class TelegramBridge { { command: 'stop', description: '中止当前正在运行的任务' }, { command: 'mission', description: '查看任务清单与完成情况' }, { command: 'new', description: '在当前工作区新开对话并附着' }, + { command: 'cancel', description: '关闭 TG 端作答/审批(Web 端仍可答)' }, { command: 'help', description: '显示帮助' }, ]).then(() => { this.ctx.logger.info('dsh-telegram-channel: bot commands registered') @@ -320,17 +321,18 @@ export class TelegramBridge { case 'new': await this.newSessionHere(chatId) return - case 'unknown': + case 'cancel': { // /cancel closes the TG-side answer/approval channel; the UI side stays open. - if (parsed.command === 'cancel') { - let cancelled = false - if (this.pendingApprovalsTG.delete(String(chatId))) cancelled = true - if (this.pendingAsks.delete(String(chatId))) cancelled = true - if (cancelled) { - await this.enqueueNotice(chatId, '已关闭 TG 端作答/审批(该问题仍可在 Web 端回答)') - return - } - } + let cancelled = false + if (this.pendingApprovalsTG.delete(String(chatId))) cancelled = true + if (this.pendingAsks.delete(String(chatId))) cancelled = true + if (cancelled) + await this.enqueueNotice(chatId, '已关闭 TG 端作答/审批(该问题仍可在 Web 端回答)') + else + await this.client.sendMessage(chatId, '当前没有待作答的提问或审批') + return + } + case 'unknown': await this.client.sendMessage(chatId, MSG.unknown(parsed.command)) return case 'plain': { diff --git a/src/commands.ts b/src/commands.ts index 76d0aec..5cb8b0c 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -73,6 +73,7 @@ export type ParsedCommand = | { type: 'stop'; text: string } | { type: 'mission'; text: string } | { type: 'new'; text: string } + | { type: 'cancel'; text: string } | { type: 'unknown'; command: string; text: string } | { type: 'plain'; text: string } @@ -107,6 +108,8 @@ export function parseCommand(text: string): ParsedCommand { case '/new': case '/create': return { type: 'new', text } + case '/cancel': + return { type: 'cancel', text } default: return { type: 'unknown', command, text } }