verstak-docs/docs/superpowers/plans/2026-07-11-platform-localiz...

11 KiB

Platform Localization Implementation Plan

Execution note: implement task-by-task in the current session. Do not use subagents. Use TDD for every production boundary and keep commits scoped to a single repository.

Goal: Add persisted System/Russian/English language selection to Verstak Desktop, localize the shell and all official plugins, and establish the public SDK contract used by future multilingual plugins.

Architecture: Desktop owns the application preference, locale resolution, shell catalogs, safe plugin-catalog loading, and a generic runtime bridge. Each plugin owns its manifest and UI catalogs and accesses them through api.i18n. Manifest literals remain English fallbacks. Locale changes update mounted UI without remounting plugin components.

Tech stack: Go/Wails backend tests, Svelte 4 and plain JavaScript frontend, TypeScript SDK with Vitest, JSON Schema, browserless Node plugin smoke tests, Playwright mocked-Wails E2E.

Global Constraints

  • ~/git/verstak is UI reference only; do not copy its implementation.
  • Core must not contain official plugin messages or depend on official plugin IDs.
  • Official and third-party plugins use the same manifest and runtime API.
  • Store only system, ru, or en; default to system.
  • Resolve ru-* system locales to ru, everything else to en.
  • Do not remount plugins on locale changes or discard form/editor state.
  • Preserve existing unrelated generated Wails binding changes in the desktop worktree.
  • Add tests before production changes and observe each focused test fail before implementing its boundary.

Task 1: SDK localization contract

Files:

  • Modify verstak-sdk/schemas/manifest.json
  • Modify verstak-sdk/src/types.ts
  • Modify verstak-sdk/src/plugin-api.ts
  • Modify verstak-sdk/src/test-utils.ts
  • Modify verstak-sdk/src/plugin-api.test.ts
  • Generated by build: verstak-sdk/dist/*

Contract produced:

interface PluginLocalizationConfig {
  defaultLocale: string;
  locales: Record<string, string>;
}

interface PluginI18nAPI {
  getLocale(): 'ru' | 'en';
  t(key: string, params?: Record<string, string | number>, fallback?: string): string;
  onDidChangeLocale(listener: (locale: 'ru' | 'en') => void): Unsubscribe;
}
  • Add failing schema/type/mock tests for a valid manifest localization block, required default catalog, safe relative paths, API shape, fallback, interpolation, and locale-change notification.
  • Run npm test -- --run src/plugin-api.test.ts and confirm RED.
  • Add localization to the JSON Schema and TypeScript manifest types.
  • Add i18n to VerstakPluginAPI and configurable locale/messages to createMockPluginAPI.
  • Run focused tests GREEN.
  • Run npm test, npm run lint, and npm run build.
  • Commit only SDK source/schema/generated dist changes.

Task 2: Desktop application language setting

Files:

  • Modify verstak-desktop/internal/core/appsettings/manager.go
  • Modify verstak-desktop/internal/core/appsettings/manager_test.go
  • Modify verstak-desktop/internal/api/app.go
  • Modify verstak-desktop/internal/api/app_test.go

Behavior: missing language becomes system; valid updates persist; invalid updates return an error; unrelated settings remain unchanged.

  • Add failing manager tests for default, reload, and preservation.
  • Add failing API tests for GetAppSettings and accepted/rejected patches.
  • Run focused Go tests and confirm RED.
  • Add Language to appsettings.Config, default/load normalization, and update handling without changing unrelated values.
  • Expose and validate language in the Wails API.
  • Run focused tests GREEN.
  • Run gofmt on changed Go files and go test ./internal/core/appsettings ./internal/api.

Task 3: Plugin localization metadata and safe catalog loading

Files:

  • Modify verstak-desktop/internal/core/plugin/plugin.go
  • Modify verstak-desktop/internal/core/plugin/plugin_test.go
  • Modify verstak-desktop/internal/api/app.go
  • Modify verstak-desktop/internal/api/app_test.go
  • Generated Wails bindings are intentionally not regenerated over existing user changes; frontend imports call the binding only after generation is explicitly reconciled.

Backend API:

GetPluginLocalization(pluginID, locale string) (map[string]string, string)
  • Add failing manifest parsing tests for localization metadata.
  • Add failing API tests for declared catalog reads, locale fallback input, malformed JSON, non-string values, missing declarations, absolute paths, backslashes, traversal, and containment.
  • Run focused Go tests and confirm RED.
  • Add localization manifest structs and the read-only safe catalog API.
  • Run focused tests GREEN and go test ./internal/core/plugin ./internal/api.

Task 4: Frontend localization service

Files:

  • Add verstak-desktop/frontend/src/lib/i18n/catalogs/en.js

  • Add verstak-desktop/frontend/src/lib/i18n/catalogs/ru.js

  • Add verstak-desktop/frontend/src/lib/i18n/index.js

  • Add verstak-desktop/frontend/tests/i18n-test.mjs

  • Modify verstak-desktop/frontend/src/main.js

  • Modify verstak-desktop/frontend/src/lib/test/wails-mock.js

  • Add a failing standalone Node test for preference validation, system locale resolution, interpolation, shell fallback, plugin catalog fallback, subscription, and contribution-copy localization.

  • Run node frontend/tests/i18n-test.mjs and confirm RED.

  • Implement the framework-independent locale store and catalog cache.

  • Initialize it from GetAppSettings before mounting Svelte.

  • Extend the Wails mock with language state and plugin catalogs.

  • Run the focused test GREEN and npm run build.


Task 5: Runtime api.i18n bridge

Files:

  • Modify verstak-desktop/frontend/src/lib/plugin-host/VerstakPluginAPI.js

  • Modify verstak-desktop/frontend/src/lib/plugin-host/PluginBundleHost.svelte

  • Modify verstak-desktop/frontend/tests/plugin-api-contributions-test.mjs

  • Modify verstak-desktop/frontend/tests/bundle-host-test.cjs

  • Extend bridge tests first to require getLocale, t, and disposable onDidChangeLocale behavior.

  • Confirm focused RED.

  • Preload the plugin catalog before mount and expose the i18n service through the public API.

  • Keep locale subscriptions under existing API disposal cleanup.

  • Translate host loading/error states through shell catalogs.

  • Confirm bridge/bundle tests GREEN.


Task 6: Language selector and shell migration

Files:

  • Modify verstak-desktop/frontend/src/App.svelte

  • Modify every Svelte file under verstak-desktop/frontend/src/lib/shell/

  • Modify every Svelte file under verstak-desktop/frontend/src/lib/plugin-manager/

  • Modify verstak-desktop/frontend/src/lib/plugin-host/PluginBundleHost.svelte

  • Modify verstak-desktop/frontend/e2e/status-bar.spec.js

  • Add verstak-desktop/frontend/e2e/localization.spec.js

  • Modify verstak-desktop/frontend/tests/shell-source-contract-test.mjs where assertions intentionally depend on translated literals.

  • Add failing E2E assertions for the language submenu/radio state, persistence, Russian system locale, English fallback, and live shell update.

  • Confirm focused Playwright RED.

  • Add the language submenu to StatusBar and persist changes through UpdateAppSettings.

  • Replace shell user-facing literals with shell catalog keys, including aria labels, tooltips, empty/loading/error/confirmation text.

  • Localize copies of plugin manifests and contributions before display.

  • Confirm focused E2E GREEN, standalone shell tests GREEN, and frontend production build GREEN.


Task 7: Official plugin localization declarations and catalog checks

Files:

  • Modify every verstak-official-plugins/plugins/*/plugin.json

  • Add locales/en.json and locales/ru.json under every official plugin

  • Add verstak-official-plugins/scripts/check-locales.mjs

  • Modify verstak-official-plugins/scripts/check.sh

  • Modify relevant plugin smoke harness API mocks under verstak-official-plugins/scripts/

  • Add the locale checker first and confirm it fails for missing metadata and catalogs.

  • Add localization declarations to all 13 manifests.

  • Add English and Russian manifest/contribution keys to all catalogs.

  • Verify catalog parity, string-only values, safe paths, and required derived manifest keys.

  • Run ./scripts/check.sh GREEN before migrating runtime UI strings.


Task 8: Plain-JavaScript official plugin UI migration

Files:

  • Modify frontend/src/index.js for activity, browser-inbox, default-editor, file-preview, files, journal, notes, platform-test, search, secrets, todo, and trash.
  • Expand each plugin's locales/en.json and locales/ru.json.
  • Modify focused scripts/smoke-*-plugin.js tests.

For each plugin, repeat independently:

  • Add a failing bilingual rendering assertion and a locale-change state preservation assertion to its existing smoke test.
  • Add a local t helper backed only by api.i18n.
  • Replace user-visible literals, attributes, empty/loading/error states, confirmation prompts, and known validation messages with stable keys.
  • Subscribe once at mount, update only rendered text/state, and unsubscribe at unmount.
  • Run the focused plugin smoke test GREEN before moving to the next plugin.

Do not translate IDs, paths, user data, logs, API labels in diagnostics, or provider-returned values.


Task 9: Svelte Sync plugin migration

Files:

  • Modify verstak-official-plugins/plugins/sync/frontend/src/SyncSettings.svelte

  • Modify verstak-official-plugins/plugins/sync/frontend/src/SyncStatusBar.svelte

  • Modify verstak-official-plugins/plugins/sync/frontend/src/index.js

  • Expand verstak-official-plugins/plugins/sync/locales/en.json

  • Expand verstak-official-plugins/plugins/sync/locales/ru.json

  • Modify Sync smoke/E2E tests as appropriate.

  • Add failing English/Russian and live-change assertions.

  • Bridge api.i18n into reactive Svelte state without remounting.

  • Translate UI labels and known status/error chrome.

  • Run Sync plugin build and focused tests GREEN.


Task 10: Full verification and documentation

Files:

  • Modify verstak-docs/04_Plugin_System.md

  • Modify verstak-docs/07_Full_Implementation_Roadmap.md

  • Modify other contract docs only where the implemented behavior requires it.

  • Run SDK: npm test, npm run lint, npm run build.

  • Run desktop backend: go test -count=1 ./... and go vet ./....

  • Run desktop standalone frontend tests, production build, and focused then full npm run test:e2e.

  • Run official plugins: ./scripts/check.sh and all plugin builds.

  • Run git diff --check in every changed repository.

  • Inspect changed-file lists and ensure pre-existing Wails generated changes are not staged or overwritten.

  • Update docs to match only verified behavior.

  • Commit scoped changes in each repository.

  • Report exact verification labels. If native Wails/WebKit was not exercised, state: GUI behavior was not verified in the real desktop shell.