surf-cli 2.9.0 → 2.11.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.
- package/README.md +61 -4
- package/dist/content/accessibility-tree.js +11 -0
- package/dist/content/accessibility-tree.js.map +1 -0
- package/dist/content/visual-indicator.js +111 -0
- package/dist/content/visual-indicator.js.map +1 -0
- package/dist/manifest.json +11 -2
- package/dist/options/options.js +3 -3
- package/dist/options/options.js.map +1 -1
- package/dist/service-worker/index.js +61 -261
- package/dist/service-worker/index.js.map +1 -1
- package/native/activity-journal.cjs +55 -0
- package/native/chatgpt-client-response.cjs +336 -0
- package/native/chatgpt-client-selection.cjs +119 -0
- package/native/chatgpt-client-ui.cjs +481 -0
- package/native/chatgpt-client.cjs +254 -664
- package/native/cli.cjs +100 -273
- package/native/do-executor.cjs +52 -475
- package/native/do-parser.cjs +8 -249
- package/native/host-helpers.cjs +32 -15
- package/native/host-sessions.cjs +6 -1
- package/native/host.cjs +228 -6
- package/native/network-export.cjs +20 -17
- package/native/network-store.cjs +38 -58
- package/native/oracle-cli.cjs +434 -0
- package/native/oracle-context.cjs +311 -0
- package/native/oracle-host.cjs +301 -0
- package/native/oracle-jobs.cjs +253 -0
- package/native/playbook-authoring.cjs +44 -0
- package/native/playbook-cli.cjs +157 -0
- package/native/playbook-client.cjs +259 -0
- package/native/playbook-receipts.cjs +109 -0
- package/native/playbook-records.cjs +208 -0
- package/native/playbook-runtime.cjs +177 -0
- package/native/playbooks.cjs +235 -0
- package/native/private-state.cjs +156 -0
- package/native/redaction.cjs +104 -0
- package/native/workflow-definition.cjs +369 -0
- package/native/workflow-runtime.cjs +225 -0
- package/package.json +2 -1
- package/playbooks/page/ops/read.json +22 -0
- package/playbooks/page/playbook.json +7 -0
- package/skills/surf/SKILL.md +72 -1
- package/dist/content/index.js +0 -116
- package/dist/content/index.js.map +0 -1
package/skills/surf/SKILL.md
CHANGED
|
@@ -82,6 +82,37 @@ surf chatgpt "review" --model gpt-4o # Specify model
|
|
|
82
82
|
surf chatgpt "analyze" --file document.pdf # With file attachment
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
### Oracle
|
|
86
|
+
|
|
87
|
+
Use `surf chatgpt` for quick one-shot questions. Use `surf oracle` for long-running or Pro coding consults that need a durable job, explicit model and effort selection, file context, recovery, or follow-up turns. Oracle is local-only.
|
|
88
|
+
|
|
89
|
+
For agent workflows, detach after dispatch and keep the returned `.id`:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
surf oracle ask "Review this change and identify release risks" \
|
|
93
|
+
--files "src/**/*.ts" --files "package.json" \
|
|
94
|
+
--model pro --effort extended --detach --json
|
|
95
|
+
|
|
96
|
+
surf oracle status <job-id> --json
|
|
97
|
+
surf oracle result <job-id> --json
|
|
98
|
+
# Or let Surf keep polling until capture:
|
|
99
|
+
surf oracle result <job-id> --wait --json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`status` reads persisted state without touching Chrome. `result` attempts to harvest the answer and returns the job object with `response` once its state is `captured`. A Ctrl-C during waiting exits with status 130 and prints `Recover with: surf oracle result <id>`. Once the job is `awaiting`, the persisted ChatGPT conversation URL is its durable key, so `surf oracle result <id>` can recover after CLI exit, native-host restart, or Chrome restart by reopening that conversation.
|
|
103
|
+
|
|
104
|
+
Treat Pro quota as scarce. Oracle never selects Pro implicitly; request it with `--model pro`. Accepted `--effort` values are `light`, `standard`, `extended`, and `heavy`. Requested model and effort selections are read back before submission, and an unverifiable selection fails with `model_verification_failed` instead of silently continuing. Capacity is one non-terminal oracle job. A `capacity` error includes the in-flight job ID; poll that job or wait for it to finish rather than submitting the same consult again.
|
|
105
|
+
|
|
106
|
+
Context comes from repeatable `--files` globs. Surf fails closed when a glob matches nothing or a matched file is unreadable, binary, or invalid UTF-8. It also blocks gitignored files and basenames matching `.env*`, `*.pem`, `*.key`, `id_rsa*`, `id_ed25519*`, `*.p12`, `*.pfx`, `credentials*`, or `secrets*`. Use `--allow-sensitive` only after intentionally reviewing those files; it overrides the block rather than redacting content. Context up to 60,000 evidence characters is inserted inline, while larger context becomes one private text attachment. The assembly manifest records each path, byte count, SHA-256, inline or bundle disposition, and deny-list outcome.
|
|
107
|
+
|
|
108
|
+
Continue a captured consult with `follow`. Use the ID returned by each turn for the next turn:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
surf oracle follow <job-id> "Challenge your recommendation. What could invalidate it?" --detach --json
|
|
112
|
+
surf oracle result <follow-job-id> --wait --json
|
|
113
|
+
surf oracle follow <follow-job-id> "Give the final decision and concrete next steps." --detach --json
|
|
114
|
+
```
|
|
115
|
+
|
|
85
116
|
### Gemini
|
|
86
117
|
```bash
|
|
87
118
|
surf gemini "explain quantum computing"
|
|
@@ -410,10 +441,13 @@ surf network.body --id "req-123" # Get response body
|
|
|
410
441
|
surf network.curl --id "req-123" # Generate curl command
|
|
411
442
|
surf network.origins # List origins with stats
|
|
412
443
|
surf network.stats # Capture statistics
|
|
413
|
-
surf network
|
|
444
|
+
surf network -vv --body-mode text --per-body-bytes 65536
|
|
445
|
+
surf network.export --har --output ./trace.har
|
|
414
446
|
surf network.clear # Clear captured requests
|
|
415
447
|
```
|
|
416
448
|
|
|
449
|
+
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.
|
|
450
|
+
|
|
417
451
|
## Console
|
|
418
452
|
|
|
419
453
|
```bash
|
|
@@ -582,6 +616,43 @@ surf workflow.validate workflow.json
|
|
|
582
616
|
|
|
583
617
|
**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
618
|
|
|
619
|
+
## Playbooks
|
|
620
|
+
|
|
621
|
+
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.
|
|
622
|
+
|
|
623
|
+
```bash
|
|
624
|
+
surf playbook list
|
|
625
|
+
surf pb show page
|
|
626
|
+
surf pb ops page
|
|
627
|
+
surf use page read --json
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
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.
|
|
631
|
+
|
|
632
|
+
Author from redacted recent activity when it contains only read/navigation behavior, or use an explicit record for richer evidence:
|
|
633
|
+
|
|
634
|
+
```bash
|
|
635
|
+
surf pb suggest --since 1h
|
|
636
|
+
surf pb save example --op read --from-recent 1h
|
|
637
|
+
surf pb record start example --op read --network --watch
|
|
638
|
+
surf pb record mark "loaded results"
|
|
639
|
+
surf pb record stop --draft
|
|
640
|
+
surf pb save --from-record <record-id>
|
|
641
|
+
surf pb trace export --from-record <record-id> --har ./trace.har
|
|
642
|
+
surf pb export example --out ./example-playbook
|
|
643
|
+
surf pb import ./example-playbook
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
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.
|
|
647
|
+
|
|
648
|
+
Client projections replay a validated read endpoint and never embed captured browser credentials:
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
surf pb client derive example --op read --from-record <record-id> --request-id <request-id> --out ./client
|
|
652
|
+
surf pb client export example --op read --out ./client
|
|
653
|
+
surf pb client verify ./client
|
|
654
|
+
```
|
|
655
|
+
|
|
585
656
|
## Error Diagnostics
|
|
586
657
|
|
|
587
658
|
```bash
|
package/dist/content/index.js
DELETED
|
@@ -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
|