Skip to content

[Docs]: Plugin-side daemon spawn pattern + multi-daemon gap in lifecycle spec #1056

@jackwener

Description

@jackwener

Context

Future OpenCLI adapters may need to spawn their own background daemons (analogous to the browser-bridge daemon that bridges CDP traffic). When researching the spawn pattern used by browser-bridge, two documentation-worthy findings surfaced:

  1. The spawn pattern is simple, correct, and stable — it's worth recording so plugin authors copy it verbatim rather than inventing variations.
  2. The recently-drafted docs/superpowers/specs/2026-03-31-daemon-lifecycle-redesign.md implicitly assumes a single daemon and doesn't cover how opencli daemon status/stop/restart would behave if a second (plugin-side) daemon coexists.

This issue tracks adding docs for (1) and deciding the scope for (2).

1. Verified spawn pattern

src/browser/bridge.ts:102-107:

this._daemonProc = spawn(spawnArgs[0], spawnArgs.slice(1), {
  detached: true,
  stdio: 'ignore',
  env: { ...process.env },
});
this._daemonProc.unref();

Properties worth highlighting in plugin-author docs:

  • detached: true + .unref() lets the CLI process exit without keeping the daemon as a child — daemon outlives any single invocation.
  • stdio: 'ignore' is required for .unref() to actually release the pipes; otherwise the parent stays attached until stdio closes.
  • No setsid / explicit pgid management is needed on macOS or Linux for this use case — detached: true + stdio: 'ignore' is sufficient. Plugin authors do not need to reimplement process-group logic.
  • env: { ...process.env } is intentional: the daemon inherits the caller's env (including adapter-specific OPENCLI_* vars and PATH).
  • Spawn happens lazily from the CLI entry point (bridge.ts), not at module import — important for plugin authors who want the daemon to come up only when their adapter actually runs.

Suggested home for this doc: a new docs/developer/plugin-daemons.md (or extending docs/advanced/remote-chrome.md's daemon section).

2. Multi-daemon gap in the daemon lifecycle redesign spec

docs/superpowers/specs/2026-03-31-daemon-lifecycle-redesign.md introduces opencli daemon status/stop/restart subcommands. The current /status example returns a single daemon's state:

Daemon: running (PID 12345)
Uptime: 2h 15m
Extension: connected
Last CLI request: 8 min ago
Memory: 12.3 MB
Port: 19825

If plugin-side daemons land later, this shape doesn't generalize cleanly. Two orthogonal questions to settle before the spec is implemented:

  • Discovery: should opencli daemon status auto-enumerate known daemons (via a registry / well-known port range / pidfile convention), or require --name browser-bridge to target one?
  • Targeting: should daemon stop / daemon restart require an explicit target when >1 daemon is running, and default to "all" / "browser-bridge" / error when ambiguous?

Neither needs to be solved immediately — but the spec should at least reserve namespace for multi-daemon (e.g. accept opencli daemon status [name] with today's behavior being name = browser-bridge implicit), so later extension doesn't break existing flags.

Out of scope

This issue is strictly documentation / spec-scope. It does not commit to adding any new plugin daemon; it only records patterns and flags a gap so future work has an easier on-ramp.

Suggested resolution

  • Add a short "plugin-side daemons" section to developer docs citing the spawn pattern above.
  • Amend the daemon lifecycle redesign spec to reserve single-vs-multi daemon namespace in the CLI surface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions