feat: show token usage
This commit is contained in:
parent
6dea9e8cfe
commit
7cb684d411
|
|
@ -11,7 +11,6 @@ import { PanelStyleSection } from "./ai/PanelStyleSection"
|
|||
import { PersonalizePromptSection } from "./ai/PersonalizePromptSection"
|
||||
import { AIShortcutsSection } from "./ai/shortcuts/AIShortcutsSection"
|
||||
import { TaskSchedulingSection } from "./ai/tasks"
|
||||
import { TokenUsageSection } from "./ai/TokenUsageSection"
|
||||
|
||||
const SettingBuilder = createSettingBuilder(useAISettingValue)
|
||||
const defineSettingItem = createDefineSettingItem(useAISettingValue, setAISetting)
|
||||
|
|
@ -23,11 +22,6 @@ export const SettingAI = () => {
|
|||
<div className="mt-4">
|
||||
<SettingBuilder
|
||||
settings={[
|
||||
{
|
||||
type: "title",
|
||||
value: t("token_usage.title"),
|
||||
},
|
||||
TokenUsageSection,
|
||||
{
|
||||
type: "title",
|
||||
value: t("features.title"),
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
import { Progress } from "@follow/components/ui/progress/index.jsx"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { followClient } from "~/lib/api-client"
|
||||
|
||||
import { SettingDescription } from "../../control"
|
||||
|
||||
const useTokenUsage = () => {
|
||||
return useQuery({
|
||||
queryKey: ["aiTokenUsage"],
|
||||
queryFn: async () => {
|
||||
return (await followClient.api.ai.config()).usage
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const TokenUsageSection = () => {
|
||||
const { t } = useTranslation("ai")
|
||||
|
||||
const tokenUsage = useTokenUsage().data || {
|
||||
total: 0,
|
||||
used: 0,
|
||||
remaining: 0,
|
||||
resetAt: new Date(),
|
||||
}
|
||||
|
||||
const usagePercentage = tokenUsage.total === 0 ? 0 : (tokenUsage.used / tokenUsage.total) * 100
|
||||
const resetDate = new Date(tokenUsage.resetAt)
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<SettingDescription>{t("token_usage.description")}</SettingDescription>
|
||||
|
||||
<div className="bg-material-medium border-border space-y-4 rounded-lg border p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<p className="text-text text-sm font-medium">
|
||||
{t("token_usage.tokens_used", {
|
||||
used: tokenUsage.used.toLocaleString(),
|
||||
total: tokenUsage.total.toLocaleString(),
|
||||
})}
|
||||
</p>
|
||||
<p className="text-text-secondary text-xs">
|
||||
{tokenUsage.remaining.toLocaleString()} {t("token_usage.tokens_remaining")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="text-right">
|
||||
<div className="text-text text-sm font-medium">{Math.round(usagePercentage)}%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Progress value={usagePercentage} className="h-2" />
|
||||
|
||||
<div className="text-text-tertiary flex items-center justify-between text-xs">
|
||||
<span>0</span>
|
||||
<span>
|
||||
{t("token_usage.resets_at")}: {resetDate.toLocaleString()}
|
||||
</span>
|
||||
<span>{tokenUsage.total.toLocaleString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 pt-2">
|
||||
<div className="bg-accent size-3 rounded-full" />
|
||||
<span className="text-text-secondary text-xs">Current usage</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
export { PanelStyleSection } from "./PanelStyleSection"
|
||||
export { PersonalizePromptSection } from "./PersonalizePromptSection"
|
||||
export { AIShortcutsSection } from "./shortcuts"
|
||||
export { TokenUsageSection } from "./TokenUsageSection"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
import { Progress } from "@follow/components/ui/progress/index.jsx"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@follow/components/ui/table/index.jsx"
|
||||
import { cn } from "@follow/utils/utils"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { pick } from "es-toolkit"
|
||||
import { useMemo } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
import { followClient } from "~/lib/api-client"
|
||||
|
||||
import { SettingDescription } from "../control"
|
||||
|
||||
const useTokenUsage = () => {
|
||||
return useQuery({
|
||||
queryKey: ["aiTokenUsage"],
|
||||
queryFn: async () => {
|
||||
const res = await followClient.api.ai.config()
|
||||
return pick(res, ["usage", "usageHistory"])
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Format large numbers with appropriate units
|
||||
const formatTokenCount = (count: number): { value: string; unit: string } => {
|
||||
if (count >= 1_000_000) {
|
||||
return { value: (count / 1_000_000).toFixed(1), unit: "M" }
|
||||
}
|
||||
if (count >= 1_000) {
|
||||
return { value: (count / 1_000).toFixed(1), unit: "K" }
|
||||
}
|
||||
return { value: count.toString(), unit: "" }
|
||||
}
|
||||
|
||||
// Format percentage for display
|
||||
const formatPercentage = (percentage: number): string => {
|
||||
return percentage < 1 && percentage > 0 ? "<1" : Math.round(percentage).toString()
|
||||
}
|
||||
|
||||
const TokenUsageSection = () => {
|
||||
const { t } = useTranslation("ai")
|
||||
|
||||
const { usage: tokenUsage, usageHistory } = useTokenUsage().data || {
|
||||
usage: {
|
||||
total: 0,
|
||||
used: 0,
|
||||
remaining: 0,
|
||||
resetAt: new Date(),
|
||||
},
|
||||
usageHistory: [],
|
||||
}
|
||||
|
||||
const usagePercentage = tokenUsage.total === 0 ? 0 : (tokenUsage.used / tokenUsage.total) * 100
|
||||
const resetDate = useMemo(() => new Date(tokenUsage.resetAt), [tokenUsage.resetAt])
|
||||
|
||||
const usedFormatted = useMemo(() => formatTokenCount(tokenUsage.used), [tokenUsage.used])
|
||||
const totalFormatted = useMemo(() => formatTokenCount(tokenUsage.total), [tokenUsage.total])
|
||||
const remainingFormatted = useMemo(
|
||||
() => formatTokenCount(tokenUsage.remaining),
|
||||
[tokenUsage.remaining],
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<SettingDescription>{t("token_usage.description")}</SettingDescription>
|
||||
|
||||
{/* Usage Overview */}
|
||||
<div className="space-y-6">
|
||||
{/* Main Usage Display */}
|
||||
<div className="rounded-lg border border-gray-200 bg-white p-6">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h3 className="text-lg font-medium text-gray-900">Token Usage</h3>
|
||||
<span className="font-mono text-2xl text-gray-900">
|
||||
{formatPercentage(usagePercentage)}%
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<Progress value={usagePercentage} className="h-2" />
|
||||
<div className="flex items-center justify-between text-sm text-gray-600">
|
||||
<span>
|
||||
{usedFormatted.value}
|
||||
{usedFormatted.unit} of {totalFormatted.value}
|
||||
{totalFormatted.unit} tokens used
|
||||
</span>
|
||||
<span>
|
||||
{remainingFormatted.value}
|
||||
{remainingFormatted.unit} remaining
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
<div className="grid gap-4 md:grid-cols-3">
|
||||
<div className="rounded-lg border border-gray-200 bg-white p-4">
|
||||
<div className="text-sm text-gray-600">Used</div>
|
||||
<div className="mt-1 font-mono text-xl text-gray-900">
|
||||
{usedFormatted.value}
|
||||
<span className="text-sm text-gray-500">{usedFormatted.unit}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-gray-200 bg-white p-4">
|
||||
<div className="text-sm text-gray-600">Total</div>
|
||||
<div className="mt-1 font-mono text-xl text-gray-900">
|
||||
{totalFormatted.value}
|
||||
<span className="text-sm text-gray-500">{totalFormatted.unit}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-gray-200 bg-white p-4">
|
||||
<div className="text-sm text-gray-600">Resets</div>
|
||||
<div className="mt-1 font-mono text-sm text-gray-900">
|
||||
{resetDate.toLocaleDateString([], {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: resetDate.getFullYear() !== new Date().getFullYear() ? "numeric" : undefined,
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Usage History */}
|
||||
{usageHistory && usageHistory.length > 0 && (
|
||||
<div className="rounded-lg border border-gray-200 bg-white">
|
||||
<div className="border-b border-gray-200 px-6 py-4">
|
||||
<h3 className="text-lg font-medium text-gray-900">Usage History</h3>
|
||||
<p className="mt-1 text-sm text-gray-600">Recent token usage activity</p>
|
||||
</div>
|
||||
|
||||
<div className="overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="border-gray-200 hover:bg-transparent">
|
||||
<TableHead className="text-gray-900">Change</TableHead>
|
||||
<TableHead className="text-gray-900">Description</TableHead>
|
||||
<TableHead className="text-right text-gray-900">Date</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{usageHistory.map((entry, index) => (
|
||||
<TableRow key={entry.id || index} className="border-gray-200 hover:bg-gray-50">
|
||||
<TableCell className="py-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className={cn(
|
||||
"flex size-6 items-center justify-center rounded text-xs font-medium",
|
||||
entry.changes > 0
|
||||
? "bg-green-100 text-green-700"
|
||||
: entry.changes < 0
|
||||
? "bg-red-100 text-red-700"
|
||||
: "bg-gray-100 text-gray-700",
|
||||
)}
|
||||
>
|
||||
{entry.changes > 0 ? "+" : entry.changes < 0 ? "−" : "="}
|
||||
</div>
|
||||
<span className="font-mono text-sm text-gray-900">
|
||||
{entry.changes > 0
|
||||
? `+${entry.changes.toLocaleString()}`
|
||||
: entry.changes.toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="py-3">
|
||||
<span className="text-sm text-gray-900">{entry.comment || ""}</span>
|
||||
</TableCell>
|
||||
<TableCell className="py-3 text-right">
|
||||
<span className="font-mono text-sm text-gray-600">
|
||||
{new Date(entry.createdAt).toLocaleDateString([], {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
})}
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const SettingTokenUsage = () => {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<TokenUsageSection />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { getFeature } from "~/hooks/biz/useFeature"
|
||||
import { SettingTokenUsage } from "~/modules/settings/tabs/token-usage"
|
||||
import { SettingsTitle } from "~/modules/settings/title"
|
||||
import { defineSettingPageData } from "~/modules/settings/utils"
|
||||
|
||||
const iconName = "i-mgc-rada-cute-re"
|
||||
const priority = (1000 << 1) + 16
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const loader = defineSettingPageData({
|
||||
icon: iconName,
|
||||
name: "titles.token_usage",
|
||||
priority,
|
||||
hideIf: () => !getFeature("ai"),
|
||||
})
|
||||
|
||||
export function Component() {
|
||||
return (
|
||||
<>
|
||||
<SettingsTitle />
|
||||
<SettingTokenUsage />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -669,6 +669,7 @@
|
|||
"titles.referral.short": "Invite & Earn",
|
||||
"titles.shortcuts": "Shortcuts",
|
||||
"titles.sign_out": "Sign Out",
|
||||
"titles.token_usage": "Token Usage",
|
||||
"wallet.balance.activePoints": "Active Points",
|
||||
"wallet.balance.dailyReward": "Your Daily Reward",
|
||||
"wallet.balance.title": "Your Balance",
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ settings:
|
|||
catalogs:
|
||||
default:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 0.3.46
|
||||
version: 0.3.46
|
||||
specifier: 0.3.47
|
||||
version: 0.3.47
|
||||
tailwindcss-uikit-colors:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
|
|
@ -465,7 +465,7 @@ importers:
|
|||
version: 3.0.2(electron@37.2.0)
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
version: 0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
'@follow/database':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/internal/database
|
||||
|
|
@ -1673,7 +1673,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
version: 0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
'@follow/configs':
|
||||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
|
@ -1685,7 +1685,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
version: 0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
'@follow/constants':
|
||||
specifier: workspace:*
|
||||
version: link:../constants
|
||||
|
|
@ -1757,7 +1757,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
version: 0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
'@follow/constants':
|
||||
specifier: workspace:*
|
||||
version: link:../constants
|
||||
|
|
@ -1821,7 +1821,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
version: 0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
'@follow/configs':
|
||||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
|
@ -4045,14 +4045,14 @@ packages:
|
|||
'@floating-ui/utils@0.2.10':
|
||||
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
||||
|
||||
'@follow-app/client-sdk@0.3.46':
|
||||
resolution: {integrity: sha512-mk1S3EuWt700E26o0S8OQBLvPqd4adIhQfpr8UKeFRbbaUH/qZGwrPboJ8solq62DKqK7p++H0BoMMnuAc3ctw==}
|
||||
'@follow-app/client-sdk@0.3.47':
|
||||
resolution: {integrity: sha512-RyQivFAJOnY5KEkpX5cJ2Z01Spq6sGOD8Btg2lIg4UWvE0gr8dBN8AcfFI7qyLXDg9FlSGZLUuDzEBkdGntVhg==}
|
||||
|
||||
'@folo-services/ai-tools@0.2.20':
|
||||
resolution: {integrity: sha512-1AJI48H2g64JhuTruSqQKUrn4Tc353hMFdKAbohh65AxTAMN/1pIw9w17Dtjm+g5BVlZUXYKaiIvaN9tHsXLNA==}
|
||||
|
||||
'@folo-services/constants@0.1.25':
|
||||
resolution: {integrity: sha512-qRAasMUOsNCIgKpQjtAoBWSm4EuibHJDRK7eWQAGgSb2KaMtMQ/VKiOraLHCNauML25/mkyqL2PIzKhflMCutA==}
|
||||
'@folo-services/constants@0.1.26':
|
||||
resolution: {integrity: sha512-Twk3LGC1G3KWMIr1usLnvq2CnojNtRFNs/xzZwtsHhgdXCG0waqm4dlZnnUEqwBsEyoTgxrZLq7mqUB//32VzA==}
|
||||
|
||||
'@folo-services/drizzle@0.1.13':
|
||||
resolution: {integrity: sha512-h6tndGnTLrAmfvxK5XsXGdZaMi2GBmFZBFiBqtabC7Y05A1ZSOaWg/d9f60Ydh586LmVonz5VGrhvzTdn5ukhg==}
|
||||
|
|
@ -18934,9 +18934,9 @@ snapshots:
|
|||
|
||||
'@floating-ui/utils@0.2.10': {}
|
||||
|
||||
'@follow-app/client-sdk@0.3.46(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)':
|
||||
'@follow-app/client-sdk@0.3.47(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.25
|
||||
'@folo-services/constants': 0.1.26
|
||||
'@folo-services/drizzle': 0.1.20(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)
|
||||
'@folo-services/exceptions': 0.1.15
|
||||
'@folo-services/shared': 0.0.15(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.1(@babel/core@7.28.0)(@types/react@19.1.8)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.2)(pg@8.16.3)
|
||||
|
|
@ -19012,7 +19012,7 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/constants@0.1.25':
|
||||
'@folo-services/constants@0.1.26':
|
||||
dependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ packages:
|
|||
|
||||
catalog:
|
||||
typescript: 5.8.3
|
||||
"@follow-app/client-sdk": 0.3.46
|
||||
"@follow-app/client-sdk": 0.3.47
|
||||
tailwindcss-uikit-colors: 1.0.0
|
||||
|
||||
onlyBuiltDependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue