@getjack/jack 0.1.28 → 0.1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/package.json +1 -1
  2. package/src/commands/cd.ts +163 -0
  3. package/src/commands/clone.ts +112 -68
  4. package/src/commands/domain.ts +506 -0
  5. package/src/commands/domains.ts +215 -0
  6. package/src/commands/down.ts +18 -12
  7. package/src/commands/hack.ts +185 -8
  8. package/src/commands/init.ts +52 -1
  9. package/src/commands/link.ts +25 -43
  10. package/src/commands/logs.ts +2 -2
  11. package/src/commands/mcp.ts +74 -3
  12. package/src/commands/new.ts +48 -54
  13. package/src/commands/projects.ts +53 -10
  14. package/src/commands/secrets.ts +5 -1
  15. package/src/commands/services.ts +16 -4
  16. package/src/commands/shell-init.ts +43 -0
  17. package/src/commands/ship.ts +2 -11
  18. package/src/commands/skills.ts +335 -0
  19. package/src/commands/update.ts +31 -0
  20. package/src/commands/upgrade.ts +14 -0
  21. package/src/index.ts +116 -24
  22. package/src/lib/agent-integration.ts +1 -2
  23. package/src/lib/agents.ts +2 -2
  24. package/src/lib/auth/login-flow.ts +1 -1
  25. package/src/lib/clone-core.ts +252 -0
  26. package/src/lib/config.ts +22 -0
  27. package/src/lib/control-plane.ts +31 -5
  28. package/src/lib/fuzzy.ts +93 -0
  29. package/src/lib/managed-deploy.ts +4 -1
  30. package/src/lib/managed-down.ts +20 -5
  31. package/src/lib/output.ts +90 -9
  32. package/src/lib/picker.ts +406 -0
  33. package/src/lib/project-detection.ts +5 -2
  34. package/src/lib/project-list.ts +66 -5
  35. package/src/lib/project-operations.ts +68 -6
  36. package/src/lib/prompts.ts +1 -1
  37. package/src/lib/services/db-execute.ts +8 -1
  38. package/src/lib/services/db-list.ts +4 -1
  39. package/src/lib/services/domain-operations.ts +379 -0
  40. package/src/lib/services/storage-config.ts +1 -5
  41. package/src/lib/services/storage-delete.ts +1 -1
  42. package/src/lib/services/storage-info.ts +2 -4
  43. package/src/lib/services/vectorize-config.ts +1 -5
  44. package/src/lib/services/vectorize-create.ts +3 -1
  45. package/src/lib/shell-integration.ts +202 -0
  46. package/src/lib/telemetry-config.ts +50 -4
  47. package/src/lib/telemetry.ts +71 -2
  48. package/src/lib/version-check.ts +1 -3
  49. package/src/lib/wrangler-config.test.ts +2 -2
  50. package/src/lib/wrangler-config.ts +1 -1
  51. package/src/lib/zip-packager.ts +1 -3
  52. package/src/mcp/tools/index.ts +261 -7
  53. package/src/templates/index.ts +10 -1
  54. package/templates/ai-chat/.jack.json +1 -5
  55. package/templates/ai-chat/public/chat.js +130 -130
  56. package/templates/ai-chat/src/index.ts +9 -13
  57. package/templates/ai-chat/src/jack-ai.ts +6 -2
  58. package/templates/saas/.jack.json +6 -1
  59. package/templates/saas/src/auth.ts +8 -4
  60. package/templates/saas/src/client/App.tsx +22 -7
  61. package/templates/saas/src/client/components/ProtectedRoute.tsx +9 -2
  62. package/templates/saas/src/client/components/ThemeToggle.tsx +1 -6
  63. package/templates/saas/src/client/components/ui/accordion.tsx +1 -1
  64. package/templates/saas/src/client/components/ui/alert-dialog.tsx +2 -2
  65. package/templates/saas/src/client/components/ui/alert.tsx +2 -2
  66. package/templates/saas/src/client/components/ui/avatar.tsx +1 -1
  67. package/templates/saas/src/client/components/ui/badge.tsx +2 -2
  68. package/templates/saas/src/client/components/ui/breadcrumb.tsx +1 -1
  69. package/templates/saas/src/client/components/ui/button-group.tsx +2 -2
  70. package/templates/saas/src/client/components/ui/button.tsx +2 -2
  71. package/templates/saas/src/client/components/ui/card.tsx +1 -1
  72. package/templates/saas/src/client/components/ui/carousel.tsx +2 -2
  73. package/templates/saas/src/client/components/ui/checkbox.tsx +1 -1
  74. package/templates/saas/src/client/components/ui/command.tsx +2 -2
  75. package/templates/saas/src/client/components/ui/context-menu.tsx +1 -1
  76. package/templates/saas/src/client/components/ui/dialog.tsx +1 -1
  77. package/templates/saas/src/client/components/ui/drawer.tsx +1 -1
  78. package/templates/saas/src/client/components/ui/dropdown-menu.tsx +1 -1
  79. package/templates/saas/src/client/components/ui/empty.tsx +1 -1
  80. package/templates/saas/src/client/components/ui/field.tsx +2 -2
  81. package/templates/saas/src/client/components/ui/form.tsx +5 -5
  82. package/templates/saas/src/client/components/ui/hover-card.tsx +1 -1
  83. package/templates/saas/src/client/components/ui/input-group.tsx +3 -3
  84. package/templates/saas/src/client/components/ui/input-otp.tsx +1 -1
  85. package/templates/saas/src/client/components/ui/input.tsx +1 -1
  86. package/templates/saas/src/client/components/ui/item.tsx +3 -3
  87. package/templates/saas/src/client/components/ui/label.tsx +1 -1
  88. package/templates/saas/src/client/components/ui/menubar.tsx +1 -1
  89. package/templates/saas/src/client/components/ui/navigation-menu.tsx +1 -1
  90. package/templates/saas/src/client/components/ui/pagination.tsx +2 -2
  91. package/templates/saas/src/client/components/ui/popover.tsx +1 -1
  92. package/templates/saas/src/client/components/ui/progress.tsx +1 -1
  93. package/templates/saas/src/client/components/ui/radio-group.tsx +1 -1
  94. package/templates/saas/src/client/components/ui/resizable.tsx +1 -1
  95. package/templates/saas/src/client/components/ui/scroll-area.tsx +1 -1
  96. package/templates/saas/src/client/components/ui/select.tsx +1 -1
  97. package/templates/saas/src/client/components/ui/separator.tsx +1 -1
  98. package/templates/saas/src/client/components/ui/sheet.tsx +1 -1
  99. package/templates/saas/src/client/components/ui/sidebar.tsx +4 -4
  100. package/templates/saas/src/client/components/ui/slider.tsx +1 -1
  101. package/templates/saas/src/client/components/ui/switch.tsx +1 -1
  102. package/templates/saas/src/client/components/ui/table.tsx +1 -1
  103. package/templates/saas/src/client/components/ui/tabs.tsx +1 -1
  104. package/templates/saas/src/client/components/ui/textarea.tsx +1 -1
  105. package/templates/saas/src/client/components/ui/toggle-group.tsx +3 -3
  106. package/templates/saas/src/client/components/ui/toggle.tsx +2 -2
  107. package/templates/saas/src/client/components/ui/tooltip.tsx +1 -1
  108. package/templates/saas/src/client/hooks/useSubscription.ts +5 -4
  109. package/templates/saas/src/client/lib/auth-client.ts +1 -1
  110. package/templates/saas/src/client/lib/plans.ts +1 -6
  111. package/templates/saas/src/client/lib/utils.ts +1 -1
  112. package/templates/saas/src/client/main.tsx +1 -1
  113. package/templates/saas/src/client/pages/DashboardPage.tsx +41 -9
  114. package/templates/saas/src/client/pages/ForgotPasswordPage.tsx +11 -2
  115. package/templates/saas/src/client/pages/HomePage.tsx +11 -2
  116. package/templates/saas/src/client/pages/LoginPage.tsx +11 -2
  117. package/templates/saas/src/client/pages/PricingPage.tsx +20 -10
  118. package/templates/saas/src/client/pages/ResetPasswordPage.tsx +14 -11
  119. package/templates/saas/src/client/pages/SignupPage.tsx +11 -2
  120. package/templates/saas/src/index.ts +28 -19
  121. package/templates/saas/vite.config.ts +1 -1
  122. package/templates/semantic-search/.jack.json +1 -5
  123. package/templates/semantic-search/src/index.ts +8 -4
  124. package/templates/semantic-search/src/jack-ai.ts +6 -2
  125. package/templates/semantic-search/src/jack-vectorize.ts +5 -1
@@ -1,9 +1,9 @@
1
+ import { type VariantProps, cva } from "class-variance-authority";
1
2
  import { useMemo } from "react";
2
- import { cva, type VariantProps } from "class-variance-authority";
3
3
 
4
- import { cn } from "@/lib/utils";
5
4
  import { Label } from "@/components/ui/label";
6
5
  import { Separator } from "@/components/ui/separator";
6
+ import { cn } from "@/lib/utils";
7
7
 
8
8
  function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
9
9
  return (
@@ -1,20 +1,20 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import type * as LabelPrimitive from "@radix-ui/react-label";
5
4
  import { Slot } from "@radix-ui/react-slot";
5
+ import * as React from "react";
6
6
  import {
7
7
  Controller,
8
- FormProvider,
9
- useFormContext,
10
- useFormState,
11
8
  type ControllerProps,
12
9
  type FieldPath,
13
10
  type FieldValues,
11
+ FormProvider,
12
+ useFormContext,
13
+ useFormState,
14
14
  } from "react-hook-form";
15
15
 
16
- import { cn } from "@/lib/utils";
17
16
  import { Label } from "@/components/ui/label";
17
+ import { cn } from "@/lib/utils";
18
18
 
19
19
  const Form = FormProvider;
20
20
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
- import { cva, type VariantProps } from "class-variance-authority";
3
+ import { type VariantProps, cva } from "class-variance-authority";
4
+ import type * as React from "react";
5
5
 
6
- import { cn } from "@/lib/utils";
7
6
  import { Button } from "@/components/ui/button";
8
7
  import { Input } from "@/components/ui/input";
9
8
  import { Textarea } from "@/components/ui/textarea";
9
+ import { cn } from "@/lib/utils";
10
10
 
11
11
  function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
12
12
  return (
@@ -1,6 +1,6 @@
1
- import * as React from "react";
2
1
  import { OTPInput, OTPInputContext } from "input-otp";
3
2
  import { MinusIcon } from "lucide-react";
3
+ import * as React from "react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import type * as React from "react";
2
2
 
3
3
  import { cn } from "@/lib/utils";
4
4
 
@@ -1,9 +1,9 @@
1
- import * as React from "react";
2
1
  import { Slot } from "@radix-ui/react-slot";
3
- import { cva, type VariantProps } from "class-variance-authority";
2
+ import { type VariantProps, cva } from "class-variance-authority";
3
+ import type * as React from "react";
4
4
 
5
- import { cn } from "@/lib/utils";
6
5
  import { Separator } from "@/components/ui/separator";
6
+ import { cn } from "@/lib/utils";
7
7
 
8
8
  function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
9
9
  return (
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as LabelPrimitive from "@radix-ui/react-label";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,6 +1,6 @@
1
- import * as React from "react";
2
1
  import * as MenubarPrimitive from "@radix-ui/react-menubar";
3
2
  import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
3
+ import type * as React from "react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
@@ -1,7 +1,7 @@
1
- import * as React from "react";
2
1
  import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
3
2
  import { cva } from "class-variance-authority";
4
3
  import { ChevronDownIcon } from "lucide-react";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,8 +1,8 @@
1
- import * as React from "react";
2
1
  import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
2
+ import type * as React from "react";
3
3
 
4
+ import { type Button, buttonVariants } from "@/components/ui/button";
4
5
  import { cn } from "@/lib/utils";
5
- import { buttonVariants, type Button } from "@/components/ui/button";
6
6
 
7
7
  function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
8
8
  return (
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as PopoverPrimitive from "@radix-ui/react-popover";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,5 +1,5 @@
1
- import * as React from "react";
2
1
  import * as ProgressPrimitive from "@radix-ui/react-progress";
2
+ import type * as React from "react";
3
3
 
4
4
  import { cn } from "@/lib/utils";
5
5
 
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
5
4
  import { CircleIcon } from "lucide-react";
5
+ import type * as React from "react";
6
6
 
7
7
  import { cn } from "@/lib/utils";
8
8
 
@@ -1,5 +1,5 @@
1
- import * as React from "react";
2
1
  import { GripVerticalIcon } from "lucide-react";
2
+ import type * as React from "react";
3
3
  import { Group, Panel, Separator } from "react-resizable-panels";
4
4
 
5
5
  import { cn } from "@/lib/utils";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,6 +1,6 @@
1
- import * as React from "react";
2
1
  import * as SelectPrimitive from "@radix-ui/react-select";
3
2
  import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
3
+ import type * as React from "react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as SeparatorPrimitive from "@radix-ui/react-separator";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,6 +1,6 @@
1
- import * as React from "react";
2
1
  import * as SheetPrimitive from "@radix-ui/react-dialog";
3
2
  import { XIcon } from "lucide-react";
3
+ import type * as React from "react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
@@ -1,12 +1,10 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import { Slot } from "@radix-ui/react-slot";
5
- import { cva, type VariantProps } from "class-variance-authority";
4
+ import { type VariantProps, cva } from "class-variance-authority";
6
5
  import { PanelLeftIcon } from "lucide-react";
6
+ import * as React from "react";
7
7
 
8
- import { useIsMobile } from "@/hooks/use-mobile";
9
- import { cn } from "@/lib/utils";
10
8
  import { Button } from "@/components/ui/button";
11
9
  import { Input } from "@/components/ui/input";
12
10
  import { Separator } from "@/components/ui/separator";
@@ -19,6 +17,8 @@ import {
19
17
  } from "@/components/ui/sheet";
20
18
  import { Skeleton } from "@/components/ui/skeleton";
21
19
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
20
+ import { useIsMobile } from "@/hooks/use-mobile";
21
+ import { cn } from "@/lib/utils";
22
22
 
23
23
  const SIDEBAR_COOKIE_NAME = "sidebar_state";
24
24
  const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as SliderPrimitive from "@radix-ui/react-slider";
4
+ import * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as SwitchPrimitive from "@radix-ui/react-switch";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import type * as React from "react";
2
2
 
3
3
  import { cn } from "@/lib/utils";
4
4
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as TabsPrimitive from "@radix-ui/react-tabs";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import type * as React from "react";
2
2
 
3
3
  import { cn } from "@/lib/utils";
4
4
 
@@ -1,9 +1,9 @@
1
- import * as React from "react";
2
1
  import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
3
- import { type VariantProps } from "class-variance-authority";
2
+ import type { VariantProps } from "class-variance-authority";
3
+ import * as React from "react";
4
4
 
5
- import { cn } from "@/lib/utils";
6
5
  import { toggleVariants } from "@/components/ui/toggle";
6
+ import { cn } from "@/lib/utils";
7
7
 
8
8
  const ToggleGroupContext = React.createContext<
9
9
  VariantProps<typeof toggleVariants> & {
@@ -1,6 +1,6 @@
1
- import * as React from "react";
2
1
  import * as TogglePrimitive from "@radix-ui/react-toggle";
3
- import { cva, type VariantProps } from "class-variance-authority";
2
+ import { type VariantProps, cva } from "class-variance-authority";
3
+ import type * as React from "react";
4
4
 
5
5
  import { cn } from "@/lib/utils";
6
6
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
- import * as React from "react";
4
3
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4
+ import type * as React from "react";
5
5
 
6
6
  import { cn } from "@/lib/utils";
7
7
 
@@ -1,4 +1,4 @@
1
- import { useState, useEffect } from "react";
1
+ import { useEffect, useState } from "react";
2
2
  import { authClient } from "../lib/auth-client";
3
3
 
4
4
  type Subscription = {
@@ -8,7 +8,7 @@ type Subscription = {
8
8
  stripeCustomerId?: string;
9
9
  stripeSubscriptionId?: string;
10
10
  cancelAtPeriodEnd?: boolean;
11
- cancelAt?: Date | string | null; // Better Auth uses this
11
+ cancelAt?: Date | string | null; // Better Auth uses this
12
12
  periodEnd?: Date | string | null;
13
13
  };
14
14
 
@@ -60,11 +60,12 @@ export function useSubscription() {
60
60
  const isCancelling =
61
61
  stripeStatus?.cancelAtPeriodEnd ||
62
62
  activeSubscription?.cancelAtPeriodEnd ||
63
- !!activeSubscription?.cancelAt || // Better Auth sets cancelAt date when cancelling
63
+ !!activeSubscription?.cancelAt || // Better Auth sets cancelAt date when cancelling
64
64
  false;
65
65
 
66
66
  // Get period end from either source
67
- const periodEnd = stripeStatus?.periodEnd ||
67
+ const periodEnd =
68
+ stripeStatus?.periodEnd ||
68
69
  (activeSubscription?.periodEnd ? String(activeSubscription.periodEnd) : null);
69
70
 
70
71
  return {
@@ -1,5 +1,5 @@
1
- import { createAuthClient } from "better-auth/react";
2
1
  import { stripeClient } from "@better-auth/stripe/client";
2
+ import { createAuthClient } from "better-auth/react";
3
3
 
4
4
  export const authClient = createAuthClient({
5
5
  baseURL: window.location.origin,
@@ -20,12 +20,7 @@ export const plans: PlanConfig[] = [
20
20
  price: "$0",
21
21
  priceMonthly: 0,
22
22
  description: "Perfect for getting started",
23
- features: [
24
- "Up to 100 users",
25
- "Basic analytics",
26
- "Community support",
27
- "1 project",
28
- ],
23
+ features: ["Up to 100 users", "Basic analytics", "Community support", "1 project"],
29
24
  },
30
25
  {
31
26
  id: "pro",
@@ -1,4 +1,4 @@
1
- import { clsx, type ClassValue } from "clsx";
1
+ import { type ClassValue, clsx } from "clsx";
2
2
  import { twMerge } from "tailwind-merge";
3
3
 
4
4
  export function cn(...inputs: ClassValue[]) {
@@ -1,6 +1,6 @@
1
+ import { ThemeProvider } from "next-themes";
1
2
  import { StrictMode } from "react";
2
3
  import { createRoot } from "react-dom/client";
3
- import { ThemeProvider } from "next-themes";
4
4
  import App from "./App";
5
5
  import { Toaster } from "./components/ui/sonner";
6
6
  import "./index.css";
@@ -1,18 +1,33 @@
1
1
  import { useEffect, useState } from "react";
2
+ import { ThemeToggle } from "../components/ThemeToggle";
3
+ import { Button } from "../components/ui/button";
4
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/ui/card";
2
5
  import { useAuth } from "../hooks/useAuth";
3
6
  import { useSubscription } from "../hooks/useSubscription";
4
- import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/ui/card";
5
- import { Button } from "../components/ui/button";
6
- import { ThemeToggle } from "../components/ThemeToggle";
7
7
  import { getPlanName } from "../lib/plans";
8
8
 
9
9
  interface DashboardPageProps {
10
- navigate: (route: "/" | "/login" | "/signup" | "/pricing" | "/dashboard" | "/forgot-password" | "/reset-password") => void;
10
+ navigate: (
11
+ route:
12
+ | "/"
13
+ | "/login"
14
+ | "/signup"
15
+ | "/pricing"
16
+ | "/dashboard"
17
+ | "/forgot-password"
18
+ | "/reset-password",
19
+ ) => void;
11
20
  }
12
21
 
13
22
  export default function DashboardPage({ navigate }: DashboardPageProps) {
14
23
  const { user, signOut } = useAuth();
15
- const { plan, isSubscribed, isCancelling, periodEnd, isLoading: isSubscriptionLoading } = useSubscription();
24
+ const {
25
+ plan,
26
+ isSubscribed,
27
+ isCancelling,
28
+ periodEnd,
29
+ isLoading: isSubscriptionLoading,
30
+ } = useSubscription();
16
31
  const [showUpgradeSuccess, setShowUpgradeSuccess] = useState(false);
17
32
 
18
33
  // Check for upgrade success
@@ -103,19 +118,33 @@ export default function DashboardPage({ navigate }: DashboardPageProps) {
103
118
  className="absolute top-4 right-4 text-white/80 hover:text-white"
104
119
  >
105
120
  <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
106
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
121
+ <path
122
+ strokeLinecap="round"
123
+ strokeLinejoin="round"
124
+ strokeWidth={2}
125
+ d="M6 18L18 6M6 6l12 12"
126
+ />
107
127
  </svg>
108
128
  </button>
109
129
  <div className="flex items-start gap-4">
110
130
  <div className="flex-shrink-0 w-12 h-12 bg-white/20 rounded-full flex items-center justify-center">
111
131
  <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
112
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
132
+ <path
133
+ strokeLinecap="round"
134
+ strokeLinejoin="round"
135
+ strokeWidth={2}
136
+ d="M5 13l4 4L19 7"
137
+ />
113
138
  </svg>
114
139
  </div>
115
140
  <div className="flex-1">
116
141
  <h2 className="text-xl font-bold mb-1">You're all set!</h2>
117
142
  <p className="text-white/90 mb-4">
118
- Your upgrade to <span className="font-semibold">{plan === "enterprise" ? "Enterprise" : "Pro"}</span> is complete. Here's what you just unlocked:
143
+ Your upgrade to{" "}
144
+ <span className="font-semibold">
145
+ {plan === "enterprise" ? "Enterprise" : "Pro"}
146
+ </span>{" "}
147
+ is complete. Here's what you just unlocked:
119
148
  </p>
120
149
  <div className="grid gap-2 sm:grid-cols-3 mb-4">
121
150
  <div className="bg-white/10 rounded-lg p-3">
@@ -184,7 +213,10 @@ export default function DashboardPage({ navigate }: DashboardPageProps) {
184
213
  </p>
185
214
  <p className="text-sm text-yellow-700 dark:text-yellow-300">
186
215
  You'll have access to {getPlanName(currentPlan)} features until{" "}
187
- {periodEnd ? new Date(periodEnd).toLocaleDateString() : "the end of your billing period"}.
216
+ {periodEnd
217
+ ? new Date(periodEnd).toLocaleDateString()
218
+ : "the end of your billing period"}
219
+ .
188
220
  </p>
189
221
  </div>
190
222
  <Button variant="outline" onClick={() => navigate("/pricing")}>
@@ -1,11 +1,20 @@
1
1
  import { useState } from "react";
2
- import { authClient } from "../lib/auth-client";
3
2
  import { toast } from "sonner";
4
3
  import { ThemeToggle } from "../components/ThemeToggle";
5
4
  import { Button } from "../components/ui/button";
5
+ import { authClient } from "../lib/auth-client";
6
6
 
7
7
  interface ForgotPasswordPageProps {
8
- navigate: (route: "/" | "/login" | "/signup" | "/pricing" | "/dashboard" | "/forgot-password" | "/reset-password") => void;
8
+ navigate: (
9
+ route:
10
+ | "/"
11
+ | "/login"
12
+ | "/signup"
13
+ | "/pricing"
14
+ | "/dashboard"
15
+ | "/forgot-password"
16
+ | "/reset-password",
17
+ ) => void;
9
18
  }
10
19
 
11
20
  export default function ForgotPasswordPage({ navigate }: ForgotPasswordPageProps) {
@@ -1,9 +1,18 @@
1
1
  import { useEffect, useState } from "react";
2
- import { authClient } from "../lib/auth-client";
3
2
  import { ThemeToggle } from "../components/ThemeToggle";
3
+ import { authClient } from "../lib/auth-client";
4
4
 
5
5
  interface HomePageProps {
6
- navigate: (route: "/" | "/login" | "/signup" | "/pricing" | "/dashboard" | "/forgot-password" | "/reset-password") => void;
6
+ navigate: (
7
+ route:
8
+ | "/"
9
+ | "/login"
10
+ | "/signup"
11
+ | "/pricing"
12
+ | "/dashboard"
13
+ | "/forgot-password"
14
+ | "/reset-password",
15
+ ) => void;
7
16
  }
8
17
 
9
18
  export default function HomePage({ navigate }: HomePageProps) {
@@ -1,9 +1,18 @@
1
1
  import { useState } from "react";
2
- import { authClient } from "../lib/auth-client";
3
2
  import { ThemeToggle } from "../components/ThemeToggle";
3
+ import { authClient } from "../lib/auth-client";
4
4
 
5
5
  interface LoginPageProps {
6
- navigate: (route: "/" | "/login" | "/signup" | "/pricing" | "/dashboard" | "/forgot-password" | "/reset-password") => void;
6
+ navigate: (
7
+ route:
8
+ | "/"
9
+ | "/login"
10
+ | "/signup"
11
+ | "/pricing"
12
+ | "/dashboard"
13
+ | "/forgot-password"
14
+ | "/reset-password",
15
+ ) => void;
7
16
  }
8
17
 
9
18
  export default function LoginPage({ navigate }: LoginPageProps) {
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useState } from "react";
2
- import { authClient } from "../lib/auth-client";
3
2
  import { toast } from "sonner";
3
+ import { ThemeToggle } from "../components/ThemeToggle";
4
+ import { Button } from "../components/ui/button";
4
5
  import {
5
6
  Card,
6
7
  CardContent,
@@ -9,12 +10,20 @@ import {
9
10
  CardHeader,
10
11
  CardTitle,
11
12
  } from "../components/ui/card";
12
- import { Button } from "../components/ui/button";
13
- import { ThemeToggle } from "../components/ThemeToggle";
14
- import { plans, getPlanName, isPaidPlan, type PlanId, type PlanConfig } from "../lib/plans";
13
+ import { authClient } from "../lib/auth-client";
14
+ import { type PlanConfig, type PlanId, getPlanName, isPaidPlan, plans } from "../lib/plans";
15
15
 
16
16
  interface PricingPageProps {
17
- navigate: (route: "/" | "/login" | "/signup" | "/pricing" | "/dashboard" | "/forgot-password" | "/reset-password") => void;
17
+ navigate: (
18
+ route:
19
+ | "/"
20
+ | "/login"
21
+ | "/signup"
22
+ | "/pricing"
23
+ | "/dashboard"
24
+ | "/forgot-password"
25
+ | "/reset-password",
26
+ ) => void;
18
27
  }
19
28
 
20
29
  export default function PricingPage({ navigate }: PricingPageProps) {
@@ -45,7 +54,7 @@ export default function PricingPage({ navigate }: PricingPageProps) {
45
54
  try {
46
55
  const subscription = await authClient.subscription.list();
47
56
  const activeSub = subscription?.data?.find(
48
- (s: { status: string }) => s.status === "active" || s.status === "trialing"
57
+ (s: { status: string }) => s.status === "active" || s.status === "trialing",
49
58
  );
50
59
  if (activeSub?.plan) {
51
60
  setCurrentPlan(activeSub.plan as PlanId);
@@ -283,7 +292,10 @@ export default function PricingPage({ navigate }: PricingPageProps) {
283
292
  <p className="text-sm text-yellow-800 dark:text-yellow-200">
284
293
  <strong>Your subscription is set to cancel.</strong> You'll have access to{" "}
285
294
  {getPlanName(currentPlan || "free")} features until{" "}
286
- {periodEnd ? new Date(periodEnd).toLocaleDateString() : "the end of your billing period"}.
295
+ {periodEnd
296
+ ? new Date(periodEnd).toLocaleDateString()
297
+ : "the end of your billing period"}
298
+ .
287
299
  </p>
288
300
  <Button variant="outline" size="sm" asChild className="shrink-0">
289
301
  <a href="/api/billing-portal">Manage in Stripe</a>
@@ -320,9 +332,7 @@ export default function PricingPage({ navigate }: PricingPageProps) {
320
332
  <CardTitle className="text-2xl">{plan.name}</CardTitle>
321
333
  <div className="mt-2">
322
334
  <span className="text-4xl font-bold">{plan.price}</span>
323
- {plan.id !== "free" && (
324
- <span className="text-muted-foreground">/month</span>
325
- )}
335
+ {plan.id !== "free" && <span className="text-muted-foreground">/month</span>}
326
336
  </div>
327
337
  <CardDescription className="mt-2">{plan.description}</CardDescription>
328
338
  </CardHeader>