Skip to content

v0.8 [1/4]: Daemon core — server, watcher, queue, handlers #72

@ashu17706

Description

@ashu17706

Part of #71. The daemon process itself, no service-file plumbing, no CLI wiring yet.

Scope

Create `src/daemon/` with five focused modules:

  • `src/daemon/server.ts` — Unix socket bind at `/.cache/smriti/daemon.sock`, single-instance guard via bind-fail, signal handling (SIGTERM/SIGINT graceful drain), diagnostic PID file at `/.cache/smriti/daemon.pid`, log rotation to `~/.cache/smriti/daemon.log`
  • `src/daemon/watcher.ts` — `fs.watch` wrapper. macOS: `{ recursive: true }` native. Linux: walk-and-watch with dir-create re-watch (use `chokidar` to abstract; verified Bun-compatible)
  • `src/daemon/queue.ts` — per-project debounce queue, default 30s via `SMRITI_DAEMON_DEBOUNCE_MS`, in-process timers, exposes `schedule(projectId)` and `flush(projectId)`
  • `src/daemon/handlers.ts` — socket connection handler for Claude Stop hook poke; protocol: any byte received = "wake up and check Claude logs"
  • `src/daemon/client.ts` — socket client used by `smriti daemon stop` / `status`. Parses daemon socket messages

The watcher's events feed the queue; the queue's timer fires call into `src/ingest/index.ts`'s `ingest()` function in-process (no subprocess).

Verified prerequisites

  • ✅ `ingest()` and `ingestAll()` are clean async exports from `src/ingest/index.ts` — importable standalone
  • ✅ Bun 1.3.6 supports Node-compatible `fs.watch` with `{ recursive: true }` on macOS

Acceptance

  • `bun src/daemon/server.ts` runs in foreground, binds socket, exits cleanly on SIGTERM
  • Second instance attempting to bind same socket exits 0 with a "already running" message
  • Touching a file under any configured agent log dir triggers ingest after debounce window
  • Sending bytes to the socket triggers immediate Claude ingest
  • SIGKILL leaves no stale socket file blocking the next start

Out of scope (other issues in milestone)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions