vite-plugin-aipanel 1.2.27 → 1.3.1

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.
@@ -1,4 +1,9 @@
1
- import { VUE_DEVTOOLS_ACTIONS } from "@aipanel/core";
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: `\u83B7\u53D6\u6307\u5B9A\u9875\u9762\u6240\u6709 Vue \u5E94\u7528\u5B9E\u4F8B\u5217\u8868\u3002
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
- - \u6392\u67E5\u5FAE\u524D\u7AEF/\u591A\u5B9E\u4F8B\u573A\u666F\u4E0B\u64CD\u4F5C\u7684\u662F\u54EA\u4E2A\u5E94\u7528
92
- - \u5207\u6362\u6D3B\u8DC3\u5E94\u7528\u524D\u67E5\u770B\u6709\u54EA\u4E9B\u53EF\u7528`,
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\u6307\u5B9A\u9875\u9762\u7684\u6D3B\u8DC3 Vue \u5E94\u7528\u5B9E\u4F8B\u3002\u540E\u7EED\u6240\u6709 vue-devtools_* \u5DE5\u5177\u90FD\u64CD\u4F5C\u8FD9\u4E2A\u5E94\u7528\u3002`,
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\u6307\u5B9A\u9875\u9762\u5F53\u524D\u6D3B\u8DC3 Vue \u5E94\u7528\u7684\u7EC4\u4EF6\u6811\u3002
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
- - \u4E86\u89E3\u9875\u9762\u7EC4\u4EF6\u5C42\u7EA7\u7ED3\u6784
114
- - \u627E\u5230\u76EE\u6807\u7EC4\u4EF6\u7684 nodeId\uFF08\u540E\u7EED\u67E5\u72B6\u6001\u7528\uFF09
115
- - \u6392\u67E5\u7EC4\u4EF6\u672A\u6E32\u67D3\u95EE\u9898
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\u6811 [{ id, name, children, file, ... }]`,
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\u4E0D\u654F\u611F\u7684\u5B50\u4E32\u5339\u914D\uFF09\uFF0C\u53EF\u9009" }
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\u5B8C\u6574\u8FD0\u884C\u65F6\u72B6\u6001\u3002
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
- - \u6392\u67E5 props \u4F20\u503C\u662F\u5426\u6B63\u786E
133
- - \u67E5\u770B ref/reactive \u54CD\u5E94\u5F0F\u6570\u636E\u7684\u5F53\u524D\u503C
134
- - \u68C0\u67E5 computed \u8BA1\u7B97\u7ED3\u679C
135
- - \u67E5\u770B attrs / events / inject / provide / template refs`,
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\u7684\u6E32\u67D3\u51FD\u6570\u6E90\u7801\u3002`,
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 Vue Router \u7684\u5F53\u524D\u8DEF\u7531\u4FE1\u606F\u3002
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\u95EE\u9898
164
- - \u67E5\u770B\u5F53\u524D\u8DEF\u7531 path/params/query/hash
165
- - \u786E\u8BA4\u8DEF\u7531\u5B88\u536B\u548C matched \u8BB0\u5F55`,
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 Vue Router \u7684\u5B8C\u6574\u8DEF\u7531\u8868\u3002
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
- - \u67E5\u770B\u6240\u6709\u5DF2\u6CE8\u518C\u8DEF\u7531
175
- - \u786E\u8BA4\u8DEF\u7531\u914D\u7F6E\u662F\u5426\u6B63\u786E
176
- - \u67E5\u770B\u8DEF\u7531\u5D4C\u5957\u5173\u7CFB`,
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; return window.__aipanel_vue.safeStringify({ currentRoute: r?.currentRoute?.value ?? null, routes: r?.getRoutes?.() ?? [] }) }`;
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
- const MAX_STRING_LENGTH = 150;
3
- const MAX_DEPTH = 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
- * API Proxy 自动对读操作做 safeStringify,getInspectorState 额外裁剪 Vue 内部数据
6
+ * - api Proxy:对读操作自动 safeStringify,getInspectorState 额外裁剪 Vue 内部数据;
7
+ * - timeline:页面侧时间线采集器(常驻采集,见 vue-devtools-timeline.ts)。
7
8
  */
8
9
  import { devtools, devtoolsRouter } from "@vue/devtools-kit";
9
- declare function safeStringify(obj: unknown): string;
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,128 @@
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 seen = /* @__PURE__ */ new WeakSet();
109
+ return JSON.stringify(obj, (_key, value) => {
110
+ if (typeof value === "object" && value !== null) {
111
+ if (seen.has(value)) return "[Circular Reference]";
112
+ seen.add(value);
113
+ }
114
+ if (typeof value === "function") return "[Function]";
115
+ if (typeof value === "symbol") return value.toString();
116
+ if (typeof value === "bigint") return `${value}n`;
117
+ if (value === void 0) return "__undefined__";
118
+ return value;
119
+ });
120
+ }
121
+ // Annotate the CommonJS export names for ESM import in node:
122
+ 0 && (module.exports = {
123
+ SANITIZE_PLACEHOLDERS,
124
+ SKIP_STATE_TYPES,
125
+ safeStringify,
126
+ sanitizeState,
127
+ sanitizeValue
128
+ });
@@ -0,0 +1,23 @@
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
+ export declare function safeStringify(obj: unknown): string;