| | @@ -188,15 +188,21 @@ |
| 188 | 188 | _ = relay.Close(closeCtx) |
| 189 | 189 | }() |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | 192 | startedAt := time.Now() |
| 193 | | - args := make([]string, 0, len(cfg.Args)+2) |
| 194 | | - args = append(args, "--session-id", cfg.ClaudeSessionID) |
| 195 | | - args = append(args, cfg.Args...) |
| 196 | | - fmt.Fprintf(os.Stderr, "claude-relay: session-id %s\n", cfg.ClaudeSessionID) |
| 197 | | - cmd := exec.Command(cfg.ClaudeBin, args...) |
| 193 | + // If resuming, extract the session ID from --resume arg. Otherwise use |
| 194 | + // our generated UUID via --session-id for new sessions. |
| 195 | + if resumeID := extractResumeID(cfg.Args); resumeID != "" { |
| 196 | + cfg.ClaudeSessionID = resumeID |
| 197 | + fmt.Fprintf(os.Stderr, "claude-relay: resuming session %s\n", resumeID) |
| 198 | + } else { |
| 199 | + // New session — inject --session-id so the file name is deterministic. |
| 200 | + cfg.Args = append([]string{"--session-id", cfg.ClaudeSessionID}, cfg.Args...) |
| 201 | + fmt.Fprintf(os.Stderr, "claude-relay: new session %s\n", cfg.ClaudeSessionID) |
| 202 | + } |
| 203 | + cmd := exec.Command(cfg.ClaudeBin, cfg.Args...) |
| 198 | 204 | cmd.Env = append(os.Environ(), |
| 199 | 205 | "SCUTTLEBOT_CONFIG_FILE="+cfg.ConfigFile, |
| 200 | 206 | "SCUTTLEBOT_URL="+cfg.URL, |
| 201 | 207 | "SCUTTLEBOT_TOKEN="+cfg.Token, |
| 202 | 208 | "SCUTTLEBOT_CHANNEL="+cfg.Channel, |
| | @@ -339,10 +345,25 @@ |
| 339 | 345 | return "", fmt.Errorf("session file %s not found after %v", target, defaultDiscoverWait) |
| 340 | 346 | case <-ticker.C: |
| 341 | 347 | } |
| 342 | 348 | } |
| 343 | 349 | } |
| 350 | + |
| 351 | +// extractResumeID finds --resume or -r in args and returns the session UUID |
| 352 | +// that follows it. Returns "" if not resuming or if the value isn't a UUID. |
| 353 | +func extractResumeID(args []string) string { |
| 354 | + for i := 0; i < len(args)-1; i++ { |
| 355 | + if args[i] == "--resume" || args[i] == "-r" || args[i] == "--continue" { |
| 356 | + val := args[i+1] |
| 357 | + // Must look like a UUID (contains dashes, right length) |
| 358 | + if len(val) >= 32 && strings.Contains(val, "-") { |
| 359 | + return val |
| 360 | + } |
| 361 | + } |
| 362 | + } |
| 363 | + return "" |
| 364 | +} |
| 344 | 365 | |
| 345 | 366 | // claudeSessionsRoot returns ~/.claude/projects/<sanitized-cwd>/ |
| 346 | 367 | func claudeSessionsRoot(cwd string) (string, error) { |
| 347 | 368 | home, err := os.UserHomeDir() |
| 348 | 369 | if err != nil { |
| 349 | 370 | |