nuxt.config.ts
Rama main · réplica de lectura del repositorio original.
// https://nuxt.com/docs/api/configuration/nuxt-config
import tailwindcss from "@tailwindcss/vite";
import { fileURLToPath } from "node:url";
export default defineNuxtConfig({
compatibilityDate: "2025-07-15",
devtools: { enabled: true },
sourcemap: {
client: false,
server: false,
},
experimental: {
// Nuxt 4.6 owns the route type tree (fetchdts), avoiding Nitro's deep InternalApi unions.
// Keep unknown API paths as type errors so a renamed endpoint fails lint before the E2E run.
routeTypedFetch: true,
strictRouteTypes: true,
checkOutdatedBuildInterval: 5 * 60_000,
emitRouteChunkError: "automatic-immediate",
// Nuxt 4.5 reuses Vite's watcher instead of opening a second watcher tree.
watcher: "builder",
},
css: ["~/assets/css/tailwind.css"],
modules: ["@pinia/nuxt", "@nuxtjs/device", "@nuxtjs/i18n", "nuxt-echarts", "@vite-pwa/nuxt"],
pwa: {
strategies: "injectManifest",
// Nuxt 4 roots relative PWA paths under app/. Keep the worker outside that DOM TS project
// and resolve from this config so the production build and E2E layer use the same entry.
srcDir: fileURLToPath(new URL("./service-worker", import.meta.url)),
filename: "notifications.ts",
// The Nuxt module owns registration, updates, and the manifest. Business stores only manage
// notification permission and account subscriptions through its native runtime hooks.
manifest: {
name: "Codex Gateway",
short_name: "Codex",
id: "/",
start_url: "/",
scope: "/",
display: "standalone",
background_color: "#ffffff",
theme_color: "#ffffff",
icons: [
{ src: "/android-chrome-192x192.png", sizes: "192x192", type: "image/png" },
{ src: "/android-chrome-512x512.png", sizes: "512x512", type: "image/png" },
],
},
// This worker owns push only. Never precache authenticated pages, API replies, or Nuxt
// bundles: that would introduce another stale-history/cache path alongside the live Gateway.
injectManifest: { injectionPoint: undefined, globPatterns: [] },
},
echarts: {
renderer: "canvas",
charts: ["LineChart"],
components: ["GridComponent", "TooltipComponent", "LegendComponent"],
},
vite: {
resolve: {
// Open File Viewer loads Prism languages in dependency order. One shared Prism instance
// preserves that side-effect ordering without forcing all languages into a vendor chunk.
dedupe: ["prismjs"],
},
plugins: [tailwindcss()],
},
nitro: {
rollupConfig: {
external: ["node:sqlite"],
},
experimental: {
websocket: true,
tasks: true,
},
scheduledTasks: {
"*/30 * * * * *": ["gateway:sync-running-threads"],
"*/5 * * * *": ["gateway:poll-tmux-monitors"],
"0 * * * *": ["gateway:prune-expired-sessions"],
},
},
i18n: {
defaultLocale: "zh",
strategy: "no_prefix",
detectBrowserLanguage: false,
locales: [
{ code: "zh", name: "中文", file: "zh.json" },
{ code: "en", name: "English", file: "en.json" },
],
},
});