aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-06-19 09:11:18 +0100
committerdiogo464 <[email protected]>2025-06-19 09:11:18 +0100
commit0f9ae08bae9a9b417a741ebc8161cdeb6dbb39ca (patch)
tree32c6f8e72ae8a4c746687158accfe2aef386ee86
parent413b3214f2a1a5714fe872220c46ff210178ab76 (diff)
Add llm command for comprehensive usage documentation
- Add 'demon llm' command that outputs detailed usage guide - Comprehensive documentation targeted at LLM consumption - Covers all commands with syntax, behavior, and examples - Includes common workflows, best practices, and integration tips - Explains file management, error handling, and scripting patterns - Add test to verify LLM command output contains key sections This provides a complete reference that other LLMs can use to understand how to effectively use the demon CLI tool. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
-rw-r--r--src/main.rs238
-rw-r--r--tests/cli.rs20
2 files changed, 258 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 8e2efc0..09000ff 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -42,6 +42,9 @@ enum Commands {
42 42
43 /// Clean up orphaned pid and log files 43 /// Clean up orphaned pid and log files
44 Clean, 44 Clean,
45
46 /// Output comprehensive usage guide for LLMs
47 Llm,
45} 48}
46 49
47#[derive(Args)] 50#[derive(Args)]
@@ -152,6 +155,10 @@ fn run_command(command: Commands) -> Result<()> {
152 Commands::Clean => { 155 Commands::Clean => {
153 clean_orphaned_files() 156 clean_orphaned_files()
154 } 157 }
158 Commands::Llm => {
159 print_llm_guide();
160 Ok(())
161 }
155 } 162 }
156} 163}
157 164
@@ -725,3 +732,234 @@ fn clean_orphaned_files() -> Result<()> {
725 732
726 Ok(()) 733 Ok(())
727} 734}
735
736fn print_llm_guide() {
737 println!(r#"# Demon - Daemon Process Management CLI
738
739## Overview
740Demon is a command-line tool for spawning, managing, and monitoring background processes (daemons) on Linux systems. It redirects process stdout/stderr to files and provides commands to control and observe these processes.
741
742## Core Concept
743- Each daemon is identified by a unique string ID
744- Three files are created per daemon: `<id>.pid`, `<id>.stdout`, `<id>.stderr`
745- Files are created in the current working directory
746- Processes run detached from the parent shell
747
748## Available Commands
749
750### demon run --id <identifier> <command...>
751Spawns a background process with the given identifier.
752
753**Syntax**: `demon run --id <id> [--] <command> [args...]`
754
755**Behavior**:
756- Creates `<id>.pid`, `<id>.stdout`, `<id>.stderr` files
757- Truncates log files if they already exist
758- Fails if a process with the same ID is already running
759- Parent process exits immediately, child continues in background
760- Use `--` to separate flags from command when command has flags
761
762**Examples**:
763```bash
764demon run --id web-server python -m http.server 8080
765demon run --id backup-job -- rsync -av /data/ /backup/
766demon run --id log-monitor tail -f /var/log/app.log
767```
768
769### demon stop --id <id> [--timeout <seconds>]
770Stops a running daemon process gracefully.
771
772**Syntax**: `demon stop --id <id> [--timeout <seconds>]`
773
774**Behavior**:
775- Sends SIGTERM to the process first
776- Waits for specified timeout (default: 10 seconds)
777- Sends SIGKILL if process doesn't terminate
778- Removes PID file after successful termination
779- Handles already-dead processes gracefully
780
781**Examples**:
782```bash
783demon stop --id web-server
784demon stop --id backup-job --timeout 30
785```
786
787### demon list [--quiet]
788Lists all managed daemon processes and their status.
789
790**Syntax**: `demon list [-q|--quiet]`
791
792**Normal Output Format**:
793```
794ID PID STATUS COMMAND
795--------------------------------------------------
796web-server 12345 RUNNING N/A
797backup-job 12346 DEAD N/A
798```
799
800**Quiet Output Format** (machine-readable):
801```
802web-server:12345:RUNNING
803backup-job:12346:DEAD
804```
805
806**Status Values**:
807- `RUNNING`: Process is actively running
808- `DEAD`: Process has terminated, files still exist
809
810### demon status --id <id>
811Shows detailed status information for a specific daemon.
812
813**Syntax**: `demon status --id <id>`
814
815**Output includes**:
816- Daemon ID and PID file location
817- Process ID (if available)
818- Current status (RUNNING/DEAD/NOT FOUND/ERROR)
819- Log file locations and sizes
820- Suggestions for cleanup if needed
821
822**Example**:
823```bash
824demon status --id web-server
825```
826
827### demon cat --id <id> [--stdout] [--stderr]
828Displays the contents of daemon log files.
829
830**Syntax**: `demon cat --id <id> [--stdout] [--stderr]`
831
832**Behavior**:
833- Shows both stdout and stderr by default
834- Use flags to show only specific streams
835- Displays file headers when showing multiple files
836- Handles missing files gracefully
837
838**Examples**:
839```bash
840demon cat --id web-server # Show both logs
841demon cat --id web-server --stdout # Show only stdout
842demon cat --id web-server --stderr # Show only stderr
843```
844
845### demon tail --id <id> [--stdout] [--stderr]
846Follows daemon log files in real-time (like `tail -f`).
847
848**Syntax**: `demon tail --id <id> [--stdout] [--stderr]`
849
850**Behavior**:
851- Shows existing content first, then follows new content
852- Shows both stdout and stderr by default
853- Uses file system notifications for efficient monitoring
854- Press Ctrl+C to stop tailing
855- Handles file creation, rotation, and truncation
856
857**Examples**:
858```bash
859demon tail --id web-server # Follow both logs
860demon tail --id web-server --stdout # Follow only stdout
861```
862
863### demon clean
864Removes orphaned files from processes that are no longer running.
865
866**Syntax**: `demon clean`
867
868**Behavior**:
869- Scans for `.pid` files in current directory
870- Checks if corresponding processes are still running
871- Removes `.pid`, `.stdout`, `.stderr` files for dead processes
872- Handles invalid PID files gracefully
873- Reports what was cleaned up
874
875**Example**:
876```bash
877demon clean
878```
879
880## File Management
881
882### Created Files
883For each daemon with ID "example":
884- `example.pid`: Contains the process ID
885- `example.stdout`: Contains standard output from the process
886- `example.stderr`: Contains standard error from the process
887
888### File Locations
889All files are created in the current working directory where `demon run` is executed.
890
891### Cleanup
892- Files persist after process termination for inspection
893- Use `demon clean` to remove files from dead processes
894- Consider adding `*.pid`, `*.stdout`, `*.stderr` to `.gitignore`
895
896## Common Workflows
897
898### Starting a Web Server
899```bash
900demon run --id my-web-server python -m http.server 8080
901demon status --id my-web-server # Check if it started
902demon tail --id my-web-server # Monitor logs
903```
904
905### Running a Backup Job
906```bash
907demon run --id nightly-backup -- rsync -av /data/ /backup/
908demon cat --id nightly-backup # Check output when done
909demon clean # Clean up after completion
910```
911
912### Managing Multiple Services
913```bash
914demon run --id api-server ./api --port 3000
915demon run --id worker-queue ./worker --config prod.conf
916demon list # See all running services
917demon stop --id api-server # Stop specific service
918```
919
920### Monitoring and Debugging
921```bash
922demon list --quiet | grep RUNNING # Machine-readable active processes
923demon tail --id problematic-app --stderr # Monitor just errors
924demon status --id failing-service # Get detailed status
925```
926
927## Error Handling
928
929### Common Error Scenarios
930- **"Process already running"**: Another process with the same ID exists
931- **"Command cannot be empty"**: No command specified after `--id`
932- **"Process not found"**: No PID file exists for the given ID
933- **"Failed to start process"**: Command not found or permission denied
934
935### Best Practices
9361. Use descriptive, unique IDs for each daemon
9372. Check status before starting to avoid conflicts
9383. Use `demon clean` periodically to remove old files
9394. Monitor logs with `demon tail` for debugging
9405. Use `--timeout` with stop for processes that may take time to shutdown
941
942## Integration Tips
943
944### Scripting
945```bash
946# Check if service is running
947if demon status --id my-service | grep -q "RUNNING"; then
948 echo "Service is running"
949fi
950
951# Start service if not running
952demon list --quiet | grep -q "my-service:" || demon run --id my-service ./my-app
953
954# Get machine-readable process list
955demon list --quiet > process_status.txt
956```
957
958### Process Management
959- Demon handles process detachment automatically
960- Processes continue running even if demon exits
961- Use standard Unix signals for process control
962- Log rotation should be handled by the application itself
963
964This tool is designed for Linux environments and provides a simple interface for managing background processes with persistent logging."#);
965}
diff --git a/tests/cli.rs b/tests/cli.rs
index 05e3efd..37398e6 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -376,4 +376,24 @@ fn test_list_quiet_mode() {
376 .stdout(predicate::str::contains("ID").not()) 376 .stdout(predicate::str::contains("ID").not())
377 .stdout(predicate::str::contains("PID").not()) 377 .stdout(predicate::str::contains("PID").not())
378 .stdout(predicate::str::contains("STATUS").not()); 378 .stdout(predicate::str::contains("STATUS").not());
379}
380
381#[test]
382fn test_llm_command() {
383 let mut cmd = Command::cargo_bin("demon").unwrap();
384 cmd.args(&["llm"])
385 .assert()
386 .success()
387 .stdout(predicate::str::contains("# Demon - Daemon Process Management CLI"))
388 .stdout(predicate::str::contains("## Available Commands"))
389 .stdout(predicate::str::contains("demon run"))
390 .stdout(predicate::str::contains("demon stop"))
391 .stdout(predicate::str::contains("demon list"))
392 .stdout(predicate::str::contains("demon tail"))
393 .stdout(predicate::str::contains("demon cat"))
394 .stdout(predicate::str::contains("demon status"))
395 .stdout(predicate::str::contains("demon clean"))
396 .stdout(predicate::str::contains("Common Workflows"))
397 .stdout(predicate::str::contains("Best Practices"))
398 .stdout(predicate::str::contains("Integration Tips"));
379} \ No newline at end of file 399} \ No newline at end of file