Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

`daemon-cli` is a Rust library for building streaming daemon-client applications with automatic lifecycle management. It enables CLI tools to communicate with long-running background processes via stdin/stdout streaming over Unix domain sockets.
`daemon-cli` is a Rust library for building streaming daemon-client applications with automatic lifecycle management. It enables CLI tools to communicate with long-running background processes via stdin/stdout streaming (Unix domain sockets on Unix, named pipes on Windows).

## Essential Commands

Expand Down Expand Up @@ -91,16 +91,22 @@ Note: Multiple clients can execute commands concurrently. Each connection gets i
The `CommandHandler` trait is the primary extension point:
```rust
#[async_trait]
pub trait CommandHandler: Send + Sync {
pub trait CommandHandler<P = ()>: Send + Sync
where
P: PayloadCollector,
{
async fn handle(
&self,
command: &str, // Command string from stdin
output: impl AsyncWrite, // Stream output here incrementally
command: &str, // Command string from stdin
ctx: CommandContext<P>, // Terminal info + custom payload
output: impl AsyncWrite, // Stream output here incrementally
cancel_token: CancellationToken, // Check for cancellation
) -> Result<()>;
) -> Result<i32>; // Return exit code (0 = success)
}
```

The generic `P` parameter allows passing custom data from client to daemon via `PayloadCollector::collect()`.

**Concurrency Considerations:**
- Handlers must implement `Clone + Send + Sync` for concurrent execution
- Each client connection receives a cloned handler instance
Expand All @@ -126,7 +132,7 @@ use daemon_cli::prelude::*;

let handler = MyHandler::new();
// Automatically detects daemon name and binary mtime
let (server, _handle) = DaemonServer::new("/path/to/project", handler);
let (server, _handle) = DaemonServer::new("/path/to/project", handler, StartupReason::default());
// Default: max 100 concurrent connections
```

Expand All @@ -139,6 +145,7 @@ let handler = MyHandler::new();
let (server, _handle) = DaemonServer::new_with_limit(
"/path/to/project",
handler,
StartupReason::default(),
10 // Max 10 concurrent clients
);
```
Expand All @@ -147,8 +154,8 @@ When the limit is reached, new connections wait for an available slot. This is i

## Platform Requirements

- Unix-like systems only (Linux, macOS)
- Uses Unix domain sockets (not portable to Windows)
- Cross-platform: Linux, macOS, Windows
- Uses Unix domain sockets on Unix, named pipes on Windows
- Edition: Rust 2024

# Other memory
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ Cargo.lock

/*.md
!/README.md
!/PRD.md
!/CHANGELOG.md
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.9.0] - 2025-12-29

### Changed (BREAKING)

- Removed `EnvVarFilter` - use `PayloadCollector` trait instead for passing env vars
- `CommandContext<P>` is now generic with custom payload support via `PayloadCollector`
- Removed `DaemonClient::with_env_filter()` method

### Migration

```rust
// Before (0.8.0):
let client = DaemonClient::connect(path)
.await?
.with_env_filter(EnvVarFilter::with_names(["MY_VAR"]));

// After (0.9.0):
#[derive(Serialize, Deserialize, Clone, Default)]
struct MyPayload { my_var: Option<String> }

#[async_trait]
impl PayloadCollector for MyPayload {
async fn collect() -> Self {
Self { my_var: std::env::var("MY_VAR").ok() }
}
}

let client = DaemonClient::<MyPayload>::connect(path).await?;
```

## [0.8.0] - 2025-12-09

### Changed (BREAKING)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "daemon-cli"
version = "0.8.0"
version = "0.9.0"
edition = "2024"

[dependencies]
Expand Down
174 changes: 0 additions & 174 deletions PRD.md

This file was deleted.

Loading