feat: add portfolio

This commit is contained in:
ytshih committed 2026-09-11 09:54:49 +08:00
1 parent ba63c5deb0
commit f09cf4d5c2
11 files changed
+669 -38

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
// Package memory persists Claude's own freeform notes between runs — its
// running thesis on positions, why past calls were made, and anything else
// it wants available as context for future decisions. It is intentionally
// just a flat text file: Claude rewrites it each run (Load hands back the
// previous content, Save overwrites with the new content extracted from the
// response), so summarization and pruning are Claude's job, not Go's.
package memory
import (
"fmt"
"os"
"path/filepath"
"strings"
"gitea.konchin.com/service/stonks/internal/config"
)
const fileName = "memory.md"
// Load reads back the memory file from cfg.Dir. Returns "" with no error if
// it doesn't exist yet (e.g. first-ever run).
func Load(cfg config.PortfolioConfig) (string, error) {
dir, err := resolveDir(cfg.Dir)
if err != nil {
return "", err
}
data, err := os.ReadFile(filepath.Join(dir, fileName))
if err != nil {
if os.IsNotExist(err) {
return "", nil
}
return "", fmt.Errorf("memory: read: %w", err)
}
return string(data), nil
}
// Save overwrites the memory file under cfg.Dir with content. A blank
// content is a no-op — it leaves whatever was there alone, rather than
// wiping out prior notes if Claude's response happened to omit the section.
func Save(cfg config.PortfolioConfig, content string) error {
content = strings.TrimSpace(content)
if content == "" {
return nil
}
dir, err := resolveDir(cfg.Dir)
if err != nil {
return err
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("memory: create %q: %w", dir, err)
}
if err := os.WriteFile(filepath.Join(dir, fileName), []byte(content+"\n"), 0o644); err != nil {
return fmt.Errorf("memory: write: %w", err)
}
return nil
}
func resolveDir(dir string) (string, error) {
if dir == "" {
dir = "~/.local/state/stonks"
}
if dir != "~" && !strings.HasPrefix(dir, "~/") {
return dir, nil
}
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("memory: resolve home directory: %w", err)
}
if dir == "~" {
return home, nil
}
return filepath.Join(home, dir[2:]), nil
}