Add EventCompacted to event system (bd-262)

- Add EventCompacted event type constant
- Add compaction fields to Issue struct (CompactionLevel, CompactedAt, OriginalSize)
- Update ApplyCompaction to record compaction events with JSON metadata
- Update bd show to display compaction status with emoji indicators
- Update GetIssue query to load compaction fields
- All tests passing

Amp-Thread-ID: https://ampcode.com/threads/T-3f7946c6-8f5e-4a81-9527-1217041c7b39
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-16 01:00:27 -07:00
parent 5e420e8ee0
commit e99de1b5e3
7 changed files with 74 additions and 7 deletions

View File

@@ -5,6 +5,8 @@ import (
"database/sql"
"fmt"
"time"
"github.com/steveyegge/beads/internal/types"
)
// CompactionCandidate represents an issue eligible for compaction
@@ -278,10 +280,16 @@ func (s *SQLiteStorage) CheckEligibility(ctx context.Context, issueID string, ti
// ApplyCompaction updates the compaction metadata for an issue after successfully compacting it.
// This sets compaction_level, compacted_at, and original_size fields.
func (s *SQLiteStorage) ApplyCompaction(ctx context.Context, issueID string, level int, originalSize int) error {
func (s *SQLiteStorage) ApplyCompaction(ctx context.Context, issueID string, level int, originalSize int, compressedSize int) error {
now := time.Now().UTC()
_, err := s.db.ExecContext(ctx, `
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("failed to begin transaction: %w", err)
}
defer tx.Rollback()
_, err = tx.ExecContext(ctx, `
UPDATE issues
SET compaction_level = ?,
compacted_at = ?,
@@ -294,5 +302,26 @@ func (s *SQLiteStorage) ApplyCompaction(ctx context.Context, issueID string, lev
return fmt.Errorf("failed to apply compaction metadata: %w", err)
}
reductionPct := 0.0
if originalSize > 0 {
reductionPct = (1.0 - float64(compressedSize)/float64(originalSize)) * 100
}
eventData := fmt.Sprintf(`{"tier":%d,"original_size":%d,"compressed_size":%d,"reduction_pct":%.1f}`,
level, originalSize, compressedSize, reductionPct)
_, err = tx.ExecContext(ctx, `
INSERT INTO events (issue_id, event_type, actor, comment)
VALUES (?, ?, 'compactor', ?)
`, issueID, types.EventCompacted, eventData)
if err != nil {
return fmt.Errorf("failed to record compaction event: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("failed to commit transaction: %w", err)
}
return nil
}

View File

@@ -333,7 +333,7 @@ func TestApplyCompaction(t *testing.T) {
}
originalSize := len(issue.Description)
err := store.ApplyCompaction(ctx, issue.ID, 1, originalSize)
err := store.ApplyCompaction(ctx, issue.ID, 1, originalSize, 500)
if err != nil {
t.Fatalf("ApplyCompaction failed: %v", err)
}

View File

@@ -843,11 +843,14 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
var estimatedMinutes sql.NullInt64
var assignee sql.NullString
var externalRef sql.NullString
var compactedAt sql.NullTime
var originalSize sql.NullInt64
err := s.db.QueryRowContext(ctx, `
SELECT id, title, description, design, acceptance_criteria, notes,
status, priority, issue_type, assignee, estimated_minutes,
created_at, updated_at, closed_at, external_ref
created_at, updated_at, closed_at, external_ref,
compaction_level, compacted_at, original_size
FROM issues
WHERE id = ?
`, id).Scan(
@@ -855,6 +858,7 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
&issue.AcceptanceCriteria, &issue.Notes, &issue.Status,
&issue.Priority, &issue.IssueType, &assignee, &estimatedMinutes,
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef,
&issue.CompactionLevel, &compactedAt, &originalSize,
)
if err == sql.ErrNoRows {
@@ -877,6 +881,12 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
if externalRef.Valid {
issue.ExternalRef = &externalRef.String
}
if compactedAt.Valid {
issue.CompactedAt = &compactedAt.Time
}
if originalSize.Valid {
issue.OriginalSize = int(originalSize.Int64)
}
return &issue, nil
}