mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-08 01:43:07 +00:00
feat(cli): ping-peer CLI + MCP ping_peer for peer messaging (#1195)
* feat(cli): add ping-peer CLI and MCP ping_peer for peer messaging Promote resume-if-inactive + wait-active + POST message into a first-class CLI command and session MCP tool so agents stop reinventing JWT+curl. Fixes #1194 Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli): do not auto-approve MCP ping_peer Cross-session messaging can resume a peer and inject a prompt, so keep permission-mode gating (Codex PR review Major on #1195). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli): require approval for ping_peer in read-only mode Read-only auto-approve treated non-write names as safe; ping_peer can still resume a peer and inject prompts, so gate it like a write tool. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli): keep ping_peer out of Claude --allowedTools toolNames still registers the MCP tool, but Claude auto-allow must not pre-approve cross-session resume+inject without a permission prompt. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli): re-check session active before ping-peer send List/get can race; POST /messages still 409s if the target flips inactive before send. Resume+wait again (and re-gate pi) immediately before POST. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,8 +14,8 @@ vi.mock('@/claude/utils/startHappyServer', () => ({
|
||||
return {
|
||||
url: 'http://127.0.0.1:43006/',
|
||||
toolNames: options.skillLookup
|
||||
? ['change_title', 'display_image', 'skill_lookup']
|
||||
: ['change_title', 'display_image'],
|
||||
? ['change_title', 'display_image', 'ping_peer', 'skill_lookup']
|
||||
: ['change_title', 'display_image', 'ping_peer'],
|
||||
stop: vi.fn()
|
||||
}
|
||||
})
|
||||
@@ -71,7 +71,7 @@ describe('buildHapiMcpBridge skill lookup config', () => {
|
||||
'--url',
|
||||
'http://127.0.0.1:43006/',
|
||||
'--tools',
|
||||
'change_title,display_image,skill_lookup'
|
||||
'change_title,display_image,ping_peer,skill_lookup'
|
||||
])
|
||||
expect(bridge.mcpServers.hapi.tools).toEqual({
|
||||
change_title: { approval_mode: 'approve' },
|
||||
@@ -82,7 +82,7 @@ describe('buildHapiMcpBridge skill lookup config', () => {
|
||||
it('does not expose skill_lookup for native-skill bridge callers', async () => {
|
||||
const bridge = await buildHapiMcpBridge(createClient())
|
||||
|
||||
expect(harness.cliArgs.at(-1)).toBe('change_title,display_image')
|
||||
expect(harness.cliArgs.at(-1)).toBe('change_title,display_image,ping_peer')
|
||||
expect(bridge.mcpServers.hapi.tools).toEqual({
|
||||
change_title: { approval_mode: 'approve' }
|
||||
})
|
||||
|
||||
@@ -95,6 +95,8 @@ export async function buildHapiMcpBridge(
|
||||
approval_mode: 'approve'
|
||||
};
|
||||
}
|
||||
// ping_peer is registered on the HTTP MCP server / stdio bridge, but is not
|
||||
// auto-approved: it targets another session (resume + inject message).
|
||||
if (options.skillLookup) {
|
||||
tools.skill_lookup = {
|
||||
approval_mode: 'approve'
|
||||
|
||||
@@ -19,6 +19,7 @@ export const TITLE_INSTRUCTION = trimIdent(`
|
||||
Do not rename the chat for routine progress, substeps, implementation details, or a slightly better wording.
|
||||
Rename only when the user's primary objective changes substantially and the existing title would be misleading.
|
||||
When you create or find a local image file that the user should see, call functions.hapi__display_image with the image path. If that exact tool name is unavailable, use an equivalent alias such as hapi__display_image, mcp__hapi__display_image, or hapi_display_image.
|
||||
To message another HAPI session (peer handoff / nudge), call functions.hapi__ping_peer with sessionIdPrefix and message - do not reinvent JWT+curl. Shell fallback: hapi ping-peer <prefix> <message>.
|
||||
`);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user