hale-commenting-system 2.0.2 → 2.0.3

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.
package/dist/index.js CHANGED
@@ -426,39 +426,11 @@ var CommentOverlay = ({
426
426
  };
427
427
 
428
428
  // src/components/CommentDrawer.tsx
429
- var React5 = __toESM(require("react"));
429
+ var React4 = __toESM(require("react"));
430
430
  var import_react_core2 = require("@patternfly/react-core");
431
431
  var import_react_icons2 = require("@patternfly/react-icons");
432
432
  var import_react_router_dom2 = require("react-router-dom");
433
-
434
- // src/contexts/GitLabAuthContext.tsx
435
- var React4 = __toESM(require("react"));
436
433
  var import_jsx_runtime5 = require("react/jsx-runtime");
437
- var GitLabAuthContext = React4.createContext(void 0);
438
- var GitLabAuthProvider = ({ children }) => {
439
- const value = {
440
- user: null,
441
- isAuthenticated: false,
442
- login: () => {
443
- console.log("GitLab login not available in local mode");
444
- },
445
- logout: () => {
446
- console.log("GitLab logout not available in local mode");
447
- },
448
- getToken: () => null
449
- };
450
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GitLabAuthContext.Provider, { value, children });
451
- };
452
- var useGitLabAuth = () => {
453
- const ctx = React4.useContext(GitLabAuthContext);
454
- if (!ctx) {
455
- throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
456
- }
457
- return ctx;
458
- };
459
-
460
- // src/components/CommentDrawer.tsx
461
- var import_jsx_runtime6 = require("react/jsx-runtime");
462
434
  var CommentDrawer = ({
463
435
  children,
464
436
  selectedThreadId,
@@ -474,18 +446,17 @@ var CommentDrawer = ({
474
446
  enableCommenting
475
447
  } = useComments();
476
448
  const { currentVersion } = useVersion();
477
- const { isAuthenticated: isGitLabAuthenticated } = useGitLabAuth();
478
- const [editingCommentId, setEditingCommentId] = React5.useState(null);
479
- const [editText, setEditText] = React5.useState("");
480
- const [replyText, setReplyText] = React5.useState("");
481
- const replyTextAreaRef = React5.useRef(null);
482
- const [threadSummaries, setThreadSummaries] = React5.useState({});
483
- const [loadingSummary, setLoadingSummary] = React5.useState(false);
484
- const [summaryExpanded, setSummaryExpanded] = React5.useState(true);
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);
485
456
  const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);
486
457
  const selectedThread = currentRouteThreads.find((t) => t.id === selectedThreadId);
487
458
  const isDrawerOpen = selectedThreadId !== null && selectedThread !== void 0;
488
- React5.useEffect(() => {
459
+ React4.useEffect(() => {
489
460
  if (!isDrawerOpen || !enableCommenting) return;
490
461
  const timer = setTimeout(() => {
491
462
  replyTextAreaRef.current?.focus();
@@ -529,45 +500,45 @@ var CommentDrawer = ({
529
500
  minute: "2-digit"
530
501
  });
531
502
  };
532
- const panelContent = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.DrawerPanelContent, { isResizable: true, defaultSize: "400px", minSize: "300px", children: [
533
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.DrawerHead, { children: [
534
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.Title, { headingLevel: "h2", size: "xl", children: [
535
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.CommentIcon, { style: { marginRight: "0.5rem", color: "#C9190B" } }),
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" } }),
536
507
  "Thread"
537
508
  ] }) }),
538
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.DrawerActions, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
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) }) })
539
510
  ] }),
540
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.DrawerContentBody, { style: { padding: "1rem" }, children: !selectedThread ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.EmptyState, { children: [
541
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.CommentIcon, { style: { fontSize: "3rem", color: "var(--pf-v6-global--Color--200)", marginBottom: "1rem" } }),
542
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Title, { headingLevel: "h3", size: "lg", children: "No thread selected" }),
543
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.EmptyStateBody, { children: "Click a pin to view its comments." })
544
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
545
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Card, { isCompact: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.CardBody, { children: [
546
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
547
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Location:" }),
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:" }),
548
519
  " (",
549
520
  Math.round(selectedThread.x),
550
521
  ", ",
551
522
  Math.round(selectedThread.y),
552
523
  ")"
553
524
  ] }),
554
- selectedThread.version && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
555
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Version:" }),
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:" }),
556
527
  " ",
557
528
  selectedThread.version
558
529
  ] }),
559
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Comments:" }),
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:" }),
561
532
  " ",
562
533
  selectedThread.comments.length
563
534
  ] }),
564
- selectedThread.comments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
535
+ selectedThread.comments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
565
536
  import_react_core2.Button,
566
537
  {
567
538
  id: `ai-summarize-thread-${selectedThread.id}`,
568
539
  variant: "secondary",
569
540
  size: "sm",
570
- icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.MagicIcon, {}),
541
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.MagicIcon, {}),
571
542
  onClick: handleSummarizeThread,
572
543
  isLoading: loadingSummary,
573
544
  isDisabled: loadingSummary,
@@ -575,26 +546,26 @@ var CommentDrawer = ({
575
546
  children: loadingSummary ? "Generating..." : "AI Summarize Thread"
576
547
  }
577
548
  ),
578
- enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
549
+ enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
579
550
  import_react_core2.Button,
580
551
  {
581
552
  id: `delete-thread-${selectedThread.id}`,
582
553
  variant: "danger",
583
554
  size: "sm",
584
- icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.TimesIcon, {}),
555
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {}),
585
556
  onClick: handleDeleteThread,
586
557
  style: { marginTop: "0.5rem", marginLeft: selectedThread.comments.length > 0 ? "0.5rem" : "0" },
587
558
  children: "Delete Thread"
588
559
  }
589
560
  )
590
561
  ] }) }),
591
- threadSummaries[selectedThread.id] && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
562
+ threadSummaries[selectedThread.id] && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
592
563
  import_react_core2.Alert,
593
564
  {
594
565
  variant: "info",
595
566
  isInline: true,
596
567
  title: "AI Summary",
597
- actionClose: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
568
+ actionClose: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
598
569
  import_react_core2.Button,
599
570
  {
600
571
  variant: "plain",
@@ -604,39 +575,39 @@ var CommentDrawer = ({
604
575
  setThreadSummaries(newSummaries);
605
576
  },
606
577
  "aria-label": "Clear summary",
607
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.TimesIcon, {})
578
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {})
608
579
  }
609
580
  ),
610
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
581
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
611
582
  import_react_core2.ExpandableSection,
612
583
  {
613
584
  toggleText: summaryExpanded ? "Hide summary" : "Show summary",
614
585
  onToggle: (_event, isExpanded) => setSummaryExpanded(isExpanded),
615
586
  isExpanded: summaryExpanded,
616
587
  isIndented: true,
617
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
588
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
618
589
  }
619
590
  )
620
591
  }
621
592
  ),
