feat(t-paliad-151) frontend: friendly errors for remote-Paliadin codes
Extends the SSE error switch in frontend/src/client/paliadin.ts' friendlyErrorMessage to map four new error codes from RemotePaliadin Service into localised messages: - mriver_unreachable: mRiver is offline / paliadin-shim unreachable (DE: "mRiver ist offline — Paliadin nicht erreichbar. Mach mRiver an, oder nutze Paliadin lokal mit ./paliad." EN: "mRiver is offline — Paliadin can't reach it. Wake mRiver, or run Paliadin locally with ./paliad.") - shim_auth_failed: SSH key / authorized_keys mismatch (Permission denied) - shim_error / bootstrap_failed: generic remote-shim failure - timeout: Claude didn't write the response file in 60 s Adds the matching i18n keys (DE + EN) plus the type-union entries in i18n-keys.ts so the t() typecheck stays sound. The old codes (tmux_unavailable, connection_lost, upstream) are unchanged — local-PoC deployments keep their existing UX. Frontend `bun run build` clean: 1886 keys (unchanged sync). Refs m/paliad#12
This commit is contained in:
@@ -1558,6 +1558,10 @@ const translations: Record<Lang, Record<string, string>> = {
|
|||||||
"paliadin.stop": "Stop",
|
"paliadin.stop": "Stop",
|
||||||
"paliadin.reset": "Neue Unterhaltung",
|
"paliadin.reset": "Neue Unterhaltung",
|
||||||
"paliadin.error.local_only": "Paliadin läuft nur lokal. Diese Instanz hat kein tmux/claude installiert — lokal mit ./paliad starten.",
|
"paliadin.error.local_only": "Paliadin läuft nur lokal. Diese Instanz hat kein tmux/claude installiert — lokal mit ./paliad starten.",
|
||||||
|
"paliadin.error.mriver_unreachable": "mRiver ist offline — Paliadin nicht erreichbar. Mach mRiver an, oder nutze Paliadin lokal mit ./paliad.",
|
||||||
|
"paliadin.error.shim_auth_failed": "Paliadin-Authentifizierung fehlgeschlagen. SSH-Schlüssel oder Berechtigung auf mRiver prüfen.",
|
||||||
|
"paliadin.error.shim_error": "Paliadin-Fehler auf mRiver. tmux/claude-Pane prüfen.",
|
||||||
|
"paliadin.error.timeout": "Paliadin antwortet nicht (Timeout 60s). Nochmal versuchen.",
|
||||||
"paliadin.error.connection_lost": "Verbindung verloren.",
|
"paliadin.error.connection_lost": "Verbindung verloren.",
|
||||||
"paliadin.error.upstream": "Fehler beim Senden.",
|
"paliadin.error.upstream": "Fehler beim Senden.",
|
||||||
"nav.admin.paliadin": "Paliadin Monitor",
|
"nav.admin.paliadin": "Paliadin Monitor",
|
||||||
@@ -3553,6 +3557,10 @@ const translations: Record<Lang, Record<string, string>> = {
|
|||||||
"paliadin.stop": "Stop",
|
"paliadin.stop": "Stop",
|
||||||
"paliadin.reset": "New conversation",
|
"paliadin.reset": "New conversation",
|
||||||
"paliadin.error.local_only": "Paliadin only runs locally. This instance has no tmux/claude installed — start it locally via ./paliad.",
|
"paliadin.error.local_only": "Paliadin only runs locally. This instance has no tmux/claude installed — start it locally via ./paliad.",
|
||||||
|
"paliadin.error.mriver_unreachable": "mRiver is offline — Paliadin can't reach it. Wake mRiver, or run Paliadin locally with ./paliad.",
|
||||||
|
"paliadin.error.shim_auth_failed": "Paliadin auth failed. Check the SSH key or authorized_keys on mRiver.",
|
||||||
|
"paliadin.error.shim_error": "Paliadin error on mRiver. Check the tmux/claude pane.",
|
||||||
|
"paliadin.error.timeout": "Paliadin didn't respond in time (60s). Try again.",
|
||||||
"paliadin.error.connection_lost": "Connection lost.",
|
"paliadin.error.connection_lost": "Connection lost.",
|
||||||
"paliadin.error.upstream": "Send failed.",
|
"paliadin.error.upstream": "Send failed.",
|
||||||
"nav.admin.paliadin": "Paliadin Monitor",
|
"nav.admin.paliadin": "Paliadin Monitor",
|
||||||
|
|||||||
@@ -210,8 +210,24 @@ function friendlyErrorMessage(data: unknown): string {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(data) as { code?: string };
|
const parsed = JSON.parse(data) as { code?: string };
|
||||||
if (parsed.code === "tmux_unavailable") {
|
switch (parsed.code) {
|
||||||
return t("paliadin.error.local_only");
|
case "tmux_unavailable":
|
||||||
|
// Local PoC path: paliad is running on a host without tmux/claude
|
||||||
|
// (typically the legacy laptop-only build).
|
||||||
|
return t("paliadin.error.local_only");
|
||||||
|
case "mriver_unreachable":
|
||||||
|
// t-paliad-151: prod path's mRiver is offline (laptop asleep, off
|
||||||
|
// tailnet, or paliadin-shim missing).
|
||||||
|
return t("paliadin.error.mriver_unreachable");
|
||||||
|
case "shim_auth_failed":
|
||||||
|
// SSH key wrong or authorized_keys drifted.
|
||||||
|
return t("paliadin.error.shim_auth_failed");
|
||||||
|
case "shim_error":
|
||||||
|
case "bootstrap_failed":
|
||||||
|
// Generic remote shim failure or system-prompt bootstrap error.
|
||||||
|
return t("paliadin.error.shim_error");
|
||||||
|
case "timeout":
|
||||||
|
return t("paliadin.error.timeout");
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Not JSON — fall through to the generic connection-lost message
|
// Not JSON — fall through to the generic connection-lost message
|
||||||
|
|||||||
@@ -1423,6 +1423,10 @@ export type I18nKey =
|
|||||||
| "paliadin.empty"
|
| "paliadin.empty"
|
||||||
| "paliadin.error.connection_lost"
|
| "paliadin.error.connection_lost"
|
||||||
| "paliadin.error.local_only"
|
| "paliadin.error.local_only"
|
||||||
|
| "paliadin.error.mriver_unreachable"
|
||||||
|
| "paliadin.error.shim_auth_failed"
|
||||||
|
| "paliadin.error.shim_error"
|
||||||
|
| "paliadin.error.timeout"
|
||||||
| "paliadin.error.upstream"
|
| "paliadin.error.upstream"
|
||||||
| "paliadin.heading"
|
| "paliadin.heading"
|
||||||
| "paliadin.input.placeholder"
|
| "paliadin.input.placeholder"
|
||||||
|
|||||||
Reference in New Issue
Block a user