Skip to content

feat: add configurable home language for visible product strings - #2783

Open
thelad-dev wants to merge 9 commits into
kunchenguid:mainfrom
thelad-dev:feat/calm-sichtbare-texte-de
Open

feat: add configurable home language for visible product strings#2783
thelad-dev wants to merge 9 commits into
kunchenguid:mainfrom
thelad-dev:feat/calm-sichtbare-texte-de

Conversation

@thelad-dev

@thelad-dev thelad-dev commented Aug 22, 2026

Copy link
Copy Markdown

Intent

Firstmate soll um eine Home-Sprache erweitert werden. Die sichtbare Produktkommunikation folgt config/language; der Standard ist Englisch. Welche konkrete Sprache ein Home wählt — Deutsch, Spanisch, Französisch oder eine andere — ist eine lokale Home-Entscheidung und keine Festlegung im Upstream-Repo von kunchenguid. Zusätzliche Sprachen kommen als optionale Katalogdateien oder lokale Overlays, nicht als fest verdrahtete Default-Texte. Hintergrund-Diagnosen dürfen englisch bleiben. Die Änderung passt den bestehenden no-mistakes-PR nach kunchenguid/firstmate an, wie CONTRIBUTING verlangt.

What Changed

  • Neues Modul fm-language.ts liest config/language, merged optionale Kataloge unter languages/<tag>.json und lokale Overlays unter config/languages/<tag>.json und fällt bei fehlenden oder ungültigen Tags auf englische Quelltexte zurück.
  • Calm nutzt den Formatter für sichtbare Pi-Strings (/calm-Hilfe und Tool-Kollisionswarnungen) statt fest verdrahteter Texte.
  • Dokumentation in docs/configuration.md, docs/calm.md und AGENTS.md ergänzt, AFK-Skill auf Home-Sprache umgestellt und Shell-Tests für Standard-Englisch, Katalog-, Overlay- und Regionaltag-Fallback hinzugefügt.

Risk Assessment

✅ Low: The home-language resolver is small and well-bounded, prior review findings are resolved (docs restored, command-help lifecycle documented), and the change matches the stated intent without introducing reachable correctness or security regressions.

Testing

Ich habe die Sprachauflösung über die Calm-Extension-API gegen Default-Englisch, es-Pack/Overlay/Fallback und ein deutsches Home-Overlay geprüft; dabei zeigen CLI-Transkripte und ein HTML-Artefakt die sichtbaren Produkttexte. Eine Live-Pi-TUI-Screenshot-Evidenz war hier nicht möglich, weil weder tmux noch ein Browser verfügbar sind; stattdessen wurde das reale Extension-Interface ausgeführt.

Evidence: Home-Sprache: Resolver-Evidenz (Default, es, de, Warnung/Diagnose)
Home language resolver evidence
================================

[default / no config/language]
  /calm description: Toggle Firstmate's supported conversation-only transcript presentation.
  expected English: PASS

[invalid tag -> English fallback]
  /calm description: Toggle Firstmate's supported conversation-only transcript presentation.
  expected English: PASS

[tracked es.json pack]
  /calm description: Cambia la presentacion Calm de Firstmate.

[local config/languages/es.json overlay wins]
  /calm description: Cambia Calm desde un overlay local.

[es-mx falls back to es pack]
  /calm description: Cambia la presentacion Calm de Firstmate.

[local de overlay via config/language=de]
  /calm description: Schaltet Firstmates Calm-Darstellung um.

[German visible warning + English diagnostic]
  user notification: Firstmate Calm: Das eingebaute Tool "bash" wird bereits von einer anderen Erweiterung bereitgestellt; Calm funktioniert dafuer in dieser Sitzung moeglicherweise nicht vollstaendig.
  notification type: warning
  console diagnostic: Firstmate Calm: skipped claiming built-in "bash" because another extension already owns it.
