diff --git a/.changeset/i18n-localization-foundation.md b/.changeset/i18n-localization-foundation.md new file mode 100644 index 0000000000..5b2d8a4618 --- /dev/null +++ b/.changeset/i18n-localization-foundation.md @@ -0,0 +1,9 @@ +--- +"@runfusion/fusion": minor +--- + +Add a localization (i18n) foundation across the UI. Introduces react-i18next-backed translation for both the dashboard and the terminal UI, with English as the source language and Simplified Chinese, Traditional Chinese, French, and Spanish as target locales. + +- New `@fusion/i18n` package holding the authored catalogs and shared i18next configuration (namespace split, script-aware zh-CN/zh-TW fallback, plural setup). +- A `language` preference (`fusion settings`) and a Settings language switcher; the CLI resolves locale from `--lang`, settings, then environment. +- An `i18next-cli` workflow (`extract`/`sync`/`types`/`status`/`lint`) so adding a future language is a translate-only, near-zero-code operation. diff --git a/.gitignore b/.gitignore index 7362b6f83b..149f014bc0 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,10 @@ dist/ dist-electron/ *.tsbuildinfo +# Generated i18n catalogs synced into the dashboard tree from @fusion/i18n +# (authored source-of-truth lives in packages/i18n/locales/) +packages/dashboard/app/locales/ + # Desktop packaging artifacts *.dmg *.dmg.blockmap diff --git a/i18next.config.ts b/i18next.config.ts new file mode 100644 index 0000000000..03283d9f7d --- /dev/null +++ b/i18next.config.ts @@ -0,0 +1,46 @@ +import { + defineConfig, + recommendedAcceptedAttributes, + recommendedAcceptedTags, +} from "i18next-cli"; + +/** + * i18next-cli workflow config for the whole monorepo. + * + * - `extract` pulls t()/ keys from the dashboard and CLI source into the + * authored `en` catalogs under @fusion/i18n. + * - `sync` propagates the `en` key structure to the four other locales. + * - `types` regenerates key types from the `en` catalogs. + * - `status` reports per-locale completion (CI gate). + * - `lint` flags hardcoded user-facing strings (primary guardrail). + * + * Namespaces are routed by the `ns:` prefix in keys / `useTranslation(ns)` in + * source, not by file path. `common` is the default namespace. + */ +export default defineConfig({ + locales: ["en", "zh-CN", "zh-TW", "fr", "es"], + extract: { + input: [ + "packages/dashboard/app/**/*.{ts,tsx}", + "packages/cli/src/**/*.{ts,tsx}", + "!**/__tests__/**", + "!**/*.test.*", + ], + output: "packages/i18n/locales/{{language}}/{{namespace}}.json", + primaryLanguage: "en", + defaultNS: "common", + keySeparator: ".", + nsSeparator: ":", + // Untranslated secondary-locale keys stay empty so `status` can measure + // real completion; the active locale falls back to `en` at runtime. + defaultValue: "", + }, + types: { + input: ["packages/i18n/locales/en/*.json"], + output: "packages/i18n/src/i18next-resources.d.ts", + }, + lint: { + acceptedTags: recommendedAcceptedTags, + acceptedAttributes: recommendedAcceptedAttributes, + }, +}); diff --git a/package.json b/package.json index 5029049d85..2274f588fd 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,12 @@ "test:coverage:dashboard": "pnpm --filter @fusion/dashboard exec vitest run --silent=passed-only --reporter=dot --coverage", "test:slow-cli": "pnpm --filter @runfusion/fusion test:slow-cli", "typecheck": "pnpm -r --filter=!@fusion/desktop --filter=!@fusion/mobile typecheck", + "i18n:extract": "i18next-cli extract", + "i18n:sync": "i18next-cli sync", + "i18n:types": "i18next-cli types", + "i18n:status": "i18next-cli status", + "i18n:lint": "i18next-cli lint", + "i18n:gen-cli": "pnpm --filter @fusion/i18n gen:cli-catalogs", "changeset": "changeset", "version": "changeset version", "release": "node scripts/release.mjs", @@ -76,6 +82,7 @@ "@eslint/js": "^9.0.0", "eslint": "^9.0.0", "fast-glob": "^3.3.3", + "i18next-cli": "^1.59.1", "react-devtools-core": "^7.0.1", "tsx": "^4.19.0", "typescript": "^5.7.0", diff --git a/packages/cli/package.json b/packages/cli/package.json index c0ae9e86dd..1d3c52eb36 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -59,13 +59,15 @@ "@earendil-works/pi-coding-agent": "^0.78.0", "dockerode": "^4.0.12", "express": "^5.1.0", + "i18next": "^26.3.1", "ink": "^6.8.0", "ink-spinner": "^5.0.0", "ink-text-input": "^6.0.0", "ioredis": "^5.6.0", "multer": "^2.1.1", "node-pty": "npm:@homebridge/node-pty-prebuilt-multiarch@^0.13.1", - "react": "^19.0.0" + "react": "^19.0.0", + "react-i18next": "^17.0.8" }, "peerDependencies": { "@earendil-works/pi-ai": "*", @@ -87,6 +89,7 @@ "@fusion/core": "workspace:*", "@fusion/dashboard": "workspace:*", "@fusion/engine": "workspace:*", + "@fusion/i18n": "workspace:*", "@fusion/pi-claude-cli": "workspace:*", "@fusion/pi-llama-cpp": "workspace:*", "@types/node": "^22.0.0", diff --git a/packages/cli/scripts/prepare-publish-manifest.mjs b/packages/cli/scripts/prepare-publish-manifest.mjs index a19a9d523f..8a872f646d 100644 --- a/packages/cli/scripts/prepare-publish-manifest.mjs +++ b/packages/cli/scripts/prepare-publish-manifest.mjs @@ -8,6 +8,7 @@ export function applyPrepackTransform(pkg) { delete devDependencies["@fusion/core"]; delete devDependencies["@fusion/dashboard"]; delete devDependencies["@fusion/engine"]; + delete devDependencies["@fusion/i18n"]; delete devDependencies["@fusion/pi-claude-cli"]; delete devDependencies["@fusion/pi-llama-cpp"]; delete devDependencies["@fusion-plugin-examples/roadmap"]; diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 436fd0fb7a..7ff2cd7be2 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -90,17 +90,18 @@ "@codemirror/state": "^6.5.2", "@codemirror/theme-one-dark": "^6.1.2", "@codemirror/view": "^6.36.4", + "@earendil-works/pi-coding-agent": "^0.78.0", + "@fusion-plugin-examples/cli-printing-press": "workspace:*", + "@fusion-plugin-examples/cursor-runtime": "workspace:*", "@fusion-plugin-examples/dependency-graph": "workspace:*", - "@fusion-plugin-examples/roadmap": "workspace:*", + "@fusion-plugin-examples/droid-runtime": "workspace:*", "@fusion-plugin-examples/hermes-runtime": "workspace:*", "@fusion-plugin-examples/openclaw-runtime": "workspace:*", - "@fusion-plugin-examples/droid-runtime": "workspace:*", - "@fusion-plugin-examples/cursor-runtime": "workspace:*", - "@fusion-plugin-examples/cli-printing-press": "workspace:*", "@fusion-plugin-examples/paperclip-runtime": "workspace:*", + "@fusion-plugin-examples/roadmap": "workspace:*", "@fusion/core": "workspace:*", "@fusion/engine": "workspace:*", - "@earendil-works/pi-coding-agent": "^0.78.0", + "@fusion/i18n": "workspace:*", "@types/multer": "^2.1.0", "@xterm/addon-fit": "^0.10.0", "@xterm/addon-search": "^0.15.0", @@ -109,6 +110,9 @@ "@xterm/xterm": "^5.5.0", "archiver": "^7.0.1", "express": "^5.1.0", + "i18next": "^26.3.1", + "i18next-browser-languagedetector": "^8.2.1", + "i18next-resources-to-backend": "^1.2.1", "ioredis": "^5.6.0", "lucide-react": "^1.7.0", "multer": "^2.1.1", @@ -116,6 +120,7 @@ "qrcode": "^1.5.4", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-i18next": "^17.0.8", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", "ws": "^8.18.0", diff --git a/packages/i18n/locales/en/app.json b/packages/i18n/locales/en/app.json new file mode 100644 index 0000000000..63cf775b30 --- /dev/null +++ b/packages/i18n/locales/en/app.json @@ -0,0 +1,9 @@ +{ + "settings": { + "appearance": { + "title": "Appearance", + "language": "Language", + "languageHint": "Choose the language for the {{brand}} interface." + } + } +} diff --git a/packages/i18n/locales/en/cli.json b/packages/i18n/locales/en/cli.json new file mode 100644 index 0000000000..7bfc7fe5c3 --- /dev/null +++ b/packages/i18n/locales/en/cli.json @@ -0,0 +1,6 @@ +{ + "tui": { + "loading": "Loading…", + "quit": "Quit" + } +} diff --git a/packages/i18n/locales/en/common.json b/packages/i18n/locales/en/common.json new file mode 100644 index 0000000000..5536dda5d3 --- /dev/null +++ b/packages/i18n/locales/en/common.json @@ -0,0 +1,15 @@ +{ + "columns": { + "triage": "Planning", + "todo": "Todo", + "in-progress": "In Progress", + "in-review": "In Review", + "done": "Done", + "archived": "Archived" + }, + "actions": { + "save": "Save", + "cancel": "Cancel", + "close": "Close" + } +} diff --git a/packages/i18n/locales/en/errors.json b/packages/i18n/locales/en/errors.json new file mode 100644 index 0000000000..0abd051afd --- /dev/null +++ b/packages/i18n/locales/en/errors.json @@ -0,0 +1,4 @@ +{ + "fetchProjectsFailed": "Failed to fetch projects", + "openTaskLogsFailed": "Failed to open task logs: {{detail}}" +} diff --git a/packages/i18n/locales/es/app.json b/packages/i18n/locales/es/app.json new file mode 100644 index 0000000000..0b4940a283 --- /dev/null +++ b/packages/i18n/locales/es/app.json @@ -0,0 +1,9 @@ +{ + "settings": { + "appearance": { + "title": "", + "language": "", + "languageHint": "" + } + } +} diff --git a/packages/i18n/locales/es/cli.json b/packages/i18n/locales/es/cli.json new file mode 100644 index 0000000000..8ccc6193b3 --- /dev/null +++ b/packages/i18n/locales/es/cli.json @@ -0,0 +1,6 @@ +{ + "tui": { + "loading": "", + "quit": "" + } +} diff --git a/packages/i18n/locales/es/common.json b/packages/i18n/locales/es/common.json new file mode 100644 index 0000000000..4593684237 --- /dev/null +++ b/packages/i18n/locales/es/common.json @@ -0,0 +1,15 @@ +{ + "columns": { + "triage": "", + "todo": "", + "in-progress": "", + "in-review": "", + "done": "", + "archived": "" + }, + "actions": { + "save": "", + "cancel": "", + "close": "" + } +} diff --git a/packages/i18n/locales/es/errors.json b/packages/i18n/locales/es/errors.json new file mode 100644 index 0000000000..0af69d4b5d --- /dev/null +++ b/packages/i18n/locales/es/errors.json @@ -0,0 +1,4 @@ +{ + "fetchProjectsFailed": "", + "openTaskLogsFailed": "" +} diff --git a/packages/i18n/locales/fr/app.json b/packages/i18n/locales/fr/app.json new file mode 100644 index 0000000000..0b4940a283 --- /dev/null +++ b/packages/i18n/locales/fr/app.json @@ -0,0 +1,9 @@ +{ + "settings": { + "appearance": { + "title": "", + "language": "", + "languageHint": "" + } + } +} diff --git a/packages/i18n/locales/fr/cli.json b/packages/i18n/locales/fr/cli.json new file mode 100644 index 0000000000..8ccc6193b3 --- /dev/null +++ b/packages/i18n/locales/fr/cli.json @@ -0,0 +1,6 @@ +{ + "tui": { + "loading": "", + "quit": "" + } +} diff --git a/packages/i18n/locales/fr/common.json b/packages/i18n/locales/fr/common.json new file mode 100644 index 0000000000..4593684237 --- /dev/null +++ b/packages/i18n/locales/fr/common.json @@ -0,0 +1,15 @@ +{ + "columns": { + "triage": "", + "todo": "", + "in-progress": "", + "in-review": "", + "done": "", + "archived": "" + }, + "actions": { + "save": "", + "cancel": "", + "close": "" + } +} diff --git a/packages/i18n/locales/fr/errors.json b/packages/i18n/locales/fr/errors.json new file mode 100644 index 0000000000..0af69d4b5d --- /dev/null +++ b/packages/i18n/locales/fr/errors.json @@ -0,0 +1,4 @@ +{ + "fetchProjectsFailed": "", + "openTaskLogsFailed": "" +} diff --git a/packages/i18n/locales/zh-CN/app.json b/packages/i18n/locales/zh-CN/app.json new file mode 100644 index 0000000000..0b4940a283 --- /dev/null +++ b/packages/i18n/locales/zh-CN/app.json @@ -0,0 +1,9 @@ +{ + "settings": { + "appearance": { + "title": "", + "language": "", + "languageHint": "" + } + } +} diff --git a/packages/i18n/locales/zh-CN/cli.json b/packages/i18n/locales/zh-CN/cli.json new file mode 100644 index 0000000000..8ccc6193b3 --- /dev/null +++ b/packages/i18n/locales/zh-CN/cli.json @@ -0,0 +1,6 @@ +{ + "tui": { + "loading": "", + "quit": "" + } +} diff --git a/packages/i18n/locales/zh-CN/common.json b/packages/i18n/locales/zh-CN/common.json new file mode 100644 index 0000000000..4593684237 --- /dev/null +++ b/packages/i18n/locales/zh-CN/common.json @@ -0,0 +1,15 @@ +{ + "columns": { + "triage": "", + "todo": "", + "in-progress": "", + "in-review": "", + "done": "", + "archived": "" + }, + "actions": { + "save": "", + "cancel": "", + "close": "" + } +} diff --git a/packages/i18n/locales/zh-CN/errors.json b/packages/i18n/locales/zh-CN/errors.json new file mode 100644 index 0000000000..0af69d4b5d --- /dev/null +++ b/packages/i18n/locales/zh-CN/errors.json @@ -0,0 +1,4 @@ +{ + "fetchProjectsFailed": "", + "openTaskLogsFailed": "" +} diff --git a/packages/i18n/locales/zh-TW/app.json b/packages/i18n/locales/zh-TW/app.json new file mode 100644 index 0000000000..0b4940a283 --- /dev/null +++ b/packages/i18n/locales/zh-TW/app.json @@ -0,0 +1,9 @@ +{ + "settings": { + "appearance": { + "title": "", + "language": "", + "languageHint": "" + } + } +} diff --git a/packages/i18n/locales/zh-TW/cli.json b/packages/i18n/locales/zh-TW/cli.json new file mode 100644 index 0000000000..8ccc6193b3 --- /dev/null +++ b/packages/i18n/locales/zh-TW/cli.json @@ -0,0 +1,6 @@ +{ + "tui": { + "loading": "", + "quit": "" + } +} diff --git a/packages/i18n/locales/zh-TW/common.json b/packages/i18n/locales/zh-TW/common.json new file mode 100644 index 0000000000..4593684237 --- /dev/null +++ b/packages/i18n/locales/zh-TW/common.json @@ -0,0 +1,15 @@ +{ + "columns": { + "triage": "", + "todo": "", + "in-progress": "", + "in-review": "", + "done": "", + "archived": "" + }, + "actions": { + "save": "", + "cancel": "", + "close": "" + } +} diff --git a/packages/i18n/locales/zh-TW/errors.json b/packages/i18n/locales/zh-TW/errors.json new file mode 100644 index 0000000000..0af69d4b5d --- /dev/null +++ b/packages/i18n/locales/zh-TW/errors.json @@ -0,0 +1,4 @@ +{ + "fetchProjectsFailed": "", + "openTaskLogsFailed": "" +} diff --git a/packages/i18n/package.json b/packages/i18n/package.json new file mode 100644 index 0000000000..5f05137e5a --- /dev/null +++ b/packages/i18n/package.json @@ -0,0 +1,37 @@ +{ + "name": "@fusion/i18n", + "version": "0.39.0", + "license": "MIT", + "description": "Fusion i18n: authored translation catalogs and shared i18next configuration for the Fusion dashboard and terminal UI.", + "type": "module", + "exports": { + ".": { + "types": "./src/index.ts", + "source": "./src/index.ts", + "import": "./src/index.ts" + }, + "./config": { + "types": "./src/config.ts", + "source": "./src/config.ts", + "import": "./src/config.ts" + } + }, + "scripts": { + "typecheck": "tsc --noEmit", + "gen:cli-catalogs": "node scripts/gen-cli-catalogs.mjs", + "test": "vitest run --silent=passed-only --reporter=dot" + }, + "dependencies": { + "@fusion/core": "workspace:*", + "i18next": "^26.3.1" + }, + "devDependencies": { + "@types/node": "^25.5.0", + "typescript": "^5.7.0", + "vitest": "^3.1.0" + }, + "engines": { + "node": ">=22.5.0" + }, + "private": true +} diff --git a/packages/i18n/scripts/gen-cli-catalogs.mjs b/packages/i18n/scripts/gen-cli-catalogs.mjs new file mode 100644 index 0000000000..7e878bfdad --- /dev/null +++ b/packages/i18n/scripts/gen-cli-catalogs.mjs @@ -0,0 +1,49 @@ +// Generates src/cli-catalogs.ts: a static import map of the CLI-relevant +// catalogs for every locale present under locales/. The terminal UI bundles +// catalogs statically (tsup, no lazy loading), so it needs an explicit import +// map rather than a dynamic loader. Driving this off the locales/ directory +// listing keeps "add a language" a no-code operation on the CLI side: add the +// locale (via `i18next-cli sync`), regenerate, done. +import { readdirSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const here = dirname(fileURLToPath(import.meta.url)); +const root = join(here, ".."); +const localesDir = join(root, "locales"); + +// Keep in sync with CLI_NAMESPACES in src/config.ts. +const CLI_NAMESPACES = ["common", "cli", "errors"]; + +const locales = readdirSync(localesDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name) + .sort(); + +const ident = (s) => s.replace(/[^a-zA-Z0-9]/g, "_"); + +const imports = []; +const entries = []; +for (const lng of locales) { + const nsLines = []; + for (const ns of CLI_NAMESPACES) { + const id = `${ident(lng)}_${ns}`; + imports.push(`import ${id} from "../locales/${lng}/${ns}.json";`); + nsLines.push(` ${ns}: ${id},`); + } + entries.push(` "${lng}": {\n${nsLines.join("\n")}\n },`); +} + +const out = [ + "// GENERATED by scripts/gen-cli-catalogs.mjs — do not edit by hand.", + "// Run `pnpm --filter @fusion/i18n gen:cli-catalogs` to regenerate.", + ...imports, + "", + "export const cliResources = {", + ...entries, + "} as const;", + "", +].join("\n"); + +writeFileSync(join(root, "src", "cli-catalogs.ts"), out); +console.log(`Generated cli-catalogs.ts for ${locales.length} locale(s): ${locales.join(", ")}`); diff --git a/packages/i18n/src/__tests__/config.test.ts b/packages/i18n/src/__tests__/config.test.ts new file mode 100644 index 0000000000..91836e5c90 --- /dev/null +++ b/packages/i18n/src/__tests__/config.test.ts @@ -0,0 +1,51 @@ +import { SUPPORTED_LOCALES } from "@fusion/core"; +import { describe, expect, it } from "vitest"; +import { cliResources } from "../cli-catalogs.js"; +import { + baseInitOptions, + CLI_NAMESPACES, + DASHBOARD_NAMESPACES, + DEFAULT_NAMESPACE, + FALLBACK_LNG, + NAMESPACES, +} from "../config.js"; + +describe("@fusion/i18n config", () => { + it("dashboard and cli namespaces are subsets of NAMESPACES", () => { + for (const ns of [...DASHBOARD_NAMESPACES, ...CLI_NAMESPACES]) { + expect(NAMESPACES).toContain(ns); + } + }); + + it("defaults to the common namespace", () => { + expect(DEFAULT_NAMESPACE).toBe("common"); + }); + + it("keeps zh-CN and zh-TW separate (load: currentOnly)", () => { + const opts = baseInitOptions(); + expect(opts.load).toBe("currentOnly"); + expect(opts.supportedLngs).toEqual([...SUPPORTED_LOCALES]); + expect(opts.interpolation?.escapeValue).toBe(false); + }); + + it("routes Chinese scripts and defaults everything else to en", () => { + expect(FALLBACK_LNG.zh).toEqual(["zh-CN"]); + expect(FALLBACK_LNG["zh-Hans"]).toEqual(["zh-CN"]); + expect(FALLBACK_LNG["zh-Hant"]).toEqual(["zh-TW"]); + expect(FALLBACK_LNG.default).toEqual(["en"]); + }); + + it("ships a CLI catalog map for every supported locale and namespace", () => { + for (const lng of SUPPORTED_LOCALES) { + expect(cliResources).toHaveProperty(lng); + for (const ns of CLI_NAMESPACES) { + expect(cliResources[lng]).toHaveProperty(ns); + } + } + }); + + it("has real en content (catalogs wired, not empty)", () => { + expect(cliResources.en.cli).toMatchObject({ tui: { loading: expect.any(String) } }); + expect(cliResources.en.common).toMatchObject({ columns: { done: "Done" } }); + }); +}); diff --git a/packages/i18n/src/cli-catalogs.ts b/packages/i18n/src/cli-catalogs.ts new file mode 100644 index 0000000000..354c3bc256 --- /dev/null +++ b/packages/i18n/src/cli-catalogs.ts @@ -0,0 +1,45 @@ +// GENERATED by scripts/gen-cli-catalogs.mjs — do not edit by hand. +// Run `pnpm --filter @fusion/i18n gen:cli-catalogs` to regenerate. +import en_common from "../locales/en/common.json"; +import en_cli from "../locales/en/cli.json"; +import en_errors from "../locales/en/errors.json"; +import es_common from "../locales/es/common.json"; +import es_cli from "../locales/es/cli.json"; +import es_errors from "../locales/es/errors.json"; +import fr_common from "../locales/fr/common.json"; +import fr_cli from "../locales/fr/cli.json"; +import fr_errors from "../locales/fr/errors.json"; +import zh_CN_common from "../locales/zh-CN/common.json"; +import zh_CN_cli from "../locales/zh-CN/cli.json"; +import zh_CN_errors from "../locales/zh-CN/errors.json"; +import zh_TW_common from "../locales/zh-TW/common.json"; +import zh_TW_cli from "../locales/zh-TW/cli.json"; +import zh_TW_errors from "../locales/zh-TW/errors.json"; + +export const cliResources = { + "en": { + common: en_common, + cli: en_cli, + errors: en_errors, + }, + "es": { + common: es_common, + cli: es_cli, + errors: es_errors, + }, + "fr": { + common: fr_common, + cli: fr_cli, + errors: fr_errors, + }, + "zh-CN": { + common: zh_CN_common, + cli: zh_CN_cli, + errors: zh_CN_errors, + }, + "zh-TW": { + common: zh_TW_common, + cli: zh_TW_cli, + errors: zh_TW_errors, + }, +} as const; diff --git a/packages/i18n/src/config.ts b/packages/i18n/src/config.ts new file mode 100644 index 0000000000..016ddec593 --- /dev/null +++ b/packages/i18n/src/config.ts @@ -0,0 +1,54 @@ +import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from "@fusion/core"; +import type { FallbackLngObjList, InitOptions } from "i18next"; + +/** + * Shared, framework-agnostic i18next configuration for both Fusion UI surfaces. + * + * The dashboard (browser) and the terminal UI (Node) each build their own + * i18next instance, but they share the locale list, namespace split, fallback + * chain, and base options defined here so the two surfaces stay consistent. + */ + +/** All translation namespaces. Split so each surface loads only what it needs. */ +export const NAMESPACES = ["common", "app", "errors", "cli"] as const; +export type Namespace = (typeof NAMESPACES)[number]; + +/** Default namespace keys resolve against when none is specified. */ +export const DEFAULT_NAMESPACE: Namespace = "common"; + +/** Namespaces the browser dashboard loads (skips the terminal-only `cli`). */ +export const DASHBOARD_NAMESPACES: readonly Namespace[] = ["common", "app", "errors"]; + +/** Namespaces the terminal UI loads (skips the dashboard-only `app`). */ +export const CLI_NAMESPACES: readonly Namespace[] = ["common", "cli", "errors"]; + +/** + * Script-aware fallback chain. A generic `zh` resolves to Simplified, the + * Han-script tags resolve to their region catalog, and everything else falls + * back to the source language. Combined with `load: "currentOnly"` this keeps + * `zh-CN` and `zh-TW` from ever collapsing into a single generic `zh`. + */ +export const FALLBACK_LNG: FallbackLngObjList = { + "zh-Hans": ["zh-CN"], + "zh-Hant": ["zh-TW"], + zh: ["zh-CN"], + default: [DEFAULT_LOCALE], +}; + +/** + * Base init options shared by every surface. Each surface spreads these and + * adds its own resource-loading strategy (lazy backend for the dashboard, + * static `resources` for the CLI) plus framework plugins. + */ +export function baseInitOptions(): InitOptions { + return { + supportedLngs: [...SUPPORTED_LOCALES], + fallbackLng: FALLBACK_LNG, + // Never collapse zh-CN/zh-TW into a generic `zh`. + load: "currentOnly", + nonExplicitSupportedLngs: false, + // React (and Ink) escape on render; double-escaping mangles output. + interpolation: { escapeValue: false }, + returnNull: false, + }; +} diff --git a/packages/i18n/src/index.ts b/packages/i18n/src/index.ts new file mode 100644 index 0000000000..38192f8e46 --- /dev/null +++ b/packages/i18n/src/index.ts @@ -0,0 +1,3 @@ +export * from "./config.js"; +export { cliResources } from "./cli-catalogs.js"; +export type { Locale } from "@fusion/core"; diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json new file mode 100644 index 0000000000..b55e80cea4 --- /dev/null +++ b/packages/i18n/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "rootDir": ".", + "types": ["node", "vitest/globals"], + "resolveJsonModule": true + }, + "include": ["src/**/*", "locales/**/*.json"], + "exclude": ["src/**/*.test.ts"] +} diff --git a/packages/i18n/vitest.config.ts b/packages/i18n/vitest.config.ts new file mode 100644 index 0000000000..3d2ce17782 --- /dev/null +++ b/packages/i18n/vitest.config.ts @@ -0,0 +1,14 @@ +import { resolve } from "node:path"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + resolve: { + alias: { + // Use @fusion/core's TypeScript source so tests don't require a dist build. + "@fusion/core": resolve(__dirname, "../core/src/index.ts"), + }, + }, + test: { + include: ["src/**/*.test.ts"], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 659232f24d..cab0352575 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: fast-glob: specifier: ^3.3.3 version: 3.3.3 + i18next-cli: + specifier: ^1.59.1 + version: 1.59.1(@types/node@25.5.2)(typescript@5.9.3) react-devtools-core: specifier: ^7.0.1 version: 7.0.1 @@ -43,16 +46,19 @@ importers: dependencies: '@earendil-works/pi-ai': specifier: ^0.78.0 - version: 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) + version: 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) '@earendil-works/pi-coding-agent': specifier: ^0.78.0 - version: 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) + version: 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) dockerode: specifier: ^4.0.12 version: 4.0.12 express: specifier: ^5.1.0 version: 5.2.1 + i18next: + specifier: ^26.3.1 + version: 26.3.1(typescript@5.9.3) ink: specifier: ^6.8.0 version: 6.8.0(@types/react@19.2.14)(react-devtools-core@7.0.1)(react@19.2.4) @@ -74,6 +80,9 @@ importers: react: specifier: ^19.0.0 version: 19.2.4 + react-i18next: + specifier: ^17.0.8 + version: 17.0.8(i18next@26.3.1(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) devDependencies: '@fusion/core': specifier: workspace:* @@ -84,6 +93,9 @@ importers: '@fusion/engine': specifier: workspace:* version: link:../engine + '@fusion/i18n': + specifier: workspace:* + version: link:../i18n '@fusion/pi-claude-cli': specifier: workspace:* version: link:../pi-claude-cli @@ -110,7 +122,7 @@ importers: version: 4.0.0(@types/react@19.2.14) tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + version: 8.5.1(@swc/core@1.15.40)(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) tsx: specifier: ^4.19.0 version: 4.21.0 @@ -236,6 +248,9 @@ importers: '@fusion/engine': specifier: workspace:* version: link:../engine + '@fusion/i18n': + specifier: workspace:* + version: link:../i18n '@types/multer': specifier: ^2.1.0 version: 2.1.0 @@ -260,6 +275,15 @@ importers: express: specifier: ^5.1.0 version: 5.2.1 + i18next: + specifier: ^26.3.1 + version: 26.3.1(typescript@5.9.3) + i18next-browser-languagedetector: + specifier: ^8.2.1 + version: 8.2.1 + i18next-resources-to-backend: + specifier: ^1.2.1 + version: 1.2.1 ioredis: specifier: ^5.6.0 version: 5.10.1 @@ -281,6 +305,9 @@ importers: react-dom: specifier: ^19.0.0 version: 19.2.4(react@19.2.4) + react-i18next: + specifier: ^17.0.8 + version: 17.0.8(i18next@26.3.1(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) react-markdown: specifier: ^10.1.0 version: 10.1.0(@types/react@19.2.14)(react@19.2.4) @@ -472,6 +499,25 @@ importers: specifier: ^3.1.0 version: 3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(jiti@2.7.0)(jsdom@29.0.1)(tsx@4.21.0)(yaml@2.9.0) + packages/i18n: + dependencies: + '@fusion/core': + specifier: workspace:* + version: link:../core + i18next: + specifier: ^26.3.1 + version: 26.3.1(typescript@5.9.3) + devDependencies: + '@types/node': + specifier: ^25.5.2 + version: 25.5.2 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vitest: + specifier: ^3.1.0 + version: 3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(jiti@2.7.0)(jsdom@29.0.1)(tsx@4.21.0)(yaml@2.9.0) + packages/mobile: dependencies: '@capacitor/app': @@ -516,10 +562,10 @@ importers: dependencies: '@earendil-works/pi-ai': specifier: '*' - version: 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + version: 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) '@earendil-works/pi-coding-agent': specifier: '*' - version: 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + version: 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) devDependencies: '@types/node': specifier: ^25.5.2 @@ -1334,6 +1380,12 @@ packages: '@codemirror/view@6.40.0': resolution: {integrity: sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg==} + '@croct/json5-parser@0.2.2': + resolution: {integrity: sha512-0NJMLrbeLbQ0eCVj3UoH/kG2QckUgOASfwmfDTjyW1xAYPyTNJXcWVT/dssJdTJd0pRchW+qF0VFWQHcxs1OVw==} + + '@croct/json@2.1.0': + resolution: {integrity: sha512-UrWfjNQVlBxN+OVcFwHmkjARMW55MBN04E9KfGac8ac8z1QnFVuiOOFtMWXCk3UwsyRqhsNaFoYLZC+xxqsVjQ==} + '@csstools/color-helpers@6.0.2': resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} engines: {node: '>=20.19.0'} @@ -1987,6 +2039,55 @@ packages: cpu: [x64] os: [win32] + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + + '@inquirer/checkbox@5.2.1': + resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@5.2.2': + resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@5.1.1': + resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} @@ -1996,6 +2097,91 @@ packages: '@types/node': optional: true + '@inquirer/external-editor@3.0.3': + resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + + '@inquirer/input@5.1.2': + resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@4.1.1': + resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@5.1.1': + resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@8.5.2': + resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@5.3.1': + resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@4.2.1': + resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@5.2.1': + resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@ionic/cli-framework-output@2.2.8': resolution: {integrity: sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==} engines: {node: '>=16.0.0'} @@ -2406,6 +2592,9 @@ packages: cpu: [x64] os: [win32] + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@silvia-odwyer/photon-node@0.3.4': resolution: {integrity: sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==} @@ -2413,6 +2602,10 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@smithy/core@3.24.5': resolution: {integrity: sha512-Kt8phUg45M15EjhYAbZ+fFikYneijLu9Liugz8ZsYz2i8j0hzGv27LWKpEHYRfvj+LyCOSijpcR/2i8RouV+cA==} engines: {node: '>=18.0.0'} @@ -2453,6 +2646,99 @@ packages: resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} + '@swc/core-darwin-arm64@1.15.40': + resolution: {integrity: sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.40': + resolution: {integrity: sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.40': + resolution: {integrity: sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.40': + resolution: {integrity: sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-arm64-musl@1.15.40': + resolution: {integrity: sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@swc/core-linux-ppc64-gnu@1.15.40': + resolution: {integrity: sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-s390x-gnu@1.15.40': + resolution: {integrity: sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-gnu@1.15.40': + resolution: {integrity: sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-musl@1.15.40': + resolution: {integrity: sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@swc/core-win32-arm64-msvc@1.15.40': + resolution: {integrity: sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.40': + resolution: {integrity: sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.40': + resolution: {integrity: sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.40': + resolution: {integrity: sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.26': + resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} + '@szmarczak/http-timer@4.0.6': resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} @@ -3242,6 +3528,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -3272,10 +3562,18 @@ packages: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} + cli-truncate@2.1.0: resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} engines: {node: '>=8'} @@ -3284,6 +3582,10 @@ packages: resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} engines: {node: '>=20'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -3334,6 +3636,10 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -3817,6 +4123,10 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -3869,9 +4179,18 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + fast-xml-builder@1.2.0: resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} @@ -3898,6 +4217,10 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -4037,6 +4360,10 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-tsconfig@4.13.7: resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} @@ -4156,6 +4483,9 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + html-url-attributes@3.0.1: resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} @@ -4182,6 +4512,33 @@ packages: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + i18next-browser-languagedetector@8.2.1: + resolution: {integrity: sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==} + + i18next-cli@1.59.1: + resolution: {integrity: sha512-Zr65j0BVePuFzMz7kz0h7TdDEZn2msWt4+F59UhvQghH6nHAu0xMlzOmPR7ddxcKjpK0HFJfRoTJX3QIlZToEg==} + engines: {node: '>=22'} + hasBin: true + + i18next-resources-for-ts@2.1.0: + resolution: {integrity: sha512-n5UexwEVt0OoIAhG2MWpSnAVJW1U8mQrQTmXyxc5DMAx+NLhcLZhSMJo/FnUsA5JQ3obTYqTgB7YIuZKWpDgow==} + hasBin: true + + i18next-resources-to-backend@1.2.1: + resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} + + i18next@26.3.1: + resolution: {integrity: sha512-txQqd5EULsqEh9OJqRH15aCaOuy/nLJyhw5EHCSKLKJE1aBbb3Zve2+uQIxgWhPm1QqUQoWyQBm2kfmmIrzkcQ==} + peerDependencies: + typescript: ^5 || ^6 + peerDependenciesMeta: + typescript: + optional: true + iconv-corefoundation@1.1.7: resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} engines: {node: ^8.11.2 || >=10} @@ -4275,6 +4632,15 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + inquirer@13.4.3: + resolution: {integrity: sha512-EPd3IqieHSavSOXh+LZhrIkdQcOELWeRblLT6kslQr+cF9XTh/HxZdSt1YkHH1iq4dvqBnV42uwg2YlorgOy6g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': ^25.5.2 + peerDependenciesMeta: + '@types/node': + optional: true + ioredis@5.10.1: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} @@ -4332,6 +4698,10 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -4350,6 +4720,10 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} @@ -4358,6 +4732,10 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -4484,6 +4862,9 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -4582,6 +4963,10 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} + engines: {node: '>=18'} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -4834,6 +5219,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -4932,6 +5321,10 @@ packages: resolution: {integrity: sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==} engines: {node: '>=10'} + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -5012,6 +5405,10 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -5042,6 +5439,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -5069,6 +5470,10 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + ora@9.4.0: + resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==} + engines: {node: '>=20'} + outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} @@ -5125,6 +5530,10 @@ packages: parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parse5@8.0.0: resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} @@ -5155,6 +5564,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -5278,6 +5691,10 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + proc-log@5.0.0: resolution: {integrity: sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==} engines: {node: ^18.17.0 || >=20.5.0} @@ -5386,6 +5803,22 @@ packages: peerDependencies: react: ^19.2.4 + react-i18next@17.0.8: + resolution: {integrity: sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==} + peerDependencies: + i18next: '>= 26.2.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + typescript: ^5 || ^6 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -5409,6 +5842,10 @@ packages: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} + engines: {node: '>=0.10.0'} + read-binary-file-arch@1.0.6: resolution: {integrity: sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==} hasBin: true @@ -5439,6 +5876,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} @@ -5507,6 +5948,10 @@ packages: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -5542,9 +5987,16 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + run-async@4.0.6: + resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -5764,6 +6216,10 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stdin-discarder@0.3.2: + resolution: {integrity: sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==} + engines: {node: '>=18'} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -5808,6 +6264,10 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -6093,6 +6553,10 @@ packages: resolution: {integrity: sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==} engines: {node: '>=22.19.0'} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -6144,6 +6608,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -6242,6 +6711,10 @@ packages: jsdom: optional: true + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -6410,6 +6883,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + yoga-layout@3.2.1: resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} @@ -7124,6 +7601,12 @@ snapshots: style-mod: 4.1.3 w3c-keyname: 2.2.8 + '@croct/json5-parser@0.2.2': + dependencies: + '@croct/json': 2.1.0 + + '@croct/json@2.1.0': {} + '@csstools/color-helpers@6.0.2': {} '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': @@ -7167,9 +7650,9 @@ snapshots: - ws - zod - '@earendil-works/pi-agent-core@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@earendil-works/pi-agent-core@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': dependencies: - '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) ignore: 7.0.5 typebox: 1.1.38 yaml: 2.9.0 @@ -7181,9 +7664,9 @@ snapshots: - ws - zod - '@earendil-works/pi-agent-core@0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': + '@earendil-works/pi-agent-core@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: - '@earendil-works/pi-ai': 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) + '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) ignore: 7.0.5 typebox: 1.1.38 yaml: 2.9.0 @@ -7243,16 +7726,16 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@earendil-works/pi-ai@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': dependencies: - '@anthropic-ai/sdk': 0.91.1(zod@4.3.6) + '@anthropic-ai/sdk': 0.91.1(zod@3.25.76) '@aws-sdk/client-bedrock-runtime': 3.1048.0 - '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6)) + '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76)) '@mistralai/mistralai': 2.2.1 '@smithy/node-http-handler': 4.7.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - openai: 6.26.0(ws@8.20.0)(zod@4.3.6) + openai: 6.26.0(ws@8.20.0)(zod@3.25.76) partial-json: 0.1.7 typebox: 1.1.38 transitivePeerDependencies: @@ -7263,16 +7746,16 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': + '@earendil-works/pi-ai@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: - '@anthropic-ai/sdk': 0.91.1(zod@3.25.76) + '@anthropic-ai/sdk': 0.91.1(zod@4.3.6) '@aws-sdk/client-bedrock-runtime': 3.1048.0 - '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76)) + '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6)) '@mistralai/mistralai': 2.2.1 '@smithy/node-http-handler': 4.7.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 - openai: 6.26.0(ws@8.20.0)(zod@3.25.76) + openai: 6.26.0(ws@8.20.0)(zod@4.3.6) partial-json: 0.1.7 typebox: 1.1.38 transitivePeerDependencies: @@ -7352,10 +7835,10 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + '@earendil-works/pi-coding-agent@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': dependencies: - '@earendil-works/pi-agent-core': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) - '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@earendil-works/pi-agent-core': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) + '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) '@earendil-works/pi-tui': 0.77.0 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 @@ -7381,11 +7864,11 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76)': + '@earendil-works/pi-coding-agent@0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': dependencies: - '@earendil-works/pi-agent-core': 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) - '@earendil-works/pi-ai': 0.78.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.20.0)(zod@3.25.76) - '@earendil-works/pi-tui': 0.78.0 + '@earendil-works/pi-agent-core': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@earendil-works/pi-ai': 0.77.0(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@earendil-works/pi-tui': 0.77.0 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cross-spawn: 7.0.6 @@ -7946,6 +8429,51 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true + '@inquirer/ansi@2.0.7': {} + + '@inquirer/checkbox@5.2.1(@types/node@25.5.2)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/confirm@6.1.1(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/core@11.2.1(@types/node@25.5.2)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@25.5.2) + cli-width: 4.1.0 + fast-wrap-ansi: 0.2.2 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/editor@5.2.2(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/external-editor': 3.0.3(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/expand@5.1.1(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + '@inquirer/external-editor@1.0.3(@types/node@25.5.2)': dependencies: chardet: 2.1.1 @@ -7953,6 +8481,80 @@ snapshots: optionalDependencies: '@types/node': 25.5.2 + '@inquirer/external-editor@3.0.3(@types/node@25.5.2)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/figures@2.0.7': {} + + '@inquirer/input@5.1.2(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/number@4.1.1(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/password@5.1.1(@types/node@25.5.2)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/prompts@8.5.2(@types/node@25.5.2)': + dependencies: + '@inquirer/checkbox': 5.2.1(@types/node@25.5.2) + '@inquirer/confirm': 6.1.1(@types/node@25.5.2) + '@inquirer/editor': 5.2.2(@types/node@25.5.2) + '@inquirer/expand': 5.1.1(@types/node@25.5.2) + '@inquirer/input': 5.1.2(@types/node@25.5.2) + '@inquirer/number': 4.1.1(@types/node@25.5.2) + '@inquirer/password': 5.1.1(@types/node@25.5.2) + '@inquirer/rawlist': 5.3.1(@types/node@25.5.2) + '@inquirer/search': 4.2.1(@types/node@25.5.2) + '@inquirer/select': 5.2.1(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/rawlist@5.3.1(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/search@4.2.1(@types/node@25.5.2)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/select@5.2.1(@types/node@25.5.2)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@25.5.2) + optionalDependencies: + '@types/node': 25.5.2 + + '@inquirer/type@4.0.7(@types/node@25.5.2)': + optionalDependencies: + '@types/node': 25.5.2 + '@ionic/cli-framework-output@2.2.8': dependencies: '@ionic/utils-terminal': 2.3.5 @@ -8384,10 +8986,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.0': optional: true + '@sec-ant/readable-stream@0.4.1': {} + '@silvia-odwyer/photon-node@0.3.4': {} '@sindresorhus/is@4.6.0': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@smithy/core@3.24.5': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -8442,6 +9048,66 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 + '@swc/core-darwin-arm64@1.15.40': + optional: true + + '@swc/core-darwin-x64@1.15.40': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.40': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.40': + optional: true + + '@swc/core-linux-arm64-musl@1.15.40': + optional: true + + '@swc/core-linux-ppc64-gnu@1.15.40': + optional: true + + '@swc/core-linux-s390x-gnu@1.15.40': + optional: true + + '@swc/core-linux-x64-gnu@1.15.40': + optional: true + + '@swc/core-linux-x64-musl@1.15.40': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.40': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.40': + optional: true + + '@swc/core-win32-x64-msvc@1.15.40': + optional: true + + '@swc/core@1.15.40': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.26 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.40 + '@swc/core-darwin-x64': 1.15.40 + '@swc/core-linux-arm-gnueabihf': 1.15.40 + '@swc/core-linux-arm64-gnu': 1.15.40 + '@swc/core-linux-arm64-musl': 1.15.40 + '@swc/core-linux-ppc64-gnu': 1.15.40 + '@swc/core-linux-s390x-gnu': 1.15.40 + '@swc/core-linux-x64-gnu': 1.15.40 + '@swc/core-linux-x64-musl': 1.15.40 + '@swc/core-win32-arm64-msvc': 1.15.40 + '@swc/core-win32-ia32-msvc': 1.15.40 + '@swc/core-win32-x64-msvc': 1.15.40 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.26': + dependencies: + '@swc/counter': 0.1.3 + '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 @@ -9426,6 +10092,10 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chownr@1.1.4: {} chownr@3.0.0: {} @@ -9446,8 +10116,14 @@ snapshots: dependencies: restore-cursor: 4.0.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} + cli-spinners@3.4.0: {} + cli-truncate@2.1.0: dependencies: slice-ansi: 3.0.0 @@ -9459,6 +10135,8 @@ snapshots: slice-ansi: 8.0.0 string-width: 8.2.0 + cli-width@4.1.0: {} + cliui@6.0.0: dependencies: string-width: 4.2.3 @@ -9509,6 +10187,8 @@ snapshots: commander@12.1.0: {} + commander@14.0.3: {} + commander@4.1.1: {} commander@5.1.0: {} @@ -10071,6 +10751,21 @@ snapshots: dependencies: eventsource-parser: 3.0.6 + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + expand-template@2.0.3: {} expect-type@1.3.0: {} @@ -10148,8 +10843,18 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + fast-uri@3.1.0: {} + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + fast-xml-builder@1.2.0: dependencies: path-expression-matcher: 1.5.0 @@ -10179,6 +10884,10 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -10344,6 +11053,11 @@ snapshots: dependencies: pump: 3.0.4 + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-tsconfig@4.13.7: dependencies: resolve-pkg-maps: 1.0.0 @@ -10509,6 +11223,10 @@ snapshots: html-escaper@2.0.2: {} + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + html-url-attributes@3.0.1: {} http-cache-semantics@4.2.0: {} @@ -10542,6 +11260,55 @@ snapshots: human-id@4.1.3: {} + human-signals@8.0.1: {} + + i18next-browser-languagedetector@8.2.1: + dependencies: + '@babel/runtime': 7.29.2 + + i18next-cli@1.59.1(@types/node@25.5.2)(typescript@5.9.3): + dependencies: + '@croct/json5-parser': 0.2.2 + '@swc/core': 1.15.40 + chokidar: 5.0.0 + commander: 14.0.3 + execa: 9.6.1 + glob: 13.0.6 + i18next: 26.3.1(typescript@5.9.3) + i18next-resources-for-ts: 2.1.0 + inquirer: 13.4.3(@types/node@25.5.2) + jiti: 2.7.0 + jsonc-parser: 3.3.1 + magic-string: 0.30.21 + minimatch: 10.2.5 + ora: 9.4.0 + react: 19.2.7 + react-i18next: 17.0.8(i18next@26.3.1(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3) + yaml: 2.9.0 + transitivePeerDependencies: + - '@swc/helpers' + - '@types/node' + - react-dom + - react-native + - typescript + + i18next-resources-for-ts@2.1.0: + dependencies: + '@babel/runtime': 7.29.2 + '@swc/core': 1.15.40 + chokidar: 5.0.0 + yaml: 2.9.0 + transitivePeerDependencies: + - '@swc/helpers' + + i18next-resources-to-backend@1.2.1: + dependencies: + '@babel/runtime': 7.29.2 + + i18next@26.3.1(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + iconv-corefoundation@1.1.7: dependencies: cli-truncate: 2.1.0 @@ -10638,6 +11405,18 @@ snapshots: inline-style-parser@0.2.7: {} + inquirer@13.4.3(@types/node@25.5.2): + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@25.5.2) + '@inquirer/prompts': 8.5.2(@types/node@25.5.2) + '@inquirer/type': 4.0.7(@types/node@25.5.2) + mute-stream: 3.0.0 + run-async: 4.0.6 + rxjs: 7.8.2 + optionalDependencies: + '@types/node': 25.5.2 + ioredis@5.10.1: dependencies: '@ioredis/commands': 1.5.1 @@ -10687,6 +11466,8 @@ snapshots: is-interactive@1.0.0: {} + is-interactive@2.0.0: {} + is-number@7.0.0: {} is-plain-obj@4.1.0: {} @@ -10697,12 +11478,16 @@ snapshots: is-stream@2.0.1: {} + is-stream@4.0.1: {} + is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 is-unicode-supported@0.1.0: {} + is-unicode-supported@2.1.0: {} + is-windows@1.0.2: {} is-wsl@2.2.0: @@ -10827,6 +11612,8 @@ snapshots: json5@2.2.3: {} + jsonc-parser@3.3.1: {} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -10921,6 +11708,11 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 + long@5.3.2: {} longest-streak@3.1.0: {} @@ -11369,6 +12161,8 @@ snapshots: mimic-fn@2.1.0: {} + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -11476,6 +12270,8 @@ snapshots: transitivePeerDependencies: - supports-color + mute-stream@3.0.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -11564,6 +12360,11 @@ snapshots: normalize-url@6.1.0: {} + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -11592,6 +12393,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -11635,6 +12440,17 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + ora@9.4.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.3.2 + string-width: 8.2.0 + outdent@0.5.0: {} p-cancelable@2.1.1: {} @@ -11690,6 +12506,8 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-ms@4.0.0: {} + parse5@8.0.0: dependencies: entities: 6.0.1 @@ -11708,6 +12526,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -11823,6 +12643,10 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + proc-log@5.0.0: {} process-nextick-args@2.0.1: {} @@ -11952,6 +12776,27 @@ snapshots: react: 19.2.4 scheduler: 0.27.0 + react-i18next@17.0.8(i18next@26.3.1(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + html-parse-stringify: 3.0.1 + i18next: 26.3.1(typescript@5.9.3) + react: 19.2.4 + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + typescript: 5.9.3 + + react-i18next@17.0.8(i18next@26.3.1(typescript@5.9.3))(react@19.2.7)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + html-parse-stringify: 3.0.1 + i18next: 26.3.1(typescript@5.9.3) + react: 19.2.7 + use-sync-external-store: 1.6.0(react@19.2.7) + optionalDependencies: + typescript: 5.9.3 + react-is@17.0.2: {} react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4): @@ -11981,6 +12826,8 @@ snapshots: react@19.2.4: {} + react@19.2.7: {} + read-binary-file-arch@1.0.6: dependencies: debug: 4.4.3 @@ -12028,6 +12875,8 @@ snapshots: readdirp@4.1.2: {} + readdirp@5.0.0: {} + real-require@0.2.0: {} redent@3.0.0: @@ -12107,6 +12956,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + retry@0.12.0: {} retry@0.13.1: {} @@ -12173,10 +13027,16 @@ snapshots: transitivePeerDependencies: - supports-color + run-async@4.0.6: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -12422,6 +13282,8 @@ snapshots: std-env@3.10.0: {} + stdin-discarder@0.3.2: {} + streamsearch@1.1.0: {} streamx@2.25.0: @@ -12479,6 +13341,8 @@ snapshots: strip-bom@3.0.0: {} + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -12689,7 +13553,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.1(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3): + tsup@8.5.1(@swc/core@1.15.40)(jiti@2.7.0)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3): dependencies: bundle-require: 5.1.0(esbuild@0.27.4) cac: 6.7.14 @@ -12709,6 +13573,7 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: + '@swc/core': 1.15.40 postcss: 8.5.8 typescript: 5.9.3 transitivePeerDependencies: @@ -12781,6 +13646,8 @@ snapshots: undici@8.3.0: {} + unicorn-magic@0.3.0: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -12840,6 +13707,14 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + + use-sync-external-store@1.6.0(react@19.2.7): + dependencies: + react: 19.2.7 + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} @@ -13023,6 +13898,8 @@ snapshots: - tsx - yaml + void-elements@3.1.0: {} + w3c-keyname@2.2.8: {} w3c-xmlserializer@5.0.0: @@ -13165,6 +14042,8 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors@2.1.2: {} + yoga-layout@3.2.1: {} zip-stream@6.0.1: