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.
Files changed (44) hide show
  1. package/README.md +61 -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-response.cjs +336 -0
  13. package/native/chatgpt-client-selection.cjs +119 -0
  14. package/native/chatgpt-client-ui.cjs +481 -0
  15. package/native/chatgpt-client.cjs +254 -664
  16. package/native/cli.cjs +100 -273
  17. package/native/do-executor.cjs +52 -475
  18. package/native/do-parser.cjs +8 -249
  19. package/native/host-helpers.cjs +32 -15
  20. package/native/host-sessions.cjs +6 -1
  21. package/native/host.cjs +228 -6
  22. package/native/network-export.cjs +20 -17
  23. package/native/network-store.cjs +38 -58
  24. package/native/oracle-cli.cjs +434 -0
  25. package/native/oracle-context.cjs +311 -0
  26. package/native/oracle-host.cjs +301 -0
  27. package/native/oracle-jobs.cjs +253 -0
  28. package/native/playbook-authoring.cjs +44 -0
  29. package/native/playbook-cli.cjs +157 -0
  30. package/native/playbook-client.cjs +259 -0
  31. package/native/playbook-receipts.cjs +109 -0
  32. package/native/playbook-records.cjs +208 -0
  33. package/native/playbook-runtime.cjs +177 -0
  34. package/native/playbooks.cjs +235 -0
  35. package/native/private-state.cjs +156 -0
  36. package/native/redaction.cjs +104 -0
  37. package/native/workflow-definition.cjs +369 -0
  38. package/native/workflow-runtime.cjs +225 -0
  39. package/package.json +2 -1
  40. package/playbooks/page/ops/read.json +22 -0
  41. package/playbooks/page/playbook.json +7 -0
  42. package/skills/surf/SKILL.md +72 -1
  43. package/dist/content/index.js +0 -116
  44. package/dist/content/index.js.map +0 -1
