@akropolys/kiku 1.6.2 → 1.6.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.mjs CHANGED
@@ -1167,6 +1167,25 @@ var ShoppingBagIcon = () => /* @__PURE__ */ jsxs6("svg", { width: "13", height:
1167
1167
  /* @__PURE__ */ jsx7("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
1168
1168
  /* @__PURE__ */ jsx7("path", { d: "M16 10a4 4 0 0 1-8 0" })
1169
1169
  ] });
1170
+ var SecureShieldIcon = ({ className, size = 18 }) => /* @__PURE__ */ jsxs6(
1171
+ "svg",
1172
+ {
1173
+ className,
1174
+ width: size,
1175
+ height: size,
1176
+ viewBox: "0 0 24 24",
1177
+ fill: "none",
1178
+ stroke: "currentColor",
1179
+ strokeWidth: "2.5",
1180
+ strokeLinecap: "round",
1181
+ strokeLinejoin: "round",
1182
+ children: [
1183
+ /* @__PURE__ */ jsx7("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
1184
+ /* @__PURE__ */ jsx7("path", { d: "M12 11a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z" }),
1185
+ /* @__PURE__ */ jsx7("path", { d: "M12 11v4" })
1186
+ ]
1187
+ }
1188
+ );
1170
1189
  var PaperclipIcon = () => /* @__PURE__ */ jsx7("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx7("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
1171
1190
  var MicIcon2 = () => /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1172
1191
  /* @__PURE__ */ jsx7("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3z" }),
@@ -1189,6 +1208,173 @@ var DEFAULT_CHIPS = [
1189
1208
  ];
1190
1209
  var SESSIONS_KEY = "akropolys_chat_sessions";
1191
1210
  var MAX_SESSIONS = 20;
1211
+ function parseAtKiku(raw) {
1212
+ const trimmed = raw.trim();
1213
+ if (!/^@kiku\b/i.test(trimmed)) return null;
1214
+ const rest = trimmed.slice(5).trim();
1215
+ if (rest === "" || /^(capture|save)\b/i.test(rest)) {
1216
+ return {
1217
+ intent: "capture",
1218
+ cleanQuery: rest.replace(/^(capture|save)\s*/i, "").trim() || trimmed
1219
+ };
1220
+ }
1221
+ if (/^(history|what have you|show my|my items|what did you|saved|captures|recall)\b/i.test(rest)) {
1222
+ return { intent: "view_history", cleanQuery: "show my saved items" };
1223
+ }
1224
+ if (/^(delete|forget|remove|unsave)\b/i.test(rest)) {
1225
+ return {
1226
+ intent: "delete",
1227
+ cleanQuery: rest.replace(/^(delete|forget|remove|unsave)\s*/i, "").trim() || trimmed
1228
+ };
1229
+ }
1230
+ return { intent: "capture", cleanQuery: rest || trimmed };
1231
+ }
1232
+ function KikuPickerMenu({
1233
+ sources,
1234
+ referencedIds,
1235
+ defaultCurrency,
1236
+ onCapture,
1237
+ onCaptureAll,
1238
+ onViewHistory,
1239
+ onDelete,
1240
+ onDismiss
1241
+ }) {
1242
+ const discussed = sources.filter((s) => s.id && referencedIds.includes(s.id));
1243
+ return /* @__PURE__ */ jsxs6(
1244
+ "div",
1245
+ {
1246
+ className: "hsk-kiku-picker",
1247
+ role: "menu",
1248
+ "aria-label": "@kiku commands",
1249
+ onMouseDown: (e) => e.preventDefault(),
1250
+ children: [
1251
+ /* @__PURE__ */ jsxs6("div", { className: "hsk-kiku-picker-header", children: [
1252
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-at", children: "@kiku" }),
1253
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-hint", children: "What would you like to do?" }),
1254
+ /* @__PURE__ */ jsx7("button", { className: "hsk-kiku-picker-close", onClick: onDismiss, "aria-label": "Close", children: /* @__PURE__ */ jsx7(CloseIcon, {}) })
1255
+ ] }),
1256
+ discussed.length > 0 && /* @__PURE__ */ jsxs6(Fragment3, { children: [
1257
+ /* @__PURE__ */ jsx7("div", { className: "hsk-kiku-picker-section", children: "Discussed in this chat" }),
1258
+ discussed.map((src, i) => /* @__PURE__ */ jsxs6(
1259
+ "button",
1260
+ {
1261
+ className: "hsk-kiku-picker-item",
1262
+ role: "menuitem",
1263
+ onClick: () => {
1264
+ onCapture(src);
1265
+ onDismiss();
1266
+ },
1267
+ children: [
1268
+ src.image ? /* @__PURE__ */ jsx7("img", { src: src.image, alt: src.name, className: "hsk-kiku-picker-img" }) : /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-img-placeholder", children: /* @__PURE__ */ jsx7(SecureShieldIcon, { size: 14 }) }),
1269
+ /* @__PURE__ */ jsxs6("span", { className: "hsk-kiku-picker-item-body", children: [
1270
+ /* @__PURE__ */ jsxs6("span", { className: "hsk-kiku-picker-item-name", children: [
1271
+ "\u{1F4CC} ",
1272
+ src.name
1273
+ ] }),
1274
+ src.price && /* @__PURE__ */ jsxs6("span", { className: "hsk-kiku-picker-item-price", children: [
1275
+ src.currency ?? defaultCurrency,
1276
+ " ",
1277
+ parseFloat(String(src.price).replace(/[^0-9.]/g, "") || "0").toLocaleString()
1278
+ ] })
1279
+ ] })
1280
+ ]
1281
+ },
1282
+ src.id ?? i
1283
+ )),
1284
+ discussed.length > 1 && /* @__PURE__ */ jsx7(
1285
+ "button",
1286
+ {
1287
+ className: "hsk-kiku-picker-item hsk-kiku-picker-item--all",
1288
+ role: "menuitem",
1289
+ onClick: () => {
1290
+ onCaptureAll(discussed);
1291
+ onDismiss();
1292
+ },
1293
+ children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ jsxs6("span", { className: "hsk-kiku-picker-item-name", children: [
1294
+ "\u{1F4CC} Capture all (",
1295
+ discussed.length,
1296
+ " items)"
1297
+ ] }) })
1298
+ }
1299
+ ),
1300
+ /* @__PURE__ */ jsx7("div", { className: "hsk-kiku-picker-divider" })
1301
+ ] }),
1302
+ discussed.length === 0 && /* @__PURE__ */ jsxs6(Fragment3, { children: [
1303
+ /* @__PURE__ */ jsx7(
1304
+ "button",
1305
+ {
1306
+ className: "hsk-kiku-picker-item",
1307
+ role: "menuitem",
1308
+ onClick: () => {
1309
+ onCapture({ name: "current page", id: void 0 });
1310
+ onDismiss();
1311
+ },
1312
+ children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F4CC} Capture current page" }) })
1313
+ }
1314
+ ),
1315
+ /* @__PURE__ */ jsx7("div", { className: "hsk-kiku-picker-divider" })
1316
+ ] }),
1317
+ /* @__PURE__ */ jsx7(
1318
+ "button",
1319
+ {
1320
+ className: "hsk-kiku-picker-item",
1321
+ role: "menuitem",
1322
+ onClick: () => {
1323
+ onViewHistory();
1324
+ onDismiss();
1325
+ },
1326
+ children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F4CB} What have you saved?" }) })
1327
+ }
1328
+ ),
1329
+ /* @__PURE__ */ jsx7(
1330
+ "button",
1331
+ {
1332
+ className: "hsk-kiku-picker-item",
1333
+ role: "menuitem",
1334
+ onClick: () => {
1335
+ onDelete();
1336
+ onDismiss();
1337
+ },
1338
+ children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-body", children: /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-name", children: "\u{1F5D1}\uFE0F Delete this" }) })
1339
+ }
1340
+ )
1341
+ ]
1342
+ }
1343
+ );
1344
+ }
1345
+ function AtPickerMenu({ onSelect, onDismiss }) {
1346
+ return /* @__PURE__ */ jsxs6(
1347
+ "div",
1348
+ {
1349
+ className: "hsk-kiku-picker",
1350
+ role: "menu",
1351
+ "aria-label": "Extensions",
1352
+ onMouseDown: (e) => e.preventDefault(),
1353
+ children: [
1354
+ /* @__PURE__ */ jsxs6("div", { className: "hsk-kiku-picker-header", children: [
1355
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-at", children: "@" }),
1356
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-hint", children: "Use an extension" }),
1357
+ /* @__PURE__ */ jsx7("button", { className: "hsk-kiku-picker-close", onClick: onDismiss, "aria-label": "Close", children: /* @__PURE__ */ jsx7(CloseIcon, {}) })
1358
+ ] }),
1359
+ /* @__PURE__ */ jsxs6(
1360
+ "button",
1361
+ {
1362
+ className: "hsk-kiku-picker-item",
1363
+ role: "menuitem",
1364
+ onClick: () => onSelect("@kiku"),
1365
+ children: [
1366
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-img-placeholder", style: { background: "color-mix(in srgb, var(--hsk-primary, #7c5cfc) 15%, transparent)", color: "var(--hsk-primary, #7c5cfc)" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
1367
+ /* @__PURE__ */ jsxs6("span", { className: "hsk-kiku-picker-item-body", children: [
1368
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-name", children: "@kiku" }),
1369
+ /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-picker-item-price", style: { fontSize: "11px", whiteSpace: "normal", lineHeight: "1.3" }, children: "Ask Kiku to capture pages, remember items, or show your history" })
1370
+ ] })
1371
+ ]
1372
+ }
1373
+ )
1374
+ ]
1375
+ }
1376
+ );
1377
+ }
1192
1378
  function loadSessions() {
1193
1379
  try {
1194
1380
  if (typeof window === "undefined") return [];
@@ -1717,6 +1903,8 @@ function ChatModal({
1717
1903
  });
1718
1904
  const [paymentPhase, setPaymentPhase] = useState5("idle");
1719
1905
  const [memoryKey, setMemoryKey] = useState5(null);
1906
+ const [showKikuPicker, setShowKikuPicker] = useState5(false);
1907
+ const [showAtPicker, setShowAtPicker] = useState5(false);
1720
1908
  const [sessions, setSessions] = useState5(() => loadSessions());
1721
1909
  const [sidebarOpen, setSidebarOpen] = useState5(false);
1722
1910
  const [replayMessages, setReplayMessages] = useState5(null);
@@ -1787,27 +1975,97 @@ function ChatModal({
1787
1975
  const q = `Tell me more about the ${src.name}${src.price ? ` (${src.currency ?? defaultCurrency} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
1788
1976
  send(q);
1789
1977
  };
1790
- const handleSend = async (text, extraAttachments) => {
1791
- const q = (text ?? input).trim();
1792
- if (!q || loading) return;
1978
+ const handleSend = async (text, extraAttachments, forcedIntent, captureTargets) => {
1979
+ const raw = (text ?? input).trim();
1980
+ if (!raw || loading) return;
1981
+ const kiku = parseAtKiku(raw);
1982
+ const q = kiku ? kiku.cleanQuery : raw;
1983
+ const resolvedForcedIntent = forcedIntent ?? kiku?.intent;
1793
1984
  setReplayMessages(null);
1794
1985
  setSelectedProduct(null);
1986
+ setShowKikuPicker(false);
1987
+ setShowAtPicker(false);
1795
1988
  setInput("");
1796
1989
  if (textareaRef.current) {
1797
1990
  textareaRef.current.style.height = "auto";
1798
1991
  }
1799
1992
  const toSend = extraAttachments ?? attachments;
1800
1993
  setAttachments([]);
1801
- await send(q, void 0, toSend.length > 0 ? toSend : void 0);
1994
+ await send(q, raw, toSend.length > 0 ? toSend : void 0, resolvedForcedIntent, captureTargets);
1802
1995
  };
1996
+ const handleSelectExtension = (ext) => {
1997
+ setInput(ext + " ");
1998
+ setShowAtPicker(false);
1999
+ setShowKikuPicker(true);
2000
+ if (textareaRef.current) {
2001
+ textareaRef.current.focus();
2002
+ }
2003
+ };
2004
+ const handleKikuCapture = useCallback2((product) => {
2005
+ const name = product.name || "";
2006
+ const display = `@kiku capture${name ? " " + name : ""}`;
2007
+ const q = name || "capture current page";
2008
+ setInput("");
2009
+ setReplayMessages(null);
2010
+ setSelectedProduct(null);
2011
+ const toSend = attachments;
2012
+ setAttachments([]);
2013
+ send(q, display, toSend.length > 0 ? toSend : void 0, "capture");
2014
+ }, [attachments, send]);
2015
+ const handleKikuCaptureAll = useCallback2((products) => {
2016
+ const targets = products.filter((p) => p.id).map((p) => ({
2017
+ name: p.name || "",
2018
+ url: p.url || "",
2019
+ image: p.image || "",
2020
+ price: p.price ? String(p.price) : "",
2021
+ currency: p.currency || defaultCurrency
2022
+ }));
2023
+ const names = products.map((p) => p.name).filter(Boolean).join(", ");
2024
+ const display = `@kiku capture all (${products.length} items)`;
2025
+ setInput("");
2026
+ setReplayMessages(null);
2027
+ setSelectedProduct(null);
2028
+ setAttachments([]);
2029
+ send(names || "capture all", display, void 0, "capture_all", targets);
2030
+ }, [defaultCurrency, send]);
2031
+ const handleKikuViewHistory = useCallback2(() => {
2032
+ const display = "@kiku what have you saved?";
2033
+ setInput("");
2034
+ setReplayMessages(null);
2035
+ setSelectedProduct(null);
2036
+ setAttachments([]);
2037
+ send("show my saved items", display, void 0, "view_history");
2038
+ }, [send]);
2039
+ const handleKikuDelete = useCallback2(() => {
2040
+ const display = "@kiku delete this";
2041
+ setInput("");
2042
+ setReplayMessages(null);
2043
+ setSelectedProduct(null);
2044
+ setAttachments([]);
2045
+ send("delete this", display, void 0, "delete");
2046
+ }, [send]);
1803
2047
  const handleKeyDown = (e) => {
2048
+ if (e.key === "Escape" && showKikuPicker) {
2049
+ e.preventDefault();
2050
+ setShowKikuPicker(false);
2051
+ return;
2052
+ }
2053
+ if (e.key === "Escape" && showAtPicker) {
2054
+ e.preventDefault();
2055
+ setShowAtPicker(false);
2056
+ return;
2057
+ }
1804
2058
  if (e.key === "Enter" && !e.shiftKey) {
1805
2059
  e.preventDefault();
1806
2060
  handleSend();
1807
2061
  }
1808
2062
  };
1809
2063
  const handleInput = (e) => {
1810
- setInput(e.target.value);
2064
+ const val = e.target.value;
2065
+ setInput(val);
2066
+ const trimmed = val.trim();
2067
+ setShowAtPicker(trimmed === "@");
2068
+ setShowKikuPicker(/^@kiku\b/i.test(trimmed));
1811
2069
  const t = e.target;
1812
2070
  t.style.height = "auto";
1813
2071
  t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
@@ -1944,7 +2202,10 @@ function ChatModal({
1944
2202
  const displayContent = !isUser && isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages ? stripMarkdownTables(msg.content) : msg.content;
1945
2203
  return /* @__PURE__ */ jsx7("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-user-msg", children: [
1946
2204
  msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-user-imgs", children: msg.images.map((img, i) => /* @__PURE__ */ jsx7("img", { src: img, alt: `attachment ${i + 1}`, className: "hsk-cb-user-img-thumb" }, i)) }),
1947
- msg.content && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-user-bubble", children: msg.content })
2205
+ msg.content && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-user-bubble", children: [
2206
+ /^@kiku\b/i.test(msg.content) && /* @__PURE__ */ jsx7("span", { className: "hsk-kiku-badge", children: "@kiku" }),
2207
+ msg.content
2208
+ ] })
1948
2209
  ] }) : /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-msg", children: [
1949
2210
  /* @__PURE__ */ jsx7("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx7(SparkleIcon2, {}) }),
1950
2211
  /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-ai-body", children: [
@@ -1959,7 +2220,7 @@ function ChatModal({
1959
2220
  ] });
1960
2221
  })(),
1961
2222
  isLast && lastIntent === "compare" && sources.length >= 2 && !replayMessages && /* @__PURE__ */ jsx7(ComparisonMatrix, { sources, defaultCurrency }),
1962
- isLast && referencedIds.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_phone" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && !msg.cartSnapshot && /* @__PURE__ */ jsx7(
2223
+ isLast && referencedIds.length > 0 && lastIntent !== "compare" && lastAction?.type !== "request_phone" && lastAction?.type !== "awaiting_payment" && lastAction?.type !== "checkout" && lastAction?.type !== "capture" && lastAction?.type !== "delete" && lastAction?.type !== "view_history" && !msg.cartSnapshot && /* @__PURE__ */ jsx7(
1963
2224
  SourcesCarousel,
1964
2225
  {
1965
2226
  sources,
@@ -2070,6 +2331,26 @@ function ChatModal({
2070
2331
  /* @__PURE__ */ jsx7("div", { ref: bottomRef, style: { height: 1 } })
2071
2332
  ] }),
2072
2333
  !replayMessages && /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-input-wrap", children: [
2334
+ showAtPicker && /* @__PURE__ */ jsx7(
2335
+ AtPickerMenu,
2336
+ {
2337
+ onSelect: handleSelectExtension,
2338
+ onDismiss: () => setShowAtPicker(false)
2339
+ }
2340
+ ),
2341
+ showKikuPicker && /* @__PURE__ */ jsx7(
2342
+ KikuPickerMenu,
2343
+ {
2344
+ sources,
2345
+ referencedIds,
2346
+ defaultCurrency,
2347
+ onCapture: handleKikuCapture,
2348
+ onCaptureAll: handleKikuCaptureAll,
2349
+ onViewHistory: handleKikuViewHistory,
2350
+ onDelete: handleKikuDelete,
2351
+ onDismiss: () => setShowKikuPicker(false)
2352
+ }
2353
+ ),
2073
2354
  attachments.length > 0 && /* @__PURE__ */ jsx7("div", { className: "hsk-cb-img-strip", children: attachments.map((att, i) => /* @__PURE__ */ jsxs6("div", { className: "hsk-cb-img-thumb-wrap", children: [
2074
2355
  /* @__PURE__ */ jsx7("img", { src: att.data, alt: `attachment ${i + 1}`, className: "hsk-cb-img-thumb" }),
2075
2356
  /* @__PURE__ */ jsx7(