You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The pulse aggregator service — `pulse-svc`. Eight lifecycle events plus three control
221
+
events; payload is a single space-free CSV. Full contract in [PROTOCOL.md](PROTOCOL.md):
222
+
223
+
```sh
224
+
noctalia msg plugin lowcache/claude-companion:pulse-svc all <event> [payload]
225
+
noctalia msg plugin lowcache/claude-companion:pulse-svc all needs_attention # bar icon -> red bell
226
+
noctalia msg plugin lowcache/claude-companion:pulse-svc all idle # back to robot
227
+
```
228
+
229
+
The quick-ask backend service — `claude-ask`. A bare poke; the question is written to
230
+
`$XDG_RUNTIME_DIR/claude-companion/ask` first, because a payload cannot contain spaces:
231
+
232
+
```sh
233
+
noctalia msg plugin lowcache/claude-companion:claude-ask all ask
234
+
```
235
+
236
+
Launcher provider — id `claude`, **prefix `claude`**. Type `claude ` in the Noctalia
237
+
launcher to start a session, or `claude ? <question>` for a quick-ask.
238
+
239
+
The bar widget `pulse` and the desktop widget `orb` are pure subscribers to the
240
+
`claude.pulse` shared-state key and take no IPC of their own.
241
+
206
242
## Wiring up other agents
207
243
208
244
None of this is Claude-specific under the hood. The pulse speaks a plain event format and doesn't care who's talking — any agent, CI job, or shell script that can run a command on its own lifecycle can light up the same bar. [PROTOCOL.md](PROTOCOL.md) has the full eight-event vocabulary, the CSV payload, session semantics, and the adapter contract. The reference emitter, `hooks/pulse-emit`, is plain POSIX sh and needs nothing but `noctalia` on your PATH:
**What it writes.** Runtime files live in `$XDG_RUNTIME_DIR/claude-companion/` (tmpfs,
255
+
0700, per-user): the consent `mode` mirror, the `presence` message, the `ask` handoff, and
256
+
`consent/<id>.req|.res` while a prompt is outstanding. Durable state lives in
257
+
`$XDG_STATE_HOME/noctalia/claude-companion/` (0600): `allow.jsonl` and `learn.jsonl` for the
258
+
consent gate. The shim's memory tool also appends to `~/.memory/inbox/`.
259
+
260
+
**What it spawns.**`noctalia msg …` for every dispatch; `python3` for the lifecycle hooks,
261
+
the consent gate and the MCP shim; `notify-send` for toasts; `claude -p` for quick-ask only.
262
+
The shim reads the compositor through `niri msg -j`, `hyprctl -j` or `swaymsg -t`, and media
263
+
through `playerctl` — all read-only queries.
264
+
265
+
**Network.** The plugin makes none. Quick-ask spawns `claude -p`, which talks to Anthropic's
266
+
API exactly as Claude Code does from a terminal.
267
+
268
+
**Compositors.** Everything except the shim's window/workspace tools is compositor-agnostic.
269
+
Those tools support niri, Hyprland and Sway, detected from the running socket.
217
270
218
-
A few things worth knowing before they surprise you:
271
+
**Rough edges.**A few things worth knowing before they surprise you:
219
272
220
273
- Plugin panels render at `Layer::Top`, so an overlay window — a notification, a quake terminal, a polkit prompt — can sit on top of the answer panel. The answer's still there; clear the overlay and you'll see it. There's an upstream ask in for panel layer control.
221
274
- Eight-digit hex alpha is ignored by bar widgets — brightness is done by scaling RGB toward black. (Earlier builds didn't fire `state.watch` on bars, so the pulse polled; the Noctalia 5 beta fires it, so the bar dot is now event-driven like the orb.)
0 commit comments