@helloleo/plugins 0.2.0 → 0.2.2

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.
package/dist/index.js CHANGED
@@ -1,12 +1,16 @@
1
1
  // @bun
2
2
  var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
3
7
  var __export = (target, all) => {
4
8
  for (var name in all)
5
9
  __defProp(target, name, {
6
10
  get: all[name],
7
11
  enumerable: true,
8
12
  configurable: true,
9
- set: (newValue) => all[name] = () => newValue
13
+ set: __exportSetter.bind(all, name)
10
14
  });
11
15
  };
12
16
 
@@ -10741,7 +10745,7 @@ class JSONSchemaGenerator {
10741
10745
  if (val === undefined) {
10742
10746
  if (this.unrepresentable === "throw") {
10743
10747
  throw new Error("Literal `undefined` cannot be represented in JSON Schema");
10744
- } else {}
10748
+ }
10745
10749
  } else if (typeof val === "bigint") {
10746
10750
  if (this.unrepresentable === "throw") {
10747
10751
  throw new Error("BigInt literals cannot be represented in JSON Schema");
@@ -23286,7 +23290,7 @@ class JSONSchemaGenerator2 {
23286
23290
  if (val === undefined) {
23287
23291
  if (this.unrepresentable === "throw") {
23288
23292
  throw new Error("Literal `undefined` cannot be represented in JSON Schema");
23289
- } else {}
23293
+ }
23290
23294
  } else if (typeof val === "bigint") {
23291
23295
  if (this.unrepresentable === "throw") {
23292
23296
  throw new Error("BigInt literals cannot be represented in JSON Schema");
@@ -0,0 +1,47 @@
1
+ import { useState } from 'react'
2
+ import { useRouterState } from '@tanstack/react-router'
3
+ import { Button } from '@/components/ui/button'
4
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
5
+
6
+ // Rendered by the router's defaultErrorComponent for any uncaught render or
7
+ // loader error. Per-route `errorComponent` options override it. Keep this
8
+ // component free of app dependencies (toasts, auth, etc.) -- it must still
9
+ // render when the rest of the app is broken.
10
+ export function DefaultErrorComponent({ error }: { error: Error }) {
11
+ const pathname = useRouterState({ select: (s) => s.location.pathname })
12
+ const [copied, setCopied] = useState(false)
13
+
14
+ async function copyForLeo() {
15
+ // Blank lines + fenced stack so the report keeps its structure when
16
+ // pasted into a markdown-rendering chat.
17
+ const report = [
18
+ 'My app threw an error, please fix it:',
19
+ `Page: ${pathname}`,
20
+ `Error: ${error.message}`,
21
+ ['Stack:', '```', error.stack ?? '(no stack trace)', '```'].join('\n'),
22
+ ].join('\n\n')
23
+
24
+ await navigator.clipboard.writeText(report)
25
+ setCopied(true)
26
+ setTimeout(() => setCopied(false), 2000)
27
+ }
28
+
29
+ return (
30
+ <div className="min-h-screen flex items-center justify-center bg-background p-4">
31
+ <Card className="w-full max-w-lg">
32
+ <CardHeader>
33
+ <CardTitle>Something went wrong</CardTitle>
34
+ </CardHeader>
35
+ <CardContent className="space-y-4">
36
+ <pre className="text-sm text-destructive whitespace-pre-wrap break-words rounded-md bg-muted p-3">
37
+ {error.message}
38
+ </pre>
39
+ <Button onClick={copyForLeo}>{copied ? 'Copied!' : 'Copy error'}</Button>
40
+ <p className="text-sm text-muted-foreground">
41
+ Paste the copied error to Leo and it will help you fix it.
42
+ </p>
43
+ </CardContent>
44
+ </Card>
45
+ </div>
46
+ )
47
+ }
@@ -2,6 +2,7 @@ import { QueryClient } from '@tanstack/react-query'
2
2
  import { createRouter as createTanStackRouter } from '@tanstack/react-router'
3
3
  import { routerWithQueryClient } from '@tanstack/react-router-with-query'
4
4
  import { routeTree } from './routeTree.gen'
5
+ import { DefaultErrorComponent } from '@/components/error-component'
5
6
 
6
7
  // TanStack Start calls getRouter() on both server and client. routerWithQueryClient
7
8
  // wires the QueryClient into the router context and handles SSR dehydration /
@@ -15,6 +16,9 @@ export function getRouter() {
15
16
  routeTree,
16
17
  context: { queryClient },
17
18
  scrollRestoration: true,
19
+ // Catches uncaught render/loader errors on any route. Routes can still
20
+ // set their own `errorComponent` to override this.
21
+ defaultErrorComponent: DefaultErrorComponent,
18
22
  defaultPreload: 'intent',
19
23
  // With React Query we never want loader data to be stale -- the loader runs
20
24
  // on every preload/visit and React Query owns caching from there.
@@ -6,6 +6,7 @@ import {
6
6
  } from '@tanstack/react-router'
7
7
  import type { QueryClient } from '@tanstack/react-query'
8
8
  import type { ReactNode } from 'react'
9
+ import { Toaster } from '@/components/ui/sonner'
9
10
 
10
11
  // Side-effect order matters: Tailwind needs to be linked into the SSR'd
11
12
  // document. Importing the stylesheet as a URL and listing it in `head.links`
@@ -56,6 +57,7 @@ function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
56
57
  </head>
57
58
  <body>
58
59
  {children}
60
+ <Toaster richColors position="top-right" />
59
61
  <Scripts />
60
62
  </body>
61
63
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helloleo/plugins",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "OpenCode plugins for HelloLeo",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -0,0 +1,47 @@
1
+ import { useState } from 'react'
2
+ import { useRouterState } from '@tanstack/react-router'
3
+ import { Button } from '@/components/ui/button'
4
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
5
+
6
+ // Rendered by the router's defaultErrorComponent for any uncaught render or
7
+ // loader error. Per-route `errorComponent` options override it. Keep this
8
+ // component free of app dependencies (toasts, auth, etc.) -- it must still
9
+ // render when the rest of the app is broken.
10
+ export function DefaultErrorComponent({ error }: { error: Error }) {
11
+ const pathname = useRouterState({ select: (s) => s.location.pathname })
12
+ const [copied, setCopied] = useState(false)
13
+
14
+ async function copyForLeo() {
15
+ // Blank lines + fenced stack so the report keeps its structure when
16
+ // pasted into a markdown-rendering chat.
17
+ const report = [
18
+ 'My app threw an error, please fix it:',
19
+ `Page: ${pathname}`,
20
+ `Error: ${error.message}`,
21
+ ['Stack:', '```', error.stack ?? '(no stack trace)', '```'].join('\n'),
22
+ ].join('\n\n')
23
+
24
+ await navigator.clipboard.writeText(report)
25
+ setCopied(true)
26
+ setTimeout(() => setCopied(false), 2000)
27
+ }
28
+
29
+ return (
30
+ <div className="min-h-screen flex items-center justify-center bg-background p-4">
31
+ <Card className="w-full max-w-lg">
32
+ <CardHeader>
33
+ <CardTitle>Something went wrong</CardTitle>
34
+ </CardHeader>
35
+ <CardContent className="space-y-4">
36
+ <pre className="text-sm text-destructive whitespace-pre-wrap break-words rounded-md bg-muted p-3">
37
+ {error.message}
38
+ </pre>
39
+ <Button onClick={copyForLeo}>{copied ? 'Copied!' : 'Copy error'}</Button>
40
+ <p className="text-sm text-muted-foreground">
41
+ Paste the copied error to Leo and it will help you fix it.
42
+ </p>
43
+ </CardContent>
44
+ </Card>
45
+ </div>
46
+ )
47
+ }
@@ -2,6 +2,7 @@ import { QueryClient } from '@tanstack/react-query'
2
2
  import { createRouter as createTanStackRouter } from '@tanstack/react-router'
3
3
  import { routerWithQueryClient } from '@tanstack/react-router-with-query'
4
4
  import { routeTree } from './routeTree.gen'
5
+ import { DefaultErrorComponent } from '@/components/error-component'
5
6
 
6
7
  // TanStack Start calls getRouter() on both server and client. routerWithQueryClient
7
8
  // wires the QueryClient into the router context and handles SSR dehydration /
@@ -15,6 +16,9 @@ export function getRouter() {
15
16
  routeTree,
16
17
  context: { queryClient },
17
18
  scrollRestoration: true,
19
+ // Catches uncaught render/loader errors on any route. Routes can still
20
+ // set their own `errorComponent` to override this.
21
+ defaultErrorComponent: DefaultErrorComponent,
18
22
  defaultPreload: 'intent',
19
23
  // With React Query we never want loader data to be stale -- the loader runs
20
24
  // on every preload/visit and React Query owns caching from there.
@@ -6,6 +6,7 @@ import {
6
6
  } from '@tanstack/react-router'
7
7
  import type { QueryClient } from '@tanstack/react-query'
8
8
  import type { ReactNode } from 'react'
9
+ import { Toaster } from '@/components/ui/sonner'
9
10
 
10
11
  // Side-effect order matters: Tailwind needs to be linked into the SSR'd
11
12
  // document. Importing the stylesheet as a URL and listing it in `head.links`
@@ -56,6 +57,7 @@ function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
56
57
  </head>
57
58
  <body>
58
59
  {children}
60
+ <Toaster richColors position="top-right" />
59
61
  <Scripts />
60
62
  </body>
61
63
  </html>