Skip to content

[refactor] stringutil catch-all file split + sanitizer dedup noteΒ #49025

Description

@github-actions

πŸ”§ Semantic Function Clustering Analysis

Analysis of github/gh-aw β€” scope: pkg/stringutil, pkg/styles (10 non-test .go files)

Executive Summary

Both packages are, overall, cleanly feature-organized. Scope covered 10 files / ~35 functions. No exact duplicates and no misplaced cross-domain functions (e.g. no parser logic in a network file) were found. Two low/medium-impact organizational opportunities surfaced and are detailed below. Everything else clusters correctly and is left as-is.

Function Inventory

By file / cluster

pkg/stringutil

  • ansi.go β€” StripANSI, skipEscapeSequence, skipCSISequence, skipOSCSequence, isFinalCSIChar, isCSIParameterChar (cohesive ANSI cluster)
  • fuzzy_match.go β€” FindClosestMatches, LevenshteinDistance (cohesive)
  • identifiers.go β€” NormalizeWorkflowName, NormalizeSafeOutputIdentifier, MarkdownToLockFile, LockFileToMarkdown (cohesive)
  • pat_validation.go β€” PATType + methods, ClassifyPAT, ValidateCopilotPAT, GetPATTypeDescription (cohesive)
  • sanitize.go β€” SanitizeName, SanitizeErrorMessage, SanitizeIdentifierName, SanitizeParameterName, SanitizePythonVariableName, SanitizeToolID, SanitizeForFilename + helpers
  • urls.go β€” NormalizeGitHubHostURL, ExtractDomainFromURL, extractDomainFallback (cohesive)
  • stringutil.go β€” Truncate, NormalizeWhitespace, ParseVersionValue, FormatList, NormalizeLeadingWhitespace, IsPositiveInteger (grab-bag)

pkg/styles

  • theme.go / theme_wasm.go β€” build-tag pair (real vs Wasm no-op); intentional pattern
  • huh_theme.go β€” huh form theme mapping; correctly shares the color* palette vars with theme.go

Identified Issues

1. stringutil.go is a catch-all file (medium)

  • File: pkg/stringutil/stringutil.go
  • Issue: Unlike its six siblings (each named after one feature), this file bundles unrelated concerns: whitespace normalization (NormalizeWhitespace, NormalizeLeadingWhitespace), truncation (Truncate), version stringifying (ParseVersionValue), list formatting (FormatList), and integer validation (IsPositiveInteger). This breaks the package's own one-file-per-feature convention.
  • Recommendation: Extract the two whitespace functions into whitespace.go (they form a clear cluster). The remaining small, genuinely-generic helpers (Truncate, FormatList, ParseVersionValue, IsPositiveInteger) can stay in stringutil.go as the residual utility file. No signature or behavior changes β€” pure file moves.
  • Impact: Better discoverability; brings this file in line with the rest of the package. Low risk (same package, no API change).

2. Two parallel rune-mapping sanitizers (low)

  • Occurrence 1: sanitize.go:223 SanitizeIdentifierName(name, extraAllowed) β€” strings.Map, allows [A-Za-z0-9_] + extraAllowed, replaces disallowed with _, prepends _ if leading digit.
  • Occurrence 2: sanitize.go:325 SanitizeForFilename(slug) β€” strings.Builder loop, allows [A-Za-z0-9-_.], replaces disallowed with -.
  • Similarity: Same underlying shape (rune-by-rune, isASCIIAlphanumeric gate, replace-disallowed). They differ only in the allow-set, the replacement char, and the leading-digit rule.
  • Recommendation: Optional. A shared private helper mapRunes(s string, allow func(rune) bool, replacement rune) string would let SanitizeForFilename reuse the same core as SanitizeIdentifierName. Given the semantic differences (hyphen vs underscore output, leading-digit handling), this is a judgment call β€” only worth it if a third rune-mapping sanitizer appears. Flagged for awareness, not urgent.
  • Impact: Marginal dedup; do not do preemptively.

Not Issues (verified, left alone)

  • theme.go and theme_wasm.go duplicated var lists β€” intentional build-tag no-op stubs, not a refactor target.
  • huh_theme.go re-deriving colors β€” already sourced from the shared color* vars; single source of truth is intact.
  • SanitizeParameterName / SanitizePythonVariableName β€” thin, well-named wrappers over SanitizeIdentifierName; idiomatic, keep.

Recommendations

  1. Priority 1 β€” Split whitespace helpers out of stringutil.go into whitespace.go (finding 1). ~30 min, mechanical.
  2. Priority 3 β€” Revisit sanitizer consolidation (finding 2) only when/if a third similar sanitizer lands.

Analysis Metadata

  • Files analyzed: 10 (test files excluded)
  • Functions cataloged: ~35
  • Clusters: 9 (7 cohesive, 1 grab-bag, 1 build-tag pair)
  • Outliers: 1 file (catch-all)
  • Exact duplicates: 0
  • Near-duplicates: 1 pair (low significance)
  • Method: per-file symbol inventory + naming/purpose clustering

Generated by πŸ”§ Semantic Function Refactoring Β· sonnet46 Β· 197.1 AIC Β· βŒ– 9.95 AIC Β· ⊞ 9.7K Β· β—·

  • expires on Jul 31, 2026, 7:30 PM UTC-08:00

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions