Repository navigation
fix(triage): slugify agent names for labels + pre-create missing labels #785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| '@bradygaster/squad-sdk': patch | ||
| '@bradygaster/squad-cli': patch | ||
| --- | ||
|
|
||
| Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). | ||
|
|
||
| Pre-create all `squad:{member}` labels at watch startup via `ensureTag()` so `gh issue edit --add-label` never fails on missing labels. |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -128,6 +128,17 @@ export class GitHubAdapter implements PlatformAdapter { | |||||||||||||
| this.gh(['issue', 'edit', String(workItemId), '--repo', this.repoFlag, '--add-label', tag]); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| async ensureTag(tag: string, options?: { color?: string; description?: string }): Promise<void> { | ||||||||||||||
| const args = ['label', 'create', tag, '--repo', this.repoFlag, '--force']; | ||||||||||||||
| if (options?.color) args.push('--color', options.color); | ||||||||||||||
| if (options?.description) args.push('--description', options.description); | ||||||||||||||
| try { | ||||||||||||||
| this.gh(args); | ||||||||||||||
| } catch { | ||||||||||||||
| // Label already exists or creation failed — continue either way | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+135
to
+139
|
||||||||||||||
| try { | |
| this.gh(args); | |
| } catch { | |
| // Label already exists or creation failed — continue either way | |
| } | |
| this.gh(args); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,4 +1,7 @@ | ||||||
| import { normalizeEol } from '../utils/normalize-eol.js'; | ||||||
| import { slugify } from '../utils/slugify.js'; | ||||||
|
|
||||||
| export { slugify } from '../utils/slugify.js'; | ||||||
|
|
||||||
|
Comment on lines
+4
to
5
|
||||||
| export { slugify } from '../utils/slugify.js'; | |
Copilot
AI
Apr 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parseRoster() now derives label via slugify(name), but the TeamMember.label field doc comment still describes it as squad:{lowercase name}. Since this function defines the canonical label format, the type-level documentation should be updated to match the slugified behavior to avoid misleading SDK consumers.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| /** | ||
| * Convert a display name to a URL/label-safe slug. | ||
| * | ||
| * "Steve Rogers" → "steve-rogers" | ||
| * "Tony Stark (Iron Man)" → "tony-stark-iron-man" | ||
| * "Doctor Strange (Stephen Strange)" → "doctor-strange-stephen-strange" | ||
| * "Thor" → "thor" | ||
| * "already-slugified" → "already-slugified" | ||
| */ | ||
| export function slugify(name: string): string { | ||
| return name | ||
| .toLowerCase() | ||
| .replace(/[^a-z0-9]+/g, '-') | ||
| .replace(/^-|-$/g, ''); | ||
| } | ||
|
Comment on lines
+1
to
+15
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The startup message says labels were “ensured … exist”, but label creation is best-effort and both
ensureTag()and this caller swallow errors. This can produce a misleading success message even when none of the labels were created. Consider tracking successes and reporting “attempted to ensure” (or only printing the message when all creations succeed / when verbose is enabled).