consciousness/schema/daemon.capnp
ProofOfConcept eab656aa64 idle: persist timeout, suppress restart fire, add debug/save/idle-timeout commands
Several idle timer fixes and new inspection capabilities:

- Persist idle_timeout across daemon restarts (was reverting to 5min default)
- Set fired=true on load to suppress immediate fire from stale timestamps
- Add human-readable ISO timestamps to daemon-state.json for debugging
- Use to_string_pretty for readable state file
- Make save() public for RPC access
- Remove kb_idle_minutes() — go purely off message timestamps
- Add maybe_prompt_notification() with idle gate so notifications only
  inject via tmux when truly idle, not during active sessions
- Add debug_json() for full state inspection with computed values
  (would_fire, block_reason, all timers)

New RPC commands (schema @16-18):
  poc-daemon idle-timeout <secs>  — set idle timeout
  poc-daemon save                 — force state persistence
  poc-daemon debug                — dump full internal state as JSON

Also: save state on clean shutdown, route module notifications through
maybe_prompt_notification before submitting to queue.

Co-Authored-By: ProofOfConcept <poc@bcachefs.org>
2026-03-05 21:17:43 -05:00

71 lines
1.9 KiB
Cap'n Proto

@0xb8e2f4a1c3d56789;
# Claude daemon RPC interface.
#
# Served over a Unix domain socket. Clients connect, bootstrap
# the Daemon interface, make calls, disconnect.
struct Notification {
type @0 :Text;
urgency @1 :UInt8;
message @2 :Text;
timestamp @3 :Float64;
}
struct TypeInfo {
name @0 :Text;
count @1 :UInt64;
firstSeen @2 :Float64;
lastSeen @3 :Float64;
threshold @4 :Int8; # -1 = inherit, 0-3 = explicit level
}
enum Activity {
idle @0;
focused @1;
sleeping @2;
}
struct Status {
lastUserMsg @0 :Float64;
lastResponse @1 :Float64;
claudePane @2 :Text;
sleepUntil @3 :Float64; # 0 = not sleeping, -1 = indefinite
quietUntil @4 :Float64;
consolidating @5 :Bool;
dreaming @6 :Bool;
fired @7 :Bool;
kentPresent @8 :Bool;
uptime @9 :Float64;
activity @10 :Activity;
pendingCount @11 :UInt32;
}
interface Daemon {
# Idle timer
user @0 (pane :Text) -> ();
response @1 (pane :Text) -> ();
sleep @2 (until :Float64) -> (); # 0 = indefinite
wake @3 () -> ();
quiet @4 (seconds :UInt32) -> ();
consolidating @5 () -> ();
consolidated @6 () -> ();
dreamStart @7 () -> ();
dreamEnd @8 () -> ();
stop @9 () -> ();
status @10 () -> (status :Status);
# Notifications
notify @11 (notification :Notification) -> (interrupt :Bool);
getNotifications @12 (minUrgency :UInt8) -> (notifications :List(Notification));
getTypes @13 () -> (types :List(TypeInfo));
setThreshold @14 (type :Text, level :UInt8) -> ();
idleTimeout @16 (seconds :Float64) -> ();
save @17 () -> ();
debug @18 () -> (json :Text);
# Modules
moduleCommand @15 (module :Text, command :Text, args :List(Text))
-> (result :Text);
}