hale-commenting-system 2.0.3 → 2.1.0

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 (58) hide show
  1. package/README.md +16 -207
  2. package/bin/detect.d.ts +10 -0
  3. package/bin/detect.js +134 -0
  4. package/bin/generators.d.ts +18 -0
  5. package/bin/generators.js +193 -0
  6. package/bin/hale-commenting.js +4 -0
  7. package/bin/index.d.ts +2 -0
  8. package/bin/index.js +61 -0
  9. package/bin/onboarding.d.ts +1 -0
  10. package/bin/onboarding.js +344 -0
  11. package/bin/postinstall.d.ts +2 -0
  12. package/bin/postinstall.js +65 -0
  13. package/bin/validators.d.ts +2 -0
  14. package/bin/validators.js +66 -0
  15. package/dist/cli/detect.d.ts +10 -0
  16. package/dist/cli/detect.js +134 -0
  17. package/dist/cli/generators.d.ts +18 -0
  18. package/dist/cli/generators.js +193 -0
  19. package/dist/cli/index.d.ts +2 -0
  20. package/dist/cli/index.js +61 -0
  21. package/dist/cli/onboarding.d.ts +1 -0
  22. package/dist/cli/onboarding.js +344 -0
  23. package/dist/cli/postinstall.d.ts +2 -0
  24. package/dist/cli/postinstall.js +65 -0
  25. package/dist/cli/validators.d.ts +2 -0
  26. package/dist/cli/validators.js +66 -0
  27. package/dist/components/CommentOverlay.d.ts +2 -0
  28. package/dist/components/CommentOverlay.js +101 -0
  29. package/dist/components/CommentPanel.d.ts +6 -0
  30. package/dist/components/CommentPanel.js +334 -0
  31. package/dist/components/CommentPin.d.ts +11 -0
  32. package/dist/components/CommentPin.js +64 -0
  33. package/dist/components/DetailsTab.d.ts +2 -0
  34. package/dist/components/DetailsTab.js +380 -0
  35. package/dist/components/FloatingWidget.d.ts +8 -0
  36. package/dist/components/FloatingWidget.js +128 -0
  37. package/dist/components/JiraTab.d.ts +2 -0
  38. package/dist/components/JiraTab.js +507 -0
  39. package/dist/contexts/CommentContext.d.ts +30 -0
  40. package/dist/contexts/CommentContext.js +891 -0
  41. package/dist/contexts/GitHubAuthContext.d.ts +13 -0
  42. package/dist/contexts/GitHubAuthContext.js +96 -0
  43. package/dist/index.d.ts +10 -97
  44. package/dist/index.js +26 -786
  45. package/dist/services/githubAdapter.d.ts +56 -0
  46. package/dist/services/githubAdapter.js +321 -0
  47. package/dist/types/index.d.ts +25 -0
  48. package/dist/types/index.js +2 -0
  49. package/dist/utils/version.d.ts +1 -0
  50. package/dist/utils/version.js +23 -0
  51. package/package.json +39 -38
  52. package/templates/webpack-middleware.js +226 -0
  53. package/cli/dist/index.js +0 -370
  54. package/cli/dist/index.js.map +0 -1
  55. package/dist/index.d.mts +0 -97
  56. package/dist/index.js.map +0 -1
  57. package/dist/index.mjs +0 -759
  58. package/dist/index.mjs.map +0 -1
