feat: add bounded history previews across nine channels

Add shared /history parsing, read-only session access, message filtering, and bounded replies. Default to three messages, cap at five, and exclude saved history commands.

Include channel integration tests, translations, command help, and the Issue #62 implementation plan.
This commit is contained in:
xmanrui 2026-08-28 03:01:53 +08:00
parent bf0e157cd4
commit 8c6c31a1b6
23 changed files with 1965 additions and 221 deletions

View file

@ -30,6 +30,7 @@ import {
isBatchInputCommand,
} from '../shared/batch-input.mjs';
import { runCompactCommand } from '../shared/compact-command.mjs';
import { isHistoryCommand, runHistoryCommand } from '../shared/history-command.mjs';
import {
isControlCommand,
runControlCommand,
@ -620,12 +621,15 @@ export class FeishuHarnessBridge {
.finally(() => this.#acceptedMessageIds.delete(messageId));
return processing;
}
const commandRunner = hasInboundFiles(commandMessage) ? null : isControlCommand(commandText)
const commandRunner = isHistoryCommand(commandText) ? runHistoryCommand
: hasInboundFiles(commandMessage) ? null : isControlCommand(commandText)
? runControlCommand
: (isModelCommand(commandText)
? runModelCommand
: (isPresetCommand(commandText) ? runPresetCommand : null));
if (commandRunner && addressed) {
// In all-message group mode, history must still be refused locally rather
// than becoming a normal prompt when no mention is present.
if (commandRunner && (addressed || commandRunner === runHistoryCommand)) {
const processing = this.#processFastCommand(
event,
messageId,
@ -913,6 +917,7 @@ export class FeishuHarnessBridge {
key,
{
signal: this.#signal,
isDirect: event.message.chat_type === 'p2p',
hasImages: hasInboundImages(message),
hasFiles: hasInboundFiles(message),
pendingInteraction: this.#hasPendingInteraction(key),
@ -2083,7 +2088,10 @@ export class FeishuHarnessBridge {
try {
const bound = await this.#harness.bindWorkspaceSession(key, sessionId);
const title = String(bound?.title ?? '').replace(/\s+/gu, ' ').trim() || t('暂无标题');
await this.#send(chatId, t('已绑定会话「{title}」\nID:{id}', { title, id: bound?.sessionId ?? sessionId }));
await this.#send(chatId, [
t('已绑定会话「{title}」\nID:{id}', { title, id: bound?.sessionId ?? sessionId }),
t('发送 /history 查看最近对话。'),
].join('\n'));
await this.#sendMenuCard(key, chatId, { updateMessageId });
} catch (error) {
await this.#sendFailure(chatId, error, {

View file

@ -497,6 +497,7 @@ export function menuHelpText() {
'/status 连接状态',
'/version 查看插件版本',
'/compact 压缩当前会话上下文',
'/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)',
'/archived on/off 会话列表显示/隐藏归档',
'',
'👁 关注',
@ -593,6 +594,7 @@ export function helpCard(extraTextLines = []) {
{ tag: 'div', text: markdown([
t(HELP_TEXT_COMMANDS),
t('`/version` — 查看插件版本'),
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
].join('\n') + extraText) },
{ tag: 'hr' },
{ tag: 'div', text: markdown(t(HELP_NUMBER_FALLBACK)) },