@adea-ai/ui 0.11.0 → 0.12.1

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 (90) hide show
  1. package/dist/components/account-drawer.d.ts +1 -1
  2. package/dist/components/account-drawer.js +12 -12
  3. package/dist/components/on-screen-controls.js +12 -12
  4. package/dist/components/scene-settings.d.ts +3 -3
  5. package/dist/components/scene-settings.js +11 -11
  6. package/dist/components/theme-provider.d.ts +1 -1
  7. package/dist/components/theme-provider.js +2 -2
  8. package/dist/components/theme-toggle.js +8 -8
  9. package/dist/components/ui/badge.d.ts +3 -3
  10. package/dist/components/ui/badge.js +15 -15
  11. package/dist/components/ui/button.d.ts +2 -2
  12. package/dist/components/ui/button.js +19 -19
  13. package/dist/components/ui/card.d.ts +1 -1
  14. package/dist/components/ui/card.js +3 -3
  15. package/dist/components/ui/dialog.d.ts +4 -4
  16. package/dist/components/ui/dialog.js +10 -10
  17. package/dist/components/ui/drawer.d.ts +5 -5
  18. package/dist/components/ui/drawer.js +26 -26
  19. package/dist/components/ui/dropdown-menu.d.ts +5 -5
  20. package/dist/components/ui/dropdown-menu.js +12 -12
  21. package/dist/components/ui/empty.d.ts +7 -7
  22. package/dist/components/ui/empty.js +11 -11
  23. package/dist/components/ui/field.d.ts +12 -12
  24. package/dist/components/ui/field.js +22 -22
  25. package/dist/components/ui/input.d.ts +2 -2
  26. package/dist/components/ui/input.js +3 -3
  27. package/dist/components/ui/label.d.ts +2 -2
  28. package/dist/components/ui/label.js +3 -3
  29. package/dist/components/ui/radio-group.d.ts +2 -2
  30. package/dist/components/ui/radio-group.js +6 -6
  31. package/dist/components/ui/separator.d.ts +1 -1
  32. package/dist/components/ui/separator.js +5 -5
  33. package/dist/components/ui/skeleton.d.ts +1 -1
  34. package/dist/components/ui/skeleton.js +2 -2
  35. package/dist/components/ui/spinner.d.ts +2 -2
  36. package/dist/components/ui/spinner.js +3 -3
  37. package/dist/components/ui/switch.d.ts +2 -2
  38. package/dist/components/ui/switch.js +5 -5
  39. package/dist/components/ui/tabs.d.ts +2 -2
  40. package/dist/components/ui/tabs.js +13 -13
  41. package/dist/components/ui/toggle-group.d.ts +6 -6
  42. package/dist/components/ui/toggle-group.js +13 -13
  43. package/dist/components/ui/toggle.d.ts +2 -2
  44. package/dist/components/ui/toggle.js +11 -11
  45. package/dist/components/ui/tooltip.d.ts +3 -3
  46. package/dist/components/ui/tooltip.js +5 -5
  47. package/dist/components/version-dialog.d.ts +1 -1
  48. package/dist/components/version-dialog.js +33 -33
  49. package/dist/components/workspace-brand.js +1 -1
  50. package/dist/components/workspace-logo.d.ts +1 -1
  51. package/dist/index.d.ts +19 -19
  52. package/dist/index.js +19 -19
  53. package/dist/lib/utils.d.ts +1 -1
  54. package/dist/lib/utils.js +2 -2
  55. package/dist/lib/version-notes.js +18 -18
  56. package/package.json +9 -9
  57. package/src/components/account-drawer.tsx +27 -27
  58. package/src/components/on-screen-controls.tsx +45 -45
  59. package/src/components/scene-settings.tsx +55 -55
  60. package/src/components/theme-provider.tsx +7 -7
  61. package/src/components/theme-toggle.tsx +20 -20
  62. package/src/components/ui/badge.tsx +20 -20
  63. package/src/components/ui/button.tsx +24 -24
  64. package/src/components/ui/card.tsx +6 -6
  65. package/src/components/ui/dialog.tsx +24 -24
  66. package/src/components/ui/drawer.tsx +55 -55
  67. package/src/components/ui/dropdown-menu.tsx +39 -39
  68. package/src/components/ui/empty.tsx +25 -25
  69. package/src/components/ui/field.tsx +55 -55
  70. package/src/components/ui/input.tsx +7 -7
  71. package/src/components/ui/label.tsx +7 -7
  72. package/src/components/ui/radio-group.tsx +9 -9
  73. package/src/components/ui/separator.tsx +7 -7
  74. package/src/components/ui/skeleton.tsx +5 -5
  75. package/src/components/ui/spinner.tsx +6 -6
  76. package/src/components/ui/switch.tsx +8 -8
  77. package/src/components/ui/tabs.tsx +21 -21
  78. package/src/components/ui/toggle-group.tsx +25 -25
  79. package/src/components/ui/toggle.tsx +15 -15
  80. package/src/components/ui/tooltip.tsx +13 -13
  81. package/src/components/version-dialog.tsx +113 -113
  82. package/src/components/workspace-brand.tsx +4 -4
  83. package/src/components/workspace-logo.tsx +2 -2
  84. package/src/index.tsx +19 -19
  85. package/src/lib/utils.ts +3 -3
  86. package/src/lib/version-notes.ts +23 -23
  87. package/src/styles/conventional-workspace.css +26 -26
  88. package/src/styles/globals.css +2 -2
  89. package/src/styles/theme.css +1 -1
  90. package/src/styles/workspace-shell.css +2 -2