@@ -0,0 +1,111 @@
1
+ const a="59, 178, 191";let i=null,s=null,r=null,o=!1,c=!1,p=!1,u=!1,l=null,f=1e4;chrome.storage.local.get("heartbeatInterval").then(({heartbeatInterval:e})=>{e&&typeof e=="number"&&(f=e*1e3)});chrome.storage.onChanged.addListener((e,t)=>{if(t==="local"&&e.heartbeatInterval){const n=e.heartbeatInterval.newValue;n&&typeof n=="number"&&(f=n*1e3,c&&l&&(clearInterval(l),y()))}});function y(){l=window.setInterval(async()=>{try{(await chrome.runtime.sendMessage({type:"STATIC_INDICATOR_HEARTBEAT"}))?.success||d()}catch{d()}},f)}function x(){if(document.getElementById("pi-agent-styles"))return;const e=document.createElement("style");e.id="pi-agent-styles",e.textContent=`
2
+ @keyframes pi-pulse {
3
+ 0% {
4
+ box-shadow:
5
+ inset 0 0 10px rgba(${a}, 0.5),
6
+ inset 0 0 20px rgba(${a}, 0.3),
7
+ inset 0 0 30px rgba(${a}, 0.1);
8
+ }
9
+ 50% {
10
+ box-shadow:
11
+ inset 0 0 15px rgba(${a}, 0.7),
12
+ inset 0 0 25px rgba(${a}, 0.5),
13
+ inset 0 0 35px rgba(${a}, 0.2);
14
+ }
15
+ 100% {
16
+ box-shadow:
17
+ inset 0 0 10px rgba(${a}, 0.5),
18
+ inset 0 0 20px rgba(${a}, 0.3),
19
+ inset 0 0 30px rgba(${a}, 0.1);
20
+ }
21
+ }
22
+ `,document.head.appendChild(e)}function b(){const e=document.createElement("div");return e.id="pi-agent-glow",e.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(${a}, 0.5),
35
+ inset 0 0 20px rgba(${a}, 0.3),
36
+ inset 0 0 30px rgba(${a}, 0.1);
37
+ `,e}function h(){const e=document.createElement("div");e.id="pi-agent-stop-container",e.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
+ `;const t=document.createElement("button");return t.id="pi-agent-stop-button",t.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
+ `,t.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(${a}, 0.24),
69
+ 0 4px 14px rgba(${a}, 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
+ `,t.addEventListener("mouseenter",()=>{o&&(t.style.background="#F5F4F0")}),t.addEventListener("mouseleave",()=>{o&&(t.style.background="#FAF9F5")}),t.addEventListener("click",async()=>{await chrome.runtime.sendMessage({type:"STOP_AGENT",fromTabId:"CURRENT_TAB"})}),e.appendChild(t),e}function m(){const e=document.createElement("div");e.id="pi-agent-static-indicator",e.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(${a})"/>
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
+ `,e.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
+ `;const t=e.querySelector("#pi-static-chat-button"),n=e.querySelector("#pi-static-close-button");return t&&(t.style.pointerEvents="auto",t.addEventListener("mouseenter",()=>t.style.background="#F0EEE6"),t.addEventListener("mouseleave",()=>t.style.background="transparent"),t.addEventListener("click",async()=>{await chrome.runtime.sendMessage({type:"OPEN_SIDEPANEL"})})),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:"DISMISS_STATIC_INDICATOR"}),d()})),e}function v(){o||(o=!0,x(),i?i.style.display="":(i=b(),document.body.appendChild(i)),s?s.style.display="":(s=h(),document.body.appendChild(s)),requestAnimationFrame(()=>{if(i&&(i.style.opacity="1"),s){const e=s.querySelector("#pi-agent-stop-button");e&&(e.style.transform="translateY(0)",e.style.opacity="1")}}))}function g(){if(o){if(o=!1,i&&(i.style.opacity="0"),s){const e=s.querySelector("#pi-agent-stop-button");e&&(e.style.transform="translateY(100px)",e.style.opacity="0")}setTimeout(()=>{o||(i?.parentNode&&(i.parentNode.removeChild(i),i=null),s?.parentNode&&(s.parentNode.removeChild(s),s=null))},300)}}function E(){c||(c=!0,r?r.style.display="":(r=m(),document.body.appendChild(r)),l&&clearInterval(l),y())}function d(){c&&(c=!1,l&&(clearInterval(l),l=null),r?.parentNode&&(r.parentNode.removeChild(r),r=null))}chrome.runtime.onMessage.addListener((e,t,n)=>{switch(e.type){case"SHOW_AGENT_INDICATORS":return v(),n({success:!0}),!1;case"HIDE_AGENT_INDICATORS":return g(),n({success:!0}),!1;case"HIDE_FOR_TOOL_USE":return p=o,u=c,i&&(i.style.display="none"),s&&(s.style.display="none"),r&&c&&(r.style.display="none"),n({success:!0}),!1;case"SHOW_AFTER_TOOL_USE":return p&&(i&&(i.style.display=""),s&&(s.style.display="")),u&&r&&(r.style.display=""),p=!1,u=!1,n({success:!0}),!1;case"SHOW_STATIC_INDICATOR":return E(),n({success:!0}),!1;case"HIDE_STATIC_INDICATOR":return d(),n({success:!0}),!1;default:return!1}});window.addEventListener("beforeunload",()=>{g(),d()});
111
+ //# sourceMappingURL=visual-indicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-indicator.js","sources":["../../src/content/visual-indicator.ts"],"sourcesContent":["const PI_COLOR = \"59, 178, 191\";\nconst DEFAULT_HEARTBEAT_INTERVAL = 10000;\n\nlet glowBorder: HTMLDivElement | null = null;\nlet stopButton: HTMLDivElement | null = null;\nlet staticIndicator: HTMLDivElement | null = null;\nlet isActive = false;\nlet isStaticActive = false;\nlet wasActiveBeforeToolUse = false;\nlet wasStaticActiveBeforeToolUse = false;\nlet heartbeatIntervalId: number | null = null;\nlet heartbeatIntervalMs = DEFAULT_HEARTBEAT_INTERVAL;\n\nchrome.storage.local.get(\"heartbeatInterval\").then(({ heartbeatInterval }) => {\n if (heartbeatInterval && typeof heartbeatInterval === \"number\") {\n heartbeatIntervalMs = heartbeatInterval * 1000;\n }\n});\n\nchrome.storage.onChanged.addListener((changes, areaName) => {\n if (areaName === \"local\" && changes.heartbeatInterval) {\n const newValue = changes.heartbeatInterval.newValue;\n if (newValue && typeof newValue === \"number\") {\n heartbeatIntervalMs = newValue * 1000;\n if (isStaticActive && heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n startHeartbeat();\n }\n }\n }\n});\n\nfunction startHeartbeat() {\n heartbeatIntervalId = window.setInterval(async () => {\n try {\n const response = await chrome.runtime.sendMessage({ type: \"STATIC_INDICATOR_HEARTBEAT\" });\n if (!response?.success) hideStaticIndicator();\n } catch {\n hideStaticIndicator();\n }\n }, heartbeatIntervalMs);\n}\n\nfunction injectStyles() {\n if (document.getElementById(\"pi-agent-styles\")) return;\n\n const style = document.createElement(\"style\");\n style.id = \"pi-agent-styles\";\n style.textContent = `\n @keyframes pi-pulse {\n 0% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n 50% {\n box-shadow: \n inset 0 0 15px rgba(${PI_COLOR}, 0.7),\n inset 0 0 25px rgba(${PI_COLOR}, 0.5),\n inset 0 0 35px rgba(${PI_COLOR}, 0.2);\n }\n 100% {\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n }\n }\n `;\n document.head.appendChild(style);\n}\n\nfunction createGlowBorder(): HTMLDivElement {\n const el = document.createElement(\"div\");\n el.id = \"pi-agent-glow\";\n el.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n z-index: 2147483646;\n opacity: 0;\n transition: opacity 0.3s ease-in-out;\n animation: pi-pulse 2s ease-in-out infinite;\n box-shadow: \n inset 0 0 10px rgba(${PI_COLOR}, 0.5),\n inset 0 0 20px rgba(${PI_COLOR}, 0.3),\n inset 0 0 30px rgba(${PI_COLOR}, 0.1);\n `;\n return el;\n}\n\nfunction createStopButton(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-stop-container\";\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n justify-content: center;\n align-items: center;\n pointer-events: none;\n z-index: 2147483647;\n `;\n\n const button = document.createElement(\"button\");\n button.id = \"pi-agent-stop-button\";\n button.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 256 256\" fill=\"currentColor\" style=\"margin-right: 12px; vertical-align: middle;\">\n <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>\n </svg>\n <span style=\"vertical-align: middle;\">Stop Surf</span>\n `;\n button.style.cssText = `\n position: relative;\n transform: translateY(100px);\n padding: 12px 16px;\n background: #FAF9F5;\n color: #141413;\n border: 0.5px solid rgba(31, 30, 29, 0.4);\n border-radius: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-shadow: \n 0 40px 80px rgba(${PI_COLOR}, 0.24),\n 0 4px 14px rgba(${PI_COLOR}, 0.24);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n opacity: 0;\n user-select: none;\n pointer-events: auto;\n white-space: nowrap;\n margin: 0 auto;\n `;\n\n button.addEventListener(\"mouseenter\", () => {\n if (isActive) button.style.background = \"#F5F4F0\";\n });\n\n button.addEventListener(\"mouseleave\", () => {\n if (isActive) button.style.background = \"#FAF9F5\";\n });\n\n button.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"STOP_AGENT\", fromTabId: \"CURRENT_TAB\" });\n });\n\n container.appendChild(button);\n return container;\n}\n\nfunction createStaticIndicator(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.id = \"pi-agent-static-indicator\";\n container.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style=\"width: 16px; height: 16px; margin-right: 8px; flex-shrink: 0;\">\n <circle cx=\"8\" cy=\"8\" r=\"7\" fill=\"rgb(${PI_COLOR})\"/>\n <text x=\"8\" y=\"11\" font-size=\"9\" fill=\"white\" text-anchor=\"middle\" font-weight=\"bold\">π</text>\n </svg>\n <span style=\"color: #141413; font-size: 14px;\">Surf is active in this tab group</span>\n <div style=\"width: 0.5px; height: 32px; background: rgba(31, 30, 29, 0.15); margin: 0 8px;\"></div>\n <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;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"#141413\">\n <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\"/>\n </svg>\n </button>\n <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;\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <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\"/>\n </svg>\n </button>\n `;\n container.style.cssText = `\n position: fixed;\n bottom: 16px;\n left: 50%;\n transform: translateX(-50%);\n display: inline-flex;\n align-items: center;\n padding: 6px 6px 6px 16px;\n background: #FAF9F5;\n border: 0.5px solid rgba(31, 30, 29, 0.30);\n border-radius: 14px;\n box-shadow: 0 40px 80px 0 rgba(0, 0, 0, 0.15);\n z-index: 2147483647;\n pointer-events: none;\n white-space: nowrap;\n user-select: none;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n `;\n\n const chatButton = container.querySelector(\"#pi-static-chat-button\") as HTMLButtonElement;\n const closeButton = container.querySelector(\"#pi-static-close-button\") as HTMLButtonElement;\n\n if (chatButton) {\n chatButton.style.pointerEvents = \"auto\";\n chatButton.addEventListener(\"mouseenter\", () => chatButton.style.background = \"#F0EEE6\");\n chatButton.addEventListener(\"mouseleave\", () => chatButton.style.background = \"transparent\");\n chatButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"OPEN_SIDEPANEL\" });\n });\n }\n\n if (closeButton) {\n closeButton.style.pointerEvents = \"auto\";\n closeButton.addEventListener(\"mouseenter\", () => closeButton.style.background = \"#F0EEE6\");\n closeButton.addEventListener(\"mouseleave\", () => closeButton.style.background = \"transparent\");\n closeButton.addEventListener(\"click\", async () => {\n await chrome.runtime.sendMessage({ type: \"DISMISS_STATIC_INDICATOR\" });\n hideStaticIndicator();\n });\n }\n\n return container;\n}\n\nfunction showIndicators() {\n if (isActive) return;\n isActive = true;\n\n injectStyles();\n\n if (!glowBorder) {\n glowBorder = createGlowBorder();\n document.body.appendChild(glowBorder);\n } else {\n glowBorder.style.display = \"\";\n }\n\n if (!stopButton) {\n stopButton = createStopButton();\n document.body.appendChild(stopButton);\n } else {\n stopButton.style.display = \"\";\n }\n\n requestAnimationFrame(() => {\n if (glowBorder) glowBorder.style.opacity = \"1\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(0)\";\n btn.style.opacity = \"1\";\n }\n }\n });\n}\n\nfunction hideIndicators() {\n if (!isActive) return;\n isActive = false;\n\n if (glowBorder) glowBorder.style.opacity = \"0\";\n if (stopButton) {\n const btn = stopButton.querySelector(\"#pi-agent-stop-button\") as HTMLElement;\n if (btn) {\n btn.style.transform = \"translateY(100px)\";\n btn.style.opacity = \"0\";\n }\n }\n\n setTimeout(() => {\n if (!isActive) {\n if (glowBorder?.parentNode) {\n glowBorder.parentNode.removeChild(glowBorder);\n glowBorder = null;\n }\n if (stopButton?.parentNode) {\n stopButton.parentNode.removeChild(stopButton);\n stopButton = null;\n }\n }\n }, 300);\n}\n\nfunction showStaticIndicator() {\n if (isStaticActive) return;\n isStaticActive = true;\n\n if (!staticIndicator) {\n staticIndicator = createStaticIndicator();\n document.body.appendChild(staticIndicator);\n } else {\n staticIndicator.style.display = \"\";\n }\n\n if (heartbeatIntervalId) clearInterval(heartbeatIntervalId);\n startHeartbeat();\n}\n\nfunction hideStaticIndicator() {\n if (!isStaticActive) return;\n isStaticActive = false;\n\n if (heartbeatIntervalId) {\n clearInterval(heartbeatIntervalId);\n heartbeatIntervalId = null;\n }\n\n if (staticIndicator?.parentNode) {\n staticIndicator.parentNode.removeChild(staticIndicator);\n staticIndicator = null;\n }\n}\n\nchrome.runtime.onMessage.addListener((message, sender, sendResponse) => {\n switch (message.type) {\n case \"SHOW_AGENT_INDICATORS\":\n showIndicators();\n sendResponse({ success: true });\n return false;\n case \"HIDE_AGENT_INDICATORS\":\n hideIndicators();\n sendResponse({ success: true });\n return false;\n case \"HIDE_FOR_TOOL_USE\":\n wasActiveBeforeToolUse = isActive;\n wasStaticActiveBeforeToolUse = isStaticActive;\n if (glowBorder) glowBorder.style.display = \"none\";\n if (stopButton) stopButton.style.display = \"none\";\n if (staticIndicator && isStaticActive) staticIndicator.style.display = \"none\";\n sendResponse({ success: true });\n return false;\n case \"SHOW_AFTER_TOOL_USE\":\n if (wasActiveBeforeToolUse) {\n if (glowBorder) glowBorder.style.display = \"\";\n if (stopButton) stopButton.style.display = \"\";\n }\n if (wasStaticActiveBeforeToolUse && staticIndicator) {\n staticIndicator.style.display = \"\";\n }\n wasActiveBeforeToolUse = false;\n wasStaticActiveBeforeToolUse = false;\n sendResponse({ success: true });\n return false;\n case \"SHOW_STATIC_INDICATOR\":\n showStaticIndicator();\n sendResponse({ success: true });\n return false;\n case \"HIDE_STATIC_INDICATOR\":\n hideStaticIndicator();\n sendResponse({ success: true });\n return false;\n default:\n return false;\n }\n});\n\nwindow.addEventListener(\"beforeunload\", () => {\n hideIndicators();\n hideStaticIndicator();\n});\n"],"names":["PI_COLOR","glowBorder","stopButton","staticIndicator","isActive","isStaticActive","wasActiveBeforeToolUse","wasStaticActiveBeforeToolUse","heartbeatIntervalId","heartbeatIntervalMs","heartbeatInterval","changes","areaName","newValue","startHeartbeat","hideStaticIndicator","injectStyles","style","createGlowBorder","el","createStopButton","container","button","createStaticIndicator","chatButton","closeButton","showIndicators","btn","hideIndicators","showStaticIndicator","message","sender","sendResponse"],"mappings":"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"}
@@ -24,9 +24,15 @@
24
24
  "content_scripts": [
25
25
  {
26
26
  "matches": ["<all_urls>"],
27
- "js": ["content/index.js"],
27
+ "js": ["content/accessibility-tree.js"],
28
28
  "run_at": "document_start",
29
29
  "all_frames": true
30
+ },
31
+ {
32
+ "matches": ["<all_urls>"],
33
+ "js": ["content/visual-indicator.js"],
34
+ "run_at": "document_idle",
35
+ "all_frames": false
30
36
  }
31
37
  ],
32
38
  "permissions": [
@@ -54,7 +60,10 @@
54
60
  "web_accessible_resources": [
55
61
  {
56
62
  "matches": ["<all_urls>"],
57
- "resources": ["content/index.js"],
63
+ "resources": [
64
+ "content/accessibility-tree.js",
65
+ "content/visual-indicator.js"
66
+ ],
58
67
  "use_dynamic_url": false
59
68
  }
60
69
  ]
@@ -1,4 +1,4 @@
1
- (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=document.getElementById(`app`);e.innerHTML=`
1
+ (function(){const i=document.createElement("link").relList;if(i&&i.supports&&i.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))a(e);new MutationObserver(e=>{for(const t of e)if(t.type==="childList")for(const s of t.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&a(s)}).observe(document,{childList:!0,subtree:!0});function l(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?t.credentials="include":e.crossOrigin==="anonymous"?t.credentials="omit":t.credentials="same-origin",t}function a(e){if(e.ep)return;e.ep=!0;const t=l(e);fetch(e.href,t)}})();const c=document.getElementById("app");c.innerHTML=`
2
2
  <h1 style="font-size: 1.5rem; font-weight: bold; margin-bottom: 1.5rem;">Surf Settings</h1>
3
3
 
4
4
  <section style="margin-bottom: 2rem;">
@@ -26,5 +26,5 @@
26
26
  Surf v${chrome.runtime.getManifest().version}
27
27
  </p>
28
28
  </section>
29
- `;var t=document.getElementById(`debug-mode`);t&&(chrome.storage.local.get(`debugMode`).then(({debugMode:e})=>{t.checked=!!e}),t.addEventListener(`change`,()=>{chrome.storage.local.set({debugMode:t.checked})}));var n=document.getElementById(`heartbeat-interval`);n&&(chrome.storage.local.get(`heartbeatInterval`).then(({heartbeatInterval:e})=>{n.value=String(e??10)}),n.addEventListener(`change`,()=>{let e=Math.max(5,Math.min(60,parseInt(n.value,10)||10));n.value=String(e),chrome.storage.local.set({heartbeatInterval:e})}));
30
- //# sourceMappingURL=options.js.map
29
+ `;const n=document.getElementById("debug-mode");n&&(chrome.storage.local.get("debugMode").then(({debugMode:r})=>{n.checked=!!r}),n.addEventListener("change",()=>{chrome.storage.local.set({debugMode:n.checked})}));const o=document.getElementById("heartbeat-interval");o&&(chrome.storage.local.get("heartbeatInterval").then(({heartbeatInterval:r})=>{o.value=String(r??10)}),o.addEventListener("change",()=>{const r=Math.max(5,Math.min(60,parseInt(o.value,10)||10));o.value=String(r),chrome.storage.local.set({heartbeatInterval:r})}));
30
+ //# sourceMappingURL=options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","names":[],"sources":["../../src/options/main.ts"],"sourcesContent":["const app = document.getElementById(\"app\")!;\n\napp.innerHTML = `\n <h1 style=\"font-size: 1.5rem; font-weight: bold; margin-bottom: 1.5rem;\">Surf Settings</h1>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">Debug Mode</h2>\n <label style=\"display: flex; align-items: center; gap: 0.5rem;\">\n <input type=\"checkbox\" id=\"debug-mode\" style=\"width: 1rem; height: 1rem;\" />\n <span>Enable debug logging</span>\n </label>\n </section>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">Static Indicator</h2>\n <label style=\"display: flex; align-items: center; gap: 0.5rem;\">\n <span>Heartbeat interval (seconds):</span>\n <input type=\"number\" id=\"heartbeat-interval\" min=\"5\" max=\"60\" value=\"10\" style=\"width: 4rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.25rem;\" />\n </label>\n <p class=\"muted\" style=\"font-size: 0.875rem; margin-top: 0.5rem;\">\n How often the static indicator checks if Surf is still active (5-60 seconds).\n </p>\n </section>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">About</h2>\n <p class=\"muted\">\n Surf v${chrome.runtime.getManifest().version}\n </p>\n </section>\n`;\n\nconst debugCheckbox = document.getElementById(\"debug-mode\") as HTMLInputElement | null;\nif (debugCheckbox) {\n chrome.storage.local.get(\"debugMode\").then(({ debugMode }) => {\n debugCheckbox.checked = !!debugMode;\n });\n debugCheckbox.addEventListener(\"change\", () => {\n chrome.storage.local.set({ debugMode: debugCheckbox.checked });\n });\n}\n\nconst heartbeatInput = document.getElementById(\"heartbeat-interval\") as HTMLInputElement | null;\nif (heartbeatInput) {\n chrome.storage.local.get(\"heartbeatInterval\").then(({ heartbeatInterval }) => {\n heartbeatInput.value = String(heartbeatInterval ?? 10);\n });\n heartbeatInput.addEventListener(\"change\", () => {\n const value = Math.max(5, Math.min(60, parseInt(heartbeatInput.value, 10) || 10));\n heartbeatInput.value = String(value);\n chrome.storage.local.set({ heartbeatInterval: value });\n });\n}\n"],"mappings":"0rBAAA,IAAM,EAAM,SAAS,eAAe,KAAK,EAEzC,EAAI,UAAY;;;;;;;;;;;;;;;;;;;;;;;;;cAyBF,OAAO,QAAQ,YAAY,CAAC,CAAC,QAAQ;;;EAKnD,IAAM,EAAgB,SAAS,eAAe,YAAY,EACtD,IACF,OAAO,QAAQ,MAAM,IAAI,WAAW,CAAC,CAAC,MAAM,CAAE,eAAgB,CAC5D,EAAc,QAAU,CAAC,CAAC,CAC5B,CAAC,EACD,EAAc,iBAAiB,aAAgB,CAC7C,OAAO,QAAQ,MAAM,IAAI,CAAE,UAAW,EAAc,OAAQ,CAAC,CAC/D,CAAC,GAGH,IAAM,EAAiB,SAAS,eAAe,oBAAoB,EAC/D,IACF,OAAO,QAAQ,MAAM,IAAI,mBAAmB,CAAC,CAAC,MAAM,CAAE,uBAAwB,CAC5E,EAAe,MAAQ,OAAO,GAAqB,EAAE,CACvD,CAAC,EACD,EAAe,iBAAiB,aAAgB,CAC9C,IAAM,EAAQ,KAAK,IAAI,EAAG,KAAK,IAAI,GAAI,SAAS,EAAe,MAAO,EAAE,GAAK,EAAE,CAAC,EAChF,EAAe,MAAQ,OAAO,CAAK,EACnC,OAAO,QAAQ,MAAM,IAAI,CAAE,kBAAmB,CAAM,CAAC,CACvD,CAAC"}
1
+ {"version":3,"file":"options.js","sources":["../../src/options/main.ts"],"sourcesContent":["const app = document.getElementById(\"app\")!;\n\napp.innerHTML = `\n <h1 style=\"font-size: 1.5rem; font-weight: bold; margin-bottom: 1.5rem;\">Surf Settings</h1>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">Debug Mode</h2>\n <label style=\"display: flex; align-items: center; gap: 0.5rem;\">\n <input type=\"checkbox\" id=\"debug-mode\" style=\"width: 1rem; height: 1rem;\" />\n <span>Enable debug logging</span>\n </label>\n </section>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">Static Indicator</h2>\n <label style=\"display: flex; align-items: center; gap: 0.5rem;\">\n <span>Heartbeat interval (seconds):</span>\n <input type=\"number\" id=\"heartbeat-interval\" min=\"5\" max=\"60\" value=\"10\" style=\"width: 4rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.25rem;\" />\n </label>\n <p class=\"muted\" style=\"font-size: 0.875rem; margin-top: 0.5rem;\">\n How often the static indicator checks if Surf is still active (5-60 seconds).\n </p>\n </section>\n \n <section style=\"margin-bottom: 2rem;\">\n <h2 style=\"font-size: 1.125rem; font-weight: 600; margin-bottom: 1rem;\">About</h2>\n <p class=\"muted\">\n Surf v${chrome.runtime.getManifest().version}\n </p>\n </section>\n`;\n\nconst debugCheckbox = document.getElementById(\"debug-mode\") as HTMLInputElement | null;\nif (debugCheckbox) {\n chrome.storage.local.get(\"debugMode\").then(({ debugMode }) => {\n debugCheckbox.checked = !!debugMode;\n });\n debugCheckbox.addEventListener(\"change\", () => {\n chrome.storage.local.set({ debugMode: debugCheckbox.checked });\n });\n}\n\nconst heartbeatInput = document.getElementById(\"heartbeat-interval\") as HTMLInputElement | null;\nif (heartbeatInput) {\n chrome.storage.local.get(\"heartbeatInterval\").then(({ heartbeatInterval }) => {\n heartbeatInput.value = String(heartbeatInterval ?? 10);\n });\n heartbeatInput.addEventListener(\"change\", () => {\n const value = Math.max(5, Math.min(60, parseInt(heartbeatInput.value, 10) || 10));\n heartbeatInput.value = String(value);\n chrome.storage.local.set({ heartbeatInterval: value });\n });\n}\n"],"names":["app","debugCheckbox","debugMode","heartbeatInput","heartbeatInterval","value"],"mappings":"ssBAAA,MAAMA,EAAM,SAAS,eAAe,KAAK,EAEzCA,EAAI,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAyBF,OAAO,QAAQ,YAAA,EAAc,OAAO;AAAA;AAAA;AAAA,EAKlD,MAAMC,EAAgB,SAAS,eAAe,YAAY,EACtDA,IACF,OAAO,QAAQ,MAAM,IAAI,WAAW,EAAE,KAAK,CAAC,CAAE,UAAAC,KAAgB,CAC5DD,EAAc,QAAU,CAAC,CAACC,CAC5B,CAAC,EACDD,EAAc,iBAAiB,SAAU,IAAM,CAC7C,OAAO,QAAQ,MAAM,IAAI,CAAE,UAAWA,EAAc,QAAS,CAC/D,CAAC,GAGH,MAAME,EAAiB,SAAS,eAAe,oBAAoB,EAC/DA,IACF,OAAO,QAAQ,MAAM,IAAI,mBAAmB,EAAE,KAAK,CAAC,CAAE,kBAAAC,KAAwB,CAC5ED,EAAe,MAAQ,OAAOC,GAAqB,EAAE,CACvD,CAAC,EACDD,EAAe,iBAAiB,SAAU,IAAM,CAC9C,MAAME,EAAQ,KAAK,IAAI,EAAG,KAAK,IAAI,GAAI,SAASF,EAAe,MAAO,EAAE,GAAK,EAAE,CAAC,EAChFA,EAAe,MAAQ,OAAOE,CAAK,EACnC,OAAO,QAAQ,MAAM,IAAI,CAAE,kBAAmBA,EAAO,CACvD,CAAC"}