mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
Release version 0.16.3
This commit is contained in:
@@ -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
@@ -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)
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user