622
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Divider, {}),
623
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: selectedThread.comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.EmptyState, { children: [
624
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Title, { headingLevel: "h4", size: "md", children: "No comments yet" }),
625
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.EmptyStateBody, { children: enableCommenting ? "Add a reply below to start the conversation." : "Enable commenting to add replies." })
626
- ] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.Card, { isCompact: true, children: [
627
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.CardTitle, { children: [
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: [
628
599
  "Comment #",
629
600
  index + 1,
630
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: "0.75rem", color: "var(--pf-v6-global--Color--200)", fontWeight: "normal" }, children: [
631
- comment.author && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: { marginRight: "0.5rem" }, children: [
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: [
632
603
  "@",
633
604
  comment.author
634
605
  ] }),
635
606
  formatDate(comment.createdAt)
636
607
  ] })
637
608
  ] }),
638
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
639
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
640
611
  import_react_core2.TextArea,
641
612
  {
642
613
  id: `edit-comment-${comment.id}`,
@@ -655,8 +626,8 @@ var CommentDrawer = ({
655
626
  }
656
627
  }
657
628
  ),
658
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
659
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
629
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
660
631
  import_react_core2.Button,
661
632
  {
662
633
  id: `save-comment-${comment.id}`,
@@ -666,7 +637,7 @@ var CommentDrawer = ({
666
637
  children: "Save"
667
638
  }
668
639
  ),
669
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
640
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
670
641
  import_react_core2.Button,
671
642
  {
672
643
  id: `cancel-edit-${comment.id}`,
@@ -677,10 +648,10 @@ var CommentDrawer = ({
677
648
  }
678
649
  )
679
650
  ] })
680
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
681
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginBottom: "0.75rem", whiteSpace: "pre-wrap" }, children: comment.text || /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { style: { color: "var(--pf-v6-global--Color--200)" }, children: "No text" }) }),
682
- enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: "0.5rem" }, children: [
683
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
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)(
684
655
  import_react_core2.Button,
685
656
  {
686
657
  id: `edit-comment-btn-${comment.id}`,
@@ -690,13 +661,13 @@ var CommentDrawer = ({
690
661
  children: "Edit"
691
662
  }
692
663
  ),
693
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
664
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
694
665
  import_react_core2.Button,
695
666
  {
696
667
  id: `delete-comment-btn-${comment.id}`,
697
668
  variant: "danger",
698
669
  size: "sm",
699
- icon: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.TimesIcon, {}),
670
+ icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_icons2.TimesIcon, {}),
700
671
  onClick: () => handleDeleteComment(selectedThread.id, comment.id),
701
672
  children: "Delete"
702
673
  }
@@ -704,15 +675,15 @@ var CommentDrawer = ({
704
675
  ] })
705
676
  ] }) })
706
677
  ] }, comment.id)) }),
707
- enableCommenting && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
708
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Divider, {}),
709
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.Card, { isCompact: true, children: [
710
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.CardTitle, { children: [
711
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_icons2.PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
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" } }),
712
683
  "Add Reply"
713
684
  ] }),
714
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core2.CardBody, { children: [
715
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
685
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core2.CardBody, { children: [
686
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
716
687
  import_react_core2.TextArea,
717
688
  {
718
689
  ref: replyTextAreaRef,
@@ -730,7 +701,7 @@ var CommentDrawer = ({
730
701
  }
731
702
  }
732
703
  ),
733
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
704
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
734
705
  import_react_core2.Button,
735
706
  {
736
707
  id: `add-reply-${selectedThread.id}`,
@@ -746,13 +717,13 @@ var CommentDrawer = ({
746
717
  ] })
747
718
  ] }) })
748
719
  ] });
749
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core2.DrawerContentBody, { children }) }) });
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 }) }) });
750
721
  };
751
722
 
752
723
  // src/contexts/GitHubAuthContext.tsx
753
- var React6 = __toESM(require("react"));
754
- var import_jsx_runtime7 = require("react/jsx-runtime");
755
- var GitHubAuthContext = React6.createContext(void 0);
724
+ var React5 = __toESM(require("react"));
725
+ var import_jsx_runtime6 = require("react/jsx-runtime");
726
+ var GitHubAuthContext = React5.createContext(void 0);
756
727
  var GitHubAuthProvider = ({ children }) => {
757
728
  const value = {
758
729
  user: null,
@@ -764,15 +735,41 @@ var GitHubAuthProvider = ({ children }) => {
764
735
  console.log("GitHub logout not available in local mode");
765
736
  }
766
737
  };
767
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(GitHubAuthContext.Provider, { value, children });
738
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GitHubAuthContext.Provider, { value, children });
768
739
  };
769
740
  var useGitHubAuth = () => {
770
- const context = React6.useContext(GitHubAuthContext);
741
+ const context = React5.useContext(GitHubAuthContext);
771
742
  if (context === void 0) {
772
743
  throw new Error("useGitHubAuth must be used within a GitHubAuthProvider");
773
744
  }
774
745
  return context;
775
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
+ };
776
773
  // Annotate the CommonJS export names for ESM import in node:
