fix(cli): filter isMeta and isCompactSummary messages in local and remote mode (#359)

This commit is contained in:
Haoqing Wang
2026-03-25 05:36:41 +08:00
committed by GitHub
parent a200fe9628
commit 6384697b03
4 changed files with 85 additions and 1 deletions
@@ -105,4 +105,32 @@ describe('claudeLocalLauncher message filtering', () => {
expect(sentMessages).toHaveLength(2)
})
it('filters out isMeta messages (e.g. skill injections)', async () => {
const { session, sentMessages } = createSessionStub()
await claudeLocalLauncher(session as never)
harness.scannerOnMessage!({
type: 'user',
isMeta: true,
uuid: '1',
message: { content: [{ type: 'text', text: '# Skill content...' }] }
})
expect(sentMessages).toHaveLength(0)
})
it('filters out isCompactSummary messages', async () => {
const { session, sentMessages } = createSessionStub()
await claudeLocalLauncher(session as never)
harness.scannerOnMessage!({
type: 'assistant',
isCompactSummary: true,
uuid: '1',
message: { content: 'compacted context' }
})
expect(sentMessages).toHaveLength(0)
})
})
+5
View File
@@ -15,6 +15,11 @@ export async function claudeLocalLauncher(session: Session): Promise<'switch' |
if (message.type === 'summary') {
return
}
// Filter out internal meta messages (e.g. skill injections) and
// compact summaries to avoid them appearing in the web UI
if (message.isMeta || message.isCompactSummary) {
return
}
// Filter out invisible system messages (e.g. init, stop_hook_summary)
// to avoid them showing as raw JSON in the web UI
if (!isClaudeChatVisibleMessage(message)) {
@@ -0,0 +1,51 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { OutgoingMessageQueue } from './OutgoingMessageQueue'
describe('OutgoingMessageQueue message filtering', () => {
let sent: Array<Record<string, unknown>>
let queue: OutgoingMessageQueue
beforeEach(() => {
sent = []
queue = new OutgoingMessageQueue((msg) => { sent.push(msg) })
})
afterEach(() => {
queue.destroy()
})
it('sends normal messages', async () => {
queue.enqueue({ type: 'assistant', uuid: '1' })
queue.enqueue({ type: 'user', uuid: '2' })
await queue.flush()
expect(sent).toHaveLength(2)
})
it('filters out system messages', async () => {
queue.enqueue({ type: 'system', subtype: 'init', uuid: '1' })
queue.enqueue({ type: 'assistant', uuid: '2' })
await queue.flush()
expect(sent).toHaveLength(1)
expect(sent[0]).toMatchObject({ type: 'assistant' })
})
it('filters out isMeta messages', async () => {
queue.enqueue({ type: 'user', isMeta: true, uuid: '1' })
queue.enqueue({ type: 'assistant', uuid: '2' })
await queue.flush()
expect(sent).toHaveLength(1)
expect(sent[0]).toMatchObject({ type: 'assistant' })
})
it('filters out isCompactSummary messages', async () => {
queue.enqueue({ type: 'assistant', isCompactSummary: true, uuid: '1' })
queue.enqueue({ type: 'user', uuid: '2' })
await queue.flush()
expect(sent).toHaveLength(1)
expect(sent[0]).toMatchObject({ type: 'user' })
})
})
+1 -1
View File
@@ -121,7 +121,7 @@ export class OutgoingMessageQueue {
// Send if not already sent
if (!item.sent) {
if (item.logMessage.type !== 'system') {
if (item.logMessage.type !== 'system' && !item.logMessage.isMeta && !item.logMessage.isCompactSummary) {
this.sendFunction(item.logMessage);
}
item.sent = true;