@@ -1,6 +1,6 @@
1
- "use client";
1
+ 'use client'
2
2
 
3
- import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import { useCallback, useEffect, useMemo, useState } from 'react'
4
4
  import {
5
5
  Check,
6
6
  Download,
@@ -9,10 +9,10 @@ import {
9
9
  LoaderCircle,
10
10
  RefreshCw,
11
11
  Sparkles,
12
- } from "lucide-react";
12
+ } from 'lucide-react'
13
13
 
14
- import { formatReleaseDate, plainTextFromMarkdown } from "#lib/version-notes";
15
- import { Button } from "#components/ui/button";
14
+ import { formatReleaseDate, plainTextFromMarkdown } from '#lib/version-notes'
15
+ import { Button } from '#components/ui/button'
16
16
  import {
17
17
  Dialog,
18
18
  DialogClose,
@@ -22,165 +22,165 @@ import {
22
22
  DialogHeader,
23
23
  DialogTitle,
24
24
  DialogTrigger,
25
- } from "#components/ui/dialog";
25
+ } from '#components/ui/dialog'
26
26
 
27
27
  export type SharedDesktopUpdate = Readonly<{
28
- available_version: string | null;
29
- changelog: string;
30
- current_version: string;
31
- downloaded_bytes: number;
32
- error: string | null;
33
- github_url: string;
28
+ available_version: string | null
29
+ changelog: string
30
+ current_version: string
31
+ downloaded_bytes: number
32
+ error: string | null
33
+ github_url: string
34
34
  phase:
35
- | "idle"
36
- | "checking"
37
- | "current"
38
- | "available"
39
- | "downloading"
40
- | "installing"
41
- | "installed"
42
- | "failed";
43
- release_date: string | null;
44
- release_notes: string | null;
45
- restart_required: boolean;
46
- total_bytes: number | null;
47
- }>;
35
+ | 'idle'
36
+ | 'checking'
37
+ | 'current'
38
+ | 'available'
39
+ | 'downloading'
40
+ | 'installing'
41
+ | 'installed'
42
+ | 'failed'
43
+ release_date: string | null
44
+ release_notes: string | null
45
+ restart_required: boolean
46
+ total_bytes: number | null
47
+ }>
48
48
 
49
49
  export type VersionDialogAdapter = Readonly<{
50
- check(): Promise<SharedDesktopUpdate>;
51
- getStatus(): Promise<SharedDesktopUpdate>;
52
- install(expectedVersion: string): Promise<SharedDesktopUpdate>;
53
- isDesktopRuntime(): boolean;
54
- }>;
50
+ check(): Promise<SharedDesktopUpdate>
51
+ getStatus(): Promise<SharedDesktopUpdate>
52
+ install(expectedVersion: string): Promise<SharedDesktopUpdate>
53
+ isDesktopRuntime(): boolean
54
+ }>
55
55
 
56
56
  function errorMessage(caught: unknown, fallback: string): string {
57
- if (caught instanceof Error && caught.message) return caught.message;
58
- if (typeof caught === "string" && caught) return caught;
59
- return fallback;
57
+ if (caught instanceof Error && caught.message) return caught.message
58
+ if (typeof caught === 'string' && caught) return caught
59
+ return fallback
60
60
  }
61
61
 
62
62
  function phaseLabel(update: SharedDesktopUpdate | null, fallbackVersion: string): string {
63
- if (!update) return `Adea v${fallbackVersion}`;
64
- if (update.phase === "checking") return "Checking for updates…";
65
- if (update.phase === "available" && update.available_version) {
66
- return `Update v${update.available_version} available`;
63
+ if (!update) return `Adea v${fallbackVersion}`
64
+ if (update.phase === 'checking') return 'Checking for updates…'
65
+ if (update.phase === 'available' && update.available_version) {
66
+ return `Update v${update.available_version} available`
67
67
  }
68
- if (update.phase === "downloading" || update.phase === "installing") {
69
- return "Installing update…";
68
+ if (update.phase === 'downloading' || update.phase === 'installing') {
69
+ return 'Installing update…'
70
70
  }
71
- if (update.phase === "failed") return `Version ${update.current_version} · Retry`;
72
- return `Adea v${update.current_version || fallbackVersion}`;
71
+ if (update.phase === 'failed') return `Version ${update.current_version} · Retry`
72
+ return `Adea v${update.current_version || fallbackVersion}`
73
73
  }
74
74
 
75
75
  function isUpdateBusy(update: SharedDesktopUpdate | null): boolean {
76
76
  return (
77
- update?.phase === "checking" ||
78
- update?.phase === "downloading" ||
79
- update?.phase === "installing"
80
- );
77
+ update?.phase === 'checking' ||
78
+ update?.phase === 'downloading' ||
79
+ update?.phase === 'installing'
80
+ )
81
81
  }
82
82
 
83
83
  export function VersionDialog({
84
84
  adapter,
85
- fallbackVersion = "0.1.0",
85
+ fallbackVersion = '0.1.0',
86
86
  onOpenChange,
87
87
  open: controlledOpen,
88
88
  }: Readonly<{
89
- adapter: VersionDialogAdapter;
90
- fallbackVersion?: string;
91
- onOpenChange?: (open: boolean) => void;
92
- open?: boolean;
89
+ adapter: VersionDialogAdapter
90
+ fallbackVersion?: string
91
+ onOpenChange?: (open: boolean) => void
92
+ open?: boolean
93
93
  }>) {
94
- const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
95
- const open = controlledOpen ?? uncontrolledOpen;
94
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(false)
95
+ const open = controlledOpen ?? uncontrolledOpen
96
96
  const setOpen = useCallback(
97
97
  (nextOpen: boolean) => {
98
- if (controlledOpen === undefined) setUncontrolledOpen(nextOpen);
99
- onOpenChange?.(nextOpen);
98
+ if (controlledOpen === undefined) setUncontrolledOpen(nextOpen)
99
+ onOpenChange?.(nextOpen)
100
100
  },
101
101
  [controlledOpen, onOpenChange]
102
- );
103
- const [desktopRuntime, setDesktopRuntime] = useState(false);
104
- const [update, setUpdate] = useState<SharedDesktopUpdate | null>(null);
105
- const [busy, setBusy] = useState(false);
106
- const [error, setError] = useState("");
102
+ )
103
+ const [desktopRuntime, setDesktopRuntime] = useState(false)
104
+ const [update, setUpdate] = useState<SharedDesktopUpdate | null>(null)
105
+ const [busy, setBusy] = useState(false)
106
+ const [error, setError] = useState('')
107
107
 
108
- useEffect(() => setDesktopRuntime(adapter.isDesktopRuntime()), [adapter]);
108
+ useEffect(() => setDesktopRuntime(adapter.isDesktopRuntime()), [adapter])
109
109
 
110
110
  const loadCurrentStatus = useCallback(async () => {
111
- if (!desktopRuntime) return;
111
+ if (!desktopRuntime) return
112
112
  try {
113
- setUpdate(await adapter.getStatus());
113
+ setUpdate(await adapter.getStatus())
114
114
  } catch (caught) {
115
- setError(errorMessage(caught, "Version status is unavailable"));
115
+ setError(errorMessage(caught, 'Version status is unavailable'))
116
116
  }
117
- }, [adapter, desktopRuntime]);
117
+ }, [adapter, desktopRuntime])
118
118
 
119
119
  useEffect(() => {
120
- if (desktopRuntime) void loadCurrentStatus();
121
- }, [desktopRuntime, loadCurrentStatus]);
120
+ if (desktopRuntime) void loadCurrentStatus()
121
+ }, [desktopRuntime, loadCurrentStatus])
122
122
 
123
123
  const checkForUpdates = useCallback(async () => {
124
124
  if (!desktopRuntime) {
125
- setError("Update checks are available from the desktop app.");
126
- return;
125
+ setError('Update checks are available from the desktop app.')
126
+ return
127
127
  }
128
- setBusy(true);
129
- setError("");
128
+ setBusy(true)
129
+ setError('')
130
130
  try {
131
- setUpdate(await adapter.check());
131
+ setUpdate(await adapter.check())
132
132
  } catch (caught) {
133
- setError(errorMessage(caught, "Could not check for updates"));
134
- await loadCurrentStatus();
133
+ setError(errorMessage(caught, 'Could not check for updates'))
134
+ await loadCurrentStatus()
135
135
  } finally {
136
- setBusy(false);
136
+ setBusy(false)
137
137
  }
138
- }, [adapter, desktopRuntime, loadCurrentStatus]);
138
+ }, [adapter, desktopRuntime, loadCurrentStatus])
139
139
 
140
140
  useEffect(() => {
141
- if (!open || !desktopRuntime) return;
142
- let active = true;
143
- setError("");
144
- setBusy(true);
141
+ if (!open || !desktopRuntime) return
142
+ let active = true
143
+ setError('')
144
+ setBusy(true)
145
145
  void (async () => {
146
146
  try {
147
- const current = await adapter.getStatus();
148
- if (!active) return;
149
- setUpdate(current);
150
- const checked = await adapter.check();
151
- if (active) setUpdate(checked);
147
+ const current = await adapter.getStatus()
148
+ if (!active) return
149
+ setUpdate(current)
150
+ const checked = await adapter.check()
151
+ if (active) setUpdate(checked)
152
152
  } catch (caught) {
153
- if (active) setError(errorMessage(caught, "Could not check for updates"));
153
+ if (active) setError(errorMessage(caught, 'Could not check for updates'))
154
154
  } finally {
155
- if (active) setBusy(false);
155
+ if (active) setBusy(false)
156
156
  }
157
- })();
157
+ })()
158
158
  return () => {
159
- active = false;
160
- };
161
- }, [adapter, desktopRuntime, open]);
159
+ active = false
160
+ }
161
+ }, [adapter, desktopRuntime, open])
162
162
 
