feat(schema): add messaging fields for bd-kwro epic

- Add TypeMessage issue type for inter-agent communication
- Add 6 new Issue fields: Sender, Ephemeral, RepliesTo, RelatesTo,
  DuplicateOf, SupersededBy
- Add 4 new dependency types: replies-to, relates-to, duplicates, supersedes
- Create migration 019_messaging_fields with indexes
- Update all CRUD operations across storage layer
- Fix reset_test.go to use correct function names
- Fix redundant newline lint error in sync.go

Closes: bd-kwro.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-16 13:06:47 -08:00
parent 8c07a4df44
commit 0aea2d93c6
14 changed files with 381 additions and 74 deletions

View File

@@ -225,6 +225,7 @@ func (s *SQLiteStorage) GetDependenciesWithMetadata(ctx context.Context, issueID
i.status, i.priority, i.issue_type, i.assignee, i.estimated_minutes,
i.created_at, i.updated_at, i.closed_at, i.external_ref, i.source_repo,
i.deleted_at, i.deleted_by, i.delete_reason, i.original_type,
i.sender, i.ephemeral, i.replies_to, i.relates_to, i.duplicate_of, i.superseded_by,
d.type
FROM issues i
JOIN dependencies d ON i.id = d.depends_on_id
@@ -246,6 +247,7 @@ func (s *SQLiteStorage) GetDependentsWithMetadata(ctx context.Context, issueID s
i.status, i.priority, i.issue_type, i.assignee, i.estimated_minutes,
i.created_at, i.updated_at, i.closed_at, i.external_ref, i.source_repo,
i.deleted_at, i.deleted_by, i.delete_reason, i.original_type,
i.sender, i.ephemeral, i.replies_to, i.relates_to, i.duplicate_of, i.superseded_by,
d.type
FROM issues i
JOIN dependencies d ON i.id = d.issue_id
@@ -695,6 +697,13 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
var deletedBy sql.NullString
var deleteReason sql.NullString
var originalType sql.NullString
// Messaging fields (bd-kwro)
var sender sql.NullString
var ephemeral sql.NullInt64
var repliesTo sql.NullString
var relatesTo sql.NullString
var duplicateOf sql.NullString
var supersededBy sql.NullString
err := rows.Scan(
&issue.ID, &contentHash, &issue.Title, &issue.Description, &issue.Design,
@@ -702,6 +711,7 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
&issue.Priority, &issue.IssueType, &assignee, &estimatedMinutes,
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef, &sourceRepo, &closeReason,
&deletedAt, &deletedBy, &deleteReason, &originalType,
&sender, &ephemeral, &repliesTo, &relatesTo, &duplicateOf, &supersededBy,
)
if err != nil {
return nil, fmt.Errorf("failed to scan issue: %w", err)
@@ -739,6 +749,25 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
if originalType.Valid {
issue.OriginalType = originalType.String
}
// Messaging fields (bd-kwro)
if sender.Valid {
issue.Sender = sender.String
}
if ephemeral.Valid && ephemeral.Int64 != 0 {
issue.Ephemeral = true
}
if repliesTo.Valid {
issue.RepliesTo = repliesTo.String
}
if relatesTo.Valid && relatesTo.String != "" {
issue.RelatesTo = parseJSONStringArray(relatesTo.String)
}
if duplicateOf.Valid {
issue.DuplicateOf = duplicateOf.String
}
if supersededBy.Valid {
issue.SupersededBy = supersededBy.String
}
issues = append(issues, &issue)
issueIDs = append(issueIDs, issue.ID)
@@ -775,6 +804,13 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
var deletedBy sql.NullString
var deleteReason sql.NullString
var originalType sql.NullString
// Messaging fields (bd-kwro)
var sender sql.NullString
var ephemeral sql.NullInt64
var repliesTo sql.NullString
var relatesTo sql.NullString
var duplicateOf sql.NullString
var supersededBy sql.NullString
var depType types.DependencyType
err := rows.Scan(
@@ -783,6 +819,7 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
&issue.Priority, &issue.IssueType, &assignee, &estimatedMinutes,
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef, &sourceRepo,
&deletedAt, &deletedBy, &deleteReason, &originalType,
&sender, &ephemeral, &repliesTo, &relatesTo, &duplicateOf, &supersededBy,
&depType,
)
if err != nil {
@@ -818,6 +855,25 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
if originalType.Valid {
issue.OriginalType = originalType.String
}
// Messaging fields (bd-kwro)
if sender.Valid {
issue.Sender = sender.String
}
if ephemeral.Valid && ephemeral.Int64 != 0 {
issue.Ephemeral = true
}
if repliesTo.Valid {
issue.RepliesTo = repliesTo.String
}
if relatesTo.Valid && relatesTo.String != "" {
issue.RelatesTo = parseJSONStringArray(relatesTo.String)
}
if duplicateOf.Valid {
issue.DuplicateOf = duplicateOf.String
}
if supersededBy.Valid {
issue.SupersededBy = supersededBy.String
}
// Fetch labels for this issue
labels, err := s.GetLabels(ctx, issue.ID)