diff --git a/cmd/bd/git_sync_test.go b/cmd/bd/git_sync_test.go index ac937ba0..9548afcc 100644 --- a/cmd/bd/git_sync_test.go +++ b/cmd/bd/git_sync_test.go @@ -296,13 +296,3 @@ func verifyIssueClosed(t *testing.T, store *sqlite.SQLiteStorage, issueID string t.Errorf("Expected issue %s to be closed, got status %s", issueID, issue.Status) } } - -func verifyIssueOpen(t *testing.T, store *sqlite.SQLiteStorage, issueID string) { - issue, err := store.GetIssue(context.Background(), issueID) - if err != nil { - t.Fatalf("Failed to get issue %s: %v", issueID, err) - } - if issue.Status != types.StatusOpen { - t.Errorf("Expected issue %s to be open, got status %s", issueID, issue.Status) - } -} diff --git a/internal/compact/haiku.go b/internal/compact/haiku.go index 033a01bc..7803a5c1 100644 --- a/internal/compact/haiku.go +++ b/internal/compact/haiku.go @@ -30,7 +30,6 @@ type HaikuClient struct { client anthropic.Client model anthropic.Model tier1Template *template.Template - tier2Template *template.Template maxRetries int initialBackoff time.Duration } @@ -52,16 +51,10 @@ func NewHaikuClient(apiKey string) (*HaikuClient, error) { return nil, fmt.Errorf("failed to parse tier1 template: %w", err) } - tier2Tmpl, err := template.New("tier2").Parse(tier2PromptTemplate) - if err != nil { - return nil, fmt.Errorf("failed to parse tier2 template: %w", err) - } - return &HaikuClient{ client: client, model: defaultModel, tier1Template: tier1Tmpl, - tier2Template: tier2Tmpl, maxRetries: maxRetries, initialBackoff: initialBackoff, }, nil @@ -77,16 +70,6 @@ func (h *HaikuClient) SummarizeTier1(ctx context.Context, issue *types.Issue) (s return h.callWithRetry(ctx, prompt) } -// SummarizeTier2 creates an ultra-compressed single-paragraph summary (≤150 words). -func (h *HaikuClient) SummarizeTier2(ctx context.Context, issue *types.Issue) (string, error) { - prompt, err := h.renderTier2Prompt(issue) - if err != nil { - return "", fmt.Errorf("failed to render prompt: %w", err) - } - - return h.callWithRetry(ctx, prompt) -} - func (h *HaikuClient) callWithRetry(ctx context.Context, prompt string) (string, error) { var lastErr error params := anthropic.MessageNewParams{ @@ -186,26 +169,6 @@ func (h *HaikuClient) renderTier1Prompt(issue *types.Issue) (string, error) { return string(w.buf), nil } -type tier2Data struct { - Title string - CurrentDescription string -} - -func (h *HaikuClient) renderTier2Prompt(issue *types.Issue) (string, error) { - var buf []byte - w := &bytesWriter{buf: buf} - - data := tier2Data{ - Title: issue.Title, - CurrentDescription: issue.Description, - } - - if err := h.tier2Template.Execute(w, data); err != nil { - return "", err - } - return string(w.buf), nil -} - type bytesWriter struct { buf []byte } @@ -243,17 +206,3 @@ Provide a summary in this exact format: **Key Decisions:** [Brief bullet points of only the most important technical choices] **Resolution:** [One sentence on final outcome and lasting impact]` - -const tier2PromptTemplate = `You are performing ultra-compression on a closed software issue. The issue has already been summarized once. Your task is to create a single concise paragraph (≤150 words) that captures the essence. - -**Title:** {{.Title}} - -**Current Summary:** -{{.CurrentDescription}} - -Provide a single paragraph that covers: -- What was built/fixed -- Why it mattered -- Any lasting impact or decisions - -Keep it under 150 words while retaining the most important context.` diff --git a/internal/compact/haiku_test.go b/internal/compact/haiku_test.go index 2bd0e1dc..11de2827 100644 --- a/internal/compact/haiku_test.go +++ b/internal/compact/haiku_test.go @@ -90,38 +90,6 @@ func TestRenderTier1Prompt(t *testing.T) { } } -func TestRenderTier2Prompt(t *testing.T) { - client, err := NewHaikuClient("test-key") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - issue := &types.Issue{ - ID: "bd-1", - Title: "Fix authentication bug", - Description: "**Summary:** Fixed OAuth login flow by adding proper error handling.", - Status: types.StatusClosed, - } - - prompt, err := client.renderTier2Prompt(issue) - if err != nil { - t.Fatalf("failed to render prompt: %v", err) - } - - if !strings.Contains(prompt, "Fix authentication bug") { - t.Error("prompt should contain title") - } - if !strings.Contains(prompt, "Fixed OAuth login flow") { - t.Error("prompt should contain current description") - } - if !strings.Contains(prompt, "150 words") { - t.Error("prompt should contain word limit") - } - if !strings.Contains(prompt, "ultra-compression") { - t.Error("prompt should indicate ultra-compression") - } -} - func TestRenderTier1Prompt_HandlesEmptyFields(t *testing.T) { client, err := NewHaikuClient("test-key") if err != nil { diff --git a/internal/config/config.go b/internal/config/config.go index 563d3664..e0d09209 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -147,14 +147,6 @@ func Set(key string, value interface{}) { // return v.BindPFlag(key, flag) // } -// FileUsed returns the path to the active configuration file. -func FileUsed() string { - if v == nil { - return "" - } - return v.ConfigFileUsed() -} - // AllSettings returns all configuration settings as a map func AllSettings() map[string]interface{} { if v == nil { diff --git a/internal/storage/sqlite/hash.go b/internal/storage/sqlite/hash.go index 41cd58ae..55b1362f 100644 --- a/internal/storage/sqlite/hash.go +++ b/internal/storage/sqlite/hash.go @@ -2,41 +2,10 @@ package sqlite import ( "context" - "crypto/sha256" "database/sql" - "encoding/hex" - "encoding/json" "fmt" - "time" - - "github.com/steveyegge/beads/internal/types" ) -// computeIssueContentHash computes a SHA256 hash of an issue's content, excluding timestamps. -// This is used for detecting timestamp-only changes during export deduplication. -func computeIssueContentHash(issue *types.Issue) (string, error) { - // Clone issue and zero out timestamps to exclude them from hash - normalized := *issue - normalized.CreatedAt = time.Time{} - normalized.UpdatedAt = time.Time{} - - // Also zero out ClosedAt if present - if normalized.ClosedAt != nil { - zeroTime := time.Time{} - normalized.ClosedAt = &zeroTime - } - - // Serialize to JSON - data, err := json.Marshal(normalized) - if err != nil { - return "", err - } - - // SHA256 hash - hash := sha256.Sum256(data) - return hex.EncodeToString(hash[:]), nil -} - // GetExportHash retrieves the content hash of the last export for an issue. // Returns empty string if no hash is stored (first export). func (s *SQLiteStorage) GetExportHash(ctx context.Context, issueID string) (string, error) {