- Remove SKILL tool registration with nil handler (was causing nil
pointer in StageHost.ExecuteTool)
- Rewrite loadOCPlugin: notifications are the only registration path.
Synchronously drain all buffered register notifications after
waitReady, then start persistent notifyLoop for future registrations.
ListTools is verification-only, no longer registers tools.
- notifyLoop: persistent via for n := range sp.NotifyChan(), lifecycle
bound to sidecar process
- StageHost.ExecuteTool: add nil-handler check (defense-in-depth)
- Remove unused OCNamedParam, DrainNotify from sidecar.go
- simulator/main.js: All 30+ register* methods now send JSON-RPC notifications
to Go instead of being silent no-ops. Each plugin capability registration
(tool, provider, channel, hook, http_route, command, service, etc.) is
forwarded to Go via the notify channel.
- sidecar.go: Refactored to async reader goroutine. Single goroutine reads
all stdout lines, routes responses to pending callers via channel by ID,
and dispatches notifications (no-ID messages) to notifyCh for handling.
- plugin.go: drainNotify() collects all capabilities registered during
plugin init. handleNotify() logs each registered capability for visibility.
- All 9 openclaw tests pass including simulator + full pipeline tests.