Skip to content

Commit 18a48a4

Browse files
authored
feat: trim to 18 active languages, add active flag, multilingual test suite (#104)
Major pivot from 51 languages to 18 actively maintained ones. Adds `active: true/false` to languages.json so forks can re-enable others. Languages retained: ar, de, en, es, fr, hi, id, it, ja, ko, pl, pt-br, ru, th, tr, uk, vi, zh — covering major dev populations and script families (Latin, CJK, Cyrillic, Arabic, Devanagari, Thai). Changes: - languages.json: added `active` field to all 51 entries - Stripped 2,633 inactive locale entries from 83 .locales.jsonl files - Fixed duplicate entries in ea/tasks/tasks.locales.jsonl - Filled gaps: pii-free (hi), environment (13 languages) - ways-cli: `is_language_active()` and `get_active_languages()` helpers - All consumers respect active flag: corpus, tune, template, language, util, pack-locales.sh - New Makefile targets: test-unit, test-lang, test-locales, test-multilingual - Automated test: tests/test-multilingual.sh (18 prompts across 12 languages) - Interactive test: tests/multilingual-test.md (16-step protocol) - Updated all interactive tests to use `bin/ways match` explicitly
1 parent c34f012 commit 18a48a4

100 files changed

Lines changed: 2237 additions & 437 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ hooks/ways/.obsidian/
9191
!scripts/doc-graph.sh
9292
!scripts/install.sh
9393
!scripts/project-pulse
94+
!scripts/test-locales.py
9495

9596
# Governance traceability (separable)
9697
# CLI tools (root symlinks to implementation scripts)

Makefile

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# Update: make update
77

88
.DEFAULT_GOAL := help
9-
.PHONY: setup install uninstall update clean help ways ways-rebuild test test-sim release
9+
.PHONY: setup install uninstall update clean help ways ways-rebuild test test-unit test-sim test-lang test-locales test-multilingual release
1010

1111
WAYS_BIN = bin/ways
1212
XDG_BIN = $(or $(XDG_BIN_HOME),$(HOME)/.local/bin)
@@ -21,8 +21,12 @@ help:
2121
@echo " make update Pull latest changes and re-run install"
2222
@echo " make ways Get ways binary (download or build from source)"
2323
@echo " make ways-rebuild Force rebuild ways from source"
24-
@echo " make test Smoke test the ways binary"
24+
@echo " make test Run all tests (smoke + unit + sim + lang)"
25+
@echo " make test-unit Run Rust unit tests"
2526
@echo " make test-sim Run session simulator (8 scenarios)"
27+
@echo " make test-lang Validate active language coverage"
28+
@echo " make test-locales Check locale files for gaps and duplicates"
29+
@echo " make test-multilingual Verify multilingual way matching (18 languages)"
2630
@echo " make release Build release binary for current platform"
2731
@echo " make uninstall Remove ways from PATH"
2832
@echo " make clean Remove build artifacts"
@@ -91,18 +95,42 @@ ways-rebuild:
9195

9296
# --- Test ---
9397

94-
test: ways
98+
test: test-smoke test-unit test-sim test-lang test-locales test-multilingual
99+
@echo "All tests passed."
100+
101+
test-smoke: ways
95102
@echo "Smoke testing ways binary..."
96103
@$(WAYS_BIN) --version
97104
@$(WAYS_BIN) lint --check --global && echo " lint: PASS"
98105
@$(WAYS_BIN) match "write a unit test" >/dev/null && echo " match: PASS"
99106
@$(WAYS_BIN) graph --output /dev/null && echo " graph: PASS"
100-
@echo "All smoke tests passed."
107+
@echo "Smoke tests passed."
108+
109+
test-unit:
110+
@echo "Running Rust unit tests..."
111+
@cargo test --manifest-path tools/ways-cli/Cargo.toml --bin ways --quiet
112+
@echo "Unit tests passed."
101113

102114
test-sim: ways
103115
@echo "Running session simulator (8 scenarios)..."
104116
@cargo test --manifest-path tools/ways-cli/Cargo.toml --test session_sim -- --test-threads=1
105-
@echo "All simulation scenarios passed."
117+
@echo "Simulation tests passed."
118+
119+
test-lang: ways
120+
@echo "Validating active language coverage..."
121+
@$(WAYS_BIN) language --json | python3 -c "\
122+
import json,sys; d=json.load(sys.stdin); \
123+
active=d['locales_found']; \
124+
print(f' Active locales in corpus: {len(active)}'); \
125+
assert len(active) > 0, 'No active locales found in corpus'" \
126+
&& echo " Language coverage: PASS"
127+
128+
test-locales:
129+
@echo "Checking locale files for gaps and duplicates..."
130+
@python3 scripts/test-locales.py
131+
132+
test-multilingual: ways
133+
@bash tests/test-multilingual.sh
106134

107135
# --- Release ---
108136

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
{"lang":"ar","description":"إعداد الإحاطة الصباحية وملخص الأحداث الليلية","vocabulary":"إحاطة صباحية ملخص ليلي تقرير يومي مستجدات","embed_threshold":0.56}
2-
{"lang":"de","description":"Morgendliches Briefing, was ist über Nacht passiert, Tagesübersicht über alle Posteingänge und Kalender","vocabulary":"Morgenbriefing Tagesübersicht aufholen was habe ich verpasst Zusammenfassung Prioritäten Posteingang Kalender Überblick","embed_threshold":0.69}
3-
{"lang":"es","description":"Resumen matutino, ponerse al día con lo que pasó durante la noche","vocabulary":"ponerse al día resumen matutino inicio del día agenda prioridades briefing","embed_threshold":0.62}
4-
{"lang":"ja","description":"朝のブリーフィング、昨夜の出来事の要約、一日の予定確認","vocabulary":"朝礼 ブリーフィング 要約 まとめ 予定 優先事項 今日のタスク","embed_threshold":0.7}
1+
{"lang": "ar", "description": "إعداد الإحاطة الصباحية وملخص الأحداث الليلية", "vocabulary": "إحاطة صباحية ملخص ليلي تقرير يومي مستجدات", "embed_threshold": 0.56}
2+
{"lang": "de", "description": "Morgendliches Briefing, was ist über Nacht passiert, Tagesübersicht über alle Posteingänge und Kalender", "vocabulary": "Morgenbriefing Tagesübersicht aufholen was habe ich verpasst Zusammenfassung Prioritäten Posteingang Kalender Überblick", "embed_threshold": 0.69}
3+
{"lang": "es", "description": "Resumen matutino, ponerse al día con lo que pasó durante la noche", "vocabulary": "ponerse al día resumen matutino inicio del día agenda prioridades briefing", "embed_threshold": 0.62}
4+
{"lang": "ja", "description": "朝のブリーフィング、昨夜の出来事の要約、一日の予定確認", "vocabulary": "朝礼 ブリーフィング 要約 まとめ 予定 優先事項 今日のタスク", "embed_threshold": 0.7}
5+
{"lang": "hi", "description": "सुबह की ब्रीफिंग, रात भर में क्या हुआ इसका सारांश, दिन की समीक्षा", "vocabulary": "ब्रीफिंग सुबह सारांश रात अपडेट प्राथमिकता दैनिक इनबॉक्स कैलेंडर"}
6+
{"lang": "id", "description": "Briefing pagi, ringkasan kejadian semalam, tinjauan hari ini", "vocabulary": "briefing pagi ringkasan semalam tinjauan hari prioritas pembaruan kotak masuk kalender"}
7+
{"lang": "it", "description": "Briefing mattutino, riepilogo notturno, panoramica della giornata", "vocabulary": "briefing mattutino riepilogo notturno panoramica giornata priorità aggiornamento posta calendario"}
8+
{"lang": "ko", "description": "아침 브리핑, 밤사이 일어난 일 요약, 하루 일정 확인", "vocabulary": "브리핑 아침 요약 야간 일정 우선순위 업데이트 하루 받은편지함 캘린더"}
9+
{"lang": "th", "description": "สรุปข้อมูลตอนเช้า ทบทวนเหตุการณ์ข้ามคืน ภาพรวมประจำวัน", "vocabulary": "บรีฟฟิ่ง เช้า สรุป ข้ามคืน ภาพรวม วัน ลำดับความสำคัญ กล่องจดหมาย ปฏิทิน"}
10+
{"lang": "tr", "description": "Sabah brifing, gece boyunca neler olduğunun özeti, günlük genel bakış", "vocabulary": "brifing sabah özet gece günlük genel bakış öncelikler gelen kutusu takvim"}
11+
{"lang": "uk", "description": "Ранковий брифінг, підсумок нічних подій, огляд дня", "vocabulary": "брифінг ранковий підсумок ніч огляд день пріоритети оновлення календар"}
12+
{"lang": "vi", "description": "Tóm tắt buổi sáng, tổng hợp sự kiện qua đêm, tổng quan ngày", "vocabulary": "tóm tắt sáng briefing đêm tổng quan ngày ưu tiên hộp thư lịch"}
13+
{"lang": "zh", "description": "早间简报,夜间事件摘要,全天日程概览", "vocabulary": "简报 早间 摘要 夜间 日程 优先级 收件箱 日历 概览"}
14+
{"lang": "fr", "description": "Briefing matinal, rattraper ce qui s'est passé pendant la nuit, résumé de la journée", "vocabulary": "briefing matinal résumé nuit agenda priorités boîte de réception calendrier rattraper"}
15+
{"lang": "pl", "description": "Poranny briefing, podsumowanie tego co wydarzyło się w nocy, przegląd dnia", "vocabulary": "briefing poranny podsumowanie przegląd dnia priorytety skrzynka kalendarz"}
16+
{"lang": "pt-br", "description": "Resumo da manhã, o que aconteceu durante a noite, visão geral do dia", "vocabulary": "resumo manhã briefing agenda prioridades caixa de entrada calendário atualização"}
17+
{"lang": "ru", "description": "Утренний брифинг, сводка событий за ночь, обзор дня", "vocabulary": "брифинг утренний сводка обзор дня приоритеты почта календарь"}
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
{"lang":"ar","description":"جدولة الاجتماعات والتحقق من التوفر في التقويم","vocabulary":"تقويم اجتماع موعد جدولة توفر حجز","embed_threshold":0.69}
2-
{"lang":"de","description":"Termine planen, Verfügbarkeit prüfen, Zeitblöcke im Kalender reservieren, Besprechungen erstellen, freie Zeitfenster finden","vocabulary":"Termin Kalender Verfügbarkeit Zeitblock Besprechung Einladung Erinnerung verschieben freier Slot buchen Zeitzone Terminplanung","embed_threshold":0.74}
3-
{"lang":"es","description":"Agendar reuniones, consultar disponibilidad, bloquear tiempo, eventos del calendario","vocabulary":"agendar calendario disponibilidad bloquear tiempo evento reunión invitación horario","embed_threshold":0.68}
4-
{"lang":"ja","description":"会議のスケジュール調整、空き時間の確認、カレンダー管理","vocabulary":"スケジュール カレンダー 予定 会議 空き時間 予約 招待 日程調整","embed_threshold":0.76}
1+
{"lang": "ar", "description": "جدولة الاجتماعات والتحقق من التوفر في التقويم", "vocabulary": "تقويم اجتماع موعد جدولة توفر حجز", "embed_threshold": 0.69}
2+
{"lang": "de", "description": "Termine planen, Verfügbarkeit prüfen, Zeitblöcke im Kalender reservieren, Besprechungen erstellen, freie Zeitfenster finden", "vocabulary": "Termin Kalender Verfügbarkeit Zeitblock Besprechung Einladung Erinnerung verschieben freier Slot buchen Zeitzone Terminplanung", "embed_threshold": 0.74}
3+
{"lang": "es", "description": "Agendar reuniones, consultar disponibilidad, bloquear tiempo, eventos del calendario", "vocabulary": "agendar calendario disponibilidad bloquear tiempo evento reunión invitación horario", "embed_threshold": 0.68}
4+
{"lang": "ja", "description": "会議のスケジュール調整、空き時間の確認、カレンダー管理", "vocabulary": "スケジュール カレンダー 予定 会議 空き時間 予約 招待 日程調整", "embed_threshold": 0.76}
5+
{"lang": "hi", "description": "मीटिंग शेड्यूल करें, उपलब्धता जांचें, कैलेंडर पर समय ब्लॉक करें", "vocabulary": "कैलेंडर मीटिंग शेड्यूल उपलब्धता समय इवेंट निमंत्रण रिमाइंडर"}
6+
{"lang": "id", "description": "Menjadwalkan rapat, memeriksa ketersediaan, memblokir waktu di kalender", "vocabulary": "kalender rapat jadwal ketersediaan waktu acara undangan pengingat"}
7+
{"lang": "it", "description": "Pianificare riunioni, verificare disponibilità, bloccare tempo nel calendario", "vocabulary": "calendario riunione pianificare disponibilità tempo evento invito promemoria"}
8+
{"lang": "ko", "description": "회의 일정 잡기, 가용 시간 확인, 캘린더에 시간 차단", "vocabulary": "캘린더 회의 일정 가용성 시간 이벤트 초대 알림"}
9+
{"lang": "fr", "description": "Planifier des réunions, vérifier les disponibilités, gérer les événements du calendrier", "vocabulary": "calendrier réunion disponibilité planifier événement invitation rappel créneau réserver"}
10+
{"lang": "pl", "description": "Planowanie spotkań, sprawdzanie dostępności, rezerwacja czasu w kalendarzu", "vocabulary": "kalendarz spotkanie termin planowanie dostępność rezerwacja zaproszenie przypomnienie"}
11+
{"lang": "pt-br", "description": "Marcar reuniões, checar disponibilidade, bloquear horário na agenda", "vocabulary": "agenda reunião compromisso marcar disponibilidade bloquear convite lembrete horário"}
12+
{"lang": "ru", "description": "Планирование встреч, проверка доступности, бронирование времени в календаре", "vocabulary": "календарь встреча планирование доступность бронирование приглашение напоминание слот"}
13+
{"lang": "th", "description": "นัดหมายประชุม ตรวจสอบตารางว่าง จัดการปฏิทิน", "vocabulary": "ปฏิทิน ประชุม นัดหมาย ตารางว่าง กิจกรรม เตือน จอง เวลา"}
14+
{"lang": "tr", "description": "Toplantı planlama, müsaitlik kontrolü, takvim etkinlikleri yönetimi", "vocabulary": "takvim toplantı planlama müsaitlik etkinlik hatırlatıcı randevu saat dilimi"}
15+
{"lang": "uk", "description": "Планування зустрічей, перевірка доступності, керування подіями календаря", "vocabulary": "календар зустріч планування доступність подія нагадування бронювання часовий пояс"}
16+
{"lang": "vi", "description": "Lên lịch họp, kiểm tra lịch trống, quản lý sự kiện lịch", "vocabulary": "lịch họp đặt lịch khả dụng sự kiện nhắc nhở đặt chỗ múi giờ"}
17+
{"lang": "zh", "description": "安排会议、查看日程空闲、管理日历事件", "vocabulary": "日历 会议 安排 空闲 事件 提醒 预约 时区 日程"}
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
{"lang":"ar","description":"إدارة محادثات الفريق ومنصات التراسل","vocabulary":"محادثة فريق رسائل تواصل منصة تراسل","embed_threshold":0.64}
2-
{"lang":"de","description":"Team-Chat und Messaging-Plattformen, Nachrichten lesen und mit Freigabe senden, Kommunikationskanäle","vocabulary":"Teams Chat Nachricht Slack Kanal ungelesen Konversation Direktnachricht Gruppenchat senden antworten Benachrichtigung Erwähnung","embed_threshold":0.66}
3-
{"lang":"es","description":"Chat de equipo y plataformas de mensajería, envío de mensajes","vocabulary":"teams chat mensaje slack canal no leído conversación respuesta notificación","embed_threshold":0.62}
4-
{"lang":"ja","description":"チームチャットやメッセージングの管理、メッセージ送信","vocabulary":"チャット メッセージ 通知 チャンネル 返信 未読 会話 連絡","embed_threshold":0.61}
1+
{"lang": "ar", "description": "إدارة محادثات الفريق ومنصات التراسل", "vocabulary": "محادثة فريق رسائل تواصل منصة تراسل", "embed_threshold": 0.64}
2+
{"lang": "de", "description": "Team-Chat und Messaging-Plattformen, Nachrichten lesen und mit Freigabe senden, Kommunikationskanäle", "vocabulary": "Teams Chat Nachricht Slack Kanal ungelesen Konversation Direktnachricht Gruppenchat senden antworten Benachrichtigung Erwähnung", "embed_threshold": 0.66}
3+
{"lang": "es", "description": "Chat de equipo y plataformas de mensajería, envío de mensajes", "vocabulary": "teams chat mensaje slack canal no leído conversación respuesta notificación", "embed_threshold": 0.62}
4+
{"lang": "ja", "description": "チームチャットやメッセージングの管理、メッセージ送信", "vocabulary": "チャット メッセージ 通知 チャンネル 返信 未読 会話 連絡", "embed_threshold": 0.61}
5+
{"lang": "fr", "description": "Chat d'équipe et plateformes de messagerie, lecture et envoi de messages", "vocabulary": "chat message équipe canal non lu conversation réponse notification"}
6+
{"lang": "hi", "description": "टीम चैट और मैसेजिंग प्लेटफॉर्म, संदेश पढ़ना और भेजना", "vocabulary": "चैट संदेश टीम चैनल अपठित बातचीत जवाब सूचना"}
7+
{"lang": "id", "description": "Chat tim dan platform pesan, membaca dan mengirim pesan", "vocabulary": "chat pesan tim kanal belum dibaca percakapan balas notifikasi"}
8+
{"lang": "it", "description": "Chat di team e piattaforme di messaggistica, leggere e inviare messaggi", "vocabulary": "chat messaggio team canale non letto conversazione risposta notifica"}
9+
{"lang": "ko", "description": "팀 채팅 및 메시징 플랫폼, 메시지 읽기 및 보내기", "vocabulary": "채팅 메시지 팀 채널 읽지않음 대화 답장 알림"}
10+
{"lang": "pl", "description": "Czat zespołowy i platformy komunikacyjne, czytanie i wysyłanie wiadomości", "vocabulary": "czat wiadomości teams slack kanał nieprzeczytane rozmowa odpowiedź powiadomienie"}
11+
{"lang": "pt-br", "description": "Chat de equipe e plataformas de mensagens, ler e enviar mensagens", "vocabulary": "chat mensagens teams slack canal não lida conversa resposta notificação"}
12+
{"lang": "ru", "description": "Командный чат и платформы обмена сообщениями, чтение и отправка сообщений", "vocabulary": "чат сообщения teams slack канал непрочитанное переписка ответ уведомление"}
13+
{"lang": "th", "description": "แชททีมและแพลตฟอร์มรับส่งข้อความ อ่านและส่งข้อความ", "vocabulary": "แชท ข้อความ ทีม ช่อง ยังไม่อ่าน สนทนา ตอบ แจ้งเตือน"}
14+
{"lang": "tr", "description": "Takım sohbeti ve mesajlaşma platformları, mesaj okuma ve gönderme", "vocabulary": "sohbet mesaj takım kanal okunmamış konuşma yanıt bildirim"}
15+
{"lang": "uk", "description": "Командний чат та платформи обміну повідомленнями", "vocabulary": "чат повідомлення команда канал непрочитане розмова відповідь сповіщення"}
16+
{"lang": "vi", "description": "Chat nhóm và nền tảng nhắn tin, đọc và gửi tin nhắn", "vocabulary": "chat tin nhắn nhóm kênh chưa đọc hội thoại trả lời thông báo"}
17+
{"lang": "zh", "description": "团队聊天和消息平台,阅读和发送消息", "vocabulary": "聊天 消息 团队 频道 未读 对话 回复 通知"}

0 commit comments

Comments
 (0)