163
163
  const install = async () => {
164
- const version = update?.available_version;
165
- if (!version) return;
166
- setBusy(true);
167
- setError("");
164
+ const version = update?.available_version
165
+ if (!version) return
166
+ setBusy(true)
167
+ setError('')
168
168
  try {
169
- setUpdate(await adapter.install(version));
169
+ setUpdate(await adapter.install(version))
170
170
  } catch (caught) {
171
- setError(errorMessage(caught, "Update installation failed"));
172
- await loadCurrentStatus();
171
+ setError(errorMessage(caught, 'Update installation failed'))
172
+ await loadCurrentStatus()
173
173
  } finally {
174
- setBusy(false);
174
+ setBusy(false)
175
175
  }
176
- };
176
+ }
177
177
 
178
178
  const currentChangelog = useMemo(
179
- () => plainTextFromMarkdown(update?.changelog || "Changelog is loading…"),
179
+ () => plainTextFromMarkdown(update?.changelog || 'Changelog is loading…'),
180
180
  [update?.changelog]
181
- );
182
- const releaseNotes = update?.release_notes ? plainTextFromMarkdown(update.release_notes) : "";
183
- const busyFromSnapshot = isUpdateBusy(update);
181
+ )
182
+ const releaseNotes = update?.release_notes ? plainTextFromMarkdown(update.release_notes) : ''
183
+ const busyFromSnapshot = isUpdateBusy(update)
184
184
 
