thepopebot 1.2.42 → 1.2.43

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.
@@ -164,11 +164,8 @@ export async function markNotificationsRead() {
164
164
  */
165
165
  export async function getAppVersion() {
166
166
  await requireAuth();
167
- const { createRequire } = await import('module');
168
- const require = createRequire(import.meta.url);
169
- const version = require('../../../package.json').version;
170
- const { getUpdateAvailable } = await import('../cron.js');
171
- return { version, updateAvailable: getUpdateAvailable() };
167
+ const { getInstalledVersion, getUpdateAvailable } = await import('../cron.js');
168
+ return { version: getInstalledVersion(), updateAvailable: getUpdateAvailable() };
172
169
  }
173
170
 
174
171
  /**
@@ -5,6 +5,7 @@ import { MessageIcon, TrashIcon, MoreHorizontalIcon, StarIcon, StarFilledIcon, P
5
5
  import { SidebarMenuButton, SidebarMenuItem, useSidebar } from "./ui/sidebar.js";
6
6
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from "./ui/dropdown-menu.js";
7
7
  import { ConfirmDialog } from "./ui/confirm-dialog.js";
8
+ import { RenameDialog } from "./ui/rename-dialog.js";
8
9
  import { useChatNav } from "./chat-nav-context.js";
9
10
  import { cn } from "../utils.js";
10
11
  function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
@@ -13,9 +14,11 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
13
14
  const [hovered, setHovered] = useState(false);
14
15
  const [dropdownOpen, setDropdownOpen] = useState(false);
15
16
  const [confirmDelete, setConfirmDelete] = useState(false);
17
+ const [renameDialogOpen, setRenameDialogOpen] = useState(false);
16
18
  const [editing, setEditing] = useState(false);
17
19
  const [editTitle, setEditTitle] = useState(chat.title || "");
18
20
  const inputRef = useRef(null);
21
+ const clickTimer = useRef(null);
19
22
  const showMenu = hovered || dropdownOpen;
20
23
  useEffect(() => {
21
24
  if (editing && inputRef.current) {
@@ -23,6 +26,11 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
23
26
  inputRef.current.select();
24
27
  }
25
28
  }, [editing]);
29
+ useEffect(() => {
30
+ return () => {
31
+ if (clickTimer.current) clearTimeout(clickTimer.current);
32
+ };
33
+ }, []);
26
34
  const startRename = () => {
27
35
  setEditTitle(chat.title || "");
28
36
  setEditing(true);
@@ -69,8 +77,10 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
69
77
  className: "pr-8",
70
78
  isActive,
71
79
  onClick: () => {
72
- navigateToChat(chat.id);
73
- setOpenMobile(false);
80
+ clickTimer.current = setTimeout(() => {
81
+ navigateToChat(chat.id);
82
+ setOpenMobile(false);
83
+ }, 250);
74
84
  },
75
85
  children: [
76
86
  /* @__PURE__ */ jsx(MessageIcon, { size: 14 }),
@@ -81,6 +91,7 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
81
91
  onDoubleClick: (e) => {
82
92
  e.stopPropagation();
83
93
  e.preventDefault();
94
+ if (clickTimer.current) clearTimeout(clickTimer.current);
84
95
  startRename();
85
96
  },
86
97
  children: chat.title
@@ -124,7 +135,7 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
124
135
  {
125
136
  onClick: (e) => {
126
137
  e.stopPropagation();
127
- startRename();
138
+ setRenameDialogOpen(true);
128
139
  },
129
140
  children: [
130
141
  /* @__PURE__ */ jsx(PencilIcon, { size: 14 }),
@@ -165,6 +176,15 @@ function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename }) {
165
176
  },
166
177
  onCancel: () => setConfirmDelete(false)
167
178
  }
179
+ ),
180
+ /* @__PURE__ */ jsx(
181
+ RenameDialog,
182
+ {
183
+ open: renameDialogOpen,
184
+ currentValue: chat.title || "",
185
+ onSave: (newTitle) => onRename(chat.id, newTitle),
186
+ onCancel: () => setRenameDialogOpen(false)
187
+ }
168
188
  )
169
189
  ] });
170
190
  }
@@ -5,6 +5,7 @@ import { MessageIcon, TrashIcon, MoreHorizontalIcon, StarIcon, StarFilledIcon, P
5
5
  import { SidebarMenuButton, SidebarMenuItem, useSidebar } from './ui/sidebar.js';
6
6
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from './ui/dropdown-menu.js';
7
7
  import { ConfirmDialog } from './ui/confirm-dialog.js';
8
+ import { RenameDialog } from './ui/rename-dialog.js';
8
9
  import { useChatNav } from './chat-nav-context.js';
9
10
  import { cn } from '../utils.js';
10
11
 
@@ -14,9 +15,11 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
14
15
  const [hovered, setHovered] = useState(false);
15
16
  const [dropdownOpen, setDropdownOpen] = useState(false);
16
17
  const [confirmDelete, setConfirmDelete] = useState(false);
18
+ const [renameDialogOpen, setRenameDialogOpen] = useState(false);
17
19
  const [editing, setEditing] = useState(false);
18
20
  const [editTitle, setEditTitle] = useState(chat.title || '');
19
21
  const inputRef = useRef(null);
22
+ const clickTimer = useRef(null);
20
23
 
21
24
  const showMenu = hovered || dropdownOpen;
22
25
 
@@ -27,6 +30,12 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
27
30
  }
28
31
  }, [editing]);
29
32
 
33
+ useEffect(() => {
34
+ return () => {
35
+ if (clickTimer.current) clearTimeout(clickTimer.current);
36
+ };
37
+ }, []);
38
+
30
39
  const startRename = () => {
31
40
  setEditTitle(chat.title || '');
32
41
  setEditing(true);
@@ -73,8 +82,10 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
73
82
  className="pr-8"
74
83
  isActive={isActive}
75
84
  onClick={() => {
76
- navigateToChat(chat.id);
77
- setOpenMobile(false);
85
+ clickTimer.current = setTimeout(() => {
86
+ navigateToChat(chat.id);
87
+ setOpenMobile(false);
88
+ }, 250);
78
89
  }}
79
90
  >
80
91
  <MessageIcon size={14} />
@@ -83,6 +94,7 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
83
94
  onDoubleClick={(e) => {
84
95
  e.stopPropagation();
85
96
  e.preventDefault();
97
+ if (clickTimer.current) clearTimeout(clickTimer.current);
86
98
  startRename();
87
99
  }}
88
100
  >
@@ -122,7 +134,7 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
122
134
  <DropdownMenuItem
123
135
  onClick={(e) => {
124
136
  e.stopPropagation();
125
- startRename();
137
+ setRenameDialogOpen(true);
126
138
  }}
127
139
  >
128
140
  <PencilIcon size={14} />
@@ -155,6 +167,12 @@ export function SidebarHistoryItem({ chat, isActive, onDelete, onStar, onRename
155
167
  }}
156
168
  onCancel={() => setConfirmDelete(false)}
157
169
  />
170
+ <RenameDialog
171
+ open={renameDialogOpen}
172
+ currentValue={chat.title || ''}
173
+ onSave={(newTitle) => onRename(chat.id, newTitle)}
174
+ onCancel={() => setRenameDialogOpen(false)}
175
+ />
158
176
  </SidebarMenuItem>
159
177
  );
160
178
  }
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState, useEffect, useRef } from "react";
4
+ function RenameDialog({ open, onSave, onCancel, title = "Rename chat", currentValue = "" }) {
5
+ const [value, setValue] = useState(currentValue);
6
+ const inputRef = useRef(null);
7
+ useEffect(() => {
8
+ if (open) {
9
+ setValue(currentValue);
10
+ setTimeout(() => {
11
+ if (inputRef.current) {
12
+ inputRef.current.focus();
13
+ inputRef.current.select();
14
+ }
15
+ }, 0);
16
+ }
17
+ }, [open, currentValue]);
18
+ useEffect(() => {
19
+ if (!open) return;
20
+ const handleEsc = (e) => {
21
+ if (e.key === "Escape") onCancel();
22
+ };
23
+ document.addEventListener("keydown", handleEsc);
24
+ return () => document.removeEventListener("keydown", handleEsc);
25
+ }, [open, onCancel]);
26
+ const handleSave = () => {
27
+ const trimmed = value.trim();
28
+ if (trimmed && trimmed !== currentValue) {
29
+ onSave(trimmed);
30
+ }
31
+ onCancel();
32
+ };
33
+ if (!open) return null;
34
+ return /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
35
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 bg-black/50", onClick: onCancel }),
36
+ /* @__PURE__ */ jsxs("div", { className: "relative z-50 w-full max-w-sm rounded-lg border border-border bg-background p-6 shadow-lg", onClick: (e) => e.stopPropagation(), children: [
37
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: title }),
38
+ /* @__PURE__ */ jsx(
39
+ "input",
40
+ {
41
+ ref: inputRef,
42
+ type: "text",
43
+ value,
44
+ onChange: (e) => setValue(e.target.value),
45
+ onKeyDown: (e) => {
46
+ if (e.key === "Enter") handleSave();
47
+ },
48
+ className: "mt-3 w-full rounded-md border border-input bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
49
+ }
50
+ ),
51
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [
52
+ /* @__PURE__ */ jsx(
53
+ "button",
54
+ {
55
+ onClick: onCancel,
56
+ className: "rounded-md px-3 py-1.5 text-sm font-medium border border-input bg-background hover:bg-muted",
57
+ children: "Cancel"
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsx(
61
+ "button",
62
+ {
63
+ onClick: handleSave,
64
+ className: "rounded-md px-3 py-1.5 text-sm font-medium text-white bg-foreground hover:bg-foreground/90",
65
+ children: "Save"
66
+ }
67
+ )
68
+ ] })
69
+ ] })
70
+ ] });
71
+ }
72
+ export {
73
+ RenameDialog
74
+ };
@@ -0,0 +1,72 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect, useRef } from 'react';
4
+
5
+ export function RenameDialog({ open, onSave, onCancel, title = 'Rename chat', currentValue = '' }) {
6
+ const [value, setValue] = useState(currentValue);
7
+ const inputRef = useRef(null);
8
+
9
+ useEffect(() => {
10
+ if (open) {
11
+ setValue(currentValue);
12
+ setTimeout(() => {
13
+ if (inputRef.current) {
14
+ inputRef.current.focus();
15
+ inputRef.current.select();
16
+ }
17
+ }, 0);
18
+ }
19
+ }, [open, currentValue]);
20
+
21
+ useEffect(() => {
22
+ if (!open) return;
23
+ const handleEsc = (e) => {
24
+ if (e.key === 'Escape') onCancel();
25
+ };
26
+ document.addEventListener('keydown', handleEsc);
27
+ return () => document.removeEventListener('keydown', handleEsc);
28
+ }, [open, onCancel]);
29
+
30
+ const handleSave = () => {
31
+ const trimmed = value.trim();
32
+ if (trimmed && trimmed !== currentValue) {
33
+ onSave(trimmed);
34
+ }
35
+ onCancel();
36
+ };
37
+
38
+ if (!open) return null;
39
+
40
+ return (
41
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
42
+ <div className="fixed inset-0 bg-black/50" onClick={onCancel} />
43
+ <div className="relative z-50 w-full max-w-sm rounded-lg border border-border bg-background p-6 shadow-lg" onClick={(e) => e.stopPropagation()}>
44
+ <h3 className="text-lg font-semibold">{title}</h3>
45
+ <input
46
+ ref={inputRef}
47
+ type="text"
48
+ value={value}
49
+ onChange={(e) => setValue(e.target.value)}
50
+ onKeyDown={(e) => {
51
+ if (e.key === 'Enter') handleSave();
52
+ }}
53
+ className="mt-3 w-full rounded-md border border-input bg-background px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
54
+ />
55
+ <div className="mt-4 flex justify-end gap-2">
56
+ <button
57
+ onClick={onCancel}
58
+ className="rounded-md px-3 py-1.5 text-sm font-medium border border-input bg-background hover:bg-muted"
59
+ >
60
+ Cancel
61
+ </button>
62
+ <button
63
+ onClick={handleSave}
64
+ className="rounded-md px-3 py-1.5 text-sm font-medium text-white bg-foreground hover:bg-foreground/90"
65
+ >
66
+ Save
67
+ </button>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ );
72
+ }
package/lib/cron.js CHANGED
@@ -149,4 +149,4 @@ function loadCrons() {
149
149
  return tasks;
150
150
  }
151
151
 
152
- export { loadCrons, startBuiltinCrons, getUpdateAvailable, setUpdateAvailable };
152
+ export { loadCrons, startBuiltinCrons, getUpdateAvailable, setUpdateAvailable, getInstalledVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thepopebot",
3
- "version": "1.2.42",
3
+ "version": "1.2.43",
4
4
  "type": "module",
5
5
  "description": "Create autonomous AI agents with a two-layer architecture: Next.js Event Handler + Docker Agent.",
6
6
  "bin": {