Evidence: Offizieller test_home_language-Lauf
ok - Pi calm visible strings follow config/language, default to English, use a tracked pack, prefer a local overlay, and fall back from a regional tag
Evidence: Englische Default-Kollisionswarnung
ok - Default English home shows English collision warning and English diagnostic
Evidence: Gerendertes HTML mit sichtbaren Calm-Produkttexten (EN-Default vs. DE-Overlay)
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="utf-8">
  <title>Firstmate Home-Sprache – Calm-Oberflächentexte</title>
  <style>
    body { font-family: system-ui, sans-serif; max-width: 880px; margin: 2rem auto; line-height: 1.5; }
    h1 { font-size: 1.4rem; }
    section { margin: 1.5rem 0; padding: 1rem 1.25rem; border: 1px solid #ccc; border-radius: 8px; }
    .label { font-size: 0.85rem; color: #555; margin-bottom: 0.5rem; }
    .pi-command { background: #1e1e1e; color: #d4d4d4; padding: 0.75rem 1rem; border-radius: 6px; font-family: ui-monospace, monospace; }
    .pi-warning { background: #3b2f00; color: #ffe08a; padding: 0.75rem 1rem; border-radius: 6px; border-left: 4px solid #f0b429; }
    .pi-diagnostic { background: #f5f5f5; color: #333; padding: 0.75rem 1rem; border-radius: 6px; font-family: ui-monospace, monospace; font-size: 0.9rem; }
    .pass { color: #0a7a2f; font-weight: 600; }
  </style>
</head>
<body>
  <h1>Calm-Oberflächentexte folgen <code>config/language</code></h1>
  <p>Deutsch kommt aus einem lokalen Overlay (<code>config/languages/de.json</code>), nicht aus fest verdrahtetem Upstream-Text. Standard ohne Konfiguration ist Englisch.</p>

  <section>
    <div class="label">Standard (kein <code>config/language</code>) – /calm Hilfe</div>
    <div class="pi-command">/calm — Toggle Firstmate's supported conversation-only transcript presentation.</div>
    <p class="pass">PASS: Englisch als Default</p>
  </section>

  <section>
    <div class="label">Lokales Home mit <code>config/language=de</code> – /calm Hilfe</div>
    <div class="pi-command">/calm — Schaltet Firstmates Calm-Darstellung um.</div>
    <p class="pass">PASS: sichtbarer Produkttext aus lokalem Overlay</p>
  </section>

  <section>
    <div class="label">Lokales Home mit <code>config/language=de</code> – sichtbare Warnung bei Tool-Kollision</div>
    <div class="pi-warning">Firstmate Calm: Das eingebaute Tool "bash" wird bereits von einer anderen Erweiterung bereitgestellt; Calm funktioniert dafuer in dieser Sitzung moeglicherweise nicht vollstaendig.</div>
    <p class="pass">PASS: Benutzer-sichtbare Warnung auf Deutsch</p>
  </section>

  <section>
    <div class="label">Hintergrund-Diagnose (bleibt Englisch)</div>
    <div class="pi-diagnostic">Firstmate Calm: skipped claiming built-in "bash" because another extension already owns it.</div>
    <p class="pass">PASS: Diagnose nicht lokalisiert</p>
  </section>
</body>
</html>

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed (2) ✅
  • ⚠️ .pi/extensions/fm-calm.ts:483 - The /calm command description is resolved once at extension initialization via formatHomeString(language, &#34;calm.command.description&#34;), while config/calm is re-read on every session_start (line 421) and the collision warning re-reads config/language at notify time (lines 379–383). After the extension first loads, changing config/language and starting a new Pi session with /new, resume, or fork leaves the command help in the old language until a full Pi reload rebuilds extension registrations. docs/calm.md states both visible strings follow config/language, so this lifecycle gap is user-visible.

🔧 Fix: Calm-Hilfe-Lebensdauer in Doku festhalten
1 error still open:

  • 🚨 docs/configuration.md:388 - Commit 9a2830c accidentally deleted roughly 360 lines from docs/configuration.md: the watched-tools section is cut off mid-prose after announce_args, and entire sections for Relay (.env), Process-to-event sources, Spoken interface/captain inbox, and Environment variables are gone (file shrank from ~763 to ~390 lines). This removes operator documentation that architecture.md, remote-secondmates.md, verification/public-followup.md, and other docs link to via anchors such as #relay-env, #process-to-event-sources-stateprocevent, and #promised-public-replies-statepublic-followup.

🔧 Fix: configuration.md-Abschnitte wiederhergestellt
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • tests/fm-calm-pi-extension.test.shtest_home_language (Default Englisch, ungültiger Tag, es-Pack, lokales Overlay, es-mx-Fallback)
  • Erweitertes Node-Fixture gegen fm-calm.ts/fm-language.ts mit config/language=de und lokalem config/languages/de.json (deutscher /calm-Hilfetext, deutsch sichtbare Kollisionswarnung, englische Konsole)
  • Node-Fixture für englisches Default-Home: Kollisionswarnung und Diagnose bleiben Englisch
  • Prüfung, dass im Upstream keine fest verdrahteten Nicht-Englisch-Strings in .pi/extensions/ liegen und kein languages/-Verzeichnis im Repo existiert
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Reviews (4): Last reviewed commit: "no-mistakes: apply CI fixes" | Re-trigger Greptile

@thelad-dev thelad-dev changed the title fix(calm): use German for visible Pi UI strings feat: add configurable home language for visible product strings Aug 22, 2026
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

Opt-in home language for visible product strings. Default stays English; any other tag is a tracked pack or a local overlay. Calm wires two Pi strings through the resolver; background diagnostics stay English.

VISION:

  • One captain, one interface — presentation is welcome when opt-in. Aligns.
  • Authority is explicit — new capability as config/language, never a non-English default. Aligns.
  • Scripts own the mechanics — lookup and {name} formatting are deterministic. Aligns.
  • A restart is a non-event — the choice lives in gitignored config. The /calm help lifecycle (fixed until a Pi reload) is documented rather than hidden. Aligns.
  • Shared surface stays captain-agnostic — no non-English catalog is hardcoded upstream. Aligns.

Security: no. Language tags are regex-bounded before they become filenames; catalogs are JSON objects of strings only.

Overlap: AGENTS.md / docs/configuration.md also move in #2781 and #2784. tests/fm-calm-pi-extension.test.sh also moves in #2742. Do not land those together. The new fm-language.ts module is unique to this PR.

Fork CI approved (runs 32555816808 CI, 32555816824 and 32555834695 Require no-mistakes). no-mistakes/CI have not finished, so this is not merge-eligible yet.

Docs nit for the author, not a captain question: AGENTS.md and docs/configuration.md write the pack path as languages/.json (and as.json) instead of languages/<tag>.json.

This is waiting on CI, not on the captain.

@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

Follow-up after fork CI started: no-mistakes is red (blocking). The signature line is present, but the structured <!-- no-mistakes-pipeline-attestation:v1 ... --> comment is missing (needs no-mistakes >= 1.46.0). Re-run git push no-mistakes so that attestation lands in the PR body.

CI itself is still in progress (several portable/Herdr jobs running; coverage guard, repo invariants, and two parallel shards already green).

This is waiting on the author, not the captain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants