@kite-copilot/chat-panel 0.2.18 → 0.2.20

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/auto.cjs CHANGED
@@ -935,7 +935,7 @@ function renderMarkdown(text) {
935
935
  "a",
936
936
  {
937
937
  href: linkMatch[2],
938
- className: "text-blue-600 hover:underline",
938
+ className: "kite-link",
939
939
  target: "_blank",
940
940
  rel: "noopener noreferrer",
941
941
  children: linkMatch[1]
@@ -946,7 +946,44 @@ function renderMarkdown(text) {
946
946
  remaining = remaining.slice(linkMatch[0].length);
947
947
  continue;
948
948
  }
949
- const nextSpecial = remaining.search(/[`*\[]/);
949
+ const urlMatch = remaining.match(/^(https?:\/\/[^\s<>]+|www\.[^\s<>]+)/);
950
+ if (urlMatch) {
951
+ const url = urlMatch[1];
952
+ const href = url.startsWith("www.") ? `https://${url}` : url;
953
+ parts.push(
954
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
955
+ "a",
956
+ {
957
+ href,
958
+ className: "kite-link",
959
+ target: "_blank",
960
+ rel: "noopener noreferrer",
961
+ children: url
962
+ },
963
+ keyIndex++
964
+ )
965
+ );
966
+ remaining = remaining.slice(url.length);
967
+ continue;
968
+ }
969
+ const emailMatch = remaining.match(/^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/);
970
+ if (emailMatch) {
971
+ const email = emailMatch[1];
972
+ parts.push(
973
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
974
+ "a",
975
+ {
976
+ href: `mailto:${email}`,
977
+ className: "kite-link",
978
+ children: email
979
+ },
980
+ keyIndex++
981
+ )
982
+ );
983
+ remaining = remaining.slice(email.length);
984
+ continue;
985
+ }
986
+ const nextSpecial = remaining.search(/[`*\[@h]/);
950
987
  if (nextSpecial === -1) {
951
988
  parts.push(remaining);
952
989
  break;
@@ -1266,6 +1303,7 @@ var initialMessages = [];
1266
1303
  function ChatPanel({
1267
1304
  isOpen = true,
1268
1305
  onClose,
1306
+ onOpen,
1269
1307
  onBack,
1270
1308
  onNavigate,
1271
1309
  onActionComplete,
@@ -1367,6 +1405,9 @@ function ChatPanel({
1367
1405
  const [pendingBulkSession, setPendingBulkSession] = React4.useState(null);
1368
1406
  const pendingBulkSessionRef = React4.useRef(null);
1369
1407
  const fileInputRef = React4.useRef(null);
1408
+ const [searchExpanded, setSearchExpanded] = React4.useState(false);
1409
+ const [searchInput, setSearchInput] = React4.useState("");
1410
+ const searchInputRef = React4.useRef(null);
1370
1411
  React4.useEffect(() => {
1371
1412
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1372
1413
  return;
@@ -2597,6 +2638,81 @@ ${userText}`
2597
2638
  ]);
2598
2639
  }
2599
2640
  }
2641
+ if (!isOpen) {
2642
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fixed bottom-6 left-1/2 -translate-x-1/2 z-50", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `flex items-center gap-3 rounded-xl bg-white border border-gray-200 shadow-lg px-4 py-3 hover:shadow-xl transition-all duration-300 ease-out ${searchExpanded ? "w-[480px]" : "w-[320px]"}`, children: !searchExpanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3 w-full", children: [
2643
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2644
+ "button",
2645
+ {
2646
+ onClick: () => {
2647
+ setSearchExpanded(true);
2648
+ setTimeout(() => searchInputRef.current?.focus(), 100);
2649
+ },
2650
+ className: "flex items-center gap-3 flex-1 group",
2651
+ children: [
2652
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm text-gray-500 flex-1 text-left", children: "Ask a question..." }),
2653
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs text-gray-400 font-medium", children: "\u2318I" })
2654
+ ]
2655
+ }
2656
+ ),
2657
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2658
+ "button",
2659
+ {
2660
+ onClick: () => {
2661
+ onOpen?.();
2662
+ },
2663
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors",
2664
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2665
+ }
2666
+ )
2667
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2668
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2669
+ "input",
2670
+ {
2671
+ ref: searchInputRef,
2672
+ type: "text",
2673
+ value: searchInput,
2674
+ onChange: (e) => setSearchInput(e.target.value),
2675
+ onKeyDown: (e) => {
2676
+ if (e.key === "Enter" && searchInput.trim()) {
2677
+ e.preventDefault();
2678
+ onOpen?.();
2679
+ startChatFlow(searchInput.trim());
2680
+ setSearchInput("");
2681
+ setSearchExpanded(false);
2682
+ } else if (e.key === "Escape") {
2683
+ setSearchExpanded(false);
2684
+ setSearchInput("");
2685
+ }
2686
+ },
2687
+ onBlur: () => {
2688
+ if (!searchInput.trim()) {
2689
+ setTimeout(() => setSearchExpanded(false), 200);
2690
+ }
2691
+ },
2692
+ placeholder: "Ask a question...",
2693
+ className: "flex-1 text-sm text-gray-700 outline-none bg-transparent"
2694
+ }
2695
+ ),
2696
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
2697
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-xs text-gray-400 font-medium", children: "\u21B5 Enter" }),
2698
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2699
+ "button",
2700
+ {
2701
+ onClick: () => {
2702
+ onOpen?.();
2703
+ if (searchInput.trim()) {
2704
+ setInput(searchInput);
2705
+ }
2706
+ setSearchInput("");
2707
+ setSearchExpanded(false);
2708
+ },
2709
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors cursor-pointer",
2710
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2711
+ }
2712
+ )
2713
+ ] })
2714
+ ] }) }) });
2715
+ }
2600
2716
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2601
2717
  "section",
