@gperezmz/bb-plugin-thread-glance 0.1.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.
Files changed (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/THIRD_PARTY_NOTICES.md +230 -0
  4. package/app.tsx +12 -0
  5. package/components/ui/alert-dialog.tsx +142 -0
  6. package/components/ui/button.tsx +59 -0
  7. package/components/ui/card.tsx +83 -0
  8. package/components/ui/coarse-pointer-sizing.ts +66 -0
  9. package/components/ui/context-menu.tsx +355 -0
  10. package/components/ui/dialog.tsx +416 -0
  11. package/components/ui/dropdown-menu.tsx +640 -0
  12. package/components/ui/hooks/use-compact-viewport.tsx +37 -0
  13. package/components/ui/hooks/use-media-query.ts +70 -0
  14. package/components/ui/hooks/use-pointer-coarse.ts +7 -0
  15. package/components/ui/hover-card.tsx +36 -0
  16. package/components/ui/icon-extended.tsx +333 -0
  17. package/components/ui/icon-registry.ts +189 -0
  18. package/components/ui/icon.tsx +444 -0
  19. package/components/ui/input.tsx +30 -0
  20. package/components/ui/menu-item-hover.tsx +93 -0
  21. package/components/ui/motion.ts +4 -0
  22. package/components/ui/overlay-trigger.ts +84 -0
  23. package/components/ui/popover.tsx +223 -0
  24. package/components/ui/responsive-overlay.tsx +823 -0
  25. package/components/ui/tooltip.tsx +63 -0
  26. package/dist/app.css +2 -0
  27. package/dist/app.js +66 -0
  28. package/dist/app.meta.json +11 -0
  29. package/dist/server.js +71 -0
  30. package/dist/server.js.map +6 -0
  31. package/dist/server.meta.json +11 -0
  32. package/features/thread-list/components/Dialogs.tsx +299 -0
  33. package/features/thread-list/components/FoldRows.tsx +147 -0
  34. package/features/thread-list/components/GroupSection.tsx +370 -0
  35. package/features/thread-list/components/ProviderBadge.tsx +57 -0
  36. package/features/thread-list/components/PullRequestBadge.tsx +50 -0
  37. package/features/thread-list/components/Rails.tsx +28 -0
  38. package/features/thread-list/components/RenameEditor.tsx +118 -0
  39. package/features/thread-list/components/RowMenu.tsx +168 -0
  40. package/features/thread-list/components/SplitMiniMap.tsx +55 -0
  41. package/features/thread-list/components/ThreadDetails.tsx +138 -0
  42. package/features/thread-list/components/ThreadList.tsx +855 -0
  43. package/features/thread-list/components/ThreadRowView.tsx +631 -0
  44. package/features/thread-list/components/Toolbar.tsx +296 -0
  45. package/features/thread-list/components/controller.ts +64 -0
  46. package/features/thread-list/components/glyphs.tsx +129 -0
  47. package/features/thread-list/components/row-card.ts +127 -0
  48. package/features/thread-list/data/storage.ts +18 -0
  49. package/features/thread-list/data/useAutoExpand.ts +53 -0
  50. package/features/thread-list/data/useClientPreferences.ts +20 -0
  51. package/features/thread-list/data/useNotes.ts +41 -0
  52. package/features/thread-list/data/useNow.ts +19 -0
  53. package/features/thread-list/data/usePreferences.ts +126 -0
  54. package/features/thread-list/data/useScheduled.ts +43 -0
  55. package/features/thread-list/data/useStamps.ts +68 -0
  56. package/features/thread-list/icons.ts +44 -0
  57. package/features/thread-list/index.ts +2 -0
  58. package/features/thread-list/model/attention.ts +89 -0
  59. package/features/thread-list/model/counters.ts +67 -0
  60. package/features/thread-list/model/details.ts +79 -0
  61. package/features/thread-list/model/drag.ts +104 -0
  62. package/features/thread-list/model/expansion.ts +71 -0
  63. package/features/thread-list/model/families.ts +297 -0
  64. package/features/thread-list/model/groups.ts +263 -0
  65. package/features/thread-list/model/labels.ts +50 -0
  66. package/features/thread-list/model/layout.ts +61 -0
  67. package/features/thread-list/model/menu.ts +78 -0
  68. package/features/thread-list/model/move.ts +46 -0
  69. package/features/thread-list/model/notes.ts +52 -0
  70. package/features/thread-list/model/provider-mark.ts +59 -0
  71. package/features/thread-list/model/share.ts +101 -0
  72. package/features/thread-list/model/sort.ts +78 -0
  73. package/features/thread-list/model/state.ts +330 -0
  74. package/features/thread-list/model/time.ts +107 -0
  75. package/features/thread-list/model/toggles.ts +99 -0
  76. package/features/thread-list/model/view.ts +669 -0
  77. package/features/thread-list/model/windowing.ts +27 -0
  78. package/features/thread-list/testing/fixtures.ts +162 -0
  79. package/hooks/useBrowserDimmingModal.ts +5 -0
  80. package/lib/portal-scope.ts +15 -0
  81. package/lib/utils.ts +17 -0
  82. package/package.json +96 -0
  83. package/server/cli.ts +107 -0
  84. package/server/failures.ts +136 -0
  85. package/server/import.ts +144 -0
  86. package/server/notes.ts +236 -0
  87. package/server/preference-store.ts +96 -0
  88. package/server/scheduled.ts +129 -0
  89. package/server/serial.ts +12 -0
  90. package/server/stamps.ts +142 -0
  91. package/server/startup.ts +121 -0
  92. package/server.ts +126 -0
  93. package/shared/contract.ts +73 -0
  94. package/shared/preferences.ts +241 -0
  95. package/shared/signals.ts +71 -0
  96. package/skills/thread-glance/SKILL.md +69 -0
  97. package/tsconfig.json +36 -0
  98. package/types/global-jsx.d.ts +10 -0
@@ -0,0 +1,355 @@
1
+ import * as React from "react";
2
+ import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
3
+
4
+ import { cn } from "../../lib/utils";
5
+ import { usePortalScopeProps } from "../../lib/portal-scope";
6
+ import { COARSE_POINTER_CHECK_SLOT_CLASS } from "./coarse-pointer-sizing.js";
7
+ import {
8
+ MENU_ITEM_LAST_HOVERED_CLASS,
9
+ MenuHoverProvider,
10
+ useMenuItemHover,
11
+ } from "./menu-item-hover.js";
12
+ import { LIST_HOVER_TRANSITION } from "./motion.js";
13
+ import { Icon } from "../../components/ui/icon.js";
14
+
15
+ type ContextMenuSubTriggerElement = React.ComponentRef<
16
+ typeof ContextMenuPrimitive.SubTrigger
17
+ >;
18
+ type ContextMenuSubTriggerProps = React.ComponentPropsWithoutRef<
19
+ typeof ContextMenuPrimitive.SubTrigger
20
+ > & {
21
+ inset?: boolean;
22
+ };
23
+
24
+ type ContextMenuSubContentElement = React.ComponentRef<
25
+ typeof ContextMenuPrimitive.SubContent
26
+ >;
27
+ type ContextMenuSubContentProps = React.ComponentPropsWithoutRef<
28
+ typeof ContextMenuPrimitive.SubContent
29
+ >;
30
+
31
+ type ContextMenuContentElement = React.ComponentRef<
32
+ typeof ContextMenuPrimitive.Content
33
+ >;
34
+ type ContextMenuContentProps = React.ComponentPropsWithoutRef<
35
+ typeof ContextMenuPrimitive.Content
36
+ >;
37
+
38
+ type ContextMenuItemElement = React.ComponentRef<
39
+ typeof ContextMenuPrimitive.Item
40
+ >;
41
+ type ContextMenuItemProps = React.ComponentPropsWithoutRef<
42
+ typeof ContextMenuPrimitive.Item
43
+ > & {
44
+ inset?: boolean;
45
+ };
46
+
47
+ type ContextMenuCheckboxItemElement = React.ComponentRef<
48
+ typeof ContextMenuPrimitive.CheckboxItem
49
+ >;
50
+ type ContextMenuCheckboxItemProps = React.ComponentPropsWithoutRef<
51
+ typeof ContextMenuPrimitive.CheckboxItem
52
+ >;
53
+
54
+ type ContextMenuRadioItemElement = React.ComponentRef<
55
+ typeof ContextMenuPrimitive.RadioItem
56
+ >;
57
+ type ContextMenuRadioItemProps = React.ComponentPropsWithoutRef<
58
+ typeof ContextMenuPrimitive.RadioItem
59
+ >;
60
+
61
+ type ContextMenuLabelElement = React.ComponentRef<
62
+ typeof ContextMenuPrimitive.Label
63
+ >;
64
+ type ContextMenuLabelProps = React.ComponentPropsWithoutRef<
65
+ typeof ContextMenuPrimitive.Label
66
+ > & {
67
+ inset?: boolean;
68
+ };
69
+
70
+ type ContextMenuSeparatorElement = React.ComponentRef<
71
+ typeof ContextMenuPrimitive.Separator
72
+ >;
73
+ type ContextMenuSeparatorProps = React.ComponentPropsWithoutRef<
74
+ typeof ContextMenuPrimitive.Separator
75
+ >;
76
+
77
+ type ContextMenuShortcutProps = React.HTMLAttributes<HTMLSpanElement>;
78
+
79
+ const CONTEXT_MENU_LAYER_CLASS = "z-[70]";
80
+
81
+ const ContextMenu = ContextMenuPrimitive.Root;
82
+ const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
83
+ const ContextMenuGroup = ContextMenuPrimitive.Group;
84
+ const ContextMenuPortal = ContextMenuPrimitive.Portal;
85
+ const ContextMenuSub = ContextMenuPrimitive.Sub;
86
+ const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
87
+
88
+ const ContextMenuSubTrigger = React.forwardRef<
89
+ ContextMenuSubTriggerElement,
90
+ ContextMenuSubTriggerProps
91
+ >(
92
+ (
93
+ {
94
+ className,
95
+ inset,
96
+ children,
97
+ onPointerEnter: callerPointerEnter,
98
+ onKeyDown: callerKeyDown,
99
+ ...props
100
+ },
101
+ ref,
102
+ ) => {
103
+ const { hoverProps } = useMenuItemHover({
104
+ onPointerEnter: callerPointerEnter,
105
+ onKeyDown: callerKeyDown,
106
+ });
107
+
108
+ return (
109
+ <ContextMenuPrimitive.SubTrigger
110
+ ref={ref}
111
+ className={cn(
112
+ "flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-[0.3125rem] text-xs outline-none focus:bg-state-hover focus:text-foreground data-[state=open]:bg-state-active data-[state=open]:text-foreground [&_[data-icon-root]]:pointer-events-none [&_[data-icon-root]]:size-4 [&_[data-icon-root]]:shrink-0",
113
+ LIST_HOVER_TRANSITION,
114
+ MENU_ITEM_LAST_HOVERED_CLASS,
115
+ inset && "pl-8",
116
+ className,
117
+ )}
118
+ {...props}
119
+ {...hoverProps}
120
+ >
121
+ {children}
122
+ <Icon name="ChevronRight" className="ml-auto" />
123
+ </ContextMenuPrimitive.SubTrigger>
124
+ );
125
+ },
126
+ );
127
+ ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
128
+
129
+ const ContextMenuSubContent = React.forwardRef<
130
+ ContextMenuSubContentElement,
131
+ ContextMenuSubContentProps
132
+ >(({ className, ...props }, ref) => (
133
+ <ContextMenuPrimitive.SubContent
134
+ ref={ref}
135
+ {...usePortalScopeProps()}
136
+ className={cn(
137
+ CONTEXT_MENU_LAYER_CLASS,
138
+ "min-w-28 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 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",
139
+ className,
140
+ )}
141
+ {...props}
142
+ />
143
+ ));
144
+ ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
145
+
146
+ const ContextMenuContent = React.forwardRef<
147
+ ContextMenuContentElement,
148
+ ContextMenuContentProps
149
+ >(({ className, children, ...props }, ref) => (
150
+ <ContextMenuPrimitive.Portal>
151
+ <ContextMenuPrimitive.Content
152
+ ref={ref}
153
+ {...usePortalScopeProps()}
154
+ className={cn(
155
+ CONTEXT_MENU_LAYER_CLASS,
156
+ "min-w-28 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 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",
157
+ className,
158
+ )}
159
+ {...props}
160
+ >
161
+ <MenuHoverProvider>{children}</MenuHoverProvider>
162
+ </ContextMenuPrimitive.Content>
163
+ </ContextMenuPrimitive.Portal>
164
+ ));
165
+ ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
166
+
167
+ const ContextMenuItem = React.forwardRef<
168
+ ContextMenuItemElement,
169
+ ContextMenuItemProps
170
+ >(
171
+ (
172
+ {
173
+ className,
174
+ inset,
175
+ onPointerEnter: callerPointerEnter,
176
+ onKeyDown: callerKeyDown,
177
+ ...props
178
+ },
179
+ ref,
180
+ ) => {
181
+ const { hoverProps } = useMenuItemHover({
182
+ onPointerEnter: callerPointerEnter,
183
+ onKeyDown: callerKeyDown,
184
+ });
185
+
186
+ return (
187
+ <ContextMenuPrimitive.Item
188
+ ref={ref}
189
+ className={cn(
190
+ "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-[0.3125rem] text-xs outline-none focus:bg-state-hover focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>[data-icon-root]]:size-4 [&>[data-icon-root]]:shrink-0",
191
+ LIST_HOVER_TRANSITION,
192
+ MENU_ITEM_LAST_HOVERED_CLASS,
193
+ inset && "pl-8",
194
+ className,
195
+ )}
196
+ {...props}
197
+ {...hoverProps}
198
+ />
199
+ );
200
+ },
201
+ );
202
+ ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
203
+
204
+ const ContextMenuCheckboxItem = React.forwardRef<
205
+ ContextMenuCheckboxItemElement,
206
+ ContextMenuCheckboxItemProps
207
+ >(
208
+ (
209
+ {
210
+ className,
211
+ children,
212
+ checked,
213
+ onPointerEnter: callerPointerEnter,
214
+ onKeyDown: callerKeyDown,
215
+ ...props
216
+ },
217
+ ref,
218
+ ) => {
219
+ const { hoverProps } = useMenuItemHover({
220
+ onPointerEnter: callerPointerEnter,
221
+ onKeyDown: callerKeyDown,
222
+ });
223
+
224
+ return (
225
+ <ContextMenuPrimitive.CheckboxItem
226
+ ref={ref}
227
+ className={cn(
228
+ "relative flex cursor-default select-none items-center rounded-sm py-[0.3125rem] pl-2 pr-8 text-xs outline-none focus:bg-state-hover focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
229
+ LIST_HOVER_TRANSITION,
230
+ MENU_ITEM_LAST_HOVERED_CLASS,
231
+ className,
232
+ )}
233
+ checked={checked}
234
+ {...props}
235
+ {...hoverProps}
236
+ >
237
+ <span
238
+ className={cn(
239
+ "absolute right-2 flex items-center justify-center",
240
+ COARSE_POINTER_CHECK_SLOT_CLASS,
241
+ )}
242
+ >
243
+ <ContextMenuPrimitive.ItemIndicator>
244
+ <Icon name="Check" className={COARSE_POINTER_CHECK_SLOT_CLASS} />
245
+ </ContextMenuPrimitive.ItemIndicator>
246
+ </span>
247
+ {children}
248
+ </ContextMenuPrimitive.CheckboxItem>
249
+ );
250
+ },
251
+ );
252
+ ContextMenuCheckboxItem.displayName =
253
+ ContextMenuPrimitive.CheckboxItem.displayName;
254
+
255
+ const ContextMenuRadioItem = React.forwardRef<
256
+ ContextMenuRadioItemElement,
257
+ ContextMenuRadioItemProps
258
+ >(
259
+ (
260
+ {
261
+ className,
262
+ children,
263
+ onPointerEnter: callerPointerEnter,
264
+ onKeyDown: callerKeyDown,
265
+ ...props
266
+ },
267
+ ref,
268
+ ) => {
269
+ const { hoverProps } = useMenuItemHover({
270
+ onPointerEnter: callerPointerEnter,
271
+ onKeyDown: callerKeyDown,
272
+ });
273
+
274
+ return (
275
+ <ContextMenuPrimitive.RadioItem
276
+ ref={ref}
277
+ className={cn(
278
+ "relative flex cursor-default select-none items-center rounded-sm py-[0.3125rem] pl-8 pr-2 text-xs outline-none focus:bg-state-hover focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
279
+ LIST_HOVER_TRANSITION,
280
+ MENU_ITEM_LAST_HOVERED_CLASS,
281
+ className,
282
+ )}
283
+ {...props}
284
+ {...hoverProps}
285
+ >
286
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
287
+ <ContextMenuPrimitive.ItemIndicator>
288
+ <Icon name="Circle" className="h-2 w-2 fill-current" />
289
+ </ContextMenuPrimitive.ItemIndicator>
290
+ </span>
291
+ {children}
292
+ </ContextMenuPrimitive.RadioItem>
293
+ );
294
+ },
295
+ );
296
+ ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
297
+
298
+ const ContextMenuLabel = React.forwardRef<
299
+ ContextMenuLabelElement,
300
+ ContextMenuLabelProps
301
+ >(({ className, inset, ...props }, ref) => (
302
+ <ContextMenuPrimitive.Label
303
+ ref={ref}
304
+ className={cn(
305
+ "px-2 py-[0.3125rem] text-xs font-medium text-muted-foreground",
306
+ inset && "pl-8",
307
+ className,
308
+ )}
309
+ {...props}
310
+ />
311
+ ));
312
+ ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
313
+
314
+ const ContextMenuSeparator = React.forwardRef<
315
+ ContextMenuSeparatorElement,
316
+ ContextMenuSeparatorProps
317
+ >(({ className, ...props }, ref) => (
318
+ <ContextMenuPrimitive.Separator
319
+ ref={ref}
320
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
321
+ {...props}
322
+ />
323
+ ));
324
+ ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
325
+
326
+ function ContextMenuShortcut({
327
+ className,
328
+ ...props
329
+ }: ContextMenuShortcutProps) {
330
+ return (
331
+ <span
332
+ className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
333
+ {...props}
334
+ />
335
+ );
336
+ }
337
+ ContextMenuShortcut.displayName = "ContextMenuShortcut";
338
+
339
+ export {
340
+ ContextMenu,
341
+ ContextMenuTrigger,
342
+ ContextMenuContent,
343
+ ContextMenuItem,
344
+ ContextMenuCheckboxItem,
345
+ ContextMenuRadioItem,
346
+ ContextMenuLabel,
347
+ ContextMenuSeparator,
348
+ ContextMenuShortcut,
349
+ ContextMenuGroup,
350
+ ContextMenuPortal,
351
+ ContextMenuSub,
352
+ ContextMenuSubContent,
353
+ ContextMenuSubTrigger,
354
+ ContextMenuRadioGroup,
355
+ };