Skip to content

fix(mobile): normalize frontmatter skill names and localize skill sources - #8505

Merged
iscekic merged 3 commits into
mainfrom
drain/mobile-skill-name-and-source-labels
Oct 22, 2026
Merged

iscekic merged 3 commits into
mainfrom
drain/mobile-skill-name-and-source-labels

Conversation

@iscekic

@iscekic iscekic commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

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.md with frontmatter name: My Skill filled my-skill and 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 rendered Benutzerdefiniert and Marktplatz for 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.md frontmatter name into 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. skillNameFromMarkdown now 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. skillRowSubtitle now returns the copy key for the server sourceType (profiles.skillSourceCustom / profiles.skillSourceMarketplace) and SkillRow renders it through t(). 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; Custom and Marketplace were not used by any existing key.

The parseSkillMarkdown re-export from components/profiles/skill-markdown.ts had 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 typecheck and run lint → clean.
  • Android emulator (Android 36, device language German), local dev stack, owned fake account:
    • Press Save with both fields empty, then type a SKILL.md whose frontmatter is name: My Skill: the name field became my-skill and the required-name message disappeared while typing.
    • Paste a SKILL.md whose 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.
    • The skills list renders Benutzerdefiniert under a custom row and Marktplatz under 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.

  1. Question: Name rule: The server skill-name schema (packages/cloud-agent-profile/src/contracts/skills.ts) is /^[a-z0-9][a-z0-9-]*$/, the same rule the web editor uses, and the name becomes a sandbox directory (.kilocode/skills/). How should the mobile sheet treat a frontmatter name like 'مراجعة الجودة'?
    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.
  2. Question: Catalog scope: The brief says new copy in en.json only, but tools/i18n/check-catalogs.mjs requires every key in every catalog. Which scope?
    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.
  3. Question: Subtitle: How should the skill row subtitle handle the server sourceType values?
    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.
  4. Question: Head review: PR fix(mobile): normalize frontmatter skill names and localize skill sources #8505's head cd61948 is a merge commit (main merged to clear conflicts). The Kilo app deliberately skips merge commits on synchronize and only re-points an in-flight review, so the head has no 'Kilo Code Review' check. Both feature commits were reviewed green (18cbd7d, 04ff55b) and CI is green except ios still building. How should I obtain a review of the head commit?
    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).

…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.
@iscekic iscekic added drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer labels Oct 21, 2026
@iscekic

iscekic commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator Author

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.

  • After a Save on an empty sheet, pasting a SKILL.md whose frontmatter is name: My Skill fills the name field as my-skill and the required-name message disappears.
  • Pasting a SKILL.md whose frontmatter name is Arabic leaves the name field empty.
  • Saving in that state reports the required-name message, not the name-pattern message; the skill saves once a valid name is typed, keeping the pasted content.
  • The list shows the localized source labels for a custom row and a marketplace-sourced row.

Skill sheet after a pasted frontmatter name fills the name field

Skill sheet with Arabic frontmatter pasted and the name field left empty

Skill sheet reporting the required-name message before saving

Skills list with localized source labels under each row

Comment thread apps/mobile/src/i18n/locales/vi.json Resolved
@kilo-code-bot

kilo-code-bot Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

No new issues: the branch has no PR-authored commits after 04ff55bf, the merge from main only brought unrelated changes, and the two previously reported defects remain fixed at HEAD (foldForSearch strips diacritics, Vietnamese marketplace label is Marketplace).

Assumptions: [INFERENCE] This read-only session could not run pnpm test, check:i18n, typecheck, lint, or the Android emulator, and could not execute a JSON parser (the node invocation was denied), so catalog parity was verified by key-presence counts across all 87 locale files. The main merge diff (825 files) was treated as out of scope because GitHub's PR diff contains only the two PR commits; only the files the PR changes were re-verified at HEAD. The owner's post-merge emulator re-verification comment could not be read (permission denied) and was not relied on.

Overview

  • Verified at HEAD cd61948e: skillNameFromMarkdown uses foldForSearch and produces naive-cafe for naïve café; the 100-character cap matches MAX_SKILL_NAME_LENGTH and the regex matches SKILL_NAME_PATTERN in packages/cloud-agent-profile/src/contracts/skills.ts.
  • skillRowSubtitle returns the profiles.skillSourceCustom / profiles.skillSourceMarketplace keys, and SkillRow falls back to the raw sourceType for unknown values.
  • All 87 locale catalogs contain both new keys; en.json has no duplicate copy for Custom or Marketplace.
  • The removed parseSkillMarkdown re-export has no remaining callers.
  • No memory-leak vectors introduced: the changed sheet/screen code adds no listeners, timers, subscriptions, or async work.
Files Reviewed (7 files plus 87 catalogs)
  • apps/mobile/src/lib/agent-profile-forms.ts - no issues
  • apps/mobile/src/lib/agent-profile-forms.test.ts - no issues
  • apps/mobile/src/components/profiles/skill-form-sheet.tsx - no issues
  • apps/mobile/src/components/profiles/skill-form-sheet.mounted.test.tsx - no issues
  • apps/mobile/src/components/profiles/skill-markdown.ts - no issues
  • apps/mobile/src/components/profiles/skill-markdown.test.ts - no issues
  • apps/mobile/src/components/profiles/profile-skills-screen.tsx - no issues
  • apps/mobile/src/i18n/fold-for-search.ts - no issues
  • apps/mobile/src/i18n/locales/*.json (87 catalogs) - no issues
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 Summary

The follow-up commit routes skill-name derivation through foldForSearch, fixing the diacritic-splitting defect on decomposed characters, and the Vietnamese marketplace label now matches the product word used by the other catalogs; both changes are covered by tests and consistent with current code.

Assumptions: [INFERENCE] I could not execute the test suites, check:i18n, typecheck, or the Android emulator in this read-only session; catalog parity, diff shape, and the fold behavior were verified by reading fold-for-search.ts, agent-profile-forms.ts, the catalogs, and the added test. The shared foldForSearch uses NFD, so it does not apply compatibility decomposition (NFKD forms such as ligatures or full-width Latin no longer slug); that edge case is outside normal SKILL.md names and was not raised as a finding.

Overview

Both previously reported items are resolved on the current HEAD:

  • apps/mobile/src/lib/agent-profile-forms.ts - 111: diacritics are now stripped via foldForSearch, and the added test asserts naïve café → naive-cafe.
  • apps/mobile/src/i18n/locales/vi.json - 3659: skillSourceMarketplace now reads Marketplace, consistent with es, fr, pt, cs, and others.
Files Reviewed (4 files in the incremental diff)
  • apps/mobile/src/lib/agent-profile-forms.ts - no issues
  • apps/mobile/src/lib/agent-profile-forms.test.ts - no issues
  • apps/mobile/src/i18n/fold-for-search.ts - no issues (doc comment updated to name the new caller)
  • apps/mobile/src/i18n/locales/vi.json - no issues

Previous review (commit 18cbd7d)

Status: 2 Issues Found | Recommendation: Merge with suggestions

Executive Summary

The 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: [INFERENCE] I could not execute check:i18n, the test suites, typecheck, or the Android emulator; catalog coverage, diff shape, and checker behavior were verified by reading the catalogs and tools/i18n/check-catalogs.mjs instead. Translation-quality judgments outside the reported labels (Hausa, Central Kurdish) were not confident enough to raise.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 2
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/lib/agent-profile-forms.ts 111 NFKD is not followed by removal of combining marks, so Müller derives mu-ller and Español derives espa-ol.
apps/mobile/src/i18n/locales/vi.json 3659 Cửa hàng ứng dụng means "app store", not a skills marketplace.
Files Reviewed (95 files)
  • apps/mobile/src/lib/agent-profile-forms.ts - 1 suggestion
  • apps/mobile/src/lib/agent-profile-forms.test.ts - no issues
  • apps/mobile/src/components/profiles/skill-form-sheet.tsx - no issues
  • apps/mobile/src/components/profiles/skill-form-sheet.mounted.test.tsx - no issues
  • apps/mobile/src/components/profiles/skill-markdown.ts - no issues
  • apps/mobile/src/components/profiles/skill-markdown.test.ts - no issues
  • apps/mobile/src/components/profiles/profile-skills-screen.tsx - no issues
  • apps/mobile/src/components/profiles/profile-skills-screen.mounted.test.tsx - no issues
  • apps/mobile/src/i18n/locales/en.json - no issues
  • apps/mobile/src/i18n/locales/vi.json - 1 suggestion
  • 86 other locale catalogs - key coverage and diff shape verified; no further issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 73.4K · Output: 11.8K · Cached: 980.9K

Review guidance: REVIEW.md from base branch main

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.
@iscekic iscekic added the merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. label Oct 21, 2026
@iscekic
iscekic enabled auto-merge October 22, 2026 02:07
…me-and-source-labels

# Conflicts:
#	apps/mobile/src/i18n/locales/de.json
@iscekic
iscekic disabled auto-merge October 22, 2026 13:21
@iscekic iscekic removed the merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. label Oct 22, 2026
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Re-verified on the branch after merging main, on the Android emulator (device language German) against the local dev stack with an owned test account.

  • Add-skill sheet: pasting a SKILL.md whose frontmatter is name: My Skill fills the name field with my-skill, and the required-name message left by an earlier Save on the empty sheet is gone. The panel hint renders in the informal German form.
  • Skills list: each row shows the localized source type — Marktplatz for a marketplace-sourced skill and Benutzerdefiniert for a custom one.

Skill sheet with the name filled from the pasted frontmatter and no required-name message

Skills list with a marketplace row and a custom row, each showing its localized source label

@iscekic
iscekic marked this pull request as draft October 22, 2026 14:13
@iscekic
iscekic marked this pull request as ready for review October 22, 2026 14:13
@iscekic iscekic added the merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. label Oct 22, 2026
@iscekic
iscekic enabled auto-merge October 22, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain explorer:android Finding surfaced by the Android explorer merge:bot Bot-owned review; merge when ready once readiness passes and a review approves.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants