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