surf-cli 2.9.0 → 2.10.0

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.
Files changed (37) hide show
  1. package/README.md +48 -4
  2. package/dist/content/accessibility-tree.js +11 -0
  3. package/dist/content/accessibility-tree.js.map +1 -0
  4. package/dist/content/visual-indicator.js +111 -0
  5. package/dist/content/visual-indicator.js.map +1 -0
  6. package/dist/manifest.json +11 -2
  7. package/dist/options/options.js +3 -3
  8. package/dist/options/options.js.map +1 -1
  9. package/dist/service-worker/index.js +61 -261
  10. package/dist/service-worker/index.js.map +1 -1
  11. package/native/activity-journal.cjs +55 -0
  12. package/native/chatgpt-client.cjs +2 -0
  13. package/native/cli.cjs +52 -278
  14. package/native/do-executor.cjs +52 -475
  15. package/native/do-parser.cjs +8 -249
  16. package/native/host-helpers.cjs +6 -14
  17. package/native/host-sessions.cjs +5 -1
  18. package/native/host.cjs +199 -1
  19. package/native/network-export.cjs +20 -17
  20. package/native/network-store.cjs +38 -58
  21. package/native/playbook-authoring.cjs +44 -0
  22. package/native/playbook-cli.cjs +157 -0
  23. package/native/playbook-client.cjs +259 -0
  24. package/native/playbook-receipts.cjs +109 -0
  25. package/native/playbook-records.cjs +208 -0
  26. package/native/playbook-runtime.cjs +177 -0
  27. package/native/playbooks.cjs +235 -0
  28. package/native/private-state.cjs +156 -0
  29. package/native/redaction.cjs +104 -0
  30. package/native/workflow-definition.cjs +368 -0
  31. package/native/workflow-runtime.cjs +225 -0
  32. package/package.json +2 -1
  33. package/playbooks/page/ops/read.json +22 -0
  34. package/playbooks/page/playbook.json +7 -0
  35. package/skills/surf/SKILL.md +41 -1
  36. package/dist/content/index.js +0 -116
  37. package/dist/content/index.js.map +0 -1
@@ -410,10 +410,13 @@ surf network.body --id "req-123" # Get response body
410
410
  surf network.curl --id "req-123" # Generate curl command
411
411
  surf network.origins # List origins with stats
412
412
  surf network.stats # Capture statistics
413
- surf network.export # Export all requests
413
+ surf network -vv --body-mode text --per-body-bytes 65536
414
+ surf network.export --har --output ./trace.har
414
415
  surf network.clear # Clear captured requests
415
416
  ```
416
417
 
418
+ Response-body capture supports `none`, `text`, and `all` modes plus per-body and per-tab-session byte caps. HAR exports carry body completeness metadata. Persistent network state is private under `~/.surf/state/network/` by default; configure `SURF_NETWORK_PATH` in the native host environment to change it.
419
+
417
420
  ## Console
418
421
 
419
422
  ```bash
@@ -582,6 +585,43 @@ surf workflow.validate workflow.json
582
585
 
583
586
  **Why use `do`?** Instead of 6-8 separate CLI calls with LLM orchestration between each, a workflow executes deterministically. Faster, cheaper, and more reliable.
584
587
 
588
+ ## Playbooks
589
+
590
+ Use `surf do` for a direct command sequence. Use a playbook for a reusable site capability with provenance, browser-session network execution, workflow fallback, and write-safety policy.
591
+
592
+ ```bash
593
+ surf playbook list
594
+ surf pb show page
595
+ surf pb ops page
596
+ surf use page read --json
597
+ ```
598
+
599
+ Resolution order is project (`./.surf/playbooks/`), user (`~/.surf/playbooks/`), then built-in. Provider compatibility commands stay on their validated command paths until provider playbooks have real login-flow validation. A write op requires `--write`; Surf records semantic intent before dispatch so a timeout or concurrent retry cannot silently double-submit.
600
+
601
+ Author from redacted recent activity when it contains only read/navigation behavior, or use an explicit record for richer evidence:
602
+
603
+ ```bash
604
+ surf pb suggest --since 1h
605
+ surf pb save example --op read --from-recent 1h
606
+ surf pb record start example --op read --network --watch
607
+ surf pb record mark "loaded results"
608
+ surf pb record stop --draft
609
+ surf pb save --from-record <record-id>
610
+ surf pb trace export --from-record <record-id> --har ./trace.har
611
+ surf pb export example --out ./example-playbook
612
+ surf pb import ./example-playbook
613
+ ```
614
+
615
+ Records, trace slices, receipts, and the bounded activity journal are private Surf state. Inputs and authentication headers are redacted by default. Use `--include-input-values` only when the saved values are necessary and acceptable.
616
+
617
+ Client projections replay a validated read endpoint and never embed captured browser credentials:
618
+
619
+ ```bash
620
+ surf pb client derive example --op read --from-record <record-id> --request-id <request-id> --out ./client
621
+ surf pb client export example --op read --out ./client
622
+ surf pb client verify ./client
623
+ ```
624
+
585
625
  ## Error Diagnostics
586
626
 
