feat: done vibing

This commit is contained in:
ytshih committed 2026-09-05 09:55:24 +08:00
1 parent 3de31a57c3
commit 4352fd1ad1
27 files changed
+1922 -13

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
package analyze
import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
"github.com/ytshih/stonks/internal/config"
)
func init() {
Register("subscription", newSubscriptionAnalyzer)
}
// subscriptionAnalyzer shells out to the `claude` CLI in headless/print mode
// (`claude -p`), using whatever session `claude login` established on this
// host. Usage is billed against that Claude Pro/Max subscription's
// rate limits rather than a separate per-token API bill.
//
// The CLI has no separate "system prompt" flag documented for scripting, so
// the system and user prompts are concatenated and piped in over stdin —
// the most robust interface regardless of CLI version.
type subscriptionAnalyzer struct{}
func newSubscriptionAnalyzer(cfg config.AnalyzerConfig) (Analyzer, error) {
if _, err := exec.LookPath("claude"); err != nil {
return nil, fmt.Errorf("analyze (subscription mode): `claude` CLI not found on PATH — install Claude Code and run `claude login`: %w", err)
}
return &subscriptionAnalyzer{}, nil
}
func (a *subscriptionAnalyzer) Analyze(ctx context.Context, prompt string) (string, error) {
fullPrompt := SystemPrompt + "\n\n---\n\n" + prompt
cmd := exec.CommandContext(ctx, "claude", "-p")
cmd.Stdin = strings.NewReader(fullPrompt)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("analyze (subscription mode): claude CLI failed: %w (stderr: %s)", err, strings.TrimSpace(stderr.String()))
}
out := strings.TrimSpace(stdout.String())
if out == "" {
return "", fmt.Errorf("analyze (subscription mode): claude CLI produced no output (stderr: %s)", strings.TrimSpace(stderr.String()))
}
return out, nil
}