2602
2718
  {
@@ -3909,26 +4025,6 @@ ${userText}`
3909
4025
  }
3910
4026
  );
3911
4027
  }
3912
- function PanelToggle({
3913
- isOpen,
3914
- onClick,
3915
- className = ""
3916
- }) {
3917
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3918
- "button",
3919
- {
3920
- type: "button",
3921
- onClick,
3922
- className: `fixed top-1/2 z-50 flex items-center justify-center w-6 h-16 bg-gray-100 hover:bg-gray-200 border border-gray-200 border-r-0 rounded-l-lg text-gray-600 hover:text-gray-800 shadow-md transition-all duration-300 ${className}`,
3923
- "aria-label": isOpen ? "Close help panel" : "Open help panel",
3924
- style: {
3925
- right: isOpen ? `${PANEL_WIDTH}px` : "0px",
3926
- transform: "translateY(-50%)"
3927
- },
3928
- children: isOpen ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react4.ChevronLeft, { className: "h-4 w-4" })
3929
- }
3930
- );
3931
- }
3932
4028
  function ChatPanelWithToggle({
3933
4029
  onNavigate,
3934
4030
  onActionComplete,
@@ -3958,22 +4054,20 @@ function ChatPanelWithToggle({
3958
4054
  document.body.style.transition = originalTransition;
3959
4055
  };
3960
4056
  }, [isOpen]);
3961
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3962
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PanelToggle, { isOpen, onClick: () => setIsOpen(!isOpen) }),
3963
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3964
- ChatPanel,
3965
- {
3966
- isOpen,
3967
- onClose: () => setIsOpen(false),
3968
- onNavigate,
3969
- onActionComplete,
3970
- currentPage,
3971
- agentUrl,
3972
- startingQuestions,
3973
- startingQuestionsEndpoint
3974
- }
3975
- )
3976
- ] });
4057
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4058
+ ChatPanel,
4059
+ {
4060
+ isOpen,
4061
+ onClose: () => setIsOpen(false),
4062
+ onOpen: () => setIsOpen(true),
4063
+ onNavigate,
4064
+ onActionComplete,
4065
+ currentPage,
4066
+ agentUrl,
4067
+ startingQuestions,
4068
+ startingQuestionsEndpoint
4069
+ }
4070
+ );
3977
4071
  }
3978
4072
 
3979
4073
  // src/createKiteChat.tsx
package/dist/auto.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-BMLaQQQk.cjs';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.cjs';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-BMLaQQQk.js';
1
+ import { K as KiteChatConfig, a as KiteChatInstance } from './createKiteChat-CyoN-YV4.js';
2
2
  import 'react/jsx-runtime';
3
3
 
4
4
  /**
package/dist/auto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKiteChat
3
- } from "./chunk-UW3AFJMK.js";
3
+ } from "./chunk-INXKWC6D.js";
4
4
 
5
5
  // src/auto.ts
6
6
  function mountKiteChat(config) {
@@ -934,7 +934,7 @@ function renderMarkdown(text) {
934
934
  "a",
935
935
  {
936
936
  href: linkMatch[2],
937
- className: "text-blue-600 hover:underline",
937
+ className: "kite-link",
938
938
  target: "_blank",
939
939
  rel: "noopener noreferrer",
940
940
  children: linkMatch[1]
@@ -945,7 +945,44 @@ function renderMarkdown(text) {
945
945
  remaining = remaining.slice(linkMatch[0].length);
946
946
  continue;
947
947
  }
948
- const nextSpecial = remaining.search(/[`*\[]/);
948
+ const urlMatch = remaining.match(/^(https?:\/\/[^\s<>]+|www\.[^\s<>]+)/);
949
+ if (urlMatch) {
950
+ const url = urlMatch[1];
951
+ const href = url.startsWith("www.") ? `https://${url}` : url;
952
+ parts.push(
953
+ /* @__PURE__ */ jsx9(
954
+ "a",
955
+ {
956
+ href,
957
+ className: "kite-link",
958
+ target: "_blank",
959
+ rel: "noopener noreferrer",
960
+ children: url
961
+ },
962
+ keyIndex++
963
+ )
964
+ );
965
+ remaining = remaining.slice(url.length);
966
+ continue;
967
+ }
968
+ const emailMatch = remaining.match(/^([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/);
969
+ if (emailMatch) {
970
+ const email = emailMatch[1];
971
+ parts.push(
972
+ /* @__PURE__ */ jsx9(
973
+ "a",
974
+ {
975
+ href: `mailto:${email}`,
976
+ className: "kite-link",
977
+ children: email
978
+ },
979
+ keyIndex++
980
+ )
981
+ );
982
+ remaining = remaining.slice(email.length);
983
+ continue;
984
+ }
985
+ const nextSpecial = remaining.search(/[`*\[@h]/);
949
986
  if (nextSpecial === -1) {
950
987
  parts.push(remaining);
951
988
  break;
@@ -1265,6 +1302,7 @@ var initialMessages = [];
1265
1302
  function ChatPanel({
1266
1303
  isOpen = true,
1267
1304
  onClose,
1305
+ onOpen,
1268
1306
  onBack,
1269
1307
  onNavigate,
1270
1308
  onActionComplete,
@@ -1366,6 +1404,9 @@ function ChatPanel({
1366
1404
  const [pendingBulkSession, setPendingBulkSession] = React4.useState(null);
1367
1405
  const pendingBulkSessionRef = React4.useRef(null);
1368
1406
  const fileInputRef = React4.useRef(null);
1407
+ const [searchExpanded, setSearchExpanded] = React4.useState(false);
1408
+ const [searchInput, setSearchInput] = React4.useState("");
1409
+ const searchInputRef = React4.useRef(null);
1369
1410
  React4.useEffect(() => {
1370
1411
  if (!activeGuide || activeGuide.id !== "add-api-key" || activeGuide.stepIndex !== 2) {
1371
1412
  return;
@@ -2596,6 +2637,81 @@ ${userText}`
2596
2637
  ]);
2597
2638
  }
2598
2639
  }
2640
+ if (!isOpen) {
2641
+ return /* @__PURE__ */ jsx9("div", { className: "fixed bottom-6 left-1/2 -translate-x-1/2 z-50", children: /* @__PURE__ */ jsx9("div", { className: `flex items-center gap-3 rounded-xl bg-white border border-gray-200 shadow-lg px-4 py-3 hover:shadow-xl transition-all duration-300 ease-out ${searchExpanded ? "w-[480px]" : "w-[320px]"}`, children: !searchExpanded ? /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3 w-full", children: [
2642
+ /* @__PURE__ */ jsxs5(
2643
+ "button",
2644
+ {
2645
+ onClick: () => {
2646
+ setSearchExpanded(true);
2647
+ setTimeout(() => searchInputRef.current?.focus(), 100);
2648
+ },
2649
+ className: "flex items-center gap-3 flex-1 group",
2650
+ children: [
2651
+ /* @__PURE__ */ jsx9("span", { className: "text-sm text-gray-500 flex-1 text-left", children: "Ask a question..." }),
2652
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-gray-400 font-medium", children: "\u2318I" })
2653
+ ]
2654
+ }
2655
+ ),
2656
+ /* @__PURE__ */ jsx9(
2657
+ "button",
2658
+ {
2659
+ onClick: () => {
2660
+ onOpen?.();
2661
+ },
2662
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors",
2663
+ children: /* @__PURE__ */ jsx9(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2664
+ }
2665
+ )
2666
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2667
+ /* @__PURE__ */ jsx9(
2668
+ "input",
2669
+ {
2670
+ ref: searchInputRef,
2671
+ type: "text",
2672
+ value: searchInput,
2673
+ onChange: (e) => setSearchInput(e.target.value),
2674
+ onKeyDown: (e) => {
2675
+ if (e.key === "Enter" && searchInput.trim()) {
2676
+ e.preventDefault();
2677
+ onOpen?.();
2678
+ startChatFlow(searchInput.trim());
2679
+ setSearchInput("");
2680
+ setSearchExpanded(false);
2681
+ } else if (e.key === "Escape") {
2682
+ setSearchExpanded(false);
2683
+ setSearchInput("");
2684
+ }
2685
+ },
2686
+ onBlur: () => {
2687
+ if (!searchInput.trim()) {
2688
+ setTimeout(() => setSearchExpanded(false), 200);
2689
+ }
2690
+ },
2691
+ placeholder: "Ask a question...",
2692
+ className: "flex-1 text-sm text-gray-700 outline-none bg-transparent"
2693
+ }
2694
+ ),
2695
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
2696
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-gray-400 font-medium", children: "\u21B5 Enter" }),
2697
+ /* @__PURE__ */ jsx9(
2698
+ "button",
2699
+ {
2700
+ onClick: () => {
2701
+ onOpen?.();
2702
+ if (searchInput.trim()) {
2703
+ setInput(searchInput);
2704
+ }
2705
+ setSearchInput("");
2706
+ setSearchExpanded(false);
2707
+ },
2708
+ className: "h-7 w-7 rounded-lg bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors cursor-pointer",
2709
+ children: /* @__PURE__ */ jsx9(Sparkles, { className: "h-3.5 w-3.5 text-black", fill: "currentColor" })
2710
+ }
2711
+ )
2712
+ ] })
2713
+ ] }) }) });
2714
+ }
2599
2715
  return /* @__PURE__ */ jsxs5(
2600
2716
  "section",
2601
2717
  {
@@ -3957,22 +4073,20 @@ function ChatPanelWithToggle({
3957
4073
  document.body.style.transition = originalTransition;
3958
4074
  };
3959
4075
  }, [isOpen]);
3960
- return /* @__PURE__ */ jsxs5(Fragment2, { children: [
3961
- /* @__PURE__ */ jsx9(PanelToggle, { isOpen, onClick: () => setIsOpen(!isOpen) }),
3962
- /* @__PURE__ */ jsx9(
3963
- ChatPanel,
3964
- {
3965
- isOpen,
3966
- onClose: () => setIsOpen(false),
3967
- onNavigate,
3968
- onActionComplete,
3969
- currentPage,
3970
- agentUrl,
3971
- startingQuestions,
3972
- startingQuestionsEndpoint
3973
- }
3974
- )
3975
- ] });
4076
+ return /* @__PURE__ */ jsx9(
4077
+ ChatPanel,
4078
+ {
4079
+ isOpen,
4080
+ onClose: () => setIsOpen(false),
4081
+ onOpen: () => setIsOpen(true),
4082
+ onNavigate,
4083
+ onActionComplete,
4084
+ currentPage,
4085
+ agentUrl,
4086
+ startingQuestions,
4087
+ startingQuestionsEndpoint
4088
+ }
4089
+ );
3976
4090
  }
