@vite-plugin-opencode-assistant/components 1.0.26 → 1.0.27
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/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/open-code-widget/composables/use-inspector.js +118 -79
- package/es/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/es/open-code-widget/composables/use-persist-state.js +59 -0
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/es/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/es/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/es/open-code-widget/src/context.d.ts +3 -0
- package/es/open-code-widget/src/index-sfc.css +1 -1
- package/es/open-code-widget/src/index.vue.d.ts +10 -10
- package/es/open-code-widget/src/index.vue.js +107 -29
- package/lib/@vite-plugin-opencode-assistant/components.cjs.js +304 -140
- package/lib/@vite-plugin-opencode-assistant/components.es.js +305 -141
- package/lib/components.css +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/open-code-widget/composables/use-inspector.js +118 -79
- package/lib/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/lib/open-code-widget/composables/use-persist-state.js +78 -0
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/lib/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/lib/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/lib/open-code-widget/src/context.d.ts +3 -0
- package/lib/open-code-widget/src/index-sfc.css +1 -1
- package/lib/open-code-widget/src/index.vue.d.ts +10 -10
- package/lib/open-code-widget/src/index.vue.js +106 -28
- package/lib/web-types.json +1 -1
- package/package.json +2 -2
|
@@ -609,6 +609,19 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
609
609
|
bottom: windowHeight.value - state.value.height - gapY.value,
|
|
610
610
|
left: gapX.value
|
|
611
611
|
}));
|
|
612
|
+
const closest = (arr, target) => {
|
|
613
|
+
return arr.reduce((pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur);
|
|
614
|
+
};
|
|
615
|
+
const applyMagnetic = () => {
|
|
616
|
+
if (props.magnetic === "x") {
|
|
617
|
+
const nextX = closest([boundary.value.left, boundary.value.right], state.value.x);
|
|
618
|
+
state.value.x = nextX;
|
|
619
|
+
}
|
|
620
|
+
if (props.magnetic === "y") {
|
|
621
|
+
const nextY = closest([boundary.value.top, boundary.value.bottom], state.value.y);
|
|
622
|
+
state.value.y = nextY;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
612
625
|
const dragging = (0, vue.ref)(false);
|
|
613
626
|
const initialized = (0, vue.ref)(false);
|
|
614
627
|
const rootStyle = (0, vue.computed)(() => {
|
|
@@ -630,12 +643,25 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
630
643
|
if (x > maxX) x = maxX;
|
|
631
644
|
if (y < gapY.value) y = gapY.value;
|
|
632
645
|
if (y > maxY) y = maxY;
|
|
646
|
+
const oldX = state.value.x;
|
|
647
|
+
const oldY = state.value.y;
|
|
633
648
|
state.value = {
|
|
634
649
|
x,
|
|
635
650
|
y,
|
|
636
651
|
width: rect.width,
|
|
637
652
|
height: rect.height
|
|
638
653
|
};
|
|
654
|
+
if (!dragging.value) {
|
|
655
|
+
applyMagnetic();
|
|
656
|
+
if (state.value.x !== oldX || state.value.y !== oldY) {
|
|
657
|
+
const offset2 = {
|
|
658
|
+
x: state.value.x,
|
|
659
|
+
y: state.value.y
|
|
660
|
+
};
|
|
661
|
+
emit("update:offset", offset2);
|
|
662
|
+
emit("offset-change", offset2);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
639
665
|
};
|
|
640
666
|
const touch = {
|
|
641
667
|
startX: (0, vue.ref)(0),
|
|
@@ -672,6 +698,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
672
698
|
dragging.value = true;
|
|
673
699
|
prevX = state.value.x;
|
|
674
700
|
prevY = state.value.y;
|
|
701
|
+
document.body.classList.add("floating-bubble-dragging");
|
|
675
702
|
if (!("touches" in e)) {
|
|
676
703
|
window.addEventListener("mousemove", onTouchMove, { passive: false });
|
|
677
704
|
window.addEventListener("mouseup", onTouchEnd);
|
|
@@ -702,24 +729,15 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
702
729
|
});
|
|
703
730
|
}
|
|
704
731
|
};
|
|
705
|
-
const closest = (arr, target) => {
|
|
706
|
-
return arr.reduce((pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur);
|
|
707
|
-
};
|
|
708
732
|
const onTouchEnd = (e) => {
|
|
709
733
|
dragging.value = false;
|
|
734
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
710
735
|
if (e && !("touches" in e) && e.type === "mouseup") {
|
|
711
736
|
window.removeEventListener("mousemove", onTouchMove);
|
|
712
737
|
window.removeEventListener("mouseup", onTouchEnd);
|
|
713
738
|
}
|
|
714
739
|
requestAnimationFrame(() => {
|
|
715
|
-
|
|
716
|
-
const nextX = closest([boundary.value.left, boundary.value.right], state.value.x);
|
|
717
|
-
state.value.x = nextX;
|
|
718
|
-
}
|
|
719
|
-
if (props.magnetic === "y") {
|
|
720
|
-
const nextY = closest([boundary.value.top, boundary.value.bottom], state.value.y);
|
|
721
|
-
state.value.y = nextY;
|
|
722
|
-
}
|
|
740
|
+
applyMagnetic();
|
|
723
741
|
if (!touch.isTap.value) {
|
|
724
742
|
emit("drag-end");
|
|
725
743
|
const offset = {
|
|
@@ -750,6 +768,7 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
750
768
|
if (rootRef.value) rootRef.value.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
751
769
|
});
|
|
752
770
|
(0, vue.onUnmounted)(() => {
|
|
771
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
753
772
|
if (typeof window !== "undefined") {
|
|
754
773
|
window.removeEventListener("resize", handleResize);
|
|
755
774
|
window.removeEventListener("mousemove", onTouchMove);
|
|
@@ -779,6 +798,8 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
779
798
|
windowWidth,
|
|
780
799
|
windowHeight,
|
|
781
800
|
boundary,
|
|
801
|
+
closest,
|
|
802
|
+
applyMagnetic,
|
|
782
803
|
dragging,
|
|
783
804
|
initialized,
|
|
784
805
|
rootStyle,
|
|
@@ -798,7 +819,6 @@ var __vue_sfc__$2 = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps$1(__s
|
|
|
798
819
|
},
|
|
799
820
|
onTouchStart,
|
|
800
821
|
onTouchMove,
|
|
801
|
-
closest,
|
|
802
822
|
onTouchEnd,
|
|
803
823
|
onClick,
|
|
804
824
|
handleResize
|
|
@@ -826,38 +846,20 @@ __vue_sfc__$2.render = __vue_render__$2;
|
|
|
826
846
|
var FloatingBubble_vue_default = __vue_sfc__$2;
|
|
827
847
|
//#endregion
|
|
828
848
|
//#region es/open-code-widget/src/components/Trigger.vue.js
|
|
829
|
-
var STORAGE_KEY = "opencode-bubble-offset";
|
|
830
849
|
var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
831
850
|
__name: "Trigger",
|
|
832
|
-
emits: [
|
|
833
|
-
"offset-change",
|
|
834
|
-
"drag-start",
|
|
835
|
-
"drag-end"
|
|
836
|
-
],
|
|
851
|
+
emits: ["drag-start", "drag-end"],
|
|
837
852
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
838
|
-
const { buttonActive: active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle } = useOpenCodeWidgetContext();
|
|
839
|
-
const
|
|
840
|
-
try {
|
|
841
|
-
const saved = localStorage.getItem(STORAGE_KEY);
|
|
842
|
-
if (saved) {
|
|
843
|
-
const parsed = JSON.parse(saved);
|
|
844
|
-
if (parsed && (parsed.x !== 0 || parsed.y !== 0)) return parsed;
|
|
845
|
-
}
|
|
846
|
-
} catch (e) {}
|
|
847
|
-
};
|
|
848
|
-
const offset = (0, vue.ref)(loadOffset());
|
|
853
|
+
const { buttonActive: active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, bubbleOffset, handleBubbleOffsetChange } = useOpenCodeWidgetContext();
|
|
854
|
+
const offset = (0, vue.ref)(bubbleOffset.value);
|
|
849
855
|
const emit = __emit;
|
|
850
|
-
const saveOffset = (value) => {
|
|
851
|
-
try {
|
|
852
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(value));
|
|
853
|
-
} catch (e) {}
|
|
854
|
-
};
|
|
855
856
|
const handleOffsetChange = (value) => {
|
|
856
857
|
offset.value = value;
|
|
857
|
-
|
|
858
|
-
emit("offset-change", value);
|
|
858
|
+
handleBubbleOffsetChange(value);
|
|
859
859
|
};
|
|
860
|
-
(0, vue.watch)(
|
|
860
|
+
(0, vue.watch)(bubbleOffset, (newOffset) => {
|
|
861
|
+
offset.value = newOffset;
|
|
862
|
+
});
|
|
861
863
|
__expose({ offset });
|
|
862
864
|
const __returned__ = {
|
|
863
865
|
active,
|
|
@@ -866,11 +868,10 @@ var __vue_sfc__$1 = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
|
866
868
|
thinking,
|
|
867
869
|
resolvedTheme,
|
|
868
870
|
handleToggle,
|
|
869
|
-
|
|
870
|
-
|
|
871
|
+
bubbleOffset,
|
|
872
|
+
handleBubbleOffsetChange,
|
|
871
873
|
offset,
|
|
872
874
|
emit,
|
|
873
|
-
saveOffset,
|
|
874
875
|
handleOffsetChange,
|
|
875
876
|
FloatingBubble: FloatingBubble_vue_default
|
|
876
877
|
};
|
|
@@ -1374,35 +1375,16 @@ function findFileInfo(element, inspector) {
|
|
|
1374
1375
|
};
|
|
1375
1376
|
}
|
|
1376
1377
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
1377
|
-
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
try {
|
|
1386
|
-
const elements = document.elementsFromPoint(x, y);
|
|
1387
|
-
for (const el of elements) {
|
|
1388
|
-
if (el.closest("#vue-inspector-container")) continue;
|
|
1389
|
-
if (el.closest(".opencode-widget")) continue;
|
|
1390
|
-
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
1391
|
-
if (boundary) {
|
|
1392
|
-
if (boundary.contains(el) || el === boundary) {
|
|
1393
|
-
element = el;
|
|
1394
|
-
break;
|
|
1395
|
-
}
|
|
1396
|
-
} else {
|
|
1397
|
-
element = el;
|
|
1398
|
-
break;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
} finally {
|
|
1402
|
-
if (highlight) highlight.style.display = highlightDisplay;
|
|
1403
|
-
if (tooltip) tooltip.style.display = tooltipDisplay;
|
|
1378
|
+
const elements = document.elementsFromPoint(x, y);
|
|
1379
|
+
for (const el of elements) {
|
|
1380
|
+
if (el.closest("#vue-inspector-container")) continue;
|
|
1381
|
+
if (el.closest(".opencode-widget")) continue;
|
|
1382
|
+
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
1383
|
+
if (boundary) {
|
|
1384
|
+
if (boundary.contains(el) || el === boundary) return el;
|
|
1385
|
+
} else return el;
|
|
1404
1386
|
}
|
|
1405
|
-
return
|
|
1387
|
+
return null;
|
|
1406
1388
|
}
|
|
1407
1389
|
function useInspector(options) {
|
|
1408
1390
|
const highlightVisible = (0, vue.ref)(false);
|
|
@@ -1423,74 +1405,117 @@ function useInspector(options) {
|
|
|
1423
1405
|
});
|
|
1424
1406
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
1425
1407
|
let inspectorCheckTimer = null;
|
|
1408
|
+
let currentHighlightElement = null;
|
|
1409
|
+
let currentFileInfo = {
|
|
1410
|
+
file: null,
|
|
1411
|
+
line: null,
|
|
1412
|
+
column: null
|
|
1413
|
+
};
|
|
1414
|
+
let currentPrimary = "#3b82f6";
|
|
1415
|
+
let currentPrimaryBg = "rgba(59, 130, 246, 0.1)";
|
|
1416
|
+
let currentDescription = "";
|
|
1417
|
+
let currentFileInfoText = "";
|
|
1426
1418
|
function handleMouseMoveCore(e) {
|
|
1427
1419
|
var _a, _b;
|
|
1428
1420
|
if (!options.selectMode.value) return;
|
|
1429
1421
|
const inspector = window.__VUE_INSPECTOR__;
|
|
1422
|
+
const highlight = document.querySelector(".opencode-element-highlight");
|
|
1423
|
+
const tooltip = document.querySelector(".opencode-element-tooltip");
|
|
1424
|
+
if (highlight) highlight.style.pointerEvents = "none";
|
|
1425
|
+
if (tooltip) tooltip.style.pointerEvents = "none";
|
|
1430
1426
|
let elementToHighlight = null;
|
|
1427
|
+
let targetNode = null;
|
|
1431
1428
|
let fileInfo = {
|
|
1432
1429
|
file: null,
|
|
1433
1430
|
line: null,
|
|
1434
1431
|
column: null
|
|
1435
1432
|
};
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1433
|
+
try {
|
|
1434
|
+
if (inspector) {
|
|
1435
|
+
const result = inspector.getTargetNode(e);
|
|
1436
|
+
targetNode = result.targetNode;
|
|
1437
|
+
const params = result.params;
|
|
1438
|
+
if (targetNode) {
|
|
1439
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
|
|
1440
|
+
if (params && params.file) fileInfo = {
|
|
1441
|
+
file: params.file,
|
|
1442
|
+
line: (_a = params.line) != null ? _a : null,
|
|
1443
|
+
column: (_b = params.column) != null ? _b : null
|
|
1444
|
+
};
|
|
1445
|
+
else fileInfo = findFileInfo(targetNode, inspector);
|
|
1446
|
+
}
|
|
1446
1447
|
}
|
|
1448
|
+
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1449
|
+
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1450
|
+
} finally {
|
|
1451
|
+
if (highlight) highlight.style.pointerEvents = "";
|
|
1452
|
+
if (tooltip) tooltip.style.pointerEvents = "";
|
|
1447
1453
|
}
|
|
1448
|
-
if (!elementToHighlight) elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
1449
|
-
if (elementToHighlight && !fileInfo.file) fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
1450
1454
|
if (elementToHighlight) {
|
|
1451
|
-
const
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
width: `${rect.width}px`,
|
|
1465
|
-
height: `${rect.height}px`,
|
|
1466
|
-
border: `2px solid ${primary}`,
|
|
1467
|
-
background: primaryBg
|
|
1468
|
-
};
|
|
1469
|
-
const description = getElementDescription(elementToHighlight);
|
|
1470
|
-
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
1455
|
+
const elementChanged = currentHighlightElement !== elementToHighlight;
|
|
1456
|
+
if (elementChanged) {
|
|
1457
|
+
currentHighlightElement = elementToHighlight;
|
|
1458
|
+
currentFileInfo = fileInfo;
|
|
1459
|
+
const widget = document.querySelector(".opencode-widget");
|
|
1460
|
+
if (widget) {
|
|
1461
|
+
const style = getComputedStyle(widget);
|
|
1462
|
+
currentPrimary = style.getPropertyValue("--oc-primary").trim() || currentPrimary;
|
|
1463
|
+
currentPrimaryBg = style.getPropertyValue("--oc-primary-bg").trim() || currentPrimaryBg;
|
|
1464
|
+
}
|
|
1465
|
+
currentDescription = getElementDescription(elementToHighlight);
|
|
1466
|
+
} else if (!currentFileInfo.file && fileInfo.file) currentFileInfo = fileInfo;
|
|
1467
|
+
const fileName = currentFileInfo.file ? currentFileInfo.file.split("/").pop() : "";
|
|
1471
1468
|
let lineInfo = "";
|
|
1472
|
-
if (
|
|
1473
|
-
lineInfo = `:${
|
|
1474
|
-
if (
|
|
1469
|
+
if (currentFileInfo.line) {
|
|
1470
|
+
lineInfo = `:${currentFileInfo.line}`;
|
|
1471
|
+
if (currentFileInfo.column) lineInfo += `:${currentFileInfo.column}`;
|
|
1472
|
+
}
|
|
1473
|
+
const newFileInfoText = fileName ? `${fileName}${lineInfo}` : "";
|
|
1474
|
+
if (elementChanged || currentFileInfoText !== newFileInfoText) {
|
|
1475
|
+
currentFileInfoText = newFileInfoText;
|
|
1476
|
+
tooltipContent.value = {
|
|
1477
|
+
description: currentDescription,
|
|
1478
|
+
fileInfo: currentFileInfoText
|
|
1479
|
+
};
|
|
1475
1480
|
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1481
|
+
const rect = elementToHighlight.getBoundingClientRect();
|
|
1482
|
+
const newTop = `${rect.top}px`;
|
|
1483
|
+
const newLeft = `${rect.left}px`;
|
|
1484
|
+
const newWidth = `${rect.width}px`;
|
|
1485
|
+
const newHeight = `${rect.height}px`;
|
|
1486
|
+
if (highlightStyle.value.top !== newTop || highlightStyle.value.left !== newLeft || highlightStyle.value.width !== newWidth || highlightStyle.value.height !== newHeight) highlightStyle.value = {
|
|
1487
|
+
top: newTop,
|
|
1488
|
+
left: newLeft,
|
|
1489
|
+
width: newWidth,
|
|
1490
|
+
height: newHeight,
|
|
1491
|
+
border: `2px solid ${currentPrimary}`,
|
|
1492
|
+
background: currentPrimaryBg
|
|
1479
1493
|
};
|
|
1480
|
-
tooltipVisible.value = true;
|
|
1481
1494
|
const tooltipHeight = 50;
|
|
1482
1495
|
const tooltipWidth = 200;
|
|
1483
1496
|
let tooltipTop = rect.top - tooltipHeight - 8;
|
|
1484
1497
|
let tooltipLeft = rect.left;
|
|
1485
1498
|
if (tooltipTop < 10) tooltipTop = rect.bottom + 8;
|
|
1486
1499
|
if (tooltipLeft + tooltipWidth > window.innerWidth - 10) tooltipLeft = window.innerWidth - tooltipWidth - 10;
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1500
|
+
const newTooltipTop = `${tooltipTop}px`;
|
|
1501
|
+
const newTooltipLeft = `${tooltipLeft}px`;
|
|
1502
|
+
if (tooltipStyle.value.top !== newTooltipTop || tooltipStyle.value.left !== newTooltipLeft) tooltipStyle.value = {
|
|
1503
|
+
top: newTooltipTop,
|
|
1504
|
+
left: newTooltipLeft
|
|
1490
1505
|
};
|
|
1506
|
+
if (!highlightVisible.value) highlightVisible.value = true;
|
|
1507
|
+
if (!tooltipVisible.value) tooltipVisible.value = true;
|
|
1491
1508
|
} else {
|
|
1492
|
-
|
|
1493
|
-
|
|
1509
|
+
currentHighlightElement = null;
|
|
1510
|
+
currentDescription = "";
|
|
1511
|
+
currentFileInfoText = "";
|
|
1512
|
+
currentFileInfo = {
|
|
1513
|
+
file: null,
|
|
1514
|
+
line: null,
|
|
1515
|
+
column: null
|
|
1516
|
+
};
|
|
1517
|
+
if (highlightVisible.value) highlightVisible.value = false;
|
|
1518
|
+
if (tooltipVisible.value) tooltipVisible.value = false;
|
|
1494
1519
|
}
|
|
1495
1520
|
}
|
|
1496
1521
|
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
@@ -1554,6 +1579,14 @@ function useInspector(options) {
|
|
|
1554
1579
|
if (inspector) inspector.disable();
|
|
1555
1580
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
1556
1581
|
document.removeEventListener("keydown", handleKeydown, true);
|
|
1582
|
+
currentHighlightElement = null;
|
|
1583
|
+
currentDescription = "";
|
|
1584
|
+
currentFileInfoText = "";
|
|
1585
|
+
currentFileInfo = {
|
|
1586
|
+
file: null,
|
|
1587
|
+
line: null,
|
|
1588
|
+
column: null
|
|
1589
|
+
};
|
|
1557
1590
|
highlightVisible.value = false;
|
|
1558
1591
|
tooltipVisible.value = false;
|
|
1559
1592
|
}
|
|
@@ -1584,6 +1617,62 @@ function useInspector(options) {
|
|
|
1584
1617
|
};
|
|
1585
1618
|
}
|
|
1586
1619
|
//#endregion
|
|
1620
|
+
//#region es/open-code-widget/composables/use-persist-state.js
|
|
1621
|
+
var STORAGE_KEY = "opencode-widget-state";
|
|
1622
|
+
function loadState() {
|
|
1623
|
+
if (typeof window === "undefined") return null;
|
|
1624
|
+
try {
|
|
1625
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
1626
|
+
if (stored) return JSON.parse(stored);
|
|
1627
|
+
} catch (e) {
|
|
1628
|
+
console.warn("[OpenCodeWidget] Failed to load persisted state:", e);
|
|
1629
|
+
}
|
|
1630
|
+
return null;
|
|
1631
|
+
}
|
|
1632
|
+
function saveState(state) {
|
|
1633
|
+
if (typeof window === "undefined") return;
|
|
1634
|
+
try {
|
|
1635
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
1636
|
+
} catch (e) {
|
|
1637
|
+
console.warn("[OpenCodeWidget] Failed to save state:", e);
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
function usePersistState(options) {
|
|
1641
|
+
const restoreState = () => {
|
|
1642
|
+
const saved = loadState();
|
|
1643
|
+
if (options.onRestore) options.onRestore(saved || {});
|
|
1644
|
+
return saved;
|
|
1645
|
+
};
|
|
1646
|
+
const getCurrentState = () => ({
|
|
1647
|
+
open: options.open.value,
|
|
1648
|
+
minimized: options.minimized.value,
|
|
1649
|
+
promptDockVisible: options.promptDockVisible.value,
|
|
1650
|
+
bubbleOffset: options.bubbleOffset.value,
|
|
1651
|
+
theme: options.theme.value,
|
|
1652
|
+
sessionListCollapsed: options.sessionListCollapsed.value
|
|
1653
|
+
});
|
|
1654
|
+
const persistState = () => {
|
|
1655
|
+
saveState(getCurrentState());
|
|
1656
|
+
};
|
|
1657
|
+
(0, vue.onMounted)(() => {
|
|
1658
|
+
restoreState();
|
|
1659
|
+
(0, vue.watch)([
|
|
1660
|
+
options.open,
|
|
1661
|
+
options.minimized,
|
|
1662
|
+
options.promptDockVisible,
|
|
1663
|
+
options.bubbleOffset,
|
|
1664
|
+
options.theme,
|
|
1665
|
+
options.sessionListCollapsed
|
|
1666
|
+
], () => {
|
|
1667
|
+
persistState();
|
|
1668
|
+
}, { deep: true });
|
|
1669
|
+
});
|
|
1670
|
+
return {
|
|
1671
|
+
restoreState,
|
|
1672
|
+
persistState
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
//#endregion
|
|
1587
1676
|
//#region es/open-code-widget/src/index.vue.js
|
|
1588
1677
|
var __defProp = Object.defineProperty;
|
|
1589
1678
|
var __defProps = Object.defineProperties;
|
|
@@ -1787,17 +1876,26 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
1787
1876
|
var _a;
|
|
1788
1877
|
(_a = frameRef.value) == null || _a.sendMessageToIframe(type, data);
|
|
1789
1878
|
};
|
|
1879
|
+
const localSessionListCollapsed = (0, vue.ref)(props.sessionListCollapsed);
|
|
1880
|
+
const minimized = (0, vue.ref)(false);
|
|
1881
|
+
const promptDockVisible = (0, vue.ref)(true);
|
|
1882
|
+
const isRestoring = (0, vue.ref)(true);
|
|
1883
|
+
const iframeLoaded = (0, vue.ref)(false);
|
|
1884
|
+
const syncStateToIframe = () => {
|
|
1885
|
+
if (!iframeLoaded.value) return;
|
|
1886
|
+
sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
|
|
1887
|
+
sendMessageToIframe("minimize-state-change", { minimized: minimized.value });
|
|
1888
|
+
};
|
|
1790
1889
|
const handleFrameLoaded = () => {
|
|
1791
1890
|
emit("frame-loaded");
|
|
1891
|
+
iframeLoaded.value = true;
|
|
1892
|
+
syncStateToIframe();
|
|
1792
1893
|
};
|
|
1793
1894
|
__expose({
|
|
1794
1895
|
showNotification,
|
|
1795
1896
|
showConfirmDialog,
|
|
1796
1897
|
sendMessageToIframe
|
|
1797
1898
|
});
|
|
1798
|
-
const localSessionListCollapsed = (0, vue.ref)(props.sessionListCollapsed);
|
|
1799
|
-
const minimized = (0, vue.ref)(false);
|
|
1800
|
-
const promptDockVisible = (0, vue.ref)(true);
|
|
1801
1899
|
(0, vue.watch)(() => props.sessionListCollapsed, (val) => {
|
|
1802
1900
|
localSessionListCollapsed.value = val;
|
|
1803
1901
|
});
|
|
@@ -1872,6 +1970,48 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
1872
1970
|
emit("toggle-select-mode", false);
|
|
1873
1971
|
}
|
|
1874
1972
|
});
|
|
1973
|
+
const bubbleOffset = (0, vue.ref)(void 0);
|
|
1974
|
+
usePersistState({
|
|
1975
|
+
open: (0, vue.toRef)(props, "open"),
|
|
1976
|
+
minimized,
|
|
1977
|
+
promptDockVisible,
|
|
1978
|
+
bubbleOffset,
|
|
1979
|
+
theme: (0, vue.toRef)(props, "theme"),
|
|
1980
|
+
sessionListCollapsed: localSessionListCollapsed,
|
|
1981
|
+
onRestore: (state) => {
|
|
1982
|
+
if (state.open !== void 0 && state.open !== props.open) {
|
|
1983
|
+
emit("update:open", state.open);
|
|
1984
|
+
emit("toggle", state.open);
|
|
1985
|
+
}
|
|
1986
|
+
if (state.minimized !== void 0) minimized.value = state.minimized;
|
|
1987
|
+
if (state.bubbleOffset !== void 0) {
|
|
1988
|
+
const bubbleSize = 44;
|
|
1989
|
+
const margin = 10;
|
|
1990
|
+
const maxX = window.innerWidth - bubbleSize - margin;
|
|
1991
|
+
const maxY = window.innerHeight - bubbleSize - margin;
|
|
1992
|
+
bubbleOffset.value = {
|
|
1993
|
+
x: Math.max(margin, Math.min(state.bubbleOffset.x, maxX)),
|
|
1994
|
+
y: Math.max(margin, Math.min(state.bubbleOffset.y, maxY))
|
|
1995
|
+
};
|
|
1996
|
+
}
|
|
1997
|
+
if (state.theme !== void 0 && state.theme !== props.theme) {
|
|
1998
|
+
emit("update:theme", state.theme);
|
|
1999
|
+
emit("toggle-theme", state.theme);
|
|
2000
|
+
}
|
|
2001
|
+
if (state.sessionListCollapsed !== void 0 && state.sessionListCollapsed !== props.sessionListCollapsed) {
|
|
2002
|
+
localSessionListCollapsed.value = state.sessionListCollapsed;
|
|
2003
|
+
emit("update:sessionListCollapsed", state.sessionListCollapsed);
|
|
2004
|
+
}
|
|
2005
|
+
if (state.promptDockVisible !== void 0) promptDockVisible.value = state.promptDockVisible;
|
|
2006
|
+
else if (minimized.value) promptDockVisible.value = false;
|
|
2007
|
+
(0, vue.nextTick)(() => {
|
|
2008
|
+
syncStateToIframe();
|
|
2009
|
+
setTimeout(() => {
|
|
2010
|
+
isRestoring.value = false;
|
|
2011
|
+
}, 50);
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
});
|
|
1875
2015
|
const handleToggleMinimize = () => {
|
|
1876
2016
|
minimized.value = !minimized.value;
|
|
1877
2017
|
promptDockVisible.value = !minimized.value;
|
|
@@ -1882,15 +2022,29 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
1882
2022
|
promptDockVisible.value = !promptDockVisible.value;
|
|
1883
2023
|
sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
|
|
1884
2024
|
};
|
|
1885
|
-
const
|
|
2025
|
+
const windowWidth = (0, vue.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
2026
|
+
const windowHeight = (0, vue.ref)(typeof window !== "undefined" ? window.innerHeight : 0);
|
|
2027
|
+
const handleWindowResize = () => {
|
|
2028
|
+
if (typeof window !== "undefined") {
|
|
2029
|
+
windowWidth.value = window.innerWidth;
|
|
2030
|
+
windowHeight.value = window.innerHeight;
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
(0, vue.onMounted)(() => {
|
|
2034
|
+
if (typeof window !== "undefined") window.addEventListener("resize", handleWindowResize);
|
|
2035
|
+
});
|
|
2036
|
+
(0, vue.onUnmounted)(() => {
|
|
2037
|
+
if (typeof window !== "undefined") window.removeEventListener("resize", handleWindowResize);
|
|
2038
|
+
});
|
|
1886
2039
|
const bubbleQuadrant = (0, vue.computed)(() => {
|
|
1887
2040
|
var _a, _b, _c, _d;
|
|
1888
2041
|
if (typeof window === "undefined") return "bottom-right";
|
|
1889
|
-
const centerX =
|
|
1890
|
-
const centerY =
|
|
2042
|
+
const centerX = windowWidth.value / 2;
|
|
2043
|
+
const centerY = windowHeight.value / 2;
|
|
1891
2044
|
const bubbleSize = 44;
|
|
1892
|
-
const
|
|
1893
|
-
const
|
|
2045
|
+
const currentOffset = (_b = (_a = triggerRef.value) == null ? void 0 : _a.offset) != null ? _b : bubbleOffset.value;
|
|
2046
|
+
const effectiveX = ((_c = currentOffset == null ? void 0 : currentOffset.x) != null ? _c : windowWidth.value - bubbleSize - 24) + bubbleSize / 2;
|
|
2047
|
+
const effectiveY = ((_d = currentOffset == null ? void 0 : currentOffset.y) != null ? _d : windowHeight.value - bubbleSize - 24) + bubbleSize / 2;
|
|
1894
2048
|
if (effectiveX >= centerX && effectiveY >= centerY) return "bottom-right";
|
|
1895
2049
|
else if (effectiveX < centerX && effectiveY >= centerY) return "bottom-left";
|
|
1896
2050
|
else if (effectiveX >= centerX && effectiveY < centerY) return "top-right";
|
|
@@ -1901,35 +2055,37 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
1901
2055
|
return quadrant === "top-right" || quadrant === "bottom-right";
|
|
1902
2056
|
});
|
|
1903
2057
|
const chatPositionStyle = (0, vue.computed)(() => {
|
|
1904
|
-
var _a;
|
|
2058
|
+
var _a, _b, _c;
|
|
1905
2059
|
if (typeof window === "undefined") return {};
|
|
1906
|
-
const windowWidth = window.innerWidth;
|
|
1907
|
-
const windowHeight = window.innerHeight;
|
|
1908
2060
|
const chatWidth = minimized.value ? 300 : 700;
|
|
1909
|
-
const chatHeight = minimized.value ? 300 : Math.min(windowHeight * .86, windowHeight - 40);
|
|
2061
|
+
const chatHeight = minimized.value ? 300 : Math.min(windowHeight.value * .86, windowHeight.value - 40);
|
|
1910
2062
|
const gap = 24;
|
|
1911
2063
|
const bubbleSize = 44;
|
|
1912
2064
|
const screenMargin = 20;
|
|
1913
|
-
const effectiveOffset = (_a = bubbleOffset.value) != null ?
|
|
1914
|
-
x: windowWidth - bubbleSize - gap,
|
|
1915
|
-
y: windowHeight - bubbleSize - gap
|
|
2065
|
+
const effectiveOffset = (_c = (_b = (_a = triggerRef.value) == null ? void 0 : _a.offset) != null ? _b : bubbleOffset.value) != null ? _c : {
|
|
2066
|
+
x: windowWidth.value - bubbleSize - gap,
|
|
2067
|
+
y: windowHeight.value - bubbleSize - gap
|
|
1916
2068
|
};
|
|
1917
2069
|
const style = {};
|
|
1918
2070
|
if (isBubbleOnRightSide.value) {
|
|
1919
|
-
let rightPos = windowWidth - effectiveOffset.x + gap;
|
|
1920
|
-
const
|
|
2071
|
+
let rightPos = windowWidth.value - effectiveOffset.x + gap;
|
|
2072
|
+
const minRight = screenMargin;
|
|
2073
|
+
const maxRight = windowWidth.value - chatWidth - screenMargin;
|
|
1921
2074
|
if (rightPos > maxRight) rightPos = maxRight;
|
|
2075
|
+
if (rightPos < minRight) rightPos = minRight;
|
|
1922
2076
|
style.right = `${rightPos}px`;
|
|
1923
2077
|
style.left = "auto";
|
|
1924
2078
|
} else {
|
|
1925
2079
|
let leftPos = effectiveOffset.x + bubbleSize + gap;
|
|
1926
|
-
const
|
|
2080
|
+
const minLeft = screenMargin;
|
|
2081
|
+
const maxLeft = windowWidth.value - chatWidth - screenMargin;
|
|
1927
2082
|
if (leftPos > maxLeft) leftPos = maxLeft;
|
|
2083
|
+
if (leftPos < minLeft) leftPos = minLeft;
|
|
1928
2084
|
style.left = `${leftPos}px`;
|
|
1929
2085
|
style.right = "auto";
|
|
1930
2086
|
}
|
|
1931
|
-
let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
|
|
1932
|
-
const maxBottom = windowHeight - chatHeight - screenMargin;
|
|
2087
|
+
let bottomPos = windowHeight.value - effectiveOffset.y - bubbleSize;
|
|
2088
|
+
const maxBottom = windowHeight.value - chatHeight - screenMargin;
|
|
1933
2089
|
if (bottomPos > maxBottom) bottomPos = maxBottom;
|
|
1934
2090
|
if (bottomPos < screenMargin) bottomPos = screenMargin;
|
|
1935
2091
|
style.bottom = `${bottomPos}px`;
|
|
@@ -1991,6 +2147,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
1991
2147
|
thinking: (0, vue.toRef)(props, "thinking"),
|
|
1992
2148
|
minimized,
|
|
1993
2149
|
promptDockVisible,
|
|
2150
|
+
bubbleOffset,
|
|
1994
2151
|
iframeSource,
|
|
1995
2152
|
buttonActive,
|
|
1996
2153
|
sessionListTitle,
|
|
@@ -2012,7 +2169,8 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
2012
2169
|
handleClickSelectedNode,
|
|
2013
2170
|
handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
|
|
2014
2171
|
handleClearSelectedNodes,
|
|
2015
|
-
handleFrameLoaded
|
|
2172
|
+
handleFrameLoaded,
|
|
2173
|
+
handleBubbleOffsetChange
|
|
2016
2174
|
});
|
|
2017
2175
|
const __returned__ = {
|
|
2018
2176
|
props,
|
|
@@ -2042,10 +2200,13 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
2042
2200
|
frameRef,
|
|
2043
2201
|
triggerRef,
|
|
2044
2202
|
sendMessageToIframe,
|
|
2045
|
-
handleFrameLoaded,
|
|
2046
2203
|
localSessionListCollapsed,
|
|
2047
2204
|
minimized,
|
|
2048
2205
|
promptDockVisible,
|
|
2206
|
+
isRestoring,
|
|
2207
|
+
iframeLoaded,
|
|
2208
|
+
syncStateToIframe,
|
|
2209
|
+
handleFrameLoaded,
|
|
2049
2210
|
buttonActive,
|
|
2050
2211
|
containerClasses,
|
|
2051
2212
|
iframeSource,
|
|
@@ -2072,9 +2233,12 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
|
|
|
2072
2233
|
tooltipVisible,
|
|
2073
2234
|
tooltipStyle,
|
|
2074
2235
|
tooltipContent,
|
|
2236
|
+
bubbleOffset,
|
|
2075
2237
|
handleToggleMinimize,
|
|
2076
2238
|
handleTogglePromptDock,
|
|
2077
|
-
|
|
2239
|
+
windowWidth,
|
|
2240
|
+
windowHeight,
|
|
2241
|
+
handleWindowResize,
|
|
2078
2242
|
bubbleQuadrant,
|
|
2079
2243
|
isBubbleOnRightSide,
|
|
2080
2244
|
chatPositionStyle,
|
|
@@ -2131,7 +2295,6 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
2131
2295
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)($setup.containerClasses) }, [
|
|
2132
2296
|
(0, vue.createVNode)($setup["Trigger"], {
|
|
2133
2297
|
ref: "triggerRef",
|
|
2134
|
-
onOffsetChange: $setup.handleBubbleOffsetChange,
|
|
2135
2298
|
onDragStart: $setup.handleDragStart,
|
|
2136
2299
|
onDragEnd: $setup.handleDragEnd
|
|
2137
2300
|
}, (0, vue.createSlots)({ _: 2 }, [$setup.slots["button-icon"] ? {
|
|
@@ -2143,7 +2306,8 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
2143
2306
|
class: (0, vue.normalizeClass)(["opencode-chat", {
|
|
2144
2307
|
open: $props.open,
|
|
2145
2308
|
minimized: $setup.minimized,
|
|
2146
|
-
dragging: $setup.isDragging
|
|
2309
|
+
dragging: $setup.isDragging,
|
|
2310
|
+
"no-transition": $setup.isRestoring
|
|
2147
2311
|
}]),
|
|
2148
2312
|
style: (0, vue.normalizeStyle)($setup.chatPositionStyle)
|
|
2149
2313
|
}, [
|
|
@@ -2198,11 +2362,11 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
2198
2362
|
(0, vue.createVNode)($setup["SelectHint"]),
|
|
2199
2363
|
(0, vue.withDirectives)((0, vue.createElementVNode)("div", {
|
|
2200
2364
|
class: "opencode-element-highlight",
|
|
2201
|
-
style: (0, vue.normalizeStyle)(
|
|
2365
|
+
style: (0, vue.normalizeStyle)($setup.highlightStyle)
|
|
2202
2366
|
}, null, 4), [[vue.vShow, $setup.highlightVisible]]),
|
|
2203
2367
|
(0, vue.withDirectives)((0, vue.createElementVNode)("div", {
|
|
2204
2368
|
class: "opencode-element-tooltip",
|
|
2205
|
-
style: (0, vue.normalizeStyle)(
|
|
2369
|
+
style: (0, vue.normalizeStyle)($setup.tooltipStyle)
|
|
2206
2370
|
}, [(0, vue.createElementVNode)("div", _hoisted_3, (0, vue.toDisplayString)($setup.tooltipContent.description), 1), (0, vue.createElementVNode)("div", _hoisted_4, (0, vue.toDisplayString)($setup.tooltipContent.fileInfo), 1)], 4), [[vue.vShow, $setup.tooltipVisible]]),
|
|
2207
2371
|
$setup.dialogVisible ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_5, [(0, vue.createElementVNode)("div", _hoisted_6, [(0, vue.createElementVNode)("div", _hoisted_7, [(0, vue.createElementVNode)("div", _hoisted_8, (0, vue.toDisplayString)($setup.dialogMessage), 1)]), (0, vue.createElementVNode)("div", { class: "opencode-dialog-actions" }, [(0, vue.createElementVNode)("button", {
|
|
2208
2372
|
class: "opencode-dialog-btn cancel",
|
|
@@ -2220,7 +2384,7 @@ __vue_sfc__.render = __vue_render__;
|
|
|
2220
2384
|
var open_code_widget_default = __vue_sfc__;
|
|
2221
2385
|
//#endregion
|
|
2222
2386
|
//#region es/index.js
|
|
2223
|
-
var version = "1.0.
|
|
2387
|
+
var version = "1.0.27";
|
|
2224
2388
|
function install(app, options) {
|
|
2225
2389
|
[open_code_widget_default].forEach((item) => {
|
|
2226
2390
|
if (item.install) app.use(item, options);
|