package/dist/index.mjs DELETED
@@ -1,759 +0,0 @@
1
- // src/components/CommentOverlay.tsx
2
- import * as React3 from "react";
3
- import { useLocation } from "react-router-dom";
4
-
5
- // src/contexts/CommentContext.tsx
6
- import * as React from "react";
7
- import { jsx } from "react/jsx-runtime";
8
- var CommentContext = React.createContext(void 0);
9
- var STORAGE_KEY = "hale-threads";
10
- var SHOW_PINS_KEY = "hale-show-pins";
11
- var ENABLE_COMMENTING_KEY = "hale-enable-commenting";
12
- var migrateOldComments = () => {
13
- try {
14
- const oldThreadsKey = localStorage.getItem("apollo-threads");
15
- const oldCommentsKey = localStorage.getItem("apollo-comments");
16
- if (oldThreadsKey) {
17
- const parsed = JSON.parse(oldThreadsKey);
18
- const cleanThreads = parsed.map((t) => ({
19
- id: t.id,
20
- x: t.x,
21
- y: t.y,
22
- route: t.route,
23
- comments: t.comments.map((c) => ({
24
- id: c.id,
25
- text: c.text || "",
26
- createdAt: c.createdAt,
27
- author: c.author
28
- })),
29
- version: t.version
30
- }));
31
- localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));
32
- localStorage.removeItem("apollo-threads");
33
- return cleanThreads;
34
- }
35
- if (oldCommentsKey) {
36
- const parsed = JSON.parse(oldCommentsKey);
37
- const threads = parsed.map((oldComment) => ({
38
- id: oldComment.id,
39
- x: oldComment.x,
40
- y: oldComment.y,
41
- route: oldComment.route,
42
- comments: [
43
- {
44
- id: `${oldComment.id}-comment-0`,
45
- text: oldComment.text || "",
46
- createdAt: oldComment.createdAt
47
- }
48
- ]
49
- }));
50
- localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));
51
- localStorage.removeItem("apollo-comments");
52
- return threads;
53
- }
54
- } catch (error) {
55
- console.error("Failed to migrate old comments:", error);
56
- }
57
- return [];
58
- };
59
- var CommentProvider = ({ children }) => {
60
- const [threads, setThreads] = React.useState(() => {
61
- try {
62
- const stored = localStorage.getItem(STORAGE_KEY);
63
- if (stored) {
64
- return JSON.parse(stored);
65
- }
66
- return migrateOldComments();
67
- } catch (error) {
68
- console.error("Failed to load threads from localStorage:", error);
69
- return [];
70
- }
71
- });
72
- const [showPins, setShowPins] = React.useState(() => {
73
- try {
74
- const stored = localStorage.getItem(SHOW_PINS_KEY);
75
- if (stored !== null) return stored === "true";
76
- const oldKey = localStorage.getItem("apollo-show-pins");
77
- return oldKey === "true";
78
- } catch (error) {
79
- return false;
80
- }
81
- });
82
- const [enableCommenting, setEnableCommenting] = React.useState(() => {
83
- try {
84
- const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);
85
- if (stored !== null) return stored === "true";
86
- const oldKey = localStorage.getItem("apollo-enable-commenting");
87
- return oldKey === "true";
88
- } catch (error) {
89
- return false;
90
- }
91
- });
92
- React.useEffect(() => {
93
- try {
94
- localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));
95
- } catch (error) {
96
- console.error("Failed to save threads to localStorage:", error);
97
- }
98
- }, [threads]);
99
- React.useEffect(() => {
100
- try {
101
- localStorage.setItem(SHOW_PINS_KEY, String(showPins));
102
- } catch (error) {
103
- console.error("Failed to save showPins to localStorage:", error);
104
- }
105
- }, [showPins]);
106
- React.useEffect(() => {
107
- try {
108
- localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));
109
- } catch (error) {
110
- console.error("Failed to save enableCommenting to localStorage:", error);
111
- }
112
- }, [enableCommenting]);
113
- const toggleShowPins = React.useCallback(() => {
114
- setShowPins((prev) => !prev);
115
- }, []);
116
- const toggleEnableCommenting = React.useCallback(() => {
117
- setEnableCommenting((prev) => !prev);
118
- }, []);
119
- const addThread = React.useCallback((x, y, route, version) => {
120
- const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
121
- const newThread = {
122
- id: threadId,
123
- x,
124
- y,
125
- route,
126
- comments: [],
127
- version
128
- };
129
- setThreads((prev) => [...prev, newThread]);
130
- return threadId;
131
- }, []);
132
- const addReply = React.useCallback((threadId, text) => {
133
- const commentId = `${threadId}-comment-${Date.now()}`;
134
- const newComment = {
135
- id: commentId,
136
- text,
137
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
138
- };
139
- setThreads(
140
- (prev) => prev.map((t) => {
141
- if (t.id === threadId) {
142
- return {
143
- ...t,
144
- comments: [...t.comments, newComment]
145
- };
146
- }
147
- return t;
148
- })
149
- );
150
- }, []);
151
- const updateComment = React.useCallback((threadId, commentId, text) => {
152
- setThreads(
153
- (prev) => prev.map((t) => {
154
- if (t.id === threadId) {
155
- return {
156
- ...t,
157
- comments: t.comments.map(
158
- (c) => c.id === commentId ? { ...c, text } : c
159
- )
160
- };
161
- }
162
- return t;
163
- })
164
- );
165
- }, []);
166
- const deleteComment = React.useCallback((threadId, commentId) => {
167
- setThreads(
168
- (prev) => prev.map((t) => {
169
- if (t.id === threadId) {
170
- return {
171
- ...t,
172
- comments: t.comments.filter((c) => c.id !== commentId)
173
- };
174
- }
175
- return t;
176
- })
177
- );
178
- }, []);
179
- const deleteThread = React.useCallback((threadId) => {
180
- setThreads((prev) => prev.filter((t) => t.id !== threadId));
181
- }, []);
182
- const clearAllThreads = React.useCallback(() => {
183
- setThreads([]);
184
- }, []);
185
- const getThreadsForRoute = React.useCallback((route, version) => {
186
- return threads.filter((thread) => {
187
- const routeMatch = thread.route === route;
188
- const threadVersion = thread.version || "3";
189
- const versionMatch = !version || threadVersion === version;
190
- return routeMatch && versionMatch;
191
- });
192
- }, [threads]);
193
- const value = React.useMemo(
194
- () => ({
195
- threads,
196
- showPins,
197
- enableCommenting,
198
- toggleShowPins,
199
- toggleEnableCommenting,
200
- addThread,
201
- addReply,
202
- updateComment,
203
- deleteComment,
204
- deleteThread,
205
- clearAllThreads,
206
- getThreadsForRoute
207
- }),
208
- [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]
209
- );
210
- return /* @__PURE__ */ jsx(CommentContext.Provider, { value, children });
211
- };
212
- var useComments = () => {
213
- const context = React.useContext(CommentContext);
214
- if (!context) {
215
- throw new Error("useComments must be used within a CommentProvider");
216
- }
217
- return context;
218
- };
219
-
220
- // src/contexts/VersionContext.tsx
221
- import * as React2 from "react";
222
- import { jsx as jsx2 } from "react/jsx-runtime";
223
- var VersionContext = React2.createContext(void 0);
224
- var VERSION_STORAGE_KEY = "hale-current-version";
225
- var VersionProvider = ({ children }) => {
226
- const [currentVersion, setCurrentVersionState] = React2.useState(() => {
227
- try {
228
- const stored = localStorage.getItem(VERSION_STORAGE_KEY);
229
- return stored || "3";
230
- } catch (error) {
231
- console.error("Failed to load version from localStorage:", error);
232
- return "3";
233
- }
234
- });
235
- React2.useEffect(() => {
236
- try {
237
- localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);
238
- } catch (error) {
239
- console.error("Failed to save version to localStorage:", error);
240
- }
241
- }, [currentVersion]);
242
- const setCurrentVersion = React2.useCallback((version) => {
243
- setCurrentVersionState(version);
244
- }, []);
245
- const value = React2.useMemo(
246
- () => ({
247
- currentVersion,
248
- setCurrentVersion
249
- }),
250
- [currentVersion, setCurrentVersion]
251
- );
252
- return /* @__PURE__ */ jsx2(VersionContext.Provider, { value, children });
253
- };
254
- var useVersion = () => {
255
- const context = React2.useContext(VersionContext);
256
- if (!context) {
257
- throw new Error("useVersion must be used within a VersionProvider");
258
- }
259
- return context;
260
- };
261
-
262
- // src/components/CommentPin.tsx
263
- import { Button } from "@patternfly/react-core";
264
- import { CommentIcon } from "@patternfly/react-icons";
265
- import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
266
- var CommentPin = ({
267
- thread,
268
- onPinClick,
269
- isSelected = false
270
- }) => {
271
- const commentCount = thread.comments.length;
272
- return /* @__PURE__ */ jsxs(Fragment, { children: [
273
- /* @__PURE__ */ jsx3("style", { children: `
274
- @keyframes pulse {
275
- 0%, 100% { opacity: 1; }
276
- 50% { opacity: 0.5; }
277
- }
278
- ` }),
279
- /* @__PURE__ */ jsx3(
280
- Button,
281
- {
282
- id: `comment-pin-${thread.id}`,
283
- variant: "plain",
284
- "aria-label": `Comment thread with ${commentCount} ${commentCount === 1 ? "comment" : "comments"}`,
285
- onClick: (e) => {
286
- e.stopPropagation();
287
- onPinClick();
288
- },
289
- style: {
290
- position: "absolute",
291
- left: `${thread.x}px`,
292
- top: `${thread.y}px`,
293
- transform: "translate(-50%, -50%)",
294
- width: "32px",
295
- height: "32px",
296
- borderRadius: "50%",
297
- backgroundColor: "#C9190B",
298
- color: "white",
299
- border: isSelected ? "3px solid #0066CC" : "2px solid white",
300
- boxShadow: isSelected ? "0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)" : "0 2px 8px rgba(0, 0, 0, 0.3)",
301
- padding: 0,
302
- display: "flex",
303
- alignItems: "center",
304
- justifyContent: "center",
305
- cursor: "pointer",
306
- zIndex: isSelected ? 1001 : 1e3,
307
- transition: "all 0.2s ease",
308
- fontSize: commentCount > 1 ? "0.7rem" : void 0
309
- },
310
- children: commentCount === 0 ? /* @__PURE__ */ jsx3("span", { style: { fontWeight: "bold", fontSize: "0.75rem" }, children: "0" }) : commentCount === 1 ? /* @__PURE__ */ jsx3(CommentIcon, {}) : /* @__PURE__ */ jsx3("span", { style: { fontWeight: "bold" }, children: commentCount })
311
- }
312
- )
313
- ] });
314
- };
315
-
316
- // src/components/CommentOverlay.tsx
317
- import { jsx as jsx4 } from "react/jsx-runtime";
318
- var CommentOverlay = ({
319
- selectedThreadId,
320
- onThreadSelect
321
- }) => {
322
- const location = useLocation();
323
- const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();
324
- const { currentVersion } = useVersion();
325
- const overlayRef = React3.useRef(null);
326
- const currentRouteThreads = React3.useMemo(
327
- () => getThreadsForRoute(location.pathname, currentVersion),
328
- [getThreadsForRoute, location.pathname, currentVersion]
329
- );
330
- const handleOverlayClick = React3.useCallback(
331
- (event) => {
332
- if (!enableCommenting) return;
333
- if (event.target === overlayRef.current) {
334
- const rect = overlayRef.current.getBoundingClientRect();
335
- const x = event.clientX - rect.left;
336
- const y = event.clientY - rect.top;
337
- const newThreadId = addThread(x, y, location.pathname, currentVersion);
338
- onThreadSelect(newThreadId);
339
- }
340
- },
341
- [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]
342
- );
343
- if (!showPins && !enableCommenting) {
344
- return null;
345
- }
346
- return /* @__PURE__ */ jsx4(
347
- "div",
348
- {
349
- ref: overlayRef,
350
- id: "comment-overlay",
351
- onClick: handleOverlayClick,
352
- style: {
353
- position: "absolute",
354
- top: 0,
355
- left: 0,
356
- right: 0,
357
- bottom: 0,
358
- pointerEvents: enableCommenting ? "auto" : "none",
359
- cursor: enableCommenting ? "crosshair" : "default",
360
- zIndex: 999
361
- },
362
- children: showPins && currentRouteThreads.map((thread) => /* @__PURE__ */ jsx4(
363
- "div",
364
- {
365
- style: { pointerEvents: "auto" },
366
- onClick: (e) => e.stopPropagation(),
367
- children: /* @__PURE__ */ jsx4(
368
- CommentPin,
369
- {
370
- thread,
371
- onPinClick: () => onThreadSelect(thread.id),
372
- isSelected: thread.id === selectedThreadId
373
- }
374
- )
375
- },
376
- thread.id
377
- ))
378
- }
379
- );
380
- };
381
-
382
- // src/components/CommentDrawer.tsx
383
- import * as React4 from "react";
384
- import {
385
- Drawer,
386
- DrawerContent,
387
- DrawerContentBody,
388
- DrawerPanelContent,
389
- DrawerHead,
390
- DrawerActions,
391
- DrawerCloseButton,
392
- Title,
393
- Button as Button2,
394
- TextArea,
395
- Card,
396
- CardBody,
397
- CardTitle,
398
- EmptyState,
399
- EmptyStateBody,
400
- Divider,
401
- ExpandableSection,
402
- Alert
403
- } from "@patternfly/react-core";
404
- import { CommentIcon as CommentIcon2, TimesIcon, PlusCircleIcon, MagicIcon } from "@patternfly/react-icons";
405
- import { useLocation as useLocation2 } from "react-router-dom";
406
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
407
- var CommentDrawer = ({
408
- children,
409
- selectedThreadId,
410
- onThreadSelect
411
- }) => {
412
- const location = useLocation2();
413
- const {
414
- getThreadsForRoute,
415
- addReply,
416
- updateComment,
417
- deleteComment,
418
- deleteThread,
419
- enableCommenting
420
- } = useComments();
421
- const { currentVersion } = useVersion();
422
- const [editingCommentId, setEditingCommentId] = React4.useState(null);
423
- const [editText, setEditText] = React4.useState("");
424
- const [replyText, setReplyText] = React4.useState("");
425
- const replyTextAreaRef = React4.useRef(null);
426
- const [threadSummaries, setThreadSummaries] = React4.useState({});
427
- const [loadingSummary, setLoadingSummary] = React4.useState(false);
428
- const [summaryExpanded, setSummaryExpanded] = React4.useState(true);
429
- const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);
430
- const selectedThread = currentRouteThreads.find((t) => t.id === selectedThreadId);
431
- const isDrawerOpen = selectedThreadId !== null && selectedThread !== void 0;
432
- React4.useEffect(() => {
433
- if (!isDrawerOpen || !enableCommenting) return;
434
- const timer = setTimeout(() => {
435
- replyTextAreaRef.current?.focus();
436
- }, 100);
437
- return () => clearTimeout(timer);
438
- }, [isDrawerOpen, enableCommenting, selectedThreadId]);
439
- const handleEdit = (commentId, text) => {
440
- setEditingCommentId(commentId);
441
- setEditText(text);
442
- };
443
- const handleSave = async (threadId, commentId) => {
444
- await updateComment(threadId, commentId, editText);
445
- setEditingCommentId(null);
446
- };
447
- const handleAddReply = async () => {
448
- if (selectedThreadId && replyText.trim()) {
449
- await addReply(selectedThreadId, replyText);
450
- setReplyText("");
451
- }
452
- };
453
- const handleDeleteThread = async () => {
454
- if (selectedThreadId && window.confirm("Delete this entire thread and all its comments?")) {
455
- await deleteThread(selectedThreadId);
456
- onThreadSelect(null);
457
- }
458
- };
459
- const handleSummarizeThread = async () => {
460
- console.log("AI features not available in local-only mode");
461
- };
462
- const handleDeleteComment = async (threadId, commentId) => {
463
- if (window.confirm("Delete this comment?")) {
464
- await deleteComment(threadId, commentId);
465
- }
466
- };
467
- const formatDate = (isoDate) => {
468
- const date = new Date(isoDate);
469
- return date.toLocaleString(void 0, {
470
- month: "short",
471
- day: "numeric",
472
- hour: "2-digit",
473
- minute: "2-digit"
474
- });
475
- };
476
- const panelContent = /* @__PURE__ */ jsxs2(DrawerPanelContent, { isResizable: true, defaultSize: "400px", minSize: "300px", children: [
477
- /* @__PURE__ */ jsxs2(DrawerHead, { children: [
478
- /* @__PURE__ */ jsx5("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", flex: 1 }, children: /* @__PURE__ */ jsxs2(Title, { headingLevel: "h2", size: "xl", children: [
479
- /* @__PURE__ */ jsx5(CommentIcon2, { style: { marginRight: "0.5rem", color: "#C9190B" } }),
480
- "Thread"
481
- ] }) }),
482
- /* @__PURE__ */ jsx5(DrawerActions, { children: /* @__PURE__ */ jsx5(DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
483
- ] }),
484
- /* @__PURE__ */ jsx5(DrawerContentBody, { style: { padding: "1rem" }, children: !selectedThread ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
485
- /* @__PURE__ */ jsx5(CommentIcon2, { style: { fontSize: "3rem", color: "var(--pf-v6-global--Color--200)", marginBottom: "1rem" } }),
486
- /* @__PURE__ */ jsx5(Title, { headingLevel: "h3", size: "lg", children: "No thread selected" }),
487
- /* @__PURE__ */ jsx5(EmptyStateBody, { children: "Click a pin to view its comments." })
488
- ] }) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
489
- /* @__PURE__ */ jsx5(Card, { isCompact: true, children: /* @__PURE__ */ jsxs2(CardBody, { children: [
490
- /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
491
- /* @__PURE__ */ jsx5("strong", { children: "Location:" }),
492
- " (",
493
- Math.round(selectedThread.x),
494
- ", ",
495
- Math.round(selectedThread.y),
496
- ")"
497
- ] }),
498
- selectedThread.version && /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
499
- /* @__PURE__ */ jsx5("strong", { children: "Version:" }),
500
- " ",
501
- selectedThread.version
502
- ] }),
503
- /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
504
- /* @__PURE__ */ jsx5("strong", { children: "Comments:" }),
505
- " ",
506
- selectedThread.comments.length
507
- ] }),
508
- selectedThread.comments.length > 0 && /* @__PURE__ */ jsx5(
509
- Button2,
510
- {
511
- id: `ai-summarize-thread-${selectedThread.id}`,
512
- variant: "secondary",
513
- size: "sm",
514
- icon: /* @__PURE__ */ jsx5(MagicIcon, {}),
515
- onClick: handleSummarizeThread,
516
- isLoading: loadingSummary,
517
- isDisabled: loadingSummary,
518
- style: { marginTop: "0.5rem" },
519
- children: loadingSummary ? "Generating..." : "AI Summarize Thread"
520
- }
521
- ),
522
- enableCommenting && /* @__PURE__ */ jsx5(
523
- Button2,
524
- {
525
- id: `delete-thread-${selectedThread.id}`,
526
- variant: "danger",
527
- size: "sm",
528
- icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
529
- onClick: handleDeleteThread,
530
- style: { marginTop: "0.5rem", marginLeft: selectedThread.comments.length > 0 ? "0.5rem" : "0" },
531
- children: "Delete Thread"
532
- }
533
- )
534
- ] }) }),
535
- threadSummaries[selectedThread.id] && /* @__PURE__ */ jsx5(
536
- Alert,
537
- {
538
- variant: "info",
539
- isInline: true,
540
- title: "AI Summary",
541
- actionClose: /* @__PURE__ */ jsx5(
542
- Button2,
543
- {
544
- variant: "plain",
545
- onClick: () => {
546
- const newSummaries = { ...threadSummaries };
547
- delete newSummaries[selectedThread.id];
548
- setThreadSummaries(newSummaries);
549
- },
550
- "aria-label": "Clear summary",
551
- children: /* @__PURE__ */ jsx5(TimesIcon, {})
552
- }
553
- ),
554
- children: /* @__PURE__ */ jsx5(
555
- ExpandableSection,
556
- {
557
- toggleText: summaryExpanded ? "Hide summary" : "Show summary",
558
- onToggle: (_event, isExpanded) => setSummaryExpanded(isExpanded),
559
- isExpanded: summaryExpanded,
560
- isIndented: true,
561
- children: /* @__PURE__ */ jsx5("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
562
- }
563
- )
564
- }
565
- ),
566
- /* @__PURE__ */ jsx5(Divider, {}),
567
- /* @__PURE__ */ jsx5("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: selectedThread.comments.length === 0 ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
568
- /* @__PURE__ */ jsx5(Title, { headingLevel: "h4", size: "md", children: "No comments yet" }),
569
- /* @__PURE__ */ jsx5(EmptyStateBody, { children: enableCommenting ? "Add a reply below to start the conversation." : "Enable commenting to add replies." })
570
- ] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
571
- /* @__PURE__ */ jsxs2(CardTitle, { children: [
572
- "Comment #",
573
- index + 1,
574
- /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.75rem", color: "var(--pf-v6-global--Color--200)", fontWeight: "normal" }, children: [
575
- comment.author && /* @__PURE__ */ jsxs2("span", { style: { marginRight: "0.5rem" }, children: [
576
- "@",
577
- comment.author
578
- ] }),
579
- formatDate(comment.createdAt)
580
- ] })
581
- ] }),
582
- /* @__PURE__ */ jsx5(CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
583
- /* @__PURE__ */ jsx5(
584
- TextArea,
585
- {
586
- id: `edit-comment-${comment.id}`,
587
- value: editText,
588
- onChange: (_event, value) => setEditText(value),
589
- rows: 3,
590
- style: { marginBottom: "0.5rem" },
591
- onKeyDown: (e) => {
592
- if (e.key === "Enter" && !e.shiftKey) {
593
- e.preventDefault();
594
- handleSave(selectedThread.id, comment.id);
595
- }
596
- if (e.key === "Escape") {
597
- setEditingCommentId(null);
598
- }
599
- }
600
- }
601
- ),
602
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
603
- /* @__PURE__ */ jsx5(
604
- Button2,
605
- {
606
- id: `save-comment-${comment.id}`,
607
- variant: "primary",
608
- size: "sm",
609
- onClick: () => handleSave(selectedThread.id, comment.id),
610
- children: "Save"
611
- }
612
- ),
613
- /* @__PURE__ */ jsx5(
614
- Button2,
615
- {
616
- id: `cancel-edit-${comment.id}`,
617
- variant: "link",
618
- size: "sm",
619
- onClick: () => setEditingCommentId(null),
620
- children: "Cancel"
621
- }
622
- )
623
- ] })
624
- ] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
625
- /* @__PURE__ */ jsx5("div", { style: { marginBottom: "0.75rem", whiteSpace: "pre-wrap" }, children: comment.text || /* @__PURE__ */ jsx5("em", { style: { color: "var(--pf-v6-global--Color--200)" }, children: "No text" }) }),
626
- enableCommenting && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
627
- /* @__PURE__ */ jsx5(
628
- Button2,
629
- {
630
- id: `edit-comment-btn-${comment.id}`,
631
- variant: "secondary",
632
- size: "sm",
633
- onClick: () => handleEdit(comment.id, comment.text),
634
- children: "Edit"
635
- }
636
- ),
637
- /* @__PURE__ */ jsx5(
638
- Button2,
639
- {
640
- id: `delete-comment-btn-${comment.id}`,
641
- variant: "danger",
642
- size: "sm",
643
- icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
644
- onClick: () => handleDeleteComment(selectedThread.id, comment.id),
645
- children: "Delete"
646
- }
647
- )
648
- ] })
649
- ] }) })
650
- ] }, comment.id)) }),
651
- enableCommenting && /* @__PURE__ */ jsxs2(Fragment2, { children: [
652
- /* @__PURE__ */ jsx5(Divider, {}),
653
- /* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
654
- /* @__PURE__ */ jsxs2(CardTitle, { children: [
655
- /* @__PURE__ */ jsx5(PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
656
- "Add Reply"
657
- ] }),
658
- /* @__PURE__ */ jsxs2(CardBody, { children: [
659
- /* @__PURE__ */ jsx5(
660
- TextArea,
661
- {
662
- ref: replyTextAreaRef,
663
- id: `reply-textarea-${selectedThread.id}`,
664
- value: replyText,
665
- onChange: (_event, value) => setReplyText(value),
666
- placeholder: "Enter your reply...",
667
- rows: 3,
668
- style: { marginBottom: "0.5rem" },
669
- onKeyDown: (e) => {
670
- if (e.key === "Enter" && !e.shiftKey) {
671
- e.preventDefault();
672
- handleAddReply();
673
- }
674
- }
675
- }
676
- ),
677
- /* @__PURE__ */ jsx5(
678
- Button2,
679
- {
680
- id: `add-reply-${selectedThread.id}`,
681
- variant: "primary",
682
- size: "sm",
683
- onClick: handleAddReply,
684
- isDisabled: !replyText.trim(),
685
- children: "Add Reply"
686
- }
687
- )
688
- ] })
689
- ] })
690
- ] })
691
- ] }) })
692
- ] });
693
- return /* @__PURE__ */ jsx5(Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ jsx5(DrawerContent, { panelContent, children: /* @__PURE__ */ jsx5(DrawerContentBody, { children }) }) });
694
- };
695
-
696
- // src/contexts/GitHubAuthContext.tsx
697
- import * as React5 from "react";
698
- import { jsx as jsx6 } from "react/jsx-runtime";
699
- var GitHubAuthContext = React5.createContext(void 0);
700
- var GitHubAuthProvider = ({ children }) => {
701
- const value = {
702
- user: null,
703
- isAuthenticated: false,
704
- login: () => {
705
- console.log("GitHub login not available in local mode");
706
- },
707
- logout: () => {
708
- console.log("GitHub logout not available in local mode");
709
- }
710
- };
711
- return /* @__PURE__ */ jsx6(GitHubAuthContext.Provider, { value, children });
712
- };
713
- var useGitHubAuth = () => {
714
- const context = React5.useContext(GitHubAuthContext);
715
- if (context === void 0) {
716
- throw new Error("useGitHubAuth must be used within a GitHubAuthProvider");
717
- }
718
- return context;
719
- };
720
-
721
- // src/contexts/GitLabAuthContext.tsx
722
- import * as React6 from "react";
723
- import { jsx as jsx7 } from "react/jsx-runtime";
724
- var GitLabAuthContext = React6.createContext(void 0);
725
- var GitLabAuthProvider = ({ children }) => {
726
- const value = {
727
- user: null,
728
- isAuthenticated: false,
729
- login: () => {
730
- console.log("GitLab login not available in local mode");
731
- },
732
- logout: () => {
733
- console.log("GitLab logout not available in local mode");
734
- },
735
- getToken: () => null
736
- };
737
- return /* @__PURE__ */ jsx7(GitLabAuthContext.Provider, { value, children });
738
- };
739
- var useGitLabAuth = () => {
740
- const ctx = React6.useContext(GitLabAuthContext);
741
- if (!ctx) {
742
- throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
743
- }
744
- return ctx;
745
- };
746
- export {
747
- CommentDrawer,
748
- CommentOverlay,
749
- CommentPin,
750
- CommentProvider,
751
- GitHubAuthProvider,
752
- GitLabAuthProvider,
753
- VersionProvider,
754
- useComments,
755
- useGitHubAuth,
756
- useGitLabAuth,
757
- useVersion
758
- };
759
- //# sourceMappingURL=index.mjs.map