185
185
  return (
186
186
  <Dialog open={open} onOpenChange={setOpen}>
@@ -197,7 +197,7 @@ export function VersionDialog({
197
197
  />
198
198
  }
199
199
  >
200
- {update?.phase === "available" ? (
200
+ {update?.phase === 'available' ? (
201
201
  <Sparkles aria-hidden="true" />
202
202
  ) : (
203
203
  <FileText aria-hidden="true" />
@@ -232,13 +232,13 @@ export function VersionDialog({
232
232
  v{update?.current_version || fallbackVersion}
233
233
  </p>
234
234
  <p className="text-sm text-muted-foreground">
235
- {update?.phase === "current"
236
- ? "You are running the latest desktop release."
237
- : update?.phase === "available" && update.available_version
235
+ {update?.phase === 'current'
236
+ ? 'You are running the latest desktop release.'
237
+ : update?.phase === 'available' && update.available_version
238
238
  ? `A newer desktop release, v${update.available_version}, is ready.`
239
239
  : desktopRuntime
240
- ? "Check the release channel for the latest signed build."
241
- : "Open this dialog inside the desktop app to check for updates."}
240
+ ? 'Check the release channel for the latest signed build.'
241
+ : 'Open this dialog inside the desktop app to check for updates.'}
242
242
  </p>
243
243
  </div>
244
244
  <Button
@@ -258,7 +258,7 @@ export function VersionDialog({
258
258
  </div>
259
259
  </section>
260
260
 
261
- {update?.phase === "available" && update.available_version ? (
261
+ {update?.phase === 'available' && update.available_version ? (
262
262
  <section
263
263
  className="rounded-xl border border-primary/35 bg-primary/8 p-4"
264
264
  aria-label="Available update"
@@ -295,7 +295,7 @@ export function VersionDialog({
295
295
  </section>
296
296
  ) : null}
297
297
 
298
- {update?.phase === "current" ? (
298
+ {update?.phase === 'current' ? (
299
299
  <p
300
300
  className="flex items-center gap-2 text-sm text-emerald-700 dark:text-emerald-300"
301
301
  role="status"
@@ -350,7 +350,7 @@ export function VersionDialog({
350
350
  type="button"
351
351
  variant="ghost"
352
352
  size="sm"
353
- onClick={() => window.open(update.github_url, "_blank", "noopener,noreferrer")}
353
+ onClick={() => window.open(update.github_url, '_blank', 'noopener,noreferrer')}
354
354
  >
355
355
  <ExternalLink aria-hidden="true" />
356
356
  View releases
@@ -362,5 +362,5 @@ export function VersionDialog({
362
362
  </DialogFooter>
363
363
  </DialogContent>
364
364
  </Dialog>
365
- );
365
+ )
366
366
  }
@@ -1,9 +1,9 @@
1
1
  export interface WorkspaceBrandProps {
2
- title: string;
3
- eyebrow?: string;
2
+ title: string
3
+ eyebrow?: string
4
4
  }
5
5
 
6
- export function WorkspaceBrand({ title, eyebrow = "AGENT OPERATIONS" }: WorkspaceBrandProps) {
6
+ export function WorkspaceBrand({ title, eyebrow = 'AGENT OPERATIONS' }: WorkspaceBrandProps) {
7
7
  return (
8
8
  <div className="workspace-brand">
9
9
  <div className="workspace-brand__mark" aria-hidden="true">
@@ -14,5 +14,5 @@ export function WorkspaceBrand({ title, eyebrow = "AGENT OPERATIONS" }: Workspac
14
14
  <h1>{title}</h1>
15
15
  </div>
16
16
  </div>
17
- );
17
+ )
18
18
  }
@@ -1,4 +1,4 @@
1
- import type { SVGProps } from "react";
1
+ import type { SVGProps } from 'react'
2
2
 
3
3
  /** The canonical Adea mark used by web, desktop, and dialogs. */
4
4
  export function WorkspaceLogo(props: SVGProps<SVGSVGElement>) {
@@ -13,5 +13,5 @@ export function WorkspaceLogo(props: SVGProps<SVGSVGElement>) {
13
13
  />
14
14
  <path d="m45 35 11 11-4 4-11-11z" fill="#f8fafc" />
15
15
  </svg>
16
- );
16
+ )
17
17
  }
package/src/index.tsx CHANGED
@@ -1,10 +1,10 @@
1
- export { Button, buttonVariants } from "./components/ui/button";
2
- export { Switch } from "./components/ui/switch";
3
- export { Toggle } from "./components/ui/toggle";
4
- export { ToggleGroup, ToggleGroupItem } from "./components/ui/toggle-group";
5
- export { RadioGroup, RadioGroupItem } from "./components/ui/radio-group";
6
- export { ThemeToggle } from "./components/theme-toggle";
7
- export { ThemeProvider } from "./components/theme-provider";
1
+ export { Button, buttonVariants } from './components/ui/button'
2
+ export { Switch } from './components/ui/switch'
3
+ export { Toggle } from './components/ui/toggle'
4
+ export { ToggleGroup, ToggleGroupItem } from './components/ui/toggle-group'
5
+ export { RadioGroup, RadioGroupItem } from './components/ui/radio-group'
6
+ export { ThemeToggle } from './components/theme-toggle'
7
+ export { ThemeProvider } from './components/theme-provider'
8
8
  export {
9
9
  Drawer,
10
10
  DrawerClose,
@@ -17,20 +17,20 @@ export {
17
17
  DrawerSwipeHandle,
18
18
  DrawerTitle,
19
19
  DrawerTrigger,
20
- } from "./components/ui/drawer";
21
- export { AccountDrawer, type AccountDrawerProps } from "./components/account-drawer";
22
- export { WorkspaceBrand, type WorkspaceBrandProps } from "./components/workspace-brand";
23
- export { WorkspaceLogo } from "./components/workspace-logo";
24
- export { OnScreenControls } from "./components/on-screen-controls";
25
- export { SceneSettings, type SceneSettingsProps } from "./components/scene-settings";
20
+ } from './components/ui/drawer'
21
+ export { AccountDrawer, type AccountDrawerProps } from './components/account-drawer'
22
+ export { WorkspaceBrand, type WorkspaceBrandProps } from './components/workspace-brand'
23
+ export { WorkspaceLogo } from './components/workspace-logo'
24
+ export { OnScreenControls } from './components/on-screen-controls'
25
+ export { SceneSettings, type SceneSettingsProps } from './components/scene-settings'
26
26
  export {
27
27
  VersionDialog,
28
28
  type SharedDesktopUpdate,
29
29
  type VersionDialogAdapter,
30
- } from "./components/version-dialog";
31
- export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./components/ui/tooltip";
32
- export { Card, CardContent } from "./components/ui/card";
33
- export { Spinner } from "./components/ui/spinner";
30
+ } from './components/version-dialog'
31
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './components/ui/tooltip'
32
+ export { Card, CardContent } from './components/ui/card'
33
+ export { Spinner } from './components/ui/spinner'
34
34
  export {
35
35
  Dialog,
36
36
  DialogClose,
@@ -42,5 +42,5 @@ export {
42
42
  DialogPortal,
43
43
  DialogTitle,
44
44
  DialogTrigger,
45
- } from "./components/ui/dialog";
46
- export { cn } from "./lib/utils";
45
+ } from './components/ui/dialog'
46
+ export { cn } from './lib/utils'
package/src/lib/utils.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { clsx, type ClassValue } from "clsx";
2
- import { twMerge } from "tailwind-merge";
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
3
 
4
4
  export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs));
5
+ return twMerge(clsx(inputs))
6
6
  }
@@ -1,30 +1,30 @@
1
1
  export function plainTextFromMarkdown(markdown: string): string {
2
2
  return markdown
3
- .replace(/\r\n/g, "\n")
4
- .replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1")
5
- .replace(/\[([^\]]+)\]\([^)]*\)/g, "$1")
6
- .replace(/^[ \t]*#{1,6}[ \t]*/gm, "")
7
- .replace(/^[ \t]*>[ \t]?/gm, "")
8
- .replace(/^[ \t]*---+[ \t]*$/gm, "")
9
- .replace(/^[ \t]*[-*+][ \t]+/gm, "• ")
10
- .replace(/^[ \t]*\d+\.[ \t]+/gm, "")
11
- .replace(/```[^\n]*\n?/g, "")
12
- .replace(/`([^`]+)`/g, "$1")
13
- .replace(/\*\*([^*]+)\*\*/g, "$1")
14
- .replace(/__([^_]+)__/g, "$1")
15
- .replace(/\*([^*]+)\*/g, "$1")
16
- .replace(/_([^_]+)_/g, "$1")
17
- .replace(/\n{3,}/g, "\n\n")
18
- .trim();
3
+ .replace(/\r\n/g, '\n')
4
+ .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
5
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
6
+ .replace(/^[ \t]*#{1,6}[ \t]*/gm, '')
7
+ .replace(/^[ \t]*>[ \t]?/gm, '')
8
+ .replace(/^[ \t]*---+[ \t]*$/gm, '')
9
+ .replace(/^[ \t]*[-*+][ \t]+/gm, '• ')
10
+ .replace(/^[ \t]*\d+\.[ \t]+/gm, '')
11
+ .replace(/```[^\n]*\n?/g, '')
12
+ .replace(/`([^`]+)`/g, '$1')
13
+ .replace(/\*\*([^*]+)\*\*/g, '$1')
14
+ .replace(/__([^_]+)__/g, '$1')
15
+ .replace(/\*([^*]+)\*/g, '$1')
16
+ .replace(/_([^_]+)_/g, '$1')
17
+ .replace(/\n{3,}/g, '\n\n')
18
+ .trim()
19
19
  }
20
20
 
21
21
  export function formatReleaseDate(value: string | null): string | null {
22
- if (!value) return null;
23
- const date = new Date(value);
24
- if (Number.isNaN(date.getTime())) return value;
22
+ if (!value) return null
23
+ const date = new Date(value)
24
+ if (Number.isNaN(date.getTime())) return value
25
25
  return new Intl.DateTimeFormat(undefined, {
26
- day: "numeric",
27
- month: "short",
28
- year: "numeric",
29
- }).format(date);
26
+ day: 'numeric',
27
+ month: 'short',
28
+ year: 'numeric',
29
+ }).format(date)
30
30
  }