3977
4091
  function HelpButton({ onClick, className = "" }) {
3978
4092
  return /* @__PURE__ */ jsx9(
@@ -87,6 +87,8 @@ interface ChatPanelProps {
87
87
  isOpen?: boolean;
88
88
  /** Callback when the panel should close */
89
89
  onClose?: () => void;
90
+ /** Callback when the panel should open */
91
+ onOpen?: () => void;
90
92
  onBack?: () => void;
91
93
  onNavigate?: (page: Page, subtab?: SettingsTab) => void;
92
94
  onActionComplete?: (actionType: ActionType, data: ActionData) => void;
@@ -97,7 +99,7 @@ interface ChatPanelProps {
97
99
  /** API endpoint to fetch starting questions */
98
100
  startingQuestionsEndpoint?: string;
99
101
  }
100
- declare function ChatPanel({ isOpen, onClose, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
101
103
  /**
102
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
103
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)
@@ -87,6 +87,8 @@ interface ChatPanelProps {
87
87
  isOpen?: boolean;
88
88
  /** Callback when the panel should close */
89
89
  onClose?: () => void;
90
+ /** Callback when the panel should open */
91
+ onOpen?: () => void;
90
92
  onBack?: () => void;
91
93
  onNavigate?: (page: Page, subtab?: SettingsTab) => void;
92
94
  onActionComplete?: (actionType: ActionType, data: ActionData) => void;
@@ -97,7 +99,7 @@ interface ChatPanelProps {
97
99
  /** API endpoint to fetch starting questions */
98
100
  startingQuestionsEndpoint?: string;
99
101
  }
100
- declare function ChatPanel({ isOpen, onClose, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
102
+ declare function ChatPanel({ isOpen, onClose, onOpen, onBack, onNavigate, onActionComplete, currentPage, agentUrl, startingQuestions: startingQuestionsProp, startingQuestionsEndpoint, }?: ChatPanelProps): react_jsx_runtime.JSX.Element;
101
103
  /**
102
104
  * PanelToggle - An arrow button on the right edge that toggles the side panel
103
105
  * Shows left arrow when closed (click to open), right arrow when open (click to close)