mirror of
https://fastgit.cc/github.com/Yeachan-Heo/oh-my-claudecode
synced 2026-04-21 13:20:34 +08:00
Attached multi-pane dev sessions were waking OpenClaw multiple times for what operators experience as one session-start, prompt-submit, or stop burst. The bridge now keeps a short-lived per-worktree dedupe ledger keyed by tmux session (and normalized prompt for submit bursts) so the first signal still ships while repeated pane/client echoes are collapsed before reaching downstream native gateways. Constraint: Duplicate bursts can come from separate panes or clients that share one tmux session Constraint: Preserve the first lifecycle alert and avoid adding dependencies Rejected: Deduplicate on sessionId alone | pane-local Claude sessions do not share a stable session id Rejected: Fix only downstream Clawhip routing | duplicate traffic should be suppressed before gateway dispatch Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep prompt-submit collapse keyed on tmux session plus normalized prompt unless the UserPromptSubmit bridge contract changes Tested: npx vitest run src/openclaw/__tests__/*.test.ts Tested: npx vitest run src/hooks/__tests__/bridge-openclaw.test.ts Tested: npx tsc --noEmit Not-tested: Live OpenClaw delivery against a real attached multi-pane dev tmux session
3.6 KiB
3.6 KiB
OpenClaw / Clawhip Routing Contract
This document defines the normalized event contract OMC emits through the OpenClaw bridge for native Clawhip-style consumers.
Goals
- Keep the raw hook event (
event) for backward compatibility. - Add a normalized
signalobject for routing and dedupe-friendly filtering. - Make command/native gateways receive the same logical payload shape as HTTP gateways.
Payload shape
HTTP gateways receive JSON with this structure:
{
"event": "post-tool-use",
"instruction": "...",
"timestamp": "2026-03-09T00:00:00.000Z",
"sessionId": "...",
"projectPath": "...",
"projectName": "...",
"tmuxSession": "...",
"tmuxTail": "...",
"signal": {
"kind": "test",
"name": "test-run",
"phase": "failed",
"routeKey": "test.failed",
"priority": "high",
"toolName": "Bash",
"command": "pnpm test",
"testRunner": "package-test",
"summary": "FAIL src/example.test.ts | ..."
},
"context": {
"sessionId": "...",
"projectPath": "...",
"toolName": "Bash"
}
}
signal contract
| Field | Meaning |
|---|---|
kind |
Routing family: session, tool, test, pull-request, question, keyword |
name |
Stable logical signal name |
phase |
Lifecycle phase: started, finished, failed, idle, detected, requested |
routeKey |
Canonical routing key for downstream consumers |
priority |
high for operational signals, low for generic tool noise |
Additional fields may appear when applicable:
toolNamecommandtestRunnerprUrlsummary
Native command gateway contract
Command gateways now get the same normalized payload through both:
- template variable:
{{payloadJson}} - env var:
OPENCLAW_PAYLOAD_JSON
They also receive convenience env vars:
OPENCLAW_SIGNAL_ROUTE_KEYOPENCLAW_SIGNAL_PHASEOPENCLAW_SIGNAL_KIND
That lets native Clawhip routing consume one contract whether the transport is HTTP or shell-command based.
Current high-priority route keys
session.startedsession.finishedsession.idlequestion.requestedtest.startedtest.finishedtest.failedpull-request.startedpull-request.createdpull-request.failedtool.failed
Generic tool.started / tool.finished remain available as low-priority fallback signals.
Noise reduction
AskUserQuestionnow emits only the dedicatedquestion.requestedsignal instead of also emitting generic tool lifecycle events.- OpenClaw now collapses repeated attached-tmux lifecycle bursts before dispatching them to downstream native gateways.
session-startcollapses on{projectPath, tmuxSession}for a short burst window.keyword-detector(theUserPromptSubmitbridge surface) collapses prompt-submitted bursts on{projectPath, tmuxSession, normalized prompt}.stop/session-endcollapse on{projectPath, tmuxSession}for a short burst window.
- Consumers should prefer
signal.priority === "high"or explicitsignal.routeKeyfilters instead of routing directly on raw hook names.
Stability notes
- Raw
eventnames are preserved for backward compatibility. signalis the preferred routing surface for new native Clawhip integrations.contextremains a whitelisted subset; internal raw tool input/output are used only to derive normalized signals and are not forwarded inpayload.context.