Skip to content

[Feature] Support custom app events and call-until-event completion #56

@yjmeqt

Description

@yjmeqt

Problem

Today Remo capability calls are request/response only. In some app flows, a capability can start work but the app is not actually ready for the next capability when the response returns.

A common example is login:

  • auth.login succeeds and returns
  • the app continues doing follow-up work in the background
  • after some delay, the home screen reload finishes
  • only then is the app ready for the next capability call

Right now the client has to guess with fixed sleeps or separate ad hoc polling. That is fragile and makes capability-driven flows less reliable.

Proposed Solution

Add first-class support for app-defined custom events, then add a client flow that can invoke a capability and wait for a matching event before considering the overall operation complete.

The important scope here is not a full multi-step workflow DSL. The core primitive is:

  1. call a capability
  2. let the app continue asynchronous follow-up work
  3. emit a custom event when the app is actually ready
  4. let the client wait for that event with timeout/failure handling

Example:

remo call -a <addr> auth.login '{"username":"demo","password":"demo"}' \
  --await-event homepage.reloaded \
  --timeout 30s

On the app side, Remo would need a public SDK API to emit custom events, not just built-in lifecycle events like capabilities_changed.

A more robust version should support correlation IDs so the awaited event can be tied to the specific capability invocation, for example:

  • client includes a correlation ID with auth.login
  • app emits homepage.reloaded with the same correlation ID
  • Remo waits for the matching event, not any event with that name

Potential pieces:

  • SDK API to emit custom events from Swift/ObjC
  • CLI support for call plus await event
  • timeout support
  • clear failure modes when the event never arrives
  • optional payload filtering
  • correlation ID support

Alternatives Considered

  1. Keep capability handlers open until all downstream work finishes.
    This makes the initial capability response mean both "accepted" and "fully ready", which is less expressive and may force long-running handlers to stay open unnecessarily.

  2. Use fixed sleeps between capability calls.
    This is simple but unreliable and app-specific.

  3. Add a full workflow/compound-capability DSL.
    This seems heavier than necessary right now. The smaller primitive of call + await matching event likely solves the immediate problem with less API surface.

Additional Context

This fits the existing protocol shape well because Remo already has unsolicited events and remo watch. What seems missing is a public app-side way to emit custom events plus a higher-level client flow to wait for a specific event after invoking a capability.

Example target flow:

  • call auth.login
  • receive immediate success response
  • app continues post-login sync/navigation/reload work
  • app emits homepage.reloaded
  • only then does Remo report the whole operation as complete

If helpful, expected acceptance criteria could be:

  • app code can emit named custom Remo events with JSON payload
  • remo call can optionally wait for a named event before exiting
  • waiting supports timeout
  • matching can use event kind plus optional payload fields
  • correlation is supported to avoid races with unrelated events

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions