palmier 0.9.5 → 0.9.7

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 (258) hide show
  1. package/README.md +30 -13
  2. package/dist/agents/agent.d.ts +0 -1
  3. package/dist/agents/agent.js +0 -1
  4. package/dist/agents/aider.d.ts +0 -1
  5. package/dist/agents/aider.js +0 -1
  6. package/dist/agents/claude.d.ts +0 -1
  7. package/dist/agents/claude.js +0 -1
  8. package/dist/agents/cline.d.ts +0 -1
  9. package/dist/agents/cline.js +0 -1
  10. package/dist/agents/codex.d.ts +0 -1
  11. package/dist/agents/codex.js +0 -1
  12. package/dist/agents/copilot.d.ts +0 -1
  13. package/dist/agents/copilot.js +0 -1
  14. package/dist/agents/cursor.d.ts +0 -1
  15. package/dist/agents/cursor.js +0 -1
  16. package/dist/agents/deepagents.d.ts +0 -1
  17. package/dist/agents/deepagents.js +0 -1
  18. package/dist/agents/droid.d.ts +0 -1
  19. package/dist/agents/droid.js +0 -1
  20. package/dist/agents/gemini.d.ts +0 -1
  21. package/dist/agents/gemini.js +0 -1
  22. package/dist/agents/goose.d.ts +0 -1
  23. package/dist/agents/goose.js +0 -1
  24. package/dist/agents/hermes.d.ts +0 -1
  25. package/dist/agents/hermes.js +0 -1
  26. package/dist/agents/kimi.d.ts +0 -1
  27. package/dist/agents/kimi.js +0 -1
  28. package/dist/agents/kiro.d.ts +0 -1
  29. package/dist/agents/kiro.js +0 -1
  30. package/dist/agents/openclaw.d.ts +0 -1
  31. package/dist/agents/openclaw.js +0 -1
  32. package/dist/agents/opencode.d.ts +0 -1
  33. package/dist/agents/opencode.js +0 -1
  34. package/dist/agents/qoder.d.ts +0 -1
  35. package/dist/agents/qoder.js +0 -1
  36. package/dist/agents/qwen.d.ts +0 -1
  37. package/dist/agents/qwen.js +0 -1
  38. package/dist/agents/shared-prompt.d.ts +0 -1
  39. package/dist/agents/shared-prompt.js +0 -1
  40. package/dist/client-store.d.ts +0 -1
  41. package/dist/client-store.js +0 -1
  42. package/dist/commands/clients.d.ts +0 -1
  43. package/dist/commands/clients.js +0 -1
  44. package/dist/commands/info.d.ts +0 -1
  45. package/dist/commands/info.js +0 -1
  46. package/dist/commands/init.d.ts +0 -1
  47. package/dist/commands/init.js +3 -4
  48. package/dist/commands/pair.d.ts +0 -1
  49. package/dist/commands/pair.js +0 -1
  50. package/dist/commands/restart.d.ts +0 -1
  51. package/dist/commands/restart.js +0 -1
  52. package/dist/commands/run.d.ts +0 -1
  53. package/dist/commands/run.js +0 -1
  54. package/dist/commands/serve.d.ts +0 -1
  55. package/dist/commands/serve.js +0 -1
  56. package/dist/commands/uninstall.d.ts +0 -1
  57. package/dist/commands/uninstall.js +0 -1
  58. package/dist/config.d.ts +0 -1
  59. package/dist/config.js +0 -1
  60. package/dist/event-queues.d.ts +0 -1
  61. package/dist/event-queues.js +0 -1
  62. package/dist/events.d.ts +0 -1
  63. package/dist/events.js +0 -1
  64. package/dist/index.d.ts +0 -1
  65. package/dist/index.js +0 -1
  66. package/dist/linked-device.d.ts +0 -1
  67. package/dist/linked-device.js +0 -1
  68. package/dist/mcp-handler.d.ts +0 -1
  69. package/dist/mcp-handler.js +0 -1
  70. package/dist/mcp-tools.d.ts +0 -1
  71. package/dist/mcp-tools.js +0 -1
  72. package/dist/nats-client.d.ts +0 -1
  73. package/dist/nats-client.js +0 -1
  74. package/dist/network.d.ts +0 -1
  75. package/dist/network.js +0 -1
  76. package/dist/notification-store.d.ts +0 -1
  77. package/dist/notification-store.js +0 -1
  78. package/dist/pending-requests.d.ts +0 -1
  79. package/dist/pending-requests.js +0 -1
  80. package/dist/platform/index.d.ts +0 -1
  81. package/dist/platform/index.js +0 -1
  82. package/dist/platform/linux.d.ts +0 -1
  83. package/dist/platform/linux.js +0 -1
  84. package/dist/platform/macos.d.ts +0 -1
  85. package/dist/platform/macos.js +0 -1
  86. package/dist/platform/platform.d.ts +0 -1
  87. package/dist/platform/platform.js +0 -1
  88. package/dist/platform/windows.d.ts +0 -1
  89. package/dist/platform/windows.js +0 -1
  90. package/dist/pwa/apple-touch-icon.png +0 -0
  91. package/dist/pwa/assets/index-D1bIhEbd.css +1 -0
  92. package/dist/pwa/assets/{index-Cvffaohh.js → index-DWvRAUiy.js} +31 -31
  93. package/dist/pwa/assets/{web-qdLcAD7T.js → web-C4iZbqTC.js} +1 -1
  94. package/dist/pwa/assets/{web-ChtbM4nv.js → web-CBFqJGX6.js} +1 -1
  95. package/dist/pwa/assets/{web-hExASsqW.js → web-DL4uXOpS.js} +1 -1
  96. package/dist/pwa/favicon.ico +0 -0
  97. package/dist/pwa/index.html +3 -3
  98. package/dist/pwa/manifest.webmanifest +1 -1
  99. package/dist/pwa/pwa-192x192.png +0 -0
  100. package/dist/pwa/pwa-512x512.png +0 -0
  101. package/dist/pwa/service-worker.js +1 -1
  102. package/dist/rpc-handler.d.ts +0 -1
  103. package/dist/rpc-handler.js +3 -10
  104. package/dist/sms-store.d.ts +0 -1
  105. package/dist/sms-store.js +0 -1
  106. package/dist/spawn-command.d.ts +0 -1
  107. package/dist/spawn-command.js +0 -1
  108. package/dist/task.d.ts +1 -1
  109. package/dist/task.js +14 -1
  110. package/dist/transports/http-transport.d.ts +0 -1
  111. package/dist/transports/http-transport.js +0 -1
  112. package/dist/transports/nats-transport.d.ts +0 -1
  113. package/dist/transports/nats-transport.js +0 -1
  114. package/dist/types.d.ts +0 -1
  115. package/dist/types.js +0 -1
  116. package/dist/update-checker.d.ts +0 -1
  117. package/dist/update-checker.js +0 -1
  118. package/package.json +5 -1
  119. package/.github/workflows/ci.yml +0 -16
  120. package/.github/workflows/publish.yml +0 -37
  121. package/CLAUDE.md +0 -22
  122. package/dist/pwa/assets/index-DBgOYBrB.css +0 -1
  123. package/palmier-server/.github/workflows/ci.yml +0 -21
  124. package/palmier-server/.github/workflows/deploy.yml +0 -38
  125. package/palmier-server/CLAUDE.md +0 -17
  126. package/palmier-server/PRODUCTION.md +0 -358
  127. package/palmier-server/README.md +0 -231
  128. package/palmier-server/nats.conf +0 -19
  129. package/palmier-server/package.json +0 -15
  130. package/palmier-server/pnpm-lock.yaml +0 -7639
  131. package/palmier-server/pnpm-workspace.yaml +0 -3
  132. package/palmier-server/pwa/index.html +0 -16
  133. package/palmier-server/pwa/logo/logo-prompt.md +0 -28
  134. package/palmier-server/pwa/logo/logo_20260330.png +0 -0
  135. package/palmier-server/pwa/package.json +0 -34
  136. package/palmier-server/pwa/public/apple-touch-icon.png +0 -0
  137. package/palmier-server/pwa/public/favicon.ico +0 -0
  138. package/palmier-server/pwa/public/pwa-192x192.png +0 -0
  139. package/palmier-server/pwa/public/pwa-512x512.png +0 -0
  140. package/palmier-server/pwa/src/App.css +0 -3004
  141. package/palmier-server/pwa/src/App.tsx +0 -59
  142. package/palmier-server/pwa/src/agentLabels.ts +0 -11
  143. package/palmier-server/pwa/src/api.ts +0 -67
  144. package/palmier-server/pwa/src/components/CapabilityToggles.tsx +0 -170
  145. package/palmier-server/pwa/src/components/ConnectionStatusIcon.tsx +0 -114
  146. package/palmier-server/pwa/src/components/HostMenu.tsx +0 -429
  147. package/palmier-server/pwa/src/components/PermissionsDialog.tsx +0 -34
  148. package/palmier-server/pwa/src/components/PullToRefreshIndicator.tsx +0 -46
  149. package/palmier-server/pwa/src/components/RunDetailView.tsx +0 -343
  150. package/palmier-server/pwa/src/components/SessionComposer.tsx +0 -157
  151. package/palmier-server/pwa/src/components/SessionsView.tsx +0 -326
  152. package/palmier-server/pwa/src/components/SwipeToDeleteRow.tsx +0 -170
  153. package/palmier-server/pwa/src/components/TabBar.tsx +0 -40
  154. package/palmier-server/pwa/src/components/TaskCard.tsx +0 -255
  155. package/palmier-server/pwa/src/components/TaskForm.tsx +0 -764
  156. package/palmier-server/pwa/src/components/TasksView.tsx +0 -179
  157. package/palmier-server/pwa/src/constants.ts +0 -2
  158. package/palmier-server/pwa/src/contexts/HostConnectionContext.tsx +0 -432
  159. package/palmier-server/pwa/src/contexts/HostStoreContext.tsx +0 -124
  160. package/palmier-server/pwa/src/draftGuard.ts +0 -24
  161. package/palmier-server/pwa/src/formatTime.ts +0 -44
  162. package/palmier-server/pwa/src/hooks/useBackClose.ts +0 -75
  163. package/palmier-server/pwa/src/hooks/useMediaQuery.ts +0 -17
  164. package/palmier-server/pwa/src/hooks/usePullToRefresh.ts +0 -102
  165. package/palmier-server/pwa/src/hooks/usePushSubscription.ts +0 -77
  166. package/palmier-server/pwa/src/main.tsx +0 -14
  167. package/palmier-server/pwa/src/native/Device.ts +0 -49
  168. package/palmier-server/pwa/src/pages/Dashboard.tsx +0 -542
  169. package/palmier-server/pwa/src/pages/PairHost.tsx +0 -232
  170. package/palmier-server/pwa/src/pages/PairSetup.tsx +0 -134
  171. package/palmier-server/pwa/src/service-worker.ts +0 -142
  172. package/palmier-server/pwa/src/types.ts +0 -75
  173. package/palmier-server/pwa/src/vite-env.d.ts +0 -11
  174. package/palmier-server/pwa/tsconfig.json +0 -21
  175. package/palmier-server/pwa/tsconfig.node.json +0 -19
  176. package/palmier-server/pwa/vite.config.ts +0 -47
  177. package/palmier-server/server/.env.example +0 -20
  178. package/palmier-server/server/package.json +0 -36
  179. package/palmier-server/server/src/db.ts +0 -44
  180. package/palmier-server/server/src/fcm.ts +0 -74
  181. package/palmier-server/server/src/index.ts +0 -688
  182. package/palmier-server/server/src/nats-jwt.ts +0 -299
  183. package/palmier-server/server/src/nats-setup.ts +0 -48
  184. package/palmier-server/server/src/nats.ts +0 -33
  185. package/palmier-server/server/src/notify.ts +0 -34
  186. package/palmier-server/server/src/push.ts +0 -68
  187. package/palmier-server/server/src/routes/device.ts +0 -224
  188. package/palmier-server/server/src/routes/fcm.ts +0 -64
  189. package/palmier-server/server/src/routes/hosts.ts +0 -56
  190. package/palmier-server/server/src/routes/push.ts +0 -101
  191. package/palmier-server/server/tsconfig.json +0 -20
  192. package/palmier-server/spec.md +0 -533
  193. package/src/agents/agent-instructions.md +0 -28
  194. package/src/agents/agent.ts +0 -114
  195. package/src/agents/aider.ts +0 -35
  196. package/src/agents/claude.ts +0 -39
  197. package/src/agents/cline.ts +0 -35
  198. package/src/agents/codex.ts +0 -40
  199. package/src/agents/copilot.ts +0 -37
  200. package/src/agents/cursor.ts +0 -36
  201. package/src/agents/deepagents.ts +0 -36
  202. package/src/agents/droid.ts +0 -35
  203. package/src/agents/gemini.ts +0 -43
  204. package/src/agents/goose.ts +0 -33
  205. package/src/agents/hermes.ts +0 -36
  206. package/src/agents/kimi.ts +0 -35
  207. package/src/agents/kiro.ts +0 -36
  208. package/src/agents/openclaw.ts +0 -29
  209. package/src/agents/opencode.ts +0 -36
  210. package/src/agents/qoder.ts +0 -36
  211. package/src/agents/qwen.ts +0 -32
  212. package/src/agents/shared-prompt.ts +0 -30
  213. package/src/client-store.ts +0 -68
  214. package/src/commands/clients.ts +0 -29
  215. package/src/commands/info.ts +0 -29
  216. package/src/commands/init.ts +0 -165
  217. package/src/commands/pair.ts +0 -137
  218. package/src/commands/restart.ts +0 -6
  219. package/src/commands/run.ts +0 -608
  220. package/src/commands/serve.ts +0 -211
  221. package/src/commands/uninstall.ts +0 -9
  222. package/src/config.ts +0 -36
  223. package/src/cross-spawn.d.ts +0 -5
  224. package/src/event-queues.ts +0 -41
  225. package/src/events.ts +0 -29
  226. package/src/index.ts +0 -111
  227. package/src/linked-device.ts +0 -52
  228. package/src/mcp-handler.ts +0 -200
  229. package/src/mcp-tools.ts +0 -839
  230. package/src/nats-client.ts +0 -19
  231. package/src/network.ts +0 -96
  232. package/src/notification-store.ts +0 -30
  233. package/src/pending-requests.ts +0 -73
  234. package/src/platform/index.ts +0 -20
  235. package/src/platform/linux.ts +0 -296
  236. package/src/platform/macos.ts +0 -329
  237. package/src/platform/platform.ts +0 -31
  238. package/src/platform/windows.ts +0 -299
  239. package/src/rpc-handler.ts +0 -694
  240. package/src/sms-store.ts +0 -28
  241. package/src/spawn-command.ts +0 -123
  242. package/src/task.ts +0 -330
  243. package/src/transports/http-transport.ts +0 -478
  244. package/src/transports/nats-transport.ts +0 -76
  245. package/src/types.ts +0 -89
  246. package/src/update-checker.ts +0 -40
  247. package/test/agent-instructions.test.ts +0 -209
  248. package/test/agent-output-parsing.test.ts +0 -74
  249. package/test/linux-cron.test.ts +0 -41
  250. package/test/macos-plist.test.ts +0 -112
  251. package/test/notification-store.test.ts +0 -57
  252. package/test/pairing.test.ts +0 -35
  253. package/test/result-state.test.ts +0 -110
  254. package/test/task-parsing.test.ts +0 -82
  255. package/test/taskrun-messages.test.ts +0 -224
  256. package/test/tsconfig.json +0 -9
  257. package/test/windows-xml.test.ts +0 -89
  258. package/tsconfig.json +0 -19
@@ -1,255 +0,0 @@
1
- import { useState, useRef, useEffect } from "react";
2
- import { createPortal } from "react-dom";
3
- import { useHostConnection } from "../contexts/HostConnectionContext";
4
- import { useFormatTime } from "../formatTime";
5
- import { getAgentLabel } from "../agentLabels";
6
- import type { Task, TaskStatus } from "../types";
7
-
8
- const isMobile = () => window.matchMedia("(max-width: 600px)").matches;
9
-
10
- interface TaskCardProps {
11
- task: Task;
12
- lastEvent?: TaskStatus;
13
- onEdit(task: Task): void;
14
- onDelete(taskId: string): void;
15
- onViewRun(taskId: string, runId?: string): void;
16
- }
17
-
18
- export default function TaskCard({ task, lastEvent, onEdit, onDelete, onViewRun }: TaskCardProps) {
19
- const { request, activeHost } = useHostConnection();
20
- const formatTime = useFormatTime();
21
- const timeZone = activeHost.timezone;
22
- const [aborting, setAborting] = useState(false);
23
- const [menuOpen, setMenuOpen] = useState(false);
24
- const [sheetOpen, setSheetOpen] = useState(false);
25
- const menuRef = useRef<HTMLDivElement>(null);
26
-
27
- const isRunning = lastEvent?.running_state === "started";
28
- const hasScheduleValues = (task.schedule_values?.length ?? 0) > 0;
29
- const isEventSchedule = task.schedule_type === "on_new_notification" || task.schedule_type === "on_new_sms";
30
- const scheduleActive = !!task.schedule_enabled && !!task.schedule_type && (hasScheduleValues || isEventSchedule);
31
- const stateColor =
32
- !scheduleActive
33
- ? "var(--color-text-secondary)"
34
- : isRunning
35
- ? "var(--color-success)"
36
- : lastEvent?.running_state === "failed"
37
- ? "var(--color-error)"
38
- : "var(--color-success)";
39
-
40
- // Close dropdown on outside click
41
- useEffect(() => {
42
- if (!menuOpen) return;
43
- function handleClick(e: MouseEvent) {
44
- if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
45
- setMenuOpen(false);
46
- }
47
- }
48
- document.addEventListener("mousedown", handleClick);
49
- return () => document.removeEventListener("mousedown", handleClick);
50
- }, [menuOpen]);
51
-
52
- function openMenu() {
53
- if (isMobile()) {
54
- setSheetOpen(true);
55
- } else {
56
- setMenuOpen((v) => !v);
57
- }
58
- }
59
-
60
- function closeMenu() {
61
- setMenuOpen(false);
62
- setSheetOpen(false);
63
- }
64
-
65
- async function handleAbort() {
66
- closeMenu();
67
- if (!confirm("Abort this task?")) return;
68
- setAborting(true);
69
- try {
70
- await request("task.abort", { id: task.id });
71
- } catch (err) {
72
- console.error("Abort failed:", err);
73
- } finally {
74
- setAborting(false);
75
- }
76
- }
77
-
78
- async function handleRunNow() {
79
- closeMenu();
80
- try {
81
- const result = await request<{ ok?: boolean; task_id?: string; run_id?: string }>("task.run", { id: task.id });
82
- onViewRun(task.id, result.run_id);
83
- } catch (err) {
84
- console.error("Run failed:", err);
85
- }
86
- }
87
-
88
- async function handleDelete() {
89
- closeMenu();
90
- if (!confirm("Delete this task? Results and reports will be kept.")) return;
91
- try {
92
- await request("task.delete", { id: task.id });
93
- onDelete(task.id);
94
- } catch (err) {
95
- console.error("Delete failed:", err);
96
- }
97
- }
98
-
99
- const eventLabel: Record<string, string> = {
100
- started: "Started",
101
- finished: "Finished",
102
- aborted: "Aborted",
103
- failed: "Failed",
104
- };
105
-
106
-
107
- function classifyValue(scheduleType: "crons" | "specific_times", value: string): { kind: string; detail: string } {
108
- if (scheduleType === "specific_times") {
109
- const d = new Date(value);
110
- const label = isNaN(d.getTime())
111
- ? value
112
- : `${d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric", timeZone })} at ${d.toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit", timeZone })}`;
113
- return { kind: "specific_times", detail: label };
114
- }
115
- const parts = value.split(" ");
116
- if (parts.length !== 5) return { kind: "unknown", detail: value };
117
- const [min, hour, dom, , dow] = parts;
118
- const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
119
- if (hour === "*") return { kind: "hourly", detail: "" };
120
- // Cron HH:MM is in the host's wall clock. Format directly — no Date
121
- // conversion — to avoid implicit shifting through the viewer's local zone.
122
- const h = Number(hour);
123
- const m = Number(min);
124
- const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h;
125
- const ampm = h >= 12 ? "PM" : "AM";
126
- const time = `${hour12}:${String(m).padStart(2, "0")} ${ampm}`;
127
- if (dow !== "*") return { kind: "weekly", detail: `${DAYS[Number(dow)] ?? dow} at ${time}` };
128
- if (dom !== "*") return { kind: "monthly", detail: `day ${dom} at ${time}` };
129
- return { kind: "daily", detail: time };
130
- }
131
-
132
- function formatSingleValue(scheduleType: "crons" | "specific_times", value: string): string {
133
- const c = classifyValue(scheduleType, value);
134
- if (c.kind === "hourly") return "Every hour";
135
- if (c.kind === "specific_times") return `Once on ${c.detail}`;
136
- return `${c.kind.charAt(0).toUpperCase() + c.kind.slice(1)}: ${c.detail}`;
137
- }
138
-
139
- function formatScheduleGrouped(
140
- scheduleType: "crons" | "specific_times" | "on_new_notification" | "on_new_sms" | undefined,
141
- values: string[] | undefined,
142
- ): string {
143
- if (!scheduleType) return "";
144
- if (scheduleType === "on_new_notification") return "On new notification";
145
- if (scheduleType === "on_new_sms") return "On new SMS";
146
- if (!values || values.length === 0) return "";
147
- if (values.length === 1) return formatSingleValue(scheduleType, values[0]);
148
-
149
- const classified = values.map((v) => classifyValue(scheduleType, v));
150
- const kinds = new Set(classified.map((c) => c.kind));
151
-
152
- if (kinds.size === 1) {
153
- const kind = classified[0].kind;
154
- if (kind === "hourly") return "Every hour";
155
- const details = classified.map((c) => c.detail);
156
- return `${kind.charAt(0).toUpperCase() + kind.slice(1)}: ${details.join(", ")}`;
157
- }
158
-
159
- return values.map((v) => formatSingleValue(scheduleType, v)).join(", ");
160
- }
161
-
162
- const scheduleText = formatScheduleGrouped(task.schedule_type, task.schedule_values);
163
-
164
- const actionItems = (
165
- <>
166
- <button onClick={() => { closeMenu(); onEdit(task); }}>
167
- <span className="menu-icon">&#9998;</span>Edit
168
- </button>
169
- <button onClick={() => { closeMenu(); onViewRun(task.id); }}>
170
- <span className="menu-icon">&#128196;</span>View All Runs
171
- </button>
172
- {isRunning ? (
173
- <button className="menu-item-danger" onClick={handleAbort} disabled={aborting}>
174
- <span className="menu-icon">&#9724;</span>Abort
175
- </button>
176
- ) : (
177
- <>
178
- <button onClick={handleRunNow}>
179
- <span className="menu-icon">&#9654;</span>Run Now
180
- </button>
181
- <button className="menu-item-danger" onClick={handleDelete}>
182
- <span className="menu-icon">&#128465;</span>Delete
183
- </button>
184
- </>
185
- )}
186
- </>
187
- );
188
-
189
- return (
190
- <>
191
- <div className="task-card" onClick={() => onViewRun(task.id, "latest")}>
192
- <div className="task-card-header">
193
- <div className="task-card-title-row">
194
- {isRunning ? (
195
- <span className="status-spinner">
196
- <span />
197
- </span>
198
- ) : (
199
- <span
200
- className="status-dot"
201
- style={{ backgroundColor: stateColor }}
202
- />
203
- )}
204
- <h3 className="task-card-name">{task.name || task.user_prompt}</h3>
205
- </div>
206
- <div className="task-card-actions" onClick={(e) => e.stopPropagation()}>
207
- <div className="task-card-menu" ref={menuRef}>
208
- <button
209
- className="task-card-menu-btn"
210
- onClick={openMenu}
211
- aria-label="Task actions"
212
- >
213
- &#8942;
214
- </button>
215
- {menuOpen && (
216
- <div className="task-card-menu-dropdown">
217
- {actionItems}
218
- </div>
219
- )}
220
- </div>
221
- </div>
222
- </div>
223
- <div className="task-card-meta">
224
- {task.agent && (
225
- <span className="task-card-agent">{getAgentLabel(task.agent)}</span>
226
- )}
227
- {lastEvent && eventLabel[lastEvent.running_state] && (
228
- <span className="task-card-last-event">
229
- {eventLabel[lastEvent.running_state]}
230
- {" "}{formatTime(lastEvent.time_stamp)}
231
- </span>
232
- )}
233
- {task.schedule_type && (hasScheduleValues || isEventSchedule) && (
234
- <span className="task-card-triggers">
235
- {task.schedule_enabled ? scheduleText : "Schedule disabled"}
236
- </span>
237
- )}
238
- </div>
239
- </div>
240
-
241
- {sheetOpen && createPortal(
242
- <div className="bottom-sheet-overlay" onClick={() => setSheetOpen(false)}>
243
- <div className="bottom-sheet" onClick={(e) => e.stopPropagation()}>
244
- <div className="bottom-sheet-handle" />
245
- <div className="bottom-sheet-title">{task.name || task.user_prompt}</div>
246
- <div className="bottom-sheet-actions">
247
- {actionItems}
248
- </div>
249
- </div>
250
- </div>,
251
- document.body,
252
- )}
253
- </>
254
- );
255
- }