docs: add docs:list helper and front matter

This commit is contained in:
Peter Steinberger
2025-12-09 17:51:05 +00:00
parent b3d4e5cfdf
commit bc3a14cde2
44 changed files with 436 additions and 74 deletions

View File

@@ -1,18 +1,23 @@
# Clawdis relay as a child process of the macOS app
---
summary: "Running the gateway as a child process of the macOS app and why"
read_when:
- Integrating the mac app with the gateway lifecycle
---
# Clawdis gateway as a child process of the macOS app
Date: 2025-12-06 · Status: draft · Owner: steipete
## Goal
Run the Node-based Clawdis/clawdis relay as a direct child of the LSUIElement app (instead of a launchd agent) while keeping all TCC-sensitive work inside the Swift app/XPC and wiring the existing “Clawdis Active” toggle to start/stop the child.
Run the Node-based Clawdis/clawdis gateway as a direct child of the LSUIElement app (instead of a launchd agent) while keeping all TCC-sensitive work inside the Swift app/XPC and wiring the existing “Clawdis Active” toggle to start/stop the child.
## When to prefer the child-process mode
- You want relay lifetime strictly coupled to the menu-bar app (dies when the app quits) and controlled by the “Clawdis Active” toggle without touching launchd.
- You want gateway lifetime strictly coupled to the menu-bar app (dies when the app quits) and controlled by the “Clawdis Active” toggle without touching launchd.
- Youre okay giving up login persistence/auto-restart that launchd provides, or youll add your own backoff loop.
- You want simpler log capture and supervision inside the app (no external plist or user-visible LaunchAgent).
## Tradeoffs vs. launchd
- **Pros:** tighter coupling to UI state; simpler surface (no plist install/bootout); easier to stream stdout/stderr; fewer moving parts for beta users.
- **Cons:** no built-in KeepAlive/login auto-start; app crash kills relay; you must build your own restart/backoff; Activity Monitor will show both processes under the app; still need correct TCC handling (see below).
- **Cons:** no built-in KeepAlive/login auto-start; app crash kills gateway; you must build your own restart/backoff; Activity Monitor will show both processes under the app; still need correct TCC handling (see below).
- **TCC:** behaviorally, child processes often inherit the parent apps “responsible process” for TCC, but this is *not a contract*. Continue to route all protected actions through the Swift app/XPC so prompts stay tied to the signed app bundle.
## TCC guardrails (must keep)
@@ -29,10 +34,10 @@ Run the Node-based Clawdis/clawdis relay as a direct child of the LSUIElement ap
- Add a small `RelayProcessManager` (Swift) that owns:
- `execution: Execution?` from `Swift Subprocess` to track the child.
- `start(config)` called when “Clawdis Active” flips ON:
- binary: host Node running the bundled relay under `Clawdis.app/Contents/Resources/Relay/`
- binary: host Node running the bundled gateway under `Clawdis.app/Contents/Resources/Gateway/`
- args: current clawdis entrypoint and flags
- cwd/env: point to `~/.clawdis` as today; inject the expanded PATH so Homebrew Node resolves under launchd
- output: stream stdout/stderr to `/tmp/clawdis-relay.log` (cap buffer via Subprocess OutputLimits)
- output: stream stdout/stderr to `/tmp/clawdis-gateway.log` (cap buffer via Subprocess OutputLimits)
- restart: optional linear/backoff restart if exit was non-zero and Active is still true
- `stop()` called when Active flips OFF or app terminates: cancel the execution and `waitUntilExit`.
- Wire SwiftUI toggle:
@@ -41,19 +46,19 @@ Run the Node-based Clawdis/clawdis relay as a direct child of the LSUIElement ap
- Keep the existing `LaunchdManager` around so we can switch back if needed; the toggle can choose between launchd or child mode with a flag if we want both.
## Packaging and signing
- Bundle the relay payload (dist + production node_modules) under `Contents/Resources/Relay/`; rely on host Node ≥22 instead of embedding a runtime.
- Bundle the gateway payload (dist + production node_modules) under `Contents/Resources/Gateway/`; rely on host Node ≥22 instead of embedding a runtime.
- Codesign native addons and dylibs inside the bundle; no nested runtime binary to sign now.
- Host runtime should not call TCC APIs directly; keep privileged work inside the app/XPC.
## Logging and observability
- Stream child stdout/stderr to `/tmp/clawdis-relay.log`; surface the last N lines in the Debug tab.
- Stream child stdout/stderr to `/tmp/clawdis-gateway.log`; surface the last N lines in the Debug tab.
- Emit a user notification (via existing NotificationManager) on crash/exit while Active is true.
- Add a lightweight heartbeat from Node → app (e.g., ping over stdout) so the app can show status in the menu.
## Failure/edge cases
- App crash/quit kills the relay. Decide if that is acceptable for the deployment tier; otherwise, stick with launchd for production and keep child-process for dev/experiments.
- If the relay exits repeatedly, back off (e.g., 1s/2s/5s/10s) and give up after N attempts with a menu warning.
- Respect the existing pause semantics: when paused, the XPC should return `ok=false, "clawdis paused"`; the relay should avoid calling privileged routes while paused.
- App crash/quit kills the gateway. Decide if that is acceptable for the deployment tier; otherwise, stick with launchd for production and keep child-process for dev/experiments.
- If the gateway exits repeatedly, back off (e.g., 1s/2s/5s/10s) and give up after N attempts with a menu warning.
- Respect the existing pause semantics: when paused, the XPC should return `ok=false, "clawdis paused"`; the gateway should avoid calling privileged routes while paused.
## Open questions / follow-ups
- Do we need dual-mode (launchd for prod, child for dev)? If yes, gate via a setting or build flag.
@@ -62,5 +67,5 @@ Run the Node-based Clawdis/clawdis relay as a direct child of the LSUIElement ap
## Decision snapshot (current recommendation)
- Keep all TCC surfaces in the Swift app/XPC.
- Implement `RelayProcessManager` with Swift Subprocess to start/stop the relay on the “Clawdis Active” toggle.
- Implement `RelayProcessManager` with Swift Subprocess to start/stop the gateway on the “Clawdis Active” toggle.
- Maintain the launchd path as a fallback for uptime/login persistence until child-mode proves stable.