ugly-app 0.1.715 → 0.1.717

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,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.1.715";
1
+ export declare const CLI_VERSION = "0.1.717";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.715";
2
+ export const CLI_VERSION = "0.1.717";
3
3
  //# sourceMappingURL=version.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-entry.d.ts","sourceRoot":"","sources":["../../../src/inspect/agent/bundle-entry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ // Entry for the pre-bundled, injectable agent IIFE. The ugly-app build esbuilds
2
+ // this into dist/inspect/agent-bundle.js (a single self-contained script with no
3
+ // imports), which native shells read as text and inject at document-start —
4
+ // no runtime bundler needed on the host side.
5
+ import { installInspectAgent } from './install.js';
6
+ installInspectAgent();
7
+ //# sourceMappingURL=bundle-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-entry.js","sourceRoot":"","sources":["../../../src/inspect/agent/bundle-entry.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iFAAiF;AACjF,4EAA4E;AAC5E,8CAA8C;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";(()=>{var w=class{constructor(t){this.cap=t}cap;items=[];push(t){this.items.push(t),this.items.length>this.cap&&this.items.splice(0,this.items.length-this.cap)}since(t,n){let r=0,o=this.items.length;for(;r<o;){let s=r+o>>>1;n(this.items[s])<t?r=s+1:o=s}return this.items.slice(r)}all(){return this.items.slice()}clear(){this.items=[]}size(){return this.items.length}};var b=class{seq=0;byId=new Map;put(t){let n=`o${++this.seq}`;return this.byId.set(n,t),n}get(t){return this.byId.get(t)}clear(){this.byId.clear()}};function ie(e){return typeof Node<"u"&&typeof e=="object"&&e!==null&&e instanceof Node}function E(e,t){return e.length>t?`${e.slice(0,t)}\u2026`:e}function x(e){return Object.getPrototypeOf(e)?.constructor?.name}function p(e,t){switch(typeof e){case"undefined":return{type:"undefined"};case"boolean":return{type:"boolean",value:e};case"bigint":return{type:"bigint",value:`${e}n`,preview:`${e}n`};case"symbol":return{type:"symbol",value:String(e),preview:String(e)};case"string":return{type:"string",value:E(e,1e3)};case"number":return Number.isFinite(e)?{type:"number",value:e}:{type:"number",value:String(e),preview:String(e)};case"function":return{type:"function",className:"Function",preview:`\u0192 ${e.name||"(anonymous)"}()`};case"object":break;default:return{type:"object",preview:String(e)}}if(e===null)return{type:"null"};let n=e;if(ie(e))return{type:"node",className:e.nodeName??"Node",preview:ce(e),nodeId:t.nodeIdFor?.(e)};if(e instanceof Date)return{type:"date",className:"Date",preview:le(e)};if(e instanceof RegExp)return{type:"regexp",className:"RegExp",preview:String(e)};if(e instanceof Error)return{type:"error",className:e.name||"Error",preview:E(`${e.name}: ${e.message}`,100),objectId:t.registry.put(e)};if(ue(e))return{type:"promise",className:"Promise",preview:"Promise",objectId:t.registry.put(e)};if(e instanceof Map)return{type:"map",className:"Map",size:e.size,objectId:t.registry.put(e),preview:`Map(${e.size})`,entries:C(e,t)};if(e instanceof Set)return{type:"set",className:"Set",size:e.size,objectId:t.registry.put(e),preview:`Set(${e.size})`,entries:D(e,t)};if(Array.isArray(e))return{type:"array",className:"Array",size:e.length,objectId:t.registry.put(e),preview:`Array(${e.length})`,entries:L(e,t)};let r=Object.keys(n);return{type:"object",className:x(n)??"Object",size:r.length,objectId:t.registry.put(n),preview:se(n,r),entries:v(n,r,t)}}function P(e,t){if(e instanceof Map)return C(e,t,1/0).map(n=>n.value);if(e instanceof Set)return D(e,t,1/0).map(n=>n.value);if(Array.isArray(e))return L(e,t,1/0).map(n=>n.value);if(e instanceof Error)return v({name:e.name,message:e.message,stack:e.stack},["name","message","stack"],t,1/0).map(n=>n.value);if(typeof e=="object"&&e!==null){let n=Object.keys(e);return v(e,n,t,1/0).map(r=>r.value)}return[]}function L(e,t,n=5){let r=[];for(let o=0;o<e.length&&o<n;o++)r.push({key:String(o),value:p(e[o],t)});return r}function v(e,t,n,r=5){let o=[];for(let s=0;s<t.length&&s<r;s++){let i=t[s],c;try{c=e[i]}catch{c="(getter threw)"}o.push({key:i,value:p(c,n)})}return o}function C(e,t,n=5){let r=[],o=0;for(let[s,i]of e){if(o++>=n)break;r.push({key:p(s,t),value:p(i,t)})}return r}function D(e,t,n=5){let r=[],o=0;for(let s of e){if(o++>=n)break;r.push({value:p(s,t)})}return r}function se(e,t){let n=t.slice(0,5).map(o=>{let s;try{s=e[o]}catch{s="\u2026"}return`${o}: ${ae(s)}`}),r=t.length>5?", \u2026":"";return E(`{${n.join(", ")}${r}}`,100)}function ae(e){let t=typeof e;return t==="string"?`"${E(e,20)}"`:t==="object"&&e!==null?Array.isArray(e)?`Array(${e.length})`:x(e)??"Object":String(e)}function ce(e){let t=e;if(t.nodeType===1){let n=(t.nodeName??"").toLowerCase(),r=t.id?`#${t.id}`:"",o=typeof t.className=="string"&&t.className?`.${t.className.trim().split(/\s+/).join(".")}`:"";return E(`<${n}${r}${o}>`,100)}return t.nodeName??"Node"}function ue(e){return typeof e?.then=="function"}function le(e){try{return e.toISOString()}catch{return"Invalid Date"}}var _=["log","info","warn","error","debug"];function j(e){if(typeof console>"u")return()=>{};let t=0,n={};for(let i of _){let c=console[i];typeof c=="function"&&(n[i]=c,console[i]=(...l)=>{try{s(i,l)}catch{}c.apply(console,l)})}let r=i=>{s("error",[i.message],{stack:y(i.error?.stack),source:{url:i.filename||"",line:i.lineno||0,col:i.colno||0}})},o=i=>{let c=i.reason;s("error",[`Unhandled rejection: ${c?.message??String(i.reason)}`],{stack:y(c?.stack)})};typeof window<"u"&&(window.addEventListener("error",r),window.addEventListener("unhandledrejection",o));function s(i,c,l){let f=c.map(g=>p(g,{registry:e.registry,nodeIdFor:e.nodeIdFor})),a=l?.stack??y(new Error().stack,1),d={seq:++t,ts:e.now(),level:i,args:f,text:de(c),stack:a.length?a:void 0,source:l?.source??a[0]?{url:a[0].url,line:a[0].line,col:a[0].col}:void 0};e.buffer.push(d),e.onEntry?.(d)}return()=>{for(let i of _){let c=n[i];c&&(console[i]=c)}typeof window<"u"&&(window.removeEventListener("error",r),window.removeEventListener("unhandledrejection",o))}}function de(e){return e.map(t=>{if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}).join(" ").slice(0,2e3)}function y(e,t=0){if(!e)return[];let n=[],r=e.split(`
2
+ `);for(let o of r){let s=o.trim(),i=/^at\s+(.*?)\s+\((.*?):(\d+):(\d+)\)$/.exec(s)||/^at\s+(.*?):(\d+):(\d+)$/.exec(s);if(i){i.length===5?n.push({functionName:i[1],url:i[2],line:+i[3],col:+i[4]}):n.push({functionName:"(anonymous)",url:i[1],line:+i[2],col:+i[3]});continue}i=/^(.*?)@(.*?):(\d+):(\d+)$/.exec(s),i&&n.push({functionName:i[1]||"(anonymous)",url:i[2],line:+i[3],col:+i[4]})}return n.slice(t)}function $(e,t=40,n=Date.now){let r=typeof document<"u"&&document.documentElement?M(document.documentElement,e,t,0):ge();return{documentUrl:typeof location<"u"?location.href:"",capturedAt:n(),root:r}}function M(e,t,n,r){let o={nodeId:t.idFor(e),nodeType:e.nodeType,nodeName:e.nodeName};if(e.nodeType===Node.TEXT_NODE||e.nodeType===Node.COMMENT_NODE){let a=(e.textContent??"").trim();return a&&(o.textContent=a.slice(0,200)),o}if(e.nodeType!==Node.ELEMENT_NODE)return o;let s=e;if(o.attributes=me(s),o.rect=pe(s),r>=n)return o;let i=s.shadowRoot;i&&(o.shadowRoots=Array.from(i.childNodes).filter(O).map(a=>M(a,t,n,r+1)));let c=[],l=A(s,"before");l&&c.push(l);for(let a of Array.from(s.childNodes))O(a)&&c.push(M(a,t,n,r+1));let f=A(s,"after");return f&&c.push(f),c.length&&(o.children=c),o}function A(e,t){if(typeof getComputedStyle>"u")return;let n;try{n=getComputedStyle(e,`::${t}`).content}catch{return}if(!(!n||n==="none"||n==="normal"))return{nodeId:`${fe(e)}::${t}`,nodeType:1,nodeName:`::${t}`,pseudo:t,textContent:n}}function fe(e){return e.__inspectPseudoBase??e.tagName}function O(e){return e.nodeType===Node.TEXT_NODE?!!(e.textContent??"").trim():e.nodeType===Node.ELEMENT_NODE||e.nodeType===Node.COMMENT_NODE}function me(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return t}function pe(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}function ge(){return{nodeId:"n0",nodeType:9,nodeName:"#document"}}function B(e,t){let n=ye(e,t);if(!n)throw new Error(`inspect.element: node not found (${t.nodeId??t.selector??"?"})`);let r=getComputedStyle(n),o=Se(n);return{nodeId:e.idFor(n),tag:n.tagName.toLowerCase(),attributes:Re(n),computedStyles:he(r),matchedRules:we(n),boxModel:be(n,r,o),eventListeners:ke(n),accessibility:Ne(n),rect:o}}function ye(e,t){if(t.nodeId){let n=e.get(t.nodeId);return n?.nodeType===1?n:null}return t.selector&&typeof document<"u"?document.querySelector(t.selector):null}function he(e){let t={};for(let n=0;n<e.length;n++){let r=e.item(n);t[r]=e.getPropertyValue(r)}return t}function we(e){let t=[];if(typeof document>"u")return t;for(let n of Array.from(document.styleSheets)){let r;try{r=n.cssRules}catch{continue}let o=n.href??void 0;for(let s of Array.from(r)){if(!(s instanceof CSSStyleRule))continue;let i=!1;try{i=e.matches(s.selectorText)}catch{i=!1}i&&t.push({selector:s.selectorText,source:o?{url:o,line:0,col:0}:void 0,props:Ee(s.style)})}}return t}function Ee(e){let t={};for(let n=0;n<e.length;n++){let r=e.item(n);t[r]=e.getPropertyValue(r)}return t}function be(e,t,n){let r=(o,s)=>({top:k(t.getPropertyValue(`${o}-top${s}`)),right:k(t.getPropertyValue(`${o}-right${s}`)),bottom:k(t.getPropertyValue(`${o}-bottom${s}`)),left:k(t.getPropertyValue(`${o}-left${s}`))});return{content:n,padding:r("padding",""),border:r("border","-width"),margin:r("margin","")}}function ke(e){let n=(typeof window<"u"?window:{}).__inspectGetEventListeners;if(!n)return[];try{let r=n(e),o=[];for(let[s,i]of Object.entries(r))for(let c of i)o.push({type:s,useCapture:c.useCapture,passive:c.passive});return o}catch{return[]}}function Ne(e){let t={};for(let o of Array.from(e.attributes))o.name.startsWith("aria-")&&(t[o.name]=o.value);let n=e.getAttribute("role")??void 0,r=e.getAttribute("aria-label")??e.title??(e.textContent??"").trim().slice(0,80)??void 0;return{role:n,name:r||void 0,properties:t}}function Re(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return t}function Se(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}function k(e){let t=parseFloat(e);return Number.isFinite(t)?t:0}async function V(e,t,n){let r=t.now();try{let o=ve(e,n?.replMode?{$0:t.getPicked(),$_:t.getLast()}:{});return n?.awaitPromise&&Me(o)&&(o=await o),t.setLast(o),{ok:!0,value:p(o,{registry:t.registry,nodeIdFor:t.nodeIdFor}),tookMs:t.now()-r}}catch(o){let s=o;return{ok:!1,exception:{text:`${s?.name??"Error"}: ${s?.message??String(o)}`,stack:y(s?.stack)},tookMs:t.now()-r}}}function ve(e,t){let n=Object.keys(t);if(n.length===0)return(0,eval)(e);let r=new Function(...n,`return (${e});`);try{return r(...n.map(o=>t[o]))}catch(o){if(o instanceof SyntaxError)return new Function(...n,e)(...n.map(i=>t[i]));throw o}}function Me(e){return typeof e?.then=="function"}var N=64*1024;function H(e){if(typeof window>"u")return()=>{};let t=0,n=()=>`r${++t}`,r=window.fetch?.bind(window);r&&(window.fetch=async(l,f)=>{let a=e.now(),d=(f?.method||(l instanceof Request?l.method:"GET")).toUpperCase(),g=l instanceof Request?l.url:String(l),u={id:n(),ts:a,method:d,url:g,resourceType:"fetch",requestHeaders:F(f?.headers??(l instanceof Request?l.headers:void 0)),requestBody:X(f?.body),timing:{startMs:a,durationMs:0}};try{let m=await r(l,f);return u.status=m.status,u.responseHeaders=F(m.headers),u.timing.durationMs=e.now()-a,u.fromCache=m.fromCache,await Te(m,u),c(u),m}catch(m){throw u.failed=!0,u.timing.durationMs=e.now()-a,u.responseBody={kind:"text",data:String(m?.message??m)},c(u),m}});let o=window.XMLHttpRequest,s=o?.prototype.open,i=o?.prototype.send;o&&s&&i&&(o.prototype.open=function(f,a,...d){return this.__inspect={method:f.toUpperCase(),url:a,start:0},s.apply(this,[f,a,...d])},o.prototype.send=function(f){let a=this.__inspect;return a&&(a.start=e.now(),this.addEventListener("loadend",()=>{let d={id:n(),ts:a.start,method:a.method,url:a.url,status:this.status,resourceType:"xhr",requestHeaders:{},responseHeaders:Ie(this.getAllResponseHeaders()),requestBody:X(f),responseBody:xe(this),timing:{startMs:a.start,durationMs:e.now()-a.start},failed:this.status===0};c(d)})),i.apply(this,[f])});function c(l){e.buffer.push(l),e.onEntry?.(l)}return()=>{r&&(window.fetch=r),o&&s&&(o.prototype.open=s),o&&i&&(o.prototype.send=i)}}function F(e){let t={};if(!e)return t;if(typeof Headers<"u"&&e instanceof Headers)e.forEach((n,r)=>t[r]=n);else if(Array.isArray(e))for(let[n,r]of e)t[n]=r;else Object.assign(t,e);return t}function Ie(e){let t={};for(let n of e.split(`\r
3
+ `)){let r=n.indexOf(":");r>0&&(t[n.slice(0,r).trim().toLowerCase()]=n.slice(r+1).trim())}return t}function X(e){if(e!=null)return typeof e=="string"?e.slice(0,N):typeof URLSearchParams<"u"&&e instanceof URLSearchParams?e.toString().slice(0,N):"(binary)"}async function Te(e,t){let n=e.headers.get("content-type")||"";if(!/json|text|javascript|xml|html|csv/i.test(n)){t.responseBody={kind:"omitted"};return}try{let r=await e.clone().text();t.sizeBytes=r.length;let o=/json/i.test(n)?"json":"text";t.responseBody={kind:o,data:r.slice(0,N)}}catch{t.responseBody={kind:"omitted"}}}function xe(e){try{if(e.responseType===""||e.responseType==="text"){let t=e.responseText||"",n=e.getResponseHeader("content-type")||"";return{kind:/json/i.test(n)?"json":"text",data:t.slice(0,N)}}}catch{}return{kind:"omitted"}}var R=class{seq=0;byId=new Map;idOf=new WeakMap;idFor(t){let n=this.idOf.get(t);if(n)return this.byId.set(n,t),n;let r=`n${++this.seq}`;return this.idOf.set(t,r),this.byId.set(r,t),r}get(t){return this.byId.get(t)}clear(){this.byId.clear()}};function S(e){let t=e.getAttribute?.("data-id");if(t)return`[data-id=${t}]`;let n=e.getAttribute?.("role"),r=e.tagName.toLowerCase();return e.id?`${r}#${e.id}`:n?`${r}[role=${n}]`:r}var z="__ugly_inspect_overlay__";function q(e){if(typeof document>"u")return{setEnabled:()=>{},highlight:()=>{},destroy:()=>{}};let t=!1,n=null;function r(){if(n)return n;let a=document.createElement("div");return a.id=z,Object.assign(a.style,{position:"fixed",pointerEvents:"none",zIndex:"2147483647",background:"rgba(64,128,255,0.28)",border:"1px solid rgba(64,128,255,0.9)",boxSizing:"border-box",top:"0",left:"0",display:"none"}),document.documentElement.appendChild(a),n=a,a}function o(a){let d=r();if(!a){d.style.display="none";return}Object.assign(d.style,{display:"block",transform:`translate(${a.x}px, ${a.y}px)`,width:`${a.w}px`,height:`${a.h}px`})}let s=a=>{let d=c(a.clientX,a.clientY);d&&o(I(d))},i=a=>{let d=c(a.clientX,a.clientY);d&&(a.preventDefault(),a.stopPropagation(),e.setPickedNode(d),e.onPicked({nodeId:e.reg.idFor(d),selector:S(d),rect:I(d)}),l(!1))};function c(a,d){n&&(n.style.display="none");let g=document.elementFromPoint(a,d);return g&&g.id!==z?g:null}function l(a){a!==t&&(t=a,a?(window.addEventListener("pointermove",s,!0),window.addEventListener("pointerdown",i,!0)):(window.removeEventListener("pointermove",s,!0),window.removeEventListener("pointerdown",i,!0),o(null)))}function f(a){if(!a){o(null);return}let d=e.reg.get(a);d?.nodeType===1&&o(I(d))}return{setEnabled:l,highlight:f,destroy:()=>{l(!1),n?.remove(),n=null}}}function I(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}var G=4;async function Y(e,t){let n=t(),r=[];await new Promise(s=>{let i=()=>{r.push(Pe()),t()-n>=e?s():W(i)};W(i)});let o=t();return{startTime:n,endTime:o,durationMs:o-n,sampleCount:r.length,precise:!1,root:Le(r)}}function W(e){typeof setTimeout<"u"?setTimeout(e,G):e()}function Pe(){return y(new Error().stack,1).filter(t=>!/profile\.(js|ts)/.test(t.url)).map(t=>({url:t.url,line:t.line,col:t.col,functionName:t.functionName})).reverse()}function Le(e){let t=0,n=U(t++,"(root)");for(let r of e){let o=n;o.hitCount++;for(let s of r){let i=s,c=`${i.functionName??"(anonymous)"}@${i.url}:${i.line}`,l=o.childMap.get(c);l||(l=U(t++,i.functionName??"(anonymous)",{url:i.url,line:i.line,col:i.col}),o.childMap.set(c,l),o.children.push(l)),l.hitCount++,o=l}}return Q(n,e.length),J(n)}function U(e,t,n){return{id:e,functionName:t,source:n,selfTimeMs:0,totalTimeMs:0,hitCount:0,children:[],childMap:new Map}}function Q(e,t){let n=0;for(let r of e.children)n+=Q(r,t);return e.totalTimeMs=e.hitCount*G,e.selfTimeMs=Math.max(0,e.totalTimeMs-n),e.totalTimeMs}function J(e){return{id:e.id,functionName:e.functionName,source:e.source,selfTimeMs:e.selfTimeMs,totalTimeMs:e.totalTimeMs,hitCount:e.hitCount,children:e.children.map(t=>J(t))}}async function ee(){return{localStorage:K(Z(()=>localStorage)),sessionStorage:K(Z(()=>sessionStorage)),cookies:Ce(),indexedDB:await De()}}function Z(e){try{return e()}catch{return null}}function K(e){let t={};if(!e)return t;for(let n=0;n<e.length;n++){let r=e.key(n);r!=null&&(t[r]=e.getItem(r)??"")}return t}function Ce(){if(typeof document>"u"||!document.cookie)return[];let e=typeof location<"u"?location.hostname:"";return document.cookie.split("; ").filter(Boolean).map(t=>{let n=t.indexOf("="),r=n>=0?t.slice(0,n):t,o=n>=0?t.slice(n+1):"";return{name:r,value:o,domain:e,path:"/"}})}async function De(){if(typeof indexedDB>"u"||typeof indexedDB.databases!="function")return[];try{let e=await indexedDB.databases(),t=[];for(let n of e)n.name&&t.push({name:n.name,stores:await _e(n.name)});return t}catch{return[]}}function _e(e){return new Promise(t=>{try{let n=indexedDB.open(e);n.onsuccess=()=>{let r=n.result,o=Array.from(r.objectStoreNames);r.close(),t(o)},n.onerror=()=>t([])}catch{t([])}})}function te(e){let t={longTasks:[]},n=[];if(typeof PerformanceObserver>"u")return{read:()=>({...t,navigation:T()}),stop:()=>{}};r("largest-contentful-paint",o=>{let s=o[o.length-1];if(!s)return;let i=s.element;t.lcp={valueMs:s.startTime,element:i?{nodeId:e.nodeIdFor(i),selector:S(i),rect:je(i)}:void 0}}),r("paint",o=>{for(let s of o)s.name==="first-contentful-paint"&&(t.fcp=s.startTime)}),r("layout-shift",o=>{let s=t.cls??0;for(let i of o)i.hadRecentInput||(s+=i.value);t.cls=s}),r("event",o=>{let s=t.inp??0;for(let i of o){let c=i.duration;c>s&&(s=c)}t.inp=s},{durationThreshold:40}),r("longtask",o=>{for(let s of o)t.longTasks.push({ts:e.now(),durationMs:s.duration});t.longTasks.length>200&&t.longTasks.splice(0,t.longTasks.length-200)});function r(o,s,i){try{let c=new PerformanceObserver(l=>s(l.getEntries()));c.observe({type:o,buffered:!0,...i??{}}),n.push(c)}catch{}}return{read:()=>({...t,longTasks:t.longTasks.slice(),navigation:T(),ttfb:t.ttfb??T()?.ttfbMs}),stop:()=>n.forEach(o=>o.disconnect())}}function T(){if(typeof performance>"u"||!performance.getEntriesByType)return;let e=performance.getEntriesByType("navigation")[0];if(e)return{ttfbMs:e.responseStart,domContentLoadedMs:e.domContentLoadedEventEnd,loadEventMs:e.loadEventEnd,domInteractiveMs:e.domInteractive,transferSizeBytes:e.transferSize}}function je(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}var ne=1e3;function h(){return typeof performance<"u"&&performance.now?performance.timeOrigin+performance.now():Date.now()}function Ae(e={}){let t=new b,n=new R,r=u=>n.idFor(u),o=new w(ne),s=new w(ne),i=null,c,l=j({buffer:o,registry:t,nodeIdFor:r,onEntry:u=>e.onConsole?.(u),now:h}),f=H({buffer:s,onEntry:u=>e.onNetwork?.(u),now:h}),a=te({nodeIdFor:r,now:h}),d=q({reg:n,onPicked:u=>e.onPicked?.(u),setPickedNode:u=>i=u});return{meta(){return{url:typeof location<"u"?location.href:"",title:typeof document<"u"?document.title:"",isUglyApp:typeof window<"u"&&"__uglyInspect"in window,viewport:{w:typeof window<"u"?window.innerWidth:0,h:typeof window<"u"?window.innerHeight:0,dpr:typeof window<"u"&&window.devicePixelRatio||1}}},consoleBuffer:u=>u==null?o.all():o.all().filter(m=>m.seq>u),networkBuffer:u=>u==null?s.all():s.since(u,m=>m.ts),evaluate:(u,m)=>V(u,{registry:t,nodeIdFor:r,now:h,getPicked:()=>i,getLast:()=>c,setLast:re=>c=re},m),expand:u=>({entries:P(t.get(u),{registry:t,nodeIdFor:r})}),domCapture:u=>$(n,u,h),element:u=>B(n,u),highlight:u=>d.highlight(u),setPicker:u=>d.setEnabled(u),vitals:()=>a.read(),profile:u=>Y(u,h),storage:()=>ee(),reset:()=>{t.clear(),n.clear(),o.clear(),s.clear(),i=null,c=void 0},stop:()=>{l(),f(),a.stop(),d.destroy()}}}function oe(e){if(typeof window<"u"&&window.__uglyInspectAgent)return window.__uglyInspectAgent;let t=Ae(e);return typeof window<"u"&&(window.__uglyInspectAgent=t),t}oe();})();
@@ -3,4 +3,5 @@ export type { AgentEvents, AgentMeta, InspectAgent } from './agent/types.js';
3
3
  export { createInspectAgent, installInspectAgent } from './agent/install.js';
4
4
  export { InspectClient, type InspectTransport } from './client.js';
5
5
  export { buildTarget, dispatchToAgent, HOST_ONLY_CHANNELS } from './dispatch.js';
6
+ export { createSelfInspectHost, SELF_TARGET_ID, type SelfInspectHost, type SelfInspectHostOpts, } from './selfHost.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inspect/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inspect/index.ts"],"names":[],"mappings":"AAIA,cAAc,eAAe,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC"}
@@ -5,4 +5,5 @@ export * from './protocol.js';
5
5
  export { createInspectAgent, installInspectAgent } from './agent/install.js';
6
6
  export { InspectClient } from './client.js';
7
7
  export { buildTarget, dispatchToAgent, HOST_ONLY_CHANNELS } from './dispatch.js';
8
+ export { createSelfInspectHost, SELF_TARGET_ID, } from './selfHost.js';
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inspect/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAE/E,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAyB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inspect/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,+EAA+E;AAE/E,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAyB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,cAAc,GAGf,MAAM,eAAe,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { InspectPlatform, Screenshot, ScreenshotRequest } from './protocol.js';
2
+ /** The id this host reports for its single (self) target. */
3
+ export declare const SELF_TARGET_ID = "self";
4
+ export interface SelfInspectHostOpts {
5
+ platform: InspectPlatform;
6
+ /** Screenshot delegate — on mobile this calls native (WKWebView.takeSnapshot /
7
+ * Android PixelCopy) via the uglyNative `capture.screenshot` channel. */
8
+ screenshot?: (req: ScreenshotRequest) => Promise<Screenshot>;
9
+ /** Forward live agent events to the proxy connection. Event names are the
10
+ * per-target dynamic form (`inspect.console:self`, `inspect.network:self`,
11
+ * `inspect.picked:self`). */
12
+ onEvent?: (event: string, data: unknown) => void;
13
+ }
14
+ export interface SelfInspectHost {
15
+ /** Route one inspect.* channel (targetId is ignored — there is only `self`). */
16
+ dispatch(channel: string, payload?: Record<string, unknown>): Promise<unknown>;
17
+ stop(): void;
18
+ }
19
+ export declare function createSelfInspectHost(opts: SelfInspectHostOpts): SelfInspectHost;
20
+ //# sourceMappingURL=selfHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selfHost.d.ts","sourceRoot":"","sources":["../../src/inspect/selfHost.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpF,6DAA6D;AAC7D,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,eAAe,CAAC;IAC1B;8EAC0E;IAC1E,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D;;kCAE8B;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAED,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAuBhF"}
@@ -0,0 +1,38 @@
1
+ // A single-page inspect host: answers inspect.* for the CURRENT page only,
2
+ // routing to the in-page agent. This is the building block for shells that have
3
+ // no native cross-tab host — chiefly the MOBILE SPA (iOS WKWebView / Android
4
+ // WebView), where the whole proxy stack lives in the webview JS (browser
5
+ // RTCPeerConnection) and there is exactly one inspectable page: itself.
6
+ //
7
+ // The transport that connects a remote inspector to this host (the SPA acting
8
+ // as an MSK-authenticated proxy host) is shell-specific and wired separately;
9
+ // this module is just the platform-agnostic dispatch + target it answers with.
10
+ import { installInspectAgent } from './agent/install.js';
11
+ import { buildTarget, dispatchToAgent } from './dispatch.js';
12
+ /** The id this host reports for its single (self) target. */
13
+ export const SELF_TARGET_ID = 'self';
14
+ export function createSelfInspectHost(opts) {
15
+ const agent = installInspectAgent({
16
+ onConsole: (e) => opts.onEvent?.(`inspect.console:${SELF_TARGET_ID}`, e),
17
+ onNetwork: (e) => opts.onEvent?.(`inspect.network:${SELF_TARGET_ID}`, e),
18
+ onPicked: (p) => opts.onEvent?.(`inspect.picked:${SELF_TARGET_ID}`, p),
19
+ });
20
+ return {
21
+ async dispatch(channel, payload = {}) {
22
+ if (channel === 'inspect.listTargets') {
23
+ return { targets: [buildTarget(SELF_TARGET_ID, opts.platform, agent.meta())] };
24
+ }
25
+ if (channel === 'inspect.screenshot') {
26
+ if (!opts.screenshot)
27
+ throw new Error('inspect.screenshot: no native capture on this shell');
28
+ return opts.screenshot({ ...payload, targetId: SELF_TARGET_ID });
29
+ }
30
+ // Everything else is an agent method (targetId stripped — there is only self).
31
+ return dispatchToAgent(agent, channel, payload);
32
+ },
33
+ stop() {
34
+ agent.stop();
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=selfHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selfHost.js","sourceRoot":"","sources":["../../src/inspect/selfHost.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAChF,6EAA6E;AAC7E,yEAAyE;AACzE,wEAAwE;AACxE,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAE/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAG7D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AAmBrC,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,KAAK,GAAG,mBAAmB,CAAC;QAChC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,mBAAmB,cAAc,EAAE,EAAE,CAAC,CAAC;QACxE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,mBAAmB,cAAc,EAAE,EAAE,CAAC,CAAC;QACxE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,kBAAkB,cAAc,EAAE,EAAE,CAAC,CAAC;KACvE,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAe,EAAE,UAAmC,EAAE;YACnE,IAAI,OAAO,KAAK,qBAAqB,EAAE,CAAC;gBACtC,OAAO,EAAE,OAAO,EAAE,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YACjF,CAAC;YACD,IAAI,OAAO,KAAK,oBAAoB,EAAE,CAAC;gBACrC,IAAI,CAAC,IAAI,CAAC,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;gBAC7F,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,GAAI,OAAwC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;YACrG,CAAC;YACD,+EAA+E;YAC/E,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;QACD,IAAI;YACF,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-app",
3
- "version": "0.1.715",
3
+ "version": "0.1.717",
4
4
  "type": "module",
5
5
  "comment:files": "Allowlist what ships to npm. dist = runtime; src = sourcemap targets (dist/*.js.map reference ../../src/); templates = CLI scaffold. Everything else at repo root (.pgdata local Postgres, coverage, assets/icons sources, test/, test-results/) is excluded by omission. The !negations strip the scaffold's installed deps + cruft (templates/node_modules is 200MB+ and must never ship). package.json/README/LICENSE ship automatically.",
6
6
  "files": [
@@ -52,6 +52,7 @@
52
52
  "./native/server": "./dist/native/server/index.js",
53
53
  "./inspect": "./dist/inspect/index.js",
54
54
  "./inspect/agent": "./dist/inspect/agent/install.js",
55
+ "./inspect/agent-bundle": "./dist/inspect/agent-bundle.js",
55
56
  "./inspect/ui": "./dist/inspect/ui/index.js"
56
57
  },
57
58
  "bin": {
@@ -59,7 +60,7 @@
59
60
  },
60
61
  "scripts": {
61
62
  "prebuild": "node -e \"const p=JSON.parse(require('fs').readFileSync('package.json','utf8'));require('fs').writeFileSync('src/cli/version.ts','// Auto-generated by prebuild — do not edit manually\\nexport const CLI_VERSION = '+JSON.stringify(p.version)+';\\n');\" && rm -rf dist",
62
- "build": "tsc && chmod +x dist/cli/index.js && cp src/markdown/client/*.css dist/markdown/client/ && mkdir -p dist/cli/publish/recipes && cp -R src/cli/publish/recipes/. dist/cli/publish/recipes/",
63
+ "build": "tsc && chmod +x dist/cli/index.js && cp src/markdown/client/*.css dist/markdown/client/ && mkdir -p dist/cli/publish/recipes && cp -R src/cli/publish/recipes/. dist/cli/publish/recipes/ && esbuild src/inspect/agent/bundle-entry.ts --bundle --format=iife --platform=browser --minify --outfile=dist/inspect/agent-bundle.js",
63
64
  "test": "vitest run",
64
65
  "test:e2e": "E2E=1 vitest run tests/cli/e2e-integration.test.ts",
65
66
  "test:e2e:full": "npx tsx tests/e2e/full-e2e.ts",
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.715";
2
+ export const CLI_VERSION = "0.1.717";
@@ -0,0 +1,8 @@
1
+ // Entry for the pre-bundled, injectable agent IIFE. The ugly-app build esbuilds
2
+ // this into dist/inspect/agent-bundle.js (a single self-contained script with no
3
+ // imports), which native shells read as text and inject at document-start —
4
+ // no runtime bundler needed on the host side.
5
+
6
+ import { installInspectAgent } from './install.js';
7
+
8
+ installInspectAgent();
@@ -7,3 +7,9 @@ export type { AgentEvents, AgentMeta, InspectAgent } from './agent/types.js';
7
7
  export { createInspectAgent, installInspectAgent } from './agent/install.js';
8
8
  export { InspectClient, type InspectTransport } from './client.js';
9
9
  export { buildTarget, dispatchToAgent, HOST_ONLY_CHANNELS } from './dispatch.js';
10
+ export {
11
+ createSelfInspectHost,
12
+ SELF_TARGET_ID,
13
+ type SelfInspectHost,
14
+ type SelfInspectHostOpts,
15
+ } from './selfHost.js';
@@ -0,0 +1,59 @@
1
+ // @vitest-environment jsdom
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
3
+ import { createSelfInspectHost, SELF_TARGET_ID } from './selfHost.js';
4
+ import type { Screenshot } from './protocol.js';
5
+
6
+ afterEach(() => {
7
+ // Reset the singleton agent between tests.
8
+ delete (window as { __uglyInspectAgent?: unknown }).__uglyInspectAgent;
9
+ });
10
+
11
+ describe('createSelfInspectHost', () => {
12
+ it('lists exactly one target (self) with the given platform', async () => {
13
+ document.title = 'Mobile App';
14
+ const host = createSelfInspectHost({ platform: 'ios' });
15
+ const res = (await host.dispatch('inspect.listTargets')) as { targets: { id: string; platform: string }[] };
16
+ expect(res.targets).toHaveLength(1);
17
+ expect(res.targets[0].id).toBe(SELF_TARGET_ID);
18
+ expect(res.targets[0].platform).toBe('ios');
19
+ });
20
+
21
+ it('routes inspect.eval to the in-page agent', async () => {
22
+ const host = createSelfInspectHost({ platform: 'android' });
23
+ const res = (await host.dispatch('inspect.eval', { expression: '21 * 2' })) as {
24
+ ok: boolean;
25
+ value: { value: number };
26
+ };
27
+ expect(res.ok).toBe(true);
28
+ expect(res.value.value).toBe(42);
29
+ });
30
+
31
+ it('captures the DOM via the agent', async () => {
32
+ document.body.innerHTML = '<main id="x">hi</main>';
33
+ const host = createSelfInspectHost({ platform: 'ios' });
34
+ const snap = (await host.dispatch('inspect.dom.capture')) as { root: { nodeName: string } };
35
+ expect(snap.root.nodeName).toBe('HTML');
36
+ });
37
+
38
+ it('delegates inspect.screenshot to the native capture callback', async () => {
39
+ const shot: Screenshot = { base64: 'AAAA', width: 390, height: 844, dpr: 3, format: 'png' };
40
+ const capture = vi.fn(async () => shot);
41
+ const host = createSelfInspectHost({ platform: 'ios', screenshot: capture });
42
+ const res = await host.dispatch('inspect.screenshot', { fullPage: true });
43
+ expect(res).toEqual(shot);
44
+ expect(capture).toHaveBeenCalledWith(expect.objectContaining({ targetId: SELF_TARGET_ID, fullPage: true }));
45
+ });
46
+
47
+ it('errors on screenshot when no native capture is provided', async () => {
48
+ const host = createSelfInspectHost({ platform: 'web' });
49
+ await expect(host.dispatch('inspect.screenshot', {})).rejects.toThrow(/no native capture/);
50
+ });
51
+
52
+ it('forwards live console events under the self event name', async () => {
53
+ const events: { event: string; data: unknown }[] = [];
54
+ createSelfInspectHost({ platform: 'android', onEvent: (event, data) => events.push({ event, data }) });
55
+ console.log('streamed-line');
56
+ const consoleEvt = events.find((e) => e.event === `inspect.console:${SELF_TARGET_ID}`);
57
+ expect(consoleEvt).toBeTruthy();
58
+ });
59
+ });
@@ -0,0 +1,58 @@
1
+ // A single-page inspect host: answers inspect.* for the CURRENT page only,
2
+ // routing to the in-page agent. This is the building block for shells that have
3
+ // no native cross-tab host — chiefly the MOBILE SPA (iOS WKWebView / Android
4
+ // WebView), where the whole proxy stack lives in the webview JS (browser
5
+ // RTCPeerConnection) and there is exactly one inspectable page: itself.
6
+ //
7
+ // The transport that connects a remote inspector to this host (the SPA acting
8
+ // as an MSK-authenticated proxy host) is shell-specific and wired separately;
9
+ // this module is just the platform-agnostic dispatch + target it answers with.
10
+
11
+ import { installInspectAgent } from './agent/install.js';
12
+ import { buildTarget, dispatchToAgent } from './dispatch.js';
13
+ import type { InspectPlatform, Screenshot, ScreenshotRequest } from './protocol.js';
14
+
15
+ /** The id this host reports for its single (self) target. */
16
+ export const SELF_TARGET_ID = 'self';
17
+
18
+ export interface SelfInspectHostOpts {
19
+ platform: InspectPlatform;
20
+ /** Screenshot delegate — on mobile this calls native (WKWebView.takeSnapshot /
21
+ * Android PixelCopy) via the uglyNative `capture.screenshot` channel. */
22
+ screenshot?: (req: ScreenshotRequest) => Promise<Screenshot>;
23
+ /** Forward live agent events to the proxy connection. Event names are the
24
+ * per-target dynamic form (`inspect.console:self`, `inspect.network:self`,
25
+ * `inspect.picked:self`). */
26
+ onEvent?: (event: string, data: unknown) => void;
27
+ }
28
+
29
+ export interface SelfInspectHost {
30
+ /** Route one inspect.* channel (targetId is ignored — there is only `self`). */
31
+ dispatch(channel: string, payload?: Record<string, unknown>): Promise<unknown>;
32
+ stop(): void;
33
+ }
34
+
35
+ export function createSelfInspectHost(opts: SelfInspectHostOpts): SelfInspectHost {
36
+ const agent = installInspectAgent({
37
+ onConsole: (e) => opts.onEvent?.(`inspect.console:${SELF_TARGET_ID}`, e),
38
+ onNetwork: (e) => opts.onEvent?.(`inspect.network:${SELF_TARGET_ID}`, e),
39
+ onPicked: (p) => opts.onEvent?.(`inspect.picked:${SELF_TARGET_ID}`, p),
40
+ });
41
+
42
+ return {
43
+ async dispatch(channel: string, payload: Record<string, unknown> = {}): Promise<unknown> {
44
+ if (channel === 'inspect.listTargets') {
45
+ return { targets: [buildTarget(SELF_TARGET_ID, opts.platform, agent.meta())] };
46
+ }
47
+ if (channel === 'inspect.screenshot') {
48
+ if (!opts.screenshot) throw new Error('inspect.screenshot: no native capture on this shell');
49
+ return opts.screenshot({ ...(payload as unknown as ScreenshotRequest), targetId: SELF_TARGET_ID });
50
+ }
51
+ // Everything else is an agent method (targetId stripped — there is only self).
52
+ return dispatchToAgent(agent, channel, payload);
53
+ },
54
+ stop() {
55
+ agent.stop();
56
+ },
57
+ };
58
+ }