@mcpc-tech/unplugin-dev-inspector-mcp 0.1.7 → 0.1.9
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/README.md +8 -16
- package/client/dist/inspector.js +1 -1
- package/dist/cli.cjs +92 -21
- package/dist/cli.js +87 -21
- package/dist/codemod-transformer.cjs +4 -0
- package/dist/codemod-transformer.js +3 -0
- package/dist/index.cjs +26 -4
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +25 -4
- package/dist/standalone-server.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,19 +150,17 @@ If you prefer to configure it manually:
|
|
|
150
150
|
|
|
151
151
|
If your project doesn't use HTML files (e.g., miniapp platforms that only bundle JS):
|
|
152
152
|
|
|
153
|
+
```typescript
|
|
154
|
+
// vite.config.ts
|
|
153
155
|
```typescript
|
|
154
156
|
// vite.config.ts
|
|
155
157
|
DevInspector.vite({
|
|
156
158
|
enabled: true,
|
|
157
|
-
autoInject: false // Disable HTML injection
|
|
159
|
+
autoInject: false, // Disable HTML injection
|
|
160
|
+
entry: 'src/main.ts' // Inject inspector into entry file
|
|
158
161
|
})
|
|
159
162
|
```
|
|
160
163
|
|
|
161
|
-
```typescript
|
|
162
|
-
// main.ts or app entry point
|
|
163
|
-
import 'virtual:dev-inspector-mcp'; // ← Add this import
|
|
164
|
-
```
|
|
165
|
-
|
|
166
164
|
##### TypeScript Types (Required for `virtual:dev-inspector-mcp`)
|
|
167
165
|
|
|
168
166
|
If you use TypeScript and import `virtual:dev-inspector-mcp`, make sure your TS config includes the plugin client types:
|
|
@@ -270,15 +268,6 @@ export default function RootLayout({ children }) {
|
|
|
270
268
|
|
|
271
269
|
### React Router v7+
|
|
272
270
|
|
|
273
|
-
Since React Router handles HTML generation via its own SSR/SPA mechanism, it bypasses the standard Vite HTML transformation hooks. You need to manually import the virtual module in your entry file.
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
// app/root.tsx or app/entry.client.tsx
|
|
277
|
-
import 'virtual:dev-inspector-mcp';
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
And ensure your `vite.config.ts` has the plugin:
|
|
281
|
-
|
|
282
271
|
```typescript
|
|
283
272
|
// vite.config.ts
|
|
284
273
|
import { reactRouter } from "@react-router/dev/vite";
|
|
@@ -286,7 +275,10 @@ import DevInspector from '@mcpc-tech/unplugin-dev-inspector-mcp';
|
|
|
286
275
|
|
|
287
276
|
export default defineConfig({
|
|
288
277
|
plugins: [
|
|
289
|
-
DevInspector.vite({
|
|
278
|
+
DevInspector.vite({
|
|
279
|
+
enabled: true,
|
|
280
|
+
entry: "app/root.tsx" // Inject inspector into root layout
|
|
281
|
+
}),
|
|
290
282
|
reactRouter(),
|
|
291
283
|
],
|
|
292
284
|
});
|
package/client/dist/inspector.js
CHANGED
|
@@ -352,7 +352,7 @@ Available Terminal Logs (Recent 50):
|
|
|
352
352
|
${i||`None`}
|
|
353
353
|
|
|
354
354
|
IMPORTANT: For this task, you MUST call the "context_selector" tool to return your selection. Do NOT use inspector tools like list_inspections, capture_element_context, update_inspection_status, or execute_page_script - the context is already provided above. You may read files if needed to understand the context better. Even if you select nothing, still call context_selector with empty arrays. Do not reply with text only. Note: You can ignore logs from dev-inspector itself.
|
|
355
|
-
`,o=f.find(e=>e.name===c)||f[0];await fe({text:a},{body:{agent:o,envVars:{},inferContext:!0,isAutomated:!0}})},ge=e=>{switch(e){case`error`:return`bg-red-500/20 text-red-500`;case`warn`:return`bg-yellow-500/20 text-yellow-600`;case`info`:return`bg-blue-500/20 text-blue-500`;case`debug`:return`bg-purple-500/20 text-purple-500`;default:return`bg-muted text-muted-foreground`}},_e=n?.elementInfo?.computedStyles?.typography,ve=[{id:`code`,label:`Code`,selectedCount:r.includeElement?1:0},{id:`styles`,label:`Styles`,selectedCount:r.includeStyles?1:0},{id:`page`,label:`Page`,selectedCount:r.includePageInfo?1:0},{id:`screenshot`,label:`Visual`,selectedCount:r.includeScreenshot?1:0},{id:`console`,label:`Console`,totalCount:w.length,selectedCount:r.consoleIds.length},{id:`network`,label:`Network`,totalCount:T.length,selectedCount:r.networkIds.length},{id:`stdio`,label:`Terminal`,totalCount:E.length,selectedCount:r.stdioIds.length}];return(0,M.jsxs)(`div`,{className:`border border-border rounded-md overflow-hidden`,children:[(0,M.jsxs)(`div`,{className:`w-full flex items-center justify-between px-3 py-2 text-sm bg-muted/30 border-b border-border`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-2 text-muted-foreground font-medium`,children:[(0,M.jsx)(`span`,{children:`Context`}),A>0&&(0,M.jsx)(`span`,{className:`px-1.5 py-0.5 text-xs bg-primary text-primary-foreground rounded-full`,children:A})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,M.jsxs)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),he()},disabled:D||me,className:N(`flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded transition-colors border shadow-sm`,me?`bg-blue-100 text-blue-700 border-blue-200`:`bg-blue-50 text-blue-600 border-blue-200 hover:bg-blue-100 hover:text-blue-700 hover:border-blue-300`),title:`Let AI analyze logs and network to select relevant context`,children:[(0,M.jsx)(xn,{className:N(`w-3.5 h-3.5`,me&&`animate-pulse`)}),(0,M.jsx)(`span`,{children:me?`Analyzing...`:`Smart Select`})]}),(0,M.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),k()},disabled:D,className:`p-1 hover:bg-accent rounded transition-colors`,title:`Refresh`,children:(0,M.jsx)(yn,{className:N(`w-3.5 h-3.5`,D&&`animate-spin`)})})]})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`flex gap-1 border-b border-border px-2 pt-1`,children:ve.map(e=>(0,M.jsx)(O$,{tab:e,isActive:u===e.id,onClick:()=>d(e.id)},e.id))}),(0,M.jsxs)(`div`,{className:`max-h-[200px] overflow-auto relative ${me?`min-h-[150px]`:``}`,children:[me&&(()=>{let e=ue[ue.length-1],t=e?.role===`assistant`?Bh(e):``,n=e?.role===`assistant`?Uh(e):null;return(0,M.jsxs)(`div`,{className:`absolute inset-0 z-10 bg-background/95 backdrop-blur-sm flex flex-col items-center justify-center p-4 min-h-[120px]`,children:[(0,M.jsx)(xn,{className:`w-6 h-6 text-blue-500 animate-pulse mb-3`}),(0,M.jsx)(`span`,{className:`text-sm font-medium text-foreground text-center max-w-full truncate px-2`,children:n?`Running: ${w$(n)}`:`Analyzing context...`}),t&&(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground leading-relaxed text-center mt-2 line-clamp-2 max-w-[280px]`,children:t})]})})(),O&&(u===`console`||u===`network`)&&(0,M.jsx)(`div`,{className:`p-2 text-xs text-destructive`,children:O}),r.reasoning&&!me&&(0,M.jsx)(`div`,{className:`bg-blue-50/50 p-2 border-b border-border`,children:(0,M.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,M.jsx)(xn,{className:`w-3.5 h-3.5 text-blue-500 mt-0.5 flex-shrink-0`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground leading-relaxed italic`,children:r.reasoning})]})}),u===`code`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:(()=>{let e=n?.relatedElements&&n.relatedElements.length>0?n.relatedElements:n?[n]:[],t=n?.relatedElements&&n.relatedElements.length>0,a=e.reduce((e,t,n)=>{let r=t.file||`unknown`;return e[r]||(e[r]=[]),e[r].push({el:t,idx:n}),e},{});return(0,M.jsxs)(`div`,{children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-1.5 px-2 mb-2`,children:[(0,M.jsx)(cn,{className:t?`w-3.5 h-3.5 text-muted-foreground`:`w-4 h-4 text-blue-500`}),(0,M.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:t?`Related Elements`:`Source Location`}),t&&(0,M.jsx)(`span`,{className:`ml-auto px-1.5 py-0.5 text-[10px] bg-muted text-muted-foreground rounded-full`,children:e.length})]}),(0,M.jsx)(`div`,{className:`space-y-2 max-h-60 overflow-y-auto`,children:Object.entries(a).map(([e,n])=>(0,M.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,M.jsxs)(`div`,{className:`px-2 py-1 text-[11px] font-medium text-muted-foreground/70 bg-muted/30 rounded sticky top-0`,children:[e,` (`,n.length,`)`]}),n.map(({el:e,idx:n})=>(0,M.jsxs)(`div`,{className:`group relative`,children:[(0,M.jsxs)(`label`,{className:`flex items-start gap-2 pl-4 pr-8 py-1.5 rounded hover:bg-accent/50 cursor-pointer transition-colors relative`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:t?r.relatedElementIds.includes(n):r.includeElement,onChange:()=>t?le(n):j(),className:`mt-0.5 rounded border-border`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0 text-xs font-mono`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,M.jsx)(`span`,{className:`text-foreground/80 font-medium`,children:e.component}),(0,M.jsx)(`span`,{className:`text-muted-foreground/50`,children:`•`}),(0,M.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.line,`:`,e.column]})]}),e.elementInfo&&(0,M.jsxs)(`div`,{className:`text-[10px] text-muted-foreground/60 mt-0.5 space-x-2`,children:[e.elementInfo.className&&(0,M.jsxs)(`span`,{children:[`.`,e.elementInfo.className.split(` `)[0]]}),e.elementInfo.id&&(0,M.jsxs)(`span`,{children:[`#`,e.elementInfo.id]}),e.elementInfo.textContent&&(0,M.jsxs)(`span`,{className:`italic`,children:[`"`,e.elementInfo.textContent.trim().slice(0,20),e.elementInfo.textContent.length>20?`...`:``,`"`]})]}),r.elementNotes[n]&&(0,M.jsxs)(`div`,{className:`mt-1.5 text-[11px] text-yellow-600 dark:text-yellow-500 bg-yellow-50 dark:bg-yellow-900/20 px-1.5 py-0.5 rounded border border-yellow-200 dark:border-yellow-900/40 flex items-start gap-1`,children:[(0,M.jsx)(gn,{className:`w-3 h-3 mt-0.5 flex-shrink-0`}),(0,M.jsx)(`span`,{className:`break-words`,children:r.elementNotes[n]})]})]})]}),(0,M.jsx)(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),S(n)},className:N(`absolute right-1 top-1.5 p-1 rounded transition-colors`,r.elementNotes[n]?`text-yellow-600 hover:bg-yellow-100 opacity-100`:`text-muted-foreground/40 hover:text-foreground hover:bg-accent opacity-0 group-hover:opacity-100`),title:`Add note to element`,children:(0,M.jsx)(gn,{className:`w-3.5 h-3.5`})}),x===n&&(0,M.jsx)(`div`,{className:`px-4 py-2 bg-muted/30 border-t border-b border-border`,children:(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`input`,{type:`text`,autoFocus:!0,placeholder:`Describe issue with this element...`,className:`flex-1 text-xs bg-background border border-input rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-primary`,defaultValue:r.elementNotes[n]||``,onKeyDown:e=>{if(e.key===`Enter`){e.preventDefault();let t=e.currentTarget.value.trim();i(e=>{let r={...e.elementNotes};return t?r[n]=t:delete r[n],{...e,elementNotes:r}}),S(null)}else e.key===`Escape`&&S(null)},onBlur:e=>{let t=e.currentTarget.value.trim();t!==(r.elementNotes[n]||``)&&i(e=>{let r={...e.elementNotes};return t?r[n]=t:delete r[n],{...e,elementNotes:r}}),S(null)}}),(0,M.jsx)(`button`,{onClick:()=>S(null),className:`text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]})})]},n))]},e))})]})})()}),u===`styles`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includeStyles,onChange:ie,className:`mt-0.5 rounded border-border`}),(0,M.jsx)(En,{className:`w-4 h-4 text-purple-500 flex-shrink-0`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:`Computed Styles`}),_e&&(0,M.jsxs)(`div`,{className:`text-xs text-muted-foreground space-y-0.5 mt-1`,children:[(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Font:`}),(0,M.jsx)(`span`,{className:`font-mono truncate`,children:_e.fontFamily})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Size:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.fontSize}),(0,M.jsx)(`span`,{className:`text-muted-foreground/70 ml-2`,children:`Weight:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.fontWeight})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Color:`}),(0,M.jsxs)(`span`,{className:`font-mono flex items-center gap-1`,children:[(0,M.jsx)(`span`,{className:`inline-block w-3 h-3 rounded border border-border`,style:{backgroundColor:_e.color}}),_e.color]})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Line Height:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.lineHeight})]})]}),!_e&&(0,M.jsx)(`div`,{className:`text-xs text-muted-foreground/50 italic`,children:`No style data available`})]})]})}),u===`screenshot`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:a?(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includeScreenshot,onChange:ae,className:`mt-0.5 rounded border-border`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground mb-1`,children:`Element Visual`}),(0,M.jsx)(`div`,{className:`text-[10px] text-muted-foreground/70 mb-2`,children:`Note: Copy & Go only copies text (IDEs don't support mixed text/image paste). To include the image, please right-click and copy it manually.`}),(0,M.jsx)(`div`,{className:`rounded border border-border overflow-hidden bg-muted/30`,children:(0,M.jsx)(`img`,{src:a,alt:`Element Visual`,className:`w-full h-auto max-h-[150px] object-contain`})})]})]}):(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`No visual available`})}),u===`page`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:C?(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includePageInfo,onChange:oe,className:`mt-0.5 rounded border-border`}),(0,M.jsx)(dn,{className:`w-4 h-4 text-green-500 flex-shrink-0`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground mb-1`,children:`Page Information`}),(0,M.jsxs)(`div`,{className:`text-xs text-muted-foreground space-y-1`,children:[(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`URL:`}),(0,M.jsx)(`span`,{className:`font-mono truncate`,children:C.url})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Title:`}),(0,M.jsx)(`span`,{className:`truncate`,children:C.title})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Viewport:`}),(0,M.jsxs)(`span`,{className:`font-mono`,children:[C.viewport.width,` × `,C.viewport.height]})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Language:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:C.language})]})]})]})]}):(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`Loading page info...`})}),D&&u!==`code`&&u!==`styles`&&u!==`screenshot`&&u!==`page`&&(0,M.jsx)(`div`,{className:`flex items-center justify-center py-6`,children:(0,M.jsx)(mn,{className:`w-5 h-5 animate-spin text-muted-foreground`})}),!D&&u===`console`&&(0,M.jsxs)(`div`,{className:`p-2 space-y-1`,children:[(0,M.jsxs)(`div`,{className:`relative mb-2`,children:[(0,M.jsx)(bn,{className:`absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground`}),(0,M.jsx)(`input`,{type:`text`,value:m,onChange:e=>h(e.target.value),placeholder:`Filter logs...`,className:`w-full pl-7 pr-7 py-1.5 text-xs rounded border border-border bg-background focus:outline-none focus:ring-1 focus:ring-ring`}),m&&(0,M.jsx)(`button`,{type:`button`,onClick:()=>h(``),className:`absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]}),ee.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:m?`No matching logs`:`No console logs`}):ee.map(e=>(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.consoleIds.includes(e.msgid),onChange:()=>se(e.msgid),className:`mt-0.5 rounded border-border`}),(0,M.jsx)(`span`,{className:N(`px-1.5 py-0.5 text-[10px] font-medium rounded flex-shrink-0`,ge(e.level)),children:e.level}),(0,M.jsx)(`span`,{className:`text-xs text-foreground/90 flex-1 font-mono break-all line-clamp-2`,children:e.text})]},e.msgid))]}),!D&&u===`network`&&(0,M.jsxs)(`div`,{className:`p-2 space-y-1`,children:[(0,M.jsxs)(`div`,{className:`relative mb-2`,children:[(0,M.jsx)(bn,{className:`absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground`}),(0,M.jsx)(`input`,{type:`text`,value:_,onChange:e=>v(e.target.value),placeholder:`Filter requests...`,className:`w-full pl-7 pr-7 py-1.5 text-xs rounded border border-border bg-background focus:outline-none focus:ring-1 focus:ring-ring`}),_&&(0,M.jsx)(`button`,{type:`button`,onClick:()=>v(``),className:`absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]}),te.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:_?`No matching requests`:`No network requests`}):te.map(n=>(0,M.jsx)(ra,{request:n,client:e,isClientReady:t,mode:`select`,isSelected:r.networkIds.includes(n.reqid),onSelectionChange:re,onDetailsFetched:ne,cachedDetails:y[n.reqid]},n.reqid))]}),!D&&u===`stdio`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:E.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`No terminal logs`}):E.map(e=>(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.stdioIds.includes(e.stdioid),onChange:()=>ce(e.stdioid),className:`mt-0.5 rounded border-border`}),(0,M.jsx)(`span`,{className:N(`px-1.5 py-0.5 text-[10px] font-medium rounded flex-shrink-0 border`,e.stream===`stderr`?`bg-red-500/10 text-red-500 border-red-500/20`:`bg-zinc-500/10 text-zinc-500 border-zinc-500/20`),children:e.stream}),(0,M.jsx)(`span`,{className:`text-xs text-foreground/90 flex-1 font-mono break-all whitespace-pre-wrap`,children:e.data})]},e.stdioid))})]})]})]})};function A$(e){if(!e)return``;let{tagName:t,textContent:n,className:r,id:i,domPath:a,boundingBox:o}=e,s=`### DOM Element
|
|
355
|
+
`,o=f.find(e=>e.name===c)||f[0];await fe({text:a},{body:{agent:o,envVars:{},inferContext:!0,isAutomated:!0}})},ge=e=>{switch(e){case`error`:return`bg-red-500/20 text-red-500`;case`warn`:return`bg-yellow-500/20 text-yellow-600`;case`info`:return`bg-blue-500/20 text-blue-500`;case`debug`:return`bg-purple-500/20 text-purple-500`;default:return`bg-muted text-muted-foreground`}},_e=n?.elementInfo?.computedStyles?.typography,ve=[{id:`code`,label:`Code`,selectedCount:r.includeElement?1:0},{id:`styles`,label:`Styles`,selectedCount:r.includeStyles?1:0},{id:`page`,label:`Page`,selectedCount:r.includePageInfo?1:0},{id:`screenshot`,label:`Visual`,selectedCount:r.includeScreenshot?1:0},{id:`console`,label:`Console`,totalCount:w.length,selectedCount:r.consoleIds.length},{id:`network`,label:`Network`,totalCount:T.length,selectedCount:r.networkIds.length},{id:`stdio`,label:`Terminal`,totalCount:E.length,selectedCount:r.stdioIds.length}];return(0,M.jsxs)(`div`,{className:`border border-border rounded-md overflow-hidden`,children:[(0,M.jsxs)(`div`,{className:`w-full flex items-center justify-between px-3 py-2 text-sm bg-muted/30 border-b border-border`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-2 text-muted-foreground font-medium`,children:[(0,M.jsx)(`span`,{children:`Context`}),A>0&&(0,M.jsx)(`span`,{className:`px-1.5 py-0.5 text-xs bg-primary text-primary-foreground rounded-full`,children:A})]}),(0,M.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,M.jsxs)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),he()},disabled:D||me,className:N(`flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded transition-colors border shadow-sm`,me?`bg-blue-100 text-blue-700 border-blue-200`:`bg-blue-50 text-blue-600 border-blue-200 hover:bg-blue-100 hover:text-blue-700 hover:border-blue-300`),title:`Let AI analyze logs and network to select relevant context`,children:[(0,M.jsx)(xn,{className:N(`w-3.5 h-3.5`,me&&`animate-pulse`)}),(0,M.jsx)(`span`,{children:me?`Analyzing...`:`Smart Select`})]}),(0,M.jsx)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),k()},disabled:D,className:`p-1 hover:bg-accent rounded transition-colors`,title:`Refresh`,children:(0,M.jsx)(yn,{className:N(`w-3.5 h-3.5`,D&&`animate-spin`)})})]})]}),(0,M.jsxs)(`div`,{children:[(0,M.jsx)(`div`,{className:`flex gap-1 border-b border-border px-2 pt-1`,children:ve.map(e=>(0,M.jsx)(O$,{tab:e,isActive:u===e.id,onClick:()=>d(e.id)},e.id))}),(0,M.jsxs)(`div`,{className:`max-h-[200px] overflow-auto relative ${me?`min-h-[150px]`:``}`,children:[me&&(()=>{let e=ue[ue.length-1],t=e?.role===`assistant`?Bh(e):``,n=e?.role===`assistant`?Uh(e):null;return(0,M.jsxs)(`div`,{className:`absolute inset-0 z-10 bg-background/95 backdrop-blur-sm flex flex-col items-center justify-center p-4 min-h-[120px]`,children:[(0,M.jsx)(xn,{className:`w-6 h-6 text-blue-500 animate-pulse mb-3`}),(0,M.jsx)(`span`,{className:`text-sm font-medium text-foreground text-center max-w-full truncate px-2`,children:n?`Running: ${w$(n)}`:`Analyzing context...`}),t&&(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground leading-relaxed text-center mt-2 line-clamp-2 max-w-[280px]`,children:t})]})})(),O&&(u===`console`||u===`network`)&&(0,M.jsx)(`div`,{className:`p-2 text-xs text-destructive`,children:O}),r.reasoning&&!me&&(0,M.jsx)(`div`,{className:`bg-blue-50/50 p-2 border-b border-border`,children:(0,M.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,M.jsx)(xn,{className:`w-3.5 h-3.5 text-blue-500 mt-0.5 flex-shrink-0`}),(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground leading-relaxed italic`,children:r.reasoning})]})}),u===`code`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:(()=>{let e=n?.relatedElements&&n.relatedElements.length>0?n.relatedElements:n?[n]:[],t=n?.relatedElements&&n.relatedElements.length>0,a=e.reduce((e,t,n)=>{let r=t.file||`unknown`;return e[r]||(e[r]=[]),e[r].push({el:t,idx:n}),e},{});return(0,M.jsxs)(`div`,{children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-1.5 px-2 mb-2`,children:[(0,M.jsx)(cn,{className:t?`w-3.5 h-3.5 text-muted-foreground`:`w-4 h-4 text-blue-500`}),(0,M.jsx)(`div`,{className:`text-xs font-medium text-muted-foreground`,children:t?`Related Elements`:`Source Location`}),t&&(0,M.jsx)(`span`,{className:`ml-auto px-1.5 py-0.5 text-[10px] bg-muted text-muted-foreground rounded-full`,children:e.length})]}),(0,M.jsx)(`div`,{className:`space-y-2 max-h-60 overflow-y-auto`,children:Object.entries(a).map(([e,n])=>(0,M.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,M.jsxs)(`div`,{className:`px-2 py-1 text-[11px] font-medium text-muted-foreground/70 bg-muted/30 rounded sticky top-0`,children:[e,` (`,n.length,`)`]}),n.map(({el:e,idx:n})=>(0,M.jsxs)(`div`,{className:`group relative`,children:[(0,M.jsxs)(`label`,{className:`flex items-start gap-2 pl-4 pr-8 py-1.5 rounded hover:bg-accent/50 cursor-pointer transition-colors relative`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:t?r.relatedElementIds.includes(n):r.includeElement,onChange:()=>t?le(n):j(),className:`mt-0.5 rounded border-border`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0 text-xs font-mono`,children:[(0,M.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,M.jsx)(`span`,{className:`text-foreground/80 font-medium`,children:e.component}),(0,M.jsx)(`span`,{className:`text-muted-foreground/50`,children:`•`}),(0,M.jsxs)(`span`,{className:`text-muted-foreground`,children:[e.line,`:`,e.column]})]}),e.elementInfo&&(0,M.jsxs)(`div`,{className:`text-[10px] text-muted-foreground/60 mt-0.5 space-x-2`,children:[typeof e.elementInfo.className==`string`&&e.elementInfo.className&&(0,M.jsxs)(`span`,{children:[`.`,e.elementInfo.className.split(` `)[0]]}),e.elementInfo.id&&(0,M.jsxs)(`span`,{children:[`#`,e.elementInfo.id]}),e.elementInfo.textContent&&(0,M.jsxs)(`span`,{className:`italic`,children:[`"`,e.elementInfo.textContent.trim().slice(0,20),e.elementInfo.textContent.length>20?`...`:``,`"`]})]}),r.elementNotes[n]&&(0,M.jsxs)(`div`,{className:`mt-1.5 text-[11px] text-yellow-600 dark:text-yellow-500 bg-yellow-50 dark:bg-yellow-900/20 px-1.5 py-0.5 rounded border border-yellow-200 dark:border-yellow-900/40 flex items-start gap-1`,children:[(0,M.jsx)(gn,{className:`w-3 h-3 mt-0.5 flex-shrink-0`}),(0,M.jsx)(`span`,{className:`break-words`,children:r.elementNotes[n]})]})]})]}),(0,M.jsx)(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),S(n)},className:N(`absolute right-1 top-1.5 p-1 rounded transition-colors`,r.elementNotes[n]?`text-yellow-600 hover:bg-yellow-100 opacity-100`:`text-muted-foreground/40 hover:text-foreground hover:bg-accent opacity-0 group-hover:opacity-100`),title:`Add note to element`,children:(0,M.jsx)(gn,{className:`w-3.5 h-3.5`})}),x===n&&(0,M.jsx)(`div`,{className:`px-4 py-2 bg-muted/30 border-t border-b border-border`,children:(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`input`,{type:`text`,autoFocus:!0,placeholder:`Describe issue with this element...`,className:`flex-1 text-xs bg-background border border-input rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-primary`,defaultValue:r.elementNotes[n]||``,onKeyDown:e=>{if(e.key===`Enter`){e.preventDefault();let t=e.currentTarget.value.trim();i(e=>{let r={...e.elementNotes};return t?r[n]=t:delete r[n],{...e,elementNotes:r}}),S(null)}else e.key===`Escape`&&S(null)},onBlur:e=>{let t=e.currentTarget.value.trim();t!==(r.elementNotes[n]||``)&&i(e=>{let r={...e.elementNotes};return t?r[n]=t:delete r[n],{...e,elementNotes:r}}),S(null)}}),(0,M.jsx)(`button`,{onClick:()=>S(null),className:`text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]})})]},n))]},e))})]})})()}),u===`styles`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includeStyles,onChange:ie,className:`mt-0.5 rounded border-border`}),(0,M.jsx)(En,{className:`w-4 h-4 text-purple-500 flex-shrink-0`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground`,children:`Computed Styles`}),_e&&(0,M.jsxs)(`div`,{className:`text-xs text-muted-foreground space-y-0.5 mt-1`,children:[(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Font:`}),(0,M.jsx)(`span`,{className:`font-mono truncate`,children:_e.fontFamily})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Size:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.fontSize}),(0,M.jsx)(`span`,{className:`text-muted-foreground/70 ml-2`,children:`Weight:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.fontWeight})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Color:`}),(0,M.jsxs)(`span`,{className:`font-mono flex items-center gap-1`,children:[(0,M.jsx)(`span`,{className:`inline-block w-3 h-3 rounded border border-border`,style:{backgroundColor:_e.color}}),_e.color]})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Line Height:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:_e.lineHeight})]})]}),!_e&&(0,M.jsx)(`div`,{className:`text-xs text-muted-foreground/50 italic`,children:`No style data available`})]})]})}),u===`screenshot`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:a?(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includeScreenshot,onChange:ae,className:`mt-0.5 rounded border-border`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground mb-1`,children:`Element Visual`}),(0,M.jsx)(`div`,{className:`text-[10px] text-muted-foreground/70 mb-2`,children:`Note: Copy & Go only copies text (IDEs don't support mixed text/image paste). To include the image, please right-click and copy it manually.`}),(0,M.jsx)(`div`,{className:`rounded border border-border overflow-hidden bg-muted/30`,children:(0,M.jsx)(`img`,{src:a,alt:`Element Visual`,className:`w-full h-auto max-h-[150px] object-contain`})})]})]}):(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`No visual available`})}),u===`page`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:C?(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.includePageInfo,onChange:oe,className:`mt-0.5 rounded border-border`}),(0,M.jsx)(dn,{className:`w-4 h-4 text-green-500 flex-shrink-0`}),(0,M.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,M.jsx)(`div`,{className:`text-xs font-medium text-foreground mb-1`,children:`Page Information`}),(0,M.jsxs)(`div`,{className:`text-xs text-muted-foreground space-y-1`,children:[(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`URL:`}),(0,M.jsx)(`span`,{className:`font-mono truncate`,children:C.url})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Title:`}),(0,M.jsx)(`span`,{className:`truncate`,children:C.title})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Viewport:`}),(0,M.jsxs)(`span`,{className:`font-mono`,children:[C.viewport.width,` × `,C.viewport.height]})]}),(0,M.jsxs)(`div`,{className:`flex gap-2`,children:[(0,M.jsx)(`span`,{className:`text-muted-foreground/70`,children:`Language:`}),(0,M.jsx)(`span`,{className:`font-mono`,children:C.language})]})]})]})]}):(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`Loading page info...`})}),D&&u!==`code`&&u!==`styles`&&u!==`screenshot`&&u!==`page`&&(0,M.jsx)(`div`,{className:`flex items-center justify-center py-6`,children:(0,M.jsx)(mn,{className:`w-5 h-5 animate-spin text-muted-foreground`})}),!D&&u===`console`&&(0,M.jsxs)(`div`,{className:`p-2 space-y-1`,children:[(0,M.jsxs)(`div`,{className:`relative mb-2`,children:[(0,M.jsx)(bn,{className:`absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground`}),(0,M.jsx)(`input`,{type:`text`,value:m,onChange:e=>h(e.target.value),placeholder:`Filter logs...`,className:`w-full pl-7 pr-7 py-1.5 text-xs rounded border border-border bg-background focus:outline-none focus:ring-1 focus:ring-ring`}),m&&(0,M.jsx)(`button`,{type:`button`,onClick:()=>h(``),className:`absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]}),ee.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:m?`No matching logs`:`No console logs`}):ee.map(e=>(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.consoleIds.includes(e.msgid),onChange:()=>se(e.msgid),className:`mt-0.5 rounded border-border`}),(0,M.jsx)(`span`,{className:N(`px-1.5 py-0.5 text-[10px] font-medium rounded flex-shrink-0`,ge(e.level)),children:e.level}),(0,M.jsx)(`span`,{className:`text-xs text-foreground/90 flex-1 font-mono break-all line-clamp-2`,children:e.text})]},e.msgid))]}),!D&&u===`network`&&(0,M.jsxs)(`div`,{className:`p-2 space-y-1`,children:[(0,M.jsxs)(`div`,{className:`relative mb-2`,children:[(0,M.jsx)(bn,{className:`absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground`}),(0,M.jsx)(`input`,{type:`text`,value:_,onChange:e=>v(e.target.value),placeholder:`Filter requests...`,className:`w-full pl-7 pr-7 py-1.5 text-xs rounded border border-border bg-background focus:outline-none focus:ring-1 focus:ring-ring`}),_&&(0,M.jsx)(`button`,{type:`button`,onClick:()=>v(``),className:`absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground`,children:(0,M.jsx)(On,{className:`w-3.5 h-3.5`})})]}),te.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:_?`No matching requests`:`No network requests`}):te.map(n=>(0,M.jsx)(ra,{request:n,client:e,isClientReady:t,mode:`select`,isSelected:r.networkIds.includes(n.reqid),onSelectionChange:re,onDetailsFetched:ne,cachedDetails:y[n.reqid]},n.reqid))]}),!D&&u===`stdio`&&(0,M.jsx)(`div`,{className:`p-2 space-y-1`,children:E.length===0?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground text-center py-4`,children:`No terminal logs`}):E.map(e=>(0,M.jsxs)(`label`,{className:`flex items-start gap-2 p-2 rounded hover:bg-accent/50 cursor-pointer transition-colors`,children:[(0,M.jsx)(`input`,{type:`checkbox`,checked:r.stdioIds.includes(e.stdioid),onChange:()=>ce(e.stdioid),className:`mt-0.5 rounded border-border`}),(0,M.jsx)(`span`,{className:N(`px-1.5 py-0.5 text-[10px] font-medium rounded flex-shrink-0 border`,e.stream===`stderr`?`bg-red-500/10 text-red-500 border-red-500/20`:`bg-zinc-500/10 text-zinc-500 border-zinc-500/20`),children:e.stream}),(0,M.jsx)(`span`,{className:`text-xs text-foreground/90 flex-1 font-mono break-all whitespace-pre-wrap`,children:e.data})]},e.stdioid))})]})]})]})};function A$(e){if(!e)return``;let{tagName:t,textContent:n,className:r,id:i,domPath:a,boundingBox:o}=e,s=`### DOM Element
|
|
356
356
|
\`\`\`
|
|
357
357
|
Tag: <${t}${i?` id="${i}"`:``}${r?` class="${r}"`:``}>
|
|
358
358
|
Text: ${n||`(empty)`}
|
package/dist/cli.cjs
CHANGED
|
@@ -412,6 +412,49 @@ function transformConfig(options) {
|
|
|
412
412
|
};
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Transform entry file to add DevInspector import
|
|
417
|
+
*/
|
|
418
|
+
function transformEntryFile(options) {
|
|
419
|
+
const { entryPath } = options;
|
|
420
|
+
try {
|
|
421
|
+
const code = (0, fs.readFileSync)(entryPath, "utf-8");
|
|
422
|
+
if (code.includes("virtual:dev-inspector-mcp")) return {
|
|
423
|
+
success: true,
|
|
424
|
+
modified: false,
|
|
425
|
+
message: "DevInspector is already imported in this file"
|
|
426
|
+
};
|
|
427
|
+
const s = new magic_string.default(code);
|
|
428
|
+
const ast = (0, _babel_parser.parse)(code, {
|
|
429
|
+
sourceType: "module",
|
|
430
|
+
plugins: ["typescript", "jsx"]
|
|
431
|
+
});
|
|
432
|
+
let lastImportEnd = 0;
|
|
433
|
+
traverse(ast, { ImportDeclaration(path$1) {
|
|
434
|
+
if (path$1.node.loc) lastImportEnd = Math.max(lastImportEnd, path$1.node.loc.end.line);
|
|
435
|
+
} });
|
|
436
|
+
const lines = code.split("\n");
|
|
437
|
+
const importLine = "import 'virtual:dev-inspector-mcp';\n";
|
|
438
|
+
if (lastImportEnd > 0) {
|
|
439
|
+
let insertPos = 0;
|
|
440
|
+
for (let i = 0; i < lastImportEnd; i++) insertPos += lines[i].length + 1;
|
|
441
|
+
s.appendLeft(insertPos, importLine);
|
|
442
|
+
} else s.prepend(importLine);
|
|
443
|
+
return {
|
|
444
|
+
success: true,
|
|
445
|
+
modified: true,
|
|
446
|
+
code: s.toString(),
|
|
447
|
+
message: "Successfully added DevInspector import to entry file"
|
|
448
|
+
};
|
|
449
|
+
} catch (error) {
|
|
450
|
+
return {
|
|
451
|
+
success: false,
|
|
452
|
+
modified: false,
|
|
453
|
+
error: error instanceof Error ? error.message : String(error),
|
|
454
|
+
message: "Failed to transform entry file"
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
}
|
|
415
458
|
|
|
416
459
|
//#endregion
|
|
417
460
|
//#region src/utils/package-manager.ts
|
|
@@ -474,10 +517,14 @@ async function runSetupCommand() {
|
|
|
474
517
|
let dryRun = false;
|
|
475
518
|
let configPath;
|
|
476
519
|
let bundlerType;
|
|
520
|
+
let entryPath;
|
|
477
521
|
for (let i = 0; i < args.length; i++) if (args[i] === "--dry-run") dryRun = true;
|
|
478
522
|
else if (args[i] === "--config" && args[i + 1]) {
|
|
479
523
|
configPath = args[i + 1];
|
|
480
524
|
i++;
|
|
525
|
+
} else if (args[i] === "--entry" && args[i + 1]) {
|
|
526
|
+
entryPath = args[i + 1];
|
|
527
|
+
i++;
|
|
481
528
|
} else if (args[i] === "--bundler" && args[i + 1]) {
|
|
482
529
|
bundlerType = args[i + 1];
|
|
483
530
|
i++;
|
|
@@ -485,10 +532,6 @@ async function runSetupCommand() {
|
|
|
485
532
|
console.log(`
|
|
486
533
|
╔══════════════════════════════════════════════════════════╗
|
|
487
534
|
║ 🔧 DevInspector Setup Command ║
|
|
488
|
-
╠══════════════════════════════════════════════════════════╣
|
|
489
|
-
║ ║
|
|
490
|
-
║ Automatically add DevInspector to your bundler config ║
|
|
491
|
-
║ ║
|
|
492
535
|
╚══════════════════════════════════════════════════════════╝
|
|
493
536
|
|
|
494
537
|
Usage:
|
|
@@ -496,6 +539,7 @@ Usage:
|
|
|
496
539
|
|
|
497
540
|
Options:
|
|
498
541
|
--config <path> Specify config file path (auto-detect by default)
|
|
542
|
+
--entry <path> Specify entry file path to add import (optional)
|
|
499
543
|
--bundler <type> Specify bundler type: vite, webpack, nextjs
|
|
500
544
|
--dry-run Preview changes without applying them
|
|
501
545
|
--help, -h Show this help message
|
|
@@ -504,14 +548,11 @@ Examples:
|
|
|
504
548
|
# Auto-detect and setup
|
|
505
549
|
npx @mcpc-tech/unplugin-dev-inspector-mcp setup
|
|
506
550
|
|
|
551
|
+
# Setup defining entry file (for React Router v7 / non-HTML apps)
|
|
552
|
+
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --entry src/main.tsx
|
|
553
|
+
|
|
507
554
|
# Preview changes without applying
|
|
508
555
|
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --dry-run
|
|
509
|
-
|
|
510
|
-
# Setup specific config
|
|
511
|
-
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --config vite.config.ts
|
|
512
|
-
|
|
513
|
-
# Setup for specific bundler
|
|
514
|
-
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --bundler vite
|
|
515
556
|
`);
|
|
516
557
|
process.exit(0);
|
|
517
558
|
}
|
|
@@ -565,23 +606,48 @@ Examples:
|
|
|
565
606
|
if (result.error) console.error(` Error: ${result.error}`);
|
|
566
607
|
process.exit(1);
|
|
567
608
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
609
|
+
let entryResult;
|
|
610
|
+
if (entryPath) {
|
|
611
|
+
console.log(`\n${dryRun ? "🔍 Previewing" : "🔧 Transforming"} entry file: ${entryPath}...`);
|
|
612
|
+
const { transformEntryFile: transformEntryFile$1 } = await Promise.resolve().then(() => require("./codemod-transformer.cjs"));
|
|
613
|
+
entryResult = transformEntryFile$1({
|
|
614
|
+
entryPath,
|
|
615
|
+
dryRun
|
|
616
|
+
});
|
|
617
|
+
if (!entryResult.success) {
|
|
618
|
+
console.error(`\n❌ ${entryResult.message}`);
|
|
619
|
+
if (entryResult.error) console.error(` Error: ${entryResult.error}`);
|
|
620
|
+
}
|
|
571
621
|
}
|
|
572
622
|
if (dryRun) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
623
|
+
if (result.modified) {
|
|
624
|
+
console.log("\n📄 Preview of config changes:");
|
|
625
|
+
console.log("─".repeat(60));
|
|
626
|
+
console.log(result.code);
|
|
627
|
+
console.log("─".repeat(60));
|
|
628
|
+
} else console.log(`\n✅ Config: ${result.message}`);
|
|
629
|
+
if (entryPath && entryResult) {
|
|
630
|
+
if (entryResult.modified) {
|
|
631
|
+
console.log("\n📄 Preview of entry file changes:");
|
|
632
|
+
console.log("─".repeat(60));
|
|
633
|
+
console.log(entryResult.code);
|
|
634
|
+
console.log("─".repeat(60));
|
|
635
|
+
} else if (entryResult.success) console.log(`\n✅ Entry file: ${entryResult.message}`);
|
|
636
|
+
}
|
|
577
637
|
console.log("\n💡 Run without --dry-run to apply these changes");
|
|
578
638
|
process.exit(0);
|
|
579
639
|
}
|
|
580
|
-
(0, fs.writeFileSync)(targetConfig.path, result.code, "utf-8");
|
|
581
|
-
console.log(`\n✅ ${result.message}`);
|
|
582
640
|
const installed = installPackage("@mcpc-tech/unplugin-dev-inspector-mcp", true);
|
|
641
|
+
if (result.modified) {
|
|
642
|
+
(0, fs.writeFileSync)(targetConfig.path, result.code, "utf-8");
|
|
643
|
+
console.log(`\n✅ ${result.message}`);
|
|
644
|
+
} else console.log(`\n✅ ${result.message}`);
|
|
645
|
+
if (entryPath && entryResult && entryResult.success) if (entryResult.modified) {
|
|
646
|
+
(0, fs.writeFileSync)(entryPath, entryResult.code, "utf-8");
|
|
647
|
+
console.log(`✅ ${entryResult.message}`);
|
|
648
|
+
} else console.log(`✅ ${entryResult.message}`);
|
|
583
649
|
console.log(`\n📝 Next steps:`);
|
|
584
|
-
console.log(` 1. Review the changes in ${targetConfig.path} and package.json`);
|
|
650
|
+
console.log(` 1. Review the changes in ${targetConfig.path}${entryPath ? ` and ${entryPath}` : ""} and package.json`);
|
|
585
651
|
if (!installed) {
|
|
586
652
|
console.log(` 2. Install the package: npm i -D @mcpc-tech/unplugin-dev-inspector-mcp`);
|
|
587
653
|
console.log(` 3. Start your dev server`);
|
|
@@ -682,4 +748,9 @@ main();
|
|
|
682
748
|
|
|
683
749
|
//#endregion
|
|
684
750
|
exports.StandaloneServer = StandaloneServer;
|
|
685
|
-
exports.startStandaloneServer = startStandaloneServer;
|
|
751
|
+
exports.startStandaloneServer = startStandaloneServer;
|
|
752
|
+
exports.transformConfig = transformConfig;
|
|
753
|
+
exports.transformEntryFile = transformEntryFile;
|
|
754
|
+
exports.transformNextConfig = transformNextConfig;
|
|
755
|
+
exports.transformViteConfig = transformViteConfig;
|
|
756
|
+
exports.transformWebpackConfig = transformWebpackConfig;
|
package/dist/cli.js
CHANGED
|
@@ -408,6 +408,49 @@ function transformConfig(options) {
|
|
|
408
408
|
};
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Transform entry file to add DevInspector import
|
|
413
|
+
*/
|
|
414
|
+
function transformEntryFile(options) {
|
|
415
|
+
const { entryPath } = options;
|
|
416
|
+
try {
|
|
417
|
+
const code = readFileSync(entryPath, "utf-8");
|
|
418
|
+
if (code.includes("virtual:dev-inspector-mcp")) return {
|
|
419
|
+
success: true,
|
|
420
|
+
modified: false,
|
|
421
|
+
message: "DevInspector is already imported in this file"
|
|
422
|
+
};
|
|
423
|
+
const s = new MagicString(code);
|
|
424
|
+
const ast = parse(code, {
|
|
425
|
+
sourceType: "module",
|
|
426
|
+
plugins: ["typescript", "jsx"]
|
|
427
|
+
});
|
|
428
|
+
let lastImportEnd = 0;
|
|
429
|
+
traverse(ast, { ImportDeclaration(path$1) {
|
|
430
|
+
if (path$1.node.loc) lastImportEnd = Math.max(lastImportEnd, path$1.node.loc.end.line);
|
|
431
|
+
} });
|
|
432
|
+
const lines = code.split("\n");
|
|
433
|
+
const importLine = "import 'virtual:dev-inspector-mcp';\n";
|
|
434
|
+
if (lastImportEnd > 0) {
|
|
435
|
+
let insertPos = 0;
|
|
436
|
+
for (let i = 0; i < lastImportEnd; i++) insertPos += lines[i].length + 1;
|
|
437
|
+
s.appendLeft(insertPos, importLine);
|
|
438
|
+
} else s.prepend(importLine);
|
|
439
|
+
return {
|
|
440
|
+
success: true,
|
|
441
|
+
modified: true,
|
|
442
|
+
code: s.toString(),
|
|
443
|
+
message: "Successfully added DevInspector import to entry file"
|
|
444
|
+
};
|
|
445
|
+
} catch (error) {
|
|
446
|
+
return {
|
|
447
|
+
success: false,
|
|
448
|
+
modified: false,
|
|
449
|
+
error: error instanceof Error ? error.message : String(error),
|
|
450
|
+
message: "Failed to transform entry file"
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
}
|
|
411
454
|
|
|
412
455
|
//#endregion
|
|
413
456
|
//#region src/utils/package-manager.ts
|
|
@@ -470,10 +513,14 @@ async function runSetupCommand() {
|
|
|
470
513
|
let dryRun = false;
|
|
471
514
|
let configPath;
|
|
472
515
|
let bundlerType;
|
|
516
|
+
let entryPath;
|
|
473
517
|
for (let i = 0; i < args.length; i++) if (args[i] === "--dry-run") dryRun = true;
|
|
474
518
|
else if (args[i] === "--config" && args[i + 1]) {
|
|
475
519
|
configPath = args[i + 1];
|
|
476
520
|
i++;
|
|
521
|
+
} else if (args[i] === "--entry" && args[i + 1]) {
|
|
522
|
+
entryPath = args[i + 1];
|
|
523
|
+
i++;
|
|
477
524
|
} else if (args[i] === "--bundler" && args[i + 1]) {
|
|
478
525
|
bundlerType = args[i + 1];
|
|
479
526
|
i++;
|
|
@@ -481,10 +528,6 @@ async function runSetupCommand() {
|
|
|
481
528
|
console.log(`
|
|
482
529
|
╔══════════════════════════════════════════════════════════╗
|
|
483
530
|
║ 🔧 DevInspector Setup Command ║
|
|
484
|
-
╠══════════════════════════════════════════════════════════╣
|
|
485
|
-
║ ║
|
|
486
|
-
║ Automatically add DevInspector to your bundler config ║
|
|
487
|
-
║ ║
|
|
488
531
|
╚══════════════════════════════════════════════════════════╝
|
|
489
532
|
|
|
490
533
|
Usage:
|
|
@@ -492,6 +535,7 @@ Usage:
|
|
|
492
535
|
|
|
493
536
|
Options:
|
|
494
537
|
--config <path> Specify config file path (auto-detect by default)
|
|
538
|
+
--entry <path> Specify entry file path to add import (optional)
|
|
495
539
|
--bundler <type> Specify bundler type: vite, webpack, nextjs
|
|
496
540
|
--dry-run Preview changes without applying them
|
|
497
541
|
--help, -h Show this help message
|
|
@@ -500,14 +544,11 @@ Examples:
|
|
|
500
544
|
# Auto-detect and setup
|
|
501
545
|
npx @mcpc-tech/unplugin-dev-inspector-mcp setup
|
|
502
546
|
|
|
547
|
+
# Setup defining entry file (for React Router v7 / non-HTML apps)
|
|
548
|
+
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --entry src/main.tsx
|
|
549
|
+
|
|
503
550
|
# Preview changes without applying
|
|
504
551
|
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --dry-run
|
|
505
|
-
|
|
506
|
-
# Setup specific config
|
|
507
|
-
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --config vite.config.ts
|
|
508
|
-
|
|
509
|
-
# Setup for specific bundler
|
|
510
|
-
npx @mcpc-tech/unplugin-dev-inspector-mcp setup --bundler vite
|
|
511
552
|
`);
|
|
512
553
|
process.exit(0);
|
|
513
554
|
}
|
|
@@ -561,23 +602,48 @@ Examples:
|
|
|
561
602
|
if (result.error) console.error(` Error: ${result.error}`);
|
|
562
603
|
process.exit(1);
|
|
563
604
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
605
|
+
let entryResult;
|
|
606
|
+
if (entryPath) {
|
|
607
|
+
console.log(`\n${dryRun ? "🔍 Previewing" : "🔧 Transforming"} entry file: ${entryPath}...`);
|
|
608
|
+
const { transformEntryFile: transformEntryFile$1 } = await import("./codemod-transformer.js");
|
|
609
|
+
entryResult = transformEntryFile$1({
|
|
610
|
+
entryPath,
|
|
611
|
+
dryRun
|
|
612
|
+
});
|
|
613
|
+
if (!entryResult.success) {
|
|
614
|
+
console.error(`\n❌ ${entryResult.message}`);
|
|
615
|
+
if (entryResult.error) console.error(` Error: ${entryResult.error}`);
|
|
616
|
+
}
|
|
567
617
|
}
|
|
568
618
|
if (dryRun) {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
619
|
+
if (result.modified) {
|
|
620
|
+
console.log("\n📄 Preview of config changes:");
|
|
621
|
+
console.log("─".repeat(60));
|
|
622
|
+
console.log(result.code);
|
|
623
|
+
console.log("─".repeat(60));
|
|
624
|
+
} else console.log(`\n✅ Config: ${result.message}`);
|
|
625
|
+
if (entryPath && entryResult) {
|
|
626
|
+
if (entryResult.modified) {
|
|
627
|
+
console.log("\n📄 Preview of entry file changes:");
|
|
628
|
+
console.log("─".repeat(60));
|
|
629
|
+
console.log(entryResult.code);
|
|
630
|
+
console.log("─".repeat(60));
|
|
631
|
+
} else if (entryResult.success) console.log(`\n✅ Entry file: ${entryResult.message}`);
|
|
632
|
+
}
|
|
573
633
|
console.log("\n💡 Run without --dry-run to apply these changes");
|
|
574
634
|
process.exit(0);
|
|
575
635
|
}
|
|
576
|
-
writeFileSync(targetConfig.path, result.code, "utf-8");
|
|
577
|
-
console.log(`\n✅ ${result.message}`);
|
|
578
636
|
const installed = installPackage("@mcpc-tech/unplugin-dev-inspector-mcp", true);
|
|
637
|
+
if (result.modified) {
|
|
638
|
+
writeFileSync(targetConfig.path, result.code, "utf-8");
|
|
639
|
+
console.log(`\n✅ ${result.message}`);
|
|
640
|
+
} else console.log(`\n✅ ${result.message}`);
|
|
641
|
+
if (entryPath && entryResult && entryResult.success) if (entryResult.modified) {
|
|
642
|
+
writeFileSync(entryPath, entryResult.code, "utf-8");
|
|
643
|
+
console.log(`✅ ${entryResult.message}`);
|
|
644
|
+
} else console.log(`✅ ${entryResult.message}`);
|
|
579
645
|
console.log(`\n📝 Next steps:`);
|
|
580
|
-
console.log(` 1. Review the changes in ${targetConfig.path} and package.json`);
|
|
646
|
+
console.log(` 1. Review the changes in ${targetConfig.path}${entryPath ? ` and ${entryPath}` : ""} and package.json`);
|
|
581
647
|
if (!installed) {
|
|
582
648
|
console.log(` 2. Install the package: npm i -D @mcpc-tech/unplugin-dev-inspector-mcp`);
|
|
583
649
|
console.log(` 3. Start your dev server`);
|
|
@@ -677,4 +743,4 @@ Run with --help for more information:
|
|
|
677
743
|
main();
|
|
678
744
|
|
|
679
745
|
//#endregion
|
|
680
|
-
export {
|
|
746
|
+
export { transformWebpackConfig as a, transformViteConfig as i, transformEntryFile as n, StandaloneServer as o, transformNextConfig as r, startStandaloneServer as s, transformConfig as t };
|
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,8 @@ let node_path = require("node:path");
|
|
|
6
6
|
node_path = require_chunk.__toESM(node_path);
|
|
7
7
|
let _modelcontextprotocol_sdk_client_index_js = require("@modelcontextprotocol/sdk/client/index.js");
|
|
8
8
|
let _modelcontextprotocol_sdk_client_sse_js = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
9
|
+
let path = require("path");
|
|
10
|
+
path = require_chunk.__toESM(path);
|
|
9
11
|
let _babel_parser = require("@babel/parser");
|
|
10
12
|
let magic_string = require("magic-string");
|
|
11
13
|
magic_string = require_chunk.__toESM(magic_string);
|
|
@@ -144,9 +146,21 @@ const createDevInspectorPlugin = (name, transformFactory) => {
|
|
|
144
146
|
let resolvedPort = options.port || 5173;
|
|
145
147
|
const transformImpl = transformFactory(options);
|
|
146
148
|
const chromeDisabled = require_config_updater.isChromeDisabled(options.disableChrome);
|
|
149
|
+
const entryOption = process.env.DEV_INSPECTOR_ENTRY || options.entry;
|
|
150
|
+
const resolvedEntry = entryOption ? path.default.resolve(process.cwd(), entryOption) : null;
|
|
147
151
|
const transform = (code, id) => {
|
|
148
152
|
if (!enabled) return null;
|
|
149
153
|
if (viteCommand && viteCommand !== "serve") return null;
|
|
154
|
+
if (resolvedEntry && id === resolvedEntry) {
|
|
155
|
+
const injection = `import '${virtualModuleName}';\n`;
|
|
156
|
+
const result = transformImpl(code, id);
|
|
157
|
+
if (typeof result === "string") return injection + result;
|
|
158
|
+
else if (result && typeof result === "object" && "code" in result) return {
|
|
159
|
+
...result,
|
|
160
|
+
code: injection + result.code
|
|
161
|
+
};
|
|
162
|
+
else return injection + code;
|
|
163
|
+
}
|
|
150
164
|
return transformImpl(code, id);
|
|
151
165
|
};
|
|
152
166
|
const createNoopVirtualModule = () => {
|
|
@@ -169,7 +183,11 @@ export function registerInspectorTool(_tool) {
|
|
|
169
183
|
const host = resolvedHost;
|
|
170
184
|
const port = resolvedPort;
|
|
171
185
|
const showInspectorBar = options.showInspectorBar ?? true;
|
|
172
|
-
const publicBaseUrl =
|
|
186
|
+
const publicBaseUrl = require_config_updater.getPublicBaseUrl({
|
|
187
|
+
publicBaseUrl: options.publicBaseUrl,
|
|
188
|
+
host,
|
|
189
|
+
port
|
|
190
|
+
});
|
|
173
191
|
const injectedBaseUrl = publicBaseUrl ? require_config_updater.stripTrailingSlash(publicBaseUrl) : void 0;
|
|
174
192
|
return `
|
|
175
193
|
// Development-only code - removed in production builds
|
|
@@ -254,7 +272,11 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
|
254
272
|
const port = options.port ?? server?.config.server.port ?? 5173;
|
|
255
273
|
const base = server?.config.base ?? "/";
|
|
256
274
|
const showInspectorBar = options.showInspectorBar ?? true;
|
|
257
|
-
const publicBaseUrl =
|
|
275
|
+
const publicBaseUrl = require_config_updater.getPublicBaseUrl({
|
|
276
|
+
publicBaseUrl: options.publicBaseUrl,
|
|
277
|
+
host,
|
|
278
|
+
port
|
|
279
|
+
});
|
|
258
280
|
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
259
281
|
return html.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script>
|
|
260
282
|
(function() {
|
|
@@ -488,9 +510,9 @@ function transformJSX({ code, id }) {
|
|
|
488
510
|
const s = new magic_string.default(code);
|
|
489
511
|
let hasModifications = false;
|
|
490
512
|
try {
|
|
491
|
-
traverse(ast, { JSXOpeningElement(path$
|
|
513
|
+
traverse(ast, { JSXOpeningElement(path$6) {
|
|
492
514
|
try {
|
|
493
|
-
const node = path$
|
|
515
|
+
const node = path$6.node;
|
|
494
516
|
if (!node.name || isFragment(node.name)) return;
|
|
495
517
|
if (!node.loc?.start || !node.name.end) return;
|
|
496
518
|
if (node.attributes?.some((attr$1) => attr$1.type === "JSXAttribute" && attr$1.name?.type === "JSXIdentifier" && attr$1.name.name === DATA_SOURCE_ATTR$2)) return;
|
package/dist/index.d.cts
CHANGED
|
@@ -174,12 +174,25 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
|
|
|
174
174
|
* @example "http://localhost:5173/dashboard"
|
|
175
175
|
*/
|
|
176
176
|
browserUrl?: string;
|
|
177
|
+
/**
|
|
178
|
+
* Whether to show the inspector bar UI
|
|
179
|
+
* Set to false if you only want to use the editor integration
|
|
180
|
+
* @default true
|
|
181
|
+
*/
|
|
177
182
|
/**
|
|
178
183
|
* Whether to show the inspector bar UI
|
|
179
184
|
* Set to false if you only want to use the editor integration
|
|
180
185
|
* @default true
|
|
181
186
|
*/
|
|
182
187
|
showInspectorBar?: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Entry file to safely inject the inspector import.
|
|
190
|
+
* Useful when `autoInject: false` or when using a framework where HTML injection is insufficient.
|
|
191
|
+
* Can also be set via `DEV_INSPECTOR_ENTRY` environment variable.
|
|
192
|
+
*
|
|
193
|
+
* @example "src/main.tsx"
|
|
194
|
+
*/
|
|
195
|
+
entry?: string;
|
|
183
196
|
}
|
|
184
197
|
//#endregion
|
|
185
198
|
//#region src/core.d.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -174,12 +174,25 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
|
|
|
174
174
|
* @example "http://localhost:5173/dashboard"
|
|
175
175
|
*/
|
|
176
176
|
browserUrl?: string;
|
|
177
|
+
/**
|
|
178
|
+
* Whether to show the inspector bar UI
|
|
179
|
+
* Set to false if you only want to use the editor integration
|
|
180
|
+
* @default true
|
|
181
|
+
*/
|
|
177
182
|
/**
|
|
178
183
|
* Whether to show the inspector bar UI
|
|
179
184
|
* Set to false if you only want to use the editor integration
|
|
180
185
|
* @default true
|
|
181
186
|
*/
|
|
182
187
|
showInspectorBar?: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Entry file to safely inject the inspector import.
|
|
190
|
+
* Useful when `autoInject: false` or when using a framework where HTML injection is insufficient.
|
|
191
|
+
* Can also be set via `DEV_INSPECTOR_ENTRY` environment variable.
|
|
192
|
+
*
|
|
193
|
+
* @example "src/main.tsx"
|
|
194
|
+
*/
|
|
195
|
+
entry?: string;
|
|
183
196
|
}
|
|
184
197
|
//#endregion
|
|
185
198
|
//#region src/core.d.ts
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
5
5
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
6
|
+
import path$1 from "path";
|
|
6
7
|
import { parse } from "@babel/parser";
|
|
7
8
|
import MagicString from "magic-string";
|
|
8
9
|
import { createUnplugin } from "unplugin";
|
|
@@ -140,9 +141,21 @@ const createDevInspectorPlugin = (name, transformFactory) => {
|
|
|
140
141
|
let resolvedPort = options.port || 5173;
|
|
141
142
|
const transformImpl = transformFactory(options);
|
|
142
143
|
const chromeDisabled = isChromeDisabled(options.disableChrome);
|
|
144
|
+
const entryOption = process.env.DEV_INSPECTOR_ENTRY || options.entry;
|
|
145
|
+
const resolvedEntry = entryOption ? path$1.resolve(process.cwd(), entryOption) : null;
|
|
143
146
|
const transform = (code, id) => {
|
|
144
147
|
if (!enabled) return null;
|
|
145
148
|
if (viteCommand && viteCommand !== "serve") return null;
|
|
149
|
+
if (resolvedEntry && id === resolvedEntry) {
|
|
150
|
+
const injection = `import '${virtualModuleName}';\n`;
|
|
151
|
+
const result = transformImpl(code, id);
|
|
152
|
+
if (typeof result === "string") return injection + result;
|
|
153
|
+
else if (result && typeof result === "object" && "code" in result) return {
|
|
154
|
+
...result,
|
|
155
|
+
code: injection + result.code
|
|
156
|
+
};
|
|
157
|
+
else return injection + code;
|
|
158
|
+
}
|
|
146
159
|
return transformImpl(code, id);
|
|
147
160
|
};
|
|
148
161
|
const createNoopVirtualModule = () => {
|
|
@@ -165,7 +178,11 @@ export function registerInspectorTool(_tool) {
|
|
|
165
178
|
const host = resolvedHost;
|
|
166
179
|
const port = resolvedPort;
|
|
167
180
|
const showInspectorBar = options.showInspectorBar ?? true;
|
|
168
|
-
const publicBaseUrl =
|
|
181
|
+
const publicBaseUrl = getPublicBaseUrl({
|
|
182
|
+
publicBaseUrl: options.publicBaseUrl,
|
|
183
|
+
host,
|
|
184
|
+
port
|
|
185
|
+
});
|
|
169
186
|
const injectedBaseUrl = publicBaseUrl ? stripTrailingSlash(publicBaseUrl) : void 0;
|
|
170
187
|
return `
|
|
171
188
|
// Development-only code - removed in production builds
|
|
@@ -250,7 +267,11 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
|
250
267
|
const port = options.port ?? server?.config.server.port ?? 5173;
|
|
251
268
|
const base = server?.config.base ?? "/";
|
|
252
269
|
const showInspectorBar = options.showInspectorBar ?? true;
|
|
253
|
-
const publicBaseUrl =
|
|
270
|
+
const publicBaseUrl = getPublicBaseUrl({
|
|
271
|
+
publicBaseUrl: options.publicBaseUrl,
|
|
272
|
+
host,
|
|
273
|
+
port
|
|
274
|
+
});
|
|
254
275
|
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
255
276
|
return html.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script>
|
|
256
277
|
(function() {
|
|
@@ -484,9 +505,9 @@ function transformJSX({ code, id }) {
|
|
|
484
505
|
const s = new MagicString(code);
|
|
485
506
|
let hasModifications = false;
|
|
486
507
|
try {
|
|
487
|
-
traverse(ast, { JSXOpeningElement(path$
|
|
508
|
+
traverse(ast, { JSXOpeningElement(path$2) {
|
|
488
509
|
try {
|
|
489
|
-
const node = path$
|
|
510
|
+
const node = path$2.node;
|
|
490
511
|
if (!node.name || isFragment(node.name)) return;
|
|
491
512
|
if (!node.loc?.start || !node.name.end) return;
|
|
492
513
|
if (node.attributes?.some((attr$1) => attr$1.type === "JSXAttribute" && attr$1.name?.type === "JSXIdentifier" && attr$1.name.name === DATA_SOURCE_ATTR$2)) return;
|
package/package.json
CHANGED