spiracha 1.0.0 → 1.1.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.
- package/AGENTS.md +31 -1
- package/README.md +61 -7
- package/apps/ui/AGENTS.md +70 -0
- package/apps/ui/README.md +72 -0
- package/apps/ui/dist/client/assets/_threadId-CAIeH5mq.js +1 -0
- package/apps/ui/dist/client/assets/analytics-CqWZmyV6.js +1 -0
- package/apps/ui/dist/client/assets/checkbox-DXM4lkJq.js +1 -0
- package/apps/ui/dist/client/assets/data-table-DnPYMPCD.js +4 -0
- package/apps/ui/dist/client/assets/delete-confirm-dialog-CcZaRX33.js +11 -0
- package/apps/ui/dist/client/assets/download-DOwxk-cG.js +1 -0
- package/apps/ui/dist/client/assets/es2015-Bm0kEzx2.js +41 -0
- package/apps/ui/dist/client/assets/formatters-C12LmYaa.js +1 -0
- package/apps/ui/dist/client/assets/index-DdJ7ahIt.js +22 -0
- package/apps/ui/dist/client/assets/input-CEsI7EpI.js +1 -0
- package/apps/ui/dist/client/assets/metric-card-9jwBF7rG.js +1 -0
- package/apps/ui/dist/client/assets/page-header-Dr_h1CVv.js +1 -0
- package/apps/ui/dist/client/assets/projects._project-uyNGnpjH.js +1 -0
- package/apps/ui/dist/client/assets/projects._project-zoM8d2nH.js +1 -0
- package/apps/ui/dist/client/assets/projects.index-D1CWVN-O.js +1 -0
- package/apps/ui/dist/client/assets/projects.index-DukMuny6.js +1 -0
- package/apps/ui/dist/client/assets/routes-Gr2Wwh83.js +1 -0
- package/apps/ui/dist/client/assets/select-CFim44gT.js +1 -0
- package/apps/ui/dist/client/assets/settings-DqhyDxo2.js +1 -0
- package/apps/ui/dist/client/assets/styles-CMrP9Jb4.css +1 -0
- package/apps/ui/dist/client/assets/threads._threadId-DT75NiBa.js +1 -0
- package/apps/ui/dist/client/assets/threads._threadId-Df5VXIuZ.js +7 -0
- package/apps/ui/dist/client/favicon.ico +0 -0
- package/apps/ui/dist/client/logo192.png +0 -0
- package/apps/ui/dist/client/logo512.png +0 -0
- package/apps/ui/dist/client/manifest.json +25 -0
- package/apps/ui/dist/client/robots.txt +3 -0
- package/apps/ui/dist/server/assets/__23tanstack-start-plugin-adapters-BzCA6dXo.js +5 -0
- package/apps/ui/dist/server/assets/_tanstack-start-manifest_v-C0V305Nt.js +99 -0
- package/apps/ui/dist/server/assets/_threadId-B6SrBR9E.js +6 -0
- package/apps/ui/dist/server/assets/analytics-BMxW_bZL.js +139 -0
- package/apps/ui/dist/server/assets/button-CmTDnzOn.js +46 -0
- package/apps/ui/dist/server/assets/checkbox-C0hovF41.js +19 -0
- package/apps/ui/dist/server/assets/codex-queries-CAF6HYiG.js +109 -0
- package/apps/ui/dist/server/assets/codex-server-BFZq2Y2O.js +2062 -0
- package/apps/ui/dist/server/assets/data-table-Cdct823O.js +189 -0
- package/apps/ui/dist/server/assets/delete-confirm-dialog-CWqcTXTF.js +139 -0
- package/apps/ui/dist/server/assets/download-C5rkk_Bo.js +289 -0
- package/apps/ui/dist/server/assets/formatters-FJaGZgJk.js +91 -0
- package/apps/ui/dist/server/assets/input-B4tEzctc.js +46 -0
- package/apps/ui/dist/server/assets/loading-panel-DbLdvjtR.js +27 -0
- package/apps/ui/dist/server/assets/metric-card-ByEeLu0r.js +23 -0
- package/apps/ui/dist/server/assets/model-label-B1NWGc65.js +13 -0
- package/apps/ui/dist/server/assets/page-header-CxdZM86z.js +25 -0
- package/apps/ui/dist/server/assets/path-transforms-DL2IwtYd.js +31 -0
- package/apps/ui/dist/server/assets/projects._project-CJ7l0ynC.js +18 -0
- package/apps/ui/dist/server/assets/projects._project-CLSohrBp.js +26 -0
- package/apps/ui/dist/server/assets/projects._project-CcJLp_A8.js +337 -0
- package/apps/ui/dist/server/assets/projects.index-CaplpeMy.js +26 -0
- package/apps/ui/dist/server/assets/projects.index-srtogpuF.js +172 -0
- package/apps/ui/dist/server/assets/router-C_w-haH6.js +307 -0
- package/apps/ui/dist/server/assets/routes-BhbxvJE7.js +34 -0
- package/apps/ui/dist/server/assets/routes-CPe-ppmC.js +169 -0
- package/apps/ui/dist/server/assets/select-GW76p-ld.js +76 -0
- package/apps/ui/dist/server/assets/settings-MvWDgc1u.js +100 -0
- package/apps/ui/dist/server/assets/settings-store-DpEJEQ7M.js +52 -0
- package/apps/ui/dist/server/assets/sqlite-error-LZDrnxdd.js +13 -0
- package/apps/ui/dist/server/assets/start-HeKLHD9b.js +4 -0
- package/apps/ui/dist/server/assets/threads._threadId-BSSK4nkI.js +26 -0
- package/apps/ui/dist/server/assets/threads._threadId-Ba7vv6-K.js +18 -0
- package/apps/ui/dist/server/assets/threads._threadId-euyNckhj.js +1059 -0
- package/apps/ui/dist/server/assets/utils-C_uf36nf.js +8 -0
- package/apps/ui/dist/server/server.js +5678 -0
- package/package.json +53 -7
- package/src/export-chats.ts +4 -18
- package/src/lib/claude-exporter.ts +1 -1
- package/src/lib/codex-analytics.ts +100 -0
- package/src/lib/codex-browser-db.ts +605 -0
- package/src/lib/codex-browser-export.ts +429 -0
- package/src/lib/codex-browser-types.ts +224 -0
- package/src/lib/codex-exporter-cli.ts +6 -1
- package/src/lib/codex-exporter-db.ts +19 -20
- package/src/lib/codex-exporter-transcript.ts +158 -34
- package/src/lib/codex-exporter-types.ts +8 -0
- package/src/lib/codex-thread-cache.ts +58 -0
- package/src/lib/codex-thread-parser.ts +604 -0
- package/src/lib/interactive-cli.ts +10 -25
- package/src/lib/model-label.ts +24 -0
- package/src/lib/native-open.ts +54 -0
- package/src/lib/path-transforms.ts +46 -0
- package/src/lib/shared.ts +15 -1
- package/src/lib/sqlite-error.ts +14 -0
- package/src/lib/sqlite-retry.ts +53 -0
- package/src/lib/ui-cache.ts +96 -0
- package/src/lib/ui-export-files.ts +77 -0
- package/src/mcp-server.ts +1 -0
- package/src/spiracha.ts +16 -4
- package/src/ui-cli.ts +310 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { t as cn } from "./utils-C_uf36nf.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
4
|
+
import { Select } from "radix-ui";
|
|
5
|
+
//#region src/components/ui/select.tsx
|
|
6
|
+
function Select$1({ ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(Select.Root, {
|
|
8
|
+
"data-slot": "select",
|
|
9
|
+
...props
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function SelectValue({ ...props }) {
|
|
13
|
+
return /* @__PURE__ */ jsx(Select.Value, {
|
|
14
|
+
"data-slot": "select-value",
|
|
15
|
+
...props
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function SelectTrigger({ className, size = "default", children, ...props }) {
|
|
19
|
+
return /* @__PURE__ */ jsxs(Select.Trigger, {
|
|
20
|
+
"data-slot": "select-trigger",
|
|
21
|
+
"data-size": size,
|
|
22
|
+
className: cn("flex w-fit items-center justify-between gap-2 whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[size=default]:h-9 data-[size=sm]:h-8 data-[placeholder]:text-muted-foreground *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:hover:bg-input/50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0", className),
|
|
23
|
+
...props,
|
|
24
|
+
children: [children, /* @__PURE__ */ jsx(Select.Icon, {
|
|
25
|
+
asChild: true,
|
|
26
|
+
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" })
|
|
27
|
+
})]
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
|
|
31
|
+
return /* @__PURE__ */ jsx(Select.Portal, { children: /* @__PURE__ */ jsxs(Select.Content, {
|
|
32
|
+
"data-slot": "select-content",
|
|
33
|
+
className: cn("data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in", position === "popper" && "data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1", className),
|
|
34
|
+
position,
|
|
35
|
+
align,
|
|
36
|
+
...props,
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
39
|
+
/* @__PURE__ */ jsx(Select.Viewport, {
|
|
40
|
+
className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"),
|
|
41
|
+
children
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
44
|
+
]
|
|
45
|
+
}) });
|
|
46
|
+
}
|
|
47
|
+
function SelectItem({ className, children, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsxs(Select.Item, {
|
|
49
|
+
"data-slot": "select-item",
|
|
50
|
+
className: cn("relative flex w-full cursor-default select-none items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
|
|
51
|
+
...props,
|
|
52
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
53
|
+
"data-slot": "select-item-indicator",
|
|
54
|
+
className: "absolute right-2 flex size-3.5 items-center justify-center",
|
|
55
|
+
children: /* @__PURE__ */ jsx(Select.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
|
|
56
|
+
}), /* @__PURE__ */ jsx(Select.ItemText, { children })]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function SelectScrollUpButton({ className, ...props }) {
|
|
60
|
+
return /* @__PURE__ */ jsx(Select.ScrollUpButton, {
|
|
61
|
+
"data-slot": "select-scroll-up-button",
|
|
62
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
63
|
+
...props,
|
|
64
|
+
children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function SelectScrollDownButton({ className, ...props }) {
|
|
68
|
+
return /* @__PURE__ */ jsx(Select.ScrollDownButton, {
|
|
69
|
+
"data-slot": "select-scroll-down-button",
|
|
70
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
71
|
+
...props,
|
|
72
|
+
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { SelectValue as a, SelectTrigger as i, SelectContent as n, SelectItem as r, Select$1 as t };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { n as useSettings } from "./settings-store-DpEJEQ7M.js";
|
|
2
|
+
import { t as Checkbox } from "./checkbox-C0hovF41.js";
|
|
3
|
+
import { t as PageHeader } from "./page-header-CxdZM86z.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Settings2 } from "lucide-react";
|
|
6
|
+
//#region src/routes/settings.tsx?tsr-split=component
|
|
7
|
+
function SettingsPage() {
|
|
8
|
+
const { settings, updateSetting } = useSettings();
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
10
|
+
className: "space-y-6",
|
|
11
|
+
children: [/* @__PURE__ */ jsx(PageHeader, {
|
|
12
|
+
eyebrow: "Configuration",
|
|
13
|
+
subtitle: "Control how paths and usernames appear in transcript messages.",
|
|
14
|
+
title: "Settings"
|
|
15
|
+
}), /* @__PURE__ */ jsxs("section", {
|
|
16
|
+
className: "rounded-[1.6rem] border border-[var(--border)] bg-[var(--panel)] p-5 shadow-[var(--panel-shadow)]",
|
|
17
|
+
children: [/* @__PURE__ */ jsxs("h3", {
|
|
18
|
+
className: "flex items-center gap-2 font-semibold text-[var(--muted-foreground)] text-xs uppercase tracking-[0.18em]",
|
|
19
|
+
children: [/* @__PURE__ */ jsx(Settings2, { className: "size-3.5" }), "Privacy"]
|
|
20
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
21
|
+
className: "mt-5 space-y-5",
|
|
22
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
23
|
+
className: "flex items-center gap-3",
|
|
24
|
+
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
25
|
+
checked: settings.redactUsername,
|
|
26
|
+
id: "redact-username",
|
|
27
|
+
onCheckedChange: (checked) => updateSetting("redactUsername", checked === true)
|
|
28
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
29
|
+
className: "min-w-0",
|
|
30
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
31
|
+
className: "cursor-pointer font-medium text-sm leading-none",
|
|
32
|
+
htmlFor: "redact-username",
|
|
33
|
+
children: "Redact Username"
|
|
34
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
35
|
+
className: "mt-1.5 text-[var(--muted-foreground)] text-xs leading-5",
|
|
36
|
+
children: [
|
|
37
|
+
"Replaces",
|
|
38
|
+
" ",
|
|
39
|
+
/* @__PURE__ */ jsx("code", {
|
|
40
|
+
className: "rounded bg-[var(--code-background)] px-1 py-0.5 font-mono text-[var(--code-foreground)]",
|
|
41
|
+
children: "/Users/[username]/"
|
|
42
|
+
}),
|
|
43
|
+
" ",
|
|
44
|
+
"with",
|
|
45
|
+
" ",
|
|
46
|
+
/* @__PURE__ */ jsx("code", {
|
|
47
|
+
className: "rounded bg-[var(--code-background)] px-1 py-0.5 font-mono text-[var(--code-foreground)]",
|
|
48
|
+
children: "~/"
|
|
49
|
+
}),
|
|
50
|
+
" ",
|
|
51
|
+
"in all transcript messages."
|
|
52
|
+
]
|
|
53
|
+
})]
|
|
54
|
+
})]
|
|
55
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
56
|
+
className: "flex items-center gap-3",
|
|
57
|
+
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
58
|
+
checked: settings.convertToProjectRoot,
|
|
59
|
+
id: "convert-project-root",
|
|
60
|
+
onCheckedChange: (checked) => updateSetting("convertToProjectRoot", checked === true)
|
|
61
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
62
|
+
className: "min-w-0",
|
|
63
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
64
|
+
className: "cursor-pointer font-medium text-sm leading-none",
|
|
65
|
+
htmlFor: "convert-project-root",
|
|
66
|
+
children: "Convert Absolute Paths to Project Root"
|
|
67
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
68
|
+
className: "mt-1.5 text-[var(--muted-foreground)] text-xs leading-5",
|
|
69
|
+
children: [
|
|
70
|
+
"Converts the current thread or project cwd from",
|
|
71
|
+
" ",
|
|
72
|
+
/* @__PURE__ */ jsx("code", {
|
|
73
|
+
className: "rounded bg-[var(--code-background)] px-1 py-0.5 font-mono text-[var(--code-foreground)]",
|
|
74
|
+
children: "/Users/[username]/workspace/[projectname]/"
|
|
75
|
+
}),
|
|
76
|
+
" ",
|
|
77
|
+
"to project-root-relative paths, so",
|
|
78
|
+
" ",
|
|
79
|
+
/* @__PURE__ */ jsx("code", {
|
|
80
|
+
className: "rounded bg-[var(--code-background)] px-1 py-0.5 font-mono text-[var(--code-foreground)]",
|
|
81
|
+
children: "/Users/jane/workspace/myapp/src/index.ts"
|
|
82
|
+
}),
|
|
83
|
+
" ",
|
|
84
|
+
"appear as",
|
|
85
|
+
" ",
|
|
86
|
+
/* @__PURE__ */ jsx("code", {
|
|
87
|
+
className: "rounded bg-[var(--code-background)] px-1 py-0.5 font-mono text-[var(--code-foreground)]",
|
|
88
|
+
children: "src/index.ts"
|
|
89
|
+
}),
|
|
90
|
+
". If Redact Username is also enabled, remaining absolute paths outside the project root are redacted afterward."
|
|
91
|
+
]
|
|
92
|
+
})]
|
|
93
|
+
})]
|
|
94
|
+
})]
|
|
95
|
+
})]
|
|
96
|
+
})]
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { SettingsPage as component };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/lib/settings-store.tsx
|
|
4
|
+
var STORAGE_KEY = "spiracha-settings";
|
|
5
|
+
var defaultSettings = {
|
|
6
|
+
convertToProjectRoot: false,
|
|
7
|
+
redactUsername: false
|
|
8
|
+
};
|
|
9
|
+
var SettingsContext = createContext({
|
|
10
|
+
settings: defaultSettings,
|
|
11
|
+
updateSetting: () => {}
|
|
12
|
+
});
|
|
13
|
+
var loadSettings = () => {
|
|
14
|
+
if (typeof window === "undefined") return defaultSettings;
|
|
15
|
+
try {
|
|
16
|
+
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
17
|
+
return stored ? {
|
|
18
|
+
...defaultSettings,
|
|
19
|
+
...JSON.parse(stored)
|
|
20
|
+
} : defaultSettings;
|
|
21
|
+
} catch {
|
|
22
|
+
return defaultSettings;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function SettingsProvider({ children }) {
|
|
26
|
+
const [settings, setSettings] = useState(defaultSettings);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setSettings(loadSettings());
|
|
29
|
+
}, []);
|
|
30
|
+
const updateSetting = (key, value) => {
|
|
31
|
+
setSettings((prev) => {
|
|
32
|
+
const next = {
|
|
33
|
+
...prev,
|
|
34
|
+
[key]: value
|
|
35
|
+
};
|
|
36
|
+
try {
|
|
37
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
38
|
+
} catch {}
|
|
39
|
+
return next;
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
return /* @__PURE__ */ jsx(SettingsContext.Provider, {
|
|
43
|
+
value: {
|
|
44
|
+
settings,
|
|
45
|
+
updateSetting
|
|
46
|
+
},
|
|
47
|
+
children
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var useSettings = () => useContext(SettingsContext);
|
|
51
|
+
//#endregion
|
|
52
|
+
export { useSettings as n, SettingsProvider as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region ../../src/lib/sqlite-error.ts
|
|
2
|
+
var SQLITE_RETRYABLE_PATTERNS = [
|
|
3
|
+
/unable to open database file/iu,
|
|
4
|
+
/database is locked/iu,
|
|
5
|
+
/SQLITE_BUSY/iu,
|
|
6
|
+
/SQLITE_CANTOPEN/iu
|
|
7
|
+
];
|
|
8
|
+
var isRetryableSqliteError = (error) => {
|
|
9
|
+
if (!(error instanceof Error)) return false;
|
|
10
|
+
return SQLITE_RETRYABLE_PATTERNS.some((pattern) => pattern.test(error.message));
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { isRetryableSqliteError as t };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
//#region src/routes/threads.$threadId.tsx?tsr-split=errorComponent
|
|
3
|
+
function ThreadErrorComponent({ error }) {
|
|
4
|
+
const isSqlite = error.message.includes("unable to open database") || error.message.includes("database is locked");
|
|
5
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6
|
+
className: "rounded-xl border border-[var(--border)] bg-[var(--panel)] px-6 py-10 text-center",
|
|
7
|
+
children: [
|
|
8
|
+
/* @__PURE__ */ jsx("p", {
|
|
9
|
+
className: "font-medium text-[var(--destructive)] text-sm",
|
|
10
|
+
children: isSqlite ? "Database unavailable" : "Failed to load thread"
|
|
11
|
+
}),
|
|
12
|
+
/* @__PURE__ */ jsx("p", {
|
|
13
|
+
className: "mt-2 text-[var(--muted-foreground)] text-sm",
|
|
14
|
+
children: isSqlite ? "Codex may have an exclusive lock on the database. Reload to retry." : error.message
|
|
15
|
+
}),
|
|
16
|
+
/* @__PURE__ */ jsx("button", {
|
|
17
|
+
className: "mt-4 text-[var(--accent)] text-sm underline-offset-2 hover:underline",
|
|
18
|
+
type: "button",
|
|
19
|
+
onClick: () => window.location.reload(),
|
|
20
|
+
children: "Reload"
|
|
21
|
+
})
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ThreadErrorComponent as errorComponent };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { a as threadSnapshotQueryOptions } from "./codex-queries-CAF6HYiG.js";
|
|
2
|
+
import { t as LoadingPanel } from "./loading-panel-DbLdvjtR.js";
|
|
3
|
+
import { createFileRoute, lazyRouteComponent } from "@tanstack/react-router";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/routes/threads.$threadId.tsx
|
|
6
|
+
var $$splitErrorComponentImporter = () => import("./threads._threadId-BSSK4nkI.js");
|
|
7
|
+
var $$splitComponentImporter = () => import("./threads._threadId-euyNckhj.js");
|
|
8
|
+
var Route = createFileRoute("/threads/$threadId")({
|
|
9
|
+
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
10
|
+
errorComponent: lazyRouteComponent($$splitErrorComponentImporter, "errorComponent"),
|
|
11
|
+
loader: ({ context, params }) => context.queryClient.ensureQueryData(threadSnapshotQueryOptions(params.threadId)),
|
|
12
|
+
pendingComponent: () => /* @__PURE__ */ jsx(LoadingPanel, {
|
|
13
|
+
description: "Loading the transcript, metadata, and parsed event stream for this thread.",
|
|
14
|
+
title: "Loading thread"
|
|
15
|
+
})
|
|
16
|
+
});
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Route as t };
|