587
627
  ```bash
@@ -1,116 +0,0 @@
1
- var e=`59, 178, 191`,t=1e4,n=null,r=null,i=null,a=!1,o=!1,s=!1,c=!1,l=null,u=t,d=!1,f=!1,p=window===window.top;p&&(chrome.storage.local.get(`heartbeatInterval`).then(({heartbeatInterval:e})=>{e&&typeof e==`number`&&(u=e*1e3)}),chrome.storage.onChanged.addListener((e,t)=>{if(t===`local`&&e.heartbeatInterval){let t=e.heartbeatInterval.newValue;t&&typeof t==`number`&&(u=t*1e3,o&&l&&(clearInterval(l),m()))}}));function m(){l=window.setInterval(async()=>{try{(await chrome.runtime.sendMessage({type:`STATIC_INDICATOR_HEARTBEAT`}))?.success||S()}catch{S()}},u)}function h(){if(document.getElementById(`pi-agent-styles`))return;let t=document.createElement(`style`);t.id=`pi-agent-styles`,t.textContent=`
2
- @keyframes pi-pulse {
3
- 0% {
4
- box-shadow:
5
- inset 0 0 10px rgba(${e}, 0.5),
6
- inset 0 0 20px rgba(${e}, 0.3),
7
- inset 0 0 30px rgba(${e}, 0.1);
8
- }
9
- 50% {
10
- box-shadow:
11
- inset 0 0 15px rgba(${e}, 0.7),
12
- inset 0 0 25px rgba(${e}, 0.5),
13
- inset 0 0 35px rgba(${e}, 0.2);
14
- }
15
- 100% {
16
- box-shadow:
17
- inset 0 0 10px rgba(${e}, 0.5),
18
- inset 0 0 20px rgba(${e}, 0.3),
19
- inset 0 0 30px rgba(${e}, 0.1);
20
- }
21
- }
22
- `,document.head.appendChild(t)}function g(){let t=document.createElement(`div`);return t.id=`pi-agent-glow`,t.style.cssText=`
23
- position: fixed;
24
- top: 0;
25
- left: 0;
26
- right: 0;
27
- bottom: 0;
28
- pointer-events: none;
29
- z-index: 2147483646;
30
- opacity: 0;
31
- transition: opacity 0.3s ease-in-out;
32
- animation: pi-pulse 2s ease-in-out infinite;
33
- box-shadow:
34
- inset 0 0 10px rgba(${e}, 0.5),
35
- inset 0 0 20px rgba(${e}, 0.3),
36
- inset 0 0 30px rgba(${e}, 0.1);
37
- `,t}function _(){let t=document.createElement(`div`);t.id=`pi-agent-stop-container`,t.style.cssText=`
38
- position: fixed;
39
- bottom: 16px;
40
- left: 50%;
41
- transform: translateX(-50%);
42
- display: flex;
43
- justify-content: center;
44
- align-items: center;
45
- pointer-events: none;
46
- z-index: 2147483647;
47
- `;let n=document.createElement(`button`);return n.id=`pi-agent-stop-button`,n.innerHTML=`
48
- <svg width="16" height="16" viewBox="0 0 256 256" fill="currentColor" style="margin-right: 12px; vertical-align: middle;">
49
- <path d="M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm40-112v56a12,12,0,0,1-12,12H100a12,12,0,0,1-12-12V100a12,12,0,0,1,12-12h56A12,12,0,0,1,168,100Z"></path>
50
- </svg>
51
- <span style="vertical-align: middle;">Stop Surf</span>
52
- `,n.style.cssText=`
53
- position: relative;
54
- transform: translateY(100px);
55
- padding: 12px 16px;
56
- background: #FAF9F5;
57
- color: #141413;
58
- border: 0.5px solid rgba(31, 30, 29, 0.4);
59
- border-radius: 12px;
60
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
61
- font-size: 14px;
62
- font-weight: 600;
63
- cursor: pointer;
64
- display: inline-flex;
65
- align-items: center;
66
- justify-content: center;
67
- box-shadow:
68
- 0 40px 80px rgba(${e}, 0.24),
69
- 0 4px 14px rgba(${e}, 0.24);
70
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
71
- opacity: 0;
72
- user-select: none;
73
- pointer-events: auto;
74
- white-space: nowrap;
75
- margin: 0 auto;
76
- `,n.addEventListener(`mouseenter`,()=>{a&&(n.style.background=`#F5F4F0`)}),n.addEventListener(`mouseleave`,()=>{a&&(n.style.background=`#FAF9F5`)}),n.addEventListener(`click`,async()=>{await chrome.runtime.sendMessage({type:`STOP_AGENT`,fromTabId:`CURRENT_TAB`})}),t.appendChild(n),t}function v(){let t=document.createElement(`div`);t.id=`pi-agent-static-indicator`,t.innerHTML=`
77
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" style="width: 16px; height: 16px; margin-right: 8px; flex-shrink: 0;">
78
- <circle cx="8" cy="8" r="7" fill="rgb(${e})"/>
79
- <text x="8" y="11" font-size="9" fill="white" text-anchor="middle" font-weight="bold">π</text>
80
- </svg>
81
- <span style="color: #141413; font-size: 14px;">Surf is active in this tab group</span>
82
- <div style="width: 0.5px; height: 32px; background: rgba(31, 30, 29, 0.15); margin: 0 8px;"></div>
83
- <button id="pi-static-chat-button" style="display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; border-radius: 8px; transition: background 0.2s;">
84
- <svg width="20" height="20" viewBox="0 0 20 20" fill="#141413">
85
- <path d="M10 2.5C14.1421 2.5 17.5 5.85786 17.5 10C17.5 14.1421 14.1421 17.5 10 17.5H3C2.79779 17.5 2.61549 17.3782 2.53809 17.1914C2.4607 17.0046 2.50349 16.7895 2.64648 16.6465L4.35547 14.9365C3.20124 13.6175 2.5 11.8906 2.5 10C2.5 5.85786 5.85786 2.5 10 2.5Z"/>
86
- </svg>
87
- </button>
88
- <button id="pi-static-close-button" style="display: inline-flex; align-items: center; justify-content: center; padding: 6px; background: transparent; border: none; cursor: pointer; width: 32px; height: 32px; margin-left: 4px; border-radius: 8px; transition: background 0.2s;">
89
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
90
- <path d="M15.1464 4.14642C15.3417 3.95121 15.6582 3.95118 15.8534 4.14642C16.0486 4.34168 16.0486 4.65822 15.8534 4.85346L10.7069 9.99997L15.8534 15.1465C16.0486 15.3417 16.0486 15.6583 15.8534 15.8535C15.6826 16.0244 15.4186 16.0461 15.2245 15.918L15.1464 15.8535L9.99989 10.707L4.85338 15.8535C4.65813 16.0486 4.34155 16.0486 4.14634 15.8535C3.95115 15.6583 3.95129 15.3418 4.14634 15.1465L9.29286 9.99997L4.14634 4.85346C3.95129 4.65818 3.95115 4.34162 4.14634 4.14642C4.34154 3.95128 4.65812 3.95138 4.85338 4.14642L9.99989 9.29294L15.1464 4.14642Z" fill="#141413"/>
91
- </svg>
92
- </button>
93
- `,t.style.cssText=`
94
- position: fixed;
95
- bottom: 16px;
96
- left: 50%;
97
- transform: translateX(-50%);
98
- display: inline-flex;
99
- align-items: center;
100
- padding: 6px 6px 6px 16px;
101
- background: #FAF9F5;
102
- border: 0.5px solid rgba(31, 30, 29, 0.30);
103
- border-radius: 14px;
104
- box-shadow: 0 40px 80px 0 rgba(0, 0, 0, 0.15);
105
- z-index: 2147483647;
106
- pointer-events: none;
107
- white-space: nowrap;
108
- user-select: none;
109
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
110
- `;let n=t.querySelector(`#pi-static-chat-button`),r=t.querySelector(`#pi-static-close-button`);return n&&(n.style.pointerEvents=`auto`,n.addEventListener(`mouseenter`,()=>n.style.background=`#F0EEE6`),n.addEventListener(`mouseleave`,()=>n.style.background=`transparent`),n.addEventListener(`click`,async()=>{await chrome.runtime.sendMessage({type:`OPEN_SIDEPANEL`})})),r&&(r.style.pointerEvents=`auto`,r.addEventListener(`mouseenter`,()=>r.style.background=`#F0EEE6`),r.addEventListener(`mouseleave`,()=>r.style.background=`transparent`),r.addEventListener(`click`,async()=>{await chrome.runtime.sendMessage({type:`DISMISS_STATIC_INDICATOR`}),S()})),t}function y(){if(!document.body){d||(d=!0,window.addEventListener(`DOMContentLoaded`,()=>{d&&(d=!1,y())},{once:!0}));return}d=!1,!a&&(a=!0,h(),n?n.style.display=``:(n=g(),document.body.appendChild(n)),r?r.style.display=``:(r=_(),document.body.appendChild(r)),requestAnimationFrame(()=>{if(n&&(n.style.opacity=`1`),r){let e=r.querySelector(`#pi-agent-stop-button`);e&&(e.style.transform=`translateY(0)`,e.style.opacity=`1`)}}))}function b(){if(d=!1,a){if(a=!1,n&&(n.style.opacity=`0`),r){let e=r.querySelector(`#pi-agent-stop-button`);e&&(e.style.transform=`translateY(100px)`,e.style.opacity=`0`)}setTimeout(()=>{a||(n?.parentNode&&(n.parentNode.removeChild(n),n=null),r?.parentNode&&(r.parentNode.removeChild(r),r=null))},300)}}function x(){if(!document.body){f||(f=!0,window.addEventListener(`DOMContentLoaded`,()=>{f&&(f=!1,x())},{once:!0}));return}f=!1,!o&&(o=!0,i?i.style.display=``:(i=v(),document.body.appendChild(i)),l&&clearInterval(l),m())}function S(){f=!1,o&&(o=!1,l&&=(clearInterval(l),null),i?.parentNode&&(i.parentNode.removeChild(i),i=null))}p&&(window.__piVisualIndicatorMessageHandler=e=>{switch(e){case`SHOW_AGENT_INDICATORS`:y();break;case`HIDE_AGENT_INDICATORS`:b();break;case`HIDE_FOR_TOOL_USE`:s=a||d,c=o||f,d=!1,f=!1,n&&(n.style.display=`none`),r&&(r.style.display=`none`),i&&o&&(i.style.display=`none`);break;case`SHOW_AFTER_TOOL_USE`:s&&(a?(n&&(n.style.display=``),r&&(r.style.display=``)):y()),c&&(o&&i?i.style.display=``:x()),s=!1,c=!1;break;case`SHOW_STATIC_INDICATOR`:x();break;case`HIDE_STATIC_INDICATOR`:S();break}},window.addEventListener(`beforeunload`,()=>{b(),S()}));var C=new Set(`alert.alertdialog.application.article.banner.blockquote.button.caption.cell.checkbox.code.columnheader.combobox.complementary.contentinfo.definition.deletion.dialog.directory.document.emphasis.feed.figure.form.generic.grid.gridcell.group.heading.img.insertion.link.list.listbox.listitem.log.main.mark.marquee.math.menu.menubar.menuitem.menuitemcheckbox.menuitemradio.meter.navigation.none.note.option.paragraph.presentation.progressbar.radio.radiogroup.region.row.rowgroup.rowheader.scrollbar.search.searchbox.separator.slider.spinbutton.status.strong.subscript.superscript.switch.tab.table.tablist.tabpanel.term.textbox.time.timer.toolbar.tooltip.tree.treegrid.treeitem`.split(`.`));function w(e){let t=e.tagName.toLowerCase();if([`button`,`input`,`select`,`textarea`].includes(t))return!e.disabled;if(t===`a`&&e.hasAttribute(`href`))return!0;if(e.hasAttribute(`tabindex`)){let t=parseInt(e.getAttribute(`tabindex`)||``,10);return!isNaN(t)&&t>=0}return e.getAttribute(`contenteditable`)===`true`}function T(e){let t=e.getAttribute(`role`);if(!t)return null;let n=t.split(/\s+/).filter(e=>e);for(let e of n)if(C.has(e))return e;return null}function E(e){let t=e.tagName.toLowerCase(),n=e.getAttribute(`type`),r={a:e=>e.hasAttribute(`href`)?`link`:`generic`,article:`article`,aside:`complementary`,button:`button`,datalist:`listbox`,dd:`definition`,details:`group`,dialog:`dialog`,dt:`term`,fieldset:`group`,figure:`figure`,footer:e=>e.closest(`article, aside, main, nav, section`)?`generic`:`contentinfo`,form:e=>e.hasAttribute(`aria-label`)||e.hasAttribute(`aria-labelledby`)?`form`:`generic`,h1:`heading`,h2:`heading`,h3:`heading`,h4:`heading`,h5:`heading`,h6:`heading`,header:e=>e.closest(`article, aside, main, nav, section`)?`generic`:`banner`,hr:`separator`,img:e=>e.getAttribute(`alt`)===``?`presentation`:`img`,li:`listitem`,main:`main`,math:`math`,menu:`list`,meter:`meter`,nav:`navigation`,ol:`list`,optgroup:`group`,option:`option`,output:`status`,p:`paragraph`,progress:`progressbar`,search:`search`,section:e=>e.hasAttribute(`aria-label`)||e.hasAttribute(`aria-labelledby`)?`region`:`generic`,select:e=>{let t=e;return t.hasAttribute(`multiple`)||t.size&&t.size>1?`listbox`:`combobox`},table:`table`,tbody:`rowgroup`,td:`cell`,textarea:`textbox`,tfoot:`rowgroup`,th:`columnheader`,thead:`rowgroup`,time:`time`,tr:`row`,ul:`list`};if(t===`input`)return{button:`button`,checkbox:`checkbox`,email:`textbox`,file:`button`,image:`button`,number:`spinbutton`,radio:`radio`,range:`slider`,reset:`button`,search:`searchbox`,submit:`button`,tel:`textbox`,text:`textbox`,url:`textbox`}[n||``]||`textbox`;let i=r[t];return typeof i==`function`?i(e):i||`generic`}function D(e){let t=T(e);return!t||(t===`none`||t===`presentation`)&&w(e)?E(e):t}window.__piElementMap||(window.__piElementMap={});var O=0;function k(e,t,n){let r=e._piRef;if(r&&r.role===t&&r.name===n)return r.ref;let i=`e${++O}`;return e._piRef={role:t,name:n,ref:i},i}function A(){let e=[];return document.querySelectorAll(`[role="dialog"], [role="alertdialog"], dialog[open]`).forEach(t=>{let n=window.getComputedStyle(t);if(!(n.display!==`none`&&n.visibility!==`hidden`&&n.opacity!==`0`&&t.offsetWidth>0&&t.offsetHeight>0))return;let r=t.getAttribute(`role`)||`dialog`,i=t.getAttribute(`aria-label`)||t.querySelector(`[role="heading"], h1, h2, h3`)?.textContent?.trim()||`Dialog`;i.length>100&&(i=i.substring(0,100)+`...`),e.push({type:r,description:`${r}: ${i}`,clearedBy:`computer(action=key, text=Escape)`})}),e}var j={wait(e){return new Promise(t=>setTimeout(t,e))},async waitForSelector(e,t={}){let{state:n=`visible`,timeout:r=2e4}=t,i=e=>{if(!e)return!1;let t=window.getComputedStyle(e);return t.display!==`none`&&t.visibility!==`hidden`&&t.opacity!==`0`&&e.offsetWidth>0&&e.offsetHeight>0},a=()=>{let t=document.querySelector(e);switch(n){case`attached`:return t;case`detached`:return t?null:document.body;case`hidden`:return t?i(t)?null:t:document.body;default:return i(t)?t:null}};return new Promise((t,i)=>{let o=a();if(o){t(n===`detached`||n===`hidden`?null:o);return}let s=new MutationObserver(()=>{let e=a();e&&(s.disconnect(),clearTimeout(c),t(n===`detached`||n===`hidden`?null:e))}),c=setTimeout(()=>{s.disconnect(),i(Error(`Timeout waiting for "${e}" to be ${n}`))},r);s.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`style`,`class`,`hidden`]})})},async waitForText(e,t={}){let{selector:n,timeout:r=2e4}=t,i=()=>{let t=n?document.querySelector(n):document.body;if(!t)return null;let r=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;r.nextNode();)if(r.currentNode.textContent?.includes(e))return r.currentNode.parentElement;return null};return new Promise((t,n)=>{let a=i();if(a){t(a);return}let o=new MutationObserver(()=>{let e=i();e&&(o.disconnect(),clearTimeout(s),t(e))}),s=setTimeout(()=>{o.disconnect(),n(Error(`Timeout waiting for text "${e}"`))},r);o.observe(document.documentElement,{childList:!0,subtree:!0,characterData:!0})})},async waitForHidden(e,t=2e4){await j.waitForSelector(e,{state:`hidden`,timeout:t})},getByRole(e,t={}){let{name:n}=t,r={button:[`button`,`input[type="button"]`,`input[type="submit"]`,`input[type="reset"]`],link:[`a[href]`],textbox:[`input:not([type])`,`input[type="text"]`,`input[type="email"]`,`input[type="password"]`,`input[type="search"]`,`input[type="tel"]`,`input[type="url"]`,`textarea`],checkbox:[`input[type="checkbox"]`],radio:[`input[type="radio"]`],combobox:[`select`],heading:[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`],list:[`ul`,`ol`],listitem:[`li`],navigation:[`nav`],main:[`main`],banner:[`header`],contentinfo:[`footer`],form:[`form`],img:[`img`],table:[`table`]},i=[];i.push(...document.querySelectorAll(`[role="${e}"]`));let a=r[e];if(a)for(let e of a)i.push(...document.querySelectorAll(`${e}:not([role])`));if(!n)return i[0]||null;let o=n.toLowerCase().trim();for(let e of i){let t=e.getAttribute(`aria-label`)?.toLowerCase().trim(),n=e.textContent?.toLowerCase().trim(),r=e.getAttribute(`title`)?.toLowerCase().trim(),i=e.getAttribute(`placeholder`)?.toLowerCase().trim();if(t===o||n===o||r===o||i===o||t?.includes(o)||n?.includes(o))return e}return null}};window.__piHelpers||(window.__piHelpers=j,window.piHelpers=j);function M(){return window.__piElementMap}function N(e=`interactive`,t=15,n,r=!1,i=!1){try{window.__piRefs={};function a(e){return D(e)}function o(e){let t=e.tagName.toLowerCase(),n=e.getAttribute(`aria-labelledby`);if(n){let e=n.split(/\s+/).map(e=>document.getElementById(e)?.textContent?.trim()||``).filter(Boolean);if(e.length){let t=e.join(` `);return t.length>100?t.substring(0,100)+`...`:t}}if(t===`select`){let t=e,n=t.querySelector(`option[selected]`)||(t.selectedIndex>=0?t.options[t.selectedIndex]:null);if(n?.textContent?.trim())return n.textContent.trim()}let r=e.getAttribute(`aria-label`);if(r?.trim())return r.trim();let i=e.getAttribute(`placeholder`);if(i?.trim())return i.trim();let a=e.getAttribute(`title`);if(a?.trim())return a.trim();let o=e.getAttribute(`alt`);if(o?.trim())return o.trim();if(e.id){let t=document.querySelector(`label[for="${e.id}"]`);if(t?.textContent?.trim())return t.textContent.trim()}if(t===`input`){let t=e,n=e.getAttribute(`type`)||``,r=e.getAttribute(`value`);if(n===`submit`&&r?.trim())return r.trim();if(t.value&&t.value.length<50&&t.value.trim())return t.value.trim()}if([`button`,`a`,`summary`].includes(t)){let t=e.textContent||``;if(t.trim())return t.trim()}if(/^h[1-6]$/.test(t)){let t=e.textContent;if(t?.trim()){let e=t.trim();return e.length>100?e.substring(0,100)+`...`:e}}if(t===`img`)return``;let s=``;for(let t of e.childNodes)t.nodeType===Node.TEXT_NODE&&(s+=t.textContent);if(s?.trim()&&s.trim().length>=3){let e=s.trim();return e.length>100?e.substring(0,100)+`...`:e}return``}function s(e){let t={},n=e.getAttribute(`aria-checked`);n===`true`?t.checked=!0:n===`false`?t.checked=!1:n===`mixed`?t.checked=`mixed`:e instanceof HTMLInputElement&&(e.type===`checkbox`||e.type===`radio`)&&(e.type===`checkbox`&&e.indeterminate?t.checked=`mixed`:t.checked=e.checked);let r=e instanceof HTMLButtonElement||e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement;(e.getAttribute(`aria-disabled`)===`true`||r&&e.disabled||e.closest(`fieldset:disabled`))&&(t.disabled=!0);let i=e.getAttribute(`aria-expanded`);i===`true`?t.expanded=!0:i===`false`&&(t.expanded=!1);let a=e.getAttribute(`aria-pressed`);a===`true`?t.pressed=!0:a===`false`?t.pressed=!1:a===`mixed`&&(t.pressed=`mixed`);let o=e.getAttribute(`aria-selected`);o===`true`?t.selected=!0:o===`false`&&(t.selected=!1);let s=e.getAttribute(`aria-current`);s&&s!==`false`&&(t.active=!0);let c=e.tagName.toLowerCase();if(/^h[1-6]$/.test(c))t.level=parseInt(c[1],10);else{let n=e.getAttribute(`aria-level`);n&&(t.level=parseInt(n,10))}return t}function c(e){let t=[];return e.checked!==void 0&&t.push(e.checked===`mixed`?`[checked=mixed]`:e.checked?`[checked]`:`[unchecked]`),e.disabled&&t.push(`[disabled]`),e.expanded!==void 0&&t.push(e.expanded?`[expanded]`:`[collapsed]`),e.pressed!==void 0&&t.push(e.pressed===`mixed`?`[pressed=mixed]`:e.pressed?`[pressed]`:`[not-pressed]`),e.selected!==void 0&&t.push(e.selected?`[selected]`:`[not-selected]`),e.active&&t.push(`[active]`),e.level!==void 0&&t.push(`[level=${e.level}]`),t.join(` `)}function l(e){let t=window.getComputedStyle(e);return t.display!==`none`&&t.visibility!==`hidden`&&t.opacity!==`0`&&e.offsetWidth>0&&e.offsetHeight>0}function u(e){let t=e.tagName.toLowerCase();return[`a`,`button`,`input`,`select`,`textarea`,`details`,`summary`].includes(t)||e.hasAttribute(`onclick`)||e.hasAttribute(`tabindex`)||e.getAttribute(`role`)===`button`||e.getAttribute(`role`)===`link`||e.getAttribute(`contenteditable`)===`true`}function d(e){let t=e.tagName.toLowerCase();return[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`nav`,`main`,`header`,`footer`,`section`,`article`,`aside`].includes(t)||e.hasAttribute(`role`)}function f(e){return window.getComputedStyle(e).cursor===`pointer`}function p(e,t){let n=e.tagName.toLowerCase();if([`script`,`style`,`meta`,`link`,`title`,`noscript`].includes(n)||t.filter!==`all`&&e.getAttribute(`aria-hidden`)===`true`||t.filter!==`all`&&!l(e))return!1;if(t.filter!==`all`&&!t.refId){let t=e.getBoundingClientRect();if(!(t.top<window.innerHeight&&t.bottom>0&&t.left<window.innerWidth&&t.right>0))return!1}if(t.filter===`interactive`)return u(e);if(u(e)||d(e)||o(e).length>0)return!0;let r=a(e);return t.compact&&new Set([`generic`,`group`,`region`,`article`,`section`,`complementary`]).has(r)&&o(e).length===0?!1:r!==`generic`&&r!==`img`}function m(r,l){let u=[],d={filter:e,refId:n||null,compact:i},h=M(),g=p(r,d)||n&&l===0;if(g){let e=a(r),t=o(r),n=s(r),i=k(r,e,t);window.__piRefs[i]=r,h[i]={element:new WeakRef(r),role:e,name:t};let d=`${` `.repeat(l)}${e}`;if(t){let e=t.replace(/\s+/g,` `).replace(/"/g,`\\"`);d+=` "${e}"`}d+=` [${i}]`;let p=c(n);p&&(d+=` ${p}`),f(r)&&(d+=` [cursor=pointer]`);let m=r.getAttribute(`href`);m&&(d+=` href="${m}"`);let g=r.getAttribute(`type`);g&&(d+=` type="${g}"`);let _=r.getAttribute(`placeholder`);_&&(d+=` placeholder="${_}"`),u.push(d)}if(l<t)for(let e of r.children)u.push(...m(e,g?l+1:l));return u}function h(e){return e.replace(/\[e\d+\]/g,`[REF]`)}function g(e){let t=new Map;for(let n of e){if(!n.trim())continue;let e=h(n);t.set(e,(t.get(e)||0)+1)}return t}function _(e,t){let n=e.split(`
111
- `),r=t.split(`
112
- `),i=g(n),a=g(r),o=[],s=[];for(let e of r){if(!e.trim())continue;let t=h(e),n=i.get(t)||0;(a.get(t)||0)>n&&(o.push(e),i.set(t,n+1))}let c=g(n);for(let e of n){if(!e.trim())continue;let t=h(e),n=c.get(t)||0;n>(a.get(t)||0)&&(s.push(e),c.set(t,n-1))}if(o.length===0&&s.length===0)return{diff:`[NO CHANGES]`,hasChanges:!1};let l=[];return s.length>0&&l.push(...s.map(e=>`- ${e}`)),o.length>0&&l.push(...o.map(e=>`+ ${e}`)),{diff:l.join(`
113
- `),hasChanges:!0}}let v=M(),y=null;if(n){let e=v[n];if(!e)return{error:`Element with ref_id '${n}' not found. Use read_page without ref_id to get current elements.`,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}};let t=e.element.deref();if(!t)return delete v[n],{error:`Element with ref_id '${n}' no longer exists. Use read_page without ref_id to get current elements.`,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}};y=t}else y=document.body;let b=y?m(y,0):[];for(let e of Object.keys(v))v[e].element.deref()||delete v[e];let x=b.join(`
114
- `);if(x.length>5e4)return{error:`Output exceeds 50000 character limit (${x.length} characters). Try using filter="interactive" or specify a ref_id.`,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}};let S=A(),C,w=!1,T=window.__piLastSnapshot;return!r&&!n&&T&&Date.now()-T.timestamp<5e3&&(C=_(T.content,x).diff,w=!0),window.__piLastSnapshot={content:x,timestamp:Date.now()},{pageContent:x+`\n\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,diff:w?C:void 0,viewport:{width:window.innerWidth,height:window.innerHeight},modalStates:S.length>0?S:void 0,modalLimitations:`Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.`,isIncremental:w}}catch(e){return{error:`Error generating accessibility tree: ${e instanceof Error?e.message:`Unknown error`}`,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}}}}function P(e){return e.length?/[\n\r]/.test(e)||/^[\s]/.test(e)||/[\s]$/.test(e)||/[:"{}[\]]/.test(e)?`"`+e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`).replace(/\r/g,`\\r`)+`"`:e:`""`}function F(e=`interactive`,t=15){try{window.__piRefs={};let n=[];function r(e){return D(e)}function i(e){let t=e.tagName.toLowerCase(),n=e.getAttribute(`aria-labelledby`);if(n){let e=n.split(/\s+/).map(e=>document.getElementById(e)?.textContent?.trim()||``).filter(Boolean);if(e.length){let t=e.join(` `);return t.length>100?t.substring(0,100)+`...`:t}}if(t===`select`){let t=e,n=t.querySelector(`option[selected]`)||(t.selectedIndex>=0?t.options[t.selectedIndex]:null);if(n?.textContent?.trim())return n.textContent.trim()}let r=e.getAttribute(`aria-label`);if(r?.trim())return r.trim();let i=e.getAttribute(`placeholder`);if(i?.trim())return i.trim();let a=e.getAttribute(`title`);if(a?.trim())return a.trim();let o=e.getAttribute(`alt`);if(o?.trim())return o.trim();if(e.id){let t=document.querySelector(`label[for="${e.id}"]`);if(t?.textContent?.trim())return t.textContent.trim()}if(t===`input`){let t=e,n=e.getAttribute(`type`)||``,r=e.getAttribute(`value`);if(n===`submit`&&r?.trim())return r.trim();if(t.value&&t.value.length<50&&t.value.trim())return t.value.trim()}if([`button`,`a`,`summary`].includes(t)){let t=e.textContent||``;if(t.trim())return t.trim()}if(/^h[1-6]$/.test(t)){let t=e.textContent;if(t?.trim()){let e=t.trim();return e.length>100?e.substring(0,100)+`...`:e}}if(t===`img`)return``;let s=``;for(let t of e.childNodes)t.nodeType===Node.TEXT_NODE&&(s+=t.textContent);if(s?.trim()&&s.trim().length>=3){let e=s.trim();return e.length>100?e.substring(0,100)+`...`:e}return``}function a(e){let t={},n=e.getAttribute(`aria-checked`);n===`true`?t.checked=!0:n===`false`?t.checked=!1:n===`mixed`?t.checked=`mixed`:e instanceof HTMLInputElement&&(e.type===`checkbox`||e.type===`radio`)&&(e.type===`checkbox`&&e.indeterminate?t.checked=`mixed`:t.checked=e.checked);let r=e instanceof HTMLButtonElement||e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement;(e.getAttribute(`aria-disabled`)===`true`||r&&e.disabled||e.closest(`fieldset:disabled`))&&(t.disabled=!0);let i=e.getAttribute(`aria-expanded`);i===`true`?t.expanded=!0:i===`false`&&(t.expanded=!1);let a=e.getAttribute(`aria-pressed`);a===`true`?t.pressed=!0:a===`false`?t.pressed=!1:a===`mixed`&&(t.pressed=`mixed`);let o=e.getAttribute(`aria-selected`);o===`true`?t.selected=!0:o===`false`&&(t.selected=!1);let s=e.getAttribute(`aria-current`);s&&s!==`false`&&(t.active=!0);let c=e.tagName.toLowerCase();if(/^h[1-6]$/.test(c))t.level=parseInt(c[1],10);else{let n=e.getAttribute(`aria-level`);n&&(t.level=parseInt(n,10))}return t}function o(e){let t=[];return e.checked!==void 0&&t.push(e.checked===`mixed`?`[checked=mixed]`:e.checked?`[checked]`:`[unchecked]`),e.disabled&&t.push(`[disabled]`),e.expanded!==void 0&&t.push(e.expanded?`[expanded]`:`[collapsed]`),e.pressed!==void 0&&t.push(e.pressed===`mixed`?`[pressed=mixed]`:e.pressed?`[pressed]`:`[not-pressed]`),e.selected!==void 0&&t.push(e.selected?`[selected]`:`[not-selected]`),e.active&&t.push(`[active]`),e.level!==void 0&&t.push(`[level=${e.level}]`),t.join(` `)}function s(e){let t=window.getComputedStyle(e);return t.display!==`none`&&t.visibility!==`hidden`&&t.opacity!==`0`&&e.offsetWidth>0&&e.offsetHeight>0}function c(e){let t=e.tagName.toLowerCase();return[`a`,`button`,`input`,`select`,`textarea`,`details`,`summary`].includes(t)||e.hasAttribute(`onclick`)||e.hasAttribute(`tabindex`)||e.getAttribute(`role`)===`button`||e.getAttribute(`role`)===`link`||e.getAttribute(`contenteditable`)===`true`}function l(e){let t=e.tagName.toLowerCase();return[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`nav`,`main`,`header`,`footer`,`section`,`article`,`aside`].includes(t)||e.hasAttribute(`role`)}function u(e){return window.getComputedStyle(e).cursor===`pointer`}function d(e,t,n,r){let i=e;t&&(i+=` `+P(t));let a=k(n,e,t);window.__piRefs[a]=n,i+=` [ref=${a}]`;let s=o(r);return s&&(i+=` ${s}`),u(n)&&(i+=` [cursor=pointer]`),i}function f(e){let t={},n=e.getAttribute(`href`);n&&(t.url=n);let r=e.getAttribute(`placeholder`);return r&&(t.placeholder=r),t}function p(o,u,m){if(u>t)return;let h=o.tagName.toLowerCase();if([`script`,`style`,`meta`,`link`,`title`,`noscript`].includes(h)||e!==`all`&&o.getAttribute(`aria-hidden`)===`true`||e!==`all`&&!s(o))return;if(e!==`all`){let e=o.getBoundingClientRect();if(!(e.top<window.innerHeight&&e.bottom>0&&e.left<window.innerWidth&&e.right>0))return}let g=r(o),_=i(o),v=a(o),y=c(o),b=l(o),x=_.length>0,S;if(S=e===`interactive`?y:e===`all`||y||b||x||g!==`generic`&&g!==`img`,S){let e=` `.repeat(u),t=d(g,_,o,v),r=f(o),i=[];for(let e of o.children)i.push(e);let a=i.length>0,s=Object.keys(r).length>0;if(!a&&!s)n.push(`${e}- ${t}`);else{n.push(`${e}- ${t}:`);for(let[t,i]of Object.entries(r))n.push(`${e} - /${t}: ${P(i)}`);for(let e of i)p(e,u+1,!0)}}else for(let e of o.children)p(e,u,m)}p(document.body,0,!1);let m=n.join(`
115
- `);return m.length>5e4?{error:`Output exceeds 50000 character limit (${m.length} characters). Try using filter="interactive".`,yaml:``,viewport:{width:window.innerWidth,height:window.innerHeight}}:{yaml:m+`\n\n[Viewport: ${window.innerWidth}x${window.innerHeight}]`,viewport:{width:window.innerWidth,height:window.innerHeight}}}catch(e){return{error:`Error generating YAML tree: ${e instanceof Error?e.message:`Unknown error`}`,yaml:``,viewport:{width:window.innerWidth,height:window.innerHeight}}}}function I(e){let t=M(),n=t[e],r;if(n&&(r=n.element.deref(),r||delete t[e]),!r&&window.__piRefs&&(r=window.__piRefs[e]),!r)return{x:0,y:0,error:`Element ${e} not found. Use read_page to get current elements.`};let i=r.getBoundingClientRect();return{x:Math.round(i.left+i.width/2),y:Math.round(i.top+i.height/2)}}function L(e,t){let n=M(),r=n[e],i;if(r&&(i=r.element.deref(),i||delete n[e]),!i&&window.__piRefs&&(i=window.__piRefs[e]),!i)return{success:!1,error:`Element ${e} not found. Use read_page to get current elements.`};let a=i.tagName.toLowerCase();try{if(a===`input`){let e=i,n=e.type.toLowerCase();n===`checkbox`||n===`radio`?(e.checked=!!t,e.dispatchEvent(new Event(`change`,{bubbles:!0}))):(e.value=String(t),e.dispatchEvent(new Event(`input`,{bubbles:!0})),e.dispatchEvent(new Event(`change`,{bubbles:!0})))}else if(a===`textarea`){let e=i;e.value=String(t),e.dispatchEvent(new Event(`input`,{bubbles:!0})),e.dispatchEvent(new Event(`change`,{bubbles:!0}))}else if(a===`select`){let n=i,r=String(t),a=!1;for(let e of n.options)if(e.value===r||e.textContent?.trim()===r){n.value=e.value,a=!0;break}if(!a)return{success:!1,error:`Option "${t}" not found in select element ${e}`};n.dispatchEvent(new Event(`change`,{bubbles:!0}))}else if(i.getAttribute(`contenteditable`)===`true`)i.textContent=String(t),i.dispatchEvent(new Event(`input`,{bubbles:!0}));else return{success:!1,error:`Element ${e} (${a}) is not a form field`};return{success:!0}}catch(e){return{success:!1,error:`Failed to set value: ${e instanceof Error?e.message:`Unknown error`}`}}}function R(e,t,n=!0,r=!1){try{let i=document.querySelector(e);if(!i)return{success:!1,error:`Element not found: ${e}`};let a=i.querySelector(`[contenteditable="true"]`),o=a||i,s=i.isContentEditable||!!a;if(o.focus(),n&&(s?o.textContent=``:o.value=``),s?o.textContent=t:o.value=t,o.dispatchEvent(new Event(`input`,{bubbles:!0})),o.dispatchEvent(new Event(`change`,{bubbles:!0})),r){let e=i.closest(`form`),t=e?.querySelector(`button[type="submit"], input[type="submit"]`)||document.querySelector(`button[type="submit"], button[data-testid*="send"], button[aria-label*="Send"]`);t?t.click():e?e.dispatchEvent(new Event(`submit`,{bubbles:!0})):o.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Enter`,code:`Enter`,keyCode:13,bubbles:!0}))}return{success:!0,contentEditable:s}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function z(e,t){let n=new TextEncoder().encode(e);if(n.length<=t)return e;let r=t;for(;r>0&&(n[r]&192)==128;)r--;return new TextDecoder(`utf-8`,{fatal:!1}).decode(n.subarray(0,r))}function B(e={}){try{let t=document.querySelector(`article`),n=document.querySelector(`main`),r=(t||n||document.body).textContent?.replace(/\s+/g,` `).trim()||``;return{text:Number.isFinite(e.maxBytes)&&e.maxBytes>0?z(r,e.maxBytes):r.substring(0,5e4),title:document.title,url:window.location.href}}catch(e){return{text:``,title:``,url:``,error:`Failed to extract text: ${e instanceof Error?e.message:`Unknown error`}`}}}function V(e){let t=M(),n=t[e],r;return n&&(r=n.element.deref(),r||delete t[e]),!r&&window.__piRefs&&(r=window.__piRefs[e]),r?(r.scrollIntoView({behavior:`smooth`,block:`center`}),{success:!0}):{success:!1,error:`Element ${e} not found. Run read_page to get current element refs.`}}function H(e,t,n,r=`screenshot.png`){try{let i=atob(e),a=new ArrayBuffer(i.length),o=new Uint8Array(a);for(let e=0;e<i.length;e++)o[e]=i.charCodeAt(e);let s=new Blob([a],{type:`image/png`}),c=new File([s],r,{type:`image/png`}),l=null;if(t){let e=M(),n=e[t];if(n&&(l=n.element.deref(),l||delete e[t]),!l&&window.__piRefs&&(l=window.__piRefs[t]),!l)return{success:!1,error:`Element ${t} not found. Run read_page to get current element refs.`}}else if(n&&(l=document.elementFromPoint(n[0],n[1]),!l))return{success:!1,error:`No element at (${n[0]}, ${n[1]})`};if(!l)return{success:!1,error:`No target element`};if(l.tagName===`INPUT`&&l.type===`file`){let e=l,t=new DataTransfer;return t.items.add(c),e.files=t.files,e.dispatchEvent(new Event(`change`,{bubbles:!0})),{success:!0}}let u=new DataTransfer;u.items.add(c);let d=new DragEvent(`drop`,{bubbles:!0,cancelable:!0,dataTransfer:u});return l.dispatchEvent(d),{success:!0}}catch(e){return{success:!1,error:e instanceof Error?e.message:`Upload failed`}}}chrome.runtime.onMessage.addListener((e,t,n)=>{switch(e.type){case`SHOW_AGENT_INDICATORS`:case`HIDE_AGENT_INDICATORS`:case`HIDE_FOR_TOOL_USE`:case`SHOW_AFTER_TOOL_USE`:case`SHOW_STATIC_INDICATOR`:case`HIDE_STATIC_INDICATOR`:if(!window.__piVisualIndicatorMessageHandler){n({error:`Visual indicator content script not loaded.`});break}window.__piVisualIndicatorMessageHandler(e.type),n({success:!0});break;case`GENERATE_ACCESSIBILITY_TREE`:{let t=e.options||{};if(t.format===`yaml`){let e=F(t.filter||`interactive`,t.depth??15),r=A();e.error?n({error:e.error,pageContent:``,viewport:e.viewport}):n({pageContent:e.yaml,viewport:e.viewport,modalStates:r.length>0?r:void 0,modalLimitations:`Only custom modals ([role=dialog]) detected. Native alert/confirm/prompt dialogs and system file choosers cannot be detected from content scripts.`})}else n(N(t.filter||`interactive`,t.depth??15,t.refId,t.forceFullSnapshot??!1,t.compact??!1));break}case`GET_ELEMENT_COORDINATES`:n(I(e.ref));break;case`CLICK_ELEMENT`:{let t=M(),r=t[e.ref],i;if(r&&(i=r.element.deref(),i||delete t[e.ref]),!i&&window.__piRefs&&(i=window.__piRefs[e.ref]),!i){n({error:`Element ${e.ref} not found. Use read_page to get current elements.`});break}if(e.button===`triple`){let e=new MouseEvent(`click`,{bubbles:!0,cancelable:!0,view:window,detail:3});i.dispatchEvent(e)}else e.button===`double`?i.dispatchEvent(new MouseEvent(`dblclick`,{bubbles:!0,cancelable:!0,view:window})):e.button===`right`?i.dispatchEvent(new MouseEvent(`contextmenu`,{bubbles:!0,cancelable:!0,view:window})):i.click();n({success:!0});break}case`FORM_INPUT`:n(L(e.ref,e.value));break;case`EVAL_IN_PAGE`:try{let t=document.createElement(`script`);t.textContent=`(function() { ${e.code} })();`,document.documentElement.appendChild(t),t.remove(),n({success:!0})}catch(e){n({success:!1,error:e instanceof Error?e.message:String(e)})}break;case`GET_PAGE_TEXT`:n(B(e.options||{}));break;case`SMART_TYPE`:n(R(e.selector,e.text,e.clear,e.submit));break;case`GET_FRAME_BY_SELECTOR`:try{let t=document.querySelector(e.selector);if(!t||t.tagName.toLowerCase()!==`iframe`){n({error:`No iframe found with selector "${e.selector}"`});break}n({url:t.src,name:t.name||void 0})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`GET_FRAME_NAME`:try{n({name:window.name||null})}catch{n({name:null})}break;case`LOCATE_ROLE`:try{let{role:t,name:r,all:i}=e,a=M(),o={button:[`button`,`input[type="button"]`,`input[type="submit"]`,`input[type="reset"]`,`[role="button"]`],link:[`a[href]`,`[role="link"]`],textbox:[`input:not([type])`,`input[type="text"]`,`input[type="email"]`,`input[type="password"]`,`input[type="search"]`,`input[type="tel"]`,`input[type="url"]`,`textarea`,`[role="textbox"]`],checkbox:[`input[type="checkbox"]`,`[role="checkbox"]`],radio:[`input[type="radio"]`,`[role="radio"]`],combobox:[`select`,`[role="combobox"]`],listbox:[`[role="listbox"]`,`select[multiple]`],option:[`option`,`[role="option"]`],heading:[`h1`,`h2`,`h3`,`h4`,`h5`,`h6`,`[role="heading"]`],navigation:[`nav`,`[role="navigation"]`],main:[`main`,`[role="main"]`],img:[`img[alt]`,`[role="img"]`],dialog:[`dialog`,`[role="dialog"]`,`[role="alertdialog"]`],tab:[`[role="tab"]`],tabpanel:[`[role="tabpanel"]`],menu:[`[role="menu"]`],menuitem:[`[role="menuitem"]`]}[t]||[`[role="${t}"]`],s=[];for(let e of o)try{s.push(...document.querySelectorAll(e))}catch{}let c=s.filter(e=>{let t=window.getComputedStyle(e);return t.display!==`none`&&t.visibility!==`hidden`&&e.offsetWidth>0&&e.offsetHeight>0}),l=c;if(r){let e=r.toLowerCase();l=c.filter(t=>{let n=t.getAttribute(`aria-label`)?.toLowerCase(),r=t.textContent?.trim().toLowerCase(),i=t.getAttribute(`title`)?.toLowerCase(),a=t.placeholder?.toLowerCase(),o=t.value?.toLowerCase();return n?.includes(e)||r?.includes(e)||i?.includes(e)||a?.includes(e)||o?.includes(e)})}if(l.length===0){n({error:`No element found with role "${t}"${r?` and name "${r}"`:``}`});break}let u=l.map(e=>{let n=k(e,t,r||``);return window.__piRefs=window.__piRefs||{},window.__piRefs[n]=e,a[n]={element:new WeakRef(e),role:t,name:r||``},{ref:n,text:e.textContent?.trim().slice(0,50)}});n(i?{matches:u}:{ref:u[0].ref,text:u[0].text})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`LOCATE_TEXT`:try{let{text:t,exact:r}=e,i=M(),a=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),o=[];for(;a.nextNode();){let e=a.currentNode.textContent||``;if(r?e.trim()===t:e.toLowerCase().includes(t.toLowerCase())){let e=a.currentNode.parentElement;if(e&&!o.includes(e)){let t=window.getComputedStyle(e);t.display!==`none`&&t.visibility!==`hidden`&&o.push(e)}}}if(o.length===0){n({error:`No element found with text "${t}"`});break}let s=o.sort((e,t)=>(e.textContent?.length||0)-(t.textContent?.length||0))[0],c=D(s),l=k(s,c,t);window.__piRefs=window.__piRefs||{},window.__piRefs[l]=s,i[l]={element:new WeakRef(s),role:c,name:t},n({ref:l,text:s.textContent?.trim().slice(0,50)})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`LOCATE_LABEL`:try{let{label:t}=e,r=M(),i=document.querySelectorAll(`label`),a=null;for(let e of i)if((e.textContent?.trim().toLowerCase())?.includes(t.toLowerCase())){let t=e.getAttribute(`for`);if(t&&(a=document.getElementById(t)),a||=e.querySelector(`input, select, textarea`),a)break}if(a||=(t.toLowerCase(),document.querySelector(`input[aria-label*="${t}" i], input[placeholder*="${t}" i], textarea[aria-label*="${t}" i], textarea[placeholder*="${t}" i], select[aria-label*="${t}" i]`)),!a){n({error:`No form field found with label "${t}"`});break}let o=D(a),s=k(a,o,t);window.__piRefs=window.__piRefs||{},window.__piRefs[s]=a,r[s]={element:new WeakRef(a),role:o,name:t},n({ref:s,label:t})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`GET_ELEMENT_STYLES`:try{let{selector:t}=e,r=M(),i=e=>{let t=getComputedStyle(e),n=e.getBoundingClientRect();return{tag:e.tagName.toLowerCase(),text:e.innerText?.trim().slice(0,80)||null,box:{x:Math.round(n.x),y:Math.round(n.y),width:Math.round(n.width),height:Math.round(n.height)},styles:{fontSize:t.fontSize,fontWeight:t.fontWeight,fontFamily:t.fontFamily.split(`,`)[0].trim().replace(/"/g,``),color:t.color,backgroundColor:t.backgroundColor,borderRadius:t.borderRadius,border:t.border!==`none`&&t.borderWidth!==`0px`?t.border:null,boxShadow:t.boxShadow===`none`?null:t.boxShadow,padding:t.padding}}};if(/^e\d+$/.test(t)){let e=r[t],a;if(e&&(a=e.element.deref(),a||delete r[t]),!a&&window.__piRefs&&(a=window.__piRefs[t]),!a){n({error:`Element ${t} not found`});break}n({styles:[i(a)]})}else{let e=document.querySelectorAll(t);if(e.length===0){n({error:`No elements found matching "${t}"`});break}n({styles:Array.from(e).map(i)})}}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`SELECT_OPTION`:try{let{selector:t,values:r,by:i}=e,a=M(),o=null;if(/^e\d+$/.test(t)){let e=a[t],r;if(e&&(r=e.element.deref(),r||delete a[t]),!r&&window.__piRefs&&(r=window.__piRefs[t]),!r){n({error:`Element ${t} not found`});break}if(r.tagName!==`SELECT`){n({error:`Element ${t} is not a <select>`});break}o=r}else{if(o=document.querySelector(t),!o){n({error:`No element found matching "${t}"`});break}if(o.tagName!==`SELECT`){n({error:`Element "${t}" is not a <select>`});break}}if(o.multiple)for(let e of o.options)e.selected=!1;let s=[],c=[],l=o.multiple?r:[r[0]];for(let e of l){let t=!1;for(let n of o.options){let r=!1;if(r=i===`index`?n.index===parseInt(e,10):i===`label`?n.text.toLowerCase().includes(e.toLowerCase()):n.value===e,r){n.selected=!0,s.push(n.value),t=!0;break}}t||c.push(e)}o.dispatchEvent(new Event(`change`,{bubbles:!0})),c.length>0?n({selected:s,warning:`Values not found: ${c.join(`, `)}`}):n({selected:s})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`GET_ELEMENT_TEXT`:try{let{ref:t}=e,r=M(),i=r[t],a;if(i&&(a=i.element.deref(),a||delete r[t]),!a&&window.__piRefs&&(a=window.__piRefs[t]),!a){n({error:`Element ${t} not found`});break}n({text:a.textContent?.trim()||``})}catch(e){n({error:e instanceof Error?e.message:String(e)})}break;case`SCROLL_TO_ELEMENT`:n(V(e.ref));break;case`UPLOAD_IMAGE`:n(H(e.base64,e.ref,e.coordinate,e.filename));break;case`WAIT_FOR_ELEMENT`:{let{selector:t,state:r=`visible`,timeout:i=2e4}=e,a=Math.min(i,6e4),o=e=>{if(!e)return!1;let t=window.getComputedStyle(e);return t.display!==`none`&&t.visibility!==`hidden`&&t.opacity!==`0`&&e.offsetWidth>0&&e.offsetHeight>0},s=()=>{let e=document.querySelector(t);switch(r){case`attached`:return!!e;case`detached`:return!e;case`hidden`:return!e||!o(e);default:return o(e)}},c=Date.now();return new Promise(e=>{if(s()){e({success:!0,waited:Date.now()-c});return}let n=new MutationObserver(()=>{s()&&(n.disconnect(),clearTimeout(i),e({success:!0,waited:Date.now()-c}))}),i=setTimeout(()=>{n.disconnect(),e({success:!1,waited:Date.now()-c,error:`Timeout waiting for "${t}" to be ${r}`})},a);n.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`style`,`class`,`hidden`,`disabled`]})}).then(e=>{if(!e.success){n({error:e.error,waited:e.waited,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}});return}n({...N(`interactive`,15,void 0,!0),waited:e.waited})}),!0}case`WAIT_FOR_URL`:{let{pattern:t,timeout:r=2e4}=e,i=Math.min(r,6e4),a=e=>{if(t.includes(`*`)){let n=t.replace(/[.+?^${}()|[\]\\]/g,`\\$&`).replace(/\*\*/g,`<<<GLOBSTAR>>>`).replace(/\*/g,`[^/]*`).replace(/<<<GLOBSTAR>>>/g,`.*`);return RegExp(`^${n}$`).test(e)}return e.includes(t)},o=Date.now();return new Promise(e=>{if(a(window.location.href)){e({success:!0,waited:Date.now()-o});return}let n=!1,r=()=>{n||a(window.location.href)&&(n=!0,clearInterval(s),clearTimeout(c),window.removeEventListener(`popstate`,r),window.removeEventListener(`hashchange`,r),e({success:!0,waited:Date.now()-o}))},s=setInterval(r,100),c=setTimeout(()=>{n||(n=!0,clearInterval(s),window.removeEventListener(`popstate`,r),window.removeEventListener(`hashchange`,r),e({success:!1,waited:Date.now()-o,error:`Timeout waiting for URL to match "${t}". Current: ${window.location.href}`}))},i);window.addEventListener(`popstate`,r),window.addEventListener(`hashchange`,r)}).then(e=>{if(!e.success){n({error:e.error,waited:e.waited,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}});return}n({...N(`interactive`,15,void 0,!0),waited:e.waited})}),!0}case`WAIT_FOR_DOM_STABLE`:{let{stable:t=100,timeout:r=5e3}=e,i=Math.min(r,3e4),a=Date.now();return new Promise(e=>{let n=Date.now(),r=!1,o=()=>{r||Date.now()-n>=t&&(r=!0,s.disconnect(),clearTimeout(c),clearInterval(l),e({success:!0,waited:Date.now()-a}))},s=new MutationObserver(()=>{n=Date.now()}),c=setTimeout(()=>{r||(r=!0,s.disconnect(),clearInterval(l),e({success:!1,waited:Date.now()-a,error:`Timeout: DOM did not stabilize within ${i}ms`}))},i),l=setInterval(o,Math.max(10,Math.min(50,t/2)));s.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),o()}).then(e=>{if(!e.success){n({error:e.error,waited:e.waited,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}});return}n({...N(`interactive`,15,void 0,!0),waited:e.waited})}),!0}case`FORM_FILL`:{let{data:t}=e;if(!Array.isArray(t))return n({error:`data must be an array of {ref, value} pairs`}),!0;let r=M(),i=[];for(let e of t){let{ref:t,value:n}=e;if(!t){i.push({ref:t||`unknown`,success:!1,error:`Missing ref`});continue}let a=r[t];if(!a){i.push({ref:t,success:!1,error:`Element not found (run page.read first)`});continue}let o=a.element.deref();if(!o){delete r[t],i.push({ref:t,success:!1,error:`Element no longer exists`});continue}try{if(o instanceof HTMLInputElement){let e=o.type.toLowerCase();e===`checkbox`||e===`radio`?(o.checked=n===!0||n===`true`||n===`1`||n===`checked`,o.dispatchEvent(new Event(`change`,{bubbles:!0}))):(o.focus(),o.value=String(n),o.dispatchEvent(new Event(`input`,{bubbles:!0})),o.dispatchEvent(new Event(`change`,{bubbles:!0}))),i.push({ref:t,success:!0})}else o instanceof HTMLTextAreaElement?(o.focus(),o.value=String(n),o.dispatchEvent(new Event(`input`,{bubbles:!0})),o.dispatchEvent(new Event(`change`,{bubbles:!0})),i.push({ref:t,success:!0})):o instanceof HTMLSelectElement?(o.value=String(n),o.dispatchEvent(new Event(`change`,{bubbles:!0})),i.push({ref:t,success:!0})):o.isContentEditable?(o.focus(),o.textContent=String(n),o.dispatchEvent(new Event(`input`,{bubbles:!0})),i.push({ref:t,success:!0})):i.push({ref:t,success:!1,error:`Element is not fillable`})}catch(e){i.push({ref:t,success:!1,error:e instanceof Error?e.message:String(e)})}}let a=i.filter(e=>!e.success);return n({success:a.length===0,filled:i.filter(e=>e.success).length,failed:a.length,results:i}),!0}case`GET_FILE_INPUT_SELECTOR`:{let{ref:t}=e;if(!t)return n({error:`No ref provided`}),!0;let r=M(),i=r[t];if(!i)return n({error:`Element not found (run page.read first)`}),!0;let a=i.element.deref();if(!a)return delete r[t],n({error:`Element no longer exists`}),!0;if(!(a instanceof HTMLInputElement)||a.type!==`file`)return n({error:`Element is not a file input`}),!0;let o=`__pi_file_${Date.now()}`;return a.setAttribute(`data-pi-file-id`,o),n({selector:`[data-pi-file-id="${o}"]`}),!0}case`WAIT_FOR_NETWORK_IDLE`:{let{timeout:t=1e4}=e,r=Math.min(t,6e4),i=[`doubleclick.net`,`googlesyndication.com`,`googletagmanager.com`,`google-analytics.com`,`facebook.net`,`connect.facebook.net`,`analytics`,`ads`,`tracking`,`pixel`,`hotjar.com`,`clarity.ms`,`mixpanel.com`,`segment.com`,`newrelic.com`,`nr-data.net`,`/tracker/`,`/collector/`,`/beacon/`,`/telemetry/`,`/log/`,`/events/`,`/track.`,`/metrics/`],a=[`img`,`image`,`font`,`icon`],o=e=>i.some(t=>e.includes(t)),s=e=>{let t=e.initiatorType||`unknown`;return!!(a.includes(t)||/\.(jpg|jpeg|png|gif|webp|svg|ico|woff|woff2|ttf|eot)(\?|$)/i.test(e.name))},c=()=>{let e=performance.now();return performance.getEntriesByType(`resource`).filter(t=>{if(t.responseEnd!==0||t.name.startsWith(`data:`)||t.name.length>500||o(t.name))return!1;let n=e-t.startTime;return!(n>1e4||s(t)&&n>3e3)})},l=Date.now();return new Promise(e=>{let t=()=>{let n=c(),i=Date.now()-l;if(n.length===0){e({success:!0,waited:i});return}if(i>=r){e({success:!1,waited:i,pendingCount:n.length});return}setTimeout(t,100)};t()}).then(e=>{if(!e.success){n({error:`Network not idle after ${e.waited}ms (${e.pendingCount} requests pending)`,waited:e.waited,pageContent:``,viewport:{width:window.innerWidth,height:window.innerHeight}});return}n({...N(`interactive`,15,void 0,!0),waited:e.waited})}),!0}case`SEARCH_PAGE`:{let{term:t,caseSensitive:r,limit:i}=e,a=U(t,r||!1,i||10);n({query:t,count:a.length,matches:a});break}case`GET_ELEMENT_BOUNDS_FOR_ANNOTATION`:{let e=M(),t=[];for(let[n,r]of Object.entries(e)){let e=r.element.deref();if(!e)continue;let i=e.getBoundingClientRect();i.width<=0||i.height<=0||i.bottom<0||i.top>window.innerHeight||i.right<0||i.left>window.innerWidth||t.push({ref:n,tag:e.tagName.toLowerCase(),bounds:{x:i.x,y:i.y,width:i.width,height:i.height}})}n({elements:t});break}default:return!1}return!1});function U(e,t,n){let r=[],i=t?e:e.toLowerCase(),a=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT),o=M(),s=0;for(;a.nextNode()&&r.length<n;){let c=a.currentNode,l=c.textContent||``,u=t?l:l.toLowerCase(),d=0;for(;(d=u.indexOf(i,d))!==-1&&r.length<n;){let t=c.parentElement;if(!t){d++;continue}let n=document.createRange();n.setStart(c,d),n.setEnd(c,Math.min(d+e.length,l.length));let i=n.getBoundingClientRect();if(i.width===0||i.height===0){d++;continue}let a=c.textContent||``,u=Math.max(0,d-30),f=Math.min(a.length,d+e.length+30),p=a.slice(u,f).trim(),m=null;for(let[e,n]of Object.entries(o)){let r=n.element.deref();if(r&&(r===t||r.contains(t))){m=e;break}}r.push({ref:`m${++s}`,text:a.slice(d,d+e.length),context:p,bounds:{x:Math.round(i.x),y:Math.round(i.y),width:Math.round(i.width),height:Math.round(i.height)},elementRef:m}),d++}}return r}
116
- //# sourceMappingURL=index.js.map