skilldrop-cli 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +3 -0
  2. package/catalogue.json +25 -2
  3. package/model-routing.json +20 -0
  4. package/package.json +1 -1
  5. package/packs/event-planner/pack.json +61 -0
  6. package/packs/event-planner/skills/run-of-show/SKILL.md +144 -0
  7. package/packs/event-planner/skills/run-of-show/evals/eval_queries.json +30 -0
  8. package/packs/event-planner/skills/run-of-show/evals/evals.json +103 -0
  9. package/packs/event-planner/skills/run-of-show/evals/files/1/agenda.md +16 -0
  10. package/packs/event-planner/skills/run-of-show/evals/files/2/schedule.csv +8 -0
  11. package/packs/event-planner/skills/run-of-show/evals/files/3/notes.txt +3 -0
  12. package/packs/event-planner/skills/run-of-show/evals/files/4/sessions_export.csv +25 -0
  13. package/packs/event-planner/skills/run-of-show/evals/files/4/venue_and_crew.txt +27 -0
  14. package/packs/event-planner/skills/run-of-show/evals/files/5/runsheet_v4.csv +28 -0
  15. package/packs/event-planner/skills/run-of-show/evals/files/5/venue_and_suppliers.txt +22 -0
  16. package/packs/event-planner/skills/run-of-show/evals/files/6/acts_from_booker.csv +26 -0
  17. package/packs/event-planner/skills/run-of-show/evals/files/6/venue_rooms_and_crew.txt +14 -0
  18. package/packs/event-planner/skills/run-of-show/evals/files/7/runsheet_draft_v4.csv +25 -0
  19. package/packs/event-planner/skills/run-of-show/evals/files/7/venue_and_fixed_times.txt +24 -0
  20. package/packs/event-planner/skills/run-of-show/examples/product-launch.md +77 -0
  21. package/packs/event-planner/skills/run-of-show/examples/product-launch.svg +58 -0
  22. package/packs/event-planner/skills/run-of-show/manifest.json +44 -0
  23. package/packs/event-planner/skills/run-of-show/scripts/show_check.py +295 -0
  24. package/packs/event-planner/skills/run-of-show/templates/show.json +15 -0
  25. package/packs/event-planner/skills/seating-plan/SKILL.md +155 -0
  26. package/packs/event-planner/skills/seating-plan/evals/eval_queries.json +30 -0
  27. package/packs/event-planner/skills/seating-plan/evals/evals.json +164 -0
  28. package/packs/event-planner/skills/seating-plan/evals/files/1/guests.csv +31 -0
  29. package/packs/event-planner/skills/seating-plan/evals/files/10/hall_notes.txt +13 -0
  30. package/packs/event-planner/skills/seating-plan/evals/files/10/quiz_night_registrations.csv +67 -0
  31. package/packs/event-planner/skills/seating-plan/evals/files/11/notes_for_the_plan.txt +21 -0
  32. package/packs/event-planner/skills/seating-plan/evals/files/11/rsvp_list.csv +77 -0
  33. package/packs/event-planner/skills/seating-plan/evals/files/11/table_plan_draft.csv +78 -0
  34. package/packs/event-planner/skills/seating-plan/evals/files/2/table-plan.txt +8 -0
  35. package/packs/event-planner/skills/seating-plan/evals/files/3/brief.txt +4 -0
  36. package/packs/event-planner/skills/seating-plan/evals/files/3/guests.csv +49 -0
  37. package/packs/event-planner/skills/seating-plan/evals/files/4/rsvp_export.csv +127 -0
  38. package/packs/event-planner/skills/seating-plan/evals/files/4/seating_notes.txt +21 -0
  39. package/packs/event-planner/skills/seating-plan/evals/files/5/organiser_notes.txt +10 -0
  40. package/packs/event-planner/skills/seating-plan/evals/files/5/registrations.csv +93 -0
  41. package/packs/event-planner/skills/seating-plan/evals/files/5/table_plan_v3.csv +94 -0
  42. package/packs/event-planner/skills/seating-plan/evals/files/6/bridgets_notes.txt +30 -0
  43. package/packs/event-planner/skills/seating-plan/evals/files/6/ticket_export.csv +117 -0
  44. package/packs/event-planner/skills/seating-plan/evals/files/6/venue_floorplan_notes.txt +14 -0
  45. package/packs/event-planner/skills/seating-plan/evals/files/7/keep_apart_CONFIDENTIAL.txt +9 -0
  46. package/packs/event-planner/skills/seating-plan/evals/files/7/prom_seating_v3.csv +101 -0
  47. package/packs/event-planner/skills/seating-plan/evals/files/7/ticket_list.csv +101 -0
  48. package/packs/event-planner/skills/seating-plan/evals/files/7/venue_info.txt +16 -0
  49. package/packs/event-planner/skills/seating-plan/evals/files/8/registrations_export.csv +147 -0
  50. package/packs/event-planner/skills/seating-plan/evals/files/8/room_layout.md +22 -0
  51. package/packs/event-planner/skills/seating-plan/evals/files/8/seating_requests.txt +31 -0
  52. package/packs/event-planner/skills/seating-plan/evals/files/9/guest_list.csv +84 -0
  53. package/packs/event-planner/skills/seating-plan/evals/files/9/notes.txt +16 -0
  54. package/packs/event-planner/skills/seating-plan/evals/files/9/table_plan.csv +85 -0
  55. package/packs/event-planner/skills/seating-plan/examples/wedding-dinner.md +61 -0
  56. package/packs/event-planner/skills/seating-plan/examples/wedding-dinner.svg +39 -0
  57. package/packs/event-planner/skills/seating-plan/manifest.json +44 -0
  58. package/packs/event-planner/skills/seating-plan/scripts/seating_check.py +324 -0
  59. package/packs/event-planner/skills/seating-plan/templates/seating.json +28 -0
  60. package/packs/experience-design/pack.json +5 -0
  61. package/packs/experience-design/skills/locale-check/SKILL.md +139 -0
  62. package/packs/experience-design/skills/locale-check/evals/eval_queries.json +38 -0
  63. package/packs/experience-design/skills/locale-check/evals/evals.json +104 -0
  64. package/packs/experience-design/skills/locale-check/evals/files/1/budget.json +1 -0
  65. package/packs/experience-design/skills/locale-check/evals/files/1/locales/ar.json +16 -0
  66. package/packs/experience-design/skills/locale-check/evals/files/1/locales/de.json +12 -0
  67. package/packs/experience-design/skills/locale-check/evals/files/1/locales/en.json +12 -0
  68. package/packs/experience-design/skills/locale-check/evals/files/1/locales/pl.json +12 -0
  69. package/packs/experience-design/skills/locale-check/evals/files/2/app/src/main/res/values/strings.xml +12 -0
  70. package/packs/experience-design/skills/locale-check/evals/files/2/app/src/main/res/values-es/strings.xml +11 -0
  71. package/packs/experience-design/skills/locale-check/evals/files/2/app/src/main/res/values-fr/strings.xml +12 -0
  72. package/packs/experience-design/skills/locale-check/evals/files/3/po/ja.po +20 -0
  73. package/packs/experience-design/skills/locale-check/evals/files/3/po/messages.pot +23 -0
  74. package/packs/experience-design/skills/locale-check/evals/files/3/po/ru.po +22 -0
  75. package/packs/experience-design/skills/locale-check/evals/files/4/budgets.json +15 -0
  76. package/packs/experience-design/skills/locale-check/evals/files/4/locales/ar.json +265 -0
  77. package/packs/experience-design/skills/locale-check/evals/files/4/locales/de.json +265 -0
  78. package/packs/experience-design/skills/locale-check/evals/files/4/locales/en.json +265 -0
  79. package/packs/experience-design/skills/locale-check/evals/files/4/locales/fr.json +265 -0
  80. package/packs/experience-design/skills/locale-check/evals/files/4/locales/pl.json +265 -0
  81. package/packs/experience-design/skills/locale-check/evals/files/5/app/src/main/res/values/strings.xml +77 -0
  82. package/packs/experience-design/skills/locale-check/evals/files/5/app/src/main/res/values-es/strings.xml +63 -0
  83. package/packs/experience-design/skills/locale-check/evals/files/5/app/src/main/res/values-ja/strings.xml +61 -0
  84. package/packs/experience-design/skills/locale-check/evals/files/6/po/cs.po +605 -0
  85. package/packs/experience-design/skills/locale-check/evals/files/6/po/marlin.pot +602 -0
  86. package/packs/experience-design/skills/locale-check/evals/files/6/po/pt_BR.po +602 -0
  87. package/packs/experience-design/skills/locale-check/evals/files/6/po/ru.po +608 -0
  88. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/en.lproj/Localizable.strings +160 -0
  89. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/en.lproj/Localizable.stringsdict +70 -0
  90. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/he.lproj/Localizable.strings +157 -0
  91. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/he.lproj/Localizable.stringsdict +86 -0
  92. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/it.lproj/Localizable.strings +160 -0
  93. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/it.lproj/Localizable.stringsdict +68 -0
  94. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/ko.lproj/Localizable.strings +160 -0
  95. package/packs/experience-design/skills/locale-check/evals/files/7/Tidewatch/Resources/ko.lproj/Localizable.stringsdict +62 -0
  96. package/packs/experience-design/skills/locale-check/examples/settings-release.md +107 -0
  97. package/packs/experience-design/skills/locale-check/manifest.json +45 -0
  98. package/packs/experience-design/skills/locale-check/scripts/locale_check.py +1105 -0
  99. package/packs/interior-designer/pack.json +60 -0
  100. package/packs/interior-designer/skills/furniture-layout/SKILL.md +182 -0
  101. package/packs/interior-designer/skills/furniture-layout/evals/eval_queries.json +11 -0
  102. package/packs/interior-designer/skills/furniture-layout/evals/evals.json +133 -0
  103. package/packs/interior-designer/skills/furniture-layout/evals/files/2/living-room-notes.md +24 -0
  104. package/packs/interior-designer/skills/furniture-layout/evals/files/3/office-brief.md +18 -0
  105. package/packs/interior-designer/skills/furniture-layout/evals/files/4/furniture_schedule.csv +15 -0
  106. package/packs/interior-designer/skills/furniture-layout/evals/files/4/site_survey.txt +22 -0
  107. package/packs/interior-designer/skills/furniture-layout/evals/files/5/layout_v2.csv +14 -0
  108. package/packs/interior-designer/skills/furniture-layout/evals/files/5/measurements.txt +16 -0
  109. package/packs/interior-designer/skills/furniture-layout/evals/files/6/access_consultant_email.txt +19 -0
  110. package/packs/interior-designer/skills/furniture-layout/evals/files/6/furniture_stock.csv +5 -0
  111. package/packs/interior-designer/skills/furniture-layout/evals/files/6/site_measurements.txt +14 -0
  112. package/packs/interior-designer/skills/furniture-layout/evals/files/7/room_214_layout.csv +11 -0
  113. package/packs/interior-designer/skills/furniture-layout/evals/files/7/room_and_brand_standard.txt +20 -0
  114. package/packs/interior-designer/skills/furniture-layout/evals/files/8/email_from_practice_manager.txt +44 -0
  115. package/packs/interior-designer/skills/furniture-layout/evals/files/8/furniture_we_are_keeping.csv +10 -0
  116. package/packs/interior-designer/skills/furniture-layout/evals/files/9/reading_room_schedule.csv +15 -0
  117. package/packs/interior-designer/skills/furniture-layout/evals/files/9/room_notes.txt +23 -0
  118. package/packs/interior-designer/skills/furniture-layout/examples/king-bed-bedroom.md +121 -0
  119. package/packs/interior-designer/skills/furniture-layout/examples/king-bed-bedroom.svg +57 -0
  120. package/packs/interior-designer/skills/furniture-layout/manifest.json +44 -0
  121. package/packs/interior-designer/skills/furniture-layout/scripts/layout_check.py +1130 -0
  122. package/packs/interior-designer/skills/furniture-layout/templates/layout.json +26 -0
  123. package/packs/operations-manager/pack.json +60 -0
  124. package/packs/operations-manager/skills/shift-roster/SKILL.md +169 -0
  125. package/packs/operations-manager/skills/shift-roster/evals/eval_queries.json +38 -0
  126. package/packs/operations-manager/skills/shift-roster/evals/evals.json +135 -0
  127. package/packs/operations-manager/skills/shift-roster/evals/files/1/shifts.csv +3 -0
  128. package/packs/operations-manager/skills/shift-roster/evals/files/1/staff.csv +8 -0
  129. package/packs/operations-manager/skills/shift-roster/evals/files/2/rota.csv +22 -0
  130. package/packs/operations-manager/skills/shift-roster/evals/files/2/staff.csv +6 -0
  131. package/packs/operations-manager/skills/shift-roster/evals/files/3/team.md +14 -0
  132. package/packs/operations-manager/skills/shift-roster/evals/files/4/availability_export_wk47.csv +23 -0
  133. package/packs/operations-manager/skills/shift-roster/evals/files/4/rota_notes.txt +20 -0
  134. package/packs/operations-manager/skills/shift-roster/evals/files/5/rota_draft_16-29nov.csv +107 -0
  135. package/packs/operations-manager/skills/shift-roster/evals/files/5/staff_list.csv +17 -0
  136. package/packs/operations-manager/skills/shift-roster/evals/files/6/availability_notes.txt +24 -0
  137. package/packs/operations-manager/skills/shift-roster/evals/files/6/peoplehub_staff_export.csv +14 -0
  138. package/packs/operations-manager/skills/shift-roster/evals/files/6/rota_template.csv +25 -0
  139. package/packs/operations-manager/skills/shift-roster/evals/files/7/leave_and_availability.txt +18 -0
  140. package/packs/operations-manager/skills/shift-roster/evals/files/7/rota_wc_30nov.csv +47 -0
  141. package/packs/operations-manager/skills/shift-roster/evals/files/7/staff_list.csv +15 -0
  142. package/packs/operations-manager/skills/shift-roster/evals/files/8/availability_form_responses.csv +22 -0
  143. package/packs/operations-manager/skills/shift-roster/evals/files/8/cover_requirements.csv +15 -0
  144. package/packs/operations-manager/skills/shift-roster/evals/files/8/staff_export.csv +29 -0
  145. package/packs/operations-manager/skills/shift-roster/evals/files/9/leave_and_restrictions.txt +16 -0
  146. package/packs/operations-manager/skills/shift-roster/evals/files/9/rota_export_07-13Dec.csv +85 -0
  147. package/packs/operations-manager/skills/shift-roster/evals/files/9/staff_list.csv +27 -0
  148. package/packs/operations-manager/skills/shift-roster/examples/cafe-week.md +72 -0
  149. package/packs/operations-manager/skills/shift-roster/examples/cafe-week.svg +123 -0
  150. package/packs/operations-manager/skills/shift-roster/manifest.json +34 -0
  151. package/packs/operations-manager/skills/shift-roster/scripts/roster_check.py +633 -0
  152. package/packs/operations-manager/skills/shift-roster/templates/roster.json +22 -0
@@ -0,0 +1,160 @@
1
+ /* Tidewatch — Localizable.strings (ko) */
2
+
3
+ /* Tab bar */
4
+ "tab.forecast" = "예보";
5
+
6
+ /* Tab bar */
7
+ "tab.spots" = "스팟";
8
+
9
+ /* Tab bar */
10
+ "tab.surf" = "서핑";
11
+
12
+ /* Tab bar */
13
+ "tab.settings" = "설정";
14
+
15
+ /* Tide panel */
16
+ "tide.high" = "만조";
17
+
18
+ /* Tide panel */
19
+ "tide.low" = "간조";
20
+
21
+ /* Tide panel */
22
+ "tide.rising" = "밀물";
23
+
24
+ /* Tide panel */
25
+ "tide.falling" = "썰물";
26
+
27
+ /* Tide panel */
28
+ "tide.next_high" = "다음 만조: %@";
29
+
30
+ /* Tide panel */
31
+ "tide.summary" = "만조 %1$@, 간조 %2$@";
32
+
33
+ /* Conditions card */
34
+ "swell.height" = "너울: %.1f m";
35
+
36
+ /* Conditions card */
37
+ "swell.period" = "주기: %d초";
38
+
39
+ /* Conditions card */
40
+ "water.temp" = "수온: %.1f°";
41
+
42
+ /* Conditions card */
43
+ "wind.speed" = "바람: %2$@에서 %1$d km/h";
44
+
45
+ /* Spots list */
46
+ "spot.updated" = "%1$@ %2$@ 전 업데이트됨";
47
+
48
+ /* Safety alert banner */
49
+ "alert.rip.title" = "이안류 경보";
50
+
51
+ /* Safety alert banner */
52
+ "alert.rip.body" = "강한 이안류가 있습니다. 수영을 권장하지 않습니다.";
53
+
54
+ /* Safety alert banner */
55
+ "alert.lightning.title" = "근처 낙뢰";
56
+
57
+ /* Safety alert banner */
58
+ "alert.lightning.body" = "물 밖으로 나와 해변을 떠나세요.";
59
+
60
+ /* Safety alert banner */
61
+ "alert.uv.body" = "자외선 지수 %d. 자외선 차단제를 바르세요.";
62
+
63
+ /* Spots list */
64
+ "spot.add" = "스팟 추가";
65
+
66
+ /* Spots list */
67
+ "spot.remove" = "스팟 삭제";
68
+
69
+ /* Spots list */
70
+ "spot.remove.confirm" = "%@을(를) 내 스팟에서 삭제할까요?";
71
+
72
+ /* Spots list */
73
+ "spot.search.placeholder" = "해변 검색";
74
+
75
+ /* Spots list */
76
+ "spot.empty" = "저장된 스팟이 없습니다";
77
+
78
+ /* Forecast screen */
79
+ "forecast.updated" = "%@ 업데이트됨";
80
+
81
+ /* Forecast screen */
82
+ "forecast.offline" = "오프라인 상태입니다. 마지막 예보를 표시합니다.";
83
+
84
+ /* Forecast screen */
85
+ "forecast.refresh" = "새로고침";
86
+
87
+ /* Forecast screen */
88
+ "forecast.source" = "데이터 출처: %@";
89
+
90
+ /* Settings */
91
+ "settings.units" = "단위";
92
+
93
+ /* Settings */
94
+ "settings.units.metric" = "미터법";
95
+
96
+ /* Settings */
97
+ "settings.units.imperial" = "야드파운드법";
98
+
99
+ /* Settings */
100
+ "settings.notifications" = "알림";
101
+
102
+ /* Settings */
103
+ "settings.notifications.footer" = "저장한 스팟의 상황이 바뀌면 알려 드립니다.";
104
+
105
+ /* Settings */
106
+ "settings.dawn_patrol" = "새벽 서핑 알림";
107
+
108
+ /* Settings */
109
+ "settings.dawn_patrol.time" = "%@에 알림";
110
+
111
+ /* Settings */
112
+ "settings.privacy" = "개인정보 보호";
113
+
114
+ /* Settings */
115
+ "settings.about" = "Tidewatch 정보";
116
+
117
+ /* Settings */
118
+ "settings.version" = "버전 %@ (%d)";
119
+
120
+ /* Onboarding */
121
+ "onboarding.title" = "바다에 나가기 전에 확인하세요";
122
+
123
+ /* Onboarding */
124
+ "onboarding.location" = "주변 해변을 찾으려면 위치 접근을 허용하세요.";
125
+
126
+ /* Onboarding */
127
+ "onboarding.continue" = "계속";
128
+
129
+ /* Onboarding */
130
+ "onboarding.skip" = "나중에";
131
+
132
+ /* Error banner */
133
+ "error.network" = "예보를 불러오지 못했습니다. 연결을 확인하세요.";
134
+
135
+ /* Error banner */
136
+ "error.location_denied" = "위치 서비스가 꺼져 있습니다. 설정에서 켜세요.";
137
+
138
+ /* Share sheet */
139
+ "share.forecast" = "예보 공유";
140
+
141
+ /* Share sheet */
142
+ "share.message" = "%1$@ 서핑 상태: %2$@";
143
+
144
+ /* Home-screen widget */
145
+ "widget.title" = "오늘의 물때";
146
+
147
+ /* Home-screen widget */
148
+ "widget.placeholder" = "앱에서 스팟을 선택하세요";
149
+
150
+ /* Surf rating */
151
+ "rating.good" = "좋음";
152
+
153
+ /* Surf rating */
154
+ "rating.fair" = "보통";
155
+
156
+ /* Surf rating */
157
+ "rating.poor" = "나쁨";
158
+
159
+ /* Surf rating */
160
+ "rating.flat" = "파도 없음";
@@ -0,0 +1,62 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>forecast.days.count</key>
6
+ <dict>
7
+ <key>NSStringLocalizedFormatKey</key>
8
+ <string>%#@days@</string>
9
+ <key>days</key>
10
+ <dict>
11
+ <key>NSStringFormatSpecTypeKey</key>
12
+ <string>NSStringPluralRuleType</string>
13
+ <key>NSStringFormatValueTypeKey</key>
14
+ <string>d</string>
15
+ <key>other</key>
16
+ <string>%d일 예보</string>
17
+ </dict>
18
+ </dict>
19
+ <key>swell.count</key>
20
+ <dict>
21
+ <key>NSStringLocalizedFormatKey</key>
22
+ <string>%#@swells@</string>
23
+ <key>swells</key>
24
+ <dict>
25
+ <key>NSStringFormatSpecTypeKey</key>
26
+ <string>NSStringPluralRuleType</string>
27
+ <key>NSStringFormatValueTypeKey</key>
28
+ <string>d</string>
29
+ <key>other</key>
30
+ <string>너울 %d개 접근 중</string>
31
+ </dict>
32
+ </dict>
33
+ <key>spots.saved.count</key>
34
+ <dict>
35
+ <key>NSStringLocalizedFormatKey</key>
36
+ <string>%#@spots@</string>
37
+ <key>spots</key>
38
+ <dict>
39
+ <key>NSStringFormatSpecTypeKey</key>
40
+ <string>NSStringPluralRuleType</string>
41
+ <key>NSStringFormatValueTypeKey</key>
42
+ <string>d</string>
43
+ <key>other</key>
44
+ <string>저장된 스팟 %d곳</string>
45
+ </dict>
46
+ </dict>
47
+ <key>alerts.active.count</key>
48
+ <dict>
49
+ <key>NSStringLocalizedFormatKey</key>
50
+ <string>%#@alerts@</string>
51
+ <key>alerts</key>
52
+ <dict>
53
+ <key>NSStringFormatSpecTypeKey</key>
54
+ <string>NSStringPluralRuleType</string>
55
+ <key>NSStringFormatValueTypeKey</key>
56
+ <string>d</string>
57
+ <key>other</key>
58
+ <string>활성 경보 %d건</string>
59
+ </dict>
60
+ </dict>
61
+ </dict>
62
+ </plist>
@@ -0,0 +1,107 @@
1
+ # Worked example: a settings screen in German, Russian and Arabic
2
+
3
+ Input → output oracle for `locale-check`. Shows the order findings go in (what crashes, what
4
+ shows wrong, what overflows, what is only style), a mechanical fix written out, a plural set
5
+ judged by the target language, and a wording problem handed to a translator instead of
6
+ rewritten.
7
+
8
+ ## Input
9
+
10
+ > Release candidate for the new Settings screen. Source is `en.json`; the translations are
11
+ > `de.json`, `ru.json` and `ar.json`. The toggle labels have 24 characters on a phone
12
+ > (`budget.json`). Good to go?
13
+
14
+ `en.json`
15
+
16
+ ```json
17
+ {
18
+ "settings": {
19
+ "title": "Settings",
20
+ "sync_toggle": "Sync over mobile data",
21
+ "storage": "{used} of {total} used",
22
+ "devices_one": "{{count}} device signed in",
23
+ "devices_other": "{{count}} devices signed in",
24
+ "sign_out_all": "Sign out of <b>all</b> devices?",
25
+ "last_backup": "{when, select, today {Backed up today} yesterday {Backed up yesterday} other {Backed up on {date}}}"
26
+ }
27
+ }
28
+ ```
29
+
30
+ `de.json`
31
+
32
+ ```json
33
+ {
34
+ "settings": {
35
+ "title": "Einstellungen",
36
+ "sync_toggle": "Über mobile Daten synchronisieren",
37
+ "storage": "{used} von {total} belegt",
38
+ "devices_one": "{{count}} Gerät angemeldet",
39
+ "devices_other": "{{count}} Geräte angemeldet",
40
+ "sign_out_all": "Von <b>allen</b> Geräten abmelden?",
41
+ "last_backup": "{when, select, heute {Heute gesichert} gestern {Gestern gesichert} other {Gesichert am {date}}}"
42
+ }
43
+ }
44
+ ```
45
+
46
+ `ru.json`
47
+
48
+ ```json
49
+ {
50
+ "settings": {
51
+ "title": "Настройки",
52
+ "sync_toggle": "Синхр. по мобильной сети",
53
+ "storage": "Использовано {used}",
54
+ "devices_one": "{{count}} устройство",
55
+ "devices_other": "{{count}} устройств",
56
+ "sign_out_all": "Выйти на <b>всех</b> устройствах?",
57
+ "last_backup": "{when, select, today {Сохранено сегодня} yesterday {Сохранено вчера} other {Сохранено {date}}}"
58
+ }
59
+ }
60
+ ```
61
+
62
+ `ar.json`: every key present; `devices` has all six forms; `sync_toggle` is
63
+ "المزامنة عبر بيانات الجوال" (25 characters).
64
+
65
+ `budget.json`: `{"keys": {"settings.sync_toggle": 24}}`
66
+
67
+ ## Output
68
+
69
+ **Not safe to ship yet: 2 failures in German, 2 in Russian and 1 in Arabic.** German's
70
+ backup line will show the fallback text for "today" and "yesterday", and Russian's storage
71
+ line drops the total.
72
+
73
+ **Failures**
74
+
75
+ | Locale | Key | What breaks | Source | Target | Fix |
76
+ |---|---|---|---|---|---|
77
+ | de | `settings.last_backup` | The select keywords were translated, so "today" and "yesterday" never match and every backup reads "Gesichert am …" | `{when, select, today {…} yesterday {…} other {…}}` | `{when, select, heute {…} gestern {…} other {…}}` | `{when, select, today {Heute gesichert} yesterday {Gestern gesichert} other {Gesichert am {date}}}` |
78
+ | ru | `settings.storage` | `{total}` dropped: the line says how much is used, not of what | `{used} of {total} used` | `Использовано {used}` | `Использовано {used} из {total}` |
79
+ | ru | `settings.devices` | Russian needs `few` and `many` as well: "3 устройств" is wrong, it's "3 устройства" | one, other | one, other | add `devices_few`: `{{count}} устройства` (2–4, 22–24, …) and `devices_many`: `{{count}} устройств` (5–20, 25–30, …); the existing `other` covers fractions |
80
+ | de | `settings.sync_toggle` | 33 characters on a 24-character toggle: it will wrap or truncate | Sync over mobile data | Über mobile Daten synchronisieren | needs a translator: a shorter wording such as "Sync über Mobilfunk" (19) for them to confirm |
81
+ | ar | `settings.sync_toggle` | 25 characters, one over the toggle's 24 | Sync over mobile data | المزامنة عبر بيانات الجوال | needs a translator |
82
+
83
+ **Warnings**
84
+
85
+ | Locale | Key | Note |
86
+ |---|---|---|
87
+ | ru | `settings.sync_toggle` | "Синхр." is an abbreviation the source doesn't use: fits the budget, but worth a translator's look |
88
+
89
+ **Not checked:** only the toggle has a budget, so the other strings' lengths weren't checked.
90
+
91
+ I haven't changed the files. I can write `de.fixed.json` and `ru.fixed.json` with the two
92
+ mechanical fixes (the select keywords and `{total}`) and the Russian plural forms; the
93
+ toggle wording stays with the translators.
94
+
95
+ ## Why this is the oracle
96
+
97
+ - **Crashes and wrong screens before overflow, overflow before style.** The translated select
98
+ keywords come first because they silently show the wrong sentence to every German user.
99
+ - **Plurals are judged by Russian's rules, not English's.** Two forms pass a read-through and
100
+ fail every count from 2 to 4.
101
+ - **A mechanical fix is written out; a wording fix is not.** `{total}` is restored where Russian
102
+ grammar puts it, while the over-budget toggle goes to a translator with a suggestion marked
103
+ as one.
104
+
105
+ A cheaper pass answers "looks good, a couple of strings are long". It misses the select
106
+ keywords, because "heute" reads as a correct translation of "today", and it ships "3
107
+ устройств".
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "locale-check",
3
+ "version": "0.1.0",
4
+ "description": "Check a product's translations against the source strings before they ship — every key present, every placeholder ({name}, %s, %1$d, ICU plural and select) carried over intact, the plural forms each language needs, markup tags balanced, and strings over their character budget — with a script that reads JSON, ARB, gettext .po, Android strings.xml and iOS .strings, and lists each problem with its key and locale. Use when someone asks to \"check the translations\", \"QA these locale files\", \"will the German fit\", \"why does the French build crash on this string\", or hands over locale files before a release.",
5
+ "entrypoint": "SKILL.md",
6
+ "deps": {
7
+ "npm": [],
8
+ "pip": []
9
+ },
10
+ "env": {
11
+ "required": [],
12
+ "optional": []
13
+ },
14
+ "related": [
15
+ "content-design",
16
+ "ux-writing"
17
+ ],
18
+ "handoff": [
19
+ {
20
+ "to": "ux-writing",
21
+ "when": "a source string is the cause: too long for its slot in every language, two strings for one concept, or a sentence built from fragments",
22
+ "purpose": "Rewrite the source string so every translation can fit and agree.",
23
+ "fallback": "If ux-writing is absent, name the source string, the slot and its budget, and say why it can't be translated well as written."
24
+ }
25
+ ],
26
+ "tags": [
27
+ "localization",
28
+ "l10n",
29
+ "i18n",
30
+ "translation-qa",
31
+ "plurals",
32
+ "placeholders",
33
+ "icu"
34
+ ],
35
+ "permissions": {
36
+ "network": [],
37
+ "commands": [],
38
+ "files": "named-paths",
39
+ "notes": "Reads the string files and the budget file it is given, and writes the report to the path passed with -o."
40
+ },
41
+ "model": {
42
+ "tier": "standard",
43
+ "rationale": "The script finds every mechanical defect; the model ranks them by what breaks first, writes the mechanical fixes and tells a wrong-meaning translation from an acceptable one."
44
+ }
45
+ }