vite-plugin-ai-annotator 1.16.1 → 1.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,7 @@ export declare class AnnotatorToolbar extends LitElement {
19
19
  private commentPopover;
20
20
  private tooltip;
21
21
  private toastMessage;
22
+ private channelListenerCount;
22
23
  private popoverCleanup;
23
24
  private tooltipCleanup;
24
25
  private toastTimeout;
@@ -73,10 +74,13 @@ export declare class AnnotatorToolbar extends LitElement {
73
74
  private renderCloseIcon;
74
75
  private renderHelpIcon;
75
76
  private renderSendIcon;
77
+ private renderClipboardIcon;
76
78
  private showToast;
77
79
  private showTooltip;
78
80
  private hideTooltip;
79
- private copySessionId;
81
+ private buildFeedbackPrompt;
82
+ private copyFeedbackToClipboard;
83
+ private sendFeedbackToClaude;
80
84
  private renderErrorIcon;
81
85
  private openHelpPage;
82
86
  render(): import("lit-html").TemplateResult<1>;
@@ -7528,6 +7528,7 @@
7528
7528
  this.commentPopover = { visible: false, element: null, comment: "" };
7529
7529
  this.tooltip = { visible: false, text: "", x: 0, y: 0 };
7530
7530
  this.toastMessage = "";
7531
+ this.channelListenerCount = 0;
7531
7532
  this.popoverCleanup = null;
7532
7533
  this.tooltipCleanup = null;
7533
7534
  this.toastTimeout = null;
@@ -7670,6 +7671,9 @@
7670
7671
  const prefix = data.status === "done" ? "\u2713 " : data.status === "error" ? "\u2717 " : data.status === "progress" ? "\u2026 " : "";
7671
7672
  this.showToast(prefix + data.message);
7672
7673
  });
7674
+ this.socket.on("channel:status", (data) => {
7675
+ this.channelListenerCount = typeof data?.listenerCount === "number" ? data.listenerCount : 0;
7676
+ });
7673
7677
  }
7674
7678
  wrapRpcHandler(name, handler) {
7675
7679
  return (async (...args) => {
@@ -8067,16 +8071,18 @@
8067
8071
  return;
8068
8072
  }
8069
8073
  const text = `I have selected ${elements.length} feedback item(s) in the browser (session: ${this.sessionId}). Fetch them via GET ${this.wsEndpoint}/api/sessions/${this.sessionId}/feedback and modify the code accordingly.`;
8070
- if (this.socket?.connected) {
8074
+ const willSend = this.socket?.connected && this.channelListenerCount > 0;
8075
+ if (willSend) {
8071
8076
  this.socket.emit("feedback:submitted", { count: elements.length });
8072
8077
  }
8078
+ const successToast = willSend ? `Sent ${elements.length} element(s) to Claude` : `Copied ${elements.length} element(s)`;
8073
8079
  try {
8074
8080
  await navigator.clipboard.writeText(text);
8075
- this.showToast(`Sent ${elements.length} element(s) to Claude`);
8081
+ this.showToast(successToast);
8076
8082
  this.exitInspectingMode();
8077
8083
  } catch (error) {
8078
- this.showToast(`Sent ${elements.length} element(s) to Claude`);
8079
- this.log("Clipboard copy failed (channel push still sent):", error);
8084
+ this.showToast(willSend ? successToast : "Failed to copy");
8085
+ this.log("Clipboard copy failed:", error);
8080
8086
  this.exitInspectingMode();
8081
8087
  }
8082
8088
  }
@@ -8124,6 +8130,11 @@
8124
8130
  <path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5" />
8125
8131
  </svg>`;
8126
8132
  }
8133
+ renderClipboardIcon() {
8134
+ return x`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
8135
+ <path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9.75a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184" />
8136
+ </svg>`;
8137
+ }
8127
8138
  showToast(message) {
8128
8139
  if (this.toastTimeout) {
8129
8140
  clearTimeout(this.toastTimeout);
@@ -8167,7 +8178,14 @@
8167
8178
  }
8168
8179
  this.tooltip = { visible: false, text: "", x: 0, y: 0 };
8169
8180
  }
8170
- async copySessionId() {
8181
+ // Builds the paste-prompt text that lets a Claude session fetch feedback
8182
+ // via REST. Used by both the Copy button (clipboard) and is conceptually
8183
+ // what the Send button replaces (channel push -> Claude already knows the
8184
+ // session, no text needed).
8185
+ buildFeedbackPrompt() {
8186
+ return `I have feedback in the browser (session: ${this.sessionId}). Fetch them via GET ${this.wsEndpoint}/api/sessions/${this.sessionId}/feedback`;
8187
+ }
8188
+ async copyFeedbackToClipboard() {
8171
8189
  this.exitInspectingMode();
8172
8190
  if (this.demo) {
8173
8191
  this.showToast("Demo mode \u2014 no server");
@@ -8177,18 +8195,36 @@
8177
8195
  this.showToast("No session ID");
8178
8196
  return;
8179
8197
  }
8180
- const text = `I have feedback in the browser (session: ${this.sessionId}). Fetch them via GET ${this.wsEndpoint}/api/sessions/${this.sessionId}/feedback`;
8181
- if (this.socket?.connected) {
8182
- this.socket.emit("feedback:submitted", { count: 0 });
8183
- }
8198
+ const text = this.buildFeedbackPrompt();
8184
8199
  try {
8185
8200
  await navigator.clipboard.writeText(text);
8186
- this.showToast("Sent to Claude");
8201
+ this.showToast("Copied!");
8187
8202
  this.log("Copied to clipboard:", text);
8188
8203
  } catch (error) {
8189
- this.showToast("Sent to Claude");
8190
- this.log("Clipboard copy failed (channel push still sent):", error);
8204
+ this.showToast("Failed to copy");
8205
+ this.log("Failed to copy:", error);
8206
+ }
8207
+ }
8208
+ sendFeedbackToClaude() {
8209
+ this.exitInspectingMode();
8210
+ if (this.demo) {
8211
+ this.showToast("Demo mode \u2014 no server");
8212
+ return;
8213
+ }
8214
+ if (!this.sessionId) {
8215
+ this.showToast("No session ID");
8216
+ return;
8217
+ }
8218
+ if (!this.socket?.connected) {
8219
+ this.showToast("Not connected");
8220
+ return;
8221
+ }
8222
+ if (this.channelListenerCount === 0) {
8223
+ this.showToast("No Claude listening");
8224
+ return;
8191
8225
  }
8226
+ this.socket.emit("feedback:submitted", { count: 0 });
8227
+ this.showToast("Sent to Claude");
8192
8228
  }
8193
8229
  renderErrorIcon() {
8194
8230
  return x`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
@@ -8244,11 +8280,24 @@
8244
8280
 
8245
8281
  <button
8246
8282
  class="toolbar-btn"
8247
- @click=${this.copySessionId}
8248
- @mouseenter=${(e5) => this.showTooltip("Send to Claude", e5.currentTarget)}
8283
+ @click=${this.copyFeedbackToClipboard}
8284
+ @mouseenter=${(e5) => this.showTooltip("Copy prompt for Claude", e5.currentTarget)}
8249
8285
  @mouseleave=${() => this.hideTooltip()}
8250
- aria-label="Send selections to Claude Code"
8251
- title="Send to Claude"
8286
+ aria-label="Copy feedback prompt to clipboard"
8287
+ title="Copy"
8288
+ >
8289
+ ${this.renderClipboardIcon()}
8290
+ </button>
8291
+
8292
+ <button
8293
+ class="toolbar-btn"
8294
+ @click=${this.sendFeedbackToClaude}
8295
+ @mouseenter=${(e5) => this.showTooltip(this.channelListenerCount > 0 ? "Send to Claude" : "No Claude listening \u2014 install the channel plugin", e5.currentTarget)}
8296
+ @mouseleave=${() => this.hideTooltip()}
8297
+ ?disabled=${this.channelListenerCount === 0}
8298
+ aria-label="${this.channelListenerCount > 0 ? "Send selections to Claude Code" : "Send to Claude (no listener connected)"}"
8299
+ aria-disabled="${this.channelListenerCount === 0}"
8300
+ title="${this.channelListenerCount > 0 ? "Send to Claude" : "No Claude listening"}"
8252
8301
  >
8253
8302
  ${this.renderSendIcon()}
8254
8303
  </button>
@@ -8586,6 +8635,9 @@
8586
8635
  __decorateClass([
8587
8636
  r5()
8588
8637
  ], AnnotatorToolbar.prototype, "toastMessage", 2);
8638
+ __decorateClass([
8639
+ r5()
8640
+ ], AnnotatorToolbar.prototype, "channelListenerCount", 2);
8589
8641
  if (!customElements.get("annotator-toolbar")) {
8590
8642
  customElements.define("annotator-toolbar", AnnotatorToolbar);
8591
8643
  }
package/dist/index.cjs CHANGED
@@ -66,7 +66,7 @@ const toolbar = document.createElement('annotator-toolbar');
66
66
  toolbar.setAttribute('ws-endpoint', '${e.replace("http://","ws://").replace("https://","wss://")}');
67
67
  toolbar.setAttribute('verbose', '${i}');
68
68
  document.body.prepend(toolbar);
69
- `;s.send(c+l)}catch(o){console.error("Error reading annotator-toolbar.js:",o),s.status(404).send("File not found")}}),a.get("/health",(t,s)=>{s.json({status:"ok",sessions:n.size})}),a.get("/api/sessions",(t,s)=>{s.json(kn(n))})}function kn(a){return Array.from(a.values()).map(e=>e.session)}function i0(a,e){if(e){let i=a.get(e);return i?{rpc:i.rpc,sessionId:e}:null}if(a.size===1){let i=a.entries().next().value;if(i){let[n,t]=i;return{rpc:t.rpc,sessionId:n}}}return null}var Jb="channels";function i5(a,e,i){a.on("connection",n=>{if(n.handshake.query.role==="channel"){n.join(Jb),e.log(`Channel client connected (sid: ${n.id})`),n.on("channel:notify",c=>{if(!c?.sessionId||typeof c.message!="string")return;let p=i.get(c.sessionId);p&&p.socket.emit("channel:notify",{message:c.message,status:c.status??"info"})}),n.on("disconnect",()=>{e.log(`Channel client disconnected (sid: ${n.id})`)});return}let s=e5(),o={id:s,url:"",title:"",connectedAt:Date.now(),lastActivity:Date.now()},r=Gb(n);i.set(s,{socket:n,rpc:r,session:o}),e.log(`Browser connected: ${s} (total: ${i.size})`),r.handle.getSessions(async()=>kn(i)),r.handle.ping(async()=>"pong"),r.handle.rpcError(c=>{e.error("RPC Error:",c)}),n.emit("connected",{sessionId:s}),n.on("pageContextChanged",c=>{o.url=c.url,o.title=c.title,o.lastActivity=Date.now()}),n.on("feedback:submitted",c=>{let p=typeof c?.count=="number"?c.count:0;o.lastActivity=Date.now(),a.to(Jb).emit("feedback:submitted",{sessionId:s,pageUrl:o.url,pageTitle:o.title,count:p})}),n.on("disconnect",()=>{r.dispose(),i.delete(s),e.log(`Browser disconnected: ${s} (total: ${i.size})`)})})}function n5(a,e){let i=i0(a,e);if(!i){let n=kn(a);return n.length===0?{error:"No browser connected. Add the annotator script to your webpage."}:{error:`Multiple sessions available. Specify sessionId. Available: ${n.map(t=>t.id).join(", ")}`}}return{rpc:i.rpc,sessionId:i.sessionId}}function t5(a,e,i){function n(t,s){let o=n5(i,s);return"error"in o?(t.status(400).json({error:o.error}),null):o.rpc}a.get("/api/sessions",(t,s)=>{s.json(kn(i))}),a.get("/api/sessions/:id/page-context",async(t,s)=>{let o=n(s,t.params.id);if(o)try{let r=await o.client.getPageContext(1e4);s.json(r)}catch(r){s.status(500).json({error:r instanceof Error?r.message:String(r)})}}),a.post("/api/sessions/:id/select",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{mode:r="inspect",selector:c,selectorType:p="css"}=t.body||{};try{let l=await o.client.triggerSelection(r,c,p,1e4);s.json(l)}catch(l){s.status(500).json({error:l instanceof Error?l.message:String(l)})}}),a.get("/api/sessions/:id/feedback",async(t,s)=>{let o=n(s,t.params.id);if(o)try{let r=await o.client.getSelectedElements(15e3);if(Array.isArray(r)&&r.length===0){s.json([]);return}let p=t.query.fields?.split(",").filter(Boolean),l=Qb(r,p);s.json(l)}catch(r){s.status(500).json({error:r instanceof Error?r.message:String(r)})}}),a.delete("/api/sessions/:id/feedback",(t,s)=>{let o=n(s,t.params.id);o&&(o.client.clearSelection(),s.json({success:!0}))}),a.post("/api/sessions/:id/screenshot",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{type:r="viewport",selector:c,quality:p=.7}=t.body||{};try{let l=await o.client.captureScreenshot(r,c,p,3e4);if("success"in l&&l.success&&"base64"in l&&l.base64){let u=Yb(l.base64);s.json({success:!0,filePath:u})}else s.json(l)}catch(l){s.status(500).json({error:l instanceof Error?l.message:String(l)})}}),a.post("/api/sessions/:id/inject-css",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{css:r}=t.body||{};if(!r){s.status(400).json({error:"css field is required"});return}try{let c=await o.client.injectCSS(r,1e4);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),a.post("/api/sessions/:id/inject-js",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{code:r}=t.body||{};if(!r){s.status(400).json({error:"code field is required"});return}try{let c=await o.client.injectJS(r,15e3);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),a.get("/api/sessions/:id/console",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let r=t.query.clear==="true";try{let c=await o.client.getConsole(r,15e3);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),e.log("REST API routes registered at /api/*")}async function n0(a,e,i,n=!1){let t=Kb(n),s=(0,yp.default)(),o=new Map;s.use((0,a0.default)({origin:"*",methods:["GET","POST","OPTIONS"],allowedHeaders:["Content-Type","Authorization"]})),s.use(yp.default.json({limit:"10mb"})),a5(s,i,n,o),t5(s,t,o);let r=await s5(s,a,e),c=new Vb(r,{cors:{origin:"*",methods:["GET","POST"]},path:"/socket.io",maxHttpBufferSize:5e7});return i5(c,t,o),{app:s,server:r,io:c,port:a,listenAddress:e,publicAddress:i,verbose:n,getAllSessions:()=>kn(o),getRpc:p=>i0(o,p)}}async function t0(a){return new Promise(e=>{a.io.close(()=>{e()})})}function s5(a,e,i){return new Promise((n,t)=>{let s=a.listen(e,i,()=>n(s));s.on("error",o=>{t(o)})})}var o0=require("net");var Ss=require("node:fs"),_s=require("node:path");function s0(){let a=[(0,_s.join)(__dirname,"..","package.json"),(0,_s.join)(__dirname,"package.json"),(0,_s.join)(process.cwd(),"package.json")];for(let e of a)if((0,Ss.existsSync)(e))try{let i=JSON.parse((0,Ss.readFileSync)(e,"utf-8"));if(i.name==="vite-plugin-ai-annotator"&&i.version)return i.version}catch{continue}return"0.0.0"}var o5=s0(),te=process.argv.slice(2);r5();async function r5(){let a=te.includes("--help")||te.includes("-h"),e=te.includes("--version")||te.includes("-v"),i=te.includes("--verbose")||te.includes("-V"),n=te.findIndex(x=>x==="--port"||x==="-p"),t=te.findIndex(x=>x==="--listen"||x==="-l"),s=te.findIndex(x=>x==="--public-address"||x==="-a");a&&(console.log(`
69
+ `;s.send(c+l)}catch(o){console.error("Error reading annotator-toolbar.js:",o),s.status(404).send("File not found")}}),a.get("/health",(t,s)=>{s.json({status:"ok",sessions:n.size})}),a.get("/api/sessions",(t,s)=>{s.json(kn(n))})}function kn(a){return Array.from(a.values()).map(e=>e.session)}function i0(a,e){if(e){let i=a.get(e);return i?{rpc:i.rpc,sessionId:e}:null}if(a.size===1){let i=a.entries().next().value;if(i){let[n,t]=i;return{rpc:t.rpc,sessionId:n}}}return null}var Jb="channels";function i5(a,e,i){let n=0,t=()=>{for(let s of i.values())s.socket.emit("channel:status",{listenerCount:n})};a.on("connection",s=>{if(s.handshake.query.role==="channel"){s.join(Jb),n++,t(),e.log(`Channel client connected (sid: ${s.id}, total: ${n})`),s.on("channel:notify",l=>{if(!l?.sessionId||typeof l.message!="string")return;let u=i.get(l.sessionId);u&&u.socket.emit("channel:notify",{message:l.message,status:l.status??"info"})}),s.on("disconnect",()=>{n=Math.max(0,n-1),t(),e.log(`Channel client disconnected (sid: ${s.id}, total: ${n})`)});return}let r=e5(),c={id:r,url:"",title:"",connectedAt:Date.now(),lastActivity:Date.now()},p=Gb(s);i.set(r,{socket:s,rpc:p,session:c}),e.log(`Browser connected: ${r} (total: ${i.size})`),p.handle.getSessions(async()=>kn(i)),p.handle.ping(async()=>"pong"),p.handle.rpcError(l=>{e.error("RPC Error:",l)}),s.emit("connected",{sessionId:r}),s.emit("channel:status",{listenerCount:n}),s.on("pageContextChanged",l=>{c.url=l.url,c.title=l.title,c.lastActivity=Date.now()}),s.on("feedback:submitted",l=>{let u=typeof l?.count=="number"?l.count:0;c.lastActivity=Date.now(),a.to(Jb).emit("feedback:submitted",{sessionId:r,pageUrl:c.url,pageTitle:c.title,count:u})}),s.on("disconnect",()=>{p.dispose(),i.delete(r),e.log(`Browser disconnected: ${r} (total: ${i.size})`)})})}function n5(a,e){let i=i0(a,e);if(!i){let n=kn(a);return n.length===0?{error:"No browser connected. Add the annotator script to your webpage."}:{error:`Multiple sessions available. Specify sessionId. Available: ${n.map(t=>t.id).join(", ")}`}}return{rpc:i.rpc,sessionId:i.sessionId}}function t5(a,e,i){function n(t,s){let o=n5(i,s);return"error"in o?(t.status(400).json({error:o.error}),null):o.rpc}a.get("/api/sessions",(t,s)=>{s.json(kn(i))}),a.get("/api/sessions/:id/page-context",async(t,s)=>{let o=n(s,t.params.id);if(o)try{let r=await o.client.getPageContext(1e4);s.json(r)}catch(r){s.status(500).json({error:r instanceof Error?r.message:String(r)})}}),a.post("/api/sessions/:id/select",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{mode:r="inspect",selector:c,selectorType:p="css"}=t.body||{};try{let l=await o.client.triggerSelection(r,c,p,1e4);s.json(l)}catch(l){s.status(500).json({error:l instanceof Error?l.message:String(l)})}}),a.get("/api/sessions/:id/feedback",async(t,s)=>{let o=n(s,t.params.id);if(o)try{let r=await o.client.getSelectedElements(15e3);if(Array.isArray(r)&&r.length===0){s.json([]);return}let p=t.query.fields?.split(",").filter(Boolean),l=Qb(r,p);s.json(l)}catch(r){s.status(500).json({error:r instanceof Error?r.message:String(r)})}}),a.delete("/api/sessions/:id/feedback",(t,s)=>{let o=n(s,t.params.id);o&&(o.client.clearSelection(),s.json({success:!0}))}),a.post("/api/sessions/:id/screenshot",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{type:r="viewport",selector:c,quality:p=.7}=t.body||{};try{let l=await o.client.captureScreenshot(r,c,p,3e4);if("success"in l&&l.success&&"base64"in l&&l.base64){let u=Yb(l.base64);s.json({success:!0,filePath:u})}else s.json(l)}catch(l){s.status(500).json({error:l instanceof Error?l.message:String(l)})}}),a.post("/api/sessions/:id/inject-css",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{css:r}=t.body||{};if(!r){s.status(400).json({error:"css field is required"});return}try{let c=await o.client.injectCSS(r,1e4);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),a.post("/api/sessions/:id/inject-js",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let{code:r}=t.body||{};if(!r){s.status(400).json({error:"code field is required"});return}try{let c=await o.client.injectJS(r,15e3);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),a.get("/api/sessions/:id/console",async(t,s)=>{let o=n(s,t.params.id);if(!o)return;let r=t.query.clear==="true";try{let c=await o.client.getConsole(r,15e3);s.json(c)}catch(c){s.status(500).json({error:c instanceof Error?c.message:String(c)})}}),e.log("REST API routes registered at /api/*")}async function n0(a,e,i,n=!1){let t=Kb(n),s=(0,yp.default)(),o=new Map;s.use((0,a0.default)({origin:"*",methods:["GET","POST","OPTIONS"],allowedHeaders:["Content-Type","Authorization"]})),s.use(yp.default.json({limit:"10mb"})),a5(s,i,n,o),t5(s,t,o);let r=await s5(s,a,e),c=new Vb(r,{cors:{origin:"*",methods:["GET","POST"]},path:"/socket.io",maxHttpBufferSize:5e7});return i5(c,t,o),{app:s,server:r,io:c,port:a,listenAddress:e,publicAddress:i,verbose:n,getAllSessions:()=>kn(o),getRpc:p=>i0(o,p)}}async function t0(a){return new Promise(e=>{a.io.close(()=>{e()})})}function s5(a,e,i){return new Promise((n,t)=>{let s=a.listen(e,i,()=>n(s));s.on("error",o=>{t(o)})})}var o0=require("net");var Ss=require("node:fs"),_s=require("node:path");function s0(){let a=[(0,_s.join)(__dirname,"..","package.json"),(0,_s.join)(__dirname,"package.json"),(0,_s.join)(process.cwd(),"package.json")];for(let e of a)if((0,Ss.existsSync)(e))try{let i=JSON.parse((0,Ss.readFileSync)(e,"utf-8"));if(i.name==="vite-plugin-ai-annotator"&&i.version)return i.version}catch{continue}return"0.0.0"}var o5=s0(),te=process.argv.slice(2);r5();async function r5(){let a=te.includes("--help")||te.includes("-h"),e=te.includes("--version")||te.includes("-v"),i=te.includes("--verbose")||te.includes("-V"),n=te.findIndex(x=>x==="--port"||x==="-p"),t=te.findIndex(x=>x==="--listen"||x==="-l"),s=te.findIndex(x=>x==="--public-address"||x==="-a");a&&(console.log(`
70
70
  AI Annotator - AI-powered web inspection tool
71
71
 
72
72
  Usage:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-ai-annotator",
3
- "version": "1.16.1",
3
+ "version": "1.16.2",
4
4
  "description": "AI-powered element annotator for Vite - Pick elements and get instant AI code modifications",
5
5
  "type": "module",
6
6
  "main": "dist/vite-plugin.js",