agentation-vue 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +27 -0
  2. package/dist/AgentationVue.d.vue.ts +27 -0
  3. package/dist/AgentationVue.vue +839 -0
  4. package/dist/AgentationVue.vue.d.ts +27 -0
  5. package/dist/components/AgentationToolbar.d.vue.ts +36 -0
  6. package/dist/components/AgentationToolbar.vue +233 -0
  7. package/dist/components/AgentationToolbar.vue.d.ts +36 -0
  8. package/dist/components/AnnotationInput.d.vue.ts +21 -0
  9. package/dist/components/AnnotationInput.vue +105 -0
  10. package/dist/components/AnnotationInput.vue.d.ts +21 -0
  11. package/dist/components/AnnotationMarker.d.vue.ts +15 -0
  12. package/dist/components/AnnotationMarker.vue +46 -0
  13. package/dist/components/AnnotationMarker.vue.d.ts +15 -0
  14. package/dist/components/ComponentChain.d.vue.ts +10 -0
  15. package/dist/components/ComponentChain.vue +91 -0
  16. package/dist/components/ComponentChain.vue.d.ts +10 -0
  17. package/dist/components/ElementHighlight.d.vue.ts +9 -0
  18. package/dist/components/ElementHighlight.vue +33 -0
  19. package/dist/components/ElementHighlight.vue.d.ts +9 -0
  20. package/dist/components/SettingsPanel.d.vue.ts +10 -0
  21. package/dist/components/SettingsPanel.vue +143 -0
  22. package/dist/components/SettingsPanel.vue.d.ts +10 -0
  23. package/dist/components/SettingsPopover.d.vue.ts +14 -0
  24. package/dist/components/SettingsPopover.vue +235 -0
  25. package/dist/components/SettingsPopover.vue.d.ts +14 -0
  26. package/dist/components/VaButton.d.vue.ts +23 -0
  27. package/dist/components/VaButton.vue +19 -0
  28. package/dist/components/VaButton.vue.d.ts +23 -0
  29. package/dist/components/VaIcon.d.vue.ts +6 -0
  30. package/dist/components/VaIcon.vue +18 -0
  31. package/dist/components/VaIcon.vue.d.ts +6 -0
  32. package/dist/components/VaIconButton.d.vue.ts +25 -0
  33. package/dist/components/VaIconButton.vue +43 -0
  34. package/dist/components/VaIconButton.vue.d.ts +25 -0
  35. package/dist/components/VaToggle.d.vue.ts +10 -0
  36. package/dist/components/VaToggle.vue +23 -0
  37. package/dist/components/VaToggle.vue.d.ts +10 -0
  38. package/dist/composables/useAnimationPause.d.ts +7 -0
  39. package/dist/composables/useAnimationPause.js +52 -0
  40. package/dist/composables/useAnimationPause.mjs +43 -0
  41. package/dist/composables/useAnnotations.d.ts +105 -0
  42. package/dist/composables/useAnnotations.js +106 -0
  43. package/dist/composables/useAnnotations.mjs +108 -0
  44. package/dist/composables/useAreaSelect.d.ts +21 -0
  45. package/dist/composables/useAreaSelect.js +62 -0
  46. package/dist/composables/useAreaSelect.mjs +41 -0
  47. package/dist/composables/useElementDetection.d.ts +22 -0
  48. package/dist/composables/useElementDetection.js +85 -0
  49. package/dist/composables/useElementDetection.mjs +82 -0
  50. package/dist/composables/useInteractionMode.d.ts +5 -0
  51. package/dist/composables/useInteractionMode.js +29 -0
  52. package/dist/composables/useInteractionMode.mjs +20 -0
  53. package/dist/composables/useKeyboardShortcuts.d.ts +43 -0
  54. package/dist/composables/useKeyboardShortcuts.js +202 -0
  55. package/dist/composables/useKeyboardShortcuts.mjs +223 -0
  56. package/dist/composables/useMarkerPositions.d.ts +5 -0
  57. package/dist/composables/useMarkerPositions.js +45 -0
  58. package/dist/composables/useMarkerPositions.mjs +36 -0
  59. package/dist/composables/useMultiSelect.d.ts +20 -0
  60. package/dist/composables/useMultiSelect.js +108 -0
  61. package/dist/composables/useMultiSelect.mjs +85 -0
  62. package/dist/composables/useOutputFormatter.d.ts +5 -0
  63. package/dist/composables/useOutputFormatter.js +100 -0
  64. package/dist/composables/useOutputFormatter.mjs +91 -0
  65. package/dist/composables/useSettings.d.ts +14 -0
  66. package/dist/composables/useSettings.js +48 -0
  67. package/dist/composables/useSettings.mjs +38 -0
  68. package/dist/composables/useTextSelection.d.ts +11 -0
  69. package/dist/composables/useTextSelection.js +33 -0
  70. package/dist/composables/useTextSelection.mjs +22 -0
  71. package/dist/composables/useToolbarAutoHide.d.ts +19 -0
  72. package/dist/composables/useToolbarAutoHide.js +270 -0
  73. package/dist/composables/useToolbarAutoHide.mjs +208 -0
  74. package/dist/composables/useToolbarDragSnap.d.ts +30 -0
  75. package/dist/composables/useToolbarDragSnap.js +296 -0
  76. package/dist/composables/useToolbarDragSnap.mjs +245 -0
  77. package/dist/constants.d.ts +2 -0
  78. package/dist/constants.js +8 -0
  79. package/dist/constants.mjs +2 -0
  80. package/dist/directives/vaTooltip.d.ts +22 -0
  81. package/dist/directives/vaTooltip.js +241 -0
  82. package/dist/directives/vaTooltip.mjs +257 -0
  83. package/dist/icons.d.ts +16 -0
  84. package/dist/icons.js +21 -0
  85. package/dist/icons.mjs +15 -0
  86. package/dist/index.d.ts +31 -0
  87. package/dist/index.js +168 -0
  88. package/dist/index.mjs +30 -0
  89. package/dist/styles/agentation.css +1 -0
  90. package/dist/types.d.ts +70 -0
  91. package/dist/types.js +1 -0
  92. package/dist/types.mjs +0 -0
  93. package/dist/utils/clipboard.d.ts +1 -0
  94. package/dist/utils/clipboard.js +22 -0
  95. package/dist/utils/clipboard.mjs +16 -0
  96. package/dist/utils/dom-inspector.d.ts +7 -0
  97. package/dist/utils/dom-inspector.js +168 -0
  98. package/dist/utils/dom-inspector.mjs +242 -0
  99. package/dist/utils/math.d.ts +1 -0
  100. package/dist/utils/math.js +9 -0
  101. package/dist/utils/math.mjs +3 -0
  102. package/dist/utils/portal.d.ts +2 -0
  103. package/dist/utils/portal.js +18 -0
  104. package/dist/utils/portal.mjs +11 -0
  105. package/dist/utils/selectors.d.ts +3 -0
  106. package/dist/utils/selectors.js +103 -0
  107. package/dist/utils/selectors.mjs +105 -0
  108. package/dist/utils/style.d.ts +2 -0
  109. package/dist/utils/style.js +14 -0
  110. package/dist/utils/style.mjs +8 -0
  111. package/package.json +49 -0
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useMarkerPositions = useMarkerPositions;
7
+ var _vueDemi = require("vue-demi");
8
+ function useMarkerPositions(annotations) {
9
+ let resizeObserver = null;
10
+ let rafId = null;
11
+ function recalculatePositions() {
12
+ if (rafId !== null) return;
13
+ rafId = requestAnimationFrame(() => {
14
+ rafId = null;
15
+ for (const annotation of annotations.value) {
16
+ const el = annotation._targetRef?.deref();
17
+ if (!el) continue;
18
+ const rect = el.getBoundingClientRect();
19
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
20
+ annotation.x = (rect.left + rect.width / 2) / window.innerWidth * 100;
21
+ annotation.y = annotation.isFixed ? rect.top + rect.height / 2 : rect.top + rect.height / 2 + scrollTop;
22
+ }
23
+ });
24
+ }
25
+ (0, _vueDemi.onMounted)(() => {
26
+ window.addEventListener("resize", recalculatePositions, {
27
+ passive: true
28
+ });
29
+ window.addEventListener("scroll", recalculatePositions, {
30
+ passive: true
31
+ });
32
+ resizeObserver = new ResizeObserver(recalculatePositions);
33
+ const appRoot = document.querySelector("#app") || document.body;
34
+ resizeObserver.observe(appRoot);
35
+ });
36
+ (0, _vueDemi.onBeforeUnmount)(() => {
37
+ window.removeEventListener("resize", recalculatePositions);
38
+ window.removeEventListener("scroll", recalculatePositions);
39
+ resizeObserver?.disconnect();
40
+ if (rafId !== null) cancelAnimationFrame(rafId);
41
+ });
42
+ return {
43
+ recalculatePositions
44
+ };
45
+ }
@@ -0,0 +1,36 @@
1
+ import { onBeforeUnmount, onMounted } from "vue-demi";
2
+ export function useMarkerPositions(annotations) {
3
+ let resizeObserver = null;
4
+ let rafId = null;
5
+ function recalculatePositions() {
6
+ if (rafId !== null)
7
+ return;
8
+ rafId = requestAnimationFrame(() => {
9
+ rafId = null;
10
+ for (const annotation of annotations.value) {
11
+ const el = annotation._targetRef?.deref();
12
+ if (!el)
13
+ continue;
14
+ const rect = el.getBoundingClientRect();
15
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
16
+ annotation.x = (rect.left + rect.width / 2) / window.innerWidth * 100;
17
+ annotation.y = annotation.isFixed ? rect.top + rect.height / 2 : rect.top + rect.height / 2 + scrollTop;
18
+ }
19
+ });
20
+ }
21
+ onMounted(() => {
22
+ window.addEventListener("resize", recalculatePositions, { passive: true });
23
+ window.addEventListener("scroll", recalculatePositions, { passive: true });
24
+ resizeObserver = new ResizeObserver(recalculatePositions);
25
+ const appRoot = document.querySelector("#app") || document.body;
26
+ resizeObserver.observe(appRoot);
27
+ });
28
+ onBeforeUnmount(() => {
29
+ window.removeEventListener("resize", recalculatePositions);
30
+ window.removeEventListener("scroll", recalculatePositions);
31
+ resizeObserver?.disconnect();
32
+ if (rafId !== null)
33
+ cancelAnimationFrame(rafId);
34
+ });
35
+ return { recalculatePositions };
36
+ }
@@ -0,0 +1,20 @@
1
+ import type { Ref } from 'vue-demi';
2
+ import type { BoundingBox, InteractionMode } from '../types';
3
+ export declare function useMultiSelect(mode: Ref<InteractionMode>, transitionFn: (to: InteractionMode) => boolean): {
4
+ selectionRect: Ref<{
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ } | null, BoundingBox | {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ } | null>;
15
+ selectedElements: Ref<Element[], Element[]>;
16
+ onMouseDown: (e: MouseEvent) => boolean;
17
+ onMouseMove: (e: MouseEvent) => void;
18
+ onMouseUp: () => void;
19
+ reset: () => void;
20
+ };
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useMultiSelect = useMultiSelect;
7
+ var _vueDemi = require("vue-demi");
8
+ var _constants = require("../constants");
9
+ const LEAF_TAGS = /* @__PURE__ */new Set(["button", "a", "input", "img"]);
10
+ function useMultiSelect(mode, transitionFn) {
11
+ const selectionRect = (0, _vueDemi.ref)(null);
12
+ const selectedElements = (0, _vueDemi.ref)([]);
13
+ let startX = 0;
14
+ let startY = 0;
15
+ let cachedElements = [];
16
+ let rafId = null;
17
+ function cacheElements() {
18
+ cachedElements = [];
19
+ for (const el of document.querySelectorAll("body *")) {
20
+ if (el.closest(_constants.VA_DATA_ATTR_SELECTOR)) continue;
21
+ const rect = el.getBoundingClientRect();
22
+ if (rect.width === 0 || rect.height === 0) continue;
23
+ const isLeaf = el.children.length === 0 || LEAF_TAGS.has(el.tagName.toLowerCase());
24
+ if (isLeaf) {
25
+ cachedElements.push({
26
+ el,
27
+ rect,
28
+ isLeaf
29
+ });
30
+ }
31
+ }
32
+ }
33
+ function onMouseDown(e) {
34
+ if (mode.value !== "inspect" || !e.shiftKey) return false;
35
+ e.preventDefault();
36
+ document.documentElement.style.userSelect = "none";
37
+ startX = e.clientX;
38
+ startY = e.clientY;
39
+ selectionRect.value = {
40
+ x: startX,
41
+ y: startY,
42
+ width: 0,
43
+ height: 0
44
+ };
45
+ transitionFn("multi-selecting");
46
+ cacheElements();
47
+ return true;
48
+ }
49
+ function onMouseMove(e) {
50
+ if (mode.value !== "multi-selecting") return;
51
+ const x = Math.min(startX, e.clientX);
52
+ const y = Math.min(startY, e.clientY);
53
+ const width = Math.abs(e.clientX - startX);
54
+ const height = Math.abs(e.clientY - startY);
55
+ selectionRect.value = {
56
+ x,
57
+ y,
58
+ width,
59
+ height
60
+ };
61
+ if (rafId !== null) return;
62
+ rafId = requestAnimationFrame(() => {
63
+ rafId = null;
64
+ collectIntersectedElements();
65
+ });
66
+ }
67
+ function onMouseUp() {
68
+ if (mode.value !== "multi-selecting") return;
69
+ document.documentElement.style.userSelect = "";
70
+ if (rafId !== null) {
71
+ cancelAnimationFrame(rafId);
72
+ rafId = null;
73
+ }
74
+ collectIntersectedElements();
75
+ }
76
+ function collectIntersectedElements() {
77
+ if (!selectionRect.value) return;
78
+ const rect = selectionRect.value;
79
+ const intersected = [];
80
+ for (const {
81
+ el,
82
+ rect: elRect
83
+ } of cachedElements) {
84
+ if (elRect.left < rect.x + rect.width && elRect.right > rect.x && elRect.top < rect.y + rect.height && elRect.bottom > rect.y) {
85
+ intersected.push(el);
86
+ }
87
+ }
88
+ selectedElements.value = intersected;
89
+ }
90
+ function reset() {
91
+ selectionRect.value = null;
92
+ selectedElements.value = [];
93
+ cachedElements = [];
94
+ document.documentElement.style.userSelect = "";
95
+ if (rafId !== null) {
96
+ cancelAnimationFrame(rafId);
97
+ rafId = null;
98
+ }
99
+ }
100
+ return {
101
+ selectionRect,
102
+ selectedElements,
103
+ onMouseDown,
104
+ onMouseMove,
105
+ onMouseUp,
106
+ reset
107
+ };
108
+ }
@@ -0,0 +1,85 @@
1
+ import { ref } from "vue-demi";
2
+ import { VA_DATA_ATTR_SELECTOR } from "../constants.mjs";
3
+ const LEAF_TAGS = /* @__PURE__ */ new Set(["button", "a", "input", "img"]);
4
+ export function useMultiSelect(mode, transitionFn) {
5
+ const selectionRect = ref(null);
6
+ const selectedElements = ref([]);
7
+ let startX = 0;
8
+ let startY = 0;
9
+ let cachedElements = [];
10
+ let rafId = null;
11
+ function cacheElements() {
12
+ cachedElements = [];
13
+ for (const el of document.querySelectorAll("body *")) {
14
+ if (el.closest(VA_DATA_ATTR_SELECTOR))
15
+ continue;
16
+ const rect = el.getBoundingClientRect();
17
+ if (rect.width === 0 || rect.height === 0)
18
+ continue;
19
+ const isLeaf = el.children.length === 0 || LEAF_TAGS.has(el.tagName.toLowerCase());
20
+ if (isLeaf) {
21
+ cachedElements.push({ el, rect, isLeaf });
22
+ }
23
+ }
24
+ }
25
+ function onMouseDown(e) {
26
+ if (mode.value !== "inspect" || !e.shiftKey)
27
+ return false;
28
+ e.preventDefault();
29
+ document.documentElement.style.userSelect = "none";
30
+ startX = e.clientX;
31
+ startY = e.clientY;
32
+ selectionRect.value = { x: startX, y: startY, width: 0, height: 0 };
33
+ transitionFn("multi-selecting");
34
+ cacheElements();
35
+ return true;
36
+ }
37
+ function onMouseMove(e) {
38
+ if (mode.value !== "multi-selecting")
39
+ return;
40
+ const x = Math.min(startX, e.clientX);
41
+ const y = Math.min(startY, e.clientY);
42
+ const width = Math.abs(e.clientX - startX);
43
+ const height = Math.abs(e.clientY - startY);
44
+ selectionRect.value = { x, y, width, height };
45
+ if (rafId !== null)
46
+ return;
47
+ rafId = requestAnimationFrame(() => {
48
+ rafId = null;
49
+ collectIntersectedElements();
50
+ });
51
+ }
52
+ function onMouseUp() {
53
+ if (mode.value !== "multi-selecting")
54
+ return;
55
+ document.documentElement.style.userSelect = "";
56
+ if (rafId !== null) {
57
+ cancelAnimationFrame(rafId);
58
+ rafId = null;
59
+ }
60
+ collectIntersectedElements();
61
+ }
62
+ function collectIntersectedElements() {
63
+ if (!selectionRect.value)
64
+ return;
65
+ const rect = selectionRect.value;
66
+ const intersected = [];
67
+ for (const { el, rect: elRect } of cachedElements) {
68
+ if (elRect.left < rect.x + rect.width && elRect.right > rect.x && elRect.top < rect.y + rect.height && elRect.bottom > rect.y) {
69
+ intersected.push(el);
70
+ }
71
+ }
72
+ selectedElements.value = intersected;
73
+ }
74
+ function reset() {
75
+ selectionRect.value = null;
76
+ selectedElements.value = [];
77
+ cachedElements = [];
78
+ document.documentElement.style.userSelect = "";
79
+ if (rafId !== null) {
80
+ cancelAnimationFrame(rafId);
81
+ rafId = null;
82
+ }
83
+ }
84
+ return { selectionRect, selectedElements, onMouseDown, onMouseMove, onMouseUp, reset };
85
+ }
@@ -0,0 +1,5 @@
1
+ import type { Annotation, OutputDetail } from '../types';
2
+ export declare function formatAnnotations(annotations: Annotation[], detail: OutputDetail, pageUrl: string): string;
3
+ export declare function useOutputFormatter(): {
4
+ formatAnnotations: typeof formatAnnotations;
5
+ };
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.formatAnnotations = formatAnnotations;
7
+ exports.useOutputFormatter = useOutputFormatter;
8
+ function formatAnnotations(annotations, detail, pageUrl) {
9
+ const shortUrl = pageUrl.replace(/^https?:\/\//, "");
10
+ const lines = [];
11
+ lines.push(`## Feedback \u2014 ${shortUrl}`);
12
+ lines.push("");
13
+ if (detail === "forensic") {
14
+ const viewport = typeof window !== "undefined" ? `${window.innerWidth}x${window.innerHeight}` : "unknown";
15
+ const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "unknown";
16
+ const dpr = typeof window !== "undefined" ? String(window.devicePixelRatio) : "unknown";
17
+ lines.push("### Environment");
18
+ lines.push(`- **Viewport:** ${viewport}`);
19
+ lines.push(`- **URL:** ${pageUrl}`);
20
+ lines.push(`- **User Agent:** ${userAgent}`);
21
+ lines.push(`- **Timestamp:** ${(/* @__PURE__ */new Date()).toISOString()}`);
22
+ lines.push(`- **Device Pixel Ratio:** ${dpr}`);
23
+ lines.push("");
24
+ }
25
+ for (let i = 0; i < annotations.length; i++) {
26
+ const ann = annotations[i];
27
+ const num = i + 1;
28
+ if (ann.selectedText) {
29
+ lines.push(`### ${num}. "${ann.selectedText}" (selected text)`);
30
+ } else if (ann.isMultiSelect) {
31
+ lines.push(`### ${num}. Multi-selection (${ann.elements?.length || 0} elements)`);
32
+ } else if (ann.isAreaSelect) {
33
+ lines.push(`### ${num}. Area selection`);
34
+ } else {
35
+ lines.push(`### ${num}. \`${ann.element}\` \u2014 ${ann.elementPath}`);
36
+ }
37
+ lines.push(`- **Comment:** ${ann.comment}`);
38
+ if (ann.selectedText) {
39
+ lines.push(`- **In element:** \`${ann.element}\` \u2014 ${ann.elementPath}`);
40
+ }
41
+ if (ann.isMultiSelect && ann.elements) {
42
+ lines.push(`- **Elements:**`);
43
+ for (const el of ann.elements) {
44
+ lines.push(` - \`${el.element}\` \u2014 ${el.elementPath}`);
45
+ }
46
+ }
47
+ if (ann.isAreaSelect && ann.area) {
48
+ lines.push(`- **Area:** x: ${Math.round(ann.area.x)}, y: ${Math.round(ann.area.y)}, width: ${Math.round(ann.area.width)}, height: ${Math.round(ann.area.height)}`);
49
+ }
50
+ if ((ann.isAreaSelect || ann.isMultiSelect) && ann.elementPath) {
51
+ lines.push(`- **Selection path:** ${ann.elementPath}`);
52
+ }
53
+ if ((ann.isAreaSelect || ann.isMultiSelect) && ann.boundingBox) {
54
+ const b = ann.boundingBox;
55
+ lines.push(`- **Selection box:** x: ${Math.round(b.x)}, y: ${Math.round(b.y)}, width: ${Math.round(b.width)}, height: ${Math.round(b.height)}`);
56
+ }
57
+ if (ann.vueComponents) {
58
+ lines.push(`- **Components:** ${ann.vueComponents}`);
59
+ }
60
+ if (!ann.isMultiSelect && !ann.isAreaSelect && !ann.selectedText) {
61
+ if (ann.elementPath) {
62
+ lines.push(`- **Path:** ${ann.elementPath}`);
63
+ }
64
+ }
65
+ if (ann.nearbyElements) {
66
+ lines.push(`- **Nearby:** ${ann.nearbyElements}`);
67
+ }
68
+ if (ann.nearbyText && !ann.selectedText) {
69
+ lines.push(`- **Context:** ${ann.nearbyText}`);
70
+ }
71
+ if (detail === "forensic") {
72
+ if (ann.fullPath) {
73
+ lines.push(`- **Full path:** ${ann.fullPath}`);
74
+ }
75
+ if (ann.cssClasses) {
76
+ lines.push(`- **CSS classes:** ${ann.cssClasses}`);
77
+ }
78
+ if (ann.boundingBox) {
79
+ const b = ann.boundingBox;
80
+ lines.push(`- **Bounding box:** x: ${Math.round(b.x)}, y: ${Math.round(b.y)}, width: ${Math.round(b.width)}, height: ${Math.round(b.height)}`);
81
+ }
82
+ if (ann.computedStyles) {
83
+ lines.push(`- **Computed styles:**`);
84
+ for (const line of ann.computedStyles.split("\n")) {
85
+ lines.push(` - ${line}`);
86
+ }
87
+ }
88
+ if (ann.accessibility) {
89
+ lines.push(`- **Accessibility:** ${ann.accessibility}`);
90
+ }
91
+ }
92
+ lines.push("");
93
+ }
94
+ return lines.join("\n");
95
+ }
96
+ function useOutputFormatter() {
97
+ return {
98
+ formatAnnotations
99
+ };
100
+ }
@@ -0,0 +1,91 @@
1
+ export function formatAnnotations(annotations, detail, pageUrl) {
2
+ const shortUrl = pageUrl.replace(/^https?:\/\//, "");
3
+ const lines = [];
4
+ lines.push(`## Feedback \u2014 ${shortUrl}`);
5
+ lines.push("");
6
+ if (detail === "forensic") {
7
+ const viewport = typeof window !== "undefined" ? `${window.innerWidth}x${window.innerHeight}` : "unknown";
8
+ const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "unknown";
9
+ const dpr = typeof window !== "undefined" ? String(window.devicePixelRatio) : "unknown";
10
+ lines.push("### Environment");
11
+ lines.push(`- **Viewport:** ${viewport}`);
12
+ lines.push(`- **URL:** ${pageUrl}`);
13
+ lines.push(`- **User Agent:** ${userAgent}`);
14
+ lines.push(`- **Timestamp:** ${(/* @__PURE__ */ new Date()).toISOString()}`);
15
+ lines.push(`- **Device Pixel Ratio:** ${dpr}`);
16
+ lines.push("");
17
+ }
18
+ for (let i = 0; i < annotations.length; i++) {
19
+ const ann = annotations[i];
20
+ const num = i + 1;
21
+ if (ann.selectedText) {
22
+ lines.push(`### ${num}. "${ann.selectedText}" (selected text)`);
23
+ } else if (ann.isMultiSelect) {
24
+ lines.push(`### ${num}. Multi-selection (${ann.elements?.length || 0} elements)`);
25
+ } else if (ann.isAreaSelect) {
26
+ lines.push(`### ${num}. Area selection`);
27
+ } else {
28
+ lines.push(`### ${num}. \`${ann.element}\` \u2014 ${ann.elementPath}`);
29
+ }
30
+ lines.push(`- **Comment:** ${ann.comment}`);
31
+ if (ann.selectedText) {
32
+ lines.push(`- **In element:** \`${ann.element}\` \u2014 ${ann.elementPath}`);
33
+ }
34
+ if (ann.isMultiSelect && ann.elements) {
35
+ lines.push(`- **Elements:**`);
36
+ for (const el of ann.elements) {
37
+ lines.push(` - \`${el.element}\` \u2014 ${el.elementPath}`);
38
+ }
39
+ }
40
+ if (ann.isAreaSelect && ann.area) {
41
+ lines.push(`- **Area:** x: ${Math.round(ann.area.x)}, y: ${Math.round(ann.area.y)}, width: ${Math.round(ann.area.width)}, height: ${Math.round(ann.area.height)}`);
42
+ }
43
+ if ((ann.isAreaSelect || ann.isMultiSelect) && ann.elementPath) {
44
+ lines.push(`- **Selection path:** ${ann.elementPath}`);
45
+ }
46
+ if ((ann.isAreaSelect || ann.isMultiSelect) && ann.boundingBox) {
47
+ const b = ann.boundingBox;
48
+ lines.push(`- **Selection box:** x: ${Math.round(b.x)}, y: ${Math.round(b.y)}, width: ${Math.round(b.width)}, height: ${Math.round(b.height)}`);
49
+ }
50
+ if (ann.vueComponents) {
51
+ lines.push(`- **Components:** ${ann.vueComponents}`);
52
+ }
53
+ if (!ann.isMultiSelect && !ann.isAreaSelect && !ann.selectedText) {
54
+ if (ann.elementPath) {
55
+ lines.push(`- **Path:** ${ann.elementPath}`);
56
+ }
57
+ }
58
+ if (ann.nearbyElements) {
59
+ lines.push(`- **Nearby:** ${ann.nearbyElements}`);
60
+ }
61
+ if (ann.nearbyText && !ann.selectedText) {
62
+ lines.push(`- **Context:** ${ann.nearbyText}`);
63
+ }
64
+ if (detail === "forensic") {
65
+ if (ann.fullPath) {
66
+ lines.push(`- **Full path:** ${ann.fullPath}`);
67
+ }
68
+ if (ann.cssClasses) {
69
+ lines.push(`- **CSS classes:** ${ann.cssClasses}`);
70
+ }
71
+ if (ann.boundingBox) {
72
+ const b = ann.boundingBox;
73
+ lines.push(`- **Bounding box:** x: ${Math.round(b.x)}, y: ${Math.round(b.y)}, width: ${Math.round(b.width)}, height: ${Math.round(b.height)}`);
74
+ }
75
+ if (ann.computedStyles) {
76
+ lines.push(`- **Computed styles:**`);
77
+ for (const line of ann.computedStyles.split("\n")) {
78
+ lines.push(` - ${line}`);
79
+ }
80
+ }
81
+ if (ann.accessibility) {
82
+ lines.push(`- **Accessibility:** ${ann.accessibility}`);
83
+ }
84
+ }
85
+ lines.push("");
86
+ }
87
+ return lines.join("\n");
88
+ }
89
+ export function useOutputFormatter() {
90
+ return { formatAnnotations };
91
+ }
@@ -0,0 +1,14 @@
1
+ export declare function useSettings(): {
2
+ settings: {
3
+ outputDetail: import("../types").OutputDetail;
4
+ markerColor: string;
5
+ blockPageInteractions: boolean;
6
+ autoHideToolbar: boolean;
7
+ toolbarPlacement: import("../types").ToolbarAnchor;
8
+ clearAfterCopy: boolean;
9
+ showComponentTree: boolean;
10
+ theme: "light" | "dark" | "auto";
11
+ activationKey: "none" | "Meta" | "Alt" | "Shift";
12
+ };
13
+ resetSettings: () => void;
14
+ };
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useSettings = useSettings;
7
+ var _vueDemi = require("vue-demi");
8
+ const STORAGE_KEY = "agentation-vue-settings";
9
+ const defaults = {
10
+ outputDetail: "standard",
11
+ markerColor: "#42B883",
12
+ blockPageInteractions: false,
13
+ autoHideToolbar: false,
14
+ toolbarPlacement: "bottom-right",
15
+ clearAfterCopy: false,
16
+ showComponentTree: true,
17
+ theme: "auto",
18
+ activationKey: "Shift"
19
+ };
20
+ function loadSettings() {
21
+ try {
22
+ const stored = localStorage.getItem(STORAGE_KEY);
23
+ if (stored) return {
24
+ ...defaults,
25
+ ...JSON.parse(stored)
26
+ };
27
+ } catch {}
28
+ return {
29
+ ...defaults
30
+ };
31
+ }
32
+ const settings = (0, _vueDemi.reactive)(loadSettings());
33
+ (0, _vueDemi.watch)(() => ({
34
+ ...settings
35
+ }), val => {
36
+ try {
37
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(val));
38
+ } catch {}
39
+ });
40
+ function useSettings() {
41
+ function resetSettings() {
42
+ Object.assign(settings, defaults);
43
+ }
44
+ return {
45
+ settings,
46
+ resetSettings
47
+ };
48
+ }
@@ -0,0 +1,38 @@
1
+ import { reactive, watch } from "vue-demi";
2
+ const STORAGE_KEY = "agentation-vue-settings";
3
+ const defaults = {
4
+ outputDetail: "standard",
5
+ markerColor: "#42B883",
6
+ blockPageInteractions: false,
7
+ autoHideToolbar: false,
8
+ toolbarPlacement: "bottom-right",
9
+ clearAfterCopy: false,
10
+ showComponentTree: true,
11
+ theme: "auto",
12
+ activationKey: "Shift"
13
+ };
14
+ function loadSettings() {
15
+ try {
16
+ const stored = localStorage.getItem(STORAGE_KEY);
17
+ if (stored)
18
+ return { ...defaults, ...JSON.parse(stored) };
19
+ } catch {
20
+ }
21
+ return { ...defaults };
22
+ }
23
+ const settings = reactive(loadSettings());
24
+ watch(
25
+ () => ({ ...settings }),
26
+ (val) => {
27
+ try {
28
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(val));
29
+ } catch {
30
+ }
31
+ }
32
+ );
33
+ export function useSettings() {
34
+ function resetSettings() {
35
+ Object.assign(settings, defaults);
36
+ }
37
+ return { settings, resetSettings };
38
+ }
@@ -0,0 +1,11 @@
1
+ import type { Ref } from 'vue-demi';
2
+ import type { InteractionMode } from '../types';
3
+ export interface TextSelectionResult {
4
+ selectedText: string;
5
+ range: Range;
6
+ rect: DOMRect;
7
+ anchorElement: Element;
8
+ }
9
+ export declare function useTextSelection(mode: Ref<InteractionMode>): {
10
+ checkTextSelection: (e: MouseEvent) => TextSelectionResult | null;
11
+ };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useTextSelection = useTextSelection;
7
+ function useTextSelection(mode) {
8
+ function checkTextSelection(e) {
9
+ if (mode.value !== "inspect") return null;
10
+ if (e.shiftKey || e.altKey) return null;
11
+ const selection = window.getSelection();
12
+ const selectedText = selection?.toString().trim() ?? "";
13
+ if (selectedText.length >= 2 && selection?.rangeCount) {
14
+ const range = selection.getRangeAt(0);
15
+ const rect = range.getBoundingClientRect();
16
+ if (rect.width > 5) {
17
+ const anchorElement = range.commonAncestorContainer instanceof Element ? range.commonAncestorContainer : range.commonAncestorContainer.parentElement;
18
+ if (anchorElement) {
19
+ return {
20
+ selectedText,
21
+ range,
22
+ rect,
23
+ anchorElement
24
+ };
25
+ }
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ return {
31
+ checkTextSelection
32
+ };
33
+ }
@@ -0,0 +1,22 @@
1
+ export function useTextSelection(mode) {
2
+ function checkTextSelection(e) {
3
+ if (mode.value !== "inspect")
4
+ return null;
5
+ if (e.shiftKey || e.altKey)
6
+ return null;
7
+ const selection = window.getSelection();
8
+ const selectedText = selection?.toString().trim() ?? "";
9
+ if (selectedText.length >= 2 && selection?.rangeCount) {
10
+ const range = selection.getRangeAt(0);
11
+ const rect = range.getBoundingClientRect();
12
+ if (rect.width > 5) {
13
+ const anchorElement = range.commonAncestorContainer instanceof Element ? range.commonAncestorContainer : range.commonAncestorContainer.parentElement;
14
+ if (anchorElement) {
15
+ return { selectedText, range, rect, anchorElement };
16
+ }
17
+ }
18
+ }
19
+ return null;
20
+ }
21
+ return { checkTextSelection };
22
+ }
@@ -0,0 +1,19 @@
1
+ import type { Ref } from 'vue-demi';
2
+ import type { ToolbarAnchor } from './useToolbarDragSnap';
3
+ interface UseToolbarAutoHideOptions {
4
+ enabled: Ref<boolean>;
5
+ expanded: Ref<boolean>;
6
+ isDragging: Ref<boolean>;
7
+ placement: Ref<ToolbarAnchor>;
8
+ toolbarEl: Ref<HTMLElement | null>;
9
+ }
10
+ export declare function useToolbarAutoHide(options: UseToolbarAutoHideOptions): {
11
+ isAutoHideActive: import("vue-demi").ComputedRef<boolean>;
12
+ isAutoHideRevealed: Ref<boolean, boolean>;
13
+ onToolbarPointerEnter: () => void;
14
+ onToolbarPointerLeave: () => void;
15
+ onToolbarPointerDown: () => void;
16
+ onToolbarFocusIn: () => void;
17
+ onToolbarFocusOut: () => void;
18
+ };
19
+ export {};