* fix(opencode): stop treating empty tool input as final args
OpenCode emits input/rawInput as {} on tool start (and sometimes again
during permission), then fills real arguments on running/completed.
Treat empty objects as unusable so ACP and local hooks keep waiting for
real args, never clobber them, and ignore non-tool parts as fake results.
* fix(web): add exec timing fields to ToolCard test fixture
ChatToolCall now requires execStartedAt/execCompletedAt; update the
fixture so typecheck passes.
* fix(opencode): recover late tool-call after empty execute.before
Skip empty before under name-only queue pairing, emit tool-call on after when
still missing, and reject content JSON {} on ACP initial tool_call.