fix: use ghcrawl cluster names

This commit is contained in:
Vincent Koc 2026-04-27 15:39:22 -07:00
parent f42b6166d5
commit da68251083
No known key found for this signature in database
2 changed files with 64 additions and 4 deletions

View File

@ -181,7 +181,7 @@ func (s *Store) ListRunClusterSummaries(ctx context.Context, options ClusterSumm
return nil, fmt.Errorf("scan run cluster summary: %w", err)
}
summary.Source = ClusterSourceRun
summary.StableSlug = fmt.Sprintf("cluster-%d", summary.ID)
summary.StableSlug = clusterHumanName(options.RepoID, repThreadID.Int64, summary.ID)
summary.Status = "active"
if closeReason.Valid || closedMemberCount >= summary.MemberCount {
summary.Status = "closed"
@ -1097,9 +1097,12 @@ func (s *Store) clusterSummaryByID(ctx context.Context, repoID, clusterID int64,
select cg.id, cg.stable_slug, cg.status, cg.title, cg.representative_thread_id,
rt.number, rt.kind, rt.title,
count(cm.thread_id) as member_count,
cg.updated_at, cg.closed_at
cg.updated_at, coalesce(cc.updated_at, cg.closed_at) as closed_at,
sum(case when t.closed_at_local is not null or t.state <> 'open' then 1 else 0 end) as closed_member_count
from cluster_groups cg
left join cluster_closures cc on cc.cluster_id = cg.id
left join cluster_memberships cm on cm.cluster_id = cg.id and cm.state = 'active'
left join threads t on t.id = cm.thread_id
left join threads rt on rt.id = cg.representative_thread_id
where `+where+`
group by cg.id
@ -1108,13 +1111,17 @@ func (s *Store) clusterSummaryByID(ctx context.Context, repoID, clusterID int64,
var title, closedAt, repKind, repTitle sql.NullString
var repThreadID sql.NullInt64
var repNumber sql.NullInt64
if err := row.Scan(&summary.ID, &summary.StableSlug, &summary.Status, &title, &repThreadID, &repNumber, &repKind, &repTitle, &summary.MemberCount, &summary.UpdatedAt, &closedAt); err != nil {
var closedMemberCount int
if err := row.Scan(&summary.ID, &summary.StableSlug, &summary.Status, &title, &repThreadID, &repNumber, &repKind, &repTitle, &summary.MemberCount, &summary.UpdatedAt, &closedAt, &closedMemberCount); err != nil {
if err == sql.ErrNoRows {
return ClusterSummary{}, fmt.Errorf("cluster %d was not found", clusterID)
}
return ClusterSummary{}, fmt.Errorf("scan cluster summary: %w", err)
}
summary.Source = ClusterSourceDurable
if summary.Status == "active" && summary.MemberCount > 0 && closedMemberCount >= summary.MemberCount {
summary.Status = "closed"
}
summary.Title = title.String
summary.ClosedAt = closedAt.String
summary.RepresentativeThreadID = repThreadID.Int64
@ -1187,7 +1194,7 @@ func (s *Store) runClusterSummaryByID(ctx context.Context, repoID, clusterID int
return ClusterSummary{}, 0, fmt.Errorf("scan run cluster summary: %w", err)
}
summary.Source = ClusterSourceRun
summary.StableSlug = fmt.Sprintf("cluster-%d", summary.ID)
summary.StableSlug = clusterHumanName(repoID, repThreadID.Int64, summary.ID)
summary.Status = "active"
if closeReason.Valid || closedMemberCount >= summary.MemberCount {
summary.Status = "closed"

View File

@ -0,0 +1,53 @@
package store
import (
"crypto/sha256"
"fmt"
)
var humanKeyWords = []string{
"able", "acid", "acre", "actor", "acute", "admin", "aisle", "album",
"alert", "alias", "amber", "angle", "apple", "apron", "array", "asset",
"atlas", "audio", "badge", "basic", "batch", "beach", "beacon", "bench",
"binary", "block", "bonus", "border", "branch", "bridge", "brief", "buffer",
"build", "bundle", "cable", "cache", "canal", "canvas", "carbon", "cargo",
"cedar", "center", "chance", "change", "charge", "chart", "cipher", "circle",
"civic", "clear", "client", "cloud", "cobalt", "column", "comet", "common",
"copper", "corner", "course", "credit", "crisp", "cycle", "daily", "data",
"delta", "detail", "device", "domain", "draft", "drift", "driver", "early",
"earth", "echo", "edge", "ember", "engine", "entry", "error", "event",
"fabric", "factor", "field", "filter", "final", "focus", "forge", "format",
"frame", "fresh", "future", "garden", "gentle", "glide", "golden", "graph",
"grid", "group", "harbor", "header", "helix", "hidden", "hollow", "honest",
"icon", "index", "input", "island", "kernel", "key", "keystone", "label",
"lantern", "laser", "latest", "lattice", "layer", "ledger", "level", "light",
"limit", "linear", "local", "logic", "major", "maple", "margin", "matrix",
"meadow", "medium", "memory", "merge", "method", "mirror", "mobile", "module",
"motion", "native", "needle", "noble", "normal", "notion", "nova", "number",
"object", "ocean", "offset", "olive", "online", "option", "orbit", "origin",
"output", "packet", "panel", "parcel", "patch", "pattern", "phase", "pillar",
"pixel", "plain", "planet", "plume", "point", "portal", "prime", "profile",
"prompt", "proper", "public", "pulse", "query", "quartz", "quiet", "radar",
"range", "rapid", "record", "region", "relay", "render", "reply", "report",
"result", "ripple", "river", "route", "sample", "schema", "screen", "script",
"search", "second", "section", "secure", "select", "shadow", "signal", "silver",
"simple", "single", "sketch", "socket", "solar", "source", "space", "span",
"spiral", "spring", "stable", "static", "status", "steady", "stone", "stream",
"strict", "studio", "subtle", "summit", "switch", "system", "table", "target",
"thread", "timber", "token", "trace", "transit", "union", "update", "usage",
"valid", "vector", "velvet", "vertex", "vessel", "view", "violet", "virtual",
"vista", "visual", "volume", "wave", "window", "yellow", "zenith", "zero",
}
func clusterHumanName(repoID, representativeThreadID, clusterID int64) string {
key := fmt.Sprintf("repo:%d:cluster:%d", repoID, clusterID)
if representativeThreadID != 0 {
key = fmt.Sprintf("repo:%d:cluster-representative:%d", repoID, representativeThreadID)
}
hash := sha256.Sum256([]byte(key))
return fmt.Sprintf("%s-%s-%s",
humanKeyWords[int(hash[0])%len(humanKeyWords)],
humanKeyWords[int(hash[1])%len(humanKeyWords)],
humanKeyWords[int(hash[2])%len(humanKeyWords)],
)
}