refactor: rename Ephemeral → Wisp (Steam Engine metaphor)
Wisp = ephemeral vapor produced by the Steam Engine (Gas Town). This aligns with the metaphor: - Claude = Fire - Claude Code = Steam - Gas Town = Steam Engine - Wisps = ephemeral vapor it produces Changes: - types.Issue.Ephemeral → types.Issue.Wisp - types.IssueFilter.Ephemeral → types.IssueFilter.Wisp - JSON field: "ephemeral" → "wisp" - CLI flag: --ephemeral → --wisp (bd cleanup) - All tests updated Note: SQLite column remains "ephemeral" (no migration needed). This is a breaking change for JSON consumers using 0.33.0. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -718,7 +718,7 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
|
||||
var originalType sql.NullString
|
||||
// Messaging fields (bd-kwro)
|
||||
var sender sql.NullString
|
||||
var ephemeral sql.NullInt64
|
||||
var wisp sql.NullInt64
|
||||
// Pinned field (bd-7h5)
|
||||
var pinned sql.NullInt64
|
||||
// Template field (beads-1ra)
|
||||
@@ -730,7 +730,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, &pinned, &isTemplate,
|
||||
&sender, &wisp, &pinned, &isTemplate,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan issue: %w", err)
|
||||
@@ -772,8 +772,8 @@ func (s *SQLiteStorage) scanIssues(ctx context.Context, rows *sql.Rows) ([]*type
|
||||
if sender.Valid {
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
if wisp.Valid && wisp.Int64 != 0 {
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
@@ -821,7 +821,7 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
|
||||
var originalType sql.NullString
|
||||
// Messaging fields (bd-kwro)
|
||||
var sender sql.NullString
|
||||
var ephemeral sql.NullInt64
|
||||
var wisp sql.NullInt64
|
||||
// Pinned field (bd-7h5)
|
||||
var pinned sql.NullInt64
|
||||
// Template field (beads-1ra)
|
||||
@@ -834,7 +834,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, &pinned, &isTemplate,
|
||||
&sender, &wisp, &pinned, &isTemplate,
|
||||
&depType,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -874,8 +874,8 @@ func (s *SQLiteStorage) scanIssuesWithDependencyType(ctx context.Context, rows *
|
||||
if sender.Valid {
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
if wisp.Valid && wisp.Int64 != 0 {
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
|
||||
@@ -295,7 +295,7 @@ func TestRepliesTo(t *testing.T) {
|
||||
IssueType: types.TypeMessage,
|
||||
Sender: "alice",
|
||||
Assignee: "bob",
|
||||
Ephemeral: true,
|
||||
Wisp: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
@@ -307,7 +307,7 @@ func TestRepliesTo(t *testing.T) {
|
||||
IssueType: types.TypeMessage,
|
||||
Sender: "bob",
|
||||
Assignee: "alice",
|
||||
Ephemeral: true,
|
||||
Wisp: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
@@ -363,7 +363,7 @@ func TestRepliesTo_Chain(t *testing.T) {
|
||||
IssueType: types.TypeMessage,
|
||||
Sender: "user",
|
||||
Assignee: "inbox",
|
||||
Ephemeral: true,
|
||||
Wisp: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
@@ -404,76 +404,76 @@ func TestRepliesTo_Chain(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEphemeralField(t *testing.T) {
|
||||
func TestWispField(t *testing.T) {
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
ctx := context.Background()
|
||||
|
||||
// Create ephemeral issue
|
||||
ephemeral := &types.Issue{
|
||||
Title: "Ephemeral Issue",
|
||||
// Create wisp issue
|
||||
wisp := &types.Issue{
|
||||
Title: "Wisp Issue",
|
||||
Status: types.StatusOpen,
|
||||
Priority: 2,
|
||||
IssueType: types.TypeMessage,
|
||||
Ephemeral: true,
|
||||
Wisp: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
|
||||
// Create non-ephemeral issue
|
||||
// Create non-wisp issue
|
||||
permanent := &types.Issue{
|
||||
Title: "Permanent Issue",
|
||||
Status: types.StatusOpen,
|
||||
Priority: 2,
|
||||
IssueType: types.TypeTask,
|
||||
Ephemeral: false,
|
||||
Wisp: false,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
|
||||
if err := store.CreateIssue(ctx, ephemeral, "test"); err != nil {
|
||||
t.Fatalf("Failed to create ephemeral: %v", err)
|
||||
if err := store.CreateIssue(ctx, wisp, "test"); err != nil {
|
||||
t.Fatalf("Failed to create wisp: %v", err)
|
||||
}
|
||||
if err := store.CreateIssue(ctx, permanent, "test"); err != nil {
|
||||
t.Fatalf("Failed to create permanent: %v", err)
|
||||
}
|
||||
|
||||
// Verify ephemeral flag
|
||||
savedEphemeral, err := store.GetIssue(ctx, ephemeral.ID)
|
||||
// Verify wisp flag
|
||||
savedWisp, err := store.GetIssue(ctx, wisp.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetIssue failed: %v", err)
|
||||
}
|
||||
if !savedEphemeral.Ephemeral {
|
||||
t.Error("Ephemeral issue should have Ephemeral=true")
|
||||
if !savedWisp.Wisp {
|
||||
t.Error("Wisp issue should have Wisp=true")
|
||||
}
|
||||
|
||||
savedPermanent, err := store.GetIssue(ctx, permanent.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetIssue failed: %v", err)
|
||||
}
|
||||
if savedPermanent.Ephemeral {
|
||||
t.Error("Permanent issue should have Ephemeral=false")
|
||||
if savedPermanent.Wisp {
|
||||
t.Error("Permanent issue should have Wisp=false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEphemeralFilter(t *testing.T) {
|
||||
func TestWispFilter(t *testing.T) {
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
ctx := context.Background()
|
||||
|
||||
// Create mix of ephemeral and non-ephemeral issues
|
||||
// Create mix of wisp and non-wisp issues
|
||||
for i := 0; i < 3; i++ {
|
||||
ephemeral := &types.Issue{
|
||||
Title: "Ephemeral",
|
||||
wisp := &types.Issue{
|
||||
Title: "Wisp",
|
||||
Status: types.StatusClosed, // Closed for cleanup test
|
||||
Priority: 2,
|
||||
IssueType: types.TypeMessage,
|
||||
Ephemeral: true,
|
||||
Wisp: true,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
if err := store.CreateIssue(ctx, ephemeral, "test"); err != nil {
|
||||
t.Fatalf("Failed to create ephemeral %d: %v", i, err)
|
||||
if err := store.CreateIssue(ctx, wisp, "test"); err != nil {
|
||||
t.Fatalf("Failed to create wisp %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ func TestEphemeralFilter(t *testing.T) {
|
||||
Status: types.StatusClosed,
|
||||
Priority: 2,
|
||||
IssueType: types.TypeTask,
|
||||
Ephemeral: false,
|
||||
Wisp: false,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
@@ -492,35 +492,35 @@ func TestEphemeralFilter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Filter for ephemeral only
|
||||
ephemeralTrue := true
|
||||
// Filter for wisp only
|
||||
wispTrue := true
|
||||
closedStatus := types.StatusClosed
|
||||
ephemeralFilter := types.IssueFilter{
|
||||
Status: &closedStatus,
|
||||
Ephemeral: &ephemeralTrue,
|
||||
wispFilter := types.IssueFilter{
|
||||
Status: &closedStatus,
|
||||
Wisp: &wispTrue,
|
||||
}
|
||||
|
||||
ephemeralIssues, err := store.SearchIssues(ctx, "", ephemeralFilter)
|
||||
wispIssues, err := store.SearchIssues(ctx, "", wispFilter)
|
||||
if err != nil {
|
||||
t.Fatalf("SearchIssues failed: %v", err)
|
||||
}
|
||||
if len(ephemeralIssues) != 3 {
|
||||
t.Errorf("Expected 3 ephemeral issues, got %d", len(ephemeralIssues))
|
||||
if len(wispIssues) != 3 {
|
||||
t.Errorf("Expected 3 wisp issues, got %d", len(wispIssues))
|
||||
}
|
||||
|
||||
// Filter for non-ephemeral only
|
||||
ephemeralFalse := false
|
||||
nonEphemeralFilter := types.IssueFilter{
|
||||
Status: &closedStatus,
|
||||
Ephemeral: &ephemeralFalse,
|
||||
// Filter for non-wisp only
|
||||
wispFalse := false
|
||||
nonWispFilter := types.IssueFilter{
|
||||
Status: &closedStatus,
|
||||
Wisp: &wispFalse,
|
||||
}
|
||||
|
||||
permanentIssues, err := store.SearchIssues(ctx, "", nonEphemeralFilter)
|
||||
permanentIssues, err := store.SearchIssues(ctx, "", nonWispFilter)
|
||||
if err != nil {
|
||||
t.Fatalf("SearchIssues failed: %v", err)
|
||||
}
|
||||
if len(permanentIssues) != 2 {
|
||||
t.Errorf("Expected 2 non-ephemeral issues, got %d", len(permanentIssues))
|
||||
t.Errorf("Expected 2 non-wisp issues, got %d", len(permanentIssues))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ func insertIssue(ctx context.Context, conn *sql.Conn, issue *types.Issue) error
|
||||
sourceRepo = "." // Default to primary repo
|
||||
}
|
||||
|
||||
ephemeral := 0
|
||||
if issue.Ephemeral {
|
||||
ephemeral = 1
|
||||
wisp := 0
|
||||
if issue.Wisp {
|
||||
wisp = 1
|
||||
}
|
||||
pinned := 0
|
||||
if issue.Pinned {
|
||||
@@ -55,7 +55,7 @@ func insertIssue(ctx context.Context, conn *sql.Conn, issue *types.Issue) error
|
||||
issue.EstimatedMinutes, issue.CreatedAt, issue.UpdatedAt,
|
||||
issue.ClosedAt, issue.ExternalRef, sourceRepo, issue.CloseReason,
|
||||
issue.DeletedAt, issue.DeletedBy, issue.DeleteReason, issue.OriginalType,
|
||||
issue.Sender, ephemeral, pinned, isTemplate,
|
||||
issue.Sender, wisp, pinned, isTemplate,
|
||||
)
|
||||
if err != nil {
|
||||
// INSERT OR IGNORE should handle duplicates, but driver may still return error
|
||||
@@ -90,9 +90,9 @@ func insertIssues(ctx context.Context, conn *sql.Conn, issues []*types.Issue) er
|
||||
sourceRepo = "." // Default to primary repo
|
||||
}
|
||||
|
||||
ephemeral := 0
|
||||
if issue.Ephemeral {
|
||||
ephemeral = 1
|
||||
wisp := 0
|
||||
if issue.Wisp {
|
||||
wisp = 1
|
||||
}
|
||||
pinned := 0
|
||||
if issue.Pinned {
|
||||
@@ -110,7 +110,7 @@ func insertIssues(ctx context.Context, conn *sql.Conn, issues []*types.Issue) er
|
||||
issue.EstimatedMinutes, issue.CreatedAt, issue.UpdatedAt,
|
||||
issue.ClosedAt, issue.ExternalRef, sourceRepo, issue.CloseReason,
|
||||
issue.DeletedAt, issue.DeletedBy, issue.DeleteReason, issue.OriginalType,
|
||||
issue.Sender, ephemeral, pinned, isTemplate,
|
||||
issue.Sender, wisp, pinned, isTemplate,
|
||||
)
|
||||
if err != nil {
|
||||
// INSERT OR IGNORE should handle duplicates, but driver may still return error
|
||||
|
||||
@@ -257,9 +257,9 @@ func (s *SQLiteStorage) upsertIssueInTx(ctx context.Context, tx *sql.Tx, issue *
|
||||
var existingID string
|
||||
err := tx.QueryRowContext(ctx, `SELECT id FROM issues WHERE id = ?`, issue.ID).Scan(&existingID)
|
||||
|
||||
ephemeral := 0
|
||||
if issue.Ephemeral {
|
||||
ephemeral = 1
|
||||
wisp := 0
|
||||
if issue.Wisp {
|
||||
wisp = 1
|
||||
}
|
||||
pinned := 0
|
||||
if issue.Pinned {
|
||||
@@ -287,7 +287,7 @@ func (s *SQLiteStorage) upsertIssueInTx(ctx context.Context, tx *sql.Tx, issue *
|
||||
issue.EstimatedMinutes, issue.CreatedAt, issue.UpdatedAt,
|
||||
issue.ClosedAt, issue.ExternalRef, issue.SourceRepo, issue.CloseReason,
|
||||
issue.DeletedAt, issue.DeletedBy, issue.DeleteReason, issue.OriginalType,
|
||||
issue.Sender, ephemeral, pinned, isTemplate,
|
||||
issue.Sender, wisp, pinned, isTemplate,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to insert issue: %w", err)
|
||||
@@ -319,7 +319,7 @@ func (s *SQLiteStorage) upsertIssueInTx(ctx context.Context, tx *sql.Tx, issue *
|
||||
issue.IssueType, issue.Assignee, issue.EstimatedMinutes,
|
||||
issue.UpdatedAt, issue.ClosedAt, issue.ExternalRef, issue.SourceRepo,
|
||||
issue.DeletedAt, issue.DeletedBy, issue.DeleteReason, issue.OriginalType,
|
||||
issue.Sender, ephemeral, pinned, isTemplate,
|
||||
issue.Sender, wisp, pinned, isTemplate,
|
||||
issue.ID,
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -50,11 +50,11 @@ func (s *SQLiteStorage) ExportToMultiRepo(ctx context.Context) (map[string]int,
|
||||
issue.Labels = labels
|
||||
}
|
||||
|
||||
// Filter out ephemeral issues - they should never be exported to JSONL (bd-687g)
|
||||
// Ephemeral issues exist only in SQLite and are shared via .beads/redirect, not JSONL.
|
||||
// Filter out wisps - they should never be exported to JSONL (bd-687g)
|
||||
// Wisps exist only in SQLite and are shared via .beads/redirect, not JSONL.
|
||||
filtered := make([]*types.Issue, 0, len(allIssues))
|
||||
for _, issue := range allIssues {
|
||||
if !issue.Ephemeral {
|
||||
if !issue.Wisp {
|
||||
filtered = append(filtered, issue)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
|
||||
var originalType sql.NullString
|
||||
// Messaging fields (bd-kwro)
|
||||
var sender sql.NullString
|
||||
var ephemeral sql.NullInt64
|
||||
var wisp sql.NullInt64
|
||||
// Pinned field (bd-7h5)
|
||||
var pinned sql.NullInt64
|
||||
// Template field (beads-1ra)
|
||||
@@ -271,7 +271,7 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
|
||||
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef,
|
||||
&issue.CompactionLevel, &compactedAt, &compactedAtCommit, &originalSize, &sourceRepo, &closeReason,
|
||||
&deletedAt, &deletedBy, &deleteReason, &originalType,
|
||||
&sender, &ephemeral, &pinned, &isTemplate,
|
||||
&sender, &wisp, &pinned, &isTemplate,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -326,8 +326,8 @@ func (s *SQLiteStorage) GetIssue(ctx context.Context, id string) (*types.Issue,
|
||||
if sender.Valid {
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
if wisp.Valid && wisp.Int64 != 0 {
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
@@ -442,7 +442,7 @@ func (s *SQLiteStorage) GetIssueByExternalRef(ctx context.Context, externalRef s
|
||||
var originalType sql.NullString
|
||||
// Messaging fields (bd-kwro)
|
||||
var sender sql.NullString
|
||||
var ephemeral sql.NullInt64
|
||||
var wisp sql.NullInt64
|
||||
// Pinned field (bd-7h5)
|
||||
var pinned sql.NullInt64
|
||||
// Template field (beads-1ra)
|
||||
@@ -464,7 +464,7 @@ func (s *SQLiteStorage) GetIssueByExternalRef(ctx context.Context, externalRef s
|
||||
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRefCol,
|
||||
&issue.CompactionLevel, &compactedAt, &compactedAtCommit, &originalSize, &sourceRepo, &closeReason,
|
||||
&deletedAt, &deletedBy, &deleteReason, &originalType,
|
||||
&sender, &ephemeral, &pinned, &isTemplate,
|
||||
&sender, &wisp, &pinned, &isTemplate,
|
||||
)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -519,8 +519,8 @@ func (s *SQLiteStorage) GetIssueByExternalRef(ctx context.Context, externalRef s
|
||||
if sender.Valid {
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
if wisp.Valid && wisp.Int64 != 0 {
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
@@ -556,8 +556,8 @@ var allowedUpdateFields = map[string]bool{
|
||||
"external_ref": true,
|
||||
"closed_at": true,
|
||||
// Messaging fields (bd-kwro)
|
||||
"sender": true,
|
||||
"ephemeral": true,
|
||||
"sender": true,
|
||||
"wisp": true, // Database column is 'ephemeral', mapped in UpdateIssue
|
||||
// Pinned field (bd-7h5)
|
||||
"pinned": true,
|
||||
// NOTE: replies_to, relates_to, duplicate_of, superseded_by removed per Decision 004
|
||||
@@ -665,7 +665,12 @@ func (s *SQLiteStorage) UpdateIssue(ctx context.Context, id string, updates map[
|
||||
return wrapDBError("validate field update", err)
|
||||
}
|
||||
|
||||
setClauses = append(setClauses, fmt.Sprintf("%s = ?", key))
|
||||
// Map API field names to database column names (wisp -> ephemeral)
|
||||
columnName := key
|
||||
if key == "wisp" {
|
||||
columnName = "ephemeral"
|
||||
}
|
||||
setClauses = append(setClauses, fmt.Sprintf("%s = ?", columnName))
|
||||
args = append(args, value)
|
||||
}
|
||||
|
||||
@@ -1591,10 +1596,10 @@ func (s *SQLiteStorage) SearchIssues(ctx context.Context, query string, filter t
|
||||
whereClauses = append(whereClauses, fmt.Sprintf("id IN (%s)", strings.Join(placeholders, ", ")))
|
||||
}
|
||||
|
||||
// Ephemeral filtering (bd-kwro.9)
|
||||
if filter.Ephemeral != nil {
|
||||
if *filter.Ephemeral {
|
||||
whereClauses = append(whereClauses, "ephemeral = 1")
|
||||
// Wisp filtering (bd-kwro.9)
|
||||
if filter.Wisp != nil {
|
||||
if *filter.Wisp {
|
||||
whereClauses = append(whereClauses, "ephemeral = 1") // SQL column is still 'ephemeral'
|
||||
} else {
|
||||
whereClauses = append(whereClauses, "(ephemeral = 0 OR ephemeral IS NULL)")
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ func (s *SQLiteStorage) GetStaleIssues(ctx context.Context, filter types.StaleFi
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
|
||||
@@ -1071,10 +1071,10 @@ func (t *sqliteTxStorage) SearchIssues(ctx context.Context, query string, filter
|
||||
whereClauses = append(whereClauses, fmt.Sprintf("id IN (%s)", strings.Join(placeholders, ", ")))
|
||||
}
|
||||
|
||||
// Ephemeral filtering (bd-kwro.9)
|
||||
if filter.Ephemeral != nil {
|
||||
if *filter.Ephemeral {
|
||||
whereClauses = append(whereClauses, "ephemeral = 1")
|
||||
// Wisp filtering (bd-kwro.9)
|
||||
if filter.Wisp != nil {
|
||||
if *filter.Wisp {
|
||||
whereClauses = append(whereClauses, "ephemeral = 1") // SQL column is still 'ephemeral'
|
||||
} else {
|
||||
whereClauses = append(whereClauses, "(ephemeral = 0 OR ephemeral IS NULL)")
|
||||
}
|
||||
@@ -1149,7 +1149,7 @@ func scanIssueRow(row scanner) (*types.Issue, error) {
|
||||
var originalType sql.NullString
|
||||
// Messaging fields (bd-kwro)
|
||||
var sender sql.NullString
|
||||
var ephemeral sql.NullInt64
|
||||
var wisp sql.NullInt64
|
||||
// Pinned field (bd-7h5)
|
||||
var pinned sql.NullInt64
|
||||
// Template field (beads-1ra)
|
||||
@@ -1162,7 +1162,7 @@ func scanIssueRow(row scanner) (*types.Issue, error) {
|
||||
&issue.CreatedAt, &issue.UpdatedAt, &closedAt, &externalRef,
|
||||
&issue.CompactionLevel, &compactedAt, &compactedAtCommit, &originalSize, &sourceRepo, &closeReason,
|
||||
&deletedAt, &deletedBy, &deleteReason, &originalType,
|
||||
&sender, &ephemeral, &pinned, &isTemplate,
|
||||
&sender, &wisp, &pinned, &isTemplate,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan issue: %w", err)
|
||||
@@ -1213,8 +1213,8 @@ func scanIssueRow(row scanner) (*types.Issue, error) {
|
||||
if sender.Valid {
|
||||
issue.Sender = sender.String
|
||||
}
|
||||
if ephemeral.Valid && ephemeral.Int64 != 0 {
|
||||
issue.Ephemeral = true
|
||||
if wisp.Valid && wisp.Int64 != 0 {
|
||||
issue.Wisp = true
|
||||
}
|
||||
// Pinned field (bd-7h5)
|
||||
if pinned.Valid && pinned.Int64 != 0 {
|
||||
|
||||
Reference in New Issue
Block a user