diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml
new file mode 100644
index 000000000..e65aaca88
--- /dev/null
+++ b/.github/workflows/lunaria.yml
@@ -0,0 +1,29 @@
+name: Lunaria
+
+on:
+ pull_request_target:
+ types: [opened, synchronize]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ lunaria-overview:
+ name: Translation Overview
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: 0
+ - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0
+ - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ with:
+ node-version: 22
+ cache: pnpm
+ - run: pnpm install --frozen-lockfile
+ - uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e
diff --git a/i18n/.gitignore b/i18n/.gitignore
new file mode 100644
index 000000000..849ddff3b
--- /dev/null
+++ b/i18n/.gitignore
@@ -0,0 +1 @@
+dist/
diff --git a/i18n/build.ts b/i18n/build.ts
new file mode 100644
index 000000000..78d21d456
--- /dev/null
+++ b/i18n/build.ts
@@ -0,0 +1,164 @@
+import { mkdirSync, writeFileSync } from "node:fs";
+
+import { createLunaria } from "@lunariajs/core";
+
+const lunaria = await createLunaria();
+const status = await lunaria.getFullStatus();
+const { sourceLocale, locales } = lunaria.config;
+const links = lunaria.gitHostingLinks();
+
+const fileStatus = status[0];
+if (!fileStatus) {
+ console.log("No tracked files found.");
+ process.exit(0);
+}
+
+interface LocaleStatus {
+ lang: string;
+ label: string;
+ totalKeys: number;
+ completedKeys: number;
+ missingKeys: string[];
+ percentComplete: number;
+ editUrl: string;
+ historyUrl: string;
+}
+
+const AMP = /&/g;
+const LT = //g;
+const QUOT = /"/g;
+
+function countPoEntries(contents: string): number {
+ let count = 0;
+ for (const line of contents.split("\n")) {
+ if (line.startsWith("msgid ") && line !== 'msgid ""') {
+ count++;
+ }
+ }
+ return count;
+}
+
+const totalKeys = countPoEntries(fileStatus.source.contents);
+
+const localeStatuses: LocaleStatus[] = locales.map((locale) => {
+ const localization = fileStatus.localizations.find((l) => l.lang === locale.lang);
+
+ const missingKeys: string[] = [];
+ if (localization && "missingKeys" in localization && localization.missingKeys) {
+ for (const keyPath of localization.missingKeys) {
+ missingKeys.push(Array.isArray(keyPath) ? keyPath.join(".") : String(keyPath));
+ }
+ }
+
+ const completedKeys = totalKeys - missingKeys.length;
+ const editUrl = localization
+ ? links.source(localization.path)
+ : links.create(`packages/admin/src/locales/${locale.lang}/messages.po`);
+ const historyUrl = localization ? links.history(localization.path) : "";
+
+ return {
+ lang: locale.lang,
+ label: locale.label,
+ totalKeys,
+ completedKeys,
+ missingKeys,
+ percentComplete: totalKeys > 0 ? Math.round((completedKeys / totalKeys) * 100) : 100,
+ editUrl,
+ historyUrl,
+ };
+});
+
+function barClass(percent: number): string {
+ if (percent >= 100) return "completed";
+ if (percent > 90) return "very-good";
+ if (percent > 75) return "good";
+ if (percent > 50) return "help-needed";
+ return "basic";
+}
+
+function escapeHtml(s: string): string {
+ return s.replace(AMP, "&").replace(LT, "<").replace(GT, ">").replace(QUOT, """);
+}
+
+function localeCard(s: LocaleStatus): string {
+ return `
+
+
+ ${s.label} ${s.lang}
+ ${s.completedKeys}/${s.totalKeys} · ${s.percentComplete}%
+
+
+
+ ${
+ s.missingKeys.length > 0
+ ? `${s.missingKeys.length} missing keys
${s.missingKeys.map((k) => `- ${escapeHtml(k)}
`).join("")}
`
+ : `All strings translated 🎉
`
+ }
+ `;
+}
+
+const html = `
+
+
+
+
+EmDash Translation Status
+
+
+
+
+
+EmDash Translation Status
+Admin UI · ${totalKeys} translatable strings
+${localeStatuses.map(localeCard).join("\n")}
+
+
+`;
+
+const jsonStatus = {
+ generatedAt: new Date().toISOString(),
+ sourceLocale: { lang: sourceLocale.lang, label: sourceLocale.label, totalKeys },
+ locales: localeStatuses,
+};
+
+mkdirSync("i18n/dist", { recursive: true });
+writeFileSync("i18n/dist/index.html", html);
+writeFileSync("i18n/dist/status.json", JSON.stringify(jsonStatus, null, "\t"));
+
+console.log(`Generated dashboard: ${localeStatuses.length} locales, ${totalKeys} keys`);
+for (const s of localeStatuses) {
+ console.log(` ${s.label} (${s.lang}): ${s.percentComplete}% — ${s.missingKeys.length} missing`);
+}
diff --git a/i18n/package.json b/i18n/package.json
new file mode 100644
index 000000000..cc12621af
--- /dev/null
+++ b/i18n/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "@emdash-cms/i18n-dashboard",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "cd .. && node --experimental-strip-types i18n/build.ts",
+ "deploy": "node --run build && wrangler deploy"
+ },
+ "devDependencies": {
+ "@types/node": "catalog:",
+ "wrangler": "catalog:"
+ }
+}
diff --git a/i18n/tsconfig.json b/i18n/tsconfig.json
new file mode 100644
index 000000000..9e59b3fc4
--- /dev/null
+++ b/i18n/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "module": "preserve",
+ "moduleResolution": "bundler",
+ "target": "es2022",
+ "strict": true,
+ "types": ["node"]
+ },
+ "include": ["build.ts"]
+}
diff --git a/i18n/wrangler.jsonc b/i18n/wrangler.jsonc
new file mode 100644
index 000000000..709fb252a
--- /dev/null
+++ b/i18n/wrangler.jsonc
@@ -0,0 +1,14 @@
+{
+ "name": "emdash-i18n",
+ "compatibility_date": "2026-04-01",
+ "assets": {
+ "directory": "./dist",
+ },
+ "routes": [
+ {
+ "pattern": "i18n.emdashcms.com",
+ "zone_name": "emdashcms.com",
+ "custom_domain": true,
+ },
+ ],
+}
diff --git a/lingui.config.ts b/lingui.config.ts
index 5ab1f4298..81164fc6b 100644
--- a/lingui.config.ts
+++ b/lingui.config.ts
@@ -2,7 +2,7 @@ import type { LinguiConfig } from "@lingui/conf";
const config: LinguiConfig = {
sourceLocale: "en",
- locales: ["en"],
+ locales: ["en", "de"],
catalogs: [
{
path: "/packages/admin/src/locales/{locale}/messages",
diff --git a/lunaria.config.ts b/lunaria.config.ts
new file mode 100644
index 000000000..4565929ef
--- /dev/null
+++ b/lunaria.config.ts
@@ -0,0 +1,25 @@
+import { defineConfig } from "@lunariajs/core/config";
+
+export default defineConfig({
+ repository: {
+ name: "emdash-cms/emdash",
+ branch: "main",
+ },
+ sourceLocale: {
+ label: "English",
+ lang: "en",
+ },
+ locales: [
+ {
+ label: "Deutsch",
+ lang: "de",
+ },
+ ],
+ files: [
+ {
+ include: ["packages/admin/src/locales/en/messages.po"],
+ pattern: "packages/admin/src/locales/@lang/messages.po",
+ type: "dictionary",
+ },
+ ],
+});
diff --git a/package.json b/package.json
index 0b6ed14f3..8f5a76e3c 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,9 @@
"lint:fix": "oxlint --type-aware --fix",
"knip": "knip --no-exit-code --exclude unlisted,unresolved,exports,types,duplicates",
"new": "create-emdash",
- "screenshots": "node scripts/screenshot-all-templates.mjs"
+ "screenshots": "node scripts/screenshot-all-templates.mjs",
+ "locale:extract": "pnpm --filter @emdash-cms/admin locale:extract",
+ "locale:compile": "pnpm --filter @emdash-cms/admin locale:compile"
},
"keywords": [],
"author": "Matt Kane",
@@ -34,6 +36,7 @@
"@changesets/changelog-github": "^0.5.2",
"@changesets/cli": "^2.29.8",
"@e18e/eslint-plugin": "^0.2.0",
+ "@lunariajs/core": "https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc",
"@playwright/test": "^1.58.0",
"@types/node": "catalog:",
"@typescript/native-preview": "^7.0.0-dev",
diff --git a/packages/admin/src/locales/de/messages.po b/packages/admin/src/locales/de/messages.po
new file mode 100644
index 000000000..e92183994
--- /dev/null
+++ b/packages/admin/src/locales/de/messages.po
@@ -0,0 +1,170 @@
+msgid ""
+msgstr ""
+"POT-Creation-Date: 2026-04-11 20:10+0100\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: @lingui/cli\n"
+"Language: de\n"
+
+#: packages/admin/src/components/LocaleSwitcher.tsx:72
+msgid " (default)"
+msgstr ""
+
+#: packages/admin/src/components/LocaleSwitcher.tsx:107
+msgid "{label} — no translation"
+msgstr ""
+
+#: packages/admin/src/components/LocaleSwitcher.tsx:107
+msgid "{label} — view translation"
+msgstr ""
+
+#: packages/admin/src/components/LocaleSwitcher.tsx:68
+msgid "All locales"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:99
+msgid "Allow users from specific domains to sign up"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:109
+msgid "API Tokens"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:253
+msgid "Authentication error: {error}"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:174
+#: packages/admin/src/components/LoginPage.tsx:210
+msgid "Back to login"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:158
+msgid "Check your email"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:130
+msgid "Choose your preferred admin language"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:169
+msgid "Click the link in the email to sign in."
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:110
+msgid "Create personal access tokens for programmatic API access"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:358
+msgid "Don't have an account? <0>Sign up0>"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:115
+msgid "Email"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:183
+msgid "Email address"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:127
+#: packages/admin/src/components/LoginPage.tsx:132
+msgid "Failed to send magic link"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:69
+msgid "General"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:160
+msgid "If an account exists for <0>{email}0>, we've sent a sign-in link."
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:129
+msgid "Language"
+msgstr ""
+
+#: packages/admin/src/components/LocaleSwitcher.tsx:60
+msgid "Locale"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:93
+msgid "Manage your passkeys and authentication"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:313
+msgid "Or continue with"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:82
+msgid "Search engine optimization and verification"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:92
+msgid "Security"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:98
+msgid "Self-Signup Domains"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:206
+msgid "Send magic link"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:206
+msgid "Sending..."
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:81
+msgid "SEO"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:62
+msgid "Settings"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:283
+msgid "Sign in to your site"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:284
+msgid "Sign in with email"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:340
+msgid "Sign in with email link"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:304
+msgid "Sign in with Passkey"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:70
+msgid "Site identity, logo, favicon, and reading preferences"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:75
+msgid "Social Links"
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:76
+msgid "Social media profile links"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:170
+msgid "The link will expire in 15 minutes."
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:351
+msgid "Use your registered passkey to sign in securely."
+msgstr ""
+
+#: packages/admin/src/components/Settings.tsx:116
+msgid "View email provider status and send test emails"
+msgstr ""
+
+#: packages/admin/src/components/LoginPage.tsx:352
+msgid "We'll send you a link to sign in without a password."
+msgstr ""
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1b2187624..444785b5e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -145,13 +145,16 @@ importers:
version: 4.11.1(playwright-core@1.58.2)
'@changesets/changelog-github':
specifier: ^0.5.2
- version: 0.5.2
+ version: 0.5.2(encoding@0.1.13)
'@changesets/cli':
specifier: ^2.29.8
version: 2.29.8(@types/node@24.10.13)
'@e18e/eslint-plugin':
specifier: ^0.2.0
version: 0.2.0(oxlint@1.49.0(oxlint-tsgolint@0.15.0))
+ '@lunariajs/core':
+ specifier: https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc
+ version: https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc
'@playwright/test':
specifier: ^1.58.0
version: 1.58.0
@@ -483,6 +486,15 @@ importers:
specifier: 'catalog:'
version: 19.2.4(react@19.2.4)
+ i18n:
+ devDependencies:
+ '@types/node':
+ specifier: 'catalog:'
+ version: 24.10.13
+ wrangler:
+ specifier: 'catalog:'
+ version: 4.80.0(@cloudflare/workers-types@4.20260305.1)
+
packages/admin:
dependencies:
'@cloudflare/kumo':
@@ -2740,6 +2752,12 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ '@kwsites/file-exists@1.1.1':
+ resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
+
+ '@kwsites/promise-deferred@1.1.1':
+ resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
+
'@libsql/client@0.8.1':
resolution: {integrity: sha512-xGg0F4iTDFpeBZ0r4pA6icGsYa5rG6RAG+i/iLDnpCAnSuTqEWMDdPlVseiq4Z/91lWI9jvvKKiKpovqJ1kZWA==}
@@ -2866,6 +2884,11 @@ packages:
'@loaderkit/resolve@1.0.2':
resolution: {integrity: sha512-yTCCjuQapvRz6S30B8DyqHu1WYsbYRCww6uNsmbQU4GQVf5gJzJSB60qUHj+qBSxReLtRL/mhmhYhrIc9jVFTw==}
+ '@lunariajs/core@https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc':
+ resolution: {tarball: https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc}
+ version: 0.1.1
+ engines: {node: '>=18.17.0'}
+
'@manypkg/find-root@1.1.0':
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
@@ -3865,6 +3888,12 @@ packages:
'@shikijs/vscode-textmate@10.0.2':
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+ '@simple-git/args-pathspec@1.0.2':
+ resolution: {integrity: sha512-nEFVejViHUoL8wU8GTcwqrvqfUG40S5ts6S4fr1u1Ki5CklXlRDYThPVA/qurTmCYFGnaX3XpVUmICLHdvhLaA==}
+
+ '@simple-git/argv-parser@1.0.3':
+ resolution: {integrity: sha512-NMKv9sJcSN2VvnPT9Ja7eKfGy8Q8mMFLwPTCcuZMtv3+mYcLIZflg31S/tp2XCCyiY7YAx6cgBHQ0fwA2fWHpQ==}
+
'@sinclair/typebox@0.27.10':
resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==}
@@ -5655,6 +5684,9 @@ packages:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
+ encoding@0.1.13:
+ resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+
end-of-stream@1.4.5:
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
@@ -5961,6 +5993,10 @@ packages:
get-tsconfig@4.13.6:
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
+ gettext-parser@9.0.2:
+ resolution: {integrity: sha512-dGvq3S1gpS6e9KzNkwgPED5xxfWk7mNYzzdi/fPdJF5qS7B+yo8El2ZQyyhJ79PyzTtHbwiqYOFsqBdzbQ0GPg==}
+ engines: {node: '>=20'}
+
giget@1.2.5:
resolution: {integrity: sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==}
hasBin: true
@@ -6280,6 +6316,10 @@ packages:
resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ jiti@2.3.3:
+ resolution: {integrity: sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==}
+ hasBin: true
+
jiti@2.6.1:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
@@ -7060,6 +7100,10 @@ packages:
oxlint-tsgolint:
optional: true
+ p-all@5.0.1:
+ resolution: {integrity: sha512-LMT7WX9ZSaq3J1zjloApkIVmtz0ZdMFSIqbuiEa3txGYPLjUPOvgOPOx3nFjo+f37ZYL+1aY666I2SG7GVwLOA==}
+ engines: {node: '>=16'}
+
p-filter@2.1.0:
resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==}
engines: {node: '>=8'}
@@ -7080,6 +7124,10 @@ packages:
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
engines: {node: '>=6'}
+ p-map@6.0.0:
+ resolution: {integrity: sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==}
+ engines: {node: '>=16'}
+
p-queue@9.1.0:
resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==}
engines: {node: '>=20'}
@@ -7780,6 +7828,9 @@ packages:
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
+ simple-git@3.35.2:
+ resolution: {integrity: sha512-ZMjl06lzTm1EScxEGuM6+mEX+NQd14h/B3x0vWU+YOXAMF8sicyi1K4cjTfj5is+35ChJEHDl1EjypzYFWH2FA==}
+
sirv@3.0.2:
resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
engines: {node: '>=18'}
@@ -8119,6 +8170,9 @@ packages:
ultrahtml@1.6.0:
resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
+ ultramatter@0.0.4:
+ resolution: {integrity: sha512-1f/hO3mR+/Hgue4eInOF/Qm/wzDqwhYha4DxM0hre9YIUyso3fE2XtrAU6B4njLqTC8CM49EZaYgsVSa+dXHGw==}
+
unconfig-core@7.4.2:
resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==}
@@ -9462,9 +9516,9 @@ snapshots:
dependencies:
'@changesets/types': 6.1.0
- '@changesets/changelog-github@0.5.2':
+ '@changesets/changelog-github@0.5.2(encoding@0.1.13)':
dependencies:
- '@changesets/get-github-info': 0.7.0
+ '@changesets/get-github-info': 0.7.0(encoding@0.1.13)
'@changesets/types': 6.1.0
dotenv: 8.6.0
transitivePeerDependencies:
@@ -9524,10 +9578,10 @@ snapshots:
picocolors: 1.1.1
semver: 7.7.4
- '@changesets/get-github-info@0.7.0':
+ '@changesets/get-github-info@0.7.0(encoding@0.1.13)':
dependencies:
dataloader: 1.4.0
- node-fetch: 2.7.0
+ node-fetch: 2.7.0(encoding@0.1.13)
transitivePeerDependencies:
- encoding
@@ -10168,6 +10222,14 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@kwsites/file-exists@1.1.1':
+ dependencies:
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@kwsites/promise-deferred@1.1.1': {}
+
'@libsql/client@0.8.1':
dependencies:
'@libsql/core': 0.8.1
@@ -10338,6 +10400,23 @@ snapshots:
dependencies:
'@braidai/lang': 1.0.0
+ '@lunariajs/core@https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@83617cc':
+ dependencies:
+ consola: 3.4.2
+ gettext-parser: 9.0.2
+ jiti: 2.3.3
+ js-yaml: 4.1.1
+ neotraverse: 0.6.18
+ p-all: 5.0.1
+ path-to-regexp: 6.3.0
+ picomatch: 4.0.3
+ simple-git: 3.35.2
+ tinyglobby: 0.2.15
+ ultramatter: 0.0.4
+ zod: 3.25.76
+ transitivePeerDependencies:
+ - supports-color
+
'@manypkg/find-root@1.1.0':
dependencies:
'@babel/runtime': 7.28.6
@@ -11096,6 +11175,12 @@ snapshots:
'@shikijs/vscode-textmate@10.0.2': {}
+ '@simple-git/args-pathspec@1.0.2': {}
+
+ '@simple-git/argv-parser@1.0.3':
+ dependencies:
+ '@simple-git/args-pathspec': 1.0.2
+
'@sinclair/typebox@0.27.10': {}
'@sindresorhus/is@4.6.0': {}
@@ -13389,6 +13474,10 @@ snapshots:
encodeurl@2.0.0: {}
+ encoding@0.1.13:
+ dependencies:
+ iconv-lite: 0.6.3
+
end-of-stream@1.4.5:
dependencies:
once: 1.4.0
@@ -13765,6 +13854,11 @@ snapshots:
dependencies:
resolve-pkg-maps: 1.0.0
+ gettext-parser@9.0.2:
+ dependencies:
+ content-type: 1.0.5
+ encoding: 0.1.13
+
giget@1.2.5:
dependencies:
citty: 0.1.6
@@ -14186,6 +14280,8 @@ snapshots:
leven: 3.1.0
pretty-format: 29.7.0
+ jiti@2.3.3: {}
+
jiti@2.6.1: {}
jose@6.1.3: {}
@@ -15080,9 +15176,11 @@ snapshots:
node-fetch-native@1.6.7: {}
- node-fetch@2.7.0:
+ node-fetch@2.7.0(encoding@0.1.13):
dependencies:
whatwg-url: 5.0.0
+ optionalDependencies:
+ encoding: 0.1.13
node-fetch@3.3.2:
dependencies:
@@ -15260,6 +15358,10 @@ snapshots:
'@oxlint/binding-win32-x64-msvc': 1.49.0
oxlint-tsgolint: 0.15.0
+ p-all@5.0.1:
+ dependencies:
+ p-map: 6.0.0
+
p-filter@2.1.0:
dependencies:
p-map: 2.1.0
@@ -15278,6 +15380,8 @@ snapshots:
p-map@2.1.0: {}
+ p-map@6.0.0: {}
+
p-queue@9.1.0:
dependencies:
eventemitter3: 5.0.2
@@ -16203,6 +16307,16 @@ snapshots:
once: 1.4.0
simple-concat: 1.0.1
+ simple-git@3.35.2:
+ dependencies:
+ '@kwsites/file-exists': 1.1.1
+ '@kwsites/promise-deferred': 1.1.1
+ '@simple-git/args-pathspec': 1.0.2
+ '@simple-git/argv-parser': 1.0.3
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
sirv@3.0.2:
dependencies:
'@polka/url': 1.0.0-next.29
@@ -16523,6 +16637,8 @@ snapshots:
ultrahtml@1.6.0: {}
+ ultramatter@0.0.4: {}
+
unconfig-core@7.4.2:
dependencies:
'@quansync/fs': 1.0.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 7a221bd4b..045fa8f6a 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -6,7 +6,7 @@ packages:
- packages/blocks/playground
- e2e/fixture
- docs
- - slidev
+ - i18n
catalog:
"@arethetypeswrong/cli": ^0.18.2