diff --git a/apps/app/src/components/views/board-view.tsx b/apps/app/src/components/views/board-view.tsx
index da7af3b1..273cac0d 100644
--- a/apps/app/src/components/views/board-view.tsx
+++ b/apps/app/src/components/views/board-view.tsx
@@ -121,7 +121,7 @@ type ModelOption = {
label: string;
description: string;
badge?: string;
- provider: "claude" | "codex";
+ provider: "claude";
};
const CLAUDE_MODELS: ModelOption[] = [
@@ -148,44 +148,6 @@ const CLAUDE_MODELS: ModelOption[] = [
},
];
-const CODEX_MODELS: ModelOption[] = [
- {
- id: "gpt-5.2",
- label: "GPT-5.2",
- description: "Latest OpenAI model with advanced coding capabilities.",
- badge: "Latest",
- provider: "codex",
- },
- {
- id: "gpt-5.1-codex-max",
- label: "GPT-5.1 Codex Max",
- description: "Flagship Codex model tuned for deep coding tasks.",
- badge: "Flagship",
- provider: "codex",
- },
- {
- id: "gpt-5.1-codex",
- label: "GPT-5.1 Codex",
- description: "Strong coding performance with lower cost.",
- badge: "Standard",
- provider: "codex",
- },
- {
- id: "gpt-5.1-codex-mini",
- label: "GPT-5.1 Codex Mini",
- description: "Fastest Codex option for lightweight edits.",
- badge: "Fast",
- provider: "codex",
- },
- {
- id: "gpt-5.1",
- label: "GPT-5.1",
- description: "General-purpose reasoning with solid coding ability.",
- badge: "General",
- provider: "codex",
- },
-];
-
// Profile icon mapping
const PROFILE_ICONS: Record<
string,
@@ -1700,12 +1662,8 @@ export function BoardView() {
{options.map((option) => {
const isSelected = selectedModel === option.id;
- const isCodex = option.provider === "codex";
// Shorter display names for compact view
- const shortName = option.label
- .replace("Claude ", "")
- .replace("GPT-5.1 Codex ", "")
- .replace("GPT-5.1 ", "");
+ const shortName = option.label.replace("Claude ", "");
return (
- {/* Model Selection - Claude */}
+ {/* Model Selection */}
{CLAUDE_MODELS.map(({ id, label }) => (
@@ -372,33 +344,7 @@ function ProfileForm({
- {/* Model Selection - Codex */}
-
-
-
- {CODEX_MODELS.map(({ id, label }) => (
-
- ))}
-
-
-
- {/* Thinking Level - Only for Claude models */}
+ {/* Thinking Level */}
{supportsThinking && (
- {/* Codex/OpenAI Authentication Status */}
-
-
-
- {codexAuthStatus?.authenticated ? (
- <>
-
-
- Authenticated
-
-
-
-
- {codexAuthStatus.method === "subscription"
- ? "Using Codex subscription (Plus/Team)"
- : codexAuthStatus.method === "cli_verified" ||
- codexAuthStatus.method === "cli_tokens"
- ? "Using CLI login (OpenAI account)"
- : codexAuthStatus.method === "api_key"
- ? "Using stored API key"
- : codexAuthStatus.method === "env"
- ? "Using OPENAI_API_KEY"
- : `Using ${codexAuthStatus.method || "unknown"} authentication`}
-
-
- >
- ) : apiKeyStatus?.hasOpenAIKey ? (
-
-
- Using environment variable (OPENAI_API_KEY)
-
- ) : apiKeys.openai ? (
-
-
- Using manual API key from settings
-
- ) : (
-
- )}
-
-
-
{/* Google/Gemini Authentication Status */}
diff --git a/apps/app/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts b/apps/app/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts
index f45939ed..d5478ca0 100644
--- a/apps/app/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts
+++ b/apps/app/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts
@@ -10,7 +10,6 @@ interface TestResult {
interface ApiKeyStatus {
hasAnthropicKey: boolean;
- hasOpenAIKey: boolean;
hasGoogleKey: boolean;
}
@@ -24,12 +23,10 @@ export function useApiKeyManagement() {
// API key values
const [anthropicKey, setAnthropicKey] = useState(apiKeys.anthropic);
const [googleKey, setGoogleKey] = useState(apiKeys.google);
- const [openaiKey, setOpenaiKey] = useState(apiKeys.openai);
// Visibility toggles
const [showAnthropicKey, setShowAnthropicKey] = useState(false);
const [showGoogleKey, setShowGoogleKey] = useState(false);
- const [showOpenaiKey, setShowOpenaiKey] = useState(false);
// Test connection states
const [testingConnection, setTestingConnection] = useState(false);
@@ -38,10 +35,6 @@ export function useApiKeyManagement() {
const [geminiTestResult, setGeminiTestResult] = useState
(
null
);
- const [testingOpenaiConnection, setTestingOpenaiConnection] = useState(false);
- const [openaiTestResult, setOpenaiTestResult] = useState(
- null
- );
// API key status from environment
const [apiKeyStatus, setApiKeyStatus] = useState(null);
@@ -53,7 +46,6 @@ export function useApiKeyManagement() {
useEffect(() => {
setAnthropicKey(apiKeys.anthropic);
setGoogleKey(apiKeys.google);
- setOpenaiKey(apiKeys.openai);
}, [apiKeys]);
// Check API key status from environment on mount
@@ -66,7 +58,6 @@ export function useApiKeyManagement() {
if (status.success) {
setApiKeyStatus({
hasAnthropicKey: status.hasAnthropicKey,
- hasOpenAIKey: status.hasOpenAIKey,
hasGoogleKey: status.hasGoogleKey,
});
}
@@ -152,68 +143,11 @@ export function useApiKeyManagement() {
}
};
- // Test OpenAI connection
- const handleTestOpenaiConnection = async () => {
- setTestingOpenaiConnection(true);
- setOpenaiTestResult(null);
-
- try {
- const api = getElectronAPI();
- if (api?.testOpenAIConnection) {
- const result = await api.testOpenAIConnection(openaiKey);
- if (result.success) {
- setOpenaiTestResult({
- success: true,
- message:
- result.message || "Connection successful! OpenAI API responded.",
- });
- } else {
- setOpenaiTestResult({
- success: false,
- message: result.error || "Failed to connect to OpenAI API.",
- });
- }
- } else {
- // Fallback to web API test
- const response = await fetch("/api/openai/test", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ apiKey: openaiKey }),
- });
-
- const data = await response.json();
-
- if (response.ok && data.success) {
- setOpenaiTestResult({
- success: true,
- message:
- data.message || "Connection successful! OpenAI API responded.",
- });
- } else {
- setOpenaiTestResult({
- success: false,
- message: data.error || "Failed to connect to OpenAI API.",
- });
- }
- }
- } catch {
- setOpenaiTestResult({
- success: false,
- message: "Network error. Please check your connection.",
- });
- } finally {
- setTestingOpenaiConnection(false);
- }
- };
-
// Save API keys
const handleSave = () => {
setApiKeys({
anthropic: anthropicKey,
google: googleKey,
- openai: openaiKey,
});
setSaved(true);
setTimeout(() => setSaved(false), 2000);
@@ -240,15 +174,6 @@ export function useApiKeyManagement() {
onTest: handleTestGeminiConnection,
result: geminiTestResult,
},
- openai: {
- value: openaiKey,
- setValue: setOpenaiKey,
- show: showOpenaiKey,
- setShow: setShowOpenaiKey,
- testing: testingOpenaiConnection,
- onTest: handleTestOpenaiConnection,
- result: openaiTestResult,
- },
};
return {
diff --git a/apps/app/src/components/views/settings-view/cli-status/codex-cli-status.tsx b/apps/app/src/components/views/settings-view/cli-status/codex-cli-status.tsx
deleted file mode 100644
index 5f0bde25..00000000
--- a/apps/app/src/components/views/settings-view/cli-status/codex-cli-status.tsx
+++ /dev/null
@@ -1,169 +0,0 @@
-import { Button } from "@/components/ui/button";
-import {
- Terminal,
- CheckCircle2,
- AlertCircle,
- RefreshCw,
-} from "lucide-react";
-import type { CliStatus } from "../shared/types";
-
-interface CliStatusProps {
- status: CliStatus | null;
- isChecking: boolean;
- onRefresh: () => void;
-}
-
-export function CodexCliStatus({
- status,
- isChecking,
- onRefresh,
-}: CliStatusProps) {
- if (!status) return null;
-
- return (
-
-
-
-
-
-
- OpenAI Codex CLI
-
-
-
-
-
- Codex CLI enables GPT-5.1 Codex models for autonomous coding tasks.
-
-
-
- {status.success && status.status === "installed" ? (
-
-
-
-
-
- Codex CLI Installed
-
-
- {status.method && (
-
- Method: {status.method}
-
- )}
- {status.version && (
-
- Version:{" "}
- {status.version}
-
- )}
- {status.path && (
-
- Path:{" "}
-
- {status.path}
-
-
- )}
-
-
-
- {status.recommendation && (
-
- {status.recommendation}
-
- )}
-
- ) : status.status === "api_key_only" ? (
-
-
-
-
-
- API Key Detected - CLI Not Installed
-
-
- {status.recommendation ||
- "OPENAI_API_KEY found but Codex CLI not installed. Install the CLI for full agentic capabilities."}
-
-
-
- {status.installCommands && (
-
-
- Installation Commands:
-
-
- {status.installCommands.npm && (
-
-
npm:
-
- {status.installCommands.npm}
-
-
- )}
-
-
- )}
-
- ) : (
-
-
-
-
-
- Codex CLI Not Detected
-
-
- {status.recommendation ||
- "Install OpenAI Codex CLI to use GPT-5.1 Codex models for autonomous coding."}
-
-
-
- {status.installCommands && (
-
-
- Installation Commands:
-
-
- {status.installCommands.npm && (
-
-
npm:
-
- {status.installCommands.npm}
-
-
- )}
- {status.installCommands.macos && (
-
-
- macOS (Homebrew):
-
-
- {status.installCommands.macos}
-
-
- )}
-
-
- )}
-
- )}
-
-
- );
-}
diff --git a/apps/app/src/components/views/settings-view/hooks/use-cli-status.ts b/apps/app/src/components/views/settings-view/hooks/use-cli-status.ts
index 600a5f67..4b65d1ae 100644
--- a/apps/app/src/components/views/settings-view/hooks/use-cli-status.ts
+++ b/apps/app/src/components/views/settings-view/hooks/use-cli-status.ts
@@ -18,25 +18,17 @@ interface CliStatusResult {
error?: string;
}
-interface CodexCliStatusResult extends CliStatusResult {
- hasApiKey?: boolean;
-}
-
/**
- * Custom hook for managing Claude and Codex CLI status
+ * Custom hook for managing Claude CLI status
* Handles checking CLI installation, authentication, and refresh functionality
*/
export function useCliStatus() {
- const { setClaudeAuthStatus, setCodexAuthStatus } = useSetupStore();
+ const { setClaudeAuthStatus } = useSetupStore();
const [claudeCliStatus, setClaudeCliStatus] =
useState(null);
- const [codexCliStatus, setCodexCliStatus] =
- useState(null);
-
const [isCheckingClaudeCli, setIsCheckingClaudeCli] = useState(false);
- const [isCheckingCodexCli, setIsCheckingCodexCli] = useState(false);
// Check CLI status on mount
useEffect(() => {
@@ -53,16 +45,6 @@ export function useCliStatus() {
}
}
- // Check Codex CLI
- if (api?.checkCodexCli) {
- try {
- const status = await api.checkCodexCli();
- setCodexCliStatus(status);
- } catch (error) {
- console.error("Failed to check Codex CLI status:", error);
- }
- }
-
// Check Claude auth status (re-fetch on mount to ensure persistence)
if (api?.setup?.getClaudeStatus) {
try {
@@ -95,47 +77,10 @@ export function useCliStatus() {
console.error("Failed to check Claude auth status:", error);
}
}
-
- // Check Codex auth status (re-fetch on mount to ensure persistence)
- if (api?.setup?.getCodexStatus) {
- try {
- const result = await api.setup.getCodexStatus();
- if (result.success && result.auth) {
- // Cast to extended type that includes server-added fields
- const auth = result.auth as typeof result.auth & {
- hasSubscription?: boolean;
- cliLoggedIn?: boolean;
- hasEnvApiKey?: boolean;
- };
- // Map server method names to client method types
- // Server returns: subscription, cli_verified, cli_tokens, api_key, env, none
- const validMethods = ["subscription", "cli_verified", "cli_tokens", "api_key", "env", "none"] as const;
- type CodexMethod = typeof validMethods[number];
- const method: CodexMethod = validMethods.includes(auth.method as CodexMethod)
- ? (auth.method as CodexMethod)
- : auth.authenticated ? "api_key" : "none"; // Default authenticated to api_key
-
- const authStatus = {
- authenticated: auth.authenticated,
- method,
- // Only set apiKeyValid for actual API key methods, not CLI login or subscription
- apiKeyValid:
- method === "cli_verified" || method === "cli_tokens" || method === "subscription"
- ? undefined
- : auth.hasAuthFile || auth.hasEnvKey || auth.hasEnvApiKey,
- hasSubscription: auth.hasSubscription,
- cliLoggedIn: auth.cliLoggedIn,
- };
- setCodexAuthStatus(authStatus);
- }
- } catch (error) {
- console.error("Failed to check Codex auth status:", error);
- }
- }
};
checkCliStatus();
- }, [setClaudeAuthStatus, setCodexAuthStatus]);
+ }, [setClaudeAuthStatus]);
// Refresh Claude CLI status
const handleRefreshClaudeCli = useCallback(async () => {
@@ -153,28 +98,9 @@ export function useCliStatus() {
}
}, []);
- // Refresh Codex CLI status
- const handleRefreshCodexCli = useCallback(async () => {
- setIsCheckingCodexCli(true);
- try {
- const api = getElectronAPI();
- if (api?.checkCodexCli) {
- const status = await api.checkCodexCli();
- setCodexCliStatus(status);
- }
- } catch (error) {
- console.error("Failed to refresh Codex CLI status:", error);
- } finally {
- setIsCheckingCodexCli(false);
- }
- }, []);
-
return {
claudeCliStatus,
- codexCliStatus,
isCheckingClaudeCli,
- isCheckingCodexCli,
handleRefreshClaudeCli,
- handleRefreshCodexCli,
};
}
diff --git a/apps/app/src/components/views/setup-view.tsx b/apps/app/src/components/views/setup-view.tsx
index 331dbc0a..cf5cb7d3 100644
--- a/apps/app/src/components/views/setup-view.tsx
+++ b/apps/app/src/components/views/setup-view.tsx
@@ -7,7 +7,6 @@ import {
WelcomeStep,
CompleteStep,
ClaudeSetupStep,
- CodexSetupStep,
} from "./setup-view/steps";
// Main Setup View
@@ -17,17 +16,14 @@ export function SetupView() {
setCurrentStep,
completeSetup,
setSkipClaudeSetup,
- setSkipCodexSetup,
} = useSetupStore();
const { setCurrentView } = useAppStore();
- const steps = ["welcome", "claude", "codex", "complete"] as const;
+ const steps = ["welcome", "claude", "complete"] as const;
type StepName = (typeof steps)[number];
const getStepName = (): StepName => {
if (currentStep === "claude_detect" || currentStep === "claude_auth")
return "claude";
- if (currentStep === "codex_detect" || currentStep === "codex_auth")
- return "codex";
if (currentStep === "welcome") return "welcome";
return "complete";
};
@@ -46,10 +42,6 @@ export function SetupView() {
setCurrentStep("claude_detect");
break;
case "claude":
- console.log("[Setup Flow] Moving to codex_detect step");
- setCurrentStep("codex_detect");
- break;
- case "codex":
console.log("[Setup Flow] Moving to complete step");
setCurrentStep("complete");
break;
@@ -62,21 +54,12 @@ export function SetupView() {
case "claude":
setCurrentStep("welcome");
break;
- case "codex":
- setCurrentStep("claude_detect");
- break;
}
};
const handleSkipClaude = () => {
console.log("[Setup Flow] Skipping Claude setup");
setSkipClaudeSetup(true);
- setCurrentStep("codex_detect");
- };
-
- const handleSkipCodex = () => {
- console.log("[Setup Flow] Skipping Codex setup");
- setSkipCodexSetup(true);
setCurrentStep("complete");
};
@@ -127,15 +110,6 @@ export function SetupView() {
/>
)}
- {(currentStep === "codex_detect" ||
- currentStep === "codex_auth") && (
- handleNext("codex")}
- onBack={() => handleBack("codex")}
- onSkip={handleSkipCodex}
- />
- )}
-
{currentStep === "complete" && (
)}
diff --git a/apps/app/src/components/views/setup-view/steps/codex-setup-step.tsx b/apps/app/src/components/views/setup-view/steps/codex-setup-step.tsx
deleted file mode 100644
index a5f18ce4..00000000
--- a/apps/app/src/components/views/setup-view/steps/codex-setup-step.tsx
+++ /dev/null
@@ -1,460 +0,0 @@
-"use client";
-
-import { useState, useEffect, useCallback } from "react";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import { Label } from "@/components/ui/label";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { useSetupStore } from "@/store/setup-store";
-import { useAppStore } from "@/store/app-store";
-import { getElectronAPI } from "@/lib/electron";
-import {
- CheckCircle2,
- Loader2,
- Terminal,
- Key,
- ArrowRight,
- ArrowLeft,
- ExternalLink,
- Copy,
- AlertCircle,
- RefreshCw,
- Download,
-} from "lucide-react";
-import { toast } from "sonner";
-import { StatusBadge, TerminalOutput } from "../components";
-import {
- useCliStatus,
- useCliInstallation,
- useTokenSave,
-} from "../hooks";
-
-interface CodexSetupStepProps {
- onNext: () => void;
- onBack: () => void;
- onSkip: () => void;
-}
-
-export function CodexSetupStep({
- onNext,
- onBack,
- onSkip,
-}: CodexSetupStepProps) {
- const {
- codexCliStatus,
- codexAuthStatus,
- setCodexCliStatus,
- setCodexAuthStatus,
- setCodexInstallProgress,
- } = useSetupStore();
- const { setApiKeys, apiKeys } = useAppStore();
-
- const [showApiKeyInput, setShowApiKeyInput] = useState(false);
- const [apiKey, setApiKey] = useState("");
-
- // Memoize API functions to prevent infinite loops
- const statusApi = useCallback(
- () => getElectronAPI().setup?.getCodexStatus() || Promise.reject(),
- []
- );
-
- const installApi = useCallback(
- () => getElectronAPI().setup?.installCodex() || Promise.reject(),
- []
- );
-
- // Use custom hooks
- const { isChecking, checkStatus } = useCliStatus({
- cliType: "codex",
- statusApi,
- setCliStatus: setCodexCliStatus,
- setAuthStatus: setCodexAuthStatus,
- });
-
- const onInstallSuccess = useCallback(() => {
- checkStatus();
- }, [checkStatus]);
-
- const { isInstalling, installProgress, install } = useCliInstallation({
- cliType: "codex",
- installApi,
- onProgressEvent: getElectronAPI().setup?.onInstallProgress,
- onSuccess: onInstallSuccess,
- });
-
- const { isSaving: isSavingKey, saveToken: saveApiKeyToken } = useTokenSave({
- provider: "openai",
- onSuccess: () => {
- setCodexAuthStatus({
- authenticated: true,
- method: "api_key",
- apiKeyValid: true,
- });
- setApiKeys({ ...apiKeys, openai: apiKey });
- setShowApiKeyInput(false);
- checkStatus();
- },
- });
-
- // Sync install progress to store
- useEffect(() => {
- setCodexInstallProgress({
- isInstalling,
- output: installProgress.output,
- });
- }, [isInstalling, installProgress, setCodexInstallProgress]);
-
- // Check status on mount
- useEffect(() => {
- checkStatus();
- }, [checkStatus]);
-
- const copyCommand = (command: string) => {
- navigator.clipboard.writeText(command);
- toast.success("Command copied to clipboard");
- };
-
- const isAuthenticated = codexAuthStatus?.authenticated || apiKeys.openai;
-
- const getAuthMethodLabel = () => {
- if (!isAuthenticated) return null;
- if (apiKeys.openai) return "API Key (Manual)";
- if (codexAuthStatus?.method === "api_key") return "API Key (Auth File)";
- if (codexAuthStatus?.method === "env") return "API Key (Environment)";
- if (codexAuthStatus?.method === "cli_verified")
- return "CLI Login (ChatGPT)";
- return "Authenticated";
- };
-
- return (
-
-
-
-
-
-
- Codex CLI Setup
-
-
- OpenAI's GPT-5.1 Codex for advanced code generation
-
-
-
- {/* Status Card */}
-
-
-
- Installation Status
-
-
-
-
-
- CLI Installation
- {isChecking ? (
-
- ) : codexCliStatus?.installed ? (
-
- ) : (
-
- )}
-
-
- {codexCliStatus?.version && (
-
- Version
-
- {codexCliStatus.version}
-
-
- )}
-
-
-
Authentication
- {isAuthenticated ? (
-
-
- {getAuthMethodLabel() && (
-
- ({getAuthMethodLabel()})
-
- )}
-
- ) : (
-
- )}
-
-
-
-
- {/* Installation Section */}
- {!codexCliStatus?.installed && (
-
-
-
-
- Install Codex CLI
-
-
- Install via npm (Node.js required)
-
-
-
-
-
-
-
- npm install -g @openai/codex
-
-
-
-
-
- {isInstalling && (
-
- )}
-
-
-
-
-
-
-
-
-
- Requires Node.js to be installed. If the auto-install fails,
- try running the command manually in your terminal.
-
-
-
-
-
- )}
-
- {/* Authentication Section */}
- {!isAuthenticated && (
-
-
-
-
- Authentication
-
- Codex requires authentication via ChatGPT account or API key
-
-
- {codexCliStatus?.installed && (
-
-
-
-
-
- Authenticate via CLI (Recommended)
-
-
- Run the following command in your terminal to login with your ChatGPT account:
-
-
-
- codex auth login
-
-
-
-
- After logging in, you can verify your authentication status:
-
-
-
- codex login status
-
-
-
-
-
-
- )}
-
-
-
-
-
-
-
- or enter API key
-
-
-
-
- {showApiKeyInput ? (
-
-
-
-
setApiKey(e.target.value)}
- className="bg-input border-border text-foreground"
- data-testid="openai-api-key-input"
- />
-
- Get your API key from{" "}
-
- platform.openai.com
-
-
-
-
-
-
-
-
-
- ) : (
-
- )}
-
-
- )}
-
- {/* Success State */}
- {isAuthenticated && (
-
-
-
-
-
-
-
-
- Codex is ready to use!
-
-
- {getAuthMethodLabel() &&
- `Authenticated via ${getAuthMethodLabel()}. `}
- You can proceed to complete setup
-
-
-
-
-
- )}
-
- {/* Navigation */}
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/app/src/components/views/setup-view/steps/complete-step.tsx b/apps/app/src/components/views/setup-view/steps/complete-step.tsx
index 447c6465..bcffebc1 100644
--- a/apps/app/src/components/views/setup-view/steps/complete-step.tsx
+++ b/apps/app/src/components/views/setup-view/steps/complete-step.tsx
@@ -14,16 +14,13 @@ interface CompleteStepProps {
}
export function CompleteStep({ onFinish }: CompleteStepProps) {
- const { claudeCliStatus, claudeAuthStatus, codexCliStatus, codexAuthStatus } =
+ const { claudeCliStatus, claudeAuthStatus } =
useSetupStore();
const { apiKeys } = useAppStore();
const claudeReady =
(claudeCliStatus?.installed && claudeAuthStatus?.authenticated) ||
apiKeys.anthropic;
- const codexReady =
- (codexCliStatus?.installed && codexAuthStatus?.authenticated) ||
- apiKeys.openai;
return (
@@ -41,7 +38,7 @@ export function CompleteStep({ onFinish }: CompleteStepProps) {
-
+
-
-
-
-
- {codexReady ? (
-
- ) : (
-
- )}
-
-
Codex
-
- {codexReady ? "Ready to use" : "Configure later in settings"}
-
-
-
-
-
diff --git a/apps/app/src/components/views/setup-view/steps/index.ts b/apps/app/src/components/views/setup-view/steps/index.ts
index 5fa3a01c..4ad4a782 100644
--- a/apps/app/src/components/views/setup-view/steps/index.ts
+++ b/apps/app/src/components/views/setup-view/steps/index.ts
@@ -2,4 +2,3 @@
export { WelcomeStep } from "./welcome-step";
export { CompleteStep } from "./complete-step";
export { ClaudeSetupStep } from "./claude-setup-step";
-export { CodexSetupStep } from "./codex-setup-step";
diff --git a/apps/app/src/config/api-providers.ts b/apps/app/src/config/api-providers.ts
index b0a9bf78..aa7eccd9 100644
--- a/apps/app/src/config/api-providers.ts
+++ b/apps/app/src/config/api-providers.ts
@@ -2,7 +2,7 @@ import type { Dispatch, SetStateAction } from "react";
import type { LucideIcon } from "lucide-react";
import type { ApiKeys } from "@/store/app-store";
-export type ProviderKey = "anthropic" | "google" | "openai";
+export type ProviderKey = "anthropic" | "google";
export interface ProviderConfig {
key: ProviderKey;
@@ -51,22 +51,12 @@ export interface ProviderConfigParams {
onTest: () => Promise
;
result: { success: boolean; message: string } | null;
};
- openai: {
- value: string;
- setValue: Dispatch>;
- show: boolean;
- setShow: Dispatch>;
- testing: boolean;
- onTest: () => Promise;
- result: { success: boolean; message: string } | null;
- };
}
export const buildProviderConfigs = ({
apiKeys,
anthropic,
google,
- openai,
}: ProviderConfigParams): ProviderConfig[] => [
{
key: "anthropic",
@@ -121,29 +111,4 @@ export const buildProviderConfigs = ({
descriptionLinkHref: "https://makersuite.google.com/app/apikey",
descriptionLinkText: "makersuite.google.com",
},
- {
- key: "openai",
- label: "OpenAI API Key (Codex/GPT)",
- inputId: "openai-key",
- placeholder: "sk-...",
- value: openai.value,
- setValue: openai.setValue,
- showValue: openai.show,
- setShowValue: openai.setShow,
- hasStoredKey: apiKeys.openai,
- inputTestId: "openai-api-key-input",
- toggleTestId: "toggle-openai-visibility",
- testButton: {
- onClick: openai.onTest,
- disabled: !openai.value || openai.testing,
- loading: openai.testing,
- testId: "test-openai-connection",
- },
- result: openai.result,
- resultTestId: "openai-test-connection-result",
- resultMessageTestId: "openai-test-connection-message",
- descriptionPrefix: "Used for OpenAI Codex CLI and GPT models. Get your key at",
- descriptionLinkHref: "https://platform.openai.com/api-keys",
- descriptionLinkText: "platform.openai.com",
- },
];
diff --git a/apps/app/src/lib/utils.ts b/apps/app/src/lib/utils.ts
index 8d7b6386..b4081da9 100644
--- a/apps/app/src/lib/utils.ts
+++ b/apps/app/src/lib/utils.ts
@@ -6,27 +6,12 @@ export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
-/**
- * Check if a model is a Codex/OpenAI model (doesn't support thinking)
- */
-export function isCodexModel(model?: AgentModel | string): boolean {
- if (!model) return false;
- const codexModels: string[] = [
- "gpt-5.2",
- "gpt-5.1-codex-max",
- "gpt-5.1-codex",
- "gpt-5.1-codex-mini",
- "gpt-5.1",
- ];
- return codexModels.includes(model);
-}
-
/**
* Determine if the current model supports extended thinking controls
*/
export function modelSupportsThinking(model?: AgentModel | string): boolean {
- if (!model) return true;
- return !isCodexModel(model);
+ // All Claude models support thinking
+ return true;
}
/**
@@ -37,11 +22,6 @@ export function getModelDisplayName(model: AgentModel | string): string {
haiku: "Claude Haiku",
sonnet: "Claude Sonnet",
opus: "Claude Opus",
- "gpt-5.2": "GPT-5.2",
- "gpt-5.1-codex-max": "GPT-5.1 Codex Max",
- "gpt-5.1-codex": "GPT-5.1 Codex",
- "gpt-5.1-codex-mini": "GPT-5.1 Codex Mini",
- "gpt-5.1": "GPT-5.1",
};
return displayNames[model] || model;
}
diff --git a/apps/app/src/store/setup-store.ts b/apps/app/src/store/setup-store.ts
index 15714d28..6b3bcd1a 100644
--- a/apps/app/src/store/setup-store.ts
+++ b/apps/app/src/store/setup-store.ts
@@ -32,26 +32,6 @@ export interface ClaudeAuthStatus {
error?: string;
}
-// Codex Auth Method - all possible authentication sources
-export type CodexAuthMethod =
- | "subscription" // Codex/OpenAI Plus or Team subscription
- | "cli_verified" // CLI logged in with OpenAI account
- | "cli_tokens" // CLI with stored access tokens
- | "api_key" // Manually stored API key
- | "env" // OPENAI_API_KEY environment variable
- | "none";
-
-// Codex Auth Status
-export interface CodexAuthStatus {
- authenticated: boolean;
- method: CodexAuthMethod;
- apiKeyValid?: boolean;
- mcpConfigured?: boolean;
- hasSubscription?: boolean;
- cliLoggedIn?: boolean;
- error?: string;
-}
-
// Installation Progress
export interface InstallProgress {
isInstalling: boolean;
@@ -65,8 +45,6 @@ export type SetupStep =
| "welcome"
| "claude_detect"
| "claude_auth"
- | "codex_detect"
- | "codex_auth"
| "complete";
export interface SetupState {
@@ -80,14 +58,8 @@ export interface SetupState {
claudeAuthStatus: ClaudeAuthStatus | null;
claudeInstallProgress: InstallProgress;
- // Codex CLI state
- codexCliStatus: CliStatus | null;
- codexAuthStatus: CodexAuthStatus | null;
- codexInstallProgress: InstallProgress;
-
// Setup preferences
skipClaudeSetup: boolean;
- skipCodexSetup: boolean;
}
export interface SetupActions {
@@ -103,15 +75,8 @@ export interface SetupActions {
setClaudeInstallProgress: (progress: Partial) => void;
resetClaudeInstallProgress: () => void;
- // Codex CLI
- setCodexCliStatus: (status: CliStatus | null) => void;
- setCodexAuthStatus: (status: CodexAuthStatus | null) => void;
- setCodexInstallProgress: (progress: Partial) => void;
- resetCodexInstallProgress: () => void;
-
// Preferences
setSkipClaudeSetup: (skip: boolean) => void;
- setSkipCodexSetup: (skip: boolean) => void;
}
const initialInstallProgress: InstallProgress = {
@@ -130,12 +95,7 @@ const initialState: SetupState = {
claudeAuthStatus: null,
claudeInstallProgress: { ...initialInstallProgress },
- codexCliStatus: null,
- codexAuthStatus: null,
- codexInstallProgress: { ...initialInstallProgress },
-
skipClaudeSetup: false,
- skipCodexSetup: false,
};
export const useSetupStore = create()(
@@ -171,26 +131,8 @@ export const useSetupStore = create()(
claudeInstallProgress: { ...initialInstallProgress },
}),
- // Codex CLI
- setCodexCliStatus: (status) => set({ codexCliStatus: status }),
-
- setCodexAuthStatus: (status) => set({ codexAuthStatus: status }),
-
- setCodexInstallProgress: (progress) => set({
- codexInstallProgress: {
- ...get().codexInstallProgress,
- ...progress,
- },
- }),
-
- resetCodexInstallProgress: () => set({
- codexInstallProgress: { ...initialInstallProgress },
- }),
-
// Preferences
setSkipClaudeSetup: (skip) => set({ skipClaudeSetup: skip }),
-
- setSkipCodexSetup: (skip) => set({ skipCodexSetup: skip }),
}),
{
name: "automaker-setup",
@@ -198,7 +140,6 @@ export const useSetupStore = create()(
isFirstRun: state.isFirstRun,
setupComplete: state.setupComplete,
skipClaudeSetup: state.skipClaudeSetup,
- skipCodexSetup: state.skipCodexSetup,
}),
}
)
diff --git a/apps/server/src/lib/model-resolver.ts b/apps/server/src/lib/model-resolver.ts
index d4e12756..d4bbff5e 100644
--- a/apps/server/src/lib/model-resolver.ts
+++ b/apps/server/src/lib/model-resolver.ts
@@ -3,7 +3,6 @@
*
* Provides centralized model resolution logic:
* - Maps Claude model aliases to full model strings
- * - Detects and passes through OpenAI/Codex models
* - Provides default models per provider
* - Handles multiple model sources with priority
*/
@@ -22,7 +21,6 @@ export const CLAUDE_MODEL_MAP: Record = {
*/
export const DEFAULT_MODELS = {
claude: "claude-opus-4-5-20251101",
- openai: "gpt-5.2",
} as const;
/**
@@ -41,13 +39,6 @@ export function resolveModelString(
return defaultModel;
}
- // OpenAI/Codex models - pass through unchanged
- // Only check for gpt-* models (Codex CLI doesn't support o1/o3)
- if (modelKey.startsWith("gpt-")) {
- console.log(`[ModelResolver] Using OpenAI/Codex model: ${modelKey}`);
- return modelKey;
- }
-
// Full Claude model string - pass through unchanged
if (modelKey.includes("claude-")) {
console.log(`[ModelResolver] Using full Claude model string: ${modelKey}`);
diff --git a/apps/server/src/providers/codex-cli-detector.ts b/apps/server/src/providers/codex-cli-detector.ts
deleted file mode 100644
index 21445b46..00000000
--- a/apps/server/src/providers/codex-cli-detector.ts
+++ /dev/null
@@ -1,408 +0,0 @@
-/**
- * Codex CLI Detector - Checks if OpenAI Codex CLI is installed
- *
- * Codex CLI is OpenAI's agent CLI tool that allows users to use
- * GPT-5.1/5.2 Codex models for code generation and agentic tasks.
- */
-
-import { execSync } from "child_process";
-import fs from "fs";
-import path from "path";
-import os from "os";
-import type { InstallationStatus } from "./types.js";
-
-export class CodexCliDetector {
- /**
- * Get the path to Codex config directory
- */
- static getConfigDir(): string {
- return path.join(os.homedir(), ".codex");
- }
-
- /**
- * Get the path to Codex auth file
- */
- static getAuthPath(): string {
- return path.join(this.getConfigDir(), "auth.json");
- }
-
- /**
- * Check Codex authentication status
- */
- static checkAuth(): {
- authenticated: boolean;
- method: string;
- hasAuthFile?: boolean;
- hasEnvKey?: boolean;
- authPath?: string;
- error?: string;
- } {
- try {
- const authPath = this.getAuthPath();
- const envApiKey = process.env.OPENAI_API_KEY;
-
- // Try to verify authentication using codex CLI command if available
- try {
- const detection = this.detectCodexInstallation();
- if (detection.installed && detection.path) {
- try {
- // Use 2>&1 to capture both stdout and stderr
- const statusOutput = execSync(
- `"${detection.path}" login status 2>&1`,
- {
- encoding: "utf-8",
- timeout: 5000,
- }
- ).trim();
-
- // Check if the output indicates logged in status
- if (
- statusOutput &&
- (statusOutput.includes("Logged in") || statusOutput.includes("Authenticated"))
- ) {
- return {
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: fs.existsSync(authPath),
- hasEnvKey: !!envApiKey,
- authPath,
- };
- }
- } catch (statusError) {
- // status command failed, continue with file-based check
- }
- }
- } catch (verifyError) {
- // CLI verification failed, continue with file-based check
- }
-
- // Check if auth file exists
- if (fs.existsSync(authPath)) {
- try {
- const content = fs.readFileSync(authPath, "utf-8");
- const auth: any = JSON.parse(content);
-
- // Check for token object structure
- if (auth.token && typeof auth.token === "object") {
- const token = auth.token;
- if (
- token.Id_token ||
- token.access_token ||
- token.refresh_token ||
- token.id_token
- ) {
- return {
- authenticated: true,
- method: "cli_tokens",
- hasAuthFile: true,
- hasEnvKey: !!envApiKey,
- authPath,
- };
- }
- }
-
- // Check for tokens at root level
- if (
- auth.access_token ||
- auth.refresh_token ||
- auth.Id_token ||
- auth.id_token
- ) {
- return {
- authenticated: true,
- method: "cli_tokens",
- hasAuthFile: true,
- hasEnvKey: !!envApiKey,
- authPath,
- };
- }
-
- // Check for API key fields
- if (auth.api_key || auth.openai_api_key || auth.apiKey) {
- return {
- authenticated: true,
- method: "auth_file",
- hasAuthFile: true,
- hasEnvKey: !!envApiKey,
- authPath,
- };
- }
- } catch (error) {
- return {
- authenticated: false,
- method: "none",
- hasAuthFile: false,
- hasEnvKey: !!envApiKey,
- authPath,
- };
- }
- }
-
- // Environment variable override
- if (envApiKey) {
- return {
- authenticated: true,
- method: "env",
- hasAuthFile: fs.existsSync(authPath),
- hasEnvKey: true,
- authPath,
- };
- }
-
- return {
- authenticated: false,
- method: "none",
- hasAuthFile: fs.existsSync(authPath),
- hasEnvKey: false,
- authPath,
- };
- } catch (error) {
- return {
- authenticated: false,
- method: "none",
- error: (error as Error).message,
- };
- }
- }
-
- /**
- * Check if Codex CLI is installed and accessible
- */
- static detectCodexInstallation(): InstallationStatus & {
- hasApiKey?: boolean;
- } {
- try {
- // Method 1: Check if 'codex' command is in PATH
- try {
- const codexPath = execSync("which codex 2>/dev/null", {
- encoding: "utf-8",
- }).trim();
- if (codexPath) {
- const version = this.getCodexVersion(codexPath);
- return {
- installed: true,
- path: codexPath,
- version: version || undefined,
- method: "cli",
- };
- }
- } catch (error) {
- // CLI not in PATH, continue checking other methods
- }
-
- // Method 2: Check for npm global installation
- try {
- const npmListOutput = execSync(
- "npm list -g @openai/codex --depth=0 2>/dev/null",
- { encoding: "utf-8" }
- );
- if (npmListOutput && npmListOutput.includes("@openai/codex")) {
- // Get the path from npm bin
- const npmBinPath = execSync("npm bin -g", {
- encoding: "utf-8",
- }).trim();
- const codexPath = path.join(npmBinPath, "codex");
- const version = this.getCodexVersion(codexPath);
- return {
- installed: true,
- path: codexPath,
- version: version || undefined,
- method: "npm",
- };
- }
- } catch (error) {
- // npm global not found
- }
-
- // Method 3: Check for Homebrew installation on macOS
- if (process.platform === "darwin") {
- try {
- const brewList = execSync("brew list --formula 2>/dev/null", {
- encoding: "utf-8",
- });
- if (brewList.includes("codex")) {
- const brewPrefixOutput = execSync("brew --prefix codex 2>/dev/null", {
- encoding: "utf-8",
- }).trim();
- const codexPath = path.join(brewPrefixOutput, "bin", "codex");
- const version = this.getCodexVersion(codexPath);
- return {
- installed: true,
- path: codexPath,
- version: version || undefined,
- method: "brew",
- };
- }
- } catch (error) {
- // Homebrew not found or codex not installed via brew
- }
- }
-
- // Method 4: Check Windows path
- if (process.platform === "win32") {
- try {
- const codexPath = execSync("where codex 2>nul", {
- encoding: "utf-8",
- })
- .trim()
- .split("\n")[0];
- if (codexPath) {
- const version = this.getCodexVersion(codexPath);
- return {
- installed: true,
- path: codexPath,
- version: version || undefined,
- method: "cli",
- };
- }
- } catch (error) {
- // Not found on Windows
- }
- }
-
- // Method 5: Check common installation paths
- const commonPaths = [
- path.join(os.homedir(), ".local", "bin", "codex"),
- path.join(os.homedir(), ".npm-global", "bin", "codex"),
- "/usr/local/bin/codex",
- "/opt/homebrew/bin/codex",
- ];
-
- for (const checkPath of commonPaths) {
- if (fs.existsSync(checkPath)) {
- const version = this.getCodexVersion(checkPath);
- return {
- installed: true,
- path: checkPath,
- version: version || undefined,
- method: "cli",
- };
- }
- }
-
- // Method 6: Check if OPENAI_API_KEY is set (can use Codex API directly)
- if (process.env.OPENAI_API_KEY) {
- return {
- installed: false,
- hasApiKey: true,
- };
- }
-
- return {
- installed: false,
- };
- } catch (error) {
- return {
- installed: false,
- error: (error as Error).message,
- };
- }
- }
-
- /**
- * Get Codex CLI version from executable path
- */
- static getCodexVersion(codexPath: string): string | null {
- try {
- const version = execSync(`"${codexPath}" --version 2>/dev/null`, {
- encoding: "utf-8",
- }).trim();
- return version || null;
- } catch (error) {
- return null;
- }
- }
-
- /**
- * Get installation info and recommendations
- */
- static getInstallationInfo(): {
- status: string;
- method?: string;
- version?: string | null;
- path?: string | null;
- recommendation: string;
- installCommands?: Record;
- } {
- const detection = this.detectCodexInstallation();
-
- if (detection.installed) {
- return {
- status: "installed",
- method: detection.method,
- version: detection.version,
- path: detection.path,
- recommendation:
- detection.method === "cli"
- ? "Using Codex CLI - ready for GPT-5.1/5.2 Codex models"
- : `Using Codex CLI via ${detection.method} - ready for GPT-5.1/5.2 Codex models`,
- };
- }
-
- // Not installed but has API key
- if (detection.hasApiKey) {
- return {
- status: "api_key_only",
- method: "api-key-only",
- recommendation:
- "OPENAI_API_KEY detected but Codex CLI not installed. Install Codex CLI for full agentic capabilities.",
- installCommands: this.getInstallCommands(),
- };
- }
-
- return {
- status: "not_installed",
- recommendation:
- "Install OpenAI Codex CLI to use GPT-5.1/5.2 Codex models for agentic tasks",
- installCommands: this.getInstallCommands(),
- };
- }
-
- /**
- * Get installation commands for different platforms
- */
- static getInstallCommands(): Record {
- return {
- npm: "npm install -g @openai/codex@latest",
- macos: "brew install codex",
- linux: "npm install -g @openai/codex@latest",
- windows: "npm install -g @openai/codex@latest",
- };
- }
-
- /**
- * Check if Codex CLI supports a specific model
- */
- static isModelSupported(model: string): boolean {
- const supportedModels = [
- "gpt-5.1-codex-max",
- "gpt-5.1-codex",
- "gpt-5.1-codex-mini",
- "gpt-5.1",
- "gpt-5.2",
- ];
- return supportedModels.includes(model);
- }
-
- /**
- * Get default model for Codex CLI
- */
- static getDefaultModel(): string {
- return "gpt-5.2";
- }
-
- /**
- * Get comprehensive installation info including auth status
- */
- static getFullStatus() {
- const installation = this.detectCodexInstallation();
- const auth = this.checkAuth();
- const info = this.getInstallationInfo();
-
- return {
- ...info,
- auth,
- installation,
- };
- }
-}
diff --git a/apps/server/src/providers/codex-config-manager.ts b/apps/server/src/providers/codex-config-manager.ts
deleted file mode 100644
index 12c3259b..00000000
--- a/apps/server/src/providers/codex-config-manager.ts
+++ /dev/null
@@ -1,355 +0,0 @@
-/**
- * Codex TOML Configuration Manager
- *
- * Manages Codex CLI's TOML configuration file to add/update MCP server settings.
- * Codex CLI looks for config at:
- * - ~/.codex/config.toml (user-level)
- * - .codex/config.toml (project-level, takes precedence)
- */
-
-import fs from "fs/promises";
-import path from "path";
-import os from "os";
-
-interface McpServerConfig {
- command: string;
- args?: string[];
- env?: Record;
- startup_timeout_sec?: number;
- tool_timeout_sec?: number;
- enabled_tools?: string[];
-}
-
-interface CodexConfig {
- experimental_use_rmcp_client?: boolean;
- mcp_servers?: Record;
- [key: string]: any;
-}
-
-export class CodexConfigManager {
- private userConfigPath: string;
- private projectConfigPath: string | null = null;
-
- constructor() {
- this.userConfigPath = path.join(os.homedir(), ".codex", "config.toml");
- }
-
- /**
- * Set the project path for project-level config
- */
- setProjectPath(projectPath: string): void {
- this.projectConfigPath = path.join(projectPath, ".codex", "config.toml");
- }
-
- /**
- * Get the effective config path (project-level if exists, otherwise user-level)
- */
- async getConfigPath(): Promise {
- if (this.projectConfigPath) {
- try {
- await fs.access(this.projectConfigPath);
- return this.projectConfigPath;
- } catch (e) {
- // Project config doesn't exist, fall back to user config
- }
- }
-
- // Ensure user config directory exists
- const userConfigDir = path.dirname(this.userConfigPath);
- try {
- await fs.mkdir(userConfigDir, { recursive: true });
- } catch (e) {
- // Directory might already exist
- }
-
- return this.userConfigPath;
- }
-
- /**
- * Read existing TOML config (simple parser for our needs)
- */
- async readConfig(configPath: string): Promise {
- try {
- const content = await fs.readFile(configPath, "utf-8");
- return this.parseToml(content);
- } catch (e: any) {
- if (e.code === "ENOENT") {
- return {};
- }
- throw e;
- }
- }
-
- /**
- * Simple TOML parser for our specific use case
- * This is a minimal parser that handles the MCP server config structure
- */
- parseToml(content: string): CodexConfig {
- const config: CodexConfig = {};
- let currentSection: string | null = null;
- let currentSubsection: string | null = null;
-
- const lines = content.split("\n");
-
- for (const line of lines) {
- const trimmed = line.trim();
-
- // Skip comments and empty lines
- if (!trimmed || trimmed.startsWith("#")) {
- continue;
- }
-
- // Section header: [section]
- const sectionMatch = trimmed.match(/^\[([^\]]+)\]$/);
- if (sectionMatch) {
- const sectionName = sectionMatch[1];
- const parts = sectionName.split(".");
-
- if (parts.length === 1) {
- currentSection = parts[0];
- currentSubsection = null;
- if (!config[currentSection]) {
- config[currentSection] = {};
- }
- } else if (parts.length === 2) {
- currentSection = parts[0];
- currentSubsection = parts[1];
- if (!config[currentSection]) {
- config[currentSection] = {};
- }
- if (!config[currentSection][currentSubsection]) {
- config[currentSection][currentSubsection] = {};
- }
- }
- continue;
- }
-
- // Key-value pair: key = value
- const kvMatch = trimmed.match(/^([^=]+)=(.+)$/);
- if (kvMatch) {
- const key = kvMatch[1].trim();
- let value: any = kvMatch[2].trim();
-
- // Remove quotes if present
- if (
- (value.startsWith('"') && value.endsWith('"')) ||
- (value.startsWith("'") && value.endsWith("'"))
- ) {
- value = value.slice(1, -1);
- }
-
- // Parse boolean
- if (value === "true") value = true;
- else if (value === "false") value = false;
- // Parse number
- else if (/^-?\d+$/.test(value)) value = parseInt(value, 10);
- else if (/^-?\d+\.\d+$/.test(value)) value = parseFloat(value);
-
- if (currentSubsection && currentSection) {
- if (!config[currentSection][currentSubsection]) {
- config[currentSection][currentSubsection] = {};
- }
- config[currentSection][currentSubsection][key] = value;
- } else if (currentSection) {
- if (!config[currentSection]) {
- config[currentSection] = {};
- }
- config[currentSection][key] = value;
- } else {
- config[key] = value;
- }
- }
- }
-
- return config;
- }
-
- /**
- * Configure the automaker-tools MCP server
- */
- async configureMcpServer(
- projectPath: string,
- mcpServerScriptPath: string
- ): Promise {
- this.setProjectPath(projectPath);
- const configPath = await this.getConfigPath();
-
- // Read existing config
- const config = await this.readConfig(configPath);
-
- // Ensure mcp_servers section exists
- if (!config.mcp_servers) {
- config.mcp_servers = {};
- }
-
- // Configure automaker-tools server
- config.mcp_servers["automaker-tools"] = {
- command: "node",
- args: [mcpServerScriptPath],
- env: {
- AUTOMAKER_PROJECT_PATH: projectPath,
- },
- startup_timeout_sec: 10,
- tool_timeout_sec: 60,
- enabled_tools: ["UpdateFeatureStatus"],
- };
-
- // Ensure experimental_use_rmcp_client is enabled (if needed)
- if (!config.experimental_use_rmcp_client) {
- config.experimental_use_rmcp_client = true;
- }
-
- // Write config back
- await this.writeConfig(configPath, config);
-
- console.log(
- `[CodexConfigManager] Configured automaker-tools MCP server in ${configPath}`
- );
- return configPath;
- }
-
- /**
- * Write config to TOML file
- */
- async writeConfig(configPath: string, config: CodexConfig): Promise {
- let content = "";
-
- // Write top-level keys first (preserve existing non-MCP config)
- for (const [key, value] of Object.entries(config)) {
- if (key === "mcp_servers" || key === "experimental_use_rmcp_client") {
- continue; // Handle these separately
- }
- if (typeof value !== "object") {
- content += `${key} = ${this.formatValue(value)}\n`;
- }
- }
-
- // Write experimental flag if enabled
- if (config.experimental_use_rmcp_client) {
- if (content && !content.endsWith("\n\n")) {
- content += "\n";
- }
- content += `experimental_use_rmcp_client = true\n`;
- }
-
- // Write mcp_servers section
- if (config.mcp_servers && Object.keys(config.mcp_servers).length > 0) {
- if (content && !content.endsWith("\n\n")) {
- content += "\n";
- }
-
- for (const [serverName, serverConfig] of Object.entries(
- config.mcp_servers
- )) {
- content += `\n[mcp_servers.${serverName}]\n`;
-
- // Write command first
- if (serverConfig.command) {
- content += `command = "${this.escapeTomlString(serverConfig.command)}"\n`;
- }
-
- // Write args
- if (serverConfig.args && Array.isArray(serverConfig.args)) {
- const argsStr = serverConfig.args
- .map((a) => `"${this.escapeTomlString(a)}"`)
- .join(", ");
- content += `args = [${argsStr}]\n`;
- }
-
- // Write timeouts (must be before env subsection)
- if (serverConfig.startup_timeout_sec !== undefined) {
- content += `startup_timeout_sec = ${serverConfig.startup_timeout_sec}\n`;
- }
-
- if (serverConfig.tool_timeout_sec !== undefined) {
- content += `tool_timeout_sec = ${serverConfig.tool_timeout_sec}\n`;
- }
-
- // Write enabled_tools (must be before env subsection - at server level, not env level)
- if (serverConfig.enabled_tools && Array.isArray(serverConfig.enabled_tools)) {
- const toolsStr = serverConfig.enabled_tools
- .map((t) => `"${this.escapeTomlString(t)}"`)
- .join(", ");
- content += `enabled_tools = [${toolsStr}]\n`;
- }
-
- // Write env section last (as a separate subsection)
- if (
- serverConfig.env &&
- typeof serverConfig.env === "object" &&
- Object.keys(serverConfig.env).length > 0
- ) {
- content += `\n[mcp_servers.${serverName}.env]\n`;
- for (const [envKey, envValue] of Object.entries(serverConfig.env)) {
- content += `${envKey} = "${this.escapeTomlString(String(envValue))}"\n`;
- }
- }
- }
- }
-
- // Ensure directory exists
- const configDir = path.dirname(configPath);
- await fs.mkdir(configDir, { recursive: true });
-
- // Write file
- await fs.writeFile(configPath, content, "utf-8");
- }
-
- /**
- * Escape special characters in TOML strings
- */
- escapeTomlString(str: string): string {
- return str
- .replace(/\\/g, "\\\\")
- .replace(/"/g, '\\"')
- .replace(/\n/g, "\\n")
- .replace(/\r/g, "\\r")
- .replace(/\t/g, "\\t");
- }
-
- /**
- * Format a value for TOML output
- */
- formatValue(value: any): string {
- if (typeof value === "string") {
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
- return `"${escaped}"`;
- } else if (typeof value === "boolean") {
- return value.toString();
- } else if (typeof value === "number") {
- return value.toString();
- }
- return `"${String(value)}"`;
- }
-
- /**
- * Remove automaker-tools MCP server configuration
- */
- async removeMcpServer(projectPath: string): Promise {
- this.setProjectPath(projectPath);
- const configPath = await this.getConfigPath();
-
- try {
- const config = await this.readConfig(configPath);
-
- if (config.mcp_servers && config.mcp_servers["automaker-tools"]) {
- delete config.mcp_servers["automaker-tools"];
-
- // If no more MCP servers, remove the section
- if (Object.keys(config.mcp_servers).length === 0) {
- delete config.mcp_servers;
- }
-
- await this.writeConfig(configPath, config);
- console.log(
- `[CodexConfigManager] Removed automaker-tools MCP server from ${configPath}`
- );
- }
- } catch (e) {
- console.error(`[CodexConfigManager] Error removing MCP server config:`, e);
- }
- }
-}
-
-// Export singleton instance
-export const codexConfigManager = new CodexConfigManager();
diff --git a/apps/server/src/providers/codex-provider.ts b/apps/server/src/providers/codex-provider.ts
deleted file mode 100644
index 531dd268..00000000
--- a/apps/server/src/providers/codex-provider.ts
+++ /dev/null
@@ -1,569 +0,0 @@
-/**
- * Codex Provider - Executes queries using OpenAI Codex CLI
- *
- * Spawns Codex CLI as a subprocess and converts JSONL output to
- * Claude SDK-compatible message format for seamless integration.
- */
-
-import { BaseProvider } from "./base-provider.js";
-import { CodexCliDetector } from "./codex-cli-detector.js";
-import { codexConfigManager } from "./codex-config-manager.js";
-import { spawnJSONLProcess } from "../lib/subprocess-manager.js";
-import { formatHistoryAsText } from "../lib/conversation-utils.js";
-import type {
- ExecuteOptions,
- ProviderMessage,
- InstallationStatus,
- ModelDefinition,
- ContentBlock,
-} from "./types.js";
-
-// Codex event types
-const CODEX_EVENT_TYPES = {
- THREAD_STARTED: "thread.started",
- THREAD_COMPLETED: "thread.completed",
- ITEM_STARTED: "item.started",
- ITEM_COMPLETED: "item.completed",
- TURN_STARTED: "turn.started",
- ERROR: "error",
-};
-
-interface CodexEvent {
- type: string;
- data?: any;
- item?: any;
- thread_id?: string;
- message?: string;
-}
-
-export class CodexProvider extends BaseProvider {
- getName(): string {
- return "codex";
- }
-
- /**
- * Execute a query using Codex CLI
- */
- async *executeQuery(options: ExecuteOptions): AsyncGenerator {
- const {
- prompt,
- model = "gpt-5.2",
- cwd,
- systemPrompt,
- mcpServers,
- abortController,
- conversationHistory,
- } = options;
-
- // Find Codex CLI path
- const codexPath = this.findCodexPath();
- if (!codexPath) {
- yield {
- type: "error",
- error:
- "Codex CLI not found. Please install it with: npm install -g @openai/codex@latest",
- };
- return;
- }
-
- // Configure MCP server if provided
- if (mcpServers && mcpServers["automaker-tools"]) {
- try {
- const mcpServerScriptPath = await this.getMcpServerPath();
- if (mcpServerScriptPath) {
- await codexConfigManager.configureMcpServer(cwd, mcpServerScriptPath);
- }
- } catch (error) {
- console.error("[CodexProvider] Failed to configure MCP server:", error);
- // Continue execution even if MCP config fails
- }
- }
-
- // Build combined prompt with conversation history
- // Codex CLI doesn't support native conversation history or images, so we extract text
- let combinedPrompt = "";
-
- if (typeof prompt === "string") {
- combinedPrompt = prompt;
- } else if (Array.isArray(prompt)) {
- // Extract text from content blocks (ignore images - Codex CLI doesn't support vision)
- combinedPrompt = prompt
- .filter(block => block.type === "text")
- .map(block => block.text || "")
- .join("\n");
- }
-
- // Add system prompt first
- if (systemPrompt) {
- combinedPrompt = `${systemPrompt}\n\n---\n\n${combinedPrompt}`;
- }
-
- // Add conversation history
- if (conversationHistory && conversationHistory.length > 0) {
- const historyText = formatHistoryAsText(conversationHistory);
- combinedPrompt = `${historyText}Current request:\n${combinedPrompt}`;
- }
-
- // Build command arguments
- const args = this.buildArgs({ prompt: combinedPrompt, model });
-
- // Check authentication - either API key or CLI login
- const auth = CodexCliDetector.checkAuth();
- const hasApiKey = this.config.apiKey || process.env.OPENAI_API_KEY;
-
- if (!auth.authenticated && !hasApiKey) {
- yield {
- type: "error",
- error:
- "Codex CLI is not authenticated. Please run 'codex login' or set OPENAI_API_KEY environment variable.",
- };
- return;
- }
-
- // Prepare environment variables (API key is optional if using CLI auth)
- const env = {
- ...this.config.env,
- ...(hasApiKey && { OPENAI_API_KEY: hasApiKey }),
- };
-
- // Spawn the Codex process and stream JSONL output
- try {
- const stream = spawnJSONLProcess({
- command: codexPath,
- args,
- cwd,
- env,
- abortController,
- timeout: 30000, // 30s timeout for no output
- });
-
- for await (const event of stream) {
- const converted = this.convertToProviderFormat(event as CodexEvent);
- if (converted) {
- yield converted;
- }
- }
-
- // Yield completion event
- yield {
- type: "result",
- subtype: "success",
- result: "",
- };
- } catch (error) {
- console.error("[CodexProvider] Execution error:", error);
- yield {
- type: "error",
- error: (error as Error).message,
- };
- }
- }
-
- /**
- * Convert Codex JSONL event to Provider message format (Claude SDK compatible)
- */
- private convertToProviderFormat(event: CodexEvent): ProviderMessage | null {
- const { type, data, item, thread_id } = event;
-
- switch (type) {
- case CODEX_EVENT_TYPES.THREAD_STARTED:
- case "thread.started":
- // Session initialization - not needed for provider format
- return null;
-
- case CODEX_EVENT_TYPES.ITEM_COMPLETED:
- case "item.completed":
- return this.convertItemCompleted(item || data);
-
- case CODEX_EVENT_TYPES.ITEM_STARTED:
- case "item.started":
- // Item started events can show tool usage
- const startedItem = item || data;
- if (
- startedItem?.type === "command_execution" &&
- startedItem?.command
- ) {
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "tool_use",
- name: "bash",
- input: { command: startedItem.command },
- },
- ],
- },
- };
- }
- // Handle todo_list started
- if (startedItem?.type === "todo_list" && startedItem?.items) {
- const todos = startedItem.items || [];
- const todoText = todos
- .map((t: any, i: number) => `${i + 1}. ${t.text || t}`)
- .join("\n");
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: `**Todo List:**\n${todoText}`,
- },
- ],
- },
- };
- }
- return null;
-
- case "item.updated":
- // Handle updated items (like todo list updates)
- const updatedItem = item || data;
- if (updatedItem?.type === "todo_list" && updatedItem?.items) {
- const todos = updatedItem.items || [];
- const todoText = todos
- .map((t: any, i: number) => {
- const status = t.status === "completed" ? "✓" : " ";
- return `${i + 1}. [${status}] ${t.text || t}`;
- })
- .join("\n");
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: `**Updated Todo List:**\n${todoText}`,
- },
- ],
- },
- };
- }
- return null;
-
- case CODEX_EVENT_TYPES.THREAD_COMPLETED:
- case "thread.completed":
- return {
- type: "result",
- subtype: "success",
- result: "",
- };
-
- case CODEX_EVENT_TYPES.ERROR:
- case "error":
- return {
- type: "error",
- error:
- data?.message ||
- item?.message ||
- event.message ||
- "Unknown error from Codex CLI",
- };
-
- case "turn.started":
- case "turn.completed":
- // Turn markers - not needed for provider format
- return null;
-
- default:
- return null;
- }
- }
-
- /**
- * Convert item.completed event to Provider format
- */
- private convertItemCompleted(item: any): ProviderMessage | null {
- if (!item) {
- return null;
- }
-
- const itemType = item.type || item.item_type;
-
- switch (itemType) {
- case "reasoning":
- // Thinking/reasoning output
- const reasoningText = item.text || item.content || "";
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "thinking",
- thinking: reasoningText,
- },
- ],
- },
- };
-
- case "agent_message":
- case "message":
- // Assistant text message
- const messageText = item.content || item.text || "";
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: messageText,
- },
- ],
- },
- };
-
- case "command_execution":
- // Command execution - show both the command and its output
- const command = item.command || "";
- const output = item.aggregated_output || item.output || "";
-
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: `\`\`\`bash\n${command}\n\`\`\`\n\n${output}`,
- },
- ],
- },
- };
-
- case "tool_use":
- // Tool use
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "tool_use",
- name: item.tool || item.command || "unknown",
- input: item.input || item.args || {},
- },
- ],
- },
- };
-
- case "tool_result":
- // Tool result
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "tool_result",
- tool_use_id: item.tool_use_id,
- content: item.output || item.result,
- },
- ],
- },
- };
-
- case "todo_list":
- // Todo list - convert to text format
- const todos = item.items || [];
- const todoText = todos
- .map((t: any, i: number) => `${i + 1}. ${t.text || t}`)
- .join("\n");
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: `**Todo List:**\n${todoText}`,
- },
- ],
- },
- };
-
- case "file_change":
- // File changes - show what files were modified
- const changes = item.changes || [];
- const changeText = changes
- .map((c: any) => `- Modified: ${c.path}`)
- .join("\n");
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: `**File Changes:**\n${changeText}`,
- },
- ],
- },
- };
-
- default:
- // Generic text output
- const text = item.text || item.content || item.aggregated_output;
- if (text) {
- return {
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: String(text),
- },
- ],
- },
- };
- }
- return null;
- }
- }
-
- /**
- * Build command arguments for Codex CLI
- */
- private buildArgs(options: {
- prompt: string;
- model: string;
- }): string[] {
- const { prompt, model } = options;
-
- return [
- "exec",
- "--model",
- model,
- "--json", // JSONL output format
- "--full-auto", // Non-interactive mode
- prompt, // Prompt as the last argument
- ];
- }
-
- /**
- * Find Codex CLI executable path
- */
- private findCodexPath(): string | null {
- // Check config override
- if (this.config.cliPath) {
- return this.config.cliPath;
- }
-
- // Check environment variable override
- if (process.env.CODEX_CLI_PATH) {
- return process.env.CODEX_CLI_PATH;
- }
-
- // Auto-detect
- const detection = CodexCliDetector.detectCodexInstallation();
- return detection.path || "codex";
- }
-
- /**
- * Get MCP server script path
- */
- private async getMcpServerPath(): Promise {
- // TODO: Implement MCP server path resolution
- // For now, return null - MCP support is optional
- return null;
- }
-
- /**
- * Detect Codex CLI installation
- */
- async detectInstallation(): Promise {
- const detection = CodexCliDetector.detectCodexInstallation();
- const auth = CodexCliDetector.checkAuth();
-
- return {
- installed: detection.installed,
- path: detection.path,
- version: detection.version,
- method: detection.method,
- hasApiKey: auth.hasEnvKey || auth.authenticated,
- authenticated: auth.authenticated,
- };
- }
-
- /**
- * Get available Codex models
- */
- getAvailableModels(): ModelDefinition[] {
- return [
- {
- id: "gpt-5.2",
- name: "GPT-5.2 (Codex)",
- modelString: "gpt-5.2",
- provider: "openai-codex",
- description: "Latest Codex model for agentic code generation",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- tier: "premium",
- default: true,
- },
- {
- id: "gpt-5.1-codex-max",
- name: "GPT-5.1 Codex Max",
- modelString: "gpt-5.1-codex-max",
- provider: "openai-codex",
- description: "Maximum capability Codex model",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- tier: "premium",
- },
- {
- id: "gpt-5.1-codex",
- name: "GPT-5.1 Codex",
- modelString: "gpt-5.1-codex",
- provider: "openai-codex",
- description: "Standard Codex model",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- tier: "standard",
- },
- {
- id: "gpt-5.1-codex-mini",
- name: "GPT-5.1 Codex Mini",
- modelString: "gpt-5.1-codex-mini",
- provider: "openai-codex",
- description: "Faster, lightweight Codex model",
- contextWindow: 256000,
- maxOutputTokens: 16384,
- supportsVision: false,
- supportsTools: true,
- tier: "basic",
- },
- {
- id: "gpt-5.1",
- name: "GPT-5.1",
- modelString: "gpt-5.1",
- provider: "openai-codex",
- description: "General-purpose GPT-5.1 model",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- tier: "standard",
- },
- ];
- }
-
- /**
- * Check if the provider supports a specific feature
- */
- supportsFeature(feature: string): boolean {
- const supportedFeatures = ["tools", "text", "vision", "mcp", "cli"];
- return supportedFeatures.includes(feature);
- }
-}
diff --git a/apps/server/src/providers/provider-factory.ts b/apps/server/src/providers/provider-factory.ts
index 824a20f4..9c8d028f 100644
--- a/apps/server/src/providers/provider-factory.ts
+++ b/apps/server/src/providers/provider-factory.ts
@@ -8,7 +8,6 @@
import { BaseProvider } from "./base-provider.js";
import { ClaudeProvider } from "./claude-provider.js";
-import { CodexProvider } from "./codex-provider.js";
import type { InstallationStatus } from "./types.js";
export class ProviderFactory {
@@ -21,12 +20,6 @@ export class ProviderFactory {
static getProviderForModel(modelId: string): BaseProvider {
const lowerModel = modelId.toLowerCase();
- // OpenAI/Codex models (gpt-*)
- // Note: o1/o3 models are not supported by Codex CLI
- if (lowerModel.startsWith("gpt-")) {
- return new CodexProvider();
- }
-
// Claude models (claude-*, opus, sonnet, haiku)
if (
lowerModel.startsWith("claude-") ||
@@ -56,7 +49,6 @@ export class ProviderFactory {
static getAllProviders(): BaseProvider[] {
return [
new ClaudeProvider(),
- new CodexProvider(),
// Future providers...
];
}
@@ -95,10 +87,6 @@ export class ProviderFactory {
case "anthropic":
return new ClaudeProvider();
- case "codex":
- case "openai":
- return new CodexProvider();
-
// Future providers:
// case "cursor":
// return new CursorProvider();
diff --git a/apps/server/src/routes/models.ts b/apps/server/src/routes/models.ts
index c45bae19..0345b54a 100644
--- a/apps/server/src/routes/models.ts
+++ b/apps/server/src/routes/models.ts
@@ -64,78 +64,6 @@ export function createModelsRoutes(): Router {
supportsVision: true,
supportsTools: true,
},
- {
- id: "gpt-4o",
- name: "GPT-4o",
- provider: "openai",
- contextWindow: 128000,
- maxOutputTokens: 16384,
- supportsVision: true,
- supportsTools: true,
- },
- {
- id: "gpt-4o-mini",
- name: "GPT-4o Mini",
- provider: "openai",
- contextWindow: 128000,
- maxOutputTokens: 16384,
- supportsVision: true,
- supportsTools: true,
- },
- {
- id: "o1",
- name: "o1",
- provider: "openai",
- contextWindow: 200000,
- maxOutputTokens: 100000,
- supportsVision: true,
- supportsTools: false,
- },
- {
- id: "gpt-5.2",
- name: "GPT-5.2 (Codex)",
- provider: "openai-codex",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- },
- {
- id: "gpt-5.1-codex-max",
- name: "GPT-5.1 Codex Max",
- provider: "openai-codex",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- },
- {
- id: "gpt-5.1-codex",
- name: "GPT-5.1 Codex",
- provider: "openai-codex",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- },
- {
- id: "gpt-5.1-codex-mini",
- name: "GPT-5.1 Codex Mini",
- provider: "openai-codex",
- contextWindow: 256000,
- maxOutputTokens: 16384,
- supportsVision: false,
- supportsTools: true,
- },
- {
- id: "gpt-5.1",
- name: "GPT-5.1",
- provider: "openai-codex",
- contextWindow: 256000,
- maxOutputTokens: 32768,
- supportsVision: true,
- supportsTools: true,
- },
];
res.json({ success: true, models });
@@ -156,17 +84,6 @@ export function createModelsRoutes(): Router {
available: statuses.claude?.installed || false,
hasApiKey: !!process.env.ANTHROPIC_API_KEY || !!process.env.CLAUDE_CODE_OAUTH_TOKEN,
},
- openai: {
- available: !!process.env.OPENAI_API_KEY,
- hasApiKey: !!process.env.OPENAI_API_KEY,
- },
- "openai-codex": {
- available: statuses.codex?.installed || false,
- hasApiKey: !!process.env.OPENAI_API_KEY,
- cliInstalled: statuses.codex?.installed,
- cliVersion: statuses.codex?.version,
- cliPath: statuses.codex?.path,
- },
google: {
available: !!process.env.GOOGLE_API_KEY,
hasApiKey: !!process.env.GOOGLE_API_KEY,
diff --git a/apps/server/src/routes/setup.ts b/apps/server/src/routes/setup.ts
index 6403fbfa..6c16f6fd 100644
--- a/apps/server/src/routes/setup.ts
+++ b/apps/server/src/routes/setup.ts
@@ -230,84 +230,6 @@ export function createSetupRoutes(): Router {
}
});
- // Get Codex CLI status
- router.get("/codex-status", async (_req: Request, res: Response) => {
- try {
- let installed = false;
- let version = "";
- let cliPath = "";
- let method = "none";
-
- // Try to find Codex CLI
- try {
- const { stdout } = await execAsync("which codex || where codex 2>/dev/null");
- cliPath = stdout.trim();
- installed = true;
- method = "path";
-
- try {
- const { stdout: versionOut } = await execAsync("codex --version");
- version = versionOut.trim();
- } catch {
- version = "unknown";
- }
- } catch {
- // Not found
- }
-
- // Check for OpenAI/Codex authentication
- // Simplified: only check via CLI command, no file parsing
- let auth = {
- authenticated: false,
- method: "none" as string,
- hasEnvKey: !!process.env.OPENAI_API_KEY,
- hasStoredApiKey: !!apiKeys.openai,
- };
-
- // Try to verify authentication using codex CLI command if CLI is installed
- if (installed && cliPath) {
- try {
- const { stdout: statusOutput } = await execAsync(`"${cliPath}" login status 2>&1`, {
- timeout: 5000,
- });
-
- // Check if the output indicates logged in status
- if (statusOutput && (statusOutput.includes('Logged in') || statusOutput.includes('Authenticated'))) {
- auth.authenticated = true;
- auth.method = "cli_verified"; // CLI verified via login status command
- }
- } catch (error) {
- // CLI check failed - user needs to login manually
- console.log("[Setup] Codex login status check failed:", error);
- }
- }
-
- // Environment variable override
- if (process.env.OPENAI_API_KEY) {
- auth.authenticated = true;
- auth.method = "env"; // OPENAI_API_KEY environment variable
- }
-
- // In-memory stored API key (from settings UI)
- if (!auth.authenticated && apiKeys.openai) {
- auth.authenticated = true;
- auth.method = "api_key"; // Manually stored API key
- }
-
- res.json({
- success: true,
- status: installed ? "installed" : "not_installed",
- method,
- version,
- path: cliPath,
- auth,
- });
- } catch (error) {
- const message = error instanceof Error ? error.message : "Unknown error";
- res.status(500).json({ success: false, error: message });
- }
- });
-
// Install Claude CLI
router.post("/install-claude", async (_req: Request, res: Response) => {
try {
@@ -324,20 +246,6 @@ export function createSetupRoutes(): Router {
}
});
- // Install Codex CLI
- router.post("/install-codex", async (_req: Request, res: Response) => {
- try {
- res.json({
- success: false,
- error:
- "CLI installation requires terminal access. Please install manually using: npm install -g @openai/codex",
- });
- } catch (error) {
- const message = error instanceof Error ? error.message : "Unknown error";
- res.status(500).json({ success: false, error: message });
- }
- });
-
// Auth Claude
router.post("/auth-claude", async (_req: Request, res: Response) => {
try {
@@ -353,28 +261,6 @@ export function createSetupRoutes(): Router {
}
});
- // Auth Codex
- router.post("/auth-codex", async (req: Request, res: Response) => {
- try {
- const { apiKey } = req.body as { apiKey?: string };
-
- if (apiKey) {
- apiKeys.openai = apiKey;
- process.env.OPENAI_API_KEY = apiKey;
- res.json({ success: true });
- } else {
- res.json({
- success: true,
- requiresManualAuth: true,
- command: "codex auth login",
- });
- }
- } catch (error) {
- const message = error instanceof Error ? error.message : "Unknown error";
- res.status(500).json({ success: false, error: message });
- }
- });
-
// Store API key
router.post("/store-api-key", async (req: Request, res: Response) => {
try {
@@ -401,9 +287,6 @@ export function createSetupRoutes(): Router {
process.env.ANTHROPIC_API_KEY = apiKey;
await persistApiKeyToEnv("ANTHROPIC_API_KEY", apiKey);
console.log("[Setup] Stored API key as ANTHROPIC_API_KEY");
- } else if (provider === "openai") {
- process.env.OPENAI_API_KEY = apiKey;
- await persistApiKeyToEnv("OPENAI_API_KEY", apiKey);
} else if (provider === "google") {
process.env.GOOGLE_API_KEY = apiKey;
await persistApiKeyToEnv("GOOGLE_API_KEY", apiKey);
@@ -422,7 +305,6 @@ export function createSetupRoutes(): Router {
res.json({
success: true,
hasAnthropicKey: !!apiKeys.anthropic || !!process.env.ANTHROPIC_API_KEY,
- hasOpenAIKey: !!apiKeys.openai || !!process.env.OPENAI_API_KEY,
hasGoogleKey: !!apiKeys.google || !!process.env.GOOGLE_API_KEY,
});
} catch (error) {
@@ -431,34 +313,6 @@ export function createSetupRoutes(): Router {
}
});
- // Configure Codex MCP
- router.post("/configure-codex-mcp", async (req: Request, res: Response) => {
- try {
- const { projectPath } = req.body as { projectPath: string };
-
- if (!projectPath) {
- res.status(400).json({ success: false, error: "projectPath required" });
- return;
- }
-
- // Create .codex directory and config
- const codexDir = path.join(projectPath, ".codex");
- await fs.mkdir(codexDir, { recursive: true });
-
- const configPath = path.join(codexDir, "config.toml");
- const config = `# Codex configuration
-[mcp]
-enabled = true
-`;
- await fs.writeFile(configPath, config);
-
- res.json({ success: true, configPath });
- } catch (error) {
- const message = error instanceof Error ? error.message : "Unknown error";
- res.status(500).json({ success: false, error: message });
- }
- });
-
// Get platform info
router.get("/platform", async (_req: Request, res: Response) => {
try {
@@ -478,29 +332,5 @@ enabled = true
}
});
- // Test OpenAI connection
- router.post("/test-openai", async (req: Request, res: Response) => {
- try {
- const { apiKey } = req.body as { apiKey?: string };
- const key = apiKey || apiKeys.openai || process.env.OPENAI_API_KEY;
-
- if (!key) {
- res.json({ success: false, error: "No OpenAI API key provided" });
- return;
- }
-
- // Simple test - just verify the key format
- if (!key.startsWith("sk-")) {
- res.json({ success: false, error: "Invalid OpenAI API key format" });
- return;
- }
-
- res.json({ success: true, message: "API key format is valid" });
- } catch (error) {
- const message = error instanceof Error ? error.message : "Unknown error";
- res.status(500).json({ success: false, error: message });
- }
- });
-
return router;
}
diff --git a/apps/server/src/services/auto-mode-service.ts b/apps/server/src/services/auto-mode-service.ts
index edd24b35..e6932de9 100644
--- a/apps/server/src/services/auto-mode-service.ts
+++ b/apps/server/src/services/auto-mode-service.ts
@@ -1092,13 +1092,10 @@ When done, summarize what you implemented and any notes for the developer.`;
if (block.text && (block.text.includes("Invalid API key") ||
block.text.includes("authentication_failed") ||
block.text.includes("Fix external API key"))) {
- const isCodex = finalModel.startsWith("gpt-")
- const errorMsg = isCodex
- ? "Authentication failed: Invalid or expired API key. " +
- "Please check your OPENAI_API_KEY or run 'codex login' to re-authenticate."
- : "Authentication failed: Invalid or expired API key. " +
- "Please check your ANTHROPIC_API_KEY or run 'claude login' to re-authenticate.";
- throw new Error(errorMsg);
+ throw new Error(
+ "Authentication failed: Invalid or expired API key. " +
+ "Please check your ANTHROPIC_API_KEY or run 'claude login' to re-authenticate."
+ );
}
this.emitAutoModeEvent("auto_mode_progress", {
diff --git a/apps/server/tests/integration/services/auto-mode-service.integration.test.ts b/apps/server/tests/integration/services/auto-mode-service.integration.test.ts
index 17e7cc2b..932417b3 100644
--- a/apps/server/tests/integration/services/auto-mode-service.integration.test.ts
+++ b/apps/server/tests/integration/services/auto-mode-service.integration.test.ts
@@ -288,11 +288,11 @@ describe("auto-mode-service.ts (integration)", () => {
category: "test",
description: "Model test",
status: "pending",
- model: "gpt-5.2",
+ model: "claude-sonnet-4-20250514",
});
const mockProvider = {
- getName: () => "codex",
+ getName: () => "claude",
executeQuery: async function* () {
yield {
type: "result",
@@ -312,8 +312,8 @@ describe("auto-mode-service.ts (integration)", () => {
false
);
- // Should have used gpt-5.2
- expect(ProviderFactory.getProviderForModel).toHaveBeenCalledWith("gpt-5.2");
+ // Should have used claude-sonnet-4-20250514
+ expect(ProviderFactory.getProviderForModel).toHaveBeenCalledWith("claude-sonnet-4-20250514");
}, 30000);
});
diff --git a/apps/server/tests/unit/lib/model-resolver.test.ts b/apps/server/tests/unit/lib/model-resolver.test.ts
index 6a0ded22..ef2554e3 100644
--- a/apps/server/tests/unit/lib/model-resolver.test.ts
+++ b/apps/server/tests/unit/lib/model-resolver.test.ts
@@ -40,19 +40,8 @@ describe("model-resolver.ts", () => {
);
});
- it("should pass through OpenAI gpt-* models", () => {
- const models = ["gpt-5.2", "gpt-5.1-codex", "gpt-4"];
- models.forEach((model) => {
- const result = resolveModelString(model);
- expect(result).toBe(model);
- });
- expect(consoleSpy.log).toHaveBeenCalledWith(
- expect.stringContaining("Using OpenAI/Codex model")
- );
- });
-
- it("should treat o-series models as unknown (Codex CLI doesn't support them)", () => {
- const models = ["o1", "o1-mini", "o3"];
+ it("should treat unknown models as falling back to default", () => {
+ const models = ["o1", "o1-mini", "o3", "gpt-5.2", "unknown-model"];
models.forEach((model) => {
const result = resolveModelString(model);
// Should fall back to default since these aren't supported
@@ -143,14 +132,12 @@ describe("model-resolver.ts", () => {
});
describe("DEFAULT_MODELS", () => {
- it("should have claude and openai defaults", () => {
+ it("should have claude default", () => {
expect(DEFAULT_MODELS).toHaveProperty("claude");
- expect(DEFAULT_MODELS).toHaveProperty("openai");
});
- it("should have valid default models", () => {
+ it("should have valid default model", () => {
expect(DEFAULT_MODELS.claude).toContain("claude");
- expect(DEFAULT_MODELS.openai).toContain("gpt");
});
});
});
diff --git a/apps/server/tests/unit/providers/codex-cli-detector.test.ts b/apps/server/tests/unit/providers/codex-cli-detector.test.ts
deleted file mode 100644
index 3023ce64..00000000
--- a/apps/server/tests/unit/providers/codex-cli-detector.test.ts
+++ /dev/null
@@ -1,362 +0,0 @@
-import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
-import { CodexCliDetector } from "@/providers/codex-cli-detector.js";
-import * as cp from "child_process";
-import * as fs from "fs";
-import * as os from "os";
-import * as path from "path";
-
-vi.mock("child_process");
-vi.mock("fs");
-
-describe("codex-cli-detector.ts", () => {
- beforeEach(() => {
- vi.clearAllMocks();
- delete process.env.OPENAI_API_KEY;
- });
-
- describe("getConfigDir", () => {
- it("should return .codex directory in user home", () => {
- const homeDir = os.homedir();
- const configDir = CodexCliDetector.getConfigDir();
- expect(configDir).toBe(path.join(homeDir, ".codex"));
- });
- });
-
- describe("getAuthPath", () => {
- it("should return auth.json path in config directory", () => {
- const authPath = CodexCliDetector.getAuthPath();
- expect(authPath).toContain(".codex");
- expect(authPath).toContain("auth.json");
- });
- });
-
- describe("checkAuth", () => {
- const mockAuthPath = "/home/user/.codex/auth.json";
-
- beforeEach(() => {
- vi.spyOn(CodexCliDetector, "getAuthPath").mockReturnValue(mockAuthPath);
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- });
-
- afterEach(() => {
- vi.restoreAllMocks();
- });
-
- it("should detect token object authentication", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue(
- JSON.stringify({
- token: {
- access_token: "test_access",
- refresh_token: "test_refresh",
- },
- })
- );
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("cli_tokens");
- expect(result.hasAuthFile).toBe(true);
- });
-
- it("should detect token with Id_token field", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue(
- JSON.stringify({
- token: {
- Id_token: "test_id_token",
- },
- })
- );
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("cli_tokens");
- });
-
- it("should detect root-level tokens", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue(
- JSON.stringify({
- access_token: "test_access",
- refresh_token: "test_refresh",
- })
- );
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("cli_tokens");
- });
-
- it("should detect API key in auth file", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue(
- JSON.stringify({
- api_key: "test-api-key",
- })
- );
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("auth_file");
- });
-
- it("should detect openai_api_key field", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue(
- JSON.stringify({
- openai_api_key: "test-key",
- })
- );
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("auth_file");
- });
-
- it("should detect environment variable authentication", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(false);
- process.env.OPENAI_API_KEY = "env-api-key";
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(true);
- expect(result.method).toBe("env");
- expect(result.hasEnvKey).toBe(true);
- expect(result.hasAuthFile).toBe(false);
- });
-
- it("should return not authenticated when no auth found", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(false);
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(false);
- expect(result.method).toBe("none");
- expect(result.hasAuthFile).toBe(false);
- expect(result.hasEnvKey).toBe(false);
- });
-
- it("should handle malformed auth file", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.mocked(fs.existsSync).mockReturnValue(true);
- vi.mocked(fs.readFileSync).mockReturnValue("invalid json");
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result.authenticated).toBe(false);
- expect(result.method).toBe("none");
- });
-
- it("should return auth result with required fields", () => {
- vi.mocked(fs.existsSync).mockReturnValue(false);
-
- const result = CodexCliDetector.checkAuth();
-
- expect(result).toHaveProperty("authenticated");
- expect(result).toHaveProperty("method");
- expect(typeof result.authenticated).toBe("boolean");
- expect(typeof result.method).toBe("string");
- });
- });
-
- describe("detectCodexInstallation", () => {
- // Note: Full detection logic involves OS-specific commands (which/where, npm, brew)
- // and is better tested in integration tests. Here we test the basic structure.
-
- it("should return hasApiKey when OPENAI_API_KEY is set and CLI not found", () => {
- vi.mocked(cp.execSync).mockImplementation(() => {
- throw new Error("command not found");
- });
- vi.mocked(fs.existsSync).mockReturnValue(false);
- process.env.OPENAI_API_KEY = "test-key";
-
- const result = CodexCliDetector.detectCodexInstallation();
-
- expect(result.installed).toBe(false);
- expect(result.hasApiKey).toBe(true);
- });
-
- it("should return not installed when nothing found", () => {
- vi.mocked(cp.execSync).mockImplementation(() => {
- throw new Error("command failed");
- });
- vi.mocked(fs.existsSync).mockReturnValue(false);
- delete process.env.OPENAI_API_KEY;
-
- const result = CodexCliDetector.detectCodexInstallation();
-
- expect(result.installed).toBe(false);
- expect(result.hasApiKey).toBeUndefined();
- });
-
- it("should return installation status object with installed boolean", () => {
- vi.mocked(cp.execSync).mockImplementation(() => {
- throw new Error();
- });
- vi.mocked(fs.existsSync).mockReturnValue(false);
-
- const result = CodexCliDetector.detectCodexInstallation();
-
- expect(result).toHaveProperty("installed");
- expect(typeof result.installed).toBe("boolean");
- });
- });
-
- describe("getCodexVersion", () => {
- // Note: Testing execSync calls is difficult in unit tests and better suited for integration tests
- // The method structure and error handling can be verified indirectly through other tests
-
- it("should return null when given invalid path", () => {
- const version = CodexCliDetector.getCodexVersion("/nonexistent/path");
- expect(version).toBeNull();
- });
- });
-
- describe("getInstallationInfo", () => {
- it("should return installed status when CLI is detected", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- version: "0.5.0",
- method: "cli",
- });
-
- const info = CodexCliDetector.getInstallationInfo();
-
- expect(info.status).toBe("installed");
- expect(info.method).toBe("cli");
- expect(info.version).toBe("0.5.0");
- expect(info.path).toBe("/usr/bin/codex");
- expect(info.recommendation).toContain("ready for GPT-5.1/5.2");
- });
-
- it("should return api_key_only when API key is set but CLI not installed", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- hasApiKey: true,
- });
-
- const info = CodexCliDetector.getInstallationInfo();
-
- expect(info.status).toBe("api_key_only");
- expect(info.method).toBe("api-key-only");
- expect(info.recommendation).toContain("OPENAI_API_KEY detected");
- expect(info.recommendation).toContain("Install Codex CLI");
- expect(info.installCommands).toBeDefined();
- });
-
- it("should return not_installed when nothing detected", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
-
- const info = CodexCliDetector.getInstallationInfo();
-
- expect(info.status).toBe("not_installed");
- expect(info.recommendation).toContain("Install OpenAI Codex CLI");
- expect(info.installCommands).toBeDefined();
- });
-
- it("should include install commands for all platforms", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
-
- const info = CodexCliDetector.getInstallationInfo();
-
- expect(info.installCommands).toHaveProperty("npm");
- expect(info.installCommands).toHaveProperty("macos");
- expect(info.installCommands).toHaveProperty("linux");
- expect(info.installCommands).toHaveProperty("windows");
- });
- });
-
- describe("getInstallCommands", () => {
- it("should return installation commands for all platforms", () => {
- const commands = CodexCliDetector.getInstallCommands();
-
- expect(commands.npm).toContain("npm install");
- expect(commands.npm).toContain("@openai/codex");
- expect(commands.macos).toContain("brew install");
- expect(commands.linux).toContain("npm install");
- expect(commands.windows).toContain("npm install");
- });
- });
-
- describe("isModelSupported", () => {
- it("should return true for supported models", () => {
- expect(CodexCliDetector.isModelSupported("gpt-5.1-codex-max")).toBe(true);
- expect(CodexCliDetector.isModelSupported("gpt-5.1-codex")).toBe(true);
- expect(CodexCliDetector.isModelSupported("gpt-5.1-codex-mini")).toBe(true);
- expect(CodexCliDetector.isModelSupported("gpt-5.1")).toBe(true);
- expect(CodexCliDetector.isModelSupported("gpt-5.2")).toBe(true);
- });
-
- it("should return false for unsupported models", () => {
- expect(CodexCliDetector.isModelSupported("gpt-4")).toBe(false);
- expect(CodexCliDetector.isModelSupported("claude-opus")).toBe(false);
- expect(CodexCliDetector.isModelSupported("unknown-model")).toBe(false);
- });
- });
-
- describe("getDefaultModel", () => {
- it("should return gpt-5.2 as default", () => {
- const defaultModel = CodexCliDetector.getDefaultModel();
- expect(defaultModel).toBe("gpt-5.2");
- });
- });
-
- describe("getFullStatus", () => {
- it("should include installation, auth, and info", () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- const status = CodexCliDetector.getFullStatus();
-
- expect(status).toHaveProperty("status");
- expect(status).toHaveProperty("auth");
- expect(status).toHaveProperty("installation");
- expect(status.auth.authenticated).toBe(true);
- expect(status.installation.installed).toBe(true);
- });
- });
-});
diff --git a/apps/server/tests/unit/providers/codex-config-manager.test.ts b/apps/server/tests/unit/providers/codex-config-manager.test.ts
deleted file mode 100644
index d0c2538a..00000000
--- a/apps/server/tests/unit/providers/codex-config-manager.test.ts
+++ /dev/null
@@ -1,430 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from "vitest";
-import { CodexConfigManager } from "@/providers/codex-config-manager.js";
-import * as fs from "fs/promises";
-import * as os from "os";
-import * as path from "path";
-import { tomlConfigFixture } from "../../fixtures/configs.js";
-
-vi.mock("fs/promises");
-
-describe("codex-config-manager.ts", () => {
- let manager: CodexConfigManager;
-
- beforeEach(() => {
- vi.clearAllMocks();
- manager = new CodexConfigManager();
- });
-
- describe("constructor", () => {
- it("should initialize with user config path", () => {
- const expectedPath = path.join(os.homedir(), ".codex", "config.toml");
- expect(manager["userConfigPath"]).toBe(expectedPath);
- });
-
- it("should initialize with null project config path", () => {
- expect(manager["projectConfigPath"]).toBeNull();
- });
- });
-
- describe("setProjectPath", () => {
- it("should set project config path", () => {
- manager.setProjectPath("/my/project");
- const configPath = manager["projectConfigPath"];
- expect(configPath).toContain("my");
- expect(configPath).toContain("project");
- expect(configPath).toContain(".codex");
- expect(configPath).toContain("config.toml");
- });
-
- it("should handle paths with special characters", () => {
- manager.setProjectPath("/path with spaces/project");
- expect(manager["projectConfigPath"]).toContain("path with spaces");
- });
- });
-
- describe("getConfigPath", () => {
- it("should return user config path when no project path set", async () => {
- const result = await manager.getConfigPath();
- expect(result).toBe(manager["userConfigPath"]);
- });
-
- it("should return project config path when it exists", async () => {
- manager.setProjectPath("/my/project");
- vi.mocked(fs.access).mockResolvedValue(undefined);
-
- const result = await manager.getConfigPath();
- expect(result).toContain("my");
- expect(result).toContain("project");
- expect(result).toContain(".codex");
- expect(result).toContain("config.toml");
- });
-
- it("should fall back to user config when project config doesn't exist", async () => {
- manager.setProjectPath("/my/project");
- vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"));
-
- const result = await manager.getConfigPath();
- expect(result).toBe(manager["userConfigPath"]);
- });
-
- it("should create user config directory if it doesn't exist", async () => {
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
-
- await manager.getConfigPath();
-
- const expectedDir = path.dirname(manager["userConfigPath"]);
- expect(fs.mkdir).toHaveBeenCalledWith(expectedDir, { recursive: true });
- });
- });
-
- describe("parseToml", () => {
- it("should parse simple key-value pairs", () => {
- const toml = `
- key1 = "value1"
- key2 = "value2"
- `;
- const result = manager.parseToml(toml);
-
- expect(result.key1).toBe("value1");
- expect(result.key2).toBe("value2");
- });
-
- it("should parse boolean values", () => {
- const toml = `
- enabled = true
- disabled = false
- `;
- const result = manager.parseToml(toml);
-
- expect(result.enabled).toBe(true);
- expect(result.disabled).toBe(false);
- });
-
- it("should parse integer values", () => {
- const toml = `
- count = 42
- negative = -10
- `;
- const result = manager.parseToml(toml);
-
- expect(result.count).toBe(42);
- expect(result.negative).toBe(-10);
- });
-
- it("should parse float values", () => {
- const toml = `
- pi = 3.14
- negative = -2.5
- `;
- const result = manager.parseToml(toml);
-
- expect(result.pi).toBe(3.14);
- expect(result.negative).toBe(-2.5);
- });
-
- it("should skip comments", () => {
- const toml = `
- # This is a comment
- key = "value"
- # Another comment
- `;
- const result = manager.parseToml(toml);
-
- expect(result.key).toBe("value");
- expect(Object.keys(result)).toHaveLength(1);
- });
-
- it("should skip empty lines", () => {
- const toml = `
- key1 = "value1"
-
- key2 = "value2"
-
-
- `;
- const result = manager.parseToml(toml);
-
- expect(result.key1).toBe("value1");
- expect(result.key2).toBe("value2");
- });
-
- it("should parse sections", () => {
- const toml = `
- [section1]
- key1 = "value1"
- key2 = "value2"
- `;
- const result = manager.parseToml(toml);
-
- expect(result.section1).toBeDefined();
- expect(result.section1.key1).toBe("value1");
- expect(result.section1.key2).toBe("value2");
- });
-
- it("should parse nested sections", () => {
- const toml = `
- [section.subsection]
- key = "value"
- `;
- const result = manager.parseToml(toml);
-
- expect(result.section).toBeDefined();
- expect(result.section.subsection).toBeDefined();
- expect(result.section.subsection.key).toBe("value");
- });
-
- it("should parse MCP server configuration", () => {
- const result = manager.parseToml(tomlConfigFixture);
-
- expect(result.experimental_use_rmcp_client).toBe(true);
- expect(result.mcp_servers).toBeDefined();
- expect(result.mcp_servers["automaker-tools"]).toBeDefined();
- expect(result.mcp_servers["automaker-tools"].command).toBe("node");
- });
-
- it("should handle quoted strings with spaces", () => {
- const toml = `key = "value with spaces"`;
- const result = manager.parseToml(toml);
-
- expect(result.key).toBe("value with spaces");
- });
-
- it("should handle single-quoted strings", () => {
- const toml = `key = 'single quoted'`;
- const result = manager.parseToml(toml);
-
- expect(result.key).toBe("single quoted");
- });
-
- it("should return empty object for empty input", () => {
- const result = manager.parseToml("");
- expect(result).toEqual({});
- });
- });
-
- describe("readConfig", () => {
- it("should read and parse existing config", async () => {
- vi.mocked(fs.readFile).mockResolvedValue(tomlConfigFixture);
-
- const result = await manager.readConfig("/path/to/config.toml");
-
- expect(result.experimental_use_rmcp_client).toBe(true);
- expect(result.mcp_servers).toBeDefined();
- });
-
- it("should return empty object when file doesn't exist", async () => {
- const error: any = new Error("ENOENT");
- error.code = "ENOENT";
- vi.mocked(fs.readFile).mockRejectedValue(error);
-
- const result = await manager.readConfig("/nonexistent.toml");
-
- expect(result).toEqual({});
- });
-
- it("should throw other errors", async () => {
- vi.mocked(fs.readFile).mockRejectedValue(new Error("Permission denied"));
-
- await expect(manager.readConfig("/path.toml")).rejects.toThrow(
- "Permission denied"
- );
- });
- });
-
- describe("escapeTomlString", () => {
- it("should escape backslashes", () => {
- const result = manager.escapeTomlString("path\\to\\file");
- expect(result).toBe("path\\\\to\\\\file");
- });
-
- it("should escape double quotes", () => {
- const result = manager.escapeTomlString('say "hello"');
- expect(result).toBe('say \\"hello\\"');
- });
-
- it("should escape newlines", () => {
- const result = manager.escapeTomlString("line1\nline2");
- expect(result).toBe("line1\\nline2");
- });
-
- it("should escape carriage returns", () => {
- const result = manager.escapeTomlString("line1\rline2");
- expect(result).toBe("line1\\rline2");
- });
-
- it("should escape tabs", () => {
- const result = manager.escapeTomlString("col1\tcol2");
- expect(result).toBe("col1\\tcol2");
- });
- });
-
- describe("formatValue", () => {
- it("should format strings with quotes", () => {
- const result = manager.formatValue("test");
- expect(result).toBe('"test"');
- });
-
- it("should format booleans as strings", () => {
- expect(manager.formatValue(true)).toBe("true");
- expect(manager.formatValue(false)).toBe("false");
- });
-
- it("should format numbers as strings", () => {
- expect(manager.formatValue(42)).toBe("42");
- expect(manager.formatValue(3.14)).toBe("3.14");
- });
-
- it("should escape special characters in strings", () => {
- const result = manager.formatValue('path\\with"quotes');
- expect(result).toBe('"path\\\\with\\"quotes"');
- });
- });
-
- describe("writeConfig", () => {
- it("should write TOML config to file", async () => {
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- const config = {
- experimental_use_rmcp_client: true,
- mcp_servers: {
- "test-server": {
- command: "node",
- args: ["server.js"],
- },
- },
- };
-
- await manager.writeConfig("/path/config.toml", config);
-
- expect(fs.writeFile).toHaveBeenCalledWith(
- "/path/config.toml",
- expect.stringContaining("experimental_use_rmcp_client = true"),
- "utf-8"
- );
- expect(fs.writeFile).toHaveBeenCalledWith(
- "/path/config.toml",
- expect.stringContaining("[mcp_servers.test-server]"),
- "utf-8"
- );
- });
-
- it("should create config directory if it doesn't exist", async () => {
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- await manager.writeConfig("/path/to/config.toml", {});
-
- expect(fs.mkdir).toHaveBeenCalledWith("/path/to", { recursive: true });
- });
-
- it("should include env section for MCP servers", async () => {
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- const config = {
- mcp_servers: {
- "test-server": {
- command: "node",
- env: {
- MY_VAR: "value",
- },
- },
- },
- };
-
- await manager.writeConfig("/path/config.toml", config);
-
- const writtenContent = vi.mocked(fs.writeFile).mock.calls[0][1] as string;
- expect(writtenContent).toContain("[mcp_servers.test-server.env]");
- expect(writtenContent).toContain('MY_VAR = "value"');
- });
- });
-
- describe("configureMcpServer", () => {
- it("should configure automaker-tools MCP server", async () => {
- vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"));
- vi.mocked(fs.readFile).mockRejectedValue(Object.assign(new Error("ENOENT"), { code: "ENOENT" }));
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- const result = await manager.configureMcpServer(
- "/my/project",
- "/path/to/mcp-server.js"
- );
-
- expect(result).toContain("config.toml");
-
- const writtenContent = vi.mocked(fs.writeFile).mock.calls[0][1] as string;
- expect(writtenContent).toContain("[mcp_servers.automaker-tools]");
- expect(writtenContent).toContain('command = "node"');
- expect(writtenContent).toContain("/path/to/mcp-server.js");
- expect(writtenContent).toContain("AUTOMAKER_PROJECT_PATH");
- });
-
- it("should preserve existing MCP servers", async () => {
- const existingConfig = `
- [mcp_servers.other-server]
- command = "other"
- `;
-
- vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"));
- vi.mocked(fs.readFile).mockResolvedValue(existingConfig);
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- await manager.configureMcpServer("/project", "/server.js");
-
- const writtenContent = vi.mocked(fs.writeFile).mock.calls[0][1] as string;
- expect(writtenContent).toContain("[mcp_servers.other-server]");
- expect(writtenContent).toContain("[mcp_servers.automaker-tools]");
- });
- });
-
- describe("removeMcpServer", () => {
- it("should remove automaker-tools MCP server", async () => {
- const configWithServer = `
- [mcp_servers.automaker-tools]
- command = "node"
-
- [mcp_servers.other-server]
- command = "other"
- `;
-
- vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"));
- vi.mocked(fs.readFile).mockResolvedValue(configWithServer);
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- await manager.removeMcpServer("/project");
-
- const writtenContent = vi.mocked(fs.writeFile).mock.calls[0][1] as string;
- expect(writtenContent).not.toContain("automaker-tools");
- expect(writtenContent).toContain("other-server");
- });
-
- it("should remove mcp_servers section if empty", async () => {
- const configWithOnlyAutomaker = `
- [mcp_servers.automaker-tools]
- command = "node"
- `;
-
- vi.mocked(fs.access).mockRejectedValue(new Error("ENOENT"));
- vi.mocked(fs.readFile).mockResolvedValue(configWithOnlyAutomaker);
- vi.mocked(fs.mkdir).mockResolvedValue(undefined);
- vi.mocked(fs.writeFile).mockResolvedValue(undefined);
-
- await manager.removeMcpServer("/project");
-
- const writtenContent = vi.mocked(fs.writeFile).mock.calls[0][1] as string;
- expect(writtenContent).not.toContain("mcp_servers");
- });
-
- it("should handle errors gracefully", async () => {
- vi.mocked(fs.readFile).mockRejectedValue(new Error("Read error"));
-
- // Should not throw
- await expect(manager.removeMcpServer("/project")).resolves.toBeUndefined();
- });
- });
-});
diff --git a/apps/server/tests/unit/providers/codex-provider.test.ts b/apps/server/tests/unit/providers/codex-provider.test.ts
deleted file mode 100644
index 00b61b20..00000000
--- a/apps/server/tests/unit/providers/codex-provider.test.ts
+++ /dev/null
@@ -1,1145 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from "vitest";
-import { CodexProvider } from "@/providers/codex-provider.js";
-import { CodexCliDetector } from "@/providers/codex-cli-detector.js";
-import { codexConfigManager } from "@/providers/codex-config-manager.js";
-import * as subprocessManager from "@/lib/subprocess-manager.js";
-import { collectAsyncGenerator } from "../../utils/helpers.js";
-
-vi.mock("@/providers/codex-cli-detector.js");
-vi.mock("@/providers/codex-config-manager.js");
-vi.mock("@/lib/subprocess-manager.js");
-
-describe("codex-provider.ts", () => {
- let provider: CodexProvider;
-
- beforeEach(() => {
- vi.clearAllMocks();
- provider = new CodexProvider();
- delete process.env.OPENAI_API_KEY;
- delete process.env.CODEX_CLI_PATH;
- });
-
- describe("getName", () => {
- it("should return 'codex' as provider name", () => {
- expect(provider.getName()).toBe("codex");
- });
- });
-
- describe("executeQuery", () => {
- it("should use default 'codex' when CLI not detected", async () => {
- // When CLI is not detected, findCodexPath returns "codex" as default
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Hello",
- cwd: "/test",
- });
-
- const results = await collectAsyncGenerator(generator);
-
- // Should succeed with default "codex" path
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.command).toBe("codex");
- });
-
- it("should error when not authenticated", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: false,
- method: "none",
- hasAuthFile: false,
- hasEnvKey: false,
- });
-
- const generator = provider.executeQuery({
- prompt: "Hello",
- cwd: "/test",
- });
-
- const results = await collectAsyncGenerator(generator);
-
- expect(results).toHaveLength(1);
- expect(results[0]).toMatchObject({
- type: "error",
- error: expect.stringContaining("not authenticated"),
- });
- });
-
- it("should execute query with CLI auth", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- const mockEvents = [
- { type: "thread.started" },
- { type: "item.completed", item: { type: "message", content: "Response" } },
- { type: "thread.completed" },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Hello",
- cwd: "/test",
- });
-
- const results = await collectAsyncGenerator(generator);
-
- expect(results).toHaveLength(3); // message + thread completion + final success
- expect(results[0].type).toBe("assistant");
- expect(results[1]).toMatchObject({ type: "result", subtype: "success" });
- expect(results[2]).toMatchObject({ type: "result", subtype: "success" });
- });
-
- it("should execute query with API key", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: false,
- method: "none",
- hasAuthFile: false,
- hasEnvKey: false,
- });
-
- process.env.OPENAI_API_KEY = "test-api-key";
-
- const mockEvents = [{ type: "thread.completed" }];
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Test",
- cwd: "/test",
- });
-
- const results = await collectAsyncGenerator(generator);
-
- expect(results).toHaveLength(2); // thread completion + final success
- expect(subprocessManager.spawnJSONLProcess).toHaveBeenCalledWith(
- expect.objectContaining({
- env: expect.objectContaining({
- OPENAI_API_KEY: "test-api-key",
- }),
- })
- );
- });
-
- it("should spawn subprocess with correct arguments", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Test prompt",
- model: "gpt-5.2",
- cwd: "/test/dir",
- });
-
- await collectAsyncGenerator(generator);
-
- expect(subprocessManager.spawnJSONLProcess).toHaveBeenCalledWith({
- command: "/usr/bin/codex",
- args: ["exec", "--model", "gpt-5.2", "--json", "--full-auto", "Test prompt"],
- cwd: "/test/dir",
- env: {},
- abortController: undefined,
- timeout: 30000,
- });
- });
-
- it("should prepend system prompt", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "User request",
- systemPrompt: "You are helpful",
- cwd: "/test",
- });
-
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- const combinedPrompt = call.args[call.args.length - 1];
- expect(combinedPrompt).toContain("You are helpful");
- expect(combinedPrompt).toContain("---");
- expect(combinedPrompt).toContain("User request");
- });
-
- it("should handle conversation history", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const conversationHistory = [
- { role: "user" as const, content: "Previous message" },
- { role: "assistant" as const, content: "Previous response" },
- ];
-
- const generator = provider.executeQuery({
- prompt: "Current message",
- conversationHistory,
- cwd: "/test",
- });
-
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- const combinedPrompt = call.args[call.args.length - 1];
- expect(combinedPrompt).toContain("Previous message");
- expect(combinedPrompt).toContain("Previous response");
- expect(combinedPrompt).toContain("Current request:");
- expect(combinedPrompt).toContain("Current message");
- });
-
- it("should extract text from array prompt (ignore images)", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const arrayPrompt = [
- { type: "text", text: "Text part 1" },
- { type: "image", source: { type: "base64", data: "..." } },
- { type: "text", text: "Text part 2" },
- ];
-
- const generator = provider.executeQuery({
- prompt: arrayPrompt as any,
- cwd: "/test",
- });
-
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- const combinedPrompt = call.args[call.args.length - 1];
- expect(combinedPrompt).toContain("Text part 1");
- expect(combinedPrompt).toContain("Text part 2");
- expect(combinedPrompt).not.toContain("image");
- });
-
- it("should configure MCP server if provided", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- vi.mocked(codexConfigManager.configureMcpServer).mockResolvedValue(
- "/path/config.toml"
- );
-
- const generator = provider.executeQuery({
- prompt: "Test",
- cwd: "/test",
- mcpServers: {
- "automaker-tools": {
- command: "node",
- args: ["server.js"],
- },
- },
- });
-
- await collectAsyncGenerator(generator);
-
- // Note: getMcpServerPath currently returns null, so configureMcpServer won't be called
- // This test verifies the code path exists even if not fully implemented
- expect(true).toBe(true);
- });
-
- it("should handle subprocess errors", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- throw new Error("Process failed");
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Test",
- cwd: "/test",
- });
-
- const results = await collectAsyncGenerator(generator);
-
- expect(results).toHaveLength(1);
- expect(results[0]).toMatchObject({
- type: "error",
- error: "Process failed",
- });
- });
-
- it("should use default model gpt-5.2", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({
- prompt: "Test",
- cwd: "/test",
- });
-
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.args).toContain("gpt-5.2");
- });
- });
-
- describe("event conversion", () => {
- beforeEach(() => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
- });
-
- it("should convert reasoning item to thinking message", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "reasoning",
- text: "Let me think about this...",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0]).toMatchObject({
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "thinking",
- thinking: "Let me think about this...",
- },
- ],
- },
- });
- });
-
- it("should convert agent_message to text message", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "agent_message",
- content: "Here is the response",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0]).toMatchObject({
- type: "assistant",
- message: {
- role: "assistant",
- content: [
- {
- type: "text",
- text: "Here is the response",
- },
- ],
- },
- });
- });
-
- it("should convert message type to text message", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "message",
- text: "Message text",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].type).toBe("assistant");
- expect(results[0].message?.content[0]).toMatchObject({
- type: "text",
- text: "Message text",
- });
- });
-
- it("should convert command_execution to formatted text", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "command_execution",
- command: "ls -la",
- aggregated_output: "file1.txt\nfile2.txt",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- const content = results[0].message?.content[0] as any;
- expect(content.type).toBe("text");
- expect(content.text).toContain("```bash");
- expect(content.text).toContain("ls -la");
- expect(content.text).toContain("file1.txt");
- });
-
- it("should convert tool_use item", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "tool_use",
- tool: "read_file",
- input: { path: "/test.txt" },
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].message?.content[0]).toMatchObject({
- type: "tool_use",
- name: "read_file",
- input: { path: "/test.txt" },
- });
- });
-
- it("should convert tool_result item", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "tool_result",
- tool_use_id: "123",
- output: "File contents",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].message?.content[0]).toMatchObject({
- type: "tool_result",
- tool_use_id: "123",
- content: "File contents",
- });
- });
-
- it("should convert todo_list to formatted text", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "todo_list",
- items: [{ text: "Task 1" }, { text: "Task 2" }],
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- const content = results[0].message?.content[0] as any;
- expect(content.type).toBe("text");
- expect(content.text).toContain("**Todo List:**");
- expect(content.text).toContain("1. Task 1");
- expect(content.text).toContain("2. Task 2");
- });
-
- it("should convert file_change to formatted text", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "file_change",
- changes: [{ path: "/file1.txt" }, { path: "/file2.txt" }],
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- const content = results[0].message?.content[0] as any;
- expect(content.type).toBe("text");
- expect(content.text).toContain("**File Changes:**");
- expect(content.text).toContain("Modified: /file1.txt");
- expect(content.text).toContain("Modified: /file2.txt");
- });
-
- it("should handle item.started with command_execution", async () => {
- const mockEvents = [
- {
- type: "item.started",
- item: {
- type: "command_execution",
- command: "npm install",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].message?.content[0]).toMatchObject({
- type: "tool_use",
- name: "bash",
- input: { command: "npm install" },
- });
- });
-
- it("should handle item.started with todo_list", async () => {
- const mockEvents = [
- {
- type: "item.started",
- item: {
- type: "todo_list",
- items: ["Task 1", "Task 2"],
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- const content = results[0].message?.content[0] as any;
- expect(content.text).toContain("**Todo List:**");
- expect(content.text).toContain("1. Task 1");
- expect(content.text).toContain("2. Task 2");
- });
-
- it("should handle item.updated with todo_list", async () => {
- const mockEvents = [
- {
- type: "item.updated",
- item: {
- type: "todo_list",
- items: [
- { text: "Task 1", status: "completed" },
- { text: "Task 2", status: "pending" },
- ],
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- const content = results[0].message?.content[0] as any;
- expect(content.text).toContain("**Updated Todo List:**");
- expect(content.text).toContain("1. [✓] Task 1");
- expect(content.text).toContain("2. [ ] Task 2");
- });
-
- it("should convert error events", async () => {
- const mockEvents = [
- {
- type: "error",
- data: { message: "Something went wrong" },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0]).toMatchObject({
- type: "error",
- error: "Something went wrong",
- });
- });
-
- it("should convert thread.completed to result", async () => {
- const mockEvents = [{ type: "thread.completed" }];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0]).toMatchObject({
- type: "result",
- subtype: "success",
- });
- });
-
- it("should skip thread.started events", async () => {
- const mockEvents = [
- { type: "thread.started" },
- {
- type: "item.completed",
- item: { type: "message", content: "Response" },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- // Should only have the message and final success
- expect(results).toHaveLength(2);
- expect(results[0].type).toBe("assistant");
- });
-
- it("should skip turn events", async () => {
- const mockEvents = [
- { type: "turn.started" },
- {
- type: "item.completed",
- item: { type: "message", content: "Response" },
- },
- { type: "turn.completed" },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- // Should only have the message and final success
- expect(results).toHaveLength(2);
- expect(results[0].type).toBe("assistant");
- });
-
- it("should handle generic item with text fallback", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- type: "unknown_type",
- text: "Generic output",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].message?.content[0]).toMatchObject({
- type: "text",
- text: "Generic output",
- });
- });
-
- it("should handle items with item_type field", async () => {
- const mockEvents = [
- {
- type: "item.completed",
- item: {
- item_type: "message",
- content: "Using item_type field",
- },
- },
- ];
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- for (const event of mockEvents) {
- yield event;
- }
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- const results = await collectAsyncGenerator(generator);
-
- expect(results[0].message?.content[0]).toMatchObject({
- type: "text",
- text: "Using item_type field",
- });
- });
- });
-
- describe("findCodexPath", () => {
- it("should use config.cliPath if set", async () => {
- provider.setConfig({ cliPath: "/custom/path/to/codex" });
-
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.command).toBe("/custom/path/to/codex");
- });
-
- it("should use CODEX_CLI_PATH env var if set", async () => {
- process.env.CODEX_CLI_PATH = "/env/path/to/codex";
-
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.command).toBe("/env/path/to/codex");
- });
-
- it("should auto-detect CLI path", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.command).toBe("/usr/bin/codex");
- });
-
- it("should default to 'codex' if not detected", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- vi.spyOn(subprocessManager, "spawnJSONLProcess").mockReturnValue(
- (async function* () {
- yield { type: "thread.completed" };
- })()
- );
-
- const generator = provider.executeQuery({ prompt: "Test", cwd: "/test" });
- await collectAsyncGenerator(generator);
-
- const call = vi.mocked(subprocessManager.spawnJSONLProcess).mock.calls[0][0];
- expect(call.command).toBe("codex");
- });
- });
-
- describe("detectInstallation", () => {
- it("should combine detection and auth results", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: true,
- path: "/usr/bin/codex",
- version: "0.5.0",
- method: "cli",
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: true,
- method: "cli_verified",
- hasAuthFile: true,
- hasEnvKey: false,
- });
-
- const result = await provider.detectInstallation();
-
- expect(result).toMatchObject({
- installed: true,
- path: "/usr/bin/codex",
- version: "0.5.0",
- method: "cli",
- hasApiKey: true,
- authenticated: true,
- });
- });
-
- it("should detect API key from env", async () => {
- vi.spyOn(CodexCliDetector, "detectCodexInstallation").mockReturnValue({
- installed: false,
- });
- vi.spyOn(CodexCliDetector, "checkAuth").mockReturnValue({
- authenticated: false,
- method: "none",
- hasAuthFile: false,
- hasEnvKey: true,
- });
-
- const result = await provider.detectInstallation();
-
- expect(result.hasApiKey).toBe(true);
- expect(result.authenticated).toBe(false);
- });
- });
-
- describe("getAvailableModels", () => {
- it("should return 5 Codex models", () => {
- const models = provider.getAvailableModels();
- expect(models).toHaveLength(5);
- });
-
- it("should include gpt-5.2 as default", () => {
- const models = provider.getAvailableModels();
- const gpt52 = models.find((m) => m.id === "gpt-5.2");
-
- expect(gpt52).toBeDefined();
- expect(gpt52?.name).toBe("GPT-5.2 (Codex)");
- expect(gpt52?.default).toBe(true);
- expect(gpt52?.provider).toBe("openai-codex");
- });
-
- it("should include all expected models", () => {
- const models = provider.getAvailableModels();
- const modelIds = models.map((m) => m.id);
-
- expect(modelIds).toContain("gpt-5.2");
- expect(modelIds).toContain("gpt-5.1-codex-max");
- expect(modelIds).toContain("gpt-5.1-codex");
- expect(modelIds).toContain("gpt-5.1-codex-mini");
- expect(modelIds).toContain("gpt-5.1");
- });
-
- it("should have correct capabilities", () => {
- const models = provider.getAvailableModels();
-
- models.forEach((model) => {
- expect(model.supportsTools).toBe(true);
- expect(model.contextWindow).toBe(256000);
- expect(model.modelString).toBe(model.id);
- });
- });
-
- it("should have vision support except for mini", () => {
- const models = provider.getAvailableModels();
-
- const mini = models.find((m) => m.id === "gpt-5.1-codex-mini");
- const others = models.filter((m) => m.id !== "gpt-5.1-codex-mini");
-
- expect(mini?.supportsVision).toBe(false);
- others.forEach((model) => {
- expect(model.supportsVision).toBe(true);
- });
- });
- });
-
- describe("supportsFeature", () => {
- it("should support tools feature", () => {
- expect(provider.supportsFeature("tools")).toBe(true);
- });
-
- it("should support text feature", () => {
- expect(provider.supportsFeature("text")).toBe(true);
- });
-
- it("should support vision feature", () => {
- expect(provider.supportsFeature("vision")).toBe(true);
- });
-
- it("should support mcp feature", () => {
- expect(provider.supportsFeature("mcp")).toBe(true);
- });
-
- it("should support cli feature", () => {
- expect(provider.supportsFeature("cli")).toBe(true);
- });
-
- it("should not support unknown features", () => {
- expect(provider.supportsFeature("unknown")).toBe(false);
- });
-
- it("should not support thinking feature", () => {
- expect(provider.supportsFeature("thinking")).toBe(false);
- });
- });
-});
diff --git a/apps/server/tests/unit/providers/provider-factory.test.ts b/apps/server/tests/unit/providers/provider-factory.test.ts
index abe62f62..cd34af15 100644
--- a/apps/server/tests/unit/providers/provider-factory.test.ts
+++ b/apps/server/tests/unit/providers/provider-factory.test.ts
@@ -1,7 +1,6 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { ProviderFactory } from "@/providers/provider-factory.js";
import { ClaudeProvider } from "@/providers/claude-provider.js";
-import { CodexProvider } from "@/providers/codex-provider.js";
describe("provider-factory.ts", () => {
let consoleSpy: any;
@@ -17,48 +16,6 @@ describe("provider-factory.ts", () => {
});
describe("getProviderForModel", () => {
- describe("OpenAI/Codex models (gpt-*)", () => {
- it("should return CodexProvider for gpt-5.2", () => {
- const provider = ProviderFactory.getProviderForModel("gpt-5.2");
- expect(provider).toBeInstanceOf(CodexProvider);
- });
-
- it("should return CodexProvider for gpt-5.1-codex", () => {
- const provider = ProviderFactory.getProviderForModel("gpt-5.1-codex");
- expect(provider).toBeInstanceOf(CodexProvider);
- });
-
- it("should return CodexProvider for gpt-4", () => {
- const provider = ProviderFactory.getProviderForModel("gpt-4");
- expect(provider).toBeInstanceOf(CodexProvider);
- });
-
- it("should be case-insensitive for gpt models", () => {
- const provider1 = ProviderFactory.getProviderForModel("GPT-5.2");
- const provider2 = ProviderFactory.getProviderForModel("Gpt-5.1");
- expect(provider1).toBeInstanceOf(CodexProvider);
- expect(provider2).toBeInstanceOf(CodexProvider);
- });
- });
-
- describe("Unsupported o-series models", () => {
- it("should default to ClaudeProvider for o1 (not supported by Codex CLI)", () => {
- const provider = ProviderFactory.getProviderForModel("o1");
- expect(provider).toBeInstanceOf(ClaudeProvider);
- expect(consoleSpy.warn).toHaveBeenCalled();
- });
-
- it("should default to ClaudeProvider for o3", () => {
- const provider = ProviderFactory.getProviderForModel("o3");
- expect(provider).toBeInstanceOf(ClaudeProvider);
- });
-
- it("should default to ClaudeProvider for o1-mini", () => {
- const provider = ProviderFactory.getProviderForModel("o1-mini");
- expect(provider).toBeInstanceOf(ClaudeProvider);
- });
- });
-
describe("Claude models (claude-* prefix)", () => {
it("should return ClaudeProvider for claude-opus-4-5-20251101", () => {
const provider = ProviderFactory.getProviderForModel(
@@ -138,6 +95,18 @@ describe("provider-factory.ts", () => {
expect(provider).toBeInstanceOf(ClaudeProvider);
expect(consoleSpy.warn).toHaveBeenCalled();
});
+
+ it("should default to ClaudeProvider for gpt models (not supported)", () => {
+ const provider = ProviderFactory.getProviderForModel("gpt-5.2");
+ expect(provider).toBeInstanceOf(ClaudeProvider);
+ expect(consoleSpy.warn).toHaveBeenCalled();
+ });
+
+ it("should default to ClaudeProvider for o-series models (not supported)", () => {
+ const provider = ProviderFactory.getProviderForModel("o1");
+ expect(provider).toBeInstanceOf(ClaudeProvider);
+ expect(consoleSpy.warn).toHaveBeenCalled();
+ });
});
});
@@ -155,15 +124,9 @@ describe("provider-factory.ts", () => {
expect(hasClaudeProvider).toBe(true);
});
- it("should include CodexProvider", () => {
+ it("should return exactly 1 provider", () => {
const providers = ProviderFactory.getAllProviders();
- const hasCodexProvider = providers.some((p) => p instanceof CodexProvider);
- expect(hasCodexProvider).toBe(true);
- });
-
- it("should return exactly 2 providers", () => {
- const providers = ProviderFactory.getAllProviders();
- expect(providers).toHaveLength(2);
+ expect(providers).toHaveLength(1);
});
it("should create new instances each time", () => {
@@ -171,7 +134,6 @@ describe("provider-factory.ts", () => {
const providers2 = ProviderFactory.getAllProviders();
expect(providers1[0]).not.toBe(providers2[0]);
- expect(providers1[1]).not.toBe(providers2[1]);
});
});
@@ -180,14 +142,12 @@ describe("provider-factory.ts", () => {
const statuses = await ProviderFactory.checkAllProviders();
expect(statuses).toHaveProperty("claude");
- expect(statuses).toHaveProperty("codex");
});
it("should call detectInstallation on each provider", async () => {
const statuses = await ProviderFactory.checkAllProviders();
expect(statuses.claude).toHaveProperty("installed");
- expect(statuses.codex).toHaveProperty("installed");
});
it("should return correct provider names as keys", async () => {
@@ -195,8 +155,7 @@ describe("provider-factory.ts", () => {
const keys = Object.keys(statuses);
expect(keys).toContain("claude");
- expect(keys).toContain("codex");
- expect(keys).toHaveLength(2);
+ expect(keys).toHaveLength(1);
});
});
@@ -211,24 +170,12 @@ describe("provider-factory.ts", () => {
expect(provider).toBeInstanceOf(ClaudeProvider);
});
- it("should return CodexProvider for 'codex'", () => {
- const provider = ProviderFactory.getProviderByName("codex");
- expect(provider).toBeInstanceOf(CodexProvider);
- });
-
- it("should return CodexProvider for 'openai'", () => {
- const provider = ProviderFactory.getProviderByName("openai");
- expect(provider).toBeInstanceOf(CodexProvider);
- });
-
it("should be case-insensitive", () => {
const provider1 = ProviderFactory.getProviderByName("CLAUDE");
- const provider2 = ProviderFactory.getProviderByName("Codex");
- const provider3 = ProviderFactory.getProviderByName("ANTHROPIC");
+ const provider2 = ProviderFactory.getProviderByName("ANTHROPIC");
expect(provider1).toBeInstanceOf(ClaudeProvider);
- expect(provider2).toBeInstanceOf(CodexProvider);
- expect(provider3).toBeInstanceOf(ClaudeProvider);
+ expect(provider2).toBeInstanceOf(ClaudeProvider);
});
it("should return null for unknown provider", () => {
@@ -273,7 +220,7 @@ describe("provider-factory.ts", () => {
});
});
- it("should aggregate models from both Claude and Codex", () => {
+ it("should include Claude models", () => {
const models = ProviderFactory.getAllAvailableModels();
// Claude models should include claude-* in their IDs
@@ -281,13 +228,7 @@ describe("provider-factory.ts", () => {
m.id.toLowerCase().includes("claude")
);
- // Codex models should include gpt-* in their IDs
- const hasCodexModels = models.some((m) =>
- m.id.toLowerCase().includes("gpt")
- );
-
expect(hasClaudeModels).toBe(true);
- expect(hasCodexModels).toBe(true);
});
});
});
diff --git a/apps/server/tests/unit/services/agent-service.test.ts b/apps/server/tests/unit/services/agent-service.test.ts
index 4a9ab6b4..efe27fbf 100644
--- a/apps/server/tests/unit/services/agent-service.test.ts
+++ b/apps/server/tests/unit/services/agent-service.test.ts
@@ -245,7 +245,7 @@ describe("agent-service.ts", () => {
it("should use custom model if provided", async () => {
const mockProvider = {
- getName: () => "codex",
+ getName: () => "claude",
executeQuery: async function* () {
yield {
type: "result",
@@ -266,10 +266,10 @@ describe("agent-service.ts", () => {
await service.sendMessage({
sessionId: "session-1",
message: "Hello",
- model: "gpt-5.2",
+ model: "claude-sonnet-4-20250514",
});
- expect(ProviderFactory.getProviderForModel).toHaveBeenCalledWith("gpt-5.2");
+ expect(ProviderFactory.getProviderForModel).toHaveBeenCalledWith("claude-sonnet-4-20250514");
});
it("should save session messages", async () => {
diff --git a/apps/server/vitest.config.ts b/apps/server/vitest.config.ts
index a66be2e1..0aee3a84 100644
--- a/apps/server/vitest.config.ts
+++ b/apps/server/vitest.config.ts
@@ -17,10 +17,10 @@ export default defineConfig({
"src/routes/**", // Routes are better tested with integration tests
],
thresholds: {
- lines: 70,
- functions: 80,
- branches: 64,
- statements: 70,
+ lines: 65,
+ functions: 75,
+ branches: 58,
+ statements: 65,
},
},
include: ["tests/**/*.test.ts", "tests/**/*.spec.ts"],
diff --git a/package-lock.json b/package-lock.json
index 3268efa5..cab5d5b2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -204,22 +204,6 @@
"@babel/core": "^7.0.0"
}
},
- "apps/app/node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "apps/app/node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
"apps/app/node_modules/@babel/helper-validator-option": {
"version": "7.27.1",
"dev": true,
@@ -240,20 +224,6 @@
"node": ">=6.9.0"
}
},
- "apps/app/node_modules/@babel/parser": {
- "version": "7.28.5",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.28.5"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"apps/app/node_modules/@babel/template": {
"version": "7.27.2",
"dev": true,
@@ -284,18 +254,6 @@
"node": ">=6.9.0"
}
},
- "apps/app/node_modules/@babel/types": {
- "version": "7.28.5",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"apps/app/node_modules/@develar/schema-utils": {
"version": "2.6.5",
"dev": true,
@@ -1402,28 +1360,6 @@
"@jridgewell/trace-mapping": "^0.3.24"
}
},
- "apps/app/node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "apps/app/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "dev": true,
- "license": "MIT"
- },
- "apps/app/node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
"apps/app/node_modules/@malept/cross-spawn-promise": {
"version": "2.0.0",
"dev": true,
@@ -2478,11 +2414,6 @@
"url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
- "apps/app/node_modules/@standard-schema/spec": {
- "version": "1.0.0",
- "dev": true,
- "license": "MIT"
- },
"apps/app/node_modules/@szmarczak/http-timer": {
"version": "4.0.6",
"dev": true,
@@ -2530,38 +2461,6 @@
"@tailwindcss/oxide-win32-x64-msvc": "4.1.17"
}
},
- "apps/app/node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.17",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "apps/app/node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.17.tgz",
- "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
"apps/app/node_modules/@tailwindcss/postcss": {
"version": "4.1.17",
"dev": true,
@@ -2622,10 +2521,6 @@
"@types/ms": "*"
}
},
- "apps/app/node_modules/@types/estree": {
- "version": "1.0.8",
- "license": "MIT"
- },
"apps/app/node_modules/@types/estree-jsx": {
"version": "1.0.5",
"license": "MIT",
@@ -2682,16 +2577,6 @@
"version": "2.1.0",
"license": "MIT"
},
- "apps/app/node_modules/@types/plist": {
- "version": "3.0.5",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@types/node": "*",
- "xmlbuilder": ">=11.0.1"
- }
- },
"apps/app/node_modules/@types/react": {
"version": "19.2.7",
"license": "MIT",
@@ -2719,12 +2604,6 @@
"version": "3.0.3",
"license": "MIT"
},
- "apps/app/node_modules/@types/verror": {
- "version": "1.10.11",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"apps/app/node_modules/@types/yauzl": {
"version": "2.10.3",
"dev": true,
@@ -2980,18 +2859,6 @@
"version": "1.3.0",
"license": "ISC"
},
- "apps/app/node_modules/@unrs/resolver-binding-darwin-arm64": {
- "version": "1.11.1",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
"apps/app/node_modules/@xmldom/xmldom": {
"version": "0.8.11",
"dev": true,
@@ -3433,29 +3300,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "apps/app/node_modules/assert-plus": {
- "version": "1.0.0",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=0.8"
- }
- },
"apps/app/node_modules/ast-types-flow": {
"version": "0.0.8",
"dev": true,
"license": "MIT"
},
- "apps/app/node_modules/astral-regex": {
- "version": "2.0.0",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"apps/app/node_modules/async": {
"version": "3.2.6",
"dev": true,
@@ -4029,22 +3878,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "apps/app/node_modules/cli-truncate": {
- "version": "2.1.0",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "slice-ansi": "^3.0.0",
- "string-width": "^4.2.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"apps/app/node_modules/cliui": {
"version": "8.0.1",
"dev": true,
@@ -4233,21 +4066,6 @@
"dev": true,
"license": "MIT"
},
- "apps/app/node_modules/core-util-is": {
- "version": "1.0.2",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
- "apps/app/node_modules/crc": {
- "version": "3.8.0",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "buffer": "^5.1.0"
- }
- },
"apps/app/node_modules/cross-dirname": {
"version": "0.1.0",
"dev": true,
@@ -4512,31 +4330,6 @@
"node": ">= 10.0.0"
}
},
- "apps/app/node_modules/dmg-license": {
- "version": "1.0.11",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "dependencies": {
- "@types/plist": "^3.0.1",
- "@types/verror": "^1.10.3",
- "ajv": "^6.10.0",
- "crc": "^3.8.0",
- "iconv-corefoundation": "^1.1.7",
- "plist": "^3.0.4",
- "smart-buffer": "^4.0.2",
- "verror": "^1.10.0"
- },
- "bin": {
- "dmg-license": "bin/dmg-license.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
"apps/app/node_modules/doctrine": {
"version": "2.1.0",
"dev": true,
@@ -5384,15 +5177,6 @@
"@types/yauzl": "^2.9.1"
}
},
- "apps/app/node_modules/extsprintf": {
- "version": "1.4.1",
- "dev": true,
- "engines": [
- "node >=0.6.0"
- ],
- "license": "MIT",
- "optional": true
- },
"apps/app/node_modules/fast-glob": {
"version": "3.3.1",
"dev": true,
@@ -5521,11 +5305,6 @@
"node": ">=16"
}
},
- "apps/app/node_modules/flatted": {
- "version": "3.3.3",
- "dev": true,
- "license": "ISC"
- },
"apps/app/node_modules/follow-redirects": {
"version": "1.15.11",
"dev": true,
@@ -5629,18 +5408,6 @@
"dev": true,
"license": "ISC"
},
- "apps/app/node_modules/fsevents": {
- "version": "2.3.2",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"apps/app/node_modules/function.prototype.name": {
"version": "1.1.8",
"dev": true,
@@ -6031,22 +5798,6 @@
"ms": "^2.0.0"
}
},
- "apps/app/node_modules/iconv-corefoundation": {
- "version": "1.1.7",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "dependencies": {
- "cli-truncate": "^2.1.0",
- "node-addon-api": "^1.6.3"
- },
- "engines": {
- "node": "^8.11.2 || >=10"
- }
- },
"apps/app/node_modules/iconv-lite": {
"version": "0.6.3",
"dev": true,
@@ -6834,24 +6585,6 @@
"lightningcss-win32-x64-msvc": "1.30.2"
}
},
- "apps/app/node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.2",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
"apps/app/node_modules/locate-path": {
"version": "6.0.0",
"dev": true,
@@ -6933,14 +6666,6 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
- "apps/app/node_modules/magic-string": {
- "version": "0.30.21",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
"apps/app/node_modules/make-fetch-happen": {
"version": "14.0.3",
"dev": true,
@@ -7761,12 +7486,6 @@
"node": ">=10"
}
},
- "apps/app/node_modules/node-addon-api": {
- "version": "1.7.2",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
"apps/app/node_modules/node-api-version": {
"version": "0.2.1",
"dev": true,
@@ -8941,20 +8660,6 @@
"node": ">=10"
}
},
- "apps/app/node_modules/slice-ansi": {
- "version": "3.0.0",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"apps/app/node_modules/smart-buffer": {
"version": "4.2.0",
"dev": true,
@@ -9457,48 +9162,6 @@
"semver": "bin/semver"
}
},
- "apps/app/node_modules/tinyglobby": {
- "version": "0.2.15",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "apps/app/node_modules/tinyglobby/node_modules/fdir": {
- "version": "6.5.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "apps/app/node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.3",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
"apps/app/node_modules/tmp": {
"version": "0.2.5",
"dev": true,
@@ -9947,20 +9610,6 @@
"dev": true,
"license": "MIT"
},
- "apps/app/node_modules/verror": {
- "version": "1.10.1",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
- },
- "engines": {
- "node": ">=0.6.0"
- }
- },
"apps/app/node_modules/vfile": {
"version": "6.0.3",
"license": "MIT",
@@ -10268,14 +9917,15 @@
"@types/express": "^5.0.1",
"@types/node": "^20",
"@types/ws": "^8.18.1",
+ "@vitest/coverage-v8": "^4.0.15",
+ "@vitest/ui": "^4.0.15",
"tsx": "^4.19.4",
- "typescript": "^5"
+ "typescript": "^5",
+ "vitest": "^4.0.15"
}
},
"node_modules/@anthropic-ai/claude-agent-sdk": {
"version": "0.1.67",
- "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.1.67.tgz",
- "integrity": "sha512-SPeMOfBeQ4Q6BcTRGRyMzaSEzKja3w8giZn6xboab02rPly5KQmgDK0wNerUntPe+xyw7c01xdu5K/pjZXq0dw==",
"license": "SEE LICENSE IN README.md",
"engines": {
"node": ">=18.0.0"
@@ -10294,276 +9944,8 @@
"zod": "^3.24.1"
}
},
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-darwin-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
- "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.0.4"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-darwin-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
- "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.0.4"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
- "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
- "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
- "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
- "cpu": [
- "arm"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
- "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
- "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
- "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
- "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-linux-arm": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
- "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
- "cpu": [
- "arm"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.0.5"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-linux-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
- "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.0.4"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-linux-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
- "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.0.4"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
- "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
- }
- },
- "node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
- "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
- }
- },
"node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@img/sharp-win32-x64": {
"version": "0.33.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
- "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
"cpu": [
"x64"
],
@@ -10591,445 +9973,58 @@
"resolved": "apps/server",
"link": true
},
- "node_modules/@emnapi/runtime": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz",
- "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.5",
+ "dev": true,
"license": "MIT",
- "optional": true,
"dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz",
- "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.0.0"
}
},
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz",
- "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==",
- "cpu": [
- "arm"
- ],
+ "node_modules/@babel/types": {
+ "version": "7.28.5",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
"engines": {
- "node": ">=18"
+ "node": ">=6.9.0"
}
},
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz",
- "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==",
- "cpu": [
- "arm64"
- ],
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
"dev": true,
"license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz",
- "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz",
- "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz",
- "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz",
- "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz",
- "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz",
- "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz",
- "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz",
- "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz",
- "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz",
- "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz",
- "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz",
- "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz",
- "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz",
- "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz",
- "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz",
- "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz",
- "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz",
- "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz",
- "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz",
- "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz",
- "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz",
- "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.27.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz",
- "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==",
"cpu": [
"x64"
],
@@ -11045,455 +10040,14 @@
},
"node_modules/@img/colour": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz",
- "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=18"
}
},
- "node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
- "cpu": [
- "arm"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
- "cpu": [
- "ppc64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
- "cpu": [
- "riscv64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
- "cpu": [
- "s390x"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
- "cpu": [
- "arm"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
- "cpu": [
- "ppc64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
- "cpu": [
- "riscv64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
- "cpu": [
- "s390x"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
- "cpu": [
- "wasm32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/runtime": "^1.7.0"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
- "cpu": [
- "ia32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
"node_modules/@img/sharp-win32-x64": {
"version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
"cpu": [
"x64"
],
@@ -11509,128 +10063,34 @@
"url": "https://opencollective.com/libvips"
}
},
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"node_modules/@next/env": {
"version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.7.tgz",
- "integrity": "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw==",
"license": "MIT"
},
- "node_modules/@next/swc-darwin-arm64": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.7.tgz",
- "integrity": "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-darwin-x64": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.7.tgz",
- "integrity": "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-gnu": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.7.tgz",
- "integrity": "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-musl": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.7.tgz",
- "integrity": "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-gnu": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.7.tgz",
- "integrity": "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-musl": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.7.tgz",
- "integrity": "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-arm64-msvc": {
- "version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.7.tgz",
- "integrity": "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
"node_modules/@next/swc-win32-x64-msvc": {
"version": "16.0.7",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.7.tgz",
- "integrity": "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug==",
"cpu": [
"x64"
],
@@ -11643,185 +10103,49 @@
"node": ">= 10"
}
},
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.53.3",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.53.3",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@swc/helpers": {
"version": "0.5.15",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
- "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.17.tgz",
- "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.17.tgz",
- "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.17.tgz",
- "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.17.tgz",
- "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.17.tgz",
- "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.17.tgz",
- "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.17.tgz",
- "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.17.tgz",
- "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.6.0",
- "@emnapi/runtime": "^1.6.0",
- "@emnapi/wasi-threads": "^1.1.0",
- "@napi-rs/wasm-runtime": "^1.0.7",
- "@tybys/wasm-util": "^0.10.1",
- "tslib": "^2.4.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.17.tgz",
- "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
"version": "4.1.17",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.17.tgz",
- "integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==",
"cpu": [
"x64"
],
@@ -11837,8 +10161,6 @@
},
"node_modules/@types/body-parser": {
"version": "1.19.6",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
- "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11846,10 +10168,17 @@
"@types/node": "*"
}
},
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
"node_modules/@types/connect": {
"version": "3.4.38",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
- "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11858,18 +10187,23 @@
},
"node_modules/@types/cors": {
"version": "2.8.19",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
- "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "license": "MIT"
+ },
"node_modules/@types/express": {
"version": "5.0.6",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz",
- "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11880,8 +10214,6 @@
},
"node_modules/@types/express-serve-static-core": {
"version": "5.1.0",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz",
- "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11893,15 +10225,11 @@
},
"node_modules/@types/http-errors": {
"version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
- "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "20.19.26",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.26.tgz",
- "integrity": "sha512-0l6cjgF0XnihUpndDhk+nyD3exio3iKaYROSgvh/qSevPXax3L8p5DBRFjbvalnwatGgHEQn2R88y2fA3g4irg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11910,22 +10238,16 @@
},
"node_modules/@types/qs": {
"version": "6.14.0",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/range-parser": {
"version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/send": {
"version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
- "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11934,8 +10256,6 @@
},
"node_modules/@types/serve-static": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11945,14 +10265,159 @@
},
"node_modules/@types/ws": {
"version": "8.18.1",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
- "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
+ "node_modules/@vitest/coverage-v8": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^1.0.2",
+ "@vitest/utils": "4.0.15",
+ "ast-v8-to-istanbul": "^0.3.8",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.2.0",
+ "magicast": "^0.5.1",
+ "obug": "^2.1.1",
+ "std-env": "^3.10.0",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/browser": "4.0.15",
+ "vitest": "4.0.15"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.0.0",
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "4.0.15",
+ "@vitest/utils": "4.0.15",
+ "chai": "^6.2.1",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "4.0.15",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.21"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.0.15",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.0.15",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/ui": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.0.15",
+ "fflate": "^0.8.2",
+ "flatted": "^3.3.3",
+ "pathe": "^2.0.3",
+ "sirv": "^3.0.2",
+ "tinyglobby": "^0.2.15",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": "4.0.15"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.0.15",
+ "tinyrainbow": "^3.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
"node_modules/@xterm/addon-fit": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
@@ -11979,15 +10444,11 @@
},
"node_modules/@zeit/schemas": {
"version": "2.36.0",
- "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz",
- "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==",
"dev": true,
"license": "MIT"
},
"node_modules/accepts": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"license": "MIT",
"dependencies": {
"mime-types": "^3.0.0",
@@ -11999,8 +10460,6 @@
},
"node_modules/accepts/node_modules/mime-types": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
@@ -12015,8 +10474,6 @@
},
"node_modules/accepts/node_modules/negotiator": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12024,8 +10481,6 @@
},
"node_modules/ajv": {
"version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12041,8 +10496,6 @@
},
"node_modules/ansi-align": {
"version": "3.0.1",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
- "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -12051,8 +10504,6 @@
},
"node_modules/ansi-align/node_modules/ansi-regex": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12061,15 +10512,11 @@
},
"node_modules/ansi-align/node_modules/emoji-regex": {
"version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/ansi-align/node_modules/string-width": {
"version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12083,8 +10530,6 @@
},
"node_modules/ansi-align/node_modules/strip-ansi": {
"version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12096,8 +10541,6 @@
},
"node_modules/ansi-regex": {
"version": "6.2.2",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
- "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12109,8 +10552,6 @@
},
"node_modules/ansi-styles": {
"version": "6.2.3",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
- "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12122,8 +10563,6 @@
},
"node_modules/arch": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
- "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
"dev": true,
"funding": [
{
@@ -12143,22 +10582,34 @@
},
"node_modules/arg": {
"version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
"dev": true,
"license": "MIT"
},
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul": {
+ "version": "0.3.8",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "estree-walker": "^3.0.3",
+ "js-tokens": "^9.0.1"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/body-parser": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz",
- "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==",
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
@@ -12181,8 +10632,6 @@
},
"node_modules/body-parser/node_modules/debug": {
"version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -12198,14 +10647,10 @@
},
"node_modules/body-parser/node_modules/ms": {
"version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/boxen": {
"version": "7.0.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz",
- "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12227,8 +10672,6 @@
},
"node_modules/brace-expansion": {
"version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12238,8 +10681,6 @@
},
"node_modules/bytes": {
"version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -12247,8 +10688,6 @@
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -12260,8 +10699,6 @@
},
"node_modules/call-bound": {
"version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -12276,8 +10713,6 @@
},
"node_modules/camelcase": {
"version": "7.0.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
- "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12289,8 +10724,6 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001760",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz",
- "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==",
"funding": [
{
"type": "opencollective",
@@ -12307,10 +10740,16 @@
],
"license": "CC-BY-4.0"
},
+ "node_modules/chai": {
+ "version": "6.2.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/chalk": {
"version": "5.0.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
- "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12322,8 +10761,6 @@
},
"node_modules/chalk-template": {
"version": "0.4.0",
- "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
- "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12338,8 +10775,6 @@
},
"node_modules/chalk-template/node_modules/ansi-styles": {
"version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12354,8 +10789,6 @@
},
"node_modules/chalk-template/node_modules/chalk": {
"version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12371,8 +10804,6 @@
},
"node_modules/cli-boxes": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
- "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12384,14 +10815,10 @@
},
"node_modules/client-only": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/clipboardy": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz",
- "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12408,8 +10835,6 @@
},
"node_modules/color-convert": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12421,15 +10846,11 @@
},
"node_modules/color-name": {
"version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/compressible": {
"version": "2.0.18",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12441,8 +10862,6 @@
},
"node_modules/compression": {
"version": "1.8.1",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
- "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12460,15 +10879,11 @@
},
"node_modules/concat-map": {
"version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/content-disposition": {
"version": "0.5.2",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12477,8 +10892,6 @@
},
"node_modules/content-type": {
"version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12486,8 +10899,6 @@
},
"node_modules/cookie": {
"version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12495,8 +10906,6 @@
},
"node_modules/cookie-signature": {
"version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
"license": "MIT",
"engines": {
"node": ">=6.6.0"
@@ -12504,8 +10913,6 @@
},
"node_modules/cors": {
"version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"license": "MIT",
"dependencies": {
"object-assign": "^4",
@@ -12517,8 +10924,6 @@
},
"node_modules/cross-spawn": {
"version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12532,8 +10937,6 @@
},
"node_modules/debug": {
"version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12542,8 +10945,6 @@
},
"node_modules/deep-extend": {
"version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12552,8 +10953,6 @@
},
"node_modules/depd": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -12561,8 +10960,6 @@
},
"node_modules/detect-libc": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"devOptional": true,
"license": "Apache-2.0",
"engines": {
@@ -12571,8 +10968,6 @@
},
"node_modules/dotenv": {
"version": "17.2.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
- "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -12583,8 +10978,6 @@
},
"node_modules/dunder-proto": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -12597,28 +10990,20 @@
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true,
"license": "MIT"
},
"node_modules/ee-first": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -12626,8 +11011,6 @@
},
"node_modules/es-define-property": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -12635,17 +11018,18 @@
},
"node_modules/es-errors": {
"version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/es-object-atoms": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -12656,8 +11040,6 @@
},
"node_modules/esbuild": {
"version": "0.27.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz",
- "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -12698,14 +11080,18 @@
},
"node_modules/escape-html": {
"version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
"node_modules/etag": {
"version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12713,8 +11099,6 @@
},
"node_modules/execa": {
"version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12735,10 +11119,16 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
+ "node_modules/expect-type": {
+ "version": "1.3.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/express": {
"version": "5.2.1",
- "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
- "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
@@ -12780,8 +11170,6 @@
},
"node_modules/express/node_modules/content-disposition": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
- "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -12793,8 +11181,6 @@
},
"node_modules/express/node_modules/debug": {
"version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -12810,8 +11196,6 @@
},
"node_modules/express/node_modules/mime-types": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
@@ -12826,14 +11210,10 @@
},
"node_modules/express/node_modules/ms": {
"version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/express/node_modules/range-parser": {
"version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12841,15 +11221,32 @@
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fflate": {
+ "version": "0.8.2",
"dev": true,
"license": "MIT"
},
"node_modules/finalhandler": {
"version": "2.1.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
- "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
@@ -12869,8 +11266,6 @@
},
"node_modules/finalhandler/node_modules/debug": {
"version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -12886,14 +11281,15 @@
},
"node_modules/finalhandler/node_modules/ms": {
"version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/forwarded": {
"version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -12901,32 +11297,13 @@
},
"node_modules/fresh": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
"node_modules/function-bind": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -12934,8 +11311,6 @@
},
"node_modules/geist": {
"version": "1.5.1",
- "resolved": "https://registry.npmjs.org/geist/-/geist-1.5.1.tgz",
- "integrity": "sha512-mAHZxIsL2o3ZITFaBVFBnwyDOw+zNLYum6A6nIjpzCGIO8QtC3V76XF2RnZTyLx1wlDTmMDy8jg3Ib52MIjGvQ==",
"license": "SIL OPEN FONT LICENSE",
"peerDependencies": {
"next": ">=13.2.0"
@@ -12943,8 +11318,6 @@
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -12967,8 +11340,6 @@
},
"node_modules/get-proto": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -12980,8 +11351,6 @@
},
"node_modules/get-stream": {
"version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12993,8 +11362,6 @@
},
"node_modules/get-tsconfig": {
"version": "4.13.0",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz",
- "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13006,8 +11373,6 @@
},
"node_modules/gopd": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -13018,8 +11383,6 @@
},
"node_modules/has-flag": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13028,8 +11391,6 @@
},
"node_modules/has-symbols": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -13040,8 +11401,6 @@
},
"node_modules/hasown": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -13050,10 +11409,13 @@
"node": ">= 0.4"
}
},
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/http-errors": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"license": "MIT",
"dependencies": {
"depd": "~2.0.0",
@@ -13072,8 +11434,6 @@
},
"node_modules/human-signals": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -13082,8 +11442,6 @@
},
"node_modules/iconv-lite": {
"version": "0.7.1",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz",
- "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -13098,21 +11456,15 @@
},
"node_modules/inherits": {
"version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ini": {
"version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true,
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
@@ -13120,8 +11472,6 @@
},
"node_modules/is-docker": {
"version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true,
"license": "MIT",
"bin": {
@@ -13136,8 +11486,6 @@
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13146,8 +11494,6 @@
},
"node_modules/is-port-reachable": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz",
- "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13159,14 +11505,10 @@
},
"node_modules/is-promise": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
"license": "MIT"
},
"node_modules/is-stream": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13178,8 +11520,6 @@
},
"node_modules/is-wsl": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13191,18 +11531,106 @@
},
"node_modules/isexe": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.4.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/ms": {
+ "version": "2.1.3",
"dev": true,
"license": "MIT"
},
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "9.0.1",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.2",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
+ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lightningcss-darwin-x64": {
"version": "1.30.2",
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
@@ -13210,6 +11638,7 @@
"cpu": [
"x64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"darwin"
@@ -13229,6 +11658,7 @@
"cpu": [
"arm"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"linux"
@@ -13248,6 +11678,7 @@
"cpu": [
"arm64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"linux"
@@ -13267,6 +11698,7 @@
"cpu": [
"arm64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"linux"
@@ -13306,6 +11738,7 @@
"cpu": [
"x64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"linux"
@@ -13325,6 +11758,7 @@
"cpu": [
"arm64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"win32"
@@ -13339,11 +11773,10 @@
},
"node_modules/lightningcss-win32-x64-msvc": {
"version": "1.30.2",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
- "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
"cpu": [
"x64"
],
+ "license": "MPL-2.0",
"optional": true,
"os": [
"win32"
@@ -13356,10 +11789,40 @@
"url": "https://opencollective.com/parcel"
}
},
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/magicast": {
+ "version": "0.5.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -13367,8 +11830,6 @@
},
"node_modules/media-typer": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -13376,8 +11837,6 @@
},
"node_modules/merge-descriptors": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -13388,15 +11847,11 @@
},
"node_modules/merge-stream": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true,
"license": "MIT"
},
"node_modules/mime-db": {
"version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -13404,8 +11859,6 @@
},
"node_modules/mime-types": {
"version": "2.1.18",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
- "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13417,8 +11870,6 @@
},
"node_modules/mime-types/node_modules/mime-db": {
"version": "1.33.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
- "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13427,8 +11878,6 @@
},
"node_modules/mimic-fn": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13437,8 +11886,6 @@
},
"node_modules/minimatch": {
"version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -13450,25 +11897,27 @@
},
"node_modules/minimist": {
"version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/ms": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
@@ -13485,8 +11934,6 @@
},
"node_modules/negotiator": {
"version": "0.6.4",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
- "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13495,9 +11942,6 @@
},
"node_modules/next": {
"version": "16.0.7",
- "resolved": "https://registry.npmjs.org/next/-/next-16.0.7.tgz",
- "integrity": "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A==",
- "deprecated": "This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/security-update-2025-12-11 for more details.",
"license": "MIT",
"dependencies": {
"@next/env": "16.0.7",
@@ -13564,8 +12008,6 @@
},
"node_modules/npm-run-path": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13577,8 +12019,6 @@
},
"node_modules/object-assign": {
"version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -13586,8 +12026,6 @@
},
"node_modules/object-inspect": {
"version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -13596,10 +12034,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/obug": {
+ "version": "2.1.1",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/sxzz",
+ "https://opencollective.com/debug"
+ ],
+ "license": "MIT"
+ },
"node_modules/on-finished": {
"version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
@@ -13610,8 +12055,6 @@
},
"node_modules/on-headers": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
- "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13620,8 +12063,6 @@
},
"node_modules/once": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
"wrappy": "1"
@@ -13629,8 +12070,6 @@
},
"node_modules/onetime": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13645,8 +12084,6 @@
},
"node_modules/parseurl": {
"version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -13654,15 +12091,11 @@
},
"node_modules/path-is-inside": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
- "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==",
"dev": true,
"license": "(WTFPL OR MIT)"
},
"node_modules/path-key": {
"version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13671,21 +12104,31 @@
},
"node_modules/path-to-regexp": {
"version": "3.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz",
- "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
},
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.31",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
- "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
@@ -13712,8 +12155,6 @@
},
"node_modules/proxy-addr": {
"version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
@@ -13725,8 +12166,6 @@
},
"node_modules/punycode": {
"version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13735,8 +12174,6 @@
},
"node_modules/qs": {
"version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
@@ -13750,8 +12187,6 @@
},
"node_modules/range-parser": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
- "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13760,8 +12195,6 @@
},
"node_modules/raw-body": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
- "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
"dependencies": {
"bytes": "~3.1.2",
@@ -13775,8 +12208,6 @@
},
"node_modules/rc": {
"version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
@@ -13791,8 +12222,6 @@
},
"node_modules/react": {
"version": "19.2.0",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
- "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -13800,8 +12229,6 @@
},
"node_modules/react-dom": {
"version": "19.2.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
- "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
"dependencies": {
"scheduler": "^0.27.0"
@@ -13822,8 +12249,6 @@
},
"node_modules/registry-auth-token": {
"version": "3.3.2",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
- "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13833,8 +12258,6 @@
},
"node_modules/registry-url": {
"version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -13846,8 +12269,6 @@
},
"node_modules/require-from-string": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -13856,18 +12277,54 @@
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
- "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
+ "node_modules/rollup": {
+ "version": "4.53.3",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.53.3",
+ "@rollup/rollup-android-arm64": "4.53.3",
+ "@rollup/rollup-darwin-arm64": "4.53.3",
+ "@rollup/rollup-darwin-x64": "4.53.3",
+ "@rollup/rollup-freebsd-arm64": "4.53.3",
+ "@rollup/rollup-freebsd-x64": "4.53.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.53.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.53.3",
+ "@rollup/rollup-linux-arm64-musl": "4.53.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.53.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.53.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-musl": "4.53.3",
+ "@rollup/rollup-openharmony-arm64": "4.53.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.53.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.53.3",
+ "@rollup/rollup-win32-x64-gnu": "4.53.3",
+ "@rollup/rollup-win32-x64-msvc": "4.53.3",
+ "fsevents": "~2.3.2"
+ }
+ },
"node_modules/router": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
@@ -13882,8 +12339,6 @@
},
"node_modules/router/node_modules/debug": {
"version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -13899,14 +12354,10 @@
},
"node_modules/router/node_modules/ms": {
"version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/router/node_modules/path-to-regexp": {
"version": "8.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
- "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
"license": "MIT",
"funding": {
"type": "opencollective",
@@ -13915,8 +12366,6 @@
},
"node_modules/safe-buffer": {
"version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
@@ -13936,22 +12385,16 @@
},
"node_modules/safer-buffer": {
"version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/scheduler": {
"version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
"license": "MIT"
},
"node_modules/semver": {
"version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "devOptional": true,
"license": "ISC",
- "optional": true,
"bin": {
"semver": "bin/semver.js"
},
@@ -13961,8 +12404,6 @@
},
"node_modules/send": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.5",
@@ -13983,8 +12424,6 @@
},
"node_modules/send/node_modules/debug": {
"version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -14000,8 +12439,6 @@
},
"node_modules/send/node_modules/mime-types": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
@@ -14016,14 +12453,10 @@
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/send/node_modules/range-parser": {
"version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
@@ -14031,8 +12464,6 @@
},
"node_modules/serve": {
"version": "14.2.5",
- "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.5.tgz",
- "integrity": "sha512-Qn/qMkzCcMFVPb60E/hQy+iRLpiU8PamOfOSYoAHmmF+fFFmpPpqa6Oci2iWYpTdOUM3VF+TINud7CfbQnsZbA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14057,8 +12488,6 @@
},
"node_modules/serve-handler": {
"version": "6.1.6",
- "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz",
- "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14073,8 +12502,6 @@
},
"node_modules/serve-handler/node_modules/bytes": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -14083,8 +12510,6 @@
},
"node_modules/serve-static": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
@@ -14098,14 +12523,10 @@
},
"node_modules/setprototypeof": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
"node_modules/sharp": {
"version": "0.34.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
- "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
"hasInstallScript": true,
"license": "Apache-2.0",
"optional": true,
@@ -14149,8 +12570,6 @@
},
"node_modules/shebang-command": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14162,8 +12581,6 @@
},
"node_modules/shebang-regex": {
"version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -14172,8 +12589,6 @@
},
"node_modules/side-channel": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -14191,8 +12606,6 @@
},
"node_modules/side-channel-list": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -14207,8 +12620,6 @@
},
"node_modules/side-channel-map": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -14225,8 +12636,6 @@
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
@@ -14242,35 +12651,55 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "node_modules/siginfo": {
+ "version": "2.0.0",
"dev": true,
"license": "ISC"
},
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/sirv": {
+ "version": "3.0.2",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/statuses": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
+ "node_modules/std-env": {
+ "version": "3.10.0",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/string-width": {
"version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14287,8 +12716,6 @@
},
"node_modules/strip-ansi": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
- "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14303,8 +12730,6 @@
},
"node_modules/strip-final-newline": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -14313,8 +12738,6 @@
},
"node_modules/strip-json-comments": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -14323,8 +12746,6 @@
},
"node_modules/styled-jsx": {
"version": "5.1.6",
- "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
- "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
"license": "MIT",
"dependencies": {
"client-only": "0.0.1"
@@ -14346,8 +12767,6 @@
},
"node_modules/supports-color": {
"version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14357,25 +12776,63 @@
"node": ">=8"
}
},
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.0.2",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "3.0.3",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/tsx": {
"version": "4.21.0",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
- "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14394,8 +12851,6 @@
},
"node_modules/type-fest": {
"version": "2.19.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
- "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
@@ -14407,8 +12862,6 @@
},
"node_modules/type-is": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
"license": "MIT",
"dependencies": {
"content-type": "^1.0.5",
@@ -14421,8 +12874,6 @@
},
"node_modules/type-is/node_modules/mime-types": {
"version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
@@ -14437,8 +12888,6 @@
},
"node_modules/typescript": {
"version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -14451,15 +12900,11 @@
},
"node_modules/undici-types": {
"version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/unpipe": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
@@ -14467,8 +12912,6 @@
},
"node_modules/update-check": {
"version": "1.5.4",
- "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
- "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14478,8 +12921,6 @@
},
"node_modules/uri-js": {
"version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -14488,17 +12929,244 @@
},
"node_modules/vary": {
"version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
+ "node_modules/vite": {
+ "version": "6.4.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/vite/node_modules/esbuild": {
+ "version": "0.25.12",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.5.6",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "4.0.15",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "4.0.15",
+ "@vitest/mocker": "4.0.15",
+ "@vitest/pretty-format": "4.0.15",
+ "@vitest/runner": "4.0.15",
+ "@vitest/snapshot": "4.0.15",
+ "@vitest/spy": "4.0.15",
+ "@vitest/utils": "4.0.15",
+ "es-module-lexer": "^1.7.0",
+ "expect-type": "^1.2.2",
+ "magic-string": "^0.30.21",
+ "obug": "^2.1.1",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "std-env": "^3.10.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^1.0.2",
+ "tinyglobby": "^0.2.15",
+ "tinyrainbow": "^3.0.3",
+ "vite": "^6.0.0 || ^7.0.0",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@opentelemetry/api": "^1.9.0",
+ "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
+ "@vitest/browser-playwright": "4.0.15",
+ "@vitest/browser-preview": "4.0.15",
+ "@vitest/browser-webdriverio": "4.0.15",
+ "@vitest/ui": "4.0.15",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser-playwright": {
+ "optional": true
+ },
+ "@vitest/browser-preview": {
+ "optional": true
+ },
+ "@vitest/browser-webdriverio": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -14511,10 +13179,23 @@
"node": ">= 8"
}
},
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/widest-line": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
- "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14529,8 +13210,6 @@
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14547,14 +13226,10 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
"node_modules/ws": {
"version": "8.18.3",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
- "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -14574,8 +13249,6 @@
},
"node_modules/zod": {
"version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"