777
774
  0 && (module.exports = {
778
775
  CommentDrawer,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitLabAuthContext.tsx","../src/contexts/GitHubAuthContext.tsx"],"sourcesContent":["// Components\nexport { CommentOverlay } from './components/CommentOverlay';\nexport { CommentDrawer } from './components/CommentDrawer';\nexport { CommentPin } from './components/CommentPin';\n\n// Contexts / Providers\nexport { CommentProvider, useComments } from './contexts/CommentContext';\nexport { VersionProvider, useVersion } from './contexts/VersionContext';\nexport { GitHubAuthProvider, useGitHubAuth } from './contexts/GitHubAuthContext';\nexport { GitLabAuthProvider, useGitLabAuth } from './contexts/GitLabAuthContext';\n\n// Types\nexport type { \n Comment, \n Thread\n} from './contexts/CommentContext';\n","import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\nimport { useGitLabAuth } from '../contexts/GitLabAuthContext';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n const { isAuthenticated: isGitLabAuthenticated } = useGitLabAuth();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n"],"mappings":"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","names":["React","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react_core","import_react_icons","import_react_router_dom","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitHubAuthContext.tsx","../src/contexts/GitLabAuthContext.tsx"],"sourcesContent":["// Components\nexport { CommentOverlay } from './components/CommentOverlay';\nexport { CommentDrawer } from './components/CommentDrawer';\nexport { CommentPin } from './components/CommentPin';\n\n// Contexts / Providers\nexport { CommentProvider, useComments } from './contexts/CommentContext';\nexport { VersionProvider, useVersion } from './contexts/VersionContext';\nexport { GitHubAuthProvider, useGitHubAuth } from './contexts/GitHubAuthContext';\nexport { GitLabAuthProvider, useGitLabAuth } from './contexts/GitLabAuthContext';\n\n// Types\nexport type { \n Comment, \n Thread\n} from './contexts/CommentContext';\n","import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n"],"mappings":"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","names":["React","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_react_core","import_react_icons","import_react_router_dom","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -380,7 +380,7 @@ var CommentOverlay = ({
380
380
  };
381
381
 
382
382
  // src/components/CommentDrawer.tsx
383
- import * as React5 from "react";
383
+ import * as React4 from "react";
384
384
  import {
385
385
  Drawer,
386
386
  DrawerContent,
@@ -403,35 +403,7 @@ import {
403
403
  } from "@patternfly/react-core";
404
404
  import { CommentIcon as CommentIcon2, TimesIcon, PlusCircleIcon, MagicIcon } from "@patternfly/react-icons";
405
405
  import { useLocation as useLocation2 } from "react-router-dom";
406
-
407
- // src/contexts/GitLabAuthContext.tsx
408
- import * as React4 from "react";
409
- import { jsx as jsx5 } from "react/jsx-runtime";
410
- var GitLabAuthContext = React4.createContext(void 0);
411
- var GitLabAuthProvider = ({ children }) => {
412
- const value = {
413
- user: null,
414
- isAuthenticated: false,
415
- login: () => {
416
- console.log("GitLab login not available in local mode");
417
- },
418
- logout: () => {
419
- console.log("GitLab logout not available in local mode");
420
- },
421
- getToken: () => null
422
- };
423
- return /* @__PURE__ */ jsx5(GitLabAuthContext.Provider, { value, children });
424
- };
425
- var useGitLabAuth = () => {
426
- const ctx = React4.useContext(GitLabAuthContext);
427
- if (!ctx) {
428
- throw new Error("useGitLabAuth must be used within a GitLabAuthProvider");
429
- }
430
- return ctx;
431
- };
432
-
433
- // src/components/CommentDrawer.tsx
434
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
406
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
435
407
  var CommentDrawer = ({
436
408
  children,
437
409
  selectedThreadId,
@@ -447,18 +419,17 @@ var CommentDrawer = ({
447
419
  enableCommenting
448
420
  } = useComments();
449
421
  const { currentVersion } = useVersion();
450
- const { isAuthenticated: isGitLabAuthenticated } = useGitLabAuth();
451
- const [editingCommentId, setEditingCommentId] = React5.useState(null);
452
- const [editText, setEditText] = React5.useState("");
453
- const [replyText, setReplyText] = React5.useState("");
454
- const replyTextAreaRef = React5.useRef(null);
455
- const [threadSummaries, setThreadSummaries] = React5.useState({});
456
- const [loadingSummary, setLoadingSummary] = React5.useState(false);
457
- const [summaryExpanded, setSummaryExpanded] = React5.useState(true);
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);
458
429
  const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);
459
430
  const selectedThread = currentRouteThreads.find((t) => t.id === selectedThreadId);
460
431
  const isDrawerOpen = selectedThreadId !== null && selectedThread !== void 0;
461
- React5.useEffect(() => {
432
+ React4.useEffect(() => {
462
433
  if (!isDrawerOpen || !enableCommenting) return;
463
434
  const timer = setTimeout(() => {
464
435
  replyTextAreaRef.current?.focus();
@@ -504,20 +475,20 @@ var CommentDrawer = ({
504
475
  };
505
476
  const panelContent = /* @__PURE__ */ jsxs2(DrawerPanelContent, { isResizable: true, defaultSize: "400px", minSize: "300px", children: [
506
477
  /* @__PURE__ */ jsxs2(DrawerHead, { children: [
507
- /* @__PURE__ */ jsx6("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", flex: 1 }, children: /* @__PURE__ */ jsxs2(Title, { headingLevel: "h2", size: "xl", children: [
508
- /* @__PURE__ */ jsx6(CommentIcon2, { style: { marginRight: "0.5rem", color: "#C9190B" } }),
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" } }),
509
480
  "Thread"
510
481
  ] }) }),
511
- /* @__PURE__ */ jsx6(DrawerActions, { children: /* @__PURE__ */ jsx6(DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
482
+ /* @__PURE__ */ jsx5(DrawerActions, { children: /* @__PURE__ */ jsx5(DrawerCloseButton, { onClick: () => onThreadSelect(null) }) })
512
483
  ] }),
513
- /* @__PURE__ */ jsx6(DrawerContentBody, { style: { padding: "1rem" }, children: !selectedThread ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
514
- /* @__PURE__ */ jsx6(CommentIcon2, { style: { fontSize: "3rem", color: "var(--pf-v6-global--Color--200)", marginBottom: "1rem" } }),
515
- /* @__PURE__ */ jsx6(Title, { headingLevel: "h3", size: "lg", children: "No thread selected" }),
516
- /* @__PURE__ */ jsx6(EmptyStateBody, { children: "Click a pin to view its comments." })
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." })
517
488
  ] }) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
518
- /* @__PURE__ */ jsx6(Card, { isCompact: true, children: /* @__PURE__ */ jsxs2(CardBody, { children: [
489
+ /* @__PURE__ */ jsx5(Card, { isCompact: true, children: /* @__PURE__ */ jsxs2(CardBody, { children: [
519
490
  /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
520
- /* @__PURE__ */ jsx6("strong", { children: "Location:" }),
491
+ /* @__PURE__ */ jsx5("strong", { children: "Location:" }),
521
492
  " (",
522
493
  Math.round(selectedThread.x),
523
494
  ", ",
@@ -525,22 +496,22 @@ var CommentDrawer = ({
525
496
  ")"
526
497
  ] }),
527
498
  selectedThread.version && /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
528
- /* @__PURE__ */ jsx6("strong", { children: "Version:" }),
499
+ /* @__PURE__ */ jsx5("strong", { children: "Version:" }),
529
500
  " ",
530
501
  selectedThread.version
531
502
  ] }),
532
503
  /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", marginBottom: "0.5rem" }, children: [
533
- /* @__PURE__ */ jsx6("strong", { children: "Comments:" }),
504
+ /* @__PURE__ */ jsx5("strong", { children: "Comments:" }),
534
505
  " ",
535
506
  selectedThread.comments.length
536
507
  ] }),
537
- selectedThread.comments.length > 0 && /* @__PURE__ */ jsx6(
508
+ selectedThread.comments.length > 0 && /* @__PURE__ */ jsx5(
538
509
  Button2,
539
510
  {
540
511
  id: `ai-summarize-thread-${selectedThread.id}`,
541
512
  variant: "secondary",
542
513
  size: "sm",
543
- icon: /* @__PURE__ */ jsx6(MagicIcon, {}),
514
+ icon: /* @__PURE__ */ jsx5(MagicIcon, {}),
544
515
  onClick: handleSummarizeThread,
545
516
  isLoading: loadingSummary,
546
517
  isDisabled: loadingSummary,
@@ -548,26 +519,26 @@ var CommentDrawer = ({
548
519
  children: loadingSummary ? "Generating..." : "AI Summarize Thread"
549
520
  }
550
521
  ),
551
- enableCommenting && /* @__PURE__ */ jsx6(
522
+ enableCommenting && /* @__PURE__ */ jsx5(
552
523
  Button2,
553
524
  {
554
525
  id: `delete-thread-${selectedThread.id}`,
555
526
  variant: "danger",
556
527
  size: "sm",
557
- icon: /* @__PURE__ */ jsx6(TimesIcon, {}),
528
+ icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
558
529
  onClick: handleDeleteThread,
559
530
  style: { marginTop: "0.5rem", marginLeft: selectedThread.comments.length > 0 ? "0.5rem" : "0" },
560
531
  children: "Delete Thread"
561
532
  }
562
533
  )
563
534
  ] }) }),
564
- threadSummaries[selectedThread.id] && /* @__PURE__ */ jsx6(
535
+ threadSummaries[selectedThread.id] && /* @__PURE__ */ jsx5(
565
536
  Alert,
566
537
  {
567
538
  variant: "info",
568
539
  isInline: true,
569
540
  title: "AI Summary",
570
- actionClose: /* @__PURE__ */ jsx6(
541
+ actionClose: /* @__PURE__ */ jsx5(
571
542
  Button2,
572
543
  {
573
544
  variant: "plain",
@@ -577,25 +548,25 @@ var CommentDrawer = ({
577
548
  setThreadSummaries(newSummaries);
578
549
  },
579
550
  "aria-label": "Clear summary",
580
- children: /* @__PURE__ */ jsx6(TimesIcon, {})
551
+ children: /* @__PURE__ */ jsx5(TimesIcon, {})
581
552
  }
582
553
  ),
583
- children: /* @__PURE__ */ jsx6(
554
+ children: /* @__PURE__ */ jsx5(
584
555
  ExpandableSection,
585
556
  {
586
557
  toggleText: summaryExpanded ? "Hide summary" : "Show summary",
587
558
  onToggle: (_event, isExpanded) => setSummaryExpanded(isExpanded),
588
559
  isExpanded: summaryExpanded,
589
560
  isIndented: true,
590
- children: /* @__PURE__ */ jsx6("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
561
+ children: /* @__PURE__ */ jsx5("div", { style: { fontSize: "0.875rem", lineHeight: "1.5" }, children: threadSummaries[selectedThread.id] })
591
562
  }
592
563
  )
593
564
  }
594
565
  ),
595
- /* @__PURE__ */ jsx6(Divider, {}),
596
- /* @__PURE__ */ jsx6("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: selectedThread.comments.length === 0 ? /* @__PURE__ */ jsxs2(EmptyState, { children: [
597
- /* @__PURE__ */ jsx6(Title, { headingLevel: "h4", size: "md", children: "No comments yet" }),
598
- /* @__PURE__ */ jsx6(EmptyStateBody, { children: enableCommenting ? "Add a reply below to start the conversation." : "Enable commenting to add replies." })
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." })
599
570
  ] }) : selectedThread.comments.map((comment, index) => /* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
600
571
  /* @__PURE__ */ jsxs2(CardTitle, { children: [
601
572
  "Comment #",
@@ -608,8 +579,8 @@ var CommentDrawer = ({
608
579
  formatDate(comment.createdAt)
609
580
  ] })
610
581
  ] }),
611
- /* @__PURE__ */ jsx6(CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
612
- /* @__PURE__ */ jsx6(
582
+ /* @__PURE__ */ jsx5(CardBody, { children: editingCommentId === comment.id ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
583
+ /* @__PURE__ */ jsx5(
613
584
  TextArea,
614
585
  {
615
586
  id: `edit-comment-${comment.id}`,
@@ -629,7 +600,7 @@ var CommentDrawer = ({
629
600
  }
630
601
  ),
631
602
  /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
632
- /* @__PURE__ */ jsx6(
603
+ /* @__PURE__ */ jsx5(
633
604
  Button2,
634
605
  {
635
606
  id: `save-comment-${comment.id}`,
@@ -639,7 +610,7 @@ var CommentDrawer = ({
639
610
  children: "Save"
640
611
  }
641
612
  ),
642
- /* @__PURE__ */ jsx6(
613
+ /* @__PURE__ */ jsx5(
643
614
  Button2,
644
615
  {
645
616
  id: `cancel-edit-${comment.id}`,
@@ -651,9 +622,9 @@ var CommentDrawer = ({
651
622
  )
652
623
  ] })
653
624
  ] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
654
- /* @__PURE__ */ jsx6("div", { style: { marginBottom: "0.75rem", whiteSpace: "pre-wrap" }, children: comment.text || /* @__PURE__ */ jsx6("em", { style: { color: "var(--pf-v6-global--Color--200)" }, children: "No text" }) }),
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" }) }),
655
626
  enableCommenting && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "0.5rem" }, children: [
656
- /* @__PURE__ */ jsx6(
627
+ /* @__PURE__ */ jsx5(
657
628
  Button2,
658
629
  {
659
630
  id: `edit-comment-btn-${comment.id}`,
@@ -663,13 +634,13 @@ var CommentDrawer = ({
663
634
  children: "Edit"
664
635
  }
665
636
  ),
666
- /* @__PURE__ */ jsx6(
637
+ /* @__PURE__ */ jsx5(
667
638
  Button2,
668
639
  {
669
640
  id: `delete-comment-btn-${comment.id}`,
670
641
  variant: "danger",
671
642
  size: "sm",
672
- icon: /* @__PURE__ */ jsx6(TimesIcon, {}),
643
+ icon: /* @__PURE__ */ jsx5(TimesIcon, {}),
673
644
  onClick: () => handleDeleteComment(selectedThread.id, comment.id),
674
645
  children: "Delete"
675
646
  }
@@ -678,14 +649,14 @@ var CommentDrawer = ({
678
649
  ] }) })
679
650
  ] }, comment.id)) }),
680
651
  enableCommenting && /* @__PURE__ */ jsxs2(Fragment2, { children: [
681
- /* @__PURE__ */ jsx6(Divider, {}),
652
+ /* @__PURE__ */ jsx5(Divider, {}),
682
653
  /* @__PURE__ */ jsxs2(Card, { isCompact: true, children: [
683
654
  /* @__PURE__ */ jsxs2(CardTitle, { children: [
684
- /* @__PURE__ */ jsx6(PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
655
+ /* @__PURE__ */ jsx5(PlusCircleIcon, { style: { marginRight: "0.5rem" } }),
685
656
  "Add Reply"
686
657
  ] }),
687
658
  /* @__PURE__ */ jsxs2(CardBody, { children: [
688
- /* @__PURE__ */ jsx6(
659
+ /* @__PURE__ */ jsx5(
689
660
  TextArea,
690
661
  {
691
662
  ref: replyTextAreaRef,
@@ -703,7 +674,7 @@ var CommentDrawer = ({
703
674
  }
704
675
  }
705
676
  ),
706
- /* @__PURE__ */ jsx6(
677
+ /* @__PURE__ */ jsx5(
707
678
  Button2,
708
679
  {
709
680
  id: `add-reply-${selectedThread.id}`,
@@ -719,13 +690,13 @@ var CommentDrawer = ({
719
690
  ] })
720
691
  ] }) })
721
692
  ] });
722
- return /* @__PURE__ */ jsx6(Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ jsx6(DrawerContent, { panelContent, children: /* @__PURE__ */ jsx6(DrawerContentBody, { children }) }) });
693
+ return /* @__PURE__ */ jsx5(Drawer, { isExpanded: isDrawerOpen, isInline: true, position: "right", children: /* @__PURE__ */ jsx5(DrawerContent, { panelContent, children: /* @__PURE__ */ jsx5(DrawerContentBody, { children }) }) });
723
694
  };
724
695
 
725
696
  // src/contexts/GitHubAuthContext.tsx
726
- import * as React6 from "react";
727
- import { jsx as jsx7 } from "react/jsx-runtime";
728
- var GitHubAuthContext = React6.createContext(void 0);
697
+ import * as React5 from "react";
698
+ import { jsx as jsx6 } from "react/jsx-runtime";
699
+ var GitHubAuthContext = React5.createContext(void 0);
729
700
  var GitHubAuthProvider = ({ children }) => {
730
701
  const value = {
731
702
  user: null,
@@ -737,15 +708,41 @@ var GitHubAuthProvider = ({ children }) => {
737
708
  console.log("GitHub logout not available in local mode");
738
709
  }
739
710
  };
740
- return /* @__PURE__ */ jsx7(GitHubAuthContext.Provider, { value, children });
711
+ return /* @__PURE__ */ jsx6(GitHubAuthContext.Provider, { value, children });
741
712
  };
742
713
  var useGitHubAuth = () => {
743
- const context = React6.useContext(GitHubAuthContext);
714
+ const context = React5.useContext(GitHubAuthContext);
744
715
  if (context === void 0) {
745
716
  throw new Error("useGitHubAuth must be used within a GitHubAuthProvider");
746
717
  }
747
718
  return context;
748
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
+ };
749
746
  export {
750
747
  CommentDrawer,
751
748
  CommentOverlay,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitLabAuthContext.tsx","../src/contexts/GitHubAuthContext.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\nimport { useGitLabAuth } from '../contexts/GitLabAuthContext';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n const { isAuthenticated: isGitLabAuthenticated } = useGitLabAuth();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n"],"mappings":"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","names":["React","React","jsx","jsx","jsx","React","Button","CommentIcon","useLocation","React","jsx","Fragment","jsx","jsxs","useLocation","CommentIcon","Button","React","jsx"]}
1
+ {"version":3,"sources":["../src/components/CommentOverlay.tsx","../src/contexts/CommentContext.tsx","../src/contexts/VersionContext.tsx","../src/components/CommentPin.tsx","../src/components/CommentDrawer.tsx","../src/contexts/GitHubAuthContext.tsx","../src/contexts/GitLabAuthContext.tsx"],"sourcesContent":["import * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { CommentPin } from './CommentPin';\n\ninterface CommentOverlayProps {\n selectedThreadId: string | null;\n onThreadSelect: (id: string) => void;\n}\n\nexport const CommentOverlay: React.FunctionComponent<CommentOverlayProps> = ({\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { showPins, enableCommenting, addThread, getThreadsForRoute } = useComments();\n const { currentVersion } = useVersion();\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n const currentRouteThreads = React.useMemo(\n () => getThreadsForRoute(location.pathname, currentVersion),\n [getThreadsForRoute, location.pathname, currentVersion]\n );\n\n const handleOverlayClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n if (!enableCommenting) return;\n\n // Only add thread if clicking the overlay itself, not a pin\n if (event.target === overlayRef.current) {\n const rect = overlayRef.current.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const newThreadId = addThread(x, y, location.pathname, currentVersion);\n \n // Auto-open the drawer for the newly created thread\n onThreadSelect(newThreadId);\n }\n },\n [enableCommenting, addThread, location.pathname, currentVersion, onThreadSelect]\n );\n\n // Don't render anything if neither showPins nor enableCommenting are true\n if (!showPins && !enableCommenting) {\n return null;\n }\n\n return (\n <div\n ref={overlayRef}\n id=\"comment-overlay\"\n onClick={handleOverlayClick}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n pointerEvents: enableCommenting ? 'auto' : 'none',\n cursor: enableCommenting ? 'crosshair' : 'default',\n zIndex: 999\n }}\n >\n {showPins && currentRouteThreads.map((thread) => (\n <div\n key={thread.id}\n style={{ pointerEvents: 'auto' }}\n onClick={(e) => e.stopPropagation()}\n >\n <CommentPin\n thread={thread}\n onPinClick={() => onThreadSelect(thread.id)}\n isSelected={thread.id === selectedThreadId}\n />\n </div>\n ))}\n </div>\n );\n};\n\n","import * as React from 'react';\n\nexport interface Comment {\n id: string;\n author?: string;\n text: string;\n createdAt: string;\n}\n\nexport interface Thread {\n id: string;\n x: number;\n y: number;\n route: string;\n comments: Comment[];\n version?: string;\n}\n\ninterface CommentContextType {\n threads: Thread[];\n showPins: boolean;\n enableCommenting: boolean;\n toggleShowPins: () => void;\n toggleEnableCommenting: () => void;\n addThread: (x: number, y: number, route: string, version?: string) => string;\n addReply: (threadId: string, text: string) => void;\n updateComment: (threadId: string, commentId: string, text: string) => void;\n deleteComment: (threadId: string, commentId: string) => void;\n deleteThread: (threadId: string) => void;\n clearAllThreads: () => void;\n getThreadsForRoute: (route: string, version?: string) => Thread[];\n}\n\nconst CommentContext = React.createContext<CommentContextType | undefined>(undefined);\n\nconst STORAGE_KEY = 'hale-threads';\nconst SHOW_PINS_KEY = 'hale-show-pins';\nconst ENABLE_COMMENTING_KEY = 'hale-enable-commenting';\n\n// Migration function to convert old Apollo comments to Hale threads\nconst migrateOldComments = (): Thread[] => {\n try {\n const oldThreadsKey = localStorage.getItem('apollo-threads');\n const oldCommentsKey = localStorage.getItem('apollo-comments');\n \n // Try apollo-threads first (newer format)\n if (oldThreadsKey) {\n const parsed = JSON.parse(oldThreadsKey);\n // Clean up sync-related fields\n const cleanThreads: Thread[] = parsed.map((t: any) => ({\n id: t.id,\n x: t.x,\n y: t.y,\n route: t.route,\n comments: t.comments.map((c: any) => ({\n id: c.id,\n text: c.text || '',\n createdAt: c.createdAt,\n author: c.author\n })),\n version: t.version\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(cleanThreads));\n localStorage.removeItem('apollo-threads');\n return cleanThreads;\n }\n \n // Fallback to old apollo-comments format (oldest)\n if (oldCommentsKey) {\n const parsed = JSON.parse(oldCommentsKey);\n const threads: Thread[] = parsed.map((oldComment: any) => ({\n id: oldComment.id,\n x: oldComment.x,\n y: oldComment.y,\n route: oldComment.route,\n comments: [\n {\n id: `${oldComment.id}-comment-0`,\n text: oldComment.text || '',\n createdAt: oldComment.createdAt\n }\n ]\n }));\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n localStorage.removeItem('apollo-comments');\n return threads;\n }\n } catch (error) {\n console.error('Failed to migrate old comments:', error);\n }\n return [];\n};\n\nexport const CommentProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n // Load initial state from localStorage with migration\n const [threads, setThreads] = React.useState<Thread[]>(() => {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n // Try to migrate old comments\n return migrateOldComments();\n } catch (error) {\n console.error('Failed to load threads from localStorage:', error);\n return [];\n }\n });\n\n const [showPins, setShowPins] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(SHOW_PINS_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-show-pins');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n const [enableCommenting, setEnableCommenting] = React.useState<boolean>(() => {\n try {\n const stored = localStorage.getItem(ENABLE_COMMENTING_KEY);\n if (stored !== null) return stored === 'true';\n // Check old key for migration\n const oldKey = localStorage.getItem('apollo-enable-commenting');\n return oldKey === 'true';\n } catch (error) {\n return false;\n }\n });\n\n // Persist threads to localStorage whenever they change\n React.useEffect(() => {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(threads));\n } catch (error) {\n console.error('Failed to save threads to localStorage:', error);\n }\n }, [threads]);\n\n // Persist showPins to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(SHOW_PINS_KEY, String(showPins));\n } catch (error) {\n console.error('Failed to save showPins to localStorage:', error);\n }\n }, [showPins]);\n\n // Persist enableCommenting to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(ENABLE_COMMENTING_KEY, String(enableCommenting));\n } catch (error) {\n console.error('Failed to save enableCommenting to localStorage:', error);\n }\n }, [enableCommenting]);\n\n const toggleShowPins = React.useCallback(() => {\n setShowPins(prev => !prev);\n }, []);\n\n const toggleEnableCommenting = React.useCallback(() => {\n setEnableCommenting(prev => !prev);\n }, []);\n\n const addThread = React.useCallback((x: number, y: number, route: string, version?: string): string => {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newThread: Thread = {\n id: threadId,\n x,\n y,\n route,\n comments: [],\n version\n };\n setThreads(prev => [...prev, newThread]);\n return threadId;\n }, []);\n\n const addReply = React.useCallback((threadId: string, text: string) => {\n const commentId = `${threadId}-comment-${Date.now()}`;\n const newComment: Comment = {\n id: commentId,\n text,\n createdAt: new Date().toISOString()\n };\n\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: [...t.comments, newComment]\n };\n }\n return t;\n })\n );\n }, []);\n\n const updateComment = React.useCallback((threadId: string, commentId: string, text: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.map(c =>\n c.id === commentId ? { ...c, text } : c\n )\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteComment = React.useCallback((threadId: string, commentId: string) => {\n setThreads(prev =>\n prev.map(t => {\n if (t.id === threadId) {\n return {\n ...t,\n comments: t.comments.filter(c => c.id !== commentId)\n };\n }\n return t;\n })\n );\n }, []);\n\n const deleteThread = React.useCallback((threadId: string) => {\n setThreads(prev => prev.filter(t => t.id !== threadId));\n }, []);\n\n const clearAllThreads = React.useCallback(() => {\n setThreads([]);\n }, []);\n\n const getThreadsForRoute = React.useCallback((route: string, version?: string): Thread[] => {\n return threads.filter(thread => {\n const routeMatch = thread.route === route;\n // Treat legacy comments (without version) as Version 3 (current)\n const threadVersion = thread.version || '3';\n const versionMatch = !version || threadVersion === version;\n return routeMatch && versionMatch;\n });\n }, [threads]);\n\n const value = React.useMemo(\n () => ({\n threads,\n showPins,\n enableCommenting,\n toggleShowPins,\n toggleEnableCommenting,\n addThread,\n addReply,\n updateComment,\n deleteComment,\n deleteThread,\n clearAllThreads,\n getThreadsForRoute\n }),\n [threads, showPins, enableCommenting, toggleShowPins, toggleEnableCommenting, addThread, addReply, updateComment, deleteComment, deleteThread, clearAllThreads, getThreadsForRoute]\n );\n\n return <CommentContext.Provider value={value}>{children}</CommentContext.Provider>;\n};\n\nexport const useComments = (): CommentContextType => {\n const context = React.useContext(CommentContext);\n if (!context) {\n throw new Error('useComments must be used within a CommentProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface VersionContextType {\n currentVersion: string;\n setCurrentVersion: (version: string) => void;\n}\n\nconst VersionContext = React.createContext<VersionContextType | undefined>(undefined);\n\nconst VERSION_STORAGE_KEY = 'hale-current-version';\n\nexport const VersionProvider: React.FunctionComponent<{ children: React.ReactNode }> = ({ children }) => {\n const [currentVersion, setCurrentVersionState] = React.useState<string>(() => {\n try {\n const stored = localStorage.getItem(VERSION_STORAGE_KEY);\n return stored || '3'; // Default to version 3 (current)\n } catch (error) {\n console.error('Failed to load version from localStorage:', error);\n return '3';\n }\n });\n\n // Persist version to localStorage\n React.useEffect(() => {\n try {\n localStorage.setItem(VERSION_STORAGE_KEY, currentVersion);\n } catch (error) {\n console.error('Failed to save version to localStorage:', error);\n }\n }, [currentVersion]);\n\n const setCurrentVersion = React.useCallback((version: string) => {\n setCurrentVersionState(version);\n }, []);\n\n const value = React.useMemo(\n () => ({\n currentVersion,\n setCurrentVersion,\n }),\n [currentVersion, setCurrentVersion]\n );\n\n return <VersionContext.Provider value={value}>{children}</VersionContext.Provider>;\n};\n\nexport const useVersion = (): VersionContextType => {\n const context = React.useContext(VersionContext);\n if (!context) {\n throw new Error('useVersion must be used within a VersionProvider');\n }\n return context;\n};\n\n","import * as React from 'react';\nimport { Button } from '@patternfly/react-core';\nimport { CommentIcon, ExclamationTriangleIcon } from '@patternfly/react-icons';\nimport { Thread } from '../contexts/CommentContext';\n\ninterface CommentPinProps {\n thread: Thread;\n onPinClick: () => void;\n isSelected?: boolean;\n}\n\nexport const CommentPin: React.FunctionComponent<CommentPinProps> = ({ \n thread, \n onPinClick,\n isSelected = false\n}) => {\n const commentCount = thread.comments.length;\n // Sync status removed in local-only version\n\n return (\n <>\n <style>\n {`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}\n </style>\n <Button\n id={`comment-pin-${thread.id}`}\n variant=\"plain\"\n aria-label={`Comment thread with ${commentCount} ${commentCount === 1 ? 'comment' : 'comments'}`}\n onClick={(e) => {\n e.stopPropagation();\n onPinClick();\n }}\n style={{\n position: 'absolute',\n left: `${thread.x}px`,\n top: `${thread.y}px`,\n transform: 'translate(-50%, -50%)',\n width: '32px',\n height: '32px',\n borderRadius: '50%',\n backgroundColor: '#C9190B',\n color: 'white',\n border: isSelected ? '3px solid #0066CC' : '2px solid white',\n boxShadow: isSelected \n ? '0 0 0 2px #0066CC, 0 4px 12px rgba(0, 0, 0, 0.4)'\n : '0 2px 8px rgba(0, 0, 0, 0.3)',\n padding: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n zIndex: isSelected ? 1001 : 1000,\n transition: 'all 0.2s ease',\n fontSize: commentCount > 1 ? '0.7rem' : undefined\n }}\n >\n {commentCount === 0 ? (\n <span style={{ fontWeight: 'bold', fontSize: '0.75rem' }}>0</span>\n ) : commentCount === 1 ? (\n <CommentIcon />\n ) : (\n <span style={{ fontWeight: 'bold' }}>{commentCount}</span>\n )}\n </Button>\n </>\n );\n};\n\n","import * as React from 'react';\nimport {\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelContent,\n DrawerHead,\n DrawerActions,\n DrawerCloseButton,\n Title,\n Button,\n TextArea,\n Card,\n CardBody,\n CardTitle,\n EmptyState,\n EmptyStateBody,\n Divider,\n Label,\n Spinner,\n ExpandableSection,\n Alert\n} from '@patternfly/react-core';\nimport { CommentIcon, TimesIcon, PlusCircleIcon, SyncAltIcon, GithubIcon, ExternalLinkAltIcon, RedoIcon, MagicIcon, InfoCircleIcon } from '@patternfly/react-icons';\nimport { useComments } from '../contexts/CommentContext';\nimport { useVersion } from '../contexts/VersionContext';\nimport { useLocation } from 'react-router-dom';\n\ninterface CommentDrawerProps {\n children: React.ReactNode;\n selectedThreadId: string | null;\n onThreadSelect: (id: string | null) => void;\n}\n\nexport const CommentDrawer: React.FunctionComponent<CommentDrawerProps> = ({\n children,\n selectedThreadId,\n onThreadSelect\n}) => {\n const location = useLocation();\n const { \n getThreadsForRoute, \n addReply, \n updateComment, \n deleteComment,\n deleteThread,\n enableCommenting\n } = useComments();\n const { currentVersion } = useVersion();\n \n const [editingCommentId, setEditingCommentId] = React.useState<string | null>(null);\n const [editText, setEditText] = React.useState('');\n const [replyText, setReplyText] = React.useState('');\n const replyTextAreaRef = React.useRef<HTMLTextAreaElement>(null);\n \n // AI Summary state\n const [threadSummaries, setThreadSummaries] = React.useState<Record<string, string>>({});\n const [loadingSummary, setLoadingSummary] = React.useState(false);\n const [summaryExpanded, setSummaryExpanded] = React.useState(true);\n\n const currentRouteThreads = getThreadsForRoute(location.pathname, currentVersion);\n const selectedThread = currentRouteThreads.find(t => t.id === selectedThreadId);\n const isDrawerOpen = selectedThreadId !== null && selectedThread !== undefined;\n\n // Auto-focus reply textarea when drawer opens and commenting is enabled\n React.useEffect(() => {\n if (!isDrawerOpen || !enableCommenting) return;\n \n // Small delay to ensure drawer animation completes\n const timer = setTimeout(() => {\n replyTextAreaRef.current?.focus();\n }, 100);\n \n return () => clearTimeout(timer);\n }, [isDrawerOpen, enableCommenting, selectedThreadId]);\n\n // Note: Sync functionality removed in local-only version\n\n const handleEdit = (commentId: string, text: string) => {\n setEditingCommentId(commentId);\n setEditText(text);\n };\n\n const handleSave = async (threadId: string, commentId: string) => {\n await updateComment(threadId, commentId, editText);\n setEditingCommentId(null);\n };\n\n const handleAddReply = async () => {\n if (selectedThreadId && replyText.trim()) {\n await addReply(selectedThreadId, replyText);\n setReplyText('');\n }\n };\n\n const handleDeleteThread = async () => {\n if (selectedThreadId && window.confirm('Delete this entire thread and all its comments?')) {\n await deleteThread(selectedThreadId);\n onThreadSelect(null);\n }\n };\n\n const handleSummarizeThread = async () => {\n // AI summarization removed in local-only version\n console.log('AI features not available in local-only mode');\n };\n\n const handleDeleteComment = async (threadId: string, commentId: string) => {\n if (window.confirm('Delete this comment?')) {\n await deleteComment(threadId, commentId);\n }\n };\n\n // Sync handlers removed in local-only version\n\n const formatDate = (isoDate: string): string => {\n const date = new Date(isoDate);\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize=\"400px\" minSize=\"300px\">\n <DrawerHead>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', flex: 1 }}>\n <Title headingLevel=\"h2\" size=\"xl\">\n <CommentIcon style={{ marginRight: '0.5rem', color: '#C9190B' }} />\n Thread\n </Title>\n {/* Sync buttons removed in local-only version */}\n </div>\n <DrawerActions>\n <DrawerCloseButton onClick={() => onThreadSelect(null)} />\n </DrawerActions>\n </DrawerHead>\n <DrawerContentBody style={{ padding: '1rem' }}>\n {!selectedThread ? (\n <EmptyState>\n <CommentIcon style={{ fontSize: '3rem', color: 'var(--pf-v6-global--Color--200)', marginBottom: '1rem' }} />\n <Title headingLevel=\"h3\" size=\"lg\">\n No thread selected\n </Title>\n <EmptyStateBody>\n Click a pin to view its comments.\n </EmptyStateBody>\n </EmptyState>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {/* Thread Info */}\n <Card isCompact>\n <CardBody>\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Location:</strong> ({Math.round(selectedThread.x)}, {Math.round(selectedThread.y)})\n </div>\n {selectedThread.version && (\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Version:</strong> {selectedThread.version}\n </div>\n )}\n <div style={{ fontSize: '0.875rem', marginBottom: '0.5rem' }}>\n <strong>Comments:</strong> {selectedThread.comments.length}\n </div>\n {/* Status and issue link removed in local-only version */}\n {/* AI Summarize Thread Button */}\n {selectedThread.comments.length > 0 && (\n <Button\n id={`ai-summarize-thread-${selectedThread.id}`}\n variant=\"secondary\"\n size=\"sm\"\n icon={<MagicIcon />}\n onClick={handleSummarizeThread}\n isLoading={loadingSummary}\n isDisabled={loadingSummary}\n style={{ marginTop: '0.5rem' }}\n >\n {loadingSummary ? 'Generating...' : 'AI Summarize Thread'}\n </Button>\n )}\n {enableCommenting && (\n <Button\n id={`delete-thread-${selectedThread.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={handleDeleteThread}\n style={{ marginTop: '0.5rem', marginLeft: selectedThread.comments.length > 0 ? '0.5rem' : '0' }}\n >\n Delete Thread\n </Button>\n )}\n </CardBody>\n </Card>\n\n {/* AI Summary Display */}\n {threadSummaries[selectedThread.id] && (\n <Alert\n variant=\"info\"\n isInline\n title=\"AI Summary\"\n actionClose={\n <Button\n variant=\"plain\"\n onClick={() => {\n const newSummaries = { ...threadSummaries };\n delete newSummaries[selectedThread.id];\n setThreadSummaries(newSummaries);\n }}\n aria-label=\"Clear summary\"\n >\n <TimesIcon />\n </Button>\n }\n >\n <ExpandableSection\n toggleText={summaryExpanded ? 'Hide summary' : 'Show summary'}\n onToggle={(_event, isExpanded) => setSummaryExpanded(isExpanded)}\n isExpanded={summaryExpanded}\n isIndented\n >\n <div style={{ fontSize: '0.875rem', lineHeight: '1.5' }}>\n {threadSummaries[selectedThread.id]}\n </div>\n </ExpandableSection>\n </Alert>\n )}\n\n <Divider />\n\n {/* Comments List */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n {selectedThread.comments.length === 0 ? (\n <EmptyState>\n <Title headingLevel=\"h4\" size=\"md\">\n No comments yet\n </Title>\n <EmptyStateBody>\n {enableCommenting \n ? 'Add a reply below to start the conversation.'\n : 'Enable commenting to add replies.'}\n </EmptyStateBody>\n </EmptyState>\n ) : (\n selectedThread.comments.map((comment, index) => (\n <Card key={comment.id} isCompact>\n <CardTitle>\n Comment #{index + 1}\n <div style={{ fontSize: '0.75rem', color: 'var(--pf-v6-global--Color--200)', fontWeight: 'normal' }}>\n {comment.author && <span style={{ marginRight: '0.5rem' }}>@{comment.author}</span>}\n {formatDate(comment.createdAt)}\n </div>\n </CardTitle>\n <CardBody>\n {editingCommentId === comment.id ? (\n <>\n <TextArea\n id={`edit-comment-${comment.id}`}\n value={editText}\n onChange={(_event, value) => setEditText(value)}\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleSave(selectedThread.id, comment.id);\n }\n if (e.key === 'Escape') {\n setEditingCommentId(null);\n }\n }}\n />\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`save-comment-${comment.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={() => handleSave(selectedThread.id, comment.id)}\n >\n Save\n </Button>\n <Button\n id={`cancel-edit-${comment.id}`}\n variant=\"link\"\n size=\"sm\"\n onClick={() => setEditingCommentId(null)}\n >\n Cancel\n </Button>\n </div>\n </>\n ) : (\n <>\n <div style={{ marginBottom: '0.75rem', whiteSpace: 'pre-wrap' }}>\n {comment.text || <em style={{ color: 'var(--pf-v6-global--Color--200)' }}>No text</em>}\n </div>\n {enableCommenting && (\n <div style={{ display: 'flex', gap: '0.5rem' }}>\n <Button\n id={`edit-comment-btn-${comment.id}`}\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => handleEdit(comment.id, comment.text)}\n >\n Edit\n </Button>\n <Button\n id={`delete-comment-btn-${comment.id}`}\n variant=\"danger\"\n size=\"sm\"\n icon={<TimesIcon />}\n onClick={() => handleDeleteComment(selectedThread.id, comment.id)}\n >\n Delete\n </Button>\n </div>\n )}\n </>\n )}\n </CardBody>\n </Card>\n ))\n )}\n </div>\n\n {/* Add Reply */}\n {enableCommenting && (\n <>\n <Divider />\n <Card isCompact>\n <CardTitle>\n <PlusCircleIcon style={{ marginRight: '0.5rem' }} />\n Add Reply\n </CardTitle>\n <CardBody>\n <TextArea\n ref={replyTextAreaRef}\n id={`reply-textarea-${selectedThread.id}`}\n value={replyText}\n onChange={(_event, value) => setReplyText(value)}\n placeholder=\"Enter your reply...\"\n rows={3}\n style={{ marginBottom: '0.5rem' }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n handleAddReply();\n }\n }}\n />\n <Button\n id={`add-reply-${selectedThread.id}`}\n variant=\"primary\"\n size=\"sm\"\n onClick={handleAddReply}\n isDisabled={!replyText.trim()}\n >\n Add Reply\n </Button>\n </CardBody>\n </Card>\n </>\n )}\n </div>\n )}\n </DrawerContentBody>\n </DrawerPanelContent>\n );\n\n return (\n <Drawer isExpanded={isDrawerOpen} isInline position=\"right\">\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{children}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n );\n};\n","import * as React from 'react';\n\ninterface GitHubUser {\n login: string;\n avatar: string;\n}\n\ninterface GitHubAuthContextType {\n user: GitHubUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n}\n\nconst GitHubAuthContext = React.createContext<GitHubAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitHubAuthProvider: React.FC<{ children: React.ReactNode; config?: any }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitHub login not available in local mode');\n },\n logout: () => {\n console.log('GitHub logout not available in local mode');\n },\n };\n\n return (\n <GitHubAuthContext.Provider value={value}>\n {children}\n </GitHubAuthContext.Provider>\n );\n};\n\nexport const useGitHubAuth = () => {\n const context = React.useContext(GitHubAuthContext);\n if (context === undefined) {\n throw new Error('useGitHubAuth must be used within a GitHubAuthProvider');\n }\n return context;\n};\n","import * as React from 'react';\n\ninterface GitLabUser {\n username?: string;\n avatar?: string;\n}\n\ninterface GitLabAuthContextType {\n user: GitLabUser | null;\n isAuthenticated: boolean;\n login: () => void;\n logout: () => void;\n getToken: () => string | null;\n}\n\nconst GitLabAuthContext = React.createContext<GitLabAuthContextType | undefined>(undefined);\n\n// Mock provider for local-only mode (no actual OAuth)\nexport const GitLabAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const value = {\n user: null,\n isAuthenticated: false,\n login: () => {\n console.log('GitLab login not available in local mode');\n },\n logout: () => {\n console.log('GitLab logout not available in local mode');\n },\n getToken: () => null,\n };\n\n return (\n <GitLabAuthContext.Provider value={value}>\n {children}\n </GitLabAuthContext.Provider>\n );\n};\n\nexport const useGitLabAuth = () => {\n const ctx = React.useContext(GitLabAuthContext);\n if (!ctx) {\n throw new Error('useGitLabAuth must be used within a GitLabAuthProvider');\n }\n return ctx;\n};\n"],"mappings":"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","names":["React","React","jsx","jsx","jsx","React","Button","CommentIcon","useLocation","Fragment","jsx","jsxs","CommentIcon","Button","React","jsx","React","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hale-commenting-system",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "Local-first commenting system for React applications with localStorage persistence",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",