Repository navigation
fix(mobile): normalize frontmatter skill names and localize skill sources - #8505
Conversation
…rces The add/edit skill sheet copied a SKILL.md frontmatter name into the name field verbatim while Save validated it against the server's name rule (^[a-z0-9][a-z0-9-]*$), so a name the app itself extracted could be refused, and the refusal left the required-name error over a field the paste had just filled. Derive the field value through skillNameFromMarkdown: lowercase, collapse each run outside [a-z0-9] into one dash, trim edge dashes, cap at the server's 100-character bound. A name with no ASCII letter or digit left fills nothing, so the field never holds a value Save would refuse. A fill that satisfies the validator clears a name error left by an earlier save. The skill row subtitle now resolves the server source type through the catalog (Custom / Marketplace) and falls back to the raw value for a source this app has no copy for. The two new keys are translated in every catalog.
|
bot: Exercised the skill sheet and the skills list on the Android emulator (Android 36, device language German) against the local dev stack with an owned test account.
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryNo new issues: the branch has no PR-authored commits after Assumptions: Overview
Files Reviewed (7 files plus 87 catalogs)
Previous Review Summaries (2 snapshots, latest commit 04ff55b)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 04ff55b)Status: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit routes skill-name derivation through Assumptions: OverviewBoth previously reported items are resolved on the current HEAD:
Files Reviewed (4 files in the incremental diff)
Previous review (commit 18cbd7d)Status: 2 Issues Found | Recommendation: Merge with suggestions Executive SummaryThe name-normalization and source-label changes behave as described and are covered by focused tests; the only findings are one slug-derivation gap for accented names and one misleading Vietnamese marketplace label. Assumptions: Overview
Issue Details (click to expand)SUGGESTION
Files Reviewed (95 files)
Reviewed by deepseek-flash-latest · Input: 73.4K · Output: 11.8K · Cached: 980.9K Review guidance: REVIEW.md from base branch |
A frontmatter name with an accent decomposed into base letter plus a combining mark, and the run that collapses everything outside [a-z0-9] into a dash turned that mark into a word break, so `Müller` filled `mu-ller`. Reuse the app's search folding, which strips diacritics after decomposition, before the slug is built. The Vietnamese marketplace label named an app store; use the product word instead.
…me-and-source-labels # Conflicts: # apps/mobile/src/i18n/locales/de.json
|
bot: Re-verified on the branch after merging
|






Evidence
Evidence: demonstrated — on the Android emulator (Android 36, device language German) against the local dev stack with an owned fake account: after a Save on the empty sheet, pasting a
SKILL.mdwith frontmattername: My Skillfilledmy-skilland cleared the required-name message; an Arabic frontmatter name filled nothing, so Save reported the required-name message rather than the pattern message; the skills list renderedBenutzerdefiniertandMarktplatzfor a custom and a marketplace-sourced row. Screenshots are in the follow-up comment.Change
Frontmatter name. The add/edit skill sheet copied a
SKILL.mdfrontmatternameinto the name field verbatim while Save validated it against the server rule (^[a-z0-9][a-z0-9-]*$,packages/cloud-agent-profile/src/contracts/skills.ts), so a name the app had just extracted could be refused.skillNameFromMarkdownnow derives the field value through that rule: lowercase, diacritics folded, each run outside[a-z0-9]collapsed into one dash, edge dashes trimmed, capped at the server's 100-character bound. A name with no ASCII letter or digit left — a name written in another script — fills nothing, so the field never holds a value Save would refuse.Stale error. A fill that satisfies the validator clears the name error an earlier save left on the empty field, so the message and red border no longer describe a field that is already filled.
Row subtitle.
skillRowSubtitlenow returns the copy key for the serversourceType(profiles.skillSourceCustom/profiles.skillSourceMarketplace) andSkillRowrenders it throught(). A source type this app has no copy for keeps the raw value instead of rendering blank. The two keys are translated in every catalog;CustomandMarketplacewere not used by any existing key.The
parseSkillMarkdownre-export fromcomponents/profiles/skill-markdown.tshad no remaining caller and was removed; the parser stays where it is defined and tested.Verification
pnpm --filter kilo-app run check:i18n→check-catalogs: 87 languages, every catalog matches en.json.pnpm --filter kilo-app run check:plurals→ clean.pnpm --filter kilo-app exec vitest run src/i18n src/lib/agent-profile-forms.test.ts src/components/profiles→ 44 files, 1921 tests passed.pnpm --filter kilo-app test→ 1241 files, 18437 passed, 2 skipped.pnpm --filter kilo-app run typecheckandrun lint→ clean.SKILL.mdwhose frontmatter isname: My Skill: the name field becamemy-skilland the required-name message disappeared while typing.SKILL.mdwhose frontmatter name is Arabic: the name field stays empty and Save reports the required-name message, never the pattern message; the skill saved normally once a valid name was typed, with the pasted content kept.Benutzerdefiniertunder a custom row andMarktplatzunder a marketplace-sourced row.Screenshots of the exercised screens are posted in a follow-up comment.
Proxy answers
The owner's proxy gave these answers in the owner's place.
Answer: Normalize when filling (mobile only)
Confidence: 0.60 · Precedent: Speed and least work: "do the least amount of work possible, with no drop in quality" (7f3470e0ba6f). The brief allows normalizing, and this keeps the server, sandbox, and web contract that this repo cannot verify end to end. An Arabic name then yields an empty field and a clear Save prompt, never a rejected value.
Answer: Translate every catalog (Recommended)
Confidence: 0.75 · Precedent: UX and design quality: "the mobile app always must respect i18n" (dcb3f9170164). Git and pull requests: "make sure that CI is passing too (standard procedure)" (1473782d4df9). The brief's en.json-only scope would fail check:i18n.
Answer: Localize known, raw fallback (Recommended)
Confidence: 0.80 · Precedent: Autonomy and decisions: "fix class of issue" (7f3470e0ba6f). The brief names both custom and marketplace, and a fallback keeps future values from showing blank.
Answer: Toggle draft → ready
Confidence: 0.72 · Precedent: Speed and least work: "do the least amount of work possible, with no drop in quality" (session 7f3470e0ba6f); draft/ready rule: human ready means kilobot recommends merge, no conflicts, CI passes (session 640cb4aa808a).