@aipanel/ui 1.2.0-beta.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 (153) hide show
  1. package/es/AI-panel-widget/composables/use-inspector.d.ts +52 -0
  2. package/es/AI-panel-widget/composables/use-inspector.mjs +437 -0
  3. package/es/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
  4. package/es/AI-panel-widget/composables/use-persist-state.mjs +83 -0
  5. package/es/AI-panel-widget/composables/use-selection.d.ts +19 -0
  6. package/es/AI-panel-widget/composables/use-selection.mjs +112 -0
  7. package/es/AI-panel-widget/composables/use-session.d.ts +16 -0
  8. package/es/AI-panel-widget/composables/use-session.mjs +47 -0
  9. package/es/AI-panel-widget/composables/use-split.d.ts +30 -0
  10. package/es/AI-panel-widget/composables/use-split.mjs +133 -0
  11. package/es/AI-panel-widget/composables/use-widget.d.ts +27 -0
  12. package/es/AI-panel-widget/composables/use-widget.mjs +78 -0
  13. package/es/AI-panel-widget/index.d.ts +5 -0
  14. package/es/AI-panel-widget/index.mjs +9 -0
  15. package/es/AI-panel-widget/src/assets/logo.svg +13 -0
  16. package/es/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
  17. package/es/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
  18. package/es/AI-panel-widget/src/components/AIPanelLogo.vue.mjs +40 -0
  19. package/es/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
  20. package/es/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
  21. package/es/AI-panel-widget/src/components/ChatPanel.vue.mjs +308 -0
  22. package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
  23. package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
  24. package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.mjs +311 -0
  25. package/es/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
  26. package/es/AI-panel-widget/src/components/FloatingBubble/index.mjs +5 -0
  27. package/es/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
  28. package/es/AI-panel-widget/src/components/FloatingBubble/types.mjs +0 -0
  29. package/es/AI-panel-widget/src/components/Frame-sfc.css +1 -0
  30. package/es/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
  31. package/es/AI-panel-widget/src/components/Frame.vue.mjs +143 -0
  32. package/es/AI-panel-widget/src/components/Header-sfc.css +1 -0
  33. package/es/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
  34. package/es/AI-panel-widget/src/components/Header.vue.mjs +683 -0
  35. package/es/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
  36. package/es/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
  37. package/es/AI-panel-widget/src/components/ResizeHandle.vue.mjs +79 -0
  38. package/es/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
  39. package/es/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
  40. package/es/AI-panel-widget/src/components/SelectHint.vue.mjs +40 -0
  41. package/es/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
  42. package/es/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
  43. package/es/AI-panel-widget/src/components/SelectedBubbles.vue.mjs +84 -0
  44. package/es/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
  45. package/es/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
  46. package/es/AI-panel-widget/src/components/SelectedNodes.vue.mjs +103 -0
  47. package/es/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
  48. package/es/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
  49. package/es/AI-panel-widget/src/components/SessionList.vue.mjs +222 -0
  50. package/es/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
  51. package/es/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
  52. package/es/AI-panel-widget/src/components/SplitTrigger.vue.mjs +112 -0
  53. package/es/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
  54. package/es/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
  55. package/es/AI-panel-widget/src/components/Trigger.vue.mjs +74 -0
  56. package/es/AI-panel-widget/src/context.d.ts +67 -0
  57. package/es/AI-panel-widget/src/context.mjs +16 -0
  58. package/es/AI-panel-widget/src/index-sfc.css +1 -0
  59. package/es/AI-panel-widget/src/index.vue.d.ts +69 -0
  60. package/es/AI-panel-widget/src/index.vue.mjs +782 -0
  61. package/es/AI-panel-widget/src/types.d.ts +2 -0
  62. package/es/AI-panel-widget/src/types.mjs +0 -0
  63. package/es/AI-panel-widget/style/index-pure.d.ts +0 -0
  64. package/es/AI-panel-widget/style/index-pure.mjs +0 -0
  65. package/es/AI-panel-widget/style/index.d.ts +0 -0
  66. package/es/AI-panel-widget/style/index.mjs +0 -0
  67. package/es/AI-panel-widget/style/less-pure.d.ts +0 -0
  68. package/es/AI-panel-widget/style/less-pure.mjs +0 -0
  69. package/es/AI-panel-widget/style/less.d.ts +0 -0
  70. package/es/AI-panel-widget/style/less.mjs +0 -0
  71. package/es/env.d.ts +15 -0
  72. package/es/index.d.ts +7 -0
  73. package/es/index.mjs +22 -0
  74. package/es/setup.d.ts +1 -0
  75. package/es/setup.mjs +4 -0
  76. package/lib/AI-panel-widget/composables/use-inspector.cjs +466 -0
  77. package/lib/AI-panel-widget/composables/use-inspector.d.ts +52 -0
  78. package/lib/AI-panel-widget/composables/use-persist-state.cjs +102 -0
  79. package/lib/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
  80. package/lib/AI-panel-widget/composables/use-selection.cjs +131 -0
  81. package/lib/AI-panel-widget/composables/use-selection.d.ts +19 -0
  82. package/lib/AI-panel-widget/composables/use-session.cjs +66 -0
  83. package/lib/AI-panel-widget/composables/use-session.d.ts +16 -0
  84. package/lib/AI-panel-widget/composables/use-split.cjs +152 -0
  85. package/lib/AI-panel-widget/composables/use-split.d.ts +30 -0
  86. package/lib/AI-panel-widget/composables/use-widget.cjs +97 -0
  87. package/lib/AI-panel-widget/composables/use-widget.d.ts +27 -0
  88. package/lib/AI-panel-widget/index.cjs +39 -0
  89. package/lib/AI-panel-widget/index.d.ts +5 -0
  90. package/lib/AI-panel-widget/src/assets/logo.svg +13 -0
  91. package/lib/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
  92. package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.cjs +69 -0
  93. package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
  94. package/lib/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
  95. package/lib/AI-panel-widget/src/components/ChatPanel.vue.cjs +337 -0
  96. package/lib/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
  97. package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
  98. package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.cjs +330 -0
  99. package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
  100. package/lib/AI-panel-widget/src/components/FloatingBubble/index.cjs +35 -0
  101. package/lib/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
  102. package/lib/AI-panel-widget/src/components/FloatingBubble/types.cjs +15 -0
  103. package/lib/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
  104. package/lib/AI-panel-widget/src/components/Frame-sfc.css +1 -0
  105. package/lib/AI-panel-widget/src/components/Frame.vue.cjs +162 -0
  106. package/lib/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
  107. package/lib/AI-panel-widget/src/components/Header-sfc.css +1 -0
  108. package/lib/AI-panel-widget/src/components/Header.vue.cjs +702 -0
  109. package/lib/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
  110. package/lib/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
  111. package/lib/AI-panel-widget/src/components/ResizeHandle.vue.cjs +98 -0
  112. package/lib/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
  113. package/lib/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
  114. package/lib/AI-panel-widget/src/components/SelectHint.vue.cjs +59 -0
  115. package/lib/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
  116. package/lib/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
  117. package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.cjs +103 -0
  118. package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
  119. package/lib/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
  120. package/lib/AI-panel-widget/src/components/SelectedNodes.vue.cjs +122 -0
  121. package/lib/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
  122. package/lib/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
  123. package/lib/AI-panel-widget/src/components/SessionList.vue.cjs +241 -0
  124. package/lib/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
  125. package/lib/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
  126. package/lib/AI-panel-widget/src/components/SplitTrigger.vue.cjs +131 -0
  127. package/lib/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
  128. package/lib/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
  129. package/lib/AI-panel-widget/src/components/Trigger.vue.cjs +103 -0
  130. package/lib/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
  131. package/lib/AI-panel-widget/src/context.cjs +35 -0
  132. package/lib/AI-panel-widget/src/context.d.ts +67 -0
  133. package/lib/AI-panel-widget/src/index-sfc.css +1 -0
  134. package/lib/AI-panel-widget/src/index.vue.cjs +811 -0
  135. package/lib/AI-panel-widget/src/index.vue.d.ts +69 -0
  136. package/lib/AI-panel-widget/src/types.cjs +15 -0
  137. package/lib/AI-panel-widget/src/types.d.ts +2 -0
  138. package/lib/AI-panel-widget/style/index-pure.cjs +0 -0
  139. package/lib/AI-panel-widget/style/index-pure.d.ts +0 -0
  140. package/lib/AI-panel-widget/style/index.cjs +0 -0
  141. package/lib/AI-panel-widget/style/index.d.ts +0 -0
  142. package/lib/AI-panel-widget/style/less-pure.cjs +0 -0
  143. package/lib/AI-panel-widget/style/less-pure.d.ts +0 -0
  144. package/lib/AI-panel-widget/style/less.cjs +0 -0
  145. package/lib/AI-panel-widget/style/less.d.ts +0 -0
  146. package/lib/env.d.ts +15 -0
  147. package/lib/index.cjs +42 -0
  148. package/lib/index.css +0 -0
  149. package/lib/index.d.ts +7 -0
  150. package/lib/index.less +0 -0
  151. package/lib/setup.cjs +23 -0
  152. package/lib/setup.d.ts +1 -0
  153. package/package.json +42 -0
@@ -0,0 +1,2 @@
1
+ export type { AIPanelWidgetTheme, AIPanelWidgetSession, AIPanelSelectedElement, AIPanelRemoveSelectedPayload, AIPanelWidgetSessionItem, AIPanelSelectedElementItem, AIPanelWidgetProps, AIPanelWidgetEmits, AIPanelSessionThinkingState, DisplayMode, SplitModeOptions, } from "@aipanel/core";
2
+ export type AIPanelWidgetThemeLocal = "light" | "dark" | "auto";
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/es/env.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /// <reference lib="dom" />
2
+ /// <reference lib="dom.iterable" />
3
+
4
+ declare module "*.vue" {
5
+ import type { DefineComponent } from "vue";
6
+
7
+ const component: DefineComponent<Record<string, never>, Record<string, never>, unknown>;
8
+
9
+ export default component;
10
+ }
11
+
12
+ declare module "*.svg?raw" {
13
+ const content: string;
14
+ export default content;
15
+ }
package/es/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { App } from 'vue';
2
+ declare const version = "1.2.0-beta.0";
3
+ declare function install(app: App<any>, options?: any): void;
4
+ export { install, version, };
5
+ export * from './AI-panel-widget';
6
+ export * from './setup';
7
+ export default install;
package/es/index.mjs ADDED
@@ -0,0 +1,22 @@
1
+ import { AIPanelWidget } from "./AI-panel-widget/index.mjs";
2
+ const version = "1.2.0-beta.0";
3
+ function install(app, options) {
4
+ const components = [
5
+ AIPanelWidget
6
+ ];
7
+ components.forEach((item) => {
8
+ if (item.install) {
9
+ app.use(item, options);
10
+ } else if (item.name) {
11
+ app.component(item.name, item);
12
+ }
13
+ });
14
+ }
15
+ export * from "./AI-panel-widget/index.mjs";
16
+ export * from "./setup.mjs";
17
+ var es_default = install;
18
+ export {
19
+ es_default as default,
20
+ install,
21
+ version
22
+ };
package/es/setup.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { AIPanelLogo } from "./AI-panel-widget";
package/es/setup.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import { AIPanelLogo } from "./AI-panel-widget/index.mjs";
2
+ export {
3
+ AIPanelLogo
4
+ };
@@ -0,0 +1,466 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var use_inspector_exports = {};
29
+ __export(use_inspector_exports, {
30
+ useInspector: () => useInspector
31
+ });
32
+ module.exports = __toCommonJS(use_inspector_exports);
33
+ var import_vue = require("vue");
34
+ var import_core = require("@aipanel/core");
35
+ var import_css_selector_generator = __toESM(require("css-selector-generator"));
36
+ const IGNORE_SELECTORS = [
37
+ "#vue-inspector-container",
38
+ ".aipanel-widget",
39
+ ".aipanel-element-highlight",
40
+ ".aipanel-element-tooltip",
41
+ ".aipanel-select-mode-hint",
42
+ ".floating-bubble"
43
+ ];
44
+ const IGNORE_ATTRIBUTE = "data-v-inspector-ignore";
45
+ const KEY_PROPS_DATA = "__v_inspector";
46
+ const KEY_DATA = "data-v-inspector";
47
+ function getDirectText(element) {
48
+ let text = "";
49
+ for (let i = 0; i < element.childNodes.length; i++) {
50
+ const child = element.childNodes[i];
51
+ if (child.nodeType === Node.TEXT_NODE) {
52
+ text += child.textContent || "";
53
+ }
54
+ }
55
+ return text.trim();
56
+ }
57
+ const DYNAMIC_ID_PATTERN = /^(?:el-|:r[0-9]+:|radix-|uid-|ts-|uuid-|id-[a-f0-9]{4,}|.*[0-9]{4,}.*|.*-[a-f0-9]{6,}$)/i;
58
+ const STATE_CLASS_PATTERN = /^(?:hover|active|focus|focus-visible|focus-within|disabled|enabled|checked|selected|open|closed|loading|error|success|warning|hidden|visible|show|hide|current|expanded|collapsed|pressed|dragging|droppable|sortable|placeholder|transition|enter|leave|appear|move)$/i;
59
+ const STATE_CLASS_PREFIX_PATTERN = /^(?:is-|has-|was-|are-|can-|should-|will-|did-|does-|on-|off-|in-|out-|at-|to-|from-)/i;
60
+ function isDynamicId(id) {
61
+ if (!id) return false;
62
+ if (DYNAMIC_ID_PATTERN.test(id)) {
63
+ return true;
64
+ }
65
+ const digitCount = (id.match(/\d/g) || []).length;
66
+ const letterCount = (id.match(/[a-zA-Z]/g) || []).length;
67
+ if (digitCount > letterCount && digitCount >= 3) {
68
+ return true;
69
+ }
70
+ const dashParts = id.split("-");
71
+ if (dashParts.length >= 3) {
72
+ const lastPart = dashParts[dashParts.length - 1];
73
+ if (/^\d+$/.test(lastPart) || /^[a-f0-9]{4,}$/i.test(lastPart)) {
74
+ return true;
75
+ }
76
+ }
77
+ return false;
78
+ }
79
+ function isStateClass(className) {
80
+ if (!className) return false;
81
+ if (STATE_CLASS_PATTERN.test(className)) {
82
+ return true;
83
+ }
84
+ if (STATE_CLASS_PREFIX_PATTERN.test(className)) {
85
+ return true;
86
+ }
87
+ if (className.includes("-active") || className.includes("-hover") || className.includes("-focus")) {
88
+ return true;
89
+ }
90
+ if (/^(?:router-link|nuxt-link)/.test(className)) {
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ function getElementDescription(element) {
96
+ return (0, import_css_selector_generator.default)(element, {
97
+ selectors: ["id", "class", "tag", "nthchild"],
98
+ combineWithinSelector: true,
99
+ combineBetweenSelectors: true,
100
+ maxCombinations: 100,
101
+ maxCandidates: 100,
102
+ blacklist: [
103
+ (selectorValue) => {
104
+ const idMatch = selectorValue.match(/^#(.+)$/);
105
+ if (idMatch) {
106
+ return isDynamicId(idMatch[1]);
107
+ }
108
+ const classMatch = selectorValue.match(/^\.([a-zA-Z_-][\w-]*)$/);
109
+ if (classMatch) {
110
+ return isStateClass(classMatch[1]);
111
+ }
112
+ return false;
113
+ }
114
+ ]
115
+ });
116
+ }
117
+ function getFileInfoFromVueInstance(element) {
118
+ const vue3Instance = element.__vueParentComponent;
119
+ if (vue3Instance) {
120
+ let current = vue3Instance;
121
+ while (current) {
122
+ const file = current.type?.__file || current.vnode?.type?.__file;
123
+ if (file) {
124
+ return { file, line: null, column: null };
125
+ }
126
+ current = current.parent;
127
+ }
128
+ }
129
+ const vue2Instance = element.__vue__;
130
+ if (vue2Instance) {
131
+ let current = vue2Instance;
132
+ while (current) {
133
+ const file = current.$options?.__file;
134
+ if (file) {
135
+ return { file, line: null, column: null };
136
+ }
137
+ current = current.$parent;
138
+ }
139
+ }
140
+ return null;
141
+ }
142
+ function shouldIgnoreElement(el) {
143
+ if (el.hasAttribute(IGNORE_ATTRIBUTE)) return true;
144
+ for (const selector of IGNORE_SELECTORS) {
145
+ if (el.closest(selector)) return true;
146
+ }
147
+ return false;
148
+ }
149
+ function getDataFromElement(el) {
150
+ const vnodeData = el.__vnode?.props?.[KEY_PROPS_DATA];
151
+ if (vnodeData) return vnodeData;
152
+ const ctxVNode = el.__vnode?.ctx?.vnode;
153
+ if (ctxVNode?.el === el) {
154
+ const ctxData = ctxVNode.props?.[KEY_PROPS_DATA];
155
+ if (ctxData) return ctxData;
156
+ }
157
+ const vueInstance = el.__vueParentComponent;
158
+ let currentParent = vueInstance?.parent;
159
+ while (currentParent) {
160
+ if (currentParent.vnode?.el === el) {
161
+ const parentData = currentParent.vnode.props?.[KEY_PROPS_DATA];
162
+ if (parentData) return parentData;
163
+ }
164
+ currentParent = currentParent.parent;
165
+ }
166
+ const attr = el.getAttribute(KEY_DATA);
167
+ return attr ?? void 0;
168
+ }
169
+ function findInspectorFileInfo(element) {
170
+ let current = element;
171
+ while (current) {
172
+ if (shouldIgnoreElement(current)) {
173
+ current = current.parentElement;
174
+ continue;
175
+ }
176
+ const data = getDataFromElement(current);
177
+ if (data) {
178
+ const splitRE = /(.+):([\d]+):([\d]+)$/;
179
+ const match = data.match(splitRE);
180
+ if (match) {
181
+ return {
182
+ file: match[1],
183
+ line: parseInt(match[2], 10),
184
+ column: parseInt(match[3], 10)
185
+ };
186
+ }
187
+ }
188
+ current = current.parentElement;
189
+ }
190
+ return null;
191
+ }
192
+ function mergeFileInfo(inspectorFileInfo, vueFileInfo) {
193
+ if (!inspectorFileInfo?.file && !vueFileInfo?.file) {
194
+ return { file: null, line: null, column: null };
195
+ }
196
+ const isNodeModules = (path) => path.includes("node_modules");
197
+ if (inspectorFileInfo?.file && vueFileInfo?.file) {
198
+ if (!isNodeModules(inspectorFileInfo.file)) {
199
+ return inspectorFileInfo;
200
+ } else if (!isNodeModules(vueFileInfo.file)) {
201
+ return vueFileInfo;
202
+ } else {
203
+ return inspectorFileInfo;
204
+ }
205
+ } else if (inspectorFileInfo?.file) {
206
+ return inspectorFileInfo;
207
+ } else {
208
+ return vueFileInfo;
209
+ }
210
+ }
211
+ function getTargetElement(e) {
212
+ if (!e.target || !(e.target instanceof Element)) return null;
213
+ const el = e.target;
214
+ if (shouldIgnoreElement(el)) return null;
215
+ return el;
216
+ }
217
+ function getFileInfo(e, element) {
218
+ let inspectorFileInfo = null;
219
+ if (element) {
220
+ inspectorFileInfo = findInspectorFileInfo(element);
221
+ }
222
+ const vueFileInfo = element ? getFileInfoFromVueInstance(element) : null;
223
+ return mergeFileInfo(inspectorFileInfo, vueFileInfo);
224
+ }
225
+ function useInspector(options) {
226
+ const highlightVisible = (0, import_vue.ref)(false);
227
+ const highlightStyle = (0, import_vue.ref)({
228
+ top: "0px",
229
+ left: "0px",
230
+ width: "0px",
231
+ height: "0px"
232
+ });
233
+ const tooltipVisible = (0, import_vue.ref)(false);
234
+ const tooltipStyle = (0, import_vue.ref)({ top: "0px", left: "0px" });
235
+ const tooltipContent = (0, import_vue.ref)({ description: "", fileInfo: "" });
236
+ const INSPECTOR_CHECK_INTERVAL = 500;
237
+ let inspectorCheckTimer = null;
238
+ let currentPrimary = "#3b82f6";
239
+ let currentPrimaryBg = "rgba(59, 130, 246, 0.1)";
240
+ function setPointerEventsNone(elements) {
241
+ elements.forEach((el) => {
242
+ if (el) el.style.pointerEvents = "none";
243
+ });
244
+ }
245
+ function setPointerEventsAuto(elements) {
246
+ elements.forEach((el) => {
247
+ if (el) el.style.pointerEvents = "";
248
+ });
249
+ }
250
+ function handleMouseMoveCore(e) {
251
+ if (!options.selectMode.value) return;
252
+ const highlight = document.querySelector(".aipanel-element-highlight");
253
+ const tooltip = document.querySelector(".aipanel-element-tooltip");
254
+ const selectHint = document.querySelector(".aipanel-select-mode-hint");
255
+ const floatingBubble = document.querySelector(".floating-bubble");
256
+ const uiElements = [highlight, tooltip, selectHint, floatingBubble];
257
+ setPointerEventsNone(uiElements);
258
+ const elementToHighlight = getTargetElement(e);
259
+ const fileInfo = getFileInfo(e, elementToHighlight);
260
+ setPointerEventsAuto(uiElements);
261
+ if (elementToHighlight) {
262
+ const widget = document.querySelector(".aipanel-widget");
263
+ if (widget) {
264
+ const style = getComputedStyle(widget);
265
+ currentPrimary = style.getPropertyValue("--ap-primary").trim() || currentPrimary;
266
+ currentPrimaryBg = style.getPropertyValue("--ap-primary-bg").trim() || currentPrimaryBg;
267
+ }
268
+ const description = getElementDescription(elementToHighlight);
269
+ const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
270
+ let lineInfo = "";
271
+ if (fileInfo.line) {
272
+ lineInfo = `:${fileInfo.line}`;
273
+ if (fileInfo.column) {
274
+ lineInfo += `:${fileInfo.column}`;
275
+ }
276
+ }
277
+ const fileInfoText = fileName ? `${fileName}${lineInfo}` : "";
278
+ tooltipContent.value = {
279
+ description,
280
+ fileInfo: fileInfoText
281
+ };
282
+ const rect = elementToHighlight.getBoundingClientRect();
283
+ const newTop = `${rect.top}px`;
284
+ const newLeft = `${rect.left}px`;
285
+ const newWidth = `${rect.width}px`;
286
+ const newHeight = `${rect.height}px`;
287
+ if (highlightStyle.value.top !== newTop || highlightStyle.value.left !== newLeft || highlightStyle.value.width !== newWidth || highlightStyle.value.height !== newHeight) {
288
+ highlightStyle.value = {
289
+ top: newTop,
290
+ left: newLeft,
291
+ width: newWidth,
292
+ height: newHeight,
293
+ border: `2px solid ${currentPrimary}`,
294
+ background: currentPrimaryBg
295
+ };
296
+ }
297
+ highlightVisible.value = true;
298
+ tooltipVisible.value = true;
299
+ void (0, import_vue.nextTick)(() => {
300
+ const tooltipEl = document.querySelector(".aipanel-element-tooltip");
301
+ if (!tooltipEl) return;
302
+ const tooltipWidth = tooltipEl.offsetWidth;
303
+ const tooltipHeight = tooltipEl.offsetHeight;
304
+ if (tooltipWidth === 0 || tooltipHeight === 0) return;
305
+ const margin = 10;
306
+ const gap = 4;
307
+ const viewportWidth = window.innerWidth;
308
+ const viewportHeight = window.innerHeight;
309
+ const clampLeft = (left) => Math.max(margin, Math.min(left, viewportWidth - tooltipWidth - margin));
310
+ const clampTop = (top) => Math.max(margin, Math.min(top, viewportHeight - tooltipHeight - margin));
311
+ const candidateTop = rect.top - tooltipHeight - gap;
312
+ const candidateBottom = rect.bottom + gap;
313
+ const candidateRight = rect.right + gap;
314
+ const candidateLeft = rect.left - tooltipWidth - gap;
315
+ const verticalCenter = rect.top + (rect.height - tooltipHeight) / 2;
316
+ let tooltipTop = 0;
317
+ let tooltipLeft = 0;
318
+ let placed = false;
319
+ if (candidateTop >= margin) {
320
+ tooltipTop = candidateTop;
321
+ tooltipLeft = clampLeft(rect.left);
322
+ placed = true;
323
+ }
324
+ if (!placed && candidateBottom + tooltipHeight <= viewportHeight - margin) {
325
+ tooltipTop = candidateBottom;
326
+ tooltipLeft = clampLeft(rect.left);
327
+ placed = true;
328
+ }
329
+ if (!placed && candidateRight + tooltipWidth <= viewportWidth - margin) {
330
+ tooltipLeft = candidateRight;
331
+ tooltipTop = clampTop(verticalCenter);
332
+ placed = true;
333
+ }
334
+ if (!placed && candidateLeft >= margin) {
335
+ tooltipLeft = candidateLeft;
336
+ tooltipTop = clampTop(verticalCenter);
337
+ placed = true;
338
+ }
339
+ if (!placed) {
340
+ const corners = [
341
+ { top: margin, left: margin },
342
+ { top: margin, left: viewportWidth - tooltipWidth - margin },
343
+ { top: viewportHeight - tooltipHeight - margin, left: margin },
344
+ {
345
+ top: viewportHeight - tooltipHeight - margin,
346
+ left: viewportWidth - tooltipWidth - margin
347
+ }
348
+ ];
349
+ for (const corner of corners) {
350
+ const tooltipRight = corner.left + tooltipWidth;
351
+ const tooltipBottom = corner.top + tooltipHeight;
352
+ const overlaps = tooltipRight <= rect.left || rect.right <= corner.left || tooltipBottom <= rect.top || rect.bottom <= corner.top;
353
+ if (overlaps) {
354
+ tooltipTop = corner.top;
355
+ tooltipLeft = corner.left;
356
+ placed = true;
357
+ break;
358
+ }
359
+ }
360
+ if (!placed) {
361
+ tooltipTop = margin;
362
+ tooltipLeft = margin;
363
+ }
364
+ }
365
+ const newTooltipTop = `${tooltipTop}px`;
366
+ const newTooltipLeft = `${tooltipLeft}px`;
367
+ if (tooltipStyle.value.top !== newTooltipTop || tooltipStyle.value.left !== newTooltipLeft) {
368
+ tooltipStyle.value = {
369
+ top: newTooltipTop,
370
+ left: newTooltipLeft
371
+ };
372
+ }
373
+ });
374
+ } else {
375
+ highlightVisible.value = false;
376
+ tooltipVisible.value = false;
377
+ }
378
+ }
379
+ const handleMouseMove = handleMouseMoveCore;
380
+ function setupInspectorHook() {
381
+ const inspector = window.__VUE_INSPECTOR__;
382
+ if (!inspector || inspector.__aipanel_hooked) return;
383
+ const originalHandleClick = inspector.handleClick.bind(inspector);
384
+ inspector.handleClick = function(e) {
385
+ if (options.selectMode.value) {
386
+ const targetEl = e.target instanceof Element ? e.target : null;
387
+ if (targetEl && targetEl.closest(".aipanel-widget")) {
388
+ return originalHandleClick.call(inspector, e);
389
+ }
390
+ e.preventDefault();
391
+ e.stopPropagation();
392
+ const elementToSelect = getTargetElement(e);
393
+ const fileInfo = getFileInfo(e, elementToSelect);
394
+ if (elementToSelect) {
395
+ const innerText = getDirectText(elementToSelect);
396
+ const description = getElementDescription(elementToSelect);
397
+ const elementInfo = {
398
+ filePath: fileInfo.file,
399
+ line: fileInfo.line,
400
+ column: fileInfo.column,
401
+ innerText: (0, import_core.truncate)(innerText, 200),
402
+ description
403
+ };
404
+ options.onAddSelectedNode(elementInfo);
405
+ }
406
+ return;
407
+ }
408
+ return originalHandleClick.call(inspector, e);
409
+ };
410
+ inspector.__aipanel_hooked = true;
411
+ }
412
+ function handleKeydown(e) {
413
+ if (e.key === "Escape" && options.selectMode.value) {
414
+ e.preventDefault();
415
+ e.stopPropagation();
416
+ options.onExitSelectMode();
417
+ }
418
+ }
419
+ (0, import_vue.watch)(options.selectMode, (newVal) => {
420
+ const inspector = window.__VUE_INSPECTOR__;
421
+ if (newVal) {
422
+ if (inspector) {
423
+ inspector.enable();
424
+ }
425
+ document.addEventListener("mousemove", handleMouseMove);
426
+ document.addEventListener("keydown", handleKeydown, true);
427
+ } else {
428
+ if (inspector) {
429
+ inspector.disable();
430
+ }
431
+ document.removeEventListener("mousemove", handleMouseMove);
432
+ document.removeEventListener("keydown", handleKeydown, true);
433
+ highlightVisible.value = false;
434
+ tooltipVisible.value = false;
435
+ }
436
+ });
437
+ (0, import_vue.onMounted)(() => {
438
+ if (window.__VUE_INSPECTOR__) {
439
+ setupInspectorHook();
440
+ } else {
441
+ inspectorCheckTimer = window.setInterval(() => {
442
+ if (window.__VUE_INSPECTOR__) {
443
+ setupInspectorHook();
444
+ if (inspectorCheckTimer) {
445
+ window.clearInterval(inspectorCheckTimer);
446
+ inspectorCheckTimer = null;
447
+ }
448
+ }
449
+ }, INSPECTOR_CHECK_INTERVAL);
450
+ }
451
+ });
452
+ (0, import_vue.onUnmounted)(() => {
453
+ if (inspectorCheckTimer) {
454
+ window.clearInterval(inspectorCheckTimer);
455
+ }
456
+ document.removeEventListener("mousemove", handleMouseMove);
457
+ document.removeEventListener("keydown", handleKeydown, true);
458
+ });
459
+ return {
460
+ highlightVisible,
461
+ highlightStyle,
462
+ tooltipVisible,
463
+ tooltipStyle,
464
+ tooltipContent
465
+ };
466
+ }
@@ -0,0 +1,52 @@
1
+ import { type Ref } from "vue";
2
+ import type { AIPanelSelectedElement } from "../src/types";
3
+ interface VueInspector {
4
+ getTargetNode: (e: MouseEvent) => {
5
+ targetNode: Element | null;
6
+ params: {
7
+ file?: string;
8
+ line?: number;
9
+ column?: number;
10
+ } | null;
11
+ };
12
+ handleClick: (e: MouseEvent) => void;
13
+ enable: () => void;
14
+ disable: () => void;
15
+ __aipanel_hooked?: boolean;
16
+ }
17
+ declare global {
18
+ interface Window {
19
+ __VUE_INSPECTOR__?: VueInspector;
20
+ }
21
+ }
22
+ interface UseInspectorOptions {
23
+ selectMode: Ref<boolean>;
24
+ onAddSelectedNode: (element: AIPanelSelectedElement) => void;
25
+ onExitSelectMode: () => void;
26
+ }
27
+ export declare function useInspector(options: UseInspectorOptions): {
28
+ highlightVisible: Ref<boolean, boolean>;
29
+ highlightStyle: Ref<Record<string, string>, Record<string, string>>;
30
+ tooltipVisible: Ref<boolean, boolean>;
31
+ tooltipStyle: Ref<{
32
+ top: string;
33
+ left: string;
34
+ }, {
35
+ top: string;
36
+ left: string;
37
+ } | {
38
+ top: string;
39
+ left: string;
40
+ }>;
41
+ tooltipContent: Ref<{
42
+ description: string;
43
+ fileInfo: string;
44
+ }, {
45
+ description: string;
46
+ fileInfo: string;
47
+ } | {
48
+ description: string;
49
+ fileInfo: string;
50
+ }>;
51
+ };
52
+ export {};