package summarize import ( "bytes" "context" "fmt" "os/exec" "strings" ) // ClaudeCLI shells out to the `claude` CLI in print mode. The transcript is // sent on stdin so we don't bump into ARG_MAX for very long services. type ClaudeCLI struct { // Bin is the binary name; defaults to "claude". Bin string // Model passes through to `claude --model`. Empty leaves the CLI default. Model string // ExtraArgs are appended verbatim before the prompt arg. ExtraArgs []string } func (c *ClaudeCLI) Name() string { return "claude-cli" } func (c *ClaudeCLI) Summarize(ctx context.Context, systemPrompt, userContent string) (string, error) { bin := c.Bin if bin == "" { bin = "claude" } if _, err := exec.LookPath(bin); err != nil { return "", fmt.Errorf("%q not on PATH: %w", bin, err) } args := []string{"-p"} if c.Model != "" { args = append(args, "--model", c.Model) } args = append(args, c.ExtraArgs...) args = append(args, systemPrompt) cmd := exec.CommandContext(ctx, bin, args...) cmd.Stdin = strings.NewReader(userContent) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return "", fmt.Errorf("%s: %w (stderr: %s)", bin, err, strings.TrimSpace(stderr.String())) } return strings.TrimSpace(stdout.String()), nil }