diff --git a/docs/i18n.md b/docs/i18n.md index e558e2c..3453a0f 100644 --- a/docs/i18n.md +++ b/docs/i18n.md @@ -61,13 +61,17 @@ | Area | Strings | Status | |---|---|---| -| `settings.*` | 125 (+ 41 in `common.*`, `col.*`, `confirm.*`, `toast.*`) | done | -| `artifacts.*` | 41 (+ 4 in `common.*`, 11 in `col.*`) | done | -| `sidebar.*` | 28 (+ 2 in `common.*`, 1 in `confirm.*`) | done | -| `messages.*` | ~27 | pending | +| `settings.*` | 125 (+ 41 across `common.*`, `col.*`, `confirm.*`, `toast.*`) | done | +| `artifacts.*` | 39 (+ 11 in `col.*`, 10 in `common.*`) | done | +| `sidebar.*` | 28 (+ 4 in `common.*`, 1 in `confirm.*`) | done | +| `messages.*` | 23 (+ 5 in `common.*`, 6 reused from `artifacts.*`) | done | | `chat.*` | ~21 | pending | | `ui.*` | ~20 | pending | +A parenthetical counts the words outside the area that the area's screens also +render — a shared word is written once in the vocabulary area and read from +there, so the same slug can appear in two parentheticals. + A slug can reach `t()` in three shapes — a plain literal, one arm of a ternary (`t(server.has_key ? 'settings.mcpKeyPlaceholder' : …)`) and a template literal — so counting occurrences means walking the whole argument list of every `t(` @@ -75,6 +79,15 @@ templates (text nodes, `placeholder`, `title`, `aria-label`, `label`, `alt`) plus keyed strings in ` - + +
diff --git a/webclient/dist/sw.js b/webclient/dist/sw.js index 356ac44..d0e65c0 100644 --- a/webclient/dist/sw.js +++ b/webclient/dist/sw.js @@ -8,13 +8,13 @@ * - /images/*: cache-first, capped — except the app's own artwork (below); * - everything dynamic (/api, /ws, /auth, /push, /content, ...): pass-through. * - * 9cf53dc088adc2d4 is stamped at build time (vite.config.js closeBundle) + * 8b32905768274a92 is stamped at build time (vite.config.js closeBundle) * with a digest of index.html + the hashed asset filenames — so sw.js bytes * change on every build, the browser picks the new SW up (served no-store), * and activation evicts caches from previous builds. */ -const VERSION = '9cf53dc088adc2d4'; +const VERSION = '8b32905768274a92'; const SHELL_CACHE = `navi-shell-${VERSION}`; const ASSETS_CACHE = `navi-assets-${VERSION}`; const IMAGES_CACHE = 'navi-images'; diff --git a/webclient/src/components/messages/AssistantMessage.vue b/webclient/src/components/messages/AssistantMessage.vue index a59ad9b..68e9e2b 100644 --- a/webclient/src/components/messages/AssistantMessage.vue +++ b/webclient/src/components/messages/AssistantMessage.vue @@ -13,11 +13,11 @@
- {{ entry.total }} tools + {{ t('messages.toolsCount', { n: entry.total }) }}
@@ -32,7 +32,7 @@
- Plan + {{ t('messages.plan') }}
@@ -78,14 +78,14 @@ { const pending = findPendingTool(props.msg.tools || []) if (!pending) return '' - return `Running ${toolDisplayName(pending)}...` + return t('messages.runningTool', { tool: toolDisplayName(pending) }) }) const turnActivityLabel = computed(() => { if (props.msg.done) return '' if (props.msg.statusLabel) return props.msg.statusLabel if (activeToolLabel.value) return activeToolLabel.value if (props.msg.text) return '' - if (hasVisibleToolProgress(props.msg.tools || [])) return 'Preparing next action...' - return 'Thinking...' + if (hasVisibleToolProgress(props.msg.tools || [])) return t('messages.preparingNext') + return t('messages.thinkingStatus') }) // Only history blocks (id `h_`) are persisted and can be rated. // Streaming / summary / error placeholders skip the rating UI. diff --git a/webclient/src/components/messages/CompressionNotice.vue b/webclient/src/components/messages/CompressionNotice.vue index 51fb3f5..1a0f189 100644 --- a/webclient/src/components/messages/CompressionNotice.vue +++ b/webclient/src/components/messages/CompressionNotice.vue @@ -1,14 +1,14 @@