Skip to content

Commit f81c027

Browse files
intel352claude
andcommitted
feat: add --debug flag to daemon start for request/response logging
Adds a --debug flag to `ratchet daemon start` that enables logging of outgoing message arrays and response content to ~/.ratchet/debug.log. Threads the Debug bool through EngineContext so handleChat can gate on it without global state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 279f81f commit f81c027

5 files changed

Lines changed: 46 additions & 7 deletions

File tree

cmd/ratchet/cmd_daemon.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,23 @@ func handleDaemon(args []string) {
1616
switch args[0] {
1717
case "start":
1818
bg := false
19+
debug := false
1920
for _, a := range args[1:] {
2021
if a == "--background" || a == "-b" {
2122
bg = true
2223
}
24+
if a == "--debug" {
25+
debug = true
26+
}
2327
}
2428
if bg {
25-
if err := daemon.StartBackground(); err != nil {
29+
if err := daemon.StartBackground(debug); err != nil {
2630
fmt.Fprintf(os.Stderr, "error: %v\n", err)
2731
os.Exit(1)
2832
}
2933
fmt.Println("daemon started in background")
3034
} else {
31-
if err := daemon.Start(context.Background()); err != nil {
35+
if err := daemon.Start(context.Background(), debug); err != nil {
3236
fmt.Fprintf(os.Stderr, "error: %v\n", err)
3337
os.Exit(1)
3438
}
@@ -42,7 +46,7 @@ func handleDaemon(args []string) {
4246
case "restart":
4347
// Stop the old daemon (ignore errors — it may not be running).
4448
_ = daemon.Stop()
45-
if err := daemon.StartBackground(); err != nil {
49+
if err := daemon.StartBackground(false); err != nil {
4650
fmt.Fprintf(os.Stderr, "error: %v\n", err)
4751
os.Exit(1)
4852
}

internal/client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Connect() (*Client, error) {
4141
// EnsureDaemon starts the daemon if not running, then connects.
4242
func EnsureDaemon() (*Client, error) {
4343
if !daemon.IsRunning() {
44-
if err := daemon.StartBackground(); err != nil {
44+
if err := daemon.StartBackground(false); err != nil {
4545
return nil, fmt.Errorf("start daemon: %w", err)
4646
}
4747
}

internal/daemon/chat.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"fmt"
77
"log"
8+
"os"
9+
"path/filepath"
810
"slices"
911
"strings"
1012
"sync"
@@ -76,6 +78,22 @@ const compactSentinel = "\x00compact\x00"
7678
// The diff content follows immediately after the sentinel.
7779
const reviewSentinel = "\x00review\x00"
7880

81+
// debugLog appends a log entry to ~/.ratchet/debug.log when debug mode is active.
82+
func debugLog(format string, args ...any) {
83+
home, err := os.UserHomeDir()
84+
if err != nil {
85+
return
86+
}
87+
logPath := filepath.Join(home, ".ratchet", "debug.log")
88+
f, err := os.OpenFile(logPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
89+
if err != nil {
90+
return
91+
}
92+
defer f.Close()
93+
logger := log.New(f, "", log.LstdFlags)
94+
logger.Printf(format, args...)
95+
}
96+
7997
// broadcastStream wraps a send-message stream and fans out each event to the broadcaster.
8098
type broadcastStream struct {
8199
pb.RatchetDaemon_SendMessageServer
@@ -152,6 +170,12 @@ func (s *Service) handleChat(ctx context.Context, sessionID, userMessage string,
152170
Content: userMessage,
153171
})
154172

173+
// Debug: log outgoing messages.
174+
if s.engine.Debug {
175+
msgJSON, _ := json.Marshal(messages)
176+
debugLog("[chat] session=%s sending %d messages: %s", sessionID, len(messages), string(msgJSON))
177+
}
178+
155179
// Stream from provider (save user message AFTER successful stream start,
156180
// so failed requests don't pollute conversation history).
157181
eventCh, err := prov.Stream(ctx, messages, nil) // tools will be added in later task
@@ -271,6 +295,11 @@ func (s *Service) handleChat(ctx context.Context, sessionID, userMessage string,
271295
}
272296
}
273297

298+
// Debug: log response content.
299+
if s.engine.Debug {
300+
debugLog("[chat] session=%s response (%d chars): %s", sessionID, len(fullResponse), fullResponse)
301+
}
302+
274303
// Save assistant response
275304
if err := s.saveMessage(ctx, sessionID, "assistant", fullResponse, "", ""); err != nil {
276305
log.Printf("save assistant message: %v", err)

internal/daemon/daemon.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var reloadSignal = syscall.SIGUSR1
2222

2323
// Start runs the daemon in the foreground. It creates the Unix socket,
2424
// starts the gRPC server, and blocks until signal.
25-
func Start(ctx context.Context) error {
25+
func Start(ctx context.Context, debug bool) error {
2626
if err := EnsureDataDir(); err != nil {
2727
return err
2828
}
@@ -55,6 +55,7 @@ func Start(ctx context.Context) error {
5555
if err != nil {
5656
return fmt.Errorf("create service: %w", err)
5757
}
58+
svc.engine.Debug = debug
5859
pb.RegisterRatchetDaemonServer(srv, svc)
5960

6061
// Graceful shutdown on SIGINT/SIGTERM.
@@ -94,7 +95,7 @@ func Start(ctx context.Context) error {
9495
}
9596

9697
// StartBackground forks the current process as a background daemon.
97-
func StartBackground() error {
98+
func StartBackground(debug bool) error {
9899
if IsRunning() {
99100
return nil // already running
100101
}
@@ -104,7 +105,11 @@ func StartBackground() error {
104105
return fmt.Errorf("get executable: %w", err)
105106
}
106107

107-
cmd := exec.Command(exe, "daemon", "start")
108+
args := []string{"daemon", "start"}
109+
if debug {
110+
args = append(args, "--debug")
111+
}
112+
cmd := exec.Command(exe, args...)
108113
cmd.Stdout = nil
109114
cmd.Stderr = nil
110115
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}

internal/daemon/engine.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type EngineContext struct {
3232
ModelRouting config.ModelRouting
3333
Actors *ActorManager
3434
Hooks *hooks.HookConfig
35+
Debug bool // enable request/response debug logging to ~/.ratchet/debug.log
3536
// Plugin-contributed capabilities
3637
PluginSkills []skills.Skill
3738
PluginAgents []agent.AgentDefinition

0 commit comments

Comments
 (0)