i18nsmith VS Code ExtensionTL;DR: Lightweight VS Code integration for i18nsmith — run health checks, sync locales, extract strings, and transform files from inside the editor. VS Code integration for i18nsmith — automated i18n tooling. Install the VSIX (see "How to test") or use the Marketplace once published. Features
Setup
Commands
Per-file WorkflowsSync just the active file (
|
| Setting | Default | Description |
|---|---|---|
i18nsmith.reportPath |
.i18nsmith/check-report.json |
Path to the report file |
i18nsmith.autoRefresh |
true |
Auto-refresh when report changes |
i18nsmith.showCodeLens |
true |
Show CodeLens actions |
i18nsmith.enableVerboseLogging |
false |
Enable verbose logging to Output channel for debugging sync/transform operations |
Development
# Install dependencies (from repo root)
pnpm install
# Build all workspace packages (required before first run)
pnpm -r build
# Compile the extension
pnpm --filter i18nsmith-vscode run compile
# Watch mode
pnpm --filter i18nsmith-vscode run watch
# Run in VS Code
# Press F5 or use "Run Extension" launch config
Testing
The extension has two complementary test layers: fast unit tests driven by vitest and real E2E integration tests that launch a headless VS Code Extension Host.
Prerequisites
# From repo root — install everything and build once
pnpm install
pnpm -r build
Unit Tests (vitest)
Unit tests are co-located *.test.ts files that mock the vscode API.
They run in Node.js with vitest — no VS Code instance needed.
# Run all unit tests (17 files, 55 tests)
pnpm --filter i18nsmith-vscode test:unit
# Watch mode — re-runs on file changes
pnpm --filter i18nsmith-vscode test:unit:watch
# With coverage report
pnpm --filter i18nsmith-vscode test:unit:coverage
Using the shared VS Code mock
A shared mock factory eliminates the 60+ line vi.mock('vscode') block
that was previously duplicated across every test file:
import { mockVSCode, mockServiceContainer } from '../test-helpers/vscode-mock';
// Basic usage — complete VS Code API mock
vi.mock('vscode', () => mockVSCode());
// With overrides — shallow-merge specific parts
vi.mock('vscode', () => mockVSCode({
window: { activeTextEditor: myEditorStub },
}));
// For controller tests — get a pre-wired ServiceContainer mock
const container = mockServiceContainer({
cliService: { runCliCommand: vi.fn() },
});
E2E Integration Tests (@vscode/test-cli)
E2E tests launch a real VS Code headlessly, open a scaffolded fixture project, activate the extension, and run Mocha test suites. They verify end-to-end behavior: activation, command execution, diagnostics, CodeLens, and file operations.
The test suite runs against all four supported i18n adapters:
| Adapter | Fixture entry file | What it tests |
|---|---|---|
react-i18next |
src/App.tsx |
useTranslation() calls |
vue-i18n |
src/App.vue |
useI18n() + composable |
next-intl |
src/app/page.tsx |
useTranslations() calls |
svelte-i18n |
src/routes/+page.svelte |
$t() store pattern |
Running E2E tests
# Run E2E against ALL frameworks (recommended for CI)
pnpm --filter i18nsmith-vscode test:e2e
# Run for a single framework
pnpm --filter i18nsmith-vscode test:e2e:react
pnpm --filter i18nsmith-vscode test:e2e:vue
pnpm --filter i18nsmith-vscode test:e2e:next
pnpm --filter i18nsmith-vscode test:e2e:svelte
# Keep generated fixtures after tests (for manual inspection)
pnpm --filter i18nsmith-vscode test:e2e:keep
Each run:
- Compiles E2E TypeScript tests →
out/e2e/ - Compiles the extension via esbuild →
dist/extension.js - Scaffolds a temporary fixture project per adapter
- Downloads VS Code (first run only) and launches it headlessly
- Runs 9 Mocha tests per adapter, then cleans up fixtures
What the 9 E2E tests verify (per adapter)
- Extension is present and active
i18nsmith.*commands are registered- Quick Actions view is registered
- Configuration settings have defaults
- Opening the adapter's source file causes no errors
i18nsmith.syncFilecommand is invocable- CodeLens providers return arrays for source files
i18nsmith.check(health check) is invocable- Diagnostics infrastructure is functional
Test fixture scaffolder
Fixtures are generated at runtime by scripts/scaffold-e2e-fixture.ts
and never committed (the test-fixtures/ directory is gitignored).
# Generate all 4 fixtures locally (for Dev Extension Host testing)
pnpm --filter i18nsmith-vscode fixture:create:all
# Generate a single fixture
pnpm --filter i18nsmith-vscode fixture:create # defaults to react-i18next
Each fixture provides:
i18n.config.json(triggers extension activation)locales/en.jsonandlocales/fr.json(with intentional missing keys)- Framework-specific source files with translation function calls
package.jsonand optionaltsconfig.json
Debugging tests
Five launch configurations are available in .vscode/launch.json:
| Config | Purpose |
|---|---|
| Run Extension (Dev Host) | Manual testing against any workspace |
| Run Extension (React Fixture) | Opens scaffolded react-i18next fixture |
| Run Extension (Vue Fixture) | Opens scaffolded vue-i18n fixture |
| E2E Tests (React Fixture) | Debug E2E tests with breakpoints |
| Debug Unit Tests (Vitest) | Debug unit tests in Node |
First time: Run
pnpm --filter i18nsmith-vscode fixture:create:allbefore using fixture-based launch configs.
CI integration
The GitHub Actions workflow (ci-vscode-extension.yml) runs both layers:
# Unit tests — fast, all platforms
- run: pnpm --filter i18nsmith-vscode test:unit
# E2E tests — headless VS Code
# Linux requires xvfb for virtual display
- run: xvfb-run -a pnpm --filter i18nsmith-vscode test:e2e # Linux
- run: pnpm --filter i18nsmith-vscode test:e2e # macOS / Windows
Quick reference
| Script | What it does |
|---|---|
test:unit |
Run vitest unit tests |
test:unit:watch |
Run vitest in watch mode |
test:unit:coverage |
Run vitest with v8 coverage |
test:e2e |
Run E2E for all adapters |
test:e2e:react |
E2E for react-i18next only |
test:e2e:vue |
E2E for vue-i18n only |
test:e2e:next |
E2E for next-intl only |
test:e2e:svelte |
E2E for svelte-i18n only |
test:e2e:keep |
All adapters, keep fixtures |
test:e2e:compile |
Compile E2E tests only |
fixture:create |
Scaffold single fixture |
fixture:create:all |
Scaffold all 4 fixtures |
Bundle Size
Latest dev build (esbuild) recorded a 12.2 MB dist/extension.js when running pnpm --filter i18nsmith-vscode run compile on 2025‑12‑11 after embedding Syncer + Transformer integrations.
How It Works
- The extension activates when
i18n.config.jsonor.i18nsmith/is detected - It watches for changes to the report file (default:
.i18nsmith/check-report.json) - When the report changes, it parses the JSON and creates VS Code diagnostics
- Diagnostics appear in the Problems panel and as squiggles in the editor
- CodeLens actions appear above files with issues
Report Schema
The extension expects a JSON report with this structure:
{
"actionableItems": [
{
"kind": "missing-key",
"severity": "warn",
"message": "Key 'common.greeting' is missing in locale 'fr'",
"filePath": "src/App.tsx",
"line": 10,
"column": 5,
"key": "common.greeting"
}
],
"hasConflicts": false,
"hasDrift": true
}
Integration with CI
The extension pairs well with the i18nsmith GitHub Action:
- uses: IMAGINARY9/i18nsmith@v1
with:
command: check
report-path: .i18nsmith/check-report.json
Contributing
For contributors, please review these resources:
- Extension Architecture - Internal design and patterns
- Core Integration Roadmap - Integration history
- Main Architecture - Monorepo-level design
Development Setup
# Clone the repository
git clone https://github.com/IMAGINARY9/i18nsmith.git
cd i18nsmith
# Install dependencies
pnpm install
# Build all packages
pnpm -r build
# Compile the extension
pnpm --filter i18nsmith-vscode run compile
# Run in development mode
# Press F5 in VS Code with the extension folder open
# Run unit tests
pnpm --filter i18nsmith-vscode test:unit
# Run E2E tests (all adapters)
pnpm --filter i18nsmith-vscode test:e2e
# Generate test fixtures for Dev Extension Host
pnpm --filter i18nsmith-vscode fixture:create:all
Architecture Guidelines
- Interfaces First: Define interfaces in
src/interfaces/before implementations - State Management: Use
StateManagerinstead of module-level variables - Error Handling: Use
ErrorHandlerServicefor consistent UX - Pure Functions: Put testable logic in
src/domain/ - Controllers: Keep VS Code-specific code in controllers
- Line Limits: Services ≤300 lines, Controllers ≤400 lines
The generated report artifact can be downloaded and viewed locally with the extension.
How to test (Open testing)
Follow these steps to perform a focused open-testing session with the packaged VSIX or a locally built copy:
- Build and package the extension to a VSIX (from repo root):
pnpm install --no-frozen-lockfile
pnpm --filter i18nsmith-vscode run compile
cd packages/vscode-extension
npx -y @vscode/vsce package --out ../../i18nsmith-vscode.vsix --no-dependencies
- Install the VSIX in VS Code:
- Open VS Code → Extensions view → … → "Install from VSIX..." → choose
i18nsmith-vscode.vsix.
- Prepare a simple workspace for testing:
- Create an
i18n.config.jsonin workspace root (example below). - Add
locales/en.jsonand a test source file (see.github/workflows/test-action.ymlfor a minimal fixture).
Example i18n.config.json:
{
"sourceLanguage": "en",
"targetLanguages": ["es","fr"],
"localesDir": "./locales",
"include": ["src/**/*.tsx"]
}
- Generate a report the extension will consume:
npx i18nsmith check --report .i18nsmith/check-report.json
💡 Offline usage: the scanner shell‑outs to the i18nsmith CLI. If your workspace doesn’t have the package installed, a fallback of
npx i18nsmithis used which requires network access. A timeout or other network error will surface as a generic failure in the output channel; you’ll also see a warning notification suggesting you install the CLI or seti18nsmith.cliPathso the extension can run without internet.
- Verify extension features in VS Code:
- Open a source file and confirm diagnostics appear (Problems panel + squiggles).
- Test hover preview on
t('key')calls. - Use the Command Palette to run: "i18nsmith: Run Health Check", "i18nsmith: Sync Current File", "i18nsmith: Transform Current File", and other commands listed in the Commands section.
- Try the editor context menu actions (Extract selection as translation key) and CodeLens quick actions.
Quick smoke test checklist
- Install the VSIX or run the extension in the debugger (F5).
- Open a project with
i18n.config.jsonandlocales/present. - Run
i18nsmith check --report .i18nsmith/check-report.jsonand confirm diagnostics appear. - Run
i18nsmith: Sync Current Fileandi18nsmith: Transform Current Fileto exercise UI flows. - Check the
i18nsmithOutput channel for errors.
- Smoke checks to perform:
- Confirm diagnostics refresh when
.i18nsmith/check-report.jsonis updated. - Confirm the Sync/Transform dry-run previews show expected diffs and that Apply writes changes and refreshes diagnostics.
- Confirm undo/VS Code's undo stack works after applying transforms.
If you spot runtime errors or missing behavior, capture the Output channel logs (View → Output → select "i18nsmith") and attach them to the GitHub issue.
Privacy & Telemetry
- Short statement: This extension does not collect or transmit telemetry, usage analytics, or source code to external services by default. All diagnostic data and logs remain local to the user's environment (Output channel and files in the workspace).
- Verbose logging: Enabling
i18nsmith.enableVerboseLoggingonly increases local logging to thei18nsmithOutput channel; it does not send logs to a remote server. - Opt-in uploads: If future features add optional upload or remote diagnostics, they will be explicitly documented and require opt-in consent. No automatic uploads occur without explicit, documented user action.
If your organization requires a formal privacy policy, link it from the repository homepage or add a PRIVACY.md with the required legal text.
Reporting issues & open testing feedback
- Open an issue at: https://github.com/IMAGINARY9/i18nsmith/issues
- When filing issues during open testing, please include:
- VS Code version and platform
- Extension version (found in
Help → AboutorExtensionsview) - Steps to reproduce
- Attach
.i18nsmith/check-report.json(if applicable) - The
i18nsmithOutput channel contents (copy/paste)
Label feature requests as enhancement and runtime bugs as bug to help triage. If you want a dedicated testing/discussion channel, we can add a DISCUSSION template or use GitHub Discussions.
Publishing to the Visual Studio Marketplace (automation)
An optional workflow (.github/workflows/publish-to-marketplace.yml) is included that will publish the extension when a GitHub Release is published.
Requirements:
- A repository secret named
VSCE_TOKENthat contains a Personal Access Token (PAT) for publishing to the Visual Studio Marketplace. Create the token according to the@vscode/vscedocumentation and add it to GitHub → Settings → Secrets → Actions. - Ensure the
publisherfield inpackages/vscode-extension/package.jsonmatches the Marketplace publisher id that will own the extension.
Workflow behavior and safety:
- The workflow triggers on
releaseevents (when you publish a GitHub Release). It builds the extension, runs@vscode/vsce publishusing the token, and uploads a VSIX artifact. - Publishing from a release reduces accidental publishes; we recommend creating a Draft release and verifying the produced VSIX artifact before publishing it to the Marketplace.
Manual publish alternative:
If you prefer manual publishing, you can publish locally with:
cd packages/vscode-extension
npx -y @vscode/vsce publish --pat <YOUR_TOKEN>
This will package and publish the extension using the token you provide.
Troubleshooting
- "code: command not found": enable the
codeCLI from VS Code (Cmd+Shift+P → "Shell Command: Install 'code' command in PATH") or create a symlink to the app bundle. See the project root README for exact commands. - Packaging fails (vsce errors): ensure
packages/vscode-extension/LICENSEexists and runpnpm --filter i18nsmith-vscode run compilebefore packaging. - Large bundle size: If runtime errors relate to missing modules, confirm workspace dependencies are built and that
esbuildbundles required code. Usepnpm -r buildat repo root to build workspace packages.
If you need help with any of these steps I can update the README further or add scripts to simplify packaging and local testing.