vite-plugin-aipanel 1.2.28 → 1.3.2
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/client/vue-devtools-bridge.d.ts +5 -2
- package/es/client/vue-devtools-bridge.mjs +25 -91
- package/es/client/vue-devtools-sanitize.d.ts +31 -0
- package/es/client/vue-devtools-sanitize.mjs +103 -0
- package/es/client/vue-devtools-timeline.d.ts +173 -0
- package/es/client/vue-devtools-timeline.mjs +617 -0
- package/es/core/mcp-tools.d.ts +7 -0
- package/es/core/mcp-tools.mjs +170 -26
- package/es/endpoints/vue-devtools.mjs +15 -1
- package/lib/client/vue-devtools-bridge.cjs +28 -96
- package/lib/client/vue-devtools-bridge.d.ts +5 -2
- package/lib/client/vue-devtools-sanitize.cjs +130 -0
- package/lib/client/vue-devtools-sanitize.d.ts +31 -0
- package/lib/client/vue-devtools-timeline.cjs +636 -0
- package/lib/client/vue-devtools-timeline.d.ts +173 -0
- package/lib/client.js +1263 -1248
- package/lib/core/mcp-tools.cjs +164 -25
- package/lib/core/mcp-tools.d.ts +7 -0
- package/lib/endpoints/vue-devtools.cjs +15 -1
- package/package.json +5 -5
package/es/core/mcp-tools.mjs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
VUE_DEVTOOLS_ACTIONS,
|
|
3
|
+
VUE_DEVTOOLS_TIMELINE_DEFAULTS,
|
|
4
|
+
VUE_DEVTOOLS_TIMELINE_INCLUDES,
|
|
5
|
+
VUE_DEVTOOLS_TIMELINE_LAYERS
|
|
6
|
+
} from "@aipanel/core";
|
|
2
7
|
import { OFFICIAL_TOOL_META } from "./official-meta.mjs";
|
|
3
8
|
const MCP_PREFIX = "chrome-devtools_";
|
|
4
9
|
function displayToolName(short) {
|
|
@@ -85,17 +90,25 @@ const VUE_DEVTOOLS_TOOLS = [
|
|
|
85
90
|
{
|
|
86
91
|
name: `${VUE_DEVTOOLS_PREFIX}get_apps`,
|
|
87
92
|
action: VUE_DEVTOOLS_ACTIONS.GET_APPS,
|
|
88
|
-
description: `\
|
|
93
|
+
description: `\u5217\u51FA\u9875\u9762\u91CC\u7684 Vue \u5E94\u7528\u5B9E\u4F8B\uFF08\u5FAE\u524D\u7AEF / \u591A\u5B9E\u4F8B\u573A\u666F\u7528\uFF09\u3002
|
|
89
94
|
|
|
90
95
|
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
91
|
-
- \
|
|
92
|
-
- \
|
|
96
|
+
- \u9875\u9762\u4E0A\u4E0D\u6B62\u4E00\u4E2A Vue \u5E94\u7528\uFF0C\u5148\u786E\u8BA4\u8981\u67E5\u54EA\u4E2A
|
|
97
|
+
- \u8C03 set_active_app \u524D\u53D6\u53EF\u7528 appId
|
|
98
|
+
|
|
99
|
+
**\u8FD4\u56DE**\uFF1A[{ id, name }]\uFF0Cid \u4F9B set_active_app \u4F7F\u7528\u3002`,
|
|
93
100
|
inputSchema: withPageIdSchema({ type: "object", properties: {} })
|
|
94
101
|
},
|
|
95
102
|
{
|
|
96
103
|
name: `${VUE_DEVTOOLS_PREFIX}set_active_app`,
|
|
97
104
|
action: VUE_DEVTOOLS_ACTIONS.TOGGLE_APP,
|
|
98
|
-
description: `\u5207\u6362\
|
|
105
|
+
description: `\u5207\u6362\u540E\u7EED vue-devtools_* \u7EC4\u4EF6/\u8DEF\u7531\u5DE5\u5177\u64CD\u4F5C\u7684\u6D3B\u8DC3 Vue \u5E94\u7528\u3002
|
|
106
|
+
|
|
107
|
+
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
108
|
+
- get_apps \u663E\u793A\u591A\u4E2A\u5E94\u7528\uFF0C\u800C\u7EC4\u4EF6\u6811/\u72B6\u6001\u67E5\u7684\u662F\u53E6\u4E00\u4E2A
|
|
109
|
+
- \u5FAE\u524D\u7AEF\u5B50\u5E94\u7528\u91CC\u7EC4\u4EF6\u600E\u4E48\u90FD\u67E5\u4E0D\u5230\uFF08\u5F88\u53EF\u80FD\u6D3B\u8DC3\u5E94\u7528\u4E0D\u662F\u5B83\uFF09
|
|
110
|
+
|
|
111
|
+
**\u6CE8\u610F**\uFF1A\u53EA\u6539\u540E\u7EED\u67E5\u8BE2\u7684\u76EE\u6807\u5E94\u7528\uFF0C\u4E0D\u6539\u9875\u9762\u672C\u8EAB\u3002`,
|
|
99
112
|
inputSchema: withPageIdSchema({
|
|
100
113
|
type: "object",
|
|
101
114
|
properties: {
|
|
@@ -107,32 +120,46 @@ const VUE_DEVTOOLS_TOOLS = [
|
|
|
107
120
|
{
|
|
108
121
|
name: `${VUE_DEVTOOLS_PREFIX}get_component_tree`,
|
|
109
122
|
action: VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_TREE,
|
|
110
|
-
description: `\u83B7\u53D6\
|
|
123
|
+
description: `\u83B7\u53D6\u6D3B\u8DC3 Vue \u5E94\u7528\u7684\u7EC4\u4EF6\u6811\uFF08\u6BCF\u4E2A\u8282\u70B9\u5E26 nodeId \u4E0E\u6E90\u7801\u8DEF\u5F84\uFF09\u3002
|
|
111
124
|
|
|
112
125
|
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
113
|
-
- \
|
|
114
|
-
- \
|
|
115
|
-
- \
|
|
116
|
-
- \u53EA\u5173\u5FC3\u67D0\u7C7B\u7EC4\u4EF6\u65F6\u7528 filter \u7F29\u5C0F\u8303\u56F4
|
|
126
|
+
- \u53D6\u7EC4\u4EF6\u7684 nodeId\uFF1Aget_component_state / get_component_render_code \u90FD\u8981\u5B83
|
|
127
|
+
- \u4E86\u89E3\u7EC4\u4EF6\u5C42\u7EA7\uFF1B\u786E\u8BA4\u67D0\u4E2A\u7EC4\u4EF6\u662F\u5426\u6E32\u67D3\u3001\u88AB\u8C01\u6E32\u67D3
|
|
128
|
+
- \u7531 file \u53CD\u67E5\u67D0\u4E2A .vue \u6587\u4EF6\u5BF9\u5E94\u54EA\u4E2A\u7EC4\u4EF6
|
|
117
129
|
|
|
118
|
-
**\u8FD4\u56DE**\uFF1A\u7EC4\u4EF6\
|
|
130
|
+
**\u8FD4\u56DE**\uFF1A\u7EC4\u4EF6\u8282\u70B9\u6570\u7EC4 [{ id, name, uid, file, children, ... }]
|
|
131
|
+
- id \u5C31\u662F nodeId\uFF08\u5F62\u5982 app-1:57\uFF1B\u6839\u8282\u70B9\u4E3A app-1:root\uFF09
|
|
132
|
+
- file \u662F\u6E90\u7801\u8DEF\u5F84\uFF1B\u7A7A\u5B57\u7B26\u4E32\u8868\u793A\u53D6\u4E0D\u5230\uFF08\u6846\u67B6\u5185\u7F6E\u6216\u533F\u540D\u7EC4\u4EF6\uFF09
|
|
133
|
+
|
|
134
|
+
**filter \u7684\u771F\u5B9E\u8BED\u4E49\uFF08\u5BB9\u6613\u8E29\uFF09**\uFF1A
|
|
135
|
+
- **\u5927\u5C0F\u5199\u654F\u611F**\uFF1A\u5185\u90E8\u7528\u5C0F\u5199\u5316\u7684\u7EC4\u4EF6\u540D\uFF08classify / kebabize \u4E24\u79CD\u5F62\u6001\uFF09\u5339\u914D\uFF0C**\u4F20\u5168\u5C0F\u5199\u6700\u7A33**
|
|
136
|
+
\uFF08filter:"App" \u8FD4\u56DE\u7A7A\uFF0Cfilter:"app" \u624D\u6709\u7ED3\u679C\uFF09
|
|
137
|
+
- \u547D\u4E2D\u7EC4\u4EF6\u4F1A\u8FDE\u5E26\u8FD4\u56DE\u5B83\u6574\u4E2A\u5B50\u6811\uFF08\u540E\u4EE3\u4E0D\u8981\u6C42\u5339\u914D\uFF09
|
|
138
|
+
- \u5339\u914D\u7684\u662F\u7EC4\u4EF6\u540D\uFF0C\u4E0D\u662F file \u8DEF\u5F84
|
|
139
|
+
|
|
140
|
+
**\u6CE8\u610F**\uFF1A\u6811\u53EF\u80FD\u5F88\u5927\uFF08UI \u5E93\u5185\u7F6E\u7EC4\u4EF6\u5360\u6BD4\u5F88\u9AD8\uFF09\uFF0C\u62FF\u4E0D\u51C6\u5C31\u5148 filter\u3002`,
|
|
119
141
|
inputSchema: withPageIdSchema({
|
|
120
142
|
type: "object",
|
|
121
143
|
properties: {
|
|
122
|
-
filter: { type: "string", description: "\u6309\u7EC4\u4EF6\u540D\u8FC7\u6EE4\uFF08\u5927\u5C0F\u5199\
|
|
144
|
+
filter: { type: "string", description: "\u6309\u7EC4\u4EF6\u540D\u8FC7\u6EE4\uFF08\u89C1\u63CF\u8FF0\uFF1A\u5927\u5C0F\u5199\u654F\u611F\uFF0C\u4F20\u5168\u5C0F\u5199\u6700\u7A33\uFF09" }
|
|
123
145
|
}
|
|
124
146
|
})
|
|
125
147
|
},
|
|
126
148
|
{
|
|
127
149
|
name: `${VUE_DEVTOOLS_PREFIX}get_component_state`,
|
|
128
150
|
action: VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_STATE,
|
|
129
|
-
description: `\u83B7\u53D6\u6307\u5B9A\u7EC4\u4EF6\u7684\
|
|
151
|
+
description: `\u83B7\u53D6\u6307\u5B9A\u7EC4\u4EF6\u7684\u8FD0\u884C\u65F6\u72B6\u6001\u3002
|
|
130
152
|
|
|
131
153
|
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
132
|
-
- \
|
|
133
|
-
- \u67E5\u770B
|
|
134
|
-
|
|
135
|
-
|
|
154
|
+
- \u6838\u5BF9 props \u4F20\u503C\u3001ref/reactive \u5F53\u524D\u503C\u3001computed \u7ED3\u679C
|
|
155
|
+
- \u6392\u67E5"\u503C\u6CA1\u66F4\u65B0"\uFF1A\u5148\u770B\u72B6\u6001\uFF0C\u518D\u7528 get_timeline \u770B\u662F\u54EA\u6B21\u6E32\u67D3/\u66F4\u65B0\u5F15\u8D77\u7684
|
|
156
|
+
|
|
157
|
+
**\u8FD4\u56DE**\uFF1A{ state: { <\u5206\u7C7B>: { <\u5B57\u6BB5>: { value, type? } } } }
|
|
158
|
+
- \u5206\u7C7B\u968F\u7EC4\u4EF6\u800C\u5B9A\uFF0C\u5E38\u89C1\uFF1Aprops / setup / setup (other) / computed / data / attrs\uFF08Vuex \u9879\u76EE\u8FD8\u6709 vuex bindings\uFF09
|
|
159
|
+
- \u503C\u53EF\u80FD\u88AB\u88C1\u526A\u6210**\u5360\u4F4D\u8BB0\u53F7**\uFF0C\u522B\u5F53\u6210\u771F\u5B9E\u503C\uFF1A__undefined__\uFF08\u8BE5\u503C\u662F undefined\uFF0C\u5373\u672A\u4F20/\u672A\u8BBE\u7F6E\uFF09\u3001[Function]\uFF08\u51FD\u6570\uFF09\u3001<max depth>\uFF08\u8D85\u51FA\u88C1\u526A\u6DF1\u5EA6\uFF09\u3001<\u524D\u7F00... (N chars)>\uFF08\u957F\u5B57\u7B26\u4E32\u622A\u65AD\uFF09\uFF1BVue \u5185\u90E8\u5BF9\u8C61\uFF08dep/subs/effect \u7B49\uFF09\u76F4\u63A5\u4E22\u5F03
|
|
160
|
+
|
|
161
|
+
**\u6CE8\u610F\uFF08\u522B\u628A"\u770B\u4E0D\u5230"\u5F53\u6210"\u4E0D\u5B58\u5728"\uFF09**\uFF1Aprovided / injected / event listeners / template refs
|
|
162
|
+
**\u88AB\u523B\u610F\u88C1\u6389\u4EE5\u7701 token**\uFF0C\u6C38\u8FDC\u67E5\u4E0D\u5230\uFF1B\u8981\u786E\u8BA4\u8FD9\u4E9B\u8BF7\u7528 chrome-devtools_evaluate_script\u3002`,
|
|
136
163
|
inputSchema: withPageIdSchema({
|
|
137
164
|
type: "object",
|
|
138
165
|
properties: {
|
|
@@ -147,7 +174,13 @@ const VUE_DEVTOOLS_TOOLS = [
|
|
|
147
174
|
{
|
|
148
175
|
name: `${VUE_DEVTOOLS_PREFIX}get_component_render_code`,
|
|
149
176
|
action: VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_RENDER_CODE,
|
|
150
|
-
description: `\u83B7\u53D6\u7EC4\u4EF6\
|
|
177
|
+
description: `\u83B7\u53D6\u7EC4\u4EF6\u6E32\u67D3\u51FD\u6570\u7684\u6E90\u7801\uFF08\u7F16\u8BD1\u4EA7\u7269\uFF0C\u7528\u6765\u770B\u6A21\u677F\u6700\u7EC8\u751F\u6210\u4E86\u4EC0\u4E48\uFF09\u3002
|
|
178
|
+
|
|
179
|
+
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
180
|
+
- \u6A21\u677F\u884C\u4E3A\u53CD\u76F4\u89C9\uFF0C\u9700\u8981\u770B\u7F16\u8BD1\u7ED3\u679C
|
|
181
|
+
- \u914D\u5408 get_component_tree \u7684 file \u4E00\u8D77\u5B9A\u4F4D\u6E90\u7801
|
|
182
|
+
|
|
183
|
+
**\u53C2\u6570**\uFF1AnodeId \u6765\u81EA get_component_tree\uFF08write-\u7C7B\u5DE5\u5177\u6539\u5B8C\u4EE3\u7801\u540E\uFF0CnodeId \u53EF\u80FD\u56E0 HMR \u5931\u6548\uFF0C\u9700\u91CD\u65B0\u53D6\uFF09\u3002`,
|
|
151
184
|
inputSchema: withPageIdSchema({
|
|
152
185
|
type: "object",
|
|
153
186
|
properties: { nodeId: { type: "string", description: "\u7EC4\u4EF6\u8282\u70B9 ID" } },
|
|
@@ -157,23 +190,134 @@ const VUE_DEVTOOLS_TOOLS = [
|
|
|
157
190
|
{
|
|
158
191
|
name: `${VUE_DEVTOOLS_PREFIX}get_current_route`,
|
|
159
192
|
action: VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO,
|
|
160
|
-
description: `\u83B7\u53D6
|
|
193
|
+
description: `\u83B7\u53D6\u5F53\u524D\u8DEF\u7531\uFF08\u542B path/params/query/hash/matched\uFF09\u3002
|
|
161
194
|
|
|
162
195
|
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
163
|
-
- \u6392\u67E5\u8DEF\u7531\u8DF3\u8F6C\
|
|
164
|
-
- \
|
|
165
|
-
|
|
196
|
+
- \u6392\u67E5\u8DEF\u7531\u8DF3\u8F6C\u662F\u5426\u53D1\u751F\u3001\u8DF3\u5230\u4E86\u54EA\u3001\u53C2\u6570\u5BF9\u4E0D\u5BF9
|
|
197
|
+
- \u770B\u5F53\u524D\u8DEF\u7531\u547D\u4E2D\u4E86\u54EA\u4E9B\u8DEF\u7531\u8BB0\u5F55\uFF08matched\uFF0C\u542B\u5404\u81EA meta\uFF09
|
|
198
|
+
|
|
199
|
+
**\u8FD4\u56DE**\uFF1A\u5F53\u524D\u8DEF\u7531\u5BF9\u8C61\uFF1B\u4E0E get_routes \u7684\u533A\u522B\u662F\u8FD9\u91CC\u53EA\u7ED9\u5F53\u524D\u8FD9\u4E00\u6761\u3002`,
|
|
166
200
|
inputSchema: withPageIdSchema({ type: "object", properties: {} })
|
|
167
201
|
},
|
|
168
202
|
{
|
|
169
203
|
name: `${VUE_DEVTOOLS_PREFIX}get_routes`,
|
|
170
204
|
action: VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO,
|
|
171
|
-
description: `\u83B7\u53D6
|
|
205
|
+
description: `\u83B7\u53D6\u5B8C\u6574\u8DEF\u7531\u8868\uFF08vue-router \u7684 getRoutes() \u8F93\u51FA\uFF0C\u5DF2\u5C55\u5F00\u4E3A**\u6241\u5E73**\u8BB0\u5F55\u5217\u8868\uFF09\u3002
|
|
172
206
|
|
|
173
207
|
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
174
|
-
- \
|
|
175
|
-
- \
|
|
176
|
-
|
|
208
|
+
- \u786E\u8BA4\u8DEF\u7531\u662F\u5426\u6CE8\u518C\u3001path / name / meta \u662F\u5426\u6B63\u786E
|
|
209
|
+
- \u9700\u8981\u8DEF\u7531\u6E05\u5355\u6765\u5224\u65AD\u67D0\u4E2A path \u662F\u5426\u53EF\u8FBE
|
|
210
|
+
|
|
211
|
+
**\u8FD4\u56DE**\uFF1A\u8DEF\u7531\u8BB0\u5F55\u6570\u7EC4 [{ path, name, meta, children, redirect, aliasOf, props, components, ... }]
|
|
212
|
+
- \u5D4C\u5957\u8DEF\u7531\u5DF2\u5C55\u5F00\uFF1Achildren \u901A\u5E38\u4E3A\u7A7A\uFF0C\u6BCF\u5C42\u5404\u5360\u4E00\u6761\u8BB0\u5F55
|
|
213
|
+
- \u5143\u6570\u636E\u5728 meta\uFF08title / lang / prefix \u7B49\uFF09\uFF1B\u503C\u540C\u6837\u4F1A\u51FA\u73B0 __undefined__ \u7B49\u5360\u4F4D\u8BB0\u53F7`,
|
|
214
|
+
inputSchema: withPageIdSchema({ type: "object", properties: {} })
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: `${VUE_DEVTOOLS_PREFIX}get_timeline`,
|
|
218
|
+
action: VUE_DEVTOOLS_ACTIONS.GET_TIMELINE,
|
|
219
|
+
description: `\u83B7\u53D6\u9875\u9762\u6700\u8FD1\u4E00\u6BB5\u7684 Vue \u8FD0\u884C\u65F6\u4E8B\u4EF6\u65F6\u95F4\u7EBF\uFF1A\u7EC4\u4EF6\u6E32\u67D3\u8017\u65F6\u3001\u7EC4\u4EF6\u4E8B\u4EF6\u3001\u8DEF\u7531\u8DF3\u8F6C\u3001agent \u6807\u8BB0\u3002
|
|
220
|
+
|
|
221
|
+
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
222
|
+
- \u9875\u9762\u5361\u987F/\u767D\u5C4F/\u5185\u5BB9\u4E0D\u66F4\u65B0\uFF0C\u5B9A\u4F4D\u662F\u54EA\u4E2A\u7EC4\u4EF6\u7684\u54EA\u6B21\u6E32\u67D3\u5F15\u8D77
|
|
223
|
+
- \u521A\u505A\u5B8C\u4E00\u6B21\u4EA4\u4E92\uFF0C\u60F3\u770B\u5B83\u5F15\u53D1\u4E86\u54EA\u4E9B\u7EC4\u4EF6\u91CD\u6E32\u67D3\u3001\u5404\u8017\u65F6\u591A\u5C11
|
|
224
|
+
- \u6392\u67E5\u8FC7\u5EA6\u6E32\u67D3\uFF1A\u67D0\u7EC4\u4EF6\u5728\u7A97\u53E3\u5185\u6E32\u67D3/\u66F4\u65B0\u4E86\u51E0\u6B21\u3001\u603B\u8017\u65F6\u591A\u5C11
|
|
225
|
+
|
|
226
|
+
**\u4E24\u6761\u6700\u5E38\u7528\u7684\u8DEF\u5F84**\uFF1A
|
|
227
|
+
- \u73B0\u8C61\u5DF2\u7ECF\u53D1\u751F\uFF08\u7528\u6237\u8BF4"\u521A\u624D\u5F88\u5361"\uFF09\u2192 \u76F4\u63A5 get_timeline
|
|
228
|
+
- \u8981\u7CBE\u786E\u5F52\u56E0\u81EA\u5DF1\u7684\u52A8\u4F5C \u2192 mark_timeline \u2192 \u89E6\u53D1\u52A8\u4F5C \u2192 get_timeline({ sinceMark })
|
|
229
|
+
- \u5168\u7A0B\u5E38\u9A7B\u91C7\u96C6\uFF0C\u4E0D\u9700\u8981 start\uFF1B\u6574\u9875\u5237\u65B0\u4F1A\u6E05\u7A7A\u7F13\u51B2\uFF0CSPA \u8DEF\u7531\u5207\u6362\u4FDD\u7559
|
|
230
|
+
|
|
231
|
+
**\u8FD4\u56DE**\uFF1A
|
|
232
|
+
- summary\uFF1Aperf\uFF08\u6309\u7EC4\u4EF6\u7684\u6B21\u6570/\u603B\u8017\u65F6/\u6700\u6162\u51E0\u6B21\uFF09\u3001lifecycle\uFF08\u7D2F\u8BA1\u589E\u5220\u6539\uFF09\u3001emit\u3001navigate\u3001agent
|
|
233
|
+
- records\uFF1A\u660E\u7EC6\uFF08t \u4E3A\u76F8\u5BF9\u73B0\u5728\u7684\u6BEB\u79D2\u3001\u8D1F\u6570=\u8FC7\u53BB\uFF1Bdur\uFF1BnodeId\uFF1Bfile\uFF09
|
|
234
|
+
- buffer\uFF1A\u5BB9\u91CF\u3001\u4E22\u5F03\u3001\u7A97\u53E3\u5B8C\u6574\u6027\u3001\u8017\u65F6\u7F3A\u5931\u8BA1\u6570
|
|
235
|
+
- omitted + notes\uFF1A\u660E\u7EC6\u88AB\u88C1\u526A\u7684\u53BB\u5411\uFF0C\u4EE5\u53CA"\u4E3A\u4EC0\u4E48\u7F3A\u6570\u636E"\u7684\u81EA\u7136\u8BED\u8A00\u8BF4\u660E
|
|
236
|
+
|
|
237
|
+
**\u8BFB\u6570\u5951\u7EA6\uFF08\u7F3A\u5931 \u2260 \u6CA1\u6709\uFF0C\u66F4 \u2260 0ms\uFF09**\uFF1A
|
|
238
|
+
- \u660E\u7EC6\u4E0D\u662F\u5168\u91CF\uFF1A\u9ED8\u8BA4\u53EA\u7559\u8017\u65F6 \u2265 minDurationMs \u7684\u6E32\u67D3\uFF0C\u518D\u53D7 limit \u4E0E\u4F53\u79EF\u4E0A\u9650\u7EA6\u675F\u3002**\u5224\u65AD"\u660E\u7EC6\u662F\u5426\u5B8C\u6574"\u8BF7\u770B detailComplete**\uFF08= omitted \u4E09\u9879\u5168\u4E3A 0\uFF09\uFF1Btruncated \u53EA\u8868\u793A\u88AB limit/\u4F53\u79EF\u88C1\u526A\u8FC7\uFF0Cslow \u6863\u7684\u9608\u503C\u8FC7\u6EE4\u4E0D\u8BA1\u5165\u5B83\u3002**\u6B21\u6570\u4E0E\u8017\u65F6\u4E00\u5F8B\u4EE5 summary \u4E3A\u51C6**
|
|
239
|
+
- buffer.windowTruncated=true\uFF1A\u7A97\u53E3\u8D77\u70B9\u4E4B\u524D\u7684\u6570\u636E\u5DF2\u88AB\u7F13\u51B2\u6DD8\u6C70\uFF0C\u7A97\u53E3\u5185\u4E0D\u5B8C\u6574
|
|
240
|
+
- buffer.unpaired / prunedStarts > 0\uFF1A\u8FD9\u4E9B\u6E32\u67D3\u6CA1\u914D\u5230\u5B8C\u6574 start/end\uFF0C\u8017\u65F6\u662F**\u7F3A\u5931**\uFF0C\u4E0D\u8981\u8BFB\u6210\u5F88\u5FEB
|
|
241
|
+
- \u6CA1\u6709 nodeId\uFF1A\u89E3\u6790\u4E0D\u51FA\u53EF\u9760\u7EC4\u4EF6 id\uFF0C\u522B\u731C\u4E5F\u522B\u590D\u7528\u522B\u7684 id
|
|
242
|
+
- records.data\uFF08emit \u53C2\u6570\u7B49\uFF09\u4E0E get_component_state \u7528\u540C\u4E00\u5957\u88C1\u526A\uFF0C\u5360\u4F4D\u8BB0\u53F7\u542B\u4E49\u76F8\u540C
|
|
243
|
+
- lifecycle \u7684 added/updated/removed \u662F\u81EA\u9875\u9762\u52A0\u8F7D\u8D77\u7684**\u5168\u9875\u7D2F\u8BA1**\uFF08\u4E0D\u53D7 windowMs\uFF0C\u4E5F\u4E0D\u53D7 component \u8FC7\u6EE4\uFF1B\u53EA\u6709 byComponent \u53D7\u8FC7\u6EE4\uFF09\uFF1BbyComponent \u53EA\u8986\u76D6\u6700\u8FD1\u6D3B\u8DC3\u7684 200 \u4E2A\u7EC4\u4EF6\uFF0CcomponentEvictions > 0 \u8868\u793A\u6709\u7EC4\u4EF6\u88AB\u6DD8\u6C70\u51FA\u8BE5\u8868
|
|
244
|
+
- include: "summary" \u65F6 records \u6309\u8BF7\u6C42\u4E3A\u7A7A\u3001detailComplete \u6052 true\uFF08\u8FD9\u662F"\u6309\u8BF7\u6C42\u53E3\u5F84"\uFF0C\u4E0D\u4EE3\u8868\u7A97\u53E3\u5185\u6CA1\u6709\u4E8B\u4EF6\uFF0C\u6B21\u6570\u770B summary\uFF09
|
|
245
|
+
|
|
246
|
+
**\u4E0B\u4E00\u6B65**\uFF1A\u62FF\u5230 nodeId \u2192 get_component_state\uFF1B\u62FF\u5230 file \u2192 \u76F4\u63A5\u53BB\u6539\u90A3\u4E2A\u6587\u4EF6\u3002
|
|
247
|
+
|
|
248
|
+
**\u4E0D\u8981\u7528\u5B83**\uFF1A\u67E5\u7F51\u7EDC\u8BF7\u6C42\u6216 console\uFF08\u7528 chrome-devtools_*\uFF09\uFF1B\u5F53\u5168\u91CF\u4E8B\u4EF6\u6D41\u7528\uFF08\u660E\u7EC6\u6709\u9608\u503C\u4E0E\u4E0A\u9650\uFF09\u3002`,
|
|
249
|
+
inputSchema: withPageIdSchema({
|
|
250
|
+
type: "object",
|
|
251
|
+
properties: {
|
|
252
|
+
windowMs: {
|
|
253
|
+
type: "number",
|
|
254
|
+
description: `\u56DE\u6EAF\u7A97\u53E3\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 ${VUE_DEVTOOLS_TIMELINE_DEFAULTS.windowMs}`,
|
|
255
|
+
default: VUE_DEVTOOLS_TIMELINE_DEFAULTS.windowMs
|
|
256
|
+
},
|
|
257
|
+
sinceMark: {
|
|
258
|
+
type: "string",
|
|
259
|
+
description: "\u4ECE\u6700\u8FD1\u4E00\u6B21 mark_timeline \u7684\u6807\u8BB0\u5F00\u59CB\uFF08\u4F18\u5148\u4E8E windowMs\uFF09"
|
|
260
|
+
},
|
|
261
|
+
layers: {
|
|
262
|
+
type: "array",
|
|
263
|
+
items: { type: "string", enum: [...VUE_DEVTOOLS_TIMELINE_LAYERS] },
|
|
264
|
+
description: "\u53EA\u770B\u6307\u5B9A\u5C42\uFF0C\u9ED8\u8BA4\u5168\u90E8\uFF08lifecycle \u53EA\u5F71\u54CD\u6458\u8981\uFF09"
|
|
265
|
+
},
|
|
266
|
+
minDurationMs: {
|
|
267
|
+
type: "number",
|
|
268
|
+
description: `\u7EC4\u4EF6\u6E32\u67D3\u660E\u7EC6\u7684\u8017\u65F6\u4E0B\u9650\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 ${VUE_DEVTOOLS_TIMELINE_DEFAULTS.minDurationMs}\uFF1B16 \u7EA6\u7B49\u4E8E\u53EA\u770B\u6389\u5E27`,
|
|
269
|
+
default: VUE_DEVTOOLS_TIMELINE_DEFAULTS.minDurationMs
|
|
270
|
+
},
|
|
271
|
+
component: {
|
|
272
|
+
type: "string",
|
|
273
|
+
description: "\u6309\u7EC4\u4EF6\u540D\u5B50\u4E32\u8FC7\u6EE4\uFF08\u5927\u5C0F\u5199\u4E0D\u654F\u611F\uFF09\u660E\u7EC6\u4E0E byComponent\uFF1B\u8DEF\u7531\u4E0E\u6807\u8BB0\u4E0D\u53D7\u5F71\u54CD\uFF0Clifecycle \u7684 added/updated/removed \u4ECD\u662F\u5168\u9875\u7D2F\u8BA1"
|
|
274
|
+
},
|
|
275
|
+
include: {
|
|
276
|
+
type: "string",
|
|
277
|
+
enum: [...VUE_DEVTOOLS_TIMELINE_INCLUDES],
|
|
278
|
+
description: "summary \u53EA\u7ED9\u6458\u8981\u3001slow \u53EA\u7ED9\u6162\u7684\u660E\u7EC6\uFF08\u9ED8\u8BA4\uFF09\u3001all \u7ED9\u7A97\u53E3\u5185\u5168\u90E8\u660E\u7EC6",
|
|
279
|
+
default: VUE_DEVTOOLS_TIMELINE_DEFAULTS.include
|
|
280
|
+
},
|
|
281
|
+
limit: {
|
|
282
|
+
type: "integer",
|
|
283
|
+
description: `\u660E\u7EC6\u6761\u6570\u4E0A\u9650\uFF1Aall \u6863\u662F\u603B\u6761\u6570\u4E0A\u9650\uFF1Bslow \u6863\u662F\u300C\u6700\u6162\u7684 perf\u300D\u4E0E\u300C\u5176\u5B83\u5C42\u300D\u5404\u81EA\u7684\u4E0A\u9650\uFF08\u603B\u6761\u6570\u6700\u591A 2\xD7limit\uFF09\u3002\u9ED8\u8BA4 ${VUE_DEVTOOLS_TIMELINE_DEFAULTS.limit}\uFF0C\u6700\u5927 ${VUE_DEVTOOLS_TIMELINE_DEFAULTS.maxLimit}`,
|
|
284
|
+
default: VUE_DEVTOOLS_TIMELINE_DEFAULTS.limit
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
})
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: `${VUE_DEVTOOLS_PREFIX}mark_timeline`,
|
|
291
|
+
action: VUE_DEVTOOLS_ACTIONS.MARK_TIMELINE,
|
|
292
|
+
description: `\u5728\u65F6\u95F4\u7EBF\u4E0A\u63D2\u4E00\u4E2A\u6807\u8BB0\uFF0C\u628A"\u6211\u63A5\u4E0B\u6765\u8981\u505A\u7684\u52A8\u4F5C"\u548C\u5B83\u5F15\u53D1\u7684\u4E8B\u4EF6\u5BF9\u9F50\uFF08\u4E0D\u6E05\u7A7A\u5386\u53F2\uFF09\u3002
|
|
293
|
+
|
|
294
|
+
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
295
|
+
- \u51C6\u5907\u7528 chrome-devtools_click / fill \u89E6\u53D1\u64CD\u4F5C\uFF0C\u60F3\u53EA\u770B\u8FD9\u6B21\u64CD\u4F5C\u5F15\u8D77\u7684\u53D8\u5316
|
|
296
|
+
- \u4E00\u6B21\u8C03\u67E5\u91CC\u8981\u591A\u4E2A\u68C0\u67E5\u70B9\uFF08"\u70B9\u51FB\u524D""\u63D0\u4EA4\u540E"\uFF09
|
|
297
|
+
|
|
298
|
+
**\u7528\u6CD5**\uFF1Amark_timeline({ label }) \u2192 \u6267\u884C\u52A8\u4F5C \u2192 get_timeline({ sinceMark: \u8FD4\u56DE\u7684 markId })
|
|
299
|
+
|
|
300
|
+
**\u8FD4\u56DE**\uFF1A{ markId, buffered }\u3002markId \u4F20\u7ED9 sinceMark\uFF1Bbuffered \u662F\u5F53\u524D\u7F13\u51B2\u6761\u6570\u3002`,
|
|
301
|
+
inputSchema: withPageIdSchema({
|
|
302
|
+
type: "object",
|
|
303
|
+
properties: {
|
|
304
|
+
label: { type: "string", description: "\u6807\u8BB0\u540D\u79F0\uFF0C\u4F8B\u5982\u201C\u70B9\u51FB\u63D0\u4EA4\u6309\u94AE\u201D" }
|
|
305
|
+
},
|
|
306
|
+
required: ["label"]
|
|
307
|
+
})
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: `${VUE_DEVTOOLS_PREFIX}clear_timeline`,
|
|
311
|
+
action: VUE_DEVTOOLS_ACTIONS.CLEAR_TIMELINE,
|
|
312
|
+
description: `\u6E05\u7A7A\u65F6\u95F4\u7EBF\u7F13\u51B2\u5E76\u91CD\u7F6E\u7D2F\u8BA1\u8BA1\u6570\u2014\u2014\u7B49\u4EF7\u4E8E"\u4ECE\u73B0\u5728\u5F00\u59CB\u5F55"\uFF08\u6CA1\u6709 start/stop \u72B6\u6001\u673A\uFF09\u3002
|
|
313
|
+
|
|
314
|
+
**\u4F55\u65F6\u4F7F\u7528**\uFF1A
|
|
315
|
+
- \u53EA\u60F3\u770B\u672C\u6B21\u64CD\u4F5C\u5F15\u8D77\u7684\u4E8B\u4EF6\uFF0C\u4E0D\u8981\u6DF7\u5165\u9875\u9762\u4E4B\u524D\u7684\u6D3B\u52A8
|
|
316
|
+
- get_timeline \u62A5 buffer.dropped \u5F88\u5927\uFF08\u7F13\u51B2\u88AB\u9AD8\u9891\u6D3B\u52A8\u585E\u6EE1\uFF09\u540E\uFF0C\u91CD\u5F00\u4E00\u4E2A\u5E72\u51C0\u7A97\u53E3
|
|
317
|
+
|
|
318
|
+
**\u8FD4\u56DE**\uFF1A{ cleared, marks }\u3002
|
|
319
|
+
|
|
320
|
+
**\u6CE8\u610F**\uFF1A\u4E0D\u53EF\u64A4\u9500\uFF1B\u6E05\u7A7A\u540E\u6B64\u524D\u7684\u4E8B\u4EF6\u4E0D\u518D\u53EF\u67E5\u3002\u60F3\u4FDD\u7559\u5386\u53F2\u53C8\u8981\u65B0\u8FB9\u754C\uFF0C\u8BF7\u7528 mark_timeline\u3002`,
|
|
177
321
|
inputSchema: withPageIdSchema({ type: "object", properties: {} })
|
|
178
322
|
}
|
|
179
323
|
];
|
|
@@ -65,11 +65,25 @@ function buildCallExpr(action, args) {
|
|
|
65
65
|
case VUE_DEVTOOLS_ACTIONS.TOGGLE_APP:
|
|
66
66
|
return `async () => { await window.__aipanel_vue.api.toggleApp(${JSON.stringify(args?.appId)}); return "ok" }`;
|
|
67
67
|
case VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO:
|
|
68
|
-
return `async () => { const r = window.__aipanel_vue.router.value;
|
|
68
|
+
return `async () => { const r = window.__aipanel_vue.router.value; const s = window.__aipanel_vue.safeStringify; return { currentRoute: JSON.parse(s(r?.currentRoute?.value ?? null)), routes: JSON.parse(s(r?.getRoutes?.() ?? [])) } }`;
|
|
69
|
+
case VUE_DEVTOOLS_ACTIONS.GET_TIMELINE:
|
|
70
|
+
return timelineExpr(`timeline.get(${JSON.stringify(withoutPageId(args))})`);
|
|
71
|
+
case VUE_DEVTOOLS_ACTIONS.MARK_TIMELINE:
|
|
72
|
+
return timelineExpr(`timeline.mark(${JSON.stringify(String(args?.label ?? ""))})`);
|
|
73
|
+
case VUE_DEVTOOLS_ACTIONS.CLEAR_TIMELINE:
|
|
74
|
+
return timelineExpr("timeline.clear()");
|
|
69
75
|
default:
|
|
70
76
|
throw new Error(`Unknown action: ${action}`);
|
|
71
77
|
}
|
|
72
78
|
}
|
|
79
|
+
function timelineExpr(call) {
|
|
80
|
+
return `async () => { const timeline = window.__aipanel_vue && window.__aipanel_vue.timeline; if (!timeline) return { error: "\u65F6\u95F4\u7EBF\u91C7\u96C6\u5668\u4E0D\u53EF\u7528\uFF1A\u9875\u9762\u6865\u7248\u672C\u8FC7\u65E7\uFF0C\u8BF7\u91CD\u542F dev server \u5E76\u6574\u9875\u5237\u65B0\u540E\u518D\u8BD5" }; return await ${call} }`;
|
|
81
|
+
}
|
|
82
|
+
function withoutPageId(args) {
|
|
83
|
+
const rest = { ...args ?? {} };
|
|
84
|
+
delete rest.pageId;
|
|
85
|
+
return rest;
|
|
86
|
+
}
|
|
73
87
|
function parseEvalResult(result) {
|
|
74
88
|
const r = result;
|
|
75
89
|
const text = r?.result?.content?.[0]?.text;
|
|
@@ -1,94 +1,6 @@
|
|
|
1
1
|
var import_devtools_kit = require("@vue/devtools-kit");
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const MAX_KEYS = 20;
|
|
5
|
-
const VUE_INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
6
|
-
"dep",
|
|
7
|
-
"subs",
|
|
8
|
-
"subsHead",
|
|
9
|
-
"deps",
|
|
10
|
-
"depsTail",
|
|
11
|
-
"activeLink",
|
|
12
|
-
"prevActiveLink",
|
|
13
|
-
"nextDep",
|
|
14
|
-
"prevDep",
|
|
15
|
-
"flags",
|
|
16
|
-
"globalVersion",
|
|
17
|
-
"sc",
|
|
18
|
-
"isSSR",
|
|
19
|
-
"__v_isRef",
|
|
20
|
-
"__v_isReadonly",
|
|
21
|
-
"__v_skip",
|
|
22
|
-
"computed",
|
|
23
|
-
"effect",
|
|
24
|
-
"setter",
|
|
25
|
-
"fn"
|
|
26
|
-
]);
|
|
27
|
-
const SKIP_STATE_TYPES = /* @__PURE__ */ new Set([
|
|
28
|
-
"provided",
|
|
29
|
-
"injected",
|
|
30
|
-
"event listeners",
|
|
31
|
-
"template refs"
|
|
32
|
-
]);
|
|
33
|
-
function isVueInternalObject(value) {
|
|
34
|
-
if (!value || typeof value !== "object") return false;
|
|
35
|
-
if (value.__isVue === true) return true;
|
|
36
|
-
const keys = Object.keys(value);
|
|
37
|
-
const internalCount = keys.filter((k) => VUE_INTERNAL_KEYS.has(k)).length;
|
|
38
|
-
return internalCount > 0 && internalCount >= keys.length * 0.5;
|
|
39
|
-
}
|
|
40
|
-
function sanitizeValue(value, depth = 0) {
|
|
41
|
-
if (depth > MAX_DEPTH) return "<max depth>";
|
|
42
|
-
if (value === null || value === "__undefined__") return null;
|
|
43
|
-
if (typeof value === "string") {
|
|
44
|
-
if (value.startsWith("data:") || value.length > MAX_STRING_LENGTH)
|
|
45
|
-
return `<${value.slice(0, 50)}... (${value.length} chars)>`;
|
|
46
|
-
if (value === "[Circular Reference]" || value === "[Function]") return null;
|
|
47
|
-
return value;
|
|
48
|
-
}
|
|
49
|
-
if (typeof value !== "object") return value;
|
|
50
|
-
if (Array.isArray(value)) {
|
|
51
|
-
return value.slice(0, MAX_KEYS).map((v) => sanitizeValue(v, depth + 1));
|
|
52
|
-
}
|
|
53
|
-
if (isVueInternalObject(value)) return null;
|
|
54
|
-
const result = {};
|
|
55
|
-
const keys = Object.keys(value).filter((k) => !k.startsWith("Symbol(")).slice(0, MAX_KEYS);
|
|
56
|
-
for (const key of keys) {
|
|
57
|
-
if (VUE_INTERNAL_KEYS.has(key)) continue;
|
|
58
|
-
const v = sanitizeValue(value[key], depth + 1);
|
|
59
|
-
if (v !== null) result[key] = v;
|
|
60
|
-
}
|
|
61
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
62
|
-
}
|
|
63
|
-
function sanitizeState(state) {
|
|
64
|
-
const result = {};
|
|
65
|
-
for (const item of state) {
|
|
66
|
-
if (SKIP_STATE_TYPES.has(item.type)) continue;
|
|
67
|
-
if (!result[item.type]) result[item.type] = {};
|
|
68
|
-
const value = sanitizeValue(item.value);
|
|
69
|
-
if (value !== null) {
|
|
70
|
-
result[item.type][item.key] = {
|
|
71
|
-
value,
|
|
72
|
-
...item.stateType ? { type: item.stateType } : {}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
function safeStringify(obj) {
|
|
79
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
80
|
-
return JSON.stringify(obj, (_key, value) => {
|
|
81
|
-
if (typeof value === "object" && value !== null) {
|
|
82
|
-
if (seen.has(value)) return "[Circular Reference]";
|
|
83
|
-
seen.add(value);
|
|
84
|
-
}
|
|
85
|
-
if (typeof value === "function") return "[Function]";
|
|
86
|
-
if (typeof value === "symbol") return value.toString();
|
|
87
|
-
if (typeof value === "bigint") return `${value}n`;
|
|
88
|
-
if (value === void 0) return "__undefined__";
|
|
89
|
-
return value;
|
|
90
|
-
});
|
|
91
|
-
}
|
|
2
|
+
var import_vue_devtools_sanitize = require("./vue-devtools-sanitize.cjs");
|
|
3
|
+
var import_vue_devtools_timeline = require("./vue-devtools-timeline.cjs");
|
|
92
4
|
const READ_METHODS = /* @__PURE__ */ new Set([
|
|
93
5
|
"getInspectorState",
|
|
94
6
|
"getInspectorTree",
|
|
@@ -118,7 +30,7 @@ const safeApi = new Proxy(import_devtools_kit.devtools.api, {
|
|
|
118
30
|
if (prop === "getInspectorState") {
|
|
119
31
|
const nodeId = args[0]?.nodeId;
|
|
120
32
|
if (!await isNodeIdValid(nodeId)) {
|
|
121
|
-
return safeStringify({
|
|
33
|
+
return (0, import_vue_devtools_sanitize.safeStringify)({
|
|
122
34
|
error: `\u7EC4\u4EF6 ${String(nodeId)} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\u6216\u7EC4\u4EF6\u5DF2\u5378\u8F7D\uFF09\uFF0C\u8BF7\u91CD\u65B0\u8C03\u7528 vue-devtools_get_component_tree \u83B7\u53D6\u6700\u65B0 nodeId \u540E\u518D\u8BD5\u3002`
|
|
123
35
|
});
|
|
124
36
|
}
|
|
@@ -126,25 +38,45 @@ const safeApi = new Proxy(import_devtools_kit.devtools.api, {
|
|
|
126
38
|
try {
|
|
127
39
|
const raw = await original.apply(target, args);
|
|
128
40
|
if (prop === "getInspectorState") {
|
|
129
|
-
return safeStringify({
|
|
130
|
-
state: sanitizeState(
|
|
41
|
+
return (0, import_vue_devtools_sanitize.safeStringify)({
|
|
42
|
+
state: (0, import_vue_devtools_sanitize.sanitizeState)(
|
|
131
43
|
raw?.state ?? raw
|
|
132
44
|
)
|
|
133
45
|
});
|
|
134
46
|
}
|
|
135
|
-
return safeStringify(raw);
|
|
47
|
+
return (0, import_vue_devtools_sanitize.safeStringify)(raw);
|
|
136
48
|
} catch (error) {
|
|
137
|
-
return safeStringify({
|
|
49
|
+
return (0, import_vue_devtools_sanitize.safeStringify)({
|
|
138
50
|
error: `\u7EC4\u4EF6\u72B6\u6001\u83B7\u53D6\u5931\u8D25\uFF08${error.message}\uFF09\u3002\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF0C\u8BF7\u91CD\u65B0\u8C03\u7528 vue-devtools_get_component_tree \u83B7\u53D6\u6700\u65B0 nodeId \u540E\u518D\u8BD5\u3002`
|
|
139
51
|
});
|
|
140
52
|
}
|
|
141
53
|
};
|
|
142
54
|
}
|
|
143
55
|
});
|
|
56
|
+
async function getInspectorTree() {
|
|
57
|
+
return import_devtools_kit.devtools.api.getInspectorTree({ inspectorId: "components", filter: "" });
|
|
58
|
+
}
|
|
59
|
+
function asRouter(value) {
|
|
60
|
+
const router = value;
|
|
61
|
+
return router && typeof router.afterEach === "function" ? router : void 0;
|
|
62
|
+
}
|
|
63
|
+
function resolveRouter(app) {
|
|
64
|
+
const fromApp = asRouter(app?.config?.globalProperties?.$router);
|
|
65
|
+
return fromApp ?? asRouter(import_devtools_kit.devtoolsRouter.value);
|
|
66
|
+
}
|
|
144
67
|
import_devtools_kit.devtools.init();
|
|
68
|
+
const globalHook = globalThis.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
|
69
|
+
const timeline = (0, import_vue_devtools_timeline.createTimelineRecorder)({
|
|
70
|
+
hook: globalHook,
|
|
71
|
+
getAppRecords: () => import_devtools_kit.devtools.ctx.state.appRecords,
|
|
72
|
+
getInspectorTree,
|
|
73
|
+
resolveRouter
|
|
74
|
+
});
|
|
75
|
+
timeline.attachRouters();
|
|
145
76
|
window.__aipanel_vue = {
|
|
146
77
|
api: safeApi,
|
|
147
78
|
router: import_devtools_kit.devtoolsRouter,
|
|
148
79
|
ctx: import_devtools_kit.devtools.ctx,
|
|
149
|
-
safeStringify
|
|
80
|
+
safeStringify: import_vue_devtools_sanitize.safeStringify,
|
|
81
|
+
timeline
|
|
150
82
|
};
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* 注入到用户页面,初始化 @vue/devtools-kit 并暴露到 window.__aipanel_vue
|
|
4
4
|
* AI 通过 Chrome DevTools evaluate_script 调用此 API
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* - api Proxy:对读操作自动 safeStringify,getInspectorState 额外裁剪 Vue 内部数据;
|
|
7
|
+
* - timeline:页面侧时间线采集器(常驻采集,见 vue-devtools-timeline.ts)。
|
|
7
8
|
*/
|
|
8
9
|
import { devtools, devtoolsRouter } from "@vue/devtools-kit";
|
|
9
|
-
|
|
10
|
+
import { safeStringify } from "./vue-devtools-sanitize";
|
|
11
|
+
import { type TimelineRecorder } from "./vue-devtools-timeline";
|
|
10
12
|
declare const safeApi: {
|
|
11
13
|
getInspectorTree(payload: Pick<import("@vue/devtools-kit").DevToolsV6PluginAPIHookPayloads[import("@vue/devtools-kit").DevToolsV6PluginAPIHookKeys.GET_INSPECTOR_TREE], "inspectorId" | "filter">): Promise<never[]>;
|
|
12
14
|
getInspectorState(payload: Pick<import("@vue/devtools-kit").DevToolsV6PluginAPIHookPayloads[import("@vue/devtools-kit").DevToolsV6PluginAPIHookKeys.GET_INSPECTOR_STATE], "inspectorId" | "nodeId">): Promise<import("@vue/devtools-kit").CustomInspectorState>;
|
|
@@ -52,6 +54,7 @@ declare global {
|
|
|
52
54
|
router: typeof devtoolsRouter;
|
|
53
55
|
ctx: typeof devtools.ctx;
|
|
54
56
|
safeStringify: typeof safeStringify;
|
|
57
|
+
timeline: TimelineRecorder;
|
|
55
58
|
};
|
|
56
59
|
}
|
|
57
60
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var vue_devtools_sanitize_exports = {};
|
|
19
|
+
__export(vue_devtools_sanitize_exports, {
|
|
20
|
+
SANITIZE_PLACEHOLDERS: () => SANITIZE_PLACEHOLDERS,
|
|
21
|
+
SKIP_STATE_TYPES: () => SKIP_STATE_TYPES,
|
|
22
|
+
safeStringify: () => safeStringify,
|
|
23
|
+
sanitizeState: () => sanitizeState,
|
|
24
|
+
sanitizeValue: () => sanitizeValue
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(vue_devtools_sanitize_exports);
|
|
27
|
+
const MAX_STRING_LENGTH = 150;
|
|
28
|
+
const MAX_DEPTH = 3;
|
|
29
|
+
const MAX_KEYS = 20;
|
|
30
|
+
const VUE_INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
31
|
+
"dep",
|
|
32
|
+
"subs",
|
|
33
|
+
"subsHead",
|
|
34
|
+
"deps",
|
|
35
|
+
"depsTail",
|
|
36
|
+
"activeLink",
|
|
37
|
+
"prevActiveLink",
|
|
38
|
+
"nextDep",
|
|
39
|
+
"prevDep",
|
|
40
|
+
"flags",
|
|
41
|
+
"globalVersion",
|
|
42
|
+
"sc",
|
|
43
|
+
"isSSR",
|
|
44
|
+
"__v_isRef",
|
|
45
|
+
"__v_isReadonly",
|
|
46
|
+
"__v_skip",
|
|
47
|
+
"computed",
|
|
48
|
+
"effect",
|
|
49
|
+
"setter",
|
|
50
|
+
"fn"
|
|
51
|
+
]);
|
|
52
|
+
const SKIP_STATE_TYPES = /* @__PURE__ */ new Set([
|
|
53
|
+
"provided",
|
|
54
|
+
"injected",
|
|
55
|
+
"event listeners",
|
|
56
|
+
"template refs"
|
|
57
|
+
]);
|
|
58
|
+
const SANITIZE_PLACEHOLDERS = ["__undefined__", "[Function]", "<max depth>"];
|
|
59
|
+
function isVueInternalObject(value) {
|
|
60
|
+
if (!value || typeof value !== "object") return false;
|
|
61
|
+
if (value.__isVue === true) return true;
|
|
62
|
+
const keys = Object.keys(value);
|
|
63
|
+
const internalCount = keys.filter((k) => VUE_INTERNAL_KEYS.has(k)).length;
|
|
64
|
+
return internalCount > 0 && internalCount >= keys.length * 0.5;
|
|
65
|
+
}
|
|
66
|
+
function sanitizeValue(value, depth = 0) {
|
|
67
|
+
if (depth > MAX_DEPTH) return "<max depth>";
|
|
68
|
+
if (value === null || value === "__undefined__") return null;
|
|
69
|
+
if (typeof value === "string") {
|
|
70
|
+
if (value.startsWith("data:") || value.length > MAX_STRING_LENGTH)
|
|
71
|
+
return `<${value.slice(0, 50)}... (${value.length} chars)>`;
|
|
72
|
+
if (value === "[Circular Reference]" || value === "[Function]") return null;
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
76
|
+
if (typeof value === "symbol") return value.toString();
|
|
77
|
+
if (typeof value === "function") return "[Function]";
|
|
78
|
+
if (typeof value !== "object") return value;
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
return value.slice(0, MAX_KEYS).map((v) => sanitizeValue(v, depth + 1));
|
|
81
|
+
}
|
|
82
|
+
if (isVueInternalObject(value)) return null;
|
|
83
|
+
const result = {};
|
|
84
|
+
const keys = Object.keys(value).filter((k) => !k.startsWith("Symbol(")).slice(0, MAX_KEYS);
|
|
85
|
+
for (const key of keys) {
|
|
86
|
+
if (VUE_INTERNAL_KEYS.has(key)) continue;
|
|
87
|
+
const v = sanitizeValue(value[key], depth + 1);
|
|
88
|
+
if (v !== null) result[key] = v;
|
|
89
|
+
}
|
|
90
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
91
|
+
}
|
|
92
|
+
function sanitizeState(state) {
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const item of state) {
|
|
95
|
+
if (SKIP_STATE_TYPES.has(item.type)) continue;
|
|
96
|
+
if (!result[item.type]) result[item.type] = {};
|
|
97
|
+
const value = sanitizeValue(item.value);
|
|
98
|
+
if (value !== null) {
|
|
99
|
+
result[item.type][item.key] = {
|
|
100
|
+
value,
|
|
101
|
+
...item.stateType ? { type: item.stateType } : {}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
function safeStringify(obj) {
|
|
108
|
+
const ancestors = [];
|
|
109
|
+
return JSON.stringify(obj, function replacer(_key, value) {
|
|
110
|
+
if (typeof value === "object" && value !== null) {
|
|
111
|
+
while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop();
|
|
112
|
+
if (ancestors.includes(value)) return "[Circular Reference]";
|
|
113
|
+
ancestors.push(value);
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === "function") return "[Function]";
|
|
117
|
+
if (typeof value === "symbol") return value.toString();
|
|
118
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
119
|
+
if (value === void 0) return "__undefined__";
|
|
120
|
+
return value;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
124
|
+
0 && (module.exports = {
|
|
125
|
+
SANITIZE_PLACEHOLDERS,
|
|
126
|
+
SKIP_STATE_TYPES,
|
|
127
|
+
safeStringify,
|
|
128
|
+
sanitizeState,
|
|
129
|
+
sanitizeValue
|
|
130
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 注入页面的 Vue DevTools 数据裁剪能力。
|
|
3
|
+
*
|
|
4
|
+
* 桥(vue-devtools-bridge)与时间线采集器(vue-devtools-timeline)共用同一套裁剪规则,
|
|
5
|
+
* 保证任何返回给 agent 的 Vue 数据都经过同样的截断/去内部字段处理。
|
|
6
|
+
*/
|
|
7
|
+
import type { InspectorState } from "@vue/devtools-kit";
|
|
8
|
+
/**
|
|
9
|
+
* 对 agent 无意义、被刻意裁掉的状态分类(省 token)。
|
|
10
|
+
* 导出给工具描述做一致性守卫:描述必须显式告诉模型这些分类永远查不到,
|
|
11
|
+
* 否则模型会按描述去查、再把"查不到"读成"不存在"。
|
|
12
|
+
*/
|
|
13
|
+
export declare const SKIP_STATE_TYPES: ReadonlySet<string>;
|
|
14
|
+
/**
|
|
15
|
+
* 裁剪后出现的**值级占位记号**(导出给工具描述做一致性守卫)。
|
|
16
|
+
* 不解释它们,模型会把占位读成真实值 —— 例如 `"__undefined__"` 被当成一个字符串 prop。
|
|
17
|
+
* 长字符串另有一种形态:`<前缀... (N chars)>`(见 sanitizeValue)。
|
|
18
|
+
*/
|
|
19
|
+
export declare const SANITIZE_PLACEHOLDERS: readonly ["__undefined__", "[Function]", "<max depth>"];
|
|
20
|
+
export declare function sanitizeValue(value: unknown, depth?: number): unknown;
|
|
21
|
+
/** 裁剪 InspectorState[],去掉 Vue 内部数据和噪音类型 */
|
|
22
|
+
export declare function sanitizeState(state: InspectorState[]): Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* JSON 序列化:函数/符号/bigint/undefined 换成可读占位,并处理循环引用。
|
|
25
|
+
*
|
|
26
|
+
* 判环用**当前路径上的祖先链**,而不是"见过的所有对象":
|
|
27
|
+
* 同一对象被多处引用是合法结构(DAG)——例如路由记录会被顶层数组与嵌套 children 同时引用
|
|
28
|
+
* (实测 `routes[0].meta === routes[6].children[0].meta` 且不是环)。seen-anywhere 会把它误标成
|
|
29
|
+
* `[Circular Reference]`,agent 读到假值、还以为数据真有环。真环仍标该占位;共享对象**重复输出**而不是被吞掉。
|
|
30
|
+
*/
|
|
31
|
+
export declare function safeStringify(obj: unknown): string;
|