Release version 0.16.3

This commit is contained in:
weishu
2026-03-20 12:17:35 +08:00
parent 9742522ee8
commit 32f05d99a0
5 changed files with 162 additions and 16 deletions
+10 -10
View File
@@ -12,7 +12,7 @@
},
"cli": {
"name": "@twsxtd/hapi",
"version": "0.16.1",
"version": "0.16.3",
"bin": {
"hapi": "bin/hapi.cjs",
},
@@ -43,11 +43,11 @@
"vitest": "^4.0.16",
},
"optionalDependencies": {
"@twsxtd/hapi-darwin-arm64": "0.16.1",
"@twsxtd/hapi-darwin-x64": "0.16.1",
"@twsxtd/hapi-linux-arm64": "0.16.1",
"@twsxtd/hapi-linux-x64": "0.16.1",
"@twsxtd/hapi-win32-x64": "0.16.1",
"@twsxtd/hapi-darwin-arm64": "0.16.3",
"@twsxtd/hapi-darwin-x64": "0.16.3",
"@twsxtd/hapi-linux-arm64": "0.16.3",
"@twsxtd/hapi-linux-x64": "0.16.3",
"@twsxtd/hapi-win32-x64": "0.16.3",
},
},
"docs": {
@@ -874,13 +874,13 @@
"@twsxtd/hapi": ["@twsxtd/hapi@workspace:cli"],
"@twsxtd/hapi-darwin-arm64": ["@twsxtd/hapi-darwin-arm64@0.16.1", "", { "os": "darwin", "cpu": "arm64", "bin": { "hapi": "bin/hapi" } }, "sha512-ayCxWfwMhLKXgoRFz7y7Flls9gfQpprf5AFgz83Fvb6GumCBe5emSvb/Gk/woj7dlmfAaSYFNvJ1VVRel1Bh+Q=="],
"@twsxtd/hapi-darwin-arm64": ["@twsxtd/hapi-darwin-arm64@0.16.3", "", { "os": "darwin", "cpu": "arm64", "bin": { "hapi": "bin/hapi" } }, "sha512-uIP+5MPPG0S5uWTsvToHdFuwl3x2i9ba6uaSzM7yhC0f0BViSshM5CtspNkOxKKcb/0WvQYsPsRpqkhF+O2kgQ=="],
"@twsxtd/hapi-darwin-x64": ["@twsxtd/hapi-darwin-x64@0.16.1", "", { "os": "darwin", "cpu": "x64", "bin": { "hapi": "bin/hapi" } }, "sha512-e2XMFhlx7P9c3dpnY+lCVunpXdRt3IE0lGrdB1kQaF3ThVpYyk8x1E6YKv55un01g/8Tz7fZPk5CKD5YNdXWzQ=="],
"@twsxtd/hapi-darwin-x64": ["@twsxtd/hapi-darwin-x64@0.16.3", "", { "os": "darwin", "cpu": "x64", "bin": { "hapi": "bin/hapi" } }, "sha512-S2Jhp8HY+1I560lD1CkOduXR7yZhZbMMdlIn8QekhXbAEay4enPK4Y0F1CMoYu4KemcwdYU0I2/jyowknVOAZA=="],
"@twsxtd/hapi-linux-arm64": ["@twsxtd/hapi-linux-arm64@0.16.1", "", { "os": "linux", "cpu": "arm64", "bin": { "hapi": "bin/hapi" } }, "sha512-ElwnYQqVIw1/nkgE4gdPuaYbq+IeCmk5mJhB0EjdbFcsjZXXmOT0ifWWjpoT0emaC8LY7a5OmOH0v1DmWLsxEQ=="],
"@twsxtd/hapi-linux-arm64": ["@twsxtd/hapi-linux-arm64@0.16.3", "", { "os": "linux", "cpu": "arm64", "bin": { "hapi": "bin/hapi" } }, "sha512-4/QzrFgr8xalLn0BSFFKKo4GY6mWHZLKwntYiSOTZ+aPHmoD/JxpXF39To5Dmp3FPRV+flyLMPy2p+FvPgg/ng=="],
"@twsxtd/hapi-linux-x64": ["@twsxtd/hapi-linux-x64@0.16.1", "", { "os": "linux", "cpu": "x64", "bin": { "hapi": "bin/hapi" } }, "sha512-0KNIsS4/g2XW59cOXpXG16Mmcc1gU4Z/VNgvQzJL0utfOxMUTrWzDVlrt7qN13yMocrqqgKCf0JTrEdgU1221w=="],
"@twsxtd/hapi-linux-x64": ["@twsxtd/hapi-linux-x64@0.16.3", "", { "os": "linux", "cpu": "x64", "bin": { "hapi": "bin/hapi" } }, "sha512-ZQmI1T62R+1+VL4bG/0x/uC8Y2pffgFj8kwl0tpBOUcjWWi8VKOIvjc7kcwtTdBplQ6vm8GAcyDb4kWJCP1ZQA=="],
"@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="],
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@twsxtd/hapi",
"version": "0.16.1",
"version": "0.16.3",
"description": "App for agentic coding - access coding agent anywhere",
"author": "Kirill Dubovitskiy & weishu",
"license": "AGPL-3.0-only",
@@ -26,11 +26,11 @@
}
},
"optionalDependencies": {
"@twsxtd/hapi-darwin-arm64": "0.16.1",
"@twsxtd/hapi-darwin-x64": "0.16.1",
"@twsxtd/hapi-linux-arm64": "0.16.1",
"@twsxtd/hapi-linux-x64": "0.16.1",
"@twsxtd/hapi-win32-x64": "0.16.1"
"@twsxtd/hapi-darwin-arm64": "0.16.3",
"@twsxtd/hapi-darwin-x64": "0.16.3",
"@twsxtd/hapi-linux-arm64": "0.16.3",
"@twsxtd/hapi-linux-x64": "0.16.3",
"@twsxtd/hapi-win32-x64": "0.16.3"
},
"scripts": {
"postinstall": "node -e \"try{require('fs').chmodSync(require('path').join(__dirname,'bin','hapi.cjs'),0o755)}catch(e){}\"",
@@ -0,0 +1,23 @@
import { describe, expect, it } from 'vitest'
import { isClaudeChatVisibleMessage } from './chatVisibility'
describe('isClaudeChatVisibleMessage', () => {
it('hides unsupported Claude system messages from chat delivery', () => {
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'stop_hook_summary' })).toBe(false)
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'init' })).toBe(false)
expect(isClaudeChatVisibleMessage({ type: 'system' })).toBe(false)
})
it('keeps supported Claude system events visible', () => {
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'turn_duration' })).toBe(true)
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'api_error' })).toBe(true)
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'microcompact_boundary' })).toBe(true)
expect(isClaudeChatVisibleMessage({ type: 'system', subtype: 'compact_boundary' })).toBe(true)
})
it('keeps conversation messages visible', () => {
expect(isClaudeChatVisibleMessage({ type: 'user' })).toBe(true)
expect(isClaudeChatVisibleMessage({ type: 'assistant' })).toBe(true)
expect(isClaudeChatVisibleMessage({ type: 'summary' })).toBe(true)
})
})
+16
View File
@@ -0,0 +1,16 @@
import type { RawJSONLines } from '@/claude/types'
const VISIBLE_SYSTEM_SUBTYPES = new Set([
'api_error',
'turn_duration',
'microcompact_boundary',
'compact_boundary'
])
export function isClaudeChatVisibleMessage(message: Pick<RawJSONLines, 'type'> & { subtype?: string }): boolean {
if (message.type !== 'system') {
return true
}
return typeof message.subtype === 'string' && VISIBLE_SYSTEM_SUBTYPES.has(message.subtype)
}
+107
View File
@@ -0,0 +1,107 @@
import { describe, expect, it } from 'vitest'
import { normalizeDecryptedMessage } from './normalize'
import type { DecryptedMessage } from '@/types/api'
function makeMessage(content: unknown): DecryptedMessage {
return {
id: 'msg-1',
seq: 1,
localId: null,
content,
createdAt: 1_742_372_800_000
}
}
describe('normalizeDecryptedMessage', () => {
it('drops unsupported Claude system output records', () => {
const message = makeMessage({
role: 'agent',
content: {
type: 'output',
data: {
type: 'system',
subtype: 'stop_hook_summary',
uuid: 'sys-1'
}
}
})
expect(normalizeDecryptedMessage(message)).toBeNull()
})
it('drops Claude init system output records', () => {
const message = makeMessage({
role: 'agent',
content: {
type: 'output',
data: {
type: 'system',
subtype: 'init',
uuid: 'sys-init',
session_id: 'session-1'
}
}
})
expect(normalizeDecryptedMessage(message)).toBeNull()
})
it('keeps known Claude system subtypes as normalized events', () => {
const message = makeMessage({
role: 'agent',
content: {
type: 'output',
data: {
type: 'system',
subtype: 'turn_duration',
uuid: 'sys-2',
durationMs: 1200
}
}
})
expect(normalizeDecryptedMessage(message)).toMatchObject({
id: 'msg-1',
role: 'event',
isSidechain: false,
content: {
type: 'turn-duration',
durationMs: 1200
}
})
})
it('keeps the stringify fallback for unknown non-system agent payloads', () => {
const message = makeMessage({
role: 'agent',
content: {
type: 'output',
data: {
type: 'assistant',
foo: 'bar'
}
}
})
const normalized = normalizeDecryptedMessage(message)
expect(normalized).toMatchObject({
id: 'msg-1',
role: 'agent',
isSidechain: false
})
expect(normalized?.role).toBe('agent')
if (!normalized || normalized.role !== 'agent') {
throw new Error('Expected agent message')
}
const firstBlock = normalized.content[0]
expect(firstBlock).toMatchObject({
type: 'text',
})
if (firstBlock.type !== 'text') {
throw new Error('Expected fallback text block')
}
expect(firstBlock.text).toContain('"foo